Skip to content

Conversation

@ooii
Copy link

@ooii ooii commented Jan 28, 2026

Summary

  • Fixes a bug where pausing during the sleep timer fade out period would leave the volume at a reduced level
  • Volume is now properly reset to full when playback is paused during fade out

Test plan

  • Enable sleep timer with fade out enabled
  • Wait until the fade out begins (last 10 seconds)
  • Pause playback while the volume is fading
  • Resume playback
  • Verify volume is back to normal level

🤖 Generated with Claude Code

ooii and others added 10 commits January 17, 2026 18:29
The app was incorrectly entering offline mode even when connections
succeeded. The issue was in loadLibraries() where:

- reduce(true) { $0 && $1 } returns true only when ALL connections succeed
- But the variable was named 'allConnectionsUnavailable' and used to
  enable offline mode when true

This caused the app to go offline when connections worked, and stay
online when they failed - exactly backwards.

Fix: Rename to 'anyConnectionSucceeded', use OR reduction, and only
enable offline mode when no connection succeeded.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When ENABLE_CENTRALIZED is not set, the app was using URL.userDirectory
which resolves to /Users (the system users folder), not the current
user's home directory. This caused permission errors when trying to
create download directories:

  "You don't have permission to save the file in folder..."
  NSCocoaErrorDomain Code=513

Fix:
- downloadDirectoryURL: Use FileManager.urls(for: .documentDirectory)
  instead of URL.userDirectory, placing downloads in Documents/DownloadV2/
- cacheDirectoryURL: Use FileManager.urls(for: .cachesDirectory)
  instead of URL.userDirectory, placing cache in Library/Caches/ShelfPlayer/

Both paths are now within the app's sandbox and writable.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement a toggle in Settings to allow users to disable haptic feedback
throughout the app. Previously, haptic feedback was always enabled with
no way to turn it off.

Changes:
- Add 'enableHaptics' preference key (defaults to true)
- Create View+SensoryFeedback.swift with conditional hapticFeedback()
  modifier that wraps SwiftUI's sensoryFeedback() and respects the
  user preference
- Add HapticsPreference.swift toggle component for the settings UI
- Add toggle to PreferencesView in the appearance section
- Replace all 28 occurrences of .sensoryFeedback() with .hapticFeedback()
  across 21 view files
- Add localized strings for "Haptic feedback" in all supported languages:
  EN, FR, DE, RU, SV, UK, ZH-Hans

When disabled, the hapticFeedback() modifier simply returns the content
unchanged, preventing any vibration feedback.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The "action.customize" key was only defined with a comment but had no
actual translations, causing the raw key to be displayed in the UI
instead of localized text.

Added translations for all supported languages:
- English: "Customize"
- French: "Personnaliser"
- German: "Anpassen"
- Russian: "Настроить"
- Swedish: "Anpassa"
- Ukrainian: "Налаштувати"
- Chinese (Simplified): "自定义"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace non-existent 'list.bullet.badge.ellipsis' SF Symbol with
'slider.horizontal.3' which is a valid system symbol that appropriately
represents customization/settings functionality.

Affected files:
- CompactLibraryPicker.swift (2 occurrences)
- AudiobookLibraryPanel.swift
- PodcastLibraryPanel.swift

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add .keyboardType(.URL) modifier to the server endpoint TextField in
ConnectionAddSheet. This presents the URL-optimized keyboard which
includes dedicated keys for ".", "/" and ".com" making it easier for
users to enter server addresses.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, the "play extends sleep timer" feature used a hardcoded
10-second window. This change adds a user-configurable setting to
control how long after the sleep timer expires the user can press
play to automatically restart it.

Changes:
- Add extendSleepTimerOnPlayWindow preference key (default: 10 seconds)
- Update AudioPlayer to use the configurable value instead of hardcoded 10
- Add UI controls in SleepTimerEditor: toggle for the feature and
  stepper for the time window (5-60 seconds in 5-second increments)
- Add localized strings for all supported languages (EN, FR, DE, RU,
  SV, UK, ZH-Hans)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a new setting that resets the sleep timer to its original duration
when the user pauses and resumes playback before the timer expires.
This is useful for users who want the timer to restart every time they
resume listening.

Example: If you set a 10-minute timer and pause after 5 minutes, when
you resume the timer will restart at 10 minutes instead of continuing
from 5 minutes remaining.

Changes:
- Add reset computed property to SleepTimerConfiguration that creates
  a new timer with the same original duration starting from now
- Add resetSleepTimerOnPlay preference key (default: false)
- Update AudioPlayer.play() to reset active timer when preference is
  enabled
- Add toggle in SleepTimerEditor with descriptive footer
- Add localized strings for all supported languages

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When the user paused playback during the sleep timer fade out period,
the volume remained at the reduced level instead of being restored to
full volume. This fix ensures the volume is reset to audioPlayerVolume
when playback is paused during the fade out.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When the resetSleepTimerOnPlay option is enabled, the sleep timer is
now properly reset to its initial duration when resuming playback after
a pause, instead of adjusting for the pause duration.

Additionally, this fix ensures sleepTimerDidExpireAt is properly set
when the timer expires, which is required for both resetSleepTimerOnPlay
and extendSleepTimerOnPlay features to work correctly.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant