@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 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
- const latestDate = latest?.scrobbledAt || new Date(0);
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 scrobbledAt = parseDate(scrobble.date);
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}:${scrobbledAt.getTime()}`,
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 scrobbledAt = scrobble.scrobbledAt;
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: scrobbledAt.toISOString(),
254
- relativeTime: formatRelativeTime(scrobbledAt),
255
- status: getPlayingStatus({ date: scrobbledAt }),
256
+ scrobbledAt: scrobbledAtISO,
257
+ relativeTime: formatRelativeTime(scrobbledAtRaw),
258
+ status: getPlayingStatus({ date: scrobbledAtRaw }),
256
259
  };
257
260
  }
258
261
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-lastfm",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Last.fm scrobble and listening activity endpoint for Indiekit. Display listening history, loved tracks, and statistics.",
5
5
  "keywords": [
6
6
  "indiekit",
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="lastfm-field__hint">{{ __("lastfm.settingsHelp") }}</p>
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="lastfm-field__hint" id="apiKey-hint">{{ __("lastfm.apiKeyHelp") }}</span>
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="lastfm-field__hint" id="username-hint">{{ __("lastfm.usernameHelp") }}</span>
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({