From a36f7fac97704dafa849e56244e85e4b7028aa1c Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Thu, 9 Jul 2026 02:41:30 +0200 Subject: [PATCH] Native Search --- RubyEvents.xcodeproj/project.pbxproj | 17 + .../xcshareddata/swiftpm/Package.resolved | 20 +- .../UserInterfaceState.xcuserstate | Bin 15413 -> 212506 bytes RubyEvents/controllers/TabBarController.swift | 59 +++- RubyEvents/search/SearchModels.swift | 139 ++++++++ RubyEvents/search/SearchView.swift | 319 ++++++++++++++++++ RubyEvents/search/SearchViewModel.swift | 134 ++++++++ 7 files changed, 674 insertions(+), 14 deletions(-) create mode 100644 RubyEvents/search/SearchModels.swift create mode 100644 RubyEvents/search/SearchView.swift create mode 100644 RubyEvents/search/SearchViewModel.swift diff --git a/RubyEvents.xcodeproj/project.pbxproj b/RubyEvents.xcodeproj/project.pbxproj index 17c031b..381d1ec 100644 --- a/RubyEvents.xcodeproj/project.pbxproj +++ b/RubyEvents.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 973DD3652D95F8BE008E0AED /* CachedAsyncImage in Frameworks */ = {isa = PBXBuildFile; productRef = 973DD3642D95F8BE008E0AED /* CachedAsyncImage */; }; 97613B4C2D0635C600220031 /* HotwireNative in Frameworks */ = {isa = PBXBuildFile; productRef = 97613B4B2D0635C600220031 /* HotwireNative */; }; 97613B572D06512900220031 /* YouTubePlayerKit in Frameworks */ = {isa = PBXBuildFile; productRef = 97613B562D06512900220031 /* YouTubePlayerKit */; }; + 97AAF2552FFF19EC009DB8C2 /* Typesense in Frameworks */ = {isa = PBXBuildFile; productRef = 97AAF2542FFF19EC009DB8C2 /* Typesense */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -43,6 +44,7 @@ buildActionMask = 2147483647; files = ( 97613B572D06512900220031 /* YouTubePlayerKit in Frameworks */, + 97AAF2552FFF19EC009DB8C2 /* Typesense in Frameworks */, 973DD3652D95F8BE008E0AED /* CachedAsyncImage in Frameworks */, 97613B4C2D0635C600220031 /* HotwireNative in Frameworks */, ); @@ -90,6 +92,7 @@ 97613B4B2D0635C600220031 /* HotwireNative */, 97613B562D06512900220031 /* YouTubePlayerKit */, 973DD3642D95F8BE008E0AED /* CachedAsyncImage */, + 97AAF2542FFF19EC009DB8C2 /* Typesense */, ); productName = RubyEvents; productReference = 97613B162D0634F500220031 /* RubyEvents.app */; @@ -123,6 +126,7 @@ 97613B4A2D0635C600220031 /* XCRemoteSwiftPackageReference "hotwire-native-ios" */, 97613B552D06512900220031 /* XCRemoteSwiftPackageReference "YouTubePlayerKit" */, 973DD3632D95F8BE008E0AED /* XCRemoteSwiftPackageReference "CachedAsyncImage" */, + 97AAF2532FFF19EC009DB8C2 /* XCRemoteSwiftPackageReference "typesense-swift" */, ); preferredProjectObjectVersion = 77; productRefGroup = 97613B172D0634F500220031 /* Products */; @@ -386,6 +390,14 @@ minimumVersion = 1.9.0; }; }; + 97AAF2532FFF19EC009DB8C2 /* XCRemoteSwiftPackageReference "typesense-swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/typesense/typesense-swift"; + requirement = { + branch = master; + kind = branch; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -404,6 +416,11 @@ package = 97613B552D06512900220031 /* XCRemoteSwiftPackageReference "YouTubePlayerKit" */; productName = YouTubePlayerKit; }; + 97AAF2542FFF19EC009DB8C2 /* Typesense */ = { + isa = XCSwiftPackageProductDependency; + package = 97AAF2532FFF19EC009DB8C2 /* XCRemoteSwiftPackageReference "typesense-swift" */; + productName = Typesense; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 97613B0E2D0634F500220031 /* Project object */; diff --git a/RubyEvents.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/RubyEvents.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 9f1703e..36f705d 100644 --- a/RubyEvents.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/RubyEvents.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,6 +1,15 @@ { - "originHash" : "c7e739a9235f7569c4841d8050af06b35acc10a3591a95cc1c3d4e2f75e46cb2", + "originHash" : "98daefcb7a9409d791c632e30170c0914ed15b50c831c51339fe6c278c527796", "pins" : [ + { + "identity" : "anycodable", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Flight-School/AnyCodable", + "state" : { + "revision" : "862808b2070cd908cb04f9aafe7de83d35f81b05", + "version" : "0.6.7" + } + }, { "identity" : "cachedasyncimage", "kind" : "remoteSourceControl", @@ -19,6 +28,15 @@ "version" : "1.1.3" } }, + { + "identity" : "typesense-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/typesense/typesense-swift", + "state" : { + "branch" : "master", + "revision" : "0d9335697a73d19a25a21e14678e8251314a33af" + } + }, { "identity" : "youtubeplayerkit", "kind" : "remoteSourceControl", diff --git a/RubyEvents.xcodeproj/project.xcworkspace/xcuserdata/marcoroth.xcuserdatad/UserInterfaceState.xcuserstate b/RubyEvents.xcodeproj/project.xcworkspace/xcuserdata/marcoroth.xcuserdatad/UserInterfaceState.xcuserstate index b82f64c13680c65ed1ca02b68a54e49859bce5e7..08ad15d90c57eccc3dbd535739900cb922cead83 100644 GIT binary patch literal 212506 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 delta 8466 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 diff --git a/RubyEvents/controllers/TabBarController.swift b/RubyEvents/controllers/TabBarController.swift index 9602282..06a8c68 100644 --- a/RubyEvents/controllers/TabBarController.swift +++ b/RubyEvents/controllers/TabBarController.swift @@ -6,6 +6,7 @@ // import HotwireNative +import SwiftUI import UIKit struct TabBarConfigurationItem { @@ -24,6 +25,7 @@ class TabBarController: UITabBarController { var configuration: TabBarConfiguration? var navigators: [Navigator] = [] var isSetup: Bool = false + private var searchPlaceholder: UIViewController? init(app: App) { self.app = app @@ -110,12 +112,6 @@ class TabBarController: UITabBarController { icon: "music.mic", url: Router.instance.talks_url(), position: 2 - ), - TabBarConfigurationItem( - title: "Speakers", - icon: "person.fill", - url: Router.instance.speakers_url(), - position: 3 ) ] ) @@ -138,17 +134,26 @@ class TabBarController: UITabBarController { tabBarItems.append(fixedTabBarItemFrom(item: item)) } - viewControllers = navigators.map(\.rootViewController) + var controllers: [UIViewController] = navigators.map(\.rootViewController) tabBarItems.enumerated().forEach { index, item in - if let viewController = self.viewControllers?[index] { -// viewController.tabBarController?.tabBar.tintColor = .white -// viewController.tabBarController?.tabBar.barTintColor = .black - viewController.tabBarItem = item + if index < controllers.count { + controllers[index].tabBarItem = item } } - // NavBar styling + let searchController = UIViewController() + searchController.tabBarItem = UITabBarItem( + title: "Search", + image: UIImage(systemName: "magnifyingglass"), + tag: controllers.count + ) + self.searchPlaceholder = searchController + controllers.append(searchController) + + viewControllers = controllers + self.delegate = self + let navigationBarAppearance = UINavigationBarAppearance() navigationBarAppearance.configureWithDefaultBackground() UINavigationBar.appearance().standardAppearance = navigationBarAppearance @@ -157,7 +162,6 @@ class TabBarController: UITabBarController { UINavigationBar.appearance().isTranslucent = true navigationBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.black] - // TabBar styling let tabBarAppearance = UITabBarAppearance() tabBarAppearance.configureWithDefaultBackground() tabBarAppearance.backgroundColor = UIColor.white @@ -182,4 +186,33 @@ class TabBarController: UITabBarController { required init?(coder _: NSCoder) { fatalError("init(coder:) has not been implemented") } + + override func viewDidLoad() { + super.viewDidLoad() + } + + private func presentSearch() { + let searchView = SearchView( + navigator: currentNavigator, + onDismiss: { [weak self] in self?.dismiss(animated: true) } + ) + + let hosting = UIHostingController(rootView: searchView) + hosting.modalPresentationStyle = .pageSheet + if let sheet = hosting.sheetPresentationController { + sheet.detents = [.large()] + sheet.prefersGrabberVisible = true + } + present(hosting, animated: true) + } +} + +extension TabBarController: UITabBarControllerDelegate { + func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { + if viewController === searchPlaceholder { + presentSearch() + return false + } + return true + } } diff --git a/RubyEvents/search/SearchModels.swift b/RubyEvents/search/SearchModels.swift new file mode 100644 index 0000000..117c609 --- /dev/null +++ b/RubyEvents/search/SearchModels.swift @@ -0,0 +1,139 @@ +// +// SearchModels.swift +// RubyEvents +// + +import Foundation + +// Config from /hotwire/native/v1/search_config.json + +struct SearchConfig: Decodable { + struct Node: Decodable { + let host: String + let port: Int + let `protocol`: String + } + + struct CollectionConfig: Decodable { + let collection: String + let query_by: String + let query_by_weights: String? + let filter_by: String? + } + + let nodes: [Node] + let nearest_node: Node? + let search_api_key: String? + let per_page: Int? + let talks: CollectionConfig + let speakers: CollectionConfig + let events: CollectionConfig +} + +struct SearchTalk: Codable { + let id: String? + let title: String + let slug: String + let thumbnail_url: String? + let duration_in_seconds: Int32? + let video_provider: String? + let video_id: String? + let event_name: String? + let speakers: [SearchDocSpeaker]? + + struct SearchDocSpeaker: Codable { + let id: Int64? + let name: String + let slug: String + } + + private var derivedVideoURL: String? { + switch video_provider { + case "mp4": return video_id + case "youtube": return video_id.map { "https://www.youtube.com/watch?v=\($0)" } + case "vimeo": return video_id.map { "https://vimeo.com/video/\($0)" } + default: return nil + } + } + + func toTalk() -> Talk { + Talk( + id: Int64(id ?? "") ?? 0, + title: title, + speakers: (speakers ?? []).map { Speaker(id: $0.id ?? 0, name: $0.name, slug: $0.slug, avatar_url: nil) }, + duration_in_seconds: duration_in_seconds, + event_name: event_name ?? "", + url: Router.instance.root_url().appendingPathComponent("/talks/\(slug)"), + thumbnail_url: thumbnail_url.flatMap { URL(string: $0) }, + slug: slug + // TODO: native player — add when the player branch's Talk model is integrated: + // , video_provider: video_provider, video_id: video_id, video_url: derivedVideoURL + ) + } +} + +struct SearchSpeaker: Codable { + let id: String? + let name: String + let slug: String + let avatar_url: String? + let github_handle: String? + + var avatarURL: URL? { avatar_url.flatMap { URL(string: $0) } } + var profileURL: URL { Router.instance.speaker_url(slug: slug) } +} + +struct SearchEvent: Codable { + let id: String? + let name: String + let slug: String + let city: String? + let country_name: String? + let avatar_url: String? + let start_date_timestamp: Int64? + let end_date_timestamp: Int64? + + var eventURL: URL { Router.instance.root_url().appendingPathComponent("/events/\(slug)") } + + var avatarURL: URL? { + guard let avatar_url, !avatar_url.isEmpty else { return nil } + if avatar_url.hasPrefix("http") { return URL(string: avatar_url) } + + return URL(string: Router.instance.root_url().appendingPathComponent(avatar_url).absoluteString) + } + + var locationText: String? { + let parts = [city, country_name].compactMap { $0 }.filter { !$0.isEmpty } + + return parts.isEmpty ? nil : parts.joined(separator: ", ") + } + + var dateText: String? { + guard let start = start_date_timestamp, start > 0 else { return nil } + let startDate = Date(timeIntervalSince1970: TimeInterval(start)) + + let full = DateFormatter() + full.dateFormat = "MMM d, yyyy" + + if let end = end_date_timestamp, end > 0 { + let endDate = Date(timeIntervalSince1970: TimeInterval(end)) + + if Calendar.current.isDate(startDate, inSameDayAs: endDate) { + return full.string(from: startDate) + } + + let short = DateFormatter() + short.dateFormat = "MMM d" + + return "\(short.string(from: startDate)) – \(full.string(from: endDate))" + } + + return full.string(from: startDate) + } + + var subtitle: String? { + [dateText, locationText].compactMap { $0 }.first.flatMap { _ in + [dateText, locationText].compactMap { $0 }.joined(separator: " · ") + } + } +} diff --git a/RubyEvents/search/SearchView.swift b/RubyEvents/search/SearchView.swift new file mode 100644 index 0000000..b749474 --- /dev/null +++ b/RubyEvents/search/SearchView.swift @@ -0,0 +1,319 @@ +// +// SearchView.swift +// RubyEvents +// + +import HotwireNative +import SwiftUI + +enum SearchScope: String, CaseIterable, Identifiable { + case all, speakers, events, talks + + var id: String { rawValue } + + var title: String { + switch self { + case .all: return "All" + case .speakers: return "Speakers" + case .events: return "Events" + case .talks: return "Talks" + } + } +} + +struct SearchView: View { + @StateObject private var viewModel = SearchViewModel() + var navigator: Navigator? + var onDismiss: () -> Void + + @State private var scope: SearchScope = .all + @FocusState private var searchFocused: Bool + + private var showSpeakers: Bool { scope == .all || scope == .speakers } + private var showEvents: Bool { scope == .all || scope == .events } + private var showTalks: Bool { scope == .all || scope == .talks } + + private var visibleResultsEmpty: Bool { + (!showSpeakers || viewModel.speakerResults.isEmpty) + && (!showEvents || viewModel.eventResults.isEmpty) + && (!showTalks || viewModel.talkResults.isEmpty) + } + + private let previewLimit = 4 + private var displayedSpeakers: [SearchSpeaker] { scope == .all ? Array(viewModel.speakerResults.prefix(previewLimit)) : viewModel.speakerResults } + private var displayedEvents: [SearchEvent] { scope == .all ? Array(viewModel.eventResults.prefix(previewLimit)) : viewModel.eventResults } + private var displayedTalks: [Talk] { scope == .all ? Array(viewModel.talkResults.prefix(previewLimit)) : viewModel.talkResults } + + var body: some View { + NavigationStack { + ScrollView { + LazyVStack(alignment: .leading, spacing: 0) { + if showSpeakers, !viewModel.speakerResults.isEmpty { + sectionHeader("Speakers", total: viewModel.speakerResults.count, seeAll: .speakers) + ForEach(displayedSpeakers, id: \.slug) { speaker in + SpeakerResultRow(speaker: speaker, onSelect: { route(speaker.profileURL) }) + Divider().padding(.leading, 68) + } + } + + if showEvents, !viewModel.eventResults.isEmpty { + sectionHeader("Events", total: viewModel.eventResults.count, seeAll: .events) + ForEach(displayedEvents, id: \.slug) { event in + EventResultRow(event: event, onSelect: { route(event.eventURL) }) + Divider().padding(.leading, 16) + } + } + + if showTalks, !viewModel.talkResults.isEmpty { + sectionHeader("Talks", total: viewModel.talkResults.count, seeAll: .talks) + ForEach(displayedTalks) { talk in + TalkResultRow(talk: talk, navigator: navigator) + Divider().padding(.leading, 16) + } + } + } + } + .overlay { + if visibleResultsEmpty { + emptyState + } + } + .navigationTitle("") + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Button(action: onDismiss) { + Image(systemName: "xmark.circle.fill") + .font(.title3) + .foregroundStyle(.secondary, Color(.tertiarySystemFill)) + } + .accessibilityLabel("Close") + } + } + .searchable( + text: $viewModel.query, + placement: .navigationBarDrawer(displayMode: .always), + prompt: "Search talks, speakers, events" + ) + .searchScopes($scope) { + ForEach(SearchScope.allCases) { scope in + Text(scope.title).tag(scope) + } + } + .modifier(SearchAutoFocus(focused: $searchFocused)) + .autocorrectionDisabled() + .textInputAutocapitalization(.never) + } + .task { await viewModel.loadConfigIfNeeded() } + .onAppear { + searchFocused = true + } + } + + private func route(_ url: URL) { + onDismiss() + navigator?.route(url) + } + + private func sectionHeader(_ title: String, total: Int, seeAll: SearchScope) -> some View { + HStack(alignment: .firstTextBaseline) { + Text(title) + .font(.headline) + .foregroundStyle(.primary) + + Spacer() + + if scope == .all, total > previewLimit { + Button("See all \(total)") { + withAnimation { scope = seeAll } + } + .font(.subheadline) + } + } + .padding(.horizontal, 16) + .padding(.top, 16) + .padding(.bottom, 8) + } + + @ViewBuilder + private var emptyState: some View { + if let error = viewModel.errorMessage { + VStack(spacing: 8) { + Image(systemName: "exclamationmark.triangle") + .font(.largeTitle) + .foregroundStyle(.orange) + Text("Search unavailable") + .font(.headline) + Text(error) + .font(.subheadline) + .foregroundStyle(.secondary) + .multilineTextAlignment(.center) + .padding(.horizontal, 32) + } + } else if viewModel.isSearching { + ProgressView() + } else if viewModel.hasSearched { + emptyMessage("No results", subtitle: "Try a different search") + } else { + emptyMessage("Search Ruby talks", subtitle: "By title, speaker, event, topic…") + } + } + + private func emptyMessage(_ title: String, subtitle: String) -> some View { + VStack(spacing: 8) { + Image(systemName: "magnifyingglass") + .font(.largeTitle) + .foregroundStyle(.secondary) + Text(title).font(.headline) + Text(subtitle).font(.subheadline).foregroundStyle(.secondary) + } + } +} + +private struct SpeakerResultRow: View { + let speaker: SearchSpeaker + var onSelect: () -> Void + + var body: some View { + Button(action: onSelect) { + HStack(spacing: 12) { + Avatar(name: speaker.name, url: speaker.avatar_url) + .frame(width: 40, height: 40) + .clipShape(Circle()) + + VStack(alignment: .leading, spacing: 2) { + Text(speaker.name) + .font(.subheadline.weight(.medium)) + .foregroundStyle(.primary) + .lineLimit(1) + if let handle = speaker.github_handle, !handle.isEmpty { + Text("@\(handle)") + .font(.caption) + .foregroundStyle(.secondary) + .lineLimit(1) + } + } + + Spacer(minLength: 0) + Image(systemName: "chevron.right").font(.caption).foregroundStyle(.tertiary) + } + .padding(.horizontal, 16) + .padding(.vertical, 8) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + } +} + +private struct EventResultRow: View { + let event: SearchEvent + var onSelect: () -> Void + + var body: some View { + Button(action: onSelect) { + HStack(spacing: 12) { + AsyncImage(url: event.avatarURL) { image in + image.resizable().scaledToFill() + } placeholder: { + Image(systemName: "calendar") + .font(.headline) + .foregroundStyle(.secondary) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color(.secondarySystemBackground)) + } + .frame(width: 40, height: 40) + .clipShape(RoundedRectangle(cornerRadius: 8)) + + VStack(alignment: .leading, spacing: 2) { + Text(event.name) + .font(.subheadline.weight(.medium)) + .foregroundStyle(.primary) + .lineLimit(1) + if let subtitle = event.subtitle { + Text(subtitle) + .font(.caption) + .foregroundStyle(.secondary) + .lineLimit(1) + } + } + + Spacer(minLength: 0) + Image(systemName: "chevron.right").font(.caption).foregroundStyle(.tertiary) + } + .padding(.horizontal, 16) + .padding(.vertical, 8) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + } +} + +private struct SearchAutoFocus: ViewModifier { + var focused: FocusState.Binding + + func body(content: Content) -> some View { + if #available(iOS 18.0, *) { + content.searchFocused(focused) + } else { + content + } + } +} + +private struct TalkResultRow: View { + let talk: Talk + var navigator: Navigator? + + // TODO: native player — re-enable when the player branch is integrated. + // @State private var showPlayer = false + + var body: some View { + Button(action: { + // TODO: native player — when integrated, prefer: + // if talk.opensNativeScreen { showPlayer = true } else if let url = talk.url { navigator?.route(url) } + if let url = talk.url { + navigator?.route(url) + } + }) { + HStack(spacing: 12) { + AsyncImage(url: talk.thumbnail_url) { image in + image.resizable().scaledToFill() + } placeholder: { + Rectangle().fill(Color(.secondarySystemBackground)) + } + .frame(width: 120, height: 68) + .clipShape(RoundedRectangle(cornerRadius: 8)) + + VStack(alignment: .leading, spacing: 4) { + Text(talk.title) + .font(.subheadline.weight(.medium)) + .foregroundStyle(.primary) + .lineLimit(2) + .multilineTextAlignment(.leading) + + Text(talk.speakers.first.map { "\($0.name) • \(talk.event_name)" } ?? talk.event_name) + .font(.caption) + .foregroundStyle(.secondary) + .lineLimit(1) + } + + Spacer(minLength: 0) + } + .padding(.horizontal, 16) + .padding(.vertical, 10) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + // TODO: native player — re-enable when the player branch is integrated. + // .fullScreenCover(isPresented: $showPlayer) { + // if let params = talk.playerParams { + // TalkPlayerScreen( + // params: params, + // navigator: navigator, + // onProgress: { _ in }, + // onDismiss: { showPlayer = false } + // ) + // } + // } + } +} diff --git a/RubyEvents/search/SearchViewModel.swift b/RubyEvents/search/SearchViewModel.swift new file mode 100644 index 0000000..dbe2640 --- /dev/null +++ b/RubyEvents/search/SearchViewModel.swift @@ -0,0 +1,134 @@ +// +// SearchViewModel.swift +// RubyEvents +// + +import Combine +import Foundation +import Typesense + +@MainActor +final class SearchViewModel: ObservableObject { + @Published var query = "" + @Published var talkResults: [Talk] = [] + @Published var speakerResults: [SearchSpeaker] = [] + @Published var eventResults: [SearchEvent] = [] + @Published var isSearching = false + @Published var hasSearched = false + @Published var errorMessage: String? + + var isEmpty: Bool { talkResults.isEmpty && speakerResults.isEmpty && eventResults.isEmpty } + + private var client: Client? + private var config: SearchConfig? + private var searchTask: Task? + private var cancellables = Set() + + init() { + $query + .debounce(for: .milliseconds(300), scheduler: RunLoop.main) + .removeDuplicates() + .sink { [weak self] value in self?.performSearch(value) } + .store(in: &cancellables) + } + + func loadConfigIfNeeded() async { + guard client == nil else { return } + + let endpoint = Router.instance.root_url() + .appendingPathComponent("/hotwire/native/v1/search_config.json") + .absoluteString + + do { + let config: SearchConfig = try await APIService.shared.fetchData(from: endpoint) + self.config = config + + guard let key = config.search_api_key, !key.isEmpty else { + errorMessage = "Search isn't configured on the server (missing search key)." + return + } + let nodes = config.nodes.map { Node(host: $0.host, port: String($0.port), nodeProtocol: $0.protocol) } + client = Client(config: Configuration(nodes: nodes, apiKey: key)) + errorMessage = nil + } catch { + errorMessage = "Couldn't load search config: \(error.localizedDescription)" + } + } + + private func performSearch(_ value: String) { + searchTask?.cancel() + + let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines) + guard !trimmed.isEmpty else { + talkResults = [] + speakerResults = [] + eventResults = [] + hasSearched = false + return + } + + searchTask = Task { [weak self] in await self?.search(trimmed) } + } + + private func search(_ query: String) async { + guard client != nil, config != nil else { return } + + isSearching = true + defer { isSearching = false } + + async let talks = searchTalks(query) + async let speakers = searchSpeakers(query) + async let events = searchEvents(query) + + let (t, s, e) = await (talks, speakers, events) + guard !Task.isCancelled else { return } + + talkResults = t + speakerResults = s + eventResults = e + hasSearched = true + } + + private let fetchLimit = 40 + + private func searchTalks(_ query: String) async -> [Talk] { + guard let client, let c = config?.talks else { return [] } + do { + let params = SearchParameters( + q: query, + queryBy: c.query_by, + queryByWeights: c.query_by_weights, filterBy: c.filter_by, + sortBy: "_text_match:desc,recency_score:desc,date_timestamp:desc", + perPage: fetchLimit + ) + let (result, _) = try await client.collection(name: c.collection).documents().search(params, for: SearchTalk.self) + return (result?.hits ?? []).compactMap { $0.document?.toTalk() } + } catch { + return [] + } + } + + private func searchSpeakers(_ query: String) async -> [SearchSpeaker] { + guard let client, let c = config?.speakers else { return [] } + do { + let params = SearchParameters(q: query, queryBy: c.query_by, queryByWeights: c.query_by_weights, perPage: fetchLimit) + let (result, _) = try await client.collection(name: c.collection).documents().search(params, for: SearchSpeaker.self) + return (result?.hits ?? []).compactMap { $0.document } + } catch { + print("⚠️ Typesense speakers search failed:", error) + return [] + } + } + + private func searchEvents(_ query: String) async -> [SearchEvent] { + guard let client, let c = config?.events else { return [] } + do { + let params = SearchParameters(q: query, queryBy: c.query_by, queryByWeights: c.query_by_weights, perPage: fetchLimit) + let (result, _) = try await client.collection(name: c.collection).documents().search(params, for: SearchEvent.self) + return (result?.hits ?? []).compactMap { $0.document } + } catch { + print("⚠️ Typesense events search failed:", error) + return [] + } + } +}