mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
6.6 KiB
Objective-C
197 lines
6.6 KiB
Objective-C
//
|
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
#import "OWSMessageHeaderView.h"
|
|
#import "ConversationViewItem.h"
|
|
#import "Session-Swift.h"
|
|
#import <SignalUtilitiesKit/OWSUnreadIndicator.h>
|
|
#import <SignalUtilitiesKit/UIColor+OWS.h>
|
|
#import <SignalUtilitiesKit/UIFont+OWS.h>
|
|
#import <SessionUtilitiesKit/UIView+OWS.h>
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
const CGFloat OWSMessageHeaderViewDateHeaderVMargin = 16; // Values.mediumSpacing
|
|
|
|
@interface OWSMessageHeaderView ()
|
|
|
|
@property (nonatomic) UILabel *titleLabel;
|
|
@property (nonatomic) UILabel *subtitleLabel;
|
|
@property (nonatomic) UIView *strokeView;
|
|
@property (nonatomic) NSArray<NSLayoutConstraint *> *layoutConstraints;
|
|
@property (nonatomic) UIStackView *stackView;
|
|
|
|
@end
|
|
|
|
#pragma mark -
|
|
|
|
@implementation OWSMessageHeaderView
|
|
|
|
// `[UIView init]` invokes `[self initWithFrame:...]`.
|
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
{
|
|
if (self = [super initWithFrame:frame]) {
|
|
[self commontInit];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)commontInit
|
|
{
|
|
OWSAssertDebug(!self.titleLabel);
|
|
|
|
self.layoutMargins = UIEdgeInsetsZero;
|
|
self.layoutConstraints = @[];
|
|
|
|
// Intercept touches.
|
|
// Date breaks and unread indicators are not interactive.
|
|
self.userInteractionEnabled = YES;
|
|
|
|
self.strokeView = [UIView new];
|
|
[self.strokeView setContentHuggingHigh];
|
|
|
|
self.titleLabel = [UILabel new];
|
|
self.titleLabel.textAlignment = NSTextAlignmentCenter;
|
|
self.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
|
|
self.titleLabel.textColor = [LKColors.text colorWithAlphaComponent:0.8];
|
|
|
|
self.subtitleLabel = [UILabel new];
|
|
// The subtitle may wrap to a second line.
|
|
self.subtitleLabel.numberOfLines = 0;
|
|
self.subtitleLabel.lineBreakMode = NSLineBreakByWordWrapping;
|
|
self.subtitleLabel.textAlignment = NSTextAlignmentCenter;
|
|
|
|
self.stackView = [[UIStackView alloc] initWithArrangedSubviews:@[
|
|
self.strokeView,
|
|
self.titleLabel,
|
|
self.subtitleLabel,
|
|
]];
|
|
self.stackView.axis = NSTextLayoutOrientationVertical;
|
|
self.stackView.spacing = 2;
|
|
[self addSubview:self.stackView];
|
|
}
|
|
|
|
- (void)loadForDisplayWithViewItem:(id<ConversationViewItem>)viewItem
|
|
conversationStyle:(ConversationStyle *)conversationStyle
|
|
{
|
|
OWSAssertDebug(viewItem);
|
|
OWSAssertDebug(conversationStyle);
|
|
OWSAssertDebug(viewItem.unreadIndicator || viewItem.shouldShowDate);
|
|
|
|
self.titleLabel.textColor = [LKColors.text colorWithAlphaComponent:0.8];
|
|
self.subtitleLabel.textColor = [LKColors.text colorWithAlphaComponent:0.8];
|
|
|
|
[self configureLabelsWithViewItem:viewItem];
|
|
|
|
CGFloat strokeThickness = [self strokeThicknessWithViewItem:viewItem];
|
|
self.strokeView.layer.cornerRadius = strokeThickness * 0.5f;
|
|
self.strokeView.backgroundColor = [self strokeColorWithViewItem:viewItem];
|
|
self.strokeView.hidden = viewItem.unreadIndicator == nil;
|
|
|
|
self.subtitleLabel.hidden = self.subtitleLabel.text.length < 1;
|
|
|
|
[NSLayoutConstraint deactivateConstraints:self.layoutConstraints];
|
|
self.layoutConstraints = @[
|
|
[self.strokeView autoSetDimension:ALDimensionHeight toSize:strokeThickness],
|
|
|
|
[self.stackView autoPinEdgeToSuperviewEdge:ALEdgeTop],
|
|
[self.stackView autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:conversationStyle.headerGutterLeading],
|
|
[self.stackView autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:conversationStyle.headerGutterTrailing]
|
|
];
|
|
}
|
|
|
|
- (CGFloat)strokeThicknessWithViewItem:(id<ConversationViewItem>)viewItem
|
|
{
|
|
OWSAssertDebug(viewItem);
|
|
|
|
if (viewItem.unreadIndicator) {
|
|
return 1.f;
|
|
} else {
|
|
return 0.f;
|
|
}
|
|
}
|
|
|
|
- (UIColor *)strokeColorWithViewItem:(id<ConversationViewItem>)viewItem
|
|
{
|
|
OWSAssertDebug(viewItem);
|
|
|
|
if (viewItem.unreadIndicator) {
|
|
return Theme.secondaryColor;
|
|
} else {
|
|
return Theme.hairlineColor;
|
|
}
|
|
}
|
|
|
|
- (void)configureLabelsWithViewItem:(id<ConversationViewItem>)viewItem
|
|
{
|
|
OWSAssertDebug(viewItem);
|
|
|
|
NSDate *date = viewItem.interaction.receivedAtDate;
|
|
NSString *dateString = [DateUtil formatDateForConversationDateBreaks:date];
|
|
|
|
// Update cell to reflect changes in dynamic text.
|
|
if (viewItem.unreadIndicator) {
|
|
self.titleLabel.font = [UIFont boldSystemFontOfSize:LKValues.verySmallFontSize];
|
|
|
|
NSString *title = NSLocalizedString(
|
|
@"MESSAGES_VIEW_UNREAD_INDICATOR", @"Indicator that separates read from unread messages.");
|
|
if (viewItem.shouldShowDate) {
|
|
title = [[dateString rtlSafeAppend:@" \u00B7 "] rtlSafeAppend:title];
|
|
}
|
|
self.titleLabel.text = title;
|
|
|
|
if (!viewItem.unreadIndicator.hasMoreUnseenMessages) {
|
|
self.subtitleLabel.text = nil;
|
|
} else {
|
|
self.subtitleLabel.text = (viewItem.unreadIndicator.missingUnseenSafetyNumberChangeCount > 0
|
|
? NSLocalizedString(@"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES",
|
|
@"Messages that indicates that there are more unseen messages.")
|
|
: NSLocalizedString(
|
|
@"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_AND_SAFETY_NUMBER_CHANGES",
|
|
@"Messages that indicates that there are more unseen messages including safety number "
|
|
@"changes."));
|
|
}
|
|
} else {
|
|
self.titleLabel.font = [UIFont boldSystemFontOfSize:LKValues.verySmallFontSize];
|
|
self.titleLabel.text = dateString;
|
|
self.subtitleLabel.text = nil;
|
|
}
|
|
}
|
|
|
|
- (CGSize)measureWithConversationViewItem:(id<ConversationViewItem>)viewItem
|
|
conversationStyle:(ConversationStyle *)conversationStyle
|
|
{
|
|
OWSAssertDebug(viewItem);
|
|
OWSAssertDebug(conversationStyle);
|
|
OWSAssertDebug(viewItem.unreadIndicator || viewItem.shouldShowDate);
|
|
|
|
[self configureLabelsWithViewItem:viewItem];
|
|
|
|
CGSize result = CGSizeMake(conversationStyle.viewWidth, 0);
|
|
|
|
CGFloat strokeThickness = [self strokeThicknessWithViewItem:viewItem];
|
|
result.height += strokeThickness;
|
|
|
|
if (strokeThickness != 0) {
|
|
result.height += self.stackView.spacing;
|
|
}
|
|
|
|
CGFloat maxTextWidth = conversationStyle.headerViewContentWidth;
|
|
CGSize titleSize = [self.titleLabel sizeThatFits:CGSizeMake(maxTextWidth, CGFLOAT_MAX)];
|
|
result.height += titleSize.height;
|
|
|
|
if (self.subtitleLabel.text.length > 0) {
|
|
CGSize subtitleSize = [self.subtitleLabel sizeThatFits:CGSizeMake(maxTextWidth, CGFLOAT_MAX)];
|
|
result.height += self.stackView.spacing + subtitleSize.height;
|
|
}
|
|
result.height += OWSMessageHeaderViewDateHeaderVMargin;
|
|
|
|
return CGSizeCeil(result);
|
|
}
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|