fix: add entries for the reporting
This commit is contained in:
parent
1b05d787df
commit
ad8df6813f
|
@ -52,7 +52,8 @@
|
||||||
"share": "Share",
|
"share": "Share",
|
||||||
"share_user": "Share %s",
|
"share_user": "Share %s",
|
||||||
"open_in_safari": "Open in Safari",
|
"open_in_safari": "Open in Safari",
|
||||||
"skip": "Skip"
|
"skip": "Skip",
|
||||||
|
"report_user": "Report %s"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"user_reblogged": "%s reblogged",
|
"user_reblogged": "%s reblogged",
|
||||||
|
|
|
@ -301,6 +301,9 @@ extension StatusSection {
|
||||||
case is NotificationStatusTableViewCell:
|
case is NotificationStatusTableViewCell:
|
||||||
let notificationTableViewCell = cell as! NotificationStatusTableViewCell
|
let notificationTableViewCell = cell as! NotificationStatusTableViewCell
|
||||||
parent = notificationTableViewCell.delegate?.parent()
|
parent = notificationTableViewCell.delegate?.parent()
|
||||||
|
case is ReportedStatusTableViewCell:
|
||||||
|
let reportTableViewCell = cell as! ReportedStatusTableViewCell
|
||||||
|
parent = reportTableViewCell.dependency
|
||||||
default:
|
default:
|
||||||
parent = nil
|
parent = nil
|
||||||
assertionFailure("unknown cell")
|
assertionFailure("unknown cell")
|
||||||
|
@ -394,7 +397,12 @@ extension StatusSection {
|
||||||
}
|
}
|
||||||
|
|
||||||
// toolbar
|
// toolbar
|
||||||
StatusSection.configureActionToolBar(cell: cell, status: status, requestUserID: requestUserID)
|
StatusSection.configureActionToolBar(
|
||||||
|
cell: cell,
|
||||||
|
dependency: dependency,
|
||||||
|
status: status,
|
||||||
|
requestUserID: requestUserID
|
||||||
|
)
|
||||||
|
|
||||||
// separator line
|
// separator line
|
||||||
if let statusTableViewCell = cell as? StatusTableViewCell {
|
if let statusTableViewCell = cell as? StatusTableViewCell {
|
||||||
|
@ -418,7 +426,12 @@ extension StatusSection {
|
||||||
} receiveValue: { change in
|
} receiveValue: { change in
|
||||||
guard case .update(let object) = change.changeType,
|
guard case .update(let object) = change.changeType,
|
||||||
let status = object as? Status else { return }
|
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: 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)
|
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(
|
static func configureActionToolBar(
|
||||||
cell: StatusCell,
|
cell: StatusCell,
|
||||||
|
dependency: NeedsDependency,
|
||||||
status: Status,
|
status: Status,
|
||||||
requestUserID: String
|
requestUserID: String
|
||||||
) {
|
) {
|
||||||
|
@ -600,6 +614,8 @@ extension StatusSection {
|
||||||
}()
|
}()
|
||||||
cell.statusView.actionToolbarContainer.favoriteButton.setTitle(favoriteCountTitle, for: .normal)
|
cell.statusView.actionToolbarContainer.favoriteButton.setTitle(favoriteCountTitle, for: .normal)
|
||||||
cell.statusView.actionToolbarContainer.isFavoriteButtonHighlight = isLike
|
cell.statusView.actionToolbarContainer.isFavoriteButtonHighlight = isLike
|
||||||
|
|
||||||
|
self.setupStatusMoreButtonMenu(cell: cell, dependency: dependency, status: status)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func configurePoll(
|
static func configurePoll(
|
||||||
|
@ -726,4 +742,37 @@ extension StatusSection {
|
||||||
guard let number = number, number > 0 else { return "" }
|
guard let number = number, number > 0 else { return "" }
|
||||||
return String(number)
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,10 @@ internal enum L10n {
|
||||||
internal static let preview = L10n.tr("Localizable", "Common.Controls.Actions.Preview")
|
internal static let preview = L10n.tr("Localizable", "Common.Controls.Actions.Preview")
|
||||||
/// Remove
|
/// Remove
|
||||||
internal static let remove = L10n.tr("Localizable", "Common.Controls.Actions.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
|
/// Save
|
||||||
internal static let save = L10n.tr("Localizable", "Common.Controls.Actions.Save")
|
internal static let save = L10n.tr("Localizable", "Common.Controls.Actions.Save")
|
||||||
/// Save photo
|
/// Save photo
|
||||||
|
|
|
@ -218,6 +218,24 @@ extension UserProviderFacade {
|
||||||
children.append(shareAction)
|
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)
|
return UIMenu(title: "", options: [], children: children)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ Please check your internet connection.";
|
||||||
"Common.Controls.Actions.OpenInSafari" = "Open in Safari";
|
"Common.Controls.Actions.OpenInSafari" = "Open in Safari";
|
||||||
"Common.Controls.Actions.Preview" = "Preview";
|
"Common.Controls.Actions.Preview" = "Preview";
|
||||||
"Common.Controls.Actions.Remove" = "Remove";
|
"Common.Controls.Actions.Remove" = "Remove";
|
||||||
|
"Common.Controls.Actions.ReportUser" = "Report %@";
|
||||||
"Common.Controls.Actions.Save" = "Save";
|
"Common.Controls.Actions.Save" = "Save";
|
||||||
"Common.Controls.Actions.SavePhoto" = "Save photo";
|
"Common.Controls.Actions.SavePhoto" = "Save photo";
|
||||||
"Common.Controls.Actions.SeeMore" = "See More";
|
"Common.Controls.Actions.SeeMore" = "See More";
|
||||||
|
|
|
@ -41,10 +41,6 @@ extension HomeTimelineViewController {
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
self.showSettings(action)
|
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
|
UIAction(title: "Sign Out", image: UIImage(systemName: "escape"), attributes: .destructive) { [weak self] action in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
self.signOutAction(action)
|
self.signOutAction(action)
|
||||||
|
@ -339,42 +335,5 @@ extension HomeTimelineViewController {
|
||||||
transition: .modal(animated: true, completion: nil)
|
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
|
#endif
|
||||||
|
|
|
@ -242,7 +242,7 @@ class ReportViewController: UIViewController, NeedsDependency {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let request = MastodonUser.sortedFetchRequest
|
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.fetchLimit = 1
|
||||||
request.returnsObjectsAsFaults = false
|
request.returnsObjectsAsFaults = false
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -22,6 +22,7 @@ extension ReportViewModel {
|
||||||
context.apiService.userTimeline(
|
context.apiService.userTimeline(
|
||||||
domain: domain,
|
domain: domain,
|
||||||
accountID: accountId,
|
accountID: accountId,
|
||||||
|
excludeReblogs: true,
|
||||||
authorizationBox: authorizationBox
|
authorizationBox: authorizationBox
|
||||||
)
|
)
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
|
@ -30,7 +31,7 @@ extension ReportViewModel {
|
||||||
case .failure(let error):
|
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)
|
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 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
|
var statusIDs = self.statusFetchedResultsController.statusIDs.value
|
||||||
guard statusIDs.contains(reportStatusId) else { return }
|
guard statusIDs.contains(reportStatusId) else { return }
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ extension ReportViewModel {
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
var statusIDs = response.value.map { $0.id }
|
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)
|
statusIDs.append(reportStatusId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +87,7 @@ extension ReportViewModel {
|
||||||
guard let status = managedObjectContext.object(with: objectID) as? Status else {
|
guard let status = managedObjectContext.object(with: objectID) as? Status else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if status.id == self.statusId {
|
if status.id == self.status?.id {
|
||||||
attribute.isSelected = true
|
attribute.isSelected = true
|
||||||
self.append(statusID: status.id)
|
self.append(statusID: status.id)
|
||||||
self.continueEnableSubject.send(true)
|
self.continueEnableSubject.send(true)
|
||||||
|
|
|
@ -23,8 +23,8 @@ class ReportViewModel: NSObject {
|
||||||
|
|
||||||
// confirm set only once
|
// confirm set only once
|
||||||
weak var context: AppContext! { willSet { precondition(context == nil) } }
|
weak var context: AppContext! { willSet { precondition(context == nil) } }
|
||||||
var userId: String
|
var user: MastodonUser
|
||||||
var statusId: String?
|
var status: Status?
|
||||||
|
|
||||||
var statusIDs = [Mastodon.Entity.Status.ID]()
|
var statusIDs = [Mastodon.Entity.Status.ID]()
|
||||||
var comment: String?
|
var comment: String?
|
||||||
|
@ -56,12 +56,12 @@ class ReportViewModel: NSObject {
|
||||||
|
|
||||||
init(context: AppContext,
|
init(context: AppContext,
|
||||||
domain: String,
|
domain: String,
|
||||||
userId: String,
|
user: MastodonUser,
|
||||||
statusId: String?
|
status: Status?
|
||||||
) {
|
) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.userId = userId
|
self.user = user
|
||||||
self.statusId = statusId
|
self.status = status
|
||||||
self.statusFetchedResultsController = StatusFetchedResultsController(
|
self.statusFetchedResultsController = StatusFetchedResultsController(
|
||||||
managedObjectContext: context.managedObjectContext,
|
managedObjectContext: context.managedObjectContext,
|
||||||
domain: domain,
|
domain: domain,
|
||||||
|
@ -69,7 +69,7 @@ class ReportViewModel: NSObject {
|
||||||
)
|
)
|
||||||
|
|
||||||
self.reportQuery = FileReportQuery(
|
self.reportQuery = FileReportQuery(
|
||||||
accountID: userId,
|
accountID: user.id,
|
||||||
statusIDs: [],
|
statusIDs: [],
|
||||||
comment: nil,
|
comment: nil,
|
||||||
forward: nil
|
forward: nil
|
||||||
|
@ -97,7 +97,7 @@ class ReportViewModel: NSObject {
|
||||||
|
|
||||||
requestRecentStatus(
|
requestRecentStatus(
|
||||||
domain: domain,
|
domain: domain,
|
||||||
accountId: self.userId,
|
accountId: self.user.id,
|
||||||
authorizationBox: activeMastodonAuthenticationBox
|
authorizationBox: activeMastodonAuthenticationBox
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue