Merge branch 'swiftui' into swiftui-color-palette
* swiftui: Register AppDefaults. Issue #2190 Removed obsolete AppDefaults values Revert to using List for timeline and use infinite scrolling technique to speed up timeline loads Add action sheet for adding feed resources Stub out Article code Delete dead code Fix bad merge where we were missing a file reference # Conflicts: # NetNewsWire.xcodeproj/project.pbxproj
This commit is contained in:
commit
7cc71eac95
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// ArticleContainerView.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 7/2/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Articles
|
||||
|
||||
struct ArticleContainerView: View {
|
||||
|
||||
@EnvironmentObject private var sceneModel: SceneModel
|
||||
@StateObject private var articleModel = ArticleModel()
|
||||
var article: Article? = nil
|
||||
|
||||
@ViewBuilder var body: some View {
|
||||
if let article = article {
|
||||
ArticleView()
|
||||
.environmentObject(articleModel)
|
||||
.onAppear {
|
||||
sceneModel.articleModel = articleModel
|
||||
articleModel.delegate = sceneModel
|
||||
}
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// ArticleModel.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 7/2/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
import Foundation
|
||||
import RSCore
|
||||
import Account
|
||||
import Articles
|
||||
|
||||
protocol ArticleModelDelegate: class {
|
||||
func timelineRequestedWebFeedSelection(_: TimelineModel, webFeed: WebFeed)
|
||||
}
|
||||
|
||||
class ArticleModel: ObservableObject {
|
||||
|
||||
weak var delegate: ArticleModelDelegate?
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// ArticleView.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 7/2/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ArticleView: View {
|
||||
var body: some View {
|
||||
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
|
||||
}
|
||||
}
|
||||
|
||||
struct ArticleView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ArticleView()
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ final class SceneModel: ObservableObject {
|
|||
|
||||
var sidebarModel: SidebarModel?
|
||||
var timelineModel: TimelineModel?
|
||||
var articleModel: ArticleModel?
|
||||
|
||||
}
|
||||
|
||||
|
@ -35,3 +36,10 @@ extension SceneModel: TimelineModelDelegate {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: ArticleModelDelegate
|
||||
|
||||
extension SceneModel: ArticleModelDelegate {
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -30,38 +30,6 @@ struct CompactSidebarContainerView: View {
|
|||
},alignment: .bottom)
|
||||
}
|
||||
|
||||
|
||||
var compactToolBar: some View {
|
||||
VStack {
|
||||
Divider()
|
||||
HStack(alignment: .center) {
|
||||
Button(action: {
|
||||
showSettings = true
|
||||
}, label: {
|
||||
Image(systemName: "gear")
|
||||
.font(.title3)
|
||||
.foregroundColor(.accentColor)
|
||||
}).help("Settings")
|
||||
Spacer()
|
||||
Text("Last updated")
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
Spacer()
|
||||
Button(action: {}, label: {
|
||||
Image(systemName: "plus")
|
||||
.font(.title3)
|
||||
.foregroundColor(.accentColor)
|
||||
}).help("Add")
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.bottom, 12)
|
||||
.padding(.top, 4)
|
||||
}
|
||||
.background(VisualEffectBlur(blurStyle: .systemChromeMaterial).edgesIgnoringSafeArea(.bottom))
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
struct CompactSidebarContainerView_Previews: PreviewProvider {
|
||||
|
|
|
@ -12,6 +12,11 @@ struct SidebarToolbar: View {
|
|||
|
||||
@EnvironmentObject private var appSettings: AppDefaults
|
||||
@State private var showSettings: Bool = false
|
||||
@State private var showAddSheet: Bool = false
|
||||
|
||||
var addActionSheetButtons = [
|
||||
Button(action: {}, label: { Text("Add Feed") })
|
||||
]
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
|
@ -29,11 +34,23 @@ struct SidebarToolbar: View {
|
|||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
Spacer()
|
||||
Button(action: {}, label: {
|
||||
Button(action: {
|
||||
showAddSheet = true
|
||||
}, label: {
|
||||
Image(systemName: "plus")
|
||||
.font(.title3)
|
||||
.foregroundColor(.accentColor)
|
||||
}).help("Add")
|
||||
})
|
||||
.help("Add")
|
||||
.actionSheet(isPresented: $showAddSheet) {
|
||||
ActionSheet(title: Text("Add"), buttons: [
|
||||
.cancel(),
|
||||
.default(Text("Add Web Feed")),
|
||||
.default(Text("Add Twitter Feed")),
|
||||
.default(Text("Add Reddit Feed")),
|
||||
.default(Text("Add Folder"))
|
||||
])
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.bottom, 12)
|
||||
|
|
|
@ -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")
|
||||
|
@ -45,7 +45,6 @@ struct TimelineItemView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
Divider()
|
||||
}
|
||||
.onAppear {
|
||||
articleIconImageLoader.loadImage(for: timelineItem.article)
|
||||
|
|
|
@ -55,6 +55,14 @@ class TimelineModel: ObservableObject {
|
|||
fetchAndReplaceArticlesAsync()
|
||||
}
|
||||
|
||||
// TODO: Replace this with ScrollViewReader if we have to keep it
|
||||
func loadMoreTimelineItemsIfNecessary(_ timelineItem: TimelineItem) {
|
||||
let thresholdIndex = timelineItems.index(timelineItems.endIndex, offsetBy: -10)
|
||||
if timelineItems.firstIndex(where: { $0.id == timelineItem.id }) == thresholdIndex {
|
||||
nextBatch()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
|
@ -112,12 +120,19 @@ private extension TimelineModel {
|
|||
|
||||
func replaceArticles(with unsortedArticles: Set<Article>) {
|
||||
articles = Array(unsortedArticles).sortedByDate(sortDirection ? .orderedDescending : .orderedAscending, groupByFeed: groupByFeed)
|
||||
timelineItems = articles.map { TimelineItem(article: $0) }
|
||||
|
||||
timelineItems = [TimelineItem]()
|
||||
nextBatch()
|
||||
// TODO: Update unread counts and other item done in didSet on AppKit
|
||||
}
|
||||
|
||||
|
||||
func nextBatch() {
|
||||
let rangeEndIndex = timelineItems.endIndex + 50 > articles.endIndex ? articles.endIndex : timelineItems.endIndex + 50
|
||||
let range = timelineItems.endIndex..<rangeEndIndex
|
||||
for i in range {
|
||||
timelineItems.append(TimelineItem(article: articles[i]))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Notifications
|
||||
|
||||
}
|
||||
|
|
|
@ -13,12 +13,11 @@ struct TimelineView: View {
|
|||
@EnvironmentObject private var timelineModel: TimelineModel
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
LazyVStack() {
|
||||
ForEach(timelineModel.timelineItems) { timelineItem in
|
||||
TimelineItemView(timelineItem: timelineItem)
|
||||
List(timelineModel.timelineItems) { timelineItem in
|
||||
TimelineItemView(timelineItem: timelineItem)
|
||||
.onAppear {
|
||||
timelineModel.loadMoreTimelineItemsIfNecessary(timelineItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
511D43EF231FBDE900FB1562 /* LaunchScreenPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 511D43ED231FBDE800FB1562 /* LaunchScreenPad.storyboard */; };
|
||||
511D4419231FC02D00FB1562 /* KeyboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 511D4410231FC02D00FB1562 /* KeyboardManager.swift */; };
|
||||
51236339236915B100951F16 /* RoundedProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 512363372369155100951F16 /* RoundedProgressView.swift */; };
|
||||
5125E6CA24AE461D002A7562 /* TimelineLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17B223DB24AC24D2001E4592 /* TimelineLayoutView.swift */; };
|
||||
5126EE97226CB48A00C22AFC /* SceneCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5126EE96226CB48A00C22AFC /* SceneCoordinator.swift */; };
|
||||
5127B238222B4849006D641D /* DetailKeyboardDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5127B236222B4849006D641D /* DetailKeyboardDelegate.swift */; };
|
||||
5127B23A222B4849006D641D /* DetailKeyboardShortcuts.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5127B237222B4849006D641D /* DetailKeyboardShortcuts.plist */; };
|
||||
|
@ -264,6 +265,12 @@
|
|||
51A1699D235E10D700EB091F /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16993235E10D600EB091F /* SettingsViewController.swift */; };
|
||||
51A1699F235E10D700EB091F /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16995235E10D600EB091F /* AboutViewController.swift */; };
|
||||
51A169A0235E10D700EB091F /* FeedbinAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16996235E10D700EB091F /* FeedbinAccountViewController.swift */; };
|
||||
51A5769624AE617200078888 /* ArticleContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A5769524AE617200078888 /* ArticleContainerView.swift */; };
|
||||
51A5769724AE617200078888 /* ArticleContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A5769524AE617200078888 /* ArticleContainerView.swift */; };
|
||||
51A576BB24AE621800078888 /* ArticleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A576BA24AE621800078888 /* ArticleModel.swift */; };
|
||||
51A576BC24AE621800078888 /* ArticleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A576BA24AE621800078888 /* ArticleModel.swift */; };
|
||||
51A576BE24AE637400078888 /* ArticleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A576BD24AE637400078888 /* ArticleView.swift */; };
|
||||
51A576BF24AE637400078888 /* ArticleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A576BD24AE637400078888 /* ArticleView.swift */; };
|
||||
51A66685238075AE00CB272D /* AddWebFeedDefaultContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A66684238075AE00CB272D /* AddWebFeedDefaultContainer.swift */; };
|
||||
51A9A5E12380C4FE0033AADF /* AppDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C45255226507D200C03939 /* AppDefaults.swift */; };
|
||||
51A9A5E42380C8880033AADF /* ShareFolderPickerAccountCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 51A9A5E32380C8870033AADF /* ShareFolderPickerAccountCell.xib */; };
|
||||
|
@ -1866,6 +1873,9 @@
|
|||
51A16993235E10D600EB091F /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
|
||||
51A16995235E10D600EB091F /* AboutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutViewController.swift; sourceTree = "<group>"; };
|
||||
51A16996235E10D700EB091F /* FeedbinAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedbinAccountViewController.swift; sourceTree = "<group>"; };
|
||||
51A5769524AE617200078888 /* ArticleContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleContainerView.swift; sourceTree = "<group>"; };
|
||||
51A576BA24AE621800078888 /* ArticleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleModel.swift; sourceTree = "<group>"; };
|
||||
51A576BD24AE637400078888 /* ArticleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleView.swift; sourceTree = "<group>"; };
|
||||
51A66684238075AE00CB272D /* AddWebFeedDefaultContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedDefaultContainer.swift; sourceTree = "<group>"; };
|
||||
51A9A5E32380C8870033AADF /* ShareFolderPickerAccountCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShareFolderPickerAccountCell.xib; sourceTree = "<group>"; };
|
||||
51A9A5E52380C8B20033AADF /* ShareFolderPickerFolderCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShareFolderPickerFolderCell.xib; sourceTree = "<group>"; };
|
||||
|
@ -2674,6 +2684,16 @@
|
|||
path = Activity;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
51A576B924AE617B00078888 /* Article */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
51A5769524AE617200078888 /* ArticleContainerView.swift */,
|
||||
51A576BA24AE621800078888 /* ArticleModel.swift */,
|
||||
51A576BD24AE637400078888 /* ArticleView.swift */,
|
||||
);
|
||||
path = Article;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
51B5C85A23F22A7A00032075 /* CommonExtension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -2732,6 +2752,7 @@
|
|||
51E499D724A912C200B667CB /* SceneModel.swift */,
|
||||
51E49A0224A91FF600B667CB /* SceneNavigationView.swift */,
|
||||
51C0513824A77DF800194D5E /* Assets.xcassets */,
|
||||
51A576B924AE617B00078888 /* Article */,
|
||||
51919FB124AAB95300541E64 /* Images */,
|
||||
514E6BFD24AD252400AC6F6E /* Previews */,
|
||||
51E499FB24A9135A00B667CB /* Sidebar */,
|
||||
|
@ -3928,46 +3949,46 @@
|
|||
TargetAttributes = {
|
||||
51314636235A7BBE00387FDC = {
|
||||
CreatedOnToolsVersion = 11.2;
|
||||
DevelopmentTeam = FQLBNX3GP7;
|
||||
DevelopmentTeam = SHJK2V3AJG;
|
||||
LastSwiftMigration = 1120;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
513C5CE5232571C2003D4054 = {
|
||||
CreatedOnToolsVersion = 11.0;
|
||||
DevelopmentTeam = FQLBNX3GP7;
|
||||
DevelopmentTeam = SHJK2V3AJG;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
518B2ED12351B3DD00400001 = {
|
||||
CreatedOnToolsVersion = 11.2;
|
||||
DevelopmentTeam = FQLBNX3GP7;
|
||||
DevelopmentTeam = SHJK2V3AJG;
|
||||
ProvisioningStyle = Automatic;
|
||||
TestTargetID = 840D617B2029031C009BC708;
|
||||
};
|
||||
51C0513C24A77DF800194D5E = {
|
||||
CreatedOnToolsVersion = 12.0;
|
||||
DevelopmentTeam = FQLBNX3GP7;
|
||||
DevelopmentTeam = SHJK2V3AJG;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
51C0514324A77DF800194D5E = {
|
||||
CreatedOnToolsVersion = 12.0;
|
||||
DevelopmentTeam = FQLBNX3GP7;
|
||||
DevelopmentTeam = SHJK2V3AJG;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
6581C73220CED60000F4AD34 = {
|
||||
DevelopmentTeam = FQLBNX3GP7;
|
||||
DevelopmentTeam = SHJK2V3AJG;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
65ED3FA2235DEF6C0081F399 = {
|
||||
DevelopmentTeam = FQLBNX3GP7;
|
||||
DevelopmentTeam = SHJK2V3AJG;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
65ED4090235DEF770081F399 = {
|
||||
DevelopmentTeam = FQLBNX3GP7;
|
||||
DevelopmentTeam = SHJK2V3AJG;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
840D617B2029031C009BC708 = {
|
||||
CreatedOnToolsVersion = 9.3;
|
||||
DevelopmentTeam = FQLBNX3GP7;
|
||||
DevelopmentTeam = SHJK2V3AJG;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.BackgroundModes = {
|
||||
|
@ -3977,7 +3998,7 @@
|
|||
};
|
||||
849C645F1ED37A5D003D8FC0 = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
DevelopmentTeam = FQLBNX3GP7;
|
||||
DevelopmentTeam = SHJK2V3AJG;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.HardenedRuntime = {
|
||||
|
@ -3987,7 +4008,7 @@
|
|||
};
|
||||
849C64701ED37A5D003D8FC0 = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
DevelopmentTeam = FQLBNX3GP7;
|
||||
DevelopmentTeam = SHJK2V3AJG;
|
||||
ProvisioningStyle = Automatic;
|
||||
TestTargetID = 849C645F1ED37A5D003D8FC0;
|
||||
};
|
||||
|
@ -4791,11 +4812,13 @@
|
|||
51E4995424A8734D00B667CB /* ExtensionPointIdentifer.swift in Sources */,
|
||||
51E4996924A8760C00B667CB /* ArticleStylesManager.swift in Sources */,
|
||||
51E498F324A8085D00B667CB /* PseudoFeed.swift in Sources */,
|
||||
51A5769624AE617200078888 /* ArticleContainerView.swift in Sources */,
|
||||
51E4996B24A8762D00B667CB /* ArticleExtractor.swift in Sources */,
|
||||
51E49A0324A91FF600B667CB /* SceneNavigationView.swift in Sources */,
|
||||
51E4990124A808BB00B667CB /* FaviconURLFinder.swift in Sources */,
|
||||
51E4991D24A8092100B667CB /* NSAttributedString+NetNewsWire.swift in Sources */,
|
||||
51E499FD24A9137600B667CB /* SidebarModel.swift in Sources */,
|
||||
51A576BE24AE637400078888 /* ArticleView.swift in Sources */,
|
||||
51E4995324A8734D00B667CB /* RedditFeedProvider-Extensions.swift in Sources */,
|
||||
172199C924AB228900A31D04 /* SettingsView.swift in Sources */,
|
||||
51E4994224A8713C00B667CB /* ArticleStatusSyncTimer.swift in Sources */,
|
||||
|
@ -4809,17 +4832,18 @@
|
|||
51E4992624A80AAB00B667CB /* AppAssets.swift in Sources */,
|
||||
514E6C0624AD2B5F00AC6F6E /* Image-Extensions.swift in Sources */,
|
||||
51E4995624A8734D00B667CB /* TwitterFeedProvider-Extensions.swift in Sources */,
|
||||
65CBAD3624AE02D50006DD91 /* TimelineLayoutView.swift in Sources */,
|
||||
5125E6CA24AE461D002A7562 /* TimelineLayoutView.swift in Sources */,
|
||||
51E4996824A8760C00B667CB /* ArticleStyle.swift in Sources */,
|
||||
51E4990024A808BB00B667CB /* FaviconGenerator.swift in Sources */,
|
||||
51E4997124A8764C00B667CB /* ActivityType.swift in Sources */,
|
||||
51E4991E24A8094300B667CB /* RSImage-AppIcons.swift in Sources */,
|
||||
51E499D824A912C200B667CB /* SceneModel.swift in Sources */,
|
||||
51919FB324AAB97900541E64 /* FeedImageLoader.swift in Sources */,
|
||||
51919FB324AAB97900541E64 /* FeedIconImageLoader.swift in Sources */,
|
||||
51919FB324AAB97900541E64 /* FeedIconImageLoader.swift in Sources */,
|
||||
51E4991324A808FB00B667CB /* AddWebFeedDefaultContainer.swift in Sources */,
|
||||
51E4993C24A8709900B667CB /* AppDelegate.swift in Sources */,
|
||||
51E498F924A8085D00B667CB /* SmartFeed.swift in Sources */,
|
||||
51A576BB24AE621800078888 /* ArticleModel.swift in Sources */,
|
||||
51E4995124A8734D00B667CB /* ExtensionPointManager.swift in Sources */,
|
||||
51E4990C24A808C500B667CB /* AuthorAvatarDownloader.swift in Sources */,
|
||||
51E4992124A8095000B667CB /* RSImage-Extensions.swift in Sources */,
|
||||
|
@ -4892,6 +4916,7 @@
|
|||
51919FB424AAB97900541E64 /* FeedIconImageLoader.swift in Sources */,
|
||||
51E4994A24A8734C00B667CB /* ExtensionPointManager.swift in Sources */,
|
||||
514E6C0324AD29A300AC6F6E /* TimelineItemStatusView.swift in Sources */,
|
||||
51A576BC24AE621800078888 /* ArticleModel.swift in Sources */,
|
||||
51E4996D24A8762D00B667CB /* ArticleExtractor.swift in Sources */,
|
||||
51E4994024A8713B00B667CB /* AccountRefreshTimer.swift in Sources */,
|
||||
51E49A0424A91FF600B667CB /* SceneNavigationView.swift in Sources */,
|
||||
|
@ -4910,6 +4935,7 @@
|
|||
51E4996E24A8764C00B667CB /* ActivityManager.swift in Sources */,
|
||||
51E4995A24A873F900B667CB /* ErrorHandler.swift in Sources */,
|
||||
51E4991F24A8094300B667CB /* RSImage-AppIcons.swift in Sources */,
|
||||
51A5769724AE617200078888 /* ArticleContainerView.swift in Sources */,
|
||||
51E4991224A808FB00B667CB /* AddWebFeedDefaultContainer.swift in Sources */,
|
||||
51E4993E24A870F900B667CB /* UserNotificationManager.swift in Sources */,
|
||||
51E4992E24A8676300B667CB /* FetchRequestQueue.swift in Sources */,
|
||||
|
@ -4933,6 +4959,7 @@
|
|||
51E4992D24A8676300B667CB /* FetchRequestOperation.swift in Sources */,
|
||||
51E4992424A8098400B667CB /* SmartFeedPasteboardWriter.swift in Sources */,
|
||||
51E4991424A808FF00B667CB /* ArticleStringFormatter.swift in Sources */,
|
||||
51A576BF24AE637400078888 /* ArticleView.swift in Sources */,
|
||||
51E4991024A808DE00B667CB /* SmallIconProvider.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
@ -45,7 +45,7 @@ final class AppDefaults {
|
|||
static let timelineGroupByFeed = "timelineGroupByFeed"
|
||||
static let refreshClearsReadArticles = "refreshClearsReadArticles"
|
||||
static let timelineNumberOfLines = "timelineNumberOfLines"
|
||||
static let timelineIconSize = "timelineIconSize"
|
||||
static let timelineIconDimension = "timelineIconSize"
|
||||
static let timelineSortDirection = "timelineSortDirection"
|
||||
static let articleFullscreenAvailable = "articleFullscreenAvailable"
|
||||
static let articleFullscreenEnabled = "articleFullscreenEnabled"
|
||||
|
@ -202,11 +202,11 @@ final class AppDefaults {
|
|||
|
||||
var timelineIconSize: IconSize {
|
||||
get {
|
||||
let rawValue = AppDefaults.store.integer(forKey: Key.timelineIconSize)
|
||||
let rawValue = AppDefaults.store.integer(forKey: Key.timelineIconDimension)
|
||||
return IconSize(rawValue: rawValue) ?? IconSize.medium
|
||||
}
|
||||
set {
|
||||
AppDefaults.store.set(newValue.rawValue, forKey: Key.timelineIconSize)
|
||||
AppDefaults.store.set(newValue.rawValue, forKey: Key.timelineIconDimension)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ final class AppDefaults {
|
|||
Key.timelineGroupByFeed: false,
|
||||
Key.refreshClearsReadArticles: false,
|
||||
Key.timelineNumberOfLines: 2,
|
||||
Key.timelineIconSize: IconSize.medium.rawValue,
|
||||
Key.timelineIconDimension: IconSize.medium.rawValue,
|
||||
Key.timelineSortDirection: ComparisonResult.orderedDescending.rawValue,
|
||||
Key.articleFullscreenAvailable: false,
|
||||
Key.articleFullscreenEnabled: false,
|
||||
|
|
Loading…
Reference in New Issue