From eadf01bead4d28b01f299c0757f065b76d4c063b Mon Sep 17 00:00:00 2001 From: Sean Molenaar Date: Mon, 27 Jan 2025 16:40:44 +0100 Subject: [PATCH] Rework list --- Fosdem.xcodeproj/project.pbxproj | 28 ++++-- Fosdem/Views/Lists/EventList.swift | 44 ++++++---- Fosdem/Views/Lists/EventListView.swift | 23 ++--- Localizable.xcstrings | 114 +++++++++++++++++++------ Package.resolved | 29 ++++++- Package.swift | 10 ++- 6 files changed, 180 insertions(+), 68 deletions(-) diff --git a/Fosdem.xcodeproj/project.pbxproj b/Fosdem.xcodeproj/project.pbxproj index c31069c..ec41c0d 100644 --- a/Fosdem.xcodeproj/project.pbxproj +++ b/Fosdem.xcodeproj/project.pbxproj @@ -34,7 +34,6 @@ 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 */; }; 9290384C2C9613FD002201FC /* ScheduleFetchingActor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9290384B2C9613F6002201FC /* ScheduleFetchingActor.swift */; }; 92B987FC2981CD10007574EB /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92B987FB2981CD10007574EB /* AboutView.swift */; }; @@ -48,6 +47,7 @@ 92CE31B128FC4A940073813E /* EventListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92CE31B028FC4A940073813E /* EventListView.swift */; }; 92D9E7B8291D7B9B007D203D /* HTMLFormattedText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D9E7B7291D7B9B007D203D /* HTMLFormattedText.swift */; }; 92D9E7BA291D95E1007D203D /* EventDetailHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D9E7B9291D95E1007D203D /* EventDetailHeader.swift */; }; + 92EF5F422D47D8B50050C67D /* SectionedQuery in Frameworks */ = {isa = PBXBuildFile; productRef = 92EF5F412D47D8B50050C67D /* SectionedQuery */; }; 92F70AA02922B49A000BE6CB /* UrlHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92F70A9F2922B49A000BE6CB /* UrlHelper.swift */; }; /* End PBXBuildFile section */ @@ -124,7 +124,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 92775AC22CFF7FEB00D44236 /* SectionedQuery in Frameworks */, + 92EF5F422D47D8B50050C67D /* SectionedQuery in Frameworks */, 9203845F2B5B0A2100B793AA /* PentabarfKit in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -287,12 +287,13 @@ buildRules = ( ); dependencies = ( + 92E5C1112D4817250017CEE0 /* PBXTargetDependency */, 92FC930A2B5C2DA100C2D13D /* PBXTargetDependency */, ); name = Fosdem; packageProductDependencies = ( 9203845E2B5B0A2100B793AA /* PentabarfKit */, - 92775AC12CFF7FEB00D44236 /* SectionedQuery */, + 92EF5F412D47D8B50050C67D /* SectionedQuery */, ); productName = Fosdem; productReference = 14D277152205D07200740042 /* Fosdem.app */; @@ -373,7 +374,7 @@ mainGroup = 14D2770C2205D07200740042; packageReferences = ( 9203845D2B5B0A2100B793AA /* XCRemoteSwiftPackageReference "PentabarfKit" */, - 92775AC02CFF7F1F00D44236 /* XCRemoteSwiftPackageReference "swiftdata-sectionedquery" */, + 92EF5F402D47D8B50050C67D /* XCRemoteSwiftPackageReference "swiftdata-sectionedquery" */, ); preferredProjectObjectVersion = 77; productRefGroup = 14D277162205D07200740042 /* Products */; @@ -508,6 +509,10 @@ target = 14D277142205D07200740042 /* Fosdem */; targetProxy = 14D2773A2205D07500740042 /* PBXContainerItemProxy */; }; + 92E5C1112D4817250017CEE0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + productRef = 92E5C1102D4817250017CEE0 /* SectionedQuery */; + }; 92FC930A2B5C2DA100C2D13D /* PBXTargetDependency */ = { isa = PBXTargetDependency; productRef = 92FC93092B5C2DA100C2D13D /* PentabarfKit */; @@ -844,12 +849,12 @@ kind = branch; }; }; - 92775AC02CFF7F1F00D44236 /* XCRemoteSwiftPackageReference "swiftdata-sectionedquery" */ = { + 92EF5F402D47D8B50050C67D /* XCRemoteSwiftPackageReference "swiftdata-sectionedquery" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/beechtom/swiftdata-sectionedquery"; + repositoryURL = "https://github.com/Whiffer/swiftdata-sectionedquery"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 1.2.0; + minimumVersion = 1.0.3; }; }; /* End XCRemoteSwiftPackageReference section */ @@ -860,9 +865,14 @@ package = 9203845D2B5B0A2100B793AA /* XCRemoteSwiftPackageReference "PentabarfKit" */; productName = PentabarfKit; }; - 92775AC12CFF7FEB00D44236 /* SectionedQuery */ = { + 92E5C1102D4817250017CEE0 /* SectionedQuery */ = { + isa = XCSwiftPackageProductDependency; + package = 92EF5F402D47D8B50050C67D /* XCRemoteSwiftPackageReference "swiftdata-sectionedquery" */; + productName = SectionedQuery; + }; + 92EF5F412D47D8B50050C67D /* SectionedQuery */ = { isa = XCSwiftPackageProductDependency; - package = 92775AC02CFF7F1F00D44236 /* XCRemoteSwiftPackageReference "swiftdata-sectionedquery" */; + package = 92EF5F402D47D8B50050C67D /* XCRemoteSwiftPackageReference "swiftdata-sectionedquery" */; productName = SectionedQuery; }; 92FC93092B5C2DA100C2D13D /* PentabarfKit */ = { diff --git a/Fosdem/Views/Lists/EventList.swift b/Fosdem/Views/Lists/EventList.swift index 80d23df..43f85bc 100644 --- a/Fosdem/Views/Lists/EventList.swift +++ b/Fosdem/Views/Lists/EventList.swift @@ -11,36 +11,44 @@ import SwiftUI import SectionedQuery struct EventList: View { - @SectionedQuery private var events: SectionedResults + @SectionedQuery private var sections: SectionedResults - let terms: ListSettings + private let terms: ListSettings init(_ type: ListPredicateType, terms: ListSettings) { + self.terms = terms + let key = switch type { case .room: - \Event.roomName + \Event.room.name case .person: - \Event.authorName + \Event.authors.first!.name case .track: - \Event.trackName + \Event.track!.name } - self.terms = terms - _events = SectionedQuery(key, - filter: terms.predicate(type), - sort: [SortDescriptor(\.start, order: .forward)]) + + _sections = SectionedQuery(sectionIdentifier: key, + sortDescriptors: [ + SortDescriptor(key, order: .forward), + SortDescriptor(\Event.start, order: .forward) + ], + predicate: terms.predicate(type)) } var body: some View { - List(events, id: \.id) { section in - Section(header: Text("\(section.id)")) { - ForEach(section, id: \.id) { event in - NavigationLink(value: event, - label: { - ListItem(event, bookmarkEmphasis: !terms.onlyBookmarks).id(event.id) - }) + List { + ForEach(sections) { section in + Section(header: Text(section.id)) { + ForEach(section, id: \.id) { event in + NavigationLink(value: event, + label: { + ListItem(event, bookmarkEmphasis: !terms.onlyBookmarks) + .id(event.id) + }) + } } } - }.overlay(ListStatusOverlay(empty: events.isEmpty, terms: terms)) - .listStyle(.plain) + }.overlay(ListStatusOverlay(empty: sections.isEmpty, terms: terms)) + .listStyle(.plain) } } diff --git a/Fosdem/Views/Lists/EventListView.swift b/Fosdem/Views/Lists/EventListView.swift index 3950b2f..72030d0 100644 --- a/Fosdem/Views/Lists/EventListView.swift +++ b/Fosdem/Views/Lists/EventListView.swift @@ -14,10 +14,11 @@ struct EventListView: View { @State private var query = "" @State private var isSheetPresented: Bool = false @State private var isSearchPresented: Bool = false + @State private var selectedEvent: Event? @State private var onlyBookmarks: Bool @State private var onlyFuture: Bool - @State private var list: ListPredicateType = .track + @State private var listType: ListPredicateType = .track @StateObject private var predicate = ListSettings() @@ -29,25 +30,27 @@ struct EventListView: View { self.onlyFuture = UserDefaults.standard.bool(forKey: "onlyFuture") } + var eventList: EventList { + EventList(listType, terms: predicate) + } + var body: some View { NavigationStack { - EventList(self.list, terms: predicate) + self.eventList .onChange(of: query) { value, _ in predicate.query = value }.onChange(of: isSearchPresented) { _, value in if value { return } predicate.query = nil - }.searchable(text: $query, isPresented: $isSearchPresented) + } + .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: { + Picker("List grouping", selection: $listType) { + ForEach(ListPredicateType.all, id: \.self) { type in Label(ListPredicateType.getName(type), systemImage: ListPredicateType.getIcon(type)) - .foregroundStyle(self.list == type ? .primary : .secondary) } } } @@ -85,9 +88,9 @@ struct EventListView: View { SettingsView(localTime: predicate.localTime, year: predicate.year) .presentationDetents([.medium]) }) - .navigationTitle(ListPredicateType.getName(list)) + .navigationTitle(ListPredicateType.getName(listType)) .toolbarTitleDisplayMode(.inline) - .refreshable { + .refreshable { Task { await RoomStatusFetcher.fetchRoomStatus() await RemoteScheduleFetcher.fetchSchedule() diff --git a/Localizable.xcstrings b/Localizable.xcstrings index 00b4dbf..471236a 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -1,20 +1,17 @@ { "sourceLanguage" : "en", "strings" : { - "%@" : { - - }, "🇺🇦" : { - + "shouldTranslate" : false }, "🍺" : { - + "shouldTranslate" : false }, "🔨" : { - + "shouldTranslate" : false }, "🧑‍💻" : { - + "shouldTranslate" : false }, "About" : { "localizations" : { @@ -27,7 +24,14 @@ } }, "All events filtered out" : { - + "localizations" : { + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Alle evenementen zijn gefilterd" + } + } + } }, "Bookmarks only" : { "localizations" : { @@ -47,6 +51,12 @@ "state" : "translated", "value" : "Chat" } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chat" + } } } }, @@ -61,7 +71,14 @@ } }, "Details" : { - + "localizations" : { + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Details" + } + } + } }, "Favorite" : { "localizations" : { @@ -74,13 +91,21 @@ } }, "Filters" : { - + "localizations" : { + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Filters" + } + } + } }, "FOSDEM" : { - + "shouldTranslate" : false }, "Fosdem %@" : { - "extractionState" : "manual" + "extractionState" : "manual", + "shouldTranslate" : false }, "Future events only" : { "localizations" : { @@ -103,7 +128,7 @@ } }, "Homebrew" : { - + "shouldTranslate" : false }, "If you have improvements you can suggest them at:" : { "localizations" : { @@ -116,34 +141,41 @@ } }, "Links" : { - - }, - "Live Video" : { - + "localizations" : { + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Links" + } + } + } }, - "Local timezone" : { + "List grouping" : { "localizations" : { "nl" : { "stringUnit" : { "state" : "translated", - "value" : "Lokale tijdzone" + "value" : "Groepering van de lijst" } } } }, - "My events" : { - "extractionState" : "manual", + "Live Video" : { "localizations" : { - "en" : { + "nl" : { "stringUnit" : { "state" : "translated", - "value" : "My bookmarks" + "value" : "Live video" } - }, + } + } + }, + "Local timezone" : { + "localizations" : { "nl" : { "stringUnit" : { - "state" : "needs_review", - "value" : "Mijn keuzes" + "state" : "translated", + "value" : "Lokale tijdzone" } } } @@ -169,7 +201,14 @@ } }, "No events" : { - + "localizations" : { + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Geen evenementen" + } + } + } }, "No links" : { "localizations" : { @@ -182,7 +221,14 @@ } }, "No results" : { - + "localizations" : { + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Geen resultaten" + } + } + } }, "People" : { "extractionState" : "manual", @@ -274,6 +320,12 @@ "state" : "translated", "value" : "Oekraïne" } + }, + "uk" : { + "stringUnit" : { + "state" : "translated", + "value" : "Україна" + } } } }, @@ -284,6 +336,12 @@ "state" : "translated", "value" : "Jaar" } + }, + "uk" : { + "stringUnit" : { + "state" : "translated", + "value" : "Рік" + } } } } diff --git a/Package.resolved b/Package.resolved index 12e9411..d88d830 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,7 +6,34 @@ "location" : "https://github.com/SMillerDev/PentabarfKit", "state" : { "branch" : "main", - "revision" : "845f413bd7bb48c4bed1650153a33bbaf184c941" + "revision" : "1b418ad6c833264eaf6a9218a855a27827365228" + } + }, + { + "identity" : "swift-algorithms", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-algorithms", + "state" : { + "revision" : "f6919dfc309e7f1b56224378b11e28bab5bccc42", + "version" : "1.2.0" + } + }, + { + "identity" : "swift-numerics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-numerics.git", + "state" : { + "revision" : "0a5bc04095a675662cf24757cc0640aa2204253b", + "version" : "1.0.2" + } + }, + { + "identity" : "swiftdata-sectionedquery", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Whiffer/swiftdata-sectionedquery", + "state" : { + "branch" : "main", + "revision" : "958835024bffa9ee8a995b34ba1821e6358c041f" } }, { diff --git a/Package.swift b/Package.swift index 37a25ee..f944750 100644 --- a/Package.swift +++ b/Package.swift @@ -5,14 +5,20 @@ let package = Package( name: "Fosdem", platforms: [ .iOS(.v16), + .macOS(.v13), ], products: [ + ], dependencies: [ - .package(url: "https://github.com/SMillerDev/PentabarfKit", .branch("main")) + .package(url: "https://github.com/SMillerDev/PentabarfKit", branch: "main"), + .package(url: "https://github.com/Whiffer/swiftdata-sectionedquery", branch: "main") ], targets: [ - .target(name: "Fosdem", dependencies: ["PentabarfKit"], path: "Fosdem"), + .target(name: "Fosdem", + dependencies: ["PentabarfKit"], + path: "Fosdem" + ), .testTarget( name: "FosdemTests", dependencies: ["Fosdem"],