diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index a33b9a761..0a932159a 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -871,6 +871,10 @@ DFB349A0294E87B700BC81AD /* LocalAddAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFB3499F294E87B700BC81AD /* LocalAddAccountView.swift */; }; DFB349A2294E90B500BC81AD /* FeedbinAddAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFB349A1294E90B500BC81AD /* FeedbinAddAccountView.swift */; }; DFB349A4294E914D00BC81AD /* AccountSectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFB349A3294E914D00BC81AD /* AccountSectionHeader.swift */; }; + DFBB4EAC2951BC0200639228 /* NNWThemeDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFBB4EAB2951BC0200639228 /* NNWThemeDocument.swift */; }; + DFBB4EAD2951BC0200639228 /* NNWThemeDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFBB4EAB2951BC0200639228 /* NNWThemeDocument.swift */; }; + DFBB4EAE2951BC0200639228 /* NNWThemeDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFBB4EAB2951BC0200639228 /* NNWThemeDocument.swift */; }; + DFBB4EB02951BCAC00639228 /* ArticleThemeManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFBB4EAF2951BCAC00639228 /* ArticleThemeManagerView.swift */; }; DFC14F0F28EA55BD00F6EE86 /* AboutWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFC14F0E28EA55BD00F6EE86 /* AboutWindowController.swift */; }; DFC14F1228EA5DC500F6EE86 /* AboutData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF790D6128E990A900455FC7 /* AboutData.swift */; }; DFC14F1328EA677C00F6EE86 /* Bundle-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F85BF42273625800C787DC /* Bundle-Extensions.swift */; }; @@ -1633,6 +1637,8 @@ DFB3499F294E87B700BC81AD /* LocalAddAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAddAccountView.swift; sourceTree = ""; }; DFB349A1294E90B500BC81AD /* FeedbinAddAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinAddAccountView.swift; sourceTree = ""; }; DFB349A3294E914D00BC81AD /* AccountSectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSectionHeader.swift; sourceTree = ""; }; + DFBB4EAB2951BC0200639228 /* NNWThemeDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NNWThemeDocument.swift; sourceTree = ""; }; + DFBB4EAF2951BCAC00639228 /* ArticleThemeManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleThemeManagerView.swift; sourceTree = ""; }; DFC14F0E28EA55BD00F6EE86 /* AboutWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindowController.swift; sourceTree = ""; }; DFC14F1428EB177000F6EE86 /* AboutNetNewsWireView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutNetNewsWireView.swift; sourceTree = ""; }; DFC14F1628EB17A800F6EE86 /* CreditsNetNewsWireView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreditsNetNewsWireView.swift; sourceTree = ""; }; @@ -1923,7 +1929,9 @@ 5123DB95233EC69300282CC9 /* Inspector */ = { isa = PBXGroup; children = ( - DFB3497D294B076C00BC81AD /* Views */, + DFB3497F294B085100BC81AD /* AccountInspectorView.swift */, + DFB34989294B45AC00BC81AD /* ExtensionInspectorView.swift */, + DFB3498B294B4CA700BC81AD /* WebFeedInspectorView.swift */, ); path = Inspector; sourceTree = ""; @@ -1993,7 +2001,11 @@ 516A093E236123A800EAE89B /* Account */ = { isa = PBXGroup; children = ( - DFB3498F294C0B0D00BC81AD /* Views */, + DFB3499F294E87B700BC81AD /* LocalAddAccountView.swift */, + DFB3499D294C5D5000BC81AD /* CloudKitAddAccountView.swift */, + DFB349A1294E90B500BC81AD /* FeedbinAddAccountView.swift */, + DF28B44E294ED92F00C4D8CA /* NewsBlurAddAccountView.swift */, + DFB34990294C0B2200BC81AD /* ReaderAPIAddAccountView.swift */, ); path = Account; sourceTree = ""; @@ -2023,7 +2035,11 @@ 5183CCEB227117C70010922C /* Settings */ = { isa = PBXGroup; children = ( - DFD406F8291FB5D500C02962 /* Views */, + DF766FEB2936344D006FBBE2 /* General */, + DFD406FD291FDBD900C02962 /* Appearance */, + DF59F0752920E42000ACD33D /* Account and Extensions */, + DF3630E92936038400326FB8 /* New Article Notifications */, + DF766FEA2936337A006FBBE2 /* Help */, 5137C2E926F63AE6009EFEDB /* ArticleThemeImporter.swift */, 510FFAB226EEA22C00F32265 /* ArticleThemesTableViewController.swift */, 51A16990235E10D600EB091F /* Settings.storyboard */, @@ -2786,6 +2802,7 @@ 849A97591ED9EB0D007D329B /* DefaultFeedsImporter.swift */, 84A3EE52223B667F00557320 /* DefaultFeeds.opml */, DF3630EA2936183D00326FB8 /* OPMLDocument.swift */, + DFBB4EAB2951BC0200639228 /* NNWThemeDocument.swift */, ); path = Importers; sourceTree = ""; @@ -2957,16 +2974,6 @@ path = Extensions; sourceTree = ""; }; - DFB3497D294B076C00BC81AD /* Views */ = { - isa = PBXGroup; - children = ( - DFB3497F294B085100BC81AD /* AccountInspectorView.swift */, - DFB34989294B45AC00BC81AD /* ExtensionInspectorView.swift */, - DFB3498B294B4CA700BC81AD /* WebFeedInspectorView.swift */, - ); - path = Views; - sourceTree = ""; - }; DFB3497E294B07D900BC81AD /* Views */ = { isa = PBXGroup; children = ( @@ -2999,18 +3006,6 @@ path = "SwiftUI Extensions"; sourceTree = ""; }; - DFB3498F294C0B0D00BC81AD /* Views */ = { - isa = PBXGroup; - children = ( - DFB3499F294E87B700BC81AD /* LocalAddAccountView.swift */, - DFB3499D294C5D5000BC81AD /* CloudKitAddAccountView.swift */, - DFB349A1294E90B500BC81AD /* FeedbinAddAccountView.swift */, - DF28B44E294ED92F00C4D8CA /* NewsBlurAddAccountView.swift */, - DFB34990294C0B2200BC81AD /* ReaderAPIAddAccountView.swift */, - ); - path = Views; - sourceTree = ""; - }; DFC14F0928EA51AB00F6EE86 /* About */ = { isa = PBXGroup; children = ( @@ -3021,24 +3016,13 @@ path = About; sourceTree = ""; }; - DFD406F8291FB5D500C02962 /* Views */ = { - isa = PBXGroup; - children = ( - DF766FEB2936344D006FBBE2 /* General */, - DFD406FD291FDBD900C02962 /* Appearance */, - DF59F0752920E42000ACD33D /* Account and Extensions */, - DF3630E92936038400326FB8 /* New Article Notifications */, - DF766FEA2936337A006FBBE2 /* Help */, - ); - path = Views; - sourceTree = ""; - }; DFD406FD291FDBD900C02962 /* Appearance */ = { isa = PBXGroup; children = ( DFD406FE291FDC0C00C02962 /* DisplayAndBehaviorsView.swift */, DF59F071292085B800ACD33D /* ColorPaletteSelectorView.swift */, DF84E562295122BA0045C334 /* TimelineCustomizerView.swift */, + DFBB4EAF2951BCAC00639228 /* ArticleThemeManagerView.swift */, ); path = Appearance; sourceTree = ""; @@ -4042,6 +4026,7 @@ 65ED3FD5235DEF6C0081F399 /* SmartFeed.swift in Sources */, 51333D1724685D2E00EB5C91 /* AddRedditFeedWindowController.swift in Sources */, 65ED3FD6235DEF6C0081F399 /* MarkStatusCommand.swift in Sources */, + DFBB4EAD2951BC0200639228 /* NNWThemeDocument.swift in Sources */, 5183CFB0254C78C8006B83A5 /* EnableExtensionPointView.swift in Sources */, 65ED3FD7235DEF6C0081F399 /* NSApplication+Scriptability.swift in Sources */, 65ED3FD8235DEF6C0081F399 /* NSView-Extensions.swift in Sources */, @@ -4211,6 +4196,7 @@ 518ED21D23D0F26000E0A862 /* UIViewController-Extensions.swift in Sources */, DFD406FF291FDC0C00C02962 /* DisplayAndBehaviorsView.swift in Sources */, 51A9A5F52380F6A60033AADF /* ModalNavigationController.swift in Sources */, + DFBB4EAE2951BC0200639228 /* NNWThemeDocument.swift in Sources */, 51EAED96231363EF00A9EEE3 /* NonIntrinsicButton.swift in Sources */, 51C4527B2265091600C03939 /* MasterUnreadIndicatorView.swift in Sources */, 5186A635235EF3A800C97195 /* VibrantLabel.swift in Sources */, @@ -4295,6 +4281,7 @@ 51E4398023805EBC00015C31 /* AddComboTableViewCell.swift in Sources */, 51C4529A22650A0400C03939 /* ArticleTheme.swift in Sources */, 51C4527F2265092C00C03939 /* ArticleViewController.swift in Sources */, + DFBB4EB02951BCAC00639228 /* ArticleThemeManagerView.swift in Sources */, 51C4526A226508F600C03939 /* MasterFeedTableViewCellLayout.swift in Sources */, 51C452AE2265104D00C03939 /* ArticleStringFormatter.swift in Sources */, 512E08E62268800D00BDCFDD /* FolderTreeControllerDelegate.swift in Sources */, @@ -4490,6 +4477,7 @@ 845A29241FC9255E007B49E3 /* SidebarCellAppearance.swift in Sources */, 515A5107243D0CCD0089E588 /* TwitterFeedProvider-Extensions.swift in Sources */, 845EE7B11FC2366500854A1F /* StarredFeedDelegate.swift in Sources */, + DFBB4EAC2951BC0200639228 /* NNWThemeDocument.swift in Sources */, DFC14F1228EA5DC500F6EE86 /* AboutData.swift in Sources */, 848F6AE51FC29CFB002D422E /* FaviconDownloader.swift in Sources */, 511B9806237DCAC90028BCAA /* UserInfoKey.swift in Sources */, diff --git a/Shared/ArticleStyles/ArticleThemesManager.swift b/Shared/ArticleStyles/ArticleThemesManager.swift index 8e7d53dbc..80b38d293 100644 --- a/Shared/ArticleStyles/ArticleThemesManager.swift +++ b/Shared/ArticleStyles/ArticleThemesManager.swift @@ -34,6 +34,7 @@ final class ArticleThemesManager: NSObject, NSFilePresenter, Logging, Observable do { currentTheme = try articleThemeWithThemeName(newValue) AppDefaults.shared.currentThemeName = newValue + objectWillChange.send() } catch { logger.error("Unable to set new theme: \(error.localizedDescription, privacy: .public)") } @@ -51,12 +52,14 @@ final class ArticleThemesManager: NSObject, NSFilePresenter, Logging, Observable }() { didSet { NotificationCenter.default.post(name: .CurrentArticleThemeDidChangeNotification, object: self) + objectWillChange.send() } } lazy var themeNames = { buildThemeNames() }() { didSet { NotificationCenter.default.post(name: .ArticleThemeNamesDidChangeNotification, object: self) + objectWillChange.send() } } @@ -102,6 +105,7 @@ final class ArticleThemesManager: NSObject, NSFilePresenter, Logging, Observable } try FileManager.default.copyItem(atPath: filename, toPath: toFilename) + objectWillChange.send() } func articleThemeWithThemeName(_ themeName: String) throws -> ArticleTheme { @@ -127,6 +131,7 @@ final class ArticleThemesManager: NSObject, NSFilePresenter, Logging, Observable func deleteTheme(themeName: String) { if let filename = pathForThemeName(themeName, folder: folderPath) { try? FileManager.default.removeItem(atPath: filename) + objectWillChange.send() } } diff --git a/Shared/Importers/NNWThemeDocument.swift b/Shared/Importers/NNWThemeDocument.swift new file mode 100644 index 000000000..63956a9fe --- /dev/null +++ b/Shared/Importers/NNWThemeDocument.swift @@ -0,0 +1,33 @@ +// +// NNWThemeDocument.swift +// NetNewsWire +// +// Created by Stuart Breckenridge on 20/12/2022. +// Copyright © 2022 Ranchero Software. All rights reserved. +// + +import SwiftUI +import Account +import UniformTypeIdentifiers + +public struct NNWThemeDocument: FileDocument { + + public static var readableContentTypes: [UTType] { + UTType.types(tag: "nnwtheme", tagClass: .filenameExtension, conformingTo: nil) + } + + public static var writableContentTypes: [UTType] { + UTType.types(tag: "nnwtheme", tagClass: .filenameExtension, conformingTo: nil) + } + + public init(configuration: ReadConfiguration) throws { + + } + + public func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { + let wrapper = try FileWrapper(url: URL(string: "")!) + return wrapper + } + +} + diff --git a/Shared/Localizations/Buttons.strings b/Shared/Localizations/Buttons.strings index 07dd633d4..e4f9cf191 100644 --- a/Shared/Localizations/Buttons.strings +++ b/Shared/Localizations/Buttons.strings @@ -17,3 +17,5 @@ "ENABLE_EXTENSION_BUTTON_TITLE" = "Enable Extension"; "UPDATE_CREDENTIALS_BUTTON_TITLE" = "Update Credentials"; "USE_CLOUDKIT_BUTTON_TITLE" = "Use iCloud"; +"DELETE_THEME_BUTTON_TITLE" = "Delete Theme"; +"IMPORT_THEME_BUTTON_TITLE" = "Import Theme"; diff --git a/Shared/Localizations/Settings.strings b/Shared/Localizations/Settings.strings index 38435801a..243f0cf30 100644 --- a/Shared/Localizations/Settings.strings +++ b/Shared/Localizations/Settings.strings @@ -43,7 +43,15 @@ "TIMELINE_LAYOUT" = "Timeline Layout"; "ICON_SIZE" = "Icon Size"; "NUMBER_OF_LINES" = "Number of Lines"; +"INSTALLED_THEMES" = "Installed Themes"; +"ARTICLE_THEMES_TITLE" = "Article Themes"; "ARTICLE_THEME" = "Article Theme"; +"IMPORT_THEME_CONFIRMATION_TITLE" = "Import Theme"; +"IMPORT_THEME_CONFIRMATION_MESSAGE_%@_%@" = "Are you sure you want to import “%@” by %@?"; +"IMPORT_THEME_SUCCESS_TITLE" = "Import Successful"; +"IMPORT_THEME_SUCCESS_MESSAGE_%@" = "“%@” has been imported successfully."; +"DELETE_THEME_ALERT_TITLE_%@" = "Are you sure you want to delete “%@”?"; +"DELETE_THEME_ALERT_MESSAGE" = "Are you sure you want to delete this theme? This action is not reversible."; "CONFIRM_MARK_ALL_AS_READ" = "Confirm Mark All as Read"; "OPEN_LINKS_IN_APP" = "Open Links in NetNewsWire"; "SMALL_ICON_SIZE" = "Small"; diff --git a/iOS/Account/Views/CloudKitAddAccountView.swift b/iOS/Account/CloudKitAddAccountView.swift similarity index 100% rename from iOS/Account/Views/CloudKitAddAccountView.swift rename to iOS/Account/CloudKitAddAccountView.swift diff --git a/iOS/Account/Views/FeedbinAddAccountView.swift b/iOS/Account/FeedbinAddAccountView.swift similarity index 100% rename from iOS/Account/Views/FeedbinAddAccountView.swift rename to iOS/Account/FeedbinAddAccountView.swift diff --git a/iOS/Account/Views/LocalAddAccountView.swift b/iOS/Account/LocalAddAccountView.swift similarity index 100% rename from iOS/Account/Views/LocalAddAccountView.swift rename to iOS/Account/LocalAddAccountView.swift diff --git a/iOS/Account/Views/NewsBlurAddAccountView.swift b/iOS/Account/NewsBlurAddAccountView.swift similarity index 100% rename from iOS/Account/Views/NewsBlurAddAccountView.swift rename to iOS/Account/NewsBlurAddAccountView.swift diff --git a/iOS/Account/Views/ReaderAPIAddAccountView.swift b/iOS/Account/ReaderAPIAddAccountView.swift similarity index 100% rename from iOS/Account/Views/ReaderAPIAddAccountView.swift rename to iOS/Account/ReaderAPIAddAccountView.swift diff --git a/iOS/Inspector/Views/AccountInspectorView.swift b/iOS/Inspector/AccountInspectorView.swift similarity index 100% rename from iOS/Inspector/Views/AccountInspectorView.swift rename to iOS/Inspector/AccountInspectorView.swift diff --git a/iOS/Inspector/Views/ExtensionInspectorView.swift b/iOS/Inspector/ExtensionInspectorView.swift similarity index 90% rename from iOS/Inspector/Views/ExtensionInspectorView.swift rename to iOS/Inspector/ExtensionInspectorView.swift index b2ce94540..6a2785673 100644 --- a/iOS/Inspector/Views/ExtensionInspectorView.swift +++ b/iOS/Inspector/ExtensionInspectorView.swift @@ -17,7 +17,7 @@ struct ExtensionInspectorView: View { var body: some View { Form { Section(header: extensionHeader) {} - Section(footer: Text(extensionPoint?.description.string ?? ""), content: { + Section(footer: extensionExplainer, content: { // }) @@ -65,6 +65,11 @@ struct ExtensionInspectorView: View { Spacer() } } + + var extensionExplainer: some View { + Text(extensionPoint?.description.string ?? "") + .multilineTextAlignment(.center) + } } struct ExtensionInspectorView_Previews: PreviewProvider { diff --git a/iOS/Inspector/Views/WebFeedInspectorView.swift b/iOS/Inspector/WebFeedInspectorView.swift similarity index 100% rename from iOS/Inspector/Views/WebFeedInspectorView.swift rename to iOS/Inspector/WebFeedInspectorView.swift diff --git a/iOS/Settings/Views/Account and Extensions/Accounts/AccountsManagementView.swift b/iOS/Settings/Account and Extensions/Accounts/AccountsManagementView.swift similarity index 100% rename from iOS/Settings/Views/Account and Extensions/Accounts/AccountsManagementView.swift rename to iOS/Settings/Account and Extensions/Accounts/AccountsManagementView.swift diff --git a/iOS/Settings/Views/Account and Extensions/Accounts/AddAccountListView.swift b/iOS/Settings/Account and Extensions/Accounts/AddAccountListView.swift similarity index 100% rename from iOS/Settings/Views/Account and Extensions/Accounts/AddAccountListView.swift rename to iOS/Settings/Account and Extensions/Accounts/AddAccountListView.swift diff --git a/iOS/Settings/Views/Account and Extensions/Extensions/AddExtensionListView.swift b/iOS/Settings/Account and Extensions/Extensions/AddExtensionListView.swift similarity index 100% rename from iOS/Settings/Views/Account and Extensions/Extensions/AddExtensionListView.swift rename to iOS/Settings/Account and Extensions/Extensions/AddExtensionListView.swift diff --git a/iOS/Settings/Views/Account and Extensions/Extensions/EnableExtensionPointView.swift b/iOS/Settings/Account and Extensions/Extensions/EnableExtensionPointView.swift similarity index 100% rename from iOS/Settings/Views/Account and Extensions/Extensions/EnableExtensionPointView.swift rename to iOS/Settings/Account and Extensions/Extensions/EnableExtensionPointView.swift diff --git a/iOS/Settings/Views/Account and Extensions/Extensions/EnableExtensionViewModel.swift b/iOS/Settings/Account and Extensions/Extensions/EnableExtensionViewModel.swift similarity index 100% rename from iOS/Settings/Views/Account and Extensions/Extensions/EnableExtensionViewModel.swift rename to iOS/Settings/Account and Extensions/Extensions/EnableExtensionViewModel.swift diff --git a/iOS/Settings/Views/Account and Extensions/Extensions/ExtensionsManagementView.swift b/iOS/Settings/Account and Extensions/Extensions/ExtensionsManagementView.swift similarity index 100% rename from iOS/Settings/Views/Account and Extensions/Extensions/ExtensionsManagementView.swift rename to iOS/Settings/Account and Extensions/Extensions/ExtensionsManagementView.swift diff --git a/iOS/Settings/Appearance/ArticleThemeManagerView.swift b/iOS/Settings/Appearance/ArticleThemeManagerView.swift new file mode 100644 index 000000000..d8ac8fedb --- /dev/null +++ b/iOS/Settings/Appearance/ArticleThemeManagerView.swift @@ -0,0 +1,140 @@ +// +// ArticleThemeManagerView.swift +// NetNewsWire-iOS +// +// Created by Stuart Breckenridge on 20/12/2022. +// Copyright © 2022 Ranchero Software. All rights reserved. +// + +import SwiftUI + +struct ArticleThemeManagerView: View { + + @StateObject private var themeManager = ArticleThemesManager.shared + @State private var showDeleteConfirmation: (String, Bool) = ("", false) + @State private var showImportThemeView: Bool = false + @State private var showImportConfirmationAlert: (ArticleTheme?, Bool) = (nil, false) + @State private var showImportErrorAlert: (Error?, Bool) = (nil, false) + @State private var showImportSuccessAlert: Bool = false + + var body: some View { + Form { + Section(header: Text("INSTALLED_THEMES", tableName: "Settings")) { + articleThemeRow("Default") + ForEach(themeManager.themeNames, id: \.self) {theme in + articleThemeRow(theme) + } + } + } + .navigationTitle(Text("ARTICLE_THEMES_TITLE", tableName: "Settings")) + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Button { + showImportThemeView = true + } label: { + Label { + Text("IMPORT_THEME_BUTTON_TITLE", tableName: "Buttons") + } icon: { + Image(systemName: "plus") + } + } + } + } + .fileImporter(isPresented: $showImportThemeView, allowedContentTypes: NNWThemeDocument.readableContentTypes) { result in + switch result { + case .success(let success): + do { + let theme = try ArticleTheme(path: success.path, isAppTheme: true) + showImportConfirmationAlert = (theme, true) + } catch { + showImportErrorAlert = (error, true) + } + case .failure(let failure): + showImportErrorAlert = (failure, true) + } + } + .alert(Text("DELETE_THEME_ALERT_TITLE_\(showDeleteConfirmation.0)", tableName: "Settings"), isPresented: $showDeleteConfirmation.1, actions: { + Button(role: .destructive) { + ArticleThemesManager.shared.deleteTheme(themeName: showDeleteConfirmation.0) + } label: { + Text("DELETE_THEME_BUTTON_TITLE", tableName: "Buttons") + } + + Button(role: .cancel) { + + } label: { + Text("CANCEL_BUTTON_TITLE", tableName: "Buttons") + } + }, message: { + Text("DELETE_THEME_ALERT_MESSAGE", tableName: "Settings") + }) + .alert(Text("IMPORT_THEME_CONFIRMATION_TITLE", tableName: "Settings"), + isPresented: $showImportConfirmationAlert.1, + actions: { + Button { + do { + try ArticleThemesManager.shared.importTheme(filename: showImportConfirmationAlert.0!.path!) + showImportSuccessAlert = true + } catch { + showImportErrorAlert = (error, true) + } + + } label: { + Text("IMPORT_THEME_BUTTON_TITLE", tableName: "Buttons") + } + + Button(role: .cancel) { + + } label: { + Text("CANCEL_BUTTON_TITLE", tableName: "Buttons") + } + }, message: { + Text("IMPORT_THEME_CONFIRMATION_MESSAGE_\(showImportConfirmationAlert.0?.name ?? "")_\(showImportConfirmationAlert.0?.creatorName ?? "")", tableName: "Settings") + }) + .alert(Text("IMPORT_THEME_SUCCESS_TITLE", tableName: "Settings"), + isPresented: $showImportSuccessAlert, + actions: { + Button(role: .cancel) { + + } label: { + Text("DISMISS_BUTTON_TITLE", tableName: "Buttons") + } + }, message: { + Text("IMPORT_THEME_SUCCESS_MESSAGE_\(showImportConfirmationAlert.0?.name ?? "")", tableName: "Settings") + }) + } + + func articleThemeRow(_ theme: String) -> some View { + Button { + ArticleThemesManager.shared.currentThemeName = theme + } label: { + HStack { + Text(theme) + .foregroundColor(.primary) + Spacer() + if ArticleThemesManager.shared.currentThemeName == theme { + Image(systemName: "checkmark") + .foregroundColor(Color(uiColor: AppAssets.primaryAccentColor)) + } + } + } + .swipeActions(edge: .trailing, allowsFullSwipe: false) { + if theme == "Default" || ArticleThemesManager.shared.currentThemeName == theme { } + else { + Button { + showDeleteConfirmation = (theme, true) + } label: { + Text("DELETE_BUTTON_TITLE", tableName: "Buttons") + Image(systemName: "trash") + } + .tint(.red) + } + } + } +} + +struct ArticleThemeImporterView_Previews: PreviewProvider { + static var previews: some View { + ArticleThemeManagerView() + } +} diff --git a/iOS/Settings/Views/Appearance/ColorPaletteSelectorView.swift b/iOS/Settings/Appearance/ColorPaletteSelectorView.swift similarity index 100% rename from iOS/Settings/Views/Appearance/ColorPaletteSelectorView.swift rename to iOS/Settings/Appearance/ColorPaletteSelectorView.swift diff --git a/iOS/Settings/Views/Appearance/DisplayAndBehaviorsView.swift b/iOS/Settings/Appearance/DisplayAndBehaviorsView.swift similarity index 100% rename from iOS/Settings/Views/Appearance/DisplayAndBehaviorsView.swift rename to iOS/Settings/Appearance/DisplayAndBehaviorsView.swift diff --git a/iOS/Settings/Views/Appearance/TimelineCustomizerView.swift b/iOS/Settings/Appearance/TimelineCustomizerView.swift similarity index 100% rename from iOS/Settings/Views/Appearance/TimelineCustomizerView.swift rename to iOS/Settings/Appearance/TimelineCustomizerView.swift diff --git a/iOS/Settings/Views/General/SettingsRows.swift b/iOS/Settings/General/SettingsRows.swift similarity index 98% rename from iOS/Settings/Views/General/SettingsRows.swift rename to iOS/Settings/General/SettingsRows.swift index ef2c306f3..4ca8b7c40 100644 --- a/iOS/Settings/Views/General/SettingsRows.swift +++ b/iOS/Settings/General/SettingsRows.swift @@ -154,7 +154,7 @@ struct SettingsViewRows { /// This row, when tapped, will push the the Theme Selector screen /// in to view. static var themeSelection: some View { - NavigationLink(destination: ArticleThemesWrapper().edgesIgnoringSafeArea(.all)) { + NavigationLink(destination: ArticleThemeManagerView()) { HStack { Text("ARTICLE_THEME", tableName: "Settings") Spacer() diff --git a/iOS/Settings/Views/General/SettingsView.swift b/iOS/Settings/General/SettingsView.swift similarity index 100% rename from iOS/Settings/Views/General/SettingsView.swift rename to iOS/Settings/General/SettingsView.swift diff --git a/iOS/Settings/Views/General/SettingsViewModel.swift b/iOS/Settings/General/SettingsViewModel.swift similarity index 100% rename from iOS/Settings/Views/General/SettingsViewModel.swift rename to iOS/Settings/General/SettingsViewModel.swift diff --git a/iOS/Settings/Views/Help/AboutView.swift b/iOS/Settings/Help/AboutView.swift similarity index 100% rename from iOS/Settings/Views/Help/AboutView.swift rename to iOS/Settings/Help/AboutView.swift diff --git a/iOS/Settings/Views/Help/SettingsHelpSheets.swift b/iOS/Settings/Help/SettingsHelpSheets.swift similarity index 100% rename from iOS/Settings/Views/Help/SettingsHelpSheets.swift rename to iOS/Settings/Help/SettingsHelpSheets.swift diff --git a/iOS/Settings/Views/New Article Notifications/NewArticleNotificationsView.swift b/iOS/Settings/New Article Notifications/NewArticleNotificationsView.swift similarity index 100% rename from iOS/Settings/Views/New Article Notifications/NewArticleNotificationsView.swift rename to iOS/Settings/New Article Notifications/NewArticleNotificationsView.swift