aboutsummaryrefslogtreecommitdiffstats
path: root/index.html
blob: 2bffb8492cf2b8fa08b88301a4c74eb95bb620cc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>scrobble.observer</title>
    
    <link href="/style.css" rel="stylesheet" />
    
    <style>
#wizard {
  display: flex;
  flex-direction: row;
}
#wizard * {
  box-sizing: border-box;
}
#wizard > div {
  margin: 2px;
}
#wizard-container > *,
#wizard-outputs > * {
  width: 100%;
}
#wizard-container {
  flex-grow: 1;
}
    </style>

    <!-- Open Graph Begin -->
    <meta property="og:type" value="website">
    <meta property="og:title" value="scrobble.observer">
    <meta property="og:image" value="https://scrobble.observer/favicon.ico">
    <meta property="og:url" value="https://scrobble.observer">
    <meta property="og:description"
        value="A little embed for your personal site, with whatever you're scrobbling.">
    <meta property="og:site_name" value="scrobble.observer">
    <!-- Open Graph End -->
</head>

<body>
    <hgroup>
        <h1>Scrobble.Observer</h1>
        <p>A little embed for your personal site, with whatever you're scrobbling.</p>
    </hgroup>
    <main>
        <section id=blurb>
            <img src='/logo.png' id=logo style='margin-left: calc(50% - 64px); box-shadow: white 0px 0px 16px; border-radius: 14px;'>
            <p><a href='https://last.fm'>Last.fm</a> is a cool service! It keeps a live, usually public, log, of whatever music you're listening to!
               I felt like that fit into the general set of status buttons and other widgets present in the
               Web Revival movement, and yet last.fm was basically stuck on <code>https://www.last.fm</code>. I decided to write an embed myself.
               If you'd like to know about the technical details, the code and lengthy documentation are available on my git server (link at the bottom).</p>
               <p>This project is not affiliated with or endorsed by last.fm at all, I'm just doing it for fun :&gt;</p>
        </section>
        <section id=intro>
            <h2>Introduction</h2><br>
            <iframe style='background-color: black; width: 60%; height: 3.2cm; margin-left: 20%' src='/user/LAST.HQ?dark'></iframe>
            <p>This is the embed. Currently, it's displaying the listening history of the last.fm staff. It will update once-a-minute,
               every minute, with whatever they're listening to. This rate limit is to avoid pinging the last.fm API too much, and because
               few songs are shorter than 1 minute. This embed also uses no Javascript, instead relying on other mechanisms to refresh.</p>
        </section>
        <section id=generator>
            <h2>Generate your embed!</h2><br>
            <div id=wizard>
                <div id=wizard-outputs style='width: 60%;'>
                    <iframe id=wizard-iframe style='height: 3.2cm; width: 100%; box-sizing: border-box;' src='/user/LAST.HQ?dark'></iframe>
                    <textarea id=wizard-code readonly style='width: 100%;' rows=4>&lt;iframe style='height: 3.2cm;' src='/user/LAST.HQ?theme=plain&dark'&gt;&lt;/iframe&gt;</textarea>
                </div>
                <div id=wizard-container style='width: 40%'>
                    <input type=text id=wizard-username placeholder='Your last.fm username, e.g. LAST.HQ' style='width: 100%;'>
                    <select id=wizard-theme><option selected disabled value='plain'>-- Choose a theme --</option></select><hr><p id=wizard-theme-notes></p><span>Options</span>
                    <select id=wizard-theme-params-bool multiple><option selected value='dark'>Dark Mode</option></select>
                    <div id=wizard-theme-params-text></div>
                </div>
            </div>
        </section>
        <section id=contact>
            <h2>Contact</h2>
            <p>This project is currently run by just one person, but if you need help or want to contribute, these are the places to go.</p>
            <ul>
                <li><a href='https://forum.melonland.net/index.php?topic=2280.0'>The Melonland Forum Topic</a></li>
                <li><a href='https://git.aleteoryx.me/cgit/lfm_embed/'>The Git Repository</a></li>
                <li>The Author's...</li>
                <ul>
                    <li><a href='https://aleteoryx.me'>Website</a></li>
                    <li><a href='https://mk.aleteoryx.me/@admin'>Fedi</a></li>
                    <li><a href='mailto:webmaster@aleteoryx.me'>Email</a></li>
                </ul>
            </ul>
        </section>
    </main>
    <footer>🄯 Aleteoryx 2024. Free forever. If you don't trust me, <a href='https://git.aleteoryx.me/cgit/lfm_embed/'>host it yourself</a>.</footer>
<script>
const THEMES = {
  "plain": {
    "name": "Plain (Default)",
    "notes": "This theme works best with <code>width: 10cm;</code>, at minimum. You'll need to figure out what looks best and add it to the style attribute manually on your site.",
    "style": 'height: 3.2cm;',
    "bool": {"dark": "Dark Mode"}
  }
};
console.log(THEMES);
for (const theme in THEMES) {
  const option = document.createElement('option');
  option.value = theme;
  option.innerText = THEMES[theme].name;
  document.getElementById('wizard-theme').appendChild(option);
}

window.iframetimeout = null;

function regen(throttle) {
  const username = document.getElementById('wizard-username').value.replace(" ", "") || 'LAST.HQ';
  const themename = document.getElementById('wizard-theme').value;
  const themeparams = Array.from(document.getElementById('wizard-theme-params-bool').selectedOptions).map(x => x.value);
  
  const url = 'https://scrobble.observer/user/'+username+'?theme='+themename+(themeparams.length ? '&' + themeparams.join('&') : '');

  clearTimeout(window.iframetimeout);
  if (throttle) {
    window.iframetimeout = setTimeout(() => (document.getElementById('wizard-iframe').src = url), 500);
  }
  else {
    document.getElementById('wizard-iframe').src = url;
  }

  document.getElementById('wizard-code').value = "<iframe style='"+THEMES[themename].style+"' src='"+url+"'></iframe>"
}
function themechange() {
  const themename = document.getElementById('wizard-theme').value;
  const themeparamelement = document.getElementById('wizard-theme-params-bool');
  const themenoteselement = document.getElementById('wizard-theme-notes');

  themenoteselement.innerHTML = THEMES[themename].notes;

  themeparamelement.innerHTML = '';
  for (const boolparam in THEMES[themename]['bool']) {
    const option = document.createElement('option');
    option.value = boolparam;
    option.innerText = THEMES[themename]['bool'][boolparam];
    themeparamelement.appendChild(option);
  }

  regen();
}

document.getElementById('wizard-username').oninput = () => regen(true);
document.getElementById('wizard-theme').onchange = themechange;
document.getElementById('wizard-theme-params-bool').onchange = regen;
</script>
</body>
</html>