Files
bundesmessenger-ios/bwi/FeatureBanner/FeatureBannerView.swift
2026-03-17 13:55:15 +00:00

235 lines
7.9 KiB
Swift

//
/*
* Copyright (c) 2023 BWI GmbH
*
* 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 SwiftUI
import UIKit
protocol FeatureBannerDelegate {
func didPressClose()
func didPressShowDetails()
}
@objcMembers class FeatureBannerViewCell<Content: View>: UITableViewCell, FeatureBannerDelegate {
private var parentViewController: UIViewController?
private let hostingController = UIHostingController<Content?>(rootView: nil)
private var webViewController: WebViewViewController?
private var username: String = ""
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
hostingController.view.backgroundColor = UIColor.clear
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func setupView(parent: UIViewController, rootView: Content) {
self.parentViewController = parent
hostingController.rootView = rootView
let shouldControllerMove = hostingController.parent != parent
if shouldControllerMove {
removeController()
parent.addChild(hostingController)
}
if !self.contentView.subviews.contains(hostingController.view) {
self.contentView.addSubview(hostingController.view)
self.contentView.vc_addSubViewMatchingParentSafeArea(hostingController.view)
}
if shouldControllerMove {
hostingController.didMove(toParent: parent)
}
}
func calculateHeight() -> CGFloat {
hostingController.view.setNeedsLayout()
hostingController.view.layoutIfNeeded()
let result = hostingController.view.intrinsicContentSize.height
return result
}
private func removeController() {
hostingController.willMove(toParent: nil)
hostingController.view.removeFromSuperview()
hostingController.removeFromParent()
parentViewController = nil
}
deinit {
removeController()
}
// MARK: user interaction
func hideTopBanner() {
removeController()
NotificationCenter.default.post(name: .bwiHideTopBanner, object: self, userInfo: ["type" : "feature_banner"])
}
func didPressClose() {
hideTopBanner()
}
func didPressShowDetails() {
let migrationInfoView = MigrationInfoView(username: username, getUserName: nil).environmentObject(BWIThemeService.shared).interactiveDismissDisabled(true)
let hostingViewController = UIHostingController(rootView: migrationInfoView)
if hostingViewController.popoverPresentationController != nil {
hostingViewController.modalPresentationStyle = .popover
}
hostingViewController.isModalInPresentation = true
hostingController.parent?.present(hostingViewController, animated: true, completion: nil)
}
@objc func closeModal() {
webViewController?.dismiss(animated: true)
}
func setUsername(username: String) {
self.username = username
}
}
struct FeatureBannerView: View {
var delegate: FeatureBannerDelegate?
let darkmodeBackground = UIColor(rgb:0x2394A7)
let warningColor = UIColor(rgb:0xD51928)
var backgroundColor: Color {
if BWIBuildSettings.shared.BuMXMigrationInfoLevel >= 2 {
ThemeService.shared().isCurrentThemeDark() ? Color(uiColor: warningColor) : Color(ThemeService.shared().theme.warningColor)
} else {
ThemeService.shared().isCurrentThemeDark() ? Color(uiColor: darkmodeBackground) : Color(ThemeService.shared().theme.tintColor)
}
}
var body: some View {
VStack(alignment: .center) {
header
advertisementText
HStack(alignment: .center, spacing: 12) {
remindMeLaterButton
showMoreButton
}
}
.padding(.horizontal, 12)
.background(backgroundColor)
.cornerRadius(12)
.padding(16)
}
var header: some View {
HStack() {
Image(Asset.Images.newFeatures.name)
// .renderingMode(.template)
.foregroundColor(Color(ThemeService.shared().theme.backgroundColor))
.accessibilityHidden(true)
Text(BWIL10n.bwiMobileDialogMBannerTitle)
.font(.system(size: 20).bold())
.foregroundColor(Color(ThemeService.shared().theme.backgroundColor))
Spacer()
}
.padding(.top, 16)
}
var advertisementText: some View {
VStack {
VStack {
if BWIBuildSettings.shared.isManagedViaMDM {
Text(BWIL10n.bwiMobileDialogMdmBannerTextPrefix) +
Text(BWIL10n.bwiMobileDialogMdmBannerTextBold)
.bold()
} else if BWIBuildSettings.shared.BuMXMigrationInfoLevel == 1 {
Text(BWIL10n.bwiMobileDialogM1BannerTextPrefix) +
Text(BWIL10n.bwiMobileDialogM1BannerTextBold)
.bold()
} else {
Text(BWIL10n.bwiMobileDialogM2BannerTextPrefix) +
Text(BWIL10n.bwiMobileDialogM2BannerTextBold)
.bold() +
Text(BWIL10n.bwiMobileDialogM2BannerTextSuffix)
}
}
}
.font(.system(size: 15))
.multilineTextAlignment(.leading)
.lineLimit(nil)
.fixedSize(horizontal: false, vertical: true)
.foregroundColor(Color(ThemeService.shared().theme.backgroundColor))
}
var closeButton: some View {
HStack() {
Spacer()
Button {
delegate?.didPressClose()
} label: {
Image(Asset.Images.closeButton.name)
.renderingMode(.template)
.foregroundColor(Color(ThemeService.shared().theme.backgroundColor))
.padding(10)
}
}
}
var showMoreButton: some View {
Button {
delegate?.didPressShowDetails()
} label: {
HStack() {
Spacer()
Text(BWIL10n.bwiMobileDialogMBannerButton2)
.font(.system(size: 18))
.bold()
.padding(10)
.foregroundColor(ThemeService.shared().isCurrentThemeDark() ? Color(uiColor: darkmodeBackground) : Color.black)
Spacer()
}
}
.background(Color(ThemeService.shared().theme.backgroundColor))
.cornerRadius(12)
.padding(.top, 10)
.padding(.bottom, 25)
}
var remindMeLaterButton: some View {
Button {
delegate?.didPressClose()
} label: {
HStack() {
Spacer()
Text(BWIL10n.bwiMobileDialogMBannerButton1)
.font(.system(size: 18))
.padding(10)
.foregroundColor(Color(ThemeService.shared().theme.backgroundColor))
Spacer()
}
}
.overlay(RoundedRectangle(cornerRadius: 12)
.stroke(Color(ThemeService.shared().theme.backgroundColor), lineWidth: 2))
.padding(.top, 10)
.padding(.bottom, 25)
}
}