From f3d0cd99fc22156269b22d4faf52cd13f7849fa5 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 28 Mar 2019 16:58:02 -0400 Subject: [PATCH 01/21] Handle notifications for open conversations. --- .../ConversationViewController.h | 4 ++- .../ConversationViewController.m | 17 ++++++---- Signal/src/environment/SignalApp.h | 2 ++ Signal/src/environment/SignalApp.m | 33 +++++++++++++++++-- 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.h b/Signal/src/ViewControllers/ConversationView/ConversationViewController.h index 31d7841c1..0529b940b 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.h +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import @@ -25,6 +25,8 @@ typedef NS_ENUM(NSUInteger, ConversationViewAction) { - (void)popKeyBoard; +- (void)scrollToFirstUnreadMessage:(BOOL)isAnimated; + #pragma mark 3D Touch Methods - (void)peekSetup; diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index 0002ac339..05924083e 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -752,7 +752,7 @@ typedef enum : NSUInteger { // We want to set the initial scroll state the first time we enter the view. if (!self.viewHasEverAppeared) { - [self scrollToDefaultPosition]; + [self scrollToDefaultPosition:NO]; } else if (self.menuActionsViewController != nil) { [self scrollToMenuActionInteraction:NO]; } @@ -807,7 +807,7 @@ typedef enum : NSUInteger { return [NSIndexPath indexPathForRow:row inSection:0]; } -- (void)scrollToDefaultPosition +- (void)scrollToDefaultPosition:(BOOL)isAnimated { if (self.isUserScrolling) { return; @@ -824,14 +824,14 @@ typedef enum : NSUInteger { if (indexPath) { if (indexPath.section == 0 && indexPath.row == 0) { - [self.collectionView setContentOffset:CGPointZero animated:NO]; + [self.collectionView setContentOffset:CGPointZero animated:isAnimated]; } else { [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionTop - animated:NO]; + animated:isAnimated]; } } else { - [self scrollToBottomAnimated:NO]; + [self scrollToBottomAnimated:isAnimated]; } } @@ -3899,7 +3899,7 @@ typedef enum : NSUInteger { // Adjust content offset to prevent the presented keyboard from obscuring content. if (!self.viewHasEverAppeared) { - [self scrollToDefaultPosition]; + [self scrollToDefaultPosition:NO]; } else if (wasScrolledToBottom) { // If we were scrolled to the bottom, don't do any fancy math. Just stay at the bottom. [self scrollToBottomAnimated:NO]; @@ -4026,6 +4026,11 @@ typedef enum : NSUInteger { [self didScrollToBottom]; } +- (void)scrollToFirstUnreadMessage:(BOOL)isAnimated +{ + [self scrollToDefaultPosition:isAnimated]; +} + #pragma mark - UIScrollViewDelegate - (void)updateLastKnownDistanceFromBottom diff --git a/Signal/src/environment/SignalApp.h b/Signal/src/environment/SignalApp.h index b3b5fb9dc..e89daec85 100644 --- a/Signal/src/environment/SignalApp.h +++ b/Signal/src/environment/SignalApp.h @@ -46,6 +46,8 @@ NS_ASSUME_NONNULL_BEGIN focusMessageId:(nullable NSString *)focusMessageId animated:(BOOL)isAnimated; +- (void)presentConversationForThreadAndShowFirstUnreadMessage:(TSThread *)thread animated:(BOOL)isAnimated; + #pragma mark - Methods + (void)resetAppData; diff --git a/Signal/src/environment/SignalApp.m b/Signal/src/environment/SignalApp.m index 0316ae5bd..b03834b31 100644 --- a/Signal/src/environment/SignalApp.m +++ b/Signal/src/environment/SignalApp.m @@ -109,7 +109,7 @@ NS_ASSUME_NONNULL_BEGIN DispatchMainThreadSafe(^{ UIViewController *frontmostVC = [[UIApplication sharedApplication] frontmostViewController]; - + if ([frontmostVC isKindOfClass:[ConversationViewController class]]) { ConversationViewController *conversationVC = (ConversationViewController *)frontmostVC; if ([conversationVC.thread.uniqueId isEqualToString:thread.uniqueId]) { @@ -117,11 +117,40 @@ NS_ASSUME_NONNULL_BEGIN return; } } - + [self.homeViewController presentThread:thread action:action focusMessageId:focusMessageId animated:isAnimated]; }); } +- (void)presentConversationForThreadAndShowFirstUnreadMessage:(TSThread *)thread animated:(BOOL)isAnimated +{ + OWSAssertIsOnMainThread(); + + OWSLogInfo(@""); + + if (!thread) { + OWSFailDebug(@"Can't present nil thread."); + return; + } + + DispatchMainThreadSafe(^{ + UIViewController *frontmostVC = [[UIApplication sharedApplication] frontmostViewController]; + + if ([frontmostVC isKindOfClass:[ConversationViewController class]]) { + ConversationViewController *conversationVC = (ConversationViewController *)frontmostVC; + if ([conversationVC.thread.uniqueId isEqualToString:thread.uniqueId]) { + [conversationVC scrollToFirstUnreadMessage:isAnimated]; + return; + } + } + + [self.homeViewController presentThread:thread + action:ConversationViewActionNone + focusMessageId:nil + animated:isAnimated]; + }); +} + - (void)didChangeCallLoggingPreference:(NSNotification *)notitication { [AppEnvironment.shared.callService createCallUIAdapter]; From 01d9993b9d4157d754a1d090fca57ceb5ebd8200 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 28 Mar 2019 17:03:10 -0400 Subject: [PATCH 02/21] Handle notifications for open conversations. --- .../UserInterface/Notifications/AppNotifications.swift | 2 +- Signal/src/environment/SignalApp.h | 2 +- Signal/src/environment/SignalApp.m | 8 +++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Signal/src/UserInterface/Notifications/AppNotifications.swift b/Signal/src/UserInterface/Notifications/AppNotifications.swift index 60f255f91..2f7bf636f 100644 --- a/Signal/src/UserInterface/Notifications/AppNotifications.swift +++ b/Signal/src/UserInterface/Notifications/AppNotifications.swift @@ -648,7 +648,7 @@ class NotificationActionHandler { // can be visible to the user immediately upon opening the app, rather than having to watch // it animate in from the homescreen. let shouldAnimate = UIApplication.shared.applicationState == .active - signalApp.presentConversation(forThreadId: threadId, animated: shouldAnimate) + signalApp.presentConversationAndShowFirstUnreadMessage(forThreadId: threadId, animated: shouldAnimate) return Promise.value(()) } diff --git a/Signal/src/environment/SignalApp.h b/Signal/src/environment/SignalApp.h index e89daec85..3c759094e 100644 --- a/Signal/src/environment/SignalApp.h +++ b/Signal/src/environment/SignalApp.h @@ -46,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN focusMessageId:(nullable NSString *)focusMessageId animated:(BOOL)isAnimated; -- (void)presentConversationForThreadAndShowFirstUnreadMessage:(TSThread *)thread animated:(BOOL)isAnimated; +- (void)presentConversationAndShowFirstUnreadMessageForThreadId:(NSString *)threadId animated:(BOOL)isAnimated; #pragma mark - Methods diff --git a/Signal/src/environment/SignalApp.m b/Signal/src/environment/SignalApp.m index b03834b31..8d01c8ddf 100644 --- a/Signal/src/environment/SignalApp.m +++ b/Signal/src/environment/SignalApp.m @@ -122,14 +122,16 @@ NS_ASSUME_NONNULL_BEGIN }); } -- (void)presentConversationForThreadAndShowFirstUnreadMessage:(TSThread *)thread animated:(BOOL)isAnimated +- (void)presentConversationAndShowFirstUnreadMessageForThreadId:(NSString *)threadId animated:(BOOL)isAnimated { OWSAssertIsOnMainThread(); + OWSAssertDebug(threadId.length > 0); OWSLogInfo(@""); - if (!thread) { - OWSFailDebug(@"Can't present nil thread."); + TSThread *thread = [TSThread fetchObjectWithUniqueID:threadId]; + if (thread == nil) { + OWSFailDebug(@"unable to find thread with id: %@", threadId); return; } From aad5533127cf7748fb6771d29397ec8662a4ba7b Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 28 Mar 2019 18:01:49 -0400 Subject: [PATCH 03/21] Respond to CR. --- Signal/src/UserInterface/Notifications/AppNotifications.swift | 2 +- Signal/src/environment/SignalApp.h | 2 +- Signal/src/environment/SignalApp.m | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Signal/src/UserInterface/Notifications/AppNotifications.swift b/Signal/src/UserInterface/Notifications/AppNotifications.swift index 2f7bf636f..e261a2418 100644 --- a/Signal/src/UserInterface/Notifications/AppNotifications.swift +++ b/Signal/src/UserInterface/Notifications/AppNotifications.swift @@ -648,7 +648,7 @@ class NotificationActionHandler { // can be visible to the user immediately upon opening the app, rather than having to watch // it animate in from the homescreen. let shouldAnimate = UIApplication.shared.applicationState == .active - signalApp.presentConversationAndShowFirstUnreadMessage(forThreadId: threadId, animated: shouldAnimate) + signalApp.presentConversationAndScrollToFirstUnreadMessage(forThreadId: threadId, animated: shouldAnimate) return Promise.value(()) } diff --git a/Signal/src/environment/SignalApp.h b/Signal/src/environment/SignalApp.h index 3c759094e..c46e60674 100644 --- a/Signal/src/environment/SignalApp.h +++ b/Signal/src/environment/SignalApp.h @@ -46,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN focusMessageId:(nullable NSString *)focusMessageId animated:(BOOL)isAnimated; -- (void)presentConversationAndShowFirstUnreadMessageForThreadId:(NSString *)threadId animated:(BOOL)isAnimated; +- (void)presentConversationAndScrollToFirstUnreadMessageForThreadId:(NSString *)threadId animated:(BOOL)isAnimated; #pragma mark - Methods diff --git a/Signal/src/environment/SignalApp.m b/Signal/src/environment/SignalApp.m index 8d01c8ddf..a84975323 100644 --- a/Signal/src/environment/SignalApp.m +++ b/Signal/src/environment/SignalApp.m @@ -122,7 +122,7 @@ NS_ASSUME_NONNULL_BEGIN }); } -- (void)presentConversationAndShowFirstUnreadMessageForThreadId:(NSString *)threadId animated:(BOOL)isAnimated +- (void)presentConversationAndScrollToFirstUnreadMessageForThreadId:(NSString *)threadId animated:(BOOL)isAnimated { OWSAssertIsOnMainThread(); OWSAssertDebug(threadId.length > 0); From eb5cf3978c34f7bc43fc00d4ee00b71b41566491 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 28 Mar 2019 15:11:58 -0400 Subject: [PATCH 04/21] Fix first responder issue in image editor. --- .../AttachmentApprovalViewController.swift | 4 +++- .../ImageEditor/ImageEditorBrushViewController.swift | 5 +++++ .../ImageEditor/ImageEditorCropViewController.swift | 9 +++++---- .../ImageEditor/ImageEditorTextViewController.swift | 5 +++++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalViewController.swift b/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalViewController.swift index 6c674f1b7..cba9ceffa 100644 --- a/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalViewController.swift +++ b/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalViewController.swift @@ -328,7 +328,9 @@ public class AttachmentApprovalViewController: UIPageViewController, UIPageViewC } private func updateControlVisibility() { - if !shouldHideControls, !isFirstResponder { + let hasPresentedView = self.presentedViewController != nil + + if !shouldHideControls, !isFirstResponder, !hasPresentedView { becomeFirstResponder() } bottomToolView.shouldHideControls = shouldHideControls diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift b/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift index 6848b4a13..a6ea171f3 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift @@ -119,6 +119,11 @@ public class ImageEditorBrushViewController: OWSViewController { return true } + @objc + override public var canBecomeFirstResponder: Bool { + return true + } + // MARK: - Actions @objc func didTapUndo(sender: UIButton) { diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorCropViewController.swift b/SignalMessaging/Views/ImageEditor/ImageEditorCropViewController.swift index 9714a73c3..2cfedcd9c 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorCropViewController.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorCropViewController.swift @@ -242,6 +242,11 @@ class ImageEditorCropViewController: OWSViewController { return true } + @objc + override public var canBecomeFirstResponder: Bool { + return true + } + private static let desiredCornerSize: CGFloat = 24 private static let minCropSize: CGFloat = desiredCornerSize * 2 private var cornerSize = CGSize.zero @@ -407,10 +412,6 @@ class ImageEditorCropViewController: OWSViewController { panGestureRecognizer.shouldBeRequiredToFail(by: pinchGestureRecognizer) } - override public var canBecomeFirstResponder: Bool { - return true - } - // MARK: - Gestures private class func unitTranslation(oldLocationView: CGPoint, diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorTextViewController.swift b/SignalMessaging/Views/ImageEditor/ImageEditorTextViewController.swift index beb16d220..52c4523f1 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorTextViewController.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorTextViewController.swift @@ -239,6 +239,11 @@ public class ImageEditorTextViewController: OWSViewController, VAlignTextViewDel return true } + @objc + override public var canBecomeFirstResponder: Bool { + return true + } + // MARK: - Pinch Gesture private var pinchFontStart: UIFont? From 517a550593ce7ad4ba1592d5fb11e02271e8cd9a Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 28 Mar 2019 16:29:57 -0400 Subject: [PATCH 05/21] Further improve "first responder" behavior in the image editor. --- ...AttachmentApprovalInputAccessoryView.swift | 21 +++++++++---- .../AttachmentApprovalViewController.swift | 31 ++++++++++--------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalInputAccessoryView.swift b/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalInputAccessoryView.swift index b983274e2..3f9907d86 100644 --- a/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalInputAccessoryView.swift +++ b/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalInputAccessoryView.swift @@ -101,11 +101,7 @@ class AttachmentApprovalInputAccessoryView: UIView { // MARK: - public var shouldHideControls = false { - didSet { - updateContents() - } - } + private var shouldHideControls = false private func updateContents() { var hasCurrentCaption = false @@ -135,6 +131,10 @@ class AttachmentApprovalInputAccessoryView: UIView { if !attachmentCaptionToolbar.textView.isFirstResponder { attachmentCaptionToolbar.textView.becomeFirstResponder() } + } else { + if attachmentCaptionToolbar.textView.isFirstResponder { + attachmentCaptionToolbar.textView.resignFirstResponder() + } } // NOTE: We don't automatically make attachmentTextToolbar.textView // first responder; @@ -143,9 +143,18 @@ class AttachmentApprovalInputAccessoryView: UIView { } public func update(isEditingCaptions: Bool, - currentAttachmentItem: SignalAttachmentItem?) { + currentAttachmentItem: SignalAttachmentItem?, + shouldHideControls: Bool) { + // De-bounce + guard self.isEditingCaptions != isEditingCaptions || + self.currentAttachmentItem != currentAttachmentItem || + self.shouldHideControls != shouldHideControls else { + return + } + self.isEditingCaptions = isEditingCaptions self.currentAttachmentItem = currentAttachmentItem + self.shouldHideControls = shouldHideControls updateContents() } diff --git a/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalViewController.swift b/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalViewController.swift index cba9ceffa..569ca847a 100644 --- a/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalViewController.swift +++ b/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalViewController.swift @@ -184,7 +184,6 @@ public class AttachmentApprovalViewController: UIPageViewController, UIPageViewC private func updateContents() { updateNavigationBar() updateInputAccessory() - updateControlVisibility() touchInterceptorView.isHidden = !isEditingCaptions } @@ -206,7 +205,10 @@ public class AttachmentApprovalViewController: UIPageViewController, UIPageViewC currentPageViewController = pageViewControllers.first } let currentAttachmentItem: SignalAttachmentItem? = currentPageViewController?.attachmentItem - bottomToolView.update(isEditingCaptions: isEditingCaptions, currentAttachmentItem: currentAttachmentItem) + + bottomToolView.update(isEditingCaptions: isEditingCaptions, + currentAttachmentItem: currentAttachmentItem, + shouldHideControls: shouldHideControls) } // MARK: - Navigation Bar @@ -327,15 +329,6 @@ public class AttachmentApprovalViewController: UIPageViewController, UIPageViewC return pageViewController.shouldHideControls } - private func updateControlVisibility() { - let hasPresentedView = self.presentedViewController != nil - - if !shouldHideControls, !isFirstResponder, !hasPresentedView { - becomeFirstResponder() - } - bottomToolView.shouldHideControls = shouldHideControls - } - // MARK: - View Helpers func remove(attachmentItem: SignalAttachmentItem) { @@ -411,8 +404,6 @@ public class AttachmentApprovalViewController: UIPageViewController, UIPageViewC updateMediaRail() } } - - updateContents() } // MARK: - UIPageViewControllerDataSource @@ -463,6 +454,18 @@ public class AttachmentApprovalViewController: UIPageViewController, UIPageViewC return super.viewControllers!.map { $0 as! AttachmentPrepViewController } } + @objc + public override func setViewControllers(_ viewControllers: [UIViewController]?, direction: UIPageViewController.NavigationDirection, animated: Bool, completion: ((Bool) -> Void)? = nil) { + super.setViewControllers(viewControllers, + direction: direction, + animated: animated) { [weak self] (finished) in + if let completion = completion { + completion(finished) + } + self?.updateContents() + } + } + var currentItem: SignalAttachmentItem! { get { return currentPageViewController.attachmentItem @@ -682,7 +685,7 @@ extension AttachmentApprovalViewController: AttachmentPrepViewControllerDelegate } func prepViewControllerUpdateControls() { - updateControlVisibility() + updateInputAccessory() } } From a3efb58d15f2dd6cadf1a901a1dc1b0068a6dd37 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 28 Mar 2019 18:29:19 -0400 Subject: [PATCH 06/21] Respond to CR. --- .../AttachmentApprovalInputAccessoryView.swift | 18 +++++++++++++++--- .../AttachmentApprovalViewController.swift | 6 ++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalInputAccessoryView.swift b/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalInputAccessoryView.swift index 3f9907d86..eadc0afda 100644 --- a/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalInputAccessoryView.swift +++ b/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalInputAccessoryView.swift @@ -120,6 +120,12 @@ class AttachmentApprovalInputAccessoryView: UIView { currentCaptionWrapper.isHidden = isEditingCaptions || !hasCurrentCaption attachmentTextToolbar.isHidden = isEditingCaptions + updateFirstResponder() + + layoutSubviews() + } + + private func updateFirstResponder() { if (shouldHideControls) { if attachmentCaptionToolbar.textView.isFirstResponder { attachmentCaptionToolbar.textView.resignFirstResponder() @@ -138,8 +144,6 @@ class AttachmentApprovalInputAccessoryView: UIView { } // NOTE: We don't automatically make attachmentTextToolbar.textView // first responder; - - layoutSubviews() } public func update(isEditingCaptions: Bool, @@ -149,7 +153,9 @@ class AttachmentApprovalInputAccessoryView: UIView { guard self.isEditingCaptions != isEditingCaptions || self.currentAttachmentItem != currentAttachmentItem || self.shouldHideControls != shouldHideControls else { - return + + updateFirstResponder() + return } self.isEditingCaptions = isEditingCaptions @@ -168,6 +174,12 @@ class AttachmentApprovalInputAccessoryView: UIView { return CGSize.zero } } + + public var hasFirstResponder: Bool { + return (isFirstResponder || + attachmentCaptionToolbar.textView.isFirstResponder || + attachmentTextToolbar.textView.isFirstResponder) + } } // MARK: - diff --git a/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalViewController.swift b/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalViewController.swift index 569ca847a..dc837b294 100644 --- a/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalViewController.swift +++ b/SignalMessaging/ViewControllers/AttachmentApproval/AttachmentApprovalViewController.swift @@ -206,6 +206,12 @@ public class AttachmentApprovalViewController: UIPageViewController, UIPageViewC } let currentAttachmentItem: SignalAttachmentItem? = currentPageViewController?.attachmentItem + let hasPresentedView = self.presentedViewController != nil + let isToolbarFirstResponder = bottomToolView.hasFirstResponder + if !shouldHideControls, !isFirstResponder, !hasPresentedView, !isToolbarFirstResponder { + becomeFirstResponder() + } + bottomToolView.update(isEditingCaptions: isEditingCaptions, currentAttachmentItem: currentAttachmentItem, shouldHideControls: shouldHideControls) From 0d822597a12cf7e2aa4750ac463dfe0e7385eeee Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 28 Mar 2019 16:07:01 -0600 Subject: [PATCH 07/21] specify locale when timestamp parsing --- SignalServiceKit/src/Contacts/ContactDiscoveryService.m | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/SignalServiceKit/src/Contacts/ContactDiscoveryService.m b/SignalServiceKit/src/Contacts/ContactDiscoveryService.m index 1fe6c1dd7..38565bab8 100644 --- a/SignalServiceKit/src/Contacts/ContactDiscoveryService.m +++ b/SignalServiceKit/src/Contacts/ContactDiscoveryService.m @@ -624,6 +624,15 @@ NSError *ContactDiscoveryServiceErrorMakeWithReason(NSInteger code, NSString *re NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"]; [dateFormatter setTimeZone:timeZone]; [dateFormatter setDateFormat:@"yyy-MM-dd'T'HH:mm:ss.SSSSSS"]; + + // Specify parsing locale + // from: https://developer.apple.com/library/archive/qa/qa1480/_index.html + // Q: I'm using NSDateFormatter to parse an Internet-style date, but this fails for some users in some regions. + // I've set a specific date format string; shouldn't that force NSDateFormatter to work independently of the user's + // region settings? A: No. While setting a date format string will appear to work for most users, it's not the right + // solution to this problem. There are many places where format strings behave in unexpected ways. [...] + NSLocale *enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; + [dateFormatter setLocale:enUSPOSIXLocale]; NSDate *timestampDate = [dateFormatter dateFromString:signatureBodyEntity.timestamp]; if (!timestampDate) { OWSFailDebug(@"Could not parse signature body timestamp: %@", signatureBodyEntity.timestamp); From 5e52d66b05b35968cc2e104e96c494b424353e8d Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 28 Mar 2019 16:28:26 -0600 Subject: [PATCH 08/21] bump feedback endpoint --- SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m index ab4dd9017..68214a7d7 100644 --- a/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m +++ b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m @@ -516,7 +516,7 @@ NS_ASSUME_NONNULL_BEGIN } parameters = @{ @"reason": limitedReason }; } - NSString *path = [NSString stringWithFormat:@"/v1/directory/feedback-v2/%@", status]; + NSString *path = [NSString stringWithFormat:@"/v1/directory/feedback-v3/%@", status]; return [TSRequest requestWithUrl:[NSURL URLWithString:path] method:@"PUT" parameters:parameters]; } From 048f19c6b8f065d568bffc4f0ea2e475eaeaab58 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 28 Mar 2019 16:31:06 -0600 Subject: [PATCH 09/21] specify yyyy date format --- SignalServiceKit/src/Contacts/ContactDiscoveryService.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SignalServiceKit/src/Contacts/ContactDiscoveryService.m b/SignalServiceKit/src/Contacts/ContactDiscoveryService.m index 38565bab8..7c04e333e 100644 --- a/SignalServiceKit/src/Contacts/ContactDiscoveryService.m +++ b/SignalServiceKit/src/Contacts/ContactDiscoveryService.m @@ -623,7 +623,7 @@ NSError *ContactDiscoveryServiceErrorMakeWithReason(NSInteger code, NSString *re NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"]; [dateFormatter setTimeZone:timeZone]; - [dateFormatter setDateFormat:@"yyy-MM-dd'T'HH:mm:ss.SSSSSS"]; + [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSSSS"]; // Specify parsing locale // from: https://developer.apple.com/library/archive/qa/qa1480/_index.html From 5ed16355d78ea28472686f63e575839c4feefe15 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 29 Mar 2019 10:09:50 -0600 Subject: [PATCH 10/21] iOS9 needs a different assertion --- SignalServiceKit/src/Network/SSKWebSocket.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/SignalServiceKit/src/Network/SSKWebSocket.swift b/SignalServiceKit/src/Network/SSKWebSocket.swift index c5724b1c1..b72a680ad 100644 --- a/SignalServiceKit/src/Network/SSKWebSocket.swift +++ b/SignalServiceKit/src/Network/SSKWebSocket.swift @@ -146,8 +146,13 @@ extension SSKWebSocketImpl: WebSocketDelegate { case let wsError as WSError: websocketError = SSKWebSocketError(underlyingError: wsError) case let nsError as NSError: - let networkDownCode = 50 - assert(nsError.domain == "NSPOSIXErrorDomain" && nsError.code == networkDownCode) + // Assert that error is either a Starscream.WSError or an OS level networking error + if #available(iOS 10, *) { + let networkDownCode = 50 + assert(nsError.domain == "NSPOSIXErrorDomain" && nsError.code == networkDownCode) + } else { + assert(nsError.domain == kCFErrorDomainCFNetwork as String) + } websocketError = error default: assert(error == nil, "unexpected error type: \(String(describing: error))") From 05d8846f6c04e9dbf01c96dd04f6743cbdbf07fc Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 29 Mar 2019 10:56:04 -0600 Subject: [PATCH 11/21] match highlight behavior with search behavior --- Signal/src/ConversationSearch.swift | 3 ++- .../ConversationView/Cells/OWSMessageBubbleView.m | 8 +++++--- SignalServiceKit/src/Storage/FullTextSearchFinder.swift | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Signal/src/ConversationSearch.swift b/Signal/src/ConversationSearch.swift index ebfc27fe0..85cbc0085 100644 --- a/Signal/src/ConversationSearch.swift +++ b/Signal/src/ConversationSearch.swift @@ -82,11 +82,12 @@ extension ConversationSearchController: UISearchResultsUpdating { public func updateSearchResults(for searchController: UISearchController) { Logger.verbose("searchBar.text: \( searchController.searchBar.text ?? "")") - guard let searchText = searchController.searchBar.text?.stripped else { + guard let rawSearchText = searchController.searchBar.text?.stripped else { self.resultsBar.updateResults(resultSet: nil) self.delegate?.conversationSearchController(self, didUpdateSearchResults: nil) return } + let searchText = FullTextSearchFinder.normalize(text: rawSearchText) BenchManager.startEvent(title: "Conversation Search", eventId: searchText) guard searchText.count >= ConversationSearchController.kMinimumSearchTextLength else { diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m index d97b87c8f..1e87f7043 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m @@ -708,10 +708,12 @@ NS_ASSUME_NONNULL_BEGIN initWithString:text attributes:@{ NSFontAttributeName : font, NSForegroundColorAttributeName : textColor }]; if (searchText.length >= ConversationSearchController.kMinimumSearchTextLength) { + NSString *searchableText = [FullTextSearchFinder normalizeWithText:searchText]; NSError *error; - NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:searchText - options:NSRegularExpressionCaseInsensitive - error:&error]; + NSRegularExpression *regex = + [[NSRegularExpression alloc] initWithPattern:[NSRegularExpression escapedPatternForString:searchableText] + options:NSRegularExpressionCaseInsensitive + error:&error]; OWSAssertDebug(error == nil); for (NSTextCheckingResult *match in [regex matchesInString:text options:NSMatchingWithoutAnchoringBounds range:NSMakeRange(0, text.length)]) { diff --git a/SignalServiceKit/src/Storage/FullTextSearchFinder.swift b/SignalServiceKit/src/Storage/FullTextSearchFinder.swift index 00b64dd11..90d680ab8 100644 --- a/SignalServiceKit/src/Storage/FullTextSearchFinder.swift +++ b/SignalServiceKit/src/Storage/FullTextSearchFinder.swift @@ -138,6 +138,7 @@ public class FullTextSearchFinder: NSObject { // This is a hot method, especially while running large migrations. // Changes to it should go through a profiler to make sure large migrations // aren't adversely affected. + @objc public class func normalize(text: String) -> String { // 1. Filter out invalid characters. let filtered = text.removeCharacters(characterSet: charactersToRemove) From 5b77bc547547fcb062f9d1ffba463c8df648c75a Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 29 Mar 2019 11:07:15 -0600 Subject: [PATCH 12/21] sleep hack for iOS9 --- .../ConversationView/ConversationViewController.m | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index 05924083e..2860fcc93 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -4210,7 +4210,16 @@ typedef enum : NSUInteger { // restore first responder to VC [self becomeFirstResponder]; - [self reloadInputViews]; + if (@available(iOS 10, *)) { + [self reloadInputViews]; + } else { + // We want to change the inputAccessoryView from SearchResults -> MessageInput + // reloading too soon on an old iOS9 device caused the inputAccessoryView to go from + // SearchResults -> MessageInput -> SearchResults + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self reloadInputViews]; + }); + } } #pragma mark ConversationSearchControllerDelegate From 746fd278daf8ca5e4e5df4c31816ce0ad39d854f Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 29 Mar 2019 14:25:17 -0400 Subject: [PATCH 13/21] Restart typing indicators animations after app returns from background. --- Signal/src/views/TypingIndicatorView.swift | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Signal/src/views/TypingIndicatorView.swift b/Signal/src/views/TypingIndicatorView.swift index 4e3014519..a90200b19 100644 --- a/Signal/src/views/TypingIndicatorView.swift +++ b/Signal/src/views/TypingIndicatorView.swift @@ -38,8 +38,31 @@ self.axis = .horizontal self.spacing = kDotMaxHSpacing self.alignment = .center + + NotificationCenter.default.addObserver(self, + selector: #selector(didBecomeActive), + name: NSNotification.Name.OWSApplicationDidBecomeActive, + object: nil) } + deinit { + NotificationCenter.default.removeObserver(self) + } + + // MARK: - Notifications + + @objc func didBecomeActive() { + AssertIsOnMainThread() + + // CoreAnimation animations are stopped in the background, so ensure + // animations are restored if necessary. + if isAnimating { + startAnimation() + } + } + + // MARK: - + @objc public override func sizeThatFits(_ size: CGSize) -> CGSize { return CGSize(width: TypingIndicatorView.kMaxRadiusPt * 3 + kDotMaxHSpacing * 2, height: TypingIndicatorView.kMaxRadiusPt) @@ -49,8 +72,12 @@ return [dot1, dot2, dot3] } + private var isAnimating = false + @objc public func startAnimation() { + isAnimating = true + for dot in dots() { dot.startAnimation() } @@ -58,6 +85,8 @@ @objc public func stopAnimation() { + isAnimating = false + for dot in dots() { dot.stopAnimation() } From 8f7ad79506e46541c28c34875c1b999e2071e6b3 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 29 Mar 2019 14:11:47 -0400 Subject: [PATCH 14/21] Only update scroll state to reflect keyboard changes if view has appeared. --- .../ConversationView/ConversationViewController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index 2860fcc93..6ff11de17 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -3903,7 +3903,7 @@ typedef enum : NSUInteger { } else if (wasScrolledToBottom) { // If we were scrolled to the bottom, don't do any fancy math. Just stay at the bottom. [self scrollToBottomAnimated:NO]; - } else { + } else if (self.isViewCompletelyAppeared) { // If we were scrolled away from the bottom, shift the content in lockstep with the // keyboard, up to the limits of the content bounds. CGFloat insetChange = newInsets.bottom - oldInsets.bottom; From 2242dd240f9a56e234241eb23a70a3be21037ccf Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 29 Mar 2019 12:43:19 -0600 Subject: [PATCH 15/21] Fix "blank notification text" for oversize messages --- .../Notifications/AppNotifications.swift | 3 +- .../src/Messages/Interactions/TSMessage.m | 48 ++++++++----------- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/Signal/src/UserInterface/Notifications/AppNotifications.swift b/Signal/src/UserInterface/Notifications/AppNotifications.swift index e261a2418..4c2a4ba2f 100644 --- a/Signal/src/UserInterface/Notifications/AppNotifications.swift +++ b/Signal/src/UserInterface/Notifications/AppNotifications.swift @@ -137,8 +137,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocol { @objc public override init() { - let userNotificationsFeatureEnabled = true - if userNotificationsFeatureEnabled, #available(iOS 10, *) { + if #available(iOS 10, *) { self.adaptee = UserNotificationPresenterAdaptee() } else { self.adaptee = LegacyNotificationPresenterAdaptee() diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.m b/SignalServiceKit/src/Messages/Interactions/TSMessage.m index 8ccd7d19d..ddcbca82c 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.m @@ -315,38 +315,32 @@ static const NSUInteger OWSMessageSchemaVersion = 4; // TODO: This method contains view-specific logic and probably belongs in NotificationsManager, not in SSK. - (NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction -{ - NSString *_Nullable attachmentDescription = nil; - if ([self hasAttachments]) { - NSString *attachmentId = self.attachmentIds[0]; - TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction]; - if ([OWSMimeTypeOversizeTextMessage isEqualToString:attachment.contentType]) { - // Handle oversize text attachments. - if ([attachment isKindOfClass:[TSAttachmentStream class]]) { - TSAttachmentStream *attachmentStream = (TSAttachmentStream *)attachment; - NSData *_Nullable data = [NSData dataWithContentsOfFile:attachmentStream.originalFilePath]; - if (data) { - NSString *_Nullable text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - if (text) { - return text.filterStringForDisplay; - } - } - } - - return @""; - } else if (attachment) { - attachmentDescription = attachment.description; - } else { - attachmentDescription = NSLocalizedString(@"UNKNOWN_ATTACHMENT_LABEL", - @"In Inbox view, last message label for thread with corrupted attachment."); - } - } - +{ NSString *_Nullable bodyDescription = nil; if (self.body.length > 0) { bodyDescription = self.body; } + if (bodyDescription == nil) { + TSAttachment *_Nullable oversizeTextAttachment = [self oversizeTextAttachmentWithTransaction:transaction]; + if ([oversizeTextAttachment isKindOfClass:[TSAttachmentStream class]]) { + TSAttachmentStream *oversizeTextAttachmentStream = (TSAttachmentStream *)oversizeTextAttachment; + NSData *_Nullable data = [NSData dataWithContentsOfFile:oversizeTextAttachmentStream.originalFilePath]; + if (data) { + NSString *_Nullable text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if (text) { + bodyDescription = text.filterStringForDisplay; + } + } + } + } + + NSString *_Nullable attachmentDescription = nil; + TSAttachment *_Nullable mediaAttachment = [self mediaAttachmentsWithTransaction:transaction].firstObject; + if (mediaAttachment != nil) { + attachmentDescription = mediaAttachment.description; + } + if (attachmentDescription.length > 0 && bodyDescription.length > 0) { // Attachment with caption. if ([CurrentAppContext() isRTL]) { From 70b68f54128da03b4c795dbae2eeaeff48eb5547 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 29 Mar 2019 13:35:13 -0600 Subject: [PATCH 16/21] sync translations --- .../translations/ca.lproj/Localizable.strings | 20 +++++++++---------- .../translations/de.lproj/Localizable.strings | 2 +- .../translations/es.lproj/Localizable.strings | 2 +- .../translations/fr.lproj/Localizable.strings | 12 +++++------ .../translations/he.lproj/Localizable.strings | 20 +++++++++---------- .../translations/id.lproj/Localizable.strings | 4 ++-- .../translations/it.lproj/Localizable.strings | 2 +- .../translations/lt.lproj/Localizable.strings | 2 +- .../translations/nl.lproj/Localizable.strings | 4 ++-- .../translations/pl.lproj/Localizable.strings | 20 +++++++++---------- .../pt_PT.lproj/Localizable.strings | 2 +- .../translations/ro.lproj/Localizable.strings | 20 +++++++++---------- .../translations/ru.lproj/Localizable.strings | 18 ++++++++--------- .../translations/sq.lproj/Localizable.strings | 4 ++-- .../zh_CN.lproj/Localizable.strings | 2 +- .../zh_TW.lproj/Localizable.strings | 2 +- 16 files changed, 68 insertions(+), 68 deletions(-) diff --git a/Signal/translations/ca.lproj/Localizable.strings b/Signal/translations/ca.lproj/Localizable.strings index c484b8d1b..f3864f93c 100644 --- a/Signal/translations/ca.lproj/Localizable.strings +++ b/Signal/translations/ca.lproj/Localizable.strings @@ -96,7 +96,7 @@ "ATTACHMENT_APPROVAL_CAPTION_PLACEHOLDER" = "Afegeix una descripció..."; /* Title for 'caption' mode of the attachment approval view. */ -"ATTACHMENT_APPROVAL_CAPTION_TITLE" = "Caption"; +"ATTACHMENT_APPROVAL_CAPTION_TITLE" = "Títol"; /* Format string for file extension label in call interstitial view */ "ATTACHMENT_APPROVAL_FILE_EXTENSION_FORMAT" = "Tipus de fitxer: %@"; @@ -351,7 +351,7 @@ "CALL_VIEW_DECLINE_INCOMING_CALL_LABEL" = "Rebutja trucades"; /* tooltip label when remote party has enabled their video */ -"CALL_VIEW_ENABLE_VIDEO_HINT" = "Tap here to turn on your video"; +"CALL_VIEW_ENABLE_VIDEO_HINT" = "Toqueu aquí per activar el vídeo"; /* Accessibility label for hang up call */ "CALL_VIEW_HANGUP_LABEL" = "Finalitza la trucada"; @@ -564,13 +564,13 @@ "CONVERSATION_DELETE_CONFIRMATION_ALERT_TITLE" = "Esborrar conversa?"; /* keyboard toolbar label when no messages match the search string */ -"CONVERSATION_SEARCH_NO_RESULTS" = "No matches"; +"CONVERSATION_SEARCH_NO_RESULTS" = "Sense coincidències"; /* keyboard toolbar label when exactly 1 message matches the search string */ -"CONVERSATION_SEARCH_ONE_RESULT" = "1 match"; +"CONVERSATION_SEARCH_ONE_RESULT" = "1 coincidència"; /* keyboard toolbar label when more than 1 message matches the search string. Embeds {{number/position of the 'currently viewed' result}} and the {{total number of results}} */ -"CONVERSATION_SEARCH_RESULTS_FORMAT" = "%d of %d matches"; +"CONVERSATION_SEARCH_RESULTS_FORMAT" = "%d de %d coincidències"; /* title for conversation settings screen */ "CONVERSATION_SETTINGS" = "Configuració del xat"; @@ -624,7 +624,7 @@ "CONVERSATION_SETTINGS_NEW_CONTACT" = "Crea un contacte nou"; /* Table cell label in conversation settings which returns the user to the conversation with 'search mode' activated */ -"CONVERSATION_SETTINGS_SEARCH" = "Search Conversation"; +"CONVERSATION_SETTINGS_SEARCH" = "Cerca la conversa"; /* Label for button that opens conversation settings. */ "CONVERSATION_SETTINGS_TAP_TO_CHANGE" = "Toca per canviar"; @@ -1641,13 +1641,13 @@ "PHONE_NUMBER_TYPE_WORK_FAX" = "Fax de la feina"; /* alert title, generic error preventing user from capturing a photo */ -"PHOTO_CAPTURE_GENERIC_ERROR" = "Unable to capture image."; +"PHOTO_CAPTURE_GENERIC_ERROR" = "No s'ha pogut capturar la imatge."; /* alert title */ -"PHOTO_CAPTURE_UNABLE_TO_CAPTURE_IMAGE" = "Unable to capture image."; +"PHOTO_CAPTURE_UNABLE_TO_CAPTURE_IMAGE" = "No s'ha pogut capturar la imatge."; /* alert title */ -"PHOTO_CAPTURE_UNABLE_TO_INITIALIZE_CAMERA" = "Failed to configure camera."; +"PHOTO_CAPTURE_UNABLE_TO_INITIALIZE_CAMERA" = "Ha fallat configurar la càmera."; /* label for system photo collections which have no name. */ "PHOTO_PICKER_UNNAMED_COLLECTION" = "Àlbum sense nom"; @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Telefonades de Vídeo Segures!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "El Signal necessitarà aviat l'iOS 10 o posterior. Actualitzeu-lo a la Configuració del sistema >> General >> Actualitzacions."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "Actualitzeu l'iOS"; diff --git a/Signal/translations/de.lproj/Localizable.strings b/Signal/translations/de.lproj/Localizable.strings index 27bb3decd..397d3482f 100644 --- a/Signal/translations/de.lproj/Localizable.strings +++ b/Signal/translations/de.lproj/Localizable.strings @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Hallo, sichere Videoanrufe!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Signal wird bald iOS 10 oder neuer erfordern. Bitte aktualisieren über die iOS-Einstellungen: Einstellungen >> Allgemein >> Softwareaktualisierung."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "iOS aktualisieren"; diff --git a/Signal/translations/es.lproj/Localizable.strings b/Signal/translations/es.lproj/Localizable.strings index f87fef377..05df85c82 100644 --- a/Signal/translations/es.lproj/Localizable.strings +++ b/Signal/translations/es.lproj/Localizable.strings @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "¡Saluda a las vídeollamadas seguras!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Signal próximamente solo funcionará en iOS 10 o versiones posteriores. Actualiza en Ajustes >> General >> Actualización de software."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "Actualizar iOS"; diff --git a/Signal/translations/fr.lproj/Localizable.strings b/Signal/translations/fr.lproj/Localizable.strings index 66349d1b9..9e93e7e4d 100644 --- a/Signal/translations/fr.lproj/Localizable.strings +++ b/Signal/translations/fr.lproj/Localizable.strings @@ -351,7 +351,7 @@ "CALL_VIEW_DECLINE_INCOMING_CALL_LABEL" = "Refuser l’appel entrant"; /* tooltip label when remote party has enabled their video */ -"CALL_VIEW_ENABLE_VIDEO_HINT" = "Tap here to turn on your video"; +"CALL_VIEW_ENABLE_VIDEO_HINT" = "Touchez ici pour activer votre caméra"; /* Accessibility label for hang up call */ "CALL_VIEW_HANGUP_LABEL" = "Raccrocher"; @@ -567,7 +567,7 @@ "CONVERSATION_SEARCH_NO_RESULTS" = "Aucune correspondance"; /* keyboard toolbar label when exactly 1 message matches the search string */ -"CONVERSATION_SEARCH_ONE_RESULT" = "1 match"; +"CONVERSATION_SEARCH_ONE_RESULT" = "1 correspondance"; /* keyboard toolbar label when more than 1 message matches the search string. Embeds {{number/position of the 'currently viewed' result}} and the {{total number of results}} */ "CONVERSATION_SEARCH_RESULTS_FORMAT" = "%d sur %dcorrespondances"; @@ -1641,13 +1641,13 @@ "PHONE_NUMBER_TYPE_WORK_FAX" = "Télécopieur travail"; /* alert title, generic error preventing user from capturing a photo */ -"PHOTO_CAPTURE_GENERIC_ERROR" = "Unable to capture image."; +"PHOTO_CAPTURE_GENERIC_ERROR" = "Impossible de capturer l’image."; /* alert title */ -"PHOTO_CAPTURE_UNABLE_TO_CAPTURE_IMAGE" = "Unable to capture image."; +"PHOTO_CAPTURE_UNABLE_TO_CAPTURE_IMAGE" = "Impossible de capturer l’image."; /* alert title */ -"PHOTO_CAPTURE_UNABLE_TO_INITIALIZE_CAMERA" = "Failed to configure camera."; +"PHOTO_CAPTURE_UNABLE_TO_INITIALIZE_CAMERA" = "Échec de configuration de l’appareil photo"; /* label for system photo collections which have no name. */ "PHOTO_PICKER_UNNAMED_COLLECTION" = "Album sans nom"; @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Bienvenue aux appels vidéo sécurisés !"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Bientôt, Signal exigera iOS 10 ou ultérieure. Veuillez effectuer une mise à niveau dans l’appli Réglage >> Général >> Mise à jour logicielle"; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "Mettez iOS à niveau"; diff --git a/Signal/translations/he.lproj/Localizable.strings b/Signal/translations/he.lproj/Localizable.strings index 9390e90fc..2f65d5746 100644 --- a/Signal/translations/he.lproj/Localizable.strings +++ b/Signal/translations/he.lproj/Localizable.strings @@ -96,7 +96,7 @@ "ATTACHMENT_APPROVAL_CAPTION_PLACEHOLDER" = "הוסף כיתוב..."; /* Title for 'caption' mode of the attachment approval view. */ -"ATTACHMENT_APPROVAL_CAPTION_TITLE" = "Caption"; +"ATTACHMENT_APPROVAL_CAPTION_TITLE" = "כיתוב"; /* Format string for file extension label in call interstitial view */ "ATTACHMENT_APPROVAL_FILE_EXTENSION_FORMAT" = "סוג קובץ: %@"; @@ -351,7 +351,7 @@ "CALL_VIEW_DECLINE_INCOMING_CALL_LABEL" = "דחה שיחה נכנסת"; /* tooltip label when remote party has enabled their video */ -"CALL_VIEW_ENABLE_VIDEO_HINT" = "Tap here to turn on your video"; +"CALL_VIEW_ENABLE_VIDEO_HINT" = "הקש כאן כדי להפעיל את הוידיאו שלך"; /* Accessibility label for hang up call */ "CALL_VIEW_HANGUP_LABEL" = "סיים שיחה"; @@ -564,13 +564,13 @@ "CONVERSATION_DELETE_CONFIRMATION_ALERT_TITLE" = "למחוק שיחה?"; /* keyboard toolbar label when no messages match the search string */ -"CONVERSATION_SEARCH_NO_RESULTS" = "No matches"; +"CONVERSATION_SEARCH_NO_RESULTS" = "אין התאמות"; /* keyboard toolbar label when exactly 1 message matches the search string */ -"CONVERSATION_SEARCH_ONE_RESULT" = "1 match"; +"CONVERSATION_SEARCH_ONE_RESULT" = "התאמה 1"; /* keyboard toolbar label when more than 1 message matches the search string. Embeds {{number/position of the 'currently viewed' result}} and the {{total number of results}} */ -"CONVERSATION_SEARCH_RESULTS_FORMAT" = "%d of %d matches"; +"CONVERSATION_SEARCH_RESULTS_FORMAT" = "%d מתוך %d התאמות"; /* title for conversation settings screen */ "CONVERSATION_SETTINGS" = "הגדרות שיחה"; @@ -624,7 +624,7 @@ "CONVERSATION_SETTINGS_NEW_CONTACT" = "צור איש קשר חדש"; /* Table cell label in conversation settings which returns the user to the conversation with 'search mode' activated */ -"CONVERSATION_SETTINGS_SEARCH" = "Search Conversation"; +"CONVERSATION_SETTINGS_SEARCH" = "חפש שיחה"; /* Label for button that opens conversation settings. */ "CONVERSATION_SETTINGS_TAP_TO_CHANGE" = "הקש כדי לשנות"; @@ -1641,13 +1641,13 @@ "PHONE_NUMBER_TYPE_WORK_FAX" = "פקס עבודה"; /* alert title, generic error preventing user from capturing a photo */ -"PHOTO_CAPTURE_GENERIC_ERROR" = "Unable to capture image."; +"PHOTO_CAPTURE_GENERIC_ERROR" = "לא היה ניתן ללכוד תמונה."; /* alert title */ -"PHOTO_CAPTURE_UNABLE_TO_CAPTURE_IMAGE" = "Unable to capture image."; +"PHOTO_CAPTURE_UNABLE_TO_CAPTURE_IMAGE" = "לא היה ניתן ללכוד תמונה."; /* alert title */ -"PHOTO_CAPTURE_UNABLE_TO_INITIALIZE_CAMERA" = "Failed to configure camera."; +"PHOTO_CAPTURE_UNABLE_TO_INITIALIZE_CAMERA" = "נכשל בתיצור מצלמה."; /* label for system photo collections which have no name. */ "PHOTO_PICKER_UNNAMED_COLLECTION" = "אלבום ללא שם"; @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "שלום שיחות וידיאו מאובטחות!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Signal ידרוש בקרוב iOS 10 ומעלה. אנא שדרג דרך יישום הגדרות >> כללי >> עדכוני תוכנה."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "שדרג את iOS"; diff --git a/Signal/translations/id.lproj/Localizable.strings b/Signal/translations/id.lproj/Localizable.strings index 3b6ea43e4..a74a16caf 100644 --- a/Signal/translations/id.lproj/Localizable.strings +++ b/Signal/translations/id.lproj/Localizable.strings @@ -1524,7 +1524,7 @@ "ONBOARDING_PERMISSIONS_TITLE" = "Signal can let you know when you get a message (and who it is from)"; /* Title of the 'onboarding phone number' view. */ -"ONBOARDING_PHONE_NUMBER_TITLE" = "Enter your phone number to get started"; +"ONBOARDING_PHONE_NUMBER_TITLE" = "masukkan nomor telepon untuk memulai"; /* Label indicating that the phone number is invalid in the 'onboarding phone number' view. */ "ONBOARDING_PHONE_NUMBER_VALIDATION_WARNING" = "Nomor salah"; @@ -1536,7 +1536,7 @@ "ONBOARDING_PROFILE_NAME_PLACEHOLDER" = "Your Name"; /* Title of the 'onboarding profile' view. */ -"ONBOARDING_PROFILE_TITLE" = "Set up your profile"; +"ONBOARDING_PROFILE_TITLE" = "Siapkan profil Anda"; /* Link to the 'terms and privacy policy' in the 'onboarding splash' view. */ "ONBOARDING_SPLASH_TERM_AND_PRIVACY_POLICY" = "Syarat & Kebijakan Privasi"; diff --git a/Signal/translations/it.lproj/Localizable.strings b/Signal/translations/it.lproj/Localizable.strings index 2aed973d0..d5955b7ec 100644 --- a/Signal/translations/it.lproj/Localizable.strings +++ b/Signal/translations/it.lproj/Localizable.strings @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Videochiamate sicure!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Signal presto richiederà iOS 10 o successivo. Ti preghiamo di aggiornare andando nelle Impostazioni >> Generali >> Aggiornamento software."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "Aggiornare iOS"; diff --git a/Signal/translations/lt.lproj/Localizable.strings b/Signal/translations/lt.lproj/Localizable.strings index dc56746a6..49513dece 100644 --- a/Signal/translations/lt.lproj/Localizable.strings +++ b/Signal/translations/lt.lproj/Localizable.strings @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Sveiki, saugūs vaizdo skambučiai!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Signal greitu metu reikalaus iOS 10 ar naujesnės. Atsinaujinkite Nustatymų (angl. Settings) programėlėje >> Bendra (angl. General) >> Programinės įrangos atnaujinimas (angl. Software Update)."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "Atnaujinkite iOS"; diff --git a/Signal/translations/nl.lproj/Localizable.strings b/Signal/translations/nl.lproj/Localizable.strings index be5964c2a..3f0c5c6c8 100644 --- a/Signal/translations/nl.lproj/Localizable.strings +++ b/Signal/translations/nl.lproj/Localizable.strings @@ -2253,7 +2253,7 @@ "SETTINGS_UNIDENTIFIED_DELIVERY_SECTION_TITLE" = "Verzegelde afzender"; /* switch label */ -"SETTINGS_UNIDENTIFIED_DELIVERY_SHOW_INDICATORS" = "Indicator tonen"; +"SETTINGS_UNIDENTIFIED_DELIVERY_SHOW_INDICATORS" = "Toon verzegelde afzender indicator"; /* table section footer */ "SETTINGS_UNIDENTIFIED_DELIVERY_SHOW_INDICATORS_FOOTER" = "Laat een statuspictogram zien wanneer je drukt op ‘Meer informatie’ bij berichten die zijn afgeleverd met een verzegelde afzender."; @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Hallo, beveiligde videogesprekken!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Binnenkort vereist Signal dat je iOS 10 of een latere versie gebruikt. Werk je besturingssysteem bij in Instellingen >> Algemeen >> Software-update."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "Werk iOS bij"; diff --git a/Signal/translations/pl.lproj/Localizable.strings b/Signal/translations/pl.lproj/Localizable.strings index 6c65ebc51..b52e06fb3 100644 --- a/Signal/translations/pl.lproj/Localizable.strings +++ b/Signal/translations/pl.lproj/Localizable.strings @@ -96,7 +96,7 @@ "ATTACHMENT_APPROVAL_CAPTION_PLACEHOLDER" = "Dodaj podpis..."; /* Title for 'caption' mode of the attachment approval view. */ -"ATTACHMENT_APPROVAL_CAPTION_TITLE" = "Caption"; +"ATTACHMENT_APPROVAL_CAPTION_TITLE" = "Podpis"; /* Format string for file extension label in call interstitial view */ "ATTACHMENT_APPROVAL_FILE_EXTENSION_FORMAT" = "Typ pliku: %@"; @@ -351,7 +351,7 @@ "CALL_VIEW_DECLINE_INCOMING_CALL_LABEL" = "Odrzuć połączenie przychodzące"; /* tooltip label when remote party has enabled their video */ -"CALL_VIEW_ENABLE_VIDEO_HINT" = "Tap here to turn on your video"; +"CALL_VIEW_ENABLE_VIDEO_HINT" = "Dotknij tutaj, aby włączyć wideo"; /* Accessibility label for hang up call */ "CALL_VIEW_HANGUP_LABEL" = "Zakończ rozmowę "; @@ -564,13 +564,13 @@ "CONVERSATION_DELETE_CONFIRMATION_ALERT_TITLE" = "Usunąć konwersację?"; /* keyboard toolbar label when no messages match the search string */ -"CONVERSATION_SEARCH_NO_RESULTS" = "No matches"; +"CONVERSATION_SEARCH_NO_RESULTS" = "Brak wyników"; /* keyboard toolbar label when exactly 1 message matches the search string */ -"CONVERSATION_SEARCH_ONE_RESULT" = "1 match"; +"CONVERSATION_SEARCH_ONE_RESULT" = "1 wynik"; /* keyboard toolbar label when more than 1 message matches the search string. Embeds {{number/position of the 'currently viewed' result}} and the {{total number of results}} */ -"CONVERSATION_SEARCH_RESULTS_FORMAT" = "%d of %d matches"; +"CONVERSATION_SEARCH_RESULTS_FORMAT" = "%d z %d wyników"; /* title for conversation settings screen */ "CONVERSATION_SETTINGS" = "Ustawienia konwersacji"; @@ -624,7 +624,7 @@ "CONVERSATION_SETTINGS_NEW_CONTACT" = "Utwórz nowy kontakt"; /* Table cell label in conversation settings which returns the user to the conversation with 'search mode' activated */ -"CONVERSATION_SETTINGS_SEARCH" = "Search Conversation"; +"CONVERSATION_SETTINGS_SEARCH" = "Szukaj w konwersacji"; /* Label for button that opens conversation settings. */ "CONVERSATION_SETTINGS_TAP_TO_CHANGE" = "Dotknij, by zmienić"; @@ -1641,13 +1641,13 @@ "PHONE_NUMBER_TYPE_WORK_FAX" = "Fax w pracy"; /* alert title, generic error preventing user from capturing a photo */ -"PHOTO_CAPTURE_GENERIC_ERROR" = "Unable to capture image."; +"PHOTO_CAPTURE_GENERIC_ERROR" = "Nie można wykonać zdjęcia."; /* alert title */ -"PHOTO_CAPTURE_UNABLE_TO_CAPTURE_IMAGE" = "Unable to capture image."; +"PHOTO_CAPTURE_UNABLE_TO_CAPTURE_IMAGE" = "Nie można wykonać zdjęcia."; /* alert title */ -"PHOTO_CAPTURE_UNABLE_TO_INITIALIZE_CAMERA" = "Failed to configure camera."; +"PHOTO_CAPTURE_UNABLE_TO_INITIALIZE_CAMERA" = "Nie można skonfigurować kamery."; /* label for system photo collections which have no name. */ "PHOTO_PICKER_UNNAMED_COLLECTION" = "Album bez nazwy"; @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Szyfrowane wideo rozmowy witają!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Signal wkrótce będzie wymagał systemu iOS 10 lub nowszego. Zaktualizuj system przechodząc do Ustawienia >> Ogólne >> Aktualizacja oprogramowania."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "Uaktualnij iOS"; diff --git a/Signal/translations/pt_PT.lproj/Localizable.strings b/Signal/translations/pt_PT.lproj/Localizable.strings index d5f5f2b57..86789f7f9 100644 --- a/Signal/translations/pt_PT.lproj/Localizable.strings +++ b/Signal/translations/pt_PT.lproj/Localizable.strings @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Olá videochamadas seguras!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "O Signal brevemente irá requerer o iOS 10 ou superior. Por favor atualize em Definições >> Geral >> Atualização de Software."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "Atualizar iOS"; diff --git a/Signal/translations/ro.lproj/Localizable.strings b/Signal/translations/ro.lproj/Localizable.strings index 3d92b9df3..cedb11182 100644 --- a/Signal/translations/ro.lproj/Localizable.strings +++ b/Signal/translations/ro.lproj/Localizable.strings @@ -96,7 +96,7 @@ "ATTACHMENT_APPROVAL_CAPTION_PLACEHOLDER" = "Adaugă un titlu..."; /* Title for 'caption' mode of the attachment approval view. */ -"ATTACHMENT_APPROVAL_CAPTION_TITLE" = "Caption"; +"ATTACHMENT_APPROVAL_CAPTION_TITLE" = "Titlu"; /* Format string for file extension label in call interstitial view */ "ATTACHMENT_APPROVAL_FILE_EXTENSION_FORMAT" = "Tip fișier: %@"; @@ -351,7 +351,7 @@ "CALL_VIEW_DECLINE_INCOMING_CALL_LABEL" = "Respingeți apelul de intrare"; /* tooltip label when remote party has enabled their video */ -"CALL_VIEW_ENABLE_VIDEO_HINT" = "Tap here to turn on your video"; +"CALL_VIEW_ENABLE_VIDEO_HINT" = "Apăsați aici pentru a porni video-ul tău"; /* Accessibility label for hang up call */ "CALL_VIEW_HANGUP_LABEL" = "Închideți apelul"; @@ -564,13 +564,13 @@ "CONVERSATION_DELETE_CONFIRMATION_ALERT_TITLE" = "Șterg conversația?"; /* keyboard toolbar label when no messages match the search string */ -"CONVERSATION_SEARCH_NO_RESULTS" = "No matches"; +"CONVERSATION_SEARCH_NO_RESULTS" = "Nici o potrivire"; /* keyboard toolbar label when exactly 1 message matches the search string */ -"CONVERSATION_SEARCH_ONE_RESULT" = "1 match"; +"CONVERSATION_SEARCH_ONE_RESULT" = "1 potrivire"; /* keyboard toolbar label when more than 1 message matches the search string. Embeds {{number/position of the 'currently viewed' result}} and the {{total number of results}} */ -"CONVERSATION_SEARCH_RESULTS_FORMAT" = "%d of %d matches"; +"CONVERSATION_SEARCH_RESULTS_FORMAT" = "%d din %d potriviri"; /* title for conversation settings screen */ "CONVERSATION_SETTINGS" = "Setări conversație"; @@ -624,7 +624,7 @@ "CONVERSATION_SETTINGS_NEW_CONTACT" = "Creează contact nou"; /* Table cell label in conversation settings which returns the user to the conversation with 'search mode' activated */ -"CONVERSATION_SETTINGS_SEARCH" = "Search Conversation"; +"CONVERSATION_SETTINGS_SEARCH" = "Caută conversație"; /* Label for button that opens conversation settings. */ "CONVERSATION_SETTINGS_TAP_TO_CHANGE" = "Apasă pentru a modifica"; @@ -1641,13 +1641,13 @@ "PHONE_NUMBER_TYPE_WORK_FAX" = "Fax serviciu"; /* alert title, generic error preventing user from capturing a photo */ -"PHOTO_CAPTURE_GENERIC_ERROR" = "Unable to capture image."; +"PHOTO_CAPTURE_GENERIC_ERROR" = "Imaginea nu a putut fi capturată."; /* alert title */ -"PHOTO_CAPTURE_UNABLE_TO_CAPTURE_IMAGE" = "Unable to capture image."; +"PHOTO_CAPTURE_UNABLE_TO_CAPTURE_IMAGE" = "Imaginea nu a putut fi capturată."; /* alert title */ -"PHOTO_CAPTURE_UNABLE_TO_INITIALIZE_CAMERA" = "Failed to configure camera."; +"PHOTO_CAPTURE_UNABLE_TO_INITIALIZE_CAMERA" = "Eroare la configurarea camerei."; /* label for system photo collections which have no name. */ "PHOTO_PICKER_UNNAMED_COLLECTION" = "Album fără nume"; @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Bun venit la apeluri video securizate!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Signal va necesita în curând iOS 10 sau o versiune mai nouă. Vă rugăm să actualizați din aplicația Setări >> General >> Actualizări Software."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "Actualizează-ți iOS-ul"; diff --git a/Signal/translations/ru.lproj/Localizable.strings b/Signal/translations/ru.lproj/Localizable.strings index 7dee18460..f921301e3 100644 --- a/Signal/translations/ru.lproj/Localizable.strings +++ b/Signal/translations/ru.lproj/Localizable.strings @@ -459,7 +459,7 @@ "CONFIRM_LINK_NEW_DEVICE_ACTION" = "Привязать устройство"; /* Action sheet body presented when a user's SN has recently changed. Embeds {{contact's name or phone number}} */ -"CONFIRM_SENDING_TO_CHANGED_IDENTITY_BODY_FORMAT" = "%@ мог переустановить Signal или сменить устройство. Сверьте ваши коды безопасности для того, чтобы убедиться в конфиденциальности общения."; +"CONFIRM_SENDING_TO_CHANGED_IDENTITY_BODY_FORMAT" = "%@ мог(-ла) переустановить Signal или сменить устройство. Сверьте ваши коды безопасности для того, чтобы убедиться в конфиденциальности общения."; /* Action sheet title presented when a user's SN has recently changed. Embeds {{contact's name or phone number}} */ "CONFIRM_SENDING_TO_CHANGED_IDENTITY_TITLE_FORMAT" = "Код безопасности с %@ изменился"; @@ -940,7 +940,7 @@ "ERROR_MESSAGE_UNKNOWN_ERROR" = "Неизвестная ошибка."; /* No comment provided by engineer. */ -"ERROR_MESSAGE_WRONG_TRUSTED_IDENTITY_KEY" = "Код безопасности изменился"; +"ERROR_MESSAGE_WRONG_TRUSTED_IDENTITY_KEY" = "Код безопасности изменился."; /* Format string for 'unregistered user' error. Embeds {{the unregistered user's name or signal id}}. */ "ERROR_UNREGISTERED_USER_FORMAT" = "Незарегистрированный пользователь: %@"; @@ -1674,7 +1674,7 @@ "PRIVACY_UNVERIFY_BUTTON" = "Сбросить проверку"; /* Alert body when verifying with {{contact name}} */ -"PRIVACY_VERIFICATION_FAILED_I_HAVE_WRONG_KEY_FOR_THEM" = "Это не код безопасности для %@. Убедитесь, что подтверждаете соединение с верным пользователем."; +"PRIVACY_VERIFICATION_FAILED_I_HAVE_WRONG_KEY_FOR_THEM" = "Это не код безопасности для %@. Убедитесь, что вы подтверждаете верного пользователя."; /* Alert body */ "PRIVACY_VERIFICATION_FAILED_MISMATCHED_SAFETY_NUMBERS_IN_CLIPBOARD" = "Содержимое буфера обмена не является кодом безопасности для данного собеседника."; @@ -1908,10 +1908,10 @@ "SAFETY_NUMBER_CHANGED_CONFIRM_SEND_ACTION" = "Отправить в любом случае"; /* Snippet to share {{safety number}} with a friend. sent e.g. via SMS */ -"SAFETY_NUMBER_SHARE_FORMAT" = "Наш код безопасности:\n%@"; +"SAFETY_NUMBER_SHARE_FORMAT" = "Наш код безопасности Signal:\n%@"; /* Action sheet heading */ -"SAFETY_NUMBERS_ACTIONSHEET_TITLE" = "Код безопасности с пользователем %@ изменился. Возможно, вы хотите его подтвердить."; +"SAFETY_NUMBERS_ACTIONSHEET_TITLE" = "Код безопасности с %@ изменился. Возможно, вы хотите его подтвердить."; /* label presented once scanning (camera) view is visible. */ "SCAN_CODE_INSTRUCTIONS" = "Отсканируйте QR-код на устройстве пользователя."; @@ -2325,7 +2325,7 @@ "SUCCESSFUL_VERIFICATION_TITLE" = "Коды безопасности совпадают!"; /* Label for button to verify a user's safety number. */ -"SYSTEM_MESSAGE_ACTION_VERIFY_SAFETY_NUMBER" = "Верифицировать код безопасности"; +"SYSTEM_MESSAGE_ACTION_VERIFY_SAFETY_NUMBER" = "Подтвердить код безопасности"; /* {{number of days}} embedded in strings, e.g. 'Alice updated disappearing messages expiration to {{5 days}}'. See other *_TIME_AMOUNT strings */ "TIME_AMOUNT_DAYS" = "%@ дней"; @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Добро пожаловать в видеозвонки!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "В скором времени Signal будет работать только на iOS 10 и выше. Пожалуйста, обновите iOS, перейдя в приложение Настройки >> Основные >> Обновление ПО."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "Обновите IOS"; @@ -2505,10 +2505,10 @@ "VERIFICATION_STATE_CHANGE_GENERIC" = "Состояние проверки изменено."; /* Label for button or row which allows users to verify the safety number of another user. */ -"VERIFY_PRIVACY" = "Посмотреть номер безопасности"; +"VERIFY_PRIVACY" = "Просмотреть код безопасности"; /* Label for button or row which allows users to verify the safety numbers of multiple users. */ -"VERIFY_PRIVACY_MULTIPLE" = "Просмотр кодов безопасности"; +"VERIFY_PRIVACY_MULTIPLE" = "Проверить коды безопасности"; /* Indicates how to cancel a voice message. */ "VOICE_MESSAGE_CANCEL_INSTRUCTIONS" = "Проведите для отмены"; diff --git a/Signal/translations/sq.lproj/Localizable.strings b/Signal/translations/sq.lproj/Localizable.strings index be4541b40..777308ab1 100644 --- a/Signal/translations/sq.lproj/Localizable.strings +++ b/Signal/translations/sq.lproj/Localizable.strings @@ -90,7 +90,7 @@ "ATTACHMENT" = "Bashkëngjitje"; /* One-line label indicating the user can add no more text to the attachment caption. */ -"ATTACHMENT_APPROVAL_CAPTION_LENGTH_LIMIT_REACHED" = "U mbërrrit në kufi përshkrimes."; +"ATTACHMENT_APPROVAL_CAPTION_LENGTH_LIMIT_REACHED" = "U mbërrrit në kufi përshkrimesh."; /* placeholder text for an empty captioning field */ "ATTACHMENT_APPROVAL_CAPTION_PLACEHOLDER" = "Shtoni një përshkrim…"; @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Tungjatjeta Thirrjeve Video të Sigurta!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Signal-i së shpejti do të dojë iOS 10 ose të mëvonshëm. Ju lutemi, përmirësojeni që nga aplikacioni Rregullime >> Të përgjithshme >> Përditësim Software-i."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "Përmirësoni iOS-in"; diff --git a/Signal/translations/zh_CN.lproj/Localizable.strings b/Signal/translations/zh_CN.lproj/Localizable.strings index 1ca986678..7d7ecdc5f 100644 --- a/Signal/translations/zh_CN.lproj/Localizable.strings +++ b/Signal/translations/zh_CN.lproj/Localizable.strings @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "现推出安全的视频通话!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Signal 即将仅支持 iOS 10 或更新的系统版本。请到 设置 >> 通用 >> 软件更新 升级 iOS。"; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "升级 iOS"; diff --git a/Signal/translations/zh_TW.lproj/Localizable.strings b/Signal/translations/zh_TW.lproj/Localizable.strings index f5f3f953e..ba66a5d17 100644 --- a/Signal/translations/zh_TW.lproj/Localizable.strings +++ b/Signal/translations/zh_TW.lproj/Localizable.strings @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "現推出安全的視訊通話!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Signal 將要求 iOS 10 以上才能使用。請在 \"設定\" >> \"一般\" >> \"軟體更新\" 中升級。"; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "更新 iOS"; From 6c4dbfbc4c6623db0e8f31e103a5941f748e05b5 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 29 Mar 2019 13:35:35 -0600 Subject: [PATCH 17/21] "Bump build to 2.38.0.10." --- Signal/Signal-Info.plist | 2 +- SignalShareExtension/Info.plist | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist index e33e14b84..a22f827d3 100644 --- a/Signal/Signal-Info.plist +++ b/Signal/Signal-Info.plist @@ -47,7 +47,7 @@ CFBundleVersion - 2.38.0.9 + 2.38.0.10 ITSAppUsesNonExemptEncryption LOGS_EMAIL diff --git a/SignalShareExtension/Info.plist b/SignalShareExtension/Info.plist index 08f7b0a94..9c5fe74cd 100644 --- a/SignalShareExtension/Info.plist +++ b/SignalShareExtension/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 2.38.0 CFBundleVersion - 2.38.0.9 + 2.38.0.10 ITSAppUsesNonExemptEncryption NSAppTransportSecurity From e42192624f47f6d6fd88276b1eb4489c584575bd Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 29 Mar 2019 15:43:08 -0600 Subject: [PATCH 18/21] fixup tests --- SignalServiceKit/tests/Messages/OWSLinkPreviewTest.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SignalServiceKit/tests/Messages/OWSLinkPreviewTest.swift b/SignalServiceKit/tests/Messages/OWSLinkPreviewTest.swift index 79d93e0d0..f6e0c86e5 100644 --- a/SignalServiceKit/tests/Messages/OWSLinkPreviewTest.swift +++ b/SignalServiceKit/tests/Messages/OWSLinkPreviewTest.swift @@ -213,11 +213,11 @@ class OWSLinkPreviewTest: SSKBaseTestSwift { let expectation = self.expectation(description: "link download and parsing") OWSLinkPreview.tryToBuildPreviewInfo(previewUrl: "https://www.youtube.com/watch?v=tP-Ipsat90c") - .done { (draft) in + .done { (draft: OWSLinkPreviewDraft) in XCTAssertNotNil(draft) XCTAssertEqual(draft.title, "Randomness is Random - Numberphile") - XCTAssertNotNil(draft.imageFilePath) + XCTAssertNotNil(draft.jpegImageData) expectation.fulfill() }.catch { (error) in From e69494450b0ce05c63bd16f90b6830b5ed5a7627 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Mon, 1 Apr 2019 13:56:20 -0600 Subject: [PATCH 19/21] put conversation search behind feature flag --- .../OWSConversationSettingsViewController.m | 31 ++++++++++--------- SignalServiceKit/src/Util/FeatureFlags.swift | 5 +++ 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index 1cc654e74..d18d868b3 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -371,21 +371,22 @@ const CGFloat kIconViewLength = 24; [weakSelf showMediaGallery]; }]]; - // TODO icon - [mainSection addItem:[OWSTableItem - itemWithCustomCellBlock:^{ - NSString *title = NSLocalizedString(@"CONVERSATION_SETTINGS_SEARCH", - @"Table cell label in conversation settings which returns the user to the " - @"conversation with 'search mode' activated"); - return [weakSelf - disclosureCellWithName:title - iconName:@"conversation_settings_search" - accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME( - OWSConversationSettingsViewController, @"search")]; - } - actionBlock:^{ - [weakSelf tappedConversationSearch]; - }]]; + if (SSKFeatureFlags.conversationSearch) { + [mainSection addItem:[OWSTableItem + itemWithCustomCellBlock:^{ + NSString *title = NSLocalizedString(@"CONVERSATION_SETTINGS_SEARCH", + @"Table cell label in conversation settings which returns the user to the " + @"conversation with 'search mode' activated"); + return [weakSelf + disclosureCellWithName:title + iconName:@"conversation_settings_search" + accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME( + OWSConversationSettingsViewController, @"search")]; + } + actionBlock:^{ + [weakSelf tappedConversationSearch]; + }]]; + } if (!isNoteToSelf && !self.isGroupThread && self.thread.hasSafetyNumbers) { [mainSection diff --git a/SignalServiceKit/src/Util/FeatureFlags.swift b/SignalServiceKit/src/Util/FeatureFlags.swift index 4d58938c0..d8cbac11b 100644 --- a/SignalServiceKit/src/Util/FeatureFlags.swift +++ b/SignalServiceKit/src/Util/FeatureFlags.swift @@ -9,6 +9,11 @@ import Foundation @objc(SSKFeatureFlags) public class FeatureFlags: NSObject { + @objc + public static var conversationSearch: Bool { + return false + } + /// iOS has long supported sending oversized text as a sidecar attachment. The other clients /// simply displayed it as a text attachment. As part of the new cross-client long-text feature, /// we want to be able to display long text with attachments as well. Existing iOS clients From 1d959792e8a89c19478f882d505b4b40a69e990e Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Mon, 1 Apr 2019 13:59:05 -0600 Subject: [PATCH 20/21] sync translations --- Signal/translations/bs.lproj/Localizable.strings | 4 ++-- Signal/translations/pt_PT.lproj/Localizable.strings | 4 ++-- Signal/translations/tr.lproj/Localizable.strings | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Signal/translations/bs.lproj/Localizable.strings b/Signal/translations/bs.lproj/Localizable.strings index 148a45df6..dc492024d 100644 --- a/Signal/translations/bs.lproj/Localizable.strings +++ b/Signal/translations/bs.lproj/Localizable.strings @@ -2250,7 +2250,7 @@ "SETTINGS_UNIDENTIFIED_DELIVERY_LEARN_MORE" = "Saznaj više"; /* table section label */ -"SETTINGS_UNIDENTIFIED_DELIVERY_SECTION_TITLE" = "Sealed Sender"; +"SETTINGS_UNIDENTIFIED_DELIVERY_SECTION_TITLE" = "Zapečaćeni pošiljalac"; /* switch label */ "SETTINGS_UNIDENTIFIED_DELIVERY_SHOW_INDICATORS" = "Display Indicators"; @@ -2262,7 +2262,7 @@ "SETTINGS_UNIDENTIFIED_DELIVERY_UNRESTRICTED_ACCESS" = "Allow from Anyone"; /* table section footer */ -"SETTINGS_UNIDENTIFIED_DELIVERY_UNRESTRICTED_ACCESS_FOOTER" = "Enable sealed sender for incoming messages from non-contacts and people with whom you have not shared your profile."; +"SETTINGS_UNIDENTIFIED_DELIVERY_UNRESTRICTED_ACCESS_FOOTER" = "Aktiviraj opciju zapečaćenog pošiljaoca za poruke koje dolaze od osoba koje nisu među Vašim kontaktima i s kojima niste razmijenili profile."; /* No comment provided by engineer. */ "SETTINGS_VERSION" = "Verzija"; diff --git a/Signal/translations/pt_PT.lproj/Localizable.strings b/Signal/translations/pt_PT.lproj/Localizable.strings index 86789f7f9..9fe6a3821 100644 --- a/Signal/translations/pt_PT.lproj/Localizable.strings +++ b/Signal/translations/pt_PT.lproj/Localizable.strings @@ -684,10 +684,10 @@ "DATABASE_VIEW_OVERLAY_TITLE" = "A optimizar a base de dados"; /* Format string for a relative time, expressed as a certain number of hours in the past. Embeds {{The number of hours}}. */ -"DATE_HOURS_AGO_FORMAT" = " Há %@h atrás"; +"DATE_HOURS_AGO_FORMAT" = " Há %@h"; /* Format string for a relative time, expressed as a certain number of minutes in the past. Embeds {{The number of minutes}}. */ -"DATE_MINUTES_AGO_FORMAT" = "Há %@min atrás"; +"DATE_MINUTES_AGO_FORMAT" = "Há %@min"; /* The present; the current time. */ "DATE_NOW" = "Agora"; diff --git a/Signal/translations/tr.lproj/Localizable.strings b/Signal/translations/tr.lproj/Localizable.strings index 78070ceaf..c4443f218 100644 --- a/Signal/translations/tr.lproj/Localizable.strings +++ b/Signal/translations/tr.lproj/Localizable.strings @@ -624,7 +624,7 @@ "CONVERSATION_SETTINGS_NEW_CONTACT" = "Yeni Kişi Oluştur"; /* Table cell label in conversation settings which returns the user to the conversation with 'search mode' activated */ -"CONVERSATION_SETTINGS_SEARCH" = "Sohbeti Araştır"; +"CONVERSATION_SETTINGS_SEARCH" = "Sohbette Ara"; /* Label for button that opens conversation settings. */ "CONVERSATION_SETTINGS_TAP_TO_CHANGE" = "Değiştirmek için Dokunun"; @@ -2484,7 +2484,7 @@ "UPGRADE_EXPERIENCE_VIDEO_TITLE" = "Merhaba Güvenli Görüntülü Aramalar!"; /* Message for the alert indicating that user should upgrade iOS. */ -"UPGRADE_IOS_ALERT_MESSAGE" = "Signal will soon require iOS 10 or later. Please upgrade in Settings app >> General >> Software Update."; +"UPGRADE_IOS_ALERT_MESSAGE" = "Signal yakında iOS 10 ve sonrasına gereksinim duyacaktır. Lütfen Ayarlar >> Genel >> Yazılım Güncelleme bölümünden yükseltin."; /* Title for the alert indicating that user should upgrade iOS. */ "UPGRADE_IOS_ALERT_TITLE" = "iOS'u Güncelle"; From 3b0d6991e1b9f3549b51a25e754c9de060c559bb Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Mon, 1 Apr 2019 13:59:17 -0600 Subject: [PATCH 21/21] "Bump build to 2.38.0.11." --- Signal/Signal-Info.plist | 2 +- SignalShareExtension/Info.plist | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist index a22f827d3..0bb591dc5 100644 --- a/Signal/Signal-Info.plist +++ b/Signal/Signal-Info.plist @@ -47,7 +47,7 @@ CFBundleVersion - 2.38.0.10 + 2.38.0.11 ITSAppUsesNonExemptEncryption LOGS_EMAIL diff --git a/SignalShareExtension/Info.plist b/SignalShareExtension/Info.plist index 9c5fe74cd..57a84f865 100644 --- a/SignalShareExtension/Info.plist +++ b/SignalShareExtension/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 2.38.0 CFBundleVersion - 2.38.0.10 + 2.38.0.11 ITSAppUsesNonExemptEncryption NSAppTransportSecurity