Start implementing conversation screen redesign

pull/68/head
Niels Andriesse 6 years ago
parent 34b5b000a4
commit a8ad23fdfe

@ -571,6 +571,7 @@
B82B408C239A068800A248E7 /* RegisterVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82B408B239A068800A248E7 /* RegisterVC.swift */; };
B82B408E239DC00D00A248E7 /* DisplayNameVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82B408D239DC00D00A248E7 /* DisplayNameVC.swift */; };
B82B4090239DD75000A248E7 /* RestoreVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82B408F239DD75000A248E7 /* RestoreVC.swift */; };
B82B4094239DF15900A248E7 /* ConversationTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82B4093239DF15900A248E7 /* ConversationTitleView.swift */; };
B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; };
B84664F5235022F30083A1CD /* MentionUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84664F4235022F30083A1CD /* MentionUtilities.swift */; };
B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08323399ACF000F5AE3 /* Modal.swift */; };
@ -1405,6 +1406,7 @@
B82B408B239A068800A248E7 /* RegisterVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterVC.swift; sourceTree = "<group>"; };
B82B408D239DC00D00A248E7 /* DisplayNameVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayNameVC.swift; sourceTree = "<group>"; };
B82B408F239DD75000A248E7 /* RestoreVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestoreVC.swift; sourceTree = "<group>"; };
B82B4093239DF15900A248E7 /* ConversationTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationTitleView.swift; sourceTree = "<group>"; };
B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = "<group>"; };
B84664F4235022F30083A1CD /* MentionUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionUtilities.swift; sourceTree = "<group>"; };
B86BD08323399ACF000F5AE3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = "<group>"; };
@ -2798,6 +2800,7 @@
B8CCF63D2397580E0091D419 /* View Controllers */ = {
isa = PBXGroup;
children = (
B82B4093239DF15900A248E7 /* ConversationTitleView.swift */,
B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */,
B894D0702339D6F300B4D94D /* DeviceLinkingModalDelegate.swift */,
B80C6B562384A56D00FDBC8B /* DeviceLinksVC.swift */,
@ -4003,6 +4006,7 @@
340FC8BB204DAC8D007AEB0F /* OWSAddToContactViewController.m in Sources */,
45F32C232057297A00A300D5 /* MediaPageViewController.swift in Sources */,
452C468F1E427E200087B011 /* OutboundCallInitiator.swift in Sources */,
B82B4094239DF15900A248E7 /* ConversationTitleView.swift in Sources */,
34D2CCDA2062E7D000CB1A14 /* OWSScreenLockUI.m in Sources */,
45F170BB1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */,
4CA46F4C219CCC630038ABDE /* CaptionView.swift in Sources */,

@ -0,0 +1,89 @@
@objc final class ConversationTitleView : UIView {
private let thread: TSThread
// MARK: Components
private lazy var titleLabel: UILabel = {
let result = UILabel()
result.textColor = Colors.text
result.font = .boldSystemFont(ofSize: Values.mediumFontSize)
result.lineBreakMode = .byTruncatingTail
return result
}()
private lazy var subtitleLabel: UILabel = {
let result = UILabel()
result.textColor = Colors.text
result.font = .systemFont(ofSize: Values.smallFontSize)
result.lineBreakMode = .byTruncatingTail
return result
}()
// MARK: Lifecycle
@objc init(thread: TSThread) {
self.thread = thread
super.init(frame: CGRect.zero)
setUpViewHierarchy()
update()
NotificationCenter.default.addObserver(self, selector: #selector(handleProfileChangedNotification(_:)), name: NSNotification.Name(rawValue: kNSNotificationName_OtherUsersProfileDidChange), object: nil)
}
override init(frame: CGRect) {
preconditionFailure("Use init(thread:) instead.")
}
required init?(coder: NSCoder) {
preconditionFailure("Use init(thread:) instead.")
}
private func setUpViewHierarchy() {
let stackView = UIStackView(arrangedSubviews: [ titleLabel, subtitleLabel ])
stackView.axis = .vertical
stackView.alignment = .center
stackView.layoutMargins = UIEdgeInsets(top: 4, left: 8, bottom: 4, right: 0) // Compensate for settings button trailing margin
stackView.isLayoutMarginsRelativeArrangement = true
addSubview(stackView)
stackView.pin(to: self)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
// MARK: Updating
private func update() {
let title: String
if thread.isGroupThread() {
if thread.name().isEmpty {
title = NSLocalizedString("New Group", comment: "")
} else {
title = thread.name()
}
} else {
if thread.isNoteToSelf() {
title = NSLocalizedString("Note to Self", comment: "")
} else {
let hexEncodedPublicKey = thread.contactIdentifier()!
title = DisplayNameUtilities.getPrivateChatDisplayName(for: hexEncodedPublicKey) ?? hexEncodedPublicKey
}
}
titleLabel.text = title
let subtitle = NSMutableAttributedString()
if thread.isMuted {
subtitle.append(NSAttributedString(string: "\u{e067} ", attributes: [ .font : UIFont.ows_elegantIconsFont(10), .foregroundColor : Colors.unimportant ]))
}
subtitle.append(NSAttributedString(string: "26 members")) // TODO: Implement
subtitleLabel.attributedText = subtitle
}
@objc private func handleProfileChangedNotification(_ notification: Notification) {
guard let hexEncodedPublicKey = notification.userInfo?[kNSNotificationKey_ProfileRecipientId] as? String, let thread = self.thread as? TSContactThread,
hexEncodedPublicKey == thread.contactIdentifier() else { return }
update()
}
// MARK: Layout
public override var intrinsicContentSize: CGSize {
return UIView.layoutFittingExpandedSize
}
}

@ -16,18 +16,20 @@
[self updateTableContents];
// Loki: Set gradient background
self.tableView.backgroundColor = UIColor.clearColor;
LKGradient *gradient = LKGradients.defaultLokiBackground;
self.view.backgroundColor = UIColor.clearColor;
[self.view setGradient:gradient];
self.tableView.backgroundColor = UIColor.clearColor;
// Loki: Set navigation bar background color
UINavigationBar *navigationBar = self.navigationController.navigationBar;
[navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
navigationBar.shadowImage = [UIImage new];
[navigationBar setTranslucent:NO];
navigationBar.barTintColor = LKColors.navigationBarBackground;
// Loki: Customize title
UILabel *titleLabel = [UILabel new];
titleLabel.text = NSLocalizedString(@"Content", @"");
titleLabel.textColor = LKColors.text;

@ -19,24 +19,27 @@
[self updateTableContents];
// Loki: Set gradient background
self.tableView.backgroundColor = UIColor.clearColor;
LKGradient *gradient = LKGradients.defaultLokiBackground;
self.view.backgroundColor = UIColor.clearColor;
[self.view setGradient:gradient];
self.tableView.backgroundColor = UIColor.clearColor;
// Loki: Set navigation bar background color
UINavigationBar *navigationBar = self.navigationController.navigationBar;
[navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
navigationBar.shadowImage = [UIImage new];
[navigationBar setTranslucent:NO];
navigationBar.barTintColor = LKColors.navigationBarBackground;
// Loki: Customize title
UILabel *titleLabel = [UILabel new];
titleLabel.text = NSLocalizedString(@"Notifications", @"");
titleLabel.textColor = LKColors.text;
titleLabel.font = [UIFont boldSystemFontOfSize:LKValues.veryLargeFontSize];
self.navigationItem.titleView = titleLabel;
// Loki: Set up back button
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Back", "") style:UIBarButtonItemStylePlain target:nil action:nil];
backButton.tintColor = LKColors.text;
self.navigationItem.backBarButtonItem = backButton;

@ -38,18 +38,20 @@ NS_ASSUME_NONNULL_BEGIN
[self updateTableContents];
[self updateNavigationItems];
// Loki: Set gradient background
self.tableView.backgroundColor = UIColor.clearColor;
LKGradient *gradient = LKGradients.defaultLokiBackground;
self.view.backgroundColor = UIColor.clearColor;
[self.view setGradient:gradient];
self.tableView.backgroundColor = UIColor.clearColor;
// Loki: Set navigation bar background color
UINavigationBar *navigationBar = self.navigationController.navigationBar;
[navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
navigationBar.shadowImage = [UIImage new];
[navigationBar setTranslucent:NO];
navigationBar.barTintColor = LKColors.navigationBarBackground;
// Loki: Customize title
UILabel *titleLabel = [UILabel new];
titleLabel.text = NSLocalizedString(@"Sound", @"");
titleLabel.textColor = LKColors.text;

@ -29,18 +29,20 @@ static NSString *const kSealedSenderInfoURL = @"https://signal.org/blog/sealed-s
[self updateTableContents];
// Loki: Set gradient background
self.tableView.backgroundColor = UIColor.clearColor;
LKGradient *gradient = LKGradients.defaultLokiBackground;
self.view.backgroundColor = UIColor.clearColor;
[self.view setGradient:gradient];
self.tableView.backgroundColor = UIColor.clearColor;
// Loki: Set navigation bar background color
UINavigationBar *navigationBar = self.navigationController.navigationBar;
[navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
navigationBar.shadowImage = [UIImage new];
[navigationBar setTranslucent:NO];
navigationBar.barTintColor = LKColors.navigationBarBackground;
// Loki: Customize title
UILabel *titleLabel = [UILabel new];
titleLabel.text = NSLocalizedString(@"Privacy", @"");
titleLabel.textColor = LKColors.text;

@ -38,13 +38,13 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self commontInit];
[self commonInit];
}
return self;
}
- (void)commontInit
- (void)commonInit
{
// Ensure only called once.
OWSAssertDebug(!self.messageBubbleView);

@ -119,7 +119,6 @@ typedef enum : NSUInteger {
ContactsViewHelperDelegate,
DisappearingTimerConfigurationViewDelegate,
OWSConversationSettingsViewDelegate,
ConversationHeaderViewDelegate,
ConversationViewLayoutDelegate,
ConversationViewCellDelegate,
ConversationInputTextViewDelegate,
@ -160,7 +159,7 @@ typedef enum : NSUInteger {
@property (nonatomic, nullable) NSTimer *readTimer;
@property (nonatomic) NSCache *cellMediaCache;
@property (nonatomic) ConversationHeaderView *headerView;
@property (nonatomic) ConversationTitleView *headerView;
@property (nonatomic, nullable) UIView *bannerView;
@property (nonatomic, nullable) OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration;
@ -435,10 +434,6 @@ typedef enum : NSUInteger {
NSString *recipientId = notification.userInfo[kNSNotificationKey_ProfileRecipientId];
OWSAssertDebug(recipientId.length > 0);
if (recipientId.length > 0 && [self.thread.recipientIdentifiers containsObject:recipientId]) {
if ([self.thread isKindOfClass:[TSContactThread class]]) {
// update title with profile name
[self updateNavigationTitle];
}
if (self.isGroupConversation) {
// Reload all cells if this is a group conversation,
@ -477,7 +472,6 @@ typedef enum : NSUInteger {
{
OWSAssertIsOnMainThread();
[self updateNavigationBarSubtitleLabel];
[self ensureBannerState];
}
@ -627,16 +621,26 @@ typedef enum : NSUInteger {
[self applyTheme];
[self.conversationViewModel viewDidLoad];
// Loki: Track events
if (self.thread.isGroupThread) {
if (self.isRSSFeed) {
[LKAnalytics.shared track:@"RSS Feed Opened"];
} else {
[LKAnalytics.shared track:@"Loki Public Chat Opened"];
}
} else {
[LKAnalytics.shared track:@"Conversation Opened"];
}
// Loki: Set gradient background
self.collectionView.backgroundColor = UIColor.clearColor;
LKGradient *gradient = LKGradients.defaultLokiBackground;
self.view.backgroundColor = UIColor.clearColor;
[self.view setGradient:gradient];
// Loki: Set navigation bar background color
UINavigationBar *navigationBar = self.navigationController.navigationBar;
[navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
navigationBar.shadowImage = [UIImage new];
[navigationBar setTranslucent:NO];
navigationBar.barTintColor = LKColors.navigationBarBackground;
// Loki: Set up navigation bar buttons
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Back", "") style:UIBarButtonItemStylePlain target:nil action:nil];
backButton.tintColor = LKColors.text;
self.navigationItem.backBarButtonItem = backButton;
UIBarButtonItem *settingsButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Gear"] style:UIBarButtonItemStylePlain target:self action:@selector(showConversationSettings)];
settingsButton.tintColor = LKColors.text;
self.navigationItem.rightBarButtonItem = settingsButton;
}
- (void)createContents
@ -803,7 +807,6 @@ typedef enum : NSUInteger {
[self updateDisappearingMessagesConfiguration];
[self updateBarButtonItems];
[self updateNavigationTitle];
[self resetContentAndLayout];
@ -1260,8 +1263,6 @@ typedef enum : NSUInteger {
[ProfileFetcherJob runWithThread:self.thread];
[self markVisibleMessagesAsRead];
[self startReadTimer];
[self updateNavigationBarSubtitleLabel];
[self updateBackButtonUnreadCount];
[self autoLoadMoreIfNecessary];
if (!self.viewHasEverAppeared) {
@ -1376,60 +1377,12 @@ typedef enum : NSUInteger {
#pragma mark - Initiliazers
- (void)updateNavigationTitle
{
NSAttributedString *name;
if (self.thread.isGroupThread) {
if (self.thread.name.length == 0) {
name = [[NSAttributedString alloc] initWithString:[MessageStrings newGroupDefaultTitle]];
} else {
name = [[NSAttributedString alloc] initWithString:self.thread.name];
}
} else {
OWSAssertDebug(self.thread.contactIdentifier);
if (self.thread.isNoteToSelf) {
name = [[NSAttributedString alloc]
initWithString:NSLocalizedString(@"NOTE_TO_SELF", @"Label for 1:1 conversation with yourself.")
attributes:@{
NSFontAttributeName : self.headerView.titlePrimaryFont,
}];
} else {
name = [self.contactsManager
attributedContactOrProfileNameForPhoneIdentifier:self.thread.contactIdentifier
primaryFont:self.headerView.titlePrimaryFont
secondaryFont:self.headerView.titleSecondaryFont];
}
}
self.title = nil;
if ([name isEqual:self.headerView.attributedTitle]) {
return;
}
self.headerView.attributedTitle = name;
}
- (void)createHeaderViews
{
_backButtonUnreadCountView = [UIView new];
_backButtonUnreadCountView.layer.cornerRadius = self.unreadCountViewDiameter / 2;
_backButtonUnreadCountView.backgroundColor = [UIColor redColor];
_backButtonUnreadCountView.hidden = YES;
_backButtonUnreadCountView.userInteractionEnabled = NO;
_backButtonUnreadCountLabel = [UILabel new];
_backButtonUnreadCountLabel.backgroundColor = [UIColor clearColor];
_backButtonUnreadCountLabel.textColor = [UIColor whiteColor];
_backButtonUnreadCountLabel.font = [UIFont systemFontOfSize:11];
_backButtonUnreadCountLabel.textAlignment = NSTextAlignmentCenter;
ConversationHeaderView *headerView =
[[ConversationHeaderView alloc] initWithThread:self.thread contactsManager:self.contactsManager];
ConversationTitleView *headerView = [[ConversationTitleView alloc] initWithThread:self.thread];
self.headerView = headerView;
SET_SUBVIEW_ACCESSIBILITY_IDENTIFIER(self, headerView);
headerView.delegate = self;
self.navigationItem.titleView = headerView;
if (@available(iOS 11, *)) {
@ -1441,15 +1394,6 @@ typedef enum : NSUInteger {
CGRect headerFrame = CGRectMake(0, 0, screenSize.width, 44);
headerView.frame = headerFrame;
}
#ifdef USE_DEBUG_UI
[headerView addGestureRecognizer:[[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:@selector(navigationTitleLongPressed:)]];
#endif
[self updateNavigationBarSubtitleLabel];
}
- (CGFloat)unreadCountViewDiameter
@ -1480,9 +1424,6 @@ typedef enum : NSUInteger {
[_backButtonUnreadCountView addSubview:_backButtonUnreadCountLabel];
[_backButtonUnreadCountLabel autoPinWidthToSuperviewWithMargin:4];
[_backButtonUnreadCountLabel autoPinHeightToSuperview];
// Initialize newly created unread count badge to accurately reflect the current unread count.
[self updateBackButtonUnreadCount];
}
self.navigationItem.leftBarButtonItem = backItem;
@ -1495,6 +1436,8 @@ typedef enum : NSUInteger {
- (void)updateBarButtonItems
{
return; // Loki: Re-enable later?
self.navigationItem.hidesBackButton = NO;
if (self.customBackButton) {
self.navigationItem.leftBarButtonItem = self.customBackButton;
@ -1585,62 +1528,6 @@ typedef enum : NSUInteger {
self.navigationItem.rightBarButtonItems = [barButtons copy];
}
- (void)updateNavigationBarSubtitleLabel
{
BOOL hasCompactHeader = self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact;
if (hasCompactHeader) {
self.headerView.attributedSubtitle = nil;
return;
}
NSMutableAttributedString *subtitleText = [NSMutableAttributedString new];
UIColor *subtitleColor = [Theme.navbarTitleColor colorWithAlphaComponent:(CGFloat)0.9];
if (self.thread.isMuted) {
// Show a "mute" icon before the navigation bar subtitle if this thread is muted.
[subtitleText appendAttributedString:[[NSAttributedString alloc]
initWithString:LocalizationNotNeeded(@"\ue067 ")
attributes:@{
NSFontAttributeName : [UIFont ows_elegantIconsFont:7.f],
NSForegroundColorAttributeName : subtitleColor
}]];
}
BOOL isVerified = YES;
for (NSString *recipientId in self.thread.recipientIdentifiers) {
if ([[OWSIdentityManager sharedManager] verificationStateForRecipientId:recipientId]
!= OWSVerificationStateVerified) {
isVerified = NO;
break;
}
}
if (isVerified) {
// Show a "checkmark" icon before the navigation bar subtitle if this thread is verified.
[subtitleText appendAttributedString:[[NSAttributedString alloc]
initWithString:LocalizationNotNeeded(@"\uf00c ")
attributes:@{
NSFontAttributeName : [UIFont ows_fontAwesomeFont:10.f],
NSForegroundColorAttributeName : subtitleColor,
}]];
}
[subtitleText
appendAttributedString:[[NSAttributedString alloc]
initWithString:NSLocalizedString(@"MESSAGES_VIEW_TITLE_SUBTITLE",
@"The subtitle for the messages view title indicates that the "
@"title can be tapped to access settings for this conversation.")
attributes:@{
NSFontAttributeName : self.headerView.subtitleFont,
NSForegroundColorAttributeName : subtitleColor,
}]];
if (!self.thread.isGroupThread) {
self.headerView.attributedSubtitle = subtitleText;
}
}
#pragma mark - Updating
- (void)updateInputToolbar {
@ -3754,33 +3641,6 @@ typedef enum : NSUInteger {
}
}
#pragma mark Unread Badge
- (void)updateBackButtonUnreadCount
{
OWSAssertIsOnMainThread();
self.backButtonUnreadCount = [OWSMessageUtils.sharedManager unreadMessagesCountExcept:self.thread];
}
- (void)setBackButtonUnreadCount:(NSUInteger)unreadCount
{
OWSAssertIsOnMainThread();
if (_backButtonUnreadCount == unreadCount) {
// No need to re-render same count.
return;
}
_backButtonUnreadCount = unreadCount;
OWSAssertDebug(_backButtonUnreadCountView != nil);
_backButtonUnreadCountView.hidden = unreadCount <= 0;
OWSAssertDebug(_backButtonUnreadCountLabel != nil);
// Max out the unread count at 99+.
const NSUInteger kMaxUnreadCount = 99;
_backButtonUnreadCountLabel.text = [OWSFormat formatInt:(int)MIN(kMaxUnreadCount, unreadCount)];
}
#pragma mark 3D Touch Preview Actions
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems
@ -4115,8 +3975,6 @@ typedef enum : NSUInteger {
// make sure toolbar extends below iPhoneX home button.
self.view.backgroundColor = Theme.toolbarBackgroundColor;
self.collectionView.backgroundColor = Theme.backgroundColor;
[self updateNavigationBarSubtitleLabel];
}
#pragma mark - AttachmentApprovalViewControllerDelegate
@ -4282,7 +4140,6 @@ typedef enum : NSUInteger {
- (void)conversationColorWasUpdated
{
[self.conversationStyle updateProperties];
[self.headerView updateAvatar];
[self resetContentAndLayout];
}
@ -5083,8 +4940,6 @@ typedef enum : NSUInteger {
return;
}
[self updateBackButtonUnreadCount];
[self updateNavigationBarSubtitleLabel];
[self dismissMenuActionsIfNecessary];
[self updateInputToolbar];
@ -5092,7 +4947,6 @@ typedef enum : NSUInteger {
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
[self.thread reloadWithTransaction:transaction];
}];
[self updateNavigationTitle];
}
[self updateDisappearingMessagesConfiguration];
@ -5349,7 +5203,6 @@ typedef enum : NSUInteger {
{
[super traitCollectionDidChange:previousTraitCollection];
[self updateNavigationBarSubtitleLabel];
[self ensureBannerState];
[self updateBarButtonItems];
}

Loading…
Cancel
Save