forked from zelo72/mastodon-ios
chore: show menu in statusCell
This commit is contained in:
parent
23491e60b9
commit
273305cda9
|
@ -50,6 +50,7 @@ extension NotificationSection {
|
|||
let frame = CGRect(x: 0, y: 0, width: tableView.readableContentGuide.layoutFrame.width - NotificationStatusTableViewCell.statusPadding.left - NotificationStatusTableViewCell.statusPadding.right, height: tableView.readableContentGuide.layoutFrame.height)
|
||||
StatusSection.configure(
|
||||
cell: cell,
|
||||
indexPath: indexPath,
|
||||
dependency: dependency,
|
||||
readableLayoutFrame: frame,
|
||||
timestampUpdatePublisher: timestampUpdatePublisher,
|
||||
|
|
|
@ -41,6 +41,7 @@ extension ReportSection {
|
|||
let status = managedObjectContext.object(with: objectID) as! Status
|
||||
StatusSection.configure(
|
||||
cell: cell,
|
||||
indexPath: indexPath,
|
||||
dependency: dependency,
|
||||
readableLayoutFrame: tableView.readableContentGuide.layoutFrame,
|
||||
timestampUpdatePublisher: timestampUpdatePublisher,
|
||||
|
|
|
@ -49,6 +49,7 @@ extension StatusSection {
|
|||
let timelineIndex = managedObjectContext.object(with: objectID) as! HomeTimelineIndex
|
||||
StatusSection.configure(
|
||||
cell: cell,
|
||||
indexPath: indexPath,
|
||||
dependency: dependency,
|
||||
readableLayoutFrame: tableView.readableContentGuide.layoutFrame,
|
||||
timestampUpdatePublisher: timestampUpdatePublisher,
|
||||
|
@ -71,6 +72,7 @@ extension StatusSection {
|
|||
let status = managedObjectContext.object(with: objectID) as! Status
|
||||
StatusSection.configure(
|
||||
cell: cell,
|
||||
indexPath: indexPath,
|
||||
dependency: dependency,
|
||||
readableLayoutFrame: tableView.readableContentGuide.layoutFrame,
|
||||
timestampUpdatePublisher: timestampUpdatePublisher,
|
||||
|
@ -136,6 +138,7 @@ extension StatusSection {
|
|||
|
||||
static func configure(
|
||||
cell: StatusCell,
|
||||
indexPath: IndexPath,
|
||||
dependency: NeedsDependency,
|
||||
readableLayoutFrame: CGRect?,
|
||||
timestampUpdatePublisher: AnyPublisher<Date, Never>,
|
||||
|
@ -223,7 +226,6 @@ extension StatusSection {
|
|||
meta.blurhashImagePublisher()
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak cell] image in
|
||||
guard let cell = cell else { return }
|
||||
blurhashOverlayImageView.image = image
|
||||
image?.pngData().flatMap {
|
||||
blurhashImageCache.setObject($0 as NSData, forKey: blurhashImageDataKey)
|
||||
|
@ -401,16 +403,16 @@ extension StatusSection {
|
|||
.store(in: &cell.disposeBag)
|
||||
}
|
||||
|
||||
if let statusTableViewCell = cell as? StatusTableViewCell {
|
||||
// toolbar
|
||||
StatusSection.configureActionToolBar(
|
||||
cell: cell,
|
||||
cell: statusTableViewCell,
|
||||
indexPath: indexPath,
|
||||
dependency: dependency,
|
||||
status: status,
|
||||
requestUserID: requestUserID
|
||||
)
|
||||
|
||||
// separator line
|
||||
if let statusTableViewCell = cell as? StatusTableViewCell {
|
||||
statusTableViewCell.separatorLine.isHidden = statusItemAttribute.isSeparatorLineHidden
|
||||
}
|
||||
|
||||
|
@ -434,8 +436,10 @@ extension StatusSection {
|
|||
guard let dependency = dependency else { return }
|
||||
guard case .update(let object) = change.changeType,
|
||||
let status = object as? Status else { return }
|
||||
guard let cell = cell as? StatusTableViewCell else { return }
|
||||
StatusSection.configureActionToolBar(
|
||||
cell: cell,
|
||||
indexPath: indexPath,
|
||||
dependency: dependency,
|
||||
status: status,
|
||||
requestUserID: requestUserID
|
||||
|
@ -593,7 +597,8 @@ extension StatusSection {
|
|||
}
|
||||
|
||||
static func configureActionToolBar(
|
||||
cell: StatusCell,
|
||||
cell: StatusTableViewCell,
|
||||
indexPath: IndexPath,
|
||||
dependency: NeedsDependency,
|
||||
status: Status,
|
||||
requestUserID: String
|
||||
|
@ -623,7 +628,7 @@ extension StatusSection {
|
|||
cell.statusView.actionToolbarContainer.favoriteButton.setTitle(favoriteCountTitle, for: .normal)
|
||||
cell.statusView.actionToolbarContainer.isFavoriteButtonHighlight = isLike
|
||||
|
||||
self.setupStatusMoreButtonMenu(cell: cell, dependency: dependency, status: status)
|
||||
self.setupStatusMoreButtonMenu(cell: cell, indexPath: indexPath, dependency: dependency, status: status)
|
||||
}
|
||||
|
||||
static func configurePoll(
|
||||
|
@ -752,37 +757,35 @@ extension StatusSection {
|
|||
}
|
||||
|
||||
private static func setupStatusMoreButtonMenu(
|
||||
cell: StatusCell,
|
||||
cell: StatusTableViewCell,
|
||||
indexPath: IndexPath,
|
||||
dependency: NeedsDependency,
|
||||
status: Status) {
|
||||
|
||||
cell.statusView.actionToolbarContainer.moreButton.menu = nil
|
||||
guard let userProvider = dependency as? UserProvider else { fatalError() }
|
||||
|
||||
guard let authenticationBox = dependency.context.authenticationService.activeMastodonAuthenticationBox.value else {
|
||||
return
|
||||
}
|
||||
let author = (status.reblog ?? status).author
|
||||
guard authenticationBox.userID != author.id else {
|
||||
return
|
||||
}
|
||||
var children: [UIMenuElement] = []
|
||||
let name = author.displayNameWithFallback
|
||||
let reportAction = UIAction(title: L10n.Common.Controls.Actions.reportUser(name), image: UIImage(systemName: "exclamationmark.bubble"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) {
|
||||
[weak dependency] _ in
|
||||
guard let dependency = dependency else { return }
|
||||
let viewModel = ReportViewModel(
|
||||
context: dependency.context,
|
||||
domain: authenticationBox.domain,
|
||||
user: status.author,
|
||||
status: status)
|
||||
dependency.coordinator.present(
|
||||
scene: .report(viewModel: viewModel),
|
||||
from: nil,
|
||||
transition: .modal(animated: true, completion: nil)
|
||||
let canReport = authenticationBox.userID != author.id
|
||||
|
||||
let isMuting = (author.mutingBy ?? Set()).map(\.id).contains(authenticationBox.userID)
|
||||
let isBlocking = (author.blockingBy ?? Set()).map(\.id).contains(authenticationBox.userID)
|
||||
|
||||
cell.statusView.actionToolbarContainer.moreButton.showsMenuAsPrimaryAction = true
|
||||
cell.statusView.actionToolbarContainer.moreButton.menu = UserProviderFacade.createProfileActionMenu(
|
||||
for: author,
|
||||
isMuting: isMuting,
|
||||
isBlocking: isBlocking,
|
||||
canReport: canReport,
|
||||
provider: userProvider,
|
||||
cell: cell,
|
||||
indexPath: indexPath,
|
||||
sourceView: cell.statusView.actionToolbarContainer.moreButton,
|
||||
barButtonItem: nil,
|
||||
shareUser: nil,
|
||||
shareStatus: status
|
||||
)
|
||||
}
|
||||
children.append(reportAction)
|
||||
cell.statusView.actionToolbarContainer.moreButton.menu = UIMenu(title: "", options: [], children: children)
|
||||
cell.statusView.actionToolbarContainer.moreButton.showsMenuAsPrimaryAction = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,20 +57,29 @@ extension UserProviderFacade {
|
|||
extension UserProviderFacade {
|
||||
|
||||
static func toggleUserBlockRelationship(
|
||||
provider: UserProvider
|
||||
provider: UserProvider,
|
||||
cell: UITableViewCell?,
|
||||
indexPath: IndexPath?
|
||||
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error> {
|
||||
// prepare authentication
|
||||
guard let activeMastodonAuthenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else {
|
||||
assertionFailure()
|
||||
return Fail(error: APIService.APIError.implicit(.authenticationMissing)).eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
if let cell = cell, let indexPath = indexPath {
|
||||
return _toggleUserBlockRelationship(
|
||||
context: provider.context,
|
||||
activeMastodonAuthenticationBox: activeMastodonAuthenticationBox,
|
||||
mastodonUser: provider.mastodonUser(for: cell, indexPath: indexPath).eraseToAnyPublisher()
|
||||
)
|
||||
} else {
|
||||
return _toggleUserBlockRelationship(
|
||||
context: provider.context,
|
||||
activeMastodonAuthenticationBox: activeMastodonAuthenticationBox,
|
||||
mastodonUser: provider.mastodonUser().eraseToAnyPublisher()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private static func _toggleUserBlockRelationship(
|
||||
context: AppContext,
|
||||
|
@ -97,20 +106,29 @@ extension UserProviderFacade {
|
|||
extension UserProviderFacade {
|
||||
|
||||
static func toggleUserMuteRelationship(
|
||||
provider: UserProvider
|
||||
provider: UserProvider,
|
||||
cell: UITableViewCell?,
|
||||
indexPath: IndexPath?
|
||||
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error> {
|
||||
// prepare authentication
|
||||
guard let activeMastodonAuthenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else {
|
||||
assertionFailure()
|
||||
return Fail(error: APIService.APIError.implicit(.authenticationMissing)).eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
if let cell = cell, let indexPath = indexPath {
|
||||
return _toggleUserMuteRelationship(
|
||||
context: provider.context,
|
||||
activeMastodonAuthenticationBox: activeMastodonAuthenticationBox,
|
||||
mastodonUser: provider.mastodonUser(for: cell, indexPath: indexPath).eraseToAnyPublisher()
|
||||
)
|
||||
} else {
|
||||
return _toggleUserMuteRelationship(
|
||||
context: provider.context,
|
||||
activeMastodonAuthenticationBox: activeMastodonAuthenticationBox,
|
||||
mastodonUser: provider.mastodonUser().eraseToAnyPublisher()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private static func _toggleUserMuteRelationship(
|
||||
context: AppContext,
|
||||
|
@ -140,10 +158,14 @@ extension UserProviderFacade {
|
|||
for mastodonUser: MastodonUser,
|
||||
isMuting: Bool,
|
||||
isBlocking: Bool,
|
||||
needsShareAction: Bool,
|
||||
canReport: Bool,
|
||||
provider: UserProvider,
|
||||
cell: UITableViewCell?,
|
||||
indexPath: IndexPath?,
|
||||
sourceView: UIView?,
|
||||
barButtonItem: UIBarButtonItem?
|
||||
barButtonItem: UIBarButtonItem?,
|
||||
shareUser: MastodonUser?,
|
||||
shareStatus: Status?
|
||||
) -> UIMenu {
|
||||
var children: [UIMenuElement] = []
|
||||
let name = mastodonUser.displayNameWithFallback
|
||||
|
@ -159,7 +181,9 @@ extension UserProviderFacade {
|
|||
guard let provider = provider else { return }
|
||||
|
||||
UserProviderFacade.toggleUserMuteRelationship(
|
||||
provider: provider
|
||||
provider: provider,
|
||||
cell: cell,
|
||||
indexPath: indexPath
|
||||
)
|
||||
.sink { _ in
|
||||
// do nothing
|
||||
|
@ -186,7 +210,9 @@ extension UserProviderFacade {
|
|||
guard let provider = provider else { return }
|
||||
|
||||
UserProviderFacade.toggleUserBlockRelationship(
|
||||
provider: provider
|
||||
provider: provider,
|
||||
cell: cell,
|
||||
indexPath: indexPath
|
||||
)
|
||||
.sink { _ in
|
||||
// do nothing
|
||||
|
@ -201,7 +227,7 @@ extension UserProviderFacade {
|
|||
let blockMenu = UIMenu(title: L10n.Common.Controls.Firendship.blockUser(name), image: UIImage(systemName: "hand.raised"), options: [], children: [blockAction])
|
||||
children.append(blockMenu)
|
||||
}
|
||||
|
||||
if canReport {
|
||||
let reportAction = UIAction(title: L10n.Common.Controls.Actions.reportUser(name), image: UIImage(systemName: "flag"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak provider] _ in
|
||||
guard let provider = provider else { return }
|
||||
guard let authenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else {
|
||||
|
@ -219,11 +245,12 @@ extension UserProviderFacade {
|
|||
)
|
||||
}
|
||||
children.append(reportAction)
|
||||
}
|
||||
|
||||
if needsShareAction {
|
||||
if let shareUser = shareUser {
|
||||
let shareAction = UIAction(title: L10n.Common.Controls.Actions.shareUser(name), image: UIImage(systemName: "square.and.arrow.up"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak provider] _ in
|
||||
guard let provider = provider else { return }
|
||||
let activityViewController = createActivityViewControllerForMastodonUser(mastodonUser: mastodonUser, dependency: provider)
|
||||
let activityViewController = createActivityViewControllerForMastodonUser(mastodonUser: shareUser, dependency: provider)
|
||||
provider.coordinator.present(
|
||||
scene: .activityViewController(
|
||||
activityViewController: activityViewController,
|
||||
|
|
|
@ -377,7 +377,18 @@ extension ProfileViewController {
|
|||
let isMuting = relationshipActionOptionSet.contains(.muting)
|
||||
let isBlocking = relationshipActionOptionSet.contains(.blocking)
|
||||
let needsShareAction = self.viewModel.isMeBarButtonItemsHidden.value
|
||||
self.moreMenuBarButtonItem.menu = UserProviderFacade.createProfileActionMenu(for: mastodonUser, isMuting: isMuting, isBlocking: isBlocking, needsShareAction: needsShareAction, provider: self, sourceView: nil, barButtonItem: self.moreMenuBarButtonItem)
|
||||
self.moreMenuBarButtonItem.menu = UserProviderFacade.createProfileActionMenu(
|
||||
for: mastodonUser,
|
||||
isMuting: isMuting,
|
||||
isBlocking: isBlocking,
|
||||
canReport: true,
|
||||
provider: self,
|
||||
cell: nil,
|
||||
indexPath: nil,
|
||||
sourceView: nil,
|
||||
barButtonItem: self.moreMenuBarButtonItem,
|
||||
shareUser: needsShareAction ? mastodonUser : nil,
|
||||
shareStatus: nil)
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
viewModel.isRelationshipActionButtonHidden
|
||||
|
@ -692,7 +703,7 @@ extension ProfileViewController: ProfileHeaderViewDelegate {
|
|||
)
|
||||
let unmuteAction = UIAlertAction(title: L10n.Common.Controls.Firendship.unmute, style: .default) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
UserProviderFacade.toggleUserMuteRelationship(provider: self)
|
||||
UserProviderFacade.toggleUserMuteRelationship(provider: self, cell: nil, indexPath: nil)
|
||||
.sink { _ in
|
||||
// do nothing
|
||||
} receiveValue: { _ in
|
||||
|
@ -714,7 +725,7 @@ extension ProfileViewController: ProfileHeaderViewDelegate {
|
|||
)
|
||||
let unblockAction = UIAlertAction(title: L10n.Common.Controls.Firendship.unblock, style: .default) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
UserProviderFacade.toggleUserBlockRelationship(provider: self)
|
||||
UserProviderFacade.toggleUserBlockRelationship(provider: self, cell: nil, indexPath: nil)
|
||||
.sink { _ in
|
||||
// do nothing
|
||||
} receiveValue: { _ in
|
||||
|
|
|
@ -54,7 +54,7 @@ extension SearchViewController: SearchRecommendAccountsCollectionViewCellDelegat
|
|||
)
|
||||
let unmuteAction = UIAlertAction(title: L10n.Common.Controls.Firendship.unmute, style: .default) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
UserProviderFacade.toggleUserMuteRelationship(provider: self)
|
||||
UserProviderFacade.toggleUserMuteRelationship(provider: self, cell: nil, indexPath: nil)
|
||||
.sink { _ in
|
||||
// do nothing
|
||||
} receiveValue: { _ in
|
||||
|
@ -76,7 +76,7 @@ extension SearchViewController: SearchRecommendAccountsCollectionViewCellDelegat
|
|||
)
|
||||
let unblockAction = UIAlertAction(title: L10n.Common.Controls.Firendship.unblock, style: .default) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
UserProviderFacade.toggleUserBlockRelationship(provider: self)
|
||||
UserProviderFacade.toggleUserBlockRelationship(provider: self, cell: nil, indexPath: nil)
|
||||
.sink { _ in
|
||||
// do nothing
|
||||
} receiveValue: { _ in
|
||||
|
|
Loading…
Reference in New Issue