diff --git a/apple/OmnivoreKit/Sources/App/Views/AI/FullScreenDigestView.swift b/apple/OmnivoreKit/Sources/App/Views/AI/FullScreenDigestView.swift index 51e015886..203913da2 100644 --- a/apple/OmnivoreKit/Sources/App/Views/AI/FullScreenDigestView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/AI/FullScreenDigestView.swift @@ -6,9 +6,9 @@ import MarkdownUI import Utils -func getChapterData(digest: DigestResult) -> [DigestChapterData] { +func getChapterData(digest: DigestResult) -> [(DigestChapter, DigestChapterData)] { let speed = 1.0 - var chapterData: [DigestChapterData] = [] + var chapterData: [(DigestChapter, DigestChapterData)] = [] var currentAudioIndex = 0 var currentWordCount = 0.0 @@ -16,11 +16,11 @@ func getChapterData(digest: DigestResult) -> [DigestChapterData] { let chapter = digest.chapters[index] let duration = currentWordCount / SpeechDocument.averageWPM / speed * 60.0 - chapterData.append(DigestChapterData( + chapterData.append((chapter, DigestChapterData( time: formatTimeInterval(duration) ?? "00:00", start: Int(currentAudioIndex), end: currentAudioIndex + Int(speechFile.utterances.count) - )) + ))) currentAudioIndex += Int(speechFile.utterances.count) currentWordCount += chapter.wordCount } @@ -35,7 +35,6 @@ func formatTimeInterval(_ time: TimeInterval) -> String? { return componentFormatter.string(from: time) } - @MainActor public class FullScreenDigestViewModel: ObservableObject { @Published var isLoading = false @@ -51,13 +50,17 @@ public class FullScreenDigestViewModel: ObservableObject { } do { if let digest = try await dataService.getLatestDigest(timeoutInterval: 10) { - self.digest = digest - lastVisitedDigestId = digest.id - if let playingDigest = audioController.itemAudioProperties as? DigestAudioItem, playingDigest.digest.id == digest.id { - // Don't think we need to do anything here - } else { - let chapters = getChapterData(digest: digest) - audioController.play(itemAudioProperties: DigestAudioItem(digest: digest, chapters: chapters)) + DispatchQueue.main.async { + self.digest = digest + self.chapterInfo = getChapterData(digest: digest) + self.lastVisitedDigestId = digest.id + + if let playingDigest = audioController.itemAudioProperties as? DigestAudioItem, playingDigest.digest.id == digest.id { + // 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 { @@ -170,11 +173,6 @@ struct FullScreenDigestView: View { .font(Font.system(size: 12)) .foregroundColor(Color(hex: "#898989")) .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 { Text("We're building you a new digest") .font(Font.system(size: 17, weight: .semibold)) diff --git a/apple/OmnivoreKit/Sources/Services/AudioSession/AudioController.swift b/apple/OmnivoreKit/Sources/Services/AudioSession/AudioController.swift index a55cdd90a..0e389d4a9 100644 --- a/apple/OmnivoreKit/Sources/Services/AudioSession/AudioController.swift +++ b/apple/OmnivoreKit/Sources/Services/AudioSession/AudioController.swift @@ -911,29 +911,59 @@ public struct DigestAudioItem: AudioItemProperties { } return .commandFailed } - + if let digest = self.itemAudioProperties as? DigestAudioItem { commandCenter.nextTrackCommand.isEnabled = true commandCenter.nextTrackCommand.addTarget { event -> MPRemoteCommandHandlerStatus in - let next = self.currentAudioIndex + 1 - if next < (self.document?.utterances.count ?? 0) { - self.seek(toIdx: self.currentAudioIndex + 1) + if let next = self.nextChapterIndex(chapters: digest.chapters, idx: self.currentAudioIndex) { + self.seek(toIdx: next) + 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 .commandFailed } } - + Task { await downloadAndSetArtwork() } } - func nextChapterIndex(digest: DigestResult, idx: Int) -> Int { -// for chapter in digest.chapters { -// if chapter. -// } - return 0 + func nextChapterIndex(chapters: [DigestChapterData], idx: Int) -> Int? { + if let chapterIdx = currentChapterIndex(chapters: chapters, idx: idx) { + if chapterIdx + 1 < chapters.count { + return chapters[chapterIdx + 1].start + } + } + 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 {