More settings work

This commit is contained in:
Stuart Breckenridge
2022-11-30 21:37:39 +08:00
parent 36fa87b8c4
commit f2cda7fcad
17 changed files with 275 additions and 191 deletions

View File

@@ -9,6 +9,26 @@
import UIKit
import SafariServices
import Account
import SwiftUI
struct AccountInspectorWrapper: UIViewControllerRepresentable {
var account: Account
func makeUIViewController(context: Context) -> AccountInspectorViewController {
let controller = UIStoryboard.inspector.instantiateViewController(withIdentifier: "AccountInspectorViewController") as! AccountInspectorViewController
controller.account = account
return controller
}
func updateUIViewController(_ uiViewController: AccountInspectorViewController, context: Context) {
//
}
typealias UIViewControllerType = AccountInspectorViewController
}
class AccountInspectorViewController: UITableViewController {

View File

@@ -7,6 +7,27 @@
//
import UIKit
import SwiftUI
struct ExtensionPointInspectorWrapper: UIViewControllerRepresentable {
var extensionPoint: ExtensionPoint?
func makeUIViewController(context: Context) -> ExtensionPointInspectorViewController {
let controller = UIStoryboard.inspector.instantiateViewController(withIdentifier: "ExtensionPointInspectorViewController") as! ExtensionPointInspectorViewController
controller.extensionPoint = extensionPoint
return controller
}
func updateUIViewController(_ uiViewController: ExtensionPointInspectorViewController, context: Context) {
//
}
typealias UIViewControllerType = ExtensionPointInspectorViewController
}
class ExtensionPointInspectorViewController: UITableViewController {

View File

@@ -1,119 +0,0 @@
//
// AccountsManagementView.swift
// NetNewsWire-iOS
//
// Created by Stuart Breckenridge on 13/11/2022.
// Copyright © 2022 Ranchero Software. All rights reserved.
//
import SwiftUI
import Account
import Combine
struct AccountsManagementView: View {
@State private var showAddAccountSheet: Bool = false
var cancellables = Set<AnyCancellable>()
@State private var sortedAccounts = [Account]()
var body: some View {
List {
ForEach(sortedAccounts, id: \.self) { account in
Section(header: Text("")) {
accountRow(account)
}
}
}
.navigationTitle(Text("Accounts"))
.navigationBarTitleDisplayMode(.inline)
.tint(Color(uiColor: AppAssets.primaryAccentColor))
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
//
} label: {
Image(systemName: "plus")
}
}
}
.onReceive(NotificationCenter.default.publisher(for: .AccountStateDidChange)) { _ in
sortedAccounts = AccountManager.shared.sortedAccounts
}
.onAppear {
sortedAccounts = AccountManager.shared.sortedAccounts
}
}
var addAccountButton: some View {
HStack {
Spacer()
Text("Add Account")
.padding(8)
.overlay(NavigationLink { AddAccountViewControllerRepresentable() } label: { EmptyView() }.opacity(0.0))
.background(Color(uiColor: AppAssets.primaryAccentColor))
.clipShape(RoundedRectangle(cornerRadius: 6))
Spacer()
}
}
func accountFooterText(_ account: Account) -> some View {
if account.type == .cloudKit {
return Text("iCloud Syncing Limitations & Solutions")
} else {
return Text("")
}
}
func accountRow(_ account: Account) -> some View {
VStack(alignment: .leading) {
HStack {
Image(uiImage: account.smallIcon!.image)
.resizable()
.frame(width: 25, height: 25)
TextField(text: Binding(get: { account.nameForDisplay }, set: { account.name = $0 })) {
Text(account.nameForDisplay)
}.foregroundColor(.secondary)
Spacer()
Toggle(isOn: Binding<Bool>(
get: { account.isActive },
set: { account.isActive = $0 }
)) {
Text("")
}
}
if account.type != .onMyMac {
Divider()
.edgesIgnoringSafeArea(.all)
HStack {
Spacer()
Button {
// Remove account
} label: {
Text("Remove Account")
.foregroundColor(.red)
.bold()
}
Spacer()
}
}
}
}
var inactiveFooterText: some View {
if AccountManager.shared.sortedAccounts.filter({ $0.isActive == false }).count == 0 {
return Text("There are no inactive accounts.")
} else {
return Text("")
}
}
}
struct AddAccountView_Previews: PreviewProvider {
static var previews: some View {
AccountsManagementView()
}
}

View File

@@ -11,6 +11,25 @@ import AuthenticationServices
import Account
import OAuthSwift
import Secrets
import SwiftUI
struct EnableExtensionPointViewWrapper: UIViewControllerRepresentable {
var extensionPoint: ExtensionPoint.Type?
func makeUIViewController(context: Context) -> EnableExtensionPointViewController {
let controller = UIStoryboard.settings.instantiateViewController(withIdentifier: "EnableExtensionPointViewController") as! EnableExtensionPointViewController
controller.extensionPointType = extensionPoint
return controller
}
func updateUIViewController(_ uiViewController: EnableExtensionPointViewController, context: Context) {
}
typealias UIViewControllerType = EnableExtensionPointViewController
}
class EnableExtensionPointViewController: UITableViewController {

View File

@@ -385,10 +385,10 @@
<tableViewSection headerTitle="Appearance" id="TkH-4v-yhk">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="EvG-yE-gDF" customClass="VibrantBasicTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="981.5" width="374" height="43.5"/>
<rect key="frame" x="20" y="1002" width="374" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="EvG-yE-gDF" id="wBN-zJ-6pN">
<rect key="frame" x="0.0" y="0.0" width="343.5" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="355.5" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Color Palette" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2Fp-li-dGP">
@@ -1185,7 +1185,7 @@
<!--Extension-->
<scene sceneID="sHq-4g-bAA">
<objects>
<tableViewController id="8Eu-UD-eCa" customClass="EnableExtensionPointViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableViewController storyboardIdentifier="EnableExtensionPointViewController" id="8Eu-UD-eCa" customClass="EnableExtensionPointViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="hqD-G5-jzC">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>

View File

@@ -0,0 +1,106 @@
//
// AccountsManagementView.swift
// NetNewsWire-iOS
//
// Created by Stuart Breckenridge on 13/11/2022.
// Copyright © 2022 Ranchero Software. All rights reserved.
//
import SwiftUI
import Account
import Combine
struct AddAccountWrapper: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> AddAccountViewController {
let controller = UIStoryboard.settings.instantiateViewController(withIdentifier: "AddAccountViewController") as! AddAccountViewController
return controller
}
func updateUIViewController(_ uiViewController: AddAccountViewController, context: Context) {
//
}
typealias UIViewControllerType = AddAccountViewController
}
struct AccountsManagementView: View {
@State private var showAddAccountSheet: Bool = false
var cancellables = Set<AnyCancellable>()
@State private var sortedAccounts = [Account]()
var body: some View {
List {
ForEach(sortedAccounts, id: \.self) { account in
accountRow(account)
}
}
.navigationTitle(Text("Accounts"))
.tint(Color(uiColor: AppAssets.primaryAccentColor))
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
showAddAccountSheet = true
} label: {
Image(systemName: "plus")
}
}
}
.onReceive(NotificationCenter.default.publisher(for: .AccountStateDidChange)) { _ in
refreshAccounts()
}
.onReceive(NotificationCenter.default.publisher(for: .UserDidAddAccount)) { _ in
refreshAccounts()
}
.onReceive(NotificationCenter.default.publisher(for: .UserDidDeleteAccount)) { _ in
refreshAccounts()
}
.onReceive(NotificationCenter.default.publisher(for: .DisplayNameDidChange)) { _ in
refreshAccounts()
}
.task(priority: .userInitiated) {
refreshAccounts()
}
.sheet(isPresented: $showAddAccountSheet) {
NavigationView {
AddAccountWrapper()
.navigationTitle("Add Account")
.navigationBarTitleDisplayMode(.inline)
.edgesIgnoringSafeArea(.all)
}
}
}
func refreshAccounts() {
sortedAccounts = []
sortedAccounts = AccountManager.shared.sortedAccounts
}
func accountRow(_ account: Account) -> some View {
NavigationLink {
AccountInspectorWrapper(account: account)
.edgesIgnoringSafeArea(.all)
} label: {
Image(uiImage: account.smallIcon!.image)
.resizable()
.frame(width: 25, height: 25)
Text(account.nameForDisplay)
}
}
var inactiveFooterText: some View {
if AccountManager.shared.sortedAccounts.filter({ $0.isActive == false }).count == 0 {
return Text("There are no inactive accounts.")
} else {
return Text("")
}
}
}
struct AddAccountView_Previews: PreviewProvider {
static var previews: some View {
AccountsManagementView()
}
}

View File

@@ -0,0 +1,59 @@
//
// ExtensionsManagementView.swift
// NetNewsWire-iOS
//
// Created by Stuart Breckenridge on 30/11/2022.
// Copyright © 2022 Ranchero Software. All rights reserved.
//
import SwiftUI
import Account
struct ExtensionsManagementView: View {
@State private var availableExtensionPointTypes = ExtensionPointManager.shared.availableExtensionPointTypes.sorted(by: { $0.title < $1.title })
var body: some View {
List {
Section(header: Text("Add Extension"), footer: Text("Extensions allow you to subscribe to some pages as if they were RSS feeds.")) {
ForEach(0..<availableExtensionPointTypes.count, id: \.self) { i in
NavigationLink {
EnableExtensionPointViewWrapper(extensionPoint: availableExtensionPointTypes[i])
.edgesIgnoringSafeArea(.all)
} label: {
Image(uiImage: availableExtensionPointTypes[i].image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 25, height: 25)
Text("\(availableExtensionPointTypes[i].title)")
}
}
}
Section(header: Text("Active Extensions")) {
ForEach(0..<ExtensionPointManager.shared.activeExtensionPoints.count, id: \.self) { i in
let point = Array(ExtensionPointManager.shared.activeExtensionPoints)[i]
NavigationLink {
ExtensionPointInspectorWrapper(extensionPoint: point.value)
.navigationBarTitle(Text(point.value.title))
.edgesIgnoringSafeArea(.all)
} label: {
Image(uiImage: point.value.image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 25, height: 25)
Text(point.value.title)
}
}
}
}
.navigationTitle(Text("Manage Extensions"))
}
}
struct ExtensionsManagementView_Previews: PreviewProvider {
static var previews: some View {
ExtensionsManagementView()
}
}

View File

@@ -11,38 +11,11 @@ import Account
import UniformTypeIdentifiers
// MARK: - Headers
struct SettingsViewHeaders {
static func AddAccountHeader(_ showAddAccount: Binding<Bool>) -> some View {
HStack {
//Text("Accounts")
Spacer()
Button {
showAddAccount.wrappedValue.toggle()
} label: {
Text("Add")
.font(.caption)
.bold()
Image(systemName: "plus")
.font(.caption)
}
.buttonBorderShape(.capsule)
.buttonStyle(.bordered)
.padding(.trailing, -15) // moves to trailing edge
}
}
}
// MARK: - Rows
struct SettingsViewRows {
/// This row, when tapped, will open system settings.
/// This row, when tapped, will open iOS System Settings.
static var OpenSystemSettings: some View {
Label {
Text("Open System Settings")
@@ -88,26 +61,10 @@ struct SettingsViewRows {
}
}
/// This `view` creates a `Label` for each active `Account`.
/// Each `Label`, when tapped, will present the configurator for
/// the `Account`.
static var ActiveAccounts: some View {
ForEach(AccountManager.shared.sortedActiveAccounts, id: \.self) { account in
Label {
Text(account.nameForDisplay)
} icon: {
Image(uiImage: AppAssets.image(for: account.type)!)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 25.0, height: 25.0)
}
}
}
/// This row, when tapped, will push the the Add Extension screen
/// This row, when tapped, will push the the Manage Extension screen
/// in to view.
static var AddExtension: some View {
NavigationLink(destination: NotificationsViewControllerRepresentable()) {
static var ManageExtensions: some View {
NavigationLink(destination: ExtensionsManagementView()) {
Label {
Text("Manage Extensions")
} icon: {
@@ -199,6 +156,8 @@ struct SettingsViewRows {
}
}
/// This row, when tapped, will push the the Theme Selector screen
/// in to view.
static var ThemeSelection: some View {
NavigationLink(destination: ArticleThemesViewControllerRepresentable().edgesIgnoringSafeArea(.all)) {
HStack {
@@ -220,7 +179,6 @@ struct SettingsViewRows {
}
// TODO: Add Reader Mode Defaults here. See #3684.
static func EnableFullScreenArticles(_ preference: Binding<Bool>) -> some View {
Toggle(isOn: preference) {
VStack(alignment: .leading, spacing: 4) {

View File

@@ -28,7 +28,7 @@ struct SettingsView: View {
// Account/Extensions/OPML Management
Section(header: Text("Accounts & Extensions"), footer: Text("Add, delete, enable, or disable accounts and extensions.")) {
SettingsViewRows.AddAccount
SettingsViewRows.AddExtension
SettingsViewRows.ManageExtensions
SettingsViewRows.ImportExportOPML(showImportView: $viewModel.showImportView, showExportView: $viewModel.showExportView, importAccount: $viewModel.importAccount, exportDocument: $viewModel.exportDocument)
}

View File

@@ -28,6 +28,5 @@ public final class SettingsViewModel: ObservableObject {
@Published public var showImportSuccess: Bool = false
@Published public var showExportSuccess: Bool = false
@Published public var exportDocument: OPMLDocument?
}

View File

@@ -18,7 +18,7 @@ public enum HelpSheet: CustomStringConvertible, CaseIterable {
case .help:
return NSLocalizedString("NetNewsWire Help", comment: "NetNewsWire Help")
case .website:
return NSLocalizedString("Website", comment: "Website")
return NSLocalizedString("NetNewsWire Website", comment: "NetNewsWire Website")
}
}

View File

@@ -29,6 +29,7 @@ struct NewArticleNotificationsView: View {
activeAccounts = AccountManager.shared.sortedActiveAccounts
}
}
.tint(Color(uiColor: AppAssets.primaryAccentColor))
}