mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-26 11:30:50 +02:00
Implements #4693 - Alert users of Element on iOS11 deprecation.
This commit is contained in:
committed by
Stefan Ceriu
parent
18a8d6b3ff
commit
ea699f66e3
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// Copyright 2021 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 Foundation
|
||||
|
||||
@objc protocol BannerPresentationProtocol {
|
||||
func presentBannerView(_ bannerView: UIView, animated: Bool)
|
||||
func dismissBannerView(animated: Bool)
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// Copyright 2021 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 Foundation
|
||||
|
||||
class HomeViewControllerWithBannerWrapperViewController: UIViewController, BannerPresentationProtocol {
|
||||
|
||||
@objc let homeViewController: HomeViewController
|
||||
private var bannerContainerView: UIView!
|
||||
private var stackView: UIStackView!
|
||||
|
||||
init(viewController: HomeViewController) {
|
||||
self.homeViewController = viewController
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
self.tabBarItem.tag = viewController.tabBarItem.tag
|
||||
self.tabBarItem.image = viewController.tabBarItem.image
|
||||
self.accessibilityLabel = viewController.accessibilityLabel
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("Not implemented")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
view.backgroundColor = .clear
|
||||
|
||||
stackView = UIStackView()
|
||||
stackView.axis = .vertical
|
||||
stackView.distribution = .fill
|
||||
stackView.alignment = .fill
|
||||
|
||||
view.vc_addSubViewMatchingParent(stackView)
|
||||
|
||||
addChild(homeViewController)
|
||||
stackView.addArrangedSubview(homeViewController.view)
|
||||
homeViewController.didMove(toParent: self)
|
||||
}
|
||||
|
||||
// MARK: - BannerPresentationProtocol
|
||||
|
||||
func presentBannerView(_ bannerView: UIView, animated: Bool) {
|
||||
bannerView.alpha = 0.0
|
||||
bannerView.isHidden = true
|
||||
self.stackView.insertArrangedSubview(bannerView, at: 0)
|
||||
self.stackView.layoutIfNeeded()
|
||||
|
||||
UIView.animate(withDuration: (animated ? 0.25 : 0.0)) {
|
||||
bannerView.alpha = 1.0
|
||||
bannerView.isHidden = false
|
||||
self.stackView.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
func dismissBannerView(animated: Bool) {
|
||||
guard stackView.arrangedSubviews.count > 1, let bannerView = self.stackView.arrangedSubviews.first else {
|
||||
return
|
||||
}
|
||||
|
||||
UIView.animate(withDuration: (animated ? 0.25 : 0.0)) {
|
||||
bannerView.alpha = 0.0
|
||||
bannerView.isHidden = true
|
||||
self.stackView.layoutIfNeeded()
|
||||
} completion: { _ in
|
||||
bannerView.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
//
|
||||
// Copyright 2021 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
|
||||
import Reusable
|
||||
|
||||
protocol VersionCheckAlertViewControllerDelegate: AnyObject {
|
||||
func alertViewControllerDidRequestDismissal(_ alertViewController: VersionCheckAlertViewController)
|
||||
func alertViewControllerDidRequestAction(_ alertViewController: VersionCheckAlertViewController)
|
||||
}
|
||||
|
||||
struct VersionCheckAlertViewControllerDetails {
|
||||
let title: String
|
||||
let subtitle: String
|
||||
let actionButtonTitle: String
|
||||
}
|
||||
|
||||
class VersionCheckAlertViewController: UIViewController {
|
||||
|
||||
@IBOutlet private var alertContainerView: UIView!
|
||||
@IBOutlet private var titleLabel: UILabel!
|
||||
@IBOutlet private var subtitleLabel: UILabel!
|
||||
|
||||
@IBOutlet private var dismissButton: UIButton!
|
||||
@IBOutlet private var actionButton: UIButton!
|
||||
|
||||
private var themeService: ThemeService!
|
||||
private var details: VersionCheckAlertViewControllerDetails?
|
||||
|
||||
weak var delegate: VersionCheckAlertViewControllerDelegate?
|
||||
|
||||
static func instantiate(themeService: ThemeService) -> VersionCheckAlertViewController {
|
||||
let versionCheckAlertViewController = VersionCheckAlertViewController(nibName: nil, bundle: nil)
|
||||
versionCheckAlertViewController.themeService = themeService
|
||||
versionCheckAlertViewController.modalPresentationStyle = .overFullScreen
|
||||
versionCheckAlertViewController.modalTransitionStyle = .crossDissolve
|
||||
return versionCheckAlertViewController
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
actionButton.layer.masksToBounds = true
|
||||
actionButton.layer.cornerRadius = 6.0
|
||||
|
||||
configureWithDetails(details)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(updateTheme), name: .themeServiceDidChangeTheme, object: nil)
|
||||
updateTheme()
|
||||
}
|
||||
|
||||
func configureWithDetails(_ details: VersionCheckAlertViewControllerDetails?) {
|
||||
guard let details = details else {
|
||||
return
|
||||
}
|
||||
|
||||
guard self.isViewLoaded else {
|
||||
self.details = details
|
||||
return
|
||||
}
|
||||
|
||||
titleLabel.text = details.title
|
||||
actionButton.setTitle(details.actionButtonTitle, for: .normal)
|
||||
|
||||
let attributedSubtitle = NSMutableAttributedString(string: details.subtitle)
|
||||
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
paragraphStyle.lineHeightMultiple = 1.2
|
||||
paragraphStyle.alignment = .center
|
||||
|
||||
attributedSubtitle.addAttribute(.paragraphStyle, value: paragraphStyle, range: .init(location: 0, length: attributedSubtitle.length))
|
||||
|
||||
subtitleLabel.attributedText = attributedSubtitle
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
@IBAction private func onDismissButtonTap(_ sender: UIButton) {
|
||||
delegate?.alertViewControllerDidRequestDismissal(self)
|
||||
}
|
||||
|
||||
@IBAction private func onActionButtonTap(_ sender: UIButton) {
|
||||
delegate?.alertViewControllerDidRequestAction(self)
|
||||
}
|
||||
|
||||
@objc private func updateTheme() {
|
||||
let theme = themeService.theme
|
||||
|
||||
alertContainerView.backgroundColor = theme.colors.background
|
||||
|
||||
titleLabel.textColor = theme.colors.primaryContent
|
||||
subtitleLabel.textColor = theme.colors.secondaryContent
|
||||
|
||||
dismissButton.tintColor = theme.colors.secondaryContent
|
||||
actionButton.vc_setBackgroundColor(theme.colors.accent, for: .normal)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="VersionCheckAlertViewController" customModule="Riot" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="actionButton" destination="EbY-m0-XSs" id="63P-Xf-QDA"/>
|
||||
<outlet property="alertContainerView" destination="KIG-b9-Tyx" id="U06-A9-P9c"/>
|
||||
<outlet property="dismissButton" destination="fGK-xG-RKK" id="udW-wA-Anp"/>
|
||||
<outlet property="subtitleLabel" destination="zgc-27-11w" id="EEW-oJ-npn"/>
|
||||
<outlet property="titleLabel" destination="KmG-fj-orS" id="Xcy-ek-zHo"/>
|
||||
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
|
||||
<rect key="frame" x="0.0" y="0.0" width="680" height="614"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KIG-b9-Tyx">
|
||||
<rect key="frame" x="42.5" y="186" width="595" height="242"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fGK-xG-RKK">
|
||||
<rect key="frame" x="547" y="4" width="44" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="44" id="8Pq-sX-5mB"/>
|
||||
<constraint firstAttribute="height" constant="44" id="Wyp-3I-uEw"/>
|
||||
</constraints>
|
||||
<state key="normal" image="version_check_close_icon"/>
|
||||
<connections>
|
||||
<action selector="onDismissButtonTap:" destination="-1" eventType="touchUpInside" id="doW-WY-0Gv"/>
|
||||
</connections>
|
||||
</button>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="s18-lG-O4e">
|
||||
<rect key="frame" x="16" y="52" width="563" height="174"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="Ter-fV-mb4">
|
||||
<rect key="frame" x="0.0" y="0.0" width="563" height="114"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="We’re ending support for iOS 11" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KmG-fj-orS">
|
||||
<rect key="frame" x="156.5" y="0.0" width="250.5" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
|
||||
<color key="textColor" red="0.090196078431372548" green="0.098039215686274508" blue="0.10980392156862745" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zgc-27-11w">
|
||||
<rect key="frame" x="0.0" y="32.5" width="563" height="81.5"/>
|
||||
<string key="text">We've been working on enhancing Element for a faster and more polished experience. Unfortunately your current version of iOS is not compatible with some of those fixes and will no longer be supported. We're advising you to upgrade your operating system to use Element to its full potential.</string>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.45098039215686275" green="0.49019607843137253" blue="0.5490196078431373" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EbY-m0-XSs">
|
||||
<rect key="frame" x="200" y="134" width="163" height="40"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="15"/>
|
||||
<inset key="contentEdgeInsets" minX="62" minY="11" maxX="62" maxY="11"/>
|
||||
<state key="normal" title="Got it"/>
|
||||
<connections>
|
||||
<action selector="onActionButtonTap:" destination="-1" eventType="touchUpInside" id="sg4-JL-L3g"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="600" id="EWq-BN-h4D"/>
|
||||
<constraint firstAttribute="trailing" secondItem="s18-lG-O4e" secondAttribute="trailing" constant="16" id="IGg-Uc-Vj7"/>
|
||||
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="600" id="Kq2-HB-3xI"/>
|
||||
<constraint firstItem="s18-lG-O4e" firstAttribute="top" secondItem="fGK-xG-RKK" secondAttribute="bottom" constant="4" id="SVY-JE-eRa"/>
|
||||
<constraint firstItem="fGK-xG-RKK" firstAttribute="top" secondItem="KIG-b9-Tyx" secondAttribute="top" constant="4" id="aHW-7J-fAP"/>
|
||||
<constraint firstItem="s18-lG-O4e" firstAttribute="leading" secondItem="KIG-b9-Tyx" secondAttribute="leading" constant="16" id="hUS-p8-LYF"/>
|
||||
<constraint firstAttribute="trailing" secondItem="fGK-xG-RKK" secondAttribute="trailing" constant="4" id="qel-Uc-gCm"/>
|
||||
<constraint firstAttribute="bottom" secondItem="s18-lG-O4e" secondAttribute="bottom" constant="16" id="x0D-6M-ENQ"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
|
||||
<integer key="value" value="8"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
|
||||
<color key="backgroundColor" red="0.090196078431372548" green="0.098039215686274508" blue="0.10980392156862745" alpha="0.75" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="KIG-b9-Tyx" secondAttribute="bottom" constant="27" id="O2i-3j-Zdq"/>
|
||||
<constraint firstItem="KIG-b9-Tyx" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="gla-Ua-rd6"/>
|
||||
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="KIG-b9-Tyx" secondAttribute="trailing" constant="27" id="hZu-FV-h9a"/>
|
||||
<constraint firstItem="KIG-b9-Tyx" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="rdh-sM-1Me"/>
|
||||
<constraint firstItem="KIG-b9-Tyx" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="27" id="s7X-L5-bfF"/>
|
||||
<constraint firstItem="KIG-b9-Tyx" firstAttribute="top" relation="greaterThanOrEqual" secondItem="fnl-2z-Ty3" secondAttribute="top" constant="27" id="uyT-Zm-oWx"/>
|
||||
</constraints>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="330.43478260869568" y="58.928571428571423"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="version_check_close_icon" width="16" height="16"/>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// Copyright 2021 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
|
||||
import Reusable
|
||||
|
||||
protocol VersionCheckBannerViewDelegate: AnyObject {
|
||||
func bannerViewDidRequestDismissal(_ bannerView: VersionCheckBannerView)
|
||||
func bannerViewDidRequestInteraction(_ bannerView: VersionCheckBannerView)
|
||||
}
|
||||
|
||||
struct VersionCheckBannerViewDetails {
|
||||
let title: String
|
||||
let subtitle: String
|
||||
}
|
||||
|
||||
class VersionCheckBannerView: UIView, NibLoadable, Themable {
|
||||
|
||||
@IBOutlet private var titleLabel: UILabel!
|
||||
@IBOutlet private var subtitleLabel: UILabel!
|
||||
|
||||
@IBOutlet private var infoButton: UIButton!
|
||||
@IBOutlet private var dismissButton: UIButton!
|
||||
|
||||
weak var delegate: VersionCheckBannerViewDelegate?
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
let tapGestureRecognizer = UITapGestureRecognizer()
|
||||
tapGestureRecognizer.addTarget(self, action: #selector(handleTapGesture))
|
||||
self.addGestureRecognizer(tapGestureRecognizer)
|
||||
}
|
||||
|
||||
func configureWithDetails(_ details: VersionCheckBannerViewDetails) {
|
||||
titleLabel.text = details.title
|
||||
subtitleLabel.text = details.subtitle
|
||||
}
|
||||
|
||||
// MARK: - Themable
|
||||
|
||||
func update(theme: Theme) {
|
||||
backgroundColor = theme.colors.background
|
||||
|
||||
titleLabel.textColor = theme.colors.primaryContent
|
||||
subtitleLabel.textColor = theme.colors.secondaryContent
|
||||
|
||||
infoButton.tintColor = theme.colors.primaryContent
|
||||
dismissButton.tintColor = theme.colors.secondaryContent
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
@IBAction private func onDismissButtonTap(_ sender: UIButton) {
|
||||
delegate?.bannerViewDidRequestDismissal(self)
|
||||
}
|
||||
|
||||
@objc private func handleTapGesture(_ gestureRecognizer: UITapGestureRecognizer) {
|
||||
delegate?.bannerViewDidRequestInteraction(self)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="VersionCheckBannerView" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="479" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" alignment="top" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="5ts-Up-IFL">
|
||||
<rect key="frame" x="12" y="16" width="419" height="118"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aWS-bd-dO7">
|
||||
<rect key="frame" x="0.0" y="0.0" width="45" height="24"/>
|
||||
<state key="normal" image="version_check_info_icon"/>
|
||||
</button>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="OJ5-KQ-ePa">
|
||||
<rect key="frame" x="53" y="0.0" width="366" height="75.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="We’re ending support for iOS 11" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="XGd-6U-k3l">
|
||||
<rect key="frame" x="0.0" y="0.0" width="366" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
|
||||
<color key="textColor" red="0.090196078431372548" green="0.098039215686274508" blue="0.10980392156862745" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="btO-Jc-DmU">
|
||||
<rect key="frame" x="0.0" y="28.5" width="366" height="47"/>
|
||||
<string key="text">We will soon be ending support for Element on iOS 11. To continue using Element to its full potential, we advise you to upgrade your version of iOS.</string>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<color key="textColor" red="0.090196078431372548" green="0.098039215686274508" blue="0.10980392156862745" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<button opaque="NO" contentMode="scaleToFill" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qyW-5Q-Bkm">
|
||||
<rect key="frame" x="431" y="4" width="44" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="44" id="N0T-vY-YT7"/>
|
||||
<constraint firstAttribute="height" constant="44" id="Rx3-dQ-K2O"/>
|
||||
</constraints>
|
||||
<state key="normal" image="version_check_close_icon"/>
|
||||
<connections>
|
||||
<action selector="onDismissButtonTap:" destination="iN0-l3-epB" eventType="touchUpInside" id="pDN-9q-Lr5"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="qyW-5Q-Bkm" secondAttribute="trailing" constant="4" id="Psr-tv-GLd"/>
|
||||
<constraint firstItem="qyW-5Q-Bkm" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="4" id="acO-Ae-IEB"/>
|
||||
<constraint firstItem="5ts-Up-IFL" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="16" id="bRM-rK-xBC"/>
|
||||
<constraint firstItem="5ts-Up-IFL" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="12" id="er6-CV-ezV"/>
|
||||
<constraint firstItem="qyW-5Q-Bkm" firstAttribute="leading" secondItem="5ts-Up-IFL" secondAttribute="trailing" id="rYR-NR-y0G"/>
|
||||
<constraint firstAttribute="bottom" secondItem="5ts-Up-IFL" secondAttribute="bottom" priority="100" constant="16" id="rjk-yN-Qxr"/>
|
||||
</constraints>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="dismissButton" destination="qyW-5Q-Bkm" id="1XZ-Mv-9A5"/>
|
||||
<outlet property="infoButton" destination="aWS-bd-dO7" id="Nk7-7P-PK5"/>
|
||||
<outlet property="subtitleLabel" destination="btO-Jc-DmU" id="cLh-sg-vfz"/>
|
||||
<outlet property="titleLabel" destination="XGd-6U-k3l" id="FTQ-fK-u4d"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="277.536231884058" y="-150"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="version_check_close_icon" width="16" height="16"/>
|
||||
<image name="version_check_info_icon" width="24" height="24"/>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// Copyright 2021 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 Foundation
|
||||
|
||||
private let osVersionToBeDropped = 11
|
||||
private let hasOSVersionBeenDropped = false
|
||||
|
||||
class VersionCheckCoordinator: VersionCheckBannerViewDelegate, VersionCheckAlertViewControllerDelegate {
|
||||
|
||||
private let rootViewController: UIViewController
|
||||
private let bannerPresenter: BannerPresentationProtocol
|
||||
private let themeService: ThemeService
|
||||
|
||||
@UserDefaultsBacked(key: "versionCheckCoordinatorNextDisplayDateTimeInterval")
|
||||
private var nextDisplayDateTimeInterval: Double?
|
||||
|
||||
private var versionCheckBannerView: VersionCheckBannerView?
|
||||
|
||||
init(rootViewController: UIViewController, bannerPresenter: BannerPresentationProtocol, themeService: ThemeService) {
|
||||
self.rootViewController = rootViewController
|
||||
self.bannerPresenter = bannerPresenter
|
||||
self.themeService = themeService
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(updateTheme), name: .themeServiceDidChangeTheme, object: nil)
|
||||
}
|
||||
|
||||
func performVersionCheck() {
|
||||
let majorOSVersion = ProcessInfo().operatingSystemVersion.majorVersion
|
||||
|
||||
guard majorOSVersion < osVersionToBeDropped else {
|
||||
return
|
||||
}
|
||||
|
||||
if let timeInterval = nextDisplayDateTimeInterval {
|
||||
let nextDisplayDate = Date(timeIntervalSince1970: timeInterval)
|
||||
if nextDisplayDate > Date() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let versionCheckBannerView = VersionCheckBannerView.loadFromNib()
|
||||
versionCheckBannerView.delegate = self
|
||||
versionCheckBannerView.update(theme: themeService.theme)
|
||||
|
||||
if hasOSVersionBeenDropped {
|
||||
versionCheckBannerView.configureWithDetails(VersionCheckBannerViewDetails(title: VectorL10n.versionCheckBannerTitleDeprecated(String(osVersionToBeDropped)),
|
||||
subtitle: VectorL10n.versionCheckBannerSubtitleDeprecated(String(osVersionToBeDropped))))
|
||||
} else {
|
||||
versionCheckBannerView.configureWithDetails(VersionCheckBannerViewDetails(title: VectorL10n.versionCheckBannerTitleSupported(String(osVersionToBeDropped)),
|
||||
subtitle: VectorL10n.versionCheckBannerSubtitleSupported(String(osVersionToBeDropped))))
|
||||
}
|
||||
|
||||
bannerPresenter.presentBannerView(versionCheckBannerView, animated: true)
|
||||
self.versionCheckBannerView = versionCheckBannerView
|
||||
}
|
||||
|
||||
// MARK: - VersionDropBannerViewDelegate
|
||||
|
||||
func bannerViewDidRequestDismissal(_ bannerView: VersionCheckBannerView) {
|
||||
dismissVersionCheckBanner()
|
||||
}
|
||||
|
||||
func bannerViewDidRequestInteraction(_ bannerView: VersionCheckBannerView) {
|
||||
|
||||
let versionCheckAlertViewController = VersionCheckAlertViewController.instantiate(themeService: themeService)
|
||||
versionCheckAlertViewController.delegate = self
|
||||
|
||||
if hasOSVersionBeenDropped {
|
||||
versionCheckAlertViewController.configureWithDetails(VersionCheckAlertViewControllerDetails(title: VectorL10n.versionCheckModalTitleDeprecated(String(osVersionToBeDropped)),
|
||||
subtitle: VectorL10n.versionCheckModalSubtitleDeprecated,
|
||||
actionButtonTitle: VectorL10n.versionCheckModalActionTitleDeprecated))
|
||||
} else {
|
||||
versionCheckAlertViewController.configureWithDetails(VersionCheckAlertViewControllerDetails(title: VectorL10n.versionCheckModalTitleSupported(String(osVersionToBeDropped)),
|
||||
subtitle: VectorL10n.versionCheckModalSubtitleSupported,
|
||||
actionButtonTitle: VectorL10n.versionCheckModalActionTitleSupported))
|
||||
}
|
||||
|
||||
rootViewController.present(versionCheckAlertViewController, animated: true) {
|
||||
self.dismissVersionCheckBanner()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - VersionCheckAlertViewControllerDelegate
|
||||
|
||||
func alertViewControllerDidRequestDismissal(_ alertViewController: VersionCheckAlertViewController) {
|
||||
rootViewController.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
func alertViewControllerDidRequestAction(_ alertViewController: VersionCheckAlertViewController) {
|
||||
rootViewController.dismiss(animated: true, completion: nil)
|
||||
|
||||
guard hasOSVersionBeenDropped else {
|
||||
return
|
||||
}
|
||||
|
||||
if let url = URL(string: "https://support.apple.com/en-gb/guide/iphone/iph3e504502/ios") {
|
||||
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func dismissVersionCheckBanner() {
|
||||
bannerPresenter.dismissBannerView(animated: true)
|
||||
|
||||
let nextDisplayDate = Calendar.current.date(byAdding: .month, value: 1, to: Date())
|
||||
nextDisplayDateTimeInterval = nextDisplayDate?.timeIntervalSince1970
|
||||
}
|
||||
|
||||
@objc private func updateTheme() {
|
||||
let theme = themeService.theme
|
||||
versionCheckBannerView?.update(theme: theme)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user