mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-26 02:01:02 +00:00
Redesigned settings tab
This commit is contained in:
parent
03afa1f978
commit
7f5330f284
13 changed files with 171 additions and 103 deletions
|
@ -30,6 +30,7 @@
|
||||||
9F7335EF29674F7100AFF0BA /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F7335EE29674F7100AFF0BA /* QuickLook.framework */; };
|
9F7335EF29674F7100AFF0BA /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F7335EE29674F7100AFF0BA /* QuickLook.framework */; };
|
||||||
9F7335F22967608F00AFF0BA /* AddRemoteTimelineVIew.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7335F12967608F00AFF0BA /* AddRemoteTimelineVIew.swift */; };
|
9F7335F22967608F00AFF0BA /* AddRemoteTimelineVIew.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7335F12967608F00AFF0BA /* AddRemoteTimelineVIew.swift */; };
|
||||||
9F7335F72968274500AFF0BA /* AppAccountsSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7335F62968274500AFF0BA /* AppAccountsSelectorView.swift */; };
|
9F7335F72968274500AFF0BA /* AppAccountsSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7335F62968274500AFF0BA /* AppAccountsSelectorView.swift */; };
|
||||||
|
9F7335F92968576500AFF0BA /* DisplaySettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7335F82968576500AFF0BA /* DisplaySettingsView.swift */; };
|
||||||
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAE4ACA293783B000772766 /* SettingsTab.swift */; };
|
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAE4ACA293783B000772766 /* SettingsTab.swift */; };
|
||||||
9FAE4ACE29379A5A00772766 /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAE4ACD29379A5A00772766 /* KeychainSwift */; };
|
9FAE4ACE29379A5A00772766 /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAE4ACD29379A5A00772766 /* KeychainSwift */; };
|
||||||
9FAE4AD129379AD600772766 /* AppAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAE4AD029379AD600772766 /* AppAccount.swift */; };
|
9FAE4AD129379AD600772766 /* AppAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAE4AD029379AD600772766 /* AppAccount.swift */; };
|
||||||
|
@ -67,6 +68,7 @@
|
||||||
9F7335EE29674F7100AFF0BA /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/QuickLook.framework; sourceTree = DEVELOPER_DIR; };
|
9F7335EE29674F7100AFF0BA /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/QuickLook.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
9F7335F12967608F00AFF0BA /* AddRemoteTimelineVIew.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRemoteTimelineVIew.swift; sourceTree = "<group>"; };
|
9F7335F12967608F00AFF0BA /* AddRemoteTimelineVIew.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRemoteTimelineVIew.swift; sourceTree = "<group>"; };
|
||||||
9F7335F62968274500AFF0BA /* AppAccountsSelectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppAccountsSelectorView.swift; sourceTree = "<group>"; };
|
9F7335F62968274500AFF0BA /* AppAccountsSelectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppAccountsSelectorView.swift; sourceTree = "<group>"; };
|
||||||
|
9F7335F82968576500AFF0BA /* DisplaySettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplaySettingsView.swift; sourceTree = "<group>"; };
|
||||||
9FAE4AC8293774FF00772766 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
9FAE4AC8293774FF00772766 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||||
9FAE4ACA293783B000772766 /* SettingsTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTab.swift; sourceTree = "<group>"; };
|
9FAE4ACA293783B000772766 /* SettingsTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTab.swift; sourceTree = "<group>"; };
|
||||||
9FAE4AD029379AD600772766 /* AppAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppAccount.swift; sourceTree = "<group>"; };
|
9FAE4AD029379AD600772766 /* AppAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppAccount.swift; sourceTree = "<group>"; };
|
||||||
|
@ -212,6 +214,7 @@
|
||||||
9FE151A5293C90F900E9683D /* IconSelectorView.swift */,
|
9FE151A5293C90F900E9683D /* IconSelectorView.swift */,
|
||||||
9F2B92F9295DA7D700DE16D0 /* AddAccountsView.swift */,
|
9F2B92F9295DA7D700DE16D0 /* AddAccountsView.swift */,
|
||||||
9F2B92FB295DA94500DE16D0 /* InstanceInfoView.swift */,
|
9F2B92FB295DA94500DE16D0 /* InstanceInfoView.swift */,
|
||||||
|
9F7335F82968576500AFF0BA /* DisplaySettingsView.swift */,
|
||||||
);
|
);
|
||||||
path = Settings;
|
path = Settings;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -306,6 +309,7 @@
|
||||||
9F2B92FC295DA94500DE16D0 /* InstanceInfoView.swift in Sources */,
|
9F2B92FC295DA94500DE16D0 /* InstanceInfoView.swift in Sources */,
|
||||||
9F35DB4C2952005C00B3281A /* MessagesTab.swift in Sources */,
|
9F35DB4C2952005C00B3281A /* MessagesTab.swift in Sources */,
|
||||||
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */,
|
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */,
|
||||||
|
9F7335F92968576500AFF0BA /* DisplaySettingsView.swift in Sources */,
|
||||||
9FAE4AD32937A0C600772766 /* AppAccountsManager.swift in Sources */,
|
9FAE4AD32937A0C600772766 /* AppAccountsManager.swift in Sources */,
|
||||||
9F2B92FF295EB87100DE16D0 /* AppAccountView.swift in Sources */,
|
9F2B92FF295EB87100DE16D0 /* AppAccountView.swift in Sources */,
|
||||||
9F2B92F6295AE04800DE16D0 /* Tabs.swift in Sources */,
|
9F2B92F6295AE04800DE16D0 /* Tabs.swift in Sources */,
|
||||||
|
|
|
@ -53,6 +53,8 @@ extension View {
|
||||||
ListAddAccountView(account: account)
|
ListAddAccountView(account: account)
|
||||||
case .addAccount:
|
case .addAccount:
|
||||||
AddAccountView()
|
AddAccountView()
|
||||||
|
case .addRemoteLocalTimeline:
|
||||||
|
AddRemoteTimelineView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
66
IceCubesApp/App/Tabs/Settings/DisplaySettingsView.swift
Normal file
66
IceCubesApp/App/Tabs/Settings/DisplaySettingsView.swift
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
import SwiftUI
|
||||||
|
import Models
|
||||||
|
import DesignSystem
|
||||||
|
import Status
|
||||||
|
|
||||||
|
struct DisplaySettingsView: View {
|
||||||
|
@EnvironmentObject private var theme: Theme
|
||||||
|
|
||||||
|
@State private var isThemeSelectorPresented = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Form {
|
||||||
|
Section("Theme") {
|
||||||
|
themeSelectorButton
|
||||||
|
ColorPicker("Tint color", selection: $theme.tintColor)
|
||||||
|
ColorPicker("Background color", selection: $theme.primaryBackgroundColor)
|
||||||
|
ColorPicker("Secondary Background color", selection: $theme.secondaryBackgroundColor)
|
||||||
|
}
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
|
||||||
|
Section("Display") {
|
||||||
|
Picker("Avatar position", selection: $theme.avatarPosition) {
|
||||||
|
ForEach(Theme.AvatarPosition.allCases, id: \.rawValue) { position in
|
||||||
|
Text(position.description).tag(position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Picker("Avatar shape", selection: $theme.avatarShape) {
|
||||||
|
ForEach(Theme.AvatarShape.allCases, id: \.rawValue) { shape in
|
||||||
|
Text(shape.description).tag(shape)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Picker("Status actions buttons", selection: $theme.statusActionsDisplay) {
|
||||||
|
ForEach(Theme.StatusActionsDisplay.allCases, id: \.rawValue) { buttonStyle in
|
||||||
|
Text(buttonStyle.description).tag(buttonStyle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
|
||||||
|
Section {
|
||||||
|
Button {
|
||||||
|
theme.selectedSet = .iceCubeDark
|
||||||
|
theme.avatarShape = .rounded
|
||||||
|
theme.avatarPosition = .top
|
||||||
|
theme.statusActionsDisplay = .full
|
||||||
|
} label: {
|
||||||
|
Text("Restore default")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
}
|
||||||
|
.navigationTitle("Display Settings")
|
||||||
|
.scrollContentBackground(.hidden)
|
||||||
|
.background(theme.secondaryBackgroundColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var themeSelectorButton: some View {
|
||||||
|
NavigationLink(destination: ThemePreviewView()) {
|
||||||
|
HStack {
|
||||||
|
Text("Theme")
|
||||||
|
Spacer()
|
||||||
|
Text(theme.selectedSet.rawValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,22 +9,27 @@ struct InstanceInfoView: View {
|
||||||
let instance: Instance
|
let instance: Instance
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Section("Instance info") {
|
Form {
|
||||||
LabeledContent("Name", value: instance.title)
|
Section("Instance info") {
|
||||||
Text(instance.shortDescription)
|
LabeledContent("Name", value: instance.title)
|
||||||
LabeledContent("Email", value: instance.email)
|
Text(instance.shortDescription)
|
||||||
LabeledContent("Version", value: instance.version)
|
LabeledContent("Email", value: instance.email)
|
||||||
LabeledContent("Users", value: "\(instance.stats.userCount)")
|
LabeledContent("Version", value: instance.version)
|
||||||
LabeledContent("Posts", value: "\(instance.stats.statusCount)")
|
LabeledContent("Users", value: "\(instance.stats.userCount)")
|
||||||
LabeledContent("Domains", value: "\(instance.stats.domainCount)")
|
LabeledContent("Posts", value: "\(instance.stats.statusCount)")
|
||||||
}
|
LabeledContent("Domains", value: "\(instance.stats.domainCount)")
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
|
||||||
|
|
||||||
Section("Instance rules") {
|
|
||||||
ForEach(instance.rules) { rule in
|
|
||||||
Text(rule.text)
|
|
||||||
}
|
}
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
|
||||||
|
Section("Instance rules") {
|
||||||
|
ForEach(instance.rules) { rule in
|
||||||
|
Text(rule.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
}
|
}
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.navigationTitle("Instance Info")
|
||||||
|
.scrollContentBackground(.hidden)
|
||||||
|
.background(theme.secondaryBackgroundColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Models
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
|
|
||||||
struct SettingsTabs: View {
|
struct SettingsTabs: View {
|
||||||
|
@EnvironmentObject private var preferences: UserPreferences
|
||||||
@EnvironmentObject private var client: Client
|
@EnvironmentObject private var client: Client
|
||||||
@EnvironmentObject private var currentInstance: CurrentInstance
|
@EnvironmentObject private var currentInstance: CurrentInstance
|
||||||
@EnvironmentObject private var appAccountsManager: AppAccountsManager
|
@EnvironmentObject private var appAccountsManager: AppAccountsManager
|
||||||
|
@ -15,21 +16,21 @@ struct SettingsTabs: View {
|
||||||
@StateObject private var routeurPath = RouterPath()
|
@StateObject private var routeurPath = RouterPath()
|
||||||
|
|
||||||
@State private var addAccountSheetPresented = false
|
@State private var addAccountSheetPresented = false
|
||||||
@State private var isThemeSelectorPresented = false
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $routeurPath.path) {
|
NavigationStack(path: $routeurPath.path) {
|
||||||
Form {
|
Form {
|
||||||
appSection
|
appSection
|
||||||
accountsSection
|
accountsSection
|
||||||
themeSection
|
generalSection
|
||||||
instanceSection
|
|
||||||
}
|
}
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
.navigationTitle(Text("Settings"))
|
.navigationTitle(Text("Settings"))
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.toolbarBackground(theme.primaryBackgroundColor, for: .navigationBar)
|
.toolbarBackground(theme.primaryBackgroundColor, for: .navigationBar)
|
||||||
|
.withAppRouteur()
|
||||||
|
.withSheetDestinations(sheetDestinations: $routeurPath.presentedSheet)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
routeurPath.client = client
|
routeurPath.client = client
|
||||||
|
@ -64,43 +65,29 @@ struct SettingsTabs: View {
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var themeSection: some View {
|
@ViewBuilder
|
||||||
Section("Theme") {
|
private var generalSection: some View {
|
||||||
themeSelectorButton
|
Section("General") {
|
||||||
ColorPicker("Tint color", selection: $theme.tintColor)
|
if let instanceData = currentInstance.instance {
|
||||||
ColorPicker("Background color", selection: $theme.primaryBackgroundColor)
|
NavigationLink(destination: InstanceInfoView(instance: instanceData)) {
|
||||||
ColorPicker("Secondary Background color", selection: $theme.secondaryBackgroundColor)
|
Label("Instance Information", systemImage: "server.rack")
|
||||||
Picker("Avatar position", selection: $theme.avatarPosition) {
|
|
||||||
ForEach(Theme.AvatarPosition.allCases, id: \.rawValue) { position in
|
|
||||||
Text(position.description).tag(position)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Picker("Avatar shape", selection: $theme.avatarShape) {
|
NavigationLink(destination: DisplaySettingsView()) {
|
||||||
ForEach(Theme.AvatarShape.allCases, id: \.rawValue) { shape in
|
Label("Display Settings", systemImage: "paintpalette")
|
||||||
Text(shape.description).tag(shape)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Button {
|
NavigationLink(destination: remoteLocalTimelinesView) {
|
||||||
theme.selectedSet = .iceCubeDark
|
Label("Remote Local Timelines", systemImage: "dot.radiowaves.right")
|
||||||
} label: {
|
|
||||||
Text("Restore default")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
private var instanceSection: some View {
|
|
||||||
if let instanceData = currentInstance.instance {
|
|
||||||
InstanceInfoView(instance: instanceData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var appSection: some View {
|
private var appSection: some View {
|
||||||
Section("App") {
|
Section("App") {
|
||||||
NavigationLink(destination: IconSelectorView()) {
|
NavigationLink(destination: IconSelectorView()) {
|
||||||
Label {
|
Label {
|
||||||
Text("Icon selector")
|
Text("App Icon")
|
||||||
} icon: {
|
} icon: {
|
||||||
if let icon = IconSelectorView.Icon(string: UIApplication.shared.alternateIconName ?? "AppIcon") {
|
if let icon = IconSelectorView.Icon(string: UIApplication.shared.alternateIconName ?? "AppIcon") {
|
||||||
Image(uiImage: .init(named: icon.iconName)!)
|
Image(uiImage: .init(named: icon.iconName)!)
|
||||||
|
@ -111,7 +98,7 @@ struct SettingsTabs: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Link(destination: URL(string: "https://github.com/Dimillian/IceCubesApp")!) {
|
Link(destination: URL(string: "https://github.com/Dimillian/IceCubesApp")!) {
|
||||||
Text("https://github.com/Dimillian/IceCubesApp")
|
Label("Source (Github link)", systemImage: "link")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
@ -128,25 +115,25 @@ struct SettingsTabs: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var themeSelectorButton: some View {
|
private var remoteLocalTimelinesView: some View {
|
||||||
NavigationLink(destination: ThemePreviewView()) {
|
Form {
|
||||||
Button {
|
ForEach(preferences.remoteLocalTimelines, id: \.self) { server in
|
||||||
isThemeSelectorPresented.toggle()
|
Text(server)
|
||||||
} label: {
|
}.onDelete { indexes in
|
||||||
HStack {
|
if let index = indexes.first {
|
||||||
Text("Theme")
|
_ = preferences.remoteLocalTimelines.remove(at: index)
|
||||||
Spacer()
|
|
||||||
Text(theme.selectedSet.rawValue)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
Button {
|
||||||
|
routeurPath.presentedSheet = .addRemoteLocalTimeline
|
||||||
|
} label: {
|
||||||
|
Label("Add a local timeline", systemImage: "badge.plus.radiowaves.right")
|
||||||
|
}
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
}
|
}
|
||||||
}
|
.navigationTitle("Remote Local Timelines")
|
||||||
|
.scrollContentBackground(.hidden)
|
||||||
private var signOutButton: some View {
|
.background(theme.secondaryBackgroundColor)
|
||||||
Button {
|
|
||||||
appAccountsManager.delete(account: appAccountsManager.currentAccount)
|
|
||||||
} label: {
|
|
||||||
Text("Sign out").foregroundColor(.red)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,10 @@ import DesignSystem
|
||||||
import NukeUI
|
import NukeUI
|
||||||
import Shimmer
|
import Shimmer
|
||||||
|
|
||||||
struct AddRemoteTimelineVIew: View {
|
struct AddRemoteTimelineView: View {
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
|
||||||
|
@EnvironmentObject private var preferences: UserPreferences
|
||||||
@EnvironmentObject private var theme: Theme
|
@EnvironmentObject private var theme: Theme
|
||||||
|
|
||||||
@State private var instanceName: String = ""
|
@State private var instanceName: String = ""
|
||||||
|
@ -16,9 +17,7 @@ struct AddRemoteTimelineVIew: View {
|
||||||
@State private var instances: [InstanceSocial] = []
|
@State private var instances: [InstanceSocial] = []
|
||||||
|
|
||||||
@FocusState private var isInstanceURLFieldFocused: Bool
|
@FocusState private var isInstanceURLFieldFocused: Bool
|
||||||
|
|
||||||
@Binding var addedInstance: String
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
Form {
|
Form {
|
||||||
|
@ -36,7 +35,7 @@ struct AddRemoteTimelineVIew: View {
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
guard instance != nil else { return }
|
guard instance != nil else { return }
|
||||||
addedInstance = instanceName
|
preferences.remoteLocalTimelines.append(instanceName)
|
||||||
dismiss()
|
dismiss()
|
||||||
} label: {
|
} label: {
|
||||||
Text("Add")
|
Text("Add")
|
||||||
|
|
|
@ -17,10 +17,7 @@ struct TimelineTab: View {
|
||||||
@State private var didAppear: Bool = false
|
@State private var didAppear: Bool = false
|
||||||
@State private var timeline: TimelineFilter = .home
|
@State private var timeline: TimelineFilter = .home
|
||||||
@State private var scrollToTopSignal: Int = 0
|
@State private var scrollToTopSignal: Int = 0
|
||||||
|
|
||||||
@State private var newlyAddedLocalTimeline: String = ""
|
|
||||||
@State private var isAddRemoteLocalTimelinePresented: Bool = false
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $routeurPath.path) {
|
NavigationStack(path: $routeurPath.path) {
|
||||||
TimelineView(timeline: $timeline, scrollToTopSignal: $scrollToTopSignal)
|
TimelineView(timeline: $timeline, scrollToTopSignal: $scrollToTopSignal)
|
||||||
|
@ -31,9 +28,6 @@ struct TimelineTab: View {
|
||||||
}
|
}
|
||||||
.id(currentAccount.account?.id)
|
.id(currentAccount.account?.id)
|
||||||
}
|
}
|
||||||
.sheet(isPresented: $isAddRemoteLocalTimelinePresented) {
|
|
||||||
AddRemoteTimelineVIew(addedInstance: $newlyAddedLocalTimeline)
|
|
||||||
}
|
|
||||||
.onAppear {
|
.onAppear {
|
||||||
routeurPath.client = client
|
routeurPath.client = client
|
||||||
if !didAppear {
|
if !didAppear {
|
||||||
|
@ -62,13 +56,6 @@ struct TimelineTab: View {
|
||||||
.onChange(of: currentAccount.account?.id) { _ in
|
.onChange(of: currentAccount.account?.id) { _ in
|
||||||
routeurPath.path = []
|
routeurPath.path = []
|
||||||
}
|
}
|
||||||
.onChange(of: isAddRemoteLocalTimelinePresented) { isPresented in
|
|
||||||
if !isPresented && !newlyAddedLocalTimeline.isEmpty {
|
|
||||||
preferences.remoteLocalTimelines.append(newlyAddedLocalTimeline)
|
|
||||||
timeline = .remoteLocal(server: newlyAddedLocalTimeline)
|
|
||||||
newlyAddedLocalTimeline = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.environmentObject(routeurPath)
|
.environmentObject(routeurPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,24 +93,20 @@ struct TimelineTab: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !preferences.remoteLocalTimelines.isEmpty {
|
Menu("Local Timelines") {
|
||||||
Menu("Local Timelines") {
|
ForEach(preferences.remoteLocalTimelines, id: \.self) { server in
|
||||||
ForEach(preferences.remoteLocalTimelines, id: \.self) { server in
|
Button {
|
||||||
Button {
|
timeline = .remoteLocal(server: server)
|
||||||
timeline = .remoteLocal(server: server)
|
} label: {
|
||||||
} label: {
|
Label(server, systemImage: "dot.radiowaves.right")
|
||||||
Label(server, systemImage: "dot.radiowaves.right")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Button {
|
||||||
|
routeurPath.presentedSheet = .addRemoteLocalTimeline
|
||||||
|
} label: {
|
||||||
|
Label("Add a local timeline", systemImage: "badge.plus.radiowaves.right")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
|
||||||
isAddRemoteLocalTimelinePresented = true
|
|
||||||
} label: {
|
|
||||||
Label("Add a local timeline", systemImage: "badge.plus.radiowaves.right")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var addAccountButton: some View {
|
private var addAccountButton: some View {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import SwiftUI
|
||||||
public class Theme: ObservableObject {
|
public class Theme: ObservableObject {
|
||||||
enum ThemeKey: String {
|
enum ThemeKey: String {
|
||||||
case colorScheme, tint, label, primaryBackground, secondaryBackground
|
case colorScheme, tint, label, primaryBackground, secondaryBackground
|
||||||
case avatarPosition, avatarShape
|
case avatarPosition, avatarShape, statusActionsDisplay
|
||||||
case selectedSet, selectedScheme
|
case selectedSet, selectedScheme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,21 @@ public class Theme: ObservableObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum StatusActionsDisplay: String, CaseIterable {
|
||||||
|
case full, discret, none
|
||||||
|
|
||||||
|
public var description: LocalizedStringKey {
|
||||||
|
switch self {
|
||||||
|
case .full:
|
||||||
|
return "All"
|
||||||
|
case .discret:
|
||||||
|
return "Only buttons"
|
||||||
|
case .none:
|
||||||
|
return "No buttons"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@AppStorage("is_previously_set") private var isSet: Bool = false
|
@AppStorage("is_previously_set") private var isSet: Bool = false
|
||||||
@AppStorage(ThemeKey.selectedScheme.rawValue) public var selectedScheme: ColorScheme = .dark
|
@AppStorage(ThemeKey.selectedScheme.rawValue) public var selectedScheme: ColorScheme = .dark
|
||||||
@AppStorage(ThemeKey.tint.rawValue) public var tintColor: Color = .black
|
@AppStorage(ThemeKey.tint.rawValue) public var tintColor: Color = .black
|
||||||
|
@ -43,6 +58,7 @@ public class Theme: ObservableObject {
|
||||||
@AppStorage(ThemeKey.avatarPosition.rawValue) var rawAvatarPosition: String = AvatarPosition.top.rawValue
|
@AppStorage(ThemeKey.avatarPosition.rawValue) var rawAvatarPosition: String = AvatarPosition.top.rawValue
|
||||||
@AppStorage(ThemeKey.avatarShape.rawValue) var rawAvatarShape: String = AvatarShape.rounded.rawValue
|
@AppStorage(ThemeKey.avatarShape.rawValue) var rawAvatarShape: String = AvatarShape.rounded.rawValue
|
||||||
@AppStorage(ThemeKey.selectedSet.rawValue) var storedSet: ColorSetName = .iceCubeDark
|
@AppStorage(ThemeKey.selectedSet.rawValue) var storedSet: ColorSetName = .iceCubeDark
|
||||||
|
@AppStorage(ThemeKey.statusActionsDisplay.rawValue) public var statusActionsDisplay: StatusActionsDisplay = .full
|
||||||
|
|
||||||
@Published public var avatarPosition: AvatarPosition = .top
|
@Published public var avatarPosition: AvatarPosition = .top
|
||||||
@Published public var avatarShape: AvatarShape = .rounded
|
@Published public var avatarShape: AvatarShape = .rounded
|
||||||
|
|
|
@ -25,6 +25,7 @@ public enum SheetDestinations: Identifiable {
|
||||||
case listEdit(list: Models.List)
|
case listEdit(list: Models.List)
|
||||||
case listAddAccount(account: Account)
|
case listAddAccount(account: Account)
|
||||||
case addAccount
|
case addAccount
|
||||||
|
case addRemoteLocalTimeline
|
||||||
|
|
||||||
public var id: String {
|
public var id: String {
|
||||||
switch self {
|
switch self {
|
||||||
|
@ -36,6 +37,8 @@ public enum SheetDestinations: Identifiable {
|
||||||
return "listAddAccount"
|
return "listAddAccount"
|
||||||
case .addAccount:
|
case .addAccount:
|
||||||
return "addAccount"
|
return "addAccount"
|
||||||
|
case .addRemoteLocalTimeline:
|
||||||
|
return "addRemoteLocalTimeline"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ public struct Status: AnyStatus, Codable, Identifiable {
|
||||||
|
|
||||||
public static func placeholder() -> Status {
|
public static func placeholder() -> Status {
|
||||||
.init(id: UUID().uuidString,
|
.init(id: UUID().uuidString,
|
||||||
content: "Some post content\n Some more post content \n Some more",
|
content: "This is a #toot\nWith some @content\nAnd some more content for your #eyes @only",
|
||||||
account: .placeholder(),
|
account: .placeholder(),
|
||||||
createdAt: "2022-12-16T10:20:54.000Z",
|
createdAt: "2022-12-16T10:20:54.000Z",
|
||||||
editedAt: nil,
|
editedAt: nil,
|
||||||
|
|
|
@ -29,7 +29,10 @@ struct StatusActionsView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func count(viewModel: StatusRowViewModel) -> Int? {
|
func count(viewModel: StatusRowViewModel, theme: Theme) -> Int? {
|
||||||
|
if theme.statusActionsDisplay == .discret {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
switch self {
|
switch self {
|
||||||
case .respond:
|
case .respond:
|
||||||
return viewModel.repliesCount
|
return viewModel.repliesCount
|
||||||
|
@ -71,7 +74,7 @@ struct StatusActionsView: View {
|
||||||
HStack(spacing: 2) {
|
HStack(spacing: 2) {
|
||||||
Image(systemName: action.iconName(viewModel: viewModel))
|
Image(systemName: action.iconName(viewModel: viewModel))
|
||||||
.foregroundColor(action.tintColor(viewModel: viewModel, theme: theme))
|
.foregroundColor(action.tintColor(viewModel: viewModel, theme: theme))
|
||||||
if let count = action.count(viewModel: viewModel) {
|
if let count = action.count(viewModel: viewModel, theme: theme) {
|
||||||
Text("\(count)")
|
Text("\(count)")
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ public struct StatusRowView: View {
|
||||||
replyView
|
replyView
|
||||||
}
|
}
|
||||||
statusView
|
statusView
|
||||||
if !viewModel.isCompact && !viewModel.isRemote {
|
if !viewModel.isCompact && !viewModel.isRemote, theme.statusActionsDisplay != .none {
|
||||||
StatusActionsView(viewModel: viewModel)
|
StatusActionsView(viewModel: viewModel)
|
||||||
.padding(.vertical, 8)
|
.padding(.vertical, 8)
|
||||||
.tint(viewModel.isFocused ? theme.tintColor : .gray)
|
.tint(viewModel.isFocused ? theme.tintColor : .gray)
|
||||||
|
|
|
@ -3,7 +3,7 @@ import Models
|
||||||
import Network
|
import Network
|
||||||
|
|
||||||
public enum TimelineFilter: Hashable, Equatable {
|
public enum TimelineFilter: Hashable, Equatable {
|
||||||
case federated, local, home, trending
|
case home, local, federated, trending
|
||||||
case hashtag(tag: String, accountId: String?)
|
case hashtag(tag: String, accountId: String?)
|
||||||
case list(list: List)
|
case list(list: List)
|
||||||
case remoteLocal(server: String)
|
case remoteLocal(server: String)
|
||||||
|
@ -14,9 +14,9 @@ public enum TimelineFilter: Hashable, Equatable {
|
||||||
|
|
||||||
public static func availableTimeline(client: Client) -> [TimelineFilter] {
|
public static func availableTimeline(client: Client) -> [TimelineFilter] {
|
||||||
if !client.isAuth {
|
if !client.isAuth {
|
||||||
return [.federated, .local, .trending]
|
return [.local, .federated, .trending]
|
||||||
}
|
}
|
||||||
return [.federated, .local, .trending, .home]
|
return [.home, .local, .federated, .trending]
|
||||||
}
|
}
|
||||||
|
|
||||||
public func title() -> String {
|
public func title() -> String {
|
||||||
|
|
Loading…
Reference in a new issue