Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 15 additions & 165 deletions Latest.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

232 changes: 115 additions & 117 deletions Latest/Interface/Main Window/Update Table View/Views/UpdateCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,126 +12,124 @@ import Cocoa
The cell that is used in the list of available updates
*/
class UpdateCell: NSTableCellView {
// MARK: - View Lifecycle
/// The label displaying the current version of the app
@IBOutlet private weak var nameTextField: NSTextField!

// MARK: - Outlets

/// The label displaying the app name
@IBOutlet private weak var nameTextField: NSTextField!

/// The label displaying the current version of the app
@IBOutlet private weak var currentVersionTextField: NSTextField!

/// The label displaying the newest version available for the app
@IBOutlet private weak var newVersionTextField: NSTextField!

/// The stack view holding the cells contents.
@IBOutlet private weak var contentStackView: NSStackView!

/// The constraint defining the leading inset of the content.
@available(macOS, deprecated: 11.0) @IBOutlet private weak var leadingConstraint: NSLayoutConstraint!

/// Constraint controlling the trailing inset of the cell.
@available(macOS, deprecated: 11.0) @IBOutlet private weak var trailingConstraint: NSLayoutConstraint!

/// Label displaying the last modified/update date for the app.
@IBOutlet private weak var dateTextField: NSTextField!

/// The button handling the update of the app.
@IBOutlet private weak var updateButton: UpdateButton!

/// Image view displaying a status indicator for the support status of the app.
@IBOutlet private weak var supportStateImageView: NSImageView!

override func awakeFromNib() {
super.awakeFromNib()

if #available(macOS 11.0, *) {
self.leadingConstraint.constant = 0;
self.trailingConstraint.constant = 0;
} else {
self.leadingConstraint.constant = 20;
self.trailingConstraint.constant = 20;
}
}


// MARK: - Update Progress

/// The app represented by this cell
var app: App? {
willSet {
// Remove observer from existing app
if let app = self.app {
UpdateQueue.shared.removeObserver(self, for: app.identifier)
}
}

didSet {
if let app = self.app {
UpdateQueue.shared.addObserver(self, to: app.identifier) { [weak self] progress in
guard let self = self else { return }
self.supportStateImageView.isHidden = !self.showSupportState
}
}

self.updateButton.app = self.app
self.updateContents()
}
}

var filterQuery: String? {
didSet {
if filterQuery != oldValue {
self.updateTitle()
}
}
}


// MARK: - Utilities

/// A date formatter for preparing the update date.
private lazy var dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = .none
dateFormatter.dateStyle = .short
dateFormatter.doesRelativeDateFormatting = true

return dateFormatter
}()

private func updateContents() {
guard let app = self.app, let versionInformation = app.localizedVersionInformation else { return }

self.updateTitle()

// Update the contents of the cell
self.currentVersionTextField.stringValue = versionInformation.current
self.newVersionTextField.stringValue = versionInformation.new ?? ""
self.newVersionTextField.isHidden = !app.updateAvailable
self.dateTextField.stringValue = dateFormatter.string(from: app.updateDate)

// Support state
supportStateImageView.isHidden = !showSupportState
if showSupportState {
supportStateImageView.image = app.source.supportState.statusImage
supportStateImageView.toolTip = app.source.supportState.label
}
}

/// Whether the status indicator for the apps support state should be visible.
private var showSupportState: Bool {
guard let app else { return false }

let isUpdating = switch UpdateQueue.shared.state(for: app.identifier) {
case .none, .error: false
default : true
}

return !isUpdating && (AppListSettings.shared.includeAppsWithLimitedSupport || AppListSettings.shared.includeUnsupportedApps)
}

private func updateTitle() {
self.nameTextField.attributedStringValue = self.app?.highlightedName(for: self.filterQuery) ?? NSAttributedString()
}

/// The stack view holding the cell’s contents
@IBOutlet private weak var contentStackView: NSStackView!

/// Constraints defining the horizontal insets of the cell
@IBOutlet private weak var leadingConstraint: NSLayoutConstraint!
@IBOutlet private weak var trailingConstraint: NSLayoutConstraint!

/// Label displaying the last modified/update date for the app
@IBOutlet private weak var dateTextField: NSTextField!

/// The button handling the update of the app
@IBOutlet private weak var updateButton: UpdateButton!

/// Image view displaying a status indicator for the support status of the app
@IBOutlet private weak var supportStateImageView: NSImageView!

// MARK: - View Lifecycle

override func awakeFromNib() {
super.awakeFromNib()

if #available(macOS 11.0, *) {
leadingConstraint.constant = 0
trailingConstraint.constant = 0
} else {
leadingConstraint.constant = 20
trailingConstraint.constant = 20
}
}

// MARK: - Update Progress

/// The app represented by this cell
var app: App? {
willSet {
if let app = self.app {
UpdateQueue.shared.removeObserver(self, for: app.identifier)
}
}
didSet {
if let app = self.app {
UpdateQueue.shared.addObserver(self, to: app.identifier) { [weak self] _ in
guard let self else { return }
self.supportStateImageView.isHidden = !self.showSupportState
}
}

updateButton.app = app
updateContents()
}
}

var filterQuery: String? {
didSet {
if filterQuery != oldValue {
updateTitle()
}
}
}

// MARK: - Utilities

private lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.timeStyle = .none
formatter.dateStyle = .short
formatter.doesRelativeDateFormatting = true
return formatter
}()

private func updateContents() {
guard
let app,
let versionInformation = app.localizedVersionInformation
else { return }

updateTitle()

currentVersionTextField.stringValue = versionInformation.current
newVersionTextField.stringValue = versionInformation.new ?? ""
newVersionTextField.isHidden = !app.updateAvailable
dateTextField.stringValue = dateFormatter.string(from: app.updateDate)

supportStateImageView.isHidden = !showSupportState
if showSupportState {
supportStateImageView.image = app.source.supportState.statusImage
supportStateImageView.toolTip = app.source.supportState.label
}
}

/// Whether the status indicator for the app’s support state should be visible
private var showSupportState: Bool {
guard let app else { return false }

let isUpdating = switch UpdateQueue.shared.state(for: app.identifier) {
case .none, .error: false
default: true
}

return !isUpdating &&
(AppListSettings.shared.includeAppsWithLimitedSupport ||
AppListSettings.shared.includeUnsupportedApps)
}

private func updateTitle() {
nameTextField.attributedStringValue =
app?.highlightedName(for: filterQuery) ?? NSAttributedString()
}
}
Loading