Merge branch 'pr/7' into swiftui

# Conflicts:
#	Multiplatform/Shared/Sidebar/SidebarToolbar.swift
This commit is contained in:
Stuart Breckenridge
2020-07-03 23:47:21 +08:00
13 changed files with 278 additions and 95 deletions

View File

@@ -26,13 +26,6 @@ enum UserInterfaceColorPalette: Int, CustomStringConvertible, CaseIterable {
}
}
enum FontSize: Int {
case small = 0
case medium = 1
case large = 2
case veryLarge = 3
}
final class AppDefaults: ObservableObject {
#if os(macOS)
@@ -62,26 +55,21 @@ final class AppDefaults: ObservableObject {
static let addWebFeedAccountID = "addWebFeedAccountID"
static let addWebFeedFolderName = "addWebFeedFolderName"
static let addFolderAccountID = "addFolderAccountID"
static let timelineSortDirection = "timelineSortDirection"
// iOS Defaults
static let userInterfaceColorPalette = "userInterfaceColorPalette"
static let timelineSortDirection = "timelineSortDirection"
static let timelineGroupByFeed = "timelineGroupByFeed"
static let refreshClearsReadArticles = "refreshClearsReadArticles"
static let timelineNumberOfLines = "timelineNumberOfLines"
static let timelineIconSize = "timelineIconSize"
static let articleFullscreenAvailable = "articleFullscreenAvailable"
static let timelineIconDimensions = "timelineIconDimensions"
static let timelineNumberOfLines = "timelineNumberOfLines"
// iOS Defaults
static let refreshClearsReadArticles = "refreshClearsReadArticles"
static let articleFullscreenAvailable = "articleFullscreenAvailable"
static let articleFullscreenEnabled = "articleFullscreenEnabled"
static let confirmMarkAllAsRead = "confirmMarkAllAsRead"
// macOS Defaults
static let windowState = "windowState"
static let sidebarFontSize = "sidebarFontSize"
static let timelineFontSize = "timelineFontSize"
static let detailFontSize = "detailFontSize"
static let openInBrowserInBackground = "openInBrowserInBackground"
static let importOPMLAccountID = "importOPMLAccountID"
static let exportOPMLAccountID = "exportOPMLAccountID"
static let defaultBrowserID = "defaultBrowserID"
static let checkForUpdatesAutomatically = "checkForUpdatesAutomatically"
static let downloadTestBuilds = "downloadTestBuild"
@@ -99,9 +87,6 @@ final class AppDefaults: ObservableObject {
}
private static let smallestFontSizeRawValue = FontSize.small.rawValue
private static let largestFontSizeRawValue = FontSize.veryLarge.rawValue
// MARK: Development Builds
let isDeveloperBuild: Bool = {
if let dev = Bundle.main.object(forInfoDictionaryKey: "DeveloperEntitlements") as? String, dev == "-dev" {
@@ -193,7 +178,7 @@ final class AppDefaults: ObservableObject {
}
}
@AppStorage(wrappedValue: 40.0, Key.timelineIconSize, store: store) var timelineIconSize: Double {
@AppStorage(wrappedValue: 40.0, Key.timelineIconDimensions, store: store) var timelineIconDimensions: Double {
didSet {
objectWillChange.send()
}
@@ -220,64 +205,12 @@ final class AppDefaults: ObservableObject {
}
// MARK: Window State
var windowState: [AnyHashable : Any]? {
get {
return AppDefaults.store.object(forKey: Key.windowState) as? [AnyHashable : Any]
}
set {
UserDefaults.standard.set(newValue, forKey: Key.windowState)
objectWillChange.send()
}
}
@AppStorage(wrappedValue: false, Key.openInBrowserInBackground, store: store) var openInBrowserInBackground: Bool {
didSet {
objectWillChange.send()
}
}
var sidebarFontSize: FontSize {
get {
return fontSize(for: Key.sidebarFontSize)
}
set {
AppDefaults.store.set(newValue.rawValue, forKey: Key.sidebarFontSize)
objectWillChange.send()
}
}
var timelineFontSize: FontSize {
get {
return fontSize(for: Key.timelineFontSize)
}
set {
AppDefaults.store.set(newValue.rawValue, forKey: Key.timelineFontSize)
objectWillChange.send()
}
}
var detailFontSize: FontSize {
get {
return fontSize(for: Key.detailFontSize)
}
set {
AppDefaults.store.set(newValue.rawValue, forKey: Key.detailFontSize)
objectWillChange.send()
}
}
@AppStorage(Key.importOPMLAccountID, store: store) var importOPMLAccountID: String? {
didSet {
objectWillChange.send()
}
}
@AppStorage(Key.exportOPMLAccountID, store: store) var exportOPMLAccountID: String? {
didSet {
objectWillChange.send()
}
}
@AppStorage(Key.defaultBrowserID, store: store) var defaultBrowserID: String? {
didSet {
objectWillChange.send()
@@ -333,6 +266,21 @@ final class AppDefaults: ObservableObject {
objectWillChange.send()
}
}
static func registerDefaults() {
let defaults: [String : Any] = [Key.userInterfaceColorPalette: UserInterfaceColorPalette.automatic.rawValue,
Key.timelineGroupByFeed: false,
Key.refreshClearsReadArticles: false,
Key.timelineNumberOfLines: 2,
Key.timelineIconDimensions: 40,
Key.timelineSortDirection: ComparisonResult.orderedDescending.rawValue,
Key.articleFullscreenAvailable: false,
Key.articleFullscreenEnabled: false,
Key.confirmMarkAllAsRead: true,
"NSScrollViewShouldScrollUnderTitlebar": false,
Key.refreshInterval: RefreshInterval.everyHour.rawValue]
AppDefaults.store.register(defaults: defaults)
}
}
@@ -346,8 +294,4 @@ extension AppDefaults {
return true
}
func fontSize(for key: String) -> FontSize {
// Punted till after 1.0.
return .medium
}
}

View File

@@ -150,7 +150,9 @@ struct MainApp: App {
SceneNavigationView()
.environmentObject(sceneModel)
.environmentObject(defaults)
}.commands {
.modifier(PreferredColorSchemeModifier(preferredColorScheme: defaults.userInterfaceColorPalette))
}
.commands {
CommandGroup(after: .newItem, addition: {
Button("New Feed", action: {})
.keyboardShortcut("N")
@@ -197,3 +199,20 @@ struct MainApp: App {
#endif
}
}
struct PreferredColorSchemeModifier: ViewModifier {
var preferredColorScheme: UserInterfaceColorPalette
@ViewBuilder
func body(content: Content) -> some View {
switch preferredColorScheme {
case .automatic:
content
case .dark:
content.preferredColorScheme(.dark)
case .light:
content.preferredColorScheme(.light)
}
}
}

View File

@@ -9,6 +9,7 @@
import SwiftUI
struct SidebarToolbar: View {
<<<<<<< HEAD
enum ToolbarSheets {
case none, web, twitter, reddit, folder, settings
@@ -21,6 +22,12 @@ struct SidebarToolbar: View {
}
}
@State private var showActionSheet: Bool = false
=======
@EnvironmentObject private var appSettings: AppDefaults
@State private var showSettings: Bool = false
@State private var showAddSheet: Bool = false
>>>>>>> pr/7
var addActionSheetButtons = [
Button(action: {}, label: { Text("Add Feed") })
@@ -66,6 +73,7 @@ struct SidebarToolbar: View {
.padding(.top, 4)
}
.background(VisualEffectBlur(blurStyle: .systemChromeMaterial).edgesIgnoringSafeArea(.bottom))
<<<<<<< HEAD
.sheet(isPresented: $showSheet, onDismiss: { sheetToShow = .none }) {
switch sheetToShow {
case .web:
@@ -73,6 +81,10 @@ struct SidebarToolbar: View {
default:
EmptyView()
}
=======
.sheet(isPresented: $showSettings, onDismiss: { showSettings = false }) {
SettingsView().modifier(PreferredColorSchemeModifier(preferredColorScheme: appSettings.userInterfaceColorPalette))
>>>>>>> pr/7
}
}

View File

@@ -21,7 +21,7 @@ struct TimelineItemView: View {
TimelineItemStatusView(status: timelineItem.status)
if let image = articleIconImageLoader.image {
IconImageView(iconImage: image)
.frame(width: CGFloat(defaults.timelineIconSize), height: CGFloat(defaults.timelineIconSize), alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
.frame(width: CGFloat(defaults.timelineIconDimensions), height: CGFloat(defaults.timelineIconDimensions), alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
}
VStack {
Text(verbatim: timelineItem.article.title ?? "N/A")

View File

@@ -71,7 +71,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//AppDefaults.registerDefaults()
AppDefaults.registerDefaults()
let isFirstRun = AppDefaults.shared.isFirstRun()
if isFirstRun {
@@ -103,6 +103,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
UNUserNotificationCenter.current().delegate = self
userNotificationManager = UserNotificationManager()
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange), name: UserDefaults.didChangeNotification, object: nil)
// extensionContainersFile = ExtensionContainersFile()
// extensionFeedAddRequestFile = ExtensionFeedAddRequestFile()
@@ -388,3 +391,29 @@ private extension AppDelegate {
}
}
private extension AppDelegate {
@objc func userDefaultsDidChange() {
updateUserInterfaceStyle()
}
var window: UIWindow? {
guard let scene = UIApplication.shared.connectedScenes.first,
let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate,
let window = windowSceneDelegate.window else {
return nil
}
return window
}
func updateUserInterfaceStyle() {
// switch AppDefaults.shared.userInterfaceColorPalette {
// case .automatic:
// window?.overrideUserInterfaceStyle = .unspecified
// case .light:
// window?.overrideUserInterfaceStyle = .light
// case .dark:
// window?.overrideUserInterfaceStyle = .dark
// }
}
}

View File

@@ -155,12 +155,12 @@ struct SettingsView: View {
var appearance: some View {
Section(header: Text("Appearance"), content: {
NavigationLink(
destination: EmptyView(),
destination: ColorPaletteContainerView().environmentObject(settings),
label: {
HStack {
Text("Color Pallete")
Text("Color Palette")
Spacer()
Text("Automatic")
Text(settings.userInterfaceColorPalette.description)
.foregroundColor(.secondary)
}
})

View File

@@ -0,0 +1,60 @@
//
// ColorPaletteContainerView.swift
// Multiplatform iOS
//
// Created by Rizwan on 02/07/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import SwiftUI
struct ColorPaletteContainerView: View {
private let colorPalettes = UserInterfaceColorPalette.allCases
@EnvironmentObject private var appSettings: AppDefaults
@Environment(\.presentationMode) var presentationMode
var body: some View {
List {
ForEach.init(0 ..< colorPalettes.count) { index in
Button(action: {
onTapColorPalette(at:index)
}) {
ColorPaletteView(colorPalette: colorPalettes[index])
}
}
}
.listStyle(InsetGroupedListStyle())
.navigationBarTitle("Color Palette", displayMode: .inline)
}
func onTapColorPalette(at index: Int) {
if let colorPalette = UserInterfaceColorPalette(rawValue: index) {
appSettings.userInterfaceColorPalette = colorPalette
}
self.presentationMode.wrappedValue.dismiss()
}
}
struct ColorPaletteView: View {
var colorPalette: UserInterfaceColorPalette
@EnvironmentObject private var appSettings: AppDefaults
var body: some View {
HStack {
Text(colorPalette.description).foregroundColor(.primary)
Spacer()
if colorPalette == appSettings.userInterfaceColorPalette {
Image(systemName: "checkmark")
.foregroundColor(.blue)
}
}
}
}
struct ColorPaletteContainerView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
ColorPaletteContainerView()
}
}
}

View File

@@ -33,8 +33,8 @@ struct TimelineLayoutView: View {
}
var iconSize: some View {
Slider(value: $appSettings.timelineIconSize, in: 20...60, step: 10, minimumValueLabel: Text("Small"), maximumValueLabel: Text("Large"), label: {
Text(String(appSettings.timelineIconSize))
Slider(value: $appSettings.timelineIconDimensions, in: 20...60, step: 10, minimumValueLabel: Text("Small"), maximumValueLabel: Text("Large"), label: {
Text(String(appSettings.timelineIconDimensions))
})
}
@@ -54,7 +54,7 @@ struct TimelineLayoutView: View {
Image(systemName: "paperplane.circle")
.resizable()
.frame(width: CGFloat(appSettings.timelineIconSize), height: CGFloat(appSettings.timelineIconSize), alignment: .top)
.frame(width: CGFloat(appSettings.timelineIconDimensions), height: CGFloat(appSettings.timelineIconDimensions), alignment: .top)
.foregroundColor(.accentColor)
VStack(alignment: .leading, spacing: 4) {

View File

@@ -133,7 +133,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
}
#endif
//AppDefaults.registerDefaults()
AppDefaults.registerDefaults()
let isFirstRun = AppDefaults.shared.isFirstRun()
if isFirstRun {
os_log(.debug, log: log, "Is first run.")