summaryrefslogtreecommitdiff
path: root/Sora/Views/FavoriteMenuButtonView.swift
blob: b6b99a913bbf051aafdabbc614acb4fba3f43b79 (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
import SwiftUI

struct FavoriteMenuButtonView: View {
  @EnvironmentObject var settings: SettingsManager
  @EnvironmentObject var manager: BooruManager
  let post: BooruPost
  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 isFavorited = settings.isFavorite(postId: post.id, provider: manager.provider)

    Menu {
      Button(action: {
        if isFavorited {
          settings.removeFavorite(withPostId: post.id, provider: manager.provider)
        } else {
          settings.addFavorite(post: post, provider: manager.provider)
        }
      }) {
        if isFavorited {
          Label("Remove from Favorites", systemImage: "heart.fill")
        } else {
          Label("Add to Favorites", systemImage: "heart")
        }
      }

      Menu {
        ForEach(settings.folders.filter { $0.topLevelName == nil }, id: \.id) { folder in
          Button(action: {
            settings.addFavorite(post: post, provider: manager.provider, folder: folder.id)
          }) {
            Label(folder.name, systemImage: "folder")
          }
          .disabled(isFavoritedInFolder(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.addFavorite(post: post, provider: manager.provider, folder: folder.id)
              }) {
                Text(folder.shortName)
              }
              .disabled(isFavoritedInFolder(folderId: folder.id))
            }
          } label: {
            Text(topLevelName)
          }
        }

        Button(action: {
          isNewCollectionAlertPresented = true
        }) {
          Label("New Collection", systemImage: "plus")
        }
        .disabled(disableNewCollection)
      } label: {
        Label("Favorite to Collection", systemImage: "folder.badge.plus")
      }
    } label: {
      if isFavorited {
        Label("Favorited", systemImage: "heart.fill")
      } else {
        Label("Favorite", systemImage: "heart")
      }
    }
    .collectionAlerts(
      isNewCollectionAlertPresented: $isNewCollectionAlertPresented,
      newCollectionName: $newCollectionName,
      isCollectionErrorAlertPresented: $isCollectionErrorAlertPresented
    ) { newCollectionName in
      let newFolder = SettingsFolder(name: newCollectionName)

      settings.folders.append(newFolder)

      settings.addFavorite(post: post, provider: manager.provider, folder: newFolder.id)
    }
  }

  private func isFavoritedInFolder(folderId: UUID) -> Bool {
    settings.favorites.contains { favorite in
      favorite.folder == folderId && favorite.postId == post.id
        && favorite.provider == manager.provider
    }
  }
}