@rmdes/indiekit-endpoint-lastfm 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/styles.css +0 -25
- package/lib/sync.js +6 -5
- package/lib/utils.js +8 -5
- package/package.json +1 -1
- package/views/lastfm.njk +7 -7
package/assets/styles.css
CHANGED
|
@@ -13,31 +13,6 @@
|
|
|
13
13
|
gap: var(--space-3xs);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
.lastfm-field label {
|
|
17
|
-
font-weight: var(--font-weight-semibold);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.lastfm-field__hint {
|
|
21
|
-
color: var(--color-text-secondary);
|
|
22
|
-
font-size: var(--step--1);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.lastfm-field input {
|
|
26
|
-
appearance: none;
|
|
27
|
-
background-color: var(--color-background);
|
|
28
|
-
border: 1px solid var(--color-border);
|
|
29
|
-
border-radius: var(--radius-s);
|
|
30
|
-
font-size: var(--step--1);
|
|
31
|
-
padding: var(--space-2xs) var(--space-s);
|
|
32
|
-
width: 100%;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.lastfm-field input:focus {
|
|
36
|
-
border-color: var(--color-accent);
|
|
37
|
-
outline: 2px solid var(--color-accent);
|
|
38
|
-
outline-offset: 1px;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
16
|
/* Stats grid */
|
|
42
17
|
.lastfm-stats {
|
|
43
18
|
display: grid;
|
package/lib/sync.js
CHANGED
|
@@ -177,7 +177,8 @@ export async function syncScrobbles(db, client) {
|
|
|
177
177
|
|
|
178
178
|
// Get the latest synced scrobble
|
|
179
179
|
const latest = await collection.findOne({}, { sort: { scrobbledAt: -1 } });
|
|
180
|
-
|
|
180
|
+
// Handle both Date objects (old data) and ISO strings (new data)
|
|
181
|
+
const latestDate = latest?.scrobbledAt ? new Date(latest.scrobbledAt) : new Date(0);
|
|
181
182
|
|
|
182
183
|
console.log(
|
|
183
184
|
`[Last.fm] Syncing scrobbles since: ${latestDate.toISOString()}`
|
|
@@ -236,13 +237,13 @@ export async function syncScrobbles(db, client) {
|
|
|
236
237
|
* @returns {object} - Transformed document
|
|
237
238
|
*/
|
|
238
239
|
function transformScrobble(scrobble) {
|
|
239
|
-
const
|
|
240
|
+
const scrobbledAtDate = parseDate(scrobble.date);
|
|
240
241
|
const artistName = getArtistName(scrobble);
|
|
241
242
|
const albumTitle = getAlbumName(scrobble);
|
|
242
243
|
|
|
243
244
|
return {
|
|
244
245
|
// Create a unique ID from track info and timestamp
|
|
245
|
-
lastfmId: `${artistName}:${scrobble.name}:${
|
|
246
|
+
lastfmId: `${artistName}:${scrobble.name}:${scrobbledAtDate.getTime()}`,
|
|
246
247
|
trackTitle: scrobble.name,
|
|
247
248
|
trackUrl: getTrackUrl(scrobble),
|
|
248
249
|
artistName,
|
|
@@ -252,7 +253,7 @@ function transformScrobble(scrobble) {
|
|
|
252
253
|
mbid: getMbid(scrobble),
|
|
253
254
|
coverUrl: getCoverUrl(scrobble),
|
|
254
255
|
loved: scrobble.loved === "1",
|
|
255
|
-
scrobbledAt,
|
|
256
|
-
syncedAt: new Date(),
|
|
256
|
+
scrobbledAt: scrobbledAtDate.toISOString(),
|
|
257
|
+
syncedAt: new Date().toISOString(),
|
|
257
258
|
};
|
|
258
259
|
}
|
package/lib/utils.js
CHANGED
|
@@ -239,8 +239,11 @@ export function getPlayingStatus(track) {
|
|
|
239
239
|
*/
|
|
240
240
|
export function formatScrobble(scrobble, fromDb = false) {
|
|
241
241
|
if (fromDb) {
|
|
242
|
-
// From MongoDB
|
|
243
|
-
const
|
|
242
|
+
// From MongoDB — scrobbledAt may be Date object (old) or ISO string (new)
|
|
243
|
+
const scrobbledAtRaw = scrobble.scrobbledAt;
|
|
244
|
+
const scrobbledAtISO = scrobbledAtRaw instanceof Date
|
|
245
|
+
? scrobbledAtRaw.toISOString()
|
|
246
|
+
: scrobbledAtRaw;
|
|
244
247
|
return {
|
|
245
248
|
id: scrobble.lastfmId || scrobble._id?.toString(),
|
|
246
249
|
track: scrobble.trackTitle,
|
|
@@ -250,9 +253,9 @@ export function formatScrobble(scrobble, fromDb = false) {
|
|
|
250
253
|
trackUrl: scrobble.trackUrl,
|
|
251
254
|
mbid: scrobble.mbid,
|
|
252
255
|
loved: scrobble.loved || false,
|
|
253
|
-
scrobbledAt:
|
|
254
|
-
relativeTime: formatRelativeTime(
|
|
255
|
-
status: getPlayingStatus({ date:
|
|
256
|
+
scrobbledAt: scrobbledAtISO,
|
|
257
|
+
relativeTime: formatRelativeTime(scrobbledAtRaw),
|
|
258
|
+
status: getPlayingStatus({ date: scrobbledAtRaw }),
|
|
256
259
|
};
|
|
257
260
|
}
|
|
258
261
|
|
package/package.json
CHANGED
package/views/lastfm.njk
CHANGED
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
{% block lastfm %}
|
|
4
4
|
{# Settings Section #}
|
|
5
5
|
{% call section({ title: __("lastfm.settings") }) %}
|
|
6
|
-
<p class="
|
|
6
|
+
<p class="hint">{{ __("lastfm.settingsHelp") }}</p>
|
|
7
7
|
<form method="post" action="{{ mountPath }}/settings" class="lastfm-form">
|
|
8
8
|
<div class="lastfm-field">
|
|
9
|
-
<label for="apiKey">{{ __("lastfm.apiKey") }}</label>
|
|
10
|
-
<span class="
|
|
11
|
-
<input type="password" id="apiKey" name="apiKey" value="{{ settings.apiKey }}" aria-describedby="apiKey-hint" placeholder="Your Last.fm API key" autocomplete="off">
|
|
9
|
+
<label class="label" for="apiKey">{{ __("lastfm.apiKey") }}</label>
|
|
10
|
+
<span class="hint" id="apiKey-hint">{{ __("lastfm.apiKeyHelp") }}</span>
|
|
11
|
+
<input class="input" type="password" id="apiKey" name="apiKey" value="{{ settings.apiKey }}" aria-describedby="apiKey-hint" placeholder="Your Last.fm API key" autocomplete="off">
|
|
12
12
|
</div>
|
|
13
13
|
<div class="lastfm-field">
|
|
14
|
-
<label for="username">{{ __("lastfm.username") }}</label>
|
|
15
|
-
<span class="
|
|
16
|
-
<input type="text" id="username" name="username" value="{{ settings.username }}" aria-describedby="username-hint" placeholder="Last.fm username">
|
|
14
|
+
<label class="label" for="username">{{ __("lastfm.username") }}</label>
|
|
15
|
+
<span class="hint" id="username-hint">{{ __("lastfm.usernameHelp") }}</span>
|
|
16
|
+
<input class="input" type="text" id="username" name="username" value="{{ settings.username }}" aria-describedby="username-hint" placeholder="Last.fm username">
|
|
17
17
|
</div>
|
|
18
18
|
<div>
|
|
19
19
|
{{ button({
|