fix: add entries for the reporting

This commit is contained in:
ihugo 2021-04-26 15:58:49 +08:00
parent 1b05d787df
commit ad8df6813f
9 changed files with 89 additions and 56 deletions

View File

@ -52,7 +52,8 @@
"share": "Share",
"share_user": "Share %s",
"open_in_safari": "Open in Safari",
"skip": "Skip"
"skip": "Skip",
"report_user": "Report %s"
},
"status": {
"user_reblogged": "%s reblogged",

View File

@ -301,6 +301,9 @@ extension StatusSection {
case is NotificationStatusTableViewCell:
let notificationTableViewCell = cell as! NotificationStatusTableViewCell
parent = notificationTableViewCell.delegate?.parent()
case is ReportedStatusTableViewCell:
let reportTableViewCell = cell as! ReportedStatusTableViewCell
parent = reportTableViewCell.dependency
default:
parent = nil
assertionFailure("unknown cell")
@ -394,7 +397,12 @@ extension StatusSection {
}
// toolbar
StatusSection.configureActionToolBar(cell: cell, status: status, requestUserID: requestUserID)
StatusSection.configureActionToolBar(
cell: cell,
dependency: dependency,
status: status,
requestUserID: requestUserID
)
// separator line
if let statusTableViewCell = cell as? StatusTableViewCell {
@ -418,7 +426,12 @@ extension StatusSection {
} receiveValue: { change in
guard case .update(let object) = change.changeType,
let status = object as? Status else { return }
StatusSection.configureActionToolBar(cell: cell, status: status, requestUserID: requestUserID)
StatusSection.configureActionToolBar(
cell: cell,
dependency: dependency,
status: status,
requestUserID: requestUserID
)
os_log("%{public}s[%{public}ld], %{public}s: reblog count label for status %s did update: %ld", (#file as NSString).lastPathComponent, #line, #function, status.id, status.reblogsCount.intValue)
os_log("%{public}s[%{public}ld], %{public}s: like count label for status %s did update: %ld", (#file as NSString).lastPathComponent, #line, #function, status.id, status.favouritesCount.intValue)
@ -573,6 +586,7 @@ extension StatusSection {
static func configureActionToolBar(
cell: StatusCell,
dependency: NeedsDependency,
status: Status,
requestUserID: String
) {
@ -600,6 +614,8 @@ extension StatusSection {
}()
cell.statusView.actionToolbarContainer.favoriteButton.setTitle(favoriteCountTitle, for: .normal)
cell.statusView.actionToolbarContainer.isFavoriteButtonHighlight = isLike
self.setupStatusMoreButtonMenu(cell: cell, dependency: dependency, status: status)
}
static func configurePoll(
@ -726,4 +742,37 @@ extension StatusSection {
guard let number = number, number > 0 else { return "" }
return String(number)
}
private static func setupStatusMoreButtonMenu(
cell: StatusCell,
dependency: NeedsDependency,
status: Status) {
cell.statusView.actionToolbarContainer.moreButton.menu = nil
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) { _ in
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)
)
}
children.append(reportAction)
cell.statusView.actionToolbarContainer.moreButton.menu = UIMenu(title: "", options: [], children: children)
cell.statusView.actionToolbarContainer.moreButton.showsMenuAsPrimaryAction = true
}
}

View File

@ -80,6 +80,10 @@ internal enum L10n {
internal static let preview = L10n.tr("Localizable", "Common.Controls.Actions.Preview")
/// Remove
internal static let remove = L10n.tr("Localizable", "Common.Controls.Actions.Remove")
/// Report %@
internal static func reportUser(_ p1: Any) -> String {
return L10n.tr("Localizable", "Common.Controls.Actions.ReportUser", String(describing: p1))
}
/// Save
internal static let save = L10n.tr("Localizable", "Common.Controls.Actions.Save")
/// Save photo

View File

@ -218,6 +218,24 @@ extension UserProviderFacade {
children.append(shareAction)
}
let reportAction = UIAction(title: L10n.Common.Controls.Actions.reportUser(name), image: UIImage(systemName: "exclamationmark.bubble"), 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 {
return
}
let viewModel = ReportViewModel(
context: provider.context,
domain: authenticationBox.domain,
user: mastodonUser,
status: nil)
provider.coordinator.present(
scene: .report(viewModel: viewModel),
from: provider,
transition: .modal(animated: true, completion: nil)
)
}
children.append(reportAction)
return UIMenu(title: "", options: [], children: children)
}

View File

@ -24,6 +24,7 @@ Please check your internet connection.";
"Common.Controls.Actions.OpenInSafari" = "Open in Safari";
"Common.Controls.Actions.Preview" = "Preview";
"Common.Controls.Actions.Remove" = "Remove";
"Common.Controls.Actions.ReportUser" = "Report %@";
"Common.Controls.Actions.Save" = "Save";
"Common.Controls.Actions.SavePhoto" = "Save photo";
"Common.Controls.Actions.SeeMore" = "See More";

View File

@ -41,10 +41,6 @@ extension HomeTimelineViewController {
guard let self = self else { return }
self.showSettings(action)
},
UIAction(title: "Report", image: UIImage(systemName: "exclamationmark.bubble"), attributes: []) { [weak self] action in
guard let self = self else { return }
self.showReportAction(action)
},
UIAction(title: "Sign Out", image: UIImage(systemName: "escape"), attributes: .destructive) { [weak self] action in
guard let self = self else { return }
self.signOutAction(action)
@ -339,42 +335,5 @@ extension HomeTimelineViewController {
transition: .modal(animated: true, completion: nil)
)
}
@objc private func showReportAction(_ sender: UIAction) {
let alertController = UIAlertController(title: "Enter User ID", message: nil, preferredStyle: .alert)
alertController.addTextField()
alertController.addTextField()
guard let accountTextField = alertController.textFields?.first else { return }
guard let statusTextField = alertController.textFields?.last else { return }
accountTextField.placeholder = "User ID"
statusTextField.placeholder = "Status ID"
accountTextField.text = "212477"
statusTextField.text = "106103767536113615"
let showAction = UIAlertAction(title: "Show", style: .default) { [weak self] _ in
guard let self = self else { return }
guard let userId = accountTextField.text else { return }
guard let statusId = statusTextField.text else { return }
guard let authenticationBox = self.context.authenticationService.activeMastodonAuthenticationBox.value else { return }
// itodo: delete them
// 31803
// 106093402888557459
let viewModel = ReportViewModel(
context: self.context,
domain: authenticationBox.domain,
userId: userId,
statusId: statusId
)
self.coordinator.present(
scene: .report(viewModel: viewModel),
from: self, transition: .modal(animated: true, completion: nil))
}
alertController.addAction(showAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil))
}
}
#endif

View File

@ -242,7 +242,7 @@ class ReportViewController: UIViewController, NeedsDependency {
return nil
}
let request = MastodonUser.sortedFetchRequest
request.predicate = MastodonUser.predicate(domain: domain, id: viewModel.userId)
request.predicate = MastodonUser.predicate(domain: domain, id: viewModel.user.id)
request.fetchLimit = 1
request.returnsObjectsAsFaults = false
do {

View File

@ -22,6 +22,7 @@ extension ReportViewModel {
context.apiService.userTimeline(
domain: domain,
accountID: accountId,
excludeReblogs: true,
authorizationBox: authorizationBox
)
.receive(on: DispatchQueue.main)
@ -30,7 +31,7 @@ extension ReportViewModel {
case .failure(let error):
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: fetch user timeline fail: %s", ((#file as NSString).lastPathComponent), #line, #function, error.localizedDescription)
guard let self = self else { return }
guard let reportStatusId = self.statusId else { return }
guard let reportStatusId = self.status?.id else { return }
var statusIDs = self.statusFetchedResultsController.statusIDs.value
guard statusIDs.contains(reportStatusId) else { return }
@ -44,7 +45,7 @@ extension ReportViewModel {
guard let self = self else { return }
var statusIDs = response.value.map { $0.id }
if let reportStatusId = self.statusId, !statusIDs.contains(reportStatusId) {
if let reportStatusId = self.status?.id, !statusIDs.contains(reportStatusId) {
statusIDs.append(reportStatusId)
}
@ -86,7 +87,7 @@ extension ReportViewModel {
guard let status = managedObjectContext.object(with: objectID) as? Status else {
continue
}
if status.id == self.statusId {
if status.id == self.status?.id {
attribute.isSelected = true
self.append(statusID: status.id)
self.continueEnableSubject.send(true)

View File

@ -23,8 +23,8 @@ class ReportViewModel: NSObject {
// confirm set only once
weak var context: AppContext! { willSet { precondition(context == nil) } }
var userId: String
var statusId: String?
var user: MastodonUser
var status: Status?
var statusIDs = [Mastodon.Entity.Status.ID]()
var comment: String?
@ -56,12 +56,12 @@ class ReportViewModel: NSObject {
init(context: AppContext,
domain: String,
userId: String,
statusId: String?
user: MastodonUser,
status: Status?
) {
self.context = context
self.userId = userId
self.statusId = statusId
self.user = user
self.status = status
self.statusFetchedResultsController = StatusFetchedResultsController(
managedObjectContext: context.managedObjectContext,
domain: domain,
@ -69,7 +69,7 @@ class ReportViewModel: NSObject {
)
self.reportQuery = FileReportQuery(
accountID: userId,
accountID: user.id,
statusIDs: [],
comment: nil,
forward: nil
@ -97,7 +97,7 @@ class ReportViewModel: NSObject {
requestRecentStatus(
domain: domain,
accountId: self.userId,
accountId: self.user.id,
authorizationBox: activeMastodonAuthenticationBox
)