diff options
| author | Fuwn <[email protected]> | 2026-03-24 07:57:46 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-03-24 07:57:46 +0000 |
| commit | 021e6f20a376797df32db4e4121eb4766903a995 (patch) | |
| tree | f73c6047e6f462a17c1be1a1f3369c7ea79af024 /Sora/Views | |
| parent | Refine settings language and structure (diff) | |
| download | sora-testing-021e6f20a376797df32db4e4121eb4766903a995.tar.xz sora-testing-021e6f20a376797df32db4e4121eb4766903a995.zip | |
Refocus navigation around core content
Diffstat (limited to 'Sora/Views')
| -rw-r--r-- | Sora/Views/BookmarksView.swift | 1 | ||||
| -rw-r--r-- | Sora/Views/ContentView.swift | 22 | ||||
| -rw-r--r-- | Sora/Views/FavoritesView.swift | 12 | ||||
| -rw-r--r-- | Sora/Views/Generic/GenericListView.swift | 15 | ||||
| -rw-r--r-- | Sora/Views/MainView.swift | 125 | ||||
| -rw-r--r-- | Sora/Views/Post/Grid/PostGridSearchHistoryView.swift | 1 | ||||
| -rw-r--r-- | Sora/Views/Post/Grid/PostGridView.swift | 96 |
7 files changed, 128 insertions, 144 deletions
diff --git a/Sora/Views/BookmarksView.swift b/Sora/Views/BookmarksView.swift index 5aa05ce..a20d9f0 100644 --- a/Sora/Views/BookmarksView.swift +++ b/Sora/Views/BookmarksView.swift @@ -9,6 +9,7 @@ struct BookmarksView: View { selectedTab: $selectedTab, isPresented: .constant(false), allowBookmarking: false, + showsSettingsButton: true, title: "Bookmarks", emptyMessage: "No Bookmarks", emptyIcon: "bookmark", diff --git a/Sora/Views/ContentView.swift b/Sora/Views/ContentView.swift index fa3a69f..164d3e2 100644 --- a/Sora/Views/ContentView.swift +++ b/Sora/Views/ContentView.swift @@ -9,27 +9,7 @@ struct ContentView: View { var body: some View { #if os(macOS) NavigationSplitView(columnVisibility: $columnVisibility) { - List { - Text("Posts") - .tag(0) - } - } content: { - switch selectedTab { - case 1: - PostGridSearchHistoryView( - selectedTab: $selectedTab, - isPresented: .constant(false) - ) - - case 2: - BookmarksView(selectedTab: $selectedTab) - - case 3: - SettingsView() - - default: - PostGridView(selectedTab: $selectedTab, navigationPath: $navigationPath) - } + PostGridView(selectedTab: $selectedTab, navigationPath: $navigationPath) } detail: { if let post = manager.selectedPost { PostDetailsView(post: post, navigationPath: $navigationPath, posts: nil) diff --git a/Sora/Views/FavoritesView.swift b/Sora/Views/FavoritesView.swift index 598a143..007500b 100644 --- a/Sora/Views/FavoritesView.swift +++ b/Sora/Views/FavoritesView.swift @@ -17,6 +17,7 @@ struct FavoritesView: View { // swiftlint:disable:this type_body_length @State private var sort: SettingsBookmarkSort = .dateAdded @State private var isCollectionPickerPresented = false @State private var isProviderPickerPresented = false + @State private var isSettingsPresented = false @State private var selectedProvider: BooruProvider? @State private var navigationPath = NavigationPath() @State private var isDetailsSheetPresented = false @@ -283,6 +284,12 @@ struct FavoritesView: View { // swiftlint:disable:this type_body_length #endif #if os(iOS) + ToolbarItem(placement: .topBarTrailing) { + Button(action: { isSettingsPresented = true }) { + Label("Settings", systemImage: "gear") + } + } + ToolbarItemGroup(placement: .secondaryAction) { Menu { Picker("Sort By", selection: $sort) { @@ -378,6 +385,11 @@ struct FavoritesView: View { // swiftlint:disable:this type_body_length } #endif } + #if !os(macOS) + .sheet(isPresented: $isSettingsPresented) { + SettingsView() + } + #endif .onAppear { refreshFolderHierarchy() refreshDisplayedFavorites() diff --git a/Sora/Views/Generic/GenericListView.swift b/Sora/Views/Generic/GenericListView.swift index 3e5154f..d1c1436 100644 --- a/Sora/Views/Generic/GenericListView.swift +++ b/Sora/Views/Generic/GenericListView.swift @@ -18,8 +18,10 @@ struct GenericListView<T: Identifiable & Hashable & GenericItem>: View { @State private var sort: SettingsBookmarkSort = .dateAdded @State private var isCollectionPickerPresented = false @State private var isProviderPickerPresented = false + @State private var isSettingsPresented = false @State private var selectedProvider: BooruProvider? let allowBookmarking: Bool + let showsSettingsButton: Bool let title: String let emptyMessage: String let emptyIcon: String @@ -292,6 +294,14 @@ struct GenericListView<T: Identifiable & Hashable & GenericItem>: View { #endif #if os(iOS) + if showsSettingsButton { + ToolbarItem(placement: .topBarTrailing) { + Button(action: { isSettingsPresented = true }) { + Label("Settings", systemImage: "gear") + } + } + } + ToolbarItemGroup(placement: .secondaryAction) { if !allowBookmarking { Menu { @@ -389,6 +399,11 @@ struct GenericListView<T: Identifiable & Hashable & GenericItem>: View { } #endif } + #if !os(macOS) + .sheet(isPresented: $isSettingsPresented) { + SettingsView() + } + #endif .onAppear { refreshFolderHierarchy() refreshDisplayedItems() diff --git a/Sora/Views/MainView.swift b/Sora/Views/MainView.swift index 603f7a1..06e067b 100644 --- a/Sora/Views/MainView.swift +++ b/Sora/Views/MainView.swift @@ -1,8 +1,41 @@ import SwiftUI struct MainView: View { + private enum MainSidebarSection: Int, CaseIterable, Hashable { + case posts = 0 + case bookmarks = 1 + case favorites = 2 + + var title: String { + switch self { + case .posts: + "Posts" + + case .bookmarks: + "Bookmarks" + + case .favorites: + "Favorites" + } + } + + var systemImage: String { + switch self { + case .posts: + "rectangle.stack" + + case .bookmarks: + "bookmark" + + case .favorites: + "heart" + } + } + } + @EnvironmentObject var settings: SettingsManager @State private var selectedTab: Int = 0 + @State private var selectedSidebarSection: MainSidebarSection? = .posts @State private var manager = BooruManager(.yandere) var body: some View { @@ -23,13 +56,20 @@ struct MainView: View { .onChange(of: settings.sendBooruUserAgent) { updateManager(settings.preferredBooru) } .onChange(of: settings.customBooruUserAgent) { updateManager(settings.preferredBooru) } #if os(macOS) - .onChange(of: selectedTab) { _, newValue in - if newValue == 0 { + .onChange(of: selectedSidebarSection) { _, newValue in + guard let newValue else { return } + + selectedTab = newValue.rawValue + + if newValue == .posts { Task(priority: .userInitiated) { await manager.fetchPosts() } } } + .onChange(of: selectedTab) { _, newValue in + selectedSidebarSection = MainSidebarSection(rawValue: newValue) ?? .posts + } #endif } @@ -51,21 +91,6 @@ struct MainView: View { FavoritesView(selectedTab: $selectedTab, isPresented: .constant(false)) } } - - #if os(macOS) - Tab("Search History", systemImage: "clock.arrow.circlepath", value: 4) { - PostGridSearchHistoryView( - selectedTab: $selectedTab, - isPresented: .constant(false) - ) - } - #endif - - #if DEBUG || !os(macOS) - Tab("Settings", systemImage: "gear", value: 3) { - SettingsView() - } - #endif } } else { TabView(selection: $selectedTab) { @@ -84,36 +109,54 @@ struct MainView: View { } .tabItem { Label("Favorites", systemImage: "heart") } .tag(2) - - #if os(macOS) - NavigationStack { - PostGridSearchHistoryView( - selectedTab: $selectedTab, - isPresented: .constant(false) - ) - } - .tabItem { Label("Search History", systemImage: "clock.arrow.circlepath") } - .tag(4) - #endif - - #if DEBUG || !os(macOS) - SettingsView() - .tabItem { Label("Settings", systemImage: "gear") } - .tag(3) - #endif } } } + #if os(macOS) + @ViewBuilder private var sidebarContent: some View { + List(selection: $selectedSidebarSection) { + ForEach(MainSidebarSection.allCases, id: \.self) { section in + Label(section.title, systemImage: section.systemImage) + .tag(section) + } + } + .navigationTitle("Sora") + } + + @ViewBuilder private var sidebarDetailContent: some View { + switch selectedSidebarSection ?? .posts { + case .posts: + ContentView(selectedTab: $selectedTab) + + case .bookmarks: + NavigationStack { + BookmarksView(selectedTab: $selectedTab) + } + + case .favorites: + NavigationStack { + FavoritesView(selectedTab: $selectedTab, isPresented: .constant(false)) + } + } + } + #endif + @ViewBuilder private var platformSpecificContent: some View { - if #available(iOS 26, *) { - tabViewContent - #if !os(macOS) + #if os(macOS) + NavigationSplitView { + sidebarContent + } detail: { + sidebarDetailContent + } + #else + if #available(iOS 26, *) { + tabViewContent .tabBarMinimizeBehavior(.onScrollDown) - #endif - } else { - tabViewContent - } + } else { + tabViewContent + } + #endif } private func updateManager(_ provider: BooruProvider) { diff --git a/Sora/Views/Post/Grid/PostGridSearchHistoryView.swift b/Sora/Views/Post/Grid/PostGridSearchHistoryView.swift index 13baa41..bc7c52a 100644 --- a/Sora/Views/Post/Grid/PostGridSearchHistoryView.swift +++ b/Sora/Views/Post/Grid/PostGridSearchHistoryView.swift @@ -10,6 +10,7 @@ struct PostGridSearchHistoryView: View { selectedTab: $selectedTab, isPresented: $isPresented, allowBookmarking: true, + showsSettingsButton: false, title: "Search History", emptyMessage: "No History", emptyIcon: "magnifyingglass", diff --git a/Sora/Views/Post/Grid/PostGridView.swift b/Sora/Views/Post/Grid/PostGridView.swift index 23f7c00..330e294 100644 --- a/Sora/Views/Post/Grid/PostGridView.swift +++ b/Sora/Views/Post/Grid/PostGridView.swift @@ -6,6 +6,7 @@ struct PostGridView: View { // swiftlint:disable:this type_body_length @EnvironmentObject var settings: SettingsManager @EnvironmentObject var manager: BooruManager @State private var isSearchHistoryPresented = false + @State private var isSettingsPresented = false @Binding var selectedTab: Int @State private var isSearchablePresented = false @State private var suppressNextSearchSubmit = false @@ -296,10 +297,16 @@ struct PostGridView: View { // swiftlint:disable:this type_body_length } #endif + PlatformSpecificToolbarItem { + Button(action: { Task { isSearchHistoryPresented.toggle() } }) { + Label("Search History", systemImage: "clock.arrow.circlepath") + } + } + #if !os(macOS) - PlatformSpecificToolbarItem { - Button(action: { Task { isSearchHistoryPresented.toggle() } }) { - Label("Search History", systemImage: "clock.arrow.circlepath") + ToolbarItem(placement: .topBarTrailing) { + Button(action: { isSettingsPresented = true }) { + Label("Settings", systemImage: "gear") } } @@ -345,60 +352,6 @@ struct PostGridView: View { // swiftlint:disable:this type_body_length ToolbarItem(placement: .topBarTrailing) { ProgressView() } } #endif - - #if os(macOS) - let placement = ToolbarItemPlacement.navigation - #else - let placement = ToolbarItemPlacement.topBarLeading - #endif - - if initialTag == nil { - PlatformSpecificToolbarItem(placement: placement) { - Menu { - ForEach( - Array(manager.searchHistory.enumerated().filter { $0.offset < manager.historyIndex }), - id: \.offset - ) { offset, query in - Button(action: { - manager.historyIndex = offset - }) { - Text(query.tags.isEmpty ? "No Tags" : query.tags.joined(separator: " ")) - } - } - } label: { - Label("Previous Search", systemImage: "chevron.left") - } primaryAction: { - withAnimation { - manager.goBackInHistory() - } - } - .disabled(!manager.canGoBackInHistory) - .id("previousSearchMenu") - } - - PlatformSpecificToolbarItem(placement: placement) { - Menu { - ForEach( - Array(manager.searchHistory.enumerated().filter { $0.offset > manager.historyIndex }), - id: \.offset - ) { offset, query in - Button(action: { - manager.historyIndex = offset - }) { - Text(query.tags.isEmpty ? "No Tags" : query.tags.joined(separator: " ")) - } - } - } label: { - Label("Next Search", systemImage: "chevron.right") - } primaryAction: { - withAnimation { - manager.goForwardInHistory() - } - } - .disabled(!manager.canGoForwardInHistory) - .id("nextSearchMenu") - } - } } .navigationTitle(initialTag != nil ? initialTag! : "Posts") .refreshable { @@ -428,31 +381,10 @@ struct PostGridView: View { // swiftlint:disable:this type_body_length isPresented: $isSearchHistoryPresented ) } - #if os(iOS) - .gesture( - DragGesture() - .onEnded { value in - if initialTag == nil { - if value.startLocation.x < 50, value.translation.width > 100 { - withAnimation { - manager.goBackInHistory() - } - - debugPrint("ContentView: Swipe left, \(manager.searchHistory)") - } - - if value.startLocation.x > (UIScreen.main.bounds.width - 50), - value.translation.width < -100 - { - withAnimation { - manager.goForwardInHistory() - } - - debugPrint("ContentView: Swipe right, \(manager.searchHistory)") - } - } - } - ) + #if !os(macOS) + .sheet(isPresented: $isSettingsPresented) { + SettingsView() + } #endif } |