Tags: asharahmed/scrobblr
Tags
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.
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().
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.
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.
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.
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.
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.
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.
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.
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.
PreviousNext