diff --git a/WorterBuch/FlashcardHomeView.swift b/WorterBuch/FlashcardHomeView.swift index 4ecfaea..6086241 100644 --- a/WorterBuch/FlashcardHomeView.swift +++ b/WorterBuch/FlashcardHomeView.swift @@ -22,6 +22,8 @@ struct FlashcardHomeView: View { @State private var showingSession = false @State private var showingStats = false @State private var session: FlashcardSession? + @State private var currentTime = Date() + @State private var timer: Timer? private var statistics: FlashcardStatistics { let tags = showAllTags ? nil : Array(selectedTagObjects) @@ -40,6 +42,11 @@ struct FlashcardHomeView: View { return SpacedRepetitionEngine.getDueCards(in: viewContext, tags: tags) } + private var nextCardDate: Date? { + let tags = showAllTags ? nil : Array(selectedTagObjects) + return SpacedRepetitionEngine.getNextCardDate(in: viewContext, tags: tags) + } + var body: some View { NavigationView { ScrollView { @@ -183,16 +190,30 @@ struct FlashcardHomeView: View { .font(.title3) .fontWeight(.semibold) - Text("No cards due for review right now") - .font(.caption) - .foregroundColor(.secondary) - - if statistics.totalCards == 0 { + if let nextDate = nextCardDate, nextDate > currentTime { + Text("Next card available in") + .font(.caption) + .foregroundColor(.secondary) + + Text(timeUntilNextCard(nextDate: nextDate)) + .font(.title2) + .fontWeight(.bold) + .foregroundColor(.blue) + .monospacedDigit() + } else if statistics.totalCards == 0 { + Text("No cards due for review right now") + .font(.caption) + .foregroundColor(.secondary) + Text("💡 Tip: Cards need both German word AND English translation to appear in flashcards") .font(.caption2) .foregroundColor(.orange) .multilineTextAlignment(.center) .padding(.top, 4) + } else { + Text("No cards due for review right now") + .font(.caption) + .foregroundColor(.secondary) } } .frame(maxWidth: .infinity) @@ -218,6 +239,12 @@ struct FlashcardHomeView: View { } } .navigationTitle("Flashcards") + .onAppear { + startTimer() + } + .onDisappear { + stopTimer() + } .sheet(isPresented: $showingSession) { if let session = session { FlashcardSessionView(session: session) @@ -244,6 +271,35 @@ struct FlashcardHomeView: View { session = FlashcardSession(cards: cards, context: viewContext) showingSession = true } + + private func startTimer() { + timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in + currentTime = Date() + } + } + + private func stopTimer() { + timer?.invalidate() + timer = nil + } + + private func timeUntilNextCard(nextDate: Date) -> String { + let timeInterval = nextDate.timeIntervalSince(currentTime) + + guard timeInterval > 0 else { + return "Available now!" + } + + let hours = Int(timeInterval) / 3600 + let minutes = (Int(timeInterval) % 3600) / 60 + let seconds = Int(timeInterval) % 60 + + if hours > 0 { + return String(format: "%02d:%02d:%02d", hours, minutes, seconds) + } else { + return String(format: "%02d:%02d", minutes, seconds) + } + } } // MARK: - Stat Card diff --git a/WorterBuch/SpacedRepetitionEngine.swift b/WorterBuch/SpacedRepetitionEngine.swift index ca9542f..8b69abe 100644 --- a/WorterBuch/SpacedRepetitionEngine.swift +++ b/WorterBuch/SpacedRepetitionEngine.swift @@ -163,6 +163,34 @@ class SpacedRepetitionEngine { } } + /// Get the date when the next card will become available + static func getNextCardDate( + in context: NSManagedObjectContext, + tags: [Tag]? = nil + ) -> Date? { + let fetchRequest: NSFetchRequest = VocabularyEntry.fetchRequest() + + // Filter by tags if provided + if let tags = tags, !tags.isEmpty { + fetchRequest.predicate = NSPredicate(format: "ANY tags IN %@", tags) + } + + do { + let allEntries = try context.fetch(fetchRequest) + + // Get all flashcard-ready entries that are NOT yet due + let futureCards = allEntries.filter { entry in + entry.isFlashcardReady && !entry.isDueForReview && entry.nextReviewDate != nil + } + + // Find the earliest next review date + return futureCards.compactMap { $0.nextReviewDate }.min() + } catch { + print("Error fetching next card date: \(error)") + return nil + } + } + /// Get overall statistics for flashcards static func getStatistics( in context: NSManagedObjectContext,