From effec2467438ba66d7347e76b34cd1ce49e6d7ab Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Mon, 21 Oct 2019 11:51:33 -0500
Subject: [PATCH 01/50] Change settings from using SwiftUI to using UIKit
---
NetNewsWire.xcodeproj/project.pbxproj | 100 +-
iOS/SceneCoordinator.swift | 7 +-
iOS/Settings/AboutViewController.swift | 56 +
.../Account/SettingsAccountLabelView.swift | 34 -
.../Account/SettingsAddAccountView.swift | 52 -
.../Account/SettingsDetailAccountView.swift | 137 ---
.../Account/SettingsFeedbinAccountView.swift | 161 ---
.../Account/SettingsLocalAccountView.swift | 59 -
.../SettingsReaderAPIAccountView.swift | 178 ---
iOS/Settings/AddAccountViewController.swift | 49 +
.../AddLocalAccountViewController.swift | 48 +
.../DetailAccountViewController.swift | 135 +++
.../FeedbinAccountViewController.swift | 137 +++
.../RefreshIntervalViewController.swift | 111 ++
iOS/Settings/Settings.storyboard | 1003 +++++++++++++++++
iOS/Settings/SettingsAboutView.swift | 67 --
.../SettingsRefreshSelectionView.swift | 35 -
...SubscriptionsExportAccountPickerView.swift | 34 -
...ubscriptionsExportDocumentPickerView.swift | 31 -
...SubscriptionsImportAccountPickerView.swift | 34 -
...ubscriptionsImportDocumentPickerView.swift | 43 -
iOS/Settings/SettingsTableViewCell.xib | 24 +
iOS/Settings/SettingsView.swift | 270 -----
iOS/Settings/SettingsViewController.swift | 266 +++++
.../TimelineNumberOfLinesViewController.swift | 41 +
.../UIStoryboard-Extensions.swift | 2 +
26 files changed, 1916 insertions(+), 1198 deletions(-)
create mode 100644 iOS/Settings/AboutViewController.swift
delete mode 100644 iOS/Settings/Account/SettingsAccountLabelView.swift
delete mode 100644 iOS/Settings/Account/SettingsAddAccountView.swift
delete mode 100644 iOS/Settings/Account/SettingsDetailAccountView.swift
delete mode 100644 iOS/Settings/Account/SettingsFeedbinAccountView.swift
delete mode 100644 iOS/Settings/Account/SettingsLocalAccountView.swift
delete mode 100644 iOS/Settings/Account/SettingsReaderAPIAccountView.swift
create mode 100644 iOS/Settings/AddAccountViewController.swift
create mode 100644 iOS/Settings/AddLocalAccountViewController.swift
create mode 100644 iOS/Settings/DetailAccountViewController.swift
create mode 100644 iOS/Settings/FeedbinAccountViewController.swift
create mode 100644 iOS/Settings/RefreshIntervalViewController.swift
create mode 100644 iOS/Settings/Settings.storyboard
delete mode 100644 iOS/Settings/SettingsAboutView.swift
delete mode 100644 iOS/Settings/SettingsRefreshSelectionView.swift
delete mode 100644 iOS/Settings/SettingsSubscriptionsExportAccountPickerView.swift
delete mode 100644 iOS/Settings/SettingsSubscriptionsExportDocumentPickerView.swift
delete mode 100644 iOS/Settings/SettingsSubscriptionsImportAccountPickerView.swift
delete mode 100644 iOS/Settings/SettingsSubscriptionsImportDocumentPickerView.swift
create mode 100644 iOS/Settings/SettingsTableViewCell.xib
delete mode 100644 iOS/Settings/SettingsView.swift
create mode 100644 iOS/Settings/SettingsViewController.swift
create mode 100644 iOS/Settings/TimelineNumberOfLinesViewController.swift
diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj
index cfb318ad1..dcaaca48f 100644
--- a/NetNewsWire.xcodeproj/project.pbxproj
+++ b/NetNewsWire.xcodeproj/project.pbxproj
@@ -9,7 +9,6 @@
/* Begin PBXBuildFile section */
49F40DF82335B71000552BF4 /* newsfoot.js in Resources */ = {isa = PBXBuildFile; fileRef = 49F40DEF2335B71000552BF4 /* newsfoot.js */; };
49F40DF92335B71000552BF4 /* newsfoot.js in Resources */ = {isa = PBXBuildFile; fileRef = 49F40DEF2335B71000552BF4 /* newsfoot.js */; };
- 510BD15D232D765D002692E4 /* SettingsReaderAPIAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 557EE1A522B6F4E1004206FA /* SettingsReaderAPIAccountView.swift */; };
51102165233A7D6C0007A5F7 /* ArticleExtractorButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51102164233A7D6C0007A5F7 /* ArticleExtractorButton.swift */; };
51126DA4225FDE2F00722696 /* RSImage-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51126DA3225FDE2F00722696 /* RSImage-Extensions.swift */; };
5115CAF42266301400B21BCE /* AddContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51121B5A22661FEF00BC0EC1 /* AddContainerViewController.swift */; };
@@ -43,15 +42,11 @@
513146C5235A8FDB00387FDC /* SyncDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C01228B6EB50055115A /* SyncDatabase.framework */; };
51314704235C41FC00387FDC /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 51314707235C41FC00387FDC /* Intents.intentdefinition */; };
51314705235C41FC00387FDC /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 51314707235C41FC00387FDC /* Intents.intentdefinition */; };
- 51314716235C862200387FDC /* SettingsSubscriptionsImportAccountPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51314715235C862200387FDC /* SettingsSubscriptionsImportAccountPickerView.swift */; };
- 51314718235C89ED00387FDC /* SettingsSubscriptionsExportAccountPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51314717235C89ED00387FDC /* SettingsSubscriptionsExportAccountPickerView.swift */; };
51322855232EED360033D4ED /* VibrantSelectAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51322854232EED360033D4ED /* VibrantSelectAction.swift */; };
51322859232FDDB80033D4ED /* VibrantButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51322858232FDDB80033D4ED /* VibrantButtonStyle.swift */; };
- 5132285B232FF2C40033D4ED /* SettingsRefreshSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5132285A232FF2C40033D4ED /* SettingsRefreshSelectionView.swift */; };
513228FB233037630033D4ED /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513228F2233037620033D4ED /* Reachability.swift */; };
513228FC233037630033D4ED /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513228F2233037620033D4ED /* Reachability.swift */; };
513229312330523F0033D4ED /* AttributedStringView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513229302330523F0033D4ED /* AttributedStringView.swift */; };
- 5132293B23305D4C0033D4ED /* SettingsAboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5132293A23305D4C0033D4ED /* SettingsAboutView.swift */; };
513C5CE9232571C2003D4054 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513C5CE8232571C2003D4054 /* ShareViewController.swift */; };
513C5CEC232571C2003D4054 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 513C5CEA232571C2003D4054 /* MainInterface.storyboard */; };
513C5CF0232571C2003D4054 /* NetNewsWire iOS Share Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 513C5CE6232571C2003D4054 /* NetNewsWire iOS Share Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
@@ -81,8 +76,6 @@
5148F4552336DB7000F8CD8B /* MasterTimelineTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5148F4542336DB7000F8CD8B /* MasterTimelineTitleView.swift */; };
514B7C8323205EFB00BAC947 /* RootSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514B7C8223205EFB00BAC947 /* RootSplitViewController.swift */; };
514B7D1F23219F3C00BAC947 /* AddControllerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514B7D1E23219F3C00BAC947 /* AddControllerType.swift */; };
- 5152E0F923248F6200E5C7AD /* SettingsLocalAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510D707D22B02A4B004E8F65 /* SettingsLocalAccountView.swift */; };
- 5152E1022324900D00E5C7AD /* SettingsAddAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510D707322B028E1004E8F65 /* SettingsAddAccountView.swift */; };
5154368B229404D1005E1CDF /* FaviconGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51EF0F76227716200050506E /* FaviconGenerator.swift */; };
51554C24228B71910055115A /* SyncDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C01228B6EB50055115A /* SyncDatabase.framework */; };
51554C25228B71910055115A /* SyncDatabase.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C01228B6EB50055115A /* SyncDatabase.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@@ -112,14 +105,18 @@
51938DF2231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51938DF1231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift */; };
51938DF3231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51938DF1231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift */; };
519B8D332143397200FA689C /* SharingServiceDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519B8D322143397200FA689C /* SharingServiceDelegate.swift */; };
- 519D73FB2323FF35008BB345 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F35D0822AFD4760003CE1B /* SettingsView.swift */; };
519D740623243CC0008BB345 /* RefreshInterval-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519D740523243CC0008BB345 /* RefreshInterval-Extensions.swift */; };
- 519D740723243FE7008BB345 /* SettingsSubscriptionsExportDocumentPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5194B5F122B69FCC00144881 /* SettingsSubscriptionsExportDocumentPickerView.swift */; };
- 519D740823243FEA008BB345 /* SettingsSubscriptionsImportDocumentPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5194B5ED22B6965300144881 /* SettingsSubscriptionsImportDocumentPickerView.swift */; };
519E743D22C663F900A78E47 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519E743422C663F900A78E47 /* SceneDelegate.swift */; };
- 51AF45E123246731001742EF /* SettingsAccountLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510D708122B041CC004E8F65 /* SettingsAccountLabelView.swift */; };
- 51AF460323247321001742EF /* SettingsDetailAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F772EC22B2789B0087D9D1 /* SettingsDetailAccountView.swift */; };
- 51AF460C23247F11001742EF /* SettingsFeedbinAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510D707F22B02A5F004E8F65 /* SettingsFeedbinAccountView.swift */; };
+ 51A16997235E10D700EB091F /* RefreshIntervalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A1698D235E10D600EB091F /* RefreshIntervalViewController.swift */; };
+ 51A16998235E10D700EB091F /* SettingsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 51A1698E235E10D600EB091F /* SettingsTableViewCell.xib */; };
+ 51A16999235E10D700EB091F /* AddLocalAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A1698F235E10D600EB091F /* AddLocalAccountViewController.swift */; };
+ 51A1699A235E10D700EB091F /* Settings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 51A16990235E10D600EB091F /* Settings.storyboard */; };
+ 51A1699B235E10D700EB091F /* DetailAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16991235E10D600EB091F /* DetailAccountViewController.swift */; };
+ 51A1699C235E10D700EB091F /* AddAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16992235E10D600EB091F /* AddAccountViewController.swift */; };
+ 51A1699D235E10D700EB091F /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16993235E10D600EB091F /* SettingsViewController.swift */; };
+ 51A1699E235E10D700EB091F /* TimelineNumberOfLinesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16994235E10D600EB091F /* TimelineNumberOfLinesViewController.swift */; };
+ 51A1699F235E10D700EB091F /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16995235E10D600EB091F /* AboutViewController.swift */; };
+ 51A169A0235E10D700EB091F /* FeedbinAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16996235E10D700EB091F /* FeedbinAccountViewController.swift */; };
51AF460E232488C6001742EF /* Account-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51AF460D232488C6001742EF /* Account-Extensions.swift */; };
51B62E68233186730085F949 /* MasterTimelineAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B62E67233186730085F949 /* MasterTimelineAvatarView.swift */; };
51BB7C272335A8E5008E8144 /* ArticleActivityItemSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BB7C262335A8E5008E8144 /* ArticleActivityItemSource.swift */; };
@@ -730,10 +727,6 @@
/* Begin PBXFileReference section */
49F40DEF2335B71000552BF4 /* newsfoot.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = newsfoot.js; sourceTree = ""; };
- 510D707322B028E1004E8F65 /* SettingsAddAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAddAccountView.swift; sourceTree = ""; };
- 510D707D22B02A4B004E8F65 /* SettingsLocalAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsLocalAccountView.swift; sourceTree = ""; };
- 510D707F22B02A5F004E8F65 /* SettingsFeedbinAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFeedbinAccountView.swift; sourceTree = ""; };
- 510D708122B041CC004E8F65 /* SettingsAccountLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAccountLabelView.swift; sourceTree = ""; };
51102164233A7D6C0007A5F7 /* ArticleExtractorButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleExtractorButton.swift; sourceTree = ""; };
51121AA12265430A00BC0EC1 /* NetNewsWire_iOSapp_target.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = NetNewsWire_iOSapp_target.xcconfig; sourceTree = ""; };
51121B5A22661FEF00BC0EC1 /* AddContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContainerViewController.swift; sourceTree = ""; };
@@ -754,14 +747,10 @@
513146B1235A81A400387FDC /* AddFeedIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddFeedIntentHandler.swift; sourceTree = ""; };
51314706235C41FC00387FDC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/Intents.intentdefinition; sourceTree = ""; };
51314714235C420900387FDC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Intents.strings; sourceTree = ""; };
- 51314715235C862200387FDC /* SettingsSubscriptionsImportAccountPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSubscriptionsImportAccountPickerView.swift; sourceTree = ""; };
- 51314717235C89ED00387FDC /* SettingsSubscriptionsExportAccountPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSubscriptionsExportAccountPickerView.swift; sourceTree = ""; };
51322854232EED360033D4ED /* VibrantSelectAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VibrantSelectAction.swift; sourceTree = ""; };
51322858232FDDB80033D4ED /* VibrantButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VibrantButtonStyle.swift; sourceTree = ""; };
- 5132285A232FF2C40033D4ED /* SettingsRefreshSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRefreshSelectionView.swift; sourceTree = ""; };
513228F2233037620033D4ED /* Reachability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reachability.swift; sourceTree = ""; };
513229302330523F0033D4ED /* AttributedStringView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringView.swift; sourceTree = ""; };
- 5132293A23305D4C0033D4ED /* SettingsAboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAboutView.swift; sourceTree = ""; };
513C5CE6232571C2003D4054 /* NetNewsWire iOS Share Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "NetNewsWire iOS Share Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
513C5CE8232571C2003D4054 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; };
513C5CEB232571C2003D4054 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; };
@@ -803,11 +792,19 @@
51934CC1230F5963006127BE /* ThemedNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemedNavigationController.swift; sourceTree = ""; };
51934CCD2310792F006127BE /* ActivityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityManager.swift; sourceTree = ""; };
51938DF1231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchTimelineFeedDelegate.swift; sourceTree = ""; };
- 5194B5ED22B6965300144881 /* SettingsSubscriptionsImportDocumentPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSubscriptionsImportDocumentPickerView.swift; sourceTree = ""; };
- 5194B5F122B69FCC00144881 /* SettingsSubscriptionsExportDocumentPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSubscriptionsExportDocumentPickerView.swift; sourceTree = ""; };
519B8D322143397200FA689C /* SharingServiceDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingServiceDelegate.swift; sourceTree = ""; };
519D740523243CC0008BB345 /* RefreshInterval-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RefreshInterval-Extensions.swift"; sourceTree = ""; };
519E743422C663F900A78E47 /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
+ 51A1698D235E10D600EB091F /* RefreshIntervalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshIntervalViewController.swift; sourceTree = ""; };
+ 51A1698E235E10D600EB091F /* SettingsTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsTableViewCell.xib; sourceTree = ""; };
+ 51A1698F235E10D600EB091F /* AddLocalAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddLocalAccountViewController.swift; sourceTree = ""; };
+ 51A16990235E10D600EB091F /* Settings.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = ""; };
+ 51A16991235E10D600EB091F /* DetailAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailAccountViewController.swift; sourceTree = ""; };
+ 51A16992235E10D600EB091F /* AddAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddAccountViewController.swift; sourceTree = ""; };
+ 51A16993235E10D600EB091F /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; };
+ 51A16994235E10D600EB091F /* TimelineNumberOfLinesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimelineNumberOfLinesViewController.swift; sourceTree = ""; };
+ 51A16995235E10D600EB091F /* AboutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutViewController.swift; sourceTree = ""; };
+ 51A16996235E10D700EB091F /* FeedbinAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedbinAccountViewController.swift; sourceTree = ""; };
51AF460D232488C6001742EF /* Account-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account-Extensions.swift"; sourceTree = ""; };
51B62E67233186730085F949 /* MasterTimelineAvatarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineAvatarView.swift; sourceTree = ""; };
51BB7C262335A8E5008E8144 /* ArticleActivityItemSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleActivityItemSource.swift; sourceTree = ""; };
@@ -852,8 +849,6 @@
51EF0F8D2279C9260050506E /* AccountsAdd.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountsAdd.xib; sourceTree = ""; };
51EF0F8F2279C9500050506E /* AccountsAddViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsAddViewController.swift; sourceTree = ""; };
51EF0F912279CA620050506E /* AccountsAddTableCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsAddTableCellView.swift; sourceTree = ""; };
- 51F35D0822AFD4760003CE1B /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; };
- 51F772EC22B2789B0087D9D1 /* SettingsDetailAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDetailAccountView.swift; sourceTree = ""; };
51F85BEA22724CB600C787DC /* About.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = About.rtf; sourceTree = ""; };
51F85BEC227251DF00C787DC /* Acknowledgments.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Acknowledgments.rtf; sourceTree = ""; };
51F85BEE2272520B00C787DC /* Thanks.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Thanks.rtf; sourceTree = ""; };
@@ -871,7 +866,6 @@
51FD40BD2341555600880194 /* UIImage-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage-Extensions.swift"; sourceTree = ""; };
51FD413A2342BD0500880194 /* MasterTimelineUnreadCountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineUnreadCountView.swift; sourceTree = ""; };
51FE10022345529D0056195D /* UserNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationManager.swift; sourceTree = ""; };
- 557EE1A522B6F4E1004206FA /* SettingsReaderAPIAccountView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsReaderAPIAccountView.swift; sourceTree = ""; };
55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsReaderAPI.xib; sourceTree = ""; };
55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsReaderAPIWindowController.swift; sourceTree = ""; };
5F323808231DF9F000706F6B /* NNWTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NNWTableViewCell.swift; sourceTree = ""; };
@@ -1265,19 +1259,6 @@
name = Products;
sourceTree = "";
};
- 515E4F06232506240057B0E7 /* Account */ = {
- isa = PBXGroup;
- children = (
- 510D708122B041CC004E8F65 /* SettingsAccountLabelView.swift */,
- 510D707322B028E1004E8F65 /* SettingsAddAccountView.swift */,
- 51F772EC22B2789B0087D9D1 /* SettingsDetailAccountView.swift */,
- 510D707F22B02A5F004E8F65 /* SettingsFeedbinAccountView.swift */,
- 510D707D22B02A4B004E8F65 /* SettingsLocalAccountView.swift */,
- 557EE1A522B6F4E1004206FA /* SettingsReaderAPIAccountView.swift */,
- );
- path = Account;
- sourceTree = "";
- };
5183CCDB226F1EEB0010922C /* Progress */ = {
isa = PBXGroup;
children = (
@@ -1300,14 +1281,16 @@
5183CCEB227117C70010922C /* Settings */ = {
isa = PBXGroup;
children = (
- 51F35D0822AFD4760003CE1B /* SettingsView.swift */,
- 5132293A23305D4C0033D4ED /* SettingsAboutView.swift */,
- 5132285A232FF2C40033D4ED /* SettingsRefreshSelectionView.swift */,
- 51314717235C89ED00387FDC /* SettingsSubscriptionsExportAccountPickerView.swift */,
- 5194B5F122B69FCC00144881 /* SettingsSubscriptionsExportDocumentPickerView.swift */,
- 51314715235C862200387FDC /* SettingsSubscriptionsImportAccountPickerView.swift */,
- 5194B5ED22B6965300144881 /* SettingsSubscriptionsImportDocumentPickerView.swift */,
- 515E4F06232506240057B0E7 /* Account */,
+ 51A16990235E10D600EB091F /* Settings.storyboard */,
+ 51A16995235E10D600EB091F /* AboutViewController.swift */,
+ 51A16992235E10D600EB091F /* AddAccountViewController.swift */,
+ 51A1698F235E10D600EB091F /* AddLocalAccountViewController.swift */,
+ 51A16991235E10D600EB091F /* DetailAccountViewController.swift */,
+ 51A16996235E10D700EB091F /* FeedbinAccountViewController.swift */,
+ 51A1698D235E10D600EB091F /* RefreshIntervalViewController.swift */,
+ 51A1698E235E10D600EB091F /* SettingsTableViewCell.xib */,
+ 51A16993235E10D600EB091F /* SettingsViewController.swift */,
+ 51A16994235E10D600EB091F /* TimelineNumberOfLinesViewController.swift */,
);
path = Settings;
sourceTree = "";
@@ -2648,6 +2631,7 @@
51C452862265093600C03939 /* Add.storyboard in Resources */,
511D43EF231FBDE900FB1562 /* LaunchScreenPad.storyboard in Resources */,
511D43D2231FA62C00FB1562 /* GlobalKeyboardShortcuts.plist in Resources */,
+ 51A16998235E10D700EB091F /* SettingsTableViewCell.xib in Resources */,
84C9FCA12262A1B300D921D6 /* Main.storyboard in Resources */,
51BB7C312335ACDE008E8144 /* page.html in Resources */,
51F85BF32272531500C787DC /* Dedication.rtf in Resources */,
@@ -2660,6 +2644,7 @@
51F85BF12272524100C787DC /* Credits.rtf in Resources */,
84A3EE61223B667F00557320 /* DefaultFeeds.opml in Resources */,
511D43CF231FA62200FB1562 /* DetailKeyboardShortcuts.plist in Resources */,
+ 51A1699A235E10D700EB091F /* Settings.storyboard in Resources */,
49F40DF92335B71000552BF4 /* newsfoot.js in Resources */,
51F85BEF2272520B00C787DC /* Thanks.rtf in Resources */,
84C9FC9D2262A1A900D921D6 /* Assets.xcassets in Resources */,
@@ -2913,7 +2898,6 @@
5183CCDA226E31A50010922C /* NonIntrinsicImageView.swift in Sources */,
51EAED96231363EF00A9EEE3 /* NonIntrinsicButton.swift in Sources */,
51C4527B2265091600C03939 /* MasterUnreadIndicatorView.swift in Sources */,
- 5152E1022324900D00E5C7AD /* SettingsAddAccountView.swift in Sources */,
51F85BF92274AA7B00C787DC /* UIBarButtonItem-Extensions.swift in Sources */,
51B62E68233186730085F949 /* MasterTimelineAvatarView.swift in Sources */,
51C45296226509D300C03939 /* OPMLExporter.swift in Sources */,
@@ -2927,36 +2911,30 @@
51FD413B2342BD0500880194 /* MasterTimelineUnreadCountView.swift in Sources */,
513146B2235A81A400387FDC /* AddFeedIntentHandler.swift in Sources */,
5183CCDD226F1F5C0010922C /* NavigationProgressView.swift in Sources */,
- 51AF45E123246731001742EF /* SettingsAccountLabelView.swift in Sources */,
51D87EE12311D34700E63F03 /* ActivityType.swift in Sources */,
51C452772265091600C03939 /* MultilineUILabelSizer.swift in Sources */,
51C452A522650A2D00C03939 /* SmallIconProvider.swift in Sources */,
51D5948722668EFA00DFC836 /* MarkStatusCommand.swift in Sources */,
51322859232FDDB80033D4ED /* VibrantButtonStyle.swift in Sources */,
+ 51A1699C235E10D700EB091F /* AddAccountViewController.swift in Sources */,
+ 51A16999235E10D700EB091F /* AddLocalAccountViewController.swift in Sources */,
514B7C8323205EFB00BAC947 /* RootSplitViewController.swift in Sources */,
- 5152E0F923248F6200E5C7AD /* SettingsLocalAccountView.swift in Sources */,
51FA73A52332BE110090D516 /* ArticleExtractor.swift in Sources */,
51314704235C41FC00387FDC /* Intents.intentdefinition in Sources */,
FF3ABF162325AF5D0074C542 /* ArticleSorter.swift in Sources */,
- 510BD15D232D765D002692E4 /* SettingsReaderAPIAccountView.swift in Sources */,
51C4525C226508DF00C03939 /* String-Extensions.swift in Sources */,
51C452792265091600C03939 /* MasterTimelineTableViewCell.swift in Sources */,
51FA73AB2332C2FD0090D516 /* ArticleExtractorConfig.swift in Sources */,
- 5132285B232FF2C40033D4ED /* SettingsRefreshSelectionView.swift in Sources */,
51C452852265093600C03939 /* FlattenedAccountFolderPickerData.swift in Sources */,
51C4526B226508F600C03939 /* MasterFeedViewController.swift in Sources */,
5126EE97226CB48A00C22AFC /* SceneCoordinator.swift in Sources */,
51FD40C72341555A00880194 /* UIImage-Extensions.swift in Sources */,
- 5132293B23305D4C0033D4ED /* SettingsAboutView.swift in Sources */,
84CAFCB022BC8C35007694F0 /* FetchRequestOperation.swift in Sources */,
51EF0F77227716200050506E /* FaviconGenerator.swift in Sources */,
51938DF3231AFC660055A1A0 /* SearchTimelineFeedDelegate.swift in Sources */,
51C4525A226508D600C03939 /* UIStoryboard-Extensions.swift in Sources */,
- 519D740823243FEA008BB345 /* SettingsSubscriptionsImportDocumentPickerView.swift in Sources */,
51BB7C272335A8E5008E8144 /* ArticleActivityItemSource.swift in Sources */,
- 51AF460C23247F11001742EF /* SettingsFeedbinAccountView.swift in Sources */,
51F85BF52273625800C787DC /* Bundle-Extensions.swift in Sources */,
- 519D740723243FE7008BB345 /* SettingsSubscriptionsExportDocumentPickerView.swift in Sources */,
51C452A622650A3500C03939 /* Node-Extensions.swift in Sources */,
5183CCDF226F1FCC0010922C /* UINavigationController+Progress.swift in Sources */,
51C45294226509C800C03939 /* SearchFeedDelegate.swift in Sources */,
@@ -2991,22 +2969,24 @@
84CAFCA522BC8C08007694F0 /* FetchRequestQueue.swift in Sources */,
51C4529C22650A1000C03939 /* SingleFaviconDownloader.swift in Sources */,
51E595A6228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */,
+ 51A1699F235E10D700EB091F /* AboutViewController.swift in Sources */,
51C45290226509C100C03939 /* PseudoFeed.swift in Sources */,
51C452A922650DC600C03939 /* ArticleRenderer.swift in Sources */,
- 51AF460323247321001742EF /* SettingsDetailAccountView.swift in Sources */,
5115CAF42266301400B21BCE /* AddContainerViewController.swift in Sources */,
51C45297226509E300C03939 /* DefaultFeedsImporter.swift in Sources */,
512E094D2268B8AB00BDCFDD /* DeleteCommand.swift in Sources */,
51F85BFB2275D85000C787DC /* Array-Extensions.swift in Sources */,
51C452AC22650FD200C03939 /* AppNotifications.swift in Sources */,
51EF0F7E2277A57D0050506E /* MasterTimelineAccessibilityCellLayout.swift in Sources */,
+ 51A1699B235E10D700EB091F /* DetailAccountViewController.swift in Sources */,
51C452762265091600C03939 /* MasterTimelineViewController.swift in Sources */,
- 51314718235C89ED00387FDC /* SettingsSubscriptionsExportAccountPickerView.swift in Sources */,
5183CCE9226F68D90010922C /* AccountRefreshTimer.swift in Sources */,
51C452882265093600C03939 /* AddFeedViewController.swift in Sources */,
+ 51A169A0235E10D700EB091F /* FeedbinAccountViewController.swift in Sources */,
51934CCE2310792F006127BE /* ActivityManager.swift in Sources */,
518651DA235621840078E021 /* ImageTransition.swift in Sources */,
514219372352510100E07E2C /* ImageScrollView.swift in Sources */,
+ 51A16997235E10D700EB091F /* RefreshIntervalViewController.swift in Sources */,
DF999FF722B5AEFA0064B687 /* SafariView.swift in Sources */,
51C4529B22650A1000C03939 /* FaviconDownloader.swift in Sources */,
84DEE56622C32CA4005FC42C /* SmartFeedDelegate.swift in Sources */,
@@ -3025,13 +3005,13 @@
5148F4552336DB7000F8CD8B /* MasterTimelineTitleView.swift in Sources */,
513228FC233037630033D4ED /* Reachability.swift in Sources */,
51C45259226508D300C03939 /* AppDefaults.swift in Sources */,
- 519D73FB2323FF35008BB345 /* SettingsView.swift in Sources */,
511D4419231FC02D00FB1562 /* KeyboardManager.swift in Sources */,
+ 51A1699D235E10D700EB091F /* SettingsViewController.swift in Sources */,
+ 51A1699E235E10D700EB091F /* TimelineNumberOfLinesViewController.swift in Sources */,
51C45293226509C800C03939 /* StarredFeedDelegate.swift in Sources */,
513229312330523F0033D4ED /* AttributedStringView.swift in Sources */,
51D6A5BC23199C85001C27D8 /* MasterTimelineDataSource.swift in Sources */,
51934CCB230F599B006127BE /* ThemedNavigationController.swift in Sources */,
- 51314716235C862200387FDC /* SettingsSubscriptionsImportAccountPickerView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift
index 7d9598c8c..e4ac6208e 100644
--- a/iOS/SceneCoordinator.swift
+++ b/iOS/SceneCoordinator.swift
@@ -786,9 +786,10 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
}
func showSettings() {
- rootSplitViewController.present(style: .formSheet) {
- SettingsView(viewModel: SettingsView.ViewModel()).environment(\.sceneCoordinator, self)
- }
+ let settingsNavController = UIStoryboard.settings.instantiateInitialViewController() as! UINavigationController
+ settingsNavController.modalPresentationStyle = .formSheet
+ settingsNavController.preferredContentSize = SettingsViewController.preferredContentSizeForFormSheetDisplay
+ masterFeedViewController.present(settingsNavController, animated: true)
}
func showFeedInspector() {
diff --git a/iOS/Settings/AboutViewController.swift b/iOS/Settings/AboutViewController.swift
new file mode 100644
index 000000000..31da63e9e
--- /dev/null
+++ b/iOS/Settings/AboutViewController.swift
@@ -0,0 +1,56 @@
+//
+// AboutViewController.swift
+// NetNewsWire-iOS
+//
+// Created by Maurice Parker on 4/25/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import UIKit
+
+class AboutViewController: UITableViewController {
+
+ @IBOutlet weak var aboutTextView: UITextView!
+ @IBOutlet weak var creditsTextView: UITextView!
+ @IBOutlet weak var acknowledgmentsTextView: UITextView!
+ @IBOutlet weak var thanksTextView: UITextView!
+ @IBOutlet weak var dedicationTextView: UITextView!
+
+ override func viewDidLoad() {
+
+ super.viewDidLoad()
+
+ configureCell(file: "About", textView: aboutTextView)
+ configureCell(file: "Credits", textView: creditsTextView)
+ configureCell(file: "Acknowledgments", textView: acknowledgmentsTextView)
+ configureCell(file: "Thanks", textView: thanksTextView)
+ configureCell(file: "Dedication", textView: dedicationTextView)
+
+ let buildLabel = NonIntrinsicLabel(frame: CGRect(x: 20.0, y: 0.0, width: 0.0, height: 0.0))
+ buildLabel.font = UIFont.systemFont(ofSize: 11.0)
+ buildLabel.textColor = UIColor.gray
+ buildLabel.text = NSLocalizedString("Copyright © 2002-2019 Ranchero Software", comment: "Copyright")
+ buildLabel.numberOfLines = 0
+ buildLabel.sizeToFit()
+ buildLabel.translatesAutoresizingMaskIntoConstraints = false
+ tableView.tableFooterView = buildLabel
+
+ }
+
+ override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+ return UITableView.automaticDimension
+ }
+
+}
+
+private extension AboutViewController {
+
+ func configureCell(file: String, textView: UITextView) {
+ let url = Bundle.main.url(forResource: file, withExtension: "rtf")!
+ let string = try! NSAttributedString(url: url, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.rtf], documentAttributes: nil)
+ textView.attributedText = string
+ textView.adjustsFontForContentSizeCategory = true
+ textView.font = .preferredFont(forTextStyle: .body)
+ }
+
+}
diff --git a/iOS/Settings/Account/SettingsAccountLabelView.swift b/iOS/Settings/Account/SettingsAccountLabelView.swift
deleted file mode 100644
index 0d5ead2e3..000000000
--- a/iOS/Settings/Account/SettingsAccountLabelView.swift
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// SettingsAccountLabelView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 6/11/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-
-struct SettingsAccountLabelView : View {
- let accountImage: String
- let accountLabel: String
-
- var body: some View {
- HStack {
- Image(accountImage)
- .resizable()
- .aspectRatio(1, contentMode: .fit)
- .frame(height: 32)
- Text(verbatim: accountLabel).font(.title)
- }
- .foregroundColor(.primary).padding(4.0)
- }
-}
-
-#if DEBUG
-struct SettingsAccountLabelView_Previews : PreviewProvider {
- static var previews: some View {
- SettingsAccountLabelView(accountImage: "accountLocal", accountLabel: "On My Device")
- .previewLayout(.fixed(width: 300, height: 44))
- }
-}
-#endif
diff --git a/iOS/Settings/Account/SettingsAddAccountView.swift b/iOS/Settings/Account/SettingsAddAccountView.swift
deleted file mode 100644
index f26769971..000000000
--- a/iOS/Settings/Account/SettingsAddAccountView.swift
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// SettingsAddAccountView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 6/11/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-import Account
-
-struct SettingsAddAccountView : View {
- @Environment(\.presentationMode) var presentation
- @State private var accountAddAction: Int? = nil
-
- var body: some View {
- Form {
-
- NavigationLink(destination: SettingsLocalAccountView(name: ""), tag: 1, selection: $accountAddAction) {
- SettingsAccountLabelView(accountImage: "accountLocal", accountLabel: Account.defaultLocalAccountName)
- }
- .modifier(VibrantSelectAction(action: {
- self.accountAddAction = 1
- })).padding(.vertical, 16)
-
- NavigationLink(destination: SettingsFeedbinAccountView(viewModel: SettingsFeedbinAccountView.ViewModel()), tag: 2, selection: $accountAddAction) {
- SettingsAccountLabelView(accountImage: "accountFeedbin", accountLabel: "Feedbin")
-
- }
- .modifier(VibrantSelectAction(action: {
- self.accountAddAction = 2
- })).padding(.vertical, 16)
-
-// NavigationLink(destination: SettingsReaderAPIAccountView(viewModel: SettingsReaderAPIAccountView.ViewModel(accountType: .freshRSS)), tag: 3, selection: $accountAddAction) {
-// SettingsAccountLabelView(accountImage: "accountFreshRSS", accountLabel: "Fresh RSS")
-// }
-// .modifier(VibrantSelectAction(action: {
-// self.accountAddAction = 3
-// }))
-
- }
- .navigationBarTitle(Text("Add Account"), displayMode: .inline)
- }
-}
-
-#if DEBUG
-struct AddAccountView_Previews : PreviewProvider {
- static var previews: some View {
- SettingsAddAccountView()
- }
-}
-#endif
diff --git a/iOS/Settings/Account/SettingsDetailAccountView.swift b/iOS/Settings/Account/SettingsDetailAccountView.swift
deleted file mode 100644
index f67b29833..000000000
--- a/iOS/Settings/Account/SettingsDetailAccountView.swift
+++ /dev/null
@@ -1,137 +0,0 @@
-//
-// SettingsDetailAccountView.swift
-// NetNewsWire
-//
-// Created by Maurice Parker on 6/13/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-import Combine
-import Account
-import RSWeb
-
-struct SettingsDetailAccountView : View {
- @Environment(\.presentationMode) var presentation
- @ObservedObject var viewModel: ViewModel
- @State private var credentialsAction: Int? = nil
- @State private var isDeleteAlertPresented = false
-
- var body: some View {
- Form {
- Section {
- HStack {
- TextField("Name", text: $viewModel.name)
- }
- Toggle(isOn: $viewModel.isActive) {
- Text("Active")
- }
- }
- if viewModel.isCreditialsAvailable {
- if viewModel.account.type == .feedbin {
- NavigationLink(destination: self.settingsFeedbinAccountView, tag: 1, selection: $credentialsAction) {
- Text("Credentials")
- }
- .modifier(VibrantSelectAction(action: {
- self.credentialsAction = 1
- }))
- }
- if viewModel.account.type == .freshRSS {
- NavigationLink(destination: self.settingsReaderAPIAccountView, tag: 1, selection: $credentialsAction) {
- Text("Credentials")
- }
- .modifier(VibrantSelectAction(action: {
- self.credentialsAction = 1
- }))
- }
- }
- if viewModel.isDeletable {
- Section {
- Button(action: {
- self.isDeleteAlertPresented.toggle()
- }) {
- Text("Delete Account").foregroundColor(.red)
- }
- .alert(isPresented: $isDeleteAlertPresented) {
- Alert(title: Text("Are you sure you want to delete \"\(viewModel.nameForDisplay)\"?"),
- primaryButton: Alert.Button.default(Text("Delete"), action: {
- self.viewModel.delete()
- self.presentation.wrappedValue.dismiss()
- }),
- secondaryButton: Alert.Button.cancel())
- }
- }
- }
- }
- .buttonStyle(VibrantButtonStyle(alignment: .center))
- .navigationBarTitle(Text(verbatim: viewModel.nameForDisplay), displayMode: .inline)
-
- }
-
- var settingsFeedbinAccountView: SettingsFeedbinAccountView {
- let feedbinViewModel = SettingsFeedbinAccountView.ViewModel(account: viewModel.account)
- return SettingsFeedbinAccountView(viewModel: feedbinViewModel)
- }
-
- var settingsReaderAPIAccountView: SettingsReaderAPIAccountView {
- let readerAPIModel = SettingsReaderAPIAccountView.ViewModel(account: viewModel.account)
- return SettingsReaderAPIAccountView(viewModel: readerAPIModel)
- }
-
- class ViewModel: ObservableObject {
-
- let objectWillChange = ObservableObjectPublisher()
-
- let account: Account
-
- init(_ account: Account) {
- self.account = account
- }
-
- var nameForDisplay: String {
- account.nameForDisplay
- }
-
- var name: String {
- get {
- account.name ?? ""
- }
- set {
- objectWillChange.send()
- account.name = newValue.isEmpty ? nil : newValue
- }
- }
-
- var isActive: Bool {
- get {
- account.isActive
- }
- set {
- objectWillChange.send()
- account.isActive = newValue
- }
- }
-
- var isCreditialsAvailable: Bool {
- return account.type != .onMyMac
- }
-
- var isDeletable: Bool {
- return AccountManager.shared.defaultAccount != account
- }
-
- func delete() {
- AccountManager.shared.deleteAccount(account)
- ActivityManager.cleanUp(account)
- }
- }
-}
-
-#if DEBUG
-struct SettingsDetailAccountView_Previews : PreviewProvider {
- static var previews: some View {
- let viewModel = SettingsDetailAccountView.ViewModel(AccountManager.shared.defaultAccount)
- return SettingsDetailAccountView(viewModel: viewModel)
- }
-}
-#endif
diff --git a/iOS/Settings/Account/SettingsFeedbinAccountView.swift b/iOS/Settings/Account/SettingsFeedbinAccountView.swift
deleted file mode 100644
index a685a8ada..000000000
--- a/iOS/Settings/Account/SettingsFeedbinAccountView.swift
+++ /dev/null
@@ -1,161 +0,0 @@
-//
-// SettingsFeedbinAccountView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 6/11/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-import Combine
-import Account
-import RSWeb
-
-struct SettingsFeedbinAccountView : View {
- @Environment(\.presentationMode) var presentation
- @ObservedObject var viewModel: ViewModel
- @State var busy: Bool = false
- @State var error: String = ""
-
- var body: some View {
- Form {
- Section(header:
- HStack {
- Spacer()
- SettingsAccountLabelView(accountImage: "accountFeedbin", accountLabel: "Feedbin")
- .padding()
- .layoutPriority(1.0)
- Spacer()
- }
- ) {
- TextField("Email", text: $viewModel.email)
- .keyboardType(.emailAddress)
- .textContentType(.emailAddress)
- PasswordField(password: $viewModel.password)
- }
- Section(footer:
- HStack {
- Spacer()
- Text(verbatim: error).foregroundColor(.red)
- Spacer()
- }
- ) {
- Button(action: { self.addAccount() }) {
- if viewModel.isUpdate {
- Text("Update Account")
- } else {
- Text("Add Account")
- }
- }
- .buttonStyle(VibrantButtonStyle(alignment: .center))
- .disabled(!viewModel.isValid)
- }
- }
-// .disabled(busy) // Maybe someday we can do this, but right now it crashes on the iPad
- .navigationBarTitle(Text(""), displayMode: .inline)
- }
-
- private func addAccount() {
-
- busy = true
- error = ""
-
- let emailAddress = viewModel.email.trimmingCharacters(in: .whitespaces)
- let credentials = Credentials(type: .basic, username: emailAddress, secret: viewModel.password)
-
- Account.validateCredentials(type: .feedbin, credentials: credentials) { result in
-
- self.busy = false
-
- switch result {
- case .success(let authenticated):
-
- if (authenticated != nil) {
-
- var newAccount = false
- let workAccount: Account
- if self.viewModel.account == nil {
- workAccount = AccountManager.shared.createAccount(type: .feedbin)
- newAccount = true
- } else {
- workAccount = self.viewModel.account!
- }
-
- do {
-
- do {
- try workAccount.removeCredentials(type: .basic)
- } catch {}
- try workAccount.storeCredentials(credentials)
-
- if newAccount {
- workAccount.refreshAll() { result in }
- }
-
- self.dismiss()
-
- } catch {
- self.error = "Keychain error while storing credentials."
- }
-
- } else {
- self.error = "Invalid email/password combination."
- }
-
- case .failure:
- self.error = "Network error. Try again later."
- }
-
- }
-
- }
-
- private func dismiss() {
- presentation.wrappedValue.dismiss()
- }
-
- class ViewModel: ObservableObject {
-
- let objectWillChange = ObservableObjectPublisher()
- var account: Account? = nil
-
- init() {
- }
-
- init(account: Account) {
- self.account = account
- if let credentials = try? account.retrieveCredentials(type: .basic) {
- self.email = credentials.username
- }
- }
-
- var email: String = "" {
- willSet {
- objectWillChange.send()
- }
- }
-
- var password: String = "" {
- willSet {
- objectWillChange.send()
- }
- }
-
- var isUpdate: Bool {
- return account != nil
- }
-
- var isValid: Bool {
- return !email.isEmpty && !password.isEmpty
- }
- }
-
-}
-
-#if DEBUG
-struct SettingsFeedbinAccountView_Previews : PreviewProvider {
- static var previews: some View {
- SettingsFeedbinAccountView(viewModel: SettingsFeedbinAccountView.ViewModel())
- }
-}
-#endif
diff --git a/iOS/Settings/Account/SettingsLocalAccountView.swift b/iOS/Settings/Account/SettingsLocalAccountView.swift
deleted file mode 100644
index d92cd6f9b..000000000
--- a/iOS/Settings/Account/SettingsLocalAccountView.swift
+++ /dev/null
@@ -1,59 +0,0 @@
-//
-// SettingsLocalAccountView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 6/11/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-import Account
-
-struct SettingsLocalAccountView : View {
- @Environment(\.presentationMode) var presentation
- @State var name: String
-
- var body: some View {
- Form {
- Section(header:
- HStack {
- Spacer()
- SettingsAccountLabelView(accountImage: "accountLocal", accountLabel: Account.defaultLocalAccountName)
- .padding()
- .layoutPriority(1.0)
- Spacer()
- }
- ) {
- HStack {
- TextField("Name", text: $name)
- }
- }
- Section {
- Button(action: { self.addAccount() }) {
- Text("Add Account")
- }
- .buttonStyle(VibrantButtonStyle(alignment: .center))
- }
- }
- .navigationBarTitle(Text(""), displayMode: .inline)
- }
-
- private func addAccount() {
- let account = AccountManager.shared.createAccount(type: .onMyMac)
- account.name = name
- dismiss()
- }
-
- private func dismiss() {
- presentation.wrappedValue.dismiss()
- }
-
-}
-
-#if DEBUG
-struct SettingsLocalAccountView_Previews : PreviewProvider {
- static var previews: some View {
- SettingsLocalAccountView(name: "")
- }
-}
-#endif
diff --git a/iOS/Settings/Account/SettingsReaderAPIAccountView.swift b/iOS/Settings/Account/SettingsReaderAPIAccountView.swift
deleted file mode 100644
index 9e4218e9a..000000000
--- a/iOS/Settings/Account/SettingsReaderAPIAccountView.swift
+++ /dev/null
@@ -1,178 +0,0 @@
-//
-// SettingsReaderAPIAccountView.swift
-// NetNewsWire-iOS
-//
-// Created by Jeremy Beker on 5/28/2019.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-import Combine
-import Account
-import RSWeb
-
-struct SettingsReaderAPIAccountView : View {
- @Environment(\.presentationMode) var presentation
- @ObservedObject var viewModel: ViewModel
-
- @State var busy: Bool = false
- @State var error: String = ""
-
- var body: some View {
- Form {
- Section(header:
- HStack {
- Spacer()
- SettingsAccountLabelView(accountImage: "accountFreshRSS", accountLabel: "FreshRSS")
- .padding()
- .layoutPriority(1.0)
- Spacer()
- }
- ) {
- TextField("Email", text: $viewModel.email)
- .keyboardType(.emailAddress)
- .textContentType(.emailAddress)
- SecureField("Password", text: $viewModel.password)
- TextField("API URL:", text: $viewModel.apiURL).textContentType(.URL)
- }
-
- Section(footer:
- HStack {
- Spacer()
- Text(verbatim: error).foregroundColor(.red)
- Spacer()
- }
- ) {
- Button(action: { self.addAccount() }) {
- if viewModel.isUpdate {
- Text("Update Account")
- } else {
- Text("Add Account")
- }
- }
- .buttonStyle(VibrantButtonStyle(alignment: .center))
- .disabled(!viewModel.isValid)
- }
- }
-// .disabled(busy)
- }
-
- private func addAccount() {
-
- busy = true
- error = ""
-
- let emailAddress = viewModel.email.trimmingCharacters(in: .whitespaces)
- let credentials = Credentials(type: .readerBasic, username: emailAddress, secret: viewModel.password)
- guard let apiURL = URL(string: viewModel.apiURL) else {
- self.error = "Invalid API URL."
- return
- }
-
- Account.validateCredentials(type: viewModel.accountType, credentials: credentials, endpoint: apiURL) { result in
-
- self.busy = false
-
- switch result {
- case .success(let validatedCredentials):
-
- guard let validatedCredentials = validatedCredentials else {
- self.error = "Invalid email/password combination."
- return
- }
-
- var newAccount = false
- let workAccount: Account
- if self.viewModel.account == nil {
- workAccount = AccountManager.shared.createAccount(type: self.viewModel.accountType)
- newAccount = true
- } else {
- workAccount = self.viewModel.account!
- }
-
- do {
-
- do {
- try workAccount.removeCredentials(type: .readerBasic)
- try workAccount.removeCredentials(type: .readerAPIKey)
- } catch {}
-
- workAccount.endpointURL = apiURL
-
- try workAccount.storeCredentials(credentials)
- try workAccount.storeCredentials(validatedCredentials)
-
- if newAccount {
- workAccount.refreshAll() { result in }
- }
-
- self.dismiss()
-
- } catch {
- self.error = "Keychain error while storing credentials."
- }
-
- case .failure:
- self.error = "Network error. Try again later."
- }
-
- }
-
- }
-
- private func dismiss() {
- presentation.wrappedValue.dismiss()
- }
-
- class ViewModel: ObservableObject {
-
- let objectWillChange = ObservableObjectPublisher()
- var accountType: AccountType
- var account: Account? = nil
-
- init(accountType: AccountType) {
- self.accountType = accountType
- }
-
- init(account: Account) {
- self.account = account
- self.accountType = account.type
- if let credentials = try? account.retrieveCredentials(type: .readerBasic) {
- self.email = credentials.username
- self.apiURL = account.endpointURL?.absoluteString ?? ""
- }
- }
-
- var email: String = "" {
- willSet {
- objectWillChange.send()
- }
- }
- var password: String = "" {
- willSet {
- objectWillChange.send()
- }
- }
- var apiURL: String = "" {
- willSet {
- objectWillChange.send()
- }
- }
- var isUpdate: Bool {
- return account != nil
- }
-
- var isValid: Bool {
- return !email.isEmpty && !password.isEmpty
- }
- }
-
-}
-
-#if DEBUG
-struct SettingsReaderAPIAccountView_Previews : PreviewProvider {
- static var previews: some View {
- SettingsReaderAPIAccountView(viewModel: SettingsReaderAPIAccountView.ViewModel(accountType: .freshRSS))
- }
-}
-#endif
diff --git a/iOS/Settings/AddAccountViewController.swift b/iOS/Settings/AddAccountViewController.swift
new file mode 100644
index 000000000..d1587758a
--- /dev/null
+++ b/iOS/Settings/AddAccountViewController.swift
@@ -0,0 +1,49 @@
+//
+// AddAccountViewController.swift
+// NetNewsWire-iOS
+//
+// Created by Maurice Parker on 5/16/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import Account
+import UIKit
+
+protocol AddAccountDismissDelegate: UIViewController {
+ func dismiss()
+}
+
+class AddAccountViewController: UITableViewController, AddAccountDismissDelegate {
+
+ @IBOutlet private weak var localAccountNameLabel: UILabel!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ localAccountNameLabel.text = Account.defaultLocalAccountName
+ }
+
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ switch indexPath.row {
+ case 0:
+ let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "AddLocalAccountNavigationViewController") as! UINavigationController
+ navController.modalPresentationStyle = .currentContext
+ let addViewController = navController.topViewController as! AddLocalAccountViewController
+ addViewController.delegate = self
+ present(navController, animated: true)
+ case 1:
+ let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController
+ navController.modalPresentationStyle = .currentContext
+ let addViewController = navController.topViewController as! FeedbinAccountViewController
+ addViewController.delegate = self
+ present(navController, animated: true)
+ default:
+ break
+ }
+ }
+
+ func dismiss() {
+ navigationController?.popViewController(animated: false)
+ }
+
+}
diff --git a/iOS/Settings/AddLocalAccountViewController.swift b/iOS/Settings/AddLocalAccountViewController.swift
new file mode 100644
index 000000000..c89569eaf
--- /dev/null
+++ b/iOS/Settings/AddLocalAccountViewController.swift
@@ -0,0 +1,48 @@
+//
+// AddLocalAccountViewController.swift
+// NetNewsWire-iOS
+//
+// Created by Maurice Parker on 5/19/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import UIKit
+import Account
+
+class AddLocalAccountViewController: UIViewController {
+
+ @IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
+ @IBOutlet private weak var localAccountNameLabel: UILabel!
+ @IBOutlet weak var nameTextField: UITextField!
+
+ weak var delegate: AddAccountDismissDelegate?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ localAccountNameLabel.text = Account.defaultLocalAccountName
+ nameTextField.delegate = self
+ }
+
+ @IBAction func cancel(_ sender: Any) {
+ dismiss(animated: true, completion: nil)
+ delegate?.dismiss()
+ }
+
+ @IBAction func addAccountTapped(_ sender: Any) {
+ let account = AccountManager.shared.createAccount(type: .onMyMac)
+ account.name = nameTextField.text
+ dismiss(animated: true, completion: nil)
+ delegate?.dismiss()
+ }
+
+}
+
+extension AddLocalAccountViewController: UITextFieldDelegate {
+
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+ textField.resignFirstResponder()
+ return true
+ }
+
+}
diff --git a/iOS/Settings/DetailAccountViewController.swift b/iOS/Settings/DetailAccountViewController.swift
new file mode 100644
index 000000000..6f8c45636
--- /dev/null
+++ b/iOS/Settings/DetailAccountViewController.swift
@@ -0,0 +1,135 @@
+//
+// DetailAccountViewController.swift
+// NetNewsWire-iOS
+//
+// Created by Maurice Parker on 5/17/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import UIKit
+import Account
+
+class DetailAccountViewController: UITableViewController {
+
+ @IBOutlet weak var nameTextField: UITextField!
+ @IBOutlet weak var activeSwitch: UISwitch!
+
+ weak var account: Account?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ guard let account = account else { return }
+
+ nameTextField.placeholder = account.defaultName
+ nameTextField.text = account.name
+ nameTextField.delegate = self
+ activeSwitch.isOn = account.isActive
+ }
+
+ override func viewWillDisappear(_ animated: Bool) {
+ account?.name = nameTextField.text
+ account?.isActive = activeSwitch.isOn
+ }
+
+}
+
+extension DetailAccountViewController {
+
+ override func numberOfSections(in tableView: UITableView) -> Int {
+ guard let account = account else { return 0 }
+
+ if account == AccountManager.shared.defaultAccount {
+ return 1
+ } else if account.type == .onMyMac {
+ return 2
+ } else {
+ return super.numberOfSections(in: tableView)
+ }
+ }
+
+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell: UITableViewCell
+
+ if indexPath.section == 1, let account = account, account.type == .onMyMac {
+ cell = super.tableView(tableView, cellForRowAt: IndexPath(row: 0, section: 2))
+ } else {
+ cell = super.tableView(tableView, cellForRowAt: indexPath)
+ }
+
+ return cell
+ }
+
+ override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
+ if indexPath.section > 0 {
+ return true
+ }
+ return false
+ }
+
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ if let account = account, account.type == .onMyMac {
+ if indexPath.section == 1 {
+ deleteAccount()
+ }
+ } else {
+ switch indexPath.section {
+ case 1:
+ credentials()
+ case 2:
+ deleteAccount()
+ default:
+ break
+ }
+ }
+
+ tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
+ }
+
+}
+
+private extension DetailAccountViewController {
+
+ func credentials() {
+ guard let account = account else { return }
+ switch account.type {
+ case .feedbin:
+ let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController
+ let addViewController = navController.topViewController as! FeedbinAccountViewController
+ addViewController.account = account
+ present(navController, animated: true)
+ default:
+ break
+ }
+ }
+
+ func deleteAccount() {
+ let title = NSLocalizedString("Delete Account", comment: "Delete Account")
+ let message = NSLocalizedString("Are you sure you want to delete this account? This can not be undone.", comment: "Delete Account")
+ let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
+
+ let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
+ let cancelAction = UIAlertAction(title: cancelTitle, style: .cancel)
+ alertController.addAction(cancelAction)
+
+ let markTitle = NSLocalizedString("Delete", comment: "Delete")
+ let markAction = UIAlertAction(title: markTitle, style: .default) { [weak self] (action) in
+ guard let account = self?.account else { return }
+ AccountManager.shared.deleteAccount(account)
+ self?.navigationController?.popViewController(animated: true)
+ }
+ alertController.addAction(markAction)
+
+ present(alertController, animated: true)
+ }
+
+}
+
+extension DetailAccountViewController: UITextFieldDelegate {
+
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+ textField.resignFirstResponder()
+ return true
+ }
+
+}
diff --git a/iOS/Settings/FeedbinAccountViewController.swift b/iOS/Settings/FeedbinAccountViewController.swift
new file mode 100644
index 000000000..6a8ba2129
--- /dev/null
+++ b/iOS/Settings/FeedbinAccountViewController.swift
@@ -0,0 +1,137 @@
+//
+// AddFeedbinAccountViewController.swift
+// NetNewsWire-iOS
+//
+// Created by Maurice Parker on 5/19/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import UIKit
+import Account
+import RSWeb
+
+class FeedbinAccountViewController: UIViewController {
+
+ @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
+ @IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
+ @IBOutlet weak var emailTextField: UITextField!
+ @IBOutlet weak var passwordTextField: UITextField!
+ @IBOutlet weak var actionButton: UIButton!
+
+ @IBOutlet weak var errorMessageLabel: UILabel!
+
+ weak var account: Account?
+ weak var delegate: AddAccountDismissDelegate?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ activityIndicator.isHidden = true
+ emailTextField.delegate = self
+ passwordTextField.delegate = self
+
+ if let account = account, let credentials = try? account.retrieveCredentials(type: .basic) {
+ actionButton.setTitle(NSLocalizedString("Update Credentials", comment: "Update Credentials"), for: .normal)
+ emailTextField.text = credentials.username
+ passwordTextField.text = credentials.secret
+ } else {
+ actionButton.setTitle(NSLocalizedString("Add Account", comment: "Update Credentials"), for: .normal)
+ }
+ }
+
+ @IBAction func cancel(_ sender: Any) {
+ dismiss(animated: true, completion: nil)
+ delegate?.dismiss()
+ }
+
+ @IBAction func action(_ sender: Any) {
+ self.errorMessageLabel.text = nil
+
+ guard emailTextField.text != nil && passwordTextField.text != nil else {
+ self.errorMessageLabel.text = NSLocalizedString("Username & password required.", comment: "Credentials Error")
+ return
+ }
+
+ startAnimatingActivityIndicator()
+ disableNavigation()
+
+ // When you fill in the email address via auto-complete it adds extra whitespace
+ let emailAddress = emailTextField.text?.trimmingCharacters(in: .whitespaces)
+ let credentials = Credentials(type: .basic, username: emailAddress ?? "", secret: passwordTextField.text ?? "")
+ Account.validateCredentials(type: .feedbin, credentials: credentials) { result in
+
+ self.stopAnimtatingActivityIndicator()
+ self.enableNavigation()
+
+ switch result {
+ case .success(let credentials):
+ if let credentials = credentials {
+ var newAccount = false
+ if self.account == nil {
+ self.account = AccountManager.shared.createAccount(type: .feedbin)
+ newAccount = true
+ }
+
+ do {
+
+ do {
+ try self.account?.removeCredentials(type: .basic)
+ } catch {}
+ try self.account?.storeCredentials(credentials)
+
+ if newAccount {
+ self.account?.refreshAll() { result in
+ switch result {
+ case .success:
+ break
+ case .failure(let error):
+ self.presentError(error)
+ }
+ }
+ }
+
+ self.dismiss(animated: true, completion: nil)
+ self.delegate?.dismiss()
+ } catch {
+ self.errorMessageLabel.text = NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error")
+ }
+ } else {
+ self.errorMessageLabel.text = NSLocalizedString("Invalid email/password combination.", comment: "Credentials Error")
+ }
+ case .failure:
+ self.errorMessageLabel.text = NSLocalizedString("Network error. Try again later.", comment: "Credentials Error")
+ }
+
+ }
+ }
+
+ private func enableNavigation() {
+ self.cancelBarButtonItem.isEnabled = true
+ self.actionButton.isEnabled = true
+ }
+
+ private func disableNavigation() {
+ cancelBarButtonItem.isEnabled = false
+ actionButton.isEnabled = false
+ }
+
+ private func startAnimatingActivityIndicator() {
+ activityIndicator.isHidden = false
+ activityIndicator.startAnimating()
+ }
+
+ private func stopAnimtatingActivityIndicator() {
+ self.activityIndicator.isHidden = true
+ self.activityIndicator.stopAnimating()
+ }
+
+}
+
+extension FeedbinAccountViewController: UITextFieldDelegate {
+
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+ textField.resignFirstResponder()
+ return true
+ }
+
+}
diff --git a/iOS/Settings/RefreshIntervalViewController.swift b/iOS/Settings/RefreshIntervalViewController.swift
new file mode 100644
index 000000000..8f3d89ba9
--- /dev/null
+++ b/iOS/Settings/RefreshIntervalViewController.swift
@@ -0,0 +1,111 @@
+//
+// RefreshIntervalViewController.swift
+// NetNewsWire
+//
+// Created by Maurice Parker on 4/25/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import UIKit
+
+class RefreshIntervalViewController: UITableViewController {
+
+ override func numberOfSections(in tableView: UITableView) -> Int {
+ return 1
+ }
+
+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return 7
+ }
+
+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+
+ let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
+
+ cell.textLabel?.adjustsFontForContentSizeCategory = true
+
+ let userRefreshInterval = AppDefaults.refreshInterval
+
+ switch indexPath.row {
+ case 0:
+ cell.textLabel?.text = RefreshInterval.manually.description()
+ if userRefreshInterval == RefreshInterval.manually {
+ cell.accessoryType = .checkmark
+ } else {
+ cell.accessoryType = .none
+ }
+ case 1:
+ cell.textLabel?.text = RefreshInterval.every10Minutes.description()
+ if userRefreshInterval == RefreshInterval.every10Minutes {
+ cell.accessoryType = .checkmark
+ } else {
+ cell.accessoryType = .none
+ }
+ case 2:
+ cell.textLabel?.text = RefreshInterval.every30Minutes.description()
+ if userRefreshInterval == RefreshInterval.every30Minutes {
+ cell.accessoryType = .checkmark
+ } else {
+ cell.accessoryType = .none
+ }
+ case 3:
+ cell.textLabel?.text = RefreshInterval.everyHour.description()
+ if userRefreshInterval == RefreshInterval.everyHour {
+ cell.accessoryType = .checkmark
+ } else {
+ cell.accessoryType = .none
+ }
+ case 4:
+ cell.textLabel?.text = RefreshInterval.every2Hours.description()
+ if userRefreshInterval == RefreshInterval.every2Hours {
+ cell.accessoryType = .checkmark
+ } else {
+ cell.accessoryType = .none
+ }
+ case 5:
+ cell.textLabel?.text = RefreshInterval.every4Hours.description()
+ if userRefreshInterval == RefreshInterval.every4Hours {
+ cell.accessoryType = .checkmark
+ } else {
+ cell.accessoryType = .none
+ }
+ default:
+ cell.textLabel?.text = RefreshInterval.every8Hours.description()
+ if userRefreshInterval == RefreshInterval.every8Hours {
+ cell.accessoryType = .checkmark
+ } else {
+ cell.accessoryType = .none
+ }
+ }
+
+ return cell
+
+ }
+
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+
+ let refreshInterval: RefreshInterval
+
+ switch indexPath.row {
+ case 0:
+ refreshInterval = RefreshInterval.manually
+ case 1:
+ refreshInterval = RefreshInterval.every10Minutes
+ case 2:
+ refreshInterval = RefreshInterval.every30Minutes
+ case 3:
+ refreshInterval = RefreshInterval.everyHour
+ case 4:
+ refreshInterval = RefreshInterval.every2Hours
+ case 5:
+ refreshInterval = RefreshInterval.every4Hours
+ default:
+ refreshInterval = RefreshInterval.every8Hours
+ }
+
+ AppDefaults.refreshInterval = refreshInterval
+ self.navigationController?.popViewController(animated: true)
+
+ }
+
+}
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
new file mode 100644
index 000000000..3dfa1b16a
--- /dev/null
+++ b/iOS/Settings/Settings.storyboard
@@ -0,0 +1,1003 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/iOS/Settings/SettingsAboutView.swift b/iOS/Settings/SettingsAboutView.swift
deleted file mode 100644
index e76fce4ec..000000000
--- a/iOS/Settings/SettingsAboutView.swift
+++ /dev/null
@@ -1,67 +0,0 @@
-//
-// SettingsAboutView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 9/16/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-import Combine
-
-struct SettingsAboutView: View {
-
- @ObservedObject var viewModel: ViewModel
-
- var body: some View {
- GeometryReader { geometry in
- List {
- Text("NetNewsWire").font(.largeTitle)
- AttributedStringView(string: self.viewModel.about, preferredMaxLayoutWidth: geometry.size.width - 20)
- Section(header: Text("CREDITS")) {
- AttributedStringView(string: self.viewModel.credits, preferredMaxLayoutWidth: geometry.size.width - 20)
- }
- Section(header: Text("ACKNOWLEDGEMENTS")) {
- AttributedStringView(string: self.viewModel.acknowledgements, preferredMaxLayoutWidth: geometry.size.width - 20)
- }
- Section(header: Text("THANKS")) {
- AttributedStringView(string: self.viewModel.thanks, preferredMaxLayoutWidth: geometry.size.width - 20)
- }
- Section(header: Text("DEDICATION"), footer: Text("Copyright © 2002-2019 Ranchero Software").font(.footnote)) {
- AttributedStringView(string: self.viewModel.dedication, preferredMaxLayoutWidth: geometry.size.width - 20)
- }
- }
- }
- }
-
- class ViewModel: ObservableObject {
- let objectWillChange = ObservableObjectPublisher()
-
- var about: NSAttributedString
- var credits: NSAttributedString
- var acknowledgements: NSAttributedString
- var thanks: NSAttributedString
- var dedication: NSAttributedString
-
- init() {
- about = ViewModel.loadResource("About")
- credits = ViewModel.loadResource("Credits")
- acknowledgements = ViewModel.loadResource("Acknowledgments")
- thanks = ViewModel.loadResource("Thanks")
- dedication = ViewModel.loadResource("Dedication")
- }
-
- private static func loadResource(_ resource: String) -> NSAttributedString {
- let url = Bundle.main.url(forResource: resource, withExtension: "rtf")!
- return try! NSAttributedString(url: url, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.rtf], documentAttributes: nil)
-
- }
-
- }
-}
-
-struct SettingsAboutView_Previews: PreviewProvider {
- static var previews: some View {
- SettingsAboutView(viewModel: SettingsAboutView.ViewModel())
- }
-}
diff --git a/iOS/Settings/SettingsRefreshSelectionView.swift b/iOS/Settings/SettingsRefreshSelectionView.swift
deleted file mode 100644
index 22fcce129..000000000
--- a/iOS/Settings/SettingsRefreshSelectionView.swift
+++ /dev/null
@@ -1,35 +0,0 @@
-//
-// SettingsRefreshSelectionView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 9/16/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-
-struct SettingsRefreshSelectionView: View {
-
- @Environment(\.presentationMode) var presentation
- @Binding var selectedInterval: RefreshInterval
-
- var body: some View {
- Form {
- ForEach(RefreshInterval.allCases) { interval in
- Button(action: {
- self.selectedInterval = interval
- self.presentation.wrappedValue.dismiss()
- }) {
- HStack {
- Text(interval.description())
- Spacer()
- if interval == self.selectedInterval {
- Image(systemName: "checkmark")
- }
- }
- }.buttonStyle(VibrantButtonStyle(alignment: .leading))
- }
- }
- }
-
-}
diff --git a/iOS/Settings/SettingsSubscriptionsExportAccountPickerView.swift b/iOS/Settings/SettingsSubscriptionsExportAccountPickerView.swift
deleted file mode 100644
index 33bc3ea40..000000000
--- a/iOS/Settings/SettingsSubscriptionsExportAccountPickerView.swift
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// SettingsSubscriptionsExportAccountPickerView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 10/20/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-import Account
-
-struct SettingsSubscriptionsExportAccountPickerView: View {
-
- @Environment(\.presentationMode) var presentation
- @State private var selectedAccount: Account?
- @State private var isOPMLExportDocPickerPresented: Bool = false
-
- var body: some View {
- Form {
- ForEach(AccountManager.shared.sortedAccounts) { account in
- Button(action: {
- self.selectedAccount = account
- self.isOPMLExportDocPickerPresented = true
- }) {
- Text(verbatim: account.nameForDisplay)
- }.buttonStyle(VibrantButtonStyle(alignment: .leading))
- }
- }.sheet(isPresented: $isOPMLExportDocPickerPresented, onDismiss: { self.presentation.wrappedValue.dismiss() }) {
- SettingsSubscriptionsExportDocumentPickerView(account: self.selectedAccount!)
- }
- .navigationBarTitle(Text("Select Account"), displayMode: .inline)
- }
-
-}
diff --git a/iOS/Settings/SettingsSubscriptionsExportDocumentPickerView.swift b/iOS/Settings/SettingsSubscriptionsExportDocumentPickerView.swift
deleted file mode 100644
index a471c7d27..000000000
--- a/iOS/Settings/SettingsSubscriptionsExportDocumentPickerView.swift
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// SettingsSubscriptionsExportDocumentPickerView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 6/16/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-import Account
-
-struct SettingsSubscriptionsExportDocumentPickerView : UIViewControllerRepresentable {
- var account: Account
-
- func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIDocumentPickerViewController {
-
- 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)
- try? opmlString.write(to: tempFile, atomically: true, encoding: String.Encoding.utf8)
-
- return UIDocumentPickerViewController(url: tempFile, in: .exportToService)
- }
-
- func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext) {
- //
- }
-
-}
diff --git a/iOS/Settings/SettingsSubscriptionsImportAccountPickerView.swift b/iOS/Settings/SettingsSubscriptionsImportAccountPickerView.swift
deleted file mode 100644
index 0ce3fbdc6..000000000
--- a/iOS/Settings/SettingsSubscriptionsImportAccountPickerView.swift
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// SettingsSubscriptionsImportAccountPickerView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 10/20/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-import Account
-
-struct SettingsSubscriptionsImportAccountPickerView: View {
-
- @Environment(\.presentationMode) var presentation
- @State private var selectedAccount: Account?
- @State private var isOPMLImportDocPickerPresented: Bool = false
-
- var body: some View {
- Form {
- ForEach(AccountManager.shared.sortedActiveAccounts) { account in
- Button(action: {
- self.selectedAccount = account
- self.isOPMLImportDocPickerPresented = true
- }) {
- Text(verbatim: account.nameForDisplay)
- }.buttonStyle(VibrantButtonStyle(alignment: .leading))
- }
- }.sheet(isPresented: $isOPMLImportDocPickerPresented, onDismiss: { self.presentation.wrappedValue.dismiss() }) {
- SettingsSubscriptionsImportDocumentPickerView(account: self.selectedAccount!)
- }
- .navigationBarTitle(Text("Select Account"), displayMode: .inline)
- }
-
-}
diff --git a/iOS/Settings/SettingsSubscriptionsImportDocumentPickerView.swift b/iOS/Settings/SettingsSubscriptionsImportDocumentPickerView.swift
deleted file mode 100644
index 4f4043a92..000000000
--- a/iOS/Settings/SettingsSubscriptionsImportDocumentPickerView.swift
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// SettingsSubscriptionsImportDocumentPickerView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 6/16/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-import Account
-
-struct SettingsSubscriptionsImportDocumentPickerView : UIViewControllerRepresentable {
- var account: Account
-
- func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIDocumentPickerViewController {
- let docPicker = UIDocumentPickerViewController(documentTypes: ["public.xml", "org.opml.opml"], in: .import)
- docPicker.delegate = context.coordinator
- return docPicker
- }
-
- func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext) {
- //
- }
-
- func makeCoordinator() -> Coordinator {
- return Coordinator(self)
- }
-
- class Coordinator : NSObject, UIDocumentPickerDelegate {
- var parent: SettingsSubscriptionsImportDocumentPickerView
-
- init(_ view: SettingsSubscriptionsImportDocumentPickerView) {
- self.parent = view
- }
-
- func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
- for url in urls {
- parent.account.importOPML(url) { result in}
- }
- }
-
- }
-}
diff --git a/iOS/Settings/SettingsTableViewCell.xib b/iOS/Settings/SettingsTableViewCell.xib
new file mode 100644
index 000000000..aca59947e
--- /dev/null
+++ b/iOS/Settings/SettingsTableViewCell.xib
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/iOS/Settings/SettingsView.swift b/iOS/Settings/SettingsView.swift
deleted file mode 100644
index 40b6929f0..000000000
--- a/iOS/Settings/SettingsView.swift
+++ /dev/null
@@ -1,270 +0,0 @@
-//
-// SettingsView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 6/11/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-import Combine
-import Account
-
-struct SettingsView : View {
-
- @ObservedObject var viewModel: ViewModel
-
- @Environment(\.viewController) private var viewController: UIViewController?
- @Environment(\.sceneCoordinator) private var coordinator: SceneCoordinator?
-
- @State private var accountAction: Int? = nil
- @State private var refreshAction: Int? = nil
- @State private var importOPMLAction: Int? = nil
- @State private var exportOPMLAction: Int? = nil
- @State private var aboutAction: Int? = nil
-
- @State private var isWebsitePresented: Bool = false
- @State private var website: String? = nil
-
- @State private var isOPMLImportPresented: Bool = false
- @State private var isOPMLImportDocPickerPresented: Bool = false
- @State private var isOPMLExportPresented: Bool = false
- @State private var isOPMLExportDocPickerPresented: Bool = false
- @State private var opmlAccount: Account? = nil
-
- var body: some View {
- NavigationView {
- Form {
- buildAccountsSection()
- buildTimelineSection()
- buildDatabaseSection()
- buildAboutSection()
- }
- .buttonStyle(VibrantButtonStyle(alignment: .leading))
- .navigationBarTitle(Text("Settings"), displayMode: .inline)
- .navigationBarItems(leading: Button(action: { self.viewController?.dismiss(animated: true) }) { Text("Done") } )
- }
- }
-
- func buildAccountsSection() -> some View {
- Section(header: Text("ACCOUNTS").padding(.top, 22.0)) {
- ForEach(viewModel.accounts.indices, id: \.self) { index in
- NavigationLink(destination: SettingsDetailAccountView(viewModel: SettingsDetailAccountView.ViewModel(self.viewModel.accounts[index])), tag: index, selection: self.$accountAction) {
- Text(verbatim: self.viewModel.accounts[index].nameForDisplay)
- }
- .modifier(VibrantSelectAction(action: {
- self.accountAction = index
- }))
- }
- NavigationLink(destination: SettingsAddAccountView(), tag: 1000, selection: $accountAction) {
- Text("Add Account")
- }
- .modifier(VibrantSelectAction(action: {
- self.accountAction = 1000
- }))
- }
- }
-
- func buildTimelineSection() -> some View {
- Section(header: Text("TIMELINE")) {
- Toggle(isOn: $viewModel.sortOldestToNewest) {
- Text("Sort Newest to Oldest")
- }
- Toggle(isOn: $viewModel.groupByFeed) {
- Text("Group By Feed")
- }
- Stepper(value: $viewModel.timelineNumberOfLines, in: 2...6) {
- Text("Number of Text Lines: \(viewModel.timelineNumberOfLines)")
- }
- }
- }
-
- func buildDatabaseSection() -> some View {
- Section(header: Text("DATABASE")) {
-
- NavigationLink(destination: SettingsRefreshSelectionView(selectedInterval: $viewModel.refreshInterval), tag: 1, selection: $refreshAction) {
- HStack {
- Text("Refresh Interval")
- Spacer()
- Text(verbatim: self.viewModel.refreshInterval.description()).foregroundColor(.secondary)
- }
- }
- .modifier(VibrantSelectAction(action: {
- self.refreshAction = 1
- }))
-
- NavigationLink(destination: SettingsSubscriptionsImportAccountPickerView(), tag: 1, selection: $importOPMLAction) {
- Text("Import Subscriptions")
- }
- .modifier(VibrantSelectAction(action: {
- self.importOPMLAction = 1
- }))
-
- NavigationLink(destination: SettingsSubscriptionsExportAccountPickerView(), tag: 1, selection: $exportOPMLAction) {
- Text("Export Subscriptions")
- }
- .modifier(VibrantSelectAction(action: {
- self.exportOPMLAction = 1
- }))
-
- }
- }
-
- func buildAboutSection() -> some View {
- Section(header: Text("ABOUT"), footer: buildFooter()) {
-
- NavigationLink(destination: SettingsAboutView(viewModel: SettingsAboutView.ViewModel()), tag: 1, selection: $aboutAction) {
- Text("About NetNewsWire")
- }
- .modifier(VibrantSelectAction(action: {
- self.aboutAction = 1
- }))
-
- Button(action: {
- self.isWebsitePresented.toggle()
- self.website = "https://ranchero.com/netnewswire/"
- }) {
- Text("Website")
- }
-
- Button(action: {
- self.isWebsitePresented.toggle()
- self.website = "https://github.com/brentsimmons/NetNewsWire"
- }) {
- Text("Github Repository")
- }
-
- Button(action: {
- self.isWebsitePresented.toggle()
- self.website = "https://github.com/brentsimmons/NetNewsWire/issues"
- }) {
- Text("Bug Tracker")
- }
-
- Button(action: {
- self.isWebsitePresented.toggle()
- self.website = "https://github.com/brentsimmons/NetNewsWire/tree/master/Technotes"
- }) {
- Text("Technotes")
- }
-
- Button(action: {
- self.isWebsitePresented.toggle()
- self.website = "https://github.com/brentsimmons/NetNewsWire/blob/master/Technotes/HowToSupportNetNewsWire.markdown"
- }) {
- Text("How To Support NetNewsWire")
- }
-
- if !AccountManager.shared.anyAccountHasFeedWithURL("https://nnw.ranchero.com/feed.json") {
- Button(action: {
- self.viewController?.dismiss(animated: true) {
- let feedName = NSLocalizedString("NetNewsWire News", comment: "NetNewsWire News")
- self.coordinator?.showAdd(.feed, initialFeed: "https://nnw.ranchero.com/feed.json", initialFeedName: feedName)
- }
- }) {
- Text("Add NetNewsWire News Feed")
- }
- }
-
- }.sheet(isPresented: $isWebsitePresented) {
- SafariView(url: URL(string: self.website!)!)
- }
- }
-
- func buildFooter() -> some View {
- return Text(verbatim: "\(Bundle.main.appName) v \(Bundle.main.versionNumber) (Build \(Bundle.main.buildNumber))")
- .font(.footnote)
- .foregroundColor(.secondary)
- }
-
- // MARK: ViewModel
-
- class ViewModel: ObservableObject {
-
- let objectWillChange = ObservableObjectPublisher()
-
- init() {
- NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .UserDidAddAccount, object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .UserDidDeleteAccount, object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange(_:)), name: .DisplayNameDidChange, object: nil)
- }
-
- var accounts: [Account] {
- get {
- return AccountManager.shared.sortedAccounts
- }
- set {
- }
- }
-
- var activeAccounts: [Account] {
- get {
- return AccountManager.shared.sortedActiveAccounts
- }
- set {
- }
- }
-
- var sortOldestToNewest: Bool {
- get {
- return AppDefaults.timelineSortDirection == .orderedDescending
- }
- set {
- objectWillChange.send()
- if newValue == true {
- AppDefaults.timelineSortDirection = .orderedDescending
- } else {
- AppDefaults.timelineSortDirection = .orderedAscending
- }
- }
- }
-
- var groupByFeed: Bool {
- get {
- return AppDefaults.timelineGroupByFeed
- }
- set {
- objectWillChange.send()
- AppDefaults.timelineGroupByFeed = newValue
- }
- }
-
- var timelineNumberOfLines: Int {
- get {
- return AppDefaults.timelineNumberOfLines
- }
- set {
- objectWillChange.send()
- AppDefaults.timelineNumberOfLines = newValue
- }
- }
-
- var refreshInterval: RefreshInterval {
- get {
- return AppDefaults.refreshInterval
- }
- set {
- objectWillChange.send()
- AppDefaults.refreshInterval = newValue
- }
- }
-
- @objc func accountsDidChange(_ notification: Notification) {
- objectWillChange.send()
- }
-
- @objc func displayNameDidChange(_ notification: Notification) {
- objectWillChange.send()
- }
-
- }
-
-}
-
-#if DEBUG
-struct SettingsView_Previews : PreviewProvider {
- static var previews: some View {
- SettingsView(viewModel: SettingsView.ViewModel())
- }
-}
-#endif
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
new file mode 100644
index 000000000..84a177d27
--- /dev/null
+++ b/iOS/Settings/SettingsViewController.swift
@@ -0,0 +1,266 @@
+//
+// SettingsViewController.swift
+// NetNewsWire-iOS
+//
+// Created by Maurice Parker on 4/24/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import UIKit
+import Account
+
+class SettingsViewController: UITableViewController {
+
+ static let preferredContentSizeForFormSheetDisplay = CGSize(width: 460.0, height: 400.0)
+
+ @IBOutlet weak var refreshIntervalLabel: UILabel!
+ @IBOutlet weak var timelineSortOrderSwitch: UISwitch!
+ @IBOutlet weak var timelineNumberOfLinesLabel: UILabel!
+
+ weak var presentingParentController: UIViewController?
+
+ override func viewDidLoad() {
+ // This hack mostly works around a bug in static tables with dynamic type. See: https://spin.atomicobject.com/2018/10/15/dynamic-type-static-uitableview/
+ NotificationCenter.default.removeObserver(tableView!, name: UIContentSizeCategory.didChangeNotification, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryDidChange), name: UIContentSizeCategory.didChangeNotification, object: nil)
+
+ tableView.register(UINib(nibName: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
+
+ }
+
+ override func viewWillAppear(_ animated: Bool) {
+ super.viewWillAppear(animated)
+
+ if AppDefaults.timelineSortDirection == .orderedAscending {
+ timelineSortOrderSwitch.isOn = true
+ } else {
+ timelineSortOrderSwitch.isOn = false
+ }
+
+ refreshIntervalLabel.text = AppDefaults.refreshInterval.description()
+
+ let numberOfLinesText = NSLocalizedString(" lines", comment: "Lines")
+ timelineNumberOfLinesLabel.text = "\(AppDefaults.timelineNumberOfLines)" + numberOfLinesText
+
+ let buildLabel = NonIntrinsicLabel(frame: CGRect(x: 20.0, y: 0.0, width: 0.0, height: 0.0))
+ buildLabel.font = UIFont.systemFont(ofSize: 11.0)
+ buildLabel.textColor = UIColor.gray
+ buildLabel.text = "\(Bundle.main.appName) v \(Bundle.main.versionNumber) (Build \(Bundle.main.buildNumber))"
+ buildLabel.sizeToFit()
+ buildLabel.translatesAutoresizingMaskIntoConstraints = false
+ tableView.tableFooterView = buildLabel
+
+ tableView.reloadData()
+
+ }
+
+ // MARK: UITableView
+
+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ switch section {
+ case 0:
+ return AccountManager.shared.accounts.count + 1
+ case 1:
+ let defaultNumberOfRows = super.tableView(tableView, numberOfRowsInSection: section)
+ if AccountManager.shared.activeAccounts.isEmpty {
+ // Hide the add NetNewsWire feed row if they don't have any active accounts
+ return defaultNumberOfRows - 1
+ }
+ return defaultNumberOfRows
+ default:
+ return super.tableView(tableView, numberOfRowsInSection: section)
+ }
+ }
+
+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell: UITableViewCell
+ switch indexPath.section {
+ case 0:
+
+ cell = tableView.dequeueReusableCell(withIdentifier: "SettingsTableViewCell", for: indexPath)
+ cell.textLabel?.adjustsFontForContentSizeCategory = true
+
+ let sortedAccounts = AccountManager.shared.sortedAccounts
+ if indexPath.row == sortedAccounts.count {
+ cell.textLabel?.text = NSLocalizedString("Add Account", comment: "Accounts")
+ } else {
+ cell.textLabel?.text = sortedAccounts[indexPath.row].nameForDisplay
+ }
+
+ default:
+
+ cell = super.tableView(tableView, cellForRowAt: indexPath)
+
+ }
+
+ return cell
+ }
+
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ switch indexPath.section {
+ case 0:
+ let sortedAccounts = AccountManager.shared.sortedAccounts
+ if indexPath.row == sortedAccounts.count {
+ let controller = UIStoryboard.settings.instantiateController(ofType: AddAccountViewController.self)
+ self.navigationController?.pushViewController(controller, animated: true)
+ } else {
+ let controller = UIStoryboard.settings.instantiateController(ofType: DetailAccountViewController.self)
+ controller.account = sortedAccounts[indexPath.row]
+ self.navigationController?.pushViewController(controller, animated: true)
+ }
+ case 1:
+ switch indexPath.row {
+ case 0:
+ let timeline = UIStoryboard.settings.instantiateController(ofType: AboutViewController.self)
+ self.navigationController?.pushViewController(timeline, animated: true)
+ case 1:
+ UIApplication.shared.open(URL(string: "https://ranchero.com/netnewswire/")!, options: [:])
+ case 2:
+ UIApplication.shared.open(URL(string: "https://github.com/brentsimmons/NetNewsWire")!, options: [:])
+ case 3:
+ UIApplication.shared.open(URL(string: "https://github.com/brentsimmons/NetNewsWire/issues")!, options: [:])
+ case 4:
+ UIApplication.shared.open(URL(string: "https://github.com/brentsimmons/NetNewsWire/tree/master/Technotes")!, options: [:])
+ case 5:
+ addFeed()
+ default:
+ UIApplication.shared.open(URL(string: "https://ranchero.com/netnewswire/")!, options: [:])
+ }
+ case 2:
+ if indexPath.row == 1 {
+ let timeline = UIStoryboard.settings.instantiateController(ofType: TimelineNumberOfLinesViewController.self)
+ self.navigationController?.pushViewController(timeline, animated: true)
+ }
+ case 3:
+ switch indexPath.row {
+ case 0:
+ let timeline = UIStoryboard.settings.instantiateController(ofType: RefreshIntervalViewController.self)
+ self.navigationController?.pushViewController(timeline, animated: true)
+ case 1:
+ importOPML()
+ case 2:
+ exportOPML()
+ default:
+ print("export")
+ }
+ default:
+ break
+ }
+
+ tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
+ }
+
+ override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
+ return false
+ }
+
+ override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
+ return false
+ }
+
+ override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
+ return .none
+ }
+
+ override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+ if indexPath.section == 0 {
+ return super.tableView(tableView, heightForRowAt: IndexPath(row: 0, section: 0))
+ } else {
+ return super.tableView(tableView, heightForRowAt: indexPath)
+ }
+ }
+
+ override func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int {
+ if indexPath.section == 0 {
+ return super.tableView(tableView, indentationLevelForRowAt: IndexPath(row: 0, section: 0))
+ } else {
+ return super.tableView(tableView, indentationLevelForRowAt: indexPath)
+ }
+ }
+
+ // MARK: Actions
+
+ @IBAction func done(_ sender: Any) {
+ dismiss(animated: true)
+ }
+
+ @IBAction func switchTimelineOrder(_ sender: Any) {
+ if timelineSortOrderSwitch.isOn {
+ AppDefaults.timelineSortDirection = .orderedAscending
+ } else {
+ AppDefaults.timelineSortDirection = .orderedDescending
+ }
+ }
+
+ @objc func contentSizeCategoryDidChange() {
+ tableView.reloadData()
+ }
+
+}
+
+// MARK: OPML Document Picker
+
+extension SettingsViewController: UIDocumentPickerDelegate {
+
+ func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
+
+ for url in urls {
+ AccountManager.shared.defaultAccount.importOPML(url) { result in}
+ }
+
+ }
+
+}
+
+// MARK: Private
+
+private extension SettingsViewController {
+
+ func addFeed() {
+
+ let appNewsURLString = "https://nnw.ranchero.com/feed.json"
+ if AccountManager.shared.anyAccountHasFeedWithURL(appNewsURLString) {
+ presentError(title: "Subscribe", message: "You are already subscribed to the NetNewsWire news feed.")
+ return
+ }
+
+ self.dismiss(animated: true)
+
+ let addNavViewController = UIStoryboard.add.instantiateInitialViewController() as! UINavigationController
+ let addViewController = addNavViewController.topViewController as! AddContainerViewController
+ addNavViewController.modalPresentationStyle = .formSheet
+ addNavViewController.preferredContentSize = AddContainerViewController.preferredContentSizeForFormSheetDisplay
+ addViewController.initialFeed = appNewsURLString
+ addViewController.initialFeedName = "NetNewsWire News"
+
+ presentingParentController?.present(addNavViewController, animated: true)
+
+ }
+
+ func importOPML() {
+
+ let docPicker = UIDocumentPickerViewController(documentTypes: ["public.xml", "org.opml.opml"], in: .import)
+ docPicker.delegate = self
+ docPicker.modalPresentationStyle = .formSheet
+ self.present(docPicker, animated: true)
+
+ }
+
+ func exportOPML() {
+
+ let filename = "MySubscriptions.opml"
+ let tempFile = FileManager.default.temporaryDirectory.appendingPathComponent(filename)
+ let opmlString = OPMLExporter.OPMLString(with: AccountManager.shared.defaultAccount, title: filename)
+ do {
+ try opmlString.write(to: tempFile, atomically: true, encoding: String.Encoding.utf8)
+ } catch {
+ self.presentError(title: "OPML Export Error", message: error.localizedDescription)
+ }
+
+ let docPicker = UIDocumentPickerViewController(url: tempFile, in: .exportToService)
+ docPicker.modalPresentationStyle = .formSheet
+ self.present(docPicker, animated: true)
+
+ }
+
+}
diff --git a/iOS/Settings/TimelineNumberOfLinesViewController.swift b/iOS/Settings/TimelineNumberOfLinesViewController.swift
new file mode 100644
index 000000000..5c0453b2e
--- /dev/null
+++ b/iOS/Settings/TimelineNumberOfLinesViewController.swift
@@ -0,0 +1,41 @@
+//
+// TimelineNumberOfLinesViewController.swift
+// NetNewsWire-iOS
+//
+// Created by Maurice Parker on 4/29/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import UIKit
+
+class TimelineNumberOfLinesViewController: UITableViewController {
+
+ override func numberOfSections(in tableView: UITableView) -> Int {
+ return 1
+ }
+
+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return 5
+ }
+
+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
+ cell.textLabel?.adjustsFontForContentSizeCategory = true
+ cell.textLabel?.text = "\(2 + indexPath.row)" + NSLocalizedString(" lines", comment: "Lines")
+
+ let numberOfLines = AppDefaults.timelineNumberOfLines
+ if indexPath.row + 2 == numberOfLines {
+ cell.accessoryType = .checkmark
+ } else {
+ cell.accessoryType = .none
+ }
+
+ return cell
+ }
+
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ AppDefaults.timelineNumberOfLines = indexPath.row + 2
+ self.navigationController?.popViewController(animated: true)
+ }
+
+}
diff --git a/iOS/UIKit Extensions/UIStoryboard-Extensions.swift b/iOS/UIKit Extensions/UIStoryboard-Extensions.swift
index f0b67d6ff..4d309a729 100644
--- a/iOS/UIKit Extensions/UIStoryboard-Extensions.swift
+++ b/iOS/UIKit Extensions/UIStoryboard-Extensions.swift
@@ -10,6 +10,8 @@ import UIKit
extension UIStoryboard {
+ static let preferredContentSizeForFormSheetDisplay = CGSize(width: 460.0, height: 400.0)
+
static var main: UIStoryboard {
return UIStoryboard(name: "Main", bundle: nil)
}
From ea267e80dd5151d268658b116e498c8b2f9e1748 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Mon, 21 Oct 2019 13:44:47 -0500
Subject: [PATCH 02/50] Add show hide password button and delete unused SwiftUI
extensions
---
NetNewsWire.xcodeproj/project.pbxproj | 36 ------------
.../FeedbinAccountViewController.swift | 19 ++++--
iOS/Settings/Settings.storyboard | 58 +++++++++++--------
.../AttributedStringView.swift | 45 --------------
iOS/SwiftUI Extensions/PasswordField.swift | 25 --------
iOS/SwiftUI Extensions/SafariView.swift | 52 -----------------
.../ShowHidePasswordView.swift | 51 ----------------
.../ShowHidePasswordView.xib | 46 ---------------
.../VibrantButtonStyle.swift | 25 --------
.../VibrantSelectAction.swift | 40 -------------
10 files changed, 48 insertions(+), 349 deletions(-)
delete mode 100644 iOS/SwiftUI Extensions/AttributedStringView.swift
delete mode 100644 iOS/SwiftUI Extensions/PasswordField.swift
delete mode 100644 iOS/SwiftUI Extensions/SafariView.swift
delete mode 100644 iOS/SwiftUI Extensions/ShowHidePasswordView.swift
delete mode 100644 iOS/SwiftUI Extensions/ShowHidePasswordView.xib
delete mode 100644 iOS/SwiftUI Extensions/VibrantButtonStyle.swift
delete mode 100644 iOS/SwiftUI Extensions/VibrantSelectAction.swift
diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj
index dcaaca48f..a25414c57 100644
--- a/NetNewsWire.xcodeproj/project.pbxproj
+++ b/NetNewsWire.xcodeproj/project.pbxproj
@@ -42,11 +42,8 @@
513146C5235A8FDB00387FDC /* SyncDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C01228B6EB50055115A /* SyncDatabase.framework */; };
51314704235C41FC00387FDC /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 51314707235C41FC00387FDC /* Intents.intentdefinition */; };
51314705235C41FC00387FDC /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 51314707235C41FC00387FDC /* Intents.intentdefinition */; };
- 51322855232EED360033D4ED /* VibrantSelectAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51322854232EED360033D4ED /* VibrantSelectAction.swift */; };
- 51322859232FDDB80033D4ED /* VibrantButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51322858232FDDB80033D4ED /* VibrantButtonStyle.swift */; };
513228FB233037630033D4ED /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513228F2233037620033D4ED /* Reachability.swift */; };
513228FC233037630033D4ED /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513228F2233037620033D4ED /* Reachability.swift */; };
- 513229312330523F0033D4ED /* AttributedStringView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513229302330523F0033D4ED /* AttributedStringView.swift */; };
513C5CE9232571C2003D4054 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513C5CE8232571C2003D4054 /* ShareViewController.swift */; };
513C5CEC232571C2003D4054 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 513C5CEA232571C2003D4054 /* MainInterface.storyboard */; };
513C5CF0232571C2003D4054 /* NetNewsWire iOS Share Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 513C5CE6232571C2003D4054 /* NetNewsWire iOS Share Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
@@ -196,9 +193,6 @@
51D5948722668EFA00DFC836 /* MarkStatusCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84702AA31FA27AC0006B8943 /* MarkStatusCommand.swift */; };
51D6A5BC23199C85001C27D8 /* MasterTimelineDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */; };
51D87EE12311D34700E63F03 /* ActivityType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D87EE02311D34700E63F03 /* ActivityType.swift */; };
- 51E149B3234D82E40004F7A5 /* PasswordField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E149B2234D82E40004F7A5 /* PasswordField.swift */; };
- 51E149C0234D839E0004F7A5 /* ShowHidePasswordView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 51E149BF234D839E0004F7A5 /* ShowHidePasswordView.xib */; };
- 51E149C2234D852F0004F7A5 /* ShowHidePasswordView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E149C1234D852F0004F7A5 /* ShowHidePasswordView.swift */; };
51E3EB33229AB02C00645299 /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E3EB32229AB02C00645299 /* ErrorHandler.swift */; };
51E3EB3D229AB08300645299 /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E3EB3C229AB08300645299 /* ErrorHandler.swift */; };
51E595A5228CC36500FCC42B /* ArticleStatusSyncTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E595A4228CC36500FCC42B /* ArticleStatusSyncTimer.swift */; };
@@ -417,7 +411,6 @@
D5F4EDB720074D6500B9E363 /* Feed+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB620074D6500B9E363 /* Feed+Scriptability.swift */; };
D5F4EDB920074D7C00B9E363 /* Folder+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB820074D7C00B9E363 /* Folder+Scriptability.swift */; };
DD82AB0A231003F6002269DF /* SharingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD82AB09231003F6002269DF /* SharingTests.swift */; };
- DF999FF722B5AEFA0064B687 /* SafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF999FF622B5AEFA0064B687 /* SafariView.swift */; };
FF3ABF13232599810074C542 /* ArticleSorterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF09232599450074C542 /* ArticleSorterTests.swift */; };
FF3ABF1523259DDB0074C542 /* ArticleSorter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF1423259DDB0074C542 /* ArticleSorter.swift */; };
FF3ABF162325AF5D0074C542 /* ArticleSorter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF1423259DDB0074C542 /* ArticleSorter.swift */; };
@@ -747,10 +740,7 @@
513146B1235A81A400387FDC /* AddFeedIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddFeedIntentHandler.swift; sourceTree = ""; };
51314706235C41FC00387FDC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/Intents.intentdefinition; sourceTree = ""; };
51314714235C420900387FDC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Intents.strings; sourceTree = ""; };
- 51322854232EED360033D4ED /* VibrantSelectAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VibrantSelectAction.swift; sourceTree = ""; };
- 51322858232FDDB80033D4ED /* VibrantButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VibrantButtonStyle.swift; sourceTree = ""; };
513228F2233037620033D4ED /* Reachability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reachability.swift; sourceTree = ""; };
- 513229302330523F0033D4ED /* AttributedStringView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringView.swift; sourceTree = ""; };
513C5CE6232571C2003D4054 /* NetNewsWire iOS Share Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "NetNewsWire iOS Share Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
513C5CE8232571C2003D4054 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; };
513C5CEB232571C2003D4054 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; };
@@ -833,9 +823,6 @@
51CC9B3D231720B2000E842F /* MasterFeedDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterFeedDataSource.swift; sourceTree = ""; };
51D6A5BB23199C85001C27D8 /* MasterTimelineDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineDataSource.swift; sourceTree = ""; };
51D87EE02311D34700E63F03 /* ActivityType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityType.swift; sourceTree = ""; };
- 51E149B2234D82E40004F7A5 /* PasswordField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordField.swift; sourceTree = ""; };
- 51E149BF234D839E0004F7A5 /* ShowHidePasswordView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ShowHidePasswordView.xib; sourceTree = ""; };
- 51E149C1234D852F0004F7A5 /* ShowHidePasswordView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowHidePasswordView.swift; 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 = ""; };
51E595A4228CC36500FCC42B /* ArticleStatusSyncTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleStatusSyncTimer.swift; sourceTree = ""; };
@@ -1066,7 +1053,6 @@
D5F4EDB620074D6500B9E363 /* Feed+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Feed+Scriptability.swift"; sourceTree = ""; };
D5F4EDB820074D7C00B9E363 /* Folder+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Folder+Scriptability.swift"; sourceTree = ""; };
DD82AB09231003F6002269DF /* SharingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharingTests.swift; sourceTree = ""; };
- DF999FF622B5AEFA0064B687 /* SafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariView.swift; sourceTree = ""; };
FF3ABF09232599450074C542 /* ArticleSorterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleSorterTests.swift; sourceTree = ""; };
FF3ABF1423259DDB0074C542 /* ArticleSorter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleSorter.swift; sourceTree = ""; };
FFD43E372340F320009E5CA3 /* UndoAvailableAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UndoAvailableAlertController.swift; sourceTree = ""; };
@@ -1315,20 +1301,6 @@
path = Activity;
sourceTree = "";
};
- 5194B5E222B693EC00144881 /* SwiftUI Extensions */ = {
- isa = PBXGroup;
- children = (
- 513229302330523F0033D4ED /* AttributedStringView.swift */,
- DF999FF622B5AEFA0064B687 /* SafariView.swift */,
- 51322858232FDDB80033D4ED /* VibrantButtonStyle.swift */,
- 51322854232EED360033D4ED /* VibrantSelectAction.swift */,
- 51E149B2234D82E40004F7A5 /* PasswordField.swift */,
- 51E149C1234D852F0004F7A5 /* ShowHidePasswordView.swift */,
- 51E149BF234D839E0004F7A5 /* ShowHidePasswordView.xib */,
- );
- path = "SwiftUI Extensions";
- sourceTree = "";
- };
519D740423243C68008BB345 /* Model Extensions */ = {
isa = PBXGroup;
children = (
@@ -2021,7 +1993,6 @@
5183CCDB226F1EEB0010922C /* Progress */,
5183CCEB227117C70010922C /* Settings */,
519D740423243C68008BB345 /* Model Extensions */,
- 5194B5E222B693EC00144881 /* SwiftUI Extensions */,
51C45245226506C800C03939 /* UIKit Extensions */,
513C5CE7232571C2003D4054 /* ShareExtension */,
51314643235A7C2300387FDC /* IntentsExtension */,
@@ -2640,7 +2611,6 @@
51F85BED227251DF00C787DC /* Acknowledgments.rtf in Resources */,
511D43D1231FA62800FB1562 /* SidebarKeyboardShortcuts.plist in Resources */,
51C452AB22650DC600C03939 /* template.html in Resources */,
- 51E149C0234D839E0004F7A5 /* ShowHidePasswordView.xib in Resources */,
51F85BF12272524100C787DC /* Credits.rtf in Resources */,
84A3EE61223B667F00557320 /* DefaultFeeds.opml in Resources */,
511D43CF231FA62200FB1562 /* DetailKeyboardShortcuts.plist in Resources */,
@@ -2891,7 +2861,6 @@
buildActionMask = 2147483647;
files = (
840D617F2029031C009BC708 /* AppDelegate.swift in Sources */,
- 51E149B3234D82E40004F7A5 /* PasswordField.swift in Sources */,
512E08E72268801200BDCFDD /* FeedTreeControllerDelegate.swift in Sources */,
51C452A422650A2D00C03939 /* ArticleUtilities.swift in Sources */,
51EF0F79227716380050506E /* ColorHash.swift in Sources */,
@@ -2915,7 +2884,6 @@
51C452772265091600C03939 /* MultilineUILabelSizer.swift in Sources */,
51C452A522650A2D00C03939 /* SmallIconProvider.swift in Sources */,
51D5948722668EFA00DFC836 /* MarkStatusCommand.swift in Sources */,
- 51322859232FDDB80033D4ED /* VibrantButtonStyle.swift in Sources */,
51A1699C235E10D700EB091F /* AddAccountViewController.swift in Sources */,
51A16999235E10D700EB091F /* AddLocalAccountViewController.swift in Sources */,
514B7C8323205EFB00BAC947 /* RootSplitViewController.swift in Sources */,
@@ -2956,7 +2924,6 @@
51C4529A22650A0400C03939 /* ArticleStyle.swift in Sources */,
51C4527F2265092C00C03939 /* ArticleViewController.swift in Sources */,
51C4526A226508F600C03939 /* MasterFeedTableViewCellLayout.swift in Sources */,
- 51E149C2234D852F0004F7A5 /* ShowHidePasswordView.swift in Sources */,
51C452AE2265104D00C03939 /* ArticleStringFormatter.swift in Sources */,
512E08E62268800D00BDCFDD /* FolderTreeControllerDelegate.swift in Sources */,
51C4529922650A0000C03939 /* ArticleStylesManager.swift in Sources */,
@@ -2987,12 +2954,10 @@
518651DA235621840078E021 /* ImageTransition.swift in Sources */,
514219372352510100E07E2C /* ImageScrollView.swift in Sources */,
51A16997235E10D700EB091F /* RefreshIntervalViewController.swift in Sources */,
- DF999FF722B5AEFA0064B687 /* SafariView.swift in Sources */,
51C4529B22650A1000C03939 /* FaviconDownloader.swift in Sources */,
84DEE56622C32CA4005FC42C /* SmartFeedDelegate.swift in Sources */,
512E09012268907400BDCFDD /* MasterFeedTableViewSectionHeader.swift in Sources */,
519D740623243CC0008BB345 /* RefreshInterval-Extensions.swift in Sources */,
- 51322855232EED360033D4ED /* VibrantSelectAction.swift in Sources */,
51C45268226508F600C03939 /* MasterFeedUnreadCountView.swift in Sources */,
5183CCD0226E1E880010922C /* NonIntrinsicLabel.swift in Sources */,
51C4529F22650A1900C03939 /* AuthorAvatarDownloader.swift in Sources */,
@@ -3009,7 +2974,6 @@
51A1699D235E10D700EB091F /* SettingsViewController.swift in Sources */,
51A1699E235E10D700EB091F /* TimelineNumberOfLinesViewController.swift in Sources */,
51C45293226509C800C03939 /* StarredFeedDelegate.swift in Sources */,
- 513229312330523F0033D4ED /* AttributedStringView.swift in Sources */,
51D6A5BC23199C85001C27D8 /* MasterTimelineDataSource.swift in Sources */,
51934CCB230F599B006127BE /* ThemedNavigationController.swift in Sources */,
);
diff --git a/iOS/Settings/FeedbinAccountViewController.swift b/iOS/Settings/FeedbinAccountViewController.swift
index 6a8ba2129..e7218bfe1 100644
--- a/iOS/Settings/FeedbinAccountViewController.swift
+++ b/iOS/Settings/FeedbinAccountViewController.swift
@@ -1,5 +1,5 @@
//
-// AddFeedbinAccountViewController.swift
+// FeedbinAccountViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 5/19/19.
@@ -16,6 +16,7 @@ class FeedbinAccountViewController: UIViewController {
@IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
+ @IBOutlet weak var showHideButton: UIButton!
@IBOutlet weak var actionButton: UIButton!
@IBOutlet weak var errorMessageLabel: UILabel!
@@ -44,10 +45,20 @@ class FeedbinAccountViewController: UIViewController {
delegate?.dismiss()
}
+ @IBAction func showHidePassword(_ sender: Any) {
+ if passwordTextField.isSecureTextEntry {
+ passwordTextField.isSecureTextEntry = false
+ showHideButton.setTitle("Hide", for: .normal)
+ } else {
+ passwordTextField.isSecureTextEntry = true
+ showHideButton.setTitle("Show", for: .normal)
+ }
+ }
+
@IBAction func action(_ sender: Any) {
self.errorMessageLabel.text = nil
- guard emailTextField.text != nil && passwordTextField.text != nil else {
+ guard let email = emailTextField.text, let password = passwordTextField.text else {
self.errorMessageLabel.text = NSLocalizedString("Username & password required.", comment: "Credentials Error")
return
}
@@ -56,8 +67,8 @@ class FeedbinAccountViewController: UIViewController {
disableNavigation()
// When you fill in the email address via auto-complete it adds extra whitespace
- let emailAddress = emailTextField.text?.trimmingCharacters(in: .whitespaces)
- let credentials = Credentials(type: .basic, username: emailAddress ?? "", secret: passwordTextField.text ?? "")
+ let trimmedEmail = email.trimmingCharacters(in: .whitespaces)
+ let credentials = Credentials(type: .basic, username: trimmedEmail, secret: password)
Account.validateCredentials(type: .feedbin, credentials: credentials) { result in
self.stopAnimtatingActivityIndicator()
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 3dfa1b16a..9b7b19ed1 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -437,7 +437,7 @@
-
+
@@ -457,11 +457,10 @@
+
-
-
@@ -471,7 +470,7 @@
-
+
@@ -492,10 +491,9 @@
-
+
-
@@ -660,14 +658,12 @@
-
-
-
-
-
+
+
-
-
+
+
+
@@ -680,30 +676,41 @@
-
-
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
-
+
-
+
+
@@ -733,12 +740,13 @@
-
+
+
-
+
diff --git a/iOS/SwiftUI Extensions/AttributedStringView.swift b/iOS/SwiftUI Extensions/AttributedStringView.swift
deleted file mode 100644
index 1cfe55719..000000000
--- a/iOS/SwiftUI Extensions/AttributedStringView.swift
+++ /dev/null
@@ -1,45 +0,0 @@
-//
-// AttributedStringView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 9/16/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-
-struct AttributedStringView: UIViewRepresentable {
-
- let string: NSAttributedString
- let preferredMaxLayoutWidth: CGFloat
-
- func makeUIView(context: Context) -> HackedTextView {
- return HackedTextView()
- }
-
- func updateUIView(_ view: HackedTextView, context: Context) {
- view.attributedText = string
-
- view.preferredMaxLayoutWidth = preferredMaxLayoutWidth
- view.isScrollEnabled = false
- view.textContainer.lineBreakMode = .byWordWrapping
-
- view.isUserInteractionEnabled = true
- view.adjustsFontForContentSizeCategory = true
- view.font = .preferredFont(forTextStyle: .body)
- view.textColor = UIColor.label
- view.tintColor = AppAssets.secondaryAccentColor
- view.backgroundColor = UIColor.secondarySystemGroupedBackground
-
- view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
- view.setContentCompressionResistancePriority(.required, for: .vertical)
- }
-
-}
-
-class HackedTextView: UITextView {
- var preferredMaxLayoutWidth = CGFloat.zero
- override var intrinsicContentSize: CGSize {
- return sizeThatFits(CGSize(width: preferredMaxLayoutWidth, height: .infinity))
- }
-}
diff --git a/iOS/SwiftUI Extensions/PasswordField.swift b/iOS/SwiftUI Extensions/PasswordField.swift
deleted file mode 100644
index 8875837ae..000000000
--- a/iOS/SwiftUI Extensions/PasswordField.swift
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// PasswordField.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 10/8/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-
-struct PasswordField: UIViewRepresentable {
-
- let password: Binding
-
- func makeUIView(context: Context) -> ShowHidePasswordView {
- let showHideView = Bundle.main.loadNibNamed("ShowHidePasswordView", owner: Self.self, options: nil)?[0] as! ShowHidePasswordView
- showHideView.passwordTextField.bindingString = password
- return showHideView
- }
-
- func updateUIView(_ showHideView: ShowHidePasswordView, context: Context) {
- showHideView.passwordTextField.bindingString = password
- }
-
-}
diff --git a/iOS/SwiftUI Extensions/SafariView.swift b/iOS/SwiftUI Extensions/SafariView.swift
deleted file mode 100644
index 6b5d78334..000000000
--- a/iOS/SwiftUI Extensions/SafariView.swift
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// SafariView.swift
-// NetNewsWire-iOS
-//
-// Created by Stuart Breckenridge on 16/6/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-import SafariServices
-
-struct SafariView : UIViewControllerRepresentable {
-
- let url: URL
-
- func makeUIViewController(context: UIViewControllerRepresentableContext) -> SFSafariViewController {
- let safari = SFSafariViewController(url: url)
- safari.delegate = context.coordinator
- return safari
- }
-
- func updateUIViewController(_ uiViewController: SFSafariViewController, context: UIViewControllerRepresentableContext) {
- //
- }
-
- func makeCoordinator() -> Coordinator {
- return Coordinator(self)
- }
-
- class Coordinator : NSObject, SFSafariViewControllerDelegate {
- var parent: SafariView
-
- init(_ safariView: SafariView) {
- self.parent = safariView
- }
-
- // MARK: SFSafariViewControllerDelegate
- func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
-
- }
-
- func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL) {
-
- }
-
- func safariViewController(_ controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool) {
-
- }
- }
-}
-
-
diff --git a/iOS/SwiftUI Extensions/ShowHidePasswordView.swift b/iOS/SwiftUI Extensions/ShowHidePasswordView.swift
deleted file mode 100644
index fe6b10d02..000000000
--- a/iOS/SwiftUI Extensions/ShowHidePasswordView.swift
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// ShowHidePasswordView.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 10/8/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import UIKit
-import SwiftUI
-
-class ShowHidePasswordView: UIView {
-
- @IBOutlet weak var passwordTextField: BindingTextField!
- @IBOutlet weak var showHideButton: UIButton!
-
- @IBAction func toggleShowHideButton(_ sender: Any) {
- if passwordTextField.isSecureTextEntry {
- passwordTextField.isSecureTextEntry = false
- showHideButton.setTitle(NSLocalizedString("Hide", comment: "Hide"), for: .normal)
- } else {
- passwordTextField.isSecureTextEntry = true
- showHideButton.setTitle(NSLocalizedString("Show", comment: "Show"), for: .normal)
- }
- }
-
-}
-
-class BindingTextField: UITextField, UITextFieldDelegate {
-
- var bindingString: Binding? = nil
-
- override init(frame: CGRect) {
- super.init(frame: frame)
- delegate = self
- }
-
- required init?(coder: NSCoder) {
- super.init(coder: coder)
- delegate = self
- }
-
- func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
- if let currentValue = textField.text as NSString? {
- let proposedValue = currentValue.replacingCharacters(in: range, with: string)
- bindingString?.wrappedValue = proposedValue
- }
- return true
- }
-
-}
diff --git a/iOS/SwiftUI Extensions/ShowHidePasswordView.xib b/iOS/SwiftUI Extensions/ShowHidePasswordView.xib
deleted file mode 100644
index d68686200..000000000
--- a/iOS/SwiftUI Extensions/ShowHidePasswordView.xib
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/iOS/SwiftUI Extensions/VibrantButtonStyle.swift b/iOS/SwiftUI Extensions/VibrantButtonStyle.swift
deleted file mode 100644
index 61ffd9517..000000000
--- a/iOS/SwiftUI Extensions/VibrantButtonStyle.swift
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// VibrantButtonStyle.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 9/16/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-
-struct VibrantButtonStyle: ButtonStyle {
-
- let alignment: Alignment
-
- func makeBody(configuration: Configuration) -> some View {
- GeometryReader { geometry in
- configuration.label
- .frame(width: geometry.size.width, height: geometry.size.height, alignment: self.alignment)
- }
- .foregroundColor(configuration.isPressed ? Color(AppAssets.tableViewCellHighlightedTextColor) : .primary)
- .listRowBackground(configuration.isPressed ? Color(AppAssets.primaryAccentColor) : Color(.secondarySystemGroupedBackground))
- .background(configuration.isPressed ? Color(AppAssets.primaryAccentColor) : Color(.secondarySystemGroupedBackground))
- }
-
-}
diff --git a/iOS/SwiftUI Extensions/VibrantSelectAction.swift b/iOS/SwiftUI Extensions/VibrantSelectAction.swift
deleted file mode 100644
index 45471d5e1..000000000
--- a/iOS/SwiftUI Extensions/VibrantSelectAction.swift
+++ /dev/null
@@ -1,40 +0,0 @@
-//
-// VibrantSelectAction.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 9/15/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import SwiftUI
-
-struct VibrantSelectAction: ViewModifier {
-
- let action: () -> Void
- @State var isTapped = false
- @GestureState var isLongPressed = false
-
- func body(content: Content) -> some View {
- GeometryReader { geometry in
- content
- .frame(width: geometry.size.width, height: geometry.size.height, alignment: .leading)
- .background(self.isLongPressed || self.isTapped ? Color(AppAssets.primaryAccentColor) : Color(.secondarySystemGroupedBackground))
- }
- .foregroundColor(isLongPressed || isTapped ? Color(AppAssets.tableViewCellHighlightedTextColor) : .primary)
- .listRowBackground(isLongPressed || isTapped ? Color(AppAssets.primaryAccentColor) : nil)
- .gesture(
- LongPressGesture().onEnded( { _ in self.action() })
- .updating($isLongPressed) { value, state, transcation in state = value }
- .simultaneously(with:
- TapGesture().onEnded( {
- self.isTapped = true
- self.action()
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
- self.isTapped = false
- }
- }
- ))
- )
- }
-
-}
From d54ba11c3155d9b0a6b75797733a2f65f8c17fec Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Mon, 21 Oct 2019 13:49:05 -0500
Subject: [PATCH 03/50] Fixed about page text view layout
---
iOS/Settings/Settings.storyboard | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 9b7b19ed1..c927b46ad 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -440,7 +440,7 @@
-
+
@@ -555,7 +555,7 @@
-
+
@@ -874,17 +874,17 @@
-
+
-
+
-
+
@@ -900,16 +900,16 @@
-
+
-
+
-
+
@@ -926,7 +926,7 @@
-
+
@@ -934,8 +934,8 @@
-
-
+
+
@@ -952,7 +952,7 @@
-
+
@@ -961,8 +961,8 @@
-
-
+
+
From 3116c632588f4c554a2f0080e9cb1bf76d200dc2 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Mon, 21 Oct 2019 16:14:00 -0500
Subject: [PATCH 04/50] Move done button to the leading side.
---
iOS/Settings/Settings.storyboard | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index c927b46ad..550a4a54f 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -270,7 +270,7 @@
-
+
From 872054e7d6fb7e58844976904b8ec18dd65f1790 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Mon, 21 Oct 2019 16:18:18 -0500
Subject: [PATCH 05/50] Change to use vibrant cell selection
---
iOS/Settings/Settings.storyboard | 4 ++--
iOS/Settings/SettingsTableViewCell.xib | 13 +++++--------
2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 550a4a54f..a571f849c 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -440,7 +440,7 @@
-
+
@@ -555,7 +555,7 @@
-
+
diff --git a/iOS/Settings/SettingsTableViewCell.xib b/iOS/Settings/SettingsTableViewCell.xib
index aca59947e..18048b1de 100644
--- a/iOS/Settings/SettingsTableViewCell.xib
+++ b/iOS/Settings/SettingsTableViewCell.xib
@@ -1,21 +1,18 @@
-
-
-
-
+
+
-
-
+
-
+
-
+
From c3a8c9a5abbb00ea782fc361a6d7c46ea63a4e3b Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Mon, 21 Oct 2019 16:27:54 -0500
Subject: [PATCH 06/50] Change settings order
---
iOS/Settings/Settings.storyboard | 230 +++++++++++-----------
iOS/Settings/SettingsViewController.swift | 34 ++--
2 files changed, 132 insertions(+), 132 deletions(-)
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index a571f849c..3cafee91b 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -37,116 +37,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
@@ -176,7 +70,7 @@
-
+
@@ -201,10 +95,10 @@
-
+
-
+
@@ -228,7 +122,7 @@
-
+
@@ -245,7 +139,7 @@
-
+
@@ -263,6 +157,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -440,7 +440,7 @@
-
+
@@ -555,7 +555,7 @@
-
+
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index 84a177d27..ebd7d52d9 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -109,6 +109,23 @@ class SettingsViewController: UITableViewController {
self.navigationController?.pushViewController(controller, animated: true)
}
case 1:
+ if indexPath.row == 1 {
+ let timeline = UIStoryboard.settings.instantiateController(ofType: TimelineNumberOfLinesViewController.self)
+ self.navigationController?.pushViewController(timeline, animated: true)
+ }
+ case 2:
+ switch indexPath.row {
+ case 0:
+ let timeline = UIStoryboard.settings.instantiateController(ofType: RefreshIntervalViewController.self)
+ self.navigationController?.pushViewController(timeline, animated: true)
+ case 1:
+ importOPML()
+ case 2:
+ exportOPML()
+ default:
+ print("export")
+ }
+ case 3:
switch indexPath.row {
case 0:
let timeline = UIStoryboard.settings.instantiateController(ofType: AboutViewController.self)
@@ -126,23 +143,6 @@ class SettingsViewController: UITableViewController {
default:
UIApplication.shared.open(URL(string: "https://ranchero.com/netnewswire/")!, options: [:])
}
- case 2:
- if indexPath.row == 1 {
- let timeline = UIStoryboard.settings.instantiateController(ofType: TimelineNumberOfLinesViewController.self)
- self.navigationController?.pushViewController(timeline, animated: true)
- }
- case 3:
- switch indexPath.row {
- case 0:
- let timeline = UIStoryboard.settings.instantiateController(ofType: RefreshIntervalViewController.self)
- self.navigationController?.pushViewController(timeline, animated: true)
- case 1:
- importOPML()
- case 2:
- exportOPML()
- default:
- print("export")
- }
default:
break
}
From 48db3d6d85ddffc1bf753f3ce28ce34208684245 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Mon, 21 Oct 2019 16:42:58 -0500
Subject: [PATCH 07/50] Add group by feed setting
---
iOS/Settings/Settings.storyboard | 55 ++++++++++++++++++-----
iOS/Settings/SettingsViewController.swift | 19 +++++++-
2 files changed, 60 insertions(+), 14 deletions(-)
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 3cafee91b..2c71e6cc9 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -69,9 +69,39 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -98,7 +128,7 @@
-
+
@@ -122,7 +152,7 @@
-
+
@@ -139,7 +169,7 @@
-
+
@@ -160,7 +190,7 @@
-
+
@@ -177,7 +207,7 @@
-
+
@@ -194,7 +224,7 @@
-
+
@@ -211,7 +241,7 @@
-
+
@@ -228,7 +258,7 @@
-
+
@@ -245,7 +275,7 @@
-
+
@@ -277,6 +307,7 @@
+
@@ -440,7 +471,7 @@
-
+
@@ -555,7 +586,7 @@
-
+
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index ebd7d52d9..857251d37 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -15,6 +15,7 @@ class SettingsViewController: UITableViewController {
@IBOutlet weak var refreshIntervalLabel: UILabel!
@IBOutlet weak var timelineSortOrderSwitch: UISwitch!
+ @IBOutlet weak var groupByFeedSwitch: UISwitch!
@IBOutlet weak var timelineNumberOfLinesLabel: UILabel!
weak var presentingParentController: UIViewController?
@@ -37,6 +38,12 @@ class SettingsViewController: UITableViewController {
timelineSortOrderSwitch.isOn = false
}
+ if AppDefaults.timelineGroupByFeed {
+ groupByFeedSwitch.isOn = true
+ } else {
+ groupByFeedSwitch.isOn = false
+ }
+
refreshIntervalLabel.text = AppDefaults.refreshInterval.description()
let numberOfLinesText = NSLocalizedString(" lines", comment: "Lines")
@@ -109,7 +116,7 @@ class SettingsViewController: UITableViewController {
self.navigationController?.pushViewController(controller, animated: true)
}
case 1:
- if indexPath.row == 1 {
+ if indexPath.row == 2 {
let timeline = UIStoryboard.settings.instantiateController(ofType: TimelineNumberOfLinesViewController.self)
self.navigationController?.pushViewController(timeline, animated: true)
}
@@ -123,7 +130,7 @@ class SettingsViewController: UITableViewController {
case 2:
exportOPML()
default:
- print("export")
+ break
}
case 3:
switch indexPath.row {
@@ -192,6 +199,14 @@ class SettingsViewController: UITableViewController {
}
}
+ @IBAction func switchGroupByFeed(_ sender: Any) {
+ if groupByFeedSwitch.isOn {
+ AppDefaults.timelineGroupByFeed = true
+ } else {
+ AppDefaults.timelineGroupByFeed = false
+ }
+ }
+
@objc func contentSizeCategoryDidChange() {
tableView.reloadData()
}
From cbf37d4ee0f0dbd45517bcdd8289636daa51ecd0 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Mon, 21 Oct 2019 17:19:22 -0500
Subject: [PATCH 08/50] Change number of lines setting to use a stepper
---
NetNewsWire.xcodeproj/project.pbxproj | 4 -
iOS/Settings/Settings.storyboard | 78 +++++++------------
iOS/Settings/SettingsViewController.swift | 24 ++++--
.../TimelineNumberOfLinesViewController.swift | 41 ----------
4 files changed, 44 insertions(+), 103 deletions(-)
delete mode 100644 iOS/Settings/TimelineNumberOfLinesViewController.swift
diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj
index a25414c57..ee549188e 100644
--- a/NetNewsWire.xcodeproj/project.pbxproj
+++ b/NetNewsWire.xcodeproj/project.pbxproj
@@ -111,7 +111,6 @@
51A1699B235E10D700EB091F /* DetailAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16991235E10D600EB091F /* DetailAccountViewController.swift */; };
51A1699C235E10D700EB091F /* AddAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16992235E10D600EB091F /* AddAccountViewController.swift */; };
51A1699D235E10D700EB091F /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16993235E10D600EB091F /* SettingsViewController.swift */; };
- 51A1699E235E10D700EB091F /* TimelineNumberOfLinesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16994235E10D600EB091F /* TimelineNumberOfLinesViewController.swift */; };
51A1699F235E10D700EB091F /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16995235E10D600EB091F /* AboutViewController.swift */; };
51A169A0235E10D700EB091F /* FeedbinAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16996235E10D700EB091F /* FeedbinAccountViewController.swift */; };
51AF460E232488C6001742EF /* Account-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51AF460D232488C6001742EF /* Account-Extensions.swift */; };
@@ -792,7 +791,6 @@
51A16991235E10D600EB091F /* DetailAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailAccountViewController.swift; sourceTree = ""; };
51A16992235E10D600EB091F /* AddAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddAccountViewController.swift; sourceTree = ""; };
51A16993235E10D600EB091F /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; };
- 51A16994235E10D600EB091F /* TimelineNumberOfLinesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimelineNumberOfLinesViewController.swift; sourceTree = ""; };
51A16995235E10D600EB091F /* AboutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutViewController.swift; sourceTree = ""; };
51A16996235E10D700EB091F /* FeedbinAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedbinAccountViewController.swift; sourceTree = ""; };
51AF460D232488C6001742EF /* Account-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account-Extensions.swift"; sourceTree = ""; };
@@ -1276,7 +1274,6 @@
51A1698D235E10D600EB091F /* RefreshIntervalViewController.swift */,
51A1698E235E10D600EB091F /* SettingsTableViewCell.xib */,
51A16993235E10D600EB091F /* SettingsViewController.swift */,
- 51A16994235E10D600EB091F /* TimelineNumberOfLinesViewController.swift */,
);
path = Settings;
sourceTree = "";
@@ -2972,7 +2969,6 @@
51C45259226508D300C03939 /* AppDefaults.swift in Sources */,
511D4419231FC02D00FB1562 /* KeyboardManager.swift in Sources */,
51A1699D235E10D700EB091F /* SettingsViewController.swift in Sources */,
- 51A1699E235E10D700EB091F /* TimelineNumberOfLinesViewController.swift in Sources */,
51C45293226509C800C03939 /* StarredFeedDelegate.swift in Sources */,
51D6A5BC23199C85001C27D8 /* MasterTimelineDataSource.swift in Sources */,
51934CCB230F599B006127BE /* ThemedNavigationController.swift in Sources */,
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 2c71e6cc9..8bc23dfb0 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -53,7 +53,7 @@
-
+
@@ -63,7 +63,7 @@
-
+
@@ -83,44 +83,50 @@
-
+
-
-
+
-
+
+
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -308,8 +314,9 @@
+
+
-
@@ -779,35 +786,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index 857251d37..6e0f3ae05 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -16,7 +16,8 @@ class SettingsViewController: UITableViewController {
@IBOutlet weak var refreshIntervalLabel: UILabel!
@IBOutlet weak var timelineSortOrderSwitch: UISwitch!
@IBOutlet weak var groupByFeedSwitch: UISwitch!
- @IBOutlet weak var timelineNumberOfLinesLabel: UILabel!
+ @IBOutlet weak var numberOfTextLinesLabel: UILabel!
+ @IBOutlet weak var numberOfTextLinesSteppper: UIStepper!
weak var presentingParentController: UIViewController?
@@ -46,8 +47,9 @@ class SettingsViewController: UITableViewController {
refreshIntervalLabel.text = AppDefaults.refreshInterval.description()
- let numberOfLinesText = NSLocalizedString(" lines", comment: "Lines")
- timelineNumberOfLinesLabel.text = "\(AppDefaults.timelineNumberOfLines)" + numberOfLinesText
+ let numberOfTextLines = AppDefaults.timelineNumberOfLines
+ numberOfTextLinesSteppper.value = Double(numberOfTextLines)
+ updateNumberOfTextLinesLabel(value: numberOfTextLines)
let buildLabel = NonIntrinsicLabel(frame: CGRect(x: 20.0, y: 0.0, width: 0.0, height: 0.0))
buildLabel.font = UIFont.systemFont(ofSize: 11.0)
@@ -115,11 +117,6 @@ class SettingsViewController: UITableViewController {
controller.account = sortedAccounts[indexPath.row]
self.navigationController?.pushViewController(controller, animated: true)
}
- case 1:
- if indexPath.row == 2 {
- let timeline = UIStoryboard.settings.instantiateController(ofType: TimelineNumberOfLinesViewController.self)
- self.navigationController?.pushViewController(timeline, animated: true)
- }
case 2:
switch indexPath.row {
case 0:
@@ -207,6 +204,12 @@ class SettingsViewController: UITableViewController {
}
}
+ @IBAction func stepNumberOfTextLines(_ sender: UIStepper) {
+ let numberOfLines = Int(sender.value)
+ AppDefaults.timelineNumberOfLines = numberOfLines
+ updateNumberOfTextLinesLabel(value: numberOfLines)
+ }
+
@objc func contentSizeCategoryDidChange() {
tableView.reloadData()
}
@@ -231,6 +234,11 @@ extension SettingsViewController: UIDocumentPickerDelegate {
private extension SettingsViewController {
+ func updateNumberOfTextLinesLabel(value: Int) {
+ let localizedText = NSLocalizedString("Number of Text Lines: %d", comment: "Number of Text Lines")
+ numberOfTextLinesLabel.text = NSString.localizedStringWithFormat(localizedText as NSString, value) as String
+ }
+
func addFeed() {
let appNewsURLString = "https://nnw.ranchero.com/feed.json"
diff --git a/iOS/Settings/TimelineNumberOfLinesViewController.swift b/iOS/Settings/TimelineNumberOfLinesViewController.swift
deleted file mode 100644
index 5c0453b2e..000000000
--- a/iOS/Settings/TimelineNumberOfLinesViewController.swift
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// TimelineNumberOfLinesViewController.swift
-// NetNewsWire-iOS
-//
-// Created by Maurice Parker on 4/29/19.
-// Copyright © 2019 Ranchero Software. All rights reserved.
-//
-
-import UIKit
-
-class TimelineNumberOfLinesViewController: UITableViewController {
-
- override func numberOfSections(in tableView: UITableView) -> Int {
- return 1
- }
-
- override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return 5
- }
-
- override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
- cell.textLabel?.adjustsFontForContentSizeCategory = true
- cell.textLabel?.text = "\(2 + indexPath.row)" + NSLocalizedString(" lines", comment: "Lines")
-
- let numberOfLines = AppDefaults.timelineNumberOfLines
- if indexPath.row + 2 == numberOfLines {
- cell.accessoryType = .checkmark
- } else {
- cell.accessoryType = .none
- }
-
- return cell
- }
-
- override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- AppDefaults.timelineNumberOfLines = indexPath.row + 2
- self.navigationController?.popViewController(animated: true)
- }
-
-}
From 3f974c7c2b8faf1de91a42584e10d1f9adf7be4d Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Mon, 21 Oct 2019 17:52:29 -0500
Subject: [PATCH 09/50] Change links to open in inline Safari browser.
---
iOS/Settings/Settings.storyboard | 29 ++++++++++++++++++-----
iOS/Settings/SettingsViewController.swift | 19 +++++++++++----
2 files changed, 37 insertions(+), 11 deletions(-)
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 8bc23dfb0..90bf18be9 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -229,9 +229,26 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -247,7 +264,7 @@
-
+
@@ -264,7 +281,7 @@
-
+
@@ -281,7 +298,7 @@
-
+
@@ -478,7 +495,7 @@
-
+
@@ -593,7 +610,7 @@
-
+
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index 6e0f3ae05..0a703d174 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -8,6 +8,7 @@
import UIKit
import Account
+import SafariServices
class SettingsViewController: UITableViewController {
@@ -135,17 +136,19 @@ class SettingsViewController: UITableViewController {
let timeline = UIStoryboard.settings.instantiateController(ofType: AboutViewController.self)
self.navigationController?.pushViewController(timeline, animated: true)
case 1:
- UIApplication.shared.open(URL(string: "https://ranchero.com/netnewswire/")!, options: [:])
+ openURL("https://ranchero.com/netnewswire/")
case 2:
- UIApplication.shared.open(URL(string: "https://github.com/brentsimmons/NetNewsWire")!, options: [:])
+ openURL("https://github.com/brentsimmons/NetNewsWire/blob/master/Technotes/HowToSupportNetNewsWire.markdown")
case 3:
- UIApplication.shared.open(URL(string: "https://github.com/brentsimmons/NetNewsWire/issues")!, options: [:])
+ openURL("https://github.com/brentsimmons/NetNewsWire")
case 4:
- UIApplication.shared.open(URL(string: "https://github.com/brentsimmons/NetNewsWire/tree/master/Technotes")!, options: [:])
+ openURL("https://github.com/brentsimmons/NetNewsWire/issues")
case 5:
+ openURL("https://github.com/brentsimmons/NetNewsWire/tree/master/Technotes")
+ case 6:
addFeed()
default:
- UIApplication.shared.open(URL(string: "https://ranchero.com/netnewswire/")!, options: [:])
+ break
}
default:
break
@@ -286,4 +289,10 @@ private extension SettingsViewController {
}
+ func openURL(_ urlString: String) {
+ let vc = SFSafariViewController(url: URL(string: urlString)!)
+ vc.modalPresentationStyle = .pageSheet
+ present(vc, animated: true)
+ }
+
}
From 67251da7ac48355e2e315f882424b000cefc8fd5 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Mon, 21 Oct 2019 18:02:44 -0500
Subject: [PATCH 10/50] Hide the Add NetNewsWire feed option if already
subscribed
---
iOS/SceneCoordinator.swift | 4 +++-
iOS/Settings/Settings.storyboard | 4 ++--
iOS/Settings/SettingsViewController.swift | 16 ++++++++--------
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift
index e4ac6208e..9723f0d17 100644
--- a/iOS/SceneCoordinator.swift
+++ b/iOS/SceneCoordinator.swift
@@ -787,9 +787,11 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
func showSettings() {
let settingsNavController = UIStoryboard.settings.instantiateInitialViewController() as! UINavigationController
+ let settingsViewController = settingsNavController.topViewController as! SettingsViewController
settingsNavController.modalPresentationStyle = .formSheet
settingsNavController.preferredContentSize = SettingsViewController.preferredContentSizeForFormSheetDisplay
- masterFeedViewController.present(settingsNavController, animated: true)
+ settingsViewController.presentingParentController = rootSplitViewController
+ rootSplitViewController.present(settingsNavController, animated: true)
}
func showFeedInspector() {
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 90bf18be9..a9c662f46 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -495,7 +495,7 @@
-
+
@@ -610,7 +610,7 @@
-
+
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index 0a703d174..bcf83e988 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -12,6 +12,7 @@ import SafariServices
class SettingsViewController: UITableViewController {
+ private let appNewsURLString = "https://nnw.ranchero.com/feed.json"
static let preferredContentSizeForFormSheetDisplay = CGSize(width: 460.0, height: 400.0)
@IBOutlet weak var refreshIntervalLabel: UILabel!
@@ -77,6 +78,12 @@ class SettingsViewController: UITableViewController {
return defaultNumberOfRows - 1
}
return defaultNumberOfRows
+ case 3:
+ let defaultNumberOfRows = super.tableView(tableView, numberOfRowsInSection: section)
+ if AccountManager.shared.anyAccountHasFeedWithURL(appNewsURLString) {
+ return defaultNumberOfRows - 1
+ }
+ return defaultNumberOfRows
default:
return super.tableView(tableView, numberOfRowsInSection: section)
}
@@ -243,24 +250,17 @@ private extension SettingsViewController {
}
func addFeed() {
-
- let appNewsURLString = "https://nnw.ranchero.com/feed.json"
- if AccountManager.shared.anyAccountHasFeedWithURL(appNewsURLString) {
- presentError(title: "Subscribe", message: "You are already subscribed to the NetNewsWire news feed.")
- return
- }
-
self.dismiss(animated: true)
let addNavViewController = UIStoryboard.add.instantiateInitialViewController() as! UINavigationController
let addViewController = addNavViewController.topViewController as! AddContainerViewController
addNavViewController.modalPresentationStyle = .formSheet
addNavViewController.preferredContentSize = AddContainerViewController.preferredContentSizeForFormSheetDisplay
+ addViewController.initialControllerType = .feed
addViewController.initialFeed = appNewsURLString
addViewController.initialFeedName = "NetNewsWire News"
presentingParentController?.present(addNavViewController, animated: true)
-
}
func importOPML() {
From 19400a5a508244c6854c935fea7644a9a7feaa9c Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Mon, 21 Oct 2019 18:21:42 -0500
Subject: [PATCH 11/50] Fix coloring of About scene in dark mode
---
iOS/Settings/AboutViewController.swift | 1 +
iOS/Settings/Settings.storyboard | 18 +++++++++---------
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/iOS/Settings/AboutViewController.swift b/iOS/Settings/AboutViewController.swift
index 31da63e9e..a472efd63 100644
--- a/iOS/Settings/AboutViewController.swift
+++ b/iOS/Settings/AboutViewController.swift
@@ -49,6 +49,7 @@ private extension AboutViewController {
let url = Bundle.main.url(forResource: file, withExtension: "rtf")!
let string = try! NSAttributedString(url: url, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.rtf], documentAttributes: nil)
textView.attributedText = string
+ textView.textColor = UIColor.label
textView.adjustsFontForContentSizeCategory = true
textView.font = .preferredFont(forTextStyle: .body)
}
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index a9c662f46..5f53772e1 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -1,6 +1,6 @@
-
+
@@ -495,7 +495,7 @@
-
+
@@ -610,7 +610,7 @@
-
+
@@ -851,7 +851,7 @@
-
+
@@ -875,7 +875,7 @@
-
+
@@ -901,7 +901,7 @@
-
+
@@ -927,7 +927,7 @@
-
+
@@ -953,7 +953,7 @@
-
+
@@ -979,7 +979,7 @@
-
+
From 7a644afc58227e9d1a7ed1fb6d5d14180f24ad2a Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Mon, 21 Oct 2019 20:28:50 -0500
Subject: [PATCH 12/50] Rework add account scenes to look and work like
standard iOS forms
---
.../AddLocalAccountViewController.swift | 9 +-
.../DetailAccountViewController.swift | 1 +
.../FeedbinAccountViewController.swift | 17 +-
iOS/Settings/Settings.storyboard | 365 +++++++++---------
4 files changed, 196 insertions(+), 196 deletions(-)
diff --git a/iOS/Settings/AddLocalAccountViewController.swift b/iOS/Settings/AddLocalAccountViewController.swift
index c89569eaf..b9c092336 100644
--- a/iOS/Settings/AddLocalAccountViewController.swift
+++ b/iOS/Settings/AddLocalAccountViewController.swift
@@ -9,18 +9,15 @@
import UIKit
import Account
-class AddLocalAccountViewController: UIViewController {
+class AddLocalAccountViewController: UITableViewController {
- @IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
- @IBOutlet private weak var localAccountNameLabel: UILabel!
@IBOutlet weak var nameTextField: UITextField!
weak var delegate: AddAccountDismissDelegate?
override func viewDidLoad() {
super.viewDidLoad()
-
- localAccountNameLabel.text = Account.defaultLocalAccountName
+ navigationItem.title = Account.defaultLocalAccountName
nameTextField.delegate = self
}
@@ -29,7 +26,7 @@ class AddLocalAccountViewController: UIViewController {
delegate?.dismiss()
}
- @IBAction func addAccountTapped(_ sender: Any) {
+ @IBAction func add(_ sender: Any) {
let account = AccountManager.shared.createAccount(type: .onMyMac)
account.name = nameTextField.text
dismiss(animated: true, completion: nil)
diff --git a/iOS/Settings/DetailAccountViewController.swift b/iOS/Settings/DetailAccountViewController.swift
index 6f8c45636..9e516bda3 100644
--- a/iOS/Settings/DetailAccountViewController.swift
+++ b/iOS/Settings/DetailAccountViewController.swift
@@ -97,6 +97,7 @@ private extension DetailAccountViewController {
let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController
let addViewController = navController.topViewController as! FeedbinAccountViewController
addViewController.account = account
+ navController.modalPresentationStyle = .currentContext
present(navController, animated: true)
default:
break
diff --git a/iOS/Settings/FeedbinAccountViewController.swift b/iOS/Settings/FeedbinAccountViewController.swift
index e7218bfe1..89264bb1c 100644
--- a/iOS/Settings/FeedbinAccountViewController.swift
+++ b/iOS/Settings/FeedbinAccountViewController.swift
@@ -10,7 +10,7 @@ import UIKit
import Account
import RSWeb
-class FeedbinAccountViewController: UIViewController {
+class FeedbinAccountViewController: UITableViewController {
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
@IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
@@ -19,8 +19,6 @@ class FeedbinAccountViewController: UIViewController {
@IBOutlet weak var showHideButton: UIButton!
@IBOutlet weak var actionButton: UIButton!
- @IBOutlet weak var errorMessageLabel: UILabel!
-
weak var account: Account?
weak var delegate: AddAccountDismissDelegate?
@@ -56,10 +54,9 @@ class FeedbinAccountViewController: UIViewController {
}
@IBAction func action(_ sender: Any) {
- self.errorMessageLabel.text = nil
guard let email = emailTextField.text, let password = passwordTextField.text else {
- self.errorMessageLabel.text = NSLocalizedString("Username & password required.", comment: "Credentials Error")
+ showError(NSLocalizedString("Username & password required.", comment: "Credentials Error"))
return
}
@@ -104,18 +101,22 @@ class FeedbinAccountViewController: UIViewController {
self.dismiss(animated: true, completion: nil)
self.delegate?.dismiss()
} catch {
- self.errorMessageLabel.text = NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error")
+ self.showError(NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error"))
}
} else {
- self.errorMessageLabel.text = NSLocalizedString("Invalid email/password combination.", comment: "Credentials Error")
+ self.showError(NSLocalizedString("Invalid email/password combination.", comment: "Credentials Error"))
}
case .failure:
- self.errorMessageLabel.text = NSLocalizedString("Network error. Try again later.", comment: "Credentials Error")
+ self.showError(NSLocalizedString("Network error. Try again later.", comment: "Credentials Error"))
}
}
}
+ private func showError(_ message: String) {
+ presentError(title: "Error", message: message)
+ }
+
private func enableNavigation() {
self.cancelBarButtonItem.isEnabled = true
self.actionButton.isEnabled = true
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 5f53772e1..538fbcf4a 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -1,9 +1,8 @@
-
+
-
@@ -422,7 +421,6 @@
-
@@ -495,8 +493,8 @@
-
-
+
+
@@ -529,7 +527,7 @@
-
+
@@ -575,7 +573,7 @@
-
+
@@ -591,197 +589,201 @@
-
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
-
+
+
@@ -790,18 +792,17 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
-
+
From be2823b1a1e309fbdecbca63daf22dfd3620f27e Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 02:31:07 -0500
Subject: [PATCH 13/50] Improve UI consistency of Account Detail
---
.../DetailAccountViewController.swift | 87 ++++++++-----------
iOS/Settings/Settings.storyboard | 79 +++++++++++------
2 files changed, 87 insertions(+), 79 deletions(-)
diff --git a/iOS/Settings/DetailAccountViewController.swift b/iOS/Settings/DetailAccountViewController.swift
index 9e516bda3..40dd698ee 100644
--- a/iOS/Settings/DetailAccountViewController.swift
+++ b/iOS/Settings/DetailAccountViewController.swift
@@ -32,6 +32,40 @@ class DetailAccountViewController: UITableViewController {
account?.isActive = activeSwitch.isOn
}
+ @IBAction func credentials(_ sender: Any) {
+ guard let account = account else { return }
+ switch account.type {
+ case .feedbin:
+ let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController
+ let addViewController = navController.topViewController as! FeedbinAccountViewController
+ addViewController.account = account
+ navController.modalPresentationStyle = .currentContext
+ present(navController, animated: true)
+ default:
+ break
+ }
+ }
+
+ @IBAction func deleteAccount(_ sender: Any) {
+ let title = NSLocalizedString("Delete Account", comment: "Delete Account")
+ let message = NSLocalizedString("Are you sure you want to delete this account? This can not be undone.", comment: "Delete Account")
+ let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
+
+ let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
+ let cancelAction = UIAlertAction(title: cancelTitle, style: .cancel)
+ alertController.addAction(cancelAction)
+
+ let markTitle = NSLocalizedString("Delete", comment: "Delete")
+ let markAction = UIAlertAction(title: markTitle, style: .default) { [weak self] (action) in
+ guard let account = self?.account else { return }
+ AccountManager.shared.deleteAccount(account)
+ self?.navigationController?.popViewController(animated: true)
+ }
+ alertController.addAction(markAction)
+
+ present(alertController, animated: true)
+ }
+
}
extension DetailAccountViewController {
@@ -68,64 +102,11 @@ extension DetailAccountViewController {
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- if let account = account, account.type == .onMyMac {
- if indexPath.section == 1 {
- deleteAccount()
- }
- } else {
- switch indexPath.section {
- case 1:
- credentials()
- case 2:
- deleteAccount()
- default:
- break
- }
- }
-
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
}
}
-private extension DetailAccountViewController {
-
- func credentials() {
- guard let account = account else { return }
- switch account.type {
- case .feedbin:
- let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController
- let addViewController = navController.topViewController as! FeedbinAccountViewController
- addViewController.account = account
- navController.modalPresentationStyle = .currentContext
- present(navController, animated: true)
- default:
- break
- }
- }
-
- func deleteAccount() {
- let title = NSLocalizedString("Delete Account", comment: "Delete Account")
- let message = NSLocalizedString("Are you sure you want to delete this account? This can not be undone.", comment: "Delete Account")
- let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
-
- let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
- let cancelAction = UIAlertAction(title: cancelTitle, style: .cancel)
- alertController.addAction(cancelAction)
-
- let markTitle = NSLocalizedString("Delete", comment: "Delete")
- let markAction = UIAlertAction(title: markTitle, style: .default) { [weak self] (action) in
- guard let account = self?.account else { return }
- AccountManager.shared.deleteAccount(account)
- self?.navigationController?.popViewController(animated: true)
- }
- alertController.addAction(markAction)
-
- present(alertController, animated: true)
- }
-
-}
-
extension DetailAccountViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 538fbcf4a..2bf1f6875 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -68,7 +68,7 @@
-
+
@@ -98,7 +98,7 @@
-
+
@@ -173,7 +173,7 @@
-
+
@@ -228,7 +228,7 @@
-
+
@@ -296,7 +296,7 @@
-
+
@@ -418,15 +418,23 @@
-
-
+
+
+
+
+
-
-
+
+
+
+
+
-
-
+
+
+
+
@@ -441,16 +449,25 @@
-
-
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
@@ -631,7 +648,7 @@
-
+
@@ -639,7 +656,10 @@
-
+
+
+
+
@@ -648,8 +668,10 @@
-
-
+
+
+
+
@@ -741,7 +763,7 @@
-
+
@@ -749,7 +771,10 @@
-
+
+
+
+
@@ -758,8 +783,10 @@
-
-
+
+
+
+
From d9a165151d2d891a80be086640ec16aac56b96d0 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 02:35:47 -0500
Subject: [PATCH 14/50] Rename to VibrantTableViewCell
---
NetNewsWire.xcodeproj/project.pbxproj | 12 +++--
.../Cell/MasterFeedTableViewCell.swift | 2 +-
.../Cell/MasterTimelineTableViewCell.swift | 2 +-
iOS/Settings/Settings.storyboard | 46 +++++++++----------
iOS/Settings/SettingsTableViewCell.xib | 2 +-
...wCell.swift => VibrantTableViewCell.swift} | 4 +-
6 files changed, 36 insertions(+), 32 deletions(-)
rename iOS/UIKit Extensions/{NNWTableViewCell.swift => VibrantTableViewCell.swift} (90%)
diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj
index 78e6e82de..d8f86eba7 100644
--- a/NetNewsWire.xcodeproj/project.pbxproj
+++ b/NetNewsWire.xcodeproj/project.pbxproj
@@ -231,7 +231,7 @@
51FE100A234673A00056195D /* ActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51934CCD2310792F006127BE /* ActivityManager.swift */; };
55E15BCB229D65A900D6602A /* AccountsReaderAPI.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */; };
55E15BCC229D65A900D6602A /* AccountsReaderAPIWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */; };
- 5F323809231DF9F000706F6B /* NNWTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F323808231DF9F000706F6B /* NNWTableViewCell.swift */; };
+ 5F323809231DF9F000706F6B /* VibrantTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F323808231DF9F000706F6B /* VibrantTableViewCell.swift */; };
6581C73820CED60100F4AD34 /* SafariExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6581C73720CED60100F4AD34 /* SafariExtensionHandler.swift */; };
6581C73A20CED60100F4AD34 /* SafariExtensionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6581C73920CED60100F4AD34 /* SafariExtensionViewController.swift */; };
6581C73D20CED60100F4AD34 /* SafariExtensionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6581C73B20CED60100F4AD34 /* SafariExtensionViewController.xib */; };
@@ -1323,7 +1323,7 @@
51FE10022345529D0056195D /* UserNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationManager.swift; sourceTree = ""; };
55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsReaderAPI.xib; sourceTree = ""; };
55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsReaderAPIWindowController.swift; sourceTree = ""; };
- 5F323808231DF9F000706F6B /* NNWTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NNWTableViewCell.swift; sourceTree = ""; };
+ 5F323808231DF9F000706F6B /* VibrantTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VibrantTableViewCell.swift; sourceTree = ""; };
6543108B2322D90900658221 /* common */ = {isa = PBXFileReference; lastKnownFileType = folder; path = common; sourceTree = ""; };
6581C73320CED60000F4AD34 /* Subscribe to Feed.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Subscribe to Feed.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
6581C73420CED60100F4AD34 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
@@ -1811,7 +1811,6 @@
children = (
51F85BFA2275D85000C787DC /* Array-Extensions.swift */,
51F85BF42273625800C787DC /* Bundle-Extensions.swift */,
- 5F323808231DF9F000706F6B /* NNWTableViewCell.swift */,
51EAED95231363EF00A9EEE3 /* NonIntrinsicButton.swift */,
5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */,
5183CCCF226E1E880010922C /* NonIntrinsicLabel.swift */,
@@ -1822,6 +1821,7 @@
51FD40BD2341555600880194 /* UIImage-Extensions.swift */,
512E092B2268B25500BDCFDD /* UISplitViewController-Extensions.swift */,
51C4524E226506F400C03939 /* UIStoryboard-Extensions.swift */,
+ 5F323808231DF9F000706F6B /* VibrantTableViewCell.swift */,
);
path = "UIKit Extensions";
sourceTree = "";
@@ -2904,6 +2904,10 @@
DevelopmentTeam = SHJK2V3AJG;
ProvisioningStyle = Automatic;
};
+ 65ED3FA2235DEF6C0081F399 = {
+ DevelopmentTeam = SHJK2V3AJG;
+ ProvisioningStyle = Automatic;
+ };
840D617B2029031C009BC708 = {
CreatedOnToolsVersion = 9.3;
DevelopmentTeam = SHJK2V3AJG;
@@ -3878,7 +3882,7 @@
51C452A622650A3500C03939 /* Node-Extensions.swift in Sources */,
5183CCDF226F1FCC0010922C /* UINavigationController+Progress.swift in Sources */,
51C45294226509C800C03939 /* SearchFeedDelegate.swift in Sources */,
- 5F323809231DF9F000706F6B /* NNWTableViewCell.swift in Sources */,
+ 5F323809231DF9F000706F6B /* VibrantTableViewCell.swift in Sources */,
512E09352268B25900BDCFDD /* UISplitViewController-Extensions.swift in Sources */,
51FE10042345529D0056195D /* UserNotificationManager.swift in Sources */,
51C452A022650A1900C03939 /* FeedIconDownloader.swift in Sources */,
diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
index 5f684ce8f..a99e00cfa 100644
--- a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
+++ b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
@@ -15,7 +15,7 @@ protocol MasterFeedTableViewCellDelegate: class {
func disclosureSelected(_ sender: MasterFeedTableViewCell, expanding: Bool)
}
-class MasterFeedTableViewCell : NNWTableViewCell {
+class MasterFeedTableViewCell : VibrantTableViewCell {
weak var delegate: MasterFeedTableViewCellDelegate?
diff --git a/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift b/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift
index 7e55f3dfd..d3514288d 100644
--- a/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift
+++ b/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift
@@ -9,7 +9,7 @@
import UIKit
import RSCore
-class MasterTimelineTableViewCell: NNWTableViewCell {
+class MasterTimelineTableViewCell: VibrantTableViewCell {
private let titleView = MasterTimelineTableViewCell.multiLineUILabel()
private let summaryView = MasterTimelineTableViewCell.multiLineUILabel()
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 2bf1f6875..89e5f0a42 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -17,7 +17,7 @@
-
+
@@ -38,7 +38,7 @@
-
+
@@ -68,7 +68,7 @@
-
+
@@ -98,7 +98,7 @@
-
+
@@ -132,7 +132,7 @@
-
+
@@ -156,7 +156,7 @@
-
+
@@ -173,7 +173,7 @@
-
+
@@ -194,7 +194,7 @@
-
+
@@ -211,7 +211,7 @@
-
+
@@ -228,7 +228,7 @@
-
+
@@ -245,7 +245,7 @@
-
+
@@ -262,7 +262,7 @@
-
+
@@ -279,7 +279,7 @@
-
+
@@ -296,7 +296,7 @@
-
+
@@ -351,7 +351,7 @@
-
+
@@ -382,7 +382,7 @@
-
+
@@ -411,7 +411,7 @@
-
+
@@ -442,7 +442,7 @@
-
+
@@ -499,7 +499,7 @@
-
+
@@ -532,7 +532,7 @@
-
+
@@ -648,7 +648,7 @@
-
+
@@ -763,7 +763,7 @@
-
+
@@ -840,7 +840,7 @@
-
+
diff --git a/iOS/Settings/SettingsTableViewCell.xib b/iOS/Settings/SettingsTableViewCell.xib
index 18048b1de..71f516107 100644
--- a/iOS/Settings/SettingsTableViewCell.xib
+++ b/iOS/Settings/SettingsTableViewCell.xib
@@ -8,7 +8,7 @@
-
+
diff --git a/iOS/UIKit Extensions/NNWTableViewCell.swift b/iOS/UIKit Extensions/VibrantTableViewCell.swift
similarity index 90%
rename from iOS/UIKit Extensions/NNWTableViewCell.swift
rename to iOS/UIKit Extensions/VibrantTableViewCell.swift
index 1cea8c90c..258acdd95 100644
--- a/iOS/UIKit Extensions/NNWTableViewCell.swift
+++ b/iOS/UIKit Extensions/VibrantTableViewCell.swift
@@ -1,5 +1,5 @@
//
-// NNWTableViewCell.swift
+// VibrantTableViewCell.swift
// NetNewsWire-iOS
//
// Created by Jim Correia on 9/2/19.
@@ -8,7 +8,7 @@
import UIKit
-class NNWTableViewCell: UITableViewCell {
+class VibrantTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
From 528284999fc16e7c3949120148ce97ab02590c2d Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 03:31:25 -0500
Subject: [PATCH 15/50] Correct vibrancy configuration for Settings
---
NetNewsWire.xcodeproj/project.pbxproj | 8 +++++
iOS/AppAssets.swift | 8 ++---
.../Cell/MasterFeedTableViewCell.swift | 6 ++--
.../Cell/MasterTimelineTableViewCell.swift | 2 +-
.../Cell/MasterUnreadIndicatorView.swift | 2 +-
.../Contents.json | 0
iOS/Settings/Settings.storyboard | 26 ++++++++++-----
iOS/UIKit Extensions/VibrantButton.swift | 32 +++++++++++++++++++
iOS/UIKit Extensions/VibrantLabel.swift | 27 ++++++++++++++++
.../VibrantTableViewCell.swift | 5 ++-
10 files changed, 98 insertions(+), 18 deletions(-)
rename iOS/Resources/Assets.xcassets/{tableViewCellHighlightedTextColor.colorset => vibrantTextColor.colorset}/Contents.json (100%)
create mode 100644 iOS/UIKit Extensions/VibrantButton.swift
create mode 100644 iOS/UIKit Extensions/VibrantLabel.swift
diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj
index d8f86eba7..dcbae23cd 100644
--- a/NetNewsWire.xcodeproj/project.pbxproj
+++ b/NetNewsWire.xcodeproj/project.pbxproj
@@ -96,6 +96,7 @@
5183CCE9226F68D90010922C /* AccountRefreshTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCE7226F68D90010922C /* AccountRefreshTimer.swift */; };
518651B223555EB20078E021 /* NNW3Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518651AB23555EB20078E021 /* NNW3Document.swift */; };
518651DA235621840078E021 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518651D9235621840078E021 /* ImageTransition.swift */; };
+ 5186A635235EF3A800C97195 /* VibrantLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5186A634235EF3A800C97195 /* VibrantLabel.swift */; };
518B2EE82351B45600400001 /* NetNewsWire_iOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840D61952029031D009BC708 /* NetNewsWire_iOSTests.swift */; };
51934CCB230F599B006127BE /* ThemedNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51934CC1230F5963006127BE /* ThemedNavigationController.swift */; };
51934CCE2310792F006127BE /* ActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51934CCD2310792F006127BE /* ActivityManager.swift */; };
@@ -229,6 +230,7 @@
51FE10042345529D0056195D /* UserNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FE10022345529D0056195D /* UserNotificationManager.swift */; };
51FE10092346739D0056195D /* ActivityType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D87EE02311D34700E63F03 /* ActivityType.swift */; };
51FE100A234673A00056195D /* ActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51934CCD2310792F006127BE /* ActivityManager.swift */; };
+ 51FFF0C4235EE8E5002762AA /* VibrantButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51FFF0C3235EE8E5002762AA /* VibrantButton.swift */; };
55E15BCB229D65A900D6602A /* AccountsReaderAPI.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */; };
55E15BCC229D65A900D6602A /* AccountsReaderAPIWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */; };
5F323809231DF9F000706F6B /* VibrantTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F323808231DF9F000706F6B /* VibrantTableViewCell.swift */; };
@@ -1246,6 +1248,7 @@
5183CCE7226F68D90010922C /* AccountRefreshTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRefreshTimer.swift; sourceTree = ""; };
518651AB23555EB20078E021 /* NNW3Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NNW3Document.swift; sourceTree = ""; };
518651D9235621840078E021 /* ImageTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageTransition.swift; sourceTree = ""; };
+ 5186A634235EF3A800C97195 /* VibrantLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VibrantLabel.swift; sourceTree = ""; };
518B2ED22351B3DD00400001 /* NetNewsWire-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "NetNewsWire-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
518B2EE92351B4C200400001 /* NetNewsWire_iOSTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetNewsWire_iOSTests_target.xcconfig; sourceTree = ""; };
51934CC1230F5963006127BE /* ThemedNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemedNavigationController.swift; sourceTree = ""; };
@@ -1321,6 +1324,7 @@
51FD40BD2341555600880194 /* UIImage-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage-Extensions.swift"; sourceTree = ""; };
51FD413A2342BD0500880194 /* MasterTimelineUnreadCountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineUnreadCountView.swift; sourceTree = ""; };
51FE10022345529D0056195D /* UserNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationManager.swift; sourceTree = ""; };
+ 51FFF0C3235EE8E5002762AA /* VibrantButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VibrantButton.swift; sourceTree = ""; };
55E15BC1229D65A900D6602A /* AccountsReaderAPI.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsReaderAPI.xib; sourceTree = ""; };
55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsReaderAPIWindowController.swift; sourceTree = ""; };
5F323808231DF9F000706F6B /* VibrantTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VibrantTableViewCell.swift; sourceTree = ""; };
@@ -1821,6 +1825,8 @@
51FD40BD2341555600880194 /* UIImage-Extensions.swift */,
512E092B2268B25500BDCFDD /* UISplitViewController-Extensions.swift */,
51C4524E226506F400C03939 /* UIStoryboard-Extensions.swift */,
+ 51FFF0C3235EE8E5002762AA /* VibrantButton.swift */,
+ 5186A634235EF3A800C97195 /* VibrantLabel.swift */,
5F323808231DF9F000706F6B /* VibrantTableViewCell.swift */,
);
path = "UIKit Extensions";
@@ -3843,6 +3849,7 @@
5183CCDA226E31A50010922C /* NonIntrinsicImageView.swift in Sources */,
51EAED96231363EF00A9EEE3 /* NonIntrinsicButton.swift in Sources */,
51C4527B2265091600C03939 /* MasterUnreadIndicatorView.swift in Sources */,
+ 5186A635235EF3A800C97195 /* VibrantLabel.swift in Sources */,
51F85BF92274AA7B00C787DC /* UIBarButtonItem-Extensions.swift in Sources */,
51B62E68233186730085F949 /* MasterTimelineAvatarView.swift in Sources */,
51C45296226509D300C03939 /* OPMLExporter.swift in Sources */,
@@ -3944,6 +3951,7 @@
51C4528D2265095F00C03939 /* AddFolderViewController.swift in Sources */,
51C452782265091600C03939 /* MasterTimelineCellData.swift in Sources */,
5148F4552336DB7000F8CD8B /* MasterTimelineTitleView.swift in Sources */,
+ 51FFF0C4235EE8E5002762AA /* VibrantButton.swift in Sources */,
513228FC233037630033D4ED /* Reachability.swift in Sources */,
51C45259226508D300C03939 /* AppDefaults.swift in Sources */,
511D4419231FC02D00FB1562 /* KeyboardManager.swift in Sources */,
diff --git a/iOS/AppAssets.swift b/iOS/AppAssets.swift
index 2ca4fda10..55f66027a 100644
--- a/iOS/AppAssets.swift
+++ b/iOS/AppAssets.swift
@@ -140,10 +140,6 @@ struct AppAssets {
return UIImage(systemName: "star.fill")!
}()
- static var tableViewCellHighlightedTextColor: UIColor = {
- return UIColor(named: "tableViewCellHighlightedTextColor")!
- }()
-
static var timelineStarImage: UIImage = {
let image = UIImage(systemName: "star.fill")!
return image.withTintColor(AppAssets.starColor, renderingMode: .alwaysOriginal)
@@ -161,4 +157,8 @@ struct AppAssets {
return UIImage(systemName: "largecircle.fill.circle")!
}()
+ static var vibrantTextColor: UIColor = {
+ return UIColor(named: "vibrantTextColor")!
+ }()
+
}
diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
index a99e00cfa..3662b829a 100644
--- a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
+++ b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
@@ -128,13 +128,13 @@ class MasterFeedTableViewCell : VibrantTableViewCell {
override func applyThemeProperties() {
super.applyThemeProperties()
- titleView.highlightedTextColor = AppAssets.tableViewCellHighlightedTextColor
+ titleView.highlightedTextColor = AppAssets.vibrantTextColor
}
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
- let tintColor = isHighlighted || isSelected ? AppAssets.tableViewCellHighlightedTextColor : AppAssets.secondaryAccentColor
+ let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : AppAssets.secondaryAccentColor
disclosureButton?.tintColor = tintColor
faviconImageView.tintColor = tintColor
}
@@ -142,7 +142,7 @@ class MasterFeedTableViewCell : VibrantTableViewCell {
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
- let tintColor = isHighlighted || isSelected ? AppAssets.tableViewCellHighlightedTextColor : AppAssets.secondaryAccentColor
+ let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : AppAssets.secondaryAccentColor
disclosureButton?.tintColor = tintColor
faviconImageView.tintColor = tintColor
}
diff --git a/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift b/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift
index d3514288d..24f7b725b 100644
--- a/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift
+++ b/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift
@@ -37,7 +37,7 @@ class MasterTimelineTableViewCell: VibrantTableViewCell {
override func applyThemeProperties() {
super.applyThemeProperties()
- let highlightedTextColor = AppAssets.tableViewCellHighlightedTextColor
+ let highlightedTextColor = AppAssets.vibrantTextColor
titleView.highlightedTextColor = highlightedTextColor
summaryView.highlightedTextColor = highlightedTextColor
diff --git a/iOS/MasterTimeline/Cell/MasterUnreadIndicatorView.swift b/iOS/MasterTimeline/Cell/MasterUnreadIndicatorView.swift
index 3c64e084e..88cb190f0 100644
--- a/iOS/MasterTimeline/Cell/MasterUnreadIndicatorView.swift
+++ b/iOS/MasterTimeline/Cell/MasterUnreadIndicatorView.swift
@@ -32,7 +32,7 @@ class MasterUnreadIndicatorView: UIView {
}()
override func draw(_ dirtyRect: CGRect) {
- let color = isSelected ? AppAssets.tableViewCellHighlightedTextColor : AppAssets.secondaryAccentColor
+ let color = isSelected ? AppAssets.vibrantTextColor : AppAssets.secondaryAccentColor
color.setFill()
MasterUnreadIndicatorView.bezierPath.fill()
}
diff --git a/iOS/Resources/Assets.xcassets/tableViewCellHighlightedTextColor.colorset/Contents.json b/iOS/Resources/Assets.xcassets/vibrantTextColor.colorset/Contents.json
similarity index 100%
rename from iOS/Resources/Assets.xcassets/tableViewCellHighlightedTextColor.colorset/Contents.json
rename to iOS/Resources/Assets.xcassets/vibrantTextColor.colorset/Contents.json
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 89e5f0a42..173252dae 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -3,6 +3,7 @@
+
@@ -146,7 +147,7 @@
-
+
@@ -418,13 +419,15 @@
-
+
-
+
+
+
@@ -449,7 +452,7 @@
-
+
@@ -655,13 +658,15 @@
-
+
-
+
+
+
@@ -770,13 +775,15 @@
-
+
-
+
+
+
@@ -1061,5 +1068,8 @@
+
+
+
diff --git a/iOS/UIKit Extensions/VibrantButton.swift b/iOS/UIKit Extensions/VibrantButton.swift
new file mode 100644
index 000000000..6c60e1dfc
--- /dev/null
+++ b/iOS/UIKit Extensions/VibrantButton.swift
@@ -0,0 +1,32 @@
+//
+// VibrantButton.swift
+// NetNewsWire-iOS
+//
+// Created by Maurice Parker on 10/22/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import UIKit
+
+class VibrantButton: UIButton {
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ commonInit()
+ }
+ required init?(coder: NSCoder) {
+ super.init(coder: coder)
+ commonInit()
+ }
+
+ private func commonInit() {
+ setTitleColor(AppAssets.vibrantTextColor, for: .highlighted)
+ }
+
+ override var isHighlighted: Bool {
+ didSet {
+ backgroundColor = isHighlighted ? AppAssets.secondaryAccentColor : nil
+ }
+ }
+
+}
diff --git a/iOS/UIKit Extensions/VibrantLabel.swift b/iOS/UIKit Extensions/VibrantLabel.swift
new file mode 100644
index 000000000..9e480a7c4
--- /dev/null
+++ b/iOS/UIKit Extensions/VibrantLabel.swift
@@ -0,0 +1,27 @@
+//
+// VibrantLabel.swift
+// NetNewsWire-iOS
+//
+// Created by Maurice Parker on 10/22/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import UIKit
+
+class VibrantLabel: UILabel {
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ commonInit()
+ }
+
+ required init?(coder: NSCoder) {
+ super.init(coder: coder)
+ commonInit()
+ }
+
+ private func commonInit() {
+ highlightedTextColor = AppAssets.vibrantTextColor
+ }
+
+}
diff --git a/iOS/UIKit Extensions/VibrantTableViewCell.swift b/iOS/UIKit Extensions/VibrantTableViewCell.swift
index 258acdd95..bd6998bca 100644
--- a/iOS/UIKit Extensions/VibrantTableViewCell.swift
+++ b/iOS/UIKit Extensions/VibrantTableViewCell.swift
@@ -9,6 +9,7 @@
import UIKit
class VibrantTableViewCell: UITableViewCell {
+
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
@@ -26,7 +27,9 @@ class VibrantTableViewCell: UITableViewCell {
/// Subclass overrides should call super
func applyThemeProperties() {
let selectedBackgroundView = UIView(frame: .zero)
- selectedBackgroundView.backgroundColor = AppAssets.primaryAccentColor
+ selectedBackgroundView.backgroundColor = AppAssets.secondaryAccentColor
self.selectedBackgroundView = selectedBackgroundView
+
+ textLabel?.highlightedTextColor = AppAssets.vibrantTextColor
}
}
From 8bb900e9c5084659f8b7c0087342867cc10e8e96 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 03:33:34 -0500
Subject: [PATCH 16/50] Fix vibrant labels on Settings scene
---
iOS/Settings/Settings.storyboard | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 173252dae..d2444bdeb 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -46,7 +46,7 @@
-
+
@@ -76,7 +76,7 @@
-
+
@@ -106,7 +106,7 @@
-
+
@@ -513,7 +513,7 @@
-
+
From 48fb3ebc1886591da18d2e65c9afe7992c603eba Mon Sep 17 00:00:00 2001
From: Ryan Dotson
Date: Tue, 22 Oct 2019 19:58:05 +0900
Subject: [PATCH 17/50] Curled some quotes
---
Frameworks/Account/AccountError.swift | 4 ++--
.../Feedly/FeedlyAccountDelegateError.swift | 22 +++++++++----------
.../AccountsPreferencesViewController.swift | 4 ++--
.../Account/SettingsDetailAccountView.swift | 2 +-
4 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/Frameworks/Account/AccountError.swift b/Frameworks/Account/AccountError.swift
index 480871f2b..2c7fdb720 100644
--- a/Frameworks/Account/AccountError.swift
+++ b/Frameworks/Account/AccountError.swift
@@ -28,7 +28,7 @@ public enum AccountError: LocalizedError {
switch error {
case TransportError.httpError(let status):
if status == 401 {
- let localizedText = NSLocalizedString("Your \"%@\" credentials are invalid or expired.", comment: "Invalid or expired")
+ let localizedText = NSLocalizedString("Your “%@” credentials are invalid or expired.", comment: "Invalid or expired")
return NSString.localizedStringWithFormat(localizedText as NSString, account.nameForDisplay) as String
} else {
return unknownError(error, account)
@@ -62,7 +62,7 @@ public enum AccountError: LocalizedError {
}
private func unknownError(_ error: Error, _ account: Account) -> String {
- let localizedText = NSLocalizedString("An error occurred while processing the \"%@\" account: %@", comment: "Unknown error")
+ let localizedText = NSLocalizedString("An error occurred while processing the “%@” account: %@", comment: "Unknown error")
return NSString.localizedStringWithFormat(localizedText as NSString, account.nameForDisplay, error.localizedDescription) as String
}
}
diff --git a/Frameworks/Account/Feedly/FeedlyAccountDelegateError.swift b/Frameworks/Account/Feedly/FeedlyAccountDelegateError.swift
index ed23a71cc..a77fcfe02 100644
--- a/Frameworks/Account/Feedly/FeedlyAccountDelegateError.swift
+++ b/Frameworks/Account/Feedly/FeedlyAccountDelegateError.swift
@@ -22,37 +22,37 @@ enum FeedlyAccountDelegateError: LocalizedError {
var errorDescription: String? {
switch self {
case .notLoggedIn:
- return NSLocalizedString("Please add the Feedly account again.", comment: "Feedly - Credentials not found.")
+ return NSLocalizedString("Please add the Feedly account again.", comment: "Feedly – Credentials not found.")
case .unableToAddFolder(let name):
- let template = NSLocalizedString("Could not create a folder named \"%@\".", comment: "Feedly - Could not create a folder/collection.")
+ let template = NSLocalizedString("Could not create a folder named “%@”.", comment: "Feedly – Could not create a folder/collection.")
return String(format: template, name)
case .unableToRenameFolder(let from, let to):
- let template = NSLocalizedString("Could not rename \"%@\" to \"%@\".", comment: "Feedly - Could not rename a folder/collection.")
+ let template = NSLocalizedString("Could not rename “%@” to “%@”.", comment: "Feedly – Could not rename a folder/collection.")
return String(format: template, from, to)
case .unableToRemoveFolder(let name):
- let template = NSLocalizedString("Could not remove the folder named \"%@\".", comment: "Feedly - Could not remove a folder/collection.")
+ let template = NSLocalizedString("Could not remove the folder named “%@”.", comment: "Feedly – Could not remove a folder/collection.")
return String(format: template, name)
case .unableToMoveFeedBetweenFolders(let feed, _, let to):
- let template = NSLocalizedString("Could not move \"%@\" to \"%@\".", comment: "Feedly - Could not move a feed between folders/collections.")
+ let template = NSLocalizedString("Could not move “%@” to “%@”.", comment: "Feedly – Could not move a feed between folders/collections.")
return String(format: template, feed.nameForDisplay, to.nameForDisplay)
case .addFeedChooseFolder:
- return NSLocalizedString("Please choose a folder to contain the feed.", comment: "Feedly - Feed can only be added to folders.")
+ return NSLocalizedString("Please choose a folder to contain the feed.", comment: "Feedly – Feed can only be added to folders.")
case .addFeedInvalidFolder(let invalidFolder):
- let template = NSLocalizedString("Feeds cannot be added to the \"%@\" folder.", comment: "Feedly - Feed can only be added to folders.")
+ let template = NSLocalizedString("Feeds cannot be added to the “%@” folder.", comment: "Feedly – Feed can only be added to folders.")
return String(format: template, invalidFolder.nameForDisplay)
case .unableToRenameFeed(let from, let to):
- let template = NSLocalizedString("Could not rename \"%@\" to \"%@\".", comment: "Feedly - Could not rename a feed.")
+ let template = NSLocalizedString("Could not rename “%@” to “%@”.", comment: "Feedly – Could not rename a feed.")
return String(format: template, from, to)
case .unableToRemoveFeed(let feed):
- let template = NSLocalizedString("Could not remove \"%@\".", comment: "Feedly - Could not remove a feed.")
+ let template = NSLocalizedString("Could not remove “%@”.", comment: "Feedly – Could not remove a feed.")
return String(format: template, feed.nameForDisplay)
}
}
@@ -72,14 +72,14 @@ enum FeedlyAccountDelegateError: LocalizedError {
return nil
case .unableToMoveFeedBetweenFolders(let feed, let from, let to):
- let template = NSLocalizedString("\"%@\" may be in both \"%@\" and \"%@\".", comment: "Feedly - Could not move a feed between folders/collections.")
+ let template = NSLocalizedString("“%@” may be in both “%@” and “%@”.", comment: "Feedly – Could not move a feed between folders/collections.")
return String(format: template, feed.nameForDisplay, from.nameForDisplay, to.nameForDisplay)
case .addFeedChooseFolder:
return nil
case .addFeedInvalidFolder:
- return NSLocalizedString("Please choose a different folder to contain the feed.", comment: "Feedly - Feed can only be added to folders recovery suggestion.")
+ return NSLocalizedString("Please choose a different folder to contain the feed.", comment: "Feedly – Feed can only be added to folders recovery suggestion.")
case .unableToRemoveFeed:
return nil
diff --git a/Mac/Preferences/Accounts/AccountsPreferencesViewController.swift b/Mac/Preferences/Accounts/AccountsPreferencesViewController.swift
index cfc540d09..5c5022610 100644
--- a/Mac/Preferences/Accounts/AccountsPreferencesViewController.swift
+++ b/Mac/Preferences/Accounts/AccountsPreferencesViewController.swift
@@ -52,8 +52,8 @@ final class AccountsPreferencesViewController: NSViewController {
let alert = NSAlert()
alert.alertStyle = .warning
let deletePrompt = NSLocalizedString("Delete", comment: "Delete")
- alert.messageText = "\(deletePrompt) \"\(acctName)\"?"
- alert.informativeText = NSLocalizedString("Are you sure you want to delete the account \"\(acctName)\"? This can not be undone.", comment: "Delete text")
+ alert.messageText = "\(deletePrompt) “\(acctName)”?"
+ alert.informativeText = NSLocalizedString("Are you sure you want to delete the account “\(acctName)”? This can not be undone.", comment: "Delete text")
alert.addButton(withTitle: NSLocalizedString("Delete", comment: "Delete Account"))
alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "Cancel Delete Account"))
diff --git a/iOS/Settings/Account/SettingsDetailAccountView.swift b/iOS/Settings/Account/SettingsDetailAccountView.swift
index f67b29833..8fc673c93 100644
--- a/iOS/Settings/Account/SettingsDetailAccountView.swift
+++ b/iOS/Settings/Account/SettingsDetailAccountView.swift
@@ -53,7 +53,7 @@ struct SettingsDetailAccountView : View {
Text("Delete Account").foregroundColor(.red)
}
.alert(isPresented: $isDeleteAlertPresented) {
- Alert(title: Text("Are you sure you want to delete \"\(viewModel.nameForDisplay)\"?"),
+ Alert(title: Text("Are you sure you want to delete “\(viewModel.nameForDisplay)”?"),
primaryButton: Alert.Button.default(Text("Delete"), action: {
self.viewModel.delete()
self.presentation.wrappedValue.dismiss()
From 1cefea6f2950c2b5df1de8e42a56d4ad70cf106e Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 08:43:39 -0500
Subject: [PATCH 18/50] Add Open System Settings option
---
iOS/Settings/Settings.storyboard | 51 ++++++++++++++++-------
iOS/Settings/SettingsViewController.swift | 29 ++++++-------
2 files changed, 48 insertions(+), 32 deletions(-)
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index d2444bdeb..dbf3d88a5 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -16,10 +16,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -40,7 +61,7 @@
-
+
@@ -70,7 +91,7 @@
-
+
@@ -100,7 +121,7 @@
-
+
@@ -134,7 +155,7 @@
-
+
@@ -158,7 +179,7 @@
-
+
@@ -175,7 +196,7 @@
-
+
@@ -196,7 +217,7 @@
-
+
@@ -213,7 +234,7 @@
-
+
@@ -230,7 +251,7 @@
-
+
@@ -247,7 +268,7 @@
-
+
@@ -264,7 +285,7 @@
-
+
@@ -281,7 +302,7 @@
-
+
@@ -298,7 +319,7 @@
-
+
@@ -513,7 +534,7 @@
-
+
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index bcf83e988..b8aa300a3 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -69,18 +69,11 @@ class SettingsViewController: UITableViewController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
- case 0:
- return AccountManager.shared.accounts.count + 1
case 1:
+ return AccountManager.shared.accounts.count + 1
+ case 4:
let defaultNumberOfRows = super.tableView(tableView, numberOfRowsInSection: section)
- if AccountManager.shared.activeAccounts.isEmpty {
- // Hide the add NetNewsWire feed row if they don't have any active accounts
- return defaultNumberOfRows - 1
- }
- return defaultNumberOfRows
- case 3:
- let defaultNumberOfRows = super.tableView(tableView, numberOfRowsInSection: section)
- if AccountManager.shared.anyAccountHasFeedWithURL(appNewsURLString) {
+ if AccountManager.shared.activeAccounts.isEmpty || AccountManager.shared.anyAccountHasFeedWithURL(appNewsURLString) {
return defaultNumberOfRows - 1
}
return defaultNumberOfRows
@@ -92,7 +85,7 @@ class SettingsViewController: UITableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell
switch indexPath.section {
- case 0:
+ case 1:
cell = tableView.dequeueReusableCell(withIdentifier: "SettingsTableViewCell", for: indexPath)
cell.textLabel?.adjustsFontForContentSizeCategory = true
@@ -116,6 +109,8 @@ class SettingsViewController: UITableViewController {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.section {
case 0:
+ UIApplication.shared.open(URL(string: "\(UIApplication.openSettingsURLString)")!)
+ case 1:
let sortedAccounts = AccountManager.shared.sortedAccounts
if indexPath.row == sortedAccounts.count {
let controller = UIStoryboard.settings.instantiateController(ofType: AddAccountViewController.self)
@@ -125,7 +120,7 @@ class SettingsViewController: UITableViewController {
controller.account = sortedAccounts[indexPath.row]
self.navigationController?.pushViewController(controller, animated: true)
}
- case 2:
+ case 3:
switch indexPath.row {
case 0:
let timeline = UIStoryboard.settings.instantiateController(ofType: RefreshIntervalViewController.self)
@@ -137,7 +132,7 @@ class SettingsViewController: UITableViewController {
default:
break
}
- case 3:
+ case 4:
switch indexPath.row {
case 0:
let timeline = UIStoryboard.settings.instantiateController(ofType: AboutViewController.self)
@@ -177,16 +172,16 @@ class SettingsViewController: UITableViewController {
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
- if indexPath.section == 0 {
- return super.tableView(tableView, heightForRowAt: IndexPath(row: 0, section: 0))
+ if indexPath.section == 1 {
+ return super.tableView(tableView, heightForRowAt: IndexPath(row: 0, section: 1))
} else {
return super.tableView(tableView, heightForRowAt: indexPath)
}
}
override func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int {
- if indexPath.section == 0 {
- return super.tableView(tableView, indentationLevelForRowAt: IndexPath(row: 0, section: 0))
+ if indexPath.section == 1 {
+ return super.tableView(tableView, indentationLevelForRowAt: IndexPath(row: 0, section: 1))
} else {
return super.tableView(tableView, indentationLevelForRowAt: indexPath)
}
From baa90700164c2893ae3aedffae257b6a08546ecc Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 09:06:35 -0500
Subject: [PATCH 19/50] Disable Feedbin add account button until fields are
filled
---
.../FeedbinAccountViewController.swift | 7 +++++
iOS/Settings/Settings.storyboard | 26 ++++++-------------
iOS/UIKit Extensions/VibrantButton.swift | 1 +
3 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/iOS/Settings/FeedbinAccountViewController.swift b/iOS/Settings/FeedbinAccountViewController.swift
index 89264bb1c..3196b5880 100644
--- a/iOS/Settings/FeedbinAccountViewController.swift
+++ b/iOS/Settings/FeedbinAccountViewController.swift
@@ -36,6 +36,9 @@ class FeedbinAccountViewController: UITableViewController {
} else {
actionButton.setTitle(NSLocalizedString("Add Account", comment: "Update Credentials"), for: .normal)
}
+
+ NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: UITextField.textDidChangeNotification, object: emailTextField)
+ NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: UITextField.textDidChangeNotification, object: passwordTextField)
}
@IBAction func cancel(_ sender: Any) {
@@ -113,6 +116,10 @@ class FeedbinAccountViewController: UITableViewController {
}
}
+ @objc func textDidChange(_ note: Notification) {
+ actionButton.isEnabled = !(emailTextField.text?.isEmpty ?? false) && !(passwordTextField.text?.isEmpty ?? false)
+ }
+
private func showError(_ message: String) {
presentError(title: "Error", message: message)
}
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index dbf3d88a5..5079063cf 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -3,7 +3,6 @@
-
@@ -440,15 +439,13 @@
-
+
-
-
-
+
@@ -473,7 +470,7 @@
-
+
@@ -679,15 +676,13 @@
-
+
-
-
-
+
@@ -789,22 +784,20 @@
-
+
-
+
-
-
-
+
@@ -1089,8 +1082,5 @@
-
-
-
diff --git a/iOS/UIKit Extensions/VibrantButton.swift b/iOS/UIKit Extensions/VibrantButton.swift
index 6c60e1dfc..8e070e4d1 100644
--- a/iOS/UIKit Extensions/VibrantButton.swift
+++ b/iOS/UIKit Extensions/VibrantButton.swift
@@ -26,6 +26,7 @@ class VibrantButton: UIButton {
override var isHighlighted: Bool {
didSet {
backgroundColor = isHighlighted ? AppAssets.secondaryAccentColor : nil
+ titleLabel?.alpha = 1
}
}
From 2f00285197467cebc96fb04094b3a5f25fdf3a39 Mon Sep 17 00:00:00 2001
From: Daniel Jalkut
Date: Tue, 22 Oct 2019 10:49:32 -0400
Subject: [PATCH 20/50] Add missing xcconfig file for MAS version of Safari
extension.
---
...afariextension_target_macappstore.xcconfig | 44 +++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 xcconfig/NetNewsWire_safariextension_target_macappstore.xcconfig
diff --git a/xcconfig/NetNewsWire_safariextension_target_macappstore.xcconfig b/xcconfig/NetNewsWire_safariextension_target_macappstore.xcconfig
new file mode 100644
index 000000000..c9f4822a1
--- /dev/null
+++ b/xcconfig/NetNewsWire_safariextension_target_macappstore.xcconfig
@@ -0,0 +1,44 @@
+CODE_SIGN_IDENTITY[config=Release] = 3rd Party Mac Developer Application
+CODE_SIGN_IDENTITY[config=Debug] = -
+DEVELOPMENT_TEAM = M8L2WTLA8W
+CODE_SIGN_STYLE = Manual
+ORGANIZATION_IDENTIFIER = com.ranchero
+PROVISIONING_PROFILE_SPECIFIER =
+
+// developers can locally override the Xcode settings for code signing
+// by creating a DeveloperSettings.xcconfig file locally at the appropriate path
+// This allows a pristine project to have code signing set up with the appropriate
+// developer ID and certificates, and for dev to be able to have local settings
+// without needing to check in anything into source control
+//
+// As an example, make a ../../SharedXcodeSettings/DeveloperSettings.xcconfig file and
+// give it the contents
+//
+// CODE_SIGN_IDENTITY[sdk=macosx*] = Mac Developer
+// CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer
+// CODE_SIGN_IDENTITY[sdk=iphonesimulator*] = iPhone Developer
+// DEVELOPMENT_TEAM =
+// ORGANIZATION_IDENTIFIER =
+// CODE_SIGN_STYLE = Automatic
+// PROVISIONING_PROFILE_SPECIFIER =
+//
+// And you should be able to build without code signing errors and without modifying
+// the NetNewsWire Xcode project.
+//
+// Example: if your NetNewsWire Xcode project file is at
+// /Users/Shared/git/NetNewsWire/NetNewsWire.xcodeproj
+// create your DeveloperSettings.xcconfig file at
+// /Users/Shared/git/SharedXcodeSettings/DeveloperSettings.xcconfig
+//
+
+#include? "../../SharedXcodeSettings/DeveloperSettings.xcconfig"
+#include "./common/NetNewsWire_mac_target_common.xcconfig"
+
+CODE_SIGN_ENTITLEMENTS = Mac/SafariExtension/Subscribe_to_Feed.entitlements
+INFOPLIST_FILE = Mac/SafariExtension/Info.plist
+LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks
+PRODUCT_BUNDLE_IDENTIFIER = $(ORGANIZATION_IDENTIFIER).NetNewsWire-Evergreen.MAS.Subscribe-to-Feed
+PRODUCT_NAME = $(TARGET_NAME)
+OTHER_SWIFT_FLAGS = -DMAC_APP_STORE $(inherited)
+
+SDKROOT = macosx
From 8a798a2478e5f48195cb37db74fe16010b31a8fc Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 10:32:35 -0500
Subject: [PATCH 21/50] Add multiple account capabilities for import/export
OPML
---
iOS/Settings/SettingsViewController.swift | 93 ++++++++++++++++++++---
1 file changed, 82 insertions(+), 11 deletions(-)
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index b8aa300a3..6e197fb72 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -13,6 +13,8 @@ import SafariServices
class SettingsViewController: UITableViewController {
private let appNewsURLString = "https://nnw.ranchero.com/feed.json"
+ private weak var opmlAccount: Account?
+
static let preferredContentSizeForFormSheetDisplay = CGSize(width: 460.0, height: 400.0)
@IBOutlet weak var refreshIntervalLabel: UILabel!
@@ -126,9 +128,15 @@ class SettingsViewController: UITableViewController {
let timeline = UIStoryboard.settings.instantiateController(ofType: RefreshIntervalViewController.self)
self.navigationController?.pushViewController(timeline, animated: true)
case 1:
- importOPML()
+ if let sourceView = tableView.cellForRow(at: indexPath) {
+ let sourceRect = tableView.rectForRow(at: indexPath)
+ importOPML(sourceView: sourceView, sourceRect: sourceRect)
+ }
case 2:
- exportOPML()
+ if let sourceView = tableView.cellForRow(at: indexPath) {
+ let sourceRect = tableView.rectForRow(at: indexPath)
+ exportOPML(sourceView: sourceView, sourceRect: sourceRect)
+ }
default:
break
}
@@ -226,11 +234,9 @@ class SettingsViewController: UITableViewController {
extension SettingsViewController: UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
-
for url in urls {
- AccountManager.shared.defaultAccount.importOPML(url) { result in}
+ opmlAccount?.importOPML(url) { result in}
}
-
}
}
@@ -258,20 +264,86 @@ private extension SettingsViewController {
presentingParentController?.present(addNavViewController, animated: true)
}
- func importOPML() {
+ func importOPML(sourceView: UIView, sourceRect: CGRect) {
+ switch AccountManager.shared.activeAccounts.count {
+ case 0:
+ presentError(title: "Error", message: NSLocalizedString("You must have at least one active account.", comment: "Missing active account"))
+ case 1:
+ opmlAccount = AccountManager.shared.activeAccounts.first
+ importOPMLDocumentPicker()
+ default:
+ importOPMLAccountPicker(sourceView: sourceView, sourceRect: sourceRect)
+ }
+ }
+
+ func importOPMLAccountPicker(sourceView: UIView, sourceRect: CGRect) {
+ let title = NSLocalizedString("Select an Import Account", comment: "Select an Import Account")
+ let alert = UIAlertController(title: title, message: nil, preferredStyle: .actionSheet)
+ if let popoverController = alert.popoverPresentationController {
+ popoverController.sourceView = view
+ popoverController.sourceRect = sourceRect
+ }
+
+ for account in AccountManager.shared.activeAccounts {
+ let action = UIAlertAction(title: account.nameForDisplay, style: .default) { [weak self] action in
+ self?.opmlAccount = account
+ self?.importOPMLDocumentPicker()
+ }
+ alert.addAction(action)
+ }
+
+ let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
+ alert.addAction(UIAlertAction(title: cancelTitle, style: .cancel))
+
+ self.present(alert, animated: true)
+ }
+
+ func importOPMLDocumentPicker() {
let docPicker = UIDocumentPickerViewController(documentTypes: ["public.xml", "org.opml.opml"], in: .import)
docPicker.delegate = self
docPicker.modalPresentationStyle = .formSheet
self.present(docPicker, animated: true)
-
}
- func exportOPML() {
+ func exportOPML(sourceView: UIView, sourceRect: CGRect) {
+ if AccountManager.shared.accounts.count == 1 {
+ exportOPMLDocumentPicker()
+ } else {
+ exportOPMLAccountPicker(sourceView: sourceView, sourceRect: sourceRect)
+ }
+ }
+
+ func exportOPMLAccountPicker(sourceView: UIView, sourceRect: CGRect) {
+ let title = NSLocalizedString("Select an Export Account", comment: "Select an Export Account")
+ let alert = UIAlertController(title: title, message: nil, preferredStyle: .actionSheet)
- let filename = "MySubscriptions.opml"
+ if let popoverController = alert.popoverPresentationController {
+ popoverController.sourceView = view
+ popoverController.sourceRect = sourceRect
+ }
+
+ for account in AccountManager.shared.accounts {
+ let action = UIAlertAction(title: account.nameForDisplay, style: .default) { [weak self] action in
+ self?.opmlAccount = account
+ self?.exportOPMLDocumentPicker()
+ }
+ alert.addAction(action)
+ }
+
+ let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
+ alert.addAction(UIAlertAction(title: cancelTitle, style: .cancel))
+
+ self.present(alert, animated: true)
+ }
+
+ func exportOPMLDocumentPicker() {
+ guard let account = opmlAccount else { return }
+
+ 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: AccountManager.shared.defaultAccount, title: filename)
+ let opmlString = OPMLExporter.OPMLString(with: account, title: filename)
do {
try opmlString.write(to: tempFile, atomically: true, encoding: String.Encoding.utf8)
} catch {
@@ -281,7 +353,6 @@ private extension SettingsViewController {
let docPicker = UIDocumentPickerViewController(url: tempFile, in: .exportToService)
docPicker.modalPresentationStyle = .formSheet
self.present(docPicker, animated: true)
-
}
func openURL(_ urlString: String) {
From 6b1cccc831e47e53bbb5869dfbdf5c7e184e904d Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 12:45:13 -0500
Subject: [PATCH 22/50] Update build instructions to note that we need to do a
recursive now on the submodule update
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 4cf518fe3..b8f9fe4d7 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ See the [Contributing](CONTRIBUTING.md) page for our process. It’s pretty stra
```bash
git clone https://github.com/brentsimmons/NetNewsWire.git
cd NetNewsWire
-git submodule update --init
+git submodule update --init --recursive
```
You can locally override the Xcode settings for code signing
From 9e8764377f0782dd95022294540556e42990b951 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 13:27:43 -0500
Subject: [PATCH 23/50] Make test configuration look for release configurations
as well
---
xcconfig/NetNewsWire_project_test.xcconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/xcconfig/NetNewsWire_project_test.xcconfig b/xcconfig/NetNewsWire_project_test.xcconfig
index ad10a9ae1..fa08e7ae8 100644
--- a/xcconfig/NetNewsWire_project_test.xcconfig
+++ b/xcconfig/NetNewsWire_project_test.xcconfig
@@ -1,3 +1,4 @@
#include "./NetNewsWire_project_debug.xcconfig"
OTHER_SWIFT_FLAGS = -DTEST $(inherited)
+FRAMEWORK_SEARCH_PATHS = $(inherited) $(SYMROOT)/Release$(EFFECTIVE_PLATFORM_NAME)
From 74616463e8946dfe32f456598080a14840892d26 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 13:38:11 -0500
Subject: [PATCH 24/50] Updated build instructions and updated Sparkle branch
---
README.md | 2 +-
submodules/Sparkle | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index b8f9fe4d7..f0e717aa5 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ See the [Contributing](CONTRIBUTING.md) page for our process. It’s pretty stra
```bash
git clone https://github.com/brentsimmons/NetNewsWire.git
cd NetNewsWire
-git submodule update --init --recursive
+git submodule update --init --recursive --remote
```
You can locally override the Xcode settings for code signing
diff --git a/submodules/Sparkle b/submodules/Sparkle
index d5222353e..67819be18 160000
--- a/submodules/Sparkle
+++ b/submodules/Sparkle
@@ -1 +1 @@
-Subproject commit d5222353e6d6ee7baf4c18711e5b897fe2ed886a
+Subproject commit 67819be18a4ef48e85ea30dbbf8de582f5ef405c
From ddbf7a11afb94a4099f8eea524f850bec04fbc32 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 13:42:35 -0500
Subject: [PATCH 25/50] Correct build instructions
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index f0e717aa5..b8f9fe4d7 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ See the [Contributing](CONTRIBUTING.md) page for our process. It’s pretty stra
```bash
git clone https://github.com/brentsimmons/NetNewsWire.git
cd NetNewsWire
-git submodule update --init --recursive --remote
+git submodule update --init --recursive
```
You can locally override the Xcode settings for code signing
From 9cad9d04b9b945e84288a93b2883498971ad384a Mon Sep 17 00:00:00 2001
From: Brent Simmons
Date: Tue, 22 Oct 2019 13:09:36 -0700
Subject: [PATCH 26/50] Update appcasts for 5.0.3.
---
Appcasts/netnewswire-beta.xml | 12 +++++++++++-
Appcasts/netnewswire-release.xml | 33 ++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/Appcasts/netnewswire-beta.xml b/Appcasts/netnewswire-beta.xml
index 1c67ebe4d..acd2dce0a 100755
--- a/Appcasts/netnewswire-beta.xml
+++ b/Appcasts/netnewswire-beta.xml
@@ -6,7 +6,17 @@
Most recent NetNewsWire changes with links to updates.
en
- -
+
-
+
NetNewsWire 5.0.3
+ Same as 5.0.3b2 — just bumped the version number to 5.0.3.
+ ]]>
+ Tue, 22 Oct 2019 13:00:00 -0700
+
+ 10.14.4
+
+
+ -
NetNewsWire 5.0.3b2
Significantly enhanced performance during syncs and refreshes.
diff --git a/Appcasts/netnewswire-release.xml b/Appcasts/netnewswire-release.xml
index 38abd7a04..cb77af68b 100755
--- a/Appcasts/netnewswire-release.xml
+++ b/Appcasts/netnewswire-release.xml
@@ -6,6 +6,39 @@
Most recent NetNewsWire releases (not test builds). Well, we’re including test builds up until 5.0 ships, but after that it won’t be test builds.
en
+ -
+
NetNewsWire 5.0.3
+ Significantly enhanced performance during syncs and refreshes. Fetching articles from the database is also faster.
+
+When running for the first time, and the user previously used NetNewsWire 3, it will automatically import NetNewsWire 3 subscriptions instead of the defaults for new users.
+
+You can also import NetNewsWire 3 subscriptions via the new File > Import NNW3 Subscriptions… command.
+
+Keyboard shortcuts: the 's' key toggles starred status. The 'r' and 'u' keys now both toggle read status (instead of setting read and unread status, respectively).
+
+Articles view: articles where the feed icon is quite large would be slow to render — now they render as fast as other articles.
+
+Articles view: a bug where keyboard shortcuts wouldn’t work after giving the articles view focus has been fixed.
+
+Articles view: YouTube videos could end up small. Fixed.
+
+Articles view: fixed a bug scaling images to fit in the view.
+
+Fixed the space bar when running on Catalina. It wouldn’t advance to the next unread — now it will. (This was due to a change in JavaScript in Catalina.)
+
+Fixed a crashing bug having to do with async database fetches for the timeline.
+
+Feedbin syncing: fixed a bug where renaming a tag on the Feedbin site would result in feeds in NNW ending up at the top level.
+
+Help menu: fixed the expired Slack link.
+
+ ]]>
+ Tue, 22 Oct 2019 13:00:00 -0700
+
+ 10.14.4
+
+
-
NetNewsWire 5.0.2
Date: Tue, 22 Oct 2019 15:42:48 -0500
Subject: [PATCH 27/50] Restrict builds to pushes to master and mac-release
---
.github/workflows/build.yml | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 65cff4bd6..c62955b65 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,6 +1,10 @@
name: CI
-on: [push]
+on:
+ push:
+ branches:
+ - master
+ - mac-release
jobs:
build:
From d4816506f2f30c457f15a9392661656ba9f2276c Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 16:13:08 -0500
Subject: [PATCH 28/50] Disable sparkle for test builds
---
Mac/AppDelegate.swift | 7 -------
xcconfig/NetNewsWire_project_test.xcconfig | 1 -
2 files changed, 8 deletions(-)
diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift
index 117285763..4a2002597 100644
--- a/Mac/AppDelegate.swift
+++ b/Mac/AppDelegate.swift
@@ -13,9 +13,6 @@ import RSTree
import RSWeb
import Account
import RSCore
-#if TEST
-import Sparkle
-#endif
var appDelegate: AppDelegate!
@@ -117,10 +114,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
func applicationWillFinishLaunching(_ notification: Notification) {
installAppleEventHandlers()
- #if TEST
- // Don't prompt for updates while running automated tests
- SUUpdater.shared()?.automaticallyChecksForUpdates = false
- #endif
}
func applicationDidFinishLaunching(_ note: Notification) {
diff --git a/xcconfig/NetNewsWire_project_test.xcconfig b/xcconfig/NetNewsWire_project_test.xcconfig
index fa08e7ae8..ad10a9ae1 100644
--- a/xcconfig/NetNewsWire_project_test.xcconfig
+++ b/xcconfig/NetNewsWire_project_test.xcconfig
@@ -1,4 +1,3 @@
#include "./NetNewsWire_project_debug.xcconfig"
OTHER_SWIFT_FLAGS = -DTEST $(inherited)
-FRAMEWORK_SEARCH_PATHS = $(inherited) $(SYMROOT)/Release$(EFFECTIVE_PLATFORM_NAME)
From 57eadcdb22ab23dc2c224d63dcb0465e49bb741e Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 16:18:48 -0500
Subject: [PATCH 29/50] Add mac-candidate and future ios branches to build
trigger
---
.github/workflows/build.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c62955b65..7ec5b8ce8 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -4,7 +4,10 @@ on:
push:
branches:
- master
+ - mac-candidate
- mac-release
+ - ios-candidate
+ - ios-release
jobs:
build:
From e80a5f92bb5be686d7fc830dfa156e12cb2baa68 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 16:42:17 -0500
Subject: [PATCH 30/50] Readd the SUUpdater code
---
Mac/AppDelegate.swift | 7 +++++++
xcconfig/NetNewsWire_project_test.xcconfig | 1 +
2 files changed, 8 insertions(+)
diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift
index 4a2002597..117285763 100644
--- a/Mac/AppDelegate.swift
+++ b/Mac/AppDelegate.swift
@@ -13,6 +13,9 @@ import RSTree
import RSWeb
import Account
import RSCore
+#if TEST
+import Sparkle
+#endif
var appDelegate: AppDelegate!
@@ -114,6 +117,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
func applicationWillFinishLaunching(_ notification: Notification) {
installAppleEventHandlers()
+ #if TEST
+ // Don't prompt for updates while running automated tests
+ SUUpdater.shared()?.automaticallyChecksForUpdates = false
+ #endif
}
func applicationDidFinishLaunching(_ note: Notification) {
diff --git a/xcconfig/NetNewsWire_project_test.xcconfig b/xcconfig/NetNewsWire_project_test.xcconfig
index ad10a9ae1..fa08e7ae8 100644
--- a/xcconfig/NetNewsWire_project_test.xcconfig
+++ b/xcconfig/NetNewsWire_project_test.xcconfig
@@ -1,3 +1,4 @@
#include "./NetNewsWire_project_debug.xcconfig"
OTHER_SWIFT_FLAGS = -DTEST $(inherited)
+FRAMEWORK_SEARCH_PATHS = $(inherited) $(SYMROOT)/Release$(EFFECTIVE_PLATFORM_NAME)
From 8189695b2902392514a9bbe8f016c5d4c418af02 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 17:18:37 -0500
Subject: [PATCH 31/50] Put accounts in the correct order on OPML
import/export.
---
iOS/Settings/SettingsViewController.swift | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index 6e197fb72..0c268ac1d 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -285,7 +285,7 @@ private extension SettingsViewController {
popoverController.sourceRect = sourceRect
}
- for account in AccountManager.shared.activeAccounts {
+ for account in AccountManager.shared.sortedActiveAccounts {
let action = UIAlertAction(title: account.nameForDisplay, style: .default) { [weak self] action in
self?.opmlAccount = account
self?.importOPMLDocumentPicker()
@@ -323,7 +323,7 @@ private extension SettingsViewController {
popoverController.sourceRect = sourceRect
}
- for account in AccountManager.shared.accounts {
+ for account in AccountManager.shared.sortedAccounts {
let action = UIAlertAction(title: account.nameForDisplay, style: .default) { [weak self] action in
self?.opmlAccount = account
self?.exportOPMLDocumentPicker()
From b0881f47fc8fc66bd44198d1cf0771953beabb1b Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 17:22:02 -0500
Subject: [PATCH 32/50] Remove dead code
---
iOS/SceneCoordinator.swift | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift
index 9723f0d17..ab57d6523 100644
--- a/iOS/SceneCoordinator.swift
+++ b/iOS/SceneCoordinator.swift
@@ -8,7 +8,6 @@
import UIKit
import UserNotifications
-import SwiftUI
import Account
import Articles
import RSCore
@@ -1699,20 +1698,3 @@ private extension SceneCoordinator {
}
}
-
-// MARK: SwiftUI
-
-struct SceneCoordinatorHolder {
- weak var value: SceneCoordinator?
-}
-
-struct SceneCoordinatorKey: EnvironmentKey {
- static var defaultValue: SceneCoordinatorHolder { return SceneCoordinatorHolder(value: nil ) }
-}
-
-extension EnvironmentValues {
- var sceneCoordinator: SceneCoordinator? {
- get { return self[SceneCoordinatorKey.self].value }
- set { self[SceneCoordinatorKey.self].value = newValue }
- }
-}
From 471c8ce6672ba108c117774f08ba67e41b1126b7 Mon Sep 17 00:00:00 2001
From: Daniel Jalkut
Date: Tue, 22 Oct 2019 19:33:00 -0400
Subject: [PATCH 33/50] Switch to SPUUpdater and establish our own single
instance of this updater in the app delegate. If we're building for App Store
or a TEST build, don't even initialize Sparkle.
---
Mac/AppDelegate.swift | 33 ++++++++++++++++++++-------
Mac/Base.lproj/Main.storyboard | 3 +--
Mac/Base.lproj/Preferences.storyboard | 16 +++----------
3 files changed, 29 insertions(+), 23 deletions(-)
diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift
index 117285763..9e4c8207e 100644
--- a/Mac/AppDelegate.swift
+++ b/Mac/AppDelegate.swift
@@ -13,14 +13,14 @@ import RSTree
import RSWeb
import Account
import RSCore
-#if TEST
+#if !MAC_APP_STORE && !TEST
import Sparkle
#endif
var appDelegate: AppDelegate!
@NSApplicationMain
-class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, UNUserNotificationCenterDelegate, UnreadCountProvider {
+class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, UNUserNotificationCenterDelegate, UnreadCountProvider, SPUStandardUserDriverDelegate, SPUUpdaterDelegate {
var userNotificationManager: UserNotificationManager!
var faviconDownloader: FaviconDownloader!
@@ -70,6 +70,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
private let log = Log()
private let appNewsURLString = "https://nnw.ranchero.com/feed.json"
private let appMovementMonitor = RSAppMovementMonitor()
+ #if !MAC_APP_STORE && !TEST
+ private var softwareUpdater: SPUUpdater!
+ #endif
override init() {
NSWindow.allowsAutomaticWindowTabbing = false
@@ -117,16 +120,24 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
func applicationWillFinishLaunching(_ notification: Notification) {
installAppleEventHandlers()
- #if TEST
- // Don't prompt for updates while running automated tests
- SUUpdater.shared()?.automaticallyChecksForUpdates = false
- #endif
}
func applicationDidFinishLaunching(_ note: Notification) {
- #if MAC_APP_STORE
+ #if MAC_APP_STORE || TEST
checkForUpdatesMenuItem.isHidden = true
+ #else
+ // Initialize Sparkle...
+ let hostBundle = Bundle.main
+ let updateDriver = SPUStandardUserDriver(hostBundle: hostBundle, delegate: self)
+ self.softwareUpdater = SPUUpdater(hostBundle: hostBundle, applicationBundle: hostBundle, userDriver: updateDriver, delegate: self)
+
+ do {
+ try self.softwareUpdater.start()
+ }
+ catch {
+ NSLog("Failed to start software updater with error: \(error)")
+ }
#endif
appName = (Bundle.main.infoDictionary!["CFBundleExecutable"]! as! String)
@@ -571,7 +582,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
@IBAction func groupByFeedToggled(_ sender: NSMenuItem) {
AppDefaults.timelineGroupByFeed.toggle()
}
-
+
+ @IBAction func checkForUpdates(_ sender: Any?) {
+ #if !MAC_APP_STORE && !TEST
+ self.softwareUpdater.checkForUpdates()
+ #endif
+ }
+
}
// MARK: - Debug Menu
diff --git a/Mac/Base.lproj/Main.storyboard b/Mac/Base.lproj/Main.storyboard
index 498fdd35f..ba4a9a4de 100644
--- a/Mac/Base.lproj/Main.storyboard
+++ b/Mac/Base.lproj/Main.storyboard
@@ -30,7 +30,7 @@
-
+
@@ -623,7 +623,6 @@
-
diff --git a/Mac/Base.lproj/Preferences.storyboard b/Mac/Base.lproj/Preferences.storyboard
index 46d049133..6b2ac07d5 100644
--- a/Mac/Base.lproj/Preferences.storyboard
+++ b/Mac/Base.lproj/Preferences.storyboard
@@ -234,17 +234,7 @@
-
-
-
-
-
-
-
-
-
-
-
+
@@ -293,7 +283,7 @@
-
+
@@ -382,8 +372,8 @@
-
+
From 8e37881ed875f4461d88f44bd2f6912b62ab5862 Mon Sep 17 00:00:00 2001
From: Daniel Jalkut
Date: Tue, 22 Oct 2019 19:44:06 -0400
Subject: [PATCH 34/50] Protect against unrecognized protocol errors when
building for MAC_APP_STORE or TEST.
---
Mac/AppDelegate.swift | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift
index 9e4c8207e..52eedd75e 100644
--- a/Mac/AppDelegate.swift
+++ b/Mac/AppDelegate.swift
@@ -13,14 +13,21 @@ import RSTree
import RSWeb
import Account
import RSCore
-#if !MAC_APP_STORE && !TEST
+
+// If we're not going to import Sparkle, provide dummy protocols to make it easy
+// for AppDelegate to comply
+#if MAC_APP_STORE || TEST
+protocol SPUStandardUserDriverDelegate {}
+protocol SPUUpdaterDelegate {}
+#else
import Sparkle
#endif
var appDelegate: AppDelegate!
@NSApplicationMain
-class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, UNUserNotificationCenterDelegate, UnreadCountProvider, SPUStandardUserDriverDelegate, SPUUpdaterDelegate {
+class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, UNUserNotificationCenterDelegate, UnreadCountProvider, SPUStandardUserDriverDelegate, SPUUpdaterDelegate
+{
var userNotificationManager: UserNotificationManager!
var faviconDownloader: FaviconDownloader!
From 7b51a272b0f21e4089935ae4168ac078d475a873 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Tue, 22 Oct 2019 19:20:35 -0500
Subject: [PATCH 35/50] Only clear Feed/Timeline selection after view begins to
appear. Issue #1156
---
iOS/Base.lproj/Main.storyboard | 2 +-
iOS/MasterFeed/MasterFeedViewController.swift | 5 ++-
.../MasterTimelineViewController.swift | 5 ++-
iOS/SceneCoordinator.swift | 1 +
iOS/Settings/Settings.storyboard | 2 +-
iOS/Settings/SettingsViewController.swift | 31 +++++++++++++++----
submodules/RSCore | 2 +-
7 files changed, 33 insertions(+), 15 deletions(-)
diff --git a/iOS/Base.lproj/Main.storyboard b/iOS/Base.lproj/Main.storyboard
index df20db9ac..994202c66 100644
--- a/iOS/Base.lproj/Main.storyboard
+++ b/iOS/Base.lproj/Main.storyboard
@@ -121,7 +121,7 @@
-
+
diff --git a/iOS/MasterFeed/MasterFeedViewController.swift b/iOS/MasterFeed/MasterFeedViewController.swift
index 7022f7a7f..65e6092a2 100644
--- a/iOS/MasterFeed/MasterFeedViewController.swift
+++ b/iOS/MasterFeed/MasterFeedViewController.swift
@@ -68,7 +68,6 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
override func viewWillAppear(_ animated: Bool) {
navigationController?.title = NSLocalizedString("Feeds", comment: "Feeds")
- clearsSelectionOnViewWillAppear = coordinator.isRootSplitCollapsed
applyChanges(animate: false)
super.viewWillAppear(animated)
}
@@ -451,7 +450,7 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
func restoreSelectionIfNecessary(adjustScroll: Bool) {
if let indexPath = coordinator.masterFeedIndexPathForCurrentTimeline() {
if adjustScroll {
- tableView.selectRowAndScrollIfNotVisible(at: indexPath, animated: false, deselect: coordinator.isRootSplitCollapsed)
+ tableView.selectRowAndScrollIfNotVisible(at: indexPath, animated: false)
} else {
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
}
@@ -462,7 +461,7 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
if dataSource.snapshot().numberOfItems > 0 {
if let indexPath = coordinator.currentFeedIndexPath {
if tableView.indexPathForSelectedRow != indexPath {
- tableView.selectRowAndScrollIfNotVisible(at: indexPath, animated: true, deselect: coordinator.isRootSplitCollapsed)
+ tableView.selectRowAndScrollIfNotVisible(at: indexPath, animated: true)
}
} else {
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
diff --git a/iOS/MasterTimeline/MasterTimelineViewController.swift b/iOS/MasterTimeline/MasterTimelineViewController.swift
index 8c74296ab..2dd9a9a2a 100644
--- a/iOS/MasterTimeline/MasterTimelineViewController.swift
+++ b/iOS/MasterTimeline/MasterTimelineViewController.swift
@@ -76,7 +76,6 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
}
override func viewWillAppear(_ animated: Bool) {
- clearsSelectionOnViewWillAppear = coordinator.isRootSplitCollapsed
applyChanges(animate: false)
super.viewWillAppear(animated)
}
@@ -132,7 +131,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
func restoreSelectionIfNecessary(adjustScroll: Bool) {
if let article = coordinator.currentArticle, let indexPath = dataSource.indexPath(for: article) {
if adjustScroll {
- tableView.selectRowAndScrollIfNotVisible(at: indexPath, animated: false, deselect: coordinator.isRootSplitCollapsed)
+ tableView.selectRowAndScrollIfNotVisible(at: indexPath, animated: false)
} else {
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
}
@@ -150,7 +149,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
func updateArticleSelection(animated: Bool) {
if let article = coordinator.currentArticle, let indexPath = dataSource.indexPath(for: article) {
if tableView.indexPathForSelectedRow != indexPath {
- tableView.selectRowAndScrollIfNotVisible(at: indexPath, animated: true, deselect: coordinator.isRootSplitCollapsed)
+ tableView.selectRowAndScrollIfNotVisible(at: indexPath, animated: true)
}
} else {
tableView.selectRow(at: nil, animated: animated, scrollPosition: .none)
diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift
index ab57d6523..e97a63e19 100644
--- a/iOS/SceneCoordinator.swift
+++ b/iOS/SceneCoordinator.swift
@@ -950,6 +950,7 @@ extension SceneCoordinator: UINavigationControllerDelegate {
if viewController === masterTimelineViewController && !isThreePanelMode && rootSplitViewController.isCollapsed && !isArticleViewControllerPending {
stopArticleExtractor()
currentArticle = nil
+ masterTimelineViewController?.updateArticleSelection(animated: animated)
activityManager.invalidateReading()
return
}
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 5079063cf..617b76467 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -9,7 +9,7 @@
-
+
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index 0c268ac1d..b88d37246 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -29,7 +29,10 @@ class SettingsViewController: UITableViewController {
// This hack mostly works around a bug in static tables with dynamic type. See: https://spin.atomicobject.com/2018/10/15/dynamic-type-static-uitableview/
NotificationCenter.default.removeObserver(tableView!, name: UIContentSizeCategory.didChangeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryDidChange), name: UIContentSizeCategory.didChangeNotification, object: nil)
-
+
+ NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidAddAccount, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidDeleteAccount, object: nil)
+
tableView.register(UINib(nibName: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
}
@@ -63,8 +66,11 @@ class SettingsViewController: UITableViewController {
buildLabel.translatesAutoresizingMaskIntoConstraints = false
tableView.tableFooterView = buildLabel
- tableView.reloadData()
-
+ }
+
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ self.tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
}
// MARK: UITableView
@@ -112,6 +118,7 @@ class SettingsViewController: UITableViewController {
switch indexPath.section {
case 0:
UIApplication.shared.open(URL(string: "\(UIApplication.openSettingsURLString)")!)
+ tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
case 1:
let sortedAccounts = AccountManager.shared.sortedAccounts
if indexPath.row == sortedAccounts.count {
@@ -128,11 +135,13 @@ class SettingsViewController: UITableViewController {
let timeline = UIStoryboard.settings.instantiateController(ofType: RefreshIntervalViewController.self)
self.navigationController?.pushViewController(timeline, animated: true)
case 1:
+ tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
if let sourceView = tableView.cellForRow(at: indexPath) {
let sourceRect = tableView.rectForRow(at: indexPath)
importOPML(sourceView: sourceView, sourceRect: sourceRect)
}
case 2:
+ tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
if let sourceView = tableView.cellForRow(at: indexPath) {
let sourceRect = tableView.rectForRow(at: indexPath)
exportOPML(sourceView: sourceView, sourceRect: sourceRect)
@@ -147,24 +156,28 @@ class SettingsViewController: UITableViewController {
self.navigationController?.pushViewController(timeline, animated: true)
case 1:
openURL("https://ranchero.com/netnewswire/")
+ tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
case 2:
openURL("https://github.com/brentsimmons/NetNewsWire/blob/master/Technotes/HowToSupportNetNewsWire.markdown")
+ tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
case 3:
openURL("https://github.com/brentsimmons/NetNewsWire")
+ tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
case 4:
openURL("https://github.com/brentsimmons/NetNewsWire/issues")
+ tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
case 5:
openURL("https://github.com/brentsimmons/NetNewsWire/tree/master/Technotes")
+ tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
case 6:
addFeed()
+ tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
default:
break
}
default:
- break
+ tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
}
-
- tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
@@ -223,10 +236,16 @@ class SettingsViewController: UITableViewController {
updateNumberOfTextLinesLabel(value: numberOfLines)
}
+ // MARK: Notifications
+
@objc func contentSizeCategoryDidChange() {
tableView.reloadData()
}
+ @objc func accountsDidChange() {
+ tableView.reloadData()
+ }
+
}
// MARK: OPML Document Picker
diff --git a/submodules/RSCore b/submodules/RSCore
index 29dc34284..fa16a5b1a 160000
--- a/submodules/RSCore
+++ b/submodules/RSCore
@@ -1 +1 @@
-Subproject commit 29dc34284b64af4a399d1cf3927c3469851ec0ad
+Subproject commit fa16a5b1a0bc45bb6aee6145e1095446a84f386b
From 17af3f28bf1205820882a7cba880856df68b99a3 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 08:53:09 -0500
Subject: [PATCH 36/50] Hide unread account information unless the Account is
collapsed. Issue #1159
---
.../Cell/MasterFeedTableViewSectionHeader.swift | 11 ++++++++++-
iOS/MasterFeed/MasterFeedViewController.swift | 1 -
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift
index 901184ec6..07d6ab35c 100644
--- a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift
+++ b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift
@@ -29,7 +29,7 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView {
set {
if unreadCountView.unreadCount != newValue {
unreadCountView.unreadCount = newValue
- unreadCountView.isHidden = (newValue < 1)
+ updateUnreadCountView()
setNeedsLayout()
}
}
@@ -51,6 +51,7 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView {
var disclosureExpanded = false {
didSet {
updateDisclosureImage()
+ updateUnreadCountView()
}
}
@@ -141,6 +142,14 @@ private extension MasterFeedTableViewSectionHeader {
}
}
}
+
+ func updateUnreadCountView() {
+ if !disclosureExpanded && unreadCount > 0 {
+ unreadCountView.isHidden = false
+ } else {
+ self.unreadCountView.isHidden = true
+ }
+ }
func addSubviewAtInit(_ view: UIView) {
addSubview(view)
diff --git a/iOS/MasterFeed/MasterFeedViewController.swift b/iOS/MasterFeed/MasterFeedViewController.swift
index 65e6092a2..039e5b036 100644
--- a/iOS/MasterFeed/MasterFeedViewController.swift
+++ b/iOS/MasterFeed/MasterFeedViewController.swift
@@ -11,7 +11,6 @@ import Account
import Articles
import RSCore
import RSTree
-import SwiftUI
class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
From 7448523c66850a99fc50bfb9d7f4dd2d0e53d09b Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 09:03:34 -0500
Subject: [PATCH 37/50] Correct issue where toolbar tint color could get lost
in darkmode and transitioning to the background
---
iOS/UIKit Extensions/ThemedNavigationController.swift | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/iOS/UIKit Extensions/ThemedNavigationController.swift b/iOS/UIKit Extensions/ThemedNavigationController.swift
index 979d83b78..058e6afa5 100644
--- a/iOS/UIKit Extensions/ThemedNavigationController.swift
+++ b/iOS/UIKit Extensions/ThemedNavigationController.swift
@@ -34,10 +34,10 @@ class ThemedNavigationController: UINavigationController {
if traitCollection.userInterfaceStyle == .dark {
navigationBar.standardAppearance = UINavigationBarAppearance()
- navigationBar.tintColor = view.tintColor
+ navigationBar.tintColor = AppAssets.primaryAccentColor
toolbar.standardAppearance = UIToolbarAppearance()
toolbar.compactAppearance = UIToolbarAppearance()
- toolbar.tintColor = view.tintColor
+ toolbar.tintColor = AppAssets.primaryAccentColor
} else {
let navigationAppearance = UINavigationBarAppearance()
navigationAppearance.backgroundColor = AppAssets.barBackgroundColor
From be52fde08b6d8f0d65d4ed5ac5831d24bbdb3a5c Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 09:15:13 -0500
Subject: [PATCH 38/50] Change Timeline Feed icon to 32x32
---
iOS/MasterTimeline/Cell/MasterTimelineDefaultCellLayout.swift | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/iOS/MasterTimeline/Cell/MasterTimelineDefaultCellLayout.swift b/iOS/MasterTimeline/Cell/MasterTimelineDefaultCellLayout.swift
index b1070a2eb..f7ca315c5 100644
--- a/iOS/MasterTimeline/Cell/MasterTimelineDefaultCellLayout.swift
+++ b/iOS/MasterTimeline/Cell/MasterTimelineDefaultCellLayout.swift
@@ -21,7 +21,7 @@ struct MasterTimelineDefaultCellLayout: MasterTimelineCellLayout {
static let starDimension = CGFloat(integerLiteral: 16)
static let starSize = CGSize(width: MasterTimelineDefaultCellLayout.starDimension, height: MasterTimelineDefaultCellLayout.starDimension)
- static let avatarSize = CGSize(width: 48.0, height: 48.0)
+ static let avatarSize = CGSize(width: 32.0, height: 32.0)
static let avatarMarginRight = CGFloat(integerLiteral: 8)
static let avatarCornerRadius = CGFloat(integerLiteral: 4)
From 430a4a37bfaa9a5366b53969d82177fc9f89fb93 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 10:35:53 -0500
Subject: [PATCH 39/50] Add icon next to accounts in the Settings listing.
Issue #1160
---
NetNewsWire.xcodeproj/project.pbxproj | 20 ++++++--
iOS/AppAssets.swift | 26 ++++++++++
.../SettingsAccountTableViewCell.swift | 30 ++++++++++++
iOS/Settings/SettingsAccountTableViewCell.xib | 47 +++++++++++++++++++
iOS/Settings/SettingsViewController.swift | 16 ++++---
5 files changed, 129 insertions(+), 10 deletions(-)
create mode 100644 iOS/Settings/SettingsAccountTableViewCell.swift
create mode 100644 iOS/Settings/SettingsAccountTableViewCell.xib
diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj
index dcbae23cd..1a326e674 100644
--- a/NetNewsWire.xcodeproj/project.pbxproj
+++ b/NetNewsWire.xcodeproj/project.pbxproj
@@ -81,6 +81,9 @@
515D4FC123257A3200EE1167 /* FolderTreeControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97A11ED9F180007D329B /* FolderTreeControllerDelegate.swift */; };
515D4FCA23257CB500EE1167 /* Node-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97971ED9EFAA007D329B /* Node-Extensions.swift */; };
515D4FCC2325815A00EE1167 /* SafariExt.js in Resources */ = {isa = PBXBuildFile; fileRef = 515D4FCB2325815A00EE1167 /* SafariExt.js */; };
+ 516A093723609A3600EAE89B /* SettingsAccountTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 516A091D23609A3600EAE89B /* SettingsAccountTableViewCell.xib */; };
+ 516A09392360A2AE00EAE89B /* SettingsAccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516A09382360A2AE00EAE89B /* SettingsAccountTableViewCell.swift */; };
+ 516A093B2360A4A000EAE89B /* SettingsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */; };
51707439232AA97100A461A3 /* ShareFolderPickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51707438232AA97100A461A3 /* ShareFolderPickerController.swift */; };
5170743A232AABFC00A461A3 /* FlattenedAccountFolderPickerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C452812265093600C03939 /* FlattenedAccountFolderPickerData.swift */; };
517630042336215100E15FFF /* main.js in Resources */ = {isa = PBXBuildFile; fileRef = 517630032336215100E15FFF /* main.js */; };
@@ -106,7 +109,6 @@
519D740623243CC0008BB345 /* RefreshInterval-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519D740523243CC0008BB345 /* RefreshInterval-Extensions.swift */; };
519E743D22C663F900A78E47 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519E743422C663F900A78E47 /* SceneDelegate.swift */; };
51A16997235E10D700EB091F /* RefreshIntervalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A1698D235E10D600EB091F /* RefreshIntervalViewController.swift */; };
- 51A16998235E10D700EB091F /* SettingsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 51A1698E235E10D600EB091F /* SettingsTableViewCell.xib */; };
51A16999235E10D700EB091F /* AddLocalAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A1698F235E10D600EB091F /* AddLocalAccountViewController.swift */; };
51A1699A235E10D700EB091F /* Settings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 51A16990235E10D600EB091F /* Settings.storyboard */; };
51A1699B235E10D700EB091F /* DetailAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16991235E10D600EB091F /* DetailAccountViewController.swift */; };
@@ -1237,6 +1239,9 @@
515D4FCB2325815A00EE1167 /* SafariExt.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = SafariExt.js; sourceTree = ""; };
515D4FCD2325909200EE1167 /* NetNewsWire_iOS_ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NetNewsWire_iOS_ShareExtension.entitlements; sourceTree = ""; };
515D4FCE2325B3D000EE1167 /* NetNewsWire_iOSshareextension_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetNewsWire_iOSshareextension_target.xcconfig; sourceTree = ""; };
+ 516A091D23609A3600EAE89B /* SettingsAccountTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsAccountTableViewCell.xib; sourceTree = ""; };
+ 516A09382360A2AE00EAE89B /* SettingsAccountTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAccountTableViewCell.swift; sourceTree = ""; };
+ 516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsTableViewCell.xib; sourceTree = ""; };
51707438232AA97100A461A3 /* ShareFolderPickerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareFolderPickerController.swift; sourceTree = ""; };
517630032336215100E15FFF /* main.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = ""; };
517630222336657E00E15FFF /* ArticleViewControllerWebViewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleViewControllerWebViewProvider.swift; sourceTree = ""; };
@@ -1258,7 +1263,6 @@
519D740523243CC0008BB345 /* RefreshInterval-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RefreshInterval-Extensions.swift"; sourceTree = ""; };
519E743422C663F900A78E47 /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
51A1698D235E10D600EB091F /* RefreshIntervalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshIntervalViewController.swift; sourceTree = ""; };
- 51A1698E235E10D600EB091F /* SettingsTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsTableViewCell.xib; sourceTree = ""; };
51A1698F235E10D600EB091F /* AddLocalAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddLocalAccountViewController.swift; sourceTree = ""; };
51A16990235E10D600EB091F /* Settings.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = ""; };
51A16991235E10D600EB091F /* DetailAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailAccountViewController.swift; sourceTree = ""; };
@@ -1775,7 +1779,9 @@
51A16991235E10D600EB091F /* DetailAccountViewController.swift */,
51A16996235E10D700EB091F /* FeedbinAccountViewController.swift */,
51A1698D235E10D600EB091F /* RefreshIntervalViewController.swift */,
- 51A1698E235E10D600EB091F /* SettingsTableViewCell.xib */,
+ 516A09382360A2AE00EAE89B /* SettingsAccountTableViewCell.swift */,
+ 516A091D23609A3600EAE89B /* SettingsAccountTableViewCell.xib */,
+ 516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */,
51A16993235E10D600EB091F /* SettingsViewController.swift */,
);
path = Settings;
@@ -2914,6 +2920,10 @@
DevelopmentTeam = SHJK2V3AJG;
ProvisioningStyle = Automatic;
};
+ 65ED4090235DEF770081F399 = {
+ DevelopmentTeam = SHJK2V3AJG;
+ ProvisioningStyle = Automatic;
+ };
840D617B2029031C009BC708 = {
CreatedOnToolsVersion = 9.3;
DevelopmentTeam = SHJK2V3AJG;
@@ -3361,13 +3371,14 @@
51C452862265093600C03939 /* Add.storyboard in Resources */,
511D43EF231FBDE900FB1562 /* LaunchScreenPad.storyboard in Resources */,
511D43D2231FA62C00FB1562 /* GlobalKeyboardShortcuts.plist in Resources */,
- 51A16998235E10D700EB091F /* SettingsTableViewCell.xib in Resources */,
84C9FCA12262A1B300D921D6 /* Main.storyboard in Resources */,
51BB7C312335ACDE008E8144 /* page.html in Resources */,
+ 516A093723609A3600EAE89B /* SettingsAccountTableViewCell.xib in Resources */,
51F85BF32272531500C787DC /* Dedication.rtf in Resources */,
84C9FCA42262A1B800D921D6 /* LaunchScreenPhone.storyboard in Resources */,
51F85BEB22724CB600C787DC /* About.rtf in Resources */,
51F85BED227251DF00C787DC /* Acknowledgments.rtf in Resources */,
+ 516A093B2360A4A000EAE89B /* SettingsTableViewCell.xib in Resources */,
511D43D1231FA62800FB1562 /* SidebarKeyboardShortcuts.plist in Resources */,
51C452AB22650DC600C03939 /* template.html in Resources */,
51F85BF12272524100C787DC /* Credits.rtf in Resources */,
@@ -3866,6 +3877,7 @@
51D87EE12311D34700E63F03 /* ActivityType.swift in Sources */,
51C452772265091600C03939 /* MultilineUILabelSizer.swift in Sources */,
51C452A522650A2D00C03939 /* SmallIconProvider.swift in Sources */,
+ 516A09392360A2AE00EAE89B /* SettingsAccountTableViewCell.swift in Sources */,
51D5948722668EFA00DFC836 /* MarkStatusCommand.swift in Sources */,
51A1699C235E10D700EB091F /* AddAccountViewController.swift in Sources */,
51A16999235E10D700EB091F /* AddLocalAccountViewController.swift in Sources */,
diff --git a/iOS/AppAssets.swift b/iOS/AppAssets.swift
index 55f66027a..dcb1c9227 100644
--- a/iOS/AppAssets.swift
+++ b/iOS/AppAssets.swift
@@ -7,9 +7,22 @@
//
import UIKit
import RSCore
+import Account
struct AppAssets {
+ static var accountLocalImage: UIImage = {
+ return UIImage(named: "accountLocal")!
+ }()
+
+ static var accountFeedbinImage: UIImage = {
+ return UIImage(named: "accountFeedbin")!
+ }()
+
+ static var accountFreshRSSImage: UIImage = {
+ return UIImage(named: "accountFreshRSS")!
+ }()
+
static var articleExtractorError: UIImage = {
return UIImage(named: "articleExtractorError")!
}()
@@ -161,4 +174,17 @@ struct AppAssets {
return UIColor(named: "vibrantTextColor")!
}()
+ static func image(for accountType: AccountType) -> UIImage? {
+ switch accountType {
+ case .onMyMac:
+ return AppAssets.accountLocalImage
+ case .feedbin:
+ return AppAssets.accountFeedbinImage
+ case .freshRSS:
+ return AppAssets.accountFreshRSSImage
+ default:
+ return nil
+ }
+ }
+
}
diff --git a/iOS/Settings/SettingsAccountTableViewCell.swift b/iOS/Settings/SettingsAccountTableViewCell.swift
new file mode 100644
index 000000000..cc45c59b0
--- /dev/null
+++ b/iOS/Settings/SettingsAccountTableViewCell.swift
@@ -0,0 +1,30 @@
+//
+// SettingsAccountTableViewCell.swift
+// NetNewsWire-iOS
+//
+// Created by Maurice Parker on 10/23/19.
+// Copyright © 2019 Ranchero Software. All rights reserved.
+//
+
+import UIKit
+
+class SettingsAccountTableViewCell: VibrantTableViewCell {
+
+ @IBOutlet weak var accountImage: UIImageView!
+ @IBOutlet weak var accountNameLabel: UILabel!
+
+ override func setHighlighted(_ highlighted: Bool, animated: Bool) {
+ super.setHighlighted(highlighted, animated: animated)
+ let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : UIColor.label
+ accountImage?.tintColor = tintColor
+ accountNameLabel?.highlightedTextColor = tintColor
+ }
+
+ override func setSelected(_ selected: Bool, animated: Bool) {
+ super.setSelected(selected, animated: animated)
+ let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : UIColor.label
+ accountImage?.tintColor = tintColor
+ accountNameLabel?.highlightedTextColor = tintColor
+ }
+
+}
diff --git a/iOS/Settings/SettingsAccountTableViewCell.xib b/iOS/Settings/SettingsAccountTableViewCell.xib
new file mode 100644
index 000000000..1b4d94da3
--- /dev/null
+++ b/iOS/Settings/SettingsAccountTableViewCell.xib
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index b88d37246..56fe7f11f 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -33,8 +33,9 @@ class SettingsViewController: UITableViewController {
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidAddAccount, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidDeleteAccount, object: nil)
+ tableView.register(UINib(nibName: "SettingsAccountTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsAccountTableViewCell")
tableView.register(UINib(nibName: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
-
+
}
override func viewWillAppear(_ animated: Bool) {
@@ -94,15 +95,18 @@ class SettingsViewController: UITableViewController {
let cell: UITableViewCell
switch indexPath.section {
case 1:
-
- cell = tableView.dequeueReusableCell(withIdentifier: "SettingsTableViewCell", for: indexPath)
- cell.textLabel?.adjustsFontForContentSizeCategory = true
-
+
let sortedAccounts = AccountManager.shared.sortedAccounts
if indexPath.row == sortedAccounts.count {
+ cell = tableView.dequeueReusableCell(withIdentifier: "SettingsTableViewCell", for: indexPath)
+ cell.textLabel?.adjustsFontForContentSizeCategory = true
cell.textLabel?.text = NSLocalizedString("Add Account", comment: "Accounts")
} else {
- cell.textLabel?.text = sortedAccounts[indexPath.row].nameForDisplay
+ let acctCell = tableView.dequeueReusableCell(withIdentifier: "SettingsAccountTableViewCell", for: indexPath) as! SettingsAccountTableViewCell
+ let account = sortedAccounts[indexPath.row]
+ acctCell.accountImage?.image = AppAssets.image(for: account.type)
+ acctCell.accountNameLabel?.text = account.nameForDisplay
+ cell = acctCell
}
default:
From 2e489d4093c45bcf394a9d1554120fc29df82ff3 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 11:08:34 -0500
Subject: [PATCH 40/50] Rollback timeline unread and star animations
---
.../Cell/MasterTimelineTableViewCell.swift | 28 +++++--------------
1 file changed, 7 insertions(+), 21 deletions(-)
diff --git a/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift b/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift
index 24f7b725b..0a240370e 100644
--- a/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift
+++ b/iOS/MasterTimeline/Cell/MasterTimelineTableViewCell.swift
@@ -187,30 +187,12 @@ private extension MasterTimelineTableViewCell {
}
func updateUnreadIndicator() {
- let hide = cellData.read || cellData.starred
- self.unreadIndicatorView.isHidden = hide
- self.unreadIndicatorView.frame.size = !hide ? CGSize.zero : MasterTimelineDefaultCellLayout.unreadCircleSize
- UIView.animate(
- withDuration: 0.5,
- delay: 0.0,
- usingSpringWithDamping: 0.5,
- initialSpringVelocity: 0.2,
- animations: {
- self.unreadIndicatorView.frame.size = !hide ? MasterTimelineDefaultCellLayout.unreadCircleSize : CGSize.zero
- })
+ showOrHideView(unreadIndicatorView, cellData.read || cellData.starred)
+ unreadIndicatorView.setNeedsDisplay()
}
func updateStarView() {
- self.starView.isHidden = !self.cellData.starred
- self.starView.frame.size = self.cellData.starred ? CGSize.zero : MasterTimelineDefaultCellLayout.starSize
- UIView.animate(
- withDuration: 0.5,
- delay: 0.0,
- usingSpringWithDamping: 0.5,
- initialSpringVelocity: 0.2,
- animations: {
- self.starView.frame.size = self.cellData.starred ? MasterTimelineDefaultCellLayout.starSize : CGSize.zero
- })
+ showOrHideView(starView, !cellData.starred)
}
func updateAvatar() {
@@ -251,6 +233,10 @@ private extension MasterTimelineTableViewCell {
}
}
+ func showOrHideView(_ view: UIView, _ shouldHide: Bool) {
+ shouldHide ? hideView(view) : showView(view)
+ }
+
func updateSubviews() {
updateTitleView()
updateSummaryView()
From eea450bee341d8c57a6450eb48133c5bce0393ec Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 11:47:21 -0500
Subject: [PATCH 41/50] Make icon vibrancy deselections match the deselection
animation
---
.../Cell/MasterFeedTableViewCell.swift | 19 +++++++++++--------
.../SettingsAccountTableViewCell.swift | 19 ++++++++++++++-----
iOS/Settings/SettingsViewController.swift | 1 +
3 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
index 3662b829a..d128d93f4 100644
--- a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
+++ b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
@@ -133,18 +133,12 @@ class MasterFeedTableViewCell : VibrantTableViewCell {
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
-
- let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : AppAssets.secondaryAccentColor
- disclosureButton?.tintColor = tintColor
- faviconImageView.tintColor = tintColor
+ updateVibrancy(animated: animated)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
-
- let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : AppAssets.secondaryAccentColor
- disclosureButton?.tintColor = tintColor
- faviconImageView.tintColor = tintColor
+ updateVibrancy(animated: animated)
}
override func willTransition(to state: UITableViewCell.StateMask) {
@@ -201,5 +195,14 @@ private extension MasterFeedTableViewCell {
disclosureButton?.isHidden = !isDisclosureAvailable
separatorInset = layout.separatorInsets
}
+
+ func updateVibrancy(animated: Bool) {
+ let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : AppAssets.secondaryAccentColor
+ let duration = animated ? 0.5 : 0.0
+ UIView.animate(withDuration: duration) {
+ self.disclosureButton?.tintColor = tintColor
+ self.faviconImageView.tintColor = tintColor
+ }
+ }
}
diff --git a/iOS/Settings/SettingsAccountTableViewCell.swift b/iOS/Settings/SettingsAccountTableViewCell.swift
index cc45c59b0..94b3478ac 100644
--- a/iOS/Settings/SettingsAccountTableViewCell.swift
+++ b/iOS/Settings/SettingsAccountTableViewCell.swift
@@ -15,16 +15,25 @@ class SettingsAccountTableViewCell: VibrantTableViewCell {
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
- let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : UIColor.label
- accountImage?.tintColor = tintColor
- accountNameLabel?.highlightedTextColor = tintColor
+ updateVibrancy(animated: animated)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
+ updateVibrancy(animated: animated)
+ }
+
+ override func applyThemeProperties() {
+ super.applyThemeProperties()
+ accountNameLabel?.highlightedTextColor = AppAssets.vibrantTextColor
+ }
+
+ func updateVibrancy(animated: Bool) {
let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : UIColor.label
- accountImage?.tintColor = tintColor
- accountNameLabel?.highlightedTextColor = tintColor
+ let duration = animated ? 0.5 : 0.0
+ UIView.animate(withDuration: duration) {
+ self.accountImage?.tintColor = tintColor
+ }
}
}
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index 56fe7f11f..be8f7683c 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -103,6 +103,7 @@ class SettingsViewController: UITableViewController {
cell.textLabel?.text = NSLocalizedString("Add Account", comment: "Accounts")
} else {
let acctCell = tableView.dequeueReusableCell(withIdentifier: "SettingsAccountTableViewCell", for: indexPath) as! SettingsAccountTableViewCell
+ acctCell.applyThemeProperties()
let account = sortedAccounts[indexPath.row]
acctCell.accountImage?.image = AppAssets.image(for: account.type)
acctCell.accountNameLabel?.text = account.nameForDisplay
From bac205ef84ef6b41c663327903b7d221ca4c4e9c Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 11:56:36 -0500
Subject: [PATCH 42/50] Tweak the vibrancy icon transition animation
---
iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift | 2 +-
iOS/Settings/SettingsAccountTableViewCell.swift | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
index d128d93f4..5dc3e3c3f 100644
--- a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
+++ b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift
@@ -198,7 +198,7 @@ private extension MasterFeedTableViewCell {
func updateVibrancy(animated: Bool) {
let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : AppAssets.secondaryAccentColor
- let duration = animated ? 0.5 : 0.0
+ let duration = animated ? 0.6 : 0.0
UIView.animate(withDuration: duration) {
self.disclosureButton?.tintColor = tintColor
self.faviconImageView.tintColor = tintColor
diff --git a/iOS/Settings/SettingsAccountTableViewCell.swift b/iOS/Settings/SettingsAccountTableViewCell.swift
index 94b3478ac..0ae9a6ec2 100644
--- a/iOS/Settings/SettingsAccountTableViewCell.swift
+++ b/iOS/Settings/SettingsAccountTableViewCell.swift
@@ -30,7 +30,7 @@ class SettingsAccountTableViewCell: VibrantTableViewCell {
func updateVibrancy(animated: Bool) {
let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : UIColor.label
- let duration = animated ? 0.5 : 0.0
+ let duration = animated ? 0.6 : 0.0
UIView.animate(withDuration: duration) {
self.accountImage?.tintColor = tintColor
}
From c771bd651c3db2b805eb0a9e374a67c8d300de80 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 12:01:26 -0500
Subject: [PATCH 43/50] Make vibrant button highlight more quickly
---
iOS/UIKit Extensions/VibrantButton.swift | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/iOS/UIKit Extensions/VibrantButton.swift b/iOS/UIKit Extensions/VibrantButton.swift
index 8e070e4d1..dc311d549 100644
--- a/iOS/UIKit Extensions/VibrantButton.swift
+++ b/iOS/UIKit Extensions/VibrantButton.swift
@@ -30,4 +30,19 @@ class VibrantButton: UIButton {
}
}
+ override func touchesBegan(_ touches: Set, with event: UIEvent?) {
+ isHighlighted = true
+ super.touchesBegan(touches, with: event)
+ }
+
+ override func touchesEnded(_ touches: Set, with event: UIEvent?) {
+ isHighlighted = false
+ super.touchesEnded(touches, with: event)
+ }
+
+ override func touchesCancelled(_ touches: Set, with event: UIEvent?) {
+ isHighlighted = false
+ super.touchesCancelled(touches, with: event)
+ }
+
}
From 0dff95e51f19eb11dfb4d9f073938cc3da2294fe Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 13:33:22 -0500
Subject: [PATCH 44/50] Change number of default lines in timeline to 2
---
iOS/AppDefaults.swift | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/iOS/AppDefaults.swift b/iOS/AppDefaults.swift
index 81a58a09c..31d006641 100644
--- a/iOS/AppDefaults.swift
+++ b/iOS/AppDefaults.swift
@@ -106,7 +106,7 @@ struct AppDefaults {
let defaults: [String : Any] = [Key.lastImageCacheFlushDate: Date(),
Key.refreshInterval: RefreshInterval.everyHour.rawValue,
Key.timelineGroupByFeed: false,
- Key.timelineNumberOfLines: 3,
+ Key.timelineNumberOfLines: 2,
Key.timelineSortDirection: ComparisonResult.orderedDescending.rawValue,
Key.displayUndoAvailableTip: true]
AppDefaults.shared.register(defaults: defaults)
From 4fcd134c6a5859db53cd76e860956c501f725570 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 13:52:07 -0500
Subject: [PATCH 45/50] Change the local account icon.
---
iOS/AppAssets.swift | 14 +++++++++++---
.../Contents.json | 2 +-
.../localAccountPad.pdf} | Bin 4205 -> 3897 bytes
.../accountLocalPhone.imageset/Contents.json | 16 ++++++++++++++++
.../localAccountPhone.pdf | Bin 0 -> 3904 bytes
iOS/Settings/AddAccountViewController.swift | 3 ++-
iOS/Settings/Settings.storyboard | 1 +
7 files changed, 31 insertions(+), 5 deletions(-)
rename iOS/Resources/Assets.xcassets/{accountLocal.imageset => accountLocalPad.imageset}/Contents.json (85%)
rename iOS/Resources/Assets.xcassets/{accountLocal.imageset/accountLocal.pdf => accountLocalPad.imageset/localAccountPad.pdf} (75%)
create mode 100644 iOS/Resources/Assets.xcassets/accountLocalPhone.imageset/Contents.json
create mode 100644 iOS/Resources/Assets.xcassets/accountLocalPhone.imageset/localAccountPhone.pdf
diff --git a/iOS/AppAssets.swift b/iOS/AppAssets.swift
index dcb1c9227..8f60395dd 100644
--- a/iOS/AppAssets.swift
+++ b/iOS/AppAssets.swift
@@ -11,8 +11,12 @@ import Account
struct AppAssets {
- static var accountLocalImage: UIImage = {
- return UIImage(named: "accountLocal")!
+ static var accountLocalPadImage: UIImage = {
+ return UIImage(named: "accountLocalPad")!
+ }()
+
+ static var accountLocalPhoneImage: UIImage = {
+ return UIImage(named: "accountLocalPhone")!
}()
static var accountFeedbinImage: UIImage = {
@@ -177,7 +181,11 @@ struct AppAssets {
static func image(for accountType: AccountType) -> UIImage? {
switch accountType {
case .onMyMac:
- return AppAssets.accountLocalImage
+ if UIDevice.current.userInterfaceIdiom == .pad {
+ return AppAssets.accountLocalPadImage
+ } else {
+ return AppAssets.accountLocalPhoneImage
+ }
case .feedbin:
return AppAssets.accountFeedbinImage
case .freshRSS:
diff --git a/iOS/Resources/Assets.xcassets/accountLocal.imageset/Contents.json b/iOS/Resources/Assets.xcassets/accountLocalPad.imageset/Contents.json
similarity index 85%
rename from iOS/Resources/Assets.xcassets/accountLocal.imageset/Contents.json
rename to iOS/Resources/Assets.xcassets/accountLocalPad.imageset/Contents.json
index c48efa3f2..7fe4e483c 100644
--- a/iOS/Resources/Assets.xcassets/accountLocal.imageset/Contents.json
+++ b/iOS/Resources/Assets.xcassets/accountLocalPad.imageset/Contents.json
@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "universal",
- "filename" : "accountLocal.pdf"
+ "filename" : "localAccountPad.pdf"
}
],
"info" : {
diff --git a/iOS/Resources/Assets.xcassets/accountLocal.imageset/accountLocal.pdf b/iOS/Resources/Assets.xcassets/accountLocalPad.imageset/localAccountPad.pdf
similarity index 75%
rename from iOS/Resources/Assets.xcassets/accountLocal.imageset/accountLocal.pdf
rename to iOS/Resources/Assets.xcassets/accountLocalPad.imageset/localAccountPad.pdf
index c32cc3b897b33e9b26438b96b792ab7b5afd15c7..cfc6ca9f04b3b9098564f21f56debec0ee8ff7ca 100644
GIT binary patch
delta 647
zcmaE>uv2bAKz*)%G}mDRp5Ny+OByRZFYnn`-cc3e`cq7GHdV8mHosbx85|NF9R!NsS2=4)JR3irk6QEFldP>)MuNh+6yi0#Y;iAfK>@A(sIhD43a=8k;JlDL}=H
zjZMuJz_JQ?FfjvTLj!a%VjS?+Qj1v>hOpJ|F679Hb2r5yC
dRj{+;DlP$rbwyEX8ke!DkpY*gs;j>n7XT`t%bEZH
delta 966
zcmdlf_f}y-Kz(YkW8NJDo;|-s|2RZ=PVsm(NBqeZb_tEB1H1xn{x|YGHQk%B_dt@x
zvJ($G{w?DFr4;;5E!LxD=}gPNs;hIBg{|b>X4rNqz@TqU*p5&e72}WFf>+;(lAR`_
z$&tCPy!X`Nhj*@~EoVwHJFfZC=4fr6YQn||j2d@jbQGs9DU5flUwCcDs#T4?5}I3$
zx)k{c~EBD#j2uHTlBaxJA4bnt~G_Oh0l!TYGCXhlEBw
z@3;MD4c?Y-aJK3Rv#|4fp04|$l1Fd)XFHP_hfHm{0)_OSXHQRzE;@DeckF^9`O6EQ
zzS)?g@1_-Vy;S_tu}@oUibU#zon?P?^%=%2e8+Qq`cuy9Yb}0TRYm#*RrFn`XsY#I
z?XTo>Sg~H}M-Xqm5!1PM>ibe$OJ4HMzWczJ?{ojchlWeeM7#>=SaG36_hZ6i8R^W3
z$y?Jj3fSBw65eFr{H)XV@hS5vwSCt$+idT*pLuOkFfF!vl5GEth2E$3P6^N`Ha=Yc
z;=kwo8$nC$zdZiiSX$!{@kh>jFYhW>gW0E<+#9y{`Ip{3Daa|A$KLgKQGdRx)UmUZ
z1sSE7O^i)8>oHE@X0(`mm?yg4P{BYUKPih#BR4VGKUg6wwWv5VKTpBXK+n)b&qN_c
z!>KegCq==~!qv#gEJjlyur#r#q)H*c#mzZCuOzjiM3XBuF9l?Rp%Kg|7b_zJLrViw
z14BbYBLgFgC<6m^AVR2wDzvdt@YD||%1qSQ1l0|i6l$tQVbw9O5T6%0T?Ay0t|%rG!8HL*k&Gd3|Zoh-no
zT5oD>fG%fXW`spOHg%Tf=z5J!3^B|zHZ?KBP-kih785{rsIi&3;p91dGK|KPck(I5
zC#4!$rkWd=CtDgD8l@T=Cs`O6nHd`!CmWk4CmWfi*>TwrRH6{801T<(5@3{p!^zm(
N!h%ax)z#mP3jhURQ_uha
diff --git a/iOS/Resources/Assets.xcassets/accountLocalPhone.imageset/Contents.json b/iOS/Resources/Assets.xcassets/accountLocalPhone.imageset/Contents.json
new file mode 100644
index 000000000..05bb5e471
--- /dev/null
+++ b/iOS/Resources/Assets.xcassets/accountLocalPhone.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "localAccountPhone.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template",
+ "preserves-vector-representation" : true
+ }
+}
\ No newline at end of file
diff --git a/iOS/Resources/Assets.xcassets/accountLocalPhone.imageset/localAccountPhone.pdf b/iOS/Resources/Assets.xcassets/accountLocalPhone.imageset/localAccountPhone.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..c807edece1d482cc068b120a49f95922cf54ad6a
GIT binary patch
literal 3904
zcmai%c{r49`^PPlWk@QKrMiAtUzG4?KC#DICQ6iPx-p-Jxv1iN
z41e}zrKB_ypV|?Nq)WHOa`a%gT#YTT+y0
z*1r!uWlq*0M}dGFodD@c?p9ju75^rQy|9@B
zmQXO+%jwspII~SHHU-!mk#OYZ;*aTXGM&C~jtsy|2rfUqRI(QhK>d`=jO^p>OC^zg
z0JWb1thX19v+e_I%51hN->-U`>wn5_LiHw@lWBl0r>LF*U=P5s-X7jm^K%3e8QAm%
z>w^H)e--$x#^K*;{IU-7BMWwlb0C<`rhQ%*Nz{*^fdZo8ff-x2sv#{7;(?h(|LS
z>Wr5=WC6&6RG=X6>ge%ZAk!GbP!pc02&kXl76Y;Eik42NpK{}(Wl8#CLYKmc{ettN
zCM^x7diw0acz40sQuLRh%=K35;eqi-{R1wu^!^$ylW*amMw%6OsA{g2*r%xmyB#|_
znwNNXi*k!taX)1_JA-h`dOSVf7#bNFw~x0}E`Cx8b*g=DvfNl2ymb@o|Cm
zd)1BwLnYWespgf>B#|4S=L>0y$S4F-JXbL9uIxy2xyNGB*umQN>*>(ZTq)~L$tSAW
z@wFyHnGjZfJSf-hI^?}e{zZN=g$Fhdrk6!WiOQ
zi*hzM_EgrTS#VW(@@cbKck#0T*ZdZ)s-Zu=?2YnpNN)ZhEH4x{J?-Jco#U=@@T2-#
zPPq5;`Y6m&M#rZ$%cF%7T44taccIAo?82f#BfS?dghkSsPU}me8zWCKlz+81DgTl4
zRAMgjqlM|mRKbWC*V@QqVOCdFoWKzwy{wSkYV!P&!CCHNuD*_3^hk_JwIP3-w+0vX
z0I!^vRv-_3%2pHsZmWCZTAEbulZXubKEAq7$S&54WvnA>KDH>F=tPC&DNE)LM|d>w
z?6}HLy9rheQ-Sj+pWP}GiaN(T1aL)!9v9`k#;bCihoTL-ucP^z3#@~9&Fy!|?HpH6
zSl~<0sc^M(e0HESPq&^E5)Q>_gQFUZ;M_xD6oK&1qPy~R?pzfw*p{K&Cn{|tZ~?1h
za#)P_88+ssXtMUoOX%(0N|)~BVofv_4$!1(1ne)Z-sFD?sPe6I(<8QD=jkSFea-bS
zbfDs>i~z2&AYBB0$Sz}sbDB_KVgr+d{(
zj(hul_axZ@o?`vXt0D!`j}wk3ogd}pi_Rrn-!0xEITCFh&mvk9`iLjsz1Ko`&`3b6RzmagL+45}SS=);Ad%Uj+(??}QTAxaOkU1Azz1t4y
zg)Rd<+SVUm8#>jrl?9y(c%n2UHXFXJ!RIsa;{G~th)l@d;lzC{_3~E*Z9wkf+xA}r
z2Toy5Jl4LTeF1yRZ0l{W
z9;-XoYqD(c3_bb@It-VBO8=5R(q5WUlH{H?l^z7ar}n4&r#q_T$UE*2Iq|*lTQ!eq
zgLZ>?Sbl|Nt^up6Q6th&KQk|lc$t_I=#)2RjLbhcquw~d%?8@h6e2wt4%P2F+Tk$FJ
zweg8xRL34ON0@Kb$|(*TPZZNul)RKKrpcx`r*Wqx-Z8fD?iK6Jy5o5V-vf7px)Iz4
z+}3(kN)nhwO#f_VmZR#%=(p&}ikg_f>Q%R|O_LgvDN>nIbyAX27Ei+lVzA}n9zRG{B_UJ>9aM=DyFdem@8DZ1YO&j
zSMko;`mRCWO-$3Vwu|`}Zmb*>(ulK)%Mu?HcT}EHHa|3_yw6(EdW)53)nvtL)0^f@
zcY6}OHOg&-RM}ZLIQF2l_|ULl{S5tRrhUbrc>6|p!LJb=5X}%-dQJ0F
zsEwfaZlC(ds_vYNAK{k|lE2q&STvkv-Kp5QwKHExSmLup&!OGauJf#F8ETS>lS;f}
zz`5KWi??YbHdCuFPWC5^`!#zu55CqISg&3?xXox=5-zSawJ2p=iYer9IlcT$(wXu{
z$xFmpx7i}iBbqUq37R|W{OU^Ruw}wJ&${30;Ftc-cFQ}=3yP-CGAMBN*oL!GNkM1|DU*s`Cw6OiIRiE7|%Bpvv(-*2O0)hklL5GO?
zdf4XLj}
zrB{PS(Ie9zz$2ejP=tj{a$mEN~!Sac(1XJawjxNO1ku|FHs
zpHdsWmOS2aa6Dnoewq9&36vgjKcY)7z1cp7WLRdn%W#ATuk+x&?|sMlu+iewtEu^l
zsN$~Te^DZ;maDpTA%xh9gZ3y5c?PUWH6Ma-Q{
zc;>OoV`k8~vefNux~xOjS7OJ9*bjKfyX2{1Yx5
zVwFL(b{KeB_TIjf{bD|E{!#6j={ie-?fJ9YD2YyqRmj`-87Io!aJ@y71(RV?iJ4=J
z$)HCwS#Mh3_SX-4hIDf$@IK?$+$$#YB&2Q0#JyC<^BLhC>uwWsDsQr;-X+8_L~rK!
zToMx(iM!R>nCRPkw5MPFwtA{sV?uJvy^-^+-s|tbVuN;;OqihZA1{Lr@5ju2XkFen
zn=O27;6g0@&V>AW&f>$DHnBFjeee2W9u}xkf{cTPCqlck_H^z!q;+HC;zImlMrP%6
z7b9j;=dM3)U~>F}=XF~m=i*`{qK}-RY1UMYzRD`AC>!bsOD}hrdrU2U%UJtnkzV3b
zhOs|N&!RJCqSh1o_SR-!bDR#QOgxzNWK5i^T)#F_dZlg)eSFn^4K}n`LuX&v$dcxb
z<6HftQWv!0@J?fbKD6G&U%bsh>qX$Z)7M^|Xh)?exiL6)r{%|R+t0X7b
ze~sZnY;XST-Zhn>bzt>7txrSJ*F2RTF1Z)DV8DRe>
z6K_KFpG^E0WBUNGlVm3fLDxF~u!VC{&}aa2_y;8Wa>yG2z>FwPJ{)*P{;c*JAR{)@
z|GOfVKqGi~yZpp=pI_Ym7nUP_+rYtcCtnh$15)rLknrY!C7J3&@%91`a1{g^uv5_W
zrFb|22#k&z9BHQrnEDc^v_ODE@IRnGfTqX+cTTHB_}|;PsI&k8
literal 0
HcmV?d00001
diff --git a/iOS/Settings/AddAccountViewController.swift b/iOS/Settings/AddAccountViewController.swift
index d1587758a..e0a18a590 100644
--- a/iOS/Settings/AddAccountViewController.swift
+++ b/iOS/Settings/AddAccountViewController.swift
@@ -15,11 +15,12 @@ protocol AddAccountDismissDelegate: UIViewController {
class AddAccountViewController: UITableViewController, AddAccountDismissDelegate {
+ @IBOutlet private weak var localAccountImageView: UIImageView!
@IBOutlet private weak var localAccountNameLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
-
+ localAccountImageView.image = AppAssets.image(for: .onMyMac)
localAccountNameLabel.text = Account.defaultLocalAccountName
}
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 617b76467..5aa060786 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -595,6 +595,7 @@
+
From 8c8ab39b0ce5f41362d2d9c3b30e7ffb88f31e72 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 14:21:55 -0500
Subject: [PATCH 46/50] Change the local account icon
---
.../accountLocal.imageset/Contents.json | 2 +-
.../{accountLocal.pdf => localAccountMac.pdf} | Bin 4205 -> 3910 bytes
2 files changed, 1 insertion(+), 1 deletion(-)
rename Mac/Resources/Assets.xcassets/accountLocal.imageset/{accountLocal.pdf => localAccountMac.pdf} (75%)
diff --git a/Mac/Resources/Assets.xcassets/accountLocal.imageset/Contents.json b/Mac/Resources/Assets.xcassets/accountLocal.imageset/Contents.json
index 4b7dc7acc..1d99e9ded 100644
--- a/Mac/Resources/Assets.xcassets/accountLocal.imageset/Contents.json
+++ b/Mac/Resources/Assets.xcassets/accountLocal.imageset/Contents.json
@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "universal",
- "filename" : "accountLocal.pdf"
+ "filename" : "localAccountMac.pdf"
}
],
"info" : {
diff --git a/Mac/Resources/Assets.xcassets/accountLocal.imageset/accountLocal.pdf b/Mac/Resources/Assets.xcassets/accountLocal.imageset/localAccountMac.pdf
similarity index 75%
rename from Mac/Resources/Assets.xcassets/accountLocal.imageset/accountLocal.pdf
rename to Mac/Resources/Assets.xcassets/accountLocal.imageset/localAccountMac.pdf
index c32cc3b897b33e9b26438b96b792ab7b5afd15c7..5c3292ce04da8aab5e456e6958225e12170fc66f 100644
GIT binary patch
delta 664
zcmaE>a7=DOKz(e0qu&t&o;}Y+KQsE=G3hIQ##;S|aiV}nuF|E5&p*FAZ
z4SQaNLa=M{t*Gp--G{wu;~QTVERO5)a8~gac4fQdpg$#h?W3+vy(y~MWlsE)W%l2#d#L{Vd*`3&
zDcKXcWB;j73fI4FerF#;O-3x!Bqk|lBLj=gvP_e?SuHIU%*`in<&Bu!#3xd(k(-$8
zAFL3TT2!2wpQm7Gpl4{R5ToH#nwgWLU}))RW?&SfsSsG2SX5G_5a8nGoS#>cT2Z2@
zpzmCinpgtVYG58^V4w~}Ky|+PDIg^ZSe3AV)J#6e
zC+uO!WdH{XW~QdbrV42aP%&d;a{~pitU?}4%)r>l7+nk~WI0)eUp3v>zyw{+z{CKH
zdTi><4bk-i{e)qjv9XcCVjE0ln@+-zC8(Su)m?R||m|B`A8yFi~7$v7BnHyQA
rC8kaoG@5q7bWKXUA1s0u1YlqSQ1lV^d>eE>%@me>W}w@v7Gq
delta 994
zcmX>m_f}y-Kz(YkW8NJDo;|-s|2RZ=PVsm(NBqeZb_tEB1H1xn{x|YGHQk%B_dt@x
zvJ($G{w?DFr4;;5E!LxD=}gPNs;hIBg{|b>X4rNqz@TqU*p5&e72}WFf>+;(lAR`_
z$&tCPy!X`Nhj*@~EoVwHJFfZC=4fr6YQn||j2d@jbQGs9DU5flUwCcDs#T4?5}I3$
zx)k{c~EBD#j2uHTlBaxJA4bnt~G_Oh0l!TYGCXhlEBw
z@3;MD4c?Y-aJK3Rv#|4fp04|$l1Fd)XFHP_hfHm{0)_OSXHQRzE;@DeckF^9`O6EQ
zzS)?g@1_-Vy;S_tu}@oUibU#zon?P?^%=%2e8+Qq`cuy9Yb}0TRYm#*RrFn`XsY#I
z?XTo>Sg~H}M-Xqm5!1PM>ibe$OJ4HMzWczJ?{ojchlWeeM7#>=SaG36_hZ6i8R^W3
z$y?Jj3fSBw65eFr{H)XV@hS5vwSCt$+idT*pLuOkFfF!vl5GEth2E$3P6^N`Ha=Yc
z;=kwo8$nC$zdZiiSX$!{@kh>jFYhW>gW0E<+#9y{`Ip{3Daa|A$KLgKQGdRx)UmUZ
zKegCq==~!qv#gEJjlyur#r#q)H*c#mzZCuOzjiM3XBuF9l?Rp%Kg|7b_zJ
zLrViw14BbYBLgFgC<6m^AVR2wDzvdtsMilD%1qSQ1l0|i54E(17FFf%nZHdRPdfQlKL8yYKsWfk&ZVg{xr
zmOwE0qvMir!y{WMQh6XbukOnmM*wk5?W2!U6FwfZ3#0*27sU=uU0L4*e
z=7y73^2sn7Pd>({7@w4CWSMGiV4iGgY-p5fY@B3aU}R=&Y@BRtnw)H8mS)FgLr{rA
atO76ui%Wn}2@XGFa|;VDRaIAiH!c7JL0F;y
From a39aab58e4a4fdbf088da28592d5894176468c1e Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 15:31:54 -0500
Subject: [PATCH 47/50] Fix vertical padding for Feeds that have more than one
line. Issue #1150
---
.../Cell/MasterFeedTableViewCellLayout.swift | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift
index 2df98fe02..b60177efb 100644
--- a/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift
+++ b/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift
@@ -17,6 +17,7 @@ struct MasterFeedTableViewCellLayout {
private static let unreadCountMarginLeft = CGFloat(integerLiteral: 8)
private static let unreadCountMarginRight = CGFloat(integerLiteral: 16)
private static let disclosureButtonSize = CGSize(width: 44, height: 44)
+ private static let verticalPadding = CGFloat(integerLiteral: 11)
private static let minRowHeight = CGFloat(integerLiteral: 44)
@@ -53,7 +54,7 @@ struct MasterFeedTableViewCellLayout {
var rFavicon = CGRect.zero
if !shouldShowDisclosure {
let x = bounds.origin.x + ((MasterFeedTableViewCellLayout.disclosureButtonSize.width - MasterFeedTableViewCellLayout.imageSize.width) / 2)
- let y = UIFontMetrics.default.scaledValue(for: CGFloat(integerLiteral: 4))
+ let y = UIFontMetrics.default.scaledValue(for: MasterFeedTableViewCellLayout.verticalPadding)
rFavicon = CGRect(x: x, y: y, width: MasterFeedTableViewCellLayout.imageSize.width, height: MasterFeedTableViewCellLayout.imageSize.height)
}
@@ -82,31 +83,26 @@ struct MasterFeedTableViewCellLayout {
let labelSizeInfo = MultilineUILabelSizer.size(for: label.text ?? "", font: label.font, numberOfLines: 0, width: Int(floor(labelWidth)))
let rLabelx = bounds.minX + MasterFeedTableViewCellLayout.disclosureButtonSize.width
- var rLabel = CGRect(x: rLabelx, y: 0.0, width: labelSizeInfo.size.width, height: labelSizeInfo.size.height)
+ let rLabely = UIFontMetrics.default.scaledValue(for: MasterFeedTableViewCellLayout.verticalPadding)
+ let rLabel = CGRect(x: rLabelx, y: rLabely, width: labelSizeInfo.size.width, height: labelSizeInfo.size.height)
// Determine cell height
- var cellHeight = [rFavicon, rLabel, rUnread, rDisclosure].maxY()
+ let paddedLabelHeight = rLabel.maxY + UIFontMetrics.default.scaledValue(for: MasterFeedTableViewCellLayout.verticalPadding)
+ let maxGraphicsHeight = [rFavicon, rUnread, rDisclosure].maxY()
+ var cellHeight = max(paddedLabelHeight, maxGraphicsHeight)
if cellHeight < MasterFeedTableViewCellLayout.minRowHeight {
cellHeight = MasterFeedTableViewCellLayout.minRowHeight
}
// Center in Cell
let newBounds = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.width, height: cellHeight)
-
- if !shouldShowDisclosure && labelSizeInfo.numberOfLinesUsed == 1 {
- rFavicon = MasterFeedTableViewCellLayout.centerVertically(rFavicon, newBounds)
- }
-
if !unreadCountIsHidden {
rUnread = MasterFeedTableViewCellLayout.centerVertically(rUnread, newBounds)
}
-
if shouldShowDisclosure {
rDisclosure = MasterFeedTableViewCellLayout.centerVertically(rDisclosure, newBounds)
}
- rLabel = MasterFeedTableViewCellLayout.centerVertically(rLabel, newBounds)
-
// Assign the properties
self.height = cellHeight
self.faviconRect = rFavicon
From f0d1cf62398023b2f0fee8e300d7786811412187 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 19:58:18 -0500
Subject: [PATCH 48/50] Add Account Inspector context menu item for Accounts
---
NetNewsWire.xcodeproj/project.pbxproj | 34 +-
iOS/Account/Account.storyboard | 260 +++++++++++
.../FeedbinAccountViewController.swift | 0
.../LocalAccountViewController.swift} | 6 +-
.../AccountInspectorViewController.swift} | 27 +-
iOS/Inspector/Inspector.storyboard | 169 ++++++++
iOS/MasterFeed/MasterFeedViewController.swift | 32 ++
iOS/SceneCoordinator.swift | 11 +
iOS/Settings/AddAccountViewController.swift | 6 +-
iOS/Settings/Settings.storyboard | 408 +-----------------
iOS/Settings/SettingsViewController.swift | 7 +-
.../UIStoryboard-Extensions.swift | 8 +
12 files changed, 542 insertions(+), 426 deletions(-)
create mode 100644 iOS/Account/Account.storyboard
rename iOS/{Settings => Account}/FeedbinAccountViewController.swift (100%)
rename iOS/{Settings/AddLocalAccountViewController.swift => Account/LocalAccountViewController.swift} (83%)
rename iOS/{Settings/DetailAccountViewController.swift => Inspector/AccountInspectorViewController.swift} (81%)
create mode 100644 iOS/Inspector/Inspector.storyboard
diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj
index 1a326e674..4102a510f 100644
--- a/NetNewsWire.xcodeproj/project.pbxproj
+++ b/NetNewsWire.xcodeproj/project.pbxproj
@@ -84,6 +84,8 @@
516A093723609A3600EAE89B /* SettingsAccountTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 516A091D23609A3600EAE89B /* SettingsAccountTableViewCell.xib */; };
516A09392360A2AE00EAE89B /* SettingsAccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516A09382360A2AE00EAE89B /* SettingsAccountTableViewCell.swift */; };
516A093B2360A4A000EAE89B /* SettingsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */; };
+ 516A09402361240900EAE89B /* Account.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 516A093F2361240900EAE89B /* Account.storyboard */; };
+ 516A09422361248000EAE89B /* Inspector.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 516A09412361248000EAE89B /* Inspector.storyboard */; };
51707439232AA97100A461A3 /* ShareFolderPickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51707438232AA97100A461A3 /* ShareFolderPickerController.swift */; };
5170743A232AABFC00A461A3 /* FlattenedAccountFolderPickerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C452812265093600C03939 /* FlattenedAccountFolderPickerData.swift */; };
517630042336215100E15FFF /* main.js in Resources */ = {isa = PBXBuildFile; fileRef = 517630032336215100E15FFF /* main.js */; };
@@ -109,9 +111,9 @@
519D740623243CC0008BB345 /* RefreshInterval-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519D740523243CC0008BB345 /* RefreshInterval-Extensions.swift */; };
519E743D22C663F900A78E47 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519E743422C663F900A78E47 /* SceneDelegate.swift */; };
51A16997235E10D700EB091F /* RefreshIntervalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A1698D235E10D600EB091F /* RefreshIntervalViewController.swift */; };
- 51A16999235E10D700EB091F /* AddLocalAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A1698F235E10D600EB091F /* AddLocalAccountViewController.swift */; };
+ 51A16999235E10D700EB091F /* LocalAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A1698F235E10D600EB091F /* LocalAccountViewController.swift */; };
51A1699A235E10D700EB091F /* Settings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 51A16990235E10D600EB091F /* Settings.storyboard */; };
- 51A1699B235E10D700EB091F /* DetailAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16991235E10D600EB091F /* DetailAccountViewController.swift */; };
+ 51A1699B235E10D700EB091F /* AccountInspectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16991235E10D600EB091F /* AccountInspectorViewController.swift */; };
51A1699C235E10D700EB091F /* AddAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16992235E10D600EB091F /* AddAccountViewController.swift */; };
51A1699D235E10D700EB091F /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16993235E10D600EB091F /* SettingsViewController.swift */; };
51A1699F235E10D700EB091F /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A16995235E10D600EB091F /* AboutViewController.swift */; };
@@ -1242,6 +1244,8 @@
516A091D23609A3600EAE89B /* SettingsAccountTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsAccountTableViewCell.xib; sourceTree = ""; };
516A09382360A2AE00EAE89B /* SettingsAccountTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAccountTableViewCell.swift; sourceTree = ""; };
516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsTableViewCell.xib; sourceTree = ""; };
+ 516A093F2361240900EAE89B /* Account.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Account.storyboard; sourceTree = ""; };
+ 516A09412361248000EAE89B /* Inspector.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Inspector.storyboard; sourceTree = ""; };
51707438232AA97100A461A3 /* ShareFolderPickerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareFolderPickerController.swift; sourceTree = ""; };
517630032336215100E15FFF /* main.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = ""; };
517630222336657E00E15FFF /* ArticleViewControllerWebViewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleViewControllerWebViewProvider.swift; sourceTree = ""; };
@@ -1263,9 +1267,9 @@
519D740523243CC0008BB345 /* RefreshInterval-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RefreshInterval-Extensions.swift"; sourceTree = ""; };
519E743422C663F900A78E47 /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
51A1698D235E10D600EB091F /* RefreshIntervalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshIntervalViewController.swift; sourceTree = ""; };
- 51A1698F235E10D600EB091F /* AddLocalAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddLocalAccountViewController.swift; sourceTree = ""; };
+ 51A1698F235E10D600EB091F /* LocalAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalAccountViewController.swift; sourceTree = ""; };
51A16990235E10D600EB091F /* Settings.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = ""; };
- 51A16991235E10D600EB091F /* DetailAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailAccountViewController.swift; sourceTree = ""; };
+ 51A16991235E10D600EB091F /* AccountInspectorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountInspectorViewController.swift; sourceTree = ""; };
51A16992235E10D600EB091F /* AddAccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddAccountViewController.swift; sourceTree = ""; };
51A16993235E10D600EB091F /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; };
51A16995235E10D600EB091F /* AboutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutViewController.swift; sourceTree = ""; };
@@ -1668,6 +1672,8 @@
5123DB95233EC69300282CC9 /* Inspector */ = {
isa = PBXGroup;
children = (
+ 516A09412361248000EAE89B /* Inspector.storyboard */,
+ 51A16991235E10D600EB091F /* AccountInspectorViewController.swift */,
5123DB9E233EC6FD00282CC9 /* FeedInspectorView.swift */,
);
path = Inspector;
@@ -1750,6 +1756,16 @@
name = Products;
sourceTree = "";
};
+ 516A093E236123A800EAE89B /* Account */ = {
+ isa = PBXGroup;
+ children = (
+ 516A093F2361240900EAE89B /* Account.storyboard */,
+ 51A1698F235E10D600EB091F /* LocalAccountViewController.swift */,
+ 51A16996235E10D700EB091F /* FeedbinAccountViewController.swift */,
+ );
+ path = Account;
+ sourceTree = "";
+ };
5183CCDB226F1EEB0010922C /* Progress */ = {
isa = PBXGroup;
children = (
@@ -1775,9 +1791,6 @@
51A16990235E10D600EB091F /* Settings.storyboard */,
51A16995235E10D600EB091F /* AboutViewController.swift */,
51A16992235E10D600EB091F /* AddAccountViewController.swift */,
- 51A1698F235E10D600EB091F /* AddLocalAccountViewController.swift */,
- 51A16991235E10D600EB091F /* DetailAccountViewController.swift */,
- 51A16996235E10D700EB091F /* FeedbinAccountViewController.swift */,
51A1698D235E10D600EB091F /* RefreshIntervalViewController.swift */,
516A09382360A2AE00EAE89B /* SettingsAccountTableViewCell.swift */,
516A091D23609A3600EAE89B /* SettingsAccountTableViewCell.xib */,
@@ -2521,6 +2534,7 @@
51C4525D226508F600C03939 /* MasterFeed */,
51C4526D2265091600C03939 /* MasterTimeline */,
51C4527D2265092C00C03939 /* Article */,
+ 516A093E236123A800EAE89B /* Account */,
51C452802265093600C03939 /* Add */,
5123DB95233EC69300282CC9 /* Inspector */,
513145F9235A55A700387FDC /* Intents */,
@@ -3375,11 +3389,13 @@
51BB7C312335ACDE008E8144 /* page.html in Resources */,
516A093723609A3600EAE89B /* SettingsAccountTableViewCell.xib in Resources */,
51F85BF32272531500C787DC /* Dedication.rtf in Resources */,
+ 516A09422361248000EAE89B /* Inspector.storyboard in Resources */,
84C9FCA42262A1B800D921D6 /* LaunchScreenPhone.storyboard in Resources */,
51F85BEB22724CB600C787DC /* About.rtf in Resources */,
51F85BED227251DF00C787DC /* Acknowledgments.rtf in Resources */,
516A093B2360A4A000EAE89B /* SettingsTableViewCell.xib in Resources */,
511D43D1231FA62800FB1562 /* SidebarKeyboardShortcuts.plist in Resources */,
+ 516A09402361240900EAE89B /* Account.storyboard in Resources */,
51C452AB22650DC600C03939 /* template.html in Resources */,
51F85BF12272524100C787DC /* Credits.rtf in Resources */,
84A3EE61223B667F00557320 /* DefaultFeeds.opml in Resources */,
@@ -3880,7 +3896,7 @@
516A09392360A2AE00EAE89B /* SettingsAccountTableViewCell.swift in Sources */,
51D5948722668EFA00DFC836 /* MarkStatusCommand.swift in Sources */,
51A1699C235E10D700EB091F /* AddAccountViewController.swift in Sources */,
- 51A16999235E10D700EB091F /* AddLocalAccountViewController.swift in Sources */,
+ 51A16999235E10D700EB091F /* LocalAccountViewController.swift in Sources */,
514B7C8323205EFB00BAC947 /* RootSplitViewController.swift in Sources */,
51FA73A52332BE110090D516 /* ArticleExtractor.swift in Sources */,
51314704235C41FC00387FDC /* Intents.intentdefinition in Sources */,
@@ -3940,7 +3956,7 @@
51F85BFB2275D85000C787DC /* Array-Extensions.swift in Sources */,
51C452AC22650FD200C03939 /* AppNotifications.swift in Sources */,
51EF0F7E2277A57D0050506E /* MasterTimelineAccessibilityCellLayout.swift in Sources */,
- 51A1699B235E10D700EB091F /* DetailAccountViewController.swift in Sources */,
+ 51A1699B235E10D700EB091F /* AccountInspectorViewController.swift in Sources */,
51C452762265091600C03939 /* MasterTimelineViewController.swift in Sources */,
5183CCE9226F68D90010922C /* AccountRefreshTimer.swift in Sources */,
51C452882265093600C03939 /* AddFeedViewController.swift in Sources */,
diff --git a/iOS/Account/Account.storyboard b/iOS/Account/Account.storyboard
new file mode 100644
index 000000000..b5f05cc65
--- /dev/null
+++ b/iOS/Account/Account.storyboard
@@ -0,0 +1,260 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/iOS/Settings/FeedbinAccountViewController.swift b/iOS/Account/FeedbinAccountViewController.swift
similarity index 100%
rename from iOS/Settings/FeedbinAccountViewController.swift
rename to iOS/Account/FeedbinAccountViewController.swift
diff --git a/iOS/Settings/AddLocalAccountViewController.swift b/iOS/Account/LocalAccountViewController.swift
similarity index 83%
rename from iOS/Settings/AddLocalAccountViewController.swift
rename to iOS/Account/LocalAccountViewController.swift
index b9c092336..5abf1f436 100644
--- a/iOS/Settings/AddLocalAccountViewController.swift
+++ b/iOS/Account/LocalAccountViewController.swift
@@ -1,5 +1,5 @@
//
-// AddLocalAccountViewController.swift
+// LocalAccountViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 5/19/19.
@@ -9,7 +9,7 @@
import UIKit
import Account
-class AddLocalAccountViewController: UITableViewController {
+class LocalAccountViewController: UITableViewController {
@IBOutlet weak var nameTextField: UITextField!
@@ -35,7 +35,7 @@ class AddLocalAccountViewController: UITableViewController {
}
-extension AddLocalAccountViewController: UITextFieldDelegate {
+extension LocalAccountViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
diff --git a/iOS/Settings/DetailAccountViewController.swift b/iOS/Inspector/AccountInspectorViewController.swift
similarity index 81%
rename from iOS/Settings/DetailAccountViewController.swift
rename to iOS/Inspector/AccountInspectorViewController.swift
index 40dd698ee..c08beb28c 100644
--- a/iOS/Settings/DetailAccountViewController.swift
+++ b/iOS/Inspector/AccountInspectorViewController.swift
@@ -1,5 +1,5 @@
//
-// DetailAccountViewController.swift
+// AccountInspectorViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 5/17/19.
@@ -9,11 +9,14 @@
import UIKit
import Account
-class DetailAccountViewController: UITableViewController {
+class AccountInspectorViewController: UITableViewController {
+
+ static let preferredContentSizeForFormSheetDisplay = CGSize(width: 460.0, height: 400.0)
@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var activeSwitch: UISwitch!
+ var isModal = false
weak var account: Account?
override func viewDidLoad() {
@@ -25,18 +28,28 @@ class DetailAccountViewController: UITableViewController {
nameTextField.text = account.name
nameTextField.delegate = self
activeSwitch.isOn = account.isActive
- }
-
+
+ if isModal {
+ let doneBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(done))
+ navigationItem.leftBarButtonItem = doneBarButtonItem
+ }
+
+ }
+
override func viewWillDisappear(_ animated: Bool) {
account?.name = nameTextField.text
account?.isActive = activeSwitch.isOn
}
+
+ @objc func done() {
+ dismiss(animated: true)
+ }
@IBAction func credentials(_ sender: Any) {
guard let account = account else { return }
switch account.type {
case .feedbin:
- let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController
+ let navController = UIStoryboard.account.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController
let addViewController = navController.topViewController as! FeedbinAccountViewController
addViewController.account = account
navController.modalPresentationStyle = .currentContext
@@ -68,7 +81,7 @@ class DetailAccountViewController: UITableViewController {
}
-extension DetailAccountViewController {
+extension AccountInspectorViewController {
override func numberOfSections(in tableView: UITableView) -> Int {
guard let account = account else { return 0 }
@@ -107,7 +120,7 @@ extension DetailAccountViewController {
}
-extension DetailAccountViewController: UITextFieldDelegate {
+extension AccountInspectorViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
diff --git a/iOS/Inspector/Inspector.storyboard b/iOS/Inspector/Inspector.storyboard
new file mode 100644
index 000000000..e87fb1179
--- /dev/null
+++ b/iOS/Inspector/Inspector.storyboard
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/iOS/MasterFeed/MasterFeedViewController.swift b/iOS/MasterFeed/MasterFeedViewController.swift
index 039e5b036..e9c0d4d65 100644
--- a/iOS/MasterFeed/MasterFeedViewController.swift
+++ b/iOS/MasterFeed/MasterFeedViewController.swift
@@ -182,6 +182,10 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
let tap = UITapGestureRecognizer(target: self, action:#selector(self.toggleSectionHeader(_:)))
headerView.addGestureRecognizer(tap)
+ if section != 0 {
+ headerView.addInteraction(UIContextMenuInteraction(delegate: self))
+ }
+
return headerView
}
@@ -531,6 +535,26 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
}
+// MARK: UIContextMenuInteractionDelegate
+
+extension MasterFeedViewController: UIContextMenuInteractionDelegate {
+ func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
+
+ guard let sectionIndex = interaction.view?.tag,
+ let sectionNode = coordinator.rootNode.childAtIndex(sectionIndex),
+ let account = sectionNode.representedObject as? Account,
+ let headerView = interaction.view as? MasterFeedTableViewSectionHeader
+ else {
+ return nil
+ }
+
+ return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { suggestedActions in
+ let accountInfoAction = self.getAccountInfoAction(account: account)
+ return UIMenu(title: "", children: [accountInfoAction])
+ }
+ }
+}
+
// MARK: MasterTableViewCellDelegate
extension MasterFeedViewController: MasterFeedTableViewCellDelegate {
@@ -846,6 +870,14 @@ private extension MasterFeedViewController {
return action
}
+ func getAccountInfoAction(account: Account) -> UIAction {
+ let title = NSLocalizedString("Get Info", comment: "Get Info")
+ let action = UIAction(title: title, image: AppAssets.infoImage) { [weak self] action in
+ self?.coordinator.showAccountInspector(for: account)
+ }
+ return action
+ }
+
func getInfoAlertAction(indexPath: IndexPath, completionHandler: @escaping (Bool) -> Void) -> UIAlertAction? {
guard let node = dataSource.itemIdentifier(for: indexPath), let feed = node.representedObject as? Feed else {
return nil
diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift
index e97a63e19..bfd636ccd 100644
--- a/iOS/SceneCoordinator.swift
+++ b/iOS/SceneCoordinator.swift
@@ -793,6 +793,17 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
rootSplitViewController.present(settingsNavController, animated: true)
}
+ func showAccountInspector(for account: Account) {
+ let accountInspectorNavController =
+ UIStoryboard.inspector.instantiateViewController(identifier: "AccountInspectorNavigationViewController") as! UINavigationController
+ let accountInspectorController = accountInspectorNavController.topViewController as! AccountInspectorViewController
+ accountInspectorNavController.modalPresentationStyle = .formSheet
+ accountInspectorNavController.preferredContentSize = AccountInspectorViewController.preferredContentSizeForFormSheetDisplay
+ accountInspectorController.isModal = true
+ accountInspectorController.account = account
+ rootSplitViewController.present(accountInspectorNavController, animated: true)
+ }
+
func showFeedInspector() {
guard let feed = timelineFetcher as? Feed else {
return
diff --git a/iOS/Settings/AddAccountViewController.swift b/iOS/Settings/AddAccountViewController.swift
index e0a18a590..f53d46a55 100644
--- a/iOS/Settings/AddAccountViewController.swift
+++ b/iOS/Settings/AddAccountViewController.swift
@@ -27,13 +27,13 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
- let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "AddLocalAccountNavigationViewController") as! UINavigationController
+ let navController = UIStoryboard.account.instantiateViewController(withIdentifier: "AddLocalAccountNavigationViewController") as! UINavigationController
navController.modalPresentationStyle = .currentContext
- let addViewController = navController.topViewController as! AddLocalAccountViewController
+ let addViewController = navController.topViewController as! LocalAccountViewController
addViewController.delegate = self
present(navController, animated: true)
case 1:
- let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController
+ let navController = UIStoryboard.account.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController
navController.modalPresentationStyle = .currentContext
let addViewController = navController.topViewController as! FeedbinAccountViewController
addViewController.delegate = self
diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard
index 5aa060786..3afc9391c 100644
--- a/iOS/Settings/Settings.storyboard
+++ b/iOS/Settings/Settings.storyboard
@@ -359,155 +359,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -601,257 +453,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -881,7 +483,7 @@
-
+
@@ -1061,7 +663,7 @@
-
+
@@ -1082,6 +684,6 @@
-
+
diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift
index be8f7683c..cab947682 100644
--- a/iOS/Settings/SettingsViewController.swift
+++ b/iOS/Settings/SettingsViewController.swift
@@ -32,6 +32,7 @@ class SettingsViewController: UITableViewController {
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidAddAccount, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange), name: .UserDidDeleteAccount, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange), name: .DisplayNameDidChange, object: nil)
tableView.register(UINib(nibName: "SettingsAccountTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsAccountTableViewCell")
tableView.register(UINib(nibName: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
@@ -130,7 +131,7 @@ class SettingsViewController: UITableViewController {
let controller = UIStoryboard.settings.instantiateController(ofType: AddAccountViewController.self)
self.navigationController?.pushViewController(controller, animated: true)
} else {
- let controller = UIStoryboard.settings.instantiateController(ofType: DetailAccountViewController.self)
+ let controller = UIStoryboard.inspector.instantiateController(ofType: AccountInspectorViewController.self)
controller.account = sortedAccounts[indexPath.row]
self.navigationController?.pushViewController(controller, animated: true)
}
@@ -251,6 +252,10 @@ class SettingsViewController: UITableViewController {
tableView.reloadData()
}
+ @objc func displayNameDidChange() {
+ tableView.reloadData()
+ }
+
}
// MARK: OPML Document Picker
diff --git a/iOS/UIKit Extensions/UIStoryboard-Extensions.swift b/iOS/UIKit Extensions/UIStoryboard-Extensions.swift
index 4d309a729..ef48e061d 100644
--- a/iOS/UIKit Extensions/UIStoryboard-Extensions.swift
+++ b/iOS/UIKit Extensions/UIStoryboard-Extensions.swift
@@ -24,6 +24,14 @@ extension UIStoryboard {
return UIStoryboard(name: "Settings", bundle: nil)
}
+ static var inspector: UIStoryboard {
+ return UIStoryboard(name: "Inspector", bundle: nil)
+ }
+
+ static var account: UIStoryboard {
+ return UIStoryboard(name: "Account", bundle: nil)
+ }
+
func instantiateController(ofType type: T.Type = T.self) -> T where T: UIViewController {
let storyboardId = String(describing: type)
From 9376fcd64aa303854ea2a96e2900ef9445967994 Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 20:22:31 -0500
Subject: [PATCH 49/50] Added deactivate context menu for accounts.
---
iOS/AppAssets.swift | 4 ++++
iOS/MasterFeed/MasterFeedViewController.swift | 14 +++++++++++---
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/iOS/AppAssets.swift b/iOS/AppAssets.swift
index 8f60395dd..ca3806fd9 100644
--- a/iOS/AppAssets.swift
+++ b/iOS/AppAssets.swift
@@ -77,6 +77,10 @@ struct AppAssets {
return UIImage(systemName: "doc.on.doc")!
}()
+ static var deactivateImage: UIImage = {
+ UIImage(systemName: "minus.circle")!
+ }()
+
static var editImage: UIImage = {
UIImage(systemName: "square.and.pencil")!
}()
diff --git a/iOS/MasterFeed/MasterFeedViewController.swift b/iOS/MasterFeed/MasterFeedViewController.swift
index e9c0d4d65..15a86ba80 100644
--- a/iOS/MasterFeed/MasterFeedViewController.swift
+++ b/iOS/MasterFeed/MasterFeedViewController.swift
@@ -542,15 +542,15 @@ extension MasterFeedViewController: UIContextMenuInteractionDelegate {
guard let sectionIndex = interaction.view?.tag,
let sectionNode = coordinator.rootNode.childAtIndex(sectionIndex),
- let account = sectionNode.representedObject as? Account,
- let headerView = interaction.view as? MasterFeedTableViewSectionHeader
+ let account = sectionNode.representedObject as? Account
else {
return nil
}
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { suggestedActions in
let accountInfoAction = self.getAccountInfoAction(account: account)
- return UIMenu(title: "", children: [accountInfoAction])
+ let deactivateAction = self.deactivateAccountAction(account: account)
+ return UIMenu(title: "", children: [accountInfoAction, deactivateAction])
}
}
}
@@ -878,6 +878,14 @@ private extension MasterFeedViewController {
return action
}
+ func deactivateAccountAction(account: Account) -> UIAction {
+ let title = NSLocalizedString("Deactivate", comment: "Deactivate")
+ let action = UIAction(title: title, image: AppAssets.deactivateImage) { action in
+ account.isActive = false
+ }
+ return action
+ }
+
func getInfoAlertAction(indexPath: IndexPath, completionHandler: @escaping (Bool) -> Void) -> UIAlertAction? {
guard let node = dataSource.itemIdentifier(for: indexPath), let feed = node.representedObject as? Feed else {
return nil
From f538b3304fd13a1f31bc213118f94d3ab3d306de Mon Sep 17 00:00:00 2001
From: Maurice Parker
Date: Wed, 23 Oct 2019 20:29:22 -0500
Subject: [PATCH 50/50] Added account name to account inspector title
---
iOS/Inspector/AccountInspectorViewController.swift | 2 ++
1 file changed, 2 insertions(+)
diff --git a/iOS/Inspector/AccountInspectorViewController.swift b/iOS/Inspector/AccountInspectorViewController.swift
index c08beb28c..853670755 100644
--- a/iOS/Inspector/AccountInspectorViewController.swift
+++ b/iOS/Inspector/AccountInspectorViewController.swift
@@ -29,6 +29,8 @@ class AccountInspectorViewController: UITableViewController {
nameTextField.delegate = self
activeSwitch.isOn = account.isActive
+ navigationItem.title = account.nameForDisplay
+
if isModal {
let doneBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(done))
navigationItem.leftBarButtonItem = doneBarButtonItem