summaryrefslogtreecommitdiff
path: root/Sora
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-07-08 06:05:10 -0700
committerFuwn <[email protected]>2025-07-08 06:21:44 -0700
commitf7ed210669cd0384438b45b8fa0894d3746b8399 (patch)
tree1b0140d3ec2bfe8ae8d33aba079ce47f2561b203 /Sora
parentfeat: Development commit (diff)
downloadsora-testing-f7ed210669cd0384438b45b8fa0894d3746b8399.tar.xz
sora-testing-f7ed210669cd0384438b45b8fa0894d3746b8399.zip
feat: Development commit
Diffstat (limited to 'Sora')
-rw-r--r--Sora/Views/BookmarkMenuButtonView.swift99
-rw-r--r--Sora/Views/Generic/CollectionAlertsModifier.swift59
-rw-r--r--Sora/Views/Generic/GenericListView.swift44
-rw-r--r--Sora/Views/Post/Details/PostDetailsTagsView.swift18
-rw-r--r--Sora/Views/Post/Grid/PostGridBookmarkButtonView.swift21
5 files changed, 171 insertions, 70 deletions
diff --git a/Sora/Views/BookmarkMenuButtonView.swift b/Sora/Views/BookmarkMenuButtonView.swift
new file mode 100644
index 0000000..287d7b7
--- /dev/null
+++ b/Sora/Views/BookmarkMenuButtonView.swift
@@ -0,0 +1,99 @@
+import SwiftUI
+
+struct BookmarkMenuButtonView: View {
+ @EnvironmentObject var settings: SettingsManager
+ let tags: [String]
+ let provider: BooruProvider
+ @State private var isNewCollectionAlertPresented = false
+ @State private var newCollectionName = ""
+ @State private var itemPendingCollectionAssignment: UUID?
+ @State private var isCollectionErrorAlertPresented = false
+
+ var body: some View {
+ let isBookmarked = settings.bookmarks.contains { bookmark in
+ Set(bookmark.tags) == Set(tags)
+ }
+
+ Menu {
+ Button(action: {
+ if isBookmarked {
+ settings.removeBookmark(withTags: tags)
+ } else {
+ settings.addBookmark(provider: provider, tags: tags)
+ }
+ }) {
+ if isBookmarked {
+ Label("Remove Bookmark\(tags.count == 1 ? "" : "s")", systemImage: "bookmark.fill")
+ } else {
+ Label("Bookmark Tag\(tags.count == 1 ? "" : "s")", systemImage: "bookmark")
+ }
+ }
+
+ Menu {
+ ForEach(settings.folders.filter { $0.topLevelName == nil }, id: \.id) { folder in
+ Button(action: {
+ let newBookmark = SettingsBookmark(provider: provider, tags: tags, folder: folder.id)
+
+ settings.bookmarks.append(newBookmark)
+ }) {
+ Label(folder.name, systemImage: "folder")
+ }
+ }
+
+ let topLevelFolders = settings.folders
+ .reduce(into: [String: [SettingsFolder]]()) { result, folder in
+ guard let topLevelName = folder.topLevelName else { return }
+
+ result[topLevelName, default: []].append(folder)
+ }
+
+ ForEach(topLevelFolders.keys.sorted(), id: \.self) { topLevelName in
+ Menu {
+ ForEach(topLevelFolders[topLevelName] ?? [], id: \.id) { folder in
+ Button(action: {
+ let newBookmark = SettingsBookmark(
+ provider: provider,
+ tags: tags,
+ folder: folder.id
+ )
+
+ settings.bookmarks.append(newBookmark)
+ }) {
+ Text(folder.shortName)
+ }
+ }
+ } label: {
+ Text(topLevelName)
+ }
+ }
+
+ Button(action: {
+ isNewCollectionAlertPresented = true
+ }) {
+ Label("New Collection", systemImage: "plus")
+ }
+ } label: {
+ Label("Bookmark to Collection", systemImage: "folder.badge.plus")
+ }
+ } label: {
+ if isBookmarked {
+ Label("Bookmarked", systemImage: "bookmark.fill")
+ } else {
+ Label("Bookmark", systemImage: "bookmark")
+ }
+ }
+ .collectionAlerts(
+ isNewCollectionAlertPresented: $isNewCollectionAlertPresented,
+ newCollectionName: $newCollectionName,
+ isCollectionErrorAlertPresented: $isCollectionErrorAlertPresented
+ ) { newCollectionName in
+ let newFolder = SettingsFolder(name: newCollectionName)
+
+ settings.folders.append(newFolder)
+
+ let newBookmark = SettingsBookmark(provider: provider, tags: tags, folder: newFolder.id)
+
+ settings.bookmarks.append(newBookmark)
+ }
+ }
+}
diff --git a/Sora/Views/Generic/CollectionAlertsModifier.swift b/Sora/Views/Generic/CollectionAlertsModifier.swift
new file mode 100644
index 0000000..6c39da8
--- /dev/null
+++ b/Sora/Views/Generic/CollectionAlertsModifier.swift
@@ -0,0 +1,59 @@
+import SwiftUI
+
+struct CollectionAlertsModifier: ViewModifier {
+ @Binding var isNewCollectionAlertPresented: Bool
+ @Binding var newCollectionName: String
+ @Binding var isCollectionErrorAlertPresented: Bool
+ let onCreate: (String) -> Void
+
+ func body(content: Content) -> some View {
+ content
+ .alert(
+ "New Collection",
+ isPresented: $isNewCollectionAlertPresented
+ ) {
+ TextField("Collection Name", text: $newCollectionName)
+
+ Button("Cancel") {
+ newCollectionName = ""
+ isNewCollectionAlertPresented = false
+ }
+
+ Button("Create") {
+ if newCollectionName.isEmpty {
+ isCollectionErrorAlertPresented = true
+ } else {
+ onCreate(newCollectionName)
+ newCollectionName = ""
+ isNewCollectionAlertPresented = false
+ }
+ }
+ }
+ .alert(
+ "Error",
+ isPresented: $isCollectionErrorAlertPresented
+ ) {
+ Button("OK", role: .cancel) { () }
+ } message: {
+ Text("Collection name cannot be empty.")
+ }
+ }
+}
+
+extension View {
+ func collectionAlerts(
+ isNewCollectionAlertPresented: Binding<Bool>,
+ newCollectionName: Binding<String>,
+ isCollectionErrorAlertPresented: Binding<Bool>,
+ onCreate: @escaping (String) -> Void
+ ) -> some View {
+ modifier(
+ CollectionAlertsModifier(
+ isNewCollectionAlertPresented: isNewCollectionAlertPresented,
+ newCollectionName: newCollectionName,
+ isCollectionErrorAlertPresented: isCollectionErrorAlertPresented,
+ onCreate: onCreate
+ )
+ )
+ }
+}
diff --git a/Sora/Views/Generic/GenericListView.swift b/Sora/Views/Generic/GenericListView.swift
index 0945b82..53ad364 100644
--- a/Sora/Views/Generic/GenericListView.swift
+++ b/Sora/Views/Generic/GenericListView.swift
@@ -298,42 +298,20 @@ struct GenericListView<T: Identifiable & Hashable & GenericItem>: View {
Button("Cancel", role: .cancel) { () }
}
- .alert(
- "New Collection",
- isPresented: $isNewCollectionAlertPresented
- ) {
- TextField("Collection Name", text: $newCollectionName)
+ .collectionAlerts(
+ isNewCollectionAlertPresented: $isNewCollectionAlertPresented,
+ newCollectionName: $newCollectionName,
+ isCollectionErrorAlertPresented: $isCollectionErrorAlertPresented
+ ) { newCollectionName in
+ let newFolder = SettingsFolder(name: newCollectionName)
- Button("Cancel") {
- newCollectionName = ""
- isNewCollectionAlertPresented = false
- }
+ settings.folders.append(newFolder)
- Button("Create") {
- if newCollectionName.isEmpty {
- isCollectionErrorAlertPresented = true
- } else {
- let newFolder = SettingsFolder(name: newCollectionName)
-
- settings.folders.append(newFolder)
-
- if let id = itemPendingCollectionAssignment {
- settings.updateBookmarkFolder(withID: id, folder: newFolder.id)
- }
-
- itemPendingCollectionAssignment = nil
- newCollectionName = ""
- isNewCollectionAlertPresented = false
- }
+ if let id = itemPendingCollectionAssignment {
+ settings.updateBookmarkFolder(withID: id, folder: newFolder.id)
}
- }
- .alert(
- "Error",
- isPresented: $isCollectionErrorAlertPresented,
- ) {
- Button("OK", role: .cancel) { () }
- } message: {
- Text("Collection name cannot be empty.")
+
+ itemPendingCollectionAssignment = nil
}
}
diff --git a/Sora/Views/Post/Details/PostDetailsTagsView.swift b/Sora/Views/Post/Details/PostDetailsTagsView.swift
index a8c3abc..4cd8840 100644
--- a/Sora/Views/Post/Details/PostDetailsTagsView.swift
+++ b/Sora/Views/Post/Details/PostDetailsTagsView.swift
@@ -7,8 +7,6 @@ struct PostDetailsTagsView: View {
var tags: [String]
var body: some View {
- let bookmarkedTags = Set(settings.bookmarks.flatMap(\.tags))
-
List {
ForEach(tags, id: \.self) { tag in
Button(action: {
@@ -34,21 +32,7 @@ struct PostDetailsTagsView: View {
}
}
- let isBookmarked = bookmarkedTags.contains(tag)
-
- Button(action: {
- if isBookmarked {
- settings.removeBookmark(withTags: tags)
- } else {
- settings.addBookmark(provider: settings.preferredBooru, tags: [tag])
- }
- }) {
- if isBookmarked {
- Label("Unbookmark Tag", systemImage: "bookmark.fill")
- } else {
- Label("Bookmark Tag", systemImage: "bookmark")
- }
- }
+ BookmarkMenuButtonView(tags: [tag], provider: settings.preferredBooru)
}
}
#if os(macOS)
diff --git a/Sora/Views/Post/Grid/PostGridBookmarkButtonView.swift b/Sora/Views/Post/Grid/PostGridBookmarkButtonView.swift
index 8c1c097..8f2effc 100644
--- a/Sora/Views/Post/Grid/PostGridBookmarkButtonView.swift
+++ b/Sora/Views/Post/Grid/PostGridBookmarkButtonView.swift
@@ -15,25 +15,6 @@ struct PostGridBookmarkButtonView: View {
}
var body: some View {
- Button(
- action: {
- contained
- ? settings
- .removeBookmark(withTags: manager.tags)
- : settings
- .addBookmark(
- provider: manager.provider,
- tags: manager.tags
- )
- }
- ) {
- let isBookmarked = settings.bookmarks.contains { $0.tags == manager.tags }
-
- Label(
- isBookmarked ? "Remove Bookmark" : "Bookmark",
- systemImage:
- contained ? "bookmark.fill" : "bookmark"
- )
- }
+ BookmarkMenuButtonView(tags: manager.tags, provider: manager.provider)
}
}