optimised templates, broke tracks, improved music gateway UX. we ball

Signed-off-by: ari melody <ari@arimelody.me>
This commit is contained in:
ari melody 2024-03-21 05:19:18 +00:00
parent 6ec813dd58
commit 18c13699af
17 changed files with 593 additions and 496 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
**/.DS_Store **/.DS_Store
.idea/
tmp/ tmp/

View file

@ -619,7 +619,7 @@ var placeholders = []MusicRelease{
}, },
} }
func GetAlbum(id string) (MusicRelease, bool) { func GetRelease(id string) (MusicRelease, bool) {
for _, album := range placeholders { for _, album := range placeholders {
if album.Id == id { if album.Id == id {
return album, true return album, true
@ -628,7 +628,7 @@ func GetAlbum(id string) (MusicRelease, bool) {
return MusicRelease{}, false return MusicRelease{}, false
} }
func QueryAllAlbums() ([]MusicRelease) { func QueryAllMusic() ([]MusicRelease) {
return placeholders return placeholders
} }

77
main.go
View file

@ -30,13 +30,12 @@ var mime_types = map[string]string{
"js": "application/javascript", "js": "application/javascript",
} }
var templates = template.Must(template.ParseFiles( var base_template = template.Must(template.ParseFiles(
"views/base.html",
"views/header.html", "views/header.html",
"views/footer.html", "views/footer.html",
"views/index.html", ))
"views/music.html", var htmx_template = template.Must(template.New("root").Parse(`<head>{{block "head" .}}{{end}}</head>{{block "content" .}}{{end}}`))
"views/music-gateway.html",
))
func log_request(req *http.Request, code int, start_time time.Time) { func log_request(req *http.Request, code int, start_time time.Time) {
now := time.Now() now := time.Now()
@ -56,31 +55,41 @@ func log_request(req *http.Request, code int, start_time time.Time) {
) )
} }
func web_handler(writer http.ResponseWriter, req *http.Request) { func handle_request(writer http.ResponseWriter, req *http.Request) {
uri := req.URL.Path uri := req.URL.Path
start_time := time.Now() start_time := time.Now()
if req.URL.Path == "/" { hx_boosted := len(req.Header["Hx-Boosted"]) > 0 && req.Header["Hx-Boosted"][0] == "true"
code := index_handler(writer, req)
log_request(req, code, start_time) code := func(writer http.ResponseWriter, req *http.Request) int {
return var root *template.Template
} if hx_boosted {
if uri == "/music" { root = template.Must(htmx_template.Clone())
code := music_handler(writer, req) } else {
log_request(req, code, start_time) root = template.Must(base_template.Clone())
return }
}
if strings.HasPrefix(uri, "/music/") { if req.URL.Path == "/" {
code := music_gateway_handler(writer, req) return index_handler(writer, root)
log_request(req, code, start_time) }
return
} if uri == "/music" {
code := static_handler(writer, req) return music_directory_handler(writer, root)
}
if strings.HasPrefix(uri, "/music/") {
return music_gateway_handler(writer, req, root)
}
return static_handler(writer, req)
}(writer, req)
log_request(req, code, start_time) log_request(req, code, start_time)
} }
func index_handler(writer http.ResponseWriter, req *http.Request) int { func index_handler(writer http.ResponseWriter, root *template.Template) int {
err := templates.ExecuteTemplate(writer, "index.html", nil) index_template := template.Must(root.ParseFiles("views/index.html"))
err := index_template.Execute(writer, nil)
if err != nil { if err != nil {
http.Error(writer, err.Error(), http.StatusInternalServerError) http.Error(writer, err.Error(), http.StatusInternalServerError)
return 500 return 500
@ -88,8 +97,10 @@ func index_handler(writer http.ResponseWriter, req *http.Request) int {
return 200 return 200
} }
func music_handler(writer http.ResponseWriter, req *http.Request) int { func music_directory_handler(writer http.ResponseWriter, root *template.Template) int {
err := templates.ExecuteTemplate(writer, "music.html", music.QueryAllAlbums()) music_template := template.Must(root.ParseFiles("views/music.html"))
music := music.QueryAllMusic()
err := music_template.Execute(writer, music)
if err != nil { if err != nil {
http.Error(writer, err.Error(), http.StatusInternalServerError) http.Error(writer, err.Error(), http.StatusInternalServerError)
return 500 return 500
@ -97,7 +108,7 @@ func music_handler(writer http.ResponseWriter, req *http.Request) int {
return 200 return 200
} }
func music_gateway_handler(writer http.ResponseWriter, req *http.Request) int { func music_gateway_handler(writer http.ResponseWriter, req *http.Request, root *template.Template) int {
if len(req.URL.Path) <= len("/music/") { if len(req.URL.Path) <= len("/music/") {
http.Error(writer, "400 bad request", http.StatusBadRequest) http.Error(writer, "400 bad request", http.StatusBadRequest)
return 400 return 400
@ -106,12 +117,13 @@ func music_gateway_handler(writer http.ResponseWriter, req *http.Request) int {
id := req.URL.Path[len("/music/"):] id := req.URL.Path[len("/music/"):]
// http.Redirect(writer, req, "https://mellodoot.com/music/"+title, 302) // http.Redirect(writer, req, "https://mellodoot.com/music/"+title, 302)
// return // return
album, ok := music.GetAlbum(id) release, ok := music.GetRelease(id)
if !ok { if !ok {
http.Error(writer, "404 not found", http.StatusNotFound) http.Error(writer, "404 not found", http.StatusNotFound)
return 404 return 404
} }
err := templates.ExecuteTemplate(writer, "music-gateway.html", album) gateway_template := template.Must(root.ParseFiles("views/music-gateway.html"))
err := gateway_template.Execute(writer, release)
if err != nil { if err != nil {
http.Error(writer, err.Error(), http.StatusInternalServerError) http.Error(writer, err.Error(), http.StatusInternalServerError)
return 500 return 500
@ -180,22 +192,21 @@ func parse_markdown(md []byte) []byte {
func push_to_db_this_is_a_testing_thing_and_will_be_superfluous_later() { func push_to_db_this_is_a_testing_thing_and_will_be_superfluous_later() {
db := InitDatabase() db := InitDatabase()
defer db.Close()
for _, artist := range music.QueryAllArtists() { for _, artist := range music.QueryAllArtists() {
PushArtist(db, artist) PushArtist(db, artist)
} }
for _, album := range music.QueryAllAlbums() { for _, album := range music.QueryAllMusic() {
PushRelease(db, album) PushRelease(db, album)
} }
defer db.Close()
} }
func main() { func main() {
push_to_db_this_is_a_testing_thing_and_will_be_superfluous_later() push_to_db_this_is_a_testing_thing_and_will_be_superfluous_later()
http.HandleFunc("/", web_handler) http.HandleFunc("/", handle_request)
fmt.Printf("now serving at http://127.0.0.1:%d\n", PORT) fmt.Printf("now serving at http://127.0.0.1:%d\n", PORT)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", PORT), nil)) log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", PORT), nil))

1
public/script/lib/htmx.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -55,3 +55,11 @@ function fill_list(list) {
fill_list(e); fill_list(e);
}); });
document.addEventListener("htmx:afterSwap", async event => {
const res = await event.detail.xhr.response;
var new_head = res.substring(res.indexOf("<head>")+1, res.indexOf("</head>"));
if (new_head) {
document.head.innerHTML = new_head;
}
window.scrollY = 0;
});

View file

@ -28,6 +28,34 @@ function apply_funny_bob_to_upcoming_tags() {
} }
} }
const extras_pairs = Array.from(document.querySelectorAll("div#info > div").values().map(container => {
return {
container,
button: document.getElementById("extras").querySelector(`ul li a[href="#${container.id}"]`)
};
}));
const info_container = document.getElementById("info")
info_container.addEventListener("scroll", update_extras_buttons);
function update_extras_buttons() {
console.clear();
const info_rect = info_container.getBoundingClientRect();
const info_y = info_rect.y;
const font_size = parseFloat(getComputedStyle(document.documentElement).fontSize);
console.log("info_y: " + info_y);
let current = extras_pairs[0];
extras_pairs.forEach(pair => {
pair.button.classList.remove("active");
const scroll_diff = pair.container.getBoundingClientRect().y -
info_rect.y -
info_rect.height / 2 +
4 * font_size;
if (scroll_diff <= 0) current = pair;
console.log(`${pair.container.id}: ${scroll_diff}`);
})
current.button.classList.add("active");
}
update_extras_buttons();
document.querySelectorAll("div#extras ul li a[href]").forEach(link => { document.querySelectorAll("div#extras ul li a[href]").forEach(link => {
link.addEventListener("click", event => { link.addEventListener("click", event => {
event.preventDefault(); event.preventDefault();

View file

@ -63,4 +63,4 @@ function load_pride_flag_style() {
load_pride_flag_style(); load_pride_flag_style();
pride_flag = create_pride_flag(); pride_flag = create_pride_flag();
document.body.appendChild(pride_flag); document.querySelector("main").appendChild(pride_flag);

View file

@ -3,7 +3,8 @@
main { main {
width: min(calc(100% - 4rem), 720px); width: min(calc(100% - 4rem), 720px);
min-height: calc(100vh - 10.3rem); min-height: calc(100vh - 10.3rem);
margin: 5rem auto 2rem auto; margin: 0 auto 2rem auto;
padding-top: 5rem;
} }
main h1 { main h1 {

View file

@ -21,6 +21,9 @@ body {
scroll-behavior: smooth; scroll-behavior: smooth;
} }
main {
}
a { a {
color: var(--links); color: var(--links);
text-decoration: none; text-decoration: none;

View file

@ -70,7 +70,6 @@ main {
gap: 4rem; gap: 4rem;
font-size: 16px; font-size: 16px;
animation: card-init .5s forwards; animation: card-init .5s forwards;
overflow-y: clip;
padding: 4rem; padding: 4rem;
} }
@ -97,7 +96,6 @@ main {
width: 33.3%; width: 33.3%;
height: 33.3%; height: 33.3%;
z-index: 2; z-index: 2;
/* pointer-events: none; */
} }
#art-container > div.tilt-topleft { #art-container > div.tilt-topleft {
@ -208,10 +206,25 @@ div#vertical-line {
} }
div#info { div#info {
display: flex; margin: -4rem;
flex-direction: column; padding: 4rem;
transition: transform .5s ease; height: 360px;
gap: 6rem; overflow: scroll;
scroll-behavior: smooth;
scrollbar-width: thin;
scrollbar-color: #111;
mask-image: linear-gradient(to bottom, transparent 0%, black 10%, black 90%, transparent 100%);
}
div#info > div {
min-height: 360px;
padding: 4rem 1rem 4rem 4rem;
margin: -4rem -3.5rem -4rem -4rem;
}
div#info p {
max-width: 500px;
white-space: pre-line;
} }
#title-container { #title-container {
@ -279,18 +292,26 @@ div#info {
display: inline-block; display: inline-block;
} }
#links { ul#links {
width: 100%;
margin: 1rem 0; margin: 1rem 0;
padding: 0;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
gap: .5rem gap: .5rem;
list-style: none;
} }
#links a { ul#links li {
padding: .5em .8em;
border-radius: 4px;
flex-grow: 1; flex-grow: 1;
}
ul#links a {
width: calc(100% - 1.6em);
padding: .5em .8em;
display: block;
border-radius: 4px;
font-size: 1em; font-size: 1em;
color: #111; color: #111;
background-color: #fff; background-color: #fff;
@ -299,31 +320,31 @@ div#info {
transition: filter .1s,-webkit-filter .1s transition: filter .1s,-webkit-filter .1s
} }
#links a.buy { ul#links a.buy {
background-color: #ff94e9 background-color: #ff94e9
} }
#links a.presave { ul#links a.presave {
background-color: #ff94e9 background-color: #ff94e9
} }
#links a.spotify { ul#links a.spotify {
background-color: #8cff83 background-color: #8cff83
} }
#links a.applemusic { ul#links a.applemusic {
background-color: #8cd9ff background-color: #8cd9ff
} }
#links a.soundcloud { ul#links a.soundcloud {
background-color: #fdaa6d background-color: #fdaa6d
} }
#links a.youtube { ul#links a.youtube {
background-color: #ff6e6e background-color: #ff6e6e
} }
#links a:hover { ul#links a:hover {
filter: brightness(125%); filter: brightness(125%);
-webkit-filter: brightness(125%) -webkit-filter: brightness(125%)
} }
@ -357,24 +378,11 @@ div#extras ul li a {
transition: color .1s linear; transition: color .1s linear;
} }
div#extras ul li a:hover { div#extras ul li a:hover,
div#extras ul li a.active {
color: #eee; color: #eee;
} }
div#info > div {
max-height: 360px;
min-height: 360px;
overflow-y: scroll;
padding: 2rem 1rem 2rem 4rem;
margin: -2rem -3.5rem -2rem -4rem;
mask-image: linear-gradient(to bottom, transparent 0%, black 10%, black 90%, transparent 100%);
}
div#info p {
max-width: 500px;
white-space: pre-line;
}
a.scrollback { a.scrollback {
color: #888; color: #888;
font-style: italic; font-style: italic;
@ -497,6 +505,7 @@ footer a:hover {
text-decoration: underline text-decoration: underline
} }
/*
@media only screen and (min-width: 1105px) { @media only screen and (min-width: 1105px) {
div#music-container:not(:has(> div#info #credits:target)):not(:has(> div#info #lyrics:target)) { div#music-container:not(:has(> div#info #credits:target)):not(:has(> div#info #lyrics:target)) {
div#extras ul li:first-of-type a { div#extras ul li:first-of-type a {
@ -505,23 +514,18 @@ footer a:hover {
} }
div#music-container:has(> div#info #credits:target) { div#music-container:has(> div#info #credits:target) {
div#info {
transform: translateY(calc(-360px + -6rem));
}
div#extras ul li a[href="#credits"] { div#extras ul li a[href="#credits"] {
color: #eee; color: #eee;
} }
} }
div#music-container:has(> div#info #lyrics:target) { div#music-container:has(> div#info #lyrics:target) {
div#info {
transform: translateY(calc((-360px + -6rem) * 2));
}
div#extras ul li a[href="#lyrics"] { div#extras ul li a[href="#lyrics"] {
color: #eee; color: #eee;
} }
} }
} }
*/
@media only screen and (max-width: 1105px) { @media only screen and (max-width: 1105px) {
main { main {
@ -557,11 +561,12 @@ footer a:hover {
div#info { div#info {
width: 100%; width: 100%;
gap: 2rem; gap: 2rem;
height: auto;
overflow-y: auto;
} }
div#info > div { div#info > div {
max-height: fit-content; min-height: auto;
min-height: fit-content;
padding: 0; padding: 0;
margin: 0; margin: 0;
overflow-y: unset; overflow-y: unset;

50
views/base.html Normal file
View file

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{{block "head" .}}
<!-- <title>ari melody 💫</title> -->
<!-- <link rel="shortcut icon" href="img/favicon.png" type="image/x-icon"> -->
<!---->
<!-- <meta name="description" content="home to your local SPACEGIRL 💫"> -->
<!---->
<!-- <meta property="og:title" content="ari melody"> -->
<!-- <meta property="og:type" content="website"> -->
<!-- <meta property="og:url" content="www.arimelody.me"> -->
<!-- <meta property="og:image" content="https://www.arimelody.me/img/favicon.png"> -->
<!-- <meta property="og:site_name" content="ari melody"> -->
<!-- <meta property="og:description" content="home to your local SPACEGIRL 💫"> -->
<!---->
<!-- <link rel="stylesheet" href="style/main.css"> -->
<!---->
<!-- <script type="module" src="/script/main.js" defer></script> -->
{{end}}
<!-- <script type="application/javascript" src="/script/lib/htmx.min.js"></script> -->
</head>
<body>
{{template "header"}}
{{block "content" .}}
<main>
<h1>
# hello, world!
</h1>
<p>
this is a default page!
</p>
</main>
{{end}}
{{template "footer"}}
<div id="overlay"></div>
</body>
</html>

View file

@ -1,6 +1,6 @@
{{define "footer"}} {{define "footer"}}
<footer> <footer hx-preserve="true">
<div id="footer"> <div id="footer">
<small><em>*made with ♥ by ari, 2024*</em></small> <small><em>*made with ♥ by ari, 2024*</em></small>
</div> </div>

View file

@ -1,6 +1,6 @@
{{define "header"}} {{define "header"}}
<header> <header hx-preserve="true">
<nav> <nav>
<div id="header-home"> <div id="header-home">
<img src="/img/favicon.png" id="header-icon" width="100" height="100" alt=""> <img src="/img/favicon.png" id="header-icon" width="100" height="100" alt="">

28
views/htmx-base.html Normal file
View file

@ -0,0 +1,28 @@
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{{block "head" .}}
<title>ari melody 💫</title>
<link rel="shortcut icon" href="img/favicon.png" type="image/x-icon">
<meta name="description" content="home to your local SPACEGIRL 💫">
<meta property="og:title" content="ari melody">
<meta property="og:type" content="website">
<meta property="og:url" content="www.arimelody.me">
<meta property="og:image" content="https://www.arimelody.me/img/favicon.png">
<meta property="og:site_name" content="ari melody">
<meta property="og:description" content="home to your local SPACEGIRL 💫">
<link rel="stylesheet" href="style/main.css">
<script type="module" src="/script/main.js" defer></script>
{{end}}
<script type="application/javascript" src="/script/lib/htmx.min.js"></script>
</head>
{{block "content" .}}{{end}}

View file

@ -1,195 +1,182 @@
<!DOCTYPE html> {{define "head"}}
<html lang="en"> <title>ari melody 💫</title>
<head> <link rel="shortcut icon" href="/img/favicon.png" type="image/x-icon">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ari melody 💫</title> <meta name="description" content="home to your local SPACEGIRL 💫">
<link rel="shortcut icon" href="img/favicon.png" type="image/x-icon">
<meta name="description" content="home to your local SPACEGIRL 💫"> <meta property="og:title" content="ari melody">
<meta property="og:type" content="website">
<meta property="og:url" content="www.arimelody.me">
<meta property="og:image" content="https://www.arimelody.me/img/favicon.png">
<meta property="og:site_name" content="ari melody">
<meta property="og:description" content="home to your local SPACEGIRL 💫">
<meta property="og:title" content="ari melody"> <link rel="stylesheet" href="/style/index.css">
<meta property="og:type" content="website">
<meta property="og:url" content="www.arimelody.me">
<meta property="og:image" content="https://www.arimelody.me/img/favicon.png">
<meta property="og:site_name" content="ari melody">
<meta property="og:description" content="home to your local SPACEGIRL 💫">
<link rel="stylesheet" href="style/index.css"> <script type="module" src="/script/main.js" defer></script>
<link rel="me" href="https://wetdry.world/@ari">
{{end}}
<script type="module" src="/script/main.js" defer></script> {{define "content"}}
<link rel="me" href="https://wetdry.world/@ari"> <main>
</head> <h1>
<body> # hello, world!
{{block "header" .}}{{end}} </h1>
<main>
<h1>
# hello, world!
</h1>
<p> <p>
<strong>i'm ari!</strong> <strong>i'm ari!</strong>
<br> <br>
<small>she/her 🏳️‍⚧️🏳️‍🌈💫🦆🇮🇪</small> <small>she/her 🏳️‍⚧️🏳️‍🌈💫🦆🇮🇪</small>
</p> </p>
<p> <p>
i like to create things on the internet! namely <a href="/music">music</a>, i like to create things on the internet! namely <a href="/music">music</a>,
<a href="https://youtube.com/mellodoot" target="_blank">videos</a>, art <small><em>(link pending)</em></small>, and the odd <a href="https://youtube.com/mellodoot" target="_blank">videos</a>, art <small><em>(link pending)</em></small>, and the odd
<a href="https://github.com/mellodoot?tab=repositories" target="_blank">code project</a> from time to time! <a href="https://github.com/mellodoot?tab=repositories" target="_blank">code project</a> from time to time!
if it's a thing you can create on a computer, i've probably taken a swing at it. if it's a thing you can create on a computer, i've probably taken a swing at it.
</p> </p>
<p> <p>
you're very welcome to take a look around my little slice of the internet here, you're very welcome to take a look around my little slice of the internet here,
or explore any of the other corners i inhabit! or explore any of the other corners i inhabit!
</p> </p>
<p> <p>
and if you're looking to support me financially, that's so cool of you!! and if you're looking to support me financially, that's so cool of you!!
if you like, you can buy one or more of my songs over on if you like, you can buy one or more of my songs over on
<a href="https://arimelody.bandcamp.com" target="_blank">bandcamp</a>, <a href="https://arimelody.bandcamp.com" target="_blank">bandcamp</a>,
so you can at least get something for your money. so you can at least get something for your money.
thank you very much either way!! 💕 thank you very much either way!! 💕
</p> </p>
<p> <p>
for anything else, you can reach me for any and all communications through for anything else, you can reach me for any and all communications through
<a href="mailto:ari@arimelody.me">ari@arimelody.me</a>. if your message <a href="mailto:ari@arimelody.me">ari@arimelody.me</a>. if your message
contains anything beyond a silly gag, i strongly recommend encrypting contains anything beyond a silly gag, i strongly recommend encrypting
your message using my public pgp key, listed below! your message using my public pgp key, listed below!
</p> </p>
<p> <p>
thank you for stopping by- i hope you have a lovely rest of your day! 💫 thank you for stopping by- i hope you have a lovely rest of your day! 💫
</p> </p>
<hr> <hr>
<h2> <h2>
## metadata ## metadata
</h2> </h2>
<p> <p>
<strong>my colours 🌈</strong> <strong>my colours 🌈</strong>
</p> </p>
<ul> <ul>
<li>primary: <span class="col-primary">#b7fd49</span></li> <li>primary: <span class="col-primary">#b7fd49</span></li>
<li>secondary: <span class="col-secondary">#f8e05b</span></li> <li>secondary: <span class="col-secondary">#f8e05b</span></li>
<li>tertiary: <span class="col-tertiary">#f788fe</span></li> <li>tertiary: <span class="col-tertiary">#f788fe</span></li>
</ul> </ul>
<p> <p>
<strong>my keys 🔑</strong> <strong>my keys 🔑</strong>
</p> </p>
<ul> <ul>
<li>pgp: <a href="/keys/ari melody_0x92678188_public.asc" target="_blank">[link]</a></li> <li>pgp: <a href="/keys/ari melody_0x92678188_public.asc" target="_blank">[link]</a></li>
<li>ssh (ed25519): <a href="/keys/id_ari_ed25519.pub" target="_blank">[link]</a></li> <li>ssh (ed25519): <a href="/keys/id_ari_ed25519.pub" target="_blank">[link]</a></li>
</ul> </ul>
<p> <p>
<strong>where to find me 🛰️</strong> <strong>where to find me 🛰️</strong>
</p> </p>
<ul class="links"> <ul class="links">
<li> <li>
<a href="https://youtube.com/@mellodoot" target="_blank">youtube</a> <a href="https://youtube.com/@mellodoot" target="_blank">youtube</a>
</li> </li>
<li> <li>
<a href="https://mellodoot.tumblr.com" target="_blank">tumblr</a> <a href="https://mellodoot.tumblr.com" target="_blank">tumblr</a>
</li> </li>
<li> <li>
<a href="https://twitch.tv/mellodoot" target="_blank">twitch</a> <a href="https://twitch.tv/mellodoot" target="_blank">twitch</a>
</li> </li>
<li> <li>
<a href="https://sptfy.com/mellodoot" target="_blank">spotify</a> <a href="https://sptfy.com/mellodoot" target="_blank">spotify</a>
</li> </li>
<li> <li>
<a href="https://soundcloud.com/arimelody" target="_blank">soundcloud</a> <a href="https://soundcloud.com/arimelody" target="_blank">soundcloud</a>
</li> </li>
<li> <li>
<a href="https://github.com/mellodoot" target="_blank">github</a> <a href="https://github.com/mellodoot" target="_blank">github</a>
</li> </li>
</ul> </ul>
<p> <p>
<strong>projects i've worked on 🛠️</strong> <strong>projects i've worked on 🛠️</strong>
</p> </p>
<ul class="links"> <ul class="links">
<li> <li>
<a href="https://catdance.xyz" target="_blank"> <a href="https://catdance.xyz" target="_blank">
catdance catdance
</a> </a>
</li> </li>
<li> <li>
<a href="https://github.com/mellodoot/sandblock" target="_blank"> <a href="https://github.com/mellodoot/sandblock" target="_blank">
sandblock sandblock
</a> </a>
</li> </li>
<li> <li>
<a href="https://github.com/mellodoot/prideflag" target="_blank"> <a href="https://github.com/mellodoot/prideflag" target="_blank">
pride flag pride flag
</a> </a>
</li> </li>
<li> <li>
<a href="https://github.com/mellodoot/ipaddrgen" target="_blank"> <a href="https://github.com/mellodoot/ipaddrgen" target="_blank">
ipaddrgen ipaddrgen
</a> </a>
</li> </li>
<li> <li>
<a href="https://impact.arimelody.me/" target="_blank"> <a href="https://impact.arimelody.me/" target="_blank">
impact meme impact meme
</a> </a>
</li> </li>
<li> <li>
<a href="https://term.arimelody.me/" target="_blank"> <a href="https://term.arimelody.me/" target="_blank">
OpenTerminal OpenTerminal
</a> </a>
</li> </li>
</ul> </ul>
<hr> <hr>
<h2>## cool people</h2> <h2>## cool people</h2>
<div id="web-buttons"> <div id="web-buttons">
<a href="https://arimelody.me"> <a href="https://arimelody.me">
<img src="/img/buttons/ari melody.gif" alt="ari melody web button"> <img src="/img/buttons/ari melody.gif" alt="ari melody web button">
</a> </a>
<a href="https://supitszaire.com" target="_blank"> <a href="https://supitszaire.com" target="_blank">
<img src="/img/buttons/zaire.gif" alt="zaire web button"> <img src="/img/buttons/zaire.gif" alt="zaire web button">
</a> </a>
<a href="https://mae.wtf" target="_blank"> <a href="https://mae.wtf" target="_blank">
<img src="/img/buttons/mae.png" alt="vimae web button"> <img src="/img/buttons/mae.png" alt="vimae web button">
</a> </a>
<hr> <hr>
<img src="/img/buttons/misc/debian.gif" alt="powered by debian"> <img src="/img/buttons/misc/debian.gif" alt="powered by debian">
<img src="/img/buttons/misc/girls4notepad.gif" alt="girls 4 notepad"> <img src="/img/buttons/misc/girls4notepad.gif" alt="girls 4 notepad">
<img src="/img/buttons/misc/gaywebring.gif" alt="this website is GAY"> <img src="/img/buttons/misc/gaywebring.gif" alt="this website is GAY">
<img src="/img/buttons/misc/graphicdesign.gif" alt="graphic design is my passion"> <img src="/img/buttons/misc/graphicdesign.gif" alt="graphic design is my passion">
<img src="/img/buttons/misc/gplv3.gif" alt="GPLv3 free software"> <img src="/img/buttons/misc/gplv3.gif" alt="GPLv3 free software">
<img src="/img/buttons/misc/hl.gif" alt="half-life"> <img src="/img/buttons/misc/hl.gif" alt="half-life">
<img src="/img/buttons/misc/h-free-anim.gif" alt="dis site is hentai FREE"> <img src="/img/buttons/misc/h-free-anim.gif" alt="dis site is hentai FREE">
<img src="/img/buttons/misc/sprunk.gif" alt="sprunk"> <img src="/img/buttons/misc/sprunk.gif" alt="sprunk">
<img src="/img/buttons/misc/tohell.gif" alt="go straight to hell"> <img src="/img/buttons/misc/tohell.gif" alt="go straight to hell">
<img src="/img/buttons/misc/virusalert.gif" alt="virus alert! click here" onclick="alert('meow :3')"> <img src="/img/buttons/misc/virusalert.gif" alt="virus alert! click here" onclick="alert('meow :3')">
<img src="/img/buttons/misc/wii.gif" alt="wii"> <img src="/img/buttons/misc/wii.gif" alt="wii">
<img src="/img/buttons/misc/www2.gif" alt="www"> <img src="/img/buttons/misc/www2.gif" alt="www">
<img src="/img/buttons/misc/iemandatory.gif" alt="get mandatory internet explorer"> <img src="/img/buttons/misc/iemandatory.gif" alt="get mandatory internet explorer">
<img src="/img/buttons/misc/learn_html.gif" alt="HTML - learn it today!"> <img src="/img/buttons/misc/learn_html.gif" alt="HTML - learn it today!">
<a href="https://smokepowered.com" target="_blank"> <a href="https://smokepowered.com" target="_blank">
<img src="/img/buttons/misc/smokepowered.gif" alt="high on SMOKE"> <img src="/img/buttons/misc/smokepowered.gif" alt="high on SMOKE">
</a> </a>
<a href="https://epicblazed.com" target="_blank"> <a href="https://epicblazed.com" target="_blank">
<img src="/img/buttons/misc/epicblazed.png" alt="epic blazed"> <img src="/img/buttons/misc/epicblazed.png" alt="epic blazed">
</a> </a>
</div> </div>
</main> </main>
{{end}}
{{block "footer" .}}{{end}}
<div id="overlay"></div>
</body>
</html>

View file

@ -1,160 +1,149 @@
<!DOCTYPE html> {{define "head"}}
<html lang="en"> <title>{{.PrintPrimaryArtists}} - {{.Title}}</title>
<head> <link rel="icon" href="{{.ResolveArtwork}}">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.PrintPrimaryArtists}} - {{.Title}}</title> <meta name="description" content="Stream &quot;{{.Title}}&quot; by {{.PrintPrimaryArtists}} on all platforms!">
<link rel="icon" href="{{.ResolveArtwork}}"> <meta name="author" content="{{.PrintPrimaryArtists}}">
<meta name="keywords" content="{{.PrintCommaPrimaryArtists}}, music, {{.Title}}, {{.Id}}, {{.GetReleaseYear}}">
<meta name="description" content="Stream &quot;{{.Title}}&quot; by {{.PrintPrimaryArtists}} on all platforms!"> <meta property="og:url" content="https://arimelody.me/music/{{.Id}}">
<meta name="author" content="{{.PrintPrimaryArtists}}"> <meta property="og:type" content="website">
<meta name="keywords" content="{{.PrintCommaPrimaryArtists}}, music, {{.Title}}, {{.Id}}, {{.GetReleaseYear}}"> <meta property="og:locale" content="en_IE">
<meta property="og:site_name" content="ari melody music">
<meta property="og.Title" content="{{.PrintPrimaryArtists}} - {{.Title}}">
<meta property="og:description" content="Stream &quot;{{.Title}}&quot; by {{.PrintPrimaryArtists}} on all platforms!">
<meta property="og:image" content="https://arimelody.me{{.ResolveArtwork}}">
<meta property="og:url" content="https://arimelody.me/music/{{.Id}}"> <meta name="twitter:card" content="summary_large_image">
<meta property="og:type" content="website"> <meta name="twitter:site" content="@funniduck">
<meta property="og:locale" content="en_IE"> <meta name="twitter:creator" content="@funniduck">
<meta property="og:site_name" content="ari melody music"> <meta property="twitter:domain" content="arimelody.me">
<meta property="og.Title" content="{{.PrintPrimaryArtists}} - {{.Title}}"> <meta property="twitter:url" content="https://arimelody.me/music/{{.Id}}">
<meta property="og:description" content="Stream &quot;{{.Title}}&quot; by {{.PrintPrimaryArtists}} on all platforms!"> <meta name="twitter.Title" content="{{.PrintPrimaryArtists}} - {{.Title}}">
<meta property="og:image" content="https://arimelody.me{{.ResolveArtwork}}"> <meta name="twitter:description" content="Stream &quot;{{.Title}}&quot; by mellodoot on all platforms!">
<meta name="twitter:image" content="https://arimelody.me{{.ResolveArtwork}}">
<meta name="twitter:image:alt" content="Cover art for &quot;{{.Title}}&quot;">
<meta name="twitter:card" content="summary_large_image"> <script type="module" src="/script/music-gateway.js" defer></script>
<meta name="twitter:site" content="@funniduck"> <script type="application/javascript" src="/script/prideflag.js" defer></script>
<meta name="twitter:creator" content="@funniduck"> <link rel="stylesheet" href="/style/music-gateway.css">
<meta property="twitter:domain" content="arimelody.me"> {{end}}
<meta property="twitter:url" content="https://arimelody.me/music/{{.Id}}">
<meta name="twitter.Title" content="{{.PrintPrimaryArtists}} - {{.Title}}">
<meta name="twitter:description" content="Stream &quot;{{.Title}}&quot; by mellodoot on all platforms!">
<meta name="twitter:image" content="https://arimelody.me{{.ResolveArtwork}}">
<meta name="twitter:image:alt" content="Cover art for &quot;{{.Title}}&quot;">
<script type="module" src="/script/music-gateway.js" defer></script> {{define "content"}}
<script type="text/javascript" src="/script/prideflag.js" defer></script> <main>
<link rel="stylesheet" href="/style/music-gateway.css"> <div id="background" data-url="{{.ResolveArtwork}}"></div>
</head> <div id="overlay"></div>
<body>
<div id="background" data-url="{{.ResolveArtwork}}"></div>
<div id="overlay"></div>
<a id="go-back" title="back to arimelody.me" href="/music">&lt;</a> <a id="go-back" title="back to arimelody.me" href="/music">&lt;</a>
{{block "header" .}}{{end}} <div id="music-container">
<div id="art-container">
<main> <div class="tilt-topleft"></div>
<div id="music-container"> <div class="tilt-top"></div>
<div id="art-container"> <div class="tilt-topright"></div>
<div class="tilt-topleft"></div> <div class="tilt-right"></div>
<div class="tilt-top"></div> <div class="tilt-bottomright"></div>
<div class="tilt-topright"></div> <div class="tilt-bottom"></div>
<div class="tilt-right"></div> <div class="tilt-bottomleft"></div>
<div class="tilt-bottomright"></div> <div class="tilt-left"></div>
<div class="tilt-bottom"></div> <img id="artwork" src="{{.ResolveArtwork}}" alt="{{.Title}} artwork" width=240 height=240>
<div class="tilt-bottomleft"></div> </div>
<div class="tilt-left"></div> <div id="vertical-line"></div>
<img id="artwork" src="{{.ResolveArtwork}}" alt="{{.Title}} artwork" width=240 height=240> <div id="info">
<div id="overview">
<div id="title-container">
<h1 id="title">{{.Title}}</h1>
<span id="year" title="{{.PrintReleaseDate}}">{{.GetReleaseYear}}</span>
</div> </div>
<div id="vertical-line"></div> <p id="artist">{{.PrintPrimaryArtists}}</p>
<div id="info"> <p id="type" class="{{.ResolveType}}">{{.ResolveType}}</p>
<div id="main">
<div id="title-container">
<h1 id="title">{{.Title}}</h1>
<span id="year" title="{{.PrintReleaseDate}}">{{.GetReleaseYear}}</span>
</div>
<p id="artist">{{.PrintPrimaryArtists}}</p>
<p id="type" class="{{.ResolveType}}">{{.ResolveType}}</p>
<div id="links"> <ul id="links">
{{if .Buylink}} {{if .Buylink}}
<a href="{{.Buylink}}" class="buy"> <li>
{{if .Buyname}}{{.Buyname}}{{else}}buy{{end}} <a href="{{.Buylink}}" class="buy">{{or .Buyname "buy"}}</a>
</a> </li>
{{end}}
{{range .Links}}
<a class="{{.NormaliseName}}" href="{{.Url}}">
{{.Name}}
</a>
{{end}}
</div>
{{if .Description}}
<p id="description">
{{.Description}}
</p>
{{end}}
<p id="share">share</p>
</div>
{{if .Credits}}
<div id="credits">
<h2>credits:</h2>
<ul>
{{range .Credits}}
{{$Artist := .ResolveArtist}}
{{if $Artist.Website}}
<li><strong><a href="{{$Artist.Website}}">{{$Artist.Name}}</a></strong>: {{.Role}}</li>
{{else}}
<li><strong>{{$Artist.Name}}</strong>: {{.Role}}</li>
{{end}}
{{end}}
</ul>
</div>
{{end}} {{end}}
{{if .Lyrics}} {{range .Links}}
<div id="lyrics"> <li>
<h2>lyrics:</h2> <a class="{{.NormaliseName}}" href="{{.Url}}">{{.Name}}</a>
<p>{{.Lyrics}}</p> </li>
</div>
{{end}} {{end}}
</div> </ul>
{{if or .Credits .Lyrics}} {{if .Description}}
<div id="extras"> <p id="description">
<ul> {{.Description}}
<li><a href="#">overview</a></li> </p>
{{if .Credits}}
<li><a href="#credits">credits</a></li>
{{end}}
{{if .Lyrics}}
<li><a href="#lyrics">lyrics</a></li>
{{end}}
</ul>
</div>
{{end}} {{end}}
<!-- <div id="tracks"> -->
<!-- <% var file = `/audio/preview/${data.id}.webm` %> -->
<!-- <% if (data.tracks && typeof(data.tracks) == typeof([])) { %> -->
<!-- <% for( let i = 0; i < data.tracks.length; i++ ) { %> -->
<!-- <% -->
<!-- songid = data.tracks[i].title.toLowerCase().replace(/[^a-z0-9]/g, ""); -->
<!-- file = `/audio/preview/${data.id}-${songid}.webm`; -->
<!-- %> -->
<!---->
<!-- <div class="track-preview" id="preview-<%= songid %>"> -->
<!-- <i class="fa-solid fa-play play"></i> -->
<!-- <p><%= data.tracks[i].title %></p> -->
<!-- <audio src="<%= file %>"></audio> -->
<!-- </div> -->
<!---->
<!-- <% } %> -->
<!-- <% } else { %> -->
<!-- <div class="track-preview" id="preview-<%= data.id %>"> -->
<!-- <i class="fa-solid fa-play play"></i> -->
<!-- <p>{{.Title}}</p> -->
<!-- <audio src="<%= file %>"></audio> -->
<!-- </div> -->
<!-- <% } %> -->
<!-- </div> -->
</div>
</main>
{{block "footer" .}}{{end}} <p id="share">share</p>
</body> </div>
</html>
{{if .Credits}}
<div id="credits">
<h2>credits:</h2>
<ul>
{{range .Credits}}
{{$Artist := .ResolveArtist}}
{{if $Artist.Website}}
<li><strong><a href="{{$Artist.Website}}">{{$Artist.Name}}</a></strong>: {{.Role}}</li>
{{else}}
<li><strong>{{$Artist.Name}}</strong>: {{.Role}}</li>
{{end}}
{{end}}
</ul>
</div>
{{end}}
<!-- {{if .Lyrics}} -->
<!-- <div id="lyrics"> -->
<!-- <h2>lyrics:</h2> -->
<!-- <p>{{.Lyrics}}</p> -->
<!-- </div> -->
<!-- {{end}} -->
</div>
{{if or .Credits .Lyrics}}
<div id="extras">
<ul>
<li><a href="#overview">overview</a></li>
{{if .Credits}}
<li><a href="#credits">credits</a></li>
{{end}}
<!-- {{if .Lyrics}} -->
<!-- <li><a href="#lyrics">lyrics</a></li> -->
<!-- {{end}} -->
</ul>
</div>
{{end}}
<!-- <div id="tracks"> -->
<!-- <% var file = `/audio/preview/${data.id}.webm` %> -->
<!-- <% if (data.tracks && typeof(data.tracks) == typeof([])) { %> -->
<!-- <% for( let i = 0; i < data.tracks.length; i++ ) { %> -->
<!-- <% -->
<!-- songid = data.tracks[i].title.toLowerCase().replace(/[^a-z0-9]/g, ""); -->
<!-- file = `/audio/preview/${data.id}-${songid}.webm`; -->
<!-- %> -->
<!---->
<!-- <div class="track-preview" id="preview-<%= songid %>"> -->
<!-- <i class="fa-solid fa-play play"></i> -->
<!-- <p><%= data.tracks[i].title %></p> -->
<!-- <audio src="<%= file %>"></audio> -->
<!-- </div> -->
<!---->
<!-- <% } %> -->
<!-- <% } else { %> -->
<!-- <div class="track-preview" id="preview-<%= data.id %>"> -->
<!-- <i class="fa-solid fa-play play"></i> -->
<!-- <p>{{.Title}}</p> -->
<!-- <audio src="<%= file %>"></audio> -->
<!-- </div> -->
<!-- <% } %> -->
<!-- </div> -->
</div>
</main>
{{end}}

View file

@ -1,104 +1,89 @@
<!DOCTYPE html> {{define "head"}}
<html lang="en"> <title>music - ari melody 💫</title>
<head> <link rel="shortcut icon" href="/img/favicon.png" type="image/x-icon">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>music - ari melody 💫</title> <meta name="description" content="music from your local SPACEGIRL 💫">
<link rel="shortcut icon" href="/img/favicon.png" type="image/x-icon">
<meta name="description" content="music from your local SPACEGIRL 💫"> <meta property="og:title" content="ari melody music">
<meta property="og:type" content="website">
<meta property="og:url" content="www.arimelody.me/music">
<meta property="og:image" content="https://www.arimelody.me/img/favicon.png">
<meta property="og:site_name" content="ari melody">
<meta property="og:description" content="music from your local SPACEGIRL 💫">
<meta property="og:title" content="ari melody music"> <link rel="stylesheet" href="/style/music.css">
<meta property="og:type" content="website">
<meta property="og:url" content="www.arimelody.me/music">
<meta property="og:image" content="https://www.arimelody.me/img/favicon.png">
<meta property="og:site_name" content="ari melody">
<meta property="og:description" content="music from your local SPACEGIRL 💫">
<link rel="stylesheet" href="/style/main.css"> <script type="module" src="/script/main.js" defer></script>
<link rel="stylesheet" href="/style/music.css"> <script type="application/javascript" src="/script/music.js" defer></script>
{{end}}
<script type="module" src="/script/main.js" defer></script> {{define "content"}}
<script type="application/javascript" src="/script/accessibility.js" defer></script> <main>
<script type="application/javascript" src="/script/music.js" defer></script> <h1>
</head> # my music
<body> </h1>
{{block "header" .}}{{end}}
<main> <div id="music-container">
<h1> {{range $Album := .}}
# my music <div class="music" id="{{$Album.Id}}">
</h1> <div class="music-artwork">
<img src="{{$Album.ResolveArtwork}}" alt="{{$Album.Title}} artwork" width="128">
<div id="music-container">
{{range $Album := .}}
<div class="music" id="{{$Album.Id}}">
<div class="music-artwork">
<img src="{{$Album.ResolveArtwork}}" alt="{{$Album.Title}} artwork" width="128">
</div>
<div class="music-details">
<a href="/music/{{$Album.Id}}"><h1 class="music-title">{{$Album.Title}}</h1></a>
<h2 class="music-artist">{{$Album.PrintPrimaryArtists}}</h2>
<h3 class="music-type-{{.ResolveType}}">{{$Album.ResolveType}}</h3>
<ul class="music-links">
{{range $Link := $Album.Links}}
<li>
<a href="{{$Link.Url}}">{{$Link.Name}}</a>
</li>
{{end}}
</ul>
</div>
</div>
{{end}}
</div> </div>
<div class="music-details">
<h2 id="usage" class="question"> <a href="/music/{{$Album.Id}}"><h1 class="music-title">{{$Album.Title}}</h1></a>
<a href="#usage"> <h2 class="music-artist">{{$Album.PrintPrimaryArtists}}</h2>
&gt; "can i use your music in my content?" <h3 class="music-type-{{.ResolveType}}">{{$Album.ResolveType}}</h3>
</a> <ul class="music-links">
</h2> {{range $Link := $Album.Links}}
<div class="collapse"> <li>
<p> <a href="{{$Link.Url}}">{{$Link.Name}}</a>
<strong class="big">yes!</strong> well, in most cases... </li>
</p> {{end}}
<p> </ul>
from <a href="/music/dream">Dream (2022)</a> onward, all of my <em>self-released</em> songs are
licensed under <a href="https://creativecommons.org/licenses/by-sa/3.0/" target="_blank">Creative Commons Attribution-ShareAlike 3.0</a>. anyone may use these
songs freely, so long as they provide credit back to me!
</p>
<p>
a great example of some credit text would be as follows:
</p>
<blockquote>
music used: mellodoot - Dream<br>
buy it here: <a href="/music/dream">https://arimelody.me/music/dream</a><br>
licensed under CC BY-SA 3.0.
</blockquote>
<p>
for any songs prior to this, they were all either released by me (in which case, i honestly
don't mind), or in collaboration with chill people who i don't see having an issue with it.
do be sure to ask them about it, though!
</p>
<p>
in the event the song you want to use is released under some other label, their usage rights
will more than likely trump whatever i'd otherwise have in mind. i'll try to negotiate some
nice terms, though! ;3
</p>
<p>
i love the idea of other creators using my songs in their work, so if you do happen to use
my stuff in a work you're particularly proud of, feel free to send it my way!
</p>
<p>
&gt; <a href="mailto:ari@arimelody.me">ari@arimelody.me</a>
</p>
</div> </div>
</main> </div>
{{end}}
</div>
{{block "footer" .}}{{end}} <h2 id="usage" class="question">
<a href="#usage">
<div id="overlay"></div> &gt; "can i use your music in my content?"
</body> </a>
</html> </h2>
<div class="collapse">
<p>
<strong class="big">yes!</strong> well, in most cases...
</p>
<p>
from <a href="/music/dream">Dream (2022)</a> onward, all of my <em>self-released</em> songs are
licensed under <a href="https://creativecommons.org/licenses/by-sa/3.0/" target="_blank">Creative Commons Attribution-ShareAlike 3.0</a>. anyone may use these
songs freely, so long as they provide credit back to me!
</p>
<p>
a great example of some credit text would be as follows:
</p>
<blockquote>
music used: mellodoot - Dream<br>
buy it here: <a href="/music/dream">https://arimelody.me/music/dream</a><br>
licensed under CC BY-SA 3.0.
</blockquote>
<p>
for any songs prior to this, they were all either released by me (in which case, i honestly
don't mind), or in collaboration with chill people who i don't see having an issue with it.
do be sure to ask them about it, though!
</p>
<p>
in the event the song you want to use is released under some other label, their usage rights
will more than likely trump whatever i'd otherwise have in mind. i'll try to negotiate some
nice terms, though! ;3
</p>
<p>
i love the idea of other creators using my songs in their work, so if you do happen to use
my stuff in a work you're particularly proud of, feel free to send it my way!
</p>
<p>
&gt; <a href="mailto:ari@arimelody.me">ari@arimelody.me</a>
</p>
</div>
</main>
{{end}}