diff --git a/Wikipedia/Code/TalkPageDataController.swift b/Wikipedia/Code/TalkPageDataController.swift index 27514614d89..e3dca456bf5 100644 --- a/Wikipedia/Code/TalkPageDataController.swift +++ b/Wikipedia/Code/TalkPageDataController.swift @@ -65,6 +65,17 @@ class TalkPageDataController { talkPageFetcher.subscribeToTopic(talkPageTitle: pageTitle, siteURL: siteURL, topic: topicName, shouldSubscribe: shouldSubscribe, completion: completion) } + func fetchSubscriptions(for topics: [String], completion: @escaping (Result<[String], Error>) -> Void) { + talkPageFetcher.getSubscribedTopics(siteURL: siteURL, topics: topics) { result in + switch result { + case let .success(result): + completion(.success(result)) + case let .failure(error): + completion(.failure(error)) + } + } + } + // MARK: Private private func fetchTalkPageItems(dispatchGroup group: DispatchGroup, completion: @escaping ([TalkPageItem], [Error]) -> Void) { diff --git a/Wikipedia/Code/TalkPageViewController.swift b/Wikipedia/Code/TalkPageViewController.swift index 90eee635fad..ad4963d1c83 100644 --- a/Wikipedia/Code/TalkPageViewController.swift +++ b/Wikipedia/Code/TalkPageViewController.swift @@ -1,5 +1,6 @@ import UIKit import WMF +import CocoaLumberjackSwift class TalkPageViewController: ViewController { @@ -23,63 +24,63 @@ class TalkPageViewController: ViewController { // MARK: - Overflow menu properties fileprivate var userTalkOverflowSubmenuActions: [UIAction] { - let contributionsAction = UIAction(title: MenuLocalizedStrings.contributions, image: UIImage(named: "user-contributions"), handler: { _ in + let contributionsAction = UIAction(title: TalkPageLocalizedStrings.contributions, image: UIImage(named: "user-contributions"), handler: { _ in }) - let userGroupsAction = UIAction(title: MenuLocalizedStrings.userGroups, image: UIImage(systemName: "person.2"), handler: { _ in + let userGroupsAction = UIAction(title: TalkPageLocalizedStrings.userGroups, image: UIImage(systemName: "person.2"), handler: { _ in }) - let logsAction = UIAction(title: MenuLocalizedStrings.logs, image: UIImage(systemName: "list.bullet"), handler: { _ in + let logsAction = UIAction(title: TalkPageLocalizedStrings.logs, image: UIImage(systemName: "list.bullet"), handler: { _ in }) return [contributionsAction, userGroupsAction, logsAction] } fileprivate var overflowSubmenuActions: [UIAction] { - - let goToArchivesAction = UIAction(title: MenuLocalizedStrings.archives, image: UIImage(systemName: "archivebox"), handler: { _ in + + let goToArchivesAction = UIAction(title: TalkPageLocalizedStrings.archives, image: UIImage(systemName: "archivebox"), handler: { _ in }) - - let pageInfoAction = UIAction(title: MenuLocalizedStrings.pageInfo, image: UIImage(systemName: "info.circle"), handler: { _ in + + let pageInfoAction = UIAction(title: TalkPageLocalizedStrings.pageInfo, image: UIImage(systemName: "info.circle"), handler: { _ in }) - - let goToPermalinkAction = UIAction(title: MenuLocalizedStrings.permaLink, image: UIImage(systemName: "link"), handler: { _ in + + let goToPermalinkAction = UIAction(title: TalkPageLocalizedStrings.permaLink, image: UIImage(systemName: "link"), handler: { _ in }) - - let relatedLinksAction = UIAction(title: MenuLocalizedStrings.relatedLinks, image: UIImage(systemName: "arrowshape.turn.up.forward"), handler: { _ in + + let relatedLinksAction = UIAction(title: TalkPageLocalizedStrings.relatedLinks, image: UIImage(systemName: "arrowshape.turn.up.forward"), handler: { _ in }) - + var actions = [goToArchivesAction, pageInfoAction, goToPermalinkAction, relatedLinksAction] - + if viewModel.pageType == .user { - let aboutTalkUserPagesAction = UIAction(title: MenuLocalizedStrings.aboutUserTalk, image: UIImage(systemName: "doc.plaintext"), handler: { _ in - + let aboutTalkUserPagesAction = UIAction(title: TalkPageLocalizedStrings.aboutUserTalk, image: UIImage(systemName: "doc.plaintext"), handler: { _ in + }) actions.insert(contentsOf: userTalkOverflowSubmenuActions, at: 1) actions.append(aboutTalkUserPagesAction) } else { - let changeLanguageAction = UIAction(title: MenuLocalizedStrings.changeLanguage, image: UIImage(named: "language-talk-page"), handler: { _ in + let changeLanguageAction = UIAction(title: TalkPageLocalizedStrings.changeLanguage, image: UIImage(named: "language-talk-page"), handler: { _ in }) - let aboutTalkPagesAction = UIAction(title: MenuLocalizedStrings.aboutArticleTalk, image: UIImage(systemName: "doc.plaintext"), handler: { _ in - + let aboutTalkPagesAction = UIAction(title: TalkPageLocalizedStrings.aboutArticleTalk, image: UIImage(systemName: "doc.plaintext"), handler: { _ in + }) actions.insert(changeLanguageAction, at: 3) actions.append(aboutTalkPagesAction) } return actions } - + var overflowMenu: UIMenu { - let openAllAction = UIAction(title: MenuLocalizedStrings.openAllThreads, image: UIImage(systemName: "square.stack"), handler: { _ in - + let openAllAction = UIAction(title: TalkPageLocalizedStrings.openAllThreads, image: UIImage(systemName: "square.stack"), handler: { _ in + }) let revisionHistoryAction = UIAction(title: CommonStrings.revisionHistory, image: UIImage(systemName: "clock.arrow.circlepath"), handler: { _ in }) - let openInWebAction = UIAction(title: MenuLocalizedStrings.readInWeb, image: UIImage(systemName: "display"), handler: { _ in + let openInWebAction = UIAction(title: TalkPageLocalizedStrings.readInWeb, image: UIImage(systemName: "display"), handler: { _ in }) @@ -97,21 +98,21 @@ class TalkPageViewController: ViewController { viewModel.delegate = self } - + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + override func loadView() { let talkPageView = TalkPageView(frame: UIScreen.main.bounds) view = talkPageView scrollView = talkPageView.collectionView } - + override func viewDidLoad() { super.viewDidLoad() - navigationItem.title = WMFLocalizedString("talk-pages-view-title", value: "Talk", comment: "Title of user and article talk pages view.") + navigationItem.title = TalkPageLocalizedStrings.title // Not adding fallback for other versions since we're dropping iOS 13 on the next release // TODO: this version check should be removed @@ -120,10 +121,10 @@ class TalkPageViewController: ViewController { navigationItem.rightBarButtonItem = rightBarButtonItem rightBarButtonItem.tintColor = theme.colors.link } - + talkPageView.collectionView.dataSource = self talkPageView.collectionView.delegate = self - + // Needed for reply compose views to display on top of navigation bar. navigationController?.setNavigationBarHidden(true, animated: false) navigationMode = .forceBar @@ -136,27 +137,26 @@ class TalkPageViewController: ViewController { private func setupHeaderView() { let headerView = TalkPageHeaderView() self.headerView = headerView - + headerView.configure(viewModel: viewModel) navigationBar.isBarHidingEnabled = false navigationBar.isUnderBarViewHidingEnabled = true navigationBar.allowsUnderbarHitsFallThrough = true - + navigationBar.addUnderNavigationBarView(headerView, shouldIgnoreSafeArea: true) useNavigationBarVisibleHeightForScrollViewInsets = false updateScrollViewInsets() - + headerView.apply(theme: theme) } // MARK: - Public - // MARK: - Themeable override func apply(theme: Theme) { super.apply(theme: theme) - + viewModel.theme = theme headerView?.apply(theme: theme) talkPageView.apply(theme: theme) @@ -206,7 +206,7 @@ class TalkPageViewController: ViewController { talkPageURLComponents?.path = "/wiki/\(viewModel.pageTitle)" return talkPageURLComponents?.url } - + @objc fileprivate func userDidTapShareButton() { guard let talkPageURL = talkPageURL else { return @@ -234,32 +234,44 @@ class TalkPageViewController: ViewController { toolbar.items = [shareButton, .flexibleSpaceToolbar(), revisionButton, .flexibleSpaceToolbar(), findButton,.flexibleSpaceToolbar(), addTopicButton] - shareButton.accessibilityLabel = WMFLocalizedString("talk-page-share-button", value: "Share talk page", comment: "Title for share talk page button") - findButton.accessibilityLabel = WMFLocalizedString("talk-page-find-in-page-button", value: "Find in page", comment: "Title for find content in page button") + shareButton.accessibilityLabel = TalkPageLocalizedStrings.shareButtonAccesibilityLabel + findButton.accessibilityLabel = TalkPageLocalizedStrings.findButtonAccesibilityLabel revisionButton.accessibilityLabel = CommonStrings.revisionHistory - addTopicButton.accessibilityLabel = WMFLocalizedString("talk-page-add-topic-button", value: "Add topic", comment: "Title for add topic to talk page button") + addTopicButton.accessibilityLabel = TalkPageLocalizedStrings.addTopicButtonAccesibilityLabel } - + + fileprivate func handleSubscriptionAlert(isSubscribedToTopic: Bool) { + let title = isSubscribedToTopic ? TalkPageLocalizedStrings.subscribedAlertTitle : TalkPageLocalizedStrings.unsubscribedAlertTitle + let subtitle = isSubscribedToTopic ? TalkPageLocalizedStrings.subscribedAlertSubtitle : TalkPageLocalizedStrings.unsubscribedAlertSubtitle + let image = isSubscribedToTopic ? UIImage(systemName: "bell.fill") : UIImage(systemName: "bell.slash.fill") + + if UIAccessibility.isVoiceOverRunning { + UIAccessibility.post(notification: UIAccessibility.Notification.announcement, argument: title) + } else { + WMFAlertManager.sharedInstance.showBottomAlertWithMessage(title, subtitle: subtitle, image: image ?? UIImage(), dismissPreviousAlerts: true) + } + } + } // MARK: - UICollectionViewDelegate, UICollectionViewDataSource extension TalkPageViewController: UICollectionViewDelegate, UICollectionViewDataSource { - + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return viewModel.topics.count } - + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TalkPageCell.reuseIdentifier, for: indexPath) as? TalkPageCell else { - return UICollectionViewCell() + return UICollectionViewCell() } let viewModel = viewModel.topics[indexPath.row] cell.delegate = self cell.replyDelegate = self - + cell.configure(viewModel: viewModel) cell.apply(theme: theme) @@ -270,7 +282,7 @@ extension TalkPageViewController: UICollectionViewDelegate, UICollectionViewData guard let cell = collectionView.cellForItem(at: indexPath) as? TalkPageCell else { return } - + userDidTapDisclosureButton(cellViewModel: cell.viewModel, cell: cell) } @@ -278,30 +290,29 @@ extension TalkPageViewController: UICollectionViewDelegate, UICollectionViewData // MARK: - TalkPageCellDelegate -// TODO extension TalkPageViewController: TalkPageCellDelegate { - + func userDidTapDisclosureButton(cellViewModel: TalkPageCellViewModel?, cell: TalkPageCell) { guard let cellViewModel = cellViewModel, let indexOfConfiguredCell = viewModel.topics.firstIndex(where: {$0 === cellViewModel}) else { return } - + let configuredCellViewModel = viewModel.topics[indexOfConfiguredCell] configuredCellViewModel.isThreadExpanded.toggle() cell.configure(viewModel: configuredCellViewModel) talkPageView.collectionView.collectionViewLayout.invalidateLayout() } - + func userDidTapSubscribeButton(cellViewModel: TalkPageCellViewModel?, cell: TalkPageCell) { guard let cellViewModel = cellViewModel, let indexOfConfiguredCell = viewModel.topics.firstIndex(where: {$0 === cellViewModel}) else { return } - + let configuredCellViewModel = viewModel.topics[indexOfConfiguredCell] configuredCellViewModel.isSubscribed.toggle() - cell.configure(viewModel: configuredCellViewModel) + self.handleSubscriptionAlert(isSubscribedToTopic: configuredCellViewModel.isSubscribed) } } @@ -329,9 +340,10 @@ extension TalkPageViewController: TalkPageReplyComposeDelegate { } extension TalkPageViewController { - enum MenuLocalizedStrings { + enum TalkPageLocalizedStrings { + static let title = WMFLocalizedString("talk-pages-view-title", value: "Talk", comment: "Title of user and article talk pages view.") static let openAllThreads = WMFLocalizedString("talk-page-menu-open-all", value: "Open all threads", comment: "Title for menu option open all talk page threads") - static let readInWeb = WMFLocalizedString("talk-page-open-in-web", value: "Read in web", comment: "Title for menu option to open a talk page in a web browser") + static let readInWeb = WMFLocalizedString("talk-page-read-in-web", value: "Read in web", comment: "Title for menu option to read a talk page in a web browser") static let archives = WMFLocalizedString("talk-page-archives", value: "Archives", comment: "Title for menu option that redirects to talk page archives") static let pageInfo = WMFLocalizedString("talk-page-page-info", value: "Page information", comment: "Title for menu option to go to the talk page information link") static let permaLink = WMFLocalizedString("talk-page-permanent-link", value: "Permanent link", comment: "Title for menu option to open the talk page's permanent link in a web browser") @@ -342,5 +354,14 @@ extension TalkPageViewController { static let contributions = WMFLocalizedString("talk-page-user-contributions", value: "Contributions", comment: "Title for menu option for information on the user's contributions") static let userGroups = WMFLocalizedString("talk-pages-user-groups", value: "User groups", comment: "Title for menu option for information on the user's user groups") static let logs = WMFLocalizedString("talk-pages-user-logs", value: "Logs", comment: "Title for menu option to consult the user's public logs") + + static let subscribedAlertTitle = WMFLocalizedString("talk-page-subscribed-alert-title", value: "You have subscribed!", comment: "Title for alert informing that the user subscribed to a topic") + static let unsubscribedAlertTitle = WMFLocalizedString("talk-page-unsubscribed-alert-title", value: "You have unsubscribed.", comment: "Title for alert informing that the user unsubscribed to a topic") + static let subscribedAlertSubtitle = WMFLocalizedString("talk-page-subscribed-alert-subtitle", value: "You will receive notifications about new comments in this topic.", comment: "Subtitle for alert informing that the user will receive notifications for a subscribed topic") + static let unsubscribedAlertSubtitle = WMFLocalizedString("talk-page-unsubscribed-alert-subtitle", value: "You will no longer receive notifications about new comments in this topic.", comment: "Subtitle for alert informing that the user will no longer receive notifications for a topic") + + static let shareButtonAccesibilityLabel = WMFLocalizedString("talk-page-share-button", value: "Share talk page", comment: "Title for share talk page button") + static let findButtonAccesibilityLabel = WMFLocalizedString("talk-page-find-in-page-button", value: "Find in page", comment: "Title for find content in page button") + static let addTopicButtonAccesibilityLabel = WMFLocalizedString("talk-page-add-topic-button", value: "Add topic", comment: "Title for add topic to talk page button") } } diff --git a/Wikipedia/Code/TalkPageViewModel.swift b/Wikipedia/Code/TalkPageViewModel.swift index c7f96c30e03..e250207d860 100644 --- a/Wikipedia/Code/TalkPageViewModel.swift +++ b/Wikipedia/Code/TalkPageViewModel.swift @@ -76,6 +76,19 @@ final class TalkPageViewModel { } } + func updateSubscriptionToTopic(topic: String, shouldSubscribe: Bool, completion: @escaping (Result) -> Void) { + dataController.subscribeToTopic(topicName: topic, shouldSubscribe: shouldSubscribe) { [self] result in + switch result { + case let .success(result) : + let topicUpdated = topics.filter { $0.topicTitle == topic} + topicUpdated[0].isSubscribed = result + completion(.success(result)) + case let .failure(error): + completion(.failure(error)) + } + } + } + // MARK: - Private private func populateHeaderData(articleSummary: WMFArticle?, items: [TalkPageItem]) { diff --git a/Wikipedia/Code/WMFAlertManager.swift b/Wikipedia/Code/WMFAlertManager.swift index 0f87106ecbd..8cd3a02c07c 100644 --- a/Wikipedia/Code/WMFAlertManager.swift +++ b/Wikipedia/Code/WMFAlertManager.swift @@ -79,6 +79,12 @@ open class WMFAlertManager: NSObject, RMessageProtocol, Themeable { RMessage.showNotification(in: nil, title: message, subtitle: nil, iconImage: nil, type: .error, customTypeName: nil, duration: sticky ? -1 : 2, callback: tapCallBack, buttonTitle: nil, buttonCallback: nil, at: .top, canBeDismissedByUser: true) }) } + + @objc func showBottomAlertWithMessage(_ message: String, subtitle: String, image: UIImage, dismissPreviousAlerts:Bool, tapCallBack: (() -> Void)? = nil) { + showAlert(dismissPreviousAlerts, alertBlock: { () -> Void in + RMessage.showNotification(withTitle: message, subtitle: subtitle, iconImage: image, type: .normal, customTypeName: nil, duration: 5, callback: tapCallBack, buttonTitle: nil, buttonCallback: nil, at: .bottom, canBeDismissedByUser: true) + }) + } @objc func showAlert(_ dismissPreviousAlerts:Bool, alertBlock: @escaping () -> Void) { DispatchQueue.main.async { diff --git a/Wikipedia/Localizations/en.lproj/Localizable.strings b/Wikipedia/Localizations/en.lproj/Localizable.strings index 2a76550dfc2..7407cdb3465 100644 --- a/Wikipedia/Localizations/en.lproj/Localizable.strings +++ b/Wikipedia/Localizations/en.lproj/Localizable.strings @@ -998,10 +998,10 @@ "talk-page-new-topic-body-placeholder-text" = "Compose new discussion"; "talk-page-new-topic-success-text" = "Your discussion was successfully published"; "talk-page-new-topic-title" = "New discussion"; -"talk-page-open-in-web" = "Read in web"; "talk-page-page-info" = "Page information"; "talk-page-permanent-link" = "Permanent link"; "talk-page-publish-terms-and-licenses" = "By saving changes, you agree to the $1Terms of Use$2, and agree to release your contribution under the $3CC BY-SA 3.0$4 and the $5GFDL$6 licenses."; +"talk-page-read-in-web" = "Read in web"; "talk-page-related-links" = "What links here"; "talk-page-reply-button" = "Reply"; "talk-page-reply-terms-and-licenses" = "Note your reply will be automatically signed with your username. By saving changes, you agree to the $1Terms of Use$2, and agree to release your contribution under the $3CC BY-SA 3.0$4 and the $5GFDL$6 licenses."; @@ -1009,10 +1009,14 @@ "talk-page-revision-history" = "Revision history"; "talk-page-share-button" = "Share talk page"; "talk-page-subscribe-to-topic" = "Subscribe"; +"talk-page-subscribed-alert-subtitle" = "You will receive notifications about new comments in this topic."; +"talk-page-subscribed-alert-title" = "You have subscribed!"; "talk-page-title-article-talk" = "Article Talk"; "talk-page-title-user-talk" = "User Talk"; "talk-page-topic-title" = "Discussion"; "talk-page-unsubscribe-to-topic" = "Unsubscribe"; +"talk-page-unsubscribed-alert-subtitle" = "You will no longer receive notifications about new comments in this topic."; +"talk-page-unsubscribed-alert-title" = "You have unsubscribed."; "talk-page-user-about" = "About user talk pages"; "talk-page-user-contributions" = "Contributions"; "talk-pages-coffee-roll-read-more" = "Read more"; diff --git a/Wikipedia/Localizations/qqq.lproj/Localizable.strings b/Wikipedia/Localizations/qqq.lproj/Localizable.strings index dd136f3032e..fe94fa07e4b 100644 --- a/Wikipedia/Localizations/qqq.lproj/Localizable.strings +++ b/Wikipedia/Localizations/qqq.lproj/Localizable.strings @@ -998,10 +998,10 @@ "talk-page-new-topic-body-placeholder-text" = "Placeholder text which appears initially in the new topic body field for talk pages."; "talk-page-new-topic-success-text" = "Banner text that appears after a new discussion was successfully published on a talk page."; "talk-page-new-topic-title" = "Title of page when composing a new topic on talk pages."; -"talk-page-open-in-web" = "Title for menu option to open a talk page in a web browser"; "talk-page-page-info" = "Title for menu option to go to the talk page information link"; "talk-page-permanent-link" = "Title for menu option to open the talk page's permanent link in a web browser"; "talk-page-publish-terms-and-licenses" = "Text for information about the Terms of Use and edit licenses on talk pages. Parameters:\n* $1 - app-specific non-text formatting, $2 - app-specific non-text formatting, $3 - app-specific non-text formatting, $4 - app-specific non-text formatting, $5 - app-specific non-text formatting, $6 - app-specific non-text formatting."; +"talk-page-read-in-web" = "Title for menu option to read a talk page in a web browser"; "talk-page-related-links" = "Title for menu option that redirects to a page that shows related links"; "talk-page-reply-button" = "Text used on button to reply to talk page messages."; "talk-page-reply-terms-and-licenses" = "Text for information about the Terms of Use and edit licenses on talk pages when replying. Parameters:\n* $1 - app-specific non-text formatting, $2 - app-specific non-text formatting, $3 - app-specific non-text formatting, $4 - app-specific non-text formatting, $5 - app-specific non-text formatting, $6 - app-specific non-text formatting."; @@ -1009,10 +1009,14 @@ "talk-page-revision-history" = "Title for option that leads to talk pages revision history"; "talk-page-share-button" = "Title for share talk page button"; "talk-page-subscribe-to-topic" = "Text used on button to subscribe to talk page topic."; +"talk-page-subscribed-alert-subtitle" = "Subtitle for alert informing that the user will receive notifications for a subscribed topic"; +"talk-page-subscribed-alert-title" = "Title for alert informing that the user subscribed to a topic"; "talk-page-title-article-talk" = "This title label is displayed at the top of a talk page topic list, if the talk page type is an article talk page."; "talk-page-title-user-talk" = "This title label is displayed at the top of a talk page topic list, if the talk page type is a user talk page."; "talk-page-topic-title" = "This header label is displayed at the top of a talk page topic thread."; "talk-page-unsubscribe-to-topic" = "Text used on button to unsubscribe from talk page topic."; +"talk-page-unsubscribed-alert-subtitle" = "Subtitle for alert informing that the user will no longer receive notifications for a topic"; +"talk-page-unsubscribed-alert-title" = "Title for alert informing that the user unsubscribed to a topic"; "talk-page-user-about" = "Title for menu option for information on user talk pages"; "talk-page-user-contributions" = "Title for menu option for information on the user's contributions"; "talk-pages-coffee-roll-read-more" = "Title of user and article talk pages button to read more of the coffee roll."; diff --git a/Wikipedia/Third Party Code/RMessage/RMessageView.m b/Wikipedia/Third Party Code/RMessage/RMessageView.m index 85401f6818f..f0cbebdba83 100755 --- a/Wikipedia/Third Party Code/RMessage/RMessageView.m +++ b/Wikipedia/Third Party Code/RMessage/RMessageView.m @@ -29,6 +29,7 @@ @interface RMessageView () @property (nonatomic, weak) IBOutlet UILabel *subtitleLabel; @property (nonatomic, weak) IBOutlet UIButton *button; @property (nonatomic, weak) IBOutlet UIStackView *stackView; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *titleSubtitleContainerViewLeadingConstraint; @property (nonatomic, weak) IBOutlet NSLayoutConstraint *titleSubtitleContainerViewCenterYConstraint; @property (weak, nonatomic) IBOutlet UIImageView *closeImageView; @@ -448,7 +449,7 @@ - (void)setupLayout self.topToVCLayoutConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual - toItem:self.superview + toItem:self.superview.safeAreaLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]; @@ -633,7 +634,7 @@ - (void)setupImagesAndBackground _iconImageView.clipsToBounds = YES; } else { self.iconRelativeCornerRadius = 0.f; - _iconImageView.clipsToBounds = NO; + _iconImageView.clipsToBounds = YES; } [self setupIconImageView]; } @@ -759,13 +760,13 @@ - (void)setupIconImageView NSLayoutConstraint *imgViewLeading = [NSLayoutConstraint constraintWithItem:self.iconImageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual - toItem:self + toItem:self.safeAreaLayoutGuide attribute:NSLayoutAttributeLeading multiplier:1.f constant:15.f]; NSLayoutConstraint *imgViewTrailing = [NSLayoutConstraint constraintWithItem:self.iconImageView attribute:NSLayoutAttributeTrailing - relatedBy:NSLayoutRelationEqual + relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self.titleSubtitleContainerView attribute:NSLayoutAttributeLeading multiplier:1.f @@ -777,6 +778,8 @@ - (void)setupIconImageView attribute:NSLayoutAttributeBottom multiplier:1.f constant:-10.f]; + self.titleSubtitleContainerViewLeadingConstraint.constant = 50.0; + [self addSubview:self.iconImageView]; [[self class] activateConstraints:@[imgViewCenterY, imgViewLeading, imgViewTrailing, imgViewBottom] inSuperview:self]; } diff --git a/Wikipedia/Third Party Code/RMessage/RMessageView.xib b/Wikipedia/Third Party Code/RMessage/RMessageView.xib index c2bebf83c3f..4fa451089eb 100755 --- a/Wikipedia/Third Party Code/RMessage/RMessageView.xib +++ b/Wikipedia/Third Party Code/RMessage/RMessageView.xib @@ -1,11 +1,9 @@ - - - - + + - + @@ -33,7 +31,7 @@ - @@ -41,7 +39,7 @@ - + @@ -76,11 +74,15 @@ + + + + diff --git a/Wikipedia/iOS Native Localizations/en.lproj/Localizable.strings b/Wikipedia/iOS Native Localizations/en.lproj/Localizable.strings index 4c6944e6c6c..04eb311c917 100644 Binary files a/Wikipedia/iOS Native Localizations/en.lproj/Localizable.strings and b/Wikipedia/iOS Native Localizations/en.lproj/Localizable.strings differ