diff --git a/SNUTT-2022/SNUTT/AppState/States/SearchState.swift b/SNUTT-2022/SNUTT/AppState/States/SearchState.swift index e5231f8f..d859f066 100644 --- a/SNUTT-2022/SNUTT/AppState/States/SearchState.swift +++ b/SNUTT-2022/SNUTT/AppState/States/SearchState.swift @@ -12,6 +12,7 @@ class SearchState { @Published var isFilterOpen = false @Published var searchTagList: SearchTagList? @Published var selectedTagList: [SearchTag] = [] + @Published var displayMode: SearchDisplayMode = .search /// If `nil`, the user had never started searching. /// If empty, the server returned an empty search result. diff --git a/SNUTT-2022/SNUTT/Services/SearchService.swift b/SNUTT-2022/SNUTT/Services/SearchService.swift index 6adef5fd..db3e1499 100644 --- a/SNUTT-2022/SNUTT/Services/SearchService.swift +++ b/SNUTT-2022/SNUTT/Services/SearchService.swift @@ -20,6 +20,7 @@ protocol SearchServiceProtocol: Sendable { func setSelectedLecture(_ value: Lecture?) func initializeSearchState() func getBookmark() async throws + func setSearchDisplayMode(_ mode: SearchDisplayMode) } struct SearchService: SearchServiceProtocol { @@ -47,6 +48,7 @@ struct SearchService: SearchServiceProtocol { searchState.selectedTagList = [] searchState.searchResult = nil searchState.searchText = "" + searchState.displayMode = .search } func fetchTags(quarter: Quarter) async throws { @@ -108,6 +110,10 @@ struct SearchService: SearchServiceProtocol { searchState.isFilterOpen = value } + func setSearchDisplayMode(_ mode: SearchDisplayMode) { + searchState.displayMode = mode + } + func setSelectedLecture(_ value: Lecture?) { searchState.selectedLecture = value } @@ -144,4 +150,5 @@ class FakeSearchService: SearchServiceProtocol { func setSelectedLecture(_: Lecture?) {} func initializeSearchState() {} func getBookmark() async throws {} + func setSearchDisplayMode(_ mode: SearchDisplayMode) {} } diff --git a/SNUTT-2022/SNUTT/ViewModels/SearchLectureSceneViewModel.swift b/SNUTT-2022/SNUTT/ViewModels/SearchLectureSceneViewModel.swift index 2ab2e636..75a9d043 100644 --- a/SNUTT-2022/SNUTT/ViewModels/SearchLectureSceneViewModel.swift +++ b/SNUTT-2022/SNUTT/ViewModels/SearchLectureSceneViewModel.swift @@ -13,6 +13,7 @@ class SearchLectureSceneViewModel: BaseViewModel, ObservableObject { @Published private var _timetableConfig: TimetableConfiguration = .init() @Published private var _searchText: String = "" @Published private var _isFilterOpen: Bool = false + @Published private var _displayMode: SearchDisplayMode = .search @Published var searchResult: [Lecture]? = nil @Published var selectedTagList: [SearchTag] = [] @@ -28,12 +29,9 @@ class SearchLectureSceneViewModel: BaseViewModel, ObservableObject { set { services.searchService.setIsFilterOpen(newValue) } } - private var searchState: SearchState { - appState.search - } - - private var timetableState: TimetableState { - appState.timetable + var displayMode: SearchDisplayMode { + get { _displayMode } + set { services.searchService.setSearchDisplayMode(newValue) } } override init(container: DIContainer) { @@ -47,6 +45,7 @@ class SearchLectureSceneViewModel: BaseViewModel, ObservableObject { appState.search.$isLoading.assign(to: &$isLoading) appState.search.$searchResult.assign(to: &$searchResult) appState.search.$selectedTagList.assign(to: &$selectedTagList) + appState.search.$displayMode.assign(to: &$_displayMode) } var selectedLecture: Lecture? { @@ -66,7 +65,7 @@ class SearchLectureSceneViewModel: BaseViewModel, ObservableObject { if appState.search.searchTagList != nil { return } - guard let currentTimetable = timetableState.current else { return } + guard let currentTimetable = appState.timetable.current else { return } do { try await services.searchService.fetchTags(quarter: currentTimetable.quarter) } catch { diff --git a/SNUTT-2022/SNUTT/Views/Scenes/SearchLectureScene.swift b/SNUTT-2022/SNUTT/Views/Scenes/SearchLectureScene.swift index 2a59b406..0f33427a 100644 --- a/SNUTT-2022/SNUTT/Views/Scenes/SearchLectureScene.swift +++ b/SNUTT-2022/SNUTT/Views/Scenes/SearchLectureScene.swift @@ -14,7 +14,6 @@ struct SearchLectureScene: View { static let searchBarHeight = 44.0 } - @State private var displayMode: SearchDisplayMode = .search @State private var reloadSearchList: Int = 0 var body: some View { @@ -22,7 +21,7 @@ struct SearchLectureScene: View { backgroundTimetableView VStack(spacing: 0) { - switch displayMode { + switch viewModel.displayMode { case .search: searchContentView .transition(.move(edge: .leading)) @@ -35,7 +34,7 @@ struct SearchLectureScene: View { .safeAreaInset(edge: .top, alignment: .center, spacing: 0) { SearchBar(text: $viewModel.searchText, isFilterOpen: $viewModel.isFilterOpen, - displayMode: $displayMode, + displayMode: $viewModel.displayMode, action: viewModel.fetchInitialSearchResult) .frame(height: Design.searchBarHeight) } @@ -49,7 +48,7 @@ struct SearchLectureScene: View { .animation(.customSpring, value: viewModel.searchResult?.count) .animation(.customSpring, value: viewModel.isLoading) .animation(.customSpring, value: viewModel.selectedTagList.count) - .animation(.customSpring, value: displayMode) + .animation(.customSpring, value: viewModel.displayMode) .onChange(of: viewModel.isLoading) { _ in withAnimation(.customSpring) { reloadSearchList += 1