From 3d2881c7d0c5c6e649bd8c326caba6cfeb902ced Mon Sep 17 00:00:00 2001 From: Sean Molenaar Date: Sun, 26 Jan 2025 21:53:28 +0100 Subject: [PATCH] Rework filtering --- Fosdem.xcodeproj/project.pbxproj | 22 ++-- Fosdem/Info.plist | 4 +- Fosdem/Models/Event.swift | 2 +- Fosdem/Views/EventDetailView.swift | 15 ++- Fosdem/Views/EventListView.swift | 98 ----------------- Fosdem/Views/EventTypeIcon.swift | 3 + Fosdem/Views/ListItem.swift | 8 +- Fosdem/Views/ListSettings.swift | 64 ++++++++++- Fosdem/Views/Lists/AuthorEventList.swift | 34 ------ .../{TrackEventList.swift => EventList.swift} | 22 ++-- Fosdem/Views/Lists/EventListView.swift | 104 ++++++++++++++++++ Fosdem/Views/Lists/RoomEventList.swift | 34 ------ Localizable.xcstrings | 3 - 13 files changed, 206 insertions(+), 207 deletions(-) delete mode 100644 Fosdem/Views/EventListView.swift delete mode 100644 Fosdem/Views/Lists/AuthorEventList.swift rename Fosdem/Views/Lists/{TrackEventList.swift => EventList.swift} (62%) create mode 100644 Fosdem/Views/Lists/EventListView.swift delete mode 100644 Fosdem/Views/Lists/RoomEventList.swift diff --git a/Fosdem.xcodeproj/project.pbxproj b/Fosdem.xcodeproj/project.pbxproj index 61b3adb..c31069c 100644 --- a/Fosdem.xcodeproj/project.pbxproj +++ b/Fosdem.xcodeproj/project.pbxproj @@ -32,12 +32,10 @@ 925B0263298EB2A400AFA83D /* VideoPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 925B0262298EB2A400AFA83D /* VideoPlayer.swift */; }; 925F4A7D2B2863D8007E9D1D /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 925F4A7C2B285A70007E9D1D /* Localizable.xcstrings */; }; 926414702D4650CA001378EF /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9264146F2D4650C8001378EF /* Array.swift */; }; + 926414722D46BEE9001378EF /* EventList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 926414712D46BEE9001378EF /* EventList.swift */; }; 9268D79A298F251E0067A6B1 /* ListSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9268D799298F251E0067A6B1 /* ListSettings.swift */; }; 92775AC22CFF7FEB00D44236 /* SectionedQuery in Frameworks */ = {isa = PBXBuildFile; productRef = 92775AC12CFF7FEB00D44236 /* SectionedQuery */; }; 92775AC52CFF880500D44236 /* BookmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92775AC42CFF87FD00D44236 /* BookmarkList.swift */; }; - 92775AC72CFF88BF00D44236 /* AuthorEventList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92775AC62CFF88BF00D44236 /* AuthorEventList.swift */; }; - 92775AC92CFF88F800D44236 /* TrackEventList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92775AC82CFF88F800D44236 /* TrackEventList.swift */; }; - 92775ACB2CFF8A9A00D44236 /* RoomEventList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92775ACA2CFF8A9A00D44236 /* RoomEventList.swift */; }; 9290384C2C9613FD002201FC /* ScheduleFetchingActor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9290384B2C9613F6002201FC /* ScheduleFetchingActor.swift */; }; 92B987FC2981CD10007574EB /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92B987FB2981CD10007574EB /* AboutView.swift */; }; 92BB58562B5FB84400C54292 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92BB58552B5FB84400C54292 /* SettingsView.swift */; }; @@ -101,11 +99,9 @@ 925B0262298EB2A400AFA83D /* VideoPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayer.swift; sourceTree = ""; }; 925F4A7C2B285A70007E9D1D /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; 9264146F2D4650C8001378EF /* Array.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Array.swift; sourceTree = ""; }; + 926414712D46BEE9001378EF /* EventList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventList.swift; sourceTree = ""; }; 9268D799298F251E0067A6B1 /* ListSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListSettings.swift; sourceTree = ""; }; 92775AC42CFF87FD00D44236 /* BookmarkList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkList.swift; sourceTree = ""; }; - 92775AC62CFF88BF00D44236 /* AuthorEventList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthorEventList.swift; sourceTree = ""; }; - 92775AC82CFF88F800D44236 /* TrackEventList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrackEventList.swift; sourceTree = ""; }; - 92775ACA2CFF8A9A00D44236 /* RoomEventList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomEventList.swift; sourceTree = ""; }; 9290384B2C9613F6002201FC /* ScheduleFetchingActor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScheduleFetchingActor.swift; sourceTree = ""; }; 92A2BDF92948CC5E0034864F /* FosdemTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = FosdemTests.xctestplan; path = Fosdem.xcodeproj/FosdemTests.xctestplan; sourceTree = ""; }; 92A57B392988FD1C00C0BB78 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; @@ -181,7 +177,6 @@ children = ( 92775AC32CFF87F500D44236 /* Lists */, 92BB58552B5FB84400C54292 /* SettingsView.swift */, - 92CE31B028FC4A940073813E /* EventListView.swift */, 92077D5028FF01C600BF8A03 /* EventDetailView.swift */, 92D9E7B9291D95E1007D203D /* EventDetailHeader.swift */, 924E15C229238AA5005A8EA2 /* ListItem.swift */, @@ -255,11 +250,10 @@ 92775AC32CFF87F500D44236 /* Lists */ = { isa = PBXGroup; children = ( + 92CE31B028FC4A940073813E /* EventListView.swift */, 92775AC42CFF87FD00D44236 /* BookmarkList.swift */, - 92775AC62CFF88BF00D44236 /* AuthorEventList.swift */, - 92775AC82CFF88F800D44236 /* TrackEventList.swift */, + 926414712D46BEE9001378EF /* EventList.swift */, 920085652D42F2D70082719F /* ListStatusOverlay.swift */, - 92775ACA2CFF8A9A00D44236 /* RoomEventList.swift */, ); path = Lists; sourceTree = ""; @@ -451,8 +445,8 @@ 14D277192205D07200740042 /* AppDelegate.swift in Sources */, 146A86792206ED84008A61AD /* Track.swift in Sources */, 92775AC52CFF880500D44236 /* BookmarkList.swift in Sources */, + 926414722D46BEE9001378EF /* EventList.swift in Sources */, 925321602925716A004C7E5C /* EventUserInfo.swift in Sources */, - 92775ACB2CFF8A9A00D44236 /* RoomEventList.swift in Sources */, 920085662D42F2D70082719F /* ListStatusOverlay.swift in Sources */, 142A8742222473A40034F6D7 /* UIColor+hexstring.swift in Sources */, 92CE31AF28FC49DC0073813E /* SettingsHelper.swift in Sources */, @@ -468,12 +462,10 @@ 142A873D2224651F0034F6D7 /* Hash.swift in Sources */, 926414702D4650CA001378EF /* Array.swift in Sources */, 924E15BE2922CCA9005A8EA2 /* RoomState.swift in Sources */, - 92775AC92CFF88F800D44236 /* TrackEventList.swift in Sources */, 146A866F2205EFE9008A61AD /* Room.swift in Sources */, 146A86742205EFE9008A61AD /* Event.swift in Sources */, 146A86702205EFE9008A61AD /* Person.swift in Sources */, 92BD1D302B5C34F100DB8FC1 /* EventTypeColor.swift in Sources */, - 92775AC72CFF88BF00D44236 /* AuthorEventList.swift in Sources */, 14D2774C2205D19D00740042 /* RemoteScheduleFetcher.swift in Sources */, 925B0261298EAE0E00AFA83D /* LiveIcon.swift in Sources */, 92BB58562B5FB84400C54292 /* SettingsView.swift in Sources */, @@ -671,7 +663,7 @@ "@executable_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 14.6; - MARKETING_VERSION = 1.3.0; + MARKETING_VERSION = 1.4.0; PRODUCT_BUNDLE_IDENTIFIER = eu.seanmolenaar.Fosdem; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; @@ -701,7 +693,7 @@ "@executable_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 14.6; - MARKETING_VERSION = 1.3.0; + MARKETING_VERSION = 1.4.0; PRODUCT_BUNDLE_IDENTIFIER = eu.seanmolenaar.Fosdem; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; diff --git a/Fosdem/Info.plist b/Fosdem/Info.plist index 5d4a2c2..c4e13eb 100644 --- a/Fosdem/Info.plist +++ b/Fosdem/Info.plist @@ -15,11 +15,13 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.3 + 1.4.0 CFBundleVersion 1 ITSAppUsesNonExemptEncryption + LSApplicationCategoryType + public.app-category.reference LSRequiresIPhoneOS UIBackgroundModes diff --git a/Fosdem/Models/Event.swift b/Fosdem/Models/Event.swift index b92a051..934cf6c 100644 --- a/Fosdem/Models/Event.swift +++ b/Fosdem/Models/Event.swift @@ -24,7 +24,7 @@ public class Event { public var lastUpdated: Date = Date() public var room: Room - public var track: Track? + public var track: Track! public var type: EventType? public var userInfo: EventUserInfo? diff --git a/Fosdem/Views/EventDetailView.swift b/Fosdem/Views/EventDetailView.swift index c173648..ba1e0a8 100644 --- a/Fosdem/Views/EventDetailView.swift +++ b/Fosdem/Views/EventDetailView.swift @@ -114,12 +114,11 @@ struct EventDetailView: View { ShareLink("Share web link", item: event.getPublicLink(), message: Text(event.title)) } ToolbarItem(placement: .primaryAction) { - Toggle(isOn: $event.isFavourite, label: { - Label("Favorite", - systemImage: event.userInfo!.favorite ? "bookmark.fill" : "bookmark") - .backgroundStyle(.clear) - }).onTapGesture(count: 1, perform: { - debugPrint(event.userInfo!.favorite) + Button(action: { + event.isFavourite.toggle() + if !event.isFavourite { + return + } if event.start.timeIntervalSinceNow <= 0 { return } @@ -133,6 +132,10 @@ struct EventDetailView: View { UNUserNotificationCenter.current() .removePendingNotificationRequests(withIdentifiers: [event.userInfo!.notificationUUID!.uuidString]) + }, label: { + Label("Favorite", + systemImage: event.userInfo!.favorite ? "bookmark.fill" : "bookmark") + .backgroundStyle(.clear) }) } } diff --git a/Fosdem/Views/EventListView.swift b/Fosdem/Views/EventListView.swift deleted file mode 100644 index 43d3622..0000000 --- a/Fosdem/Views/EventListView.swift +++ /dev/null @@ -1,98 +0,0 @@ -// -// EventListView.swift -// Fosdem -// -// Created by Sean Molenaar on 16/10/2022. -// Copyright © 2022 Sean Molenaar. All rights reserved. -// - -import SwiftUI -import SwiftData -import SectionedQuery - -struct EventListView: View { - @State private var query = "" - @State private var isSheetPresented: Bool = false - @State private var isSearchPresented: Bool = false - - @State private var onlyBookmarks: Bool - @State private var onlyFuture: Bool - - @StateObject private var predicate = ListSettings() - - @ModelActor public actor ScheduleFetchingActor {} - @Environment(\.modelContext) var modelContext - - init() { - self.onlyBookmarks = UserDefaults.standard.bool(forKey: "onlyBookmarks") - self.onlyFuture = UserDefaults.standard.bool(forKey: "onlyFuture") - } - - var body: some View { - NavigationStack { - TabView { - TrackEventList(terms: predicate).tabItem { - Label("Tracks", systemImage: "road.lanes") - } - AuthorEventList(terms: predicate).tabItem { - Label("People", systemImage: "person.3") - } - RoomEventList(terms: predicate).tabItem { - Label("Rooms", systemImage: "door.left.hand.open") - } - BookmarkList(terms: predicate).tabItem { - Label("My events", systemImage: "person.circle") - } - }.onChange(of: onlyFuture) { value, _ in - self.predicate.onlyFuture = value - }.searchable( - text: $query, - isPresented: $isSearchPresented - ).navigationDestination(for: Event.self, destination: { event in - EventDetailView(event) - }) - .toolbar { - ToolbarItemGroup { - Button(action: { - onlyBookmarks.toggle() - predicate.onlyBookmarks = onlyBookmarks - }, label: { - Label("Bookmarks only", systemImage: onlyBookmarks ? "bookmark.fill" : "bookmark") - }) - Button(action: { - onlyFuture.toggle() - predicate.onlyFuture = onlyFuture - }, label: { - Label("Future events only", systemImage: onlyFuture ? "clock.fill" : "clock") - }) - } label: { - Label("Filters", systemImage: "line.3.horizontal.decrease.circle") - } - ToolbarItem { - Button(action: { - isSheetPresented.toggle() - }, label: { - Label("Filter lists", systemImage: "slider.horizontal.2.square.on.square") - }) - } - } - .sheet(isPresented: $isSheetPresented, content: { - SettingsView(localTime: predicate.localTime, year: predicate.year) - .presentationDetents([.medium]) - }) - .navigationTitle("Fosdem \(predicate.year)") - .refreshable { - Task { - await RoomStatusFetcher.fetchRoomStatus() - await RemoteScheduleFetcher.fetchSchedule() - } - } - } - } -} - -struct EventListView_Previews: PreviewProvider { - static var previews: some View { - EventListView() - } -} diff --git a/Fosdem/Views/EventTypeIcon.swift b/Fosdem/Views/EventTypeIcon.swift index 589ddae..1125a9c 100644 --- a/Fosdem/Views/EventTypeIcon.swift +++ b/Fosdem/Views/EventTypeIcon.swift @@ -15,6 +15,7 @@ enum EventTypeIcon: String { case maintrack = "road.lanes" case certification = "checkmark.seal" case bof = "bird" + case junior = "figure.and.child.holdinghands" case none = "questionmark.circle" static func getIconFor(_ string: String) -> EventTypeIcon { @@ -33,6 +34,8 @@ enum EventTypeIcon: String { return .bof case "certification": return .certification + case "junior": + return .junior default: return .none } diff --git a/Fosdem/Views/ListItem.swift b/Fosdem/Views/ListItem.swift index c5f2b17..51da89a 100644 --- a/Fosdem/Views/ListItem.swift +++ b/Fosdem/Views/ListItem.swift @@ -61,9 +61,11 @@ struct ListItem: View { } ShareLink("Share web link", item: event.getPublicLink(), message: Text(event.title)) }.swipeActions { - Button(action: { event.userInfo?.favorite.toggle() }, label: { - Label("Favorite", systemImage: event.userInfo?.favorite ?? false ? "star.fill" : "star") - }).tint(.orange) + Button(action: { + event.userInfo?.favorite.toggle() + }, label: { + Label("Favorite", systemImage: (event.userInfo?.favorite ?? false) ? "star.slash" : "star") + }).tint((event.userInfo?.favorite ?? false) ? .blue : .orange) } .onAppear { event.userInfo?.lastSeen = Date() diff --git a/Fosdem/Views/ListSettings.swift b/Fosdem/Views/ListSettings.swift index 5306956..e5d2cbb 100644 --- a/Fosdem/Views/ListSettings.swift +++ b/Fosdem/Views/ListSettings.swift @@ -41,19 +41,18 @@ class ListSettings: ObservableObject { predicate = basePredicate } } + if onlyFuture { - let now = Date() - let basePredicate = #Predicate { $0.end > now } + let basePredicate = ListSettings.futurePredicate() if predicate != nil { predicate = #Predicate { predicate!.evaluate($0) && basePredicate.evaluate($0) } } else { predicate = basePredicate } } + if let query = query, !query.isEmpty { - let basePredicate = #Predicate { - $0.title.localizedStandardContains(query) || $0.trackName.localizedStandardContains(query) - } + let basePredicate = ListSettings.searchPredicate(query, type: type) if predicate != nil { predicate = #Predicate { predicate!.evaluate($0) && basePredicate.evaluate($0) } } else { @@ -63,10 +62,65 @@ class ListSettings: ObservableObject { return predicate } + + private static func futurePredicate() -> Predicate { + let now = Date() + return #Predicate { $0.end > now } + } + + private static func searchPredicate(_ searchText: String, type: ListPredicateType) -> Predicate { + var predicate = #Predicate { $0.title.localizedStandardContains(searchText) } + switch type { + case .track: + predicate = #Predicate { + $0.title.localizedStandardContains(searchText) + } + case .person: + predicate = #Predicate { + $0.title.localizedStandardContains(searchText) || + !$0.authors.filter { author in + author.name.localizedStandardContains(searchText) + }.isEmpty + } + case .room: + predicate = #Predicate { + $0.title.localizedStandardContains(searchText) || + $0.room.name.localizedStandardContains(searchText) + } + } + + return predicate + } } enum ListPredicateType { case person case room case track + + static var all: [ListPredicateType] { + return [.track, .person, .room] + } + + static func getName(_ type: ListPredicateType) -> String { + switch type { + case .person: + return "People" + case .room: + return "Rooms" + case .track: + return "Tracks" + } + } + + static func getIcon(_ type: ListPredicateType) -> String { + switch type { + case .person: + return "person" + case .room: + return "door.left.hand.open" + case .track: + return "road.lanes" + } + } } diff --git a/Fosdem/Views/Lists/AuthorEventList.swift b/Fosdem/Views/Lists/AuthorEventList.swift deleted file mode 100644 index acc4f8b..0000000 --- a/Fosdem/Views/Lists/AuthorEventList.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// AuthorEventList.swift -// Fosdem -// -// Created by Sean Molenaar on 03/12/2024. -// Copyright © 2024 Sean Molenaar. All rights reserved. -// -import SwiftData -import SwiftUI -import SectionedQuery - -struct AuthorEventList: View { - @SectionedQuery private var events: SectionedResults - - var terms: ListSettings - - init(terms: ListSettings) { - self.terms = terms - _events = SectionedQuery(\.authorName, - filter: terms.predicate(.person), - sort: [SortDescriptor(\.start, order: .forward)]) - } - - var body: some View { - List(events) { section in - Section(header: Text("\(section.id)")) { - ForEach(section) { event in - NavigationLink(value: event, label: { ListItem(event, bookmarkEmphasis: !terms.onlyBookmarks) }) - } - } - }.overlay(ListStatusOverlay(empty: events.isEmpty, terms: terms)) - .listStyle(.plain) - } -} diff --git a/Fosdem/Views/Lists/TrackEventList.swift b/Fosdem/Views/Lists/EventList.swift similarity index 62% rename from Fosdem/Views/Lists/TrackEventList.swift rename to Fosdem/Views/Lists/EventList.swift index e6ffd61..80d23df 100644 --- a/Fosdem/Views/Lists/TrackEventList.swift +++ b/Fosdem/Views/Lists/EventList.swift @@ -10,25 +10,33 @@ import SwiftData import SwiftUI import SectionedQuery -struct TrackEventList: View { +struct EventList: View { @SectionedQuery private var events: SectionedResults let terms: ListSettings - init(terms: ListSettings) { + init(_ type: ListPredicateType, terms: ListSettings) { + let key = switch type { + case .room: + \Event.roomName + case .person: + \Event.authorName + case .track: + \Event.trackName + } self.terms = terms - _events = SectionedQuery(\.trackName, - filter: terms.predicate(.track), + _events = SectionedQuery(key, + filter: terms.predicate(type), sort: [SortDescriptor(\.start, order: .forward)]) } var body: some View { - List(events) { section in + List(events, id: \.id) { section in Section(header: Text("\(section.id)")) { - ForEach(section) { event in + ForEach(section, id: \.id) { event in NavigationLink(value: event, label: { - ListItem(event, bookmarkEmphasis: !terms.onlyBookmarks) + ListItem(event, bookmarkEmphasis: !terms.onlyBookmarks).id(event.id) }) } } diff --git a/Fosdem/Views/Lists/EventListView.swift b/Fosdem/Views/Lists/EventListView.swift new file mode 100644 index 0000000..3950b2f --- /dev/null +++ b/Fosdem/Views/Lists/EventListView.swift @@ -0,0 +1,104 @@ +// +// EventListView.swift +// Fosdem +// +// Created by Sean Molenaar on 16/10/2022. +// Copyright © 2022 Sean Molenaar. All rights reserved. +// + +import SwiftUI +import SwiftData +import SectionedQuery + +struct EventListView: View { + @State private var query = "" + @State private var isSheetPresented: Bool = false + @State private var isSearchPresented: Bool = false + + @State private var onlyBookmarks: Bool + @State private var onlyFuture: Bool + @State private var list: ListPredicateType = .track + + @StateObject private var predicate = ListSettings() + + @ModelActor public actor ScheduleFetchingActor {} + @Environment(\.modelContext) var modelContext + + init() { + self.onlyBookmarks = UserDefaults.standard.bool(forKey: "onlyBookmarks") + self.onlyFuture = UserDefaults.standard.bool(forKey: "onlyFuture") + } + + var body: some View { + NavigationStack { + EventList(self.list, terms: predicate) + .onChange(of: query) { value, _ in + predicate.query = value + }.onChange(of: isSearchPresented) { _, value in + if value { return } + predicate.query = nil + }.searchable(text: $query, isPresented: $isSearchPresented) + .navigationDestination(for: Event.self, destination: { event in + EventDetailView(event) + }).toolbar { + ToolbarTitleMenu { + ForEach(ListPredicateType.all, id: \.self) { type in + Button { + self.list = type + } label: { + Label(ListPredicateType.getName(type), systemImage: ListPredicateType.getIcon(type)) + .foregroundStyle(self.list == type ? .primary : .secondary) + } + } + } + } + .toolbar { + ToolbarItem(placement: .topBarTrailing) { + Menu { + Button(action: { + onlyBookmarks.toggle() + predicate.onlyBookmarks = onlyBookmarks + }, label: { + Label("Bookmarks only", systemImage: onlyBookmarks ? "bookmark.fill" : "bookmark") + }) + Button(action: { + onlyFuture.toggle() + predicate.onlyFuture = onlyFuture + }, label: { + Label("Future events only", systemImage: onlyFuture ? "clock.fill" : "clock") + }) + } label: { + Label("Filters", + systemImage: predicate.isFiltering ? + "line.3.horizontal.decrease.circle.fill" : "line.3.horizontal.decrease.circle") + } + } + ToolbarItem(placement: .topBarTrailing) { + Button(action: { + isSheetPresented.toggle() + }, label: { + Label("Settings", systemImage: "gear") + }) + } + } + .sheet(isPresented: $isSheetPresented, content: { + SettingsView(localTime: predicate.localTime, year: predicate.year) + .presentationDetents([.medium]) + }) + .navigationTitle(ListPredicateType.getName(list)) + .toolbarTitleDisplayMode(.inline) + .refreshable { + Task { + await RoomStatusFetcher.fetchRoomStatus() + await RemoteScheduleFetcher.fetchSchedule() + } + } + } + } +} + +struct EventListView_Previews: PreviewProvider { + static var previews: some View { + EventListView() + } +} diff --git a/Fosdem/Views/Lists/RoomEventList.swift b/Fosdem/Views/Lists/RoomEventList.swift deleted file mode 100644 index 1393a43..0000000 --- a/Fosdem/Views/Lists/RoomEventList.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// RoomEventList.swift -// Fosdem -// -// Created by Sean Molenaar on 03/12/2024. -// Copyright © 2024 Sean Molenaar. All rights reserved. -// -import SwiftData -import SwiftUI -import SectionedQuery - -struct RoomEventList: View { - @SectionedQuery private var events: SectionedResults - - var terms: ListSettings - - init(terms: ListSettings) { - self.terms = terms - _events = SectionedQuery(\.roomName, - filter: terms.predicate(.room), - sort: [SortDescriptor(\.start, order: .forward)]) - } - - var body: some View { - List(events) { section in - Section(header: Text("\(section.id)")) { - ForEach(section) { event in - NavigationLink(value: event, label: { ListItem(event, bookmarkEmphasis: !terms.onlyBookmarks) }) - } - } - }.overlay(ListStatusOverlay(empty: events.isEmpty, terms: terms)) - .listStyle(.plain) - } -} diff --git a/Localizable.xcstrings b/Localizable.xcstrings index 649ca4d..00b4dbf 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -72,9 +72,6 @@ } } } - }, - "Filter lists" : { - }, "Filters" : {