Fix lint issues.

This commit is contained in:
Brent Simmons 2025-01-22 22:18:09 -08:00
parent 40ada2ba5a
commit bbef99f2d3
92 changed files with 1651 additions and 1694 deletions

View File

@ -45,7 +45,7 @@ class CloudKitAccountViewController: UITableViewController {
return return
} }
let _ = AccountManager.shared.createAccount(type: .cloudKit) _ = AccountManager.shared.createAccount(type: .cloudKit)
dismiss(animated: true, completion: nil) dismiss(animated: true, completion: nil)
delegate?.dismiss() delegate?.dismiss()
} }

View File

@ -117,7 +117,7 @@ class FeedbinAccountViewController: UITableViewController {
} catch {} } catch {}
try self.account?.storeCredentials(credentials) try self.account?.storeCredentials(credentials)
self.account?.refreshAll() { result in self.account?.refreshAll { result in
switch result { switch result {
case .success: case .success:
break break
@ -148,7 +148,6 @@ class FeedbinAccountViewController: UITableViewController {
self.present(safari, animated: true, completion: nil) self.present(safari, animated: true, completion: nil)
} }
@objc func textDidChange(_ note: Notification) { @objc func textDidChange(_ note: Notification) {
actionButton.isEnabled = !(emailTextField.text?.isEmpty ?? false) && !(passwordTextField.text?.isEmpty ?? false) actionButton.isEnabled = !(emailTextField.text?.isEmpty ?? false) && !(passwordTextField.text?.isEmpty ?? false)
} }
@ -157,12 +156,12 @@ class FeedbinAccountViewController: UITableViewController {
presentError(title: NSLocalizedString("Error", comment: "Credentials Error"), message: message) presentError(title: NSLocalizedString("Error", comment: "Credentials Error"), message: message)
} }
private func setNavigationEnabled(to value:Bool){ private func setNavigationEnabled(to value: Bool) {
cancelBarButtonItem.isEnabled = value cancelBarButtonItem.isEnabled = value
actionButton.isEnabled = value actionButton.isEnabled = value
} }
private func toggleActivityIndicatorAnimation(visible value: Bool){ private func toggleActivityIndicatorAnimation(visible value: Bool) {
activityIndicator.isHidden = !value activityIndicator.isHidden = !value
if value { if value {
activityIndicator.startAnimating() activityIndicator.startAnimating()

View File

@ -122,7 +122,7 @@ class NewsBlurAccountViewController: UITableViewController {
try self.account?.storeCredentials(basicCredentials) try self.account?.storeCredentials(basicCredentials)
try self.account?.storeCredentials(sessionCredentials) try self.account?.storeCredentials(sessionCredentials)
self.account?.refreshAll() { result in self.account?.refreshAll { result in
switch result { switch result {
case .success: case .success:
break break

View File

@ -116,7 +116,6 @@ class ReaderAPIAccountViewController: UITableViewController {
} }
} }
@IBAction func cancel(_ sender: Any) { @IBAction func cancel(_ sender: Any) {
dismiss(animated: true, completion: nil) dismiss(animated: true, completion: nil)
} }
@ -175,7 +174,7 @@ class ReaderAPIAccountViewController: UITableViewController {
self.dismiss(animated: true, completion: nil) self.dismiss(animated: true, completion: nil)
self.account?.refreshAll() { result in self.account?.refreshAll { result in
switch result { switch result {
case .success: case .success:
break break
@ -279,8 +278,6 @@ class ReaderAPIAccountViewController: UITableViewController {
} }
} }
@objc func textDidChange(_ note: Notification) { @objc func textDidChange(_ note: Notification) {
actionButton.isEnabled = !(usernameTextField.text?.isEmpty ?? false) actionButton.isEnabled = !(usernameTextField.text?.isEmpty ?? false)
} }

View File

@ -106,7 +106,7 @@ class AddFolderViewController: UITableViewController {
extension AddFolderViewController: UIPickerViewDataSource, UIPickerViewDelegate { extension AddFolderViewController: UIPickerViewDataSource, UIPickerViewDelegate {
func numberOfComponents(in pickerView: UIPickerView) ->Int { func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1 return 1
} }

View File

@ -251,7 +251,6 @@ struct AppAssets {
return UIColor(named: "controlBackgroundColor")! return UIColor(named: "controlBackgroundColor")!
}() }()
static func image(for accountType: AccountType) -> UIImage? { static func image(for accountType: AccountType) -> UIImage? {
switch accountType { switch accountType {
case .onMyMac: case .onMyMac:

View File

@ -237,7 +237,7 @@ final class AppDefaults {
} }
static func registerDefaults() { static func registerDefaults() {
let defaults: [String : Any] = [Key.userInterfaceColorPalette: UserInterfaceColorPalette.automatic.rawValue, let defaults: [String: Any] = [Key.userInterfaceColorPalette: UserInterfaceColorPalette.automatic.rawValue,
Key.timelineGroupByFeed: false, Key.timelineGroupByFeed: false,
Key.refreshClearsReadArticles: false, Key.refreshClearsReadArticles: false,
Key.timelineNumberOfLines: 2, Key.timelineNumberOfLines: 2,
@ -295,7 +295,7 @@ private extension AppDefaults {
AppDefaults.store.set(date, forKey: key) AppDefaults.store.set(date, forKey: key)
} }
static func sortDirection(for key:String) -> ComparisonResult { static func sortDirection(for key: String) -> ComparisonResult {
let rawInt = int(for: key) let rawInt = int(for: key)
if rawInt == ComparisonResult.orderedAscending.rawValue { if rawInt == ComparisonResult.orderedAscending.rawValue {
return .orderedAscending return .orderedAscending
@ -306,8 +306,7 @@ private extension AppDefaults {
static func setSortDirection(for key: String, _ value: ComparisonResult) { static func setSortDirection(for key: String, _ value: ComparisonResult) {
if value == .orderedAscending { if value == .orderedAscending {
setInt(for: key, ComparisonResult.orderedAscending.rawValue) setInt(for: key, ComparisonResult.orderedAscending.rawValue)
} } else {
else {
setInt(for: key, ComparisonResult.orderedDescending.rawValue) setInt(for: key, ComparisonResult.orderedDescending.rawValue)
} }
} }

View File

@ -95,7 +95,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
self.unreadCount = AccountManager.shared.unreadCount self.unreadCount = AccountManager.shared.unreadCount
} }
UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .sound, .alert]) { (granted, error) in UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .sound, .alert]) { (granted, _) in
if granted { if granted {
DispatchQueue.main.async { DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications() UIApplication.shared.registerForRemoteNotifications()
@ -121,7 +121,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
} }
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
DispatchQueue.main.async { DispatchQueue.main.async {
self.resumeDatabaseProcessingIfNecessary() self.resumeDatabaseProcessingIfNecessary()
AccountManager.shared.receiveRemoteNotification(userInfo: userInfo) { AccountManager.shared.receiveRemoteNotification(userInfo: userInfo) {
@ -153,8 +153,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
// MARK: - API // MARK: - API
func manualRefresh(errorHandler: @escaping (Error) -> ()) { func manualRefresh(errorHandler: @escaping (Error) -> Void) {
UIApplication.shared.connectedScenes.compactMap( { $0.delegate as? SceneDelegate } ).forEach { UIApplication.shared.connectedScenes.compactMap( { $0.delegate as? SceneDelegate }).forEach {
$0.cleanUp(conditional: true) $0.cleanUp(conditional: true)
} }
AccountManager.shared.refreshAll(errorHandler: errorHandler) AccountManager.shared.refreshAll(errorHandler: errorHandler)
@ -269,7 +269,7 @@ private extension AppDelegate {
} }
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
self?.waitToComplete() { [weak self] suspend in self?.waitToComplete { [weak self] suspend in
self?.completeProcessing(suspend) self?.completeProcessing(suspend)
} }
} }
@ -319,7 +319,7 @@ private extension AppDelegate {
} }
DispatchQueue.main.async { DispatchQueue.main.async {
AccountManager.shared.syncArticleStatusAll() { AccountManager.shared.syncArticleStatusAll {
completeProcessing() completeProcessing()
} }
} }
@ -410,7 +410,7 @@ private extension AppDelegate {
private extension AppDelegate { private extension AppDelegate {
func handleMarkAsRead(userInfo: [AnyHashable: Any]) { func handleMarkAsRead(userInfo: [AnyHashable: Any]) {
guard let articlePathUserInfo = userInfo[UserInfoKey.articlePath] as? [AnyHashable : Any], guard let articlePathUserInfo = userInfo[UserInfoKey.articlePath] as? [AnyHashable: Any],
let accountID = articlePathUserInfo[ArticlePathKey.accountID] as? String, let accountID = articlePathUserInfo[ArticlePathKey.accountID] as? String,
let articleID = articlePathUserInfo[ArticlePathKey.articleID] as? String else { let articleID = articlePathUserInfo[ArticlePathKey.articleID] as? String else {
return return
@ -437,7 +437,7 @@ private extension AppDelegate {
} }
func handleMarkAsStarred(userInfo: [AnyHashable: Any]) { func handleMarkAsStarred(userInfo: [AnyHashable: Any]) {
guard let articlePathUserInfo = userInfo[UserInfoKey.articlePath] as? [AnyHashable : Any], guard let articlePathUserInfo = userInfo[UserInfoKey.articlePath] as? [AnyHashable: Any],
let accountID = articlePathUserInfo[ArticlePathKey.accountID] as? String, let accountID = articlePathUserInfo[ArticlePathKey.accountID] as? String,
let articleID = articlePathUserInfo[ArticlePathKey.articleID] as? String else { let articleID = articlePathUserInfo[ArticlePathKey.articleID] as? String else {
return return

View File

@ -15,7 +15,6 @@ import UIKit
@objc optional func searchBar(_ searchBar: ArticleSearchBar, textDidChange: String) @objc optional func searchBar(_ searchBar: ArticleSearchBar, textDidChange: String)
} }
@IBDesignable final class ArticleSearchBar: UIStackView { @IBDesignable final class ArticleSearchBar: UIStackView {
var searchField: UISearchTextField! var searchField: UISearchTextField!
var nextButton: UIButton! var nextButton: UIButton!

View File

@ -32,7 +32,7 @@ open class ImageScrollView: UIScrollView {
@objc open var imageContentMode: ScaleMode = .widthFill @objc open var imageContentMode: ScaleMode = .widthFill
@objc open var initialOffset: Offset = .beginning @objc open var initialOffset: Offset = .beginning
@objc public private(set) var zoomView: UIImageView? = nil @objc public private(set) var zoomView: UIImageView?
@objc open weak var imageScrollViewDelegate: ImageScrollViewDelegate? @objc open weak var imageScrollViewDelegate: ImageScrollViewDelegate?
@ -146,7 +146,7 @@ open class ImageScrollView: UIScrollView {
} }
private func maximumContentOffset() -> CGPoint { private func maximumContentOffset() -> CGPoint {
return CGPoint(x: contentSize.width - bounds.width,y:contentSize.height - bounds.height) return CGPoint(x: contentSize.width - bounds.width, y: contentSize.height - bounds.height)
} }
private func minimumContentOffset() -> CGPoint { private func minimumContentOffset() -> CGPoint {
@ -238,7 +238,6 @@ open class ImageScrollView: UIScrollView {
minScale = yScale minScale = yScale
} }
let maxScale = maxScaleFromMinScale*minScale let maxScale = maxScaleFromMinScale*minScale
// don't let minScale exceed maxScale. (If the image is smaller than the screen, we don't want to force it to be zoomed.) // don't let minScale exceed maxScale. (If the image is smaller than the screen, we don't want to force it to be zoomed.)

View File

@ -48,7 +48,7 @@ class ImageTransition: NSObject, UIViewControllerAnimatedTransitioning {
UIView.animate( UIView.animate(
withDuration: duration, withDuration: duration,
delay:0.0, delay: 0.0,
usingSpringWithDamping: 0.8, usingSpringWithDamping: 0.8,
initialSpringVelocity: 0.2, initialSpringVelocity: 0.2,
animations: { animations: {
@ -87,14 +87,14 @@ class ImageTransition: NSObject, UIViewControllerAnimatedTransitioning {
UIView.animate( UIView.animate(
withDuration: duration, withDuration: duration,
delay:0.0, delay: 0.0,
usingSpringWithDamping: 0.8, usingSpringWithDamping: 0.8,
initialSpringVelocity: 0.2, initialSpringVelocity: 0.2,
animations: { animations: {
imageView.frame = self.originFrame imageView.frame = self.originFrame
}, completion: { _ in }, completion: { _ in
if let controller = self.webViewController { if let controller = self.webViewController {
controller.showClickedImage() { controller.showClickedImage {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
imageView.removeFromSuperview() imageView.removeFromSuperview()
transitionContext.completeTransition(true) transitionContext.completeTransition(true)

View File

@ -57,7 +57,7 @@ final class ImageViewController: UIViewController {
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator) super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { [weak self] context in coordinator.animate(alongsideTransition: { [weak self] _ in
self?.imageScrollView.resize() self?.imageScrollView.resize()
}) })
} }
@ -74,7 +74,7 @@ final class ImageViewController: UIViewController {
dismiss(animated: true) dismiss(animated: true)
} }
private func layoutTitleLabel(){ private func layoutTitleLabel() {
let width = view.frame.width let width = view.frame.width
let multiplier = UIDevice.current.userInterfaceIdiom == .pad ? CGFloat(0.1) : CGFloat(0.04) let multiplier = UIDevice.current.userInterfaceIdiom == .pad ? CGFloat(0.1) : CGFloat(0.04)
titleLeading.constant += width * multiplier titleLeading.constant += width * multiplier
@ -95,5 +95,4 @@ extension ImageViewController: ImageScrollViewDelegate {
dismiss(animated: true) dismiss(animated: true)
} }
} }

View File

@ -43,7 +43,7 @@ final class WebViewController: UIViewController {
private lazy var transition = ImageTransition(controller: self) private lazy var transition = ImageTransition(controller: self)
private var clickedImageCompletion: (() -> Void)? private var clickedImageCompletion: (() -> Void)?
private var articleExtractor: ArticleExtractor? = nil private var articleExtractor: ArticleExtractor?
var extractedArticle: ExtractedArticle? { var extractedArticle: ExtractedArticle? {
didSet { didSet {
windowScrollY = 0 windowScrollY = 0
@ -164,7 +164,7 @@ final class WebViewController: UIViewController {
let overlap = 2 * UIFont.systemFont(ofSize: UIFont.systemFontSize).lineHeight * UIScreen.main.scale let overlap = 2 * UIFont.systemFont(ofSize: UIFont.systemFontSize).lineHeight * UIScreen.main.scale
let scrollToY: CGFloat = { let scrollToY: CGFloat = {
let scrollDistance = webView.scrollView.layoutMarginsGuide.layoutFrame.height - overlap; let scrollDistance = webView.scrollView.layoutMarginsGuide.layoutFrame.height - overlap
let fullScroll = webView.scrollView.contentOffset.y + (scrollingUp ? -scrollDistance : scrollDistance) let fullScroll = webView.scrollView.contentOffset.y + (scrollingUp ? -scrollDistance : scrollDistance)
let final = finalScrollPosition(scrollingUp: scrollingUp) let final = finalScrollPosition(scrollingUp: scrollingUp)
return (scrollingUp ? fullScroll > final : fullScroll < final) ? fullScroll : final return (scrollingUp ? fullScroll > final : fullScroll < final) ? fullScroll : final
@ -326,7 +326,7 @@ extension WebViewController: ArticleExtractorDelegate {
extension WebViewController: UIContextMenuInteractionDelegate { extension WebViewController: UIContextMenuInteractionDelegate {
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? { func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
return UIContextMenuConfiguration(identifier: nil, previewProvider: contextMenuPreviewProvider) { [weak self] suggestedActions in return UIContextMenuConfiguration(identifier: nil, previewProvider: contextMenuPreviewProvider) { [weak self] _ in
guard let self = self else { return nil } guard let self = self else { return nil }
var menus = [UIMenu]() var menus = [UIMenu]()
@ -400,7 +400,7 @@ extension WebViewController: WKNavigationDelegate {
} }
if UIApplication.shared.canOpenURL(emailAddress) { if UIApplication.shared.canOpenURL(emailAddress) {
UIApplication.shared.open(emailAddress, options: [.universalLinksOnly : false], completionHandler: nil) UIApplication.shared.open(emailAddress, options: [.universalLinksOnly: false], completionHandler: nil)
} else { } else {
let alert = UIAlertController(title: NSLocalizedString("Error", comment: "Error"), message: NSLocalizedString("This device cannot send emails.", comment: "This device cannot send emails."), preferredStyle: .alert) let alert = UIAlertController(title: NSLocalizedString("Error", comment: "Error"), message: NSLocalizedString("This device cannot send emails.", comment: "This device cannot send emails."), preferredStyle: .alert)
alert.addAction(.init(title: NSLocalizedString("Dismiss", comment: "Dismiss"), style: .cancel, handler: nil)) alert.addAction(.init(title: NSLocalizedString("Dismiss", comment: "Dismiss"), style: .cancel, handler: nil))
@ -410,7 +410,7 @@ extension WebViewController: WKNavigationDelegate {
decisionHandler(.cancel) decisionHandler(.cancel)
if UIApplication.shared.canOpenURL(url) { if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, options: [.universalLinksOnly : false], completionHandler: nil) UIApplication.shared.open(url, options: [.universalLinksOnly: false], completionHandler: nil)
} }
} else { } else {
@ -505,8 +505,6 @@ extension WebViewController: UIScrollViewDelegate {
} }
// MARK: JSON // MARK: JSON
private struct ImageClickMessage: Codable { private struct ImageClickMessage: Codable {
@ -727,7 +725,7 @@ private extension WebViewController {
func prevArticleAction() -> UIAction? { func prevArticleAction() -> UIAction? {
guard coordinator.isPrevArticleAvailable else { return nil } guard coordinator.isPrevArticleAvailable else { return nil }
let title = NSLocalizedString("Previous Article", comment: "Previous Article") let title = NSLocalizedString("Previous Article", comment: "Previous Article")
return UIAction(title: title, image: AppAssets.prevArticleImage) { [weak self] action in return UIAction(title: title, image: AppAssets.prevArticleImage) { [weak self] _ in
self?.coordinator.selectPrevArticle() self?.coordinator.selectPrevArticle()
} }
} }
@ -735,7 +733,7 @@ private extension WebViewController {
func nextArticleAction() -> UIAction? { func nextArticleAction() -> UIAction? {
guard coordinator.isNextArticleAvailable else { return nil } guard coordinator.isNextArticleAvailable else { return nil }
let title = NSLocalizedString("Next Article", comment: "Next Article") let title = NSLocalizedString("Next Article", comment: "Next Article")
return UIAction(title: title, image: AppAssets.nextArticleImage) { [weak self] action in return UIAction(title: title, image: AppAssets.nextArticleImage) { [weak self] _ in
self?.coordinator.selectNextArticle() self?.coordinator.selectNextArticle()
} }
} }
@ -745,7 +743,7 @@ private extension WebViewController {
let title = article.status.read ? NSLocalizedString("Mark as Unread", comment: "Mark as Unread") : NSLocalizedString("Mark as Read", comment: "Mark as Read") let title = article.status.read ? NSLocalizedString("Mark as Unread", comment: "Mark as Unread") : NSLocalizedString("Mark as Read", comment: "Mark as Read")
let readImage = article.status.read ? AppAssets.circleClosedImage : AppAssets.circleOpenImage let readImage = article.status.read ? AppAssets.circleClosedImage : AppAssets.circleOpenImage
return UIAction(title: title, image: readImage) { [weak self] action in return UIAction(title: title, image: readImage) { [weak self] _ in
self?.coordinator.toggleReadForCurrentArticle() self?.coordinator.toggleReadForCurrentArticle()
} }
} }
@ -754,7 +752,7 @@ private extension WebViewController {
let starred = article?.status.starred ?? false let starred = article?.status.starred ?? false
let title = starred ? NSLocalizedString("Mark as Unstarred", comment: "Mark as Unstarred") : NSLocalizedString("Mark as Starred", comment: "Mark as Starred") let title = starred ? NSLocalizedString("Mark as Unstarred", comment: "Mark as Unstarred") : NSLocalizedString("Mark as Starred", comment: "Mark as Starred")
let starredImage = starred ? AppAssets.starOpenImage : AppAssets.starClosedImage let starredImage = starred ? AppAssets.starOpenImage : AppAssets.starClosedImage
return UIAction(title: title, image: starredImage) { [weak self] action in return UIAction(title: title, image: starredImage) { [weak self] _ in
self?.coordinator.toggleStarredForCurrentArticle() self?.coordinator.toggleStarredForCurrentArticle()
} }
} }
@ -762,7 +760,7 @@ private extension WebViewController {
func nextUnreadArticleAction() -> UIAction? { func nextUnreadArticleAction() -> UIAction? {
guard coordinator.isAnyUnreadAvailable else { return nil } guard coordinator.isAnyUnreadAvailable else { return nil }
let title = NSLocalizedString("Next Unread Article", comment: "Next Unread Article") let title = NSLocalizedString("Next Unread Article", comment: "Next Unread Article")
return UIAction(title: title, image: AppAssets.nextUnreadArticleImage) { [weak self] action in return UIAction(title: title, image: AppAssets.nextUnreadArticleImage) { [weak self] _ in
self?.coordinator.selectNextUnread() self?.coordinator.selectNextUnread()
} }
} }
@ -771,14 +769,14 @@ private extension WebViewController {
let extracted = articleExtractorButtonState == .on let extracted = articleExtractorButtonState == .on
let title = extracted ? NSLocalizedString("Show Feed Article", comment: "Show Feed Article") : NSLocalizedString("Show Reader View", comment: "Show Reader View") let title = extracted ? NSLocalizedString("Show Feed Article", comment: "Show Feed Article") : NSLocalizedString("Show Reader View", comment: "Show Reader View")
let extractorImage = extracted ? AppAssets.articleExtractorOffSF : AppAssets.articleExtractorOnSF let extractorImage = extracted ? AppAssets.articleExtractorOffSF : AppAssets.articleExtractorOnSF
return UIAction(title: title, image: extractorImage) { [weak self] action in return UIAction(title: title, image: extractorImage) { [weak self] _ in
self?.toggleArticleExtractor() self?.toggleArticleExtractor()
} }
} }
func shareAction() -> UIAction { func shareAction() -> UIAction {
let title = NSLocalizedString("Share", comment: "Share") let title = NSLocalizedString("Share", comment: "Share")
return UIAction(title: title, image: AppAssets.shareImage) { [weak self] action in return UIAction(title: title, image: AppAssets.shareImage) { [weak self] _ in
self?.showActivityDialog() self?.showActivityDialog()
} }
} }

View File

@ -18,7 +18,7 @@ class ArticleActivityItemSource: NSObject, UIActivityItemSource {
self.subject = subject self.subject = subject
} }
func activityViewControllerPlaceholderItem(_ : UIActivityViewController) -> Any { func activityViewControllerPlaceholderItem(_: UIActivityViewController) -> Any {
return url return url
} }

View File

@ -14,7 +14,7 @@ struct ErrorHandler {
private static var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "Application") private static var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "Application")
public static func present(_ viewController: UIViewController) -> (Error) -> () { public static func present(_ viewController: UIViewController) -> (Error) -> Void {
return { [weak viewController] error in return { [weak viewController] error in
if UIApplication.shared.applicationState == .active { if UIApplication.shared.applicationState == .active {
viewController?.presentError(error) viewController?.presentError(error)

View File

@ -10,7 +10,7 @@ import UIKit
final class IconView: UIView { final class IconView: UIView {
var iconImage: IconImage? = nil { var iconImage: IconImage? {
didSet { didSet {
guard iconImage !== oldValue else { guard iconImage !== oldValue else {
return return
@ -19,8 +19,7 @@ final class IconView: UIView {
if traitCollection.userInterfaceStyle == .dark { if traitCollection.userInterfaceStyle == .dark {
let isDark = iconImage?.isDark ?? false let isDark = iconImage?.isDark ?? false
isDiscernable = !isDark isDiscernable = !isDark
} } else {
else {
let isBright = iconImage?.isBright ?? false let isBright = iconImage?.isBright ?? false
isDiscernable = !isBright isDiscernable = !isBright
} }
@ -96,8 +95,7 @@ private extension IconView {
} }
let offset = floor((viewSize.height - imageSize.height) / 2.0) let offset = floor((viewSize.height - imageSize.height) / 2.0)
return CGRect(x: offset, y: offset, width: imageSize.width, height: imageSize.height) return CGRect(x: offset, y: offset, width: imageSize.width, height: imageSize.height)
} } else if imageSize.height > imageSize.width {
else if imageSize.height > imageSize.width {
let factor = viewSize.height / imageSize.height let factor = viewSize.height / imageSize.height
let width = imageSize.width * factor let width = imageSize.width * factor
let originX = floor((viewSize.width - width) / 2.0) let originX = floor((viewSize.width - width) / 2.0)

View File

@ -107,7 +107,7 @@ class AccountInspectorViewController: UITableViewController {
alertController.addAction(cancelAction) alertController.addAction(cancelAction)
let markTitle = NSLocalizedString("Remove", comment: "Remove") let markTitle = NSLocalizedString("Remove", comment: "Remove")
let markAction = UIAlertAction(title: markTitle, style: .default) { [weak self] (action) in let markAction = UIAlertAction(title: markTitle, style: .default) { [weak self] (_) in
guard let self = self, let account = self.account else { return } guard let self = self, let account = self.account else { return }
AccountManager.shared.deleteAccount(account) AccountManager.shared.deleteAccount(account)
if self.isModal { if self.isModal {

View File

@ -82,7 +82,7 @@ class FeedInspectorViewController: UITableViewController {
} else if settings.authorizationStatus == .authorized { } else if settings.authorizationStatus == .authorized {
feed.isNotifyAboutNewArticles = notifyAboutNewArticlesSwitch.isOn feed.isNotifyAboutNewArticles = notifyAboutNewArticlesSwitch.isOn
} else { } else {
UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .sound, .alert]) { (granted, error) in UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .sound, .alert]) { (granted, _) in
self.updateNotificationSettings() self.updateNotificationSettings()
if granted { if granted {
DispatchQueue.main.async { DispatchQueue.main.async {
@ -123,7 +123,6 @@ class FeedInspectorViewController: UITableViewController {
return section return section
} }
} }
// MARK: Table View // MARK: Table View
@ -214,8 +213,8 @@ extension FeedInspectorViewController {
func notificationUpdateErrorAlert() -> UIAlertController { func notificationUpdateErrorAlert() -> UIAlertController {
let alert = UIAlertController(title: NSLocalizedString("Enable Notifications", comment: "Notifications"), let alert = UIAlertController(title: NSLocalizedString("Enable Notifications", comment: "Notifications"),
message: NSLocalizedString("Notifications need to be enabled in the Settings app.", comment: "Notifications need to be enabled in the Settings app."), preferredStyle: .alert) message: NSLocalizedString("Notifications need to be enabled in the Settings app.", comment: "Notifications need to be enabled in the Settings app."), preferredStyle: .alert)
let openSettings = UIAlertAction(title: NSLocalizedString("Open Settings", comment: "Open Settings"), style: .default) { (action) in let openSettings = UIAlertAction(title: NSLocalizedString("Open Settings", comment: "Open Settings"), style: .default) { (_) in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : false], completionHandler: nil) UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly: false], completionHandler: nil)
} }
let dismiss = UIAlertAction(title: NSLocalizedString("Dismiss", comment: "Dismiss"), style: .cancel, handler: nil) let dismiss = UIAlertAction(title: NSLocalizedString("Dismiss", comment: "Dismiss"), style: .cancel, handler: nil)
alert.addAction(openSettings) alert.addAction(openSettings)

View File

@ -42,7 +42,7 @@ class KeyboardManager {
let specificFile = Bundle.main.path(forResource: type.rawValue, ofType: "plist")! let specificFile = Bundle.main.path(forResource: type.rawValue, ofType: "plist")!
let specificEntries = NSArray(contentsOfFile: specificFile)! as! [[String: Any]] let specificEntries = NSArray(contentsOfFile: specificFile)! as! [[String: Any]]
_keyCommands.append(contentsOf: specificEntries.compactMap { KeyboardManager.createKeyCommand(keyEntry: $0) } ) _keyCommands.append(contentsOf: specificEntries.compactMap { KeyboardManager.createKeyCommand(keyEntry: $0) })
} }
static func createKeyCommand(title: String, action: String, input: String, modifiers: UIKeyModifierFlags) -> UIKeyCommand { static func createKeyCommand(title: String, action: String, input: String, modifiers: UIKeyModifierFlags) -> UIKeyCommand {
@ -72,7 +72,7 @@ private extension KeyboardManager {
static func createKeyCommandInput(keyEntry: [String: Any]) -> String? { static func createKeyCommandInput(keyEntry: [String: Any]) -> String? {
guard let key = keyEntry["key"] as? String else { return nil } guard let key = keyEntry["key"] as? String else { return nil }
switch(key) { switch key {
case "[space]": case "[space]":
return "\u{0020}" return "\u{0020}"
case "[uparrow]": case "[uparrow]":

View File

@ -15,7 +15,7 @@ protocol MainFeedTableViewCellDelegate: AnyObject {
func mainFeedTableViewCellDisclosureDidToggle(_ sender: MainFeedTableViewCell, expanding: Bool) func mainFeedTableViewCellDisclosureDidToggle(_ sender: MainFeedTableViewCell, expanding: Bool)
} }
class MainFeedTableViewCell : VibrantTableViewCell { class MainFeedTableViewCell: VibrantTableViewCell {
weak var delegate: MainFeedTableViewCellDelegate? weak var delegate: MainFeedTableViewCellDelegate?
@ -126,10 +126,6 @@ class MainFeedTableViewCell : VibrantTableViewCell {
} }
} }
override func applyThemeProperties() {
super.applyThemeProperties()
}
override func willTransition(to state: UITableViewCell.StateMask) { override func willTransition(to state: UITableViewCell.StateMask) {
super.willTransition(to: state) super.willTransition(to: state)
isShowingEditControl = state.contains(.showingEditControl) isShowingEditControl = state.contains(.showingEditControl)

View File

@ -8,7 +8,7 @@
import UIKit import UIKit
class MainFeedUnreadCountView : UIView { class MainFeedUnreadCountView: UIView {
var padding: UIEdgeInsets { var padding: UIEdgeInsets {
return UIEdgeInsets(top: 1.0, left: 9.0, bottom: 1.0, right: 9.0) return UIEdgeInsets(top: 1.0, left: 9.0, bottom: 1.0, right: 9.0)
@ -120,4 +120,3 @@ class MainFeedUnreadCountView : UIView {
} }
} }

View File

@ -162,5 +162,4 @@ extension MainFeedViewController: UITableViewDropDelegate {
} }
} }
} }

View File

@ -125,7 +125,7 @@ class MainFeedViewController: UITableViewController, UndoableCommandRunner {
return return
} }
var node: Node? = nil var node: Node?
if let coordinator = unreadCountProvider as? SceneCoordinator, let feed = coordinator.timelineFeed { if let coordinator = unreadCountProvider as? SceneCoordinator, let feed = coordinator.timelineFeed {
node = coordinator.rootNode.descendantNodeRepresentingObject(feed as AnyObject) node = coordinator.rootNode.descendantNodeRepresentingObject(feed as AnyObject)
} else { } else {
@ -249,7 +249,7 @@ class MainFeedViewController: UITableViewController, UndoableCommandRunner {
} }
headerView.gestureRecognizers?.removeAll() headerView.gestureRecognizers?.removeAll()
let tap = UITapGestureRecognizer(target: self, action:#selector(self.toggleSectionHeader(_:))) let tap = UITapGestureRecognizer(target: self, action: #selector(self.toggleSectionHeader(_:)))
headerView.addGestureRecognizer(tap) headerView.addGestureRecognizer(tap)
// Without this the swipe gesture registers on the cell below // Without this the swipe gesture registers on the cell below
@ -279,7 +279,7 @@ class MainFeedViewController: UITableViewController, UndoableCommandRunner {
// Set up the delete action // Set up the delete action
let deleteTitle = NSLocalizedString("Delete", comment: "Delete") let deleteTitle = NSLocalizedString("Delete", comment: "Delete")
let deleteAction = UIContextualAction(style: .normal, title: deleteTitle) { [weak self] (action, view, completion) in let deleteAction = UIContextualAction(style: .normal, title: deleteTitle) { [weak self] (_, _, completion) in
self?.delete(indexPath: indexPath) self?.delete(indexPath: indexPath)
completion(true) completion(true)
} }
@ -288,7 +288,7 @@ class MainFeedViewController: UITableViewController, UndoableCommandRunner {
// Set up the rename action // Set up the rename action
let renameTitle = NSLocalizedString("Rename", comment: "Rename") let renameTitle = NSLocalizedString("Rename", comment: "Rename")
let renameAction = UIContextualAction(style: .normal, title: renameTitle) { [weak self] (action, view, completion) in let renameAction = UIContextualAction(style: .normal, title: renameTitle) { [weak self] (_, _, completion) in
self?.rename(indexPath: indexPath) self?.rename(indexPath: indexPath)
completion(true) completion(true)
} }
@ -686,7 +686,7 @@ extension MainFeedViewController: UIContextMenuInteractionDelegate {
return nil return nil
} }
return UIContextMenuConfiguration(identifier: sectionIndex as NSCopying, previewProvider: nil) { suggestedActions in return UIContextMenuConfiguration(identifier: sectionIndex as NSCopying, previewProvider: nil) { _ in
var menuElements = [UIMenuElement]() var menuElements = [UIMenuElement]()
menuElements.append(UIMenu(title: "", options: .displayInline, children: [self.getAccountInfoAction(account: account)])) menuElements.append(UIMenu(title: "", options: .displayInline, children: [self.getAccountInfoAction(account: account)]))
@ -890,7 +890,7 @@ private extension MainFeedViewController {
} }
func makeFeedContextMenu(indexPath: IndexPath, includeDeleteRename: Bool) -> UIContextMenuConfiguration { func makeFeedContextMenu(indexPath: IndexPath, includeDeleteRename: Bool) -> UIContextMenuConfiguration {
return UIContextMenuConfiguration(identifier: MainFeedRowIdentifier(indexPath: indexPath), previewProvider: nil, actionProvider: { [ weak self] suggestedActions in return UIContextMenuConfiguration(identifier: MainFeedRowIdentifier(indexPath: indexPath), previewProvider: nil, actionProvider: { [ weak self] _ in
guard let self = self else { return nil } guard let self = self else { return nil }
@ -935,7 +935,7 @@ private extension MainFeedViewController {
} }
func makeFolderContextMenu(indexPath: IndexPath) -> UIContextMenuConfiguration { func makeFolderContextMenu(indexPath: IndexPath) -> UIContextMenuConfiguration {
return UIContextMenuConfiguration(identifier: MainFeedRowIdentifier(indexPath: indexPath), previewProvider: nil, actionProvider: { [weak self] suggestedActions in return UIContextMenuConfiguration(identifier: MainFeedRowIdentifier(indexPath: indexPath), previewProvider: nil, actionProvider: { [weak self] _ in
guard let self = self else { return nil } guard let self = self else { return nil }
@ -962,7 +962,7 @@ private extension MainFeedViewController {
return nil return nil
} }
return UIContextMenuConfiguration(identifier: MainFeedRowIdentifier(indexPath: indexPath), previewProvider: nil, actionProvider: { suggestedActions in return UIContextMenuConfiguration(identifier: MainFeedRowIdentifier(indexPath: indexPath), previewProvider: nil, actionProvider: { _ in
return UIMenu(title: "", children: [markAllAction]) return UIMenu(title: "", children: [markAllAction])
}) })
} }
@ -973,7 +973,7 @@ private extension MainFeedViewController {
} }
let title = NSLocalizedString("Open Home Page", comment: "Open Home Page") let title = NSLocalizedString("Open Home Page", comment: "Open Home Page")
let action = UIAction(title: title, image: AppAssets.safariImage) { [weak self] action in let action = UIAction(title: title, image: AppAssets.safariImage) { [weak self] _ in
self?.coordinator.showBrowserForFeed(indexPath) self?.coordinator.showBrowserForFeed(indexPath)
} }
return action return action
@ -985,7 +985,7 @@ private extension MainFeedViewController {
} }
let title = NSLocalizedString("Open Home Page", comment: "Open Home Page") let title = NSLocalizedString("Open Home Page", comment: "Open Home Page")
let action = UIAlertAction(title: title, style: .default) { [weak self] action in let action = UIAlertAction(title: title, style: .default) { [weak self] _ in
self?.coordinator.showBrowserForFeed(indexPath) self?.coordinator.showBrowserForFeed(indexPath)
completion(true) completion(true)
} }
@ -999,7 +999,7 @@ private extension MainFeedViewController {
} }
let title = NSLocalizedString("Copy Feed URL", comment: "Copy Feed URL") let title = NSLocalizedString("Copy Feed URL", comment: "Copy Feed URL")
let action = UIAction(title: title, image: AppAssets.copyImage) { action in let action = UIAction(title: title, image: AppAssets.copyImage) { _ in
UIPasteboard.general.url = url UIPasteboard.general.url = url
} }
return action return action
@ -1012,7 +1012,7 @@ private extension MainFeedViewController {
} }
let title = NSLocalizedString("Copy Feed URL", comment: "Copy Feed URL") let title = NSLocalizedString("Copy Feed URL", comment: "Copy Feed URL")
let action = UIAlertAction(title: title, style: .default) { action in let action = UIAlertAction(title: title, style: .default) { _ in
UIPasteboard.general.url = url UIPasteboard.general.url = url
completion(true) completion(true)
} }
@ -1027,7 +1027,7 @@ private extension MainFeedViewController {
} }
let title = NSLocalizedString("Copy Home Page URL", comment: "Copy Home Page URL") let title = NSLocalizedString("Copy Home Page URL", comment: "Copy Home Page URL")
let action = UIAction(title: title, image: AppAssets.copyImage) { action in let action = UIAction(title: title, image: AppAssets.copyImage) { _ in
UIPasteboard.general.url = url UIPasteboard.general.url = url
} }
return action return action
@ -1041,7 +1041,7 @@ private extension MainFeedViewController {
} }
let title = NSLocalizedString("Copy Home Page URL", comment: "Copy Home Page URL") let title = NSLocalizedString("Copy Home Page URL", comment: "Copy Home Page URL")
let action = UIAlertAction(title: title, style: .default) { action in let action = UIAlertAction(title: title, style: .default) { _ in
UIPasteboard.general.url = url UIPasteboard.general.url = url
completion(true) completion(true)
} }
@ -1061,8 +1061,7 @@ private extension MainFeedViewController {
completion(true) completion(true)
} }
let action = UIAlertAction(title: title, style: .default) { [weak self] _ in
let action = UIAlertAction(title: title, style: .default) { [weak self] action in
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView, cancelCompletion: cancel) { [weak self] in MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView, cancelCompletion: cancel) { [weak self] in
self?.coordinator.markAllAsRead(Array(articles)) self?.coordinator.markAllAsRead(Array(articles))
completion(true) completion(true)
@ -1074,7 +1073,7 @@ private extension MainFeedViewController {
func deleteAction(indexPath: IndexPath) -> UIAction { func deleteAction(indexPath: IndexPath) -> UIAction {
let title = NSLocalizedString("Delete", comment: "Delete") let title = NSLocalizedString("Delete", comment: "Delete")
let action = UIAction(title: title, image: AppAssets.trashImage, attributes: .destructive) { [weak self] action in let action = UIAction(title: title, image: AppAssets.trashImage, attributes: .destructive) { [weak self] _ in
self?.delete(indexPath: indexPath) self?.delete(indexPath: indexPath)
} }
return action return action
@ -1082,7 +1081,7 @@ private extension MainFeedViewController {
func renameAction(indexPath: IndexPath) -> UIAction { func renameAction(indexPath: IndexPath) -> UIAction {
let title = NSLocalizedString("Rename", comment: "Rename") let title = NSLocalizedString("Rename", comment: "Rename")
let action = UIAction(title: title, image: AppAssets.editImage) { [weak self] action in let action = UIAction(title: title, image: AppAssets.editImage) { [weak self] _ in
self?.rename(indexPath: indexPath) self?.rename(indexPath: indexPath)
} }
return action return action
@ -1094,7 +1093,7 @@ private extension MainFeedViewController {
} }
let title = NSLocalizedString("Get Info", comment: "Get Info") let title = NSLocalizedString("Get Info", comment: "Get Info")
let action = UIAction(title: title, image: AppAssets.infoImage) { [weak self] action in let action = UIAction(title: title, image: AppAssets.infoImage) { [weak self] _ in
self?.coordinator.showFeedInspector(for: feed) self?.coordinator.showFeedInspector(for: feed)
} }
return action return action
@ -1102,7 +1101,7 @@ private extension MainFeedViewController {
func getAccountInfoAction(account: Account) -> UIAction { func getAccountInfoAction(account: Account) -> UIAction {
let title = NSLocalizedString("Get Info", comment: "Get Info") let title = NSLocalizedString("Get Info", comment: "Get Info")
let action = UIAction(title: title, image: AppAssets.infoImage) { [weak self] action in let action = UIAction(title: title, image: AppAssets.infoImage) { [weak self] _ in
self?.coordinator.showAccountInspector(for: account) self?.coordinator.showAccountInspector(for: account)
} }
return action return action
@ -1110,7 +1109,7 @@ private extension MainFeedViewController {
func deactivateAccountAction(account: Account) -> UIAction { func deactivateAccountAction(account: Account) -> UIAction {
let title = NSLocalizedString("Deactivate", comment: "Deactivate") let title = NSLocalizedString("Deactivate", comment: "Deactivate")
let action = UIAction(title: title, image: AppAssets.deactivateImage) { action in let action = UIAction(title: title, image: AppAssets.deactivateImage) { _ in
account.isActive = false account.isActive = false
} }
return action return action
@ -1122,7 +1121,7 @@ private extension MainFeedViewController {
} }
let title = NSLocalizedString("Get Info", comment: "Get Info") let title = NSLocalizedString("Get Info", comment: "Get Info")
let action = UIAlertAction(title: title, style: .default) { [weak self] action in let action = UIAlertAction(title: title, style: .default) { [weak self] _ in
self?.coordinator.showFeedInspector(for: feed) self?.coordinator.showFeedInspector(for: feed)
completion(true) completion(true)
} }
@ -1138,7 +1137,7 @@ private extension MainFeedViewController {
let localizedMenuText = NSLocalizedString("Mark All as Read in “%@”", comment: "Command") let localizedMenuText = NSLocalizedString("Mark All as Read in “%@”", comment: "Command")
let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, feed.nameForDisplay) as String let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, feed.nameForDisplay) as String
let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] action in let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] _ in
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in
if let articles = try? feed.fetchUnreadArticles() { if let articles = try? feed.fetchUnreadArticles() {
self?.coordinator.markAllAsRead(Array(articles)) self?.coordinator.markAllAsRead(Array(articles))
@ -1156,7 +1155,7 @@ private extension MainFeedViewController {
let localizedMenuText = NSLocalizedString("Mark All as Read in “%@”", comment: "Command") let localizedMenuText = NSLocalizedString("Mark All as Read in “%@”", comment: "Command")
let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, account.nameForDisplay) as String let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, account.nameForDisplay) as String
let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] action in let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] _ in
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in
// If you don't have this delay the screen flashes when it executes this code // If you don't have this delay the screen flashes when it executes this code
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
@ -1170,7 +1169,6 @@ private extension MainFeedViewController {
return action return action
} }
func rename(indexPath: IndexPath) { func rename(indexPath: IndexPath) {
guard let feed = coordinator.nodeFor(indexPath)?.representedObject as? SidebarItem else { return } guard let feed = coordinator.nodeFor(indexPath)?.representedObject as? SidebarItem else { return }
@ -1183,7 +1181,7 @@ private extension MainFeedViewController {
alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel)) alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel))
let renameTitle = NSLocalizedString("Rename", comment: "Rename") let renameTitle = NSLocalizedString("Rename", comment: "Rename")
let renameAction = UIAlertAction(title: renameTitle, style: .default) { [weak self] action in let renameAction = UIAlertAction(title: renameTitle, style: .default) { [weak self] _ in
guard let name = alertController.textFields?[0].text, !name.isEmpty else { guard let name = alertController.textFields?[0].text, !name.isEmpty else {
return return
@ -1214,7 +1212,7 @@ private extension MainFeedViewController {
alertController.addAction(renameAction) alertController.addAction(renameAction)
alertController.preferredAction = renameAction alertController.preferredAction = renameAction
alertController.addTextField() { textField in alertController.addTextField { textField in
textField.text = feed.nameForDisplay textField.text = feed.nameForDisplay
textField.placeholder = NSLocalizedString("Name", comment: "Name") textField.placeholder = NSLocalizedString("Name", comment: "Name")
} }
@ -1246,7 +1244,7 @@ private extension MainFeedViewController {
alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel)) alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel))
let deleteTitle = NSLocalizedString("Delete", comment: "Delete") let deleteTitle = NSLocalizedString("Delete", comment: "Delete")
let deleteAction = UIAlertAction(title: deleteTitle, style: .destructive) { [weak self] action in let deleteAction = UIAlertAction(title: deleteTitle, style: .destructive) { [weak self] _ in
self?.performDelete(indexPath: indexPath) self?.performDelete(indexPath: indexPath)
} }
alertController.addAction(deleteAction) alertController.addAction(deleteAction)
@ -1284,6 +1282,6 @@ extension MainFeedViewController: UIGestureRecognizerDelegate {
return false return false
} }
let velocity = gestureRecognizer.velocity(in: self.view) let velocity = gestureRecognizer.velocity(in: self.view)
return abs(velocity.x) > abs(velocity.y); return abs(velocity.x) > abs(velocity.y)
} }
} }

View File

@ -43,8 +43,7 @@ struct MainTimelineCellData {
if let feedName = feedName { if let feedName = feedName {
self.feedName = ArticleStringFormatter.truncatedFeedName(feedName) self.feedName = ArticleStringFormatter.truncatedFeedName(feedName)
} } else {
else {
self.feedName = "" self.feedName = ""
} }
@ -66,7 +65,7 @@ struct MainTimelineCellData {
} }
init() { //Empty init() { // Empty
self.title = "" self.title = ""
self.attributedTitle = NSAttributedString() self.attributedTitle = NSAttributedString()
self.summary = "" self.summary = ""

View File

@ -31,7 +31,6 @@ extension MainTimelineCellLayout {
return r return r
} }
static func rectForStar(_ point: CGPoint) -> CGRect { static func rectForStar(_ point: CGPoint) -> CGRect {
var r = CGRect.zero var r = CGRect.zero
r.size.width = MainTimelineDefaultCellLayout.starDimension r.size.width = MainTimelineDefaultCellLayout.starDimension

View File

@ -165,8 +165,7 @@ private extension MultilineUILabelSizer {
if oneWidth < width && (oneWidth > smallNeighbor.width || smallNeighbor.width == 0) { if oneWidth < width && (oneWidth > smallNeighbor.width || smallNeighbor.width == 0) {
smallNeighbor = (oneWidth, oneHeight) smallNeighbor = (oneWidth, oneHeight)
} } else if oneWidth > width && (oneWidth < largeNeighbor.width || largeNeighbor.width == 0) {
else if oneWidth > width && (oneWidth < largeNeighbor.width || largeNeighbor.width == 0) {
largeNeighbor = (oneWidth, oneHeight) largeNeighbor = (oneWidth, oneHeight)
} }

View File

@ -8,11 +8,10 @@
import UIKit import UIKit
class MainTimelineDataSource<SectionIdentifierType, ItemIdentifierType>: UITableViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType> where SectionIdentifierType : Hashable, ItemIdentifierType : Hashable { class MainTimelineDataSource<SectionIdentifierType, ItemIdentifierType>: UITableViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType> where SectionIdentifierType: Hashable, ItemIdentifierType: Hashable {
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true return true
} }
} }

View File

@ -24,8 +24,7 @@ class MainTimelineTitleView: UIView {
if let name = label.text { if let name = label.text {
let unreadLabel = NSLocalizedString("unread", comment: "Unread label for accessibility") let unreadLabel = NSLocalizedString("unread", comment: "Unread label for accessibility")
return "\(name) \(unreadCountView.unreadCount) \(unreadLabel)" return "\(name) \(unreadCountView.unreadCount) \(unreadLabel)"
} } else {
else {
return nil return nil
} }
} }

View File

@ -14,7 +14,6 @@ extension CGRect: MarkAsReadAlertControllerSourceType {}
extension UIView: MarkAsReadAlertControllerSourceType {} extension UIView: MarkAsReadAlertControllerSourceType {}
extension UIBarButtonItem: MarkAsReadAlertControllerSourceType {} extension UIBarButtonItem: MarkAsReadAlertControllerSourceType {}
struct MarkAsReadAlertController { struct MarkAsReadAlertController {
static func confirm<T>(_ controller: UIViewController?, static func confirm<T>(_ controller: UIViewController?,
@ -45,7 +44,6 @@ struct MarkAsReadAlertController {
sourceType: T, sourceType: T,
completion: @escaping (UIAlertAction) -> Void) -> UIAlertController where T: MarkAsReadAlertControllerSourceType { completion: @escaping (UIAlertAction) -> Void) -> UIAlertController where T: MarkAsReadAlertControllerSourceType {
let title = NSLocalizedString("Mark As Read", comment: "Mark As Read") let title = NSLocalizedString("Mark As Read", comment: "Mark As Read")
let message = NSLocalizedString("You can turn this confirmation off in Settings.", let message = NSLocalizedString("You can turn this confirmation off in Settings.",
comment: "You can turn this confirmation off in Settings.") comment: "You can turn this confirmation off in Settings.")

View File

@ -17,7 +17,7 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner {
private var numberOfTextLines = 0 private var numberOfTextLines = 0
private var iconSize = IconSize.medium private var iconSize = IconSize.medium
private lazy var feedTapGestureRecognizer = UITapGestureRecognizer(target: self, action:#selector(showFeedInspector(_:))) private lazy var feedTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showFeedInspector(_:)))
private var refreshProgressView: RefreshProgressView? private var refreshProgressView: RefreshProgressView?
@ -277,7 +277,7 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner {
NSLocalizedString("Mark as Unread", comment: "Mark as Unread") : NSLocalizedString("Mark as Unread", comment: "Mark as Unread") :
NSLocalizedString("Mark as Read", comment: "Mark as Read") NSLocalizedString("Mark as Read", comment: "Mark as Read")
let readAction = UIContextualAction(style: .normal, title: readTitle) { [weak self] (action, view, completion) in let readAction = UIContextualAction(style: .normal, title: readTitle) { [weak self] (_, _, completion) in
self?.coordinator.toggleRead(article) self?.coordinator.toggleRead(article)
completion(true) completion(true)
} }
@ -297,7 +297,7 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner {
NSLocalizedString("Unstar", comment: "Unstar") : NSLocalizedString("Unstar", comment: "Unstar") :
NSLocalizedString("Star", comment: "Star") NSLocalizedString("Star", comment: "Star")
let starAction = UIContextualAction(style: .normal, title: starTitle) { [weak self] (action, view, completion) in let starAction = UIContextualAction(style: .normal, title: starTitle) { [weak self] (_, _, completion) in
self?.coordinator.toggleStar(article) self?.coordinator.toggleStar(article)
completion(true) completion(true)
} }
@ -363,7 +363,7 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner {
guard let article = dataSource.itemIdentifier(for: indexPath) else { return nil } guard let article = dataSource.itemIdentifier(for: indexPath) else { return nil }
return UIContextMenuConfiguration(identifier: indexPath.row as NSCopying, previewProvider: nil, actionProvider: { [weak self] suggestedActions in return UIContextMenuConfiguration(identifier: indexPath.row as NSCopying, previewProvider: nil, actionProvider: { [weak self] _ in
guard let self = self else { return nil } guard let self = self else { return nil }
@ -762,7 +762,7 @@ private extension TimelineViewController {
NSLocalizedString("Mark as Read", comment: "Mark as Read") NSLocalizedString("Mark as Read", comment: "Mark as Read")
let image = article.status.read ? AppAssets.circleClosedImage : AppAssets.circleOpenImage let image = article.status.read ? AppAssets.circleClosedImage : AppAssets.circleOpenImage
let action = UIAction(title: title, image: image) { [weak self] action in let action = UIAction(title: title, image: image) { [weak self] _ in
self?.coordinator.toggleRead(article) self?.coordinator.toggleRead(article)
} }
@ -776,7 +776,7 @@ private extension TimelineViewController {
NSLocalizedString("Mark as Starred", comment: "Mark as Starred") NSLocalizedString("Mark as Starred", comment: "Mark as Starred")
let image = article.status.starred ? AppAssets.starOpenImage : AppAssets.starClosedImage let image = article.status.starred ? AppAssets.starOpenImage : AppAssets.starClosedImage
let action = UIAction(title: title, image: image) { [weak self] action in let action = UIAction(title: title, image: image) { [weak self] _ in
self?.coordinator.toggleStar(article) self?.coordinator.toggleStar(article)
} }
@ -790,7 +790,7 @@ private extension TimelineViewController {
let title = NSLocalizedString("Mark Above as Read", comment: "Mark Above as Read") let title = NSLocalizedString("Mark Above as Read", comment: "Mark Above as Read")
let image = AppAssets.markAboveAsReadImage let image = AppAssets.markAboveAsReadImage
let action = UIAction(title: title, image: image) { [weak self] action in let action = UIAction(title: title, image: image) { [weak self] _ in
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in
self?.coordinator.markAboveAsRead(article) self?.coordinator.markAboveAsRead(article)
} }
@ -805,7 +805,7 @@ private extension TimelineViewController {
let title = NSLocalizedString("Mark Below as Read", comment: "Mark Below as Read") let title = NSLocalizedString("Mark Below as Read", comment: "Mark Below as Read")
let image = AppAssets.markBelowAsReadImage let image = AppAssets.markBelowAsReadImage
let action = UIAction(title: title, image: image) { [weak self] action in let action = UIAction(title: title, image: image) { [weak self] _ in
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in
self?.coordinator.markBelowAsRead(article) self?.coordinator.markBelowAsRead(article)
} }
@ -823,7 +823,7 @@ private extension TimelineViewController {
completion(true) completion(true)
} }
let action = UIAlertAction(title: title, style: .default) { [weak self] action in let action = UIAlertAction(title: title, style: .default) { [weak self] _ in
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView, cancelCompletion: cancel) { [weak self] in MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView, cancelCompletion: cancel) { [weak self] in
self?.coordinator.markAboveAsRead(article) self?.coordinator.markAboveAsRead(article)
completion(true) completion(true)
@ -842,7 +842,7 @@ private extension TimelineViewController {
completion(true) completion(true)
} }
let action = UIAlertAction(title: title, style: .default) { [weak self] action in let action = UIAlertAction(title: title, style: .default) { [weak self] _ in
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView, cancelCompletion: cancel) { [weak self] in MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView, cancelCompletion: cancel) { [weak self] in
self?.coordinator.markBelowAsRead(article) self?.coordinator.markBelowAsRead(article)
completion(true) completion(true)
@ -856,7 +856,7 @@ private extension TimelineViewController {
!coordinator.timelineFeedIsEqualTo(feed) else { return nil } !coordinator.timelineFeedIsEqualTo(feed) else { return nil }
let title = NSLocalizedString("Go to Feed", comment: "Go to Feed") let title = NSLocalizedString("Go to Feed", comment: "Go to Feed")
let action = UIAction(title: title, image: AppAssets.openInSidebarImage) { [weak self] action in let action = UIAction(title: title, image: AppAssets.openInSidebarImage) { [weak self] _ in
self?.coordinator.discloseFeed(feed, animations: [.scroll, .navigation]) self?.coordinator.discloseFeed(feed, animations: [.scroll, .navigation])
} }
return action return action
@ -867,7 +867,7 @@ private extension TimelineViewController {
!coordinator.timelineFeedIsEqualTo(feed) else { return nil } !coordinator.timelineFeedIsEqualTo(feed) else { return nil }
let title = NSLocalizedString("Go to Feed", comment: "Go to Feed") let title = NSLocalizedString("Go to Feed", comment: "Go to Feed")
let action = UIAlertAction(title: title, style: .default) { [weak self] action in let action = UIAlertAction(title: title, style: .default) { [weak self] _ in
self?.coordinator.discloseFeed(feed, animations: [.scroll, .navigation]) self?.coordinator.discloseFeed(feed, animations: [.scroll, .navigation])
completion(true) completion(true)
} }
@ -885,11 +885,10 @@ private extension TimelineViewController {
return nil return nil
} }
let localizedMenuText = NSLocalizedString("Mark All as Read in “%@”", comment: "Command") let localizedMenuText = NSLocalizedString("Mark All as Read in “%@”", comment: "Command")
let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, feed.nameForDisplay) as String let title = NSString.localizedStringWithFormat(localizedMenuText as NSString, feed.nameForDisplay) as String
let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] action in let action = UIAction(title: title, image: AppAssets.markAllAsReadImage) { [weak self] _ in
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView) { [weak self] in
self?.coordinator.markAllAsRead(articles) self?.coordinator.markAllAsRead(articles)
} }
@ -914,7 +913,7 @@ private extension TimelineViewController {
completion(true) completion(true)
} }
let action = UIAlertAction(title: title, style: .default) { [weak self] action in let action = UIAlertAction(title: title, style: .default) { [weak self] _ in
MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView, cancelCompletion: cancel) { [weak self] in MarkAsReadAlertController.confirm(self, coordinator: self?.coordinator, confirmTitle: title, sourceType: contentView, cancelCompletion: cancel) { [weak self] in
self?.coordinator.markAllAsRead(articles) self?.coordinator.markAllAsRead(articles)
completion(true) completion(true)
@ -926,7 +925,7 @@ private extension TimelineViewController {
func copyArticleURLAction(_ article: Article) -> UIAction? { func copyArticleURLAction(_ article: Article) -> UIAction? {
guard let url = article.preferredURL else { return nil } guard let url = article.preferredURL else { return nil }
let title = NSLocalizedString("Copy Article URL", comment: "Copy Article URL") let title = NSLocalizedString("Copy Article URL", comment: "Copy Article URL")
let action = UIAction(title: title, image: AppAssets.copyImage) { action in let action = UIAction(title: title, image: AppAssets.copyImage) { _ in
UIPasteboard.general.url = url UIPasteboard.general.url = url
} }
return action return action
@ -935,17 +934,16 @@ private extension TimelineViewController {
func copyExternalURLAction(_ article: Article) -> UIAction? { func copyExternalURLAction(_ article: Article) -> UIAction? {
guard let externalLink = article.externalLink, externalLink != article.preferredLink, let url = URL(string: externalLink) else { return nil } guard let externalLink = article.externalLink, externalLink != article.preferredLink, let url = URL(string: externalLink) else { return nil }
let title = NSLocalizedString("Copy External URL", comment: "Copy External URL") let title = NSLocalizedString("Copy External URL", comment: "Copy External URL")
let action = UIAction(title: title, image: AppAssets.copyImage) { action in let action = UIAction(title: title, image: AppAssets.copyImage) { _ in
UIPasteboard.general.url = url UIPasteboard.general.url = url
} }
return action return action
} }
func openInBrowserAction(_ article: Article) -> UIAction? { func openInBrowserAction(_ article: Article) -> UIAction? {
guard let _ = article.preferredURL else { return nil } guard let _ = article.preferredURL else { return nil }
let title = NSLocalizedString("Open in Browser", comment: "Open in Browser") let title = NSLocalizedString("Open in Browser", comment: "Open in Browser")
let action = UIAction(title: title, image: AppAssets.safariImage) { [weak self] action in let action = UIAction(title: title, image: AppAssets.safariImage) { [weak self] _ in
self?.coordinator.showBrowserForArticle(article) self?.coordinator.showBrowserForArticle(article)
} }
return action return action
@ -955,7 +953,7 @@ private extension TimelineViewController {
guard let _ = article.preferredURL else { return nil } guard let _ = article.preferredURL else { return nil }
let title = NSLocalizedString("Open in Browser", comment: "Open in Browser") let title = NSLocalizedString("Open in Browser", comment: "Open in Browser")
let action = UIAlertAction(title: title, style: .default) { [weak self] action in let action = UIAlertAction(title: title, style: .default) { [weak self] _ in
self?.coordinator.showBrowserForArticle(article) self?.coordinator.showBrowserForArticle(article)
completion(true) completion(true)
} }
@ -976,7 +974,7 @@ private extension TimelineViewController {
func shareAction(_ article: Article, indexPath: IndexPath) -> UIAction? { func shareAction(_ article: Article, indexPath: IndexPath) -> UIAction? {
guard let url = article.preferredURL else { return nil } guard let url = article.preferredURL else { return nil }
let title = NSLocalizedString("Share", comment: "Share") let title = NSLocalizedString("Share", comment: "Share")
let action = UIAction(title: title, image: AppAssets.shareImage) { [weak self] action in let action = UIAction(title: title, image: AppAssets.shareImage) { [weak self] _ in
self?.shareDialogForTableCell(indexPath: indexPath, url: url, title: article.title) self?.shareDialogForTableCell(indexPath: indexPath, url: url, title: article.title)
} }
return action return action
@ -985,7 +983,7 @@ private extension TimelineViewController {
func shareAlertAction(_ article: Article, indexPath: IndexPath, completion: @escaping (Bool) -> Void) -> UIAlertAction? { func shareAlertAction(_ article: Article, indexPath: IndexPath, completion: @escaping (Bool) -> Void) -> UIAlertAction? {
guard let url = article.preferredURL else { return nil } guard let url = article.preferredURL else { return nil }
let title = NSLocalizedString("Share", comment: "Share") let title = NSLocalizedString("Share", comment: "Share")
let action = UIAlertAction(title: title, style: .default) { [weak self] action in let action = UIAlertAction(title: title, style: .default) { [weak self] _ in
completion(true) completion(true)
self?.shareDialogForTableCell(indexPath: indexPath, url: url, title: article.title) self?.shareDialogForTableCell(indexPath: indexPath, url: url, title: article.title)
} }

View File

@ -58,7 +58,7 @@ class RootSplitViewController: UISplitViewController {
} }
@objc func markAllAsReadAndGoToNextUnread(_ sender: Any?) { @objc func markAllAsReadAndGoToNextUnread(_ sender: Any?) {
coordinator.markAllAsReadInTimeline() { coordinator.markAllAsReadInTimeline {
self.coordinator.selectNextUnread() self.coordinator.selectNextUnread()
} }
} }

View File

@ -73,10 +73,10 @@ class SceneCoordinator: NSObject, UndoableCommandRunner {
private(set) var preSearchTimelineFeed: SidebarItem? private(set) var preSearchTimelineFeed: SidebarItem?
private var lastSearchString = "" private var lastSearchString = ""
private var lastSearchScope: SearchScope? = nil private var lastSearchScope: SearchScope?
private var isSearching: Bool = false private var isSearching: Bool = false
private var savedSearchArticles: ArticleArray? = nil private var savedSearchArticles: ArticleArray?
private var savedSearchArticleIds: Set<String>? = nil private var savedSearchArticleIds: Set<String>?
var isTimelineViewControllerPending = false var isTimelineViewControllerPending = false
var isArticleViewControllerPending = false var isArticleViewControllerPending = false
@ -956,7 +956,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner {
self.mainTimelineViewController?.hideSearch() self.mainTimelineViewController?.hideSearch()
} }
selectNextUnreadFeed() { selectNextUnreadFeed {
self.selectNextUnreadArticleInTimeline() self.selectNextUnreadArticleInTimeline()
} }
} }
@ -1221,8 +1221,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner {
func showInAppBrowser() { func showInAppBrowser() {
if currentArticle != nil { if currentArticle != nil {
articleViewController?.openInAppBrowser() articleViewController?.openInAppBrowser()
} } else {
else {
mainFeedViewController.openInAppBrowser() mainFeedViewController.openInAppBrowser()
} }
} }
@ -1257,7 +1256,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner {
do { do {
try ArticleThemeImporter.importTheme(controller: rootSplitViewController, url: URL(fileURLWithPath: filename)) try ArticleThemeImporter.importTheme(controller: rootSplitViewController, url: URL(fileURLWithPath: filename))
} catch { } catch {
NotificationCenter.default.post(name: .didFailToImportThemeWithError, object: nil, userInfo: ["error" : error]) NotificationCenter.default.post(name: .didFailToImportThemeWithError, object: nil, userInfo: ["error": error])
} }
} }
@ -2053,9 +2052,9 @@ private extension SceneCoordinator {
] ]
} }
func handleSelectFeed(_ userInfo: [AnyHashable : Any]?) { func handleSelectFeed(_ userInfo: [AnyHashable: Any]?) {
guard let userInfo = userInfo, guard let userInfo = userInfo,
let feedIdentifierUserInfo = userInfo[UserInfoKey.feedIdentifier] as? [AnyHashable : AnyHashable], let feedIdentifierUserInfo = userInfo[UserInfoKey.feedIdentifier] as? [AnyHashable: AnyHashable],
let feedIdentifier = SidebarItemIdentifier(userInfo: feedIdentifierUserInfo) else { let feedIdentifier = SidebarItemIdentifier(userInfo: feedIdentifierUserInfo) else {
return return
} }
@ -2111,10 +2110,10 @@ private extension SceneCoordinator {
} }
} }
func handleReadArticle(_ userInfo: [AnyHashable : Any]?) { func handleReadArticle(_ userInfo: [AnyHashable: Any]?) {
guard let userInfo = userInfo else { return } guard let userInfo = userInfo else { return }
guard let articlePathUserInfo = userInfo[UserInfoKey.articlePath] as? [AnyHashable : Any], guard let articlePathUserInfo = userInfo[UserInfoKey.articlePath] as? [AnyHashable: Any],
let accountID = articlePathUserInfo[ArticlePathKey.accountID] as? String, let accountID = articlePathUserInfo[ArticlePathKey.accountID] as? String,
let accountName = articlePathUserInfo[ArticlePathKey.accountName] as? String, let accountName = articlePathUserInfo[ArticlePathKey.accountName] as? String,
let feedID = articlePathUserInfo[ArticlePathKey.feedID] as? String, let feedID = articlePathUserInfo[ArticlePathKey.feedID] as? String,
@ -2139,8 +2138,8 @@ private extension SceneCoordinator {
} }
} }
func restoreFeedSelection(_ userInfo: [AnyHashable : Any], accountID: String, feedID: String, articleID: String) -> Bool { func restoreFeedSelection(_ userInfo: [AnyHashable: Any], accountID: String, feedID: String, articleID: String) -> Bool {
guard let feedIdentifierUserInfo = userInfo[UserInfoKey.feedIdentifier] as? [AnyHashable : AnyHashable], guard let feedIdentifierUserInfo = userInfo[UserInfoKey.feedIdentifier] as? [AnyHashable: AnyHashable],
let feedIdentifier = SidebarItemIdentifier(userInfo: feedIdentifierUserInfo), let feedIdentifier = SidebarItemIdentifier(userInfo: feedIdentifierUserInfo),
let isShowingExtractedArticle = userInfo[UserInfoKey.isShowingExtractedArticle] as? Bool, let isShowingExtractedArticle = userInfo[UserInfoKey.isShowingExtractedArticle] as? Bool,
let articleWindowScrollY = userInfo[UserInfoKey.articleWindowScrollY] as? Int else { let articleWindowScrollY = userInfo[UserInfoKey.articleWindowScrollY] as? Int else {

View File

@ -134,7 +134,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
if AccountManager.shared.isSuspended { if AccountManager.shared.isSuspended {
AccountManager.shared.resumeAll() AccountManager.shared.resumeAll()
} }
self.coordinator.selectAllUnreadFeed() { self.coordinator.selectAllUnreadFeed {
self.coordinator.selectArticleInCurrentFeed(id!) self.coordinator.selectArticleInCurrentFeed(id!)
} }
} else { } else {
@ -150,7 +150,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
if AccountManager.shared.isSuspended { if AccountManager.shared.isSuspended {
AccountManager.shared.resumeAll() AccountManager.shared.resumeAll()
} }
self.coordinator.selectTodayFeed() { self.coordinator.selectTodayFeed {
self.coordinator.selectArticleInCurrentFeed(id!) self.coordinator.selectArticleInCurrentFeed(id!)
} }
} else { } else {
@ -166,7 +166,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
if AccountManager.shared.isSuspended { if AccountManager.shared.isSuspended {
AccountManager.shared.resumeAll() AccountManager.shared.resumeAll()
} }
self.coordinator.selectStarredFeed() { self.coordinator.selectStarredFeed {
self.coordinator.selectArticleInCurrentFeed(id!) self.coordinator.selectArticleInCurrentFeed(id!)
} }
} else { } else {
@ -194,7 +194,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
DispatchQueue.main.async { DispatchQueue.main.async {
NotificationCenter.default.post(name: .didBeginDownloadingTheme, object: nil) NotificationCenter.default.post(name: .didBeginDownloadingTheme, object: nil)
} }
let task = URLSession.shared.downloadTask(with: request) { location, response, error in let task = URLSession.shared.downloadTask(with: request) { location, _, error in
guard guard
let location = location else { return } let location = location else { return }
@ -213,7 +213,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
return return
} }
} }
} }
} }
@ -250,6 +249,4 @@ private extension SceneDelegate {
} }
} }
} }

View File

@ -66,10 +66,6 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
} }
} }
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in tableView: UITableView) -> Int { override func numberOfSections(in tableView: UITableView) -> Int {
return AddAccountSections.allCases.count return AddAccountSections.allCases.count
} }

View File

@ -26,7 +26,7 @@ struct ArticleThemeImporter {
if let websiteURL = URL(string: theme.creatorHomePage) { if let websiteURL = URL(string: theme.creatorHomePage) {
let visitSiteTitle = NSLocalizedString("Show Website", comment: "Show Website") let visitSiteTitle = NSLocalizedString("Show Website", comment: "Show Website")
let visitSiteAction = UIAlertAction(title: visitSiteTitle, style: .default) { action in let visitSiteAction = UIAlertAction(title: visitSiteTitle, style: .default) { _ in
UIApplication.shared.open(websiteURL) UIApplication.shared.open(websiteURL)
try? Self.importTheme(controller: controller, url: url) try? Self.importTheme(controller: controller, url: url)
} }
@ -49,7 +49,7 @@ struct ArticleThemeImporter {
} }
let installThemeTitle = NSLocalizedString("Install Theme", comment: "Install Theme") let installThemeTitle = NSLocalizedString("Install Theme", comment: "Install Theme")
let installThemeAction = UIAlertAction(title: installThemeTitle, style: .default) { action in let installThemeAction = UIAlertAction(title: installThemeTitle, style: .default) { _ in
if ArticleThemesManager.shared.themeExists(filename: url.path) { if ArticleThemesManager.shared.themeExists(filename: url.path) {
let title = NSLocalizedString("Duplicate Theme", comment: "Duplicate Theme") let title = NSLocalizedString("Duplicate Theme", comment: "Duplicate Theme")
@ -61,7 +61,7 @@ struct ArticleThemeImporter {
let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel") let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel)) alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel))
let overwriteAction = UIAlertAction(title: NSLocalizedString("Overwrite", comment: "Overwrite"), style: .default) { action in let overwriteAction = UIAlertAction(title: NSLocalizedString("Overwrite", comment: "Overwrite"), style: .default) { _ in
importTheme() importTheme()
} }
alertController.addAction(overwriteAction) alertController.addAction(overwriteAction)

View File

@ -17,8 +17,8 @@ extension UTType {
class ArticleThemesTableViewController: UITableViewController { class ArticleThemesTableViewController: UITableViewController {
override func viewDidLoad() { override func viewDidLoad() {
let importBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(importTheme(_:))); let importBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(importTheme(_:)))
importBarButtonItem.title = NSLocalizedString("Import Theme", comment: "Import Theme"); importBarButtonItem.title = NSLocalizedString("Import Theme", comment: "Import Theme")
navigationItem.rightBarButtonItem = importBarButtonItem navigationItem.rightBarButtonItem = importBarButtonItem
NotificationCenter.default.addObserver(self, selector: #selector(articleThemeNamesDidChangeNotification(_:)), name: .ArticleThemeNamesDidChangeNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(articleThemeNamesDidChangeNotification(_:)), name: .ArticleThemeNamesDidChangeNotification, object: nil)
@ -80,7 +80,7 @@ class ArticleThemesTableViewController: UITableViewController {
!theme.isAppTheme else { return nil } !theme.isAppTheme else { return nil }
let deleteTitle = NSLocalizedString("Delete", comment: "Delete") let deleteTitle = NSLocalizedString("Delete", comment: "Delete")
let deleteAction = UIContextualAction(style: .normal, title: deleteTitle) { [weak self] (action, view, completion) in let deleteAction = UIContextualAction(style: .normal, title: deleteTitle) { [weak self] (_, _, completion) in
let title = NSLocalizedString("Delete Theme?", comment: "Delete Theme") let title = NSLocalizedString("Delete Theme?", comment: "Delete Theme")
let localizedMessageText = NSLocalizedString("Are you sure you want to delete the theme “%@”?.", comment: "Delete Theme Message") let localizedMessageText = NSLocalizedString("Are you sure you want to delete the theme “%@”?.", comment: "Delete Theme Message")
@ -89,13 +89,13 @@ class ArticleThemesTableViewController: UITableViewController {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel") let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
let cancelAction = UIAlertAction(title: cancelTitle, style: .cancel) { action in let cancelAction = UIAlertAction(title: cancelTitle, style: .cancel) { _ in
completion(true) completion(true)
} }
alertController.addAction(cancelAction) alertController.addAction(cancelAction)
let deleteTitle = NSLocalizedString("Delete", comment: "Delete") let deleteTitle = NSLocalizedString("Delete", comment: "Delete")
let deleteAction = UIAlertAction(title: deleteTitle, style: .destructive) { action in let deleteAction = UIAlertAction(title: deleteTitle, style: .destructive) { _ in
ArticleThemesManager.shared.deleteTheme(themeName: themeName) ArticleThemesManager.shared.deleteTheme(themeName: themeName)
completion(true) completion(true)
} }

View File

@ -66,7 +66,6 @@ class SettingsViewController: UITableViewController {
refreshClearsReadArticlesSwitch.isOn = false refreshClearsReadArticlesSwitch.isOn = false
} }
articleThemeDetailLabel.text = ArticleThemesManager.shared.currentTheme.name articleThemeDetailLabel.text = ArticleThemesManager.shared.currentTheme.name
if AppDefaults.shared.confirmMarkAllAsRead { if AppDefaults.shared.confirmMarkAllAsRead {
@ -85,7 +84,6 @@ class SettingsViewController: UITableViewController {
openLinksInNetNewsWire.isOn = !AppDefaults.shared.useSystemBrowser openLinksInNetNewsWire.isOn = !AppDefaults.shared.useSystemBrowser
let buildLabel = NonIntrinsicLabel(frame: CGRect(x: 32.0, y: 0.0, width: 0.0, height: 0.0)) let buildLabel = NonIntrinsicLabel(frame: CGRect(x: 32.0, y: 0.0, width: 0.0, height: 0.0))
buildLabel.font = UIFont.systemFont(ofSize: 11.0) buildLabel.font = UIFont.systemFont(ofSize: 11.0)
buildLabel.textColor = UIColor.gray buildLabel.textColor = UIColor.gray
@ -308,7 +306,6 @@ class SettingsViewController: UITableViewController {
} }
} }
// MARK: Notifications // MARK: Notifications
@objc func contentSizeCategoryDidChange() { @objc func contentSizeCategoryDidChange() {
@ -389,7 +386,7 @@ private extension SettingsViewController {
} }
for account in AccountManager.shared.sortedActiveAccounts { for account in AccountManager.shared.sortedActiveAccounts {
let action = UIAlertAction(title: account.nameForDisplay, style: .default) { [weak self] action in let action = UIAlertAction(title: account.nameForDisplay, style: .default) { [weak self] _ in
self?.opmlAccount = account self?.opmlAccount = account
self?.importOPMLDocumentPicker() self?.importOPMLDocumentPicker()
} }
@ -429,7 +426,7 @@ private extension SettingsViewController {
} }
for account in AccountManager.shared.sortedAccounts { for account in AccountManager.shared.sortedAccounts {
let action = UIAlertAction(title: account.nameForDisplay, style: .default) { [weak self] action in let action = UIAlertAction(title: account.nameForDisplay, style: .default) { [weak self] _ in
self?.opmlAccount = account self?.opmlAccount = account
self?.exportOPMLDocumentPicker() self?.exportOPMLDocumentPicker()
} }

View File

@ -42,7 +42,7 @@ class ShareViewController: SLComposeServiceViewController, ShareFolderPickerCont
tableView.rowHeight = 38 tableView.rowHeight = 38
} }
var provider: NSItemProvider? = nil var provider: NSItemProvider?
// Try to get any HTML that is maybe passed in // Try to get any HTML that is maybe passed in
for item in self.extensionContext!.inputItems as! [NSExtensionItem] { for item in self.extensionContext!.inputItems as! [NSExtensionItem] {
@ -107,7 +107,7 @@ class ShareViewController: SLComposeServiceViewController, ShareFolderPickerCont
return return
} }
var name: String? = nil var name: String?
if !contentText.mayBeURL { if !contentText.mayBeURL {
name = contentText.isEmpty ? nil : contentText name = contentText.isEmpty ? nil : contentText
} }

View File

@ -59,10 +59,9 @@ class InteractiveLabel: UILabel, UIEditMenuInteractionDelegate {
func editMenuInteraction(_ interaction: UIEditMenuInteraction, menuFor configuration: UIEditMenuConfiguration, suggestedActions: [UIMenuElement]) -> UIMenu? { func editMenuInteraction(_ interaction: UIEditMenuInteraction, menuFor configuration: UIEditMenuConfiguration, suggestedActions: [UIMenuElement]) -> UIMenu? {
let copyAction = UIAction(title: "Copy", image: nil) { [weak self] action in let copyAction = UIAction(title: "Copy", image: nil) { [weak self] _ in
self?.copy(nil) self?.copy(nil)
} }
return UIMenu(title: "", children: [copyAction]) return UIMenu(title: "", children: [copyAction])
} }
} }

View File

@ -10,9 +10,9 @@ import UIKit
extension UIFont { extension UIFont {
func withTraits(traits:UIFontDescriptor.SymbolicTraits) -> UIFont { func withTraits(traits: UIFontDescriptor.SymbolicTraits) -> UIFont {
if let descriptor = fontDescriptor.withSymbolicTraits(traits) { if let descriptor = fontDescriptor.withSymbolicTraits(traits) {
return UIFont(descriptor: descriptor, size: 0) //size 0 means keep the size as it is return UIFont(descriptor: descriptor, size: 0) // size 0 means keep the size as it is
} else { } else {
return self return self
} }