Impressia/Vernissage/Views/MainView.swift

237 lines
8.1 KiB
Swift
Raw Normal View History

2022-12-29 08:06:21 +01:00
//
// https://mczachurski.dev
// Copyright © 2022 Marcin Czachurski and the repository contributors.
// Licensed under the MIT License.
//
import SwiftUI
import UIKit
import CoreData
2023-01-10 08:04:25 +01:00
import MastodonKit
2022-12-29 08:06:21 +01:00
struct MainView: View {
2023-01-12 18:34:48 +01:00
enum Sheet: String, Identifiable {
case settings, compose
var id: String { rawValue }
}
2022-12-29 08:06:21 +01:00
@Environment(\.managedObjectContext) private var viewContext
2023-02-03 15:16:30 +01:00
2022-12-30 18:20:54 +01:00
@EnvironmentObject var applicationState: ApplicationState
2023-02-03 15:16:30 +01:00
@EnvironmentObject var client: Client
2023-01-23 18:01:27 +01:00
@EnvironmentObject var routerPath: RouterPath
2023-01-12 18:34:48 +01:00
2022-12-30 18:20:54 +01:00
@State private var navBarTitle: String = "Home"
@State private var viewMode: ViewMode = .home {
didSet {
2022-12-31 16:31:05 +01:00
self.navBarTitle = self.getViewTitle(viewMode: viewMode)
2022-12-30 18:20:54 +01:00
}
}
2022-12-29 17:27:15 +01:00
2023-01-11 13:16:43 +01:00
@FetchRequest(sortDescriptors: [SortDescriptor(\.acct, order: .forward)]) var dbAccounts: FetchedResults<AccountData>
2022-12-30 18:20:54 +01:00
private enum ViewMode {
2023-01-23 11:42:28 +01:00
case home, local, federated, profile, notifications, trending
2022-12-30 18:20:54 +01:00
}
2022-12-29 08:06:21 +01:00
var body: some View {
2022-12-30 18:20:54 +01:00
self.getMainView()
.navigationBarTitle(navBarTitle)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
self.getLeadingToolbar()
self.getPrincipalToolbar()
2023-01-12 18:34:48 +01:00
self.getTrailingToolbar()
2022-12-30 18:20:54 +01:00
}
}
@ViewBuilder
private func getMainView() -> some View {
switch self.viewMode {
case .home:
HomeFeedView(accountId: applicationState.account?.id ?? String.empty())
.id(applicationState.account?.id ?? String.empty())
2023-01-23 11:42:28 +01:00
case .trending:
TrendStatusesView(accountId: applicationState.account?.id ?? String.empty())
.id(applicationState.account?.id ?? String.empty())
2022-12-30 18:20:54 +01:00
case .local:
2023-01-23 18:01:27 +01:00
StatusesView(listType: .local)
.id(applicationState.account?.id ?? String.empty())
2022-12-30 18:20:54 +01:00
case .federated:
2023-01-23 18:01:27 +01:00
StatusesView(listType: .federated)
.id(applicationState.account?.id ?? String.empty())
2023-01-05 21:08:19 +01:00
case .profile:
if let accountData = self.applicationState.account {
2023-01-05 21:08:19 +01:00
UserProfileView(accountId: accountData.id,
accountDisplayName: accountData.displayName,
2023-01-06 13:05:21 +01:00
accountUserName: accountData.acct)
.id(applicationState.account?.id ?? String.empty())
2023-01-05 21:08:19 +01:00
}
2022-12-30 18:20:54 +01:00
case .notifications:
if let accountData = self.applicationState.account {
2023-01-18 18:41:42 +01:00
NotificationsView(accountId: accountData.id)
.id(applicationState.account?.id ?? String.empty())
2023-01-18 18:41:42 +01:00
}
2022-12-30 18:20:54 +01:00
}
}
@ToolbarContentBuilder
private func getPrincipalToolbar() -> some ToolbarContent {
ToolbarItem(placement: .principal) {
Menu {
Button {
viewMode = .home
} label: {
HStack {
2022-12-31 16:31:05 +01:00
Text(self.getViewTitle(viewMode: .home))
2022-12-30 18:20:54 +01:00
Image(systemName: "house")
2022-12-29 17:27:15 +01:00
}
2022-12-30 18:20:54 +01:00
}
2023-01-23 11:42:28 +01:00
Button {
viewMode = .trending
} label: {
HStack {
Text(self.getViewTitle(viewMode: .trending))
Image(systemName: "chart.line.uptrend.xyaxis")
}
}
2022-12-30 18:20:54 +01:00
Button {
viewMode = .local
} label: {
HStack {
2022-12-31 16:31:05 +01:00
Text(self.getViewTitle(viewMode: .local))
2022-12-30 18:20:54 +01:00
Image(systemName: "text.redaction")
2022-12-29 17:27:15 +01:00
}
2022-12-30 18:20:54 +01:00
}
2022-12-29 17:27:15 +01:00
2022-12-30 18:20:54 +01:00
Button {
viewMode = .federated
2022-12-29 17:27:15 +01:00
} label: {
2022-12-30 18:20:54 +01:00
HStack {
2022-12-31 16:31:05 +01:00
Text(self.getViewTitle(viewMode: .federated))
2022-12-30 18:20:54 +01:00
Image(systemName: "globe.europe.africa")
}
2022-12-29 17:27:15 +01:00
}
2022-12-30 18:20:54 +01:00
2023-01-03 20:42:20 +01:00
Divider()
2023-01-05 21:08:19 +01:00
Button {
viewMode = .profile
} label: {
HStack {
Text(self.getViewTitle(viewMode: .profile))
Image(systemName: "person")
}
}
2023-01-03 20:42:20 +01:00
2022-12-29 17:27:15 +01:00
Button {
2022-12-30 18:20:54 +01:00
viewMode = .notifications
2022-12-29 17:27:15 +01:00
} label: {
2022-12-30 18:20:54 +01:00
HStack {
2022-12-31 16:31:05 +01:00
Text(self.getViewTitle(viewMode: .notifications))
2022-12-30 18:20:54 +01:00
Image(systemName: "bell.badge")
2022-12-29 17:27:15 +01:00
}
}
2022-12-30 18:20:54 +01:00
} label: {
HStack {
Text(navBarTitle)
.font(.headline)
Image(systemName: "chevron.down")
.font(.subheadline)
}
.frame(width: 150)
2023-01-06 13:05:21 +01:00
.foregroundColor(.mainTextColor)
2022-12-29 08:06:21 +01:00
}
}
2022-12-30 18:20:54 +01:00
}
@ToolbarContentBuilder
private func getLeadingToolbar() -> some ToolbarContent {
ToolbarItem(placement: .navigationBarLeading) {
2023-01-03 20:42:20 +01:00
Menu {
2023-01-11 13:16:43 +01:00
ForEach(self.dbAccounts) { account in
Button {
HapticService.shared.touch()
2023-02-03 15:16:30 +01:00
let accountModel = AccountModel(accountData: account)
self.applicationState.account = accountModel
self.client.setAccount(account: accountModel)
self.applicationState.lastSeenStatusId = account.lastSeenStatusId
self.applicationState.amountOfNewStatuses = 0
2023-01-29 19:11:44 +01:00
ApplicationSettingsHandler.shared.setAccountAsDefault(accountData: account)
2023-01-11 13:16:43 +01:00
} label: {
if self.applicationState.account?.id == account.id {
2023-01-11 13:16:43 +01:00
Label(account.displayName ?? account.acct, systemImage: "checkmark")
} else {
Text(account.displayName ?? account.acct)
}
2023-01-03 20:42:20 +01:00
}
}
Divider()
Button {
HapticService.shared.touch()
2023-01-23 18:01:27 +01:00
self.routerPath.presentedSheet = .settings
2023-01-03 20:42:20 +01:00
} label: {
2023-01-11 13:16:43 +01:00
Label("Settings", systemImage: "gear")
2023-01-03 20:42:20 +01:00
}
2022-12-30 18:20:54 +01:00
} label: {
if let avatarData = self.applicationState.account?.avatarData, let uiImage = UIImage(data: avatarData) {
2022-12-30 18:20:54 +01:00
Image(uiImage: uiImage)
.resizable()
2023-01-24 12:22:53 +01:00
.clipShape(self.applicationState.avatarShape.shape())
2022-12-31 16:31:05 +01:00
.frame(width: 32.0, height: 32.0)
2022-12-30 18:20:54 +01:00
} else {
2023-01-24 12:22:53 +01:00
Image(systemName: "person")
2022-12-31 16:31:05 +01:00
.resizable()
2023-01-24 12:22:53 +01:00
.frame(width: 16, height: 16)
.foregroundColor(.white)
.padding(8)
.background(Color.lightGrayColor)
.clipShape(AvatarShape.circle.shape())
.background(
AvatarShape.circle.shape()
)
2022-12-30 18:20:54 +01:00
}
2022-12-29 08:06:21 +01:00
}
}
}
2023-01-12 18:34:48 +01:00
@ToolbarContentBuilder
private func getTrailingToolbar() -> some ToolbarContent {
if viewMode == .local || viewMode == .home || viewMode == .federated {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
HapticService.shared.touch()
2023-01-23 18:01:27 +01:00
self.routerPath.presentedSheet = .newStatusEditor
} label: {
Image(systemName: "square.and.pencil")
.tint(.mainTextColor)
}
2023-01-12 18:34:48 +01:00
}
}
}
2022-12-31 16:31:05 +01:00
private func getViewTitle(viewMode: ViewMode) -> String {
switch viewMode {
case .home:
return "Home"
2023-01-23 11:42:28 +01:00
case .trending:
return "Trending"
2022-12-31 16:31:05 +01:00
case .local:
return "Local"
case .federated:
return "Federated"
2023-01-05 21:08:19 +01:00
case .profile:
return "Profile"
2022-12-31 16:31:05 +01:00
case .notifications:
return "Notifications"
2022-12-29 08:06:21 +01:00
}
}
}