Skip to content

Tags: asharahmed/scrobblr

Tags

v0.1.15

Toggle v0.1.15's commit message
Release 0.1.15: loved tracks everywhere

- ScrobbleEngine: replace single-track lovedIdentity with a server-seeded
  Set<String> keyed by lowercase artist|title. Pulled from
  user.getLovedTracks (limit 200) at launch and after each remote sync,
  so hearts reflect actual Last.fm state across devices.
- Add toggleLove(artist:title:) for arbitrary tracks; optimistic flip,
  revert on API error.
- MenuBarContent: heart on remote-now-playing card; generalized
  loveButton(artist:title:size:) so all surfaces share the same path.
  Heart now toggles (was disabled after first love).
- SettingsView recent scrobble rows: per-row heart.

v0.1.14

Toggle v0.1.14's commit message
Release 0.1.14: performance + safety pass

- Cache decoded NSImage so SwiftUI doesn't re-decode artwork bytes on
  every body re-evaluation (the menu bar tick re-renders 4x/sec during
  smooth playback). Introduces CachedNSImage; wired into menu bar
  remote-now-playing artwork and the Stats AlbumTile.
- Use a scoped ephemeral URLSession with a 10s timeout for the direct
  remote-now-playing artwork fetch. URLSession.shared's 60s default was
  too lenient for a 15s sync cadence; a stalled CDN can no longer pin
  the task.
- Tighten SystemMonitor lifecycle: explicit stop() cancels the
  NWPathMonitor, removes NSWorkspace observers, and fires pending
  resume continuations. Wired into AppCoordinator.shutdown().

v0.1.13

Toggle v0.1.13's commit message
Release 0.1.13: faster remote sync

- Poll cadence 60s → 15s. Last.fm rate limit is 5 req/s averaged
  over 5 min; we do 2 req/15s = 0.13 req/s, well under budget.
- Initial sync delay 20s → 3s after launch.
- Menu bar dropdown open triggers an immediate sync via the new
  engine.requestImmediateSync() flag. Loop polls the flag in 1s
  chunks during its sleep window, so wake latency is under a second.

End-to-end: starting playback on iPhone now appears in the menu bar
within ~15s without interaction, or within ~1s when the user opens
the dropdown to look.

v0.1.12

Toggle v0.1.12's commit message
Release 0.1.12: remote now-playing in the menu bar

When local Music.app is idle, surface what Last.fm reports the user
is scrobbling on any other device. Uses user.getRecentTracks?limit=1
and checks @attr.nowplaying. Falls through cleanly:
local snapshot.track > remoteNowPlaying > idle.

New Track.Origin .remote case ensures these mirrored entries are
never re-submitted as scrobbles (already scrobbled by their source
client). Origin badge shows blue 'On another device' chip.

Menu bar status icon picks wave.3.right when remote-only playing.

v0.1.11

Toggle v0.1.11's commit message
Release 0.1.11: autosync from Last.fm

Periodically (every 60s while awake + online) pulls user.getRecentTracks
from Last.fm and merges any scrobbles we didn't submit ourselves into
the recentScrobbles ring buffer. Lets the menu bar and Activity view
reflect plays from iPhone, web player, or another Mac in near real-time
even when nothing is playing locally.

Dedupe by (lowercased artist, lowercased title, integer epoch second).
Updates lastScrobbled if the import beats our newest. Initial 20s
delay so we don't collide with the flush loop's existing
getRecentTracks call for two-Mac detection.

v0.1.10

Toggle v0.1.10's commit message
Release 0.1.10: menu bar dismissal, take two

Previous fix used NSApp.keyWindow?.orderOut(nil) on the assumption
that the MenuBarExtra panel is keyWindow when open. It isn't always.
Replace with a hunt by NSPanel + .nonactivatingPanel style mask,
which is the defining trait of menu-bar dropdowns and stable across
SwiftUI releases.

v0.1.9

Toggle v0.1.9's commit message
Release 0.1.9: UX polish pass 2

- Menu bar dropdown dismisses when Settings/Stats/Profile/Welcome
  buttons are clicked. SwiftUI MenuBarExtra(style: .window) panel
  doesn't auto-close on inside-clicks; we explicitly orderOut(nil)
  the keyWindow (which IS the panel) before triggering the next
  window.
- 'Connected' status row hidden when nothing newsworthy to report
  (hasStatusContent computed property). Menu is quieter when idle.
- Stats Top Tracks/Artists/Albums rows are fully clickable, not just
  the arrow icon. .contentShape(Rectangle()) + .onTapGesture pattern.
- Stats period picker label hidden + .fixedSize() to prevent the
  picker-label-wrapping bug we hit with the Ignored rules earlier.

v0.1.8

Toggle v0.1.8's commit message
Release 0.1.8: copy pass for layman comprehensibility

Rewrites every Settings card footer, menu bar tooltip, and onboarding
subtitle for a non-developer audience. Removes NSRegularExpression,
distributed notifications, EdDSA, Tahoe-fallback metadata, and
threshold terminology from user-visible strings. Drops subtitles that
were redundant with their row titles.

v0.1.7

Toggle v0.1.7's commit message
Release 0.1.7: Top Albums grid + About copy cleanup

- Stats Top Albums now renders as a 3-column cover-art grid with
  rank + play-count badges, hover lift, click-out to Last.fm.
- AlbumTile falls back to identity-colored gradient + iTunes Search
  when Last.fm's image is missing or returns its 'no artwork' placeholder.
- Removed 'Made with care on macOS' tagline. Trademark footer tightened
  to two clear sentences.

v0.1.6

Toggle v0.1.6's commit message
Release 0.1.6: fix vertical 'Match' picker label

Picker("Match", ...).pickerStyle(.segmented).frame(width: 130) was
crushing the label text to ~12pt wide, wrapping it one letter per line.
Hide the picker's built-in label via .labelsHidden() and render a
plain 'Match' Text in the HStack separately.