From 738c6ace1beb8815cf99a9e47d712c1b7ce0b832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pantale=C3=A3o=20Gon=C3=A7alves?= Date: Thu, 7 Dec 2023 13:58:52 -0300 Subject: [PATCH] Add drop support announcement view (#2471) ## Summary Add drop support announcement view ## Screenshots Screenshot 2023-12-05 at 16 44 09 ## Link to pull request in Documentation repository Documentation: home-assistant/companion.home-assistant# ## Any other notes --- HomeAssistant.xcodeproj/project.pbxproj | 12 ++ .../DropSupportMessageViewController.swift | 134 ++++++++++++++++++ .../Resources/en.lproj/Localizable.strings | 4 + Sources/App/WebView/WebViewController.swift | 7 + .../Shared/Resources/Swiftgen/Strings.swift | 13 ++ 5 files changed, 170 insertions(+) create mode 100644 Sources/App/DropSupport/DropSupportMessageViewController.swift diff --git a/HomeAssistant.xcodeproj/project.pbxproj b/HomeAssistant.xcodeproj/project.pbxproj index 5d516829f..c9af10381 100644 --- a/HomeAssistant.xcodeproj/project.pbxproj +++ b/HomeAssistant.xcodeproj/project.pbxproj @@ -520,6 +520,7 @@ 424A7F482B188BF3008C8DF3 /* WidgetContentMargin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 424A7F472B188BF3008C8DF3 /* WidgetContentMargin.swift */; }; 426740A92B17391000C1DD73 /* Data+Hexadecimal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 426740A72B17390A00C1DD73 /* Data+Hexadecimal.swift */; }; 42CA28BB2B1028330093B31A /* SimulatorThreadClientService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42CA28BA2B1028330093B31A /* SimulatorThreadClientService.swift */; }; + 42CFCD6A2B1F958A00CCEF4A /* DropSupportMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42CFCD692B1F958A00CCEF4A /* DropSupportMessageViewController.swift */; }; 42DD84132B14ACAB00936F16 /* Color+ColorAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DD84122B14ACAB00936F16 /* Color+ColorAsset.swift */; }; 42DD84162B14D7AC00936F16 /* WebViewExternalBusMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DD84142B14D68C00936F16 /* WebViewExternalBusMessage.swift */; }; 42DD84192B14D83B00936F16 /* WebViewExternalBusMessageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DD84182B14D83B00936F16 /* WebViewExternalBusMessageTests.swift */; }; @@ -1600,6 +1601,7 @@ 42CA28B52B1022680093B31A /* HAButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HAButton.swift; sourceTree = ""; }; 42CA28B72B10279D0093B31A /* ThreadClientService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadClientService.swift; sourceTree = ""; }; 42CA28BA2B1028330093B31A /* SimulatorThreadClientService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulatorThreadClientService.swift; sourceTree = ""; }; + 42CFCD692B1F958A00CCEF4A /* DropSupportMessageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropSupportMessageViewController.swift; sourceTree = ""; }; 42DD84122B14ACAB00936F16 /* Color+ColorAsset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+ColorAsset.swift"; sourceTree = ""; }; 42DD84142B14D68C00936F16 /* WebViewExternalBusMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewExternalBusMessage.swift; sourceTree = ""; }; 42DD84182B14D83B00936F16 /* WebViewExternalBusMessageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewExternalBusMessageTests.swift; sourceTree = ""; }; @@ -3045,6 +3047,14 @@ path = Mocks; sourceTree = ""; }; + 42CFCD682B1F956D00CCEF4A /* DropSupport */ = { + isa = PBXGroup; + children = ( + 42CFCD692B1F958A00CCEF4A /* DropSupportMessageViewController.swift */, + ); + path = DropSupport; + sourceTree = ""; + }; 42DD84172B14D83400936F16 /* Tests */ = { isa = PBXGroup; children = ( @@ -3366,6 +3376,7 @@ B657A8E81CA646EB00121384 /* App */ = { isa = PBXGroup; children = ( + 42CFCD682B1F956D00CCEF4A /* DropSupport */, B657A8E91CA646EB00121384 /* AppDelegate.swift */, D03D893720E0AF1B00D4F28D /* ClientEvents */, 11A183B22511BCF300CA326A /* LifecycleManager.swift */, @@ -5623,6 +5634,7 @@ 1178C4E524D5CEB200FDEC3E /* ConnectionURLViewController.swift in Sources */, B661FC88226D478300E541DD /* OnboardingScanningViewController.swift in Sources */, 11A48D8124CA8ADB0021BDD9 /* NotificationCategory+Observation.swift in Sources */, + 42CFCD6A2B1F958A00CCEF4A /* DropSupportMessageViewController.swift in Sources */, 1100D51D2496AECE00B1073C /* PermissionStatusRow.swift in Sources */, D0B25BD221323CA600678C2C /* ClientEventPayloadViewController.swift in Sources */, B641BC1F1E2097EF002CCBC1 /* AboutViewController.swift in Sources */, diff --git a/Sources/App/DropSupport/DropSupportMessageViewController.swift b/Sources/App/DropSupport/DropSupportMessageViewController.swift new file mode 100644 index 000000000..78471eb4d --- /dev/null +++ b/Sources/App/DropSupport/DropSupportMessageViewController.swift @@ -0,0 +1,134 @@ +import Shared +import UIKit + +class DropSupportMessageViewController: UIViewController { + private let imageView: UIImageView = { + let imageView = UIImageView() + imageView.contentMode = .scaleAspectFit + imageView.image = UIImage(asset: Asset.SharedAssets.logo) + return imageView + }() + + private let titleLabel: UILabel = { + let label = UILabel() + label.textAlignment = .center + label.text = L10n.Announcement.DropSupport.title + label.font = UIFont.boldSystemFont(ofSize: UIFont.preferredFont(forTextStyle: .largeTitle).pointSize) + label.adjustsFontForContentSizeCategory = true + return label + }() + + private let subtitleLabel: UILabel = { + let label = UILabel() + label.textAlignment = .center + label.text = L10n.Announcement.DropSupport.subtitle + label.font = .preferredFont(forTextStyle: .body) + label.adjustsFontForContentSizeCategory = true + label.numberOfLines = 0 + return label + }() + + private let linkButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle(L10n.Announcement.DropSupport.buttonReadMore, for: .normal) + button.addTarget(self, action: #selector(linkButtonTapped), for: .touchUpInside) + button.layer.cornerRadius = HACornerRadius.standard + button.layer.borderColor = UIColor(asset: Asset.Colors.haPrimary)?.cgColor + button.layer.borderWidth = 1 + button.titleLabel?.font = .preferredFont(forTextStyle: .body) + button.tintColor = UIColor(asset: Asset.Colors.haPrimary) + button.contentEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8) + if #available(iOS 13.0, *) { + let icon = UIImage(systemName: "arrow.up.right.square") + button.setImage(icon, for: .normal) + } + button.setContentCompressionResistancePriority(.required, for: .horizontal) + return button + }() + + private let button: UIButton = { + let button = UIButton(type: .system) + button.setTitle(L10n.Announcement.DropSupport.button, for: .normal) + button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) + button.backgroundColor = UIColor(asset: Asset.Colors.haPrimary) + button.contentEdgeInsets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16) + button.layer.cornerRadius = HACornerRadius.standard + button.titleLabel?.font = UIFont.boldSystemFont(ofSize: UIFont.preferredFont(forTextStyle: .body).pointSize) + if #available(iOS 13.0, *) { + button.tintColor = .systemBackground + } else { + button.tintColor = .white + } + return button + }() + + override func viewDidLoad() { + super.viewDidLoad() + if #available(iOS 13.0, *) { + view.backgroundColor = .systemBackground + } else { + view.backgroundColor = .white + } + + let scrollView = UIScrollView() + scrollView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(scrollView) + + let stackView = UIStackView() + stackView.axis = .vertical + stackView.alignment = .center + stackView.spacing = 16 + stackView.distribution = .fillProportionally + stackView.translatesAutoresizingMaskIntoConstraints = false + + stackView.addArrangedSubview(imageView) + + titleLabel.setContentCompressionResistancePriority(.required, for: .vertical) + stackView.addArrangedSubview(titleLabel) + + subtitleLabel.setContentCompressionResistancePriority(.required, for: .vertical) + stackView.addArrangedSubview(subtitleLabel) + + let spacer = UIView() + spacer.setContentHuggingPriority(.defaultLow, for: .vertical) + stackView.addArrangedSubview(spacer) + stackView.addArrangedSubview(linkButton) + + button.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(button) + scrollView.addSubview(stackView) + + NSLayoutConstraint.activate([ + scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + scrollView.topAnchor.constraint(equalTo: view.topAnchor), + scrollView.bottomAnchor.constraint(equalTo: button.bottomAnchor), + + stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 16), + stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -16), + stackView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 64), + stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -32), + stackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -32), + + imageView.heightAnchor.constraint(equalToConstant: 100), + imageView.widthAnchor.constraint(equalToConstant: 100), + + button.topAnchor.constraint(greaterThanOrEqualTo: scrollView.bottomAnchor, constant: 16), + button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -32), + button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16), + button.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16), + button.heightAnchor.constraint(equalToConstant: 50), + linkButton.heightAnchor.constraint(equalToConstant: 50), + ]) + view.layoutIfNeeded() + } + + @objc private func buttonTapped() { + dismiss(animated: true) + } + + @objc private func linkButtonTapped() { + guard let url = URL(string: "https://www.home-assistant.io/blog/") else { return } + UIApplication.shared.open(url) + } +} diff --git a/Sources/App/Resources/en.lproj/Localizable.strings b/Sources/App/Resources/en.lproj/Localizable.strings index 38f75691c..fe43c5ead 100644 --- a/Sources/App/Resources/en.lproj/Localizable.strings +++ b/Sources/App/Resources/en.lproj/Localizable.strings @@ -776,3 +776,7 @@ Home Assistant is free and open source home automation software with a focus on "thread.credentials.share_credentials_button_title" = "Share credential with Home Assistant"; "thread.credentials.screen_title" = "Thread Credentials"; "thread.credentials.no_credential_available" = "You don't have credentials available on your iCloud Keychain."; +"announcement.drop_support.title" = "Important update"; +"announcement.drop_support.subtitle" = "After careful consideration, we will be discontinuing support for iOS 12, 13 and 14 in our upcoming updates."; +"announcement.drop_support.button" = "Continue"; +"announcement.drop_support.button_read_more" = "Read more"; diff --git a/Sources/App/WebView/WebViewController.swift b/Sources/App/WebView/WebViewController.swift index 23cede06d..7a1c974a8 100644 --- a/Sources/App/WebView/WebViewController.swift +++ b/Sources/App/WebView/WebViewController.swift @@ -248,6 +248,13 @@ final class WebViewController: UIViewController, WKNavigationDelegate, WKUIDeleg styleUI() updateWebViewForServerValues() + + let dropSupportMessageKey = "drop-support-ios-12-13-14" + let dropSupportViewDisplayedPreviously = UserDefaults.standard.bool(forKey: dropSupportMessageKey) + if #unavailable(iOS 14.0), !dropSupportViewDisplayedPreviously { + UserDefaults.standard.set(true, forKey: dropSupportMessageKey) + present(DropSupportMessageViewController(), animated: true) + } } public func showSettingsViewController() { diff --git a/Sources/Shared/Resources/Swiftgen/Strings.swift b/Sources/Shared/Resources/Swiftgen/Strings.swift index 9856e35e5..98e0239a6 100644 --- a/Sources/Shared/Resources/Swiftgen/Strings.swift +++ b/Sources/Shared/Resources/Swiftgen/Strings.swift @@ -216,6 +216,19 @@ public enum L10n { } } + public enum Announcement { + public enum DropSupport { + /// Continue + public static var button: String { return L10n.tr("Localizable", "announcement.drop_support.button") } + /// Read more + public static var buttonReadMore: String { return L10n.tr("Localizable", "announcement.drop_support.button_read_more") } + /// After careful consideration, we will be discontinuing support for iOS 12, 13 and 14 in our upcoming updates. + public static var subtitle: String { return L10n.tr("Localizable", "announcement.drop_support.subtitle") } + /// Important update + public static var title: String { return L10n.tr("Localizable", "announcement.drop_support.title") } + } + } + public enum ClError { public enum Description { /// Deferred mode is not supported for the requested accuracy.