From c1e29cd610e94ccf1867459e6a934e83a111605c Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Mon, 29 Jan 2024 07:35:38 -0500 Subject: [PATCH 1/3] Store preference in user defaults --- .../Player Screen/PlayerViewModel.swift | 63 +++++++++---------- BookPlayer/Player/PlayerManager.swift | 6 +- BookPlayer/Player/SleepTimer.swift | 15 +++-- Shared/Constants.swift | 1 + 4 files changed, 42 insertions(+), 43 deletions(-) diff --git a/BookPlayer/Player/Player Screen/PlayerViewModel.swift b/BookPlayer/Player/Player Screen/PlayerViewModel.swift index 8456e1e2..21cc35a1 100755 --- a/BookPlayer/Player/Player Screen/PlayerViewModel.swift +++ b/BookPlayer/Player/Player Screen/PlayerViewModel.swift @@ -395,23 +395,7 @@ class PlayerViewModel: ViewModelProtocol { ) ) - let formatter = DateComponentsFormatter() - - formatter.unitsStyle = .full - formatter.allowedUnits = [.hour, .minute] - - for interval in SleepTimer.shared.intervals { - guard let formattedDuration = formatter.string(from: interval) else { continue } - - actions.append( - BPActionItem( - title: String.localizedStringWithFormat("sleep_interval_title".localized, formattedDuration), - handler: { - SleepTimer.shared.setTimer(.countdown(interval)) - } - ) - ) - } + actions.append(contentsOf: getCountdownActions()) actions.append( BPActionItem( @@ -431,21 +415,7 @@ class PlayerViewModel: ViewModelProtocol { ) ) - let stickyAction = SleepTimer.shared.getSticky() - ? BPActionItem( - title: "sleeptimer_option_sticky_on".localized, - handler: { - SleepTimer.shared.setSticky(stickyState: false) - } - ) - : BPActionItem( - title: "sleeptimer_option_sticky_off".localized, - handler: { - SleepTimer.shared.setSticky(stickyState: true) - } - ) - - actions.append(stickyAction) + actions.append(getStickyPreferenceAction()) actions.append(BPActionItem.cancelAction) sendEvent(.sleepTimerAlert( @@ -488,6 +458,35 @@ class PlayerViewModel: ViewModelProtocol { return storedTime } + + private func getCountdownActions() -> [BPActionItem] { + let formatter = DateComponentsFormatter() + formatter.unitsStyle = .full + formatter.allowedUnits = [.hour, .minute] + + return SleepTimer.shared.intervals.compactMap { interval in + guard let formattedDuration = formatter.string(from: interval) else { return nil } + + return BPActionItem( + title: String.localizedStringWithFormat("sleep_interval_title".localized, formattedDuration), + handler: { + SleepTimer.shared.setTimer(.countdown(interval)) + } + ) + } + } + + private func getStickyPreferenceAction() -> BPActionItem { + let isStickyPreferenceEnabled = SleepTimer.shared.isStickyPreferenceEnabled() + let title = isStickyPreferenceEnabled ? "sleeptimer_option_sticky_on" : "sleeptimer_option_sticky_off" + + return BPActionItem( + title: title.localized, + handler: { + SleepTimer.shared.setStickyPreference(!isStickyPreferenceEnabled) + } + ) + } } extension PlayerViewModel { diff --git a/BookPlayer/Player/PlayerManager.swift b/BookPlayer/Player/PlayerManager.swift index abdf05fd..72f78bc4 100755 --- a/BookPlayer/Player/PlayerManager.swift +++ b/BookPlayer/Player/PlayerManager.swift @@ -776,9 +776,9 @@ extension PlayerManager { } func handleStickyTimer() { - if SleepTimer.shared.getSticky() { - SleepTimer.shared.restartTimer() - } + guard SleepTimer.shared.isStickyPreferenceEnabled() else { return } + + SleepTimer.shared.restartTimer() } func setSpeed(_ newValue: Float) { diff --git a/BookPlayer/Player/SleepTimer.swift b/BookPlayer/Player/SleepTimer.swift index e0b44430..e1d2e147 100644 --- a/BookPlayer/Player/SleepTimer.swift +++ b/BookPlayer/Player/SleepTimer.swift @@ -39,8 +39,6 @@ final class SleepTimer { 1800.0, 3600.0 ] - - public var sticky = false /// Publisher when the countdown timer reaches the defined threshold public var countDownThresholdPublisher = PassthroughSubject() @@ -93,24 +91,24 @@ final class SleepTimer { // MARK: Public methods - public func setSticky(stickyState: Bool) { - sticky = stickyState + public func setStickyPreference(_ flag: Bool) { + UserDefaults.standard.set(flag, forKey: Constants.UserDefaults.stickyTimerEnabled) } - public func getSticky() -> Bool { - return sticky + public func isStickyPreferenceEnabled() -> Bool { + return UserDefaults.standard.bool(forKey: Constants.UserDefaults.stickyTimerEnabled) } public func setTimer(_ newState: SleepTimerState) { /// Always cancel any ongoing timer reset() state = newState - lastActiveState = newState switch newState { case .off: donateTimerIntent(with: .cancel) case .countdown(let interval): + lastActiveState = newState if let option = TimeParser.getTimerOption(from: interval) { donateTimerIntent(with: option) } @@ -120,11 +118,12 @@ final class SleepTimer { self?.update() } case .endOfChapter: + lastActiveState = newState donateTimerIntent(with: .endChapter) NotificationCenter.default.addObserver(self, selector: #selector(self.end), name: .chapterChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(self.end), name: .bookEnd, object: nil) } - } + } public func restartTimer() { setTimer(lastActiveState) diff --git a/Shared/Constants.swift b/Shared/Constants.swift index 7922afe4..a788ac63 100644 --- a/Shared/Constants.swift +++ b/Shared/Constants.swift @@ -35,6 +35,7 @@ public enum Constants { public static let playerListPrefersBookmarks = "userSettingsPlayerListPrefersBookmarks" public static let storageFilesSortOrder = "userSettingsStorageFilesSortOrder" public static let customSleepTimerDuration = "userSettingsCustomSleepTimerDuration" + public static let stickyTimerEnabled = "userSettingsStickyTimerEnabled" public static let rewindInterval = "userSettingsRewindInterval" public static let forwardInterval = "userSettingsForwardInterval" From cc75d6556ab2530b80ead1db19398d6d74d636c1 Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Mon, 29 Jan 2024 08:04:49 -0500 Subject: [PATCH 2/3] Rebrand sticky to auto --- BookPlayer/Base.lproj/Localizable.strings | 4 +- .../Player Screen/PlayerViewModel.swift | 13 ----- BookPlayer/Player/PlayerManager.swift | 10 ++-- BookPlayer/Player/SleepTimer.swift | 8 --- .../Settings/Base.lproj/Settings.storyboard | 56 ++++++++++++++++--- .../PlayerSettingsViewController.swift | 45 ++++++++++++--- BookPlayer/en.lproj/Localizable.strings | 4 +- Shared/Constants.swift | 2 +- 8 files changed, 94 insertions(+), 48 deletions(-) diff --git a/BookPlayer/Base.lproj/Localizable.strings b/BookPlayer/Base.lproj/Localizable.strings index 2c5c8782..7dc533b6 100644 --- a/BookPlayer/Base.lproj/Localizable.strings +++ b/BookPlayer/Base.lproj/Localizable.strings @@ -202,8 +202,6 @@ "error_loading_chapters" = "Chapters couldn't be loaded from: \n%@"; "error_empty_chapters" = "Chapters are empty, please verify the contents of the folder: %@"; "sleeptimer_option_custom" = "Custom"; -"sleeptimer_option_sticky_on" = "Sticky ✓"; -"sleeptimer_option_sticky_off" = "Sticky"; "sleeptimer_custom_alert_title" = "Custom sleep timer"; "settings_progresslabels_title" = "Progress Labels"; "settings_playerinterface_list_title" = "Opens"; @@ -305,3 +303,5 @@ We're working hard on providing a seamless experience, if possible, please conta "storage_artwork_cache_title" = "Artwork cache size"; "settings_share_debug_information" = "Share debug information"; "settings_autlock_section_title" = "Autolock"; +"settings_sleeptimer_auto_title" = "Auto Sleep Timer"; +"settings_sleeptimer_auto_description" = "Restart the last active sleep timer when playback is resumed"; diff --git a/BookPlayer/Player/Player Screen/PlayerViewModel.swift b/BookPlayer/Player/Player Screen/PlayerViewModel.swift index 21cc35a1..b39b6db5 100755 --- a/BookPlayer/Player/Player Screen/PlayerViewModel.swift +++ b/BookPlayer/Player/Player Screen/PlayerViewModel.swift @@ -415,7 +415,6 @@ class PlayerViewModel: ViewModelProtocol { ) ) - actions.append(getStickyPreferenceAction()) actions.append(BPActionItem.cancelAction) sendEvent(.sleepTimerAlert( @@ -475,18 +474,6 @@ class PlayerViewModel: ViewModelProtocol { ) } } - - private func getStickyPreferenceAction() -> BPActionItem { - let isStickyPreferenceEnabled = SleepTimer.shared.isStickyPreferenceEnabled() - let title = isStickyPreferenceEnabled ? "sleeptimer_option_sticky_on" : "sleeptimer_option_sticky_off" - - return BPActionItem( - title: title.localized, - handler: { - SleepTimer.shared.setStickyPreference(!isStickyPreferenceEnabled) - } - ) - } } extension PlayerViewModel { diff --git a/BookPlayer/Player/PlayerManager.swift b/BookPlayer/Player/PlayerManager.swift index 72f78bc4..875c4784 100755 --- a/BookPlayer/Player/PlayerManager.swift +++ b/BookPlayer/Player/PlayerManager.swift @@ -739,8 +739,8 @@ extension PlayerManager { handleSmartRewind(currentItem) - handleStickyTimer() - + handleAutoTimer() + fadeTimer?.invalidate() shakeMotionService.stopMotionUpdates() boostVolume = UserDefaults.standard.bool(forKey: Constants.UserDefaults.boostVolumeEnabled) @@ -775,9 +775,9 @@ extension PlayerManager { } } - func handleStickyTimer() { - guard SleepTimer.shared.isStickyPreferenceEnabled() else { return } - + func handleAutoTimer() { + guard UserDefaults.standard.bool(forKey: Constants.UserDefaults.autoTimerEnabled) else { return } + SleepTimer.shared.restartTimer() } diff --git a/BookPlayer/Player/SleepTimer.swift b/BookPlayer/Player/SleepTimer.swift index e1d2e147..9deedb2a 100644 --- a/BookPlayer/Player/SleepTimer.swift +++ b/BookPlayer/Player/SleepTimer.swift @@ -90,14 +90,6 @@ final class SleepTimer { } // MARK: Public methods - - public func setStickyPreference(_ flag: Bool) { - UserDefaults.standard.set(flag, forKey: Constants.UserDefaults.stickyTimerEnabled) - } - - public func isStickyPreferenceEnabled() -> Bool { - return UserDefaults.standard.bool(forKey: Constants.UserDefaults.stickyTimerEnabled) - } public func setTimer(_ newState: SleepTimerState) { /// Always cancel any ongoing timer diff --git a/BookPlayer/Settings/Base.lproj/Settings.storyboard b/BookPlayer/Settings/Base.lproj/Settings.storyboard index 5d3e4301..dbfce254 100644 --- a/BookPlayer/Settings/Base.lproj/Settings.storyboard +++ b/BookPlayer/Settings/Base.lproj/Settings.storyboard @@ -294,7 +294,7 @@ SKAN is Apple's privacy-first attribution solution that enables measuring how effective a campaign was without compromising the user privacy - + @@ -1998,12 +1998,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Doubles the volume. Use with caution and care for your hearing. - + @@ -2042,7 +2081,7 @@ Use with caution and care for your hearing. - + @@ -2081,7 +2120,7 @@ Use with caution and care for your hearing. - + @@ -2117,7 +2156,7 @@ Use with caution and care for your hearing. Toggle between displaying the remaining time, total duration and progress of either the chapter or the book in the player screen - + @@ -2152,19 +2191,19 @@ Use with caution and care for your hearing. - + - + -