From 5278002c1562cfc5b3596e7b4112c22ebbce2c0a Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Fri, 7 May 2021 16:08:07 +0800 Subject: [PATCH 1/4] feat: Add post delete action entry for user posts --- Localization/app.json | 7 ++- Mastodon.xcodeproj/project.pbxproj | 2 - .../xcshareddata/swiftpm/Package.resolved | 2 +- .../Diffiable/Section/StatusSection.swift | 1 - Mastodon/Extension/CoreDataStack/Status.swift | 2 +- Mastodon/Generated/Strings.swift | 8 +++ .../UserProvider/UserProviderFacade.swift | 29 ++++++++++ .../Resources/en.lproj/Localizable.strings | 3 + .../APIService/APIService+Status.swift | 55 +++++++++++++++++++ .../API/Mastodon+API+Statuses.swift | 52 +++++++++++++++++- .../Entity/Mastodon+Entity+Status.swift | 2 +- 11 files changed, 154 insertions(+), 9 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index fbc670da..be86eade 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -35,6 +35,10 @@ "save_photo_failure": { "title": "Save Photo Failure", "message": "Please enable photo libaray access permission to save photo." + }, + "delete_post": { + "message": "Are you sure you want to delete this post?", + "delete": "DELETE" } }, "controls": { @@ -67,7 +71,8 @@ "report_user": "Report %s", "block_domain": "Block %s", "unblock_domain": "Unblock %s", - "settings": "Settings" + "settings": "Settings", + "delete": "Delete" }, "status": { "user_reblogged": "%s reblogged", diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index ff407b6e..c778b8f9 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -935,7 +935,6 @@ DB98339B25C96DE600AD9700 /* APIService+Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Account.swift"; sourceTree = ""; }; DB9A485B2603010E008B817C /* PHPickerResultLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PHPickerResultLoader.swift; sourceTree = ""; }; DB9A486B26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AttachmentContainerView+EmptyStateView.swift"; sourceTree = ""; }; - DB9A488326034BD7008B817C /* APIService+Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Status.swift"; sourceTree = ""; }; DB9A488926034D40008B817C /* ComposeViewModel+PublishState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ComposeViewModel+PublishState.swift"; sourceTree = ""; }; DB9A488F26035963008B817C /* APIService+Media.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Media.swift"; sourceTree = ""; }; DB9A48952603685D008B817C /* MastodonAttachmentService+UploadState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonAttachmentService+UploadState.swift"; sourceTree = ""; }; @@ -1735,7 +1734,6 @@ DB71FD5125F8CCAA00512AE1 /* APIService+Status.swift */, DB938F1426241FDF00E5B6C1 /* APIService+Thread.swift */, DB49A62A25FF36C700B98345 /* APIService+CustomEmoji.swift */, - DB9A488326034BD7008B817C /* APIService+Status.swift */, 2D61254C262547C200299647 /* APIService+Notification.swift */, DB9A488F26035963008B817C /* APIService+Media.swift */, 2D34D9D026148D9E0081BFC0 /* APIService+Recommend.swift */, diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved index 3295adb4..18cf023e 100644 --- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -69,7 +69,7 @@ "repositoryURL": "https://github.com/onevcat/Kingfisher.git", "state": { "branch": null, - "revision": "bbc4bc4def7eb05a7ba8e1219f80ee9be327334e", + "revision": "15d199e84677303a7004ed2c5ecaa1a90f3863f8", "version": "6.2.1" } }, diff --git a/Mastodon/Diffiable/Section/StatusSection.swift b/Mastodon/Diffiable/Section/StatusSection.swift index 3994229e..af4b7049 100644 --- a/Mastodon/Diffiable/Section/StatusSection.swift +++ b/Mastodon/Diffiable/Section/StatusSection.swift @@ -781,7 +781,6 @@ extension StatusSection { } let author = status.authorForUserProvider let isMyself = authenticationBox.userID == author.id - let canReport = !isMyself let isInSameDomain = authenticationBox.domain == author.domainFromAcct let isMuting = (author.mutingBy ?? Set()).map(\.id).contains(authenticationBox.userID) let isBlocking = (author.blockingBy ?? Set()).map(\.id).contains(authenticationBox.userID) diff --git a/Mastodon/Extension/CoreDataStack/Status.swift b/Mastodon/Extension/CoreDataStack/Status.swift index 1a909285..73a58293 100644 --- a/Mastodon/Extension/CoreDataStack/Status.swift +++ b/Mastodon/Extension/CoreDataStack/Status.swift @@ -16,7 +16,7 @@ extension Status.Property { id: entity.id, uri: entity.uri, createdAt: entity.createdAt, - content: entity.content, + content: entity.content!, visibility: entity.visibility?.rawValue, sensitive: entity.sensitive ?? false, spoilerText: entity.spoilerText, diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index 4ec5e703..81b8f8cc 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -27,6 +27,12 @@ internal enum L10n { /// Please try again later. internal static let pleaseTryAgainLater = L10n.tr("Localizable", "Common.Alerts.Common.PleaseTryAgainLater") } + internal enum DeletePost { + /// DELETE + internal static let delete = L10n.tr("Localizable", "Common.Alerts.DeletePost.Delete") + /// Are you sure you want to delete this post? + internal static let message = L10n.tr("Localizable", "Common.Alerts.DeletePost.Message") + } internal enum DiscardPostContent { /// Confirm discard composed post content. internal static let message = L10n.tr("Localizable", "Common.Alerts.DiscardPostContent.Message") @@ -84,6 +90,8 @@ internal enum L10n { internal static let confirm = L10n.tr("Localizable", "Common.Controls.Actions.Confirm") /// Continue internal static let `continue` = L10n.tr("Localizable", "Common.Controls.Actions.Continue") + /// Delete + internal static let delete = L10n.tr("Localizable", "Common.Controls.Actions.Delete") /// Discard internal static let discard = L10n.tr("Localizable", "Common.Controls.Actions.Discard") /// Done diff --git a/Mastodon/Protocol/UserProvider/UserProviderFacade.swift b/Mastodon/Protocol/UserProvider/UserProviderFacade.swift index 9e20e414..089cf8ad 100644 --- a/Mastodon/Protocol/UserProvider/UserProviderFacade.swift +++ b/Mastodon/Protocol/UserProvider/UserProviderFacade.swift @@ -300,6 +300,35 @@ extension UserProviderFacade { children.append(shareAction) } + if let status = shareStatus, isMyself { + let deleteAction = UIAction(title: L10n.Common.Controls.Actions.delete, image: UIImage(systemName: "delete.left"), identifier: nil, discoverabilityTitle: nil, attributes: [.destructive], state: .off) { + [weak provider] _ in + guard let provider = provider else { return } + + let alertController = UIAlertController(title: "", message: L10n.Common.Alerts.DeletePost.message, preferredStyle: .alert) + let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .default) { _ in + } + alertController.addAction(cancelAction) + let deleteAction = UIAlertAction(title: L10n.Common.Alerts.DeletePost.delete, style: .destructive) { _ in + guard let activeMastodonAuthenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else { return } + provider.context.apiService.deleteStatus(domain: activeMastodonAuthenticationBox.domain, + statusID: status.id, + authorizationBox: activeMastodonAuthenticationBox + ) + .sink { _ in + // do nothing + } receiveValue: { _ in + // do nothing + } + .store(in: &provider.context.disposeBag) + } + alertController.addAction(deleteAction) + provider.present(alertController, animated: true, completion: nil) + + } + children.append(deleteAction) + } + return UIMenu(title: "", options: [], children: children) } diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index 59f83a5c..7fc28ca8 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -2,6 +2,8 @@ "Common.Alerts.BlockDomain.Message" = "Are you really, really sure you want to block the entire %@? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed."; "Common.Alerts.Common.PleaseTryAgain" = "Please try again."; "Common.Alerts.Common.PleaseTryAgainLater" = "Please try again later."; +"Common.Alerts.DeletePost.Delete" = "DELETE"; +"Common.Alerts.DeletePost.Message" = "Are you sure you want to delete this post?"; "Common.Alerts.DiscardPostContent.Message" = "Confirm discard composed post content."; "Common.Alerts.DiscardPostContent.Title" = "Discard Publish"; "Common.Alerts.PublishPostFailure.Message" = "Failed to publish the post. @@ -22,6 +24,7 @@ Please check your internet connection."; "Common.Controls.Actions.Cancel" = "Cancel"; "Common.Controls.Actions.Confirm" = "Confirm"; "Common.Controls.Actions.Continue" = "Continue"; +"Common.Controls.Actions.Delete" = "Delete"; "Common.Controls.Actions.Discard" = "Discard"; "Common.Controls.Actions.Done" = "Done"; "Common.Controls.Actions.Edit" = "Edit"; diff --git a/Mastodon/Service/APIService/APIService+Status.swift b/Mastodon/Service/APIService/APIService+Status.swift index 08806c88..2b91bbd3 100644 --- a/Mastodon/Service/APIService/APIService+Status.swift +++ b/Mastodon/Service/APIService/APIService+Status.swift @@ -88,4 +88,59 @@ extension APIService { .eraseToAnyPublisher() } + func deleteStatus( + domain: String, + statusID: Mastodon.Entity.Status.ID, + authorizationBox: AuthenticationService.MastodonAuthenticationBox + ) -> AnyPublisher, Error> { + let authorization = authorizationBox.userAuthorization + let query = Mastodon.API.Statuses.DeleteStatusQuery(id: statusID) + return Mastodon.API.Statuses.deleteStatus( + session: session, + domain: domain, + query: query, + authorization: authorization + ) + .flatMap { response -> AnyPublisher, Error> in + return self.backgroundManagedObjectContext.performChanges{ + // fetch old Status + let oldStatus: Status? = { + let request = Status.sortedFetchRequest + request.predicate = Status.predicate(domain: domain, id: response.value.id) + request.fetchLimit = 1 + request.returnsObjectsAsFaults = false + do { + return try self.backgroundManagedObjectContext.fetch(request).first + } catch { + assertionFailure(error.localizedDescription) + return nil + } + }() + if let status = oldStatus { + if let timelineIndex = status.homeTimelineIndexes?.filter({ $0.userID == status.author.id }).first { + self.backgroundManagedObjectContext.delete(timelineIndex) + } + if let poll = status.poll { + self.backgroundManagedObjectContext.delete(poll) + } + if let pollOptions = status.poll?.options { + pollOptions.forEach({ self.backgroundManagedObjectContext.delete($0) }) + } + self.backgroundManagedObjectContext.delete(status) + } + } + .setFailureType(to: Error.self) + .tryMap { result -> Mastodon.Response.Content in + switch result { + case .success: + return response + case .failure(let error): + throw error + } + } + .eraseToAnyPublisher() + } + .eraseToAnyPublisher() + } + } diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses.swift index bb5a4abf..e6c8b19d 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses.swift @@ -10,7 +10,7 @@ import Combine extension Mastodon.API.Statuses { - static func viewStatusEndpointURL(domain: String, statusID: Mastodon.Entity.Status.ID) -> URL { + static func statusEndpointURL(domain: String, statusID: Mastodon.Entity.Status.ID) -> URL { let pathComponent = "statuses/" + statusID return Mastodon.API.endpointURL(domain: domain).appendingPathComponent(pathComponent) } @@ -38,7 +38,7 @@ extension Mastodon.API.Statuses { authorization: Mastodon.API.OAuth.Authorization? ) -> AnyPublisher, Error> { let request = Mastodon.API.get( - url: viewStatusEndpointURL(domain: domain, statusID: statusID), + url: statusEndpointURL(domain: domain, statusID: statusID), query: nil, authorization: authorization ) @@ -150,6 +150,54 @@ extension Mastodon.API.Statuses { } +extension Mastodon.API.Statuses { + + /// Delete status + /// + /// Delete one of your own statuses. + /// + /// - Since: 0.0.0 + /// - Version: 3.3.0 + /// # Last Update + /// 2021/5/7 + /// # Reference + /// [Document](https://docs.joinmastodon.org/methods/statuses/) + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - query: `DeleteStatusQuery` + /// - authorization: User token + /// - Returns: `AnyPublisher` contains `Status` nested in the response + public static func deleteStatus( + session: URLSession, + domain: String, + query: DeleteStatusQuery, + authorization: Mastodon.API.OAuth.Authorization? + ) -> AnyPublisher, Error> { + let request = Mastodon.API.delete( + url: statusEndpointURL(domain: domain, statusID: query.id), + query: query, + authorization: authorization + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: Mastodon.Entity.Status.self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } + + public struct DeleteStatusQuery: Codable, DeleteQuery { + public let id: Mastodon.Entity.Status.ID + + public init( + id: Mastodon.Entity.Status.ID + ) { + self.id = id + } + } +} + extension Mastodon.API.Statuses { static func statusContextEndpointURL(domain: String, statusID: Mastodon.Entity.Status.ID) -> URL { diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Status.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Status.swift index 490429fc..7f8a4fd4 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Status.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Status.swift @@ -26,7 +26,7 @@ extension Mastodon.Entity { public let uri: String public let createdAt: Date public let account: Account - public let content: String + public let content: String? // will be optional when delete status public let visibility: Visibility? public let sensitive: Bool? From d3256f31713f29584393e1ec103500232a249363 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Fri, 7 May 2021 20:36:31 +0800 Subject: [PATCH 2/4] fix: delete reblogFrom inNotifications poll pollOption when delete status --- .../CoreData.xcdatamodel/contents | 11 ++++++----- CoreDataStack/Entity/Status.swift | 2 ++ Localization/app.json | 2 +- Mastodon/Generated/Strings.swift | 2 +- Mastodon/Resources/en.lproj/Localizable.strings | 2 +- Mastodon/Service/APIService/APIService+Status.swift | 9 --------- 6 files changed, 11 insertions(+), 17 deletions(-) diff --git a/CoreDataStack/CoreData.xcdatamodeld/CoreData.xcdatamodel/contents b/CoreDataStack/CoreData.xcdatamodeld/CoreData.xcdatamodel/contents index 93d6e473..9073b3fb 100644 --- a/CoreDataStack/CoreData.xcdatamodeld/CoreData.xcdatamodel/contents +++ b/CoreDataStack/CoreData.xcdatamodeld/CoreData.xcdatamodel/contents @@ -87,7 +87,7 @@ - + @@ -158,7 +158,7 @@ - + @@ -218,14 +218,15 @@ - + + - + @@ -279,7 +280,7 @@ - + diff --git a/CoreDataStack/Entity/Status.swift b/CoreDataStack/Entity/Status.swift index 1bb71a1d..cd1ebf3f 100644 --- a/CoreDataStack/Entity/Status.swift +++ b/CoreDataStack/Entity/Status.swift @@ -60,6 +60,8 @@ public final class Status: NSManagedObject { @NSManaged public private(set) var mediaAttachments: Set? @NSManaged public private(set) var replyFrom: Set? + @NSManaged public private(set) var inNotifications: Set? + @NSManaged public private(set) var updatedAt: Date @NSManaged public private(set) var deletedAt: Date? @NSManaged public private(set) var revealedAt: Date? diff --git a/Localization/app.json b/Localization/app.json index be86eade..1776c2c0 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -38,7 +38,7 @@ }, "delete_post": { "message": "Are you sure you want to delete this post?", - "delete": "DELETE" + "delete": "Delete" } }, "controls": { diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index 81b8f8cc..092aa5c4 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -28,7 +28,7 @@ internal enum L10n { internal static let pleaseTryAgainLater = L10n.tr("Localizable", "Common.Alerts.Common.PleaseTryAgainLater") } internal enum DeletePost { - /// DELETE + /// Delete internal static let delete = L10n.tr("Localizable", "Common.Alerts.DeletePost.Delete") /// Are you sure you want to delete this post? internal static let message = L10n.tr("Localizable", "Common.Alerts.DeletePost.Message") diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index 7fc28ca8..d88b00e9 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -2,7 +2,7 @@ "Common.Alerts.BlockDomain.Message" = "Are you really, really sure you want to block the entire %@? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed."; "Common.Alerts.Common.PleaseTryAgain" = "Please try again."; "Common.Alerts.Common.PleaseTryAgainLater" = "Please try again later."; -"Common.Alerts.DeletePost.Delete" = "DELETE"; +"Common.Alerts.DeletePost.Delete" = "Delete"; "Common.Alerts.DeletePost.Message" = "Are you sure you want to delete this post?"; "Common.Alerts.DiscardPostContent.Message" = "Confirm discard composed post content."; "Common.Alerts.DiscardPostContent.Title" = "Discard Publish"; diff --git a/Mastodon/Service/APIService/APIService+Status.swift b/Mastodon/Service/APIService/APIService+Status.swift index 2b91bbd3..c927b05a 100644 --- a/Mastodon/Service/APIService/APIService+Status.swift +++ b/Mastodon/Service/APIService/APIService+Status.swift @@ -117,15 +117,6 @@ extension APIService { } }() if let status = oldStatus { - if let timelineIndex = status.homeTimelineIndexes?.filter({ $0.userID == status.author.id }).first { - self.backgroundManagedObjectContext.delete(timelineIndex) - } - if let poll = status.poll { - self.backgroundManagedObjectContext.delete(poll) - } - if let pollOptions = status.poll?.options { - pollOptions.forEach({ self.backgroundManagedObjectContext.delete($0) }) - } self.backgroundManagedObjectContext.delete(status) } } From 04eeb0100e6ec4f61b07b2a7e95969cfefc09729 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Sat, 8 May 2021 10:38:55 +0800 Subject: [PATCH 3/4] fix: safely cancel the listenser for status --- Mastodon/Diffiable/Section/StatusSection.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Mastodon/Diffiable/Section/StatusSection.swift b/Mastodon/Diffiable/Section/StatusSection.swift index af4b7049..76bc9159 100644 --- a/Mastodon/Diffiable/Section/StatusSection.swift +++ b/Mastodon/Diffiable/Section/StatusSection.swift @@ -143,6 +143,21 @@ extension StatusSection { requestUserID: String, statusItemAttribute: Item.StatusAttribute ) { + // safely cancel the listenser when deleted + ManagedObjectObserver.observe(object: status.reblog ?? status) + .receive(on: DispatchQueue.main) + .sink { _ in + // do nothing + } receiveValue: { [weak cell] change in + guard let cell = cell else { return } + guard let changeType = change.changeType else { return } + if case .delete = changeType { + cell.disposeBag.removeAll() + } + } + .store(in: &cell.disposeBag) + + // set header StatusSection.configureHeader(cell: cell, status: status) ManagedObjectObserver.observe(object: status) From 505c251b37284a8c5b8af9ef7c2a9a1207f34126 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Mon, 10 May 2021 15:40:46 +0800 Subject: [PATCH 4/4] fix: move message to title --- Localization/app.json | 4 ++-- Mastodon/Generated/Strings.swift | 6 +++--- Mastodon/Protocol/UserProvider/UserProviderFacade.swift | 4 ++-- Mastodon/Resources/en.lproj/Localizable.strings | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index 1776c2c0..ab888f8f 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -29,7 +29,7 @@ "confirm": "Sign Out" }, "block_domain": { - "message": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", + "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", "block_entire_domain": "Block entire domain" }, "save_photo_failure": { @@ -37,7 +37,7 @@ "message": "Please enable photo libaray access permission to save photo." }, "delete_post": { - "message": "Are you sure you want to delete this post?", + "title": "Are you sure you want to delete this post?", "delete": "Delete" } }, diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index 092aa5c4..6e8c8e39 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -17,8 +17,8 @@ internal enum L10n { /// Block entire domain internal static let blockEntireDomain = L10n.tr("Localizable", "Common.Alerts.BlockDomain.BlockEntireDomain") /// Are you really, really sure you want to block the entire %@? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed. - internal static func message(_ p1: Any) -> String { - return L10n.tr("Localizable", "Common.Alerts.BlockDomain.Message", String(describing: p1)) + internal static func title(_ p1: Any) -> String { + return L10n.tr("Localizable", "Common.Alerts.BlockDomain.Title", String(describing: p1)) } } internal enum Common { @@ -31,7 +31,7 @@ internal enum L10n { /// Delete internal static let delete = L10n.tr("Localizable", "Common.Alerts.DeletePost.Delete") /// Are you sure you want to delete this post? - internal static let message = L10n.tr("Localizable", "Common.Alerts.DeletePost.Message") + internal static let title = L10n.tr("Localizable", "Common.Alerts.DeletePost.Title") } internal enum DiscardPostContent { /// Confirm discard composed post content. diff --git a/Mastodon/Protocol/UserProvider/UserProviderFacade.swift b/Mastodon/Protocol/UserProvider/UserProviderFacade.swift index 089cf8ad..1f9215a7 100644 --- a/Mastodon/Protocol/UserProvider/UserProviderFacade.swift +++ b/Mastodon/Protocol/UserProvider/UserProviderFacade.swift @@ -252,7 +252,7 @@ extension UserProviderFacade { } else { let blockDomainAction = UIAction(title: L10n.Common.Controls.Actions.blockDomain(mastodonUser.domainFromAcct), image: UIImage(systemName: "nosign"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak provider] _ in guard let provider = provider else { return } - let alertController = UIAlertController(title: "", message: L10n.Common.Alerts.BlockDomain.message(mastodonUser.domainFromAcct), preferredStyle: .alert) + let alertController = UIAlertController(title: L10n.Common.Alerts.BlockDomain.title(mastodonUser.domainFromAcct), message: nil, preferredStyle: .alert) let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .default) { _ in } alertController.addAction(cancelAction) @@ -305,7 +305,7 @@ extension UserProviderFacade { [weak provider] _ in guard let provider = provider else { return } - let alertController = UIAlertController(title: "", message: L10n.Common.Alerts.DeletePost.message, preferredStyle: .alert) + let alertController = UIAlertController(title: L10n.Common.Alerts.DeletePost.title, message: nil, preferredStyle: .alert) let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .default) { _ in } alertController.addAction(cancelAction) diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index d88b00e9..7b11194a 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -1,9 +1,9 @@ "Common.Alerts.BlockDomain.BlockEntireDomain" = "Block entire domain"; -"Common.Alerts.BlockDomain.Message" = "Are you really, really sure you want to block the entire %@? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed."; +"Common.Alerts.BlockDomain.Title" = "Are you really, really sure you want to block the entire %@? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed."; "Common.Alerts.Common.PleaseTryAgain" = "Please try again."; "Common.Alerts.Common.PleaseTryAgainLater" = "Please try again later."; "Common.Alerts.DeletePost.Delete" = "Delete"; -"Common.Alerts.DeletePost.Message" = "Are you sure you want to delete this post?"; +"Common.Alerts.DeletePost.Title" = "Are you sure you want to delete this post?"; "Common.Alerts.DiscardPostContent.Message" = "Confirm discard composed post content."; "Common.Alerts.DiscardPostContent.Title" = "Discard Publish"; "Common.Alerts.PublishPostFailure.Message" = "Failed to publish the post.