RTSDA-iOS/ViewModels/SermonBrowserViewModel.swift
2025-02-03 16:15:57 -05:00

149 lines
4.3 KiB
Swift

import Foundation
import AVKit
@MainActor
class SermonBrowserViewModel: ObservableObject {
@Published private(set) var sermons: [Sermon] = []
@Published private(set) var isLoading = false
@Published private(set) var error: Error?
@Published var selectedType: SermonType = .sermon
@Published var selectedYear: Int?
@Published var selectedMonth: Int?
let jellyfinService: JellyfinService
var organizedSermons: [Int: [Int: [Sermon]]] {
var filteredSermons = sermons.filter { $0.type == selectedType }
// Apply year filter if selected
if let selectedYear = selectedYear {
filteredSermons = filteredSermons.filter {
Calendar.current.component(.year, from: $0.date) == selectedYear
}
}
// Apply month filter if selected
if let selectedMonth = selectedMonth {
filteredSermons = filteredSermons.filter {
Calendar.current.component(.month, from: $0.date) == selectedMonth
}
}
return Dictionary(grouping: filteredSermons) { sermon in
Calendar.current.component(.year, from: sermon.date)
}.mapValues { yearSermons in
Dictionary(grouping: yearSermons) { sermon in
Calendar.current.component(.month, from: sermon.date)
}
}
}
var years: [Int] {
let filteredSermons = sermons.filter { $0.type == selectedType }
let allYears = Set(filteredSermons.map {
Calendar.current.component(.year, from: $0.date)
})
return Array(allYears).sorted(by: >)
}
func months(for year: Int) -> [Int] {
let yearSermons = sermons.filter {
$0.type == selectedType &&
Calendar.current.component(.year, from: $0.date) == year
}
return Array(Set(yearSermons.map {
Calendar.current.component(.month, from: $0.date)
})).sorted(by: >)
}
func sermons(for year: Int, month: Int) -> [Sermon] {
organizedSermons[year]?[month]?.sorted(by: { $0.date > $1.date }) ?? []
}
@MainActor
init(jellyfinService: JellyfinService) {
self.jellyfinService = jellyfinService
}
@MainActor
convenience init() {
self.init(jellyfinService: JellyfinService.shared)
}
@MainActor
func fetchSermons() async throws {
isLoading = true
error = nil
do {
sermons = try await jellyfinService.fetchSermons(type: .sermon)
if let firstYear = years.first {
selectedYear = firstYear
if let firstMonth = months(for: firstYear).first {
selectedMonth = firstMonth
}
}
} catch {
self.error = error
throw error
}
isLoading = false
}
func selectType(_ type: SermonType) {
selectedType = type
selectedYear = nil
selectedMonth = nil
if let firstYear = years.first {
selectedYear = firstYear
if let firstMonth = months(for: firstYear).first {
selectedMonth = firstMonth
}
}
}
func selectYear(_ year: Int?) {
selectedYear = year
selectedMonth = nil
if let year = year,
let firstMonth = months(for: year).first {
selectedMonth = firstMonth
}
}
func selectMonth(_ month: Int?) {
selectedMonth = month
}
@MainActor
func loadSermons() async {
isLoading = true
error = nil
do {
sermons = try await jellyfinService.fetchSermons(type: .sermon)
if let firstYear = years.first {
selectedYear = firstYear
if let firstMonth = months(for: firstYear).first {
selectedMonth = firstMonth
}
}
} catch {
self.error = error
}
isLoading = false
}
@MainActor
func requestPermissions() async {
let permissionsManager = PermissionsManager.shared
permissionsManager.requestLocationAccess()
}
}