NetNewsWire/Shared/ArticleStyles/ArticleStylesManager.swift

190 lines
4.7 KiB
Swift
Raw Normal View History

2017-05-27 19:43:27 +02:00
//
// ArticleStylesManager.sqift
2018-08-29 07:18:24 +02:00
// NetNewsWire
2017-05-27 19:43:27 +02:00
//
// Created by Brent Simmons on 9/26/15.
// Copyright © 2015 Ranchero Software, LLC. All rights reserved.
//
2020-01-13 01:38:04 +01:00
#if os(macOS)
import AppKit
#else
import UIKit
#endif
2017-05-27 19:43:27 +02:00
import RSCore
let ArticleStyleNamesDidChangeNotification = "ArticleStyleNamesDidChangeNotification"
let CurrentArticleStyleDidChangeNotification = "CurrentArticleStyleDidChangeNotification"
private let styleKey = "style"
private let defaultStyleName = "Default"
private let stylesFolderName = "Styles"
private let stylesInResourcesFolderName = "Styles"
2018-08-29 07:18:24 +02:00
private let styleSuffix = ".netnewswirestyle"
2017-05-27 19:43:27 +02:00
private let nnwStyleSuffix = ".nnwstyle"
private let cssStyleSuffix = ".css"
private let styleSuffixes = [styleSuffix, nnwStyleSuffix, cssStyleSuffix];
2017-09-23 22:59:19 +02:00
final class ArticleStylesManager {
2017-05-27 19:43:27 +02:00
2017-09-23 22:59:19 +02:00
static let shared = ArticleStylesManager()
2020-01-10 21:00:22 +01:00
private let folderPath = Platform.dataSubfolder(forApplication: nil, folderName: stylesFolderName)!
2017-05-27 19:43:27 +02:00
var currentStyleName: String {
get {
return UserDefaults.standard.string(forKey: styleKey)!
}
set {
if newValue != currentStyleName {
UserDefaults.standard.set(newValue, forKey: styleKey)
}
}
}
var currentStyle: ArticleStyle {
didSet {
NotificationCenter.default.post(name: Notification.Name(rawValue: CurrentArticleStyleDidChangeNotification), object: self)
}
}
var styleNames = [defaultStyleName] {
didSet {
NotificationCenter.default.post(name: Notification.Name(rawValue: ArticleStyleNamesDidChangeNotification), object: self)
}
}
init() {
UserDefaults.standard.register(defaults: [styleKey: defaultStyleName])
//
// let defaultStylesFolder = (Bundle.main.resourcePath! as NSString).appendingPathComponent(stylesInResourcesFolderName)
// do {
// try FileManager.default.rs_copyFiles(inFolder: defaultStylesFolder, destination: folderPath)
// }
// catch {
// print(error)
// }
2017-05-27 19:43:27 +02:00
currentStyle = ArticleStyle.defaultStyle
updateStyleNames()
updateCurrentStyle()
#if os(macOS)
2017-09-17 22:07:55 +02:00
NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive(_:)), name: NSApplication.didBecomeActiveNotification, object: nil)
#else
NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive(_:)), name: UIApplication.didBecomeActiveNotification, object: nil)
#endif
2017-05-27 19:43:27 +02:00
}
// MARK: Notifications
2017-09-17 21:34:10 +02:00
@objc dynamic func applicationDidBecomeActive(_ note: Notification) {
2017-05-27 19:43:27 +02:00
updateStyleNames()
updateCurrentStyle()
}
// MARK : Internal
private func updateStyleNames() {
let updatedStyleNames = allStylePaths(folderPath).map { styleNameForPath($0) }
if updatedStyleNames != styleNames {
styleNames = updatedStyleNames
}
}
private func articleStyleWithStyleName(_ styleName: String) -> ArticleStyle? {
if styleName == defaultStyleName {
return ArticleStyle.defaultStyle
}
guard let path = pathForStyleName(styleName, folder: folderPath) else {
return nil
}
return ArticleStyle(path: path)
}
private func defaultArticleStyle() -> ArticleStyle {
return articleStyleWithStyleName(defaultStyleName)!
}
private func updateCurrentStyle() {
var styleName = currentStyleName
if !styleNames.contains(styleName) {
styleName = defaultStyleName
currentStyleName = defaultStyleName
}
var articleStyle = articleStyleWithStyleName(styleName)
if articleStyle == nil {
articleStyle = defaultArticleStyle()
currentStyleName = defaultStyleName
}
if let articleStyle = articleStyle, articleStyle != currentStyle {
currentStyle = articleStyle
}
}
}
private func allStylePaths(_ folder: String) -> [String] {
2020-01-12 00:19:32 +01:00
let filepaths = FileManager.default.filePaths(inFolder: folder)
return filepaths?.filter { fileAtPathIsStyle($0) } ?? []
2017-05-27 19:43:27 +02:00
}
private func fileAtPathIsStyle(_ f: String) -> Bool {
if !f.hasSuffix(styleSuffix) && !f.hasSuffix(nnwStyleSuffix) && !f.hasSuffix(cssStyleSuffix) {
return false
}
if (f as NSString).lastPathComponent.hasPrefix(".") {
return false
}
return true
}
private func filenameWithStyleSuffixRemoved(_ filename: String) -> String {
for oneSuffix in styleSuffixes {
if filename.hasSuffix(oneSuffix) {
return filename.stripping(suffix: oneSuffix)
2017-05-27 19:43:27 +02:00
}
}
return filename
}
private func styleNameForPath(_ f: String) -> String {
let filename = (f as NSString).lastPathComponent
return filenameWithStyleSuffixRemoved(filename)
}
private func pathIsPathForStyleName(_ styleName: String, path: String) -> Bool {
let filename = (path as NSString).lastPathComponent
return filenameWithStyleSuffixRemoved(filename) == styleName
}
private func pathForStyleName(_ styleName: String, folder: String) -> String? {
for onePath in allStylePaths(folder) {
if pathIsPathForStyleName(styleName, path: onePath) {
return onePath
}
}
return nil
}