diff --git a/iOS/Intents/AddWebFeedIntentHandler.swift b/Intents/AddWebFeedIntentHandler.swift similarity index 100% rename from iOS/Intents/AddWebFeedIntentHandler.swift rename to Intents/AddWebFeedIntentHandler.swift diff --git a/iOS/Intents/Base.lproj/Intents.intentdefinition b/Intents/Base.lproj/Intents.intentdefinition similarity index 100% rename from iOS/Intents/Base.lproj/Intents.intentdefinition rename to Intents/Base.lproj/Intents.intentdefinition diff --git a/iOS/Intents/en.lproj/Intents.strings b/Intents/en.lproj/Intents.strings similarity index 100% rename from iOS/Intents/en.lproj/Intents.strings rename to Intents/en.lproj/Intents.strings diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 57f64bd30..7c7c8d19c 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 70; + objectVersion = 76; objects = { /* Begin PBXBuildFile section */ @@ -86,9 +86,6 @@ 511D43D0231FA62500FB1562 /* TimelineKeyboardShortcuts.plist in Resources */ = {isa = PBXBuildFile; fileRef = 845479871FEB77C000AD8B59 /* TimelineKeyboardShortcuts.plist */; }; 511D43D1231FA62800FB1562 /* SidebarKeyboardShortcuts.plist in Resources */ = {isa = PBXBuildFile; fileRef = 844B5B681FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist */; }; 511D43D2231FA62C00FB1562 /* GlobalKeyboardShortcuts.plist in Resources */ = {isa = PBXBuildFile; fileRef = 844B5B641FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist */; }; - 511D43EF231FBDE900FB1562 /* LaunchScreenPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 511D43ED231FBDE800FB1562 /* LaunchScreenPad.storyboard */; }; - 511D4419231FC02D00FB1562 /* KeyboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 511D4410231FC02D00FB1562 /* KeyboardManager.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 */; }; 512E08E62268800D00BDCFDD /* FolderTreeControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97A11ED9F180007D329B /* FolderTreeControllerDelegate.swift */; }; @@ -142,7 +139,6 @@ 5144EA40227A37EC00D19003 /* ImportOPMLWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA3E227A37EC00D19003 /* ImportOPMLWindowController.swift */; }; 5144EA51227B8E4500D19003 /* AccountsFeedbinWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA4F227B8E4500D19003 /* AccountsFeedbinWindowController.swift */; }; 5144EA52227B8E4500D19003 /* AccountsFeedbin.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5144EA50227B8E4500D19003 /* AccountsFeedbin.xib */; }; - 514B7C8323205EFB00BAC947 /* RootSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514B7C8223205EFB00BAC947 /* RootSplitViewController.swift */; }; 514C16CE24D2E63F009A3AFA /* Account in Frameworks */ = {isa = PBXBuildFile; productRef = 514C16CD24D2E63F009A3AFA /* Account */; }; 514C16DE24D2EF15009A3AFA /* RSTree in Frameworks */ = {isa = PBXBuildFile; productRef = 514C16DD24D2EF15009A3AFA /* RSTree */; }; 514C16DF24D2EF15009A3AFA /* RSTree in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 514C16DD24D2EF15009A3AFA /* RSTree */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; @@ -167,7 +163,6 @@ 51938DF3231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51938DF1231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift */; }; 519B8D332143397200FA689C /* SharingServiceDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519B8D322143397200FA689C /* SharingServiceDelegate.swift */; }; 519CA8E525841DB700EB079A /* CrashReporter in Frameworks */ = {isa = PBXBuildFile; productRef = 519CA8E425841DB700EB079A /* CrashReporter */; }; - 519E743D22C663F900A78E47 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519E743422C663F900A78E47 /* SceneDelegate.swift */; }; 51A052CE244FB9D7006C2024 /* AddFeedWIndowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A052CD244FB9D6006C2024 /* AddFeedWIndowController.swift */; }; 51A66685238075AE00CB272D /* AddWebFeedDefaultContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A66684238075AE00CB272D /* AddWebFeedDefaultContainer.swift */; }; 51A737AE24DB19730015FA66 /* RSCore in Frameworks */ = {isa = PBXBuildFile; productRef = 51A737AD24DB19730015FA66 /* RSCore */; }; @@ -176,8 +171,6 @@ 51A737C024DB197F0015FA66 /* RSDatabase in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 51A737BE24DB197F0015FA66 /* RSDatabase */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 51A737C824DB19CC0015FA66 /* RSParser in Frameworks */ = {isa = PBXBuildFile; productRef = 51A737C724DB19CC0015FA66 /* RSParser */; }; 51A737C924DB19CC0015FA66 /* RSParser in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 51A737C724DB19CC0015FA66 /* RSParser */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - 51A9A5E12380C4FE0033AADF /* AppDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C45255226507D200C03939 /* AppDefaults.swift */; }; - 51A9A5ED2380D6000033AADF /* AppAssets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C45254226507D200C03939 /* AppAssets.swift */; }; 51A9A5EF2380D63B0033AADF /* IconImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516AE9DE2372269A007DEEAA /* IconImage.swift */; }; 51A9A5F32380DE530033AADF /* AddWebFeedDefaultContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A66684238075AE00CB272D /* AddWebFeedDefaultContainer.swift */; }; 51B5C87723F22B8200032075 /* ExtensionContainers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B5C87623F22B8200032075 /* ExtensionContainers.swift */; }; @@ -193,8 +186,6 @@ 51B5C8E523F4BBFA00032075 /* ExtensionContainersFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B5C87C23F2346200032075 /* ExtensionContainersFile.swift */; }; 51B5C8E623F4BBFA00032075 /* ExtensionFeedAddRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B5C87A23F2317700032075 /* ExtensionFeedAddRequest.swift */; }; 51B5C8E723F4BBFA00032075 /* ExtensionFeedAddRequestFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B5C8BF23F3866C00032075 /* ExtensionFeedAddRequestFile.swift */; }; - 51B62E68233186730085F949 /* IconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B62E67233186730085F949 /* IconView.swift */; }; - 51BB7C272335A8E5008E8144 /* ArticleActivityItemSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BB7C262335A8E5008E8144 /* ArticleActivityItemSource.swift */; }; 51BC2F3824D3439A00E90810 /* Account in Frameworks */ = {isa = PBXBuildFile; productRef = 51BC2F3724D3439A00E90810 /* Account */; }; 51BC2F4824D3439E00E90810 /* RSTree in Frameworks */ = {isa = PBXBuildFile; productRef = 51BC2F4724D3439E00E90810 /* RSTree */; }; 51BC2F4924D3439E00E90810 /* RSTree in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 51BC2F4724D3439E00E90810 /* RSTree */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; @@ -203,8 +194,6 @@ 51BC4AFF247277E0000A6ED8 /* URL-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BC4ADD247277DF000A6ED8 /* URL-Extensions.swift */; }; 51BC4B01247277E0000A6ED8 /* URL-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BC4ADD247277DF000A6ED8 /* URL-Extensions.swift */; }; 51C03081257D815A00609262 /* UnifiedWindow.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 51C0307F257D815A00609262 /* UnifiedWindow.storyboard */; }; - 51C45258226508CF00C03939 /* AppAssets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C45254226507D200C03939 /* AppAssets.swift */; }; - 51C45259226508D300C03939 /* AppDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C45255226507D200C03939 /* AppDefaults.swift */; }; 51C4528E2265099C00C03939 /* SmartFeedsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CC88171FE59CBF00644329 /* SmartFeedsController.swift */; }; 51C4528F226509BD00C03939 /* UnreadFeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F2D5391FC2308B00998D64 /* UnreadFeed.swift */; }; 51C45290226509C100C03939 /* PseudoFeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F2D5351FC22FCB00998D64 /* PseudoFeed.swift */; }; @@ -248,7 +237,6 @@ 51DEE81826FBFF84006DAA56 /* Promenade.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 51DEE81726FBFF84006DAA56 /* Promenade.nnwtheme */; }; 51DEE81A26FBFF84006DAA56 /* Promenade.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 51DEE81726FBFF84006DAA56 /* Promenade.nnwtheme */; }; 51E3EB33229AB02C00645299 /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E3EB32229AB02C00645299 /* ErrorHandler.swift */; }; - 51E3EB3D229AB08300645299 /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E3EB3C229AB08300645299 /* ErrorHandler.swift */; }; 51E4DAED2425F6940091EB5B /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51E4DAEC2425F6940091EB5B /* CloudKit.framework */; }; 51E4DB082425F9EB0091EB5B /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51E4DB072425F9EB0091EB5B /* CloudKit.framework */; }; 51E595A5228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E595A4228CC36500FCC42B /* ArticleStatusSyncTimer.swift */; }; @@ -282,7 +270,6 @@ 8405DDA522168C62008CE1BF /* TimelineContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8405DDA422168C62008CE1BF /* TimelineContainerViewController.swift */; }; 840958632201629A002C1579 /* Subscribe to Feed.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 6581C73320CED60000F4AD34 /* Subscribe to Feed.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 840BEE4121D70E64009BBAFA /* CrashReportWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840BEE4021D70E64009BBAFA /* CrashReportWindowController.swift */; }; - 840D617F2029031C009BC708 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840D617E2029031C009BC708 /* AppDelegate.swift */; }; 8413C1382D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8413C1372D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift */; }; 8413C1392D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8413C1372D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift */; }; 84162A152038C12C00035290 /* MarkCommandValidationStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84162A142038C12C00035290 /* MarkCommandValidationStatus.swift */; }; @@ -389,8 +376,6 @@ 84C9FC8C22629E8F00D921D6 /* KeyboardShortcuts.html in Resources */ = {isa = PBXBuildFile; fileRef = 84C9FC8722629E8F00D921D6 /* KeyboardShortcuts.html */; }; 84C9FC8E22629E8F00D921D6 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 84C9FC8922629E8F00D921D6 /* Credits.rtf */; }; 84C9FC8F22629E8F00D921D6 /* NetNewsWire.sdef in Resources */ = {isa = PBXBuildFile; fileRef = 84C9FC8A22629E8F00D921D6 /* NetNewsWire.sdef */; }; - 84C9FCA12262A1B300D921D6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84C9FC9F2262A1B300D921D6 /* Main.storyboard */; }; - 84C9FCA42262A1B800D921D6 /* LaunchScreenPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84C9FCA22262A1B800D921D6 /* LaunchScreenPhone.storyboard */; }; 84CAFCA422BC8C08007694F0 /* FetchRequestQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CAFCA322BC8C08007694F0 /* FetchRequestQueue.swift */; }; 84CAFCA522BC8C08007694F0 /* FetchRequestQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CAFCA322BC8C08007694F0 /* FetchRequestQueue.swift */; }; 84CAFCAF22BC8C35007694F0 /* FetchRequestOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CAFCAE22BC8C35007694F0 /* FetchRequestOperation.swift */; }; @@ -434,7 +419,6 @@ B2B80778239C4C7000F191E0 /* RSImage-AppIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */; }; B528F81E23333C7E00E735DD /* page.html in Resources */ = {isa = PBXBuildFile; fileRef = B528F81D23333C7E00E735DD /* page.html */; }; BDCB516724282C8A00102A80 /* AccountsNewsBlur.xib in Resources */ = {isa = PBXBuildFile; fileRef = BDCB514D24282C8A00102A80 /* AccountsNewsBlur.xib */; }; - C5A6ED5223C9AF4300AB6BE2 /* TitleActivityItemSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5A6ED5123C9AF4300AB6BE2 /* TitleActivityItemSource.swift */; }; D553738B20186C20006D8857 /* Article+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D553737C20186C1F006D8857 /* Article+Scriptability.swift */; }; D57BE6E0204CD35F00D11AAC /* NSScriptCommand+NetNewsWire.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57BE6DF204CD35F00D11AAC /* NSScriptCommand+NetNewsWire.swift */; }; D5907D7F2004AC00005947E5 /* NSApplication+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5907D7E2004AC00005947E5 /* NSApplication+Scriptability.swift */; }; @@ -704,9 +688,6 @@ 51126DA3225FDE2F00722696 /* RSImage-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RSImage-Extensions.swift"; sourceTree = ""; }; 5117715424E1EA0F00A2A836 /* ArticleExtractorButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleExtractorButton.swift; sourceTree = ""; }; 511B9805237DCAC90028BCAA /* UserInfoKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInfoKey.swift; sourceTree = ""; }; - 511D43EE231FBDE800FB1562 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreenPad.storyboard; sourceTree = ""; }; - 511D4410231FC02D00FB1562 /* KeyboardManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardManager.swift; sourceTree = ""; }; - 5126EE96226CB48A00C22AFC /* SceneCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneCoordinator.swift; sourceTree = ""; }; 5127B236222B4849006D641D /* DetailKeyboardDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailKeyboardDelegate.swift; sourceTree = ""; }; 5127B237222B4849006D641D /* DetailKeyboardShortcuts.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = DetailKeyboardShortcuts.plist; sourceTree = ""; }; 51314617235A797400387FDC /* NetNewsWire_iOSintentextension_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetNewsWire_iOSintentextension_target.xcconfig; sourceTree = ""; }; @@ -727,7 +708,6 @@ 5144EA3E227A37EC00D19003 /* ImportOPMLWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportOPMLWindowController.swift; sourceTree = ""; }; 5144EA4F227B8E4500D19003 /* AccountsFeedbinWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsFeedbinWindowController.swift; sourceTree = ""; }; 5144EA50227B8E4500D19003 /* AccountsFeedbin.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountsFeedbin.xib; sourceTree = ""; }; - 514B7C8223205EFB00BAC947 /* RootSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootSplitViewController.swift; sourceTree = ""; }; 515D4FCB2325815A00EE1167 /* SafariExt.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = SafariExt.js; sourceTree = ""; }; 515D4FCE2325B3D000EE1167 /* NetNewsWire_iOSshareextension_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetNewsWire_iOSshareextension_target.xcconfig; sourceTree = ""; }; 516AE9DE2372269A007DEEAA /* IconImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconImage.swift; sourceTree = ""; }; @@ -741,7 +721,6 @@ 51934CCD2310792F006127BE /* ActivityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityManager.swift; sourceTree = ""; }; 51938DF1231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchTimelineFeedDelegate.swift; sourceTree = ""; }; 519B8D322143397200FA689C /* SharingServiceDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingServiceDelegate.swift; sourceTree = ""; }; - 519E743422C663F900A78E47 /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 51A052CD244FB9D6006C2024 /* AddFeedWIndowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AddFeedWIndowController.swift; path = AddFeed/AddFeedWIndowController.swift; sourceTree = ""; }; 51A66684238075AE00CB272D /* AddWebFeedDefaultContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedDefaultContainer.swift; sourceTree = ""; }; 51B5C87623F22B8200032075 /* ExtensionContainers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionContainers.swift; sourceTree = ""; }; @@ -749,12 +728,8 @@ 51B5C87C23F2346200032075 /* ExtensionContainersFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionContainersFile.swift; sourceTree = ""; }; 51B5C8BC23F3780900032075 /* ShareDefaultContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareDefaultContainer.swift; sourceTree = ""; }; 51B5C8BF23F3866C00032075 /* ExtensionFeedAddRequestFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionFeedAddRequestFile.swift; sourceTree = ""; }; - 51B62E67233186730085F949 /* IconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconView.swift; sourceTree = ""; }; - 51BB7C262335A8E5008E8144 /* ArticleActivityItemSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleActivityItemSource.swift; sourceTree = ""; }; 51BC4ADD247277DF000A6ED8 /* URL-Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "URL-Extensions.swift"; sourceTree = ""; }; 51C03080257D815A00609262 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Mac/Base.lproj/UnifiedWindow.storyboard; sourceTree = SOURCE_ROOT; }; - 51C45254226507D200C03939 /* AppAssets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppAssets.swift; sourceTree = ""; }; - 51C45255226507D200C03939 /* AppDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDefaults.swift; sourceTree = ""; }; 51C452B32265141B00C03939 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; }; 51C4CFEF24D37D1F00AF9874 /* Secrets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Secrets.swift; sourceTree = ""; }; 51CD32A824D2CB25009ABAEF /* SyncDatabase */ = {isa = PBXFileReference; lastKnownFileType = folder; path = SyncDatabase; sourceTree = ""; }; @@ -768,7 +743,6 @@ 51DEE81126FB9233006DAA56 /* Appanoose.nnwtheme */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Appanoose.nnwtheme; sourceTree = ""; }; 51DEE81726FBFF84006DAA56 /* Promenade.nnwtheme */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Promenade.nnwtheme; sourceTree = ""; }; 51E3EB32229AB02C00645299 /* ErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandler.swift; sourceTree = ""; }; - 51E3EB3C229AB08300645299 /* ErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandler.swift; sourceTree = ""; }; 51E4989624A8065700B667CB /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/CloudKit.framework; sourceTree = DEVELOPER_DIR; }; 51E4989824A8067000B667CB /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; }; 51E498B224A806AA00B667CB /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; @@ -804,7 +778,6 @@ 840BEE4021D70E64009BBAFA /* CrashReportWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReportWindowController.swift; sourceTree = ""; }; 840C544F2D0C9A4A00A240DB /* Core */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Core; sourceTree = ""; }; 840D617C2029031C009BC708 /* NetNewsWire.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetNewsWire.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 840D617E2029031C009BC708 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 840D61952029031D009BC708 /* NetNewsWire_iOSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetNewsWire_iOSTests.swift; sourceTree = ""; }; 840D61972029031D009BC708 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8413C1372D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UniformTypeIdentifiers+Extras.swift"; sourceTree = ""; }; @@ -911,8 +884,6 @@ 84C9FC8A22629E8F00D921D6 /* NetNewsWire.sdef */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = NetNewsWire.sdef; sourceTree = ""; }; 84C9FC9022629ECB00D921D6 /* NetNewsWire.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NetNewsWire.entitlements; sourceTree = ""; }; 84C9FC9122629F2200D921D6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 84C9FCA02262A1B300D921D6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 84C9FCA32262A1B800D921D6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreenPhone.storyboard; sourceTree = ""; }; 84CAFCA322BC8C08007694F0 /* FetchRequestQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchRequestQueue.swift; sourceTree = ""; }; 84CAFCAE22BC8C35007694F0 /* FetchRequestOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchRequestOperation.swift; sourceTree = ""; }; 84CBDDAE1FD3674C005A61AA /* Technotes */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Technotes; sourceTree = ""; }; @@ -956,7 +927,6 @@ B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RSImage-AppIcons.swift"; sourceTree = ""; }; B528F81D23333C7E00E735DD /* page.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = page.html; sourceTree = ""; }; BDCB514D24282C8A00102A80 /* AccountsNewsBlur.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsNewsBlur.xib; sourceTree = ""; }; - C5A6ED5123C9AF4300AB6BE2 /* TitleActivityItemSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleActivityItemSource.swift; sourceTree = ""; }; D519E74722EE553300923F27 /* NetNewsWire_safariextension_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetNewsWire_safariextension_target.xcconfig; sourceTree = ""; }; D553737C20186C1F006D8857 /* Article+Scriptability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Article+Scriptability.swift"; sourceTree = ""; }; D57BE6DF204CD35F00D11AAC /* NSScriptCommand+NetNewsWire.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSScriptCommand+NetNewsWire.swift"; sourceTree = ""; }; @@ -981,48 +951,48 @@ /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ - 84A6CEFD2D1B4E1600F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + 84A6D03F2D1B4EC500F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { isa = PBXFileSystemSynchronizedBuildFileExceptionSet; membershipExceptions = ( - Info.plist, - ); - target = 513C5CE5232571C2003D4054 /* NetNewsWire iOS Share Extension */; - }; - 84A6CF032D1B4E5400F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - IntentHandler.swift, - ); - target = 51314636235A7BBE00387FDC /* NetNewsWire iOS Intents Extension */; - }; - 84A6CF1D2D1B4E7C00F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - Info.plist, + /Localized/ShareExtension/MainInterface.storyboard, + IntentsExtension/Info.plist, + IntentsExtension/IntentHandler.swift, + Resources/Info.plist, + ShareExtension/Info.plist, + ShareExtension/ShareFolderPickerAccountCell.xib, + ShareExtension/ShareFolderPickerCell.swift, + ShareExtension/ShareFolderPickerController.swift, + ShareExtension/ShareFolderPickerFolderCell.xib, + ShareExtension/ShareViewController.swift, ); target = 840D617B2029031C009BC708 /* NetNewsWire-iOS */; }; - 84A6CF1E2D1B4E7C00F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + 84A6D0402D1B4EC500F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { isa = PBXFileSystemSynchronizedBuildFileExceptionSet; membershipExceptions = ( - Assets.xcassets, + /Localized/ShareExtension/MainInterface.storyboard, + AppAssets.swift, + AppDefaults.swift, + Resources/Assets.xcassets, + ShareExtension/ShareFolderPickerAccountCell.xib, + ShareExtension/ShareFolderPickerCell.swift, + ShareExtension/ShareFolderPickerController.swift, + ShareExtension/ShareFolderPickerFolderCell.xib, + ShareExtension/ShareViewController.swift, ); target = 513C5CE5232571C2003D4054 /* NetNewsWire iOS Share Extension */; }; + 84A6D0412D1B4EC500F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + IntentsExtension/IntentHandler.swift, + ); + target = 51314636235A7BBE00387FDC /* NetNewsWire iOS Intents Extension */; + }; /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ - 84352B8A2D1B446D0002B64E /* MainFeed */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = MainFeed; sourceTree = ""; }; - 84A6CE4F2D1B457500F23315 /* MainTimeline */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = MainTimeline; sourceTree = ""; }; - 84A6CE6C2D1B4D1300F23315 /* Article */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Article; sourceTree = ""; }; - 84A6CE812D1B4D2700F23315 /* Account */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Account; sourceTree = ""; }; - 84A6CE902D1B4D8300F23315 /* Add */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Add; sourceTree = ""; }; - 84A6CE9D2D1B4D9A00F23315 /* Inspector */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Inspector; sourceTree = ""; }; - 84A6CEAE2D1B4DD000F23315 /* Settings */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Settings; sourceTree = ""; }; - 84A6CED32D1B4DF700F23315 /* UIKit Extensions */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = "UIKit Extensions"; sourceTree = ""; }; - 84A6CEF52D1B4E1600F23315 /* ShareExtension */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (84A6CEFD2D1B4E1600F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = ShareExtension; sourceTree = ""; }; - 84A6CF012D1B4E5400F23315 /* IntentsExtension */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (84A6CF032D1B4E5400F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = IntentsExtension; sourceTree = ""; }; - 84A6CF112D1B4E7C00F23315 /* Resources */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (84A6CF1D2D1B4E7C00F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, 84A6CF1E2D1B4E7C00F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Resources; sourceTree = ""; }; + 84A6CFB52D1B4EC500F23315 /* iOS */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (84A6D03F2D1B4EC500F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, 84A6D0402D1B4EC500F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, 84A6D0412D1B4EC500F23315 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = iOS; sourceTree = ""; }; /* End PBXFileSystemSynchronizedRootGroup section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1621,7 +1591,8 @@ 84D2200922B0BC4B0019E085 /* CONTRIBUTING.md */, 84CBDDAE1FD3674C005A61AA /* Technotes */, 84C9FC6522629B3900D921D6 /* Mac */, - 84C9FC922262A0E600D921D6 /* iOS */, + 84A6CFB52D1B4EC500F23315 /* iOS */, + 513145F9235A55A700387FDC /* Intents */, 176813F82564BB2C00D98635 /* Widget */, 84C9FC6822629C9A00D921D6 /* Shared */, 84C9FCA52262A1E600D921D6 /* Tests */, @@ -1813,39 +1784,6 @@ path = KeyboardShortcuts; sourceTree = ""; }; - 84C9FC922262A0E600D921D6 /* iOS */ = { - isa = PBXGroup; - children = ( - 84C9FCA22262A1B800D921D6 /* LaunchScreenPhone.storyboard */, - 511D43ED231FBDE800FB1562 /* LaunchScreenPad.storyboard */, - 84C9FC9F2262A1B300D921D6 /* Main.storyboard */, - 840D617E2029031C009BC708 /* AppDelegate.swift */, - 519E743422C663F900A78E47 /* SceneDelegate.swift */, - 5126EE96226CB48A00C22AFC /* SceneCoordinator.swift */, - 514B7C8223205EFB00BAC947 /* RootSplitViewController.swift */, - 511D4410231FC02D00FB1562 /* KeyboardManager.swift */, - 51C45254226507D200C03939 /* AppAssets.swift */, - 51C45255226507D200C03939 /* AppDefaults.swift */, - 51E3EB3C229AB08300645299 /* ErrorHandler.swift */, - 51BB7C262335A8E5008E8144 /* ArticleActivityItemSource.swift */, - C5A6ED5123C9AF4300AB6BE2 /* TitleActivityItemSource.swift */, - 51B62E67233186730085F949 /* IconView.swift */, - 84352B8A2D1B446D0002B64E /* MainFeed */, - 84A6CE4F2D1B457500F23315 /* MainTimeline */, - 84A6CE6C2D1B4D1300F23315 /* Article */, - 84A6CE812D1B4D2700F23315 /* Account */, - 84A6CE902D1B4D8300F23315 /* Add */, - 84A6CE9D2D1B4D9A00F23315 /* Inspector */, - 513145F9235A55A700387FDC /* Intents */, - 84A6CEAE2D1B4DD000F23315 /* Settings */, - 84A6CED32D1B4DF700F23315 /* UIKit Extensions */, - 84A6CEF52D1B4E1600F23315 /* ShareExtension */, - 84A6CF012D1B4E5400F23315 /* IntentsExtension */, - 84A6CF112D1B4E7C00F23315 /* Resources */, - ); - path = iOS; - sourceTree = ""; - }; 84C9FCA52262A1E600D921D6 /* Tests */ = { isa = PBXGroup; children = ( @@ -2058,9 +1996,6 @@ ); dependencies = ( ); - fileSystemSynchronizedGroups = ( - 84A6CEF52D1B4E1600F23315 /* ShareExtension */, - ); name = "NetNewsWire iOS Share Extension"; packageProductDependencies = ( 51BC2F3724D3439A00E90810 /* Account */, @@ -2125,15 +2060,7 @@ 176813FF2564BB2D00D98635 /* PBXTargetDependency */, ); fileSystemSynchronizedGroups = ( - 84352B8A2D1B446D0002B64E /* MainFeed */, - 84A6CE4F2D1B457500F23315 /* MainTimeline */, - 84A6CE6C2D1B4D1300F23315 /* Article */, - 84A6CE812D1B4D2700F23315 /* Account */, - 84A6CE902D1B4D8300F23315 /* Add */, - 84A6CE9D2D1B4D9A00F23315 /* Inspector */, - 84A6CEAE2D1B4DD000F23315 /* Settings */, - 84A6CED32D1B4DF700F23315 /* UIKit Extensions */, - 84A6CF112D1B4E7C00F23315 /* Resources */, + 84A6CFB52D1B4EC500F23315 /* iOS */, ); name = "NetNewsWire-iOS"; packageProductDependencies = ( @@ -2286,7 +2213,6 @@ }; }; buildConfigurationList = 849C645B1ED37A5D003D8FC0 /* Build configuration list for PBXProject "NetNewsWire" */; - compatibilityVersion = "Xcode 3.2"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -2303,6 +2229,7 @@ 519CA8E325841DB700EB079A /* XCRemoteSwiftPackageReference "plcrashreporter" */, 179D280926F6F93D003B2E0A /* XCRemoteSwiftPackageReference "Zip" */, ); + preferredProjectObjectVersion = 46; productRefGroup = 849C64611ED37A5D003D8FC0 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -2381,14 +2308,11 @@ 5137C2E626F3F52D009EFEDB /* Sepia.nnwtheme in Resources */, 517630052336215100E15FFF /* main.js in Resources */, 511D43D0231FA62500FB1562 /* TimelineKeyboardShortcuts.plist in Resources */, - 511D43EF231FBDE900FB1562 /* LaunchScreenPad.storyboard in Resources */, 511D43D2231FA62C00FB1562 /* GlobalKeyboardShortcuts.plist in Resources */, - 84C9FCA12262A1B300D921D6 /* Main.storyboard in Resources */, 51077C5627A86C9E000C71DB /* Hyperlegible.nnwtheme in Resources */, 51DEE81A26FBFF84006DAA56 /* Promenade.nnwtheme in Resources */, 1768140B2564BB8300D98635 /* NetNewsWire_iOSwidgetextension_target.xcconfig in Resources */, 51D0214826ED617100FF2E0F /* core.css in Resources */, - 84C9FCA42262A1B800D921D6 /* LaunchScreenPhone.storyboard in Resources */, 511D43D1231FA62800FB1562 /* SidebarKeyboardShortcuts.plist in Resources */, 51C452AB22650DC600C03939 /* template.html in Resources */, 84A3EE61223B667F00557320 /* DefaultFeeds.opml in Resources */, @@ -2685,9 +2609,7 @@ 51B5C8BA23F368D000032075 /* ExtensionContainersFile.swift in Sources */, 51B5C8BB23F368D000032075 /* ExtensionFeedAddRequest.swift in Sources */, 51A9A5EF2380D63B0033AADF /* IconImage.swift in Sources */, - 51A9A5ED2380D6000033AADF /* AppAssets.swift in Sources */, 51B5C8C123F3A0DB00032075 /* ExtensionFeedAddRequestFile.swift in Sources */, - 51A9A5E12380C4FE0033AADF /* AppDefaults.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2712,12 +2634,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 840D617F2029031C009BC708 /* AppDelegate.swift in Sources */, 512E08E72268801200BDCFDD /* WebFeedTreeControllerDelegate.swift in Sources */, 51C452A422650A2D00C03939 /* ArticleUtilities.swift in Sources */, 51EF0F79227716380050506E /* ColorHash.swift in Sources */, B2B80778239C4C7000F191E0 /* RSImage-AppIcons.swift in Sources */, - 51B62E68233186730085F949 /* IconView.swift in Sources */, 179D280D26F73D83003B2E0A /* ArticleThemePlist.swift in Sources */, 51C45296226509D300C03939 /* OPMLExporter.swift in Sources */, 51C45291226509C800C03939 /* SmartFeed.swift in Sources */, @@ -2731,15 +2651,12 @@ 51D5948722668EFA00DFC836 /* MarkStatusCommand.swift in Sources */, 176813D12564BA5900D98635 /* WidgetDataDecoder.swift in Sources */, 176813D02564BA5900D98635 /* WidgetData.swift in Sources */, - 514B7C8323205EFB00BAC947 /* RootSplitViewController.swift in Sources */, 51FA73A52332BE110090D516 /* ArticleExtractor.swift in Sources */, 51314704235C41FC00387FDC /* Intents.intentdefinition in Sources */, FF3ABF162325AF5D0074C542 /* ArticleSorter.swift in Sources */, - 5126EE97226CB48A00C22AFC /* SceneCoordinator.swift in Sources */, 84CAFCB022BC8C35007694F0 /* FetchRequestOperation.swift in Sources */, 51EF0F77227716200050506E /* FaviconGenerator.swift in Sources */, 51938DF3231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift in Sources */, - 51BB7C272335A8E5008E8144 /* ArticleActivityItemSource.swift in Sources */, 51C452A622650A3500C03939 /* Node-Extensions.swift in Sources */, 51C45294226509C800C03939 /* SearchFeedDelegate.swift in Sources */, 51FE10042345529D0056195D /* UserNotificationManager.swift in Sources */, @@ -2752,9 +2669,7 @@ 51C45292226509C800C03939 /* TodayFeedDelegate.swift in Sources */, 51C452A222650A1900C03939 /* RSHTMLMetadata+Extension.swift in Sources */, 51B5C87B23F2317700032075 /* ExtensionFeedAddRequest.swift in Sources */, - 51E3EB3D229AB08300645299 /* ErrorHandler.swift in Sources */, 5183CCE5226F4DFA0010922C /* RefreshInterval.swift in Sources */, - 51C45258226508CF00C03939 /* AppAssets.swift in Sources */, 51FA73A82332BE880090D516 /* ExtractedArticle.swift in Sources */, 51C4529A22650A0400C03939 /* ArticleTheme.swift in Sources */, 51C452AE2265104D00C03939 /* ArticleStringFormatter.swift in Sources */, @@ -2779,16 +2694,12 @@ 173A642C2547BE9600267F6E /* AccountType+Helpers.swift in Sources */, 8454C3F3263F2D8700E3F9C7 /* IconImageCache.swift in Sources */, B24E9ADE245AB88400DA5718 /* NSAttributedString+NetNewsWire.swift in Sources */, - C5A6ED5223C9AF4300AB6BE2 /* TitleActivityItemSource.swift in Sources */, 17071EF126F8137400F5E71D /* ArticleTheme+Notifications.swift in Sources */, 51C4529B22650A1000C03939 /* FaviconDownloader.swift in Sources */, 84DEE56622C32CA4005FC42C /* SmartFeedDelegate.swift in Sources */, 516AE9E02372269A007DEEAA /* IconImage.swift in Sources */, 51C4529F22650A1900C03939 /* AuthorAvatarDownloader.swift in Sources */, - 519E743D22C663F900A78E47 /* SceneDelegate.swift in Sources */, 8413C1382D050A1E002E3D0F /* UniformTypeIdentifiers+Extras.swift in Sources */, - 51C45259226508D300C03939 /* AppDefaults.swift in Sources */, - 511D4419231FC02D00FB1562 /* KeyboardManager.swift in Sources */, 51C45293226509C800C03939 /* StarredFeedDelegate.swift in Sources */, 51BC4B01247277E0000A6ED8 /* URL-Extensions.swift in Sources */, ); @@ -3044,14 +2955,6 @@ name = ShareViewController.xib; sourceTree = ""; }; - 511D43ED231FBDE800FB1562 /* LaunchScreenPad.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 511D43EE231FBDE800FB1562 /* Base */, - ); - name = LaunchScreenPad.storyboard; - sourceTree = ""; - }; 51314707235C41FC00387FDC /* Intents.intentdefinition */ = { isa = PBXVariantGroup; children = ( @@ -3117,22 +3020,6 @@ name = Preferences.storyboard; sourceTree = ""; }; - 84C9FC9F2262A1B300D921D6 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 84C9FCA02262A1B300D921D6 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 84C9FCA22262A1B800D921D6 /* LaunchScreenPhone.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 84C9FCA32262A1B800D921D6 /* Base */, - ); - name = LaunchScreenPhone.storyboard; - sourceTree = ""; - }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ diff --git a/iOS/NavigationStateController.swift b/iOS/NavigationStateController.swift deleted file mode 100644 index 954d4c2f5..000000000 --- a/iOS/NavigationStateController.swift +++ /dev/null @@ -1,647 +0,0 @@ -// -// NavigationModelController.swift -// NetNewsWire-iOS -// -// Created by Maurice Parker on 4/21/19. -// Copyright © 2019 Ranchero Software. All rights reserved. -// - -import Foundation -import Account -import Articles -import RSCore -import RSTree - -public extension Notification.Name { - static let MasterSelectionDidChange = Notification.Name(rawValue: "MasterSelectionDidChange") - static let BackingStoresDidRebuild = Notification.Name(rawValue: "BackingStoresDidRebuild") - static let ArticlesReinitialized = Notification.Name(rawValue: "ArticlesReinitialized") - static let ArticleDataDidChange = Notification.Name(rawValue: "ArticleDataDidChange") - static let ArticlesDidChange = Notification.Name(rawValue: "ArticlesDidChange") - static let ArticleSelectionDidChange = Notification.Name(rawValue: "ArticleSelectionDidChange") -} - -class NavigationStateController { - - static let fetchAndMergeArticlesQueue = CoalescingQueue(name: "Fetch and Merge Articles", interval: 0.5) - - private var articleRowMap = [String: Int]() // articleID: rowIndex - - private var animatingChanges = false - private var expandedNodes = [Node]() - private var shadowTable = [[Node]]() - - private var sortDirection = AppDefaults.timelineSortDirection { - didSet { - if sortDirection != oldValue { - sortDirectionDidChange() - } - } - } - - private let treeControllerDelegate = FeedTreeControllerDelegate() - lazy var treeController: TreeController = { - return TreeController(delegate: treeControllerDelegate) - }() - - var rootNode: Node { - return treeController.rootNode - } - - var numberOfSections: Int { - return shadowTable.count - } - - var currentMasterIndexPath: IndexPath? { - didSet { - guard let ip = currentMasterIndexPath, let node = nodeFor(ip) else { - assertionFailure() - return - } - if let fetcher = node.representedObject as? ArticleFetcher { - timelineFetcher = fetcher - } - NotificationCenter.default.post(name: .MasterSelectionDidChange, object: self, userInfo: nil) - } - } - - var timelineName: String? { - return (timelineFetcher as? DisplayNameProvider)?.nameForDisplay - } - - var timelineFetcher: ArticleFetcher? { - didSet { - currentArticleIndexPath = nil - if timelineFetcher is Feed { - showFeedNames = false - } else { - showFeedNames = true - } - fetchArticles() - NotificationCenter.default.post(name: .ArticlesReinitialized, object: self, userInfo: nil) - } - } - - - var showFeedNames = false - var showAvatars = false - - var isPrevArticleAvailable: Bool { - guard let indexPath = currentArticleIndexPath else { - return false - } - return indexPath.row > 0 - } - - var isNextArticleAvailable: Bool { - guard let indexPath = currentArticleIndexPath else { - return false - } - return indexPath.row + 1 < articles.count - } - - var prevArticleIndexPath: IndexPath? { - guard let indexPath = currentArticleIndexPath else { - return nil - } - return IndexPath(row: indexPath.row - 1, section: indexPath.section) - } - - var nextArticleIndexPath: IndexPath? { - guard let indexPath = currentArticleIndexPath else { - return nil - } - return IndexPath(row: indexPath.row + 1, section: indexPath.section) - } - - var firstUnreadArticleIndexPath: IndexPath? { - for (row, article) in articles.enumerated() { - if !article.status.read { - return IndexPath(row: row, section: 0) - } - } - return nil - } - - var currentArticle: Article? { - if let indexPath = currentArticleIndexPath { - return articles[indexPath.row] - } - return nil - } - - var currentArticleIndexPath: IndexPath? { - didSet { - if currentArticleIndexPath != oldValue { - NotificationCenter.default.post(name: .ArticleSelectionDidChange, object: self, userInfo: nil) - } - } - } - - var articles = ArticleArray() { - didSet { - if articles == oldValue { - return - } - if articles.representSameArticlesInSameOrder(as: oldValue) { - articleRowMap = [String: Int]() - NotificationCenter.default.post(name: .ArticleDataDidChange, object: self, userInfo: nil) - return - } - updateShowAvatars() - articleRowMap = [String: Int]() - NotificationCenter.default.post(name: .ArticlesDidChange, object: self, userInfo: nil) - } - } - - var isTimelineUnreadAvailable: Bool { - if let unreadProvider = timelineFetcher as? UnreadCountProvider { - return unreadProvider.unreadCount > 0 - } - return false - } - - var isAnyUnreadAvailable: Bool { - return appDelegate.unreadCount > 0 - } - - init() { - - for section in treeController.rootNode.childNodes { - expandedNodes.append(section) - shadowTable.append([Node]()) - } - - rebuildShadowTable() - - NotificationCenter.default.addObserver(self, selector: #selector(containerChildrenDidChange(_:)), name: .ChildrenDidChange, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(batchUpdateDidPerform(_:)), name: .BatchUpdateDidPerform, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange(_:)), name: .DisplayNameDidChange, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(accountStateDidChange(_:)), name: .AccountStateDidChange, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .AccountsDidChange, object: nil) - - NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(accountDidDownloadArticles(_:)), name: .AccountDidDownloadArticles, object: nil) - - } - - // MARK: Notifications - - @objc func containerChildrenDidChange(_ note: Notification) { - rebuildBackingStores() - } - - @objc func batchUpdateDidPerform(_ notification: Notification) { - rebuildBackingStores() - } - - @objc func displayNameDidChange(_ note: Notification) { - rebuildBackingStores() - } - - @objc func accountStateDidChange(_ note: Notification) { - rebuildBackingStores() - } - - @objc func accountsDidChange(_ note: Notification) { - rebuildBackingStores() - } - - @objc func userDefaultsDidChange(_ note: Notification) { - self.sortDirection = AppDefaults.timelineSortDirection - } - - @objc func accountDidDownloadArticles(_ note: Notification) { - - guard let feeds = note.userInfo?[Account.UserInfoKey.feeds] as? Set else { - return - } - - let shouldFetchAndMergeArticles = timelineFetcherContainsAnyFeed(feeds) || timelineFetcherContainsAnyPseudoFeed() - if shouldFetchAndMergeArticles { - queueFetchAndMergeArticles() - } - - } - - // MARK: API - - func beginUpdates() { - animatingChanges = true - } - - func endUpdates() { - animatingChanges = false - } - - func rowsInSection(_ section: Int) -> Int { - return shadowTable[section].count - } - - func rebuildShadowTable() { - - shadowTable = [[Node]]() - - for i in 0.. Bool { - return expandedNodes.contains(node) - } - - func nodeFor(_ indexPath: IndexPath) -> Node? { - guard indexPath.section < shadowTable.count || indexPath.row < shadowTable[indexPath.section].count else { - return nil - } - return shadowTable[indexPath.section][indexPath.row] - } - - func indexPathFor(_ node: Node) -> IndexPath? { - for i in 0.. ()) { - - guard let expandNode = treeController.rootNode.childAtIndex(section) else { - return - } - expandedNodes.append(expandNode) - - animatingChanges = true - - var indexPathsToInsert = [IndexPath]() - var i = 0 - - func addNode(_ node: Node) { - indexPathsToInsert.append(IndexPath(row: i, section: section)) - shadowTable[section].insert(node, at: i) - i = i + 1 - } - - for child in expandNode.childNodes { - addNode(child) - if expandedNodes.contains(child) { - for gChild in child.childNodes { - addNode(gChild) - } - } - } - - completion(indexPathsToInsert) - - animatingChanges = false - - } - - func expand(_ indexPath: IndexPath, completion: ([IndexPath]) -> ()) { - - let expandNode = shadowTable[indexPath.section][indexPath.row] - expandedNodes.append(expandNode) - - animatingChanges = true - - var indexPathsToInsert = [IndexPath]() - for i in 0.. ()) { - - animatingChanges = true - - guard let collapseNode = treeController.rootNode.childAtIndex(section) else { - return - } - - if let removeNode = expandedNodes.firstIndex(of: collapseNode) { - expandedNodes.remove(at: removeNode) - } - - var indexPathsToRemove = [IndexPath]() - for i in 0.. ()) { - - animatingChanges = true - - let collapseNode = shadowTable[indexPath.section][indexPath.row] - if let removeNode = expandedNodes.firstIndex(of: collapseNode) { - expandedNodes.remove(at: removeNode) - } - - var indexPathsToRemove = [IndexPath]() - - for child in collapseNode.childNodes { - if let index = shadowTable[indexPath.section].firstIndex(of: child) { - indexPathsToRemove.append(IndexPath(row: index, section: indexPath.section)) - } - } - - for child in collapseNode.childNodes { - if let index = shadowTable[indexPath.section].firstIndex(of: child) { - shadowTable[indexPath.section].remove(at: index) - } - } - - completion(indexPathsToRemove) - - animatingChanges = false - - } - - func indexesForArticleIDs(_ articleIDs: Set) -> IndexSet { - - var indexes = IndexSet() - - articleIDs.forEach { (articleID) in - guard let oneIndex = row(for: articleID) else { - return - } - if oneIndex != NSNotFound { - indexes.insert(oneIndex) - } - } - - return indexes - } - - func selectNextUnread() { - - // This should never happen, but I don't want to risk throwing us - // into an infinate loop searching for an unread that isn't there. - if appDelegate.unreadCount < 1 { - return - } - - if selectNextUnreadArticleInTimeline() { - return - } - - selectNextUnreadFeedFetcher() - selectNextUnreadArticleInTimeline() - - } - -} - -private extension NavigationStateController { - - func rebuildBackingStores() { - if !animatingChanges && !BatchUpdate.shared.isPerforming { - treeController.rebuild() - rebuildShadowTable() - NotificationCenter.default.post(name: .BackingStoresDidRebuild, object: self, userInfo: nil) - } - } - - func updateShowAvatars() { - - if showFeedNames { - self.showAvatars = true - return - } - - for article in articles { - if let authors = article.authors { - for author in authors { - if author.avatarURL != nil { - self.showAvatars = true - return - } - } - } - } - - self.showAvatars = false - } - - // MARK: Select Next Unread - - @discardableResult - func selectNextUnreadArticleInTimeline() -> Bool { - - let startingRow: Int = { - if let indexPath = currentArticleIndexPath { - return indexPath.row - } else { - return 0 - } - }() - - for i in startingRow..= shadowTable[indexPath.section].count { - if indexPath.section + 1 >= shadowTable.count { - return IndexPath(row: 0, section: 0) - } else { - return IndexPath(row: 0, section: indexPath.section + 1) - } - } else { - return IndexPath(row: indexPath.row + 1, section: indexPath.section) - } - }() - - if selectNextUnreadFeedFetcher(startingWith: nextIndexPath) { - return - } - selectNextUnreadFeedFetcher(startingWith: IndexPath(row: 0, section: 0)) - - } - - @discardableResult - func selectNextUnreadFeedFetcher(startingWith indexPath: IndexPath) -> Bool { - - for i in indexPath.section.. 0 { - currentMasterIndexPath = nextIndexPath - return true - } - - } - - } - - return false - - } - - // MARK: Fetching Articles - - func fetchArticles() { - - guard let timelineFetcher = timelineFetcher else { - articles = ArticleArray() - return - } - - let fetchedArticles = timelineFetcher.fetchArticles() - updateArticles(with: fetchedArticles) - - } - - func emptyTheTimeline() { - if !articles.isEmpty { - articles = [Article]() - } - } - - func sortDirectionDidChange() { - updateArticles(with: Set(articles)) - } - - func updateArticles(with unsortedArticles: Set
) { - let sortedArticles = Array(unsortedArticles).sortedByDate(sortDirection) - if articles != sortedArticles { - articles = sortedArticles - } - } - - func row(for articleID: String) -> Int? { - updateArticleRowMapIfNeeded() - return articleRowMap[articleID] - } - - func updateArticleRowMap() { - var rowMap = [String: Int]() - var index = 0 - articles.forEach { (article) in - rowMap[article.articleID] = index - index += 1 - } - articleRowMap = rowMap - } - - func updateArticleRowMapIfNeeded() { - if articleRowMap.isEmpty { - updateArticleRowMap() - } - } - - func queueFetchAndMergeArticles() { - NavigationStateController.fetchAndMergeArticlesQueue.add(self, #selector(fetchAndMergeArticles)) - } - - @objc func fetchAndMergeArticles() { - - guard let timelineFetcher = timelineFetcher else { - return - } - - var unsortedArticles = timelineFetcher.fetchArticles() - - // Merge articles by articleID. For any unique articleID in current articles, add to unsortedArticles. - let unsortedArticleIDs = unsortedArticles.articleIDs() - for article in articles { - if !unsortedArticleIDs.contains(article.articleID) { - unsortedArticles.insert(article) - } - } - - updateArticles(with: unsortedArticles) - - } - - func timelineFetcherContainsAnyPseudoFeed() -> Bool { - if timelineFetcher is PseudoFeed { - return true - } - return false - } - - func timelineFetcherContainsAnyFeed(_ feeds: Set) -> Bool { - - // Return true if there’s a match or if a folder contains (recursively) one of feeds - - if let feed = timelineFetcher as? Feed { - for oneFeed in feeds { - if feed.feedID == oneFeed.feedID || feed.url == oneFeed.url { - return true - } - } - } else if let folder = timelineFetcher as? Folder { - for oneFeed in feeds { - if folder.hasFeed(with: oneFeed.feedID) || folder.hasFeed(withURL: oneFeed.url) { - return true - } - } - } - - return false - - } - -}