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
|
|
|
|
|
2020-11-04 03:35:53 +01:00
|
|
|
enum AddAccountSections: Int, CaseIterable {
|
2020-10-28 16:19:42 +01:00
|
|
|
case local = 0
|
|
|
|
case icloud
|
|
|
|
case web
|
|
|
|
case selfhosted
|
2020-11-04 03:35:53 +01:00
|
|
|
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")
|
2020-11-04 03:35:53 +01:00
|
|
|
case .allOrdered:
|
|
|
|
return ""
|
2020-10-28 16:19:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var sectionFooter: String {
|
|
|
|
switch self {
|
|
|
|
case .local:
|
2020-10-30 02:30:11 +01:00
|
|
|
return NSLocalizedString("Local accounts do not sync subscriptions across devices.", comment: "Local Account")
|
2020-10-28 16:19:42 +01:00
|
|
|
case .icloud:
|
|
|
|
return NSLocalizedString("Use your iCloud account to sync your subscriptions across your iOS and macOS devices.", comment: "iCloud Account")
|
|
|
|
case .web:
|
|
|
|
return NSLocalizedString("Web accounts sync your subscriptions across all your devices.", comment: "Web Account")
|
|
|
|
case .selfhosted:
|
|
|
|
return NSLocalizedString("Self-hosted accounts sync your subscriptions across all your devices.", comment: "Self hosted Account")
|
2020-11-04 03:35:53 +01:00
|
|
|
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:
|
2020-11-12 22:48:25 +01:00
|
|
|
#if DEBUG
|
2020-10-28 16:19:42 +01:00
|
|
|
return [.bazQux, .feedbin, .feedly, .feedWrangler, .inoreader, .newsBlur, .theOldReader]
|
2020-11-12 22:48:25 +01:00
|
|
|
#else
|
|
|
|
return [.bazQux, .feedbin, .feedly, .inoreader, .newsBlur, .theOldReader]
|
|
|
|
#endif
|
2020-10-28 16:19:42 +01:00
|
|
|
case .selfhosted:
|
|
|
|
return [.freshRSS]
|
2020-11-04 03:35:53 +01:00
|
|
|
case .allOrdered:
|
|
|
|
return AddAccountSections.local.sectionContent +
|
|
|
|
AddAccountSections.icloud.sectionContent +
|
|
|
|
AddAccountSections.web.sectionContent +
|
|
|
|
AddAccountSections.selfhosted.sectionContent
|
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?
|
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
|
|
|
|
icloudAccount
|
|
|
|
webAccounts
|
|
|
|
selfhostedAccounts
|
|
|
|
|
2020-10-29 05:07:18 +01:00
|
|
|
HStack(spacing: 12) {
|
2020-10-28 16:19:42 +01:00
|
|
|
Spacer()
|
|
|
|
if #available(OSX 11.0, *) {
|
|
|
|
Button(action: {
|
|
|
|
parent?.dismiss(nil)
|
|
|
|
}, label: {
|
|
|
|
Text("Cancel")
|
2020-10-29 05:07:18 +01:00
|
|
|
.frame(width: 80)
|
|
|
|
})
|
|
|
|
.help("Cancel")
|
|
|
|
.keyboardShortcut(.cancelAction)
|
|
|
|
|
2020-10-28 16:19:42 +01:00
|
|
|
} else {
|
|
|
|
Button(action: {
|
|
|
|
parent?.dismiss(nil)
|
|
|
|
}, label: {
|
|
|
|
Text("Cancel")
|
2020-10-29 05:07:18 +01:00
|
|
|
.frame(width: 80)
|
2020-10-28 16:19:42 +01:00
|
|
|
})
|
2020-10-29 05:07:18 +01:00
|
|
|
.accessibility(label: Text("Add Account"))
|
2020-10-28 16:19:42 +01:00
|
|
|
}
|
|
|
|
if #available(OSX 11.0, *) {
|
|
|
|
Button(action: {
|
|
|
|
addAccountDelegate?.presentSheetForAccount(selectedAccount)
|
|
|
|
parent?.dismiss(nil)
|
|
|
|
}, label: {
|
|
|
|
Text("Continue")
|
2020-10-29 05:07:18 +01:00
|
|
|
.frame(width: 80)
|
|
|
|
})
|
|
|
|
.help("Add Account")
|
|
|
|
.keyboardShortcut(.defaultAction)
|
|
|
|
|
2020-10-28 16:19:42 +01:00
|
|
|
} else {
|
|
|
|
Button(action: {
|
|
|
|
addAccountDelegate?.presentSheetForAccount(selectedAccount)
|
|
|
|
parent?.dismiss(nil)
|
|
|
|
}, label: {
|
|
|
|
Text("Continue")
|
2020-10-29 05:07:18 +01:00
|
|
|
.frame(width: 80)
|
2020-10-28 16:19:42 +01:00
|
|
|
})
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
var localAccount: some View {
|
|
|
|
VStack(alignment: .leading) {
|
|
|
|
Text("Local")
|
|
|
|
.font(.headline)
|
|
|
|
.padding(.horizontal)
|
2020-10-30 02:30:11 +01:00
|
|
|
|
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: 25, height: 25, alignment: .center)
|
2020-10-29 05:07:18 +01:00
|
|
|
.padding(.leading, 4)
|
2020-10-30 02:30:11 +01:00
|
|
|
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)
|
2020-10-30 02:30:11 +01:00
|
|
|
|
|
|
|
Text(AddAccountSections.local.sectionFooter).foregroundColor(.gray)
|
|
|
|
.font(.caption)
|
|
|
|
.padding(.horizontal)
|
|
|
|
|
2020-10-28 16:19:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
var icloudAccount: some View {
|
|
|
|
VStack(alignment: .leading) {
|
|
|
|
Text("iCloud")
|
|
|
|
.font(.headline)
|
|
|
|
.padding(.horizontal)
|
2020-10-30 02:30:11 +01:00
|
|
|
.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: 25, height: 25, alignment: .center)
|
2020-10-29 05:07:18 +01:00
|
|
|
.padding(.leading, 4)
|
|
|
|
|
2020-10-30 02:30:11 +01:00
|
|
|
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())
|
2020-10-30 02:30:11 +01:00
|
|
|
|
|
|
|
Text(AddAccountSections.icloud.sectionFooter).foregroundColor(.gray)
|
|
|
|
.font(.caption)
|
|
|
|
.padding(.horizontal)
|
2020-10-28 16:19:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var webAccounts: some View {
|
|
|
|
VStack(alignment: .leading) {
|
|
|
|
Text("Web")
|
|
|
|
.font(.headline)
|
|
|
|
.padding(.horizontal)
|
2020-10-30 02:30:11 +01:00
|
|
|
.padding(.top, 8)
|
|
|
|
|
2020-10-28 16:19:42 +01:00
|
|
|
Picker(selection: $selectedAccount, label: Text(""), content: {
|
|
|
|
ForEach(AddAccountSections.web.sectionContent.filter({ isRestricted($0) != true }), id: \.self, content: { account in
|
|
|
|
|
|
|
|
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: 25, height: 25, alignment: .center)
|
2020-10-29 05:07:18 +01:00
|
|
|
.padding(.leading, 4)
|
2020-10-28 16:19:42 +01:00
|
|
|
|
2020-10-30 02:30:11 +01:00
|
|
|
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-30 02:30:11 +01:00
|
|
|
|
|
|
|
Text(AddAccountSections.web.sectionFooter).foregroundColor(.gray)
|
|
|
|
.font(.caption)
|
|
|
|
.padding(.horizontal)
|
2020-10-28 16:19:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var selfhostedAccounts: some View {
|
|
|
|
VStack(alignment: .leading) {
|
|
|
|
Text("Self-hosted")
|
|
|
|
.font(.headline)
|
|
|
|
.padding(.horizontal)
|
2020-10-29 09:27:52 +01:00
|
|
|
.padding(.top, 8)
|
2020-10-30 02:30:11 +01:00
|
|
|
|
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: 25, height: 25, alignment: .center)
|
2020-10-29 05:07:18 +01:00
|
|
|
.padding(.leading, 4)
|
2020-10-30 02:30:11 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
2020-10-30 02:30:11 +01:00
|
|
|
Text(AddAccountSections.selfhosted.sectionFooter).foregroundColor(.gray)
|
|
|
|
.font(.caption)
|
|
|
|
.padding(.horizontal)
|
2020-10-28 16:19:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private func isCloudInUse() -> Bool {
|
|
|
|
AccountManager.shared.accounts.contains(where: { $0.type == .cloudKit })
|
|
|
|
}
|
|
|
|
|
|
|
|
private func isRestricted(_ accountType: AccountType) -> Bool {
|
|
|
|
if AppDefaults.shared.isDeveloperBuild && (accountType == .feedly || accountType == .feedWrangler || accountType == .inoreader) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct AddAccountsView_Previews: PreviewProvider {
|
|
|
|
static var previews: some View {
|
|
|
|
AddAccountsView(delegate: nil)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|