Merge remote-tracking branch 'origin/main' into nnwtheme-downloader
This commit is contained in:
commit
105a78bc0f
|
@ -259,6 +259,7 @@
|
||||||
5137C2E626F3F52D009EFEDB /* Sepia.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 5137C2E326F3F52D009EFEDB /* Sepia.nnwtheme */; };
|
5137C2E626F3F52D009EFEDB /* Sepia.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 5137C2E326F3F52D009EFEDB /* Sepia.nnwtheme */; };
|
||||||
5137C2E726F3F52D009EFEDB /* Sepia.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 5137C2E326F3F52D009EFEDB /* Sepia.nnwtheme */; };
|
5137C2E726F3F52D009EFEDB /* Sepia.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 5137C2E326F3F52D009EFEDB /* Sepia.nnwtheme */; };
|
||||||
5137C2E826F3F52D009EFEDB /* Sepia.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 5137C2E326F3F52D009EFEDB /* Sepia.nnwtheme */; };
|
5137C2E826F3F52D009EFEDB /* Sepia.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 5137C2E326F3F52D009EFEDB /* Sepia.nnwtheme */; };
|
||||||
|
5137C2EA26F63AE6009EFEDB /* ArticleThemeImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5137C2E926F63AE6009EFEDB /* ArticleThemeImporter.swift */; };
|
||||||
51386A8E25673277005F3762 /* AccountCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51386A8D25673276005F3762 /* AccountCell.swift */; };
|
51386A8E25673277005F3762 /* AccountCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51386A8D25673276005F3762 /* AccountCell.swift */; };
|
||||||
51386A8F25673277005F3762 /* AccountCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51386A8D25673276005F3762 /* AccountCell.swift */; };
|
51386A8F25673277005F3762 /* AccountCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51386A8D25673276005F3762 /* AccountCell.swift */; };
|
||||||
5138E93A24D33E5600AFF0FE /* RSTree in Frameworks */ = {isa = PBXBuildFile; productRef = 5138E93924D33E5600AFF0FE /* RSTree */; };
|
5138E93A24D33E5600AFF0FE /* RSTree in Frameworks */ = {isa = PBXBuildFile; productRef = 5138E93924D33E5600AFF0FE /* RSTree */; };
|
||||||
|
@ -1663,6 +1664,7 @@
|
||||||
51333D1524685D2E00EB5C91 /* AddRedditFeedWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRedditFeedWindowController.swift; sourceTree = "<group>"; };
|
51333D1524685D2E00EB5C91 /* AddRedditFeedWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRedditFeedWindowController.swift; sourceTree = "<group>"; };
|
||||||
51333D3A2468615D00EB5C91 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Mac/Base.lproj/AddRedditFeedSheet.xib; sourceTree = SOURCE_ROOT; };
|
51333D3A2468615D00EB5C91 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Mac/Base.lproj/AddRedditFeedSheet.xib; sourceTree = SOURCE_ROOT; };
|
||||||
5137C2E326F3F52D009EFEDB /* Sepia.nnwtheme */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Sepia.nnwtheme; sourceTree = "<group>"; };
|
5137C2E326F3F52D009EFEDB /* Sepia.nnwtheme */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Sepia.nnwtheme; sourceTree = "<group>"; };
|
||||||
|
5137C2E926F63AE6009EFEDB /* ArticleThemeImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleThemeImporter.swift; sourceTree = "<group>"; };
|
||||||
51386A8D25673276005F3762 /* AccountCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountCell.swift; sourceTree = "<group>"; };
|
51386A8D25673276005F3762 /* AccountCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountCell.swift; sourceTree = "<group>"; };
|
||||||
51392D1A24AC19A000BE0D35 /* SidebarExpandedContainers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarExpandedContainers.swift; sourceTree = "<group>"; };
|
51392D1A24AC19A000BE0D35 /* SidebarExpandedContainers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarExpandedContainers.swift; sourceTree = "<group>"; };
|
||||||
513C5CE6232571C2003D4054 /* NetNewsWire iOS Share Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "NetNewsWire iOS Share Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
513C5CE6232571C2003D4054 /* NetNewsWire iOS Share Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "NetNewsWire iOS Share Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -2804,13 +2806,14 @@
|
||||||
5183CCEB227117C70010922C /* Settings */ = {
|
5183CCEB227117C70010922C /* Settings */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
51A16990235E10D600EB091F /* Settings.storyboard */,
|
|
||||||
51A16995235E10D600EB091F /* AboutViewController.swift */,
|
51A16995235E10D600EB091F /* AboutViewController.swift */,
|
||||||
51A16992235E10D600EB091F /* AddAccountViewController.swift */,
|
51A16992235E10D600EB091F /* AddAccountViewController.swift */,
|
||||||
519ED47924482AEB007F8E94 /* EnableExtensionPointViewController.swift */,
|
|
||||||
519ED455244828C3007F8E94 /* AddExtensionPointViewController.swift */,
|
519ED455244828C3007F8E94 /* AddExtensionPointViewController.swift */,
|
||||||
|
5137C2E926F63AE6009EFEDB /* ArticleThemeImporter.swift */,
|
||||||
510FFAB226EEA22C00F32265 /* ArticleThemesTableViewController.swift */,
|
510FFAB226EEA22C00F32265 /* ArticleThemesTableViewController.swift */,
|
||||||
516244E2241E19F000B61C47 /* ColorPaletteTableViewController.swift */,
|
516244E2241E19F000B61C47 /* ColorPaletteTableViewController.swift */,
|
||||||
|
519ED47924482AEB007F8E94 /* EnableExtensionPointViewController.swift */,
|
||||||
|
51A16990235E10D600EB091F /* Settings.storyboard */,
|
||||||
516A09382360A2AE00EAE89B /* SettingsComboTableViewCell.swift */,
|
516A09382360A2AE00EAE89B /* SettingsComboTableViewCell.swift */,
|
||||||
516A091D23609A3600EAE89B /* SettingsComboTableViewCell.xib */,
|
516A091D23609A3600EAE89B /* SettingsComboTableViewCell.xib */,
|
||||||
516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */,
|
516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */,
|
||||||
|
@ -5631,6 +5634,7 @@
|
||||||
51C45268226508F600C03939 /* MasterFeedUnreadCountView.swift in Sources */,
|
51C45268226508F600C03939 /* MasterFeedUnreadCountView.swift in Sources */,
|
||||||
D3A39865246505DF00F9A366 /* FindInArticleActivity.swift in Sources */,
|
D3A39865246505DF00F9A366 /* FindInArticleActivity.swift in Sources */,
|
||||||
5183CCD0226E1E880010922C /* NonIntrinsicLabel.swift in Sources */,
|
5183CCD0226E1E880010922C /* NonIntrinsicLabel.swift in Sources */,
|
||||||
|
5137C2EA26F63AE6009EFEDB /* ArticleThemeImporter.swift in Sources */,
|
||||||
51C4529F22650A1900C03939 /* AuthorAvatarDownloader.swift in Sources */,
|
51C4529F22650A1900C03939 /* AuthorAvatarDownloader.swift in Sources */,
|
||||||
5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */,
|
5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */,
|
||||||
519E743D22C663F900A78E47 /* SceneDelegate.swift in Sources */,
|
519E743D22C663F900A78E47 /* SceneDelegate.swift in Sources */,
|
||||||
|
|
|
@ -1295,68 +1295,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
func importTheme(filename: String) {
|
func importTheme(filename: String) {
|
||||||
let theme = ArticleTheme(path: filename)
|
ArticleThemeImporter.importTheme(controller: rootSplitViewController, filename: filename);
|
||||||
|
|
||||||
let localizedTitleText = NSLocalizedString("Install theme “%@” by %@?", comment: "Theme message text")
|
|
||||||
let title = NSString.localizedStringWithFormat(localizedTitleText as NSString, theme.name, theme.creatorName) as String
|
|
||||||
|
|
||||||
let localizedMessageText = NSLocalizedString("Author's Website:\n%@", comment: "Authors website")
|
|
||||||
let message = NSString.localizedStringWithFormat(localizedMessageText as NSString, theme.creatorHomePage) as String
|
|
||||||
|
|
||||||
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
|
||||||
|
|
||||||
let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
|
|
||||||
alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel))
|
|
||||||
|
|
||||||
if let url = URL(string: theme.creatorHomePage) {
|
|
||||||
let visitSiteTitle = NSLocalizedString("Show Website", comment: "Show Website")
|
|
||||||
let visitSiteAction = UIAlertAction(title: visitSiteTitle, style: .default) { [weak self] action in
|
|
||||||
UIApplication.shared.open(url)
|
|
||||||
self?.importTheme(filename: filename)
|
|
||||||
}
|
|
||||||
alertController.addAction(visitSiteAction)
|
|
||||||
}
|
|
||||||
|
|
||||||
func importTheme() {
|
|
||||||
do {
|
|
||||||
try ArticleThemesManager.shared.importTheme(filename: filename)
|
|
||||||
confirmImportSuccess(themeName: theme.name)
|
|
||||||
} catch {
|
|
||||||
rootSplitViewController.presentError(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let installThemeTitle = NSLocalizedString("Install Theme", comment: "Install Theme")
|
|
||||||
let installThemeAction = UIAlertAction(title: installThemeTitle, style: .default) { [weak self] action in
|
|
||||||
|
|
||||||
if ArticleThemesManager.shared.themeExists(filename: filename) {
|
|
||||||
let title = NSLocalizedString("Duplicate Theme", comment: "Duplicate Theme")
|
|
||||||
let localizedMessageText = NSLocalizedString("The theme “%@” already exists. Overwrite it?", comment: "Overwrite theme")
|
|
||||||
let message = NSString.localizedStringWithFormat(localizedMessageText as NSString, theme.name) as String
|
|
||||||
|
|
||||||
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
|
||||||
|
|
||||||
let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
|
|
||||||
alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel))
|
|
||||||
|
|
||||||
let overwriteAction = UIAlertAction(title: NSLocalizedString("Overwrite", comment: "Overwrite"), style: .default) { action in
|
|
||||||
importTheme()
|
|
||||||
}
|
|
||||||
alertController.addAction(overwriteAction)
|
|
||||||
alertController.preferredAction = overwriteAction
|
|
||||||
|
|
||||||
self?.rootSplitViewController.present(alertController, animated: true)
|
|
||||||
} else {
|
|
||||||
importTheme()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
alertController.addAction(installThemeAction)
|
|
||||||
alertController.preferredAction = installThemeAction
|
|
||||||
|
|
||||||
rootSplitViewController.present(alertController, animated: true)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2363,18 +2302,4 @@ private extension SceneCoordinator {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func confirmImportSuccess(themeName: String) {
|
|
||||||
let title = NSLocalizedString("Theme installed", comment: "Theme installed")
|
|
||||||
|
|
||||||
let localizedMessageText = NSLocalizedString("The theme “%@” has been installed.", comment: "Theme installed")
|
|
||||||
let message = NSString.localizedStringWithFormat(localizedMessageText as NSString, themeName) as String
|
|
||||||
|
|
||||||
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
|
||||||
|
|
||||||
let doneTitle = NSLocalizedString("Done", comment: "Done")
|
|
||||||
alertController.addAction(UIAlertAction(title: doneTitle, style: .default))
|
|
||||||
|
|
||||||
rootSplitViewController.present(alertController, animated: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
//
|
||||||
|
// ArticleThemeImporter.swift
|
||||||
|
// NetNewsWire
|
||||||
|
//
|
||||||
|
// Created by Maurice Parker on 9/18/21.
|
||||||
|
// Copyright © 2021 Ranchero Software. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
struct ArticleThemeImporter {
|
||||||
|
|
||||||
|
static func importTheme(controller: UIViewController, filename: String) {
|
||||||
|
let theme = ArticleTheme(path: filename)
|
||||||
|
|
||||||
|
let localizedTitleText = NSLocalizedString("Install theme “%@” by %@?", comment: "Theme message text")
|
||||||
|
let title = NSString.localizedStringWithFormat(localizedTitleText as NSString, theme.name, theme.creatorName) as String
|
||||||
|
|
||||||
|
let localizedMessageText = NSLocalizedString("Author's Website:\n%@", comment: "Authors website")
|
||||||
|
let message = NSString.localizedStringWithFormat(localizedMessageText as NSString, theme.creatorHomePage) as String
|
||||||
|
|
||||||
|
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
||||||
|
|
||||||
|
let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
|
||||||
|
alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel))
|
||||||
|
|
||||||
|
if let url = URL(string: theme.creatorHomePage) {
|
||||||
|
let visitSiteTitle = NSLocalizedString("Show Website", comment: "Show Website")
|
||||||
|
let visitSiteAction = UIAlertAction(title: visitSiteTitle, style: .default) { action in
|
||||||
|
UIApplication.shared.open(url)
|
||||||
|
Self.importTheme(controller: controller, filename: filename)
|
||||||
|
}
|
||||||
|
alertController.addAction(visitSiteAction)
|
||||||
|
}
|
||||||
|
|
||||||
|
func importTheme() {
|
||||||
|
do {
|
||||||
|
try ArticleThemesManager.shared.importTheme(filename: filename)
|
||||||
|
confirmImportSuccess(controller: controller, themeName: theme.name)
|
||||||
|
} catch {
|
||||||
|
controller.presentError(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let installThemeTitle = NSLocalizedString("Install Theme", comment: "Install Theme")
|
||||||
|
let installThemeAction = UIAlertAction(title: installThemeTitle, style: .default) { action in
|
||||||
|
|
||||||
|
if ArticleThemesManager.shared.themeExists(filename: filename) {
|
||||||
|
let title = NSLocalizedString("Duplicate Theme", comment: "Duplicate Theme")
|
||||||
|
let localizedMessageText = NSLocalizedString("The theme “%@” already exists. Overwrite it?", comment: "Overwrite theme")
|
||||||
|
let message = NSString.localizedStringWithFormat(localizedMessageText as NSString, theme.name) as String
|
||||||
|
|
||||||
|
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
||||||
|
|
||||||
|
let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
|
||||||
|
alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel))
|
||||||
|
|
||||||
|
let overwriteAction = UIAlertAction(title: NSLocalizedString("Overwrite", comment: "Overwrite"), style: .default) { action in
|
||||||
|
importTheme()
|
||||||
|
}
|
||||||
|
alertController.addAction(overwriteAction)
|
||||||
|
alertController.preferredAction = overwriteAction
|
||||||
|
|
||||||
|
controller.present(alertController, animated: true)
|
||||||
|
} else {
|
||||||
|
importTheme()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
alertController.addAction(installThemeAction)
|
||||||
|
alertController.preferredAction = installThemeAction
|
||||||
|
|
||||||
|
controller.present(alertController, animated: true)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension ArticleThemeImporter {
|
||||||
|
|
||||||
|
static func confirmImportSuccess(controller: UIViewController, themeName: String) {
|
||||||
|
let title = NSLocalizedString("Theme installed", comment: "Theme installed")
|
||||||
|
|
||||||
|
let localizedMessageText = NSLocalizedString("The theme “%@” has been installed.", comment: "Theme installed")
|
||||||
|
let message = NSString.localizedStringWithFormat(localizedMessageText as NSString, themeName) as String
|
||||||
|
|
||||||
|
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
||||||
|
|
||||||
|
let doneTitle = NSLocalizedString("Done", comment: "Done")
|
||||||
|
alertController.addAction(UIAlertAction(title: doneTitle, style: .default))
|
||||||
|
|
||||||
|
controller.present(alertController, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -13,13 +13,26 @@ import UIKit
|
||||||
class ArticleThemesTableViewController: UITableViewController {
|
class ArticleThemesTableViewController: UITableViewController {
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
|
let importBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(importTheme(_:)));
|
||||||
|
importBarButtonItem.title = NSLocalizedString("Import Theme", comment: "Import Theme");
|
||||||
|
navigationItem.rightBarButtonItem = importBarButtonItem
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(articleThemeNamesDidChangeNotification(_:)), name: .ArticleThemeNamesDidChangeNotification, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(articleThemeNamesDidChangeNotification(_:)), name: .ArticleThemeNamesDidChangeNotification, object: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Notifications
|
||||||
|
|
||||||
@objc func articleThemeNamesDidChangeNotification(_ note: Notification) {
|
@objc func articleThemeNamesDidChangeNotification(_ note: Notification) {
|
||||||
tableView.reloadData()
|
tableView.reloadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func importTheme(_ sender: Any?) {
|
||||||
|
let docPicker = UIDocumentPickerViewController(documentTypes: ["com.ranchero.netnewswire.theme"], in: .import)
|
||||||
|
docPicker.delegate = self
|
||||||
|
docPicker.modalPresentationStyle = .formSheet
|
||||||
|
self.present(docPicker, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Table view data source
|
// MARK: - Table view data source
|
||||||
|
|
||||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||||
|
@ -92,3 +105,14 @@ class ArticleThemesTableViewController: UITableViewController {
|
||||||
return UISwipeActionsConfiguration(actions: [deleteAction])
|
return UISwipeActionsConfiguration(actions: [deleteAction])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: UIDocumentPickerDelegate
|
||||||
|
|
||||||
|
extension ArticleThemesTableViewController: UIDocumentPickerDelegate {
|
||||||
|
|
||||||
|
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
|
||||||
|
guard let url = urls.first else { return }
|
||||||
|
ArticleThemeImporter.importTheme(controller: self, filename: url.standardizedFileURL.path)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue