diff --git a/BookPlayer/Extensions/Notification+BookPlayer.swift b/BookPlayer/Extensions/Notification+BookPlayer.swift index 4381b473c..939f2d705 100644 --- a/BookPlayer/Extensions/Notification+BookPlayer.swift +++ b/BookPlayer/Extensions/Notification+BookPlayer.swift @@ -14,7 +14,7 @@ extension Notification.Name { public static let importOperation = Notification.Name("com.tortugapower.audiobookplayer.operation.new") public static let requestReview = Notification.Name("com.tortugapower.audiobookplayer.requestreview") public static let updatePercentage = Notification.Name("com.tortugapower.audiobookplayer.book.percentage") - public static let updateChapter = Notification.Name("com.tortugapower.audiobookplayer.book.chapter") + public static let chapterChange = Notification.Name("com.tortugapower.audiobookplayer.book.chapter") public static let bookReady = Notification.Name("com.tortugapower.audiobookplayer.book.ready") public static let bookPlayed = Notification.Name("com.tortugapower.audiobookplayer.book.play") public static let bookPaused = Notification.Name("com.tortugapower.audiobookplayer.book.pause") diff --git a/BookPlayer/Models/Book+CoreDataClass.swift b/BookPlayer/Models/Book+CoreDataClass.swift index 171344609..b1ccc19c3 100644 --- a/BookPlayer/Models/Book+CoreDataClass.swift +++ b/BookPlayer/Models/Book+CoreDataClass.swift @@ -20,17 +20,7 @@ public class Book: LibraryItem { return self.title + "." + self.ext } - var currentChapter: Chapter? { - guard let chapters = self.chapters?.array as? [Chapter], !chapters.isEmpty else { - return nil - } - - for chapter in chapters where chapter.start <= self.currentTime && chapter.end > self.currentTime { - return chapter - } - - return nil - } + var currentChapter: Chapter? var displayTitle: String { return self.title @@ -72,6 +62,8 @@ public class Book: LibraryItem { self.addToChapters(chapter) } } + + self.currentChapter = self.chapters?.array.first as? Chapter } convenience init(from bookUrl: FileItem, context: NSManagedObjectContext) { @@ -113,6 +105,24 @@ public class Book: LibraryItem { } } + public override func awakeFromFetch() { + super.awakeFromFetch() + + self.updateCurrentChapter() + } + + func updateCurrentChapter() { + guard let chapters = self.chapters?.array as? [Chapter], !chapters.isEmpty else { + return + } + + guard let currentChapter = (chapters.first { (chapter) -> Bool in + chapter.start <= self.currentTime && chapter.end > self.currentTime + }) else { return } + + self.currentChapter = currentChapter + } + override func getBookToPlay() -> Book? { return self } diff --git a/BookPlayer/Player/PlayerManager.swift b/BookPlayer/Player/PlayerManager.swift index c33e11b66..ddd80aa01 100644 --- a/BookPlayer/Player/PlayerManager.swift +++ b/BookPlayer/Player/PlayerManager.swift @@ -122,6 +122,12 @@ class PlayerManager: NSObject { NotificationCenter.default.post(name: .bookEnd, object: nil) } + if let currentChapter = book.currentChapter, + book.currentTime > currentChapter.end || book.currentTime < currentChapter.start { + book.updateCurrentChapter() + NotificationCenter.default.post(name: .chapterChange, object: nil, userInfo: nil) + } + let userInfo = [ "time": currentTime, "fileURL": book.fileURL @@ -159,13 +165,9 @@ class PlayerManager: NSObject { } set { - guard let player = self.audioPlayer else { - return - } + guard let player = self.audioPlayer else { return } player.currentTime = newValue - - self.currentBook?.currentTime = newValue } } @@ -236,9 +238,7 @@ class PlayerManager: NSObject { // MARK: - Seek Controls func jumpTo(_ time: Double, fromEnd: Bool = false) { - guard let player = self.audioPlayer else { - return - } + guard let player = self.audioPlayer else { return } player.currentTime = min(max(fromEnd ? player.duration - time : time, 0), player.duration) @@ -250,9 +250,7 @@ class PlayerManager: NSObject { } func jumpBy(_ direction: Double) { - guard let player = self.audioPlayer else { - return - } + guard let player = self.audioPlayer else { return } player.currentTime += direction @@ -373,9 +371,7 @@ class PlayerManager: NSObject { // Toggle play/pause of book func playPause(autoplayed _: Bool = false) { - guard let audioplayer = self.audioPlayer else { - return - } + guard let audioplayer = self.audioPlayer else { return } // Pause player if it's playing if audioplayer.isPlaying { diff --git a/BookPlayer/Player/SleepTimer.swift b/BookPlayer/Player/SleepTimer.swift index 39129c530..fb2746679 100644 --- a/BookPlayer/Player/SleepTimer.swift +++ b/BookPlayer/Player/SleepTimer.swift @@ -61,6 +61,13 @@ final class SleepTimer { })) } + self.alert.addAction(UIAlertAction(title: "End of current chapter", style: .default) { _ in + self.cancel() + self.alert.message = "Sleeping when the chapter ends" + NotificationCenter.default.addObserver(self, selector: #selector(self.end), name: .chapterChange, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.end), name: .bookChange, object: nil) + }) + self.alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) } @@ -80,6 +87,8 @@ final class SleepTimer { self.alert.message = defaultMessage self.timer?.invalidate() + NotificationCenter.default.removeObserver(self, name: .bookEnd, object: nil) + NotificationCenter.default.removeObserver(self, name: .chapterChange, object: nil) } private func cancel() { @@ -96,12 +105,16 @@ final class SleepTimer { self.alert.message = "Sleeping in \(self.durationFormatter.string(from: self.timeLeft)!)" if self.timeLeft <= 0 { - self.timer?.invalidate() - - self.onEnd?(false) + self.end() } } + @objc private func end() { + self.reset() + + self.onEnd?(false) + } + // MARK: Public methods func actionSheet(onStart: @escaping SleepTimerStart, onProgress: @escaping SleepTimerProgress, onEnd: @escaping SleepTimerEnd) -> UIAlertController {