RTSDA-iOS/Views/FilterSheet.swift
RTSDA 00679f927c docs: Update README for v2.0 release and fix git remote URL
- Comprehensive README update documenting v2.0 architectural changes
- Updated git remote to ssh://rockvilleav@git.rockvilletollandsda.church:10443/RTSDA/RTSDA-iOS.git
- Documented unified ChurchService and 60% code reduction
- Added new features: Home Feed, responsive reading, enhanced UI
- Corrected license information (GPL v3 with church content copyright)
- Updated build instructions and technical stack details
2025-08-16 18:41:51 -04:00

236 lines
9.7 KiB
Swift

import SwiftUI
struct FilterSheet: View {
let selectedTab: WatchView.WatchTab
@Binding var selectedSpeaker: String
@Binding var selectedDateRange: String
@Binding var selectedDuration: String
@Environment(\.dismiss) private var dismiss
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
@Environment(ChurchDataService.self) private var dataService
@State private var selectedYear: String = "All Time"
@State private var selectedMonth: String = "All Months"
private var availableSpeakers: [String] {
let currentContent = selectedTab == .sermons ? dataService.sermons : dataService.livestreamArchives
let cleanedSpeakers = currentContent.compactMap { sermon -> String? in
let speaker = sermon.speaker.trimmingCharacters(in: .whitespacesAndNewlines)
return speaker.isEmpty ? nil : speaker
}
let uniqueSpeakers = Set(cleanedSpeakers)
return ["All Speakers"] + Array(uniqueSpeakers).sorted()
}
private var availableYears: [String] {
var years = ["All Time"]
let calendar = Calendar.current
// Use proper date formatter for your date format: "August 02, 2025"
let formatter = DateFormatter()
formatter.dateFormat = "MMMM dd, yyyy"
formatter.locale = Locale(identifier: "en_US")
let currentContent = selectedTab == .sermons ? dataService.sermons : dataService.livestreamArchives
// Extract all unique years from content
var yearSet: Set<Int> = []
for item in currentContent {
guard let dateString = item.date,
!dateString.isEmpty,
let date = formatter.date(from: dateString) else { continue }
let year = calendar.component(.year, from: date)
yearSet.insert(year)
}
// Add years in descending order
let sortedYears = yearSet.sorted(by: >)
for year in sortedYears {
years.append(String(year))
}
return years
}
private var availableMonths: [String] {
guard selectedYear != "All Time", let targetYear = Int(selectedYear) else {
return ["All Months"]
}
var months = ["All Months"]
let calendar = Calendar.current
// Use proper date formatter for your date format: "August 02, 2025"
let formatter = DateFormatter()
formatter.dateFormat = "MMMM dd, yyyy"
formatter.locale = Locale(identifier: "en_US")
let currentContent = selectedTab == .sermons ? dataService.sermons : dataService.livestreamArchives
// Extract months for the selected year
var monthSet: Set<Int> = []
for item in currentContent {
guard let dateString = item.date,
!dateString.isEmpty,
let date = formatter.date(from: dateString) else { continue }
let year = calendar.component(.year, from: date)
let month = calendar.component(.month, from: date)
if year == targetYear {
monthSet.insert(month)
}
}
// Add months in descending order (most recent first)
let monthNames = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"]
let sortedMonths = monthSet.sorted(by: >)
for month in sortedMonths {
if month >= 1 && month <= 12 {
months.append(monthNames[month-1])
}
}
print("🔍 DEBUG: availableMonths for year \(targetYear): \(months)")
return months
}
private let durations = ["Any Duration", "Under 30 min", "30-60 min", "Over 60 min"]
var body: some View {
NavigationStack {
Form {
Section {
Text("Filter \(selectedTab.rawValue)")
.font(.headline)
.foregroundColor(.primary)
} header: {
EmptyView()
}
Section("Speaker") {
Picker("Speaker", selection: $selectedSpeaker) {
ForEach(availableSpeakers, id: \.self) { speaker in
Text(speaker).tag(speaker)
}
}
.pickerStyle(.menu)
}
Section("Date Range") {
Picker("Year", selection: $selectedYear) {
ForEach(availableYears, id: \.self) { year in
Text(year).tag(year)
}
}
.pickerStyle(.menu)
.onChange(of: selectedYear) { _, newYear in
// Don't auto-reset month when year changes during initialization
// Only reset if it's a user-initiated change
if selectedMonth != "All Months" && !availableMonths.contains(selectedMonth) {
selectedMonth = "All Months"
}
}
// Only show month picker if a specific year is selected
if selectedYear != "All Time" {
Picker("Month", selection: $selectedMonth) {
ForEach(availableMonths, id: \.self) { month in
Text(month).tag(month)
}
}
.pickerStyle(.menu)
}
}
Section("Duration") {
Picker("Duration", selection: $selectedDuration) {
ForEach(durations, id: \.self) { duration in
Text(duration).tag(duration)
}
}
.pickerStyle(.menu)
}
Section {
Button("Reset Filters") {
selectedSpeaker = "All Speakers"
selectedYear = "All Time"
selectedMonth = "All Months"
selectedDuration = "Any Duration"
}
.foregroundColor(.red)
}
}
.navigationTitle("Filters")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button("Cancel") {
dismiss()
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button("Apply") {
// Convert year/month selection to selectedDateRange format
if selectedYear == "All Time" {
selectedDateRange = "All Time"
} else if selectedMonth == "All Months" {
selectedDateRange = selectedYear
} else {
selectedDateRange = "\(selectedMonth) \(selectedYear)"
}
dismiss()
}
.fontWeight(.semibold)
.foregroundColor(Color(hex: "fb8b23"))
}
}
}
.presentationDetents([.medium, .large])
.presentationDragIndicator(.visible)
.onAppear {
// Initialize year/month from current selectedDateRange
print("🔍 DEBUG: Initializing filter sheet with selectedDateRange: '\(selectedDateRange)'")
if selectedDateRange == "All Time" {
selectedYear = "All Time"
selectedMonth = "All Months"
} else {
// Check if it's a year-only filter (e.g., "2024")
if let _ = Int(selectedDateRange) {
selectedYear = selectedDateRange
selectedMonth = "All Months"
print("🔍 DEBUG: Set year-only filter - Year: \(selectedYear), Month: \(selectedMonth)")
} else {
// It's a month-year filter (e.g., "January 2024")
let components = selectedDateRange.components(separatedBy: " ")
if components.count == 2 {
selectedYear = components[1]
selectedMonth = components[0]
print("🔍 DEBUG: Set month-year filter - Year: \(selectedYear), Month: \(selectedMonth)")
// Force a small delay to ensure availableMonths is computed before validation
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
if !availableMonths.contains(selectedMonth) {
print("🔍 DEBUG: Month '\(selectedMonth)' not found in available months, resetting")
selectedMonth = "All Months"
} else {
print("🔍 DEBUG: Month '\(selectedMonth)' validated successfully")
}
}
} else {
selectedYear = "All Time"
selectedMonth = "All Months"
print("🔍 DEBUG: Failed to parse, defaulting to All Time")
}
}
}
}
}
}