summaryrefslogtreecommitdiff
path: root/Sora/Views/BookmarkMenuButtonView.swift
blob: 714448edd7232bb8c1c5938e82a58b820cf74571 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import SwiftUI

struct BookmarkMenuButtonView: View {
  @EnvironmentObject var settings: SettingsManager
  let tags: [String]
  let provider: BooruProvider
  var disableNewCollection = false
  @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 {
      ForEach(settings.folders.filter { $0.topLevelName == nil }, id: \.id) { folder in
        Button(action: {
          settings.addBookmark(provider: provider, tags: tags)

          if let bookmarkId = settings.bookmarks.first(where: { bookmark in
            bookmark.provider == provider
              && Set(bookmark.tags) == Set(tags.map { $0.lowercased() })
          })?.id {
            settings.updateBookmarkFolder(withID: bookmarkId, folder: folder.id)
          }
        }) {
          Label(folder.name, systemImage: "folder")
        }
        .disabled(isBookmarkedInFolder(folderId: folder.id))
      }

      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: {
              settings.addBookmark(provider: provider, tags: tags)

              if let bookmarkId = settings.bookmarks.first(where: { bookmark in
                bookmark.provider == provider
                  && Set(bookmark.tags) == Set(tags.map { $0.lowercased() })
              })?.id {
                settings.updateBookmarkFolder(withID: bookmarkId, folder: folder.id)
              }
            }) {
              Text(folder.shortName)
            }
            .disabled(isBookmarkedInFolder(folderId: folder.id))
          }
        } label: {
          Text(topLevelName)
        }
      }

      Button(action: {
        isNewCollectionAlertPresented = true
      }) {
        Label("New Collection", systemImage: "plus")
      }
      .disabled(disableNewCollection)
    } label: {
      if isBookmarked {
        Label("Bookmarked", systemImage: "bookmark.fill")
      } else {
        Label("Bookmark", systemImage: "bookmark")
      }

      // if isBookmarked {
      //   Label("Remove Bookmark", systemImage: "bookmark.fill")
      // } else {
      //   Label("Bookmark Tag\(tags.count == 1 ? "" : "s")", systemImage: "bookmark")
      // }
    } primaryAction: {
      if isBookmarked {
        settings.removeBookmark(withTags: tags)
      } else {
        settings.addBookmark(provider: provider, tags: tags)
      }
    }
    .collectionAlerts(
      isNewCollectionAlertPresented: $isNewCollectionAlertPresented,
      newCollectionName: $newCollectionName,
      isCollectionErrorAlertPresented: $isCollectionErrorAlertPresented
    ) { newCollectionName in
      let newFolder = SettingsFolder(name: newCollectionName)

      settings.folders.append(newFolder)
      settings.addBookmark(provider: provider, tags: tags)

      if let bookmarkId = settings.bookmarks.first(where: { bookmark in
        bookmark.provider == provider && Set(bookmark.tags) == Set(tags.map { $0.lowercased() })
      })?.id {
        settings.updateBookmarkFolder(withID: bookmarkId, folder: newFolder.id)
      }
    }
  }

  private func isBookmarkedInFolder(folderId: UUID) -> Bool {
    settings.bookmarks.contains { bookmark in
      bookmark.folder == folderId && Set(bookmark.tags) == Set(tags)
        && bookmark.provider == provider
    }
  }
}