Fixed a number of tweaks and bugs with message requests

Removed the "Back" text from the back buttons
Removed the inset on the 'Path' settings button so the text remains horizontally centered
Hid the settings button from message request threads
Fixed an issue where the back button would remain visible in a conversation when the search field was visible
Fixed an issue where the tintColor of the conversation search field didn't match the global search field
Fixed an issue where sending an attachment response to a message request wouldn't approve the message request
Updated the size and positioning of the message request 'Clear All' button to match the DM 'Next' button
Updated the message request 'Clear All' button to start visible (so it's visible during the push animation) since that's the most likely state it'll be in
Updated the 'Message Requests' cell to use the pinned background colour
Updated the fallback for contact thread names to be a middle-truncated string (4 characters either side)
pull/567/head
Morgan Pretty 2 years ago
parent f8c0700ba0
commit e6b941ea8a

@ -10,6 +10,16 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
ConversationTitleViewDelegate {
func handleTitleViewTapped() {
// Don't take the user to settings for message requests
guard
let contactThread: TSContactThread = thread as? TSContactThread,
let contact: Contact = Storage.shared.getContact(with: contactThread.contactSessionID()),
contact.isApproved,
contact.didApproveMe
else {
return
}
openSettings()
}
@ -292,32 +302,56 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
func sendAttachments(_ attachments: [SignalAttachment], with text: String, onComplete: (() -> ())? = nil) {
guard !showBlockedModalIfNeeded() else { return }
for attachment in attachments {
if attachment.hasError {
return showErrorAlert(for: attachment, onDismiss: onComplete)
}
}
let thread = self.thread
let sentTimestamp: UInt64 = NSDate.millisecondTimestamp()
let message = VisibleMessage()
message.sentTimestamp = NSDate.millisecondTimestamp()
message.sentTimestamp = sentTimestamp
message.text = replaceMentions(in: text)
// Note: 'shouldBeVisible' is set to true the first time a thread is saved so we can
// use it to determine if the user is creating a new thread and update the 'isApproved'
// flags appropriately
let oldThreadShouldBeVisible: Bool = thread.shouldBeVisible
let tsMessage = TSOutgoingMessage.from(message, associatedWith: thread)
Storage.write(with: { transaction in
tsMessage.save(with: transaction)
// The new message cell is inserted at this point, but the TSOutgoingMessage doesn't have its attachment yet
}, completion: { [weak self] in
Storage.write(with: { transaction in
MessageSender.send(message, with: attachments, in: thread, using: transaction)
}, completion: { [weak self] in
// At this point the TSOutgoingMessage should have its attachments set, so we can scroll to the bottom knowing
// the height of the new message cell
self?.scrollToBottom(isAnimated: false)
})
self?.handleMessageSent()
// Attachment successfully sent - dismiss the screen
onComplete?()
})
Storage.write(
with: { transaction in
tsMessage.save(with: transaction)
// The new message cell is inserted at this point, but the TSOutgoingMessage doesn't have its attachment yet
},
completion: { [weak self] in
Storage.shared.write(
with: { transaction in
self?.approveMessageRequestIfNeeded(
for: self?.thread,
with: (transaction as! YapDatabaseReadWriteTransaction),
isNewThread: !oldThreadShouldBeVisible,
timestamp: (sentTimestamp - 1) // Set 1ms earlier as this is used for sorting
)
},
completion: { [weak self] in
Storage.write(with: { transaction in
MessageSender.send(message, with: attachments, in: thread, using: transaction)
}, completion: { [weak self] in
// At this point the TSOutgoingMessage should have its attachments set, so we can scroll to the bottom knowing
// the height of the new message cell
self?.scrollToBottom(isAnimated: false)
})
self?.handleMessageSent()
// Attachment successfully sent - dismiss the screen
onComplete?()
}
)
}
)
}
func handleMessageSent() {

@ -1,5 +1,6 @@
import SessionUIKit
import SessionMessagingKit
import UIKit
// TODO:
// Slight paging glitch when scrolling up and loading more content
@ -465,30 +466,53 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
// MARK: Updating
func updateNavBarButtons() {
// Back button (to appear on pushed screen)
let backButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
backButton.tintColor = Colors.text
navigationItem.backBarButtonItem = backButton
navigationItem.hidesBackButton = isShowingSearchUI
if isShowingSearchUI {
navigationItem.leftBarButtonItem = nil
navigationItem.rightBarButtonItems = []
} else {
}
else {
navigationItem.hidesBackButton = false
navigationItem.leftBarButtonItem = UIViewController.createOWSBackButton(withTarget: self, selector: #selector(handleBackPressed))
let rightBarButtonItem: UIBarButtonItem
if thread is TSContactThread {
let size = Values.verySmallProfilePictureSize
let profilePictureView = ProfilePictureView()
profilePictureView.accessibilityLabel = "Settings button"
profilePictureView.size = size
profilePictureView.update(for: thread)
profilePictureView.set(.width, to: size)
profilePictureView.set(.height, to: size)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(openSettings))
profilePictureView.addGestureRecognizer(tapGestureRecognizer)
rightBarButtonItem = UIBarButtonItem(customView: profilePictureView)
} else {
rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "Gear"), style: .plain, target: self, action: #selector(openSettings))
if let contactThread: TSContactThread = thread as? TSContactThread {
// Don't show the settings button for message requests
if let contact: Contact = Storage.shared.getContact(with: contactThread.contactSessionID()), contact.isApproved, contact.didApproveMe {
let size = Values.verySmallProfilePictureSize
let profilePictureView = ProfilePictureView()
profilePictureView.size = size
profilePictureView.update(for: thread)
profilePictureView.set(.width, to: size)
profilePictureView.set(.height, to: size)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(openSettings))
profilePictureView.addGestureRecognizer(tapGestureRecognizer)
let rightBarButtonItem: UIBarButtonItem = UIBarButtonItem(customView: profilePictureView)
rightBarButtonItem.accessibilityLabel = "Settings button"
rightBarButtonItem.isAccessibilityElement = true
navigationItem.rightBarButtonItem = rightBarButtonItem
}
else {
// Note: Adding an empty button because without it the title alignment is busted (Note: The size was
// taken from the layout inspector for the back button in Xcode
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: UIView(frame: CGRect(x: 0, y: 0, width: 37, height: 44)))
}
}
else {
let rightBarButtonItem: UIBarButtonItem = UIBarButtonItem(image: UIImage(named: "Gear"), style: .plain, target: self, action: #selector(openSettings))
rightBarButtonItem.accessibilityLabel = "Settings button"
rightBarButtonItem.isAccessibilityElement = true
navigationItem.rightBarButtonItem = rightBarButtonItem
}
rightBarButtonItem.accessibilityLabel = "Settings button"
rightBarButtonItem.isAccessibilityElement = true
navigationItem.rightBarButtonItem = rightBarButtonItem
}
}
@ -819,7 +843,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
let searchBar = searchController.uiSearchController.searchBar
searchBar.searchBarStyle = .minimal
searchBar.barStyle = .black
searchBar.tintColor = Colors.accent
searchBar.tintColor = Colors.text
let searchIcon = UIImage(named: "searchbar_search")!.asTintedImage(color: Colors.searchBarPlaceholder)
searchBar.setImage(searchIcon, for: .search, state: UIControl.State.normal)
let clearIcon = UIImage(named: "searchbar_clear")!.asTintedImage(color: Colors.searchBarPlaceholder)

@ -277,7 +277,7 @@ CGFloat kIconViewLength = 24;
contents.title = NSLocalizedString(@"CONVERSATION_SETTINGS", @"title for conversation settings screen");
BOOL isNoteToSelf = self.thread.isNoteToSelf;
__weak OWSConversationSettingsViewController *weakSelf = self;
OWSTableSection *section = [OWSTableSection new];
@ -332,7 +332,7 @@ CGFloat kIconViewLength = 24;
} actionBlock:^{
[weakSelf tappedConversationSearch];
}]];
// Disappearing messages
if (![self isOpenGroup]) {
[section addItem:[OWSTableItem itemWithCustomCellBlock:^{
@ -358,13 +358,6 @@ CGFloat kIconViewLength = 24;
switchView.on = strongSelf.disappearingMessagesConfiguration.isEnabled;
[switchView addTarget:strongSelf action:@selector(disappearingMessagesSwitchValueDidChange:)
forControlEvents:UIControlEventValueChanged];
// Disable Disappearing Messages if the conversation hasn't been approved
if (!self.thread.isGroupThread) {
TSContactThread *thread = (TSContactThread *)self.thread;
SNContact *contact = [LKStorage.shared getContactWithSessionID:thread.contactSessionID];
[switchView setEnabled:(contact.isApproved && contact.didApproveMe)];
}
UIStackView *topRow =
[[UIStackView alloc] initWithArrangedSubviews:@[ iconView, rowLabel, switchView ]];
@ -438,13 +431,6 @@ CGFloat kIconViewLength = 24;
[slider autoPinTrailingToSuperviewMargin];
[slider autoPinBottomToSuperviewMargin];
// Disable Disappearing Messages slider if the conversation hasn't been approved (just in case)
if (!self.thread.isGroupThread) {
TSContactThread *thread = (TSContactThread *)self.thread;
SNContact *contact = [LKStorage.shared getContactWithSessionID:thread.contactSessionID];
[slider setEnabled:(contact.isApproved && contact.didApproveMe)];
}
cell.userInteractionEnabled = !strongSelf.hasLeftGroup;
cell.accessibilityIdentifier = ACCESSIBILITY_IDENTIFIER_WITH_NAME(

@ -73,13 +73,17 @@ final class ConversationTitleView : UIView {
private func getTitle() -> String {
if let thread = thread as? TSGroupThread {
return thread.groupModel.groupName!
} else if thread.isNoteToSelf() {
}
else if thread.isNoteToSelf() {
return "Note to Self"
} else {
}
else {
let sessionID = (thread as! TSContactThread).contactSessionID()
var result = sessionID
Storage.read { transaction in
result = Storage.shared.getContact(with: sessionID)?.displayName(for: .regular) ?? "Anonymous"
let displayName: String = ((Storage.shared.getContact(with: sessionID)?.displayName(for: .regular)) ?? sessionID)
let middleTruncatedHexKey: String = "\(sessionID.prefix(4))...\(sessionID.suffix(4))"
result = (displayName == sessionID ? middleTruncatedHexKey : displayName)
}
return result
}

@ -393,11 +393,18 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv
profilePictureViewContainer.addSubview(pathStatusView)
pathStatusView.pin(.trailing, to: .trailing, of: profilePictureViewContainer)
pathStatusView.pin(.bottom, to: .bottom, of: profilePictureViewContainer)
// Back button (to appear on pushed screen)
let backButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
backButton.tintColor = Colors.text
navigationItem.backBarButtonItem = backButton
// Left bar button item
let leftBarButtonItem = UIBarButtonItem(customView: profilePictureViewContainer)
leftBarButtonItem.accessibilityLabel = "Settings button"
leftBarButtonItem.isAccessibilityElement = true
navigationItem.leftBarButtonItem = leftBarButtonItem
// Right bar button item - search button
let rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .search, target: self, action: #selector(showSearchUI))
rightBarButtonItem.accessibilityLabel = "Search button"

@ -63,23 +63,16 @@ class MessageRequestsViewController: BaseVC, UITableViewDelegate, UITableViewDat
return result
}()
private lazy var clearAllButton: UIButton = {
let result: UIButton = UIButton()
private lazy var clearAllButton: Button = {
let result: Button = Button(style: .destructiveOutline, size: .large)
result.translatesAutoresizingMaskIntoConstraints = false
result.clipsToBounds = true
result.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
result.setTitle(NSLocalizedString("MESSAGE_REQUESTS_CLEAR_ALL", comment: ""), for: .normal)
result.setTitleColor(Colors.destructive, for: .normal)
result.setBackgroundImage(
Colors.destructive
.withAlphaComponent(isDarkMode ? 0.2 : 0.06)
.toImage(isDarkMode: isDarkMode),
for: .highlighted
)
result.isHidden = true
result.layer.cornerRadius = (NewConversationButtonSet.collapsedButtonSize / 2)
result.layer.borderColor = Colors.destructive.cgColor
result.layer.borderWidth = 1.5
result.addTarget(self, action: #selector(clearAllTapped), for: .touchUpInside)
return result
@ -163,10 +156,11 @@ class MessageRequestsViewController: BaseVC, UITableViewDelegate, UITableViewDat
clearAllButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
clearAllButton.bottomAnchor.constraint(
equalTo: view.bottomAnchor,
constant: -Values.newConversationButtonBottomOffset // Negative due to how the constraint is set up
equalTo: view.safeAreaLayoutGuide.bottomAnchor,
constant: -Values.largeSpacing
),
clearAllButton.widthAnchor.constraint(equalToConstant: 155),
// Note: The '182' is to match the 'Next' button on the New DM page (which doesn't have a fixed width)
clearAllButton.widthAnchor.constraint(equalToConstant: 182),
clearAllButton.heightAnchor.constraint(equalToConstant: NewConversationButtonSet.collapsedButtonSize)
])
}

@ -76,7 +76,7 @@ class MessageRequestsCell: UITableViewCell {
}()
private func setUpViewHierarchy() {
backgroundColor = Colors.cellBackground
backgroundColor = Colors.cellPinned
selectedBackgroundView = UIView()
selectedBackgroundView?.backgroundColor = Colors.cellSelected

@ -139,7 +139,7 @@ final class SettingsVC : BaseVC, AvatarViewHelperDelegate {
setUpNavBarStyle()
setNavBarTitle(NSLocalizedString("vc_settings_title", comment: ""))
// Navigation bar buttons
let backButton = UIBarButtonItem(title: "Back", style: .plain, target: nil, action: nil)
let backButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
backButton.tintColor = Colors.text
navigationItem.backBarButtonItem = backButton
updateNavigationBarButtons()
@ -254,8 +254,6 @@ final class SettingsVC : BaseVC, AvatarViewHelperDelegate {
pathStatusView.pin(.leading, to: .trailing, of: pathButton.titleLabel!, withInset: Values.smallSpacing)
pathStatusView.autoVCenterInSuperview()
pathButton.titleEdgeInsets = UIEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: Values.smallSpacing)
return [
getSeparator(),
pathButton,

@ -358,15 +358,20 @@ final class ConversationCell : UITableViewCell {
if threadViewModel.isGroupThread {
if threadViewModel.name.isEmpty {
return "Unknown Group"
} else {
}
else {
return threadViewModel.name
}
} else {
}
else {
if threadViewModel.threadRecord.isNoteToSelf() {
return NSLocalizedString("NOTE_TO_SELF", comment: "")
} else {
let hexEncodedPublicKey = threadViewModel.contactSessionID!
return Storage.shared.getContact(with: hexEncodedPublicKey)?.displayName(for: .regular) ?? hexEncodedPublicKey
}
else {
let hexEncodedPublicKey: String = threadViewModel.contactSessionID!
let displayName: String = (Storage.shared.getContact(with: hexEncodedPublicKey)?.displayName(for: .regular) ?? hexEncodedPublicKey)
let middleTruncatedHexKey: String = "\(hexEncodedPublicKey.prefix(4))...\(hexEncodedPublicKey.suffix(4))"
return (displayName == hexEncodedPublicKey ? middleTruncatedHexKey : displayName)
}
}
}

@ -6,7 +6,7 @@ public final class Button : UIButton {
private var heightConstraint: NSLayoutConstraint!
public enum Style {
case unimportant, regular, prominentOutline, prominentFilled, regularBorderless
case unimportant, regular, prominentOutline, prominentFilled, regularBorderless, destructiveOutline
}
public enum Size {
@ -41,6 +41,7 @@ public final class Button : UIButton {
case .prominentOutline: fillColor = UIColor.clear
case .prominentFilled: fillColor = isLightMode ? Colors.text : Colors.accent
case .regularBorderless: fillColor = UIColor.clear
case .destructiveOutline: fillColor = UIColor.clear
}
let borderColor: UIColor
switch style {
@ -49,6 +50,7 @@ public final class Button : UIButton {
case .prominentOutline: borderColor = isLightMode ? Colors.text : Colors.accent
case .prominentFilled: borderColor = isLightMode ? Colors.text : Colors.accent
case .regularBorderless: borderColor = UIColor.clear
case .destructiveOutline: borderColor = Colors.destructive
}
let textColor: UIColor
switch style {
@ -57,6 +59,7 @@ public final class Button : UIButton {
case .prominentOutline: textColor = isLightMode ? Colors.text : Colors.accent
case .prominentFilled: textColor = isLightMode ? UIColor.white : Colors.text
case .regularBorderless: textColor = Colors.text
case .destructiveOutline: textColor = Colors.destructive
}
let height: CGFloat
switch size {

@ -28,7 +28,7 @@ public final class ViewControllerUtilities : NSObject {
}
// Set up back button
if hasCustomBackButton {
let backButton = UIBarButtonItem(title: "Back", style: .plain, target: nil, action: nil)
let backButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
backButton.tintColor = Colors.text
vc.navigationItem.backBarButtonItem = backButton
}

Loading…
Cancel
Save