fix: missing notification author name tapping handling. resolve #197

This commit is contained in:
CMK 2021-07-06 17:38:04 +08:00
parent 888d2a1408
commit dae423f28f
5 changed files with 69 additions and 281 deletions

View File

@ -55,7 +55,6 @@
2D34D9DB261494120081BFC0 /* APIService+Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D34D9DA261494120081BFC0 /* APIService+Search.swift */; };
2D34D9E226149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D34D9E126149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift */; };
2D35237A26256D920031AF25 /* NotificationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D35237926256D920031AF25 /* NotificationSection.swift */; };
2D35238126256F690031AF25 /* NotificationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D35238026256F690031AF25 /* NotificationTableViewCell.swift */; };
2D364F7225E66D7500204FDC /* MastodonResendEmailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */; };
2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */; };
2D38F1C625CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */; };
@ -666,7 +665,6 @@
2D34D9DA261494120081BFC0 /* APIService+Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Search.swift"; sourceTree = "<group>"; };
2D34D9E126149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchRecommendTagsCollectionViewCell.swift; sourceTree = "<group>"; };
2D35237926256D920031AF25 /* NotificationSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSection.swift; sourceTree = "<group>"; };
2D35238026256F690031AF25 /* NotificationTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTableViewCell.swift; sourceTree = "<group>"; };
2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewController.swift; sourceTree = "<group>"; };
2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewModel.swift; sourceTree = "<group>"; };
2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentOffsetAdjustableTimelineViewControllerDelegate.swift; sourceTree = "<group>"; };
@ -1362,7 +1360,6 @@
2D35237F26256F470031AF25 /* TableViewCell */ = {
isa = PBXGroup;
children = (
2D35238026256F690031AF25 /* NotificationTableViewCell.swift */,
2D24E11C2626D8B100A59D4F /* NotificationStatusTableViewCell.swift */,
);
path = TableViewCell;
@ -3278,7 +3275,6 @@
DBF9814A265E24F500E4BA07 /* ProfileFieldCollectionViewHeaderFooterView.swift in Sources */,
2D939AB525EDD8A90076FA61 /* String.swift in Sources */,
DB4481B925EE289600BEFB67 /* UITableView.swift in Sources */,
2D35238126256F690031AF25 /* NotificationTableViewCell.swift in Sources */,
DBE3CDBB261C427900430CC6 /* TimelineHeaderTableViewCell.swift in Sources */,
DBCBCBFF2680AE98000F5B51 /* AsyncHomeTimelineViewModel.swift in Sources */,
0FAA101C25E10E760017CCDE /* UIFont.swift in Sources */,

View File

@ -46,10 +46,6 @@ extension NotificationSection {
),
into: cell.avatarImageView
)
cell.avatarImageView.gesture().sink { [weak cell] _ in
cell?.delegate?.userAvatarDidPressed(notification: notification)
}
.store(in: &cell.disposeBag)
cell.actionImageView.image = UIImage(
systemName: notification.notificationType.actionImageName,
withConfiguration: UIImage.SymbolConfiguration(

View File

@ -12,6 +12,7 @@ import GameplayKit
import MastodonSDK
import OSLog
import UIKit
import ActiveLabel
import Meta
import MetaTextView
@ -277,6 +278,35 @@ extension NotificationViewController: ContentOffsetAdjustableTimelineViewControl
// MARK: - NotificationTableViewCellDelegate
extension NotificationViewController: NotificationTableViewCellDelegate {
func notificationStatusTableViewCell(_ cell: NotificationStatusTableViewCell, avatarImageViewDidPressed imageView: UIImageView) {
guard let diffableDataSource = viewModel.diffableDataSource else { return }
guard let indexPath = tableView.indexPath(for: cell) else { return }
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return }
switch item {
case .notification(let objectID, _):
guard let notification = try? viewModel.fetchedResultsController.managedObjectContext.existingObject(with: objectID) as? MastodonNotification else { return }
let viewModel = ProfileViewModel(context: context, optionalMastodonUser: notification.account)
coordinator.present(scene: .profile(viewModel: viewModel), from: self, transition: .show)
default:
break
}
}
func notificationStatusTableViewCell(_ cell: NotificationStatusTableViewCell, authorNameLabelDidPressed label: ActiveLabel) {
guard let diffableDataSource = viewModel.diffableDataSource else { return }
guard let indexPath = tableView.indexPath(for: cell) else { return }
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return }
switch item {
case .notification(let objectID, _):
guard let notification = try? viewModel.fetchedResultsController.managedObjectContext.existingObject(with: objectID) as? MastodonNotification else { return }
let viewModel = ProfileViewModel(context: context, optionalMastodonUser: notification.account)
coordinator.present(scene: .profile(viewModel: viewModel), from: self, transition: .show)
default:
break
}
}
func notificationTableViewCell(_ cell: NotificationStatusTableViewCell, notification: MastodonNotification, acceptButtonDidPressed button: UIButton) {
viewModel.acceptFollowRequest(notification: notification)
}
@ -284,13 +314,6 @@ extension NotificationViewController: NotificationTableViewCellDelegate {
func notificationTableViewCell(_ cell: NotificationStatusTableViewCell, notification: MastodonNotification, rejectButtonDidPressed button: UIButton) {
viewModel.rejectFollowRequest(notification: notification)
}
func userAvatarDidPressed(notification: MastodonNotification) {
let viewModel = ProfileViewModel(context: context, optionalMastodonUser: notification.account)
DispatchQueue.main.async {
self.coordinator.present(scene: .profile(viewModel: viewModel), from: self, transition: .show)
}
}
func userNameLabelDidPressed(notification: MastodonNotification) {
let viewModel = CachedProfileViewModel(context: context, mastodonUser: notification.account)

View File

@ -5,8 +5,10 @@
// Created by sxiaojian on 2021/4/14.
//
import os.log
import Combine
import Foundation
import CoreDataStack
import UIKit
import ActiveLabel
import MetaTextView
@ -14,6 +16,23 @@ import Meta
import FLAnimatedImage
import Nuke
protocol NotificationTableViewCellDelegate: AnyObject {
var context: AppContext! { get }
func parent() -> UIViewController
func notificationStatusTableViewCell(_ cell: NotificationStatusTableViewCell, avatarImageViewDidPressed imageView: UIImageView)
func notificationStatusTableViewCell(_ cell: NotificationStatusTableViewCell, authorNameLabelDidPressed label: ActiveLabel)
func notificationStatusTableViewCell(_ cell: NotificationStatusTableViewCell, statusView: StatusView, revealContentWarningButtonDidPressed button: UIButton)
func notificationStatusTableViewCell(_ cell: NotificationStatusTableViewCell, statusView: StatusView, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView)
func notificationStatusTableViewCell(_ cell: NotificationStatusTableViewCell, statusView: StatusView, playerContainerView: PlayerContainerView, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView)
func notificationStatusTableViewCell(_ cell: NotificationStatusTableViewCell, statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta)
func notificationTableViewCell(_ cell: NotificationStatusTableViewCell, notification: MastodonNotification, acceptButtonDidPressed button: UIButton)
func notificationTableViewCell(_ cell: NotificationStatusTableViewCell, notification: MastodonNotification, rejectButtonDidPressed button: UIButton)
}
final class NotificationStatusTableViewCell: UITableViewCell, StatusCell {
static let actionImageBorderWidth: CGFloat = 2
@ -246,7 +265,14 @@ extension NotificationStatusTableViewCell {
])
statusView.delegate = self
let avatarImageViewTapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer
avatarImageViewTapGestureRecognizer.addTarget(self, action: #selector(NotificationStatusTableViewCell.avatarImageViewTapGestureRecognizerHandler(_:)))
avatarImageView.addGestureRecognizer(avatarImageViewTapGestureRecognizer)
let authorNameLabelTapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer
authorNameLabelTapGestureRecognizer.addTarget(self, action: #selector(NotificationStatusTableViewCell.authorNameLabelTapGestureRecognizerHandler(_:)))
nameLabel.addGestureRecognizer(authorNameLabelTapGestureRecognizer)
resetSeparatorLineLayout()
}
@ -260,6 +286,18 @@ extension NotificationStatusTableViewCell {
}
extension NotificationStatusTableViewCell {
@objc private func avatarImageViewTapGestureRecognizerHandler(_ sender: UITapGestureRecognizer) {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
delegate?.notificationStatusTableViewCell(self, avatarImageViewDidPressed: avatarImageView)
}
@objc private func authorNameLabelTapGestureRecognizerHandler(_ sender: UITapGestureRecognizer) {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
delegate?.notificationStatusTableViewCell(self, authorNameLabelDidPressed: nameLabel)
}
}
// MARK: - StatusViewDelegate
extension NotificationStatusTableViewCell: StatusViewDelegate {

View File

@ -1,265 +0,0 @@
//
// NotificationTableViewCell.swift
// Mastodon
//
// Created by sxiaojian on 2021/4/13.
//
import Combine
import CoreDataStack
import Foundation
import UIKit
import Meta
import MetaTextView
import ActiveLabel
import FLAnimatedImage
import Nuke
protocol NotificationTableViewCellDelegate: AnyObject {
var context: AppContext! { get }
func parent() -> UIViewController
func userAvatarDidPressed(notification: MastodonNotification)
func userNameLabelDidPressed(notification: MastodonNotification)
func notificationStatusTableViewCell(_ cell: NotificationStatusTableViewCell, statusView: StatusView, revealContentWarningButtonDidPressed button: UIButton)
func notificationStatusTableViewCell(_ cell: NotificationStatusTableViewCell, statusView: StatusView, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView)
func notificationStatusTableViewCell(_ cell: NotificationStatusTableViewCell, statusView: StatusView, playerContainerView: PlayerContainerView, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView)
func notificationStatusTableViewCell(_ cell: NotificationStatusTableViewCell, statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta)
func notificationTableViewCell(_ cell: NotificationStatusTableViewCell, notification: MastodonNotification, acceptButtonDidPressed button: UIButton)
func notificationTableViewCell(_ cell: NotificationStatusTableViewCell, notification: MastodonNotification, rejectButtonDidPressed button: UIButton)
}
//final class NotificationTableViewCell: UITableViewCell {
// static let actionImageBorderWidth: CGFloat = 2
//
// var disposeBag = Set<AnyCancellable>()
//
// var delegate: NotificationTableViewCellDelegate?
//
// var avatarImageViewTask: ImageTask?
// let avatarImageView: UIImageView = {
// let imageView = FLAnimatedImageView()
// imageView.layer.cornerRadius = 4
// imageView.layer.cornerCurve = .continuous
// imageView.clipsToBounds = true
// return imageView
// }()
//
// let actionImageView: UIImageView = {
// let imageView = UIImageView()
// imageView.tintColor = Asset.Colors.Background.systemBackground.color
// return imageView
// }()
//
// let actionImageBackground: UIView = {
// let view = UIView()
// view.layer.cornerRadius = (24 + NotificationTableViewCell.actionImageBorderWidth) / 2
// view.layer.cornerCurve = .continuous
// view.clipsToBounds = true
// view.layer.borderWidth = NotificationTableViewCell.actionImageBorderWidth
// view.layer.borderColor = Asset.Colors.Background.systemBackground.color.cgColor
// view.tintColor = Asset.Colors.Background.systemBackground.color
// return view
// }()
//
// let avatarContainer: UIView = {
// let view = UIView()
// return view
// }()
//
// let actionLabel: UILabel = {
// let label = UILabel()
// label.textColor = Asset.Colors.Label.secondary.color
// label.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular), maximumPointSize: 20)
// label.lineBreakMode = .byTruncatingTail
// return label
// }()
//
// let nameLabel: ActiveLabel = {
// let label = ActiveLabel()
// label.textColor = Asset.Colors.brandBlue.color
// label.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 15, weight: .semibold), maximumPointSize: 20)
// label.lineBreakMode = .byTruncatingTail
// return label
// }()
//
// let acceptButton: UIButton = {
// let button = UIButton(type: .custom)
// let actionImage = UIImage(systemName: "checkmark.circle.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 28, weight: .semibold))?.withRenderingMode(.alwaysTemplate)
// button.setImage(actionImage, for: .normal)
// button.tintColor = Asset.Colors.Label.secondary.color
// return button
// }()
//
// let rejectButton: UIButton = {
// let button = UIButton(type: .custom)
// let actionImage = UIImage(systemName: "xmark.circle.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 28, weight: .semibold))?.withRenderingMode(.alwaysTemplate)
// button.setImage(actionImage, for: .normal)
// button.tintColor = Asset.Colors.Label.secondary.color
// return button
// }()
//
// let buttonStackView = UIStackView()
//
// let separatorLine = UIView.separatorLine
//
// var separatorLineToEdgeLeadingLayoutConstraint: NSLayoutConstraint!
// var separatorLineToEdgeTrailingLayoutConstraint: NSLayoutConstraint!
//
// var separatorLineToMarginLeadingLayoutConstraint: NSLayoutConstraint!
// var separatorLineToMarginTrailingLayoutConstraint: NSLayoutConstraint!
//
// override func prepareForReuse() {
// super.prepareForReuse()
// avatarImageViewTask?.cancel()
// avatarImageViewTask = nil
// disposeBag.removeAll()
// }
//
// override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
// super.init(style: style, reuseIdentifier: reuseIdentifier)
// configure()
// }
//
// required init?(coder: NSCoder) {
// super.init(coder: coder)
// configure()
// }
//}
//
//extension NotificationTableViewCell {
// func configure() {
// backgroundColor = Asset.Colors.Background.systemBackground.color
// selectedBackgroundView = {
// let view = UIView()
// view.backgroundColor = Asset.Colors.Background.Cell.highlight.color
// return view
// }()
//
// let containerStackView = UIStackView()
// containerStackView.axis = .vertical
// containerStackView.alignment = .fill
// containerStackView.layoutMargins = UIEdgeInsets(top: 14, left: 0, bottom: 12, right: 0)
// containerStackView.isLayoutMarginsRelativeArrangement = true
// containerStackView.translatesAutoresizingMaskIntoConstraints = false
// contentView.addSubview(containerStackView)
// NSLayoutConstraint.activate([
// containerStackView.topAnchor.constraint(equalTo: contentView.topAnchor),
// containerStackView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
// contentView.readableContentGuide.trailingAnchor.constraint(equalTo: containerStackView.trailingAnchor),
// contentView.bottomAnchor.constraint(equalTo: containerStackView.bottomAnchor),
// ])
//
// let horizontalStackView = UIStackView()
// horizontalStackView.translatesAutoresizingMaskIntoConstraints = false
// horizontalStackView.axis = .horizontal
// horizontalStackView.spacing = 6
//
// horizontalStackView.addArrangedSubview(avatarContainer)
// avatarContainer.translatesAutoresizingMaskIntoConstraints = false
// NSLayoutConstraint.activate([
// avatarContainer.heightAnchor.constraint(equalToConstant: 47).priority(.required - 1),
// avatarContainer.widthAnchor.constraint(equalToConstant: 47).priority(.required - 1)
// ])
//
// avatarContainer.addSubview(avatarImageView)
// avatarImageView.translatesAutoresizingMaskIntoConstraints = false
// NSLayoutConstraint.activate([
// avatarImageView.heightAnchor.constraint(equalToConstant: 35).priority(.required - 1),
// avatarImageView.widthAnchor.constraint(equalToConstant: 35).priority(.required - 1),
// avatarImageView.topAnchor.constraint(equalTo: avatarContainer.topAnchor),
// avatarImageView.leadingAnchor.constraint(equalTo: avatarContainer.leadingAnchor)
// ])
//
// avatarContainer.addSubview(actionImageBackground)
// actionImageBackground.translatesAutoresizingMaskIntoConstraints = false
// NSLayoutConstraint.activate([
// actionImageBackground.heightAnchor.constraint(equalToConstant: 24 + NotificationTableViewCell.actionImageBorderWidth).priority(.required - 1),
// actionImageBackground.widthAnchor.constraint(equalToConstant: 24 + NotificationTableViewCell.actionImageBorderWidth).priority(.required - 1),
// actionImageBackground.bottomAnchor.constraint(equalTo: avatarContainer.bottomAnchor),
// actionImageBackground.trailingAnchor.constraint(equalTo: avatarContainer.trailingAnchor)
// ])
//
// avatarContainer.addSubview(actionImageView)
// actionImageView.translatesAutoresizingMaskIntoConstraints = false
// NSLayoutConstraint.activate([
// actionImageView.centerXAnchor.constraint(equalTo: actionImageBackground.centerXAnchor),
// actionImageView.centerYAnchor.constraint(equalTo: actionImageBackground.centerYAnchor)
// ])
//
// nameLabel.translatesAutoresizingMaskIntoConstraints = false
// horizontalStackView.addArrangedSubview(nameLabel)
// actionLabel.translatesAutoresizingMaskIntoConstraints = false
// horizontalStackView.addArrangedSubview(actionLabel)
// nameLabel.setContentCompressionResistancePriority(.required - 1, for: .horizontal)
// nameLabel.setContentHuggingPriority(.required - 1, for: .horizontal)
// actionLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
//
// containerStackView.addArrangedSubview(horizontalStackView)
//
// buttonStackView.translatesAutoresizingMaskIntoConstraints = false
// buttonStackView.axis = .horizontal
// buttonStackView.distribution = .fillEqually
// acceptButton.translatesAutoresizingMaskIntoConstraints = false
// rejectButton.translatesAutoresizingMaskIntoConstraints = false
// buttonStackView.addArrangedSubview(acceptButton)
// buttonStackView.addArrangedSubview(rejectButton)
// containerStackView.addArrangedSubview(buttonStackView)
//
// separatorLine.translatesAutoresizingMaskIntoConstraints = false
// contentView.addSubview(separatorLine)
// separatorLineToEdgeLeadingLayoutConstraint = separatorLine.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
// separatorLineToEdgeTrailingLayoutConstraint = separatorLine.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
// separatorLineToMarginLeadingLayoutConstraint = separatorLine.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor)
// separatorLineToMarginTrailingLayoutConstraint = separatorLine.trailingAnchor.constraint(equalTo: contentView.readableContentGuide.trailingAnchor)
// NSLayoutConstraint.activate([
// separatorLine.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
// separatorLine.heightAnchor.constraint(equalToConstant: UIView.separatorLineHeight(of: contentView)),
// ])
// resetSeparatorLineLayout()
// }
//
// override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
// super.traitCollectionDidChange(previousTraitCollection)
//
// actionImageBackground.layer.borderColor = Asset.Colors.Background.systemBackground.color.cgColor
// resetSeparatorLineLayout()
// }
//}
//
//extension NotificationTableViewCell {
//
// private func resetSeparatorLineLayout() {
// separatorLineToEdgeLeadingLayoutConstraint.isActive = false
// separatorLineToEdgeTrailingLayoutConstraint.isActive = false
// separatorLineToMarginLeadingLayoutConstraint.isActive = false
// separatorLineToMarginTrailingLayoutConstraint.isActive = false
//
// if traitCollection.userInterfaceIdiom == .phone {
// // to edge
// NSLayoutConstraint.activate([
// separatorLineToEdgeLeadingLayoutConstraint,
// separatorLineToEdgeTrailingLayoutConstraint,
// ])
// } else {
// if traitCollection.horizontalSizeClass == .compact {
// // to edge
// NSLayoutConstraint.activate([
// separatorLineToEdgeLeadingLayoutConstraint,
// separatorLineToEdgeTrailingLayoutConstraint,
// ])
// } else {
// // to margin
// NSLayoutConstraint.activate([
// separatorLineToMarginLeadingLayoutConstraint,
// separatorLineToMarginTrailingLayoutConstraint,
// ])
// }
// }
// }
//
//}