Forward and backward chapter skipping

This commit is contained in:
Jackson Harper
2024-05-03 13:58:15 +08:00
parent c4644ce0e7
commit c7536dc598
2 changed files with 55 additions and 27 deletions

View File

@ -6,9 +6,9 @@ import MarkdownUI
import Utils import Utils
func getChapterData(digest: DigestResult) -> [DigestChapterData] { func getChapterData(digest: DigestResult) -> [(DigestChapter, DigestChapterData)] {
let speed = 1.0 let speed = 1.0
var chapterData: [DigestChapterData] = [] var chapterData: [(DigestChapter, DigestChapterData)] = []
var currentAudioIndex = 0 var currentAudioIndex = 0
var currentWordCount = 0.0 var currentWordCount = 0.0
@ -16,11 +16,11 @@ func getChapterData(digest: DigestResult) -> [DigestChapterData] {
let chapter = digest.chapters[index] let chapter = digest.chapters[index]
let duration = currentWordCount / SpeechDocument.averageWPM / speed * 60.0 let duration = currentWordCount / SpeechDocument.averageWPM / speed * 60.0
chapterData.append(DigestChapterData( chapterData.append((chapter, DigestChapterData(
time: formatTimeInterval(duration) ?? "00:00", time: formatTimeInterval(duration) ?? "00:00",
start: Int(currentAudioIndex), start: Int(currentAudioIndex),
end: currentAudioIndex + Int(speechFile.utterances.count) end: currentAudioIndex + Int(speechFile.utterances.count)
)) )))
currentAudioIndex += Int(speechFile.utterances.count) currentAudioIndex += Int(speechFile.utterances.count)
currentWordCount += chapter.wordCount currentWordCount += chapter.wordCount
} }
@ -35,7 +35,6 @@ func formatTimeInterval(_ time: TimeInterval) -> String? {
return componentFormatter.string(from: time) return componentFormatter.string(from: time)
} }
@MainActor @MainActor
public class FullScreenDigestViewModel: ObservableObject { public class FullScreenDigestViewModel: ObservableObject {
@Published var isLoading = false @Published var isLoading = false
@ -51,13 +50,17 @@ public class FullScreenDigestViewModel: ObservableObject {
} }
do { do {
if let digest = try await dataService.getLatestDigest(timeoutInterval: 10) { if let digest = try await dataService.getLatestDigest(timeoutInterval: 10) {
self.digest = digest DispatchQueue.main.async {
lastVisitedDigestId = digest.id self.digest = digest
if let playingDigest = audioController.itemAudioProperties as? DigestAudioItem, playingDigest.digest.id == digest.id { self.chapterInfo = getChapterData(digest: digest)
// Don't think we need to do anything here self.lastVisitedDigestId = digest.id
} else {
let chapters = getChapterData(digest: digest) if let playingDigest = audioController.itemAudioProperties as? DigestAudioItem, playingDigest.digest.id == digest.id {
audioController.play(itemAudioProperties: DigestAudioItem(digest: digest, chapters: chapters)) // Don't think we need to do anything here
} else {
let chapterData = self.chapterInfo?.map { $0.1 }
audioController.play(itemAudioProperties: DigestAudioItem(digest: digest, chapters: chapterData ?? []))
}
} }
} }
} catch { } catch {
@ -170,11 +173,6 @@ struct FullScreenDigestView: View {
.font(Font.system(size: 12)) .font(Font.system(size: 12))
.foregroundColor(Color(hex: "#898989")) .foregroundColor(Color(hex: "#898989"))
.lineLimit(1) .lineLimit(1)
Text(digest.description)
.font(Font.system(size: 14))
.lineSpacing(/*@START_MENU_TOKEN@*/10.0/*@END_MENU_TOKEN@*/)
.foregroundColor(Color.themeLibraryItemSubtle)
.lineLimit(6)
} else { } else {
Text("We're building you a new digest") Text("We're building you a new digest")
.font(Font.system(size: 17, weight: .semibold)) .font(Font.system(size: 17, weight: .semibold))

View File

@ -911,29 +911,59 @@ public struct DigestAudioItem: AudioItemProperties {
} }
return .commandFailed return .commandFailed
} }
if let digest = self.itemAudioProperties as? DigestAudioItem { if let digest = self.itemAudioProperties as? DigestAudioItem {
commandCenter.nextTrackCommand.isEnabled = true commandCenter.nextTrackCommand.isEnabled = true
commandCenter.nextTrackCommand.addTarget { event -> MPRemoteCommandHandlerStatus in commandCenter.nextTrackCommand.addTarget { event -> MPRemoteCommandHandlerStatus in
let next = self.currentAudioIndex + 1 if let next = self.nextChapterIndex(chapters: digest.chapters, idx: self.currentAudioIndex) {
if next < (self.document?.utterances.count ?? 0) { self.seek(toIdx: next)
self.seek(toIdx: self.currentAudioIndex + 1) return .success
}
return .commandFailed
}
commandCenter.previousTrackCommand.isEnabled = true
commandCenter.previousTrackCommand.addTarget { event -> MPRemoteCommandHandlerStatus in
if let next = self.prevChapterIndex(chapters: digest.chapters, idx: self.currentAudioIndex) {
self.seek(toIdx: next)
return .success return .success
} }
return .commandFailed return .commandFailed
} }
} }
Task { Task {
await downloadAndSetArtwork() await downloadAndSetArtwork()
} }
} }
func nextChapterIndex(digest: DigestResult, idx: Int) -> Int { func nextChapterIndex(chapters: [DigestChapterData], idx: Int) -> Int? {
// for chapter in digest.chapters { if let chapterIdx = currentChapterIndex(chapters: chapters, idx: idx) {
// if chapter. if chapterIdx + 1 < chapters.count {
// } return chapters[chapterIdx + 1].start
return 0 }
}
return nil
}
func prevChapterIndex(chapters: [DigestChapterData], idx: Int) -> Int? {
if let chapterIdx = currentChapterIndex(chapters: chapters, idx: idx) {
if chapterIdx - 1 > 0 {
return chapterIdx - 1
}
}
return nil
}
func currentChapterIndex(chapters: [DigestChapterData], idx: Int) -> Int? {
for (chapterIdx, chapter) in chapters.enumerated() {
if idx >= chapter.start && idx < chapter.end {
if chapterIdx + 1 < chapters.count {
return chapterIdx
}
}
}
return nil
} }
func isoLangForCurrentVoice() -> String { func isoLangForCurrentVoice() -> String {