summaryrefslogtreecommitdiff
path: root/Sora/Views
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-03-24 07:57:46 +0000
committerFuwn <[email protected]>2026-03-24 07:57:46 +0000
commit021e6f20a376797df32db4e4121eb4766903a995 (patch)
treef73c6047e6f462a17c1be1a1f3369c7ea79af024 /Sora/Views
parentRefine settings language and structure (diff)
downloadsora-testing-021e6f20a376797df32db4e4121eb4766903a995.tar.xz
sora-testing-021e6f20a376797df32db4e4121eb4766903a995.zip
Refocus navigation around core content
Diffstat (limited to 'Sora/Views')
-rw-r--r--Sora/Views/BookmarksView.swift1
-rw-r--r--Sora/Views/ContentView.swift22
-rw-r--r--Sora/Views/FavoritesView.swift12
-rw-r--r--Sora/Views/Generic/GenericListView.swift15
-rw-r--r--Sora/Views/MainView.swift125
-rw-r--r--Sora/Views/Post/Grid/PostGridSearchHistoryView.swift1
-rw-r--r--Sora/Views/Post/Grid/PostGridView.swift96
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
}