mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-05-20 06:32:08 +02:00
Merge pull request #6002 from vector-im/release/1.8.12/release
Release 1.8.12
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
## Changes in 1.8.12 (2022-04-06)
|
||||
|
||||
🐛 Bugfixes
|
||||
|
||||
- RecentsViewController: Room context preview dismissed unexpectedly ([#5992](https://github.com/vector-im/element-ios/issues/5992))
|
||||
- Notifications: Strings now fall back to English if they're missing for the current language. ([#5996](https://github.com/vector-im/element-ios/issues/5996))
|
||||
|
||||
|
||||
## Changes in 1.8.11 (2022-04-05)
|
||||
|
||||
✨ Features
|
||||
|
||||
@@ -15,5 +15,5 @@
|
||||
//
|
||||
|
||||
// Version
|
||||
MARKETING_VERSION = 1.8.11
|
||||
CURRENT_PROJECT_VERSION = 1.8.11
|
||||
MARKETING_VERSION = 1.8.12
|
||||
CURRENT_PROJECT_VERSION = 1.8.12
|
||||
|
||||
@@ -19,7 +19,7 @@ import Foundation
|
||||
public extension Bundle {
|
||||
/// Returns the real app bundle.
|
||||
/// Can also be used in app extensions.
|
||||
static var app: Bundle {
|
||||
@objc static var app: Bundle {
|
||||
let bundle = main
|
||||
if bundle.bundleURL.pathExtension == "appex" {
|
||||
// Peel off two directory levels - MY_APP.app/PlugIns/MY_APP_EXTENSION.appex
|
||||
@@ -31,6 +31,14 @@ public extension Bundle {
|
||||
return bundle
|
||||
}
|
||||
|
||||
/// Get an lproj language bundle from the main app bundle.
|
||||
/// - Parameter language: The language to try to load.
|
||||
/// - Returns: The lproj bundle if found otherwise `nil`.
|
||||
@objc static func lprojBundle(for language: String) -> Bundle? {
|
||||
guard let lprojURL = Bundle.app.url(forResource: language, withExtension: "lproj") else { return nil }
|
||||
return Bundle(url: lprojURL)
|
||||
}
|
||||
|
||||
/// Whether or not the bundle is the RiotShareExtension.
|
||||
var isShareExtension: Bool {
|
||||
bundleURL.lastPathComponent.contains("RiotShareExtension.appex")
|
||||
|
||||
@@ -8006,7 +8006,7 @@ public class VectorL10n: NSObject {
|
||||
|
||||
extension VectorL10n {
|
||||
static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
|
||||
let format = NSLocalizedString(key, tableName: table, bundle: Bundle(for: BundleToken.self), comment: "")
|
||||
let format = NSLocalizedString(key, tableName: table, bundle: Bundle.app, comment: "")
|
||||
let locale: Locale
|
||||
if let providedLocale = LocaleProvider.locale {
|
||||
locale = providedLocale
|
||||
@@ -8018,4 +8018,3 @@ extension VectorL10n {
|
||||
}
|
||||
}
|
||||
|
||||
private final class BundleToken {}
|
||||
|
||||
@@ -366,6 +366,14 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
|
||||
- (void)refreshRecentsTable
|
||||
{
|
||||
if (!self.recentsUpdateEnabled)
|
||||
{
|
||||
isRefreshNeeded = NO;
|
||||
return;
|
||||
}
|
||||
|
||||
isRefreshNeeded = NO;
|
||||
|
||||
// Refresh the tabBar icon badges
|
||||
[[AppDelegate theDelegate].masterTabBarController refreshTabBarBadges];
|
||||
|
||||
@@ -1034,6 +1042,12 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
|
||||
- (void)dataSource:(MXKDataSource *)dataSource didCellChange:(id)changes
|
||||
{
|
||||
if (!self.recentsUpdateEnabled)
|
||||
{
|
||||
[super dataSource:dataSource didCellChange:changes];
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL cellReloaded = NO;
|
||||
if ([changes isKindOfClass:RecentsSectionUpdate.class])
|
||||
{
|
||||
@@ -2502,6 +2516,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.recentsUpdateEnabled = NO;
|
||||
return [self.contextMenuProvider contextMenuConfigurationWith:cellData from:cell session:self.dataSource.mxSession];
|
||||
}
|
||||
|
||||
@@ -2511,14 +2526,22 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
|
||||
if (!roomId)
|
||||
{
|
||||
self.recentsUpdateEnabled = YES;
|
||||
return;
|
||||
}
|
||||
|
||||
[animator addCompletion:^{
|
||||
self.recentsUpdateEnabled = YES;
|
||||
[self showRoomWithRoomId:roomId inMatrixSession:self.mainSession];
|
||||
}];
|
||||
}
|
||||
|
||||
- (UITargetedPreview *)tableView:(UITableView *)tableView previewForDismissingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0))
|
||||
{
|
||||
self.recentsUpdateEnabled = YES;
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark - RoomContextActionServiceDelegate
|
||||
|
||||
- (void)roomContextActionServiceDidJoinRoom:(id<RoomContextActionServiceProtocol>)service
|
||||
|
||||
@@ -902,6 +902,7 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.recentsUpdateEnabled = NO;
|
||||
return [self.contextMenuProvider contextMenuConfigurationWith:cellData from:cell session:self.dataSource.mxSession];
|
||||
}
|
||||
|
||||
@@ -911,12 +912,20 @@
|
||||
|
||||
if (!roomId)
|
||||
{
|
||||
self.recentsUpdateEnabled = YES;
|
||||
return;
|
||||
}
|
||||
|
||||
[animator addCompletion:^{
|
||||
self.recentsUpdateEnabled = YES;
|
||||
[self showRoomWithRoomId:roomId inMatrixSession:self.mainSession];
|
||||
}];
|
||||
}
|
||||
|
||||
- (UITargetedPreview *)collectionView:(UICollectionView *)collectionView previewForDismissingContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0))
|
||||
{
|
||||
self.recentsUpdateEnabled = YES;
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#import "NSBundle+MXKLanguage.h"
|
||||
#import "GeneratedInterface-Swift.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@@ -55,37 +56,37 @@ static const char _fallbackLanguage = 0;
|
||||
[self setupMXKLanguageBundle];
|
||||
|
||||
// [NSBundle localizedStringForKey] calls will be redirected to the bundle corresponding
|
||||
// to "language"
|
||||
objc_setAssociatedObject([NSBundle mainBundle],
|
||||
&_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil,
|
||||
// to "language". `lprojBundleFor` loads this from the main app bundle as we might be running in an extension.
|
||||
objc_setAssociatedObject(NSBundle.app,
|
||||
&_bundle, language ? [NSBundle lprojBundleFor:language] : nil,
|
||||
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
|
||||
objc_setAssociatedObject([NSBundle mainBundle],
|
||||
objc_setAssociatedObject(NSBundle.app,
|
||||
&_language, language,
|
||||
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
+ (NSString *)mxk_language
|
||||
{
|
||||
return objc_getAssociatedObject([NSBundle mainBundle], &_language);
|
||||
return objc_getAssociatedObject(NSBundle.app, &_language);
|
||||
}
|
||||
|
||||
+ (void)mxk_setFallbackLanguage:(NSString *)language
|
||||
{
|
||||
[self setupMXKLanguageBundle];
|
||||
|
||||
objc_setAssociatedObject([NSBundle mainBundle],
|
||||
&_fallbackBundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil,
|
||||
objc_setAssociatedObject(NSBundle.app,
|
||||
&_fallbackBundle, language ? [NSBundle lprojBundleFor:language] : nil,
|
||||
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
|
||||
objc_setAssociatedObject([NSBundle mainBundle],
|
||||
objc_setAssociatedObject(NSBundle.app,
|
||||
&_fallbackLanguage, language,
|
||||
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
+ (NSString *)mxk_fallbackLanguage
|
||||
{
|
||||
return objc_getAssociatedObject([NSBundle mainBundle], &_fallbackLanguage);
|
||||
return objc_getAssociatedObject(NSBundle.app, &_fallbackLanguage);
|
||||
}
|
||||
|
||||
#pragma mark - Private methods
|
||||
@@ -96,7 +97,7 @@ static const char _fallbackLanguage = 0;
|
||||
dispatch_once(&onceToken, ^{
|
||||
|
||||
// Use MXKLanguageBundle as the [NSBundle mainBundle] class
|
||||
object_setClass([NSBundle mainBundle], [MXKLanguageBundle class]);
|
||||
object_setClass(NSBundle.app, MXKLanguageBundle.class);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,12 @@ limitations under the License.
|
||||
The fake top view displayed in case of vertical bounce.
|
||||
*/
|
||||
__weak UIView *topview;
|
||||
|
||||
/**
|
||||
`isRefreshNeeded` is set to `YES` if an update of the datasource has been triggered but the UI has not been updated.
|
||||
It's set to `NO` after a refresh of the UI.
|
||||
*/
|
||||
BOOL isRefreshNeeded;
|
||||
}
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UISearchBar *recentsSearchBar;
|
||||
@@ -83,6 +89,11 @@ limitations under the License.
|
||||
*/
|
||||
@property (nonatomic) BOOL enableBarButtonSearch;
|
||||
|
||||
/**
|
||||
Enabled or disabled the UI update after recents syncs. Default YES.
|
||||
*/
|
||||
@property (nonatomic, getter=isRecentsUpdateEnabled) BOOL recentsUpdateEnabled;
|
||||
|
||||
#pragma mark - Class methods
|
||||
|
||||
/**
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
{
|
||||
[super finalizeInit];
|
||||
|
||||
_recentsUpdateEnabled = YES;
|
||||
_enableBarButtonSearch = YES;
|
||||
}
|
||||
|
||||
@@ -169,6 +170,8 @@
|
||||
|
||||
// Observe the server sync
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onSyncNotification) name:kMXSessionDidSyncNotification object:nil];
|
||||
|
||||
self.recentsUpdateEnabled = YES;
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated
|
||||
@@ -319,6 +322,10 @@
|
||||
|
||||
- (void)refreshRecentsTable
|
||||
{
|
||||
if (!self.recentsUpdateEnabled) return;
|
||||
|
||||
isRefreshNeeded = NO;
|
||||
|
||||
// For now, do a simple full reload
|
||||
[self.recentsTableView reloadData];
|
||||
}
|
||||
@@ -330,6 +337,16 @@
|
||||
[self.view setNeedsUpdateConstraints];
|
||||
}
|
||||
|
||||
- (void)setRecentsUpdateEnabled:(BOOL)activeUpdate
|
||||
{
|
||||
_recentsUpdateEnabled = activeUpdate;
|
||||
|
||||
if (_recentsUpdateEnabled && isRefreshNeeded)
|
||||
{
|
||||
[self refreshRecentsTable];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Action
|
||||
|
||||
- (IBAction)search:(id)sender
|
||||
@@ -385,6 +402,12 @@
|
||||
|
||||
- (void)dataSource:(MXKDataSource *)dataSource didCellChange:(id)changes
|
||||
{
|
||||
if (!_recentsUpdateEnabled)
|
||||
{
|
||||
isRefreshNeeded = YES;
|
||||
return;
|
||||
}
|
||||
|
||||
// For now, do a simple full reload
|
||||
[self refreshRecentsTable];
|
||||
}
|
||||
|
||||
@@ -74,6 +74,17 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
private static let backgroundServiceInitQueue = DispatchQueue(label: "io.element.NotificationService.backgroundServiceInitQueue")
|
||||
// MARK: - Method Overrides
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
// Set up runtime language and fallback by considering the userDefaults object shared within the application group.
|
||||
let sharedUserDefaults = MXKAppSettings.standard().sharedUserDefaults
|
||||
if let language = sharedUserDefaults?.string(forKey: "appLanguage") {
|
||||
Bundle.mxk_setLanguage(language)
|
||||
}
|
||||
Bundle.mxk_setFallbackLanguage("en")
|
||||
}
|
||||
|
||||
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||
let userInfo = request.content.userInfo
|
||||
|
||||
@@ -341,9 +352,9 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
let isVideoCall = sdp?.contains("m=video") ?? false
|
||||
|
||||
if isVideoCall {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "VIDEO_CALL_FROM_USER", arguments: [eventSenderName as Any])
|
||||
notificationBody = NotificationService.localizedString(forKey: "VIDEO_CALL_FROM_USER", eventSenderName)
|
||||
} else {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "VOICE_CALL_FROM_USER", arguments: [eventSenderName as Any])
|
||||
notificationBody = NotificationService.localizedString(forKey: "VOICE_CALL_FROM_USER", eventSenderName)
|
||||
}
|
||||
|
||||
// call notifications should stand out from normal messages, so we don't stack them
|
||||
@@ -405,7 +416,7 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
}
|
||||
|
||||
let msgType = event.content[kMXMessageTypeKey] as? String
|
||||
let messageContent = event.content[kMXMessageBodyKey] as? String
|
||||
let messageContent = event.content[kMXMessageBodyKey] as? String ?? ""
|
||||
let isReply = event.isReply()
|
||||
|
||||
if isReply {
|
||||
@@ -416,30 +427,30 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
|
||||
if event.isEncrypted && !self.showDecryptedContentInNotifications {
|
||||
// Hide the content
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "MESSAGE", arguments: [])
|
||||
notificationBody = NotificationService.localizedString(forKey: "MESSAGE")
|
||||
break
|
||||
}
|
||||
|
||||
if event.location != nil {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "LOCATION_FROM_USER", arguments: [eventSenderName])
|
||||
notificationBody = NotificationService.localizedString(forKey: "LOCATION_FROM_USER", eventSenderName)
|
||||
break
|
||||
}
|
||||
|
||||
switch msgType {
|
||||
case kMXMessageTypeEmote:
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "ACTION_FROM_USER", arguments: [eventSenderName, messageContent as Any])
|
||||
notificationBody = NotificationService.localizedString(forKey: "ACTION_FROM_USER", eventSenderName, messageContent)
|
||||
case kMXMessageTypeImage:
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "PICTURE_FROM_USER", arguments: [eventSenderName])
|
||||
notificationBody = NotificationService.localizedString(forKey: "PICTURE_FROM_USER", eventSenderName)
|
||||
case kMXMessageTypeVideo:
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "VIDEO_FROM_USER", arguments: [eventSenderName])
|
||||
notificationBody = NotificationService.localizedString(forKey: "VIDEO_FROM_USER", eventSenderName)
|
||||
case kMXMessageTypeAudio:
|
||||
if event.isVoiceMessage() {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "VOICE_MESSAGE_FROM_USER", arguments: [eventSenderName])
|
||||
notificationBody = NotificationService.localizedString(forKey: "VOICE_MESSAGE_FROM_USER", eventSenderName)
|
||||
} else {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "AUDIO_FROM_USER", arguments: [eventSenderName, messageContent as Any])
|
||||
notificationBody = NotificationService.localizedString(forKey: "AUDIO_FROM_USER", eventSenderName, messageContent)
|
||||
}
|
||||
case kMXMessageTypeFile:
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "FILE_FROM_USER", arguments: [eventSenderName, messageContent as Any])
|
||||
notificationBody = NotificationService.localizedString(forKey: "FILE_FROM_USER", eventSenderName, messageContent)
|
||||
|
||||
// All other message types such as text, notice, server notice etc
|
||||
default:
|
||||
@@ -469,50 +480,50 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
// If there was a change, use the sender's userID if one was blank and show the change.
|
||||
if let oldDisplayname = oldContent.displayname ?? event.sender,
|
||||
let displayname = newContent.displayname ?? event.sender {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "USER_UPDATED_DISPLAYNAME", arguments: [oldDisplayname, displayname])
|
||||
notificationBody = NotificationService.localizedString(forKey: "USER_UPDATED_DISPLAYNAME", oldDisplayname, displayname)
|
||||
} else {
|
||||
// Should never be reached as the event should always have a sender.
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "GENERIC_USER_UPDATED_DISPLAYNAME", arguments: [eventSenderName])
|
||||
notificationBody = NotificationService.localizedString(forKey: "GENERIC_USER_UPDATED_DISPLAYNAME", eventSenderName)
|
||||
}
|
||||
} else {
|
||||
// If the display name hasn't changed, handle as an avatar change.
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "USER_UPDATED_AVATAR", arguments: [eventSenderName])
|
||||
notificationBody = NotificationService.localizedString(forKey: "USER_UPDATED_AVATAR", eventSenderName)
|
||||
}
|
||||
} else {
|
||||
// No known reports of having reached this situation for a membership notification
|
||||
// So use a generic membership updated fallback.
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "USER_MEMBERSHIP_UPDATED", arguments: [eventSenderName])
|
||||
notificationBody = NotificationService.localizedString(forKey: "USER_MEMBERSHIP_UPDATED", eventSenderName)
|
||||
}
|
||||
// Otherwise treat the notification as an invite.
|
||||
// This is the expected notification content for a membership event.
|
||||
} else {
|
||||
if roomDisplayName != nil && roomDisplayName != eventSenderName {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "USER_INVITE_TO_NAMED_ROOM", arguments: [eventSenderName, roomDisplayName as Any])
|
||||
if let roomDisplayName = roomDisplayName, roomDisplayName != eventSenderName {
|
||||
notificationBody = NotificationService.localizedString(forKey: "USER_INVITE_TO_NAMED_ROOM", eventSenderName, roomDisplayName)
|
||||
} else {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "USER_INVITE_TO_CHAT", arguments: [eventSenderName])
|
||||
notificationBody = NotificationService.localizedString(forKey: "USER_INVITE_TO_CHAT", eventSenderName)
|
||||
}
|
||||
}
|
||||
|
||||
case .sticker:
|
||||
notificationTitle = self.messageTitle(for: eventSenderName, in: roomDisplayName)
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "STICKER_FROM_USER", arguments: [eventSenderName as Any])
|
||||
notificationBody = NotificationService.localizedString(forKey: "STICKER_FROM_USER", eventSenderName)
|
||||
|
||||
// Reactions are unexpected notification types, but have been seen in some circumstances.
|
||||
case .reaction:
|
||||
notificationTitle = self.messageTitle(for: eventSenderName, in: roomDisplayName)
|
||||
if let reactionKey = event.relatesTo?.key {
|
||||
// Try to show the reaction key in the notification.
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "REACTION_FROM_USER", arguments: [eventSenderName, reactionKey])
|
||||
notificationBody = NotificationService.localizedString(forKey: "REACTION_FROM_USER", eventSenderName, reactionKey)
|
||||
} else {
|
||||
// Otherwise show a generic reaction.
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "GENERIC_REACTION_FROM_USER", arguments: [eventSenderName])
|
||||
notificationBody = NotificationService.localizedString(forKey: "GENERIC_REACTION_FROM_USER", eventSenderName)
|
||||
}
|
||||
|
||||
case .custom:
|
||||
if (event.type == kWidgetMatrixEventTypeString || event.type == kWidgetModularEventTypeString),
|
||||
let type = event.content?["type"] as? String,
|
||||
(type == kWidgetTypeJitsiV1 || type == kWidgetTypeJitsiV2) {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "GROUP_CALL_STARTED", arguments: nil)
|
||||
notificationBody = NotificationService.localizedString(forKey: "GROUP_CALL_STARTED")
|
||||
notificationTitle = roomDisplayName
|
||||
|
||||
// call notifications should stand out from normal messages, so we don't stack them
|
||||
@@ -566,7 +577,7 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
var validatedNotificationTitle: String? = notificationTitle
|
||||
if self.localAuthenticationService.isProtectionSet {
|
||||
MXLog.debug("[NotificationService] validateNotificationContentAndComplete: Resetting title and body because app protection is set")
|
||||
validatedNotificationBody = NSString.localizedUserNotificationString(forKey: "MESSAGE_PROTECTED", arguments: [])
|
||||
validatedNotificationBody = NotificationService.localizedString(forKey: "MESSAGE_PROTECTED")
|
||||
validatedNotificationTitle = nil
|
||||
}
|
||||
|
||||
@@ -596,7 +607,7 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
private func messageTitle(for eventSenderName: String, in roomDisplayName: String?) -> String {
|
||||
// Display the room name only if it is different than the sender name
|
||||
if let roomDisplayName = roomDisplayName, roomDisplayName != eventSenderName {
|
||||
return NSString.localizedUserNotificationString(forKey: "MSG_FROM_USER_IN_ROOM_TITLE", arguments: [eventSenderName, roomDisplayName])
|
||||
return NotificationService.localizedString(forKey: "MSG_FROM_USER_IN_ROOM_TITLE", eventSenderName, roomDisplayName)
|
||||
} else {
|
||||
return eventSenderName
|
||||
}
|
||||
@@ -605,9 +616,9 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
private func replyTitle(for eventSenderName: String, in roomDisplayName: String?) -> String {
|
||||
// Display the room name only if it is different than the sender name
|
||||
if let roomDisplayName = roomDisplayName, roomDisplayName != eventSenderName {
|
||||
return NSString.localizedUserNotificationString(forKey: "REPLY_FROM_USER_IN_ROOM_TITLE", arguments: [eventSenderName, roomDisplayName])
|
||||
return NotificationService.localizedString(forKey: "REPLY_FROM_USER_IN_ROOM_TITLE", eventSenderName, roomDisplayName)
|
||||
} else {
|
||||
return NSString.localizedUserNotificationString(forKey: "REPLY_FROM_USER_TITLE", arguments: [eventSenderName])
|
||||
return NotificationService.localizedString(forKey: "REPLY_FROM_USER_TITLE", eventSenderName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -816,4 +827,13 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static func localizedString(forKey key: String, _ args: CVarArg...) -> String {
|
||||
// The bundle needs to be an MXKLanguageBundle and contain the lproj files.
|
||||
// MatrixKit now sets the app bundle as the MXKLanguageBundle
|
||||
let format = NSLocalizedString(key, bundle: Bundle.app, comment: "")
|
||||
let locale = LocaleProvider.locale ?? Locale.current
|
||||
|
||||
return String(format: format, locale: locale, arguments: args)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ import Foundation
|
||||
|
||||
extension {{className}} {
|
||||
static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
|
||||
let format = NSLocalizedString(key, tableName: table, bundle: Bundle(for: BundleToken.self), comment: "")
|
||||
let format = NSLocalizedString(key, tableName: table, bundle: Bundle.app, comment: "")
|
||||
let locale: Locale
|
||||
|
||||
if let providedLocale = LocaleProvider.locale {
|
||||
@@ -77,7 +77,6 @@ extension {{className}} {
|
||||
}
|
||||
}
|
||||
|
||||
private final class BundleToken {}
|
||||
{% else %}
|
||||
// No string found
|
||||
{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user