blob: c76a5041745b4587090b9d170e207bb9e4deda9c [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
#import "remoting/ios/app/notification_dialog_view_controller.h"
#import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h"
#import "ios/third_party/material_components_ios/src/components/Dialogs/src/MaterialDialogs.h"
#import "remoting/ios/app/remoting_theme.h"
#include <algorithm>
#include "base/logging.h"
#include "base/strings/string_split.h"
#include "base/strings/sys_string_conversions.h"
#include "remoting/base/string_resources.h"
#include "remoting/client/notification/notification_message.h"
#include "remoting/ios/app/view_utils.h"
#include "ui/base/l10n/l10n_util.h"
static const CGFloat kLabelInset = 20.f;
static const CGFloat kSwitchInset = 10.f;
static const CGFloat kButtonHeight = 48.f;
static const CGFloat kDontShowAgainFontSize = 14.f;
static const CGFloat kDontShowAgainViewHeightAdjustment = 10.f;
@implementation NotificationDialogViewController {
NSString* _messageText;
NSString* _linkText;
NSURL* _linkUrl;
BOOL _allowSilence;
NotificationDialogCompletionBlock _completion;
MDCDialogTransitionController* _transitionController;
UILabel* _messageLabel;
MDCButton* _linkButton;
MDCButton* _dismissButton;
// These will be nil if |_allowSilence| is NO.
UISwitch* _dontShowAgainSwitch;
UILabel* _dontShowAgainLabel;
}
#pragma mark - UIViewController
- (instancetype)initWithNotificationMessage:
(const remoting::NotificationMessage&)message
allowSilence:(BOOL)allowSilence {
self = [super init];
if (self) {
_messageText = base::SysUTF8ToNSString(message.message_text);
_linkText = base::SysUTF8ToNSString(message.link_text);
_linkUrl = [NSURL URLWithString:base::SysUTF8ToNSString(message.link_url)];
_allowSilence = allowSilence;
_transitionController = [MDCDialogTransitionController new];
self.modalPresentationStyle = UIModalPresentationCustom;
self.transitioningDelegate = _transitionController;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = RemotingTheme.dialogBackgroundColor;
_messageLabel = [UILabel new];
_messageLabel.textColor = RemotingTheme.dialogTextColor;
_messageLabel.lineBreakMode = NSLineBreakByWordWrapping;
_messageLabel.numberOfLines = 0;
_messageLabel.text = _messageText;
_messageLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_messageLabel];
UIView* dontShowAgainView = [UIView new];
dontShowAgainView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:dontShowAgainView];
_linkButton = [MDCFlatButton new];
[_linkButton setTitle:_linkText forState:UIControlStateNormal];
[_linkButton addTarget:self
action:@selector(didTapLinkButton:)
forControlEvents:UIControlEventTouchUpInside];
[self addButton:_linkButton isPrimary:YES];
_dismissButton = [MDCFlatButton new];
[_dismissButton setTitle:l10n_util::GetNSString(IDS_DISMISS)
forState:UIControlStateNormal];
[_dismissButton addTarget:self
action:@selector(didTapDismissButton:)
forControlEvents:UIControlEventTouchUpInside];
[self addButton:_dismissButton isPrimary:NO];
[NSLayoutConstraint activateConstraints:@[
[_messageLabel.topAnchor constraintEqualToAnchor:self.view.topAnchor
constant:kLabelInset],
[_messageLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor
constant:kLabelInset],
[_messageLabel.trailingAnchor
constraintEqualToAnchor:self.view.trailingAnchor
constant:-kLabelInset],
[dontShowAgainView.topAnchor
constraintEqualToAnchor:_messageLabel.bottomAnchor
constant:kLabelInset],
[dontShowAgainView.leadingAnchor
constraintEqualToAnchor:self.view.leadingAnchor],
[dontShowAgainView.trailingAnchor
constraintEqualToAnchor:self.view.trailingAnchor],
[_dismissButton.topAnchor
constraintEqualToAnchor:dontShowAgainView.bottomAnchor],
[_dismissButton.heightAnchor constraintEqualToConstant:kButtonHeight],
[_dismissButton.bottomAnchor
constraintEqualToAnchor:self.view.bottomAnchor],
[_dismissButton.leadingAnchor
constraintGreaterThanOrEqualToAnchor:self.view.leadingAnchor],
[_linkButton.topAnchor constraintEqualToAnchor:_dismissButton.topAnchor],
[_linkButton.leadingAnchor
constraintEqualToAnchor:_dismissButton.trailingAnchor],
[_linkButton.trailingAnchor
constraintEqualToAnchor:self.view.trailingAnchor],
[_linkButton.bottomAnchor
constraintEqualToAnchor:_dismissButton.bottomAnchor],
[_linkButton.heightAnchor constraintEqualToConstant:kButtonHeight],
]];
if (_allowSilence) {
// This is to allow user to toggle switch by tapping the label. Tap events
// won't be bubbled down to the switch.
UITapGestureRecognizer* dontShowAgainTapGestureRecognizer =
[[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(didTapDontShowAgain:)];
dontShowAgainTapGestureRecognizer.numberOfTapsRequired = 1;
[dontShowAgainView addGestureRecognizer:dontShowAgainTapGestureRecognizer];
dontShowAgainView.userInteractionEnabled = YES;
NSString* dontShowAgainText = l10n_util::GetNSString(IDS_DONT_SHOW_AGAIN);
_dontShowAgainSwitch = [UISwitch new];
_dontShowAgainSwitch.translatesAutoresizingMaskIntoConstraints = NO;
_dontShowAgainSwitch.transform = CGAffineTransformMakeScale(0.5, 0.5);
_dontShowAgainSwitch.accessibilityLabel = dontShowAgainText;
[dontShowAgainView addSubview:_dontShowAgainSwitch];
_dontShowAgainLabel = [UILabel new];
_dontShowAgainLabel.textColor = RemotingTheme.dialogTextColor;
_dontShowAgainLabel.font = [UIFont systemFontOfSize:kDontShowAgainFontSize];
_dontShowAgainLabel.text = dontShowAgainText;
_dontShowAgainLabel.translatesAutoresizingMaskIntoConstraints = NO;
[dontShowAgainView addSubview:_dontShowAgainLabel];
[NSLayoutConstraint activateConstraints:@[
[dontShowAgainView.heightAnchor
constraintEqualToAnchor:_dontShowAgainLabel.heightAnchor
constant:kDontShowAgainViewHeightAdjustment],
[_dontShowAgainSwitch.leadingAnchor
constraintEqualToAnchor:dontShowAgainView.leadingAnchor
constant:kSwitchInset],
[_dontShowAgainSwitch.centerYAnchor
constraintEqualToAnchor:dontShowAgainView.centerYAnchor],
[_dontShowAgainLabel.leadingAnchor
constraintEqualToAnchor:_dontShowAgainSwitch.trailingAnchor],
[_dontShowAgainLabel.trailingAnchor
constraintEqualToAnchor:dontShowAgainView.trailingAnchor
constant:-kLabelInset],
[_dontShowAgainLabel.centerYAnchor
constraintEqualToAnchor:_dontShowAgainSwitch.centerYAnchor],
]];
}
[self.view setNeedsLayout];
}
- (void)viewDidLayoutSubviews {
CGFloat contentWidth =
MAX(_messageLabel.intrinsicContentSize.width + 2 * kLabelInset,
_dismissButton.intrinsicContentSize.width +
_linkButton.intrinsicContentSize.width);
CGFloat contentHeight = _messageLabel.intrinsicContentSize.height +
2 * kLabelInset + kButtonHeight;
if (_allowSilence) {
contentWidth =
MAX(contentWidth,
kSwitchInset + _dontShowAgainSwitch.intrinsicContentSize.width +
_dontShowAgainLabel.intrinsicContentSize.width + kLabelInset);
contentHeight += _dontShowAgainLabel.intrinsicContentSize.height +
kDontShowAgainViewHeightAdjustment;
}
self.preferredContentSize = CGSizeMake(contentWidth, contentHeight);
}
- (void)presentOnTopVCWithCompletion:
(NotificationDialogCompletionBlock)completion {
DCHECK(completion);
DCHECK(!_completion);
_completion = completion;
[remoting::TopPresentingVC() presentViewController:self
animated:YES
completion:nil];
}
- (void)viewDidDisappear:(BOOL)animated {
DCHECK(_completion);
_completion(_dontShowAgainSwitch && _dontShowAgainSwitch.on);
// Release the block as long as the dialog is disappeared, since it could
// potentially have retain loop.
_completion = nil;
}
#pragma mark - Private
- (void)addButton:(UIButton*)button isPrimary:(BOOL)isPrimary {
button.translatesAutoresizingMaskIntoConstraints = NO;
button.backgroundColor = UIColor.clearColor;
UIColor* titleColor = isPrimary
? RemotingTheme.dialogPrimaryButtonTextColor
: RemotingTheme.dialogSecondaryButtonTextColor;
[button setTitleColor:titleColor forState:UIControlStateNormal];
[self.view addSubview:button];
}
- (void)didTapLinkButton:(id)button {
[self dismissViewControllerAnimated:YES
completion:^() {
[UIApplication.sharedApplication openURL:_linkUrl
options:@{}
completionHandler:nil];
}];
}
- (void)didTapDismissButton:(id)button {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)didTapDontShowAgain:(id)sender {
[_dontShowAgainSwitch setOn:!_dontShowAgainSwitch.isOn animated:YES];
}
@end