chore: apply review suggestions

This commit is contained in:
sunxiaojian 2021-04-19 17:00:51 +08:00
parent c814065edb
commit bb03c10ef6
6 changed files with 112 additions and 58 deletions

View File

@ -120,6 +120,7 @@
2DA7D04425CA52B200804E11 /* TimelineLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA7D04325CA52B200804E11 /* TimelineLoaderTableViewCell.swift */; }; 2DA7D04425CA52B200804E11 /* TimelineLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA7D04325CA52B200804E11 /* TimelineLoaderTableViewCell.swift */; };
2DA7D04A25CA52CB00804E11 /* TimelineBottomLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA7D04925CA52CB00804E11 /* TimelineBottomLoaderTableViewCell.swift */; }; 2DA7D04A25CA52CB00804E11 /* TimelineBottomLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA7D04925CA52CB00804E11 /* TimelineBottomLoaderTableViewCell.swift */; };
2DA7D05725CA693F00804E11 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA7D05625CA693F00804E11 /* Application.swift */; }; 2DA7D05725CA693F00804E11 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA7D05625CA693F00804E11 /* Application.swift */; };
2DB72C8C262D764300CE6173 /* Mastodon+Entity+Notification+Type.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB72C8B262D764300CE6173 /* Mastodon+Entity+Notification+Type.swift */; };
2DCB73FD2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DCB73FC2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift */; }; 2DCB73FD2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DCB73FC2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift */; };
2DE0FAC12615F04D00CDF649 /* RecommendHashTagSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE0FAC02615F04D00CDF649 /* RecommendHashTagSection.swift */; }; 2DE0FAC12615F04D00CDF649 /* RecommendHashTagSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE0FAC02615F04D00CDF649 /* RecommendHashTagSection.swift */; };
2DE0FAC82615F5F000CDF649 /* SearchRecommendAccountsCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE0FAC72615F5F000CDF649 /* SearchRecommendAccountsCollectionViewCell.swift */; }; 2DE0FAC82615F5F000CDF649 /* SearchRecommendAccountsCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE0FAC72615F5F000CDF649 /* SearchRecommendAccountsCollectionViewCell.swift */; };
@ -518,6 +519,7 @@
2DA7D04925CA52CB00804E11 /* TimelineBottomLoaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineBottomLoaderTableViewCell.swift; sourceTree = "<group>"; }; 2DA7D04925CA52CB00804E11 /* TimelineBottomLoaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineBottomLoaderTableViewCell.swift; sourceTree = "<group>"; };
2DA7D05025CA545E00804E11 /* LoadMoreConfigurableTableViewContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadMoreConfigurableTableViewContainer.swift; sourceTree = "<group>"; }; 2DA7D05025CA545E00804E11 /* LoadMoreConfigurableTableViewContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadMoreConfigurableTableViewContainer.swift; sourceTree = "<group>"; };
2DA7D05625CA693F00804E11 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; }; 2DA7D05625CA693F00804E11 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
2DB72C8B262D764300CE6173 /* Mastodon+Entity+Notification+Type.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Mastodon+Entity+Notification+Type.swift"; sourceTree = "<group>"; };
2DCB73FC2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchRecommendCollectionHeader.swift; sourceTree = "<group>"; }; 2DCB73FC2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchRecommendCollectionHeader.swift; sourceTree = "<group>"; };
2DE0FAC02615F04D00CDF649 /* RecommendHashTagSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendHashTagSection.swift; sourceTree = "<group>"; }; 2DE0FAC02615F04D00CDF649 /* RecommendHashTagSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendHashTagSection.swift; sourceTree = "<group>"; };
2DE0FAC72615F5F000CDF649 /* SearchRecommendAccountsCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchRecommendAccountsCollectionViewCell.swift; sourceTree = "<group>"; }; 2DE0FAC72615F5F000CDF649 /* SearchRecommendAccountsCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchRecommendAccountsCollectionViewCell.swift; sourceTree = "<group>"; };
@ -1450,6 +1452,7 @@
5DDDF1982617447F00311060 /* Mastodon+Entity+Tag.swift */, 5DDDF1982617447F00311060 /* Mastodon+Entity+Tag.swift */,
5DDDF1A82617489F00311060 /* Mastodon+Entity+History.swift */, 5DDDF1A82617489F00311060 /* Mastodon+Entity+History.swift */,
2D650FAA25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift */, 2D650FAA25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift */,
2DB72C8B262D764300CE6173 /* Mastodon+Entity+Notification+Type.swift */,
); );
path = MastodonSDK; path = MastodonSDK;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2455,6 +2458,7 @@
DB938F0326240EA300E5B6C1 /* CachedThreadViewModel.swift in Sources */, DB938F0326240EA300E5B6C1 /* CachedThreadViewModel.swift in Sources */,
2D650FAB25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift in Sources */, 2D650FAB25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift in Sources */,
2D24E12D2626FD2E00A59D4F /* NotificationViewModel+LoadOldestState.swift in Sources */, 2D24E12D2626FD2E00A59D4F /* NotificationViewModel+LoadOldestState.swift in Sources */,
2DB72C8C262D764300CE6173 /* Mastodon+Entity+Notification+Type.swift in Sources */,
DB118A8C25E4BFB500FAB162 /* HighlightDimmableButton.swift in Sources */, DB118A8C25E4BFB500FAB162 /* HighlightDimmableButton.swift in Sources */,
DBAE3FA92617106E004B8251 /* MastodonMetricFormatter.swift in Sources */, DBAE3FA92617106E004B8251 /* MastodonMetricFormatter.swift in Sources */,
2D35237A26256D920031AF25 /* NotificationSection.swift in Sources */, 2D35237A26256D920031AF25 /* NotificationSection.swift in Sources */,

View File

@ -33,39 +33,15 @@ extension NotificationSection {
case .notification(let objectID): case .notification(let objectID):
let notification = managedObjectContext.object(with: objectID) as! MastodonNotification let notification = managedObjectContext.object(with: objectID) as! MastodonNotification
let type = Mastodon.Entity.Notification.NotificationType(rawValue: notification.typeRaw) guard let type = Mastodon.Entity.Notification.NotificationType(rawValue: notification.typeRaw) else {
assertionFailure()
return nil
}
let timeText = notification.createAt.shortTimeAgoSinceNow let timeText = notification.createAt.shortTimeAgoSinceNow
var actionText: String let actionText = type.actionText
var actionImageName: String let actionImageName = type.actionImageName
var color: UIColor let color = type.color
switch type {
case .follow:
actionText = L10n.Scene.Notification.Action.follow
actionImageName = "person.crop.circle.badge.checkmark"
color = Asset.Colors.brandBlue.color
case .favourite:
actionText = L10n.Scene.Notification.Action.favourite
actionImageName = "star.fill"
color = Asset.Colors.Notification.favourite.color
case .reblog:
actionText = L10n.Scene.Notification.Action.reblog
actionImageName = "arrow.2.squarepath"
color = Asset.Colors.Notification.reblog.color
case .mention:
actionText = L10n.Scene.Notification.Action.mention
actionImageName = "at"
color = Asset.Colors.Notification.mention.color
case .poll:
actionText = L10n.Scene.Notification.Action.poll
actionImageName = "list.bullet"
color = Asset.Colors.brandBlue.color
default:
actionText = ""
actionImageName = ""
color = .clear
}
if let status = notification.status { if let status = notification.status {
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: NotificationStatusTableViewCell.self), for: indexPath) as! NotificationStatusTableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: NotificationStatusTableViewCell.self), for: indexPath) as! NotificationStatusTableViewCell
@ -87,11 +63,13 @@ extension NotificationSection {
cell.actionImageBackground.backgroundColor = color cell.actionImageBackground.backgroundColor = color
cell.actionLabel.text = actionText + " · " + timeText cell.actionLabel.text = actionText + " · " + timeText
cell.nameLabel.text = notification.account.displayName.isEmpty ? notification.account.username : notification.account.displayName cell.nameLabel.text = notification.account.displayName.isEmpty ? notification.account.username : notification.account.displayName
cell.avatatImageView.af.setImage( if let url = notification.account.avatarImageURL() {
withURL: URL(string: notification.account.avatar)!, cell.avatatImageView.af.setImage(
placeholderImage: UIImage.placeholder(color: .systemFill), withURL: url,
imageTransition: .crossDissolve(0.2) placeholderImage: UIImage.placeholder(color: .systemFill),
) imageTransition: .crossDissolve(0.2)
)
}
cell.avatatImageView.gesture().sink { [weak cell] _ in cell.avatatImageView.gesture().sink { [weak cell] _ in
cell?.delegate?.userAvatarDidPressed(notification: notification) cell?.delegate?.userAvatarDidPressed(notification: notification)
} }
@ -113,11 +91,13 @@ extension NotificationSection {
cell.actionImageBackground.backgroundColor = color cell.actionImageBackground.backgroundColor = color
cell.actionLabel.text = actionText + " · " + timeText cell.actionLabel.text = actionText + " · " + timeText
cell.nameLabel.text = notification.account.displayName.isEmpty ? notification.account.username : notification.account.displayName cell.nameLabel.text = notification.account.displayName.isEmpty ? notification.account.username : notification.account.displayName
cell.avatatImageView.af.setImage( if let url = notification.account.avatarImageURL() {
withURL: URL(string: notification.account.avatar)!, cell.avatatImageView.af.setImage(
placeholderImage: UIImage.placeholder(color: .systemFill), withURL: url,
imageTransition: .crossDissolve(0.2) placeholderImage: UIImage.placeholder(color: .systemFill),
) imageTransition: .crossDissolve(0.2)
)
}
cell.avatatImageView.gesture().sink { [weak cell] _ in cell.avatatImageView.gesture().sink { [weak cell] _ in
cell?.delegate?.userAvatarDidPressed(notification: notification) cell?.delegate?.userAvatarDidPressed(notification: notification)
} }

View File

@ -0,0 +1,75 @@
//
// Mastodon+Entity+Notification+Type.swift
// Mastodon
//
// Created by sxiaojian on 2021/4/19.
//
import Foundation
import MastodonSDK
import UIKit
extension Mastodon.Entity.Notification.NotificationType {
public var color: UIColor {
get {
var color: UIColor
switch self {
case .follow:
color = Asset.Colors.brandBlue.color
case .favourite:
color = Asset.Colors.Notification.favourite.color
case .reblog:
color = Asset.Colors.Notification.reblog.color
case .mention:
color = Asset.Colors.Notification.mention.color
case .poll:
color = Asset.Colors.brandBlue.color
default:
color = .clear
}
return color
}
}
public var actionText: String {
get {
var actionText: String
switch self {
case .follow:
actionText = L10n.Scene.Notification.Action.follow
case .favourite:
actionText = L10n.Scene.Notification.Action.favourite
case .reblog:
actionText = L10n.Scene.Notification.Action.reblog
case .mention:
actionText = L10n.Scene.Notification.Action.mention
case .poll:
actionText = L10n.Scene.Notification.Action.poll
default:
actionText = ""
}
return actionText
}
}
public var actionImageName: String {
get {
var actionImageName: String
switch self {
case .follow:
actionImageName = "person.crop.circle.badge.checkmark"
case .favourite:
actionImageName = "star.fill"
case .reblog:
actionImageName = "arrow.2.squarepath"
case .mention:
actionImageName = "at"
case .poll:
actionImageName = "list.bullet"
default:
actionImageName = ""
}
return actionImageName
}
}
}

View File

@ -22,7 +22,7 @@ final class NotificationViewController: UIViewController, NeedsDependency {
let segmentControl: UISegmentedControl = { let segmentControl: UISegmentedControl = {
let control = UISegmentedControl(items: [L10n.Scene.Notification.Title.everything, L10n.Scene.Notification.Title.mentions]) let control = UISegmentedControl(items: [L10n.Scene.Notification.Title.everything, L10n.Scene.Notification.Title.mentions])
control.selectedSegmentIndex = 0 control.selectedSegmentIndex = NotificationViewModel.NotificationSegment.EveryThing.rawValue
return control return control
}() }()
@ -45,7 +45,7 @@ final class NotificationViewController: UIViewController, NeedsDependency {
extension NotificationViewController { extension NotificationViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
view.backgroundColor = Asset.Colors.Background.systemBackground.color view.backgroundColor = Asset.Colors.Background.secondarySystemBackground.color
navigationItem.titleView = segmentControl navigationItem.titleView = segmentControl
segmentControl.addTarget(self, action: #selector(NotificationViewController.segmentedControlValueChanged(_:)), for: .valueChanged) segmentControl.addTarget(self, action: #selector(NotificationViewController.segmentedControlValueChanged(_:)), for: .valueChanged)
tableView.translatesAutoresizingMaskIntoConstraints = false tableView.translatesAutoresizingMaskIntoConstraints = false
@ -115,7 +115,7 @@ extension NotificationViewController {
guard let domain = viewModel.activeMastodonAuthenticationBox.value?.domain, let userID = viewModel.activeMastodonAuthenticationBox.value?.userID else { guard let domain = viewModel.activeMastodonAuthenticationBox.value?.domain, let userID = viewModel.activeMastodonAuthenticationBox.value?.userID else {
return return
} }
if sender.selectedSegmentIndex == 0 { if sender.selectedSegmentIndex == NotificationViewModel.NotificationSegment.EveryThing.rawValue {
viewModel.notificationPredicate.value = MastodonNotification.predicate(domain: domain, userID: userID) viewModel.notificationPredicate.value = MastodonNotification.predicate(domain: domain, userID: userID)
} else { } else {
viewModel.notificationPredicate.value = MastodonNotification.predicate(domain: domain, userID: userID, typeRaw: Mastodon.Entity.Notification.NotificationType.mention.rawValue) viewModel.notificationPredicate.value = MastodonNotification.predicate(domain: domain, userID: userID, typeRaw: Mastodon.Entity.Notification.NotificationType.mention.rawValue)

View File

@ -62,6 +62,7 @@ class SearchRecommendAccountsCollectionViewCell: UICollectionViewCell {
let followButton: HighlightDimmableButton = { let followButton: HighlightDimmableButton = {
let button = HighlightDimmableButton(type: .custom) let button = HighlightDimmableButton(type: .custom)
button.setInsets(forContentPadding: UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16), imageTitlePadding: 0)
button.setTitleColor(.white, for: .normal) button.setTitleColor(.white, for: .normal)
button.setTitle(L10n.Scene.Search.Recommend.Accounts.follow, for: .normal) button.setTitle(L10n.Scene.Search.Recommend.Accounts.follow, for: .normal)
button.titleLabel?.font = .systemFont(ofSize: 14, weight: .semibold) button.titleLabel?.font = .systemFont(ofSize: 14, weight: .semibold)
@ -97,7 +98,10 @@ extension SearchRecommendAccountsCollectionViewCell {
headerImageView.layer.borderColor = Asset.Colors.Border.searchCard.color.cgColor headerImageView.layer.borderColor = Asset.Colors.Border.searchCard.color.cgColor
applyShadow(color: Asset.Colors.Shadow.searchCard.color, alpha: 0.1, x: 0, y: 3, blur: 12, spread: 0) applyShadow(color: Asset.Colors.Shadow.searchCard.color, alpha: 0.1, x: 0, y: 3, blur: 12, spread: 0)
} }
override open func layoutSubviews() {
super.layoutSubviews()
followButton.layer.cornerRadius = followButton.frame.height/2
}
private func configure() { private func configure() {
headerImageView.backgroundColor = Asset.Colors.brandBlue.color headerImageView.backgroundColor = Asset.Colors.brandBlue.color
layer.cornerRadius = 10 layer.cornerRadius = 10
@ -149,8 +153,8 @@ extension SearchRecommendAccountsCollectionViewCell {
followButton.translatesAutoresizingMaskIntoConstraints = false followButton.translatesAutoresizingMaskIntoConstraints = false
containerStackView.addArrangedSubview(followButton) containerStackView.addArrangedSubview(followButton)
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
followButton.widthAnchor.constraint(equalToConstant: 76), followButton.widthAnchor.constraint(greaterThanOrEqualToConstant: 76),
followButton.heightAnchor.constraint(equalToConstant: 24) followButton.heightAnchor.constraint(greaterThanOrEqualToConstant: 24)
]) ])
containerStackView.addArrangedSubview(followButton) containerStackView.addArrangedSubview(followButton)
} }

View File

@ -91,8 +91,7 @@ extension SearchRecommendTagsCollectionViewCell {
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
containerStackView.topAnchor.constraint(equalTo: contentView.topAnchor), containerStackView.topAnchor.constraint(equalTo: contentView.topAnchor),
containerStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), containerStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
containerStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), containerStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
containerStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
]) ])
@ -111,17 +110,9 @@ extension SearchRecommendTagsCollectionViewCell {
containerStackView.addArrangedSubview(horizontalStackView) containerStackView.addArrangedSubview(horizontalStackView)
let peopleHorizontalStackView = UIStackView()
peopleHorizontalStackView.axis = .horizontal
peopleHorizontalStackView.translatesAutoresizingMaskIntoConstraints = false
peopleHorizontalStackView.distribution = .fill
peopleHorizontalStackView.alignment = .top
peopleLabel.translatesAutoresizingMaskIntoConstraints = false peopleLabel.translatesAutoresizingMaskIntoConstraints = false
peopleLabel.setContentHuggingPriority(.defaultLow - 1, for: .vertical) peopleLabel.setContentHuggingPriority(.defaultLow - 1, for: .vertical)
peopleHorizontalStackView.addArrangedSubview(peopleLabel) containerStackView.addArrangedSubview(peopleLabel)
containerStackView.addArrangedSubview(peopleHorizontalStackView)
} }
func config(with tag: Mastodon.Entity.Tag) { func config(with tag: Mastodon.Entity.Tag) {