diff --git a/WordPress/Classes/Extensions/UIAlertController+Helpers.swift b/WordPress/Classes/Extensions/UIAlertController+Helpers.swift index 4c2a295cbc69..7ca4b3821cb5 100644 --- a/WordPress/Classes/Extensions/UIAlertController+Helpers.swift +++ b/WordPress/Classes/Extensions/UIAlertController+Helpers.swift @@ -33,17 +33,4 @@ extension UIAlertController { alertController.addCancelActionWithTitle(NSLocalizedString("Cancel", comment: "Cancel copying link to comment button title")) return alertController } - - /// This method is will present an alert controller (action sheet style) that - /// provides a copy action to allow copying the url parameter to the clip board. - /// Once copied, a notice will be posted using the dispacher so the user will know - /// the url was copied. - @objc static func presentAlertAndCopyCommentURLToClipboard(url: URL) { - let noticeTitle = NSLocalizedString("Link Copied to Clipboard", comment: "Link copied to clipboard notice title") - - let copyAlertController = UIAlertController.copyCommentURLAlertController(url) { - ActionDispatcher.dispatch(NoticeAction.post(Notice(title: noticeTitle))) - } - copyAlertController?.presentFromRootViewController() - } } diff --git a/WordPress/Classes/System/WordPress-Bridging-Header.h b/WordPress/Classes/System/WordPress-Bridging-Header.h index 01a375ecb212..1e9c97c7fa03 100644 --- a/WordPress/Classes/System/WordPress-Bridging-Header.h +++ b/WordPress/Classes/System/WordPress-Bridging-Header.h @@ -16,8 +16,6 @@ #import "CoreDataStack.h" #import "Coordinate.h" -#import "EditCommentViewController.h" - #import "LocalCoreDataService.h" #import "Media.h" diff --git a/WordPress/Classes/ViewRelated/Comments/Controllers/EditCommentViewController.h b/WordPress/Classes/ViewRelated/Comments/Controllers/EditCommentViewController.h deleted file mode 100644 index dca895fb0a54..000000000000 --- a/WordPress/Classes/ViewRelated/Comments/Controllers/EditCommentViewController.h +++ /dev/null @@ -1,23 +0,0 @@ -#import - -typedef void (^EditCommentCompletion)(BOOL hasNewContent, NSString *newContent); - -@interface EditCommentViewController : UIViewController -@property (nonatomic, copy) EditCommentCompletion onCompletion; -@property (nonatomic, strong) NSString *content; -@property (nonatomic, assign) BOOL interfaceEnabled; -@property (readonly, nonatomic, weak) IBOutlet UITextView *textView; -@property (readonly, nonatomic, weak) IBOutlet UILabel *placeholderLabel; -@property (readonly, nonatomic, assign) CGRect keyboardFrame; - -+ (instancetype)newEditViewController; -+ (NSString *)nibName; - -/// Triggered to indicate the content of the text view has changed -/// Automatically called when the user enters text into the `textView` -- (void)contentDidChange; - -// Keyboard handlers -- (void)handleKeyboardDidShow:(NSNotification *)notification; -- (void)handleKeyboardWillHide:(NSNotification *)notification; -@end diff --git a/WordPress/Classes/ViewRelated/Comments/Controllers/EditCommentViewController.m b/WordPress/Classes/ViewRelated/Comments/Controllers/EditCommentViewController.m deleted file mode 100644 index 73d744bd5a5e..000000000000 --- a/WordPress/Classes/ViewRelated/Comments/Controllers/EditCommentViewController.m +++ /dev/null @@ -1,220 +0,0 @@ -#import "EditCommentViewController.h" -#import "CommentService.h" -#import "CoreDataStack.h" - -#import "WordPress-Swift.h" - - -#pragma mark ========================================================================================== -#pragma mark Private Methods -#pragma mark ========================================================================================== - -@interface EditCommentViewController() -@property (readwrite, nonatomic, weak) IBOutlet UITextView *textView; -@property (readwrite, nonatomic, weak) IBOutlet UILabel *placeholderLabel; -@property (nonatomic, strong) NSString *pristineText; -@property (readwrite, nonatomic, assign) CGRect keyboardFrame; - -- (void)handleKeyboardDidShow:(NSNotification *)notification; -- (void)handleKeyboardWillHide:(NSNotification *)notification; - -@end - - -#pragma mark ========================================================================================== -#pragma mark EditCommentViewController -#pragma mark ========================================================================================== - -@implementation EditCommentViewController - -#pragma mark - Static Helpers - -/// Tries to determine the correct nibName to use when init'ing -/// If the current class's nib doesn't exist, then we'll use the parent class -+ (NSString *)nibName -{ - Class current = [self class]; - - //We use nib because the bundle won't look for xib's - BOOL nibExists = [[NSBundle mainBundle] pathForResource:NSStringFromClass(current) ofType:@"nib"] ? YES : NO; - - if(!nibExists){ - current = [self superclass]; - } - - nibExists = [[NSBundle mainBundle] pathForResource:NSStringFromClass(current) ofType:@"nib"] ? YES : NO; - - if(!nibExists){ - return nil; - } - - return NSStringFromClass(current); -} - - -+ (instancetype)newEditViewController -{ - NSString *xibName = [[self class] nibName]; - - return [[[self class] alloc] initWithNibName:xibName bundle:nil]; -} - -#pragma mark - Lifecycle - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.title = NSLocalizedString(@"Edit Comment", @""); - self.view.backgroundColor = [UIColor murielBasicBackground]; - self.textView.backgroundColor = [UIColor murielBasicBackground]; - self.textView.textColor = [UIColor murielText]; - self.placeholderLabel.textColor = [UIColor murielTextPlaceholder]; - - [self showCancelBarButton]; - [self showSaveBarButton]; - - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc addObserver:self selector:@selector(handleKeyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; - [nc addObserver:self selector:@selector(handleKeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; -} - -- (void)viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; - - self.textView.text = self.content; - self.pristineText = self.content; - - [self.textView becomeFirstResponder]; - [self enableSaveIfNeeded]; -} - -- (void)viewWillDisappear:(BOOL)animated -{ - [super viewWillDisappear:animated]; - - // FIX FIX: - // iOS 8+ is resigning first responder when the presentedViewController is effectively removed from screen. - // This creates a UX glitch, as a side effect (two animations!!) - [self.textView resignFirstResponder]; -} - -#pragma mark - Public -- (void)contentDidChange -{ - [self enableSaveIfNeeded]; -} - -#pragma mark - View Helpers - -- (void)showCancelBarButton -{ - self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Cancel", nil) style:UIBarButtonItemStylePlain target:self action:@selector(btnCancelPressed)]; -} - -- (void)showSaveBarButton -{ - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Save", @"Save button label (saving content, ex: Post, Page, Comment).") style:UIBarButtonItemStylePlain target:self action:@selector(btnSavePressed)]; -} - -- (void)setInterfaceEnabled:(BOOL)enabled -{ - self.textView.editable = enabled; - self.navigationItem.rightBarButtonItem.enabled = enabled; - self.navigationItem.leftBarButtonItem.enabled = enabled; - _interfaceEnabled = enabled; -} - -- (BOOL)hasChanges -{ - return ![self.textView.text isEqualToString:self.pristineText]; -} - -- (void)enableSaveIfNeeded -{ - self.navigationItem.rightBarButtonItem.enabled = self.hasChanges; -} - -#pragma mark - KeyboardNotification Methods - -- (void)handleKeyboardDidShow:(NSNotification *)notification -{ - CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; - self.keyboardFrame = keyboardRect; - CGSize kbSize = keyboardRect.size; - - UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0); - self.textView.contentInset = contentInsets; - self.textView.scrollIndicatorInsets = contentInsets; - - - // Scroll the active text field into view. - CGRect rect = [self.textView caretRectForPosition:self.textView.selectedTextRange.start]; - - [self.textView scrollRectToVisible:rect animated:NO]; -} - -- (void)handleKeyboardWillHide:(NSNotification *)notification -{ - UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, 0, 0.0); - self.textView.contentInset = contentInsets; - self.textView.scrollIndicatorInsets = contentInsets; - self.keyboardFrame = CGRectZero; -} - -#pragma mark - Text View Delegate Methods - -- (void)textViewDidChange:(UITextView *)textView -{ - [self contentDidChange]; -} - -#pragma mark - Button Delegates - -- (void)btnCancelPressed -{ - if (self.hasChanges == NO) { - [self finishWithoutUpdates]; - return; - } - - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"You have unsaved changes.", @"Show when clicking cancel on a comment text box and you didn't save your changes.") - message:nil - preferredStyle:UIAlertControllerStyleActionSheet]; - [alertController addActionWithTitle:NSLocalizedString(@"Cancel", @"") - style:UIAlertActionStyleCancel - handler:nil]; - [alertController addActionWithTitle:NSLocalizedString(@"Discard", @"") - style:UIAlertActionStyleDestructive - handler:^(UIAlertAction * __unused alertAction) { - [self finishWithoutUpdates]; - }]; - alertController.popoverPresentationController.barButtonItem = self.navigationItem.leftBarButtonItem; - [self presentViewController:alertController animated:YES completion:nil]; - -} - -- (void)btnSavePressed -{ - [self finishWithUpdates]; -} - - -#pragma mark - Helper Methods - -- (void)finishWithUpdates -{ - if (self.onCompletion) { - self.onCompletion(true, self.textView.text); - } -} - -- (void)finishWithoutUpdates -{ - if (self.onCompletion) { - self.onCompletion(false, self.pristineText); - } -} - -@end diff --git a/WordPress/Classes/ViewRelated/Comments/Views/EditCommentViewController.xib b/WordPress/Classes/ViewRelated/Comments/Views/EditCommentViewController.xib deleted file mode 100644 index 77fb9a88c708..000000000000 --- a/WordPress/Classes/ViewRelated/Comments/Views/EditCommentViewController.xib +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationDetailsViewController.swift b/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationDetailsViewController.swift index d1de100338c8..b094eb804ad4 100644 --- a/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationDetailsViewController.swift +++ b/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationDetailsViewController.swift @@ -48,10 +48,6 @@ class NotificationDetailsViewController: UIViewController, NoResultsViewHost { /// @IBOutlet var badgeCenterLayoutConstraint: NSLayoutConstraint! - /// RelpyTextView - /// - @IBOutlet var replyTextView: CommentLargeButton! - /// Embedded Media Downloader /// fileprivate var mediaDownloader = NotificationMediaDownloader() @@ -139,7 +135,6 @@ class NotificationDetailsViewController: UIViewController, NoResultsViewHost { setupTableView() setupTableViewCells() setupTableDelegates() - setupReplyTextView() } override func viewWillAppear(_ animated: Bool) { @@ -201,7 +196,6 @@ class NotificationDetailsViewController: UIViewController, NoResultsViewHost { fileprivate func refreshInterface() { formatter.resetCache() tableView.reloadData() - attachReplyViewIfNeeded() adjustLayoutConstraintsIfNeeded() refreshNavigationBar() } @@ -347,19 +341,17 @@ extension NotificationDetailsViewController { } func setupTableView() { - tableView.separatorStyle = .none - tableView.keyboardDismissMode = .interactive - tableView.accessibilityIdentifier = .notificationDetailsTableAccessibilityId - tableView.accessibilityLabel = NSLocalizedString("Notification Details Table", comment: "Notifications Details Accessibility Identifier") - tableView.backgroundColor = .systemBackground + tableView.separatorStyle = .none + tableView.keyboardDismissMode = .interactive + tableView.accessibilityIdentifier = .notificationDetailsTableAccessibilityId + tableView.accessibilityLabel = NSLocalizedString("Notification Details Table", comment: "Notifications Details Accessibility Identifier") + tableView.backgroundColor = .systemBackground } func setupTableViewCells() { let cellClassNames: [NoteBlockTableViewCell.Type] = [ NoteBlockHeaderTableViewCell.self, NoteBlockTextTableViewCell.self, - NoteBlockActionsTableViewCell.self, - NoteBlockCommentTableViewCell.self, NoteBlockImageTableViewCell.self, NoteBlockUserTableViewCell.self, NoteBlockButtonTableViewCell.self @@ -396,22 +388,6 @@ extension NotificationDetailsViewController { } } - func setupReplyTextView() { - let replyTextView = CommentLargeButton() - - replyTextView.placeholder = NSLocalizedString("Write a reply", comment: "Placeholder text for inline compose view") - replyTextView.accessibilityLabel = NSLocalizedString("Reply Text", comment: "Notifications Reply Accessibility Identifier") - - replyTextView.onTap = { - // TODO: (kean) remove the remaining .comment-related code - wpAssertionFailure("Notifications have been using NotificationCommentDetailViewController since 2023") - } - - replyTextView.setContentCompressionResistancePriority(.required, for: .vertical) - - self.replyTextView = replyTextView - } - func setupNotificationListeners() { let nc = NotificationCenter.default nc.addObserver(self, selector: #selector(notificationWasUpdated), name: .NSManagedObjectContextObjectsDidChange, object: note.managedObjectContext) @@ -423,28 +399,6 @@ extension NotificationDetailsViewController { } } -// MARK: - Reply View Helpers -// -extension NotificationDetailsViewController { - func attachReplyViewIfNeeded() { - guard shouldAttachReplyView else { - replyTextView.removeFromSuperview() - return - } - - stackView.addArrangedSubview(replyTextView) - } - - var shouldAttachReplyView: Bool { - // Attach the Reply component only if the notification has a comment, and it can be replied to. - // - guard let block: FormattableCommentContent = note.contentGroup(ofKind: .comment)?.blockOfKind(.comment) else { - return false - } - return block.action(id: ReplyToCommentAction.actionIdentifier())?.on ?? false - } -} - // MARK: - Layout Helpers // private extension NotificationDetailsViewController { @@ -480,10 +434,6 @@ private extension NotificationDetailsViewController { fallthrough case .text: return NoteBlockTextTableViewCell.reuseIdentifier() - case .comment: - return NoteBlockCommentTableViewCell.reuseIdentifier() - case .actions: - return NoteBlockActionsTableViewCell.reuseIdentifier() case .image: return NoteBlockImageTableViewCell.reuseIdentifier() case .user: @@ -515,10 +465,6 @@ private extension NotificationDetailsViewController { setupFooterCell(cell, blockGroup: blockGroup) case let cell as NoteBlockUserTableViewCell: setupUserCell(cell, blockGroup: blockGroup) - case let cell as NoteBlockCommentTableViewCell: - setupCommentCell(cell, blockGroup: blockGroup, at: indexPath) - case let cell as NoteBlockActionsTableViewCell: - setupActionsCell(cell, blockGroup: blockGroup) case let cell as NoteBlockImageTableViewCell: setupImageCell(cell, blockGroup: blockGroup) case let cell as NoteBlockTextTableViewCell: @@ -592,128 +538,6 @@ private extension NotificationDetailsViewController { cell.downloadGravatarWithURL(mediaURL) } - func setupCommentCell(_ cell: NoteBlockCommentTableViewCell, blockGroup: FormattableContentGroup, at indexPath: IndexPath) { - // Note: - // The main reason why it's a very good idea *not* to reuse NoteBlockHeaderTableViewCell, just to display the - // gravatar, is because we're implementing a custom behavior whenever the user approves/ unapproves the comment. - // - // - Font colors are updated. - // - A left separator is displayed. - // - guard let commentBlock: FormattableCommentContent = blockGroup.blockOfKind(.comment) else { - assertionFailure("Missing Comment Block for Notification [\(note.notificationId)]") - return - } - - guard let userBlock: FormattableUserContent = blockGroup.blockOfKind(.user) else { - assertionFailure("Missing User Block for Notification [\(note.notificationId)]") - return - } - - // Merge the Attachments with their ranges: [NSRange: UIImage] - let mediaMap = mediaDownloader.imagesForUrls(commentBlock.imageUrls) - let mediaRanges = commentBlock.buildRangesToImagesMap(mediaMap) - - let styles = RichTextContentStyles(key: "RichText-\(indexPath)") - let text = formatter.render(content: commentBlock, with: styles).stringByEmbeddingImageAttachments(mediaRanges) - - // Setup: Properties - cell.name = userBlock.text - cell.timestamp = (note.timestampAsDate as NSDate).mediumString() - cell.site = userBlock.metaTitlesHome ?? userBlock.metaLinksHome?.host - cell.attributedCommentText = text.trimNewlines() - cell.isApproved = commentBlock.isCommentApproved - - // Add comment author's name to Reply placeholder. - let placeholderFormat = NSLocalizedString("Reply to %1$@", - comment: "Placeholder text for replying to a comment. %1$@ is a placeholder for the comment author's name.") - replyTextView.placeholder = String(format: placeholderFormat, cell.name ?? String()) - - // Setup: Callbacks - cell.onUserClick = { [weak self] in - guard let homeURL = userBlock.metaLinksHome else { - return - } - - self?.displayURL(homeURL) - } - - cell.onUrlClick = { [weak self] url in - self?.displayURL(url as URL) - } - - cell.onAttachmentClick = { [weak self] attachment in - guard let image = attachment.image else { - return - } - self?.router.routeTo(image) - } - - cell.onTimeStampLongPress = { [weak self] in - guard let urlString = self?.note.url, - let url = URL(string: urlString) else { - return - } - UIAlertController.presentAlertAndCopyCommentURLToClipboard(url: url) - } - - // Download the Gravatar - let mediaURL = userBlock.media.first?.mediaURL - cell.downloadGravatarWithURL(mediaURL) - } - - func setupActionsCell(_ cell: NoteBlockActionsTableViewCell, blockGroup: FormattableContentGroup) { - guard let commentBlock: FormattableCommentContent = blockGroup.blockOfKind(.comment) else { - assertionFailure("Missing Comment Block for Notification \(note.notificationId)") - return - } - - // Setup: Properties - // Note: Approve Action is actually a synonym for 'Edit' (Based on Calypso's basecode) - // - cell.isReplyEnabled = UIDevice.isPad() && commentBlock.isActionOn(id: ReplyToCommentAction.actionIdentifier()) - cell.isLikeEnabled = commentBlock.isActionEnabled(id: LikeCommentAction.actionIdentifier()) - cell.isApproveEnabled = commentBlock.isActionEnabled(id: ApproveCommentAction.actionIdentifier()) - cell.isTrashEnabled = commentBlock.isActionEnabled(id: TrashCommentAction.actionIdentifier()) - cell.isSpamEnabled = commentBlock.isActionEnabled(id: MarkAsSpamAction.actionIdentifier()) - cell.isEditEnabled = commentBlock.isActionOn(id: ApproveCommentAction.actionIdentifier()) - cell.isLikeOn = commentBlock.isActionOn(id: LikeCommentAction.actionIdentifier()) - cell.isApproveOn = commentBlock.isActionOn(id: ApproveCommentAction.actionIdentifier()) - - // Setup: Callbacks - cell.onReplyClick = { _ in - wpAssertionFailure("no longer used") - } - - cell.onLikeClick = { [weak self] _ in - self?.likeCommentWithBlock(commentBlock) - } - - cell.onUnlikeClick = { [weak self] _ in - self?.unlikeCommentWithBlock(commentBlock) - } - - cell.onApproveClick = { [weak self] _ in - self?.approveCommentWithBlock(commentBlock) - } - - cell.onUnapproveClick = { [weak self] _ in - self?.unapproveCommentWithBlock(commentBlock) - } - - cell.onTrashClick = { [weak self] _ in - self?.trashCommentWithBlock(commentBlock) - } - - cell.onSpamClick = { [weak self] _ in - self?.spamCommentWithBlock(commentBlock) - } - - cell.onEditClick = { [weak self] _ in - self?.displayCommentEditorWithBlock(commentBlock) - } - } - func setupImageCell(_ cell: NoteBlockImageTableViewCell, blockGroup: FormattableContentGroup) { guard let imageBlock = blockGroup.blocks.first as? NotificationTextContent else { assertionFailure("Missing Image Block for Notification [\(note.notificationId)") @@ -912,165 +736,6 @@ private extension NotificationDetailsViewController { actionsService.unfollowSiteWithBlock(block) WPAppAnalytics.track(.notificationsSiteUnfollowAction, withBlogID: block.metaSiteID) } - - func likeCommentWithBlock(_ block: FormattableCommentContent) { - guard let likeAction = block.action(id: LikeCommentAction.actionIdentifier()) else { - return - } - let actionContext = ActionContext(block: block) - likeAction.execute(context: actionContext) - WPAppAnalytics.track(.notificationsCommentLiked, withBlogID: block.metaSiteID) - } - - func unlikeCommentWithBlock(_ block: FormattableCommentContent) { - guard let likeAction = block.action(id: LikeCommentAction.actionIdentifier()) else { - return - } - let actionContext = ActionContext(block: block) - likeAction.execute(context: actionContext) - WPAppAnalytics.track(.notificationsCommentUnliked, withBlogID: block.metaSiteID) - } - - func approveCommentWithBlock(_ block: FormattableCommentContent) { - guard let approveAction = block.action(id: ApproveCommentAction.actionIdentifier()) else { - return - } - - let actionContext = ActionContext(block: block) - approveAction.execute(context: actionContext) - WPAppAnalytics.track(.notificationsCommentApproved, withBlogID: block.metaSiteID) - } - - func unapproveCommentWithBlock(_ block: FormattableCommentContent) { - guard let approveAction = block.action(id: ApproveCommentAction.actionIdentifier()) else { - return - } - - let actionContext = ActionContext(block: block) - approveAction.execute(context: actionContext) - WPAppAnalytics.track(.notificationsCommentUnapproved, withBlogID: block.metaSiteID) - } - - func spamCommentWithBlock(_ block: FormattableCommentContent) { - guard onDeletionRequestCallback != nil else { - // callback probably missing due to state restoration. at least by - // not crashing the user can tap the back button and try again - return - } - - guard let spamAction = block.action(id: MarkAsSpamAction.actionIdentifier()) else { - return - } - - let actionContext = ActionContext(block: block, completion: { [weak self] (request, success) in - WPAppAnalytics.track(.notificationsCommentFlaggedAsSpam, withBlogID: block.metaSiteID) - guard let request else { - return - } - self?.onDeletionRequestCallback?(request) - }) - - spamAction.execute(context: actionContext) - - // We're thru - _ = navigationController?.popToRootViewController(animated: true) - } - - func trashCommentWithBlock(_ block: FormattableCommentContent) { - guard onDeletionRequestCallback != nil else { - // callback probably missing due to state restoration. at least by - // not crashing the user can tap the back button and try again - return - } - - guard let trashAction = block.action(id: TrashCommentAction.actionIdentifier()) else { - return - } - - let actionContext = ActionContext(block: block, completion: { [weak self] (request, success) in - WPAppAnalytics.track(.notificationsCommentTrashed, withBlogID: block.metaSiteID) - guard let request else { - return - } - self?.onDeletionRequestCallback?(request) - }) - - trashAction.execute(context: actionContext) - - // We're thru - _ = navigationController?.popToRootViewController(animated: true) - } - - func updateCommentWithBlock(_ block: FormattableCommentContent, content: String) { - guard let editCommentAction = block.action(id: EditCommentAction.actionIdentifier()) else { - return - } - - let generator = UINotificationFeedbackGenerator() - generator.prepare() - generator.notificationOccurred(.success) - - let actionContext = ActionContext(block: block, content: content) { [weak self] (request, success) in - guard success == false else { - CommentAnalytics.trackCommentEdited(block: block) - return - } - - generator.notificationOccurred(.error) - self?.displayCommentUpdateErrorWithBlock(block, content: content) - } - - editCommentAction.execute(context: actionContext) - } -} - -// MARK: - Editing Comments -// -private extension NotificationDetailsViewController { - - func updateComment(with commentContent: FormattableCommentContent, content: String) { - self.updateCommentWithBlock(commentContent, content: content) - } - - func displayCommentEditorWithBlock(_ block: FormattableCommentContent) { - let editViewController = EditCommentViewController.newEdit() - editViewController?.content = block.text - editViewController?.onCompletion = { (hasNewContent, newContent) in - self.dismiss(animated: true, completion: { - guard hasNewContent else { - return - } - let newContent = newContent ?? "" - self.updateComment(with: block, content: newContent) - }) - } - - let navController = UINavigationController(rootViewController: editViewController!) - navController.modalPresentationStyle = .formSheet - navController.modalTransitionStyle = .coverVertical - - CommentAnalytics.trackCommentEditorOpened(block: block) - present(navController, animated: true) - } - - func displayCommentUpdateErrorWithBlock(_ block: FormattableCommentContent, content: String) { - let message = NSLocalizedString("There has been an unexpected error while updating your comment", - comment: "Displayed whenever a Comment Update Fails") - let cancelTitle = NSLocalizedString("Give Up", comment: "Cancel") - let retryTitle = NSLocalizedString("Try Again", comment: "Retry") - - let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert) - alertController.addCancelActionWithTitle(cancelTitle) { action in - block.textOverride = nil - self.refreshInterface() - } - alertController.addDefaultActionWithTitle(retryTitle) { action in - self.updateComment(with: block, content: content) - } - - // Note: This viewController might not be visible anymore - alertController.presentFromRootViewController() - } } // MARK: - Milestone notifications @@ -1190,19 +855,19 @@ private extension NotificationDetailsViewController { } enum ContentMedia { - static let richBlockTypes = Set(arrayLiteral: FormattableContentKind.text, FormattableContentKind.comment) - static let duration = TimeInterval(0.25) - static let delay = TimeInterval(0) + static let richBlockTypes = Set(arrayLiteral: FormattableContentKind.text, FormattableContentKind.comment) + static let duration = TimeInterval(0.25) + static let delay = TimeInterval(0) static let options: UIView.AnimationOptions = [.overrideInheritedDuration, .beginFromCurrentState] } enum Settings { - static let numberOfSections = 1 - static let estimatedRowHeight = CGFloat(44) + static let numberOfSections = 1 + static let estimatedRowHeight = CGFloat(44) } enum Assets { - static let confettiBackground = "notifications-confetti-background" + static let confettiBackground = "notifications-confetti-background" } } @@ -1219,5 +884,4 @@ extension NotificationDetailsViewController { // private extension String { static let notificationDetailsTableAccessibilityId = "notifications-details-table" - static let replyTextViewAccessibilityId = "reply-text-view" } diff --git a/WordPress/Classes/ViewRelated/Notifications/Style/WPStyleGuide+Notifications.swift b/WordPress/Classes/ViewRelated/Notifications/Style/WPStyleGuide+Notifications.swift index aaf510f4cc84..dabd64854962 100644 --- a/WordPress/Classes/ViewRelated/Notifications/Style/WPStyleGuide+Notifications.swift +++ b/WordPress/Classes/ViewRelated/Notifications/Style/WPStyleGuide+Notifications.swift @@ -132,27 +132,17 @@ extension WPStyleGuide { } // Blocks - public static let contentBlockRegularFont = WPFontManager.notoRegularFont(ofSize: blockFontSize) - public static let contentBlockBoldFont = WPFontManager.notoBoldFont(ofSize: blockFontSize) - public static let contentBlockItalicFont = WPFontManager.notoItalicFont(ofSize: blockFontSize) - public static let blockRegularFont = WPFontManager.systemRegularFont(ofSize: blockFontSize) - public static let blockBoldFont = WPFontManager.systemSemiBoldFont(ofSize: blockFontSize) - - public static let blockTextColor = UIColor.label - public static let blockQuotedColor = UIAppColor.neutral - public static let blockBackgroundColor = UIColor.secondarySystemGroupedBackground - public static let blockLinkColor = UIAppColor.primary - public static let blockSeparatorColor = UIColor.separator - - public static let blockApprovedBgColor = UIColor.clear - - public static let blockUnapprovedSideColor = UIAppColor.warning(.shade60) - public static let blockUnapprovedBgColor = UIColor( - light: UIAppColor.warning(.shade0), - dark: UIAppColor.warning(.shade90) - ) - public static let blockUnapprovedTextColor = UIColor.label - public static let blockUnapprovedLinkColor = UIAppColor.primary + public static let contentBlockRegularFont = WPFontManager.notoRegularFont(ofSize: blockFontSize) + public static let contentBlockBoldFont = WPFontManager.notoBoldFont(ofSize: blockFontSize) + public static let contentBlockItalicFont = WPFontManager.notoItalicFont(ofSize: blockFontSize) + public static let blockRegularFont = WPFontManager.systemRegularFont(ofSize: blockFontSize) + public static let blockBoldFont = WPFontManager.systemSemiBoldFont(ofSize: blockFontSize) + + public static let blockTextColor = UIColor.label + public static let blockQuotedColor = UIAppColor.neutral + public static let blockBackgroundColor = UIColor.secondarySystemGroupedBackground + public static let blockLinkColor = UIAppColor.primary + public static let blockSeparatorColor = UIColor.separator public static var contentBlockRegularStyle: [NSAttributedString.Key: Any] { return [.paragraphStyle: contentBlockParagraph, @@ -199,31 +189,6 @@ extension WPStyleGuide { return isBadge ? badgeBackgroundColor : blockBackgroundColor } - // Comment Helpers - public static func blockGravatarPlaceholderImage(isApproved approved: Bool) -> UIImage { - return approved ? .gravatarPlaceholderImage : .gravatarUnapprovedImage - } - - public static func blockSeparatorColorForComment(isApproved approved: Bool) -> UIColor { - return (approved ? blockSeparatorColor : blockUnapprovedSideColor) - } - - public static func blockBackgroundColorForComment(isApproved approved: Bool) -> UIColor { - return approved ? blockApprovedBgColor : blockUnapprovedBgColor - } - - public static func blockTitleColorForComment(isApproved approved: Bool) -> UIColor { - return (approved ? blockTextColor : blockUnapprovedTextColor) - } - - public static func blockDetailsColorForComment(isApproved approved: Bool) -> UIColor { - return approved ? blockQuotedColor : blockUnapprovedSideColor - } - - public static func blockLinkColorForComment(isApproved approved: Bool) -> UIColor { - return (approved ? blockLinkColor : blockUnapprovedLinkColor) - } - // User Cell Helpers public static func configureFollowButton(_ button: UIButton) { // General diff --git a/WordPress/Classes/ViewRelated/Notifications/Views/LongPressGestureLabel.swift b/WordPress/Classes/ViewRelated/Notifications/Views/LongPressGestureLabel.swift deleted file mode 100644 index a2c1e6cc72ff..000000000000 --- a/WordPress/Classes/ViewRelated/Notifications/Views/LongPressGestureLabel.swift +++ /dev/null @@ -1,28 +0,0 @@ -import UIKit - -/// Subclass of UILabel that includes a long press gesture recognizer. -/// The action attached to the recognizer will be set by the creator of the label. - -class LongPressGestureLabel: UILabel { - var longPressAction: (() -> Void)? { - didSet { - self.addGestureRecognizer(self.gesture) - } - } - private lazy var gesture: UILongPressGestureRecognizer = { - return UILongPressGestureRecognizer(target: self, action: #selector(longPressAction(_:))) - }() - - @objc private func longPressAction(_ gesture: UILongPressGestureRecognizer) { - switch gesture.state { - case .began: - longPressAction?() - default: - break - } - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - } -} diff --git a/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockActionsTableViewCell.swift b/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockActionsTableViewCell.swift deleted file mode 100644 index 68fd19998c04..000000000000 --- a/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockActionsTableViewCell.swift +++ /dev/null @@ -1,363 +0,0 @@ -import Foundation -import WordPressShared - -// MARK: - NoteBlockActionsTableViewCell -// -class NoteBlockActionsTableViewCell: NoteBlockTableViewCell { - typealias EventHandler = ((_ sender: AnyObject) -> Void) - - /// Actions StackView - /// - @IBOutlet fileprivate var actionsView: UIStackView! - - /// Reply Action Button - /// - @IBOutlet fileprivate var btnReply: UIButton! - - /// Like Action Button - /// - @IBOutlet fileprivate var btnLike: UIButton! - - /// Approve Action Button - /// - @IBOutlet fileprivate var btnApprove: UIButton! - - /// Trash Action Button - /// - @IBOutlet fileprivate var btnTrash: UIButton! - - /// Spam Action Button - /// - @IBOutlet fileprivate var btnSpam: UIButton! - - /// Edit Action Button - /// - @IBOutlet fileprivate var btnEdit: UIButton! - - /// Handler to be executed on Reply event - /// - @objc var onReplyClick: EventHandler? - - /// Handler to be executed on Like event - /// - @objc var onLikeClick: EventHandler? - - /// Handler to be executed on Unlike event - /// - @objc var onUnlikeClick: EventHandler? - - /// Handler to be executed on Approve event - /// - @objc var onApproveClick: EventHandler? - - /// Handler to be executed on Unapprove event - /// - @objc var onUnapproveClick: EventHandler? - - /// Handler to be executed on Trash event - /// - @objc var onTrashClick: EventHandler? - - /// Handler to be executed on Spam event - /// - @objc var onSpamClick: EventHandler? - - // Handler to be executed on Edition event - // - @objc var onEditClick: EventHandler? - - /// Indicates whether the Reply Action is enabled, or not - /// - @objc var isReplyEnabled: Bool = false { - didSet { - toggleAction(button: btnReply, hidden: !isReplyEnabled) - } - } - - /// Indicates whether the Like Action is enabled, or not - /// - @objc var isLikeEnabled: Bool = false { - didSet { - toggleAction(button: btnLike, hidden: !isLikeEnabled) - } - } - - /// Indicates whether the Approve Action is enabled, or not - /// - @objc var isApproveEnabled: Bool = false { - didSet { - toggleAction(button: btnApprove, hidden: !isApproveEnabled) - } - } - - /// Indicates whether the Trash Action is enabled, or not - /// - @objc var isTrashEnabled: Bool = false { - didSet { - toggleAction(button: btnTrash, hidden: !isTrashEnabled) - } - } - - /// Indicates whether the Spam Action is enabled, or not - /// - @objc var isSpamEnabled: Bool = false { - didSet { - toggleAction(button: btnSpam, hidden: !isSpamEnabled) - } - } - - /// Indicates whether the Edit Action is enabled, or not - /// - @objc var isEditEnabled: Bool = false { - didSet { - toggleAction(button: btnEdit, hidden: !isEditEnabled) - } - } - - /// Indicates if all actions are disabled. - /// - @objc var allActionsDisabled: Bool { - return !isReplyEnabled && - !isLikeEnabled && - !isApproveEnabled && - !isTrashEnabled && - !isSpamEnabled && - !isEditEnabled - } - - /// Indicates whether Like is in it's "Selected" state, or not - /// - @objc var isLikeOn: Bool { - set { - btnLike.isSelected = newValue - btnLike.accessibilityLabel = likeAccesibilityLabel - btnLike.accessibilityHint = likeAccessibilityHint - // Force button trait to avoid automatic "Selected" trait - btnLike.accessibilityTraits = UIAccessibilityTraits.button - } - get { - return btnLike.isSelected - } - } - - /// Indicates whether Approve is in it's "Selected" state, or not - /// - @objc var isApproveOn: Bool { - set { - btnApprove.isSelected = newValue - btnApprove.accessibilityLabel = approveAccesibilityLabel - btnApprove.accessibilityHint = approveAccesibilityHint - // Force button trait to avoid automatic "Selected" trait - btnApprove.accessibilityTraits = UIAccessibilityTraits.button - } - get { - return btnApprove.isSelected - } - } - - /// Returns the required button spacing - /// - fileprivate var buttonSpacingForCurrentTraits: CGFloat { - let isHorizontallyCompact = traitCollection.horizontalSizeClass == .compact - return isHorizontallyCompact ? Constants.buttonSpacingCompact : Constants.buttonSpacing - } - - /// Returns the accessibility label for the Approve Button - /// - fileprivate var approveAccesibilityLabel: String { - return isApproveOn ? ApproveComment.TitleStrings.unapprove : ApproveComment.TitleStrings.approve - } - - /// Returns the accessibility hint for the Approve Button - /// - fileprivate var approveAccesibilityHint: String { - return isApproveOn ? ApproveComment.TitleHints.unapprove : ApproveComment.TitleHints.approve - } - - /// Returns the accessibility label for the Like Button - /// - fileprivate var likeAccesibilityLabel: String { - return isLikeOn ? LikeComment.TitleStrings.unlike : LikeComment.TitleStrings.like - } - - /// Returns the accessibility hint for the Like Button - /// - fileprivate var likeAccessibilityHint: String { - return isLikeOn ? LikeComment.TitleHints.unlike : LikeComment.TitleHints.like - } - - // MARK: - Overriden Methods - - override func awakeFromNib() { - super.awakeFromNib() - - selectionStyle = .none - - let textNormalColor = WPStyleGuide.Notifications.blockActionDisabledColor - let textSelectedColor = WPStyleGuide.Notifications.blockActionEnabledColor - - btnReply.setTitle(ReplyToComment.title, for: UIControl.State()) - btnReply.setTitleColor(textNormalColor, for: UIControl.State()) - btnReply.accessibilityLabel = ReplyToComment.title - btnReply.accessibilityHint = ReplyToComment.hint - btnReply.accessibilityIdentifier = ReplyToComment.identifier - - btnLike.setTitle(LikeComment.TitleStrings.like, for: UIControl.State()) - btnLike.setTitle(LikeComment.TitleStrings.unlike, for: .highlighted) - btnLike.setTitle(LikeComment.TitleStrings.unlike, for: .selected) - btnLike.setTitleColor(textNormalColor, for: UIControl.State()) - btnLike.setTitleColor(textSelectedColor, for: .highlighted) - btnLike.setTitleColor(textSelectedColor, for: .selected) - - btnApprove.setTitle(ApproveComment.TitleStrings.approve, for: UIControl.State()) - btnApprove.setTitle(ApproveComment.TitleStrings.unapprove, for: .highlighted) - btnApprove.setTitle(ApproveComment.TitleStrings.unapprove, for: .selected) - btnApprove.setTitleColor(textNormalColor, for: UIControl.State()) - btnApprove.setTitleColor(textSelectedColor, for: .highlighted) - btnApprove.setTitleColor(textSelectedColor, for: .selected) - - btnEdit.setTitle(EditComment.title, for: UIControl.State()) - btnEdit.setTitleColor(textNormalColor, for: UIControl.State()) - btnEdit.tintColor = textNormalColor - btnEdit.accessibilityLabel = EditComment.title - btnEdit.accessibilityHint = EditComment.hint - - btnSpam.setTitle(MarkAsSpam.title, for: .normal) - btnSpam.setTitleColor(textNormalColor, for: UIControl.State()) - btnSpam.tintColor = textNormalColor - btnSpam.accessibilityLabel = MarkAsSpam.title - btnSpam.accessibilityHint = MarkAsSpam.hint - - btnTrash.setTitle(TrashComment.title, for: .normal) - btnTrash.setTitleColor(textNormalColor, for: UIControl.State()) - btnTrash.tintColor = textNormalColor - btnTrash.accessibilityLabel = TrashComment.title - btnTrash.accessibilityHint = TrashComment.hint - } - - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - actionsView.spacing = buttonSpacingForCurrentTraits - } - - // MARK: - IBActions - @IBAction func replyWasPressed(_ sender: AnyObject) { - ReachabilityUtils.onAvailableInternetConnectionDo { - onReplyClick?(sender) - } - } - - @IBAction func likeWasPressed(_ sender: AnyObject) { - ReachabilityUtils.onAvailableInternetConnectionDo { - let onClick = isLikeOn ? onUnlikeClick : onLikeClick - isLikeOn = !isLikeOn - - if isLikeOn { - UINotificationFeedbackGenerator().notificationOccurred(.success) - } - - animateLikeButton(btnLike) { - onClick?(sender) - } - } - } - - @IBAction func approveWasPressed(_ sender: AnyObject) { - ReachabilityUtils.onAvailableInternetConnectionDo { - let onClick = isApproveOn ? onUnapproveClick : onApproveClick - isApproveOn = !isApproveOn - - if isApproveOn { - UINotificationFeedbackGenerator().notificationOccurred(.success) - } - - animateApproveButton(btnApprove) { - onClick?(sender) - } - } - } - - @IBAction func trashWasPressed(_ sender: AnyObject) { - ReachabilityUtils.onAvailableInternetConnectionDo { - onTrashClick?(sender) - } - } - - @IBAction func spamWasPressed(_ sender: AnyObject) { - ReachabilityUtils.onAvailableInternetConnectionDo { - onSpamClick?(sender) - } - } - - @IBAction func editWasPressed(_ sender: AnyObject) { - ReachabilityUtils.onAvailableInternetConnectionDo { - onEditClick?(sender) - } - } -} - -// MARK: - Action Button Helpers -// -private extension NoteBlockActionsTableViewCell { - - func toggleAction(button: UIButton, hidden: Bool) { - button.isHidden = hidden - /* - * Since these buttons are in a stackView, and since they are - * subclasses of `VerticallyStackedButton`, we need to zero the alpha of the button. - * This keeps the custom layout in `VerticallyStackedButton` from breaking out - * of the constraint-based layout the stackView sets on the button, once hidden. - * Note: ideally, we wouldn't be doing custom layout in `VerticallyStackedButton`. - * - Brent Feb 15/2017 - */ - button.alpha = hidden ? 0.0 : 1.0 - } - - func animateLikeButton(_ button: UIButton, completion: @escaping (() -> Void)) { - guard let overlayImageView = overlayForButton(button, state: .selected) else { - return - } - - button.addSubview(overlayImageView) - - let animation = button.isSelected ? overlayImageView.fadeInWithRotationAnimation : overlayImageView.fadeOutWithRotationAnimation - animation { _ in - overlayImageView.removeFromSuperview() - completion() - } - } - - func animateApproveButton(_ button: UIButton, completion: @escaping (() -> Void)) { - guard let overlayImageView = overlayForButton(button, state: .selected) else { - return - } - - button.addSubview(overlayImageView) - - let animation = button.isSelected ? overlayImageView.implodeAnimation : overlayImageView.explodeAnimation - animation { _ in - overlayImageView.removeFromSuperview() - completion() - } - } - - func overlayForButton(_ button: UIButton, state: UIControl.State) -> UIImageView? { - guard let buttonImageView = button.imageView, let targetImage = button.image(for: state) else { - return nil - } - - let overlayImageView = UIImageView(image: targetImage) - overlayImageView.frame = button.convert(buttonImageView.bounds, from: buttonImageView) - - return overlayImageView - } -} - -// MARK: - Private Constants -// -private extension NoteBlockActionsTableViewCell { - struct Constants { - static let buttonSpacing = CGFloat(20) - static let buttonSpacingCompact = CGFloat(2) - } -} diff --git a/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockActionsTableViewCell.xib b/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockActionsTableViewCell.xib deleted file mode 100644 index 320795e4e7d2..000000000000 --- a/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockActionsTableViewCell.xib +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockCommentTableViewCell.swift b/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockCommentTableViewCell.swift deleted file mode 100644 index 9a8dc5dab44d..000000000000 --- a/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockCommentTableViewCell.swift +++ /dev/null @@ -1,191 +0,0 @@ -import Foundation -import WordPressShared -import WordPressUI -import Gravatar - -// MARK: - NoteBlockCommentTableViewCell Renders a Comment Block Onscreen -// -class NoteBlockCommentTableViewCell: NoteBlockTextTableViewCell { - - // MARK: - Private Constants - private typealias Style = WPStyleGuide.Notifications - private let separatorUnapprovedInsets = UIEdgeInsets.zero - - /// Gravatar ImageView - /// - @IBOutlet private weak var gravatarImageView: CircularImageView! - - /// Source's Title - /// - @IBOutlet private weak var titleLabel: UILabel! - - /// Source's Details - /// - @IBOutlet private weak var detailsLabel: LongPressGestureLabel! - - /// Returns the Placeholder image, tinted for the current approval state - /// - private var placeholderImage: UIImage { - return Style.blockGravatarPlaceholderImage(isApproved: isApproved) - } - - /// onUserClick: Executed whenever any of the User's fields gets clicked - /// - @objc var onUserClick: (() -> Void)? - - /// onTimeStampLongPress: Executed whenever the user long press on the details label (that includes time stamp) - /// - @objc var onTimeStampLongPress: (() -> Void)? - - /// Comment's AttributedText Payload - /// - @objc var attributedCommentText: NSAttributedString? { - didSet { - refreshApprovalColors() - } - } - - /// Comments (Plain) Text Payload - /// - @objc var commentText: String? { - set { - let text = newValue ?? String() - attributedCommentText = NSAttributedString(string: text, attributes: Style.contentBlockRegularStyle) - } - get { - return attributedCommentText?.string - } - } - - /// Indicates if the comment is approved, or not. - /// - /// - Note: - /// After setting this property you should explicitly call `refreshSeparators` from within `UITableView.willDisplayCell`. - /// We're not doing so from `didSet` anymore since doing so might yield invalid `intrinsicContentSize` calculations, - /// which appears to be cached, and results in incorrect layouts. - /// - @objc var isApproved: Bool = false { - didSet { - refreshApprovalColors() - } - } - - /// Commenter's Name - /// - @objc var name: String? { - set { - titleLabel.text = newValue - } - get { - return titleLabel.text - } - } - - /// Timestamp of the comment - /// - @objc var timestamp: String? { - didSet { - refreshDetails() - } - } - - /// Originating Site - /// - @objc var site: String? { - didSet { - refreshDetails() - } - } - - // MARK: - Public Methods - - @objc func downloadGravatarWithURL(_ url: URL?) { - let gravatar = url.flatMap { AvatarURL(url: $0) } - - gravatarImageView.downloadGravatar(gravatar, placeholder: placeholderImage, animate: true) - } - - @objc func downloadGravatarWithEmail(_ email: String?) { - guard let unwrappedEmail = email else { - gravatarImageView.image = placeholderImage - return - } - - gravatarImageView.downloadGravatar(for: unwrappedEmail, placeholderImage: placeholderImage) - } - - // MARK: - View Methods - - override func awakeFromNib() { - super.awakeFromNib() - - titleLabel.font = Style.blockBoldFont - titleLabel.isUserInteractionEnabled = true - titleLabel.gestureRecognizers = [ UITapGestureRecognizer(target: self, action: #selector(titleWasPressed)) ] - - detailsLabel.font = Style.blockRegularFont - detailsLabel.isUserInteractionEnabled = true - detailsLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(detailsWasPressed))) - detailsLabel.longPressAction = { [weak self] in self?.onTimeStampLongPress?() } - } - - // MARK: - Approval Color Helpers - - /// Updates the Separators Insets / Style. This API should be called from within `UITableView.willDisplayCell`. - /// - /// - Note: - /// `readableSeparatorInsets`, if executed from within `cellForRowAtIndexPath`, will produce an "invalid" layout cycle (since there won't - /// be a superview). Such "Invalid" layout cycle appears to be yielding an invalid `intrinsicContentSize` calculation, which is then cached, - /// and we end up with strings cutoff onScreen. =( - /// - override func refreshSeparators() { - // Left Separator - separatorsView.leftVisible = !isApproved - separatorsView.leftColor = Style.blockUnapprovedSideColor - - // Bottom Separator - let bottomInsets = isApproved ? readableSeparatorInsets : separatorUnapprovedInsets - separatorsView.bottomVisible = true - separatorsView.bottomInsets = bottomInsets - separatorsView.bottomColor = Style.blockSeparatorColorForComment(isApproved: isApproved) - - // Background - separatorsView.backgroundColor = Style.blockBackgroundColorForComment(isApproved: isApproved) - } - - private func refreshDetails() { - var details = timestamp ?? String() - if let site, !site.isEmpty { - details = String(format: "%@ • %@", details, site) - } - - detailsLabel.text = details - } - - private func refreshApprovalColors() { - titleLabel.textColor = Style.blockTitleColorForComment(isApproved: isApproved) - detailsLabel.textColor = Style.blockDetailsColorForComment(isApproved: isApproved) - linkColor = Style.blockLinkColorForComment(isApproved: isApproved) - attributedText = isApproved ? attributedCommentText : attributedCommentUnapprovedText - } - - private var attributedCommentUnapprovedText: NSAttributedString? { - guard let commentText = attributedCommentText?.mutableCopy() as? NSMutableAttributedString else { - return nil - } - - let range = NSRange(location: 0, length: commentText.length) - let textColor = Style.blockUnapprovedTextColor - commentText.addAttribute(.foregroundColor, value: textColor, range: range) - - return commentText - } - - @IBAction func titleWasPressed() { - onUserClick?() - } - - @IBAction func detailsWasPressed() { - onUserClick?() - } -} diff --git a/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockCommentTableViewCell.xib b/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockCommentTableViewCell.xib deleted file mode 100644 index c54feb332fd9..000000000000 --- a/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockCommentTableViewCell.xib +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -