Files
letro-ios/ElementX/Sources/Screens/Settings/LegalInformationScreen/View/LegalInformationScreen.swift
2026-05-04 23:37:25 +04:00

103 lines
3.7 KiB
Swift

//
// Copyright 2025 Element Creations Ltd.
// Copyright 2022-2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import Compound
import SwiftUI
import WebKit
struct LegalInformationScreen: View {
let context: LegalInformationScreenViewModel.Context
@Environment(\.openURL) private var openURL
// Letro: Open legal info in a sheet instead of external browser
@State private var browserURL: BrowserURL?
var body: some View {
Form {
Section {
ListRow(label: .plain(title: L10n.commonCopyright),
kind: .button { browserURL = BrowserURL(context.viewState.copyrightURL) })
ListRow(label: .plain(title: L10n.commonAcceptableUsePolicy),
kind: .button { browserURL = BrowserURL(context.viewState.acceptableUseURL) })
ListRow(label: .plain(title: L10n.commonPrivacyPolicy),
kind: .button { browserURL = BrowserURL(context.viewState.privacyURL) })
// Letro: Add Acknowledgement row
ListRow(label: .plain(title: "Acknowledgement"),
kind: .button { browserURL = BrowserURL(acknowledgementURL) })
}
}
.compoundList()
.navigationTitle(L10n.commonAbout)
.navigationBarTitleDisplayMode(.inline)
.sheet(item: $browserURL) { browserURL in
ElementNavigationStack {
LegalInformationWebView(url: browserURL.url)
.ignoresSafeArea(edges: .bottom)
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button(L10n.actionDone) {
self.browserURL = nil
}
}
}
}
}
}
private var acknowledgementURL: URL {
let version = InfoPlistReader.main.bundleShortVersionString
let baseURL = URL(string: "https://git.postnumber.com/letro/letro-authentication-service/releases/download/")!
return URL(string: "letro-v\(version)/sbom.json", relativeTo: baseURL)!.absoluteURL
}
}
private struct BrowserURL: Identifiable {
let url: URL
var id: URL {
url
}
init(_ url: URL) {
self.url = url
}
}
private struct LegalInformationWebView: UIViewControllerRepresentable {
let url: URL
func makeUIViewController(context: Context) -> UIViewController {
let viewController = UIViewController()
let webView = WKWebView()
webView.allowsBackForwardNavigationGestures = true
webView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(webView)
NSLayoutConstraint.activate([
webView.topAnchor.constraint(equalTo: viewController.view.topAnchor),
webView.leadingAnchor.constraint(equalTo: viewController.view.leadingAnchor),
webView.trailingAnchor.constraint(equalTo: viewController.view.trailingAnchor),
webView.bottomAnchor.constraint(equalTo: viewController.view.bottomAnchor)
])
webView.load(URLRequest(url: url))
return viewController
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) { }
}
// MARK: - Previews
struct LegalInformationScreen_Previews: PreviewProvider, TestablePreview {
static let viewModel = LegalInformationScreenViewModel(appSettings: AppSettings())
static var previews: some View {
LegalInformationScreen(context: viewModel.context)
}
}