ReplyMessageView.m 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /**
  2. * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
  3. * SPDX-License-Identifier: GPL-3.0-or-later
  4. */
  5. #import "ReplyMessageView.h"
  6. #import "SLKUIConstants.h"
  7. #import "NCAppBranding.h"
  8. #import "NCChatMessage.h"
  9. #import "QuotedMessageView.h"
  10. #import "NextcloudTalk-Swift.h"
  11. @interface ReplyMessageView ()
  12. @property (nonatomic, strong) UIView *quoteContainerView;
  13. @property (nonatomic, strong) UIButton *cancelButton;
  14. @property (nonatomic, strong) NSArray<NSLayoutConstraint *> *hConstraints;
  15. @end
  16. @implementation ReplyMessageView
  17. @synthesize visible = _visible;
  18. - (instancetype)init
  19. {
  20. self = [super init];
  21. if (self) {
  22. [self configureSubviews];
  23. }
  24. return self;
  25. }
  26. - (void)configureSubviews
  27. {
  28. self.backgroundColor = [NCAppBranding backgroundColor];
  29. [self addSubview:self.quoteContainerView];
  30. [self addSubview:self.cancelButton];
  31. [self.layer addSublayer:self.topBorder];
  32. [_quoteContainerView addSubview:self.quotedMessageView];
  33. NSDictionary *views = @{
  34. @"quoteContainerView": self.quoteContainerView,
  35. @"quotedMessageView": self.quotedMessageView,
  36. @"cancelButton": self.cancelButton
  37. };
  38. self.hConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-16-[quoteContainerView]-4-[cancelButton(44)]-4-|" options:0 metrics:nil views:views];
  39. [self addConstraints:self.hConstraints];
  40. [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[quotedMessageView(quoteContainerView)]|" options:0 metrics:nil views:views]];
  41. [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[quoteContainerView]|" options:0 metrics:nil views:views]];
  42. [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[cancelButton]|" options:0 metrics:nil views:views]];
  43. // Center the quotedMessageView inside the container view (if we add a padding in the layout above, we need to break constraints when height is 0)
  44. NSLayoutConstraint *centerConstraint = [NSLayoutConstraint constraintWithItem:self.quotedMessageView
  45. attribute:NSLayoutAttributeCenterY
  46. relatedBy:NSLayoutRelationEqual
  47. toItem:self.quoteContainerView
  48. attribute:NSLayoutAttributeCenterY
  49. multiplier:1.0f
  50. constant:0.0f];
  51. [self.quoteContainerView addConstraints:@[centerConstraint]];
  52. }
  53. #pragma mark - UIView
  54. - (void)layoutSubviews
  55. {
  56. [super layoutSubviews];
  57. self.topBorder.frame = CGRectMake(0, 0, self.bounds.size.width, 1);
  58. }
  59. - (CGSize)intrinsicContentSize
  60. {
  61. // This will indicate the size of the view when calling systemLayoutSizeFittingSize in SLKTextViewController
  62. // QuoteMessageView(60) + 2*Padding(8)
  63. return CGSizeMake(UIViewNoIntrinsicMetric, 76);
  64. }
  65. - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
  66. {
  67. if (_topBorder && [self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
  68. // We use a CGColor so we loose the automatic color changing of dynamic colors -> update manually
  69. _topBorder.backgroundColor = [UIColor systemGray6Color].CGColor;
  70. }
  71. }
  72. #pragma mark - SLKReplyViewProtocol
  73. - (void)dismiss
  74. {
  75. if (self.isVisible) {
  76. self.visible = NO;
  77. }
  78. }
  79. #pragma mark - Getters
  80. - (UIView *)quoteContainerView
  81. {
  82. if (!_quoteContainerView) {
  83. _quoteContainerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];
  84. _quoteContainerView.translatesAutoresizingMaskIntoConstraints = NO;
  85. }
  86. return _quoteContainerView;
  87. }
  88. - (QuotedMessageView *)quotedMessageView
  89. {
  90. if (!_quotedMessageView) {
  91. _quotedMessageView = [[QuotedMessageView alloc] init];
  92. _quotedMessageView.translatesAutoresizingMaskIntoConstraints = NO;
  93. }
  94. return _quotedMessageView;
  95. }
  96. - (UIButton *)cancelButton
  97. {
  98. if (!_cancelButton) {
  99. _cancelButton = [UIButton buttonWithType:UIButtonTypeSystem];
  100. _cancelButton.translatesAutoresizingMaskIntoConstraints = NO;
  101. _cancelButton.titleLabel.font = [UIFont boldSystemFontOfSize:15.0];
  102. [_cancelButton setImage:[UIImage systemImageNamed:@"xmark.circle"] forState:UIControlStateNormal];
  103. [_cancelButton addTarget:self action:@selector(dismiss) forControlEvents:UIControlEventTouchUpInside];
  104. }
  105. return _cancelButton;
  106. }
  107. - (CALayer *)topBorder
  108. {
  109. if (!_topBorder) {
  110. _topBorder = [CAGradientLayer layer];
  111. _topBorder.frame = CGRectMake(0.0, 0.0, self.frame.size.width, 1);
  112. _topBorder.backgroundColor = [UIColor systemGray6Color].CGColor;
  113. }
  114. return _topBorder;
  115. }
  116. #pragma mark - ReplyMessageView
  117. - (void)presentReplyViewWithMessage:(NCChatMessage *)message withUserId:(NSString *)userId
  118. {
  119. if (!message) {
  120. return;
  121. }
  122. self.message = message;
  123. self.quotedMessageView.actorLabel.text = ([message.actorDisplayName isEqualToString:@""]) ? NSLocalizedString(@"Guest", nil) : message.actorDisplayName;
  124. self.quotedMessageView.messageLabel.text = message.parsedMarkdownForChat.string;
  125. self.quotedMessageView.highlighted = [message isMessageFrom:userId];
  126. [self.quotedMessageView.avatarView setActorAvatarForMessage:message];
  127. [self.cancelButton setHidden:NO];
  128. // Reset button size to 44 in case it was hidden before
  129. self.hConstraints[2].constant = 44;
  130. self.visible = YES;
  131. }
  132. - (void)hideCloseButton
  133. {
  134. [self.cancelButton setHidden:YES];
  135. // With 2*4 padding (left and right to the button) we add 8 to have 16 as we have on the left side of the quoteView
  136. self.hConstraints[2].constant = 8;
  137. }
  138. @end