#48 Add more icons to navigation bar
This commit is contained in:
parent
2b4b1966d5
commit
7a2c31b194
|
@ -32,6 +32,10 @@ extension ApplicationSettings {
|
|||
@NSManaged public var showAvatarsOnTimeline: Bool
|
||||
@NSManaged public var showFavouritesOnTimeline: Bool
|
||||
@NSManaged public var showAltIconOnTimeline: Bool
|
||||
|
||||
@NSManaged public var customNavigationMenuItem1: Int32
|
||||
@NSManaged public var customNavigationMenuItem2: Int32
|
||||
@NSManaged public var customNavigationMenuItem3: Int32
|
||||
}
|
||||
|
||||
extension ApplicationSettings: Identifiable {
|
||||
|
|
|
@ -165,6 +165,24 @@ class ApplicationSettingsHandler {
|
|||
CoreDataHandler.shared.save()
|
||||
}
|
||||
|
||||
func set(customNavigationMenuItem1: Int32) {
|
||||
let defaultSettings = self.get()
|
||||
defaultSettings.customNavigationMenuItem1 = customNavigationMenuItem1
|
||||
CoreDataHandler.shared.save()
|
||||
}
|
||||
|
||||
func set(customNavigationMenuItem2: Int32) {
|
||||
let defaultSettings = self.get()
|
||||
defaultSettings.customNavigationMenuItem2 = customNavigationMenuItem2
|
||||
CoreDataHandler.shared.save()
|
||||
}
|
||||
|
||||
func set(customNavigationMenuItem3: Int32) {
|
||||
let defaultSettings = self.get()
|
||||
defaultSettings.customNavigationMenuItem3 = customNavigationMenuItem3
|
||||
CoreDataHandler.shared.save()
|
||||
}
|
||||
|
||||
private func createApplicationSettingsEntity(viewContext: NSManagedObjectContext? = nil) -> ApplicationSettings {
|
||||
let context = viewContext ?? CoreDataHandler.shared.container.viewContext
|
||||
return ApplicationSettings(context: context)
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>_XCCurrentVersionName</key>
|
||||
<string>Vernissage-010.xcdatamodel</string>
|
||||
<string>Vernissage-011.xcdatamodel</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21754" systemVersion="22E261" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="AccountData" representedClassName="AccountData" syncable="YES">
|
||||
<attribute name="accessToken" optional="YES" attributeType="String"/>
|
||||
<attribute name="acct" attributeType="String"/>
|
||||
<attribute name="avatar" optional="YES" attributeType="URI"/>
|
||||
<attribute name="avatarData" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="clientId" attributeType="String"/>
|
||||
<attribute name="clientSecret" attributeType="String"/>
|
||||
<attribute name="clientVapidKey" attributeType="String"/>
|
||||
<attribute name="createdAt" attributeType="String"/>
|
||||
<attribute name="displayName" optional="YES" attributeType="String"/>
|
||||
<attribute name="followersCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="followingCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="header" optional="YES" attributeType="URI"/>
|
||||
<attribute name="id" attributeType="String"/>
|
||||
<attribute name="lastSeenStatusId" optional="YES" attributeType="String"/>
|
||||
<attribute name="locked" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="note" optional="YES" attributeType="String"/>
|
||||
<attribute name="refreshToken" optional="YES" attributeType="String"/>
|
||||
<attribute name="serverUrl" attributeType="URI"/>
|
||||
<attribute name="statusesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="url" optional="YES" attributeType="URI"/>
|
||||
<attribute name="username" attributeType="String"/>
|
||||
<relationship name="statuses" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="StatusData" inverseName="pixelfedAccount" inverseEntity="StatusData"/>
|
||||
</entity>
|
||||
<entity name="ApplicationSettings" representedClassName="ApplicationSettings" syncable="YES">
|
||||
<attribute name="activeIcon" attributeType="String" defaultValueString="Default"/>
|
||||
<attribute name="avatarShape" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="YES"/>
|
||||
<attribute name="currentAccount" optional="YES" attributeType="String"/>
|
||||
<attribute name="customNavigationMenuItem1" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="YES"/>
|
||||
<attribute name="customNavigationMenuItem2" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="YES"/>
|
||||
<attribute name="customNavigationMenuItem3" attributeType="Integer 32" defaultValueString="5" usesScalarValueType="YES"/>
|
||||
<attribute name="hapticAnimationEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="hapticButtonPressEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="hapticNotificationEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="hapticRefreshEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="hapticTabSelectionEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="lastRefreshTokens" attributeType="Date" defaultDateTimeInterval="694256400" usesScalarValueType="NO"/>
|
||||
<attribute name="menuPosition" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="YES"/>
|
||||
<attribute name="showAltIconOnTimeline" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="showAvatarsOnTimeline" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="showFavouritesOnTimeline" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="showPhotoDescription" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="showSensitive" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="theme" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="tintColor" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="YES"/>
|
||||
</entity>
|
||||
<entity name="AttachmentData" representedClassName="AttachmentData" syncable="YES">
|
||||
<attribute name="blurhash" optional="YES" attributeType="String"/>
|
||||
<attribute name="data" optional="YES" attributeType="Binary" allowsExternalBinaryDataStorage="YES"/>
|
||||
<attribute name="exifCamera" optional="YES" attributeType="String"/>
|
||||
<attribute name="exifCreatedDate" optional="YES" attributeType="String"/>
|
||||
<attribute name="exifExposure" optional="YES" attributeType="String"/>
|
||||
<attribute name="exifLens" optional="YES" attributeType="String"/>
|
||||
<attribute name="id" attributeType="String"/>
|
||||
<attribute name="metaImageHeight" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="metaImageWidth" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="previewUrl" optional="YES" attributeType="URI"/>
|
||||
<attribute name="remoteUrl" optional="YES" attributeType="URI"/>
|
||||
<attribute name="statusId" attributeType="String"/>
|
||||
<attribute name="text" optional="YES" attributeType="String"/>
|
||||
<attribute name="type" attributeType="String"/>
|
||||
<attribute name="url" attributeType="URI"/>
|
||||
<relationship name="statusRelation" maxCount="1" deletionRule="Nullify" destinationEntity="StatusData" inverseName="attachmentsRelation" inverseEntity="StatusData"/>
|
||||
</entity>
|
||||
<entity name="StatusData" representedClassName="StatusData" syncable="YES">
|
||||
<attribute name="accountAvatar" optional="YES" attributeType="URI"/>
|
||||
<attribute name="accountDisplayName" optional="YES" attributeType="String"/>
|
||||
<attribute name="accountId" attributeType="String"/>
|
||||
<attribute name="accountUsername" optional="YES" attributeType="String"/>
|
||||
<attribute name="applicationName" optional="YES" attributeType="String"/>
|
||||
<attribute name="applicationWebsite" optional="YES" attributeType="URI"/>
|
||||
<attribute name="bookmarked" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="content" attributeType="String"/>
|
||||
<attribute name="createdAt" attributeType="String"/>
|
||||
<attribute name="favourited" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="favouritesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="id" attributeType="String"/>
|
||||
<attribute name="inReplyToAccount" optional="YES" attributeType="String"/>
|
||||
<attribute name="inReplyToId" optional="YES" attributeType="String"/>
|
||||
<attribute name="muted" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="pinned" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="reblogged" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="rebloggedAccountAvatar" optional="YES" attributeType="URI"/>
|
||||
<attribute name="rebloggedAccountDisplayName" optional="YES" attributeType="String"/>
|
||||
<attribute name="rebloggedAccountId" optional="YES" attributeType="String"/>
|
||||
<attribute name="rebloggedAccountUsername" optional="YES" attributeType="String"/>
|
||||
<attribute name="rebloggedStatusId" optional="YES" attributeType="String"/>
|
||||
<attribute name="reblogsCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="repliesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="sensitive" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="spoilerText" optional="YES" attributeType="String"/>
|
||||
<attribute name="uri" attributeType="String"/>
|
||||
<attribute name="url" optional="YES" attributeType="URI"/>
|
||||
<attribute name="visibility" attributeType="String"/>
|
||||
<relationship name="attachmentsRelation" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="AttachmentData" inverseName="statusRelation" inverseEntity="AttachmentData"/>
|
||||
<relationship name="pixelfedAccount" maxCount="1" deletionRule="Nullify" destinationEntity="AccountData" inverseName="statuses" inverseEntity="AccountData"/>
|
||||
</entity>
|
||||
</model>
|
|
@ -84,6 +84,7 @@
|
|||
F86B7221296C49A300EE59EC /* EmptyButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = F86B7220296C49A300EE59EC /* EmptyButtonStyle.swift */; };
|
||||
F86BC9E929EBBB67009415EC /* ImageSaver.swift in Sources */ = {isa = PBXBuildFile; fileRef = F86BC9E829EBBB66009415EC /* ImageSaver.swift */; };
|
||||
F86BC9EB29EBDA2E009415EC /* ActivityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F86BC9EA29EBDA2E009415EC /* ActivityView.swift */; };
|
||||
F871F21D29EF0D7000A351EF /* NavigationMenuItemDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = F871F21C29EF0D7000A351EF /* NavigationMenuItemDetails.swift */; };
|
||||
F8742FC429990AFB00E9642B /* ClientError.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8742FC329990AFB00E9642B /* ClientError.swift */; };
|
||||
F8764187298ABB520057D362 /* ViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8764186298ABB520057D362 /* ViewState.swift */; };
|
||||
F876418D298AE5020057D362 /* PaginableStatusesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F876418C298AE5020057D362 /* PaginableStatusesView.swift */; };
|
||||
|
@ -277,6 +278,8 @@
|
|||
F86B7220296C49A300EE59EC /* EmptyButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyButtonStyle.swift; sourceTree = "<group>"; };
|
||||
F86BC9E829EBBB66009415EC /* ImageSaver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageSaver.swift; sourceTree = "<group>"; };
|
||||
F86BC9EA29EBDA2E009415EC /* ActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityView.swift; sourceTree = "<group>"; };
|
||||
F871F21C29EF0D7000A351EF /* NavigationMenuItemDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationMenuItemDetails.swift; sourceTree = "<group>"; };
|
||||
F871F21F29EF0FEC00A351EF /* Vernissage-011.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Vernissage-011.xcdatamodel"; sourceTree = "<group>"; };
|
||||
F8742FC329990AFB00E9642B /* ClientError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientError.swift; sourceTree = "<group>"; };
|
||||
F8764186298ABB520057D362 /* ViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewState.swift; sourceTree = "<group>"; };
|
||||
F876418C298AE5020057D362 /* PaginableStatusesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginableStatusesView.swift; sourceTree = "<group>"; };
|
||||
|
@ -483,6 +486,7 @@
|
|||
F85D4DFD29B78C8400345267 /* HashtagModel.swift */,
|
||||
F89F57AF29D1C11200001EE3 /* RelationshipModel.swift */,
|
||||
F8DF38E329DD68820047F1AA /* ViewOffsetKey.swift */,
|
||||
F871F21C29EF0D7000A351EF /* NavigationMenuItemDetails.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1065,6 +1069,7 @@
|
|||
F8742FC429990AFB00E9642B /* ClientError.swift in Sources */,
|
||||
F883402029B62AE900C3E096 /* SearchView.swift in Sources */,
|
||||
F88FAD2A295F43B8009B20C9 /* AccountData+CoreDataClass.swift in Sources */,
|
||||
F871F21D29EF0D7000A351EF /* NavigationMenuItemDetails.swift in Sources */,
|
||||
F85DBF8F296732E20069BF89 /* AccountsView.swift in Sources */,
|
||||
F805DCF129DBEF83006A1FD9 /* ReportView.swift in Sources */,
|
||||
F8B0886029943498002AB40A /* OtherSectionView.swift in Sources */,
|
||||
|
@ -1624,6 +1629,7 @@
|
|||
F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */ = {
|
||||
isa = XCVersionGroup;
|
||||
children = (
|
||||
F871F21F29EF0FEC00A351EF /* Vernissage-011.xcdatamodel */,
|
||||
F85B586C29ED169B00A16D12 /* Vernissage-010.xcdatamodel */,
|
||||
F8FFBD4929E99BEE0047EE80 /* Vernissage-009.xcdatamodel */,
|
||||
F8A4A88429E4099900267E36 /* Vernissage-008.xcdatamodel */,
|
||||
|
@ -1636,7 +1642,7 @@
|
|||
F8C937A929882CA90004D782 /* Vernissage-001.xcdatamodel */,
|
||||
F88C2477295C37BB0006098B /* Vernissage.xcdatamodel */,
|
||||
);
|
||||
currentVersion = F85B586C29ED169B00A16D12 /* Vernissage-010.xcdatamodel */;
|
||||
currentVersion = F871F21F29EF0FEC00A351EF /* Vernissage-011.xcdatamodel */;
|
||||
path = Vernissage.xcdatamodeld;
|
||||
sourceTree = "<group>";
|
||||
versionGroupType = wrapper.xcdatamodel;
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// https://mczachurski.dev
|
||||
// Copyright © 2023 Marcin Czachurski and the repository contributors.
|
||||
// Licensed under the Apache License 2.0.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class NavigationMenuItemDetails: ObservableObject, Identifiable {
|
||||
let id: Int32
|
||||
|
||||
@Published var viewMode: MainView.ViewMode
|
||||
@Published var title: String
|
||||
@Published var image: String
|
||||
|
||||
init(id: Int32, viewMode: MainView.ViewMode, title: String, image: String) {
|
||||
self.id = id
|
||||
self.viewMode = viewMode
|
||||
self.title = title
|
||||
self.image = image
|
||||
}
|
||||
}
|
|
@ -9,10 +9,11 @@ import SwiftUI
|
|||
import EnvironmentKit
|
||||
import ServicesKit
|
||||
|
||||
public extension View {
|
||||
extension View {
|
||||
func navigationMenu<MenuItems>(menuPosition: Binding<MenuPosition>,
|
||||
onViewModeIconTap: @escaping (MainView.ViewMode) -> Void,
|
||||
@ViewBuilder menuItems: @escaping () -> MenuItems) -> some View where MenuItems: View {
|
||||
modifier(NavigationMenu(menuPosition: menuPosition, menuItems: menuItems))
|
||||
modifier(NavigationMenu(menuPosition: menuPosition, onViewModeIconTap: onViewModeIconTap, menuItems: menuItems))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,10 +21,29 @@ private struct NavigationMenu<MenuItems>: ViewModifier where MenuItems: View {
|
|||
@EnvironmentObject var routerPath: RouterPath
|
||||
|
||||
private let menuItems: () -> MenuItems
|
||||
private let onViewModeIconTap: (MainView.ViewMode) -> Void
|
||||
private let imageFontSize = 20.0
|
||||
|
||||
private let customMenuItems = [
|
||||
NavigationMenuItemDetails(id: 1, viewMode: .home, title: "mainview.tab.homeTimeline", image: "house"),
|
||||
NavigationMenuItemDetails(id: 2, viewMode: .local, title: "mainview.tab.localTimeline", image: "building"),
|
||||
NavigationMenuItemDetails(id: 3, viewMode: .federated, title: "mainview.tab.federatedTimeline", image: "globe.europe.africa"),
|
||||
NavigationMenuItemDetails(id: 4, viewMode: .search, title: "mainview.tab.search", image: "magnifyingglass"),
|
||||
NavigationMenuItemDetails(id: 5, viewMode: .profile, title: "mainview.tab.userProfile", image: "person.crop.circle"),
|
||||
NavigationMenuItemDetails(id: 6, viewMode: .notifications, title: "mainview.tab.notifications", image: "bell.badge")
|
||||
]
|
||||
|
||||
@State private var selectedCustomMenuItems = [
|
||||
NavigationMenuItemDetails(id: 1, viewMode: .home, title: "mainview.tab.homeTimeline", image: "house"),
|
||||
NavigationMenuItemDetails(id: 2, viewMode: .local, title: "mainview.tab.localTimeline", image: "building"),
|
||||
NavigationMenuItemDetails(id: 3, viewMode: .profile, title: "mainview.tab.userProfile", image: "person.crop.circle")
|
||||
]
|
||||
|
||||
@Binding var menuPosition: MenuPosition
|
||||
|
||||
init(menuPosition: Binding<MenuPosition>, @ViewBuilder menuItems: @escaping () -> MenuItems) {
|
||||
init(menuPosition: Binding<MenuPosition>, onViewModeIconTap: @escaping (MainView.ViewMode) -> Void, @ViewBuilder menuItems: @escaping () -> MenuItems) {
|
||||
self.menuItems = menuItems
|
||||
self.onViewModeIconTap = onViewModeIconTap
|
||||
self._menuPosition = menuPosition
|
||||
}
|
||||
|
||||
|
@ -54,27 +74,50 @@ private struct NavigationMenu<MenuItems>: ViewModifier where MenuItems: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
self.loadCustomMenuItems()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func menuContainerView() -> some View {
|
||||
HStack(alignment: .center) {
|
||||
if self.menuPosition == .bottomRight {
|
||||
self.contextMenuView()
|
||||
self.composeImageView()
|
||||
}
|
||||
if self.menuPosition == .bottomRight {
|
||||
HStack(alignment: .center) {
|
||||
HStack {
|
||||
self.contextMenuView()
|
||||
self.customMenuItemsView()
|
||||
}
|
||||
.frame(height: 50)
|
||||
.padding(.horizontal, 8)
|
||||
.background(.ultraThinMaterial)
|
||||
.clipShape(Capsule())
|
||||
|
||||
if self.menuPosition == .bottomLeft {
|
||||
self.composeImageView()
|
||||
self.contextMenuView()
|
||||
.frame(height: 50)
|
||||
.padding(.horizontal, 8)
|
||||
.background(.ultraThinMaterial)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
} else {
|
||||
HStack(alignment: .center) {
|
||||
self.composeImageView()
|
||||
.frame(height: 50)
|
||||
.padding(.horizontal, 8)
|
||||
.background(.ultraThinMaterial)
|
||||
.clipShape(Circle())
|
||||
|
||||
HStack {
|
||||
self.customMenuItemsView()
|
||||
self.contextMenuView()
|
||||
}
|
||||
.frame(height: 50)
|
||||
.padding(.horizontal, 8)
|
||||
.background(.ultraThinMaterial)
|
||||
.clipShape(Capsule())
|
||||
}
|
||||
}
|
||||
.frame(height: 44)
|
||||
.padding(.horizontal, 8)
|
||||
.background(.ultraThinMaterial)
|
||||
.clipShape(Capsule())
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
|
@ -83,23 +126,90 @@ private struct NavigationMenu<MenuItems>: ViewModifier where MenuItems: View {
|
|||
self.menuItems()
|
||||
} label: {
|
||||
Image(systemName: "ellipsis")
|
||||
.font(.system(size: 26))
|
||||
.font(.system(size: self.imageFontSize))
|
||||
.foregroundColor(.mainTextColor.opacity(0.75))
|
||||
.padding(.vertical, 10)
|
||||
.padding(.horizontal, 8)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func customMenuItemsView() -> some View {
|
||||
ForEach(self.selectedCustomMenuItems) { item in
|
||||
self.customMenuItemView(customMenuItem: item)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func composeImageView() -> some View {
|
||||
Button {
|
||||
HapticService.shared.fireHaptic(of: .buttonPress)
|
||||
self.routerPath.presentedSheet = .newStatusEditor
|
||||
} label: {
|
||||
Image(systemName: "plus")
|
||||
.font(.system(size: 26))
|
||||
.font(.system(size: self.imageFontSize))
|
||||
.foregroundColor(.mainTextColor.opacity(0.75))
|
||||
.padding(.vertical, 10)
|
||||
.padding(.horizontal, 8)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func customMenuItemView(customMenuItem: NavigationMenuItemDetails) -> some View {
|
||||
Button {
|
||||
self.onViewModeIconTap(customMenuItem.viewMode)
|
||||
} label: {
|
||||
Image(systemName: customMenuItem.image)
|
||||
.font(.system(size: self.imageFontSize))
|
||||
.foregroundColor(.mainTextColor.opacity(0.75))
|
||||
.padding(.vertical, 10)
|
||||
.padding(.horizontal, 8)
|
||||
}.contextMenu {
|
||||
self.listOfIconsView(customMenuItem: customMenuItem)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func listOfIconsView(customMenuItem: NavigationMenuItemDetails) -> some View {
|
||||
ForEach(self.customMenuItems) { item in
|
||||
Button {
|
||||
withAnimation {
|
||||
customMenuItem.title = item.title
|
||||
customMenuItem.viewMode = item.viewMode
|
||||
customMenuItem.image = item.image
|
||||
}
|
||||
|
||||
// Saving in core data.
|
||||
switch customMenuItem.id {
|
||||
case 1:
|
||||
ApplicationSettingsHandler.shared.set(customNavigationMenuItem1: item.id)
|
||||
case 2:
|
||||
ApplicationSettingsHandler.shared.set(customNavigationMenuItem2: item.id)
|
||||
case 3:
|
||||
ApplicationSettingsHandler.shared.set(customNavigationMenuItem3: item.id)
|
||||
default:
|
||||
break
|
||||
}
|
||||
} label: {
|
||||
Label(NSLocalizedString(item.title, comment: "Custom menu item"), systemImage: item.image)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func loadCustomMenuItems() {
|
||||
let applicationSettings = ApplicationSettingsHandler.shared.get()
|
||||
|
||||
self.setCustomMenuItem(menuId: 1, savedId: Int(applicationSettings.customNavigationMenuItem1))
|
||||
self.setCustomMenuItem(menuId: 2, savedId: Int(applicationSettings.customNavigationMenuItem2))
|
||||
self.setCustomMenuItem(menuId: 3, savedId: Int(applicationSettings.customNavigationMenuItem3))
|
||||
}
|
||||
|
||||
private func setCustomMenuItem(menuId: Int, savedId: Int) {
|
||||
if let selectedCustomMenuItem = self.selectedCustomMenuItems.first(where: { $0.id == menuId }),
|
||||
let customMenuItem = self.customMenuItems.first(where: { $0.id == savedId }) {
|
||||
selectedCustomMenuItem.title = customMenuItem.title
|
||||
selectedCustomMenuItem.viewMode = customMenuItem.viewMode
|
||||
selectedCustomMenuItem.image = customMenuItem.image
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,15 +29,17 @@ struct MainView: View {
|
|||
|
||||
@FetchRequest(sortDescriptors: [SortDescriptor(\.acct, order: .forward)]) var dbAccounts: FetchedResults<AccountData>
|
||||
|
||||
private enum ViewMode {
|
||||
public enum ViewMode {
|
||||
case home, local, federated, profile, notifications, trendingPhotos, trendingTags, trendingAccounts, search
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
self.getMainView()
|
||||
.navigationMenu(menuPosition: $applicationState.menuPosition) {
|
||||
.navigationMenu(menuPosition: $applicationState.menuPosition, onViewModeIconTap: { viewMode in
|
||||
self.switchView(to: viewMode)
|
||||
}, menuItems: {
|
||||
self.navigationMenuContent()
|
||||
}
|
||||
})
|
||||
.navigationTitle(navBarTitle)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
|
|
Loading…
Reference in New Issue