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

struct ContentView: View {
  @EnvironmentObject var manager: BooruManager
  @Binding var selectedTab: Int
  @State private var viewStates: [UUID: PostGridViewState] = [:]
  @State private var viewStateSelection: UUID?
  @State private var columnVisibility = NavigationSplitViewVisibility.doubleColumn

  var sortedViewStates: [PostGridViewStateItem] {
    viewStates
      .map { PostGridViewStateItem(id: $0.key, state: $0.value) }
      .sorted { $0.state.createdAt > $1.state.createdAt }
  }

  var history: [UUID: BooruSearchQuery] {
    Dictionary(uniqueKeysWithValues: manager.searchHistory.map { ($0.id, $0) })
  }

  var body: some View {
    #if os(macOS)
      NavigationSplitView(columnVisibility: $columnVisibility) {
        List(selection: $viewStateSelection) {
          if viewStates.isEmpty {
            Text("No Tags")
              .tag(UUID.nilUUID())
          }

          ForEach(sortedViewStates, id: \.id) { item in
            if let entry = history[item.id] {
              let tags = entry.tags.joined(separator: " ")

              Text(tags.isEmpty ? "No Tags" : tags)
                .tag(item.id)
            }
          }
        }
      } content: {
        switch selectedTab {
        case 1:
          PostGridSearchHistoryView(
            selectedTab: $selectedTab,
            isPresented: .constant(false)
          )

        case 2:
          BookmarksView(selectedTab: $selectedTab)

        case 3:
          SettingsView()

        default:
          PostGridView(
            selectedTab: $selectedTab,
            viewStates: $viewStates,
            viewStateSelection: $viewStateSelection
          )
        }
      } detail: {
        if let post = manager.selectedPost {
          PostDetailsView(post: post)
        } else {
          Text("Select a Post")
            .foregroundColor(.secondary)
        }
      }
      .onChange(of: viewStateSelection) { _, newValue in
        guard let selectedID = newValue else { return }

        if let index = manager.searchHistory.firstIndex(where: { $0.id == selectedID }) {
          manager.historyIndex = index
        }
      }
      .onChange(of: sortedViewStates) { _, newKeys in
        if viewStateSelection == nil || !newKeys.contains(where: { $0.id == viewStateSelection }) {
          viewStateSelection = newKeys.first?.id ?? UUID.nilUUID()
        }
      }
      .onAppear {
        if viewStates.isEmpty && viewStateSelection == nil {
          viewStateSelection = UUID.nilUUID()
        }
      }
    #else
      NavigationStack {
        PostGridView(
          selectedTab: $selectedTab,
          viewStates: $viewStates,
          viewStateSelection: $viewStateSelection
        )
        .navigationDestination(
          isPresented: Binding(
            get: { manager.selectedPost != nil },
            set: { if !$0 { manager.selectedPost = nil } }
          )
        ) {
          if let post = manager.selectedPost { PostDetailsView(post: post) }
        }
      }
    #endif
  }
}