diff --git a/ios/App/AudiobookshelfUnitTests/Shared/player/util/PlayerTimeUtilsTests.swift b/ios/App/AudiobookshelfUnitTests/Shared/player/util/PlayerTimeUtilsTests.swift index 91bc8403..64c045c4 100644 --- a/ios/App/AudiobookshelfUnitTests/Shared/player/util/PlayerTimeUtilsTests.swift +++ b/ios/App/AudiobookshelfUnitTests/Shared/player/util/PlayerTimeUtilsTests.swift @@ -12,9 +12,36 @@ final class PlayerTimeUtilsTests: XCTestCase { func testCalcSeekBackTime() { let currentTime: Double = 1000 - let threeSecondsAgo = Date(timeIntervalSinceNow: -3) - let lastPlayedMs = threeSecondsAgo.timeIntervalSince1970 * 1000 - XCTAssertEqual(PlayerTimeUtils.calcSeekBackTime(currentTime: currentTime, lastPlayedMs: lastPlayedMs), 998) + + // 1. Nil lastPlayedMs → should seek back 5s + XCTAssertEqual(PlayerTimeUtils.calcSeekBackTime(currentTime: currentTime, lastPlayedMs: nil), 1000) + + // 2. Played ~2s ago (<6s) → should seek back 2s + let played2sAgo = Date(timeIntervalSinceNow: -2).timeIntervalSince1970 * 1000 + XCTAssertEqual(PlayerTimeUtils.calcSeekBackTime(currentTime: currentTime, lastPlayedMs: played2sAgo), 1000) + + // 3. Played ~12s ago (6-12s range) → should seek back 10s + let played12sAgo = Date(timeIntervalSinceNow: -12).timeIntervalSince1970 * 1000 + XCTAssertEqual(PlayerTimeUtils.calcSeekBackTime(currentTime: currentTime, lastPlayedMs: played12sAgo), 997) + + // 4. Played ~62s ago (12-30s range) → should seek back 15s + let played62sAgo = Date(timeIntervalSinceNow: -62).timeIntervalSince1970 * 1000 + XCTAssertEqual(PlayerTimeUtils.calcSeekBackTime(currentTime: currentTime, lastPlayedMs: played62sAgo), 990) + + // 5. Played ~302s ago (30-180s range) → should seek back 20s + let played302sAgo = Date(timeIntervalSinceNow: -302).timeIntervalSince1970 * 1000 + XCTAssertEqual(PlayerTimeUtils.calcSeekBackTime(currentTime: currentTime, lastPlayedMs: played302sAgo), 980) + + // 6. Played ~1802s ago (180-3600s range) → should seek back 25s + let played1802sAgo = Date(timeIntervalSinceNow: -1802).timeIntervalSince1970 * 1000 + XCTAssertEqual(PlayerTimeUtils.calcSeekBackTime(currentTime: currentTime, lastPlayedMs: played1802sAgo), 970) + + // 8. Edge case where currentTime is small and would go negative + XCTAssertEqual(PlayerTimeUtils.calcSeekBackTime(currentTime: 1, lastPlayedMs: played12sAgo), 0) + + // 9. Edge case: negative lastPlayedMs (should be treated as an old timestamp) + XCTAssertEqual(PlayerTimeUtils.calcSeekBackTime(currentTime: currentTime, lastPlayedMs: -5000), 970) + } func testCalcSeekBackTimeWithZeroCurrentTime() { @@ -27,18 +54,18 @@ final class PlayerTimeUtilsTests: XCTestCase { func testTimeSinceLastPlayed() throws { let fiveSecondsAgo = Date(timeIntervalSinceNow: -5) let lastPlayedMs = fiveSecondsAgo.timeIntervalSince1970 * 1000 - XCTAssertEqual(PlayerTimeUtils.timeSinceLastPlayed(lastPlayedMs)!, -5, accuracy: 1.0) + XCTAssertEqual(PlayerTimeUtils.timeSinceLastPlayed(lastPlayedMs)!, 5, accuracy: 1.0) XCTAssertNil(PlayerTimeUtils.timeSinceLastPlayed(nil)) } func testTimeToSeekBackForSinceLastPlayed() throws { - XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(nil), 5, "Seeks back 5 seconds for nil") - XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(5), 2, "Seeks back 2 seconds for less than 6 seconds") - XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(11), 10, "Seeks back 10 seconds for less than 12 seconds") - XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(29), 15, "Seeks back 15 seconds for less than 30 seconds") - XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(179), 20, "Seeks back 20 seconds for less than 2 minutes") - XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(3599), 25, "Seeks back 25 seconds for less than 59 minutes") - XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(60000), 29, "Seeks back 29 seconds for anything over 59 minuts") + XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(nil), 0, "Seeks back 0 seconds for nil") + XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(5), 0, "Seeks back 0 seconds for less than 10 seconds") + XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(11), 3, "Seeks back 3 seconds for less than 1 minute") + XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(298), 10, "Seeks back 10 seconds for less than 5 minutes") + XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(1798), 20, "Seeks back 20 seconds for less than 30 minutes") + XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(3599), 30, "Seeks back 30 seconds for greater than 30 minutes") + } } diff --git a/ios/App/Shared/player/util/PlayerTimeUtils.swift b/ios/App/Shared/player/util/PlayerTimeUtils.swift index 24fc00a1..27206008 100644 --- a/ios/App/Shared/player/util/PlayerTimeUtils.swift +++ b/ios/App/Shared/player/util/PlayerTimeUtils.swift @@ -21,27 +21,27 @@ class PlayerTimeUtils { static internal func timeSinceLastPlayed(_ lastPlayedMs: Double?) -> TimeInterval? { guard let lastPlayedMs = lastPlayedMs else { return nil } let lastPlayed = Date(timeIntervalSince1970: lastPlayedMs / 1000) - return lastPlayed.timeIntervalSinceNow + return Date().timeIntervalSince(lastPlayed) } static internal func timeToSeekBackForSinceLastPlayed(_ sinceLastPlayed: TimeInterval?) -> TimeInterval { + if isAutoRewindDisabled(){ + return 0 + } if let sinceLastPlayed = sinceLastPlayed { - if sinceLastPlayed < 6 { - return 2 - } else if sinceLastPlayed < 12 { - return 10 - } else if sinceLastPlayed < 30 { - return 15 - } else if sinceLastPlayed < 180 { - return 20 - } else if sinceLastPlayed < 3600 { - return 25 - } else { - return 29 - } + if sinceLastPlayed < 10 { return 0 } // 10s or less = no seekback + else if sinceLastPlayed < 60 { return 3 } // 10s to 1m = jump back 3s + else if sinceLastPlayed < 300 { return 10 } // 1m to 5m = jump back 10s + else if sinceLastPlayed < 1800 { return 20 } // 5m to 30m = jump back 20s + else { return 30 } // 30m and up = jump back 30s } else { - return 5 + return 0 } } + static internal func isAutoRewindDisabled() -> Bool { + let deviceSettings = Database.shared.getDeviceSettings() + return deviceSettings.disableAutoRewind + } + } diff --git a/pages/settings.vue b/pages/settings.vue index 67cfbb0a..09b3216b 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -36,7 +36,7 @@
{{ $strings.HeaderPlaybackSettings }}
-