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

@@ -15,11 +15,11 @@ class AboutViewController: UITableViewController {
@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: "Thanks", textView: thanksTextView)
@@ -32,7 +32,7 @@ class AboutViewController: UITableViewController {
buildLabel.numberOfLines = 0
buildLabel.sizeToFit()
buildLabel.translatesAutoresizingMaskIntoConstraints = false
let wrapperView = UIView(frame: CGRect(x: 0, y: 0, width: buildLabel.frame.width, height: buildLabel.frame.height + 10.0))
wrapperView.translatesAutoresizingMaskIntoConstraints = false
wrapperView.addSubview(buildLabel)
@@ -42,11 +42,11 @@ class AboutViewController: UITableViewController {
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)
@@ -55,5 +55,5 @@ private extension AboutViewController {
textView.adjustsFontForContentSizeCategory = true
textView.font = .preferredFont(forTextStyle: .body)
}
}

View File

@@ -21,7 +21,7 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
case icloud
case web
case selfhosted
var sectionHeader: String {
switch self {
case .local:
@@ -34,7 +34,7 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
return NSLocalizedString("Self-hosted", comment: "Self hosted Account")
}
}
var sectionFooter: String {
switch self {
case .local:
@@ -47,7 +47,7 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
return NSLocalizedString("Self-hosted accounts sync your feeds across all your devices", comment: "Self hosted Account")
}
}
var sectionContent: [AccountType] {
switch self {
case .local:
@@ -65,35 +65,31 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return AddAccountSections.allCases.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == AddAccountSections.local.rawValue {
return AddAccountSections.local.sectionContent.count
}
if section == AddAccountSections.icloud.rawValue {
return AddAccountSections.icloud.sectionContent.count
}
if section == AddAccountSections.web.rawValue {
return AddAccountSections.web.sectionContent.count
}
if section == AddAccountSections.selfhosted.rawValue {
return AddAccountSections.selfhosted.sectionContent.count
}
return 0
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case AddAccountSections.local.rawValue:
@@ -108,7 +104,7 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
return nil
}
}
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
switch section {
case AddAccountSections.local.rawValue:
@@ -123,10 +119,10 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
return nil
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsAccountTableViewCell", for: indexPath) as! SettingsComboTableViewCell
switch indexPath.section {
case AddAccountSections.local.rawValue:
cell.comboNameLabel?.text = AddAccountSections.local.sectionContent[indexPath.row].localizedAccountName()
@@ -149,15 +145,15 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
case AddAccountSections.selfhosted.rawValue:
cell.comboNameLabel?.text = AddAccountSections.selfhosted.sectionContent[indexPath.row].localizedAccountName()
cell.comboImage?.image = AppAssets.image(for: AddAccountSections.selfhosted.sectionContent[indexPath.row])
default:
return cell
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.section {
case AddAccountSections.local.rawValue:
let type = AddAccountSections.local.sectionContent[indexPath.row]
@@ -175,7 +171,7 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
return
}
}
private func presentController(for accountType: AccountType) {
switch accountType {
case .onMyMac:
@@ -216,18 +212,18 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
present(navController, animated: true)
}
}
func dismiss() {
navigationController?.popViewController(animated: false)
}
}
extension AddAccountViewController: OAuthAccountAuthorizationOperationDelegate {
func oauthAccountAuthorizationOperation(_ operation: OAuthAccountAuthorizationOperation, didCreate account: Account) {
let rootViewController = view.window?.rootViewController
account.refreshAll { result in
switch result {
case .success:
@@ -239,10 +235,10 @@ extension AddAccountViewController: OAuthAccountAuthorizationOperationDelegate {
viewController.presentError(error)
}
}
dismiss()
}
func oauthAccountAuthorizationOperation(_ operation: OAuthAccountAuthorizationOperation, didFailWith error: Error) {
presentError(error)
}

View File

@@ -9,7 +9,7 @@
import UIKit
struct ArticleThemeImporter {
static func importTheme(controller: UIViewController, url: URL) throws {
let theme = try ArticleTheme(url: url, isAppTheme: false)
@@ -20,13 +20,13 @@ struct ArticleThemeImporter {
let message = NSString.localizedStringWithFormat(localizedMessageText as NSString, theme.creatorHomePage) as String
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
alertController.addAction(UIAlertAction(title: cancelTitle, style: .cancel))
if let websiteURL = URL(string: theme.creatorHomePage) {
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)
try? Self.importTheme(controller: controller, url: url)
}
@@ -49,7 +49,7 @@ struct ArticleThemeImporter {
}
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) {
let title = NSLocalizedString("Duplicate Theme", comment: "Duplicate Theme")
@@ -61,7 +61,7 @@ struct ArticleThemeImporter {
let cancelTitle = NSLocalizedString("Cancel", comment: "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()
}
alertController.addAction(overwriteAction)
@@ -71,32 +71,32 @@ struct ArticleThemeImporter {
} else {
importTheme()
}
}
alertController.addAction(installThemeAction)
alertController.preferredAction = installThemeAction
controller.present(alertController, animated: true)
}
}
private extension ArticleThemeImporter {
static func confirmImportSuccess(controller: UIViewController, themeName: String) {
let title = NSLocalizedString("Theme installed", comment: "Theme installed")
let localizedMessageText = NSLocalizedString("The theme “%@” has been installed.", comment: "Theme installed")
let message = NSString.localizedStringWithFormat(localizedMessageText as NSString, themeName) as String
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let doneTitle = NSLocalizedString("Done", comment: "Done")
alertController.addAction(UIAlertAction(title: doneTitle, style: .default))
controller.present(alertController, animated: true)
}
}

View File

@@ -17,15 +17,15 @@ extension UTType {
class ArticleThemesTableViewController: UITableViewController {
override func viewDidLoad() {
let importBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(importTheme(_:)));
importBarButtonItem.title = NSLocalizedString("Import Theme", comment: "Import Theme");
let importBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(importTheme(_:)))
importBarButtonItem.title = NSLocalizedString("Import Theme", comment: "Import Theme")
navigationItem.rightBarButtonItem = importBarButtonItem
NotificationCenter.default.addObserver(self, selector: #selector(articleThemeNamesDidChangeNotification(_:)), name: .ArticleThemeNamesDidChangeNotification, object: nil)
}
// MARK: Notifications
@objc func articleThemeNamesDidChangeNotification(_ note: Notification) {
tableView.reloadData()
}
@@ -49,21 +49,21 @@ class ArticleThemesTableViewController: UITableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let themeName: String
if indexPath.row == 0 {
themeName = ArticleTheme.defaultTheme.name
} else {
themeName = ArticleThemesManager.shared.themeNames[indexPath.row - 1]
}
cell.textLabel?.text = themeName
if themeName == ArticleThemesManager.shared.currentTheme.name {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
return cell
}
@@ -80,33 +80,33 @@ class ArticleThemesTableViewController: UITableViewController {
!theme.isAppTheme else { return nil }
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 localizedMessageText = NSLocalizedString("Are you sure you want to delete the theme “%@”?.", comment: "Delete Theme Message")
let message = NSString.localizedStringWithFormat(localizedMessageText as NSString, themeName) as String
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
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)
}
alertController.addAction(cancelAction)
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)
completion(true)
}
alertController.addAction(deleteAction)
self?.present(alertController, animated: true)
}
deleteAction.image = AppAssets.trashImage
deleteAction.backgroundColor = UIColor.systemRed
return UISwipeActionsConfiguration(actions: [deleteAction])
}
}
@@ -114,12 +114,12 @@ class ArticleThemesTableViewController: UITableViewController {
// MARK: UIDocumentPickerDelegate
extension ArticleThemesTableViewController: UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let url = urls.first else { return }
if url.startAccessingSecurityScopedResource() {
defer {
url.stopAccessingSecurityScopedResource()
}

View File

@@ -16,7 +16,7 @@ class SettingsComboTableViewCell: VibrantTableViewCell {
override func updateVibrancy(animated: Bool) {
super.updateVibrancy(animated: animated)
updateLabelVibrancy(comboNameLabel, color: labelColor, animated: animated)
let tintColor = isHighlighted || isSelected ? AppAssets.vibrantTextColor : UIColor.label
if animated {
UIView.animate(withDuration: Self.duration) {
@@ -26,5 +26,5 @@ class SettingsComboTableViewCell: VibrantTableViewCell {
self.comboImage?.tintColor = tintColor
}
}
}

View File

@@ -16,7 +16,7 @@ import UniformTypeIdentifiers
class SettingsViewController: UITableViewController {
private weak var opmlAccount: Account?
@IBOutlet weak var timelineSortOrderSwitch: UISwitch!
@IBOutlet weak var groupByFeedSwitch: UISwitch!
@IBOutlet weak var refreshClearsReadArticlesSwitch: UISwitch!
@@ -25,10 +25,10 @@ class SettingsViewController: UITableViewController {
@IBOutlet weak var showFullscreenArticlesSwitch: UISwitch!
@IBOutlet weak var colorPaletteDetailLabel: UILabel!
@IBOutlet weak var openLinksInNetNewsWire: UISwitch!
var scrollToArticlesSection = false
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)
@@ -40,14 +40,14 @@ class SettingsViewController: UITableViewController {
tableView.register(UINib(nibName: "SettingsComboTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsComboTableViewCell")
tableView.register(UINib(nibName: "SettingsTableViewCell", bundle: nil), forCellReuseIdentifier: "SettingsTableViewCell")
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 44
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if AppDefaults.shared.timelineSortDirection == .orderedAscending {
timelineSortOrderSwitch.isOn = true
} else {
@@ -66,7 +66,6 @@ class SettingsViewController: UITableViewController {
refreshClearsReadArticlesSwitch.isOn = false
}
articleThemeDetailLabel.text = ArticleThemesManager.shared.currentTheme.name
if AppDefaults.shared.confirmMarkAllAsRead {
@@ -80,11 +79,10 @@ class SettingsViewController: UITableViewController {
} else {
showFullscreenArticlesSwitch.isOn = false
}
colorPaletteDetailLabel.text = String(describing: AppDefaults.userInterfaceColorPalette)
openLinksInNetNewsWire.isOn = !AppDefaults.shared.useSystemBrowser
let buildLabel = NonIntrinsicLabel(frame: CGRect(x: 32.0, y: 0.0, width: 0.0, height: 0.0))
buildLabel.font = UIFont.systemFont(ofSize: 11.0)
@@ -92,27 +90,27 @@ class SettingsViewController: UITableViewController {
buildLabel.text = "\(Bundle.main.appName) \(Bundle.main.versionNumber) (Build \(Bundle.main.buildNumber))"
buildLabel.sizeToFit()
buildLabel.translatesAutoresizingMaskIntoConstraints = false
let wrapperView = UIView(frame: CGRect(x: 0, y: 0, width: buildLabel.frame.width, height: buildLabel.frame.height + 10.0))
wrapperView.translatesAutoresizingMaskIntoConstraints = false
wrapperView.addSubview(buildLabel)
tableView.tableFooterView = wrapperView
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
if scrollToArticlesSection {
tableView.scrollToRow(at: IndexPath(row: 0, section: 4), at: .top, animated: true)
scrollToArticlesSection = false
}
}
// MARK: UITableView
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
@@ -237,7 +235,7 @@ class SettingsViewController: UITableViewController {
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return false
}
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return false
}
@@ -245,21 +243,21 @@ class SettingsViewController: UITableViewController {
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .none
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
override func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int {
return super.tableView(tableView, indentationLevelForRowAt: IndexPath(row: 0, section: 1))
}
// MARK: Actions
@IBAction func done(_ sender: Any) {
dismiss(animated: true)
}
@IBAction func switchTimelineOrder(_ sender: Any) {
if timelineSortOrderSwitch.isOn {
AppDefaults.shared.timelineSortDirection = .orderedAscending
@@ -267,7 +265,7 @@ class SettingsViewController: UITableViewController {
AppDefaults.shared.timelineSortDirection = .orderedDescending
}
}
@IBAction func switchGroupByFeed(_ sender: Any) {
if groupByFeedSwitch.isOn {
AppDefaults.shared.timelineGroupByFeed = true
@@ -275,7 +273,7 @@ class SettingsViewController: UITableViewController {
AppDefaults.shared.timelineGroupByFeed = false
}
}
@IBAction func switchClearsReadArticles(_ sender: Any) {
if refreshClearsReadArticlesSwitch.isOn {
AppDefaults.shared.refreshClearsReadArticles = true
@@ -283,7 +281,7 @@ class SettingsViewController: UITableViewController {
AppDefaults.shared.refreshClearsReadArticles = false
}
}
@IBAction func switchConfirmMarkAllAsRead(_ sender: Any) {
if confirmMarkAllAsReadSwitch.isOn {
AppDefaults.shared.confirmMarkAllAsRead = true
@@ -291,7 +289,7 @@ class SettingsViewController: UITableViewController {
AppDefaults.shared.confirmMarkAllAsRead = false
}
}
@IBAction func switchFullscreenArticles(_ sender: Any) {
if showFullscreenArticlesSwitch.isOn {
AppDefaults.shared.articleFullscreenAvailable = true
@@ -299,7 +297,7 @@ class SettingsViewController: UITableViewController {
AppDefaults.shared.articleFullscreenAvailable = false
}
}
@IBAction func switchBrowserPreference(_ sender: Any) {
if openLinksInNetNewsWire.isOn {
AppDefaults.shared.useSystemBrowser = false
@@ -307,14 +305,13 @@ class SettingsViewController: UITableViewController {
AppDefaults.shared.useSystemBrowser = true
}
}
// MARK: Notifications
@objc func contentSizeCategoryDidChange() {
tableView.reloadData()
}
@objc func accountsDidChange() {
tableView.reloadData()
}
@@ -322,17 +319,17 @@ class SettingsViewController: UITableViewController {
@objc func displayNameDidChange() {
tableView.reloadData()
}
@objc func browserPreferenceDidChange() {
tableView.reloadData()
}
}
// MARK: OPML Document Picker
extension SettingsViewController: UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
for url in urls {
opmlAccount?.importOPML(url) { result in
@@ -347,13 +344,13 @@ extension SettingsViewController: UIDocumentPickerDelegate {
}
}
}
}
// MARK: Private
private extension SettingsViewController {
func addFeed() {
self.dismiss(animated: true)
@@ -363,10 +360,10 @@ private extension SettingsViewController {
addViewController.initialFeedName = NSLocalizedString("NetNewsWire News", comment: "NetNewsWire News")
addNavViewController.modalPresentationStyle = .formSheet
addNavViewController.preferredContentSize = AddFeedViewController.preferredContentSizeForFormSheetDisplay
presentingParentController?.present(addNavViewController, animated: true)
}
func importOPML(sourceView: UIView, sourceRect: CGRect) {
switch AccountManager.shared.activeAccounts.count {
case 0:
@@ -378,18 +375,18 @@ private extension SettingsViewController {
importOPMLAccountPicker(sourceView: sourceView, sourceRect: sourceRect)
}
}
func importOPMLAccountPicker(sourceView: UIView, sourceRect: CGRect) {
let title = NSLocalizedString("Choose an account to receive the imported feeds and folders", comment: "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.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?.importOPMLDocumentPicker()
}
@@ -401,15 +398,15 @@ private extension SettingsViewController {
self.present(alert, animated: true)
}
func importOPMLDocumentPicker() {
let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [UTType.opml, UTType.xml], asCopy: true)
documentPicker.delegate = self
documentPicker.modalPresentationStyle = .formSheet
self.present(documentPicker, animated: true)
}
func exportOPML(sourceView: UIView, sourceRect: CGRect) {
if AccountManager.shared.accounts.count == 1 {
opmlAccount = AccountManager.shared.accounts.first!
@@ -418,18 +415,18 @@ private extension SettingsViewController {
exportOPMLAccountPicker(sourceView: sourceView, sourceRect: sourceRect)
}
}
func exportOPMLAccountPicker(sourceView: UIView, sourceRect: CGRect) {
let title = NSLocalizedString("Choose an account with the subscriptions to export", comment: "Export 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.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?.exportOPMLDocumentPicker()
}
@@ -441,10 +438,10 @@ private extension SettingsViewController {
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)
@@ -454,16 +451,16 @@ private extension SettingsViewController {
} catch {
self.presentError(title: "OPML Export Error", message: error.localizedDescription)
}
let documentPicker = UIDocumentPickerViewController(forExporting: [tempFile])
documentPicker.modalPresentationStyle = .formSheet
self.present(documentPicker, animated: true)
}
func openURL(_ urlString: String) {
let vc = SFSafariViewController(url: URL(string: urlString)!)
vc.modalPresentationStyle = .pageSheet
present(vc, animated: true)
}
}

View File

@@ -14,15 +14,15 @@ class TimelineCustomizerViewController: UIViewController {
@IBOutlet weak var iconSizeSlider: TickMarkSlider!
@IBOutlet weak var numberOfLinesSliderContainerView: UIView!
@IBOutlet weak var numberOfLinesSlider: TickMarkSlider!
@IBOutlet weak var previewWidthConstraint: NSLayoutConstraint!
@IBOutlet weak var previewHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var previewContainerView: UIView!
var previewController: TimelinePreviewTableViewController {
return children.first as! TimelinePreviewTableViewController
}
override func viewDidLoad() {
super.viewDidLoad()
@@ -34,13 +34,13 @@ class TimelineCustomizerViewController: UIViewController {
numberOfLinesSlider.value = Float(AppDefaults.shared.timelineNumberOfLines)
numberOfLinesSlider.addTickMarks()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
updatePreviewBorder()
updatePreview()
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
updatePreviewBorder()
updatePreview()
@@ -51,18 +51,18 @@ class TimelineCustomizerViewController: UIViewController {
AppDefaults.shared.timelineIconSize = iconSize
updatePreview()
}
@IBAction func numberOfLinesChanged(_ sender: Any) {
AppDefaults.shared.timelineNumberOfLines = Int(numberOfLinesSlider.value.rounded())
updatePreview()
}
}
// MARK: Private
private extension TimelineCustomizerViewController {
func updatePreview() {
let previewWidth: CGFloat = {
if traitCollection.userInterfaceIdiom == .phone {
@@ -71,13 +71,13 @@ private extension TimelineCustomizerViewController {
return view.bounds.width / 1.5
}
}()
previewWidthConstraint.constant = previewWidth
previewHeightConstraint.constant = previewController.heightFor(width: previewWidth)
previewController.reload()
}
func updatePreviewBorder() {
if traitCollection.userInterfaceStyle == .dark {
previewContainerView.layer.borderColor = UIColor.black.cgColor
@@ -86,5 +86,5 @@ private extension TimelineCustomizerViewController {
previewContainerView.layer.borderWidth = 0
}
}
}

View File

@@ -12,13 +12,13 @@ import Articles
class TimelinePreviewTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func heightFor(width: CGFloat) -> CGFloat {
@@ -46,7 +46,7 @@ class TimelinePreviewTableViewController: UIViewController, UITableViewDelegate,
cell.cellData = prototypeCellData
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
}
@@ -64,14 +64,14 @@ private extension TimelinePreviewTableViewController {
var prototypeCellData: MainTimelineCellData {
let longTitle = "Enim ut tellus elementum sagittis vitae et. Nibh praesent tristique magna sit amet purus gravida quis blandit. Neque volutpat ac tincidunt vitae semper quis lectus nulla. Massa id neque aliquam vestibulum morbi blandit. Ultrices vitae auctor eu augue. Enim eu turpis egestas pretium aenean pharetra magna. Eget gravida cum sociis natoque. Sit amet consectetur adipiscing elit. Auctor eu augue ut lectus arcu bibendum. Maecenas volutpat blandit aliquam etiam erat velit. Ut pharetra sit amet aliquam id diam maecenas ultricies. In hac habitasse platea dictumst quisque sagittis purus sit amet."
let prototypeID = "prototype"
let status = ArticleStatus(articleID: prototypeID, read: false, starred: false, dateArrived: Date())
let prototypeArticle = Article(accountID: prototypeID, articleID: prototypeID, feedID: prototypeID, uniqueID: prototypeID, title: longTitle, contentHTML: nil, contentText: nil, url: nil, externalURL: nil, summary: nil, imageURL: nil, datePublished: nil, dateModified: nil, authors: nil, status: status)
let iconImage = IconImage(AppAssets.faviconTemplateImage.withTintColor(AppAssets.secondaryAccentColor))
return MainTimelineCellData(article: prototypeArticle, showFeedName: .feed, feedName: "Feed Name", byline: nil, iconImage: iconImage, showIcon: true, numberOfLines: AppDefaults.shared.timelineNumberOfLines, iconSize: AppDefaults.shared.timelineIconSize)
}
}