mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-25 09:41:00 +00:00
Account for missing i18n in Mastodon notifications
This commit is contained in:
parent
f0eeb558a5
commit
2f0e35f343
4 changed files with 97 additions and 25 deletions
|
@ -163,6 +163,10 @@
|
|||
"metatext" = "Metatext";
|
||||
"notification.signed-in-as-%@" = "Logged in as %@";
|
||||
"notification.new-items" = "New notifications";
|
||||
"notification.poll" = "A poll you have voted in has ended";
|
||||
"notification.poll.own" = "Your poll has ended";
|
||||
"notification.poll.unknown" = "A poll has ended";
|
||||
"notification.status-%@" = "%@ just posted";
|
||||
"notifications.all" = "All";
|
||||
"notifications.mentions" = "Mentions";
|
||||
"ok" = "OK";
|
||||
|
|
|
@ -129,6 +129,7 @@
|
|||
D09D972225C65682007E6394 /* SeparatorConfiguredCollectionViewListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09D972125C65682007E6394 /* SeparatorConfiguredCollectionViewListCell.swift */; };
|
||||
D0A1F4F7252E7D4B004435BF /* TableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A1F4F6252E7D4B004435BF /* TableViewDataSource.swift */; };
|
||||
D0A7AC7325748BFF00E4E8AB /* ReportStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A7AC7225748BFF00E4E8AB /* ReportStatusView.swift */; };
|
||||
D0B325EB25E88ADC00C24BEA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D0C7D45724F76169001EBDBB /* Localizable.strings */; };
|
||||
D0B32F50250B373600311912 /* RegistrationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B32F4F250B373600311912 /* RegistrationView.swift */; };
|
||||
D0B5FE9B251583DB00478838 /* ProfileCollection+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B5FE9A251583DB00478838 /* ProfileCollection+Extensions.swift */; };
|
||||
D0B8510C25259E56004E0744 /* LoadMoreTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B8510B25259E56004E0744 /* LoadMoreTableViewCell.swift */; };
|
||||
|
@ -998,6 +999,7 @@
|
|||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D0B325EB25E88ADC00C24BEA /* Localizable.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Combine
|
||||
import Mastodon
|
||||
import SDWebImage
|
||||
import ServiceLayer
|
||||
|
@ -14,6 +15,7 @@ final class NotificationService: UNNotificationServiceExtension {
|
|||
|
||||
var contentHandler: ((UNNotificationContent) -> Void)?
|
||||
var bestAttemptContent: UNMutableNotificationContent?
|
||||
var cancellables = Set<AnyCancellable>()
|
||||
|
||||
override func didReceive(
|
||||
_ request: UNNotificationRequest,
|
||||
|
@ -47,18 +49,27 @@ final class NotificationService: UNNotificationServiceExtension {
|
|||
bestAttemptContent.sound = .default
|
||||
}
|
||||
|
||||
if appPreferences.notificationAccountName,
|
||||
let accountName = try? AllIdentitiesService(environment: Self.environment).identity(id: identityId)?.handle {
|
||||
bestAttemptContent.subtitle = accountName
|
||||
var identity: Identity?
|
||||
|
||||
if appPreferences.notificationAccountName {
|
||||
identity = try? AllIdentitiesService(environment: Self.environment).identity(id: identityId)
|
||||
|
||||
if let handle = identity?.handle {
|
||||
bestAttemptContent.subtitle = handle
|
||||
}
|
||||
}
|
||||
|
||||
if appPreferences.notificationPictures {
|
||||
Self.addImage(url: pushNotification.icon,
|
||||
bestAttemptContent: bestAttemptContent,
|
||||
contentHandler: contentHandler)
|
||||
} else {
|
||||
contentHandler(bestAttemptContent)
|
||||
}
|
||||
Self.attachment(imageURL: pushNotification.icon)
|
||||
.map { [$0] }
|
||||
.replaceError(with: [])
|
||||
.handleEvents(receiveOutput: { bestAttemptContent.attachments = $0 })
|
||||
.zip(parsingService.title(pushNotification: pushNotification,
|
||||
identityId: identityId,
|
||||
accountId: identity?.account?.id)
|
||||
.replaceError(with: pushNotification.title)
|
||||
.handleEvents(receiveOutput: { bestAttemptContent.title = $0 }))
|
||||
.sink { _ in contentHandler(bestAttemptContent) }
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
override func serviceExtensionTimeWillExpire() {
|
||||
|
@ -73,26 +84,32 @@ private extension NotificationService {
|
|||
userNotificationCenter: .current(),
|
||||
reduceMotion: { false })
|
||||
|
||||
static func addImage(url: URL,
|
||||
bestAttemptContent: UNMutableNotificationContent,
|
||||
contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||
let fileName = url.lastPathComponent
|
||||
enum ImageError: Error {
|
||||
case dataMissing
|
||||
}
|
||||
|
||||
static func attachment(imageURL: URL) -> AnyPublisher<UNNotificationAttachment, Error> {
|
||||
let fileName = imageURL.lastPathComponent
|
||||
let fileURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
|
||||
.appendingPathComponent(fileName)
|
||||
|
||||
SDWebImageManager.shared.loadImage(with: url, options: [], progress: nil) { _, data, _, _, _, _ in
|
||||
if let data = data {
|
||||
do {
|
||||
try data.write(to: fileURL)
|
||||
bestAttemptContent.attachments =
|
||||
[try UNNotificationAttachment(identifier: fileName, url: fileURL)]
|
||||
contentHandler(bestAttemptContent)
|
||||
} catch {
|
||||
contentHandler(bestAttemptContent)
|
||||
return Future<UNNotificationAttachment, Error> { promise in
|
||||
SDWebImageManager.shared.loadImage(with: imageURL, options: [], progress: nil) { _, data, error, _, _, _ in
|
||||
if let error = error {
|
||||
promise(.failure(error))
|
||||
} else if let data = data {
|
||||
let result = Result<UNNotificationAttachment, Error> {
|
||||
try data.write(to: fileURL)
|
||||
|
||||
return try UNNotificationAttachment(identifier: fileName, url: fileURL)
|
||||
}
|
||||
|
||||
promise(result)
|
||||
} else {
|
||||
promise(.failure(ImageError.dataMissing))
|
||||
}
|
||||
} else {
|
||||
contentHandler(bestAttemptContent)
|
||||
}
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Combine
|
||||
import CryptoKit
|
||||
import Foundation
|
||||
import Mastodon
|
||||
import MastodonAPI
|
||||
import Secrets
|
||||
|
||||
enum NotificationExtensionServiceError: Error {
|
||||
|
@ -48,6 +50,53 @@ public extension PushNotificationParsingService {
|
|||
salt: salt),
|
||||
identityId)
|
||||
}
|
||||
|
||||
func title(pushNotification: PushNotification,
|
||||
identityId: Identity.Id,
|
||||
accountId: Account.Id?) -> AnyPublisher<String, Error> {
|
||||
switch pushNotification.notificationType {
|
||||
case .poll, .status:
|
||||
let secrets = Secrets(identityId: identityId, keychain: environment.keychain)
|
||||
let instanceURL: URL
|
||||
|
||||
do {
|
||||
instanceURL = try secrets.getInstanceURL()
|
||||
} catch {
|
||||
return Fail(error: error).eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
let mastodonAPIClient = MastodonAPIClient(session: .shared, instanceURL: instanceURL)
|
||||
|
||||
mastodonAPIClient.accessToken = pushNotification.accessToken
|
||||
|
||||
let endpoint = NotificationEndpoint.notification(id: String(pushNotification.notificationId))
|
||||
|
||||
return mastodonAPIClient.request(endpoint)
|
||||
.map {
|
||||
switch pushNotification.notificationType {
|
||||
case .status:
|
||||
return String.localizedStringWithFormat(
|
||||
NSLocalizedString("notification.status-%@", comment: ""),
|
||||
$0.account.displayName)
|
||||
case .poll:
|
||||
switch accountId ?? (try? AllIdentitiesService(environment: environment)
|
||||
.identity(id: identityId)?.account?.id) {
|
||||
case .some($0.account.id):
|
||||
return NSLocalizedString("notification.poll.own", comment: "")
|
||||
case .some:
|
||||
return NSLocalizedString("notification.poll", comment: "")
|
||||
default:
|
||||
return NSLocalizedString("notification.poll.unknown", comment: "")
|
||||
}
|
||||
default:
|
||||
return pushNotification.title
|
||||
}
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
default:
|
||||
return Just(pushNotification.title).setFailureType(to: Error.self).eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension PushNotificationParsingService {
|
||||
|
|
Loading…
Reference in a new issue