Create opt-in screen

This commit is contained in:
ismailgulek
2022-04-04 16:58:33 +03:00
parent 01b17ba990
commit 72f88d6bf2
3 changed files with 332 additions and 0 deletions
@@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Threads Beta View Controller-->
<scene sceneID="s0d-6b-0kx">
<objects>
<viewController id="Y6W-OH-hqX" customClass="ThreadsBetaViewController" customModule="Riot" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="rx5-uV-e8E">
<rect key="frame" x="20" y="68" width="374" height="774"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Threads" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tre-1i-GOd">
<rect key="frame" x="0.0" y="0.0" width="374" height="20.5"/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gEs-ZC-Pju">
<rect key="frame" x="0.0" y="20.5" width="374" height="20"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="xUG-Oh-eyc"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="T3e-J2-hJW">
<rect key="frame" x="0.0" y="40.5" width="374" height="1"/>
<color key="backgroundColor" systemColor="separatorColor"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="cHN-fx-JTR"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GX0-MS-yeP">
<rect key="frame" x="0.0" y="41.5" width="374" height="12"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="12" id="7C2-8P-K3W"/>
</constraints>
</view>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" verticalCompressionResistancePriority="751" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="qbP-qu-o0V">
<rect key="frame" x="0.0" y="53.5" width="374" height="596.5"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<string key="text">Keep discussions organised with threads.
Threads help keep your conversations on-topic and easy to track. Learn more.</string>
<color key="textColor" systemColor="labelColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Eln-NO-tcW">
<rect key="frame" x="0.0" y="650" width="374" height="24"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="24" id="qOQ-o8-vuD"/>
</constraints>
</view>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Tmd-wH-3Z2">
<rect key="frame" x="0.0" y="674" width="374" height="50"/>
<color key="backgroundColor" red="0.01176470588" green="0.70196078429999997" blue="0.50588235290000005" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="PKT-BC-IIR"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Try it out">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="8"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="enableButtonAction:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="XYF-57-jtn"/>
</connections>
</button>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="y5Q-lI-JUe">
<rect key="frame" x="0.0" y="724" width="374" height="50"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="Ee3-eB-Lzt"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Not now">
<color key="titleColor" red="0.01176470588" green="0.70196078429999997" blue="0.50588235290000005" alpha="1" colorSpace="calibratedRGB"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="8"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="cancelButtonAction:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="5Ph-Jj-cbu"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="tre-1i-GOd" firstAttribute="width" secondItem="rx5-uV-e8E" secondAttribute="width" id="3Lj-N4-Oap"/>
</constraints>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="vDu-zF-Fre" firstAttribute="bottom" secondItem="rx5-uV-e8E" secondAttribute="bottom" constant="20" id="Cue-th-wBf"/>
<constraint firstItem="rx5-uV-e8E" firstAttribute="leading" secondItem="vDu-zF-Fre" secondAttribute="leading" constant="20" id="qyO-6I-iAJ"/>
<constraint firstItem="rx5-uV-e8E" firstAttribute="top" secondItem="vDu-zF-Fre" secondAttribute="top" constant="24" id="tmI-9R-Tp7"/>
<constraint firstAttribute="trailing" secondItem="rx5-uV-e8E" secondAttribute="trailing" constant="20" id="um1-A3-OIa"/>
</constraints>
</view>
<nil key="simulatedTopBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="cancelButton" destination="y5Q-lI-JUe" id="z5X-g9-N5e"/>
<outlet property="enableButton" destination="Tmd-wH-3Z2" id="5cO-XD-VPS"/>
<outlet property="informationTextView" destination="qbP-qu-o0V" id="1Kd-im-4sE"/>
<outlet property="separatorLineView" destination="T3e-J2-hJW" id="6RE-Ns-I8v"/>
<outlet property="titleLabel" destination="tre-1i-GOd" id="vAt-P9-PTT"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="57" y="105"/>
</scene>
</scenes>
<resources>
<systemColor name="labelColor">
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="separatorColor">
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.28999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
@@ -0,0 +1,178 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import UIKit
class ThreadsBetaViewController: UIViewController {
// MARK: Constants
private enum Constants {
static let learnMoreLink = "https://element.io"
}
// MARK: Outlets
@IBOutlet private weak var titleLabel: UILabel!
@IBOutlet private weak var separatorLineView: UIView!
@IBOutlet private weak var informationTextView: UITextView! {
didSet {
informationTextView.contentInset = .zero
informationTextView.textContainerInset = .zero
informationTextView.textContainer.lineFragmentPadding = 0
informationTextView.scrollsToTop = false
informationTextView.showsVerticalScrollIndicator = false
informationTextView.showsHorizontalScrollIndicator = false
informationTextView.isEditable = false
informationTextView.isScrollEnabled = false
}
}
@IBOutlet private weak var enableButton: UIButton!
@IBOutlet private weak var cancelButton: UIButton!
// MARK: Private
private var theme: Theme!
// MARK: Public
@objc var didTapEnableButton: (() -> Void)?
@objc var didTapCancelButton: (() -> Void)?
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
self.setupViews()
self.registerThemeServiceDidChangeThemeNotification()
self.update(theme: self.theme)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Hide back button
self.navigationItem.setHidesBackButton(true, animated: animated)
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return self.theme.statusBarStyle
}
// MARK: - Setup
@objc class func instantiate() -> ThreadsBetaViewController {
let viewController = StoryboardScene.ThreadsBetaViewController.initialScene.instantiate()
viewController.theme = ThemeService.shared().theme
return viewController
}
// MARK: - Private
private func registerThemeServiceDidChangeThemeNotification() {
NotificationCenter.default.addObserver(self,
selector: #selector(themeDidChange),
name: .themeServiceDidChangeTheme,
object: nil)
}
@objc private func themeDidChange() {
self.update(theme: ThemeService.shared().theme)
}
private func setupViews() {
self.vc_removeBackTitle()
self.enableButton.setTitle(VectorL10n.threadsBetaEnable, for: .normal)
self.cancelButton.setTitle(VectorL10n.threadsBetaCancel, for: .normal)
self.titleLabel.text = VectorL10n.threadsBetaTitle
guard let font = self.informationTextView.font else {
return
}
let attributedString = NSMutableAttributedString(string: VectorL10n.threadsBetaInformation,
attributes: [.font: font])
let link = NSAttributedString(string: VectorL10n.threadsBetaInformationLink,
attributes: [.link: Constants.learnMoreLink,
.font: font])
attributedString.append(link)
self.informationTextView.attributedText = attributedString
}
// MARK: - Actions
@IBAction private func enableButtonAction(_ sender: UIButton) {
self.didTapEnableButton?()
}
@IBAction private func cancelButtonAction(_ sender: UIButton) {
self.didTapCancelButton?()
}
}
// MARK: - Themable
extension ThreadsBetaViewController: Themable {
func update(theme: Theme) {
self.theme = theme
self.view.backgroundColor = theme.colors.background
if let navigationBar = self.navigationController?.navigationBar {
theme.applyStyle(onNavigationBar: navigationBar)
}
self.titleLabel.textColor = theme.textPrimaryColor
self.separatorLineView.backgroundColor = theme.colors.system
self.informationTextView.textColor = theme.textPrimaryColor
self.enableButton.vc_setBackgroundColor(theme.tintColor, for: .normal)
self.enableButton.setTitleColor(theme.baseTextPrimaryColor, for: .normal)
self.cancelButton.vc_setBackgroundColor(.clear, for: .normal)
self.cancelButton.setTitleColor(theme.tintColor, for: .normal)
}
}
// MARK: - SlidingModalPresentable
extension ThreadsBetaViewController: SlidingModalPresentable {
func allowsDismissOnBackgroundTap() -> Bool {
return false
}
func layoutHeightFittingWidth(_ width: CGFloat) -> CGFloat {
guard let view = ThreadsNoticeViewController.instantiate().view else {
return 0
}
view.widthAnchor.constraint(equalToConstant: width).isActive = true
view.setNeedsLayout()
view.layoutIfNeeded()
let fittingSize = CGSize(width: width, height: UIView.layoutFittingCompressedSize.height)
return view.systemLayoutSizeFitting(fittingSize).height
+ UIWindow().safeAreaInsets.top
+ UIWindow().safeAreaInsets.bottom
}
}