mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-08-30 22:59:35 +02:00
Merge pull request #1512 from complacentsee/ios_autorewind
IOS: Support autoRewind and disableAutoRewind setting
This commit is contained in:
commit
e7c3242765
3 changed files with 54 additions and 27 deletions
|
@ -12,9 +12,36 @@ final class PlayerTimeUtilsTests: XCTestCase {
|
||||||
|
|
||||||
func testCalcSeekBackTime() {
|
func testCalcSeekBackTime() {
|
||||||
let currentTime: Double = 1000
|
let currentTime: Double = 1000
|
||||||
let threeSecondsAgo = Date(timeIntervalSinceNow: -3)
|
|
||||||
let lastPlayedMs = threeSecondsAgo.timeIntervalSince1970 * 1000
|
// 1. Nil lastPlayedMs → should seek back 5s
|
||||||
XCTAssertEqual(PlayerTimeUtils.calcSeekBackTime(currentTime: currentTime, lastPlayedMs: lastPlayedMs), 998)
|
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() {
|
func testCalcSeekBackTimeWithZeroCurrentTime() {
|
||||||
|
@ -27,18 +54,18 @@ final class PlayerTimeUtilsTests: XCTestCase {
|
||||||
func testTimeSinceLastPlayed() throws {
|
func testTimeSinceLastPlayed() throws {
|
||||||
let fiveSecondsAgo = Date(timeIntervalSinceNow: -5)
|
let fiveSecondsAgo = Date(timeIntervalSinceNow: -5)
|
||||||
let lastPlayedMs = fiveSecondsAgo.timeIntervalSince1970 * 1000
|
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))
|
XCTAssertNil(PlayerTimeUtils.timeSinceLastPlayed(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTimeToSeekBackForSinceLastPlayed() throws {
|
func testTimeToSeekBackForSinceLastPlayed() throws {
|
||||||
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(nil), 5, "Seeks back 5 seconds for nil")
|
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(nil), 0, "Seeks back 0 seconds for nil")
|
||||||
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(5), 2, "Seeks back 2 seconds for less than 6 seconds")
|
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(5), 0, "Seeks back 0 seconds for less than 10 seconds")
|
||||||
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(11), 10, "Seeks back 10 seconds for less than 12 seconds")
|
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(11), 3, "Seeks back 3 seconds for less than 1 minute")
|
||||||
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(29), 15, "Seeks back 15 seconds for less than 30 seconds")
|
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(298), 10, "Seeks back 10 seconds for less than 5 minutes")
|
||||||
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(179), 20, "Seeks back 20 seconds for less than 2 minutes")
|
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(1798), 20, "Seeks back 20 seconds for less than 30 minutes")
|
||||||
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(3599), 25, "Seeks back 25 seconds for less than 59 minutes")
|
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(3599), 30, "Seeks back 30 seconds for greater than 30 minutes")
|
||||||
XCTAssertEqual(PlayerTimeUtils.timeToSeekBackForSinceLastPlayed(60000), 29, "Seeks back 29 seconds for anything over 59 minuts")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,27 +21,27 @@ class PlayerTimeUtils {
|
||||||
static internal func timeSinceLastPlayed(_ lastPlayedMs: Double?) -> TimeInterval? {
|
static internal func timeSinceLastPlayed(_ lastPlayedMs: Double?) -> TimeInterval? {
|
||||||
guard let lastPlayedMs = lastPlayedMs else { return nil }
|
guard let lastPlayedMs = lastPlayedMs else { return nil }
|
||||||
let lastPlayed = Date(timeIntervalSince1970: lastPlayedMs / 1000)
|
let lastPlayed = Date(timeIntervalSince1970: lastPlayedMs / 1000)
|
||||||
return lastPlayed.timeIntervalSinceNow
|
return Date().timeIntervalSince(lastPlayed)
|
||||||
}
|
}
|
||||||
|
|
||||||
static internal func timeToSeekBackForSinceLastPlayed(_ sinceLastPlayed: TimeInterval?) -> TimeInterval {
|
static internal func timeToSeekBackForSinceLastPlayed(_ sinceLastPlayed: TimeInterval?) -> TimeInterval {
|
||||||
if let sinceLastPlayed = sinceLastPlayed {
|
if isAutoRewindDisabled(){
|
||||||
if sinceLastPlayed < 6 {
|
return 0
|
||||||
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 let sinceLastPlayed = sinceLastPlayed {
|
||||||
|
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 {
|
} else {
|
||||||
return 5
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static internal func isAutoRewindDisabled() -> Bool {
|
||||||
|
let deviceSettings = Database.shared.getDeviceSettings()
|
||||||
|
return deviceSettings.disableAutoRewind
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<!-- Playback settings -->
|
<!-- Playback settings -->
|
||||||
<p class="uppercase text-xs font-semibold text-fg-muted mb-2 mt-10">{{ $strings.HeaderPlaybackSettings }}</p>
|
<p class="uppercase text-xs font-semibold text-fg-muted mb-2 mt-10">{{ $strings.HeaderPlaybackSettings }}</p>
|
||||||
<div v-if="!isiOS" class="flex items-center py-3">
|
<div class="flex items-center py-3">
|
||||||
<div class="w-10 flex justify-center" @click="toggleDisableAutoRewind">
|
<div class="w-10 flex justify-center" @click="toggleDisableAutoRewind">
|
||||||
<ui-toggle-switch v-model="settings.disableAutoRewind" @input="saveSettings" />
|
<ui-toggle-switch v-model="settings.disableAutoRewind" @input="saveSettings" />
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue