Clean up messages in digest onboarding

This commit is contained in:
Jackson Harper
2024-05-17 12:04:29 +08:00
parent 373d397539
commit a510229fe5
5 changed files with 56 additions and 36 deletions

View File

@ -40,6 +40,7 @@ public class DigestConfigViewModel: ObservableObject {
try await dataService.setupUserDigestConfig()
try await dataService.refreshDigest()
digestEnabled = true
dataService.featureFlags.digestEnabled = true
} catch {
if error is IneligibleError {
isIneligible = true
@ -109,20 +110,17 @@ struct DigestConfigView: View {
}
.padding(.top, 50)
} else if viewModel.digestEnabled {
VStack(spacing: 15) {
VStack(spacing: 25) {
Spacer()
Text("""
You've been added to the AI Digest demo. Your first issue should be ready soon.
When a new digest is ready the icon in the library header will change color.
You can close this window now.
""")
// swiftlint:disable:next line_length
Text("You've been added to the AI Digest demo. Your first issue should be ready soon. When a new digest is ready the icon in the library header will change color. You can close this window now.")
if !viewModel.notificationsEnabled {
if viewModel.isTryingToEnableNotifications {
ProgressView()
} else {
Button(action: {
viewModel.tryEnableNotifications(dataService: dataService)
}, label: { Text("Notify me when its ready") })
}, label: { Text("Enable digest notifications") })
.buttonStyle(RoundedRectButtonStyle(color: Color.blue, textColor: Color.white))
}
}

View File

@ -12,17 +12,19 @@ func getChapterData(digest: DigestResult) -> [(DigestChapter, DigestChapterData)
var currentAudioIndex = 0
var currentWordCount = 0.0
for (index, speechFile) in digest.speechFiles.enumerated() {
let chapter = digest.chapters[index]
for (index, speechFile) in (digest.speechFiles ?? []).enumerated() {
let chapter = digest.chapters?[index]
let duration = currentWordCount / SpeechDocument.averageWPM / speed * 60.0
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
if let chapter = chapter {
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
}
}
return chapterData
}
@ -39,6 +41,7 @@ func formatTimeInterval(_ time: TimeInterval) -> String? {
public class FullScreenDigestViewModel: ObservableObject {
@Published var isLoading = false
@Published var hasError = false
@Published var isRunning = false
@Published var digest: DigestResult?
@Published var chapterInfo: [(DigestChapter, DigestChapterData)]?
@Published var presentedLibraryItem: String?
@ -49,6 +52,7 @@ public class FullScreenDigestViewModel: ObservableObject {
func load(dataService: DataService, audioController: AudioController) async {
hasError = false
isLoading = true
isRunning = false
if !dataService.digestNeedsRefresh() {
if let digest = dataService.loadStoredDigest() {
@ -69,6 +73,8 @@ public class FullScreenDigestViewModel: ObservableObject {
self.digest = digest
self.chapterInfo = getChapterData(digest: digest)
self.lastVisitedDigestId = digest.id
self.isRunning = digest.jobState == "RUNNING" || digest.jobState == "PENDING"
self.hasError = digest.jobState == "FAILED"
if let playingDigest = audioController.itemAudioProperties as? DigestAudioItem, playingDigest.digest.id == digest.id {
// Don't think we need to do anything here
@ -179,9 +185,11 @@ struct FullScreenDigestView: View {
await viewModel.load(dataService: dataService, audioController: audioController)
}
}, label: { Text("Try again") })
.buttonStyle(RoundedRectButtonStyle(color: Color.blue, textColor: Color.white))
.buttonStyle(RoundedRectButtonStyle(color: Color.blue, textColor: Color.white))
Spacer()
}
} else if viewModel.isRunning {
jobRunningText
} else {
itemBody
}
@ -192,6 +200,19 @@ struct FullScreenDigestView: View {
await viewModel.load(dataService: dataService, audioController: audioController)
}
}
var jobRunningText: some View {
VStack {
Spacer()
Text("""
You've been added to the AI Digest demo. Your first issue should be ready soon.
When a new digest is ready the icon in the library header will change color.
You can close this window now.
""")
.padding(20)
Spacer()
}
}
var closeButton: some View {
Button(action: {
@ -218,7 +239,7 @@ struct FullScreenDigestView: View {
Spacer()
}
if let digest = viewModel.digest {
Text(digest.title)
Text(digest.title ?? "")
.font(Font.system(size: 17, weight: .semibold))
.lineSpacing(5)
.lineLimit(3)
@ -274,14 +295,14 @@ struct FullScreenDigestView: View {
.padding(.top, 20)
}
if let digest = viewModel.digest {
if let digest = viewModel.digest, let content = digest.content {
Text("Transcript")
.font(Font.system(size: 17, weight: .semibold))
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.top, 20)
VStack {
Markdown(digest.content)
Markdown(content)
.foregroundColor(Color.appGrayTextContrast)
}
.padding(15)

View File

@ -44,7 +44,7 @@ public struct DigestAudioItem: AudioItemProperties {
public init(digest: DigestResult, chapters: [DigestChapterData]) {
self.digest = digest
self.itemID = digest.id
self.title = digest.title
self.title = digest.title ?? "Omnivore digest"
self.chapters = chapters
self.startIndex = 0
@ -52,7 +52,7 @@ public struct DigestAudioItem: AudioItemProperties {
self.imageURL = nil
if let first = digest.speechFiles.first {
if let first = digest.speechFiles?.first {
self.language = first.language
self.byline = digest.byline
}
@ -1033,7 +1033,7 @@ public struct DigestAudioItem: AudioItemProperties {
}
func combineSpeechFiles(from digest: DigestResult) -> ([Utterance], Double) {
let allUtterances = digest.speechFiles.flatMap { $0.utterances }
let allUtterances = digest.speechFiles?.flatMap { $0.utterances } ?? []
var updatedUtterances: [Utterance] = []
var currentWordOffset = 0.0
@ -1053,7 +1053,7 @@ public struct DigestAudioItem: AudioItemProperties {
}
func downloadDigestItemSpeechFile(itemID: String, priority: DownloadPriority) async throws -> SpeechDocument? {
if let digestItem = itemAudioProperties as? DigestAudioItem, let firstFile = digestItem.digest.speechFiles.first {
if let digestItem = itemAudioProperties as? DigestAudioItem, let firstFile = digestItem.digest.speechFiles?.first {
let (utterances, wordCount) = combineSpeechFiles(from: digestItem.digest)
let document = SpeechDocument(

View File

@ -9,16 +9,16 @@ struct AITaskRequest: Decodable {
public struct DigestResult: Codable {
public let id: String
public let title: String
public let byline: String
public let content: String
public let description: String
public let urlsToAudio: [String]
public let chapters: [DigestChapter]
public let speechFiles: [SpeechDocument]
public let title: String?
public let byline: String?
public let content: String?
public let description: String?
public let urlsToAudio: [String]?
public let chapters: [DigestChapter]?
public let speechFiles: [SpeechDocument]?
public let jobState: String
public let createdAt: String
public let jobState: String?
public let createdAt: String?
}
public struct DigestChapter: Codable {
@ -169,9 +169,10 @@ extension DataService {
do {
let digest = try await networker.urlSession.performRequest(resource: resource)
let oldDigest = loadStoredDigest()
saveDigest(digest)
if digest.jobState == "SUCCEEDED" {
saveDigest(digest)
}
return digest
} catch {

View File

@ -40,7 +40,7 @@ public extension DataService {
try $0.setUserPersonalization(
input: InputObjects.SetUserPersonalizationInput(
digestConfig: OptionalArgument(
InputObjects.DigestConfigInput(channels: OptionalArgument([OptionalArgument("email")]))
InputObjects.DigestConfigInput(channels: OptionalArgument([OptionalArgument("push")]))
)
),
selection: selection