Merge branch 'swiftui' of https://github.com/brentsimmons/NetNewsWire into swiftui-progressview

# Conflicts:
#	Multiplatform/Shared/Sidebar/SidebarToolbar.swift
This commit is contained in:
Phil Viso
2020-07-04 09:15:08 -05:00
9 changed files with 343 additions and 175 deletions

View File

@@ -49,23 +49,33 @@ struct AddWebFeedView: View {
Form {
HStack {
Spacer()
Image(systemName: "globe").foregroundColor(.accentColor).font(.title)
Image(rsImage: AppAssets.faviconTemplateImage)
.resizable()
.renderingMode(.template)
.frame(width: 30, height: 30)
Text("Add a Web Feed")
.font(.title)
Spacer()
}
urlTextField
.textFieldStyle(RoundedBorderTextFieldStyle())
.help("The URL of the feed you want to add.")
providedNameTextField
.textFieldStyle(RoundedBorderTextFieldStyle())
.help("The name of the feed. (Optional.)")
folderPicker
.help("Pick the folder you want to add the feed to.")
LazyVGrid(columns: [GridItem(.fixed(75), spacing: 10, alignment: .trailing),GridItem(.fixed(400), spacing: 0, alignment: .leading) ], alignment: .leading, spacing: 10, pinnedViews: [], content:{
Text("URL:").bold()
urlTextField
.textFieldStyle(RoundedBorderTextFieldStyle())
.help("The URL of the feed you want to add.")
Text("Name:").bold()
providedNameTextField
.textFieldStyle(RoundedBorderTextFieldStyle())
.help("The name of the feed. (Optional.)")
Text("Folder:").bold()
folderPicker
.help("Pick the folder you want to add the feed to.")
})
buttonStack
}
.padding()
.frame(minWidth: 450)
.frame(maxWidth: 485)
.padding(12)
}
#endif
@@ -98,8 +108,8 @@ struct AddWebFeedView: View {
var urlTextField: some View {
HStack {
Text("Feed:")
#if os(iOS)
Text("Feed:")
TextField("URL", text: $viewModel.providedURL)
.disableAutocorrection(true)
.autocapitalization(UITextAutocapitalizationType.none)
@@ -112,12 +122,15 @@ struct AddWebFeedView: View {
var providedNameTextField: some View {
HStack(alignment: .lastTextBaseline) {
#if os(iOS)
Text("Name:")
#endif
TextField("Optional", text: $viewModel.providedName)
}
}
var folderPicker: some View {
@ViewBuilder var folderPicker: some View {
#if os(iOS)
Picker("Folder:", selection: $viewModel.selectedFolderIndex, content: {
ForEach(0..<viewModel.containers.count, id: \.self, content: { index in
if let containerName = (viewModel.containers[index] as? DisplayNameProvider)?.nameForDisplay {
@@ -129,6 +142,20 @@ struct AddWebFeedView: View {
}
})
})
#else
Picker("", selection: $viewModel.selectedFolderIndex, content: {
ForEach(0..<viewModel.containers.count, id: \.self, content: { index in
if let containerName = (viewModel.containers[index] as? DisplayNameProvider)?.nameForDisplay {
if viewModel.containers[index] is Folder {
Text("\(viewModel.containers[index].account?.nameForDisplay ?? "") / \(containerName)").padding(.leading, 2).tag(index)
} else {
Text(containerName).padding(.leading, 2).tag(index)
}
}
})
}).padding(.leading, -8)
#endif
}
var buttonStack: some View {
@@ -149,7 +176,7 @@ struct AddWebFeedView: View {
})
.disabled(!viewModel.providedURL.isValidURL)
.help("Add Feed")
}
}.padding(.trailing, 2)
}

View File

@@ -16,6 +16,7 @@ struct CompactSidebarContainerView: View {
var body: some View {
SidebarView()
.modifier(SidebarToolbar())
.environmentObject(sidebarModel)
.navigationBarTitle(Text("Feeds"))
.listStyle(PlainListStyle())
@@ -23,11 +24,7 @@ struct CompactSidebarContainerView: View {
sceneModel.sidebarModel = sidebarModel
sidebarModel.delegate = sceneModel
sidebarModel.rebuildSidebarItems()
}.overlay(Group {
#if os(iOS)
SidebarToolbar()
#endif
},alignment: .bottom)
}
}
}

View File

@@ -17,6 +17,7 @@ struct RegularSidebarContainerView: View {
@ViewBuilder var body: some View {
SidebarView()
.modifier(SidebarToolbar())
.environmentObject(sidebarModel)
.navigationTitle(Text("Feeds"))
.listStyle(SidebarListStyle())
@@ -25,12 +26,6 @@ struct RegularSidebarContainerView: View {
sidebarModel.delegate = sceneModel
sidebarModel.rebuildSidebarItems()
}
.overlay(Group {
#if os(iOS)
SidebarToolbar()
#endif
},alignment: .bottom)
}
}

View File

@@ -8,96 +8,74 @@
import SwiftUI
fileprivate enum ToolbarSheets {
case none, web, twitter, reddit, folder, settings
}
fileprivate class SidebarToolbarViewModel: ObservableObject {
@Published var showSheet: Bool = false
@Published var sheetToShow: ToolbarSheets = .none {
didSet {
sheetToShow != .none ? (showSheet = true) : (showSheet = false)
}
}
@Published var showActionSheet: Bool = false
@Published var showAddSheet: Bool = false
}
struct SidebarToolbar: View {
struct SidebarToolbar: ViewModifier {
@EnvironmentObject private var appSettings: AppDefaults
@StateObject private var viewModel = SidebarToolbarViewModel()
@StateObject private var viewModel = SidebarToolbarModel()
var body: some View {
VStack {
Divider()
HStack(alignment: .center) {
Button(action: {
viewModel.sheetToShow = .settings
}, label: {
AppAssets.settingsImage
.font(.title3)
.foregroundColor(.accentColor)
}).help("Settings")
@ViewBuilder func body(content: Content) -> some View {
#if os(iOS)
content
.toolbar {
ToolbarItem(placement: .automatic) {
Button(action: {
viewModel.sheetToShow = .settings
}, label: {
AppAssets.settingsImage
.font(.title3)
.foregroundColor(.accentColor)
Spacer()
}).help("Settings")
}
Spacer()
RefreshProgressView()
Spacer()
Button(action: {
viewModel.showActionSheet = true
}, label: {
AppAssets.addMenuImage
.font(.title3)
.foregroundColor(.accentColor)
ToolbarItem(placement: .automatic, content: {
Spacer()
Text("Last updated")
.font(.caption)
.foregroundColor(.secondary)
Spacer()
})
.help("Add")
.actionSheet(isPresented: $viewModel.showActionSheet) {
ActionSheet(title: Text("Add"), buttons: [
.cancel(),
.default(Text("Add Web Feed"), action: { viewModel.sheetToShow = .web }),
.default(Text("Add Twitter Feed")),
.default(Text("Add Reddit Feed")),
.default(Text("Add Folder"))
])
ToolbarItem(placement: .automatic, content: {
Button(action: {
viewModel.showActionSheet = true
}, label: {
Spacer()
AppAssets.addMenuImage
.font(.title3)
.foregroundColor(.accentColor)
})
.help("Add")
.actionSheet(isPresented: $viewModel.showActionSheet) {
ActionSheet(title: Text("Add"), buttons: [
.cancel(),
.default(Text("Add Web Feed"), action: { viewModel.sheetToShow = .web }),
.default(Text("Add Twitter Feed")),
.default(Text("Add Reddit Feed")),
.default(Text("Add Folder"))
])
}
})
}
.sheet(isPresented: $viewModel.showSheet, onDismiss: { viewModel.sheetToShow = .none }) {
if viewModel.sheetToShow == .web {
AddWebFeedView()
}
if viewModel.sheetToShow == .settings {
SettingsView().modifier(PreferredColorSchemeModifier(preferredColorScheme: appSettings.userInterfaceColorPalette))
}
}
.padding(.horizontal, 16)
.padding(.bottom, 12)
.padding(.top, 4)
}
.background(VisualEffectBlur(blurStyle: .systemChromeMaterial).edgesIgnoringSafeArea(.bottom))
.sheet(isPresented: $viewModel.showSheet, onDismiss: { viewModel.sheetToShow = .none }) {
if viewModel.sheetToShow == .web {
AddWebFeedView()
#else
content
.toolbar {
ToolbarItem {
Spacer()
}
}
if viewModel.sheetToShow == .settings {
SettingsView().modifier(PreferredColorSchemeModifier(preferredColorScheme: appSettings.userInterfaceColorPalette))
}
}
}
#endif
}
}
struct SidebarToolbar_Previews: PreviewProvider {
static var previews: some View {
Group {
SidebarToolbar()
.environmentObject(refreshProgressModel(lastRefreshDate: nil, tasksCompleted: 1, totalTasks: 2))
.previewDisplayName("Refresh in progress")
SidebarToolbar()
.environmentObject(refreshProgressModel(lastRefreshDate: Date(timeIntervalSinceNow: -120.0), tasksCompleted: 0, totalTasks: 0))
.previewDisplayName("Last refreshed with date")
SidebarToolbar()
.environmentObject(refreshProgressModel(lastRefreshDate: nil, tasksCompleted: 0, totalTasks: 0))
.previewDisplayName("Refresh progress hidden")
}
.previewLayout(.sizeThatFits)
}
}

View File

@@ -0,0 +1,26 @@
//
// SidebarToolbarModel.swift
// NetNewsWire
//
// Created by Stuart Breckenridge on 4/7/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Foundation
enum ToolbarSheets {
case none, web, twitter, reddit, folder, settings
}
class SidebarToolbarModel: ObservableObject {
@Published var showSheet: Bool = false
@Published var sheetToShow: ToolbarSheets = .none {
didSet {
sheetToShow != .none ? (showSheet = true) : (showSheet = false)
}
}
@Published var showActionSheet: Bool = false
@Published var showAddSheet: Bool = false
}

View File

@@ -0,0 +1,68 @@
//
// FeedsSettingsModel.swift
// Multiplatform iOS
//
// Created by Rizwan on 04/07/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Foundation
import SwiftUI
import Account
class FeedsSettingsModel: ObservableObject {
@Published var showingImportActionSheet = false
@Published var showingExportActionSheet = false
@Published var exportingFilePath = ""
func onTapExportOPML(action: ((Account?) -> Void)) {
if AccountManager.shared.accounts.count == 1 {
action(AccountManager.shared.accounts.first)
}
else {
showingExportActionSheet = true
}
}
func onTapImportOPML(action: ((Account?) -> Void)) {
switch AccountManager.shared.activeAccounts.count {
case 0:
//TODO:- show error
return
case 1:
action(AccountManager.shared.activeAccounts.first)
default:
showingImportActionSheet = true
}
}
func generateExportURL(for account: Account) -> URL? {
let accountName = account.nameForDisplay.replacingOccurrences(of: " ", with: "").trimmingCharacters(in: .whitespaces)
let filename = "Subscriptions-\(accountName).opml"
let tempFile = FileManager.default.temporaryDirectory.appendingPathComponent(filename)
let opmlString = OPMLExporter.OPMLString(with: account, title: filename)
do {
try opmlString.write(to: tempFile, atomically: true, encoding: String.Encoding.utf8)
} catch {
//TODO:- show error
return nil
}
return tempFile
}
func processImportedFiles(_ urls: [URL],_ account: Account?) {
urls.forEach{
account?.importOPML($0, completion: { result in
switch result {
case .success:
break
case .failure:
//TODO:- show error
break
}
})
}
}
}

View File

@@ -0,0 +1,49 @@
//
// SettingsModel.swift
// Multiplatform iOS
//
// Created by Maurice Parker on 7/4/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Foundation
class SettingsModel: ObservableObject {
enum HelpSites {
case netNewsWireHelp, netNewsWire, supportNetNewsWire, github, bugTracker, technotes, netNewsWireSlack, none
var url: URL? {
switch self {
case .netNewsWireHelp:
return URL(string: "https://ranchero.com/netnewswire/help/ios/5.0/en/")!
case .netNewsWire:
return URL(string: "https://ranchero.com/netnewswire/")!
case .supportNetNewsWire:
return URL(string: "https://github.com/brentsimmons/NetNewsWire/blob/master/Technotes/HowToSupportNetNewsWire.markdown")!
case .github:
return URL(string: "https://github.com/brentsimmons/NetNewsWire")!
case .bugTracker:
return URL(string: "https://github.com/brentsimmons/NetNewsWire/issues")!
case .technotes:
return URL(string: "https://github.com/brentsimmons/NetNewsWire/tree/master/Technotes")!
case .netNewsWireSlack:
return URL(string: "https://ranchero.com/netnewswire/slack")!
case .none:
return nil
}
}
}
@Published var presentSheet: Bool = false
var selectedWebsite: HelpSites = .none {
didSet {
if selectedWebsite == .none {
presentSheet = false
} else {
presentSheet = true
}
}
}
}

View File

@@ -8,57 +8,19 @@
import SwiftUI
import Account
class SettingsViewModel: ObservableObject {
enum HelpSites {
case netNewsWireHelp, netNewsWire, supportNetNewsWire, github, bugTracker, technotes, netNewsWireSlack, none
var url: URL? {
switch self {
case .netNewsWireHelp:
return URL(string: "https://ranchero.com/netnewswire/help/ios/5.0/en/")!
case .netNewsWire:
return URL(string: "https://ranchero.com/netnewswire/")!
case .supportNetNewsWire:
return URL(string: "https://github.com/brentsimmons/NetNewsWire/blob/master/Technotes/HowToSupportNetNewsWire.markdown")!
case .github:
return URL(string: "https://github.com/brentsimmons/NetNewsWire")!
case .bugTracker:
return URL(string: "https://github.com/brentsimmons/NetNewsWire/issues")!
case .technotes:
return URL(string: "https://github.com/brentsimmons/NetNewsWire/tree/master/Technotes")!
case .netNewsWireSlack:
return URL(string: "https://ranchero.com/netnewswire/slack")!
case .none:
return nil
}
}
}
@Published var presentSheet: Bool = false
var selectedWebsite: HelpSites = .none {
didSet {
if selectedWebsite == .none {
presentSheet = false
} else {
presentSheet = true
}
}
}
}
import UniformTypeIdentifiers
struct SettingsView: View {
let sortedAccounts = AccountManager.shared.sortedAccounts
@Environment(\.presentationMode) var presentationMode
@StateObject private var viewModel = SettingsViewModel()
@Environment(\.exportFiles) var exportAction
@Environment(\.importFiles) var importAction
@StateObject private var viewModel = SettingsModel()
@StateObject private var feedsSettingsModel = FeedsSettingsModel()
@StateObject private var settings = AppDefaults.shared
var body: some View {
NavigationView {
List {
@@ -114,19 +76,50 @@ struct SettingsView: View {
var importExport: some View {
Section(header: Text("Feeds"), content: {
NavigationLink(
destination: EmptyView(),
label: {
Text("Import Subscriptions")
})
NavigationLink(
destination: EmptyView(),
label: {
Text("Export Subscriptions")
})
Button(action:{
feedsSettingsModel.onTapImportOPML(action: importOPML)
}) {
Text("Import Subscriptions")
.actionSheet(isPresented: $feedsSettingsModel.showingImportActionSheet, content: importActionSheet)
.foregroundColor(.primary)
}
Button(action:{
feedsSettingsModel.onTapExportOPML(action: exportOPML)
}) {
Text("Export Subscriptions")
.actionSheet(isPresented: $feedsSettingsModel.showingExportActionSheet, content: exportActionSheet)
.foregroundColor(.primary)
}
})
}
private func importActionSheet() -> ActionSheet {
var buttons = sortedAccounts.map { (account) -> ActionSheet.Button in
ActionSheet.Button.default(Text(account.nameForDisplay)) {
importOPML(account: account)
}
}
buttons.append(.cancel())
return ActionSheet(
title: Text("Choose an account to receive the imported feeds and folders"),
buttons: buttons
)
}
private func exportActionSheet() -> ActionSheet {
var buttons = sortedAccounts.map { (account) -> ActionSheet.Button in
ActionSheet.Button.default(Text(account.nameForDisplay)) {
exportOPML(account: account)
}
}
buttons.append(.cancel())
return ActionSheet(
title: Text("Choose an account with the subscriptions to export"),
buttons: buttons
)
}
var timeline: some View {
Section(header: Text("Timeline"), content: {
Toggle("Sort Oldest to Newest", isOn: $settings.timelineSortDirection)
@@ -202,7 +195,24 @@ struct SettingsView: View {
let build = dict?.object(forKey: "CFBundleVersion") as? String ?? ""
return "NetNewsWire \(version) (Build \(build))"
}
private func exportOPML(account: Account?) {
guard let account = account,
let url = feedsSettingsModel.generateExportURL(for: account) else {
return
}
exportAction(moving: url) { _ in }
}
private func importOPML(account: Account?) {
let types = [UTType(filenameExtension: "opml"), UTType("public.xml")].compactMap { $0 }
importAction(multipleOfType: types) { (result: Result<[URL], Error>?) in
if let urls = try? result?.get() {
feedsSettingsModel.processImportedFiles(urls, account)
}
}
}
}
struct SettingsView_Previews: PreviewProvider {

View File

@@ -29,6 +29,9 @@
179DB3CE822BFCC2D774D9F4 /* AccountsNewsBlurWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DBBA2B22A659F81EED6F9 /* AccountsNewsBlurWindowController.swift */; };
17D232A824AFF10A0005F075 /* AddWebFeedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */; };
17D232A924AFF10A0005F075 /* AddWebFeedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */; };
17D5F17124B0BC6700375168 /* SidebarToolbarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D5F17024B0BC6700375168 /* SidebarToolbarModel.swift */; };
17D5F17224B0BC6700375168 /* SidebarToolbarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D5F17024B0BC6700375168 /* SidebarToolbarModel.swift */; };
17D5F19524B0C1DD00375168 /* SidebarToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 172199F024AB716900A31D04 /* SidebarToolbar.swift */; };
3B3A32A5238B820900314204 /* FeedWranglerAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3A328B238B820900314204 /* FeedWranglerAccountViewController.swift */; };
3B826DCB2385C84800FC1ADB /* AccountsFeedWrangler.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3B826DB02385C84800FC1ADB /* AccountsFeedWrangler.xib */; };
3B826DCC2385C84800FC1ADB /* AccountsFeedWranglerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826DCA2385C84800FC1ADB /* AccountsFeedWranglerWindowController.swift */; };
@@ -222,6 +225,7 @@
517A757C24451C1500B553B9 /* OAuthSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 517A755324451BD500B553B9 /* OAuthSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
5181C5AD24AF89B1002E0F70 /* PreferredColorSchemeModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5181C5AC24AF89B1002E0F70 /* PreferredColorSchemeModifier.swift */; };
5181C5AE24AF89B1002E0F70 /* PreferredColorSchemeModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5181C5AC24AF89B1002E0F70 /* PreferredColorSchemeModifier.swift */; };
5181C66224B0C326002E0F70 /* SettingsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5181C66124B0C326002E0F70 /* SettingsModel.swift */; };
5183CCD0226E1E880010922C /* NonIntrinsicLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCCF226E1E880010922C /* NonIntrinsicLabel.swift */; };
5183CCDA226E31A50010922C /* NonIntrinsicImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */; };
5183CCE5226F4DFA0010922C /* RefreshInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCE4226F4DFA0010922C /* RefreshInterval.swift */; };
@@ -635,6 +639,8 @@
6581C73D20CED60100F4AD34 /* SafariExtensionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6581C73B20CED60100F4AD34 /* SafariExtensionViewController.xib */; };
6581C74020CED60100F4AD34 /* netnewswire-subscribe-to-feed.js in Resources */ = {isa = PBXBuildFile; fileRef = 6581C73F20CED60100F4AD34 /* netnewswire-subscribe-to-feed.js */; };
6581C74220CED60100F4AD34 /* ToolbarItemIcon.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 6581C74120CED60100F4AD34 /* ToolbarItemIcon.pdf */; };
6594CA3B24AF6F2A005C7D7C /* OPMLExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8444C8F11FED81840051386C /* OPMLExporter.swift */; };
65C2E40124B05D8A000AFDF6 /* FeedsSettingsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65C2E40024B05D8A000AFDF6 /* FeedsSettingsModel.swift */; };
65CBAD5A24AE03C20006DD91 /* ColorPaletteContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65CBAD5924AE03C20006DD91 /* ColorPaletteContainerView.swift */; };
65ED3FB7235DEF6C0081F399 /* ArticleArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F204DF1FAACBB30076E152 /* ArticleArray.swift */; };
65ED3FB8235DEF6C0081F399 /* CrashReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848B937121C8C5540038DC0D /* CrashReporter.swift */; };
@@ -1737,6 +1743,7 @@
179DBBA2B22A659F81EED6F9 /* AccountsNewsBlurWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsNewsBlurWindowController.swift; sourceTree = "<group>"; };
17B223DB24AC24D2001E4592 /* TimelineLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineLayoutView.swift; sourceTree = "<group>"; };
17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedModel.swift; sourceTree = "<group>"; };
17D5F17024B0BC6700375168 /* SidebarToolbarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarToolbarModel.swift; sourceTree = "<group>"; };
3B3A328B238B820900314204 /* FeedWranglerAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedWranglerAccountViewController.swift; sourceTree = "<group>"; };
3B826DB02385C84800FC1ADB /* AccountsFeedWrangler.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsFeedWrangler.xib; sourceTree = "<group>"; };
3B826DCA2385C84800FC1ADB /* AccountsFeedWranglerWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsFeedWranglerWindowController.swift; sourceTree = "<group>"; };
@@ -1854,6 +1861,7 @@
517A745A2443665000B553B9 /* UIPageViewController-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIPageViewController-Extensions.swift"; sourceTree = "<group>"; };
517A754424451BD500B553B9 /* OAuthSwift.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OAuthSwift.xcodeproj; path = submodules/OAuthSwift/OAuthSwift.xcodeproj; sourceTree = "<group>"; };
5181C5AC24AF89B1002E0F70 /* PreferredColorSchemeModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferredColorSchemeModifier.swift; sourceTree = "<group>"; };
5181C66124B0C326002E0F70 /* SettingsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsModel.swift; sourceTree = "<group>"; };
5183CCCF226E1E880010922C /* NonIntrinsicLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicLabel.swift; sourceTree = "<group>"; };
5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicImageView.swift; sourceTree = "<group>"; };
5183CCE4226F4DFA0010922C /* RefreshInterval.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshInterval.swift; sourceTree = "<group>"; };
@@ -2013,6 +2021,7 @@
6581C73F20CED60100F4AD34 /* netnewswire-subscribe-to-feed.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = "netnewswire-subscribe-to-feed.js"; sourceTree = "<group>"; };
6581C74120CED60100F4AD34 /* ToolbarItemIcon.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = ToolbarItemIcon.pdf; sourceTree = "<group>"; };
6581C74320CED60100F4AD34 /* Subscribe_to_Feed.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Subscribe_to_Feed.entitlements; sourceTree = "<group>"; };
65C2E40024B05D8A000AFDF6 /* FeedsSettingsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedsSettingsModel.swift; sourceTree = "<group>"; };
65CBAD5924AE03C20006DD91 /* ColorPaletteContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPaletteContainerView.swift; sourceTree = "<group>"; };
65ED4083235DEF6C0081F399 /* NetNewsWire.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetNewsWire.app; sourceTree = BUILT_PRODUCTS_DIR; };
65ED409D235DEF770081F399 /* Subscribe to Feed.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Subscribe to Feed.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -2392,6 +2401,8 @@
172199EB24AB228E00A31D04 /* Settings */ = {
isa = PBXGroup;
children = (
65C2E40024B05D8A000AFDF6 /* FeedsSettingsModel.swift */,
5181C66124B0C326002E0F70 /* SettingsModel.swift */,
172199C824AB228900A31D04 /* SettingsView.swift */,
17B223B924AC24A8001E4592 /* Submenus */,
);
@@ -2975,6 +2986,7 @@
51919FAE24AA8EFA00541E64 /* SidebarItemView.swift */,
51E499FC24A9137600B667CB /* SidebarModel.swift */,
172199F024AB716900A31D04 /* SidebarToolbar.swift */,
17D5F17024B0BC6700375168 /* SidebarToolbarModel.swift */,
51919FA524AA64B000541E64 /* SidebarView.swift */,
51919FAB24AA8CCA00541E64 /* UnreadCountView.swift */,
);
@@ -3984,46 +3996,46 @@
TargetAttributes = {
51314636235A7BBE00387FDC = {
CreatedOnToolsVersion = 11.2;
DevelopmentTeam = SHJK2V3AJG;
DevelopmentTeam = FQLBNX3GP7;
LastSwiftMigration = 1120;
ProvisioningStyle = Automatic;
};
513C5CE5232571C2003D4054 = {
CreatedOnToolsVersion = 11.0;
DevelopmentTeam = SHJK2V3AJG;
DevelopmentTeam = FQLBNX3GP7;
ProvisioningStyle = Automatic;
};
518B2ED12351B3DD00400001 = {
CreatedOnToolsVersion = 11.2;
DevelopmentTeam = SHJK2V3AJG;
DevelopmentTeam = FQLBNX3GP7;
ProvisioningStyle = Automatic;
TestTargetID = 840D617B2029031C009BC708;
};
51C0513C24A77DF800194D5E = {
CreatedOnToolsVersion = 12.0;
DevelopmentTeam = SHJK2V3AJG;
DevelopmentTeam = FQLBNX3GP7;
ProvisioningStyle = Automatic;
};
51C0514324A77DF800194D5E = {
CreatedOnToolsVersion = 12.0;
DevelopmentTeam = SHJK2V3AJG;
DevelopmentTeam = FQLBNX3GP7;
ProvisioningStyle = Automatic;
};
6581C73220CED60000F4AD34 = {
DevelopmentTeam = SHJK2V3AJG;
DevelopmentTeam = FQLBNX3GP7;
ProvisioningStyle = Automatic;
};
65ED3FA2235DEF6C0081F399 = {
DevelopmentTeam = SHJK2V3AJG;
DevelopmentTeam = FQLBNX3GP7;
ProvisioningStyle = Automatic;
};
65ED4090235DEF770081F399 = {
DevelopmentTeam = SHJK2V3AJG;
DevelopmentTeam = FQLBNX3GP7;
ProvisioningStyle = Automatic;
};
840D617B2029031C009BC708 = {
CreatedOnToolsVersion = 9.3;
DevelopmentTeam = SHJK2V3AJG;
DevelopmentTeam = FQLBNX3GP7;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.BackgroundModes = {
@@ -4033,7 +4045,7 @@
};
849C645F1ED37A5D003D8FC0 = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = SHJK2V3AJG;
DevelopmentTeam = FQLBNX3GP7;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.HardenedRuntime = {
@@ -4043,7 +4055,7 @@
};
849C64701ED37A5D003D8FC0 = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = SHJK2V3AJG;
DevelopmentTeam = FQLBNX3GP7;
ProvisioningStyle = Automatic;
TestTargetID = 849C645F1ED37A5D003D8FC0;
};
@@ -4809,6 +4821,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
17D5F17124B0BC6700375168 /* SidebarToolbarModel.swift in Sources */,
51E4995924A873F900B667CB /* ErrorHandler.swift in Sources */,
51392D1B24AC19A000BE0D35 /* SidebarExpandedContainers.swift in Sources */,
51E4992F24A8676400B667CB /* ArticleArray.swift in Sources */,
@@ -4820,6 +4833,7 @@
51E498FF24A808BB00B667CB /* SingleFaviconDownloader.swift in Sources */,
51E4997224A8784300B667CB /* DefaultFeedsImporter.swift in Sources */,
514E6C0924AD39AD00AC6F6E /* ArticleIconImageLoader.swift in Sources */,
6594CA3B24AF6F2A005C7D7C /* OPMLExporter.swift in Sources */,
51919FAF24AA8EFA00541E64 /* SidebarItemView.swift in Sources */,
514E6BDA24ACEA0400AC6F6E /* TimelineItemView.swift in Sources */,
51E4990D24A808C500B667CB /* RSHTMLMetadata+Extension.swift in Sources */,
@@ -4840,6 +4854,7 @@
514E6BFF24AD255D00AC6F6E /* PreviewArticles.swift in Sources */,
51E4993024A8676400B667CB /* ArticleSorter.swift in Sources */,
51408B7E24A9EC6F0073CF4E /* SidebarItem.swift in Sources */,
65C2E40124B05D8A000AFDF6 /* FeedsSettingsModel.swift in Sources */,
51E4990A24A808C500B667CB /* FeaturedImageDownloader.swift in Sources */,
51E4993824A8680E00B667CB /* Reachability.swift in Sources */,
51E4993224A8676400B667CB /* FetchRequestQueue.swift in Sources */,
@@ -4857,6 +4872,7 @@
FF64D0E924AF53EE0084080A /* RefreshProgressView.swift in Sources */,
51E499FD24A9137600B667CB /* SidebarModel.swift in Sources */,
51A576BE24AE637400078888 /* ArticleView.swift in Sources */,
5181C66224B0C326002E0F70 /* SettingsModel.swift in Sources */,
51E4995324A8734D00B667CB /* RedditFeedProvider-Extensions.swift in Sources */,
172199C924AB228900A31D04 /* SettingsView.swift in Sources */,
17D232A824AFF10A0005F075 /* AddWebFeedModel.swift in Sources */,
@@ -4930,6 +4946,7 @@
51E4990824A808C300B667CB /* RSHTMLMetadata+Extension.swift in Sources */,
51919FF824AB8B7700541E64 /* TimelineView.swift in Sources */,
51E4992B24A8676300B667CB /* ArticleArray.swift in Sources */,
17D5F17224B0BC6700375168 /* SidebarToolbarModel.swift in Sources */,
514E6C0724AD2B5F00AC6F6E /* Image-Extensions.swift in Sources */,
51E4994D24A8734C00B667CB /* ExtensionPointIdentifer.swift in Sources */,
51E4992224A8095600B667CB /* URL-Extensions.swift in Sources */,
@@ -4975,6 +4992,7 @@
51E4995024A8734C00B667CB /* ExtensionPoint.swift in Sources */,
51E4990E24A808CC00B667CB /* HTMLMetadataDownloader.swift in Sources */,
51E498FB24A808BA00B667CB /* FaviconGenerator.swift in Sources */,
17D5F19524B0C1DD00375168 /* SidebarToolbar.swift in Sources */,
51E4996724A8760B00B667CB /* ArticleStylesManager.swift in Sources */,
1729529B24AA1FD200D65E66 /* MacSearchField.swift in Sources */,
51408B7F24A9EC6F0073CF4E /* SidebarItem.swift in Sources */,