WiP on Edit Accounts and ColorScheme
This commit is contained in:
parent
64848a9421
commit
4982211e27
|
@ -138,6 +138,17 @@ final class AppDefaults: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
static var userInterfaceColorScheme: ColorScheme? {
|
||||
switch AppDefaults.shared.userInterfaceColorPalette {
|
||||
case .light:
|
||||
return ColorScheme.light
|
||||
case .dark:
|
||||
return ColorScheme.dark
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Feeds & Folders
|
||||
@AppStorage(Key.addWebFeedAccountID, store: store) var addWebFeedAccountID: String?
|
||||
|
||||
|
|
|
@ -20,12 +20,14 @@ struct MainApp: App {
|
|||
|
||||
@StateObject private var defaults = AppDefaults.shared
|
||||
|
||||
|
||||
@SceneBuilder var body: some Scene {
|
||||
#if os(macOS)
|
||||
WindowGroup {
|
||||
SceneNavigationView()
|
||||
.frame(minWidth: 600, idealWidth: 1000, maxWidth: .infinity, minHeight: 600, idealHeight: 700, maxHeight: .infinity)
|
||||
.environmentObject(defaults)
|
||||
.preferredColorScheme(AppDefaults.userInterfaceColorScheme)
|
||||
}
|
||||
.windowToolbarStyle(UnifiedWindowToolbarStyle())
|
||||
.commands {
|
||||
|
@ -69,6 +71,7 @@ struct MainApp: App {
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
// Mac Preferences
|
||||
Settings {
|
||||
MacPreferencesView()
|
||||
|
|
|
@ -66,6 +66,8 @@ struct MacPreferencesView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.preferredColorScheme(AppDefaults.userInterfaceColorScheme)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,12 @@ import Combine
|
|||
|
||||
class AccountsPreferencesModel: ObservableObject {
|
||||
|
||||
enum AccountConfigurationSheets {
|
||||
case add, credentials, none
|
||||
}
|
||||
|
||||
public private(set) var account: Account?
|
||||
|
||||
// Configured Accounts
|
||||
@Published var sortedAccounts: [Account] = []
|
||||
@Published var selectedConfiguredAccountID: String? = AccountManager.shared.defaultAccount.accountID {
|
||||
|
@ -24,9 +30,17 @@ class AccountsPreferencesModel: ObservableObject {
|
|||
}
|
||||
}
|
||||
@Published var showAddAccountView: Bool = false
|
||||
var selectedAccountIsDefault: Bool {
|
||||
guard let selected = selectedConfiguredAccountID else {
|
||||
return true
|
||||
}
|
||||
if selected == AccountManager.shared.defaultAccount.accountID {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Edit Account
|
||||
public private(set) var account: Account?
|
||||
@Published var accountIsActive: Bool = false {
|
||||
didSet {
|
||||
account?.isActive = accountIsActive
|
||||
|
@ -37,16 +51,18 @@ class AccountsPreferencesModel: ObservableObject {
|
|||
account?.name = accountName
|
||||
}
|
||||
}
|
||||
@Published var showAddCredentialsView: Bool = false
|
||||
|
||||
var selectedAccountIsDefault: Bool {
|
||||
guard let selected = selectedConfiguredAccountID else {
|
||||
return true
|
||||
// Sheets
|
||||
@Published var showSheet: Bool = false
|
||||
@Published var sheetToShow: AccountConfigurationSheets = .none {
|
||||
didSet {
|
||||
showSheet = sheetToShow != .none
|
||||
}
|
||||
if selected == AccountManager.shared.defaultAccount.accountID {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@Published var showDeleteConfirmation: Bool = false
|
||||
|
||||
|
||||
|
||||
// Subscriptions
|
||||
var notificationSubscriptions = Set<AnyCancellable>()
|
||||
|
|
|
@ -18,36 +18,59 @@ struct AccountsPreferencesView: View {
|
|||
var body: some View {
|
||||
VStack {
|
||||
HStack(alignment: .top, spacing: 10) {
|
||||
VStack(alignment: .leading) {
|
||||
List(viewModel.sortedAccounts, id: \.accountID, selection: $viewModel.selectedConfiguredAccountID) {
|
||||
ConfiguredAccountRow(account: $0)
|
||||
.id($0.accountID)
|
||||
}.overlay(
|
||||
Group {
|
||||
bottomButtonStack
|
||||
}, alignment: .bottom)
|
||||
}
|
||||
.frame(width: 160, height: 300, alignment: .leading)
|
||||
.border(Color.gray, width: 1)
|
||||
listOfAccounts
|
||||
|
||||
EditAccountView(viewModel: viewModel)
|
||||
.frame(height: 300, alignment: .leading)
|
||||
}
|
||||
Spacer()
|
||||
}.sheet(isPresented: $viewModel.showAddAccountView,
|
||||
onDismiss: { viewModel.showAddAccountView.toggle() },
|
||||
}
|
||||
.sheet(isPresented: $viewModel.showSheet,
|
||||
onDismiss: { viewModel.sheetToShow = .none },
|
||||
content: {
|
||||
AddAccountView(preferencesModel: viewModel)
|
||||
switch viewModel.sheetToShow {
|
||||
case .add:
|
||||
AddAccountView(preferencesModel: viewModel)
|
||||
case .credentials:
|
||||
EditAccountCredentials(viewModel: viewModel)
|
||||
case .none:
|
||||
EmptyView()
|
||||
}
|
||||
})
|
||||
.alert(isPresented: $viewModel.showDeleteConfirmation, content: {
|
||||
Alert(title: Text("Delete \(viewModel.account!.nameForDisplay)?"),
|
||||
message: Text("Are you sure you want to delete the account \"\(viewModel.account!.nameForDisplay)\"? This can not be undone."),
|
||||
primaryButton: .destructive(Text("Delete"), action: {
|
||||
AccountManager.shared.deleteAccount(viewModel.account!)
|
||||
viewModel.showDeleteConfirmation = false
|
||||
}),
|
||||
secondaryButton: .cancel({
|
||||
viewModel.showDeleteConfirmation = false
|
||||
}))
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
var listOfAccounts: some View {
|
||||
VStack(alignment: .leading) {
|
||||
List(viewModel.sortedAccounts, id: \.accountID, selection: $viewModel.selectedConfiguredAccountID) {
|
||||
ConfiguredAccountRow(account: $0)
|
||||
.id($0.accountID)
|
||||
}.overlay(
|
||||
Group {
|
||||
bottomButtonStack
|
||||
}, alignment: .bottom)
|
||||
}
|
||||
.frame(width: 160, height: 300, alignment: .leading)
|
||||
.border(Color.gray, width: 1)
|
||||
}
|
||||
|
||||
var bottomButtonStack: some View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Divider()
|
||||
HStack(alignment: .center, spacing: 4) {
|
||||
Button(action: {
|
||||
viewModel.showAddAccountView.toggle()
|
||||
viewModel.sheetToShow = .add
|
||||
}, label: {
|
||||
Image(systemName: "plus")
|
||||
.font(.title)
|
||||
|
@ -63,10 +86,7 @@ struct AccountsPreferencesView: View {
|
|||
.help("Add Account")
|
||||
|
||||
Button(action: {
|
||||
if let account = viewModel.sortedAccounts.first(where: { $0.accountID == viewModel.selectedConfiguredAccountID }) {
|
||||
AccountManager.shared.deleteAccount(account)
|
||||
}
|
||||
|
||||
viewModel.showDeleteConfirmation = true
|
||||
}, label: {
|
||||
Image(systemName: "minus")
|
||||
.font(.title)
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// EditAccountCredentials.swift
|
||||
// Multiplatform macOS
|
||||
//
|
||||
// Created by Stuart Breckenridge on 14/7/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Secrets
|
||||
|
||||
struct EditAccountCredentials: View {
|
||||
|
||||
@ObservedObject var viewModel: AccountsPreferencesModel
|
||||
@Environment(\.presentationMode) var presentationMode
|
||||
|
||||
@State private var userName: String = ""
|
||||
@State private var password: String = ""
|
||||
@State private var apiUrl: String?
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
HStack {
|
||||
Spacer()
|
||||
Image(rsImage: viewModel.account!.smallIcon!.image)
|
||||
.resizable()
|
||||
.frame(width: 30, height: 30)
|
||||
Text(viewModel.account?.nameForDisplay ?? "")
|
||||
Spacer()
|
||||
}.padding()
|
||||
|
||||
HStack(alignment: .center) {
|
||||
VStack(alignment: .trailing, spacing: 12) {
|
||||
Text("Username: ")
|
||||
Text("Password: ")
|
||||
}.frame(width: 75)
|
||||
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
TextField("Username", text: $userName)
|
||||
SecureField("Password", text: $password)
|
||||
}
|
||||
}.textFieldStyle(RoundedBorderTextFieldStyle())
|
||||
|
||||
Spacer()
|
||||
HStack{
|
||||
Spacer()
|
||||
Button("Dismiss", action: {
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
})
|
||||
Button("Update", action: {
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
})
|
||||
}
|
||||
}.onAppear {
|
||||
let credentials = try? viewModel.account?.retrieveCredentials(type: .basic)
|
||||
userName = credentials?.username ?? ""
|
||||
password = credentials?.secret ?? ""
|
||||
}
|
||||
.frame(idealWidth: 300, idealHeight: 200, alignment: .top)
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
struct EditAccountCredentials_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
EditAccountCredentials(viewModel: AccountsPreferencesModel())
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,6 @@ struct EditAccountView: View {
|
|||
@ObservedObject var viewModel: AccountsPreferencesModel
|
||||
|
||||
var body: some View {
|
||||
|
||||
ZStack {
|
||||
RoundedRectangle(cornerRadius: 8, style: .circular)
|
||||
.foregroundColor(Color.secondary.opacity(0.1))
|
||||
|
@ -23,11 +22,9 @@ struct EditAccountView: View {
|
|||
|
||||
VStack {
|
||||
editAccountHeader
|
||||
|
||||
if viewModel.account != nil {
|
||||
editAccountForm
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
|
@ -67,12 +64,14 @@ struct EditAccountView: View {
|
|||
HStack {
|
||||
Spacer()
|
||||
Button("Credentials", action: {
|
||||
|
||||
viewModel.sheetToShow = .credentials
|
||||
})
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}).padding()
|
||||
})
|
||||
.padding()
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -10,7 +10,9 @@ import SwiftUI
|
|||
struct GeneralPreferencesView: View {
|
||||
|
||||
@EnvironmentObject private var defaults: AppDefaults
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
@ObservedObject var preferences: MacPreferencesModel
|
||||
private let colorPalettes = UserInterfaceColorPalette.allCases
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
@ -32,8 +34,6 @@ struct GeneralPreferencesView: View {
|
|||
Text(preferences.rssReaders[index].nameMinusAppSuffix)
|
||||
.tag(index)
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -41,6 +41,16 @@ struct GeneralPreferencesView: View {
|
|||
Toggle("Open webpages in background in browser", isOn: $defaults.openInBrowserInBackground)
|
||||
|
||||
Toggle("Hide Unread Count in Dock", isOn: $defaults.hideDockUnreadCount)
|
||||
|
||||
Divider()
|
||||
|
||||
Picker("Appearance", selection: $defaults.userInterfaceColorPalette, content: {
|
||||
ForEach(colorPalettes, id: \.self, content: {
|
||||
Text($0.description)
|
||||
})
|
||||
}).pickerStyle(RadioGroupPickerStyle())
|
||||
|
||||
|
||||
}
|
||||
.frame(width: 400, alignment: .center)
|
||||
.lineLimit(2)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
1769E32924BCAFC7000E1E8E /* AddAccountPickerRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1769E32824BCAFC7000E1E8E /* AddAccountPickerRow.swift */; };
|
||||
1769E32B24BCB030000E1E8E /* ConfiguredAccountRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1769E32A24BCB030000E1E8E /* ConfiguredAccountRow.swift */; };
|
||||
1769E32D24BD20A0000E1E8E /* EditAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1769E32C24BD20A0000E1E8E /* EditAccountView.swift */; };
|
||||
1769E33024BD6271000E1E8E /* EditAccountCredentials.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1769E32F24BD6271000E1E8E /* EditAccountCredentials.swift */; };
|
||||
1776E88E24AC5F8A00E78166 /* AppDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1776E88D24AC5F8A00E78166 /* AppDefaults.swift */; };
|
||||
1776E88F24AC5F8A00E78166 /* AppDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1776E88D24AC5F8A00E78166 /* AppDefaults.swift */; };
|
||||
17930ED424AF10EE00A9BA52 /* AddWebFeedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17930ED324AF10EE00A9BA52 /* AddWebFeedView.swift */; };
|
||||
|
@ -1800,6 +1801,7 @@
|
|||
1769E32824BCAFC7000E1E8E /* AddAccountPickerRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAccountPickerRow.swift; sourceTree = "<group>"; };
|
||||
1769E32A24BCB030000E1E8E /* ConfiguredAccountRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfiguredAccountRow.swift; sourceTree = "<group>"; };
|
||||
1769E32C24BD20A0000E1E8E /* EditAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditAccountView.swift; sourceTree = "<group>"; };
|
||||
1769E32F24BD6271000E1E8E /* EditAccountCredentials.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditAccountCredentials.swift; sourceTree = "<group>"; };
|
||||
1776E88D24AC5F8A00E78166 /* AppDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDefaults.swift; sourceTree = "<group>"; };
|
||||
17930ED324AF10EE00A9BA52 /* AddWebFeedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedView.swift; sourceTree = "<group>"; };
|
||||
179DBBA2B22A659F81EED6F9 /* AccountsNewsBlurWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsNewsBlurWindowController.swift; sourceTree = "<group>"; };
|
||||
|
@ -2548,7 +2550,7 @@
|
|||
1769E32124BC5925000E1E8E /* AccountsPreferencesModel.swift */,
|
||||
1729529024AA1CAA00D65E66 /* AccountsPreferencesView.swift */,
|
||||
1769E32A24BCB030000E1E8E /* ConfiguredAccountRow.swift */,
|
||||
1769E32C24BD20A0000E1E8E /* EditAccountView.swift */,
|
||||
1769E32E24BD5F22000E1E8E /* Edit Account */,
|
||||
1769E32324BC5A50000E1E8E /* Add Account */,
|
||||
);
|
||||
path = Accounts;
|
||||
|
@ -2572,6 +2574,15 @@
|
|||
path = "Add Account";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1769E32E24BD5F22000E1E8E /* Edit Account */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1769E32C24BD20A0000E1E8E /* EditAccountView.swift */,
|
||||
1769E32F24BD6271000E1E8E /* EditAccountCredentials.swift */,
|
||||
);
|
||||
path = "Edit Account";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
17930ED224AF10CD00A9BA52 /* Add */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -5252,6 +5263,7 @@
|
|||
51408B7F24A9EC6F0073CF4E /* SidebarItem.swift in Sources */,
|
||||
514E6BDB24ACEA0400AC6F6E /* TimelineItemView.swift in Sources */,
|
||||
51E4996E24A8764C00B667CB /* ActivityManager.swift in Sources */,
|
||||
1769E33024BD6271000E1E8E /* EditAccountCredentials.swift in Sources */,
|
||||
51E4995A24A873F900B667CB /* ErrorHandler.swift in Sources */,
|
||||
51E4991F24A8094300B667CB /* RSImage-AppIcons.swift in Sources */,
|
||||
51A5769724AE617200078888 /* ArticleContainerView.swift in Sources */,
|
||||
|
|
Loading…
Reference in New Issue