break out js and css on index

This commit is contained in:
gome 2023-01-22 12:40:49 -06:00
parent ce1349992b
commit 8323304e74
8 changed files with 624 additions and 678 deletions

445
css/gomepage.css Normal file
View File

@ -0,0 +1,445 @@
html {
color: #323a42;
background-color: #efe5d7;
height: 100%;
font-family: 'Palatino Linotype', Lora, serif;
font-size: 1.125em;
background-position: center;
background-attachment: fixed;
background-size: cover;
position: relative;
overflow-x: hidden;
}
html:before {
content: '';
display: block;
height: 100vh;
width: 100vw;
background-color: #efe5d7;
transition: opacity 2000ms 300ms;
position: absolute;
top: 0;
z-index: -1;
}
html.loaded:before {
opacity: 0;
}
header, main, .gome-img {
transition: border-color 2000ms 300ms;
}
html.loaded header, html.loaded main, html.loaded .gome-img {
border-color: #323a42;
}
html.loaded header {
z-index: 1;
}
body {
margin: 0;
min-height: 100%;
display: grid;
grid-template-columns: 1fr min-content;
grid-template-rows: 1fr auto min-content;
line-height: 1.2;
}
*::selection {
background: #eab77544;
}
header {
display: flex;
flex-direction: column;
align-items: start;
grid-column: 2;
grid-row: 1 / span 2;
width: min-content;
height: min-content;
overflow: hidden;
background-color: #efe5d7;
padding-left: 2em;
padding-bottom: 2em;
border-bottom: 2px solid #efe5d7;
border-left: 2px solid #efe5d7;
border-radius: 0 0 0 1em;
}
main {
display: flex;
flex-direction: column;
align-items: start;
grid-column: 1;
grid-row: 1;
padding: 1em;
background-color: #efe5d7;
width: fit-content;
max-width: 70ch;
height: fit-content;
border-right: 2px solid #efe5d7;
border-bottom: 2px solid #efe5d7;
border-radius: 0 0 1em 0;
margin-right: 0.5em;
margin-bottom: 0.5em;
}
footer {
display: flex;
grid-column: 1 / span 2;
grid-row: 2 / span 2;
pointer-events: none;
margin-right: 0.5em;
}
.title-box, h1, h2, h3, h4, h5, h6 {
font-weight: normal;
}
h1, h2, h3, h4, h5, h6 {
font-family: Optima, 'Palatino Linotype', Lora, serif;
}
h2, h3 {
margin: 0.5em 0;
}
.title-box {
position: relative;
border: 2px solid #323a42;
border-top: none;
border-right: none;
font-size: 48px;
height: 3em;
width: 10em;
background-color: #efe5d7;
}
.title-box .title {
background-color: inherit;
position: absolute;
bottom: -13px;
padding: 0 0.25em 0 0.25em;
user-select: none;
}
nav {
position: relative;
display: flex;
flex-direction: column;
width: 100%;
/* this counters the left offset, but adds no real padding */
padding-right: 1rem;
left: 1rem;
right: 0;
border-bottom: 2px solid #323a42;
}
a {
color: #323a42;
}
nav a {
margin: 0.25em 0.75em 0.25em 0;
padding: 0.25em;
position: relative;
left: -0.25em;
color: #323a42;
text-decoration: none;
line-height: 1.2;
border-radius: 2px;
}
nav a:first-child {
margin-top: 1em;
}
nav a:last-child {
margin-bottom: 1em;
}
a:hover, a:focus {
color: #6d747a;
outline: 0;
}
a:focus-visible {
outline: 1px dashed #beb0b1;
}
nav a .link-title {
font-weight: bold;
}
nav a .link-description::before {
font-weight: normal;
content: '— ';
}
nav a.new .link-title::after {
content: '*';
color: #984624;
}
nav a.new:hover .link-title::after, nav a.new:focus .link-title::after {
color: #bf8e7c;
}
@keyframes fade-in {
from { opacity: 0 }
to { opacity: 1 }
}
.image-credit {
padding: 4.5px;
position: relative;
font-style: italic;
text-decoration: none;
color: #323a42;
text-decoration: none;
line-height: 1.2;
border-radius: 2px;
font-size: 15px;
animation: fade-in 2000ms ease 300ms backwards;
}
header .image-credit {
margin: 9px 0 -16px 13.5px;
}
main .image-credit {
margin: 9px 0 0 -4.5px;
display: none;
}
.gome-img {
user-select: none;
border-radius: 0 1em 0 0;
border-top: 2px solid #efe5d7;
border-right: 2px solid #efe5d7;
}
.gome-img[src^='./img/desktop'] {
width: auto;
max-width: min(1280px, 100%);
}
.gome-img[src^='./img/tablet'] {
display: none;
max-width: 100%;
}
.gome-img[src^='./img/mobile'] {
display: none;
max-width: 100%;
}
#wotd h3 {
font-family: Optima, 'Palatino Linotype', Lora, serif;
font-size: 1.2em;
margin: 0 0 0.5em 0;
}
#wotd .definiendum {
font-size: 1.5em;
font-weight: bold;
margin-bottom: 0.5em;
}
#wotd time, #wotd .pronunciation {
display: block;
margin-bottom: 1em;
}
.pronunciation:not(:empty)::before, .pronunciation:not(:empty)::after {
content: '';
}
#wotd ul {
margin: 0 0 1em 0;
padding-left: 0.5em;
list-style: none;
}
#wotd li {
margin-bottom: 0.25em;
}
#status:not(.loaded) *, #wotd:not(.loaded) * {
margin: 0;
}
#statuscafe {
padding-left: 0.5em;
margin-bottom: 1em;
}
#statuscafe-username a {
margin: -0.15em;
padding: 0.15em;
border-radius: 2px;
}
#listening {
width: 100%;
}
.listening-item {
display: grid;
grid-template-columns: calc(36px + 0.5em) auto;
align-items: center;
justify-items: start;
border-radius: 4px;
padding: 0.25em 0.25em;
margin: -0.25em -0.25em 0.25em -0.25em;
cursor: default;
transition: background-color 100ms;
}
.listening-item:not(.all-loaded):last-child:hover {
background-color: #eab77522;
}
.listening-item.now-playing {
border: 2px solid #984624;
}
.listening-item.now-playing .track-title, .listening-item.now-playing .track-artist {
font-weight: bold;
}
.listening-item img {
/* accounts for border */
margin: 1px calc(0.5em + 1px) 1px 1px;
}
.listening-item img.loaded {
margin: 0 0.5em 0 0;
border-radius: 2px;
border: 1px solid #323a42;
}
.listening-item .listening-track {
line-height: 36px;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
a.journal-link {
display: grid;
text-decoration: none;
grid-template-columns: auto auto 1fr;
margin: -0.25em;
margin-right: 0;
padding: 0.25em;
margin-bottom: 1em;
padding-right: 0;
border: 1px solid #323a42;
box-shadow: 1px 1px #323a42;
border-radius: 3px;
}
a.journal-link:hover, a.journal-link:focus {
outline: 0;
border-color: #6d747a;
box-shadow: 2px 2px #6d747a;
}
a.journal-link:hover time, a.journal-link:focus time {
color: #6d747a;
}
a.journal-link h3 {
font-family: 'Palatino Linotype', Lora, serif;
font-weight: bold;
margin: 0 0.5em 0 0;
}
a.journal-link p {
grid-column: 1 / span 2;
margin: 0.5em 5px 0.5em 0;
}
a.journal-link .line {
grid-column: span 2;
align-self: end;
bottom: 6px;
}
a.journal-link time {
grid-column: span 2;
}
a.journal-link time + p {
margin-top: 5px;
}
time {
font-size: 0.9em;
color: #4E5458;
font-style: italic;
font-variant-numeric: oldstyle-nums;
}
a.journal-link + a.journal-link {
margin-top: 1em;
}
.line {
display: inline-block;
background-color: #323a42;
height: 2px;
position: relative;
}
.line.stop-0 {
background-color: #984624;
}
.line.stop-1 {
background-color: #ad5f1e;
}
.line.stop-2 {
background-color: #c59506;
}
.line.stop-3 {
background-color: #c8b500;
}
.line.stop-4 {
background-color: #8ea530;
}
.line.stop-5 {
background-color: #4b7b52;
}
.line.stop-6 {
background-color: #426153;
}
.music-box {
margin-top: 0.5em;
display: flex;
align-items: center;
width: fit-content;
padding: 2px 4px 2px 2px;
border-radius: 3px;
border: 1px solid #323a42;
user-select: none;
cursor: pointer;
box-shadow: 1px 1px #323a42;
}
.music-box:hover, .music-box:focus {
outline: 0;
color: #6d747a;
border-color: #6d747a;
box-shadow: 2px 2px #6d747a;
}
.music-box svg {
margin-right: 2px;
}
.music-box.playing svg.play {
display: none;
}
.music-box.playing svg.pause {
display: block;
}
.music-box svg.pause {
display: none;
}
@media only screen and (max-width: 960px) {
body {
grid-template-rows: min-content auto min-content;
}
header {
grid-column: 1 / span 2;
grid-row: 1;
width: 100%;
padding: 0;
border: none;
border-color: #efe5d7;
border-radius: 0;
}
header .image-credit {
display: none;
}
main .image-credit {
display: initial;
}
main {
grid-row: 2;
}
footer {
margin-top: 2em;
grid-row: 3;
}
.title-box {
border-left: none;
height: 1em;
width: 100%;
}
.title-box:hover {
cursor: initial;
border-color: #323a42;
color: #323a42;
}
.image-credit {
opacity: 1;
pointer-events: all;
}
.gome-img[src^='./img/desktop'] {
display: none;
}
.gome-img[src^='./img/tablet'] {
display: initial;
}
}
@media only screen and (max-width: 640px) {
footer {
align-items: flex-end;
}
.gome-img[src^='./img/tablet'] {
display: none;
}
.gome-img[src^='./img/mobile'] {
display: initial;
}
}

View File

@ -268,7 +268,7 @@ article figure figcaption i {
}
.page-nav .current {
font-weight: bold;
cursor: normal;
cursor: default;
}
.footnote {
font-size: 0.8em;

View File

@ -10,473 +10,12 @@
<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin>
<link rel='preload' href='https://fonts.googleapis.com/css2?family=Lora:ital@0;1&display=swap' as='style' onload='this.onload=null;this.rel="stylesheet"'>
<noscript><link rel='stylesheet' href='https://fonts.googleapis.com/css2?family=Lora:ital@0;1&display=swap'></noscript>
<style>
html {
color: #323a42;
background-color: #efe5d7;
height: 100%;
font-family: 'Palatino Linotype', Lora, serif;
font-size: 1.125em;
background-position: center;
background-attachment: fixed;
background-size: cover;
position: relative;
overflow-x: hidden;
}
html:before {
content: '';
display: block;
height: 100vh;
width: 100vw;
background-color: #efe5d7;
transition: opacity 2000ms 300ms;
position: absolute;
top: 0;
z-index: -1;
}
html.loaded:before {
opacity: 0;
}
header, main, .gome-img {
transition: border-color 2000ms 300ms;
}
html.loaded header, html.loaded main, html.loaded .gome-img {
border-color: #323a42;
}
html.loaded header.show-nav {
z-index: 1;
}
body {
margin: 0;
min-height: 100%;
display: grid;
grid-template-columns: 1fr min-content;
grid-template-rows: 1fr auto min-content;
line-height: 1.2;
}
*::selection {
background: #eab77544;
}
header {
display: flex;
flex-direction: column;
align-items: start;
grid-column: 2;
grid-row: 1 / span 2;
width: min-content;
height: min-content;
overflow: hidden;
background-color: #efe5d7;
padding-left: 2em;
padding-bottom: 2em;
border-bottom: 2px solid #efe5d7;
border-left: 2px solid #efe5d7;
border-radius: 0 0 0 1em;
}
main {
display: flex;
flex-direction: column;
align-items: start;
grid-column: 1;
grid-row: 1;
padding: 1em;
background-color: #efe5d7;
width: fit-content;
max-width: 70ch;
height: fit-content;
border-right: 2px solid #efe5d7;
border-bottom: 2px solid #efe5d7;
border-radius: 0 0 1em 0;
margin-right: 0.5em;
margin-bottom: 0.5em;
}
footer {
display: flex;
grid-column: 1 / span 2;
grid-row: 2 / span 2;
pointer-events: none;
margin-right: 0.5em;
}
.title-box, h1, h2, h3, h4, h5, h6 {
font-weight: normal;
}
h1, h2, h3, h4, h5, h6 {
font-family: Optima, 'Palatino Linotype', Lora, serif;
}
h2, h3 {
margin: 0.5em 0;
}
.title-box {
position: relative;
border: 2px solid #323a42;
border-top: none;
border-right: none;
font-size: 48px;
height: 3em;
width: 10em;
background-color: #efe5d7;
}
.title-box:hover {
cursor: pointer;
border-color: #6d747a;
color: #6d747a;
}
.title-box .title {
background-color: inherit;
position: absolute;
bottom: -13px;
padding: 0 0.25em 0 0.25em;
user-select: none;
}
nav {
position: relative;
display: flex;
flex-direction: column;
width: 100%;
/* this counters the left offset, but adds no real padding */
padding-right: 1rem;
left: 1rem;
right: 0;
border-bottom: 2px solid #323a42;
transition: opacity 50ms;
opacity: 0;
pointer-events: none;
}
a {
color: #323a42;
}
nav a {
margin: 0.25em 0.75em 0.25em 0;
padding: 0.25em;
position: relative;
left: -0.25em;
color: #323a42;
text-decoration: none;
line-height: 1.2;
border-radius: 2px;
}
nav a:first-child {
margin-top: 1em;
}
nav a:last-child {
margin-bottom: 1em;
}
a:hover, a:focus {
color: #6d747a;
outline: 0;
}
a:focus-visible {
outline: 1px dashed #beb0b1;
}
nav a .link-title {
font-weight: bold;
}
nav a .link-description::before {
font-weight: normal;
content: '— ';
}
nav a.new .link-title::after {
content: '*';
color: #984624;
}
nav a.new:hover .link-title::after, nav a.new:focus .link-title::after {
color: #bf8e7c;
}
header .image-credit {
margin: 9px 0 -16px 13.5px;
pointer-events: none;
opacity: 0;
transition: opacity 50ms;
}
.image-credit {
padding: 4.5px;
position: relative;
font-style: italic;
text-decoration: none;
color: #323a42;
text-decoration: none;
line-height: 1.2;
border-radius: 2px;
font-size: 15px;
}
main .image-credit {
margin: 9px 0 0 -4.5px;
display: none;
animation: fade-in 2000ms ease 300ms;
animation-fill-mode: backwards;
}
@keyframes fade-in {
from { opacity: 0 }
to { opacity: 1 }
}
header.show-nav .image-credit, header:focus-within .image-credit {
opacity: 1;
pointer-events: all;
}
header.show-nav nav, header:focus-within nav {
opacity: 1;
pointer-events: all;
}
.gome-img {
user-select: none;
border-radius: 0 1em 0 0;
border-top: 2px solid #efe5d7;
border-right: 2px solid #efe5d7;
}
.gome-img[src^='./img/desktop'] {
width: auto;
max-width: min(1280px, 100%);
}
.gome-img[src^='./img/tablet'] {
display: none;
max-width: 100%;
}
.gome-img[src^='./img/mobile'] {
display: none;
max-width: 100%;
}
#wotd h3 {
font-family: Optima, 'Palatino Linotype', Lora, serif;
font-size: 1.2em;
margin: 0 0 0.5em 0;
}
#wotd .definiendum {
font-size: 1.5em;
font-weight: bold;
margin-bottom: 0.5em;
}
#wotd time, #wotd .pronunciation {
display: block;
margin-bottom: 1em;
}
.pronunciation:not(:empty)::before, .pronunciation:not(:empty)::after {
content: '';
}
#wotd ul {
margin: 0 0 1em 0;
padding-left: 0.5em;
list-style: none;
}
#wotd li {
margin-bottom: 0.25em;
}
#status:not(.loaded) *, #wotd:not(.loaded) * {
margin: 0;
}
#statuscafe {
padding-left: 0.5em;
margin-bottom: 1em;
}
#statuscafe-username a {
margin: -0.15em;
padding: 0.15em;
border-radius: 2px;
}
#listening {
width: 100%;
}
.listening-item {
display: grid;
grid-template-columns: calc(36px + 0.5em) auto;
align-items: center;
justify-items: start;
border-radius: 4px;
padding: 0.25em 0.25em;
margin: -0.25em -0.25em 0.25em -0.25em;
cursor: default;
transition: background-color 100ms;
}
.listening-item:not(.all-loaded):last-child:hover {
background-color: #eab77522;
}
.listening-item.now-playing {
border: 2px solid #984624;
}
.listening-item.now-playing .track-title, .listening-item.now-playing .track-artist {
font-weight: bold;
}
.listening-item img {
/* accounts for border */
margin: 1px calc(0.5em + 1px) 1px 1px;
}
.listening-item img.loaded {
margin: 0 0.5em 0 0;
border-radius: 2px;
border: 1px solid #323a42;
}
.listening-item .listening-track {
line-height: 36px;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
a.journal-link {
display: grid;
text-decoration: none;
grid-template-columns: auto auto 1fr;
margin: -0.25em;
margin-right: 0;
padding: 0.25em;
margin-bottom: 1em;
padding-right: 0;
border: 1px solid #323a42;
box-shadow: 1px 1px #323a42;
border-radius: 3px;
}
a.journal-link:hover, a.journal-link:focus {
outline: 0;
border-color: #6d747a;
box-shadow: 2px 2px #6d747a;
}
a.journal-link:hover time, a.journal-link:focus time {
color: #6d747a;
}
a.journal-link h3 {
font-family: 'Palatino Linotype', Lora, serif;
font-weight: bold;
margin: 0 0.5em 0 0;
}
a.journal-link p {
grid-column: 1 / span 2;
margin: 0.5em 5px 0.5em 0;
}
a.journal-link .line {
grid-column: span 2;
align-self: end;
bottom: 6px;
}
a.journal-link time {
grid-column: span 2;
}
a.journal-link time + p {
margin-top: 5px;
}
time {
font-size: 0.9em;
color: #4E5458;
font-style: italic;
font-variant-numeric: oldstyle-nums;
}
a.journal-link + a.journal-link {
margin-top: 1em;
}
.line {
display: inline-block;
background-color: #323a42;
height: 2px;
position: relative;
}
.line.stop-0 {
background-color: #984624;
}
.line.stop-1 {
background-color: #ad5f1e;
}
.line.stop-2 {
background-color: #c59506;
}
.line.stop-3 {
background-color: #c8b500;
}
.line.stop-4 {
background-color: #8ea530;
}
.line.stop-5 {
background-color: #4b7b52;
}
.line.stop-6 {
background-color: #426153;
}
.music-box {
margin-top: 0.5em;
display: flex;
align-items: center;
width: fit-content;
padding: 2px 4px 2px 2px;
border-radius: 3px;
border: 1px solid #323a42;
user-select: none;
cursor: pointer;
box-shadow: 1px 1px #323a42;
}
.music-box:hover, .music-box:focus {
outline: 0;
color: #6d747a;
border-color: #6d747a;
box-shadow: 2px 2px #6d747a;
}
.music-box svg {
margin-right: 2px;
}
.music-box.playing svg.play {
display: none;
}
.music-box.playing svg.pause {
display: block;
}
.music-box svg.pause {
display: none;
}
@media only screen and (max-width: 960px) {
body {
grid-template-rows: min-content auto min-content;
}
header {
grid-column: 1 / span 2;
grid-row: 1;
width: 100%;
padding: 0;
border: none;
border-color: #efe5d7;
border-radius: 0;
}
header .image-credit {
display: none;
}
main .image-credit {
display: initial;
}
main {
grid-row: 2;
}
footer {
margin-top: 2em;
grid-row: 3;
}
.title-box {
border-left: none;
height: 1em;
width: 100%;
}
.title-box:hover {
cursor: initial;
border-color: #323a42;
color: #323a42;
}
nav, .image-credit {
opacity: 1;
pointer-events: all;
}
.gome-img[src^='./img/desktop'] {
display: none;
}
.gome-img[src^='./img/tablet'] {
display: initial;
}
}
@media only screen and (max-width: 640px) {
footer {
align-items: flex-end;
}
.gome-img[src^='./img/tablet'] {
display: none;
}
.gome-img[src^='./img/mobile'] {
display: initial;
}
}
</style>
<link rel='stylesheet' type='text/css' href='css/gomepage.css'/>
<script defer src='js/statuscafe.js'></script>
<script defer src='js/listening.js'></script>
<script defer src='js/wotd.js'></script>
<script defer src='js/background.js'></script>
<script defer src='js/gomesong.js'></script>
</head>
<body>
<header id='header' class='show-nav'>
@ -511,21 +50,6 @@
<div id='statuscafe-username'></div>
<div id='statuscafe-content'></div>
</div>
<script defer>
// based on https://status.cafe/current-status.js
fetch('https://status.cafe/users/gome/status.json')
.then( r => r.json() )
.then( r => {
if (!r.content.length) {
document.getElementById('statuscafe-content').innerHTML = 'No status yet.'
return
}
document.getElementById('status').classList.add('loaded');
document.getElementById('statuscafe-title').innerHTML = 'My status'
document.getElementById('statuscafe-username').innerHTML = "<a href='https://status.cafe/users/gome' target='_blank'>" + r.author + '</a> ' + r.face + ' ' + r.timeAgo
document.getElementById('statuscafe-content').innerHTML = r.content
})
</script>
</article>
<article>
<h2>Latest gomepost</h2>
@ -538,56 +62,6 @@
</article>
<article id='listening'>
<h2 id='listening-title'></h2>
<script defer type='module'>
const params = (new URL(document.location)).searchParams;
let user = params.get('user');
if (!user) {
user = 'atbseefeldt';
}
const disc = './img/disc.webp';
const lastfm_default_image = 'https://lastfm.freetls.fastly.net/i/u/64s/2a96cbd8b46e442fc41c2b86b821562f.png';
fetch(`https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${user}&api_key=5460c3381d64e7e9908b9fdfc5559747&format=json`)
.then(r => r.json())
.then(lastfm => {
if (!lastfm.error) {
const listening = document.getElementById('listening');
document.getElementById('listening-title').innerHTML = 'Listening to';
const add_track = (track, all_loaded) => {
let trackHTML = '';
let classes = 'listening-item';
const attr = track['@attr'];
if (attr && attr.nowplaying) {
classes += ' now-playing';
}
if (all_loaded) {
classes += ' all-loaded';
}
trackHTML += `<div class='${classes}' title='${track.name.replaceAll("'","&apos;")} ${track.artist['#text'].replaceAll("'","&apos;")}' onclick='if (!this.nextElementSibling) more_tracks(6)'>`;
let image = track.image[1]['#text'];
if (image === lastfm_default_image) {
image = disc;
}
trackHTML += `<img width=34 height=34 src='${image}' onload='if (!this.src.endsWith("${disc.substring(1)}")) this.classList.add("loaded")' onerror='this.src = "${disc}"' />`;
trackHTML += `<span class='listening-track'><span class='track-title'>${track.name}</span><span class='track-artist'>${track.artist['#text']}</span></span>`;
trackHTML += `</div>`;
listening.innerHTML += trackHTML;
}
let track_index = 0;
const more_tracks = count => {
const tracks = lastfm.recenttracks.track.slice(track_index, track_index + count);
track_index += count;
for (const track of tracks) {
add_track(track, track_index >= lastfm.recenttracks.track.length);
}
}
more_tracks(5);
window.more_tracks = more_tracks;
}
});
</script>
</article>
</main>
<footer>
@ -595,150 +69,5 @@
<img src='./img/tablet_gomes.webp' loading='lazy' class='gome-img' alt='Kabouters at work' />
<img src='./img/mobile_gome.webp' loading='lazy' class='gome-img' alt='Lone kabouter' />
</footer>
<script>
const header = document.querySelector('#header');
const nav = header.querySelector('nav');
const revealNav = () => {
header.classList.add('show-nav');
}
const hideNav = () => {
header.classList.remove('show-nav');
}
header.addEventListener('click', e => {
if (!nav.contains(e.target) && nav !== e.target) {
if (header.classList.contains('show-nav')) {
hideNav();
}
else if (!header.classList.contains('show-nav')) {
revealNav();
}
}
});
window.addEventListener('click', e => {
if (!header.contains(e.target) && header !== e.target) {
hideNav();
}
});
</script>
<script type='module'>
const months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
const wotd = document.querySelector('#wotd');
const today = new Date();
let entry;
try {
let day = today.getDate().toString();
if (day.length === 1) {
day = '0' + day;
}
let month = (today.getMonth() + 1).toString();
if (month.length === 1) {
month = '0' + month;
}
fetch(`./wotd/${today.getFullYear()}.${month}.${day}.json`)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP response ${response.status} ${response.statusText}`);
}
return response.json();
})
.then(entry => {
if (entry) {
wotd.classList.add('loaded');
wotd.querySelector('.title').textContent = 'Word of the day';
wotd.querySelector('.date').textContent = today.getDate() + ' ' + months[today.getMonth()] + ' ' + today.getFullYear();
wotd.querySelector('.definiendum').textContent = entry.word;
wotd.querySelector('.pronunciation').textContent = entry.pronunciation;
let definitionHTML = '';
for (const definitionEntry of entry.definitions) {
definitionHTML += `<h3 class='part-of-speech'>${definitionEntry.part}</h4>`;
definitionHTML += `<ul class='definitions'>`;
for (const definition of definitionEntry.definitions) {
definitionHTML += `<li class='definition'>${definition}</li>`
}
definitionHTML += `</ul>`;
}
wotd.innerHTML += definitionHTML;
}
});
} catch (e) {
console.error('Word of the Day error:', e);
}
</script>
<script>
const choose = options => {
const weight_sum = options.reduce((a, b) => a + b.weight, 0);
let choice = Math.floor(Math.random() * weight_sum);
for (const option of options) {
if (choice < option.weight) {
return option;
} else {
choice -= option.weight;
}
}
}
const images = [
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/1/1f/Hiking_Trail_at_Mew_Lake_Campground%2C_Algonquin_Park_%2829950322654%29.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Hiking_Trail_at_Mew_Lake_Campground,_Algonquin_Park_(29950322654).jpg#Licensing', },
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/a/a4/Butterfly_Garden_NBG_3_LR.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Butterfly_Garden_NBG_3_LR.jpg#Licensing', },
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/b/bb/Wandelen_over_de_Planken_Wambuis_vanuit_Mossel_069_A.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Wandelen_over_de_Planken_Wambuis_vanuit_Mossel_069_A.jpg#Licensing', },
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/f/ff/Ilsenburg%2C_Ilsetal_--_2017_--_0163.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Ilsenburg,_Ilsetal_--_2017_--_0163.jpg#Licensing', },
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/6/66/Wood_anemones_and_tree_shadows_in_Gullmarsskogen_4.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Wood_anemones_and_tree_shadows_in_Gullmarsskogen_4.jpg#Licensing', },
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/e/e8/Window_into_the_overgrown_Aulne_Abbey_%28DSC_0119%29.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Window_into_the_overgrown_Aulne_Abbey_(DSC_0119).jpg#Licensing', },
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/0/09/20170815_Zalipie_5497_DxO.jpg', credit: 'https://commons.wikimedia.org/wiki/File:20170815_Zalipie_5497_DxO.jpg#Licensing', },
{ weight: 3, src: 'https://upload.wikimedia.org/wikipedia/commons/a/a4/Maria_Saal_Freilichtmuseum_Steinerkasten_Ost-Ansicht_13092016_4233.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Maria_Saal_Freilichtmuseum_Steinerkasten_Ost-Ansicht_13092016_4233.jpg#Licensing', },
{ weight: 3, src: 'https://upload.wikimedia.org/wikipedia/commons/3/34/M%C3%BCnster%2C_Boniburger_Wald_--_2019_--_4246.jpg', credit: 'https://commons.wikimedia.org/wiki/File:M%C3%BCnster,_Boniburger_Wald_--_2019_--_4246.jpg#Licensing', },
{ weight: 3, src: 'https://upload.wikimedia.org/wikipedia/commons/a/a1/Schnepfau_Wendelinkapelle_01.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Schnepfau_Wendelinkapelle_01.jpg#Licensing', },
{ weight: 3, src: 'https://upload.wikimedia.org/wikipedia/commons/9/9b/Caba%C3%B1a_de_la_Isla_del_Pato%2C_Parque_San_Jaime%2C_Londres%2C_Inglaterra%2C_2014-08-07%2C_DD_012.JPG', credit: 'https://commons.wikimedia.org/wiki/File:Caba%C3%B1a_de_la_Isla_del_Pato,_Parque_San_Jaime,_Londres,_Inglaterra,_2014-08-07,_DD_012.JPG#Licensing', },
{ weight: 3, src: 'https://upload.wikimedia.org/wikipedia/commons/d/dd/Forest_road_Slavne_2016_G1.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Forest_road_Slavne_2016_G1.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/c/c8/Doorgang_in_muur._Locatie%2C_Chinese_tuin_Het_Verborgen_Rijk_van_Ming._Locatie._Hortus_Haren_01.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Doorgang_in_muur._Locatie,_Chinese_tuin_Het_Verborgen_Rijk_van_Ming._Locatie._Hortus_Haren_01.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/8/81/Japanese_Tea_Garden_San_Francisco_December_2016_001.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Japanese_Tea_Garden_San_Francisco_December_2016_001.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/6/61/Wooden_gate_in_Okochi_Sanso_Garden%2C_Kyoto%2C_Japan_%282%29.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Wooden_gate_in_Okochi_Sanso_Garden,_Kyoto,_Japan_(2).jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/4/4c/Nationaal_Park_Weerribben-Wieden._Bemoste_boomstronken.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Nationaal_Park_Weerribben-Wieden._Bemoste_boomstronken.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/e/e9/Ritsurin_Garden%2C_Kagawa_Prefecture%3B_November_2019_%2804%29.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Ritsurin_Garden,_Kagawa_Prefecture;_November_2019_(04).jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/0/01/14-09-02-oslo-RalfR-280.jpg', credit: 'https://commons.wikimedia.org/wiki/File:14-09-02-oslo-RalfR-280.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/6/61/Hut_in_Utsjoki_parish_village_in_Utsjoki%2C_Lapland%2C_Finland%2C_2021_September_-_3.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Hut_in_Utsjoki_parish_village_in_Utsjoki,_Lapland,_Finland,_2021_September_-_3.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/f/fa/Hut_in_Utsjoki_parish_village_in_Utsjoki%2C_Lapland%2C_Finland%2C_2021_September_-_2.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Hut_in_Utsjoki_parish_village_in_Utsjoki,_Lapland,_Finland,_2021_September_-_2.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/1/18/Langenlois_Weinweg_Weingartenh%C3%BCtte-8283.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Langenlois_Weinweg_Weingartenh%C3%BCtte-8283.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/9/93/Steuerberg_Hinterwachsenberg_3_Brentlerstuben_07042015_1537.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Steuerberg_Hinterwachsenberg_3_Brentlerstuben_07042015_1537.jpg#Licensing', },
{ weight: 1, src: 'https://upload.wikimedia.org/wikipedia/commons/b/bc/Sir_Walter_Buffalo_Grass.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Sir_Walter_Buffalo_Grass.jpg#Licensing', },
];
const image_choice = choose(images);
const html = document.querySelector('html');
const body = document.querySelector('body');
let img = new Image();
img.src = image_choice.src;
const credit = document.createElement('a');
credit.textContent = 'Image credit';
credit.className = 'image-credit';
credit.target = '_blank';
credit.href = image_choice.credit;
img.addEventListener('load', () => {
html.style.backgroundImage = `url(${img.src})`;
html.classList.add('loaded');
document.querySelector('header').appendChild(credit);
document.querySelector('main').appendChild(credit.cloneNode(true));
});
</script>
<script>
const gomesong = document.getElementById('gomesong');
const music_box = document.getElementById('music-box');
music_box.addEventListener('click', () => {
if (gomesong.paused) {
music_box.classList.add('playing');
gomesong.play();
} else {
music_box.classList.remove('playing');
gomesong.pause();
}
});
</script>
</body>
</html>

58
js/background.js Normal file
View File

@ -0,0 +1,58 @@
const choose = options => {
const weight_sum = options.reduce((a, b) => a + b.weight, 0);
let choice = Math.floor(Math.random() * weight_sum);
for (const option of options) {
if (choice < option.weight) {
return option;
} else {
choice -= option.weight;
}
}
}
const images = [
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/1/1f/Hiking_Trail_at_Mew_Lake_Campground%2C_Algonquin_Park_%2829950322654%29.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Hiking_Trail_at_Mew_Lake_Campground,_Algonquin_Park_(29950322654).jpg#Licensing', },
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/a/a4/Butterfly_Garden_NBG_3_LR.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Butterfly_Garden_NBG_3_LR.jpg#Licensing', },
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/b/bb/Wandelen_over_de_Planken_Wambuis_vanuit_Mossel_069_A.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Wandelen_over_de_Planken_Wambuis_vanuit_Mossel_069_A.jpg#Licensing', },
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/f/ff/Ilsenburg%2C_Ilsetal_--_2017_--_0163.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Ilsenburg,_Ilsetal_--_2017_--_0163.jpg#Licensing', },
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/6/66/Wood_anemones_and_tree_shadows_in_Gullmarsskogen_4.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Wood_anemones_and_tree_shadows_in_Gullmarsskogen_4.jpg#Licensing', },
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/e/e8/Window_into_the_overgrown_Aulne_Abbey_%28DSC_0119%29.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Window_into_the_overgrown_Aulne_Abbey_(DSC_0119).jpg#Licensing', },
{ weight: 4, src: 'https://upload.wikimedia.org/wikipedia/commons/0/09/20170815_Zalipie_5497_DxO.jpg', credit: 'https://commons.wikimedia.org/wiki/File:20170815_Zalipie_5497_DxO.jpg#Licensing', },
{ weight: 3, src: 'https://upload.wikimedia.org/wikipedia/commons/a/a4/Maria_Saal_Freilichtmuseum_Steinerkasten_Ost-Ansicht_13092016_4233.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Maria_Saal_Freilichtmuseum_Steinerkasten_Ost-Ansicht_13092016_4233.jpg#Licensing', },
{ weight: 3, src: 'https://upload.wikimedia.org/wikipedia/commons/3/34/M%C3%BCnster%2C_Boniburger_Wald_--_2019_--_4246.jpg', credit: 'https://commons.wikimedia.org/wiki/File:M%C3%BCnster,_Boniburger_Wald_--_2019_--_4246.jpg#Licensing', },
{ weight: 3, src: 'https://upload.wikimedia.org/wikipedia/commons/a/a1/Schnepfau_Wendelinkapelle_01.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Schnepfau_Wendelinkapelle_01.jpg#Licensing', },
{ weight: 3, src: 'https://upload.wikimedia.org/wikipedia/commons/9/9b/Caba%C3%B1a_de_la_Isla_del_Pato%2C_Parque_San_Jaime%2C_Londres%2C_Inglaterra%2C_2014-08-07%2C_DD_012.JPG', credit: 'https://commons.wikimedia.org/wiki/File:Caba%C3%B1a_de_la_Isla_del_Pato,_Parque_San_Jaime,_Londres,_Inglaterra,_2014-08-07,_DD_012.JPG#Licensing', },
{ weight: 3, src: 'https://upload.wikimedia.org/wikipedia/commons/d/dd/Forest_road_Slavne_2016_G1.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Forest_road_Slavne_2016_G1.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/c/c8/Doorgang_in_muur._Locatie%2C_Chinese_tuin_Het_Verborgen_Rijk_van_Ming._Locatie._Hortus_Haren_01.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Doorgang_in_muur._Locatie,_Chinese_tuin_Het_Verborgen_Rijk_van_Ming._Locatie._Hortus_Haren_01.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/8/81/Japanese_Tea_Garden_San_Francisco_December_2016_001.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Japanese_Tea_Garden_San_Francisco_December_2016_001.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/6/61/Wooden_gate_in_Okochi_Sanso_Garden%2C_Kyoto%2C_Japan_%282%29.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Wooden_gate_in_Okochi_Sanso_Garden,_Kyoto,_Japan_(2).jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/4/4c/Nationaal_Park_Weerribben-Wieden._Bemoste_boomstronken.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Nationaal_Park_Weerribben-Wieden._Bemoste_boomstronken.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/e/e9/Ritsurin_Garden%2C_Kagawa_Prefecture%3B_November_2019_%2804%29.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Ritsurin_Garden,_Kagawa_Prefecture;_November_2019_(04).jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/0/01/14-09-02-oslo-RalfR-280.jpg', credit: 'https://commons.wikimedia.org/wiki/File:14-09-02-oslo-RalfR-280.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/6/61/Hut_in_Utsjoki_parish_village_in_Utsjoki%2C_Lapland%2C_Finland%2C_2021_September_-_3.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Hut_in_Utsjoki_parish_village_in_Utsjoki,_Lapland,_Finland,_2021_September_-_3.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/f/fa/Hut_in_Utsjoki_parish_village_in_Utsjoki%2C_Lapland%2C_Finland%2C_2021_September_-_2.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Hut_in_Utsjoki_parish_village_in_Utsjoki,_Lapland,_Finland,_2021_September_-_2.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/1/18/Langenlois_Weinweg_Weingartenh%C3%BCtte-8283.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Langenlois_Weinweg_Weingartenh%C3%BCtte-8283.jpg#Licensing', },
{ weight: 2, src: 'https://upload.wikimedia.org/wikipedia/commons/9/93/Steuerberg_Hinterwachsenberg_3_Brentlerstuben_07042015_1537.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Steuerberg_Hinterwachsenberg_3_Brentlerstuben_07042015_1537.jpg#Licensing', },
{ weight: 1, src: 'https://upload.wikimedia.org/wikipedia/commons/b/bc/Sir_Walter_Buffalo_Grass.jpg', credit: 'https://commons.wikimedia.org/wiki/File:Sir_Walter_Buffalo_Grass.jpg#Licensing', },
];
const image_choice = choose(images);
const html = document.querySelector('html');
const body = document.querySelector('body');
let img = new Image();
img.src = image_choice.src;
const credit = document.createElement('a');
credit.textContent = 'Image credit';
credit.className = 'image-credit';
credit.target = '_blank';
credit.href = image_choice.credit;
img.addEventListener('load', () => {
html.style.backgroundImage = `url(${img.src})`;
html.classList.add('loaded');
document.querySelector('header').appendChild(credit);
document.querySelector('main').appendChild(credit.cloneNode(true));
});

11
js/gomesong.js Normal file
View File

@ -0,0 +1,11 @@
const gomesong = document.getElementById('gomesong');
const music_box = document.getElementById('music-box');
music_box.addEventListener('click', () => {
if (gomesong.paused) {
music_box.classList.add('playing');
gomesong.play();
} else {
music_box.classList.remove('playing');
gomesong.pause();
}
});

48
js/listening.js Normal file
View File

@ -0,0 +1,48 @@
const params = (new URL(document.location)).searchParams;
let user = params.get('user');
if (!user) {
user = 'atbseefeldt';
}
const disc = './img/disc.webp';
const lastfm_default_image = 'https://lastfm.freetls.fastly.net/i/u/64s/2a96cbd8b46e442fc41c2b86b821562f.png';
fetch(`https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${user}&api_key=5460c3381d64e7e9908b9fdfc5559747&format=json`)
.then(r => r.json())
.then(lastfm => {
if (!lastfm.error) {
const listening = document.getElementById('listening');
document.getElementById('listening-title').innerHTML = 'Listening to';
const add_track = (track, all_loaded) => {
let trackHTML = '';
let classes = 'listening-item';
const attr = track['@attr'];
if (attr && attr.nowplaying) {
classes += ' now-playing';
}
if (all_loaded) {
classes += ' all-loaded';
}
trackHTML += `<div class='${classes}' title='${track.name.replaceAll("'","&apos;")}${track.artist['#text'].replaceAll("'","&apos;")}' onclick='if (!this.nextElementSibling) more_tracks(6)'>`;
let image = track.image[1]['#text'];
if (image === lastfm_default_image) {
image = disc;
}
trackHTML += `<img width=34 height=34 src='${image}' onload='if (!this.src.endsWith("${disc.substring(1)}")) this.classList.add("loaded")' onerror='this.src = "${disc}"' />`;
trackHTML += `<span class='listening-track'><span class='track-title'>${track.name}</span> — <span class='track-artist'>${track.artist['#text']}</span></span>`;
trackHTML += `</div>`;
listening.innerHTML += trackHTML;
}
let track_index = 0;
const more_tracks = count => {
const tracks = lastfm.recenttracks.track.slice(track_index, track_index + count);
track_index += count;
for (const track of tracks) {
add_track(track, track_index >= lastfm.recenttracks.track.length);
}
}
more_tracks(5);
window.more_tracks = more_tracks;
}
});

13
js/statuscafe.js Normal file
View File

@ -0,0 +1,13 @@
// based on https://status.cafe/current-status.js
fetch('https://status.cafe/users/gome/status.json')
.then( r => r.json() )
.then( r => {
if (!r.content.length) {
document.getElementById('statuscafe-content').innerHTML = 'No status yet.'
return
}
document.getElementById('status').classList.add('loaded');
document.getElementById('statuscafe-title').innerHTML = 'My status'
document.getElementById('statuscafe-username').innerHTML = "<a href='https://status.cafe/users/gome' target='_blank'>" + r.author + '</a> ' + r.face + ' ' + r.timeAgo
document.getElementById('statuscafe-content').innerHTML = r.content
})

42
js/wotd.js Normal file
View File

@ -0,0 +1,42 @@
const months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
const wotd = document.querySelector('#wotd');
const today = new Date();
let entry;
try {
let day = today.getDate().toString();
if (day.length === 1) {
day = '0' + day;
}
let month = (today.getMonth() + 1).toString();
if (month.length === 1) {
month = '0' + month;
}
fetch(`./wotd/${today.getFullYear()}.${month}.${day}.json`)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP response ${response.status} ${response.statusText}`);
}
return response.json();
})
.then(entry => {
if (entry) {
wotd.classList.add('loaded');
wotd.querySelector('.title').textContent = 'Word of the day';
wotd.querySelector('.date').textContent = today.getDate() + ' ' + months[today.getMonth()] + ' ' + today.getFullYear();
wotd.querySelector('.definiendum').textContent = entry.word;
wotd.querySelector('.pronunciation').textContent = entry.pronunciation;
let definitionHTML = '';
for (const definitionEntry of entry.definitions) {
definitionHTML += `<h3 class='part-of-speech'>${definitionEntry.part}</h4>`;
definitionHTML += `<ul class='definitions'>`;
for (const definition of definitionEntry.definitions) {
definitionHTML += `<li class='definition'>${definition}</li>`
}
definitionHTML += `</ul>`;
}
wotd.innerHTML += definitionHTML;
}
});
} catch (e) {
console.error('Word of the Day error:', e);
}