NetNewsWire/Mac/Preferences/Accounts/AddAccountsView.swift

279 lines
7.1 KiB
Swift
Raw Normal View History

2020-10-28 16:19:42 +01:00
//
// AddAccountsView.swift
// NetNewsWire
//
// Created by Stuart Breckenridge on 28/10/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import SwiftUI
import Account
enum AddAccountSections: Int, CaseIterable {
2020-10-28 16:19:42 +01:00
case local = 0
case icloud
case web
case selfhosted
case allOrdered
2020-10-28 16:19:42 +01:00
var sectionHeader: String {
switch self {
case .local:
return NSLocalizedString("Local", comment: "Local Account")
case .icloud:
return NSLocalizedString("iCloud", comment: "iCloud Account")
case .web:
return NSLocalizedString("Web", comment: "Web Account")
case .selfhosted:
return NSLocalizedString("Self-hosted", comment: "Self hosted Account")
case .allOrdered:
return ""
2020-10-28 16:19:42 +01:00
}
}
var sectionFooter: String {
switch self {
case .local:
return NSLocalizedString("Local accounts do not sync feeds across devices", comment: "Local Account")
2020-10-28 16:19:42 +01:00
case .icloud:
return NSLocalizedString("Your iCloud account syncs your feeds across your Mac and iOS devices", comment: "iCloud Account")
2020-10-28 16:19:42 +01:00
case .web:
return NSLocalizedString("Web accounts sync your feeds across all your devices", comment: "Web Account")
2020-10-28 16:19:42 +01:00
case .selfhosted:
return NSLocalizedString("Self-hosted accounts sync your feeds across all your devices", comment: "Self hosted Account")
case .allOrdered:
return ""
2020-10-28 16:19:42 +01:00
}
}
var sectionContent: [AccountType] {
switch self {
case .local:
return [.onMyMac]
case .icloud:
return [.cloudKit]
case .web:
if AppDefaults.shared.isDeveloperBuild {
return [.bazQux, .feedbin, .feedly, .inoreader, .newsBlur, .theOldReader].filter({ $0.isDeveloperRestricted == false })
} else {
return [.bazQux, .feedbin, .feedly, .inoreader, .newsBlur, .theOldReader]
}
2020-10-28 16:19:42 +01:00
case .selfhosted:
return [.freshRSS]
case .allOrdered:
return AddAccountSections.local.sectionContent +
AddAccountSections.icloud.sectionContent +
AddAccountSections.web.sectionContent +
AddAccountSections.selfhosted.sectionContent
2020-10-28 16:19:42 +01:00
}
}
2020-10-28 16:19:42 +01:00
}
struct AddAccountsView: View {
weak var parent: NSHostingController<AddAccountsView>? // required because presentationMode.dismiss() doesn't work
var addAccountDelegate: AccountsPreferencesAddAccountDelegate?
private let chunkLimit = 4 // use this to control number of accounts in each web account column
2020-10-29 23:16:28 +01:00
@State private var selectedAccount: AccountType = .onMyMac
2020-10-28 16:19:42 +01:00
init(delegate: AccountsPreferencesAddAccountDelegate?) {
self.addAccountDelegate = delegate
}
var body: some View {
VStack(alignment: .leading, spacing: 8) {
Text("Choose an account type to add...")
.font(.headline)
.padding()
localAccount
if !AppDefaults.shared.isDeveloperBuild {
icloudAccount
}
2020-10-28 16:19:42 +01:00
webAccounts
selfhostedAccounts
2020-10-29 05:07:18 +01:00
HStack(spacing: 12) {
2020-10-28 16:19:42 +01:00
Spacer()
Button(action: {
parent?.dismiss(nil)
}, label: {
Text("Cancel")
.frame(width: 76)
})
.help("Cancel")
.keyboardShortcut(.cancelAction)
Button(action: {
addAccountDelegate?.presentSheetForAccount(selectedAccount)
parent?.dismiss(nil)
}, label: {
Text("Continue")
.frame(width: 76)
})
.help("Add Account")
.keyboardShortcut(.defaultAction)
2020-10-30 02:44:44 +01:00
}
.padding(.top, 12)
.padding(.bottom, 4)
2020-10-28 16:19:42 +01:00
}
.pickerStyle(RadioGroupPickerStyle())
.fixedSize(horizontal: false, vertical: true)
2020-10-29 05:07:18 +01:00
.frame(width: 420)
.padding()
2020-10-28 16:19:42 +01:00
}
@MainActor var localAccount: some View {
2020-10-28 16:19:42 +01:00
VStack(alignment: .leading) {
Text("Local")
.font(.headline)
.padding(.horizontal)
2020-10-28 16:19:42 +01:00
Picker(selection: $selectedAccount, label: Text(""), content: {
ForEach(AddAccountSections.local.sectionContent, id: \.self, content: { account in
2020-10-30 02:44:44 +01:00
HStack(alignment: .center) {
2020-10-29 05:07:18 +01:00
account.image()
2020-10-28 16:19:42 +01:00
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 20, height: 20, alignment: .center)
2020-10-29 05:07:18 +01:00
.padding(.leading, 4)
Text(account.localizedAccountName())
2020-10-28 16:19:42 +01:00
}
.tag(account)
})
})
.pickerStyle(RadioGroupPickerStyle())
2020-10-29 05:07:18 +01:00
.offset(x: 7.5, y: 0)
Text(AddAccountSections.local.sectionFooter).foregroundColor(.gray)
.padding(.horizontal)
2020-12-06 02:56:02 +01:00
.lineLimit(3)
.fixedSize(horizontal: false, vertical: true)
2020-10-28 16:19:42 +01:00
}
}
2024-03-20 07:05:30 +01:00
@MainActor var icloudAccount: some View {
2020-10-28 16:19:42 +01:00
VStack(alignment: .leading) {
Text("iCloud")
.font(.headline)
.padding(.horizontal)
.padding(.top, 8)
2020-10-28 16:19:42 +01:00
Picker(selection: $selectedAccount, label: Text(""), content: {
ForEach(AddAccountSections.icloud.sectionContent, id: \.self, content: { account in
2020-10-30 02:44:44 +01:00
HStack(alignment: .center) {
2020-10-29 05:07:18 +01:00
account.image()
2020-10-28 16:19:42 +01:00
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 20, height: 20, alignment: .center)
2020-10-29 05:07:18 +01:00
.padding(.leading, 4)
Text(account.localizedAccountName())
2020-10-28 16:19:42 +01:00
}
.tag(account)
})
})
2020-10-29 05:07:18 +01:00
.offset(x: 7.5, y: 0)
2020-10-28 16:19:42 +01:00
.disabled(isCloudInUse())
Text(AddAccountSections.icloud.sectionFooter).foregroundColor(.gray)
.padding(.horizontal)
2020-12-06 02:56:02 +01:00
.lineLimit(3)
.fixedSize(horizontal: false, vertical: true)
2020-10-28 16:19:42 +01:00
}
}
@ViewBuilder
@MainActor var webAccounts: some View {
2020-10-28 16:19:42 +01:00
VStack(alignment: .leading) {
Text("Web")
.font(.headline)
.padding(.horizontal)
.padding(.top, 8)
HStack {
2024-02-25 06:34:54 +01:00
ForEach(0..<chunkedWebAccounts().count, id: \.self, content: { chunk in
VStack {
Picker(selection: $selectedAccount, label: Text(""), content: {
ForEach(chunkedWebAccounts()[chunk], id: \.self, content: { account in
HStack(alignment: .center) {
account.image()
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 20, height: 20, alignment: .center)
.padding(.leading, 4)
Text(account.localizedAccountName())
}
.tag(account)
})
})
Spacer()
2020-10-28 16:19:42 +01:00
}
})
}
2020-10-29 05:07:18 +01:00
.offset(x: 7.5, y: 0)
Text(AddAccountSections.web.sectionFooter).foregroundColor(.gray)
.padding(.horizontal)
2020-12-06 02:56:02 +01:00
.lineLimit(3)
.fixedSize(horizontal: false, vertical: true)
2020-10-28 16:19:42 +01:00
}
}
@MainActor var selfhostedAccounts: some View {
2020-10-28 16:19:42 +01:00
VStack(alignment: .leading) {
Text("Self-hosted")
.font(.headline)
.padding(.horizontal)
2020-10-29 09:27:52 +01:00
.padding(.top, 8)
2020-10-28 16:19:42 +01:00
Picker(selection: $selectedAccount, label: Text(""), content: {
ForEach(AddAccountSections.selfhosted.sectionContent, id: \.self, content: { account in
2020-10-30 02:44:44 +01:00
HStack(alignment: .center) {
2020-10-29 05:07:18 +01:00
account.image()
2020-10-28 16:19:42 +01:00
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 20, height: 20, alignment: .center)
2020-10-29 05:07:18 +01:00
.padding(.leading, 4)
Text(account.localizedAccountName())
2020-10-28 16:19:42 +01:00
}.tag(account)
})
})
2020-10-29 05:07:18 +01:00
.offset(x: 7.5, y: 0)
2020-10-28 16:19:42 +01:00
Text(AddAccountSections.selfhosted.sectionFooter).foregroundColor(.gray)
.padding(.horizontal)
2020-12-06 02:56:02 +01:00
.lineLimit(3)
.fixedSize(horizontal: false, vertical: true)
2020-10-28 16:19:42 +01:00
}
}
2024-03-20 07:05:30 +01:00
@MainActor private func isCloudInUse() -> Bool {
AccountManager.shared.accounts.contains(where: { $0.accountType == .cloudKit })
2020-10-28 16:19:42 +01:00
}
private func chunkedWebAccounts() -> [[AccountType]] {
AddAccountSections.web.sectionContent.chunked(into: chunkLimit)
2020-10-28 16:19:42 +01:00
}
2020-10-28 16:19:42 +01:00
}
struct AddAccountsView_Previews: PreviewProvider {
static var previews: some View {
AddAccountsView(delegate: nil)
}
}