commit
fbd30ca8e5
|
@ -359,6 +359,13 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
|
|||
snInputView.hideMentionsUI()
|
||||
self.oldText = newText
|
||||
}
|
||||
|
||||
func showInputAccessoryView() {
|
||||
UIView.animate(withDuration: 0.25, animations: {
|
||||
self.inputAccessoryView?.isHidden = false
|
||||
self.inputAccessoryView?.alpha = 1
|
||||
})
|
||||
}
|
||||
|
||||
// MARK: View Item Interaction
|
||||
func handleViewItemLongPressed(_ viewItem: ConversationViewItem) {
|
||||
|
@ -560,19 +567,12 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
|
|||
return
|
||||
}
|
||||
|
||||
func showInputAccessoryView() {
|
||||
UIView.animate(withDuration: 0.25, animations: {
|
||||
self.inputAccessoryView?.isHidden = false
|
||||
self.inputAccessoryView?.alpha = 1
|
||||
})
|
||||
}
|
||||
|
||||
if viewItem.interaction.interactionType() == .outgoingMessage,
|
||||
let message = viewItem.interaction as? TSMessage, message.serverHash != nil {
|
||||
let alertVC = UIAlertController.init(title: nil, message: nil, preferredStyle: .actionSheet)
|
||||
let deleteLocallyAction = UIAlertAction.init(title: NSLocalizedString("delete_message_for_me", comment: ""), style: .destructive) { _ in
|
||||
self.deleteLocally(viewItem)
|
||||
showInputAccessoryView()
|
||||
self.showInputAccessoryView()
|
||||
}
|
||||
alertVC.addAction(deleteLocallyAction)
|
||||
|
||||
|
@ -582,12 +582,12 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
|
|||
}
|
||||
let deleteRemotelyAction = UIAlertAction.init(title: title, style: .destructive) { _ in
|
||||
self.deleteForEveryone(viewItem)
|
||||
showInputAccessoryView()
|
||||
self.showInputAccessoryView()
|
||||
}
|
||||
alertVC.addAction(deleteRemotelyAction)
|
||||
|
||||
let cancelAction = UIAlertAction.init(title: NSLocalizedString("TXT_CANCEL_TITLE", comment: ""), style: .cancel) {_ in
|
||||
showInputAccessoryView()
|
||||
self.showInputAccessoryView()
|
||||
}
|
||||
alertVC.addAction(cancelAction)
|
||||
|
||||
|
@ -674,10 +674,24 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
|
|||
|
||||
func openURL(_ url: URL) {
|
||||
// URLs can be unsafe, so always ask the user whether they want to open one
|
||||
let urlModal = URLModal(url: url)
|
||||
urlModal.modalPresentationStyle = .overFullScreen
|
||||
urlModal.modalTransitionStyle = .crossDissolve
|
||||
present(urlModal, animated: true, completion: nil)
|
||||
let title = NSLocalizedString("modal_open_url_title", comment: "")
|
||||
let message = String(format: NSLocalizedString("modal_open_url_explanation", comment: ""), url.absoluteString)
|
||||
let alertVC = UIAlertController.init(title: title, message: message, preferredStyle: .actionSheet)
|
||||
let openAction = UIAlertAction.init(title: NSLocalizedString("modal_open_url_button_title", comment: ""), style: .default) { _ in
|
||||
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
||||
self.showInputAccessoryView()
|
||||
}
|
||||
alertVC.addAction(openAction)
|
||||
let copyAction = UIAlertAction.init(title: NSLocalizedString("modal_copy_url_button_title", comment: ""), style: .default) { _ in
|
||||
UIPasteboard.general.string = url.absoluteString
|
||||
self.showInputAccessoryView()
|
||||
}
|
||||
alertVC.addAction(copyAction)
|
||||
let cancelAction = UIAlertAction.init(title: NSLocalizedString("cancel", comment: ""), style: .cancel) {_ in
|
||||
self.showInputAccessoryView()
|
||||
}
|
||||
alertVC.addAction(cancelAction)
|
||||
self.presentAlert(alertVC)
|
||||
}
|
||||
|
||||
func joinOpenGroup(name: String, url: String) {
|
||||
|
|
|
@ -258,10 +258,8 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
|
|||
override func viewWillDisappear(_ animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
let text = snInputView.text
|
||||
if !text.isEmpty {
|
||||
Storage.write { transaction in
|
||||
self.thread.setDraft(text, transaction: transaction)
|
||||
}
|
||||
Storage.write { transaction in
|
||||
self.thread.setDraft(text, transaction: transaction)
|
||||
}
|
||||
inputAccessoryView?.resignFirstResponder()
|
||||
}
|
||||
|
|
|
@ -10,15 +10,35 @@ final class ExpandingAttachmentsButton : UIView, InputViewButtonDelegate {
|
|||
private lazy var cameraButtonContainerBottomConstraint = cameraButtonContainer.pin(.bottom, to: .bottom, of: self)
|
||||
|
||||
// MARK: UI Components
|
||||
lazy var gifButton = InputViewButton(icon: #imageLiteral(resourceName: "actionsheet_gif_black"), delegate: self, hasOpaqueBackground: true)
|
||||
lazy var gifButton: InputViewButton = {
|
||||
let result = InputViewButton(icon: #imageLiteral(resourceName: "actionsheet_gif_black"), delegate: self, hasOpaqueBackground: true)
|
||||
result.accessibilityLabel = NSLocalizedString("accessibility_gif_button", comment: "")
|
||||
return result
|
||||
}()
|
||||
lazy var gifButtonContainer = container(for: gifButton)
|
||||
lazy var documentButton = InputViewButton(icon: #imageLiteral(resourceName: "actionsheet_document_black"), delegate: self, hasOpaqueBackground: true)
|
||||
lazy var documentButton: InputViewButton = {
|
||||
let result = InputViewButton(icon: #imageLiteral(resourceName: "actionsheet_document_black"), delegate: self, hasOpaqueBackground: true)
|
||||
result.accessibilityLabel = NSLocalizedString("accessibility_document_button", comment: "")
|
||||
return result
|
||||
}()
|
||||
lazy var documentButtonContainer = container(for: documentButton)
|
||||
lazy var libraryButton = InputViewButton(icon: #imageLiteral(resourceName: "actionsheet_camera_roll_black"), delegate: self, hasOpaqueBackground: true)
|
||||
lazy var libraryButton: InputViewButton = {
|
||||
let result = InputViewButton(icon: #imageLiteral(resourceName: "actionsheet_camera_roll_black"), delegate: self, hasOpaqueBackground: true)
|
||||
result.accessibilityLabel = NSLocalizedString("accessibility_library_button", comment: "")
|
||||
return result
|
||||
}()
|
||||
lazy var libraryButtonContainer = container(for: libraryButton)
|
||||
lazy var cameraButton = InputViewButton(icon: #imageLiteral(resourceName: "actionsheet_camera_black"), delegate: self, hasOpaqueBackground: true)
|
||||
lazy var cameraButton: InputViewButton = {
|
||||
let result = InputViewButton(icon: #imageLiteral(resourceName: "actionsheet_camera_black"), delegate: self, hasOpaqueBackground: true)
|
||||
result.accessibilityLabel = NSLocalizedString("accessibility_camera_button", comment: "")
|
||||
return result
|
||||
}()
|
||||
lazy var cameraButtonContainer = container(for: cameraButton)
|
||||
lazy var mainButton = InputViewButton(icon: #imageLiteral(resourceName: "ic_plus_24"), delegate: self)
|
||||
lazy var mainButton: InputViewButton = {
|
||||
let result = InputViewButton(icon: #imageLiteral(resourceName: "ic_plus_24"), delegate: self)
|
||||
result.accessibilityLabel = NSLocalizedString("accessibility_expanding_attachments_button", comment: "")
|
||||
return result
|
||||
}()
|
||||
lazy var mainButtonContainer = container(for: mainButton)
|
||||
|
||||
// MARK: Lifecycle
|
||||
|
@ -66,6 +86,7 @@ final class ExpandingAttachmentsButton : UIView, InputViewButtonDelegate {
|
|||
// MARK: Animation
|
||||
private func expandOrCollapse() {
|
||||
if isExpanded {
|
||||
mainButton.accessibilityLabel = NSLocalizedString("accessibility_main_button_collapse", comment: "")
|
||||
let expandedButtonSize = InputViewButton.expandedSize
|
||||
let spacing: CGFloat = 4
|
||||
cameraButtonContainerBottomConstraint.constant = -1 * (expandedButtonSize + spacing)
|
||||
|
@ -79,6 +100,7 @@ final class ExpandingAttachmentsButton : UIView, InputViewButtonDelegate {
|
|||
self.layoutIfNeeded()
|
||||
}
|
||||
} else {
|
||||
mainButton.accessibilityLabel = NSLocalizedString("accessibility_expanding_attachments_button", comment: "")
|
||||
[ gifButtonContainerBottomConstraint, documentButtonContainerBottomConstraint, libraryButtonContainerBottomConstraint, cameraButtonContainerBottomConstraint ].forEach {
|
||||
$0.constant = 0
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ public final class InputTextView : UITextView, UITextViewDelegate {
|
|||
super.init(frame: CGRect.zero, textContainer: nil)
|
||||
setUpViewHierarchy()
|
||||
self.delegate = self
|
||||
self.isAccessibilityElement = true
|
||||
self.accessibilityLabel = NSLocalizedString("vc_conversation_input_prompt", comment: "")
|
||||
}
|
||||
|
||||
public override init(frame: CGRect, textContainer: NSTextContainer?) {
|
||||
|
|
|
@ -22,11 +22,17 @@ final class InputView : UIView, InputViewButtonDelegate, InputTextViewDelegate,
|
|||
// MARK: UI Components
|
||||
private lazy var attachmentsButton = ExpandingAttachmentsButton(delegate: delegate)
|
||||
|
||||
private lazy var voiceMessageButton = InputViewButton(icon: #imageLiteral(resourceName: "Microphone"), delegate: self)
|
||||
private lazy var voiceMessageButton: InputViewButton = {
|
||||
let result = InputViewButton(icon: #imageLiteral(resourceName: "Microphone"), delegate: self)
|
||||
result.accessibilityLabel = NSLocalizedString("VOICE_MESSAGE_TOO_SHORT_ALERT_TITLE", comment: "")
|
||||
result.accessibilityHint = NSLocalizedString("VOICE_MESSAGE_TOO_SHORT_ALERT_MESSAGE", comment: "")
|
||||
return result
|
||||
}()
|
||||
|
||||
private lazy var sendButton: InputViewButton = {
|
||||
let result = InputViewButton(icon: #imageLiteral(resourceName: "ArrowUp"), isSendButton: true, delegate: self)
|
||||
result.isHidden = true
|
||||
result.accessibilityLabel = NSLocalizedString("ATTACHMENT_APPROVAL_SEND_BUTTON", comment: "")
|
||||
return result
|
||||
}()
|
||||
private lazy var voiceMessageButtonContainer = container(for: voiceMessageButton)
|
||||
|
|
|
@ -25,6 +25,7 @@ final class InputViewButton : UIView {
|
|||
self.hasOpaqueBackground = hasOpaqueBackground
|
||||
super.init(frame: CGRect.zero)
|
||||
setUpViewHierarchy()
|
||||
self.isAccessibilityElement = true
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "URL öffnen?";
|
||||
"modal_open_url_explanation" = "Möchten Sie %@ wirklich öffnen?";
|
||||
"modal_open_url_button_title" = "Öffnen";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "%@ entsperren?";
|
||||
"modal_blocked_explanation" = "Sind Sie sicher, dass Sie %@ entsperren möchten?";
|
||||
"modal_blocked_button_title" = "Entsperren";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "Open URL?";
|
||||
"modal_open_url_explanation" = "Are you sure you want to open %@?";
|
||||
"modal_open_url_button_title" = "Open";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Unblock %@?";
|
||||
"modal_blocked_explanation" = "Are you sure you want to unblock %@?";
|
||||
"modal_blocked_button_title" = "Unblock";
|
||||
|
@ -557,4 +558,11 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
"invalid_recovery_phrase" = "Invalid Recovery Phrase";
|
||||
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "¿Abrir URL?";
|
||||
"modal_open_url_explanation" = "¿Estás seguro de que quieres abrir %@?";
|
||||
"modal_open_url_button_title" = "Abrir";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "¿Desbloquear a %@?";
|
||||
"modal_blocked_explanation" = "¿Estás seguro de que quieres desbloquear a %@?";
|
||||
"modal_blocked_button_title" = "Desbloquear";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "URL باز شود؟";
|
||||
"modal_open_url_explanation" = "آیا مطمئن هستید که میخواهید %@ را باز کنید؟";
|
||||
"modal_open_url_button_title" = "باز کن";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Unblock %@?";
|
||||
"modal_blocked_explanation" = "Are you sure you want to unblock %@?";
|
||||
"modal_blocked_button_title" = "رفع مسدودی";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "Avataanko URL?";
|
||||
"modal_open_url_explanation" = "Oletko varma, että haluat avata linkin %@?";
|
||||
"modal_open_url_button_title" = "Avaa";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Poista esto henkilöltä %@?";
|
||||
"modal_blocked_explanation" = "Oletko varma, että haluat poistaa eston henkilöltä %@?";
|
||||
"modal_blocked_button_title" = "Poista esto";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "Ouvrir l'URL?";
|
||||
"modal_open_url_explanation" = "Êtes-vous sûr de vouloir ouvrir %@?";
|
||||
"modal_open_url_button_title" = "Ouvrir";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Débloquer %@ ?";
|
||||
"modal_blocked_explanation" = "Confirmez-vous le déblocage de %@ ?";
|
||||
"modal_blocked_button_title" = "Débloquer";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "यूआरएल खोलें";
|
||||
"modal_open_url_explanation" = "क्या आप वाकई %@ खोलना चाहते हैं?";
|
||||
"modal_open_url_button_title" = "खोलें";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "%@ अनब्लॉक करें?";
|
||||
"modal_blocked_explanation" = "क्या आप वाकई %@ को अनब्लॉक करना चाहते हैं?";
|
||||
"modal_blocked_button_title" = "अनब्लॉक करें";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "Otvori poveznicu?";
|
||||
"modal_open_url_explanation" = "Jeste li sigurni da želite otvoriti %@?";
|
||||
"modal_open_url_button_title" = "Otvori";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Deblokiraj %@?";
|
||||
"modal_blocked_explanation" = "Jeste li sigurni da želite deblokirati %@?";
|
||||
"modal_blocked_button_title" = "Deblokiraj";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "Open URL?";
|
||||
"modal_open_url_explanation" = "Are you sure you want to open %@?";
|
||||
"modal_open_url_button_title" = "Open";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Unblock %@?";
|
||||
"modal_blocked_explanation" = "Are you sure you want to unblock %@?";
|
||||
"modal_blocked_button_title" = "Unblock";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "Aprire URL?";
|
||||
"modal_open_url_explanation" = "Sei sicuro di voler aprire %@?";
|
||||
"modal_open_url_button_title" = "Apri";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Sbloccare %@?";
|
||||
"modal_blocked_explanation" = "Sei sicuro di voler sbloccare %@?";
|
||||
"modal_blocked_button_title" = "Sblocca";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "URLを開きますか?";
|
||||
"modal_open_url_explanation" = "%@を本当に開いてもよろしいですか?";
|
||||
"modal_open_url_button_title" = "開く";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "%@のブロックを解除しますか?";
|
||||
"modal_blocked_explanation" = "%@のブロックを解除してもよろしいですか?";
|
||||
"modal_blocked_button_title" = "ブロックを解除する";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "URL openen?";
|
||||
"modal_open_url_explanation" = "Weet u zeker dat u %@ wilt openen?";
|
||||
"modal_open_url_button_title" = "Openen";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Blokkering opheffen voor %@?";
|
||||
"modal_blocked_explanation" = "Weet je zeker dat je %@ weer wilt toelaten?";
|
||||
"modal_blocked_button_title" = "Deblokkeren";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "Otworzyć URL?";
|
||||
"modal_open_url_explanation" = "Czy na pewno chcesz otworzyć %@?";
|
||||
"modal_open_url_button_title" = "Otwórz";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Odblokować %@?";
|
||||
"modal_blocked_explanation" = "Czy na pewno chcesz odblokować %@?";
|
||||
"modal_blocked_button_title" = "Odblokuj";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "Abrir URL?";
|
||||
"modal_open_url_explanation" = "Você tem certeza que deseja abrir %@/?";
|
||||
"modal_open_url_button_title" = "Abrir";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Desbloquear %@?";
|
||||
"modal_blocked_explanation" = "Você tem certeza que deseja desbloquear %@?";
|
||||
"modal_blocked_button_title" = "Desbloquear";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "Открыть ссылку?";
|
||||
"modal_open_url_explanation" = "Вы уверены, что хотите открыть %@?";
|
||||
"modal_open_url_button_title" = "Открыть";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Разблокировать %@?";
|
||||
"modal_blocked_explanation" = "Вы уверены, что хотите разблокировать %@?";
|
||||
"modal_blocked_button_title" = "Разблокировать";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "Otvoriť URL?";
|
||||
"modal_open_url_explanation" = "Ste si istý, že chcete otvoriť %@?";
|
||||
"modal_open_url_button_title" = "Otvoriť";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Odblokovať %@?";
|
||||
"modal_blocked_explanation" = "Ste si istý/á, že chcete odblokovať %@?";
|
||||
"modal_blocked_button_title" = "Odblokovať";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "Öppna URL?";
|
||||
"modal_open_url_explanation" = "Är du säker på att du vill öppna %@?";
|
||||
"modal_open_url_button_title" = "Öppna";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Avblockera %@?";
|
||||
"modal_blocked_explanation" = "Är du säker på att du vill avblockera %@?";
|
||||
"modal_blocked_button_title" = "Avblockera";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "เปิดลิงค์ URL ไหม";
|
||||
"modal_open_url_explanation" = "แน่ใจไหมว่าคุณต้องกาเปิดดู %@";
|
||||
"modal_open_url_button_title" = "เปิด";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "เลิกบล็อก %@ ไหม";
|
||||
"modal_blocked_explanation" = "แน่ใจไหมว่าคุณต้องการเลิกบล็อก %@";
|
||||
"modal_blocked_button_title" = "เลิกบล็อก";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "Open URL?";
|
||||
"modal_open_url_explanation" = "Are you sure you want to open %@?";
|
||||
"modal_open_url_button_title" = "Open";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "Unblock %@?";
|
||||
"modal_blocked_explanation" = "Are you sure you want to unblock %@?";
|
||||
"modal_blocked_button_title" = "Unblock";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "打開連結?";
|
||||
"modal_open_url_explanation" = "您確定要打開 %@ 嗎?";
|
||||
"modal_open_url_button_title" = "打開";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "解除封鎖 %@ 嗎?";
|
||||
"modal_blocked_explanation" = "您確定要解除封鎖 %@ 嗎?";
|
||||
"modal_blocked_button_title" = "解除封鎖";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -531,6 +531,7 @@
|
|||
"modal_open_url_title" = "打开链接?";
|
||||
"modal_open_url_explanation" = "确定要打开 %@ 吗?";
|
||||
"modal_open_url_button_title" = "打开";
|
||||
"modal_copy_url_button_title" = "Copy Link";
|
||||
"modal_blocked_title" = "从黑名单中移除 %@ 吗?";
|
||||
"modal_blocked_explanation" = "确定解除屏蔽%@吗?";
|
||||
"modal_blocked_button_title" = "解除屏蔽";
|
||||
|
@ -557,3 +558,9 @@
|
|||
"context_menu_save" = "Save";
|
||||
"context_menu_ban_user" = "Ban User";
|
||||
"context_menu_ban_and_delete_all" = "Ban and Delete All";
|
||||
"accessibility_expanding_attachments_button" = "Add attachments";
|
||||
"accessibility_gif_button" = "Gif";
|
||||
"accessibility_document_button" = "Document";
|
||||
"accessibility_library_button" = "Photo library";
|
||||
"accessibility_camera_button" = "Camera";
|
||||
"accessibility_main_button_collapse" = "Collapse attachment options";
|
||||
|
|
|
@ -122,6 +122,14 @@ final class LinkDeviceVC : BaseVC, UIPageViewControllerDataSource, UIPageViewCon
|
|||
}
|
||||
|
||||
func continueWithSeed(_ seed: Data) {
|
||||
if (seed.count != 16) {
|
||||
let alert = UIAlertController(title: NSLocalizedString("invalid_recovery_phrase", comment: ""), message: NSLocalizedString("Please check the Recovery Phrase and try again.", comment: ""), preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default, handler: { _ in
|
||||
self.scanQRCodeWrapperVC.startCapture()
|
||||
}))
|
||||
presentAlert(alert)
|
||||
return
|
||||
}
|
||||
let (ed25519KeyPair, x25519KeyPair) = KeyPairUtilities.generate(from: seed)
|
||||
Onboarding.Flow.link.preregister(with: seed, ed25519KeyPair: ed25519KeyPair, x25519KeyPair: x25519KeyPair)
|
||||
TSAccountManager.sharedInstance().didRegister()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import UIKit
|
||||
import SessionUIKit
|
||||
|
||||
final class ConversationCell : UITableViewCell {
|
||||
var threadViewModel: ThreadViewModel! { didSet { update() } }
|
||||
|
@ -37,6 +38,26 @@ final class ConversationCell : UITableViewCell {
|
|||
return result
|
||||
}()
|
||||
|
||||
private lazy var hasMentionView: UIView = {
|
||||
let result = UIView()
|
||||
result.backgroundColor = Colors.accent
|
||||
let size = ConversationCell.unreadCountViewSize
|
||||
result.set(.width, to: size)
|
||||
result.set(.height, to: size)
|
||||
result.layer.masksToBounds = true
|
||||
result.layer.cornerRadius = size / 2
|
||||
return result
|
||||
}()
|
||||
|
||||
private lazy var hasMentionLabel: UILabel = {
|
||||
let result = UILabel()
|
||||
result.font = .boldSystemFont(ofSize: Values.verySmallFontSize)
|
||||
result.textColor = Colors.text
|
||||
result.text = "@"
|
||||
result.textAlignment = .center
|
||||
return result
|
||||
}()
|
||||
|
||||
private lazy var timestampLabel: UILabel = {
|
||||
let result = UILabel()
|
||||
result.font = .systemFont(ofSize: Values.smallFontSize)
|
||||
|
@ -98,9 +119,12 @@ final class ConversationCell : UITableViewCell {
|
|||
// Unread count view
|
||||
unreadCountView.addSubview(unreadCountLabel)
|
||||
unreadCountLabel.pin(to: unreadCountView)
|
||||
// Has mention view
|
||||
hasMentionView.addSubview(hasMentionLabel)
|
||||
hasMentionLabel.pin(to: hasMentionView)
|
||||
// Label stack view
|
||||
let topLabelSpacer = UIView.hStretchingSpacer()
|
||||
let topLabelStackView = UIStackView(arrangedSubviews: [ displayNameLabel, unreadCountView, topLabelSpacer, timestampLabel ])
|
||||
let topLabelStackView = UIStackView(arrangedSubviews: [ displayNameLabel, unreadCountView, hasMentionView, topLabelSpacer, timestampLabel ])
|
||||
topLabelStackView.axis = .horizontal
|
||||
topLabelStackView.alignment = .center
|
||||
topLabelStackView.spacing = Values.smallSpacing / 2 // Effectively Values.smallSpacing because there'll be spacing before and after the invisible spacer
|
||||
|
@ -176,6 +200,7 @@ final class ConversationCell : UITableViewCell {
|
|||
unreadCountLabel.text = unreadCount < 100 ? "\(unreadCount)" : "99+"
|
||||
let fontSize = (unreadCount < 100) ? Values.verySmallFontSize : 8
|
||||
unreadCountLabel.font = .boldSystemFont(ofSize: fontSize)
|
||||
hasMentionView.isHidden = !threadViewModel.hasUnreadMentions
|
||||
profilePictureView.update(for: thread)
|
||||
displayNameLabel.text = getDisplayName()
|
||||
timestampLabel.text = DateUtil.formatDate(forDisplay: threadViewModel.lastMessageDate)
|
||||
|
|
|
@ -71,4 +71,10 @@ final class ScanQRCodeWrapperVC : BaseVC {
|
|||
@objc private func close() {
|
||||
presentingViewController?.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
public func startCapture() {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
self?.scanQRCodeVC.startCapture()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,4 +162,3 @@ public final class AttachmentDownloadJob : NSObject, Job, NSCoding { // NSObject
|
|||
delegate?.handleJobFailed(self, with: error)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import PromiseKit
|
|||
public final class ClosedGroupPoller : NSObject {
|
||||
private var isPolling: [String:Bool] = [:]
|
||||
private var timers: [String:Timer] = [:]
|
||||
private let internalQueue: DispatchQueue = DispatchQueue(label:"isPollingQueue")
|
||||
|
||||
// MARK: Settings
|
||||
private static let minPollInterval: Double = 2
|
||||
|
@ -137,6 +138,6 @@ public final class ClosedGroupPoller : NSObject {
|
|||
|
||||
// MARK: Convenience
|
||||
private func isPolling(for groupPublicKey: String) -> Bool {
|
||||
return isPolling[groupPublicKey] ?? false
|
||||
return internalQueue.sync{ isPolling[groupPublicKey] ?? false }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,9 @@ BOOL IsNoteToSelfEnabled(void);
|
|||
- (NSUInteger)unreadMessageCountWithTransaction:(YapDatabaseReadTransaction *)transaction
|
||||
NS_SWIFT_NAME(unreadMessageCount(transaction:));
|
||||
|
||||
- (BOOL)hasUnreadMentionMessageWithTransaction:(YapDatabaseReadTransaction *)transaction
|
||||
NS_SWIFT_NAME(hasUnreadMentionMessage(transaction:));
|
||||
|
||||
- (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
|
||||
|
||||
/**
|
||||
|
|
|
@ -264,6 +264,32 @@ BOOL IsNoteToSelfEnabled(void)
|
|||
return count;
|
||||
}
|
||||
|
||||
- (BOOL)hasUnreadMentionMessageWithTransaction:(YapDatabaseReadTransaction *)transaction
|
||||
{
|
||||
__block BOOL hasUnreadMention = false;
|
||||
|
||||
YapDatabaseViewTransaction *unreadMessages = [transaction ext:TSUnreadDatabaseViewExtensionName];
|
||||
[unreadMessages enumerateKeysAndObjectsInGroup:self.uniqueId
|
||||
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) {
|
||||
if (![object isKindOfClass:[TSIncomingMessage class]]) {
|
||||
return;
|
||||
}
|
||||
TSIncomingMessage* unreadMessage = (TSIncomingMessage*)object;
|
||||
if (unreadMessage.read) {
|
||||
NSLog(@"Found an already read message in the * unread * messages list.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (unreadMessage.isUserMentioned) {
|
||||
hasUnreadMention = true;
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
|
||||
return hasUnreadMention;
|
||||
|
||||
}
|
||||
|
||||
- (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
for (id<OWSReadTracking> message in [self unseenMessagesWithTransaction:transaction]) {
|
||||
|
|
|
@ -48,7 +48,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
|
|||
case let visibleMessage as VisibleMessage:
|
||||
let tsIncomingMessageID = try MessageReceiver.handleVisibleMessage(visibleMessage, associatedWithProto: proto, openGroupID: nil, isBackgroundPoll: false, using: transaction)
|
||||
guard let tsIncomingMessage = TSIncomingMessage.fetch(uniqueId: tsIncomingMessageID, transaction: transaction) else {
|
||||
return self.handleFailure(for: notificationContent)
|
||||
return self.completeSilenty()
|
||||
}
|
||||
let thread = tsIncomingMessage.thread(with: transaction)
|
||||
if thread.isMuted {
|
||||
|
|
|
@ -15,6 +15,7 @@ public class ThreadViewModel: NSObject {
|
|||
@objc public let name: String
|
||||
@objc public let isMuted: Bool
|
||||
@objc public let isOnlyNotifyingForMentions: Bool
|
||||
@objc public let hasUnreadMentions: Bool
|
||||
|
||||
var isContactThread: Bool {
|
||||
return !isGroupThread
|
||||
|
@ -49,6 +50,7 @@ public class ThreadViewModel: NSObject {
|
|||
|
||||
self.unreadCount = thread.unreadMessageCount(transaction: transaction)
|
||||
self.hasUnreadMessages = unreadCount > 0
|
||||
self.hasUnreadMentions = thread.hasUnreadMentionMessage(transaction: transaction)
|
||||
}
|
||||
|
||||
@objc
|
||||
|
|
Loading…
Reference in New Issue