summaryrefslogtreecommitdiff
path: root/Sora
diff options
context:
space:
mode:
Diffstat (limited to 'Sora')
-rw-r--r--Sora/Data/Settings.swift27
-rw-r--r--Sora/Data/Settings/Bookmark.swift13
-rw-r--r--Sora/Views/BookmarksView.swift63
-rw-r--r--Sora/Views/ContentView.swift2
-rw-r--r--Sora/Views/MainView.swift16
-rw-r--r--Sora/Views/Post/PostGridView.swift16
6 files changed, 108 insertions, 29 deletions
diff --git a/Sora/Data/Settings.swift b/Sora/Data/Settings.swift
deleted file mode 100644
index 1d3ccba..0000000
--- a/Sora/Data/Settings.swift
+++ /dev/null
@@ -1,27 +0,0 @@
-import SwiftUI
-
-class Settings: ObservableObject {
- #if DEBUG
- @AppStorage("detailViewType") var detailViewType: PostFileType = .compressed
- #else
- @AppStorage("detailViewType") var detailViewType: PostFileType = .original
- #endif
- @AppStorage("thumbnailType") var thumbnailType: PostFileType = .preview
- @AppStorage("searchSuggestions") var searchSuggestions: Bool = false
- @AppStorage("columns") var columns: Int = 2
- @AppStorage("blurNSFWThumbnails") var blurNSFWThumbnails: Bool = true
- @AppStorage("showNSFWPosts") var showNSFWPosts: Bool = false
-
- func resetToDefaults() {
- #if DEBUG
- detailViewType = .compressed
- #else
- detailViewType = .original
- #endif
- thumbnailType = .preview
- searchSuggestions = false
- columns = 2
- blurNSFWThumbnails = true
- showNSFWPosts = false
- }
-}
diff --git a/Sora/Data/Settings/Bookmark.swift b/Sora/Data/Settings/Bookmark.swift
new file mode 100644
index 0000000..2e6fc93
--- /dev/null
+++ b/Sora/Data/Settings/Bookmark.swift
@@ -0,0 +1,13 @@
+import Foundation
+
+struct Bookmark: Codable, Identifiable, Hashable {
+ let id: UUID
+ let tags: [String]
+ let createdAt: Date
+
+ init(id: UUID = UUID(), tags: [String]) {
+ createdAt = Date()
+ self.id = id
+ self.tags = tags
+ }
+}
diff --git a/Sora/Views/BookmarksView.swift b/Sora/Views/BookmarksView.swift
new file mode 100644
index 0000000..f98f949
--- /dev/null
+++ b/Sora/Views/BookmarksView.swift
@@ -0,0 +1,63 @@
+import SwiftUI
+
+struct BookmarksView: View {
+ @EnvironmentObject var settings: Settings
+ @EnvironmentObject var manager: MoebooruManager
+ @Binding var selectedTab: Int
+ @State private var bookmarksSearchText: String = ""
+
+ var filteredBookmarks: [Bookmark] {
+ guard !bookmarksSearchText.isEmpty else {
+ return settings.bookmarks
+ }
+
+ return settings.bookmarks
+ .filter { $0.tags.joined(separator: " ").lowercased().contains(bookmarksSearchText.lowercased()) }
+ }
+
+ var body: some View {
+ NavigationStack {
+ if settings.bookmarks.isEmpty {
+ VStack {
+ Spacer()
+
+ Text("There are no bookmarks yet. Add a bookmark by tapping the bookmark button in the bottom left corner of a search page.")
+ .padding()
+
+ Spacer()
+ }
+ } else {
+ List {
+ if filteredBookmarks.isEmpty {
+ Text("No bookmarks found.")
+ }
+
+ ForEach(filteredBookmarks, id: \.self) { bookmark in
+ Button(action: {
+ manager.searchText = bookmark.tags.joined(separator: " ")
+ manager.performSearch()
+ selectedTab = 0
+ }) {
+ HStack {
+ Text(bookmark.tags.joined(separator: ", "))
+
+ Text(bookmark.createdAt.formatted())
+ .foregroundColor(.secondary)
+ .font(.caption)
+ }
+ }
+ }
+ .onDelete(perform: settings.removeBookmark)
+ }
+ }
+ }
+ .navigationTitle("Bookmarks")
+ .searchable(text: $bookmarksSearchText)
+ }
+}
+
+#Preview {
+ BookmarksView(selectedTab: .constant(1))
+ .environmentObject(Settings())
+ .environmentObject(MoebooruManager())
+}
diff --git a/Sora/Views/ContentView.swift b/Sora/Views/ContentView.swift
index c8a361e..22c17f6 100644
--- a/Sora/Views/ContentView.swift
+++ b/Sora/Views/ContentView.swift
@@ -1,7 +1,7 @@
import SwiftUI
struct ContentView: View {
- @StateObject private var manager = MoebooruManager()
+ @EnvironmentObject private var manager: MoebooruManager
var body: some View {
#if os(macOS)
diff --git a/Sora/Views/MainView.swift b/Sora/Views/MainView.swift
index c657540..7ad7c77 100644
--- a/Sora/Views/MainView.swift
+++ b/Sora/Views/MainView.swift
@@ -2,17 +2,30 @@ import SwiftUI
struct MainView: View {
@EnvironmentObject var settings: Settings
+ @State private var selectedTab: Int = 0
+ @StateObject private var manager = MoebooruManager()
var body: some View {
#if os(macOS)
ContentView()
.environmentObject(settings)
#else
- TabView {
+ TabView(selection: $selectedTab) {
ContentView()
.tabItem {
Label("Posts", systemImage: "rectangle.stack")
}
+ .tag(0)
+ .environmentObject(manager)
+
+ NavigationStack {
+ BookmarksView(selectedTab: $selectedTab)
+ .environmentObject(manager)
+ }
+ .tabItem {
+ Label("Bookmarks", systemImage: "bookmark")
+ }
+ .tag(1)
NavigationStack {
SettingsView()
@@ -20,6 +33,7 @@ struct MainView: View {
.tabItem {
Label("Settings", systemImage: "gear")
}
+ .tag(2)
}
.environmentObject(settings)
#endif
diff --git a/Sora/Views/Post/PostGridView.swift b/Sora/Views/Post/PostGridView.swift
index 2eda971..487bde8 100644
--- a/Sora/Views/Post/PostGridView.swift
+++ b/Sora/Views/Post/PostGridView.swift
@@ -82,6 +82,22 @@ struct PostGridView: View {
}
}
#endif
+ .toolbar {
+ if !manager.tags.isEmpty {
+ ToolbarItem(placement: .bottomBar) {
+ let contained = settings.bookmarks.contains(where: { $0.tags == manager.tags })
+
+ Button(action: {
+ contained ? settings.removeBookmark(withTags: manager.tags) : settings.addBookmark(tags: manager.tags)
+ }) {
+ Label("Bookmark", systemImage:
+ contained ?
+ "bookmark.fill" :
+ "bookmark")
+ }
+ }
+ }
+ }
.navigationTitle("Posts")
.refreshable {
await manager.fetchPosts(page: 1, tags: manager.tags, replace: true)