From 7fd85f5ead98b4607bcca7abce81459a448293f3 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Thu, 9 Feb 2023 17:29:48 +0800 Subject: [PATCH] Moves theme separation code to ArticleThemeManager This cherry picks a change that is in ArticleThemeManager for macOS so that the theme pickers are using the same code to separate themes. --- .../ArticleStyles/ArticleThemesManager.swift | 70 +++++++++++++++++++ .../Appearance/ArticleThemeManagerView.swift | 24 ++----- 2 files changed, 75 insertions(+), 19 deletions(-) diff --git a/Shared/ArticleStyles/ArticleThemesManager.swift b/Shared/ArticleStyles/ArticleThemesManager.swift index f97f0e7f0..6e9690972 100644 --- a/Shared/ArticleStyles/ArticleThemesManager.swift +++ b/Shared/ArticleStyles/ArticleThemesManager.swift @@ -9,6 +9,9 @@ import Foundation import RSCore import Combine +#if canImport(AppKit) +import AppKit +#endif public extension Notification.Name { static let ArticleThemeNamesDidChangeNotification = Notification.Name("ArticleThemeNamesDidChangeNotification") @@ -141,6 +144,73 @@ final class ArticleThemesManager: NSObject, NSFilePresenter, Logging, Observable } } + func themesByDeveloper() -> ([ArticleTheme], [ArticleTheme]) { + let installedProvidedThemes = themeNames.map({ try? articleThemeWithThemeName($0) }).compactMap({ $0 }).filter({ $0.isAppTheme }).sorted(by: { $0.name < $1.name }).filter({ $0.name != AppDefaults.defaultThemeName }) + + let installedOtherThemes = themeNames.map({ try? articleThemeWithThemeName($0) }).compactMap({ $0 }).filter({ !$0.isAppTheme }).sorted(by: { $0.name < $1.name }) + + return (installedProvidedThemes, installedOtherThemes) + } + + #if os(macOS) + func articleThemesMenu(for popUpButton: NSPopUpButton?) -> NSMenu { + let menu = NSMenu() + menu.autoenablesItems = false + menu.removeAllItems() + + let defaultMenuItem = NSMenuItem() + defaultMenuItem.title = ArticleTheme.defaultTheme.name + defaultMenuItem.action = #selector(updateThemeSelection(_:)) + defaultMenuItem.state = currentTheme.name == defaultMenuItem.title ? .on : .off + defaultMenuItem.target = self + menu.addItem(defaultMenuItem) + menu.addItem(NSMenuItem.separator()) + + let rancheroHeading = NSMenuItem(title: "Built-in Themes", action: nil, keyEquivalent: "") + rancheroHeading.attributedTitle = NSAttributedString(string: "Built-in Themes", attributes: [NSAttributedString.Key.foregroundColor : NSColor.secondaryLabelColor, NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 12)]) + rancheroHeading.isEnabled = false + menu.addItem(rancheroHeading) + + let installedThemes = ArticleThemesManager.shared.themesByDeveloper() + + for theme in installedThemes.0 { + let item = NSMenuItem() + item.title = theme.name + item.action = #selector(updateThemeSelection(_:)) + item.state = currentTheme.name == theme.name ? .on : .off + item.target = self + menu.addItem(item) + } + + menu.addItem(NSMenuItem.separator()) + + let thirdPartyHeading = NSMenuItem(title: "Other Themes", action: nil, keyEquivalent: "") + thirdPartyHeading.attributedTitle = NSAttributedString(string: "Other Themes", attributes: [NSAttributedString.Key.foregroundColor : NSColor.secondaryLabelColor, NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 12)]) + thirdPartyHeading.isEnabled = false + menu.addItem(thirdPartyHeading) + + for theme in installedThemes.1 { + let item = NSMenuItem() + item.title = theme.name + item.action = #selector(updateThemeSelection(_:)) + item.state = currentTheme.name == theme.name ? .on : .off + item.target = self + menu.addItem(item) + } + popUpButton?.selectItem(withTitle: ArticleThemesManager.shared.currentThemeName) + if popUpButton?.indexOfSelectedItem == -1 { + popUpButton?.selectItem(withTitle: ArticleTheme.defaultTheme.name) + } + return menu + } + + @objc + func updateThemeSelection(_ menuItem: NSMenuItem) { + currentThemeName = menuItem.title + } + + #endif + } // MARK : Private diff --git a/iOS/Settings/Appearance/ArticleThemeManagerView.swift b/iOS/Settings/Appearance/ArticleThemeManagerView.swift index b5652e154..c83f37841 100644 --- a/iOS/Settings/Appearance/ArticleThemeManagerView.swift +++ b/iOS/Settings/Appearance/ArticleThemeManagerView.swift @@ -16,29 +16,24 @@ struct ArticleThemeManagerView: View { @State private var showImportConfirmationAlert: (ArticleTheme?, Bool) = (nil, false) @State private var showImportErrorAlert: (Error?, Bool) = (nil, false) @State private var showImportSuccessAlert: Bool = false - @State private var installedFirstPartyThemes: [ArticleTheme] = [] - @State private var installedThirdPartyThemes: [ArticleTheme] = [] var body: some View { Form { Section(header: Text("Built-in Themes", comment: "Section header for installed themes"), footer: Text("These themes cannot be deleted.", comment: "Section footer for installed themes.")) { - articleThemeRow(try! themeManager.articleThemeWithThemeName("Default")) - ForEach(0.. some View { @@ -181,12 +173,6 @@ struct ArticleThemeManagerView: View { } } } - - private func updateThemesArrays() { - installedFirstPartyThemes = themeManager.themeNames.map({ try? themeManager.articleThemeWithThemeName($0) }).compactMap({ $0 }).filter({ $0.isAppTheme }).sorted(by: { $0.name < $1.name }) - - installedThirdPartyThemes = themeManager.themeNames.map({ try? themeManager.articleThemeWithThemeName($0) }).compactMap({ $0 }).filter({ !$0.isAppTheme }).sorted(by: { $0.name < $1.name }) - } } struct ArticleThemeImporterView_Previews: PreviewProvider {