Files
iOS/Sources/App/WebView/DownloadManager/DownloadManagerView.swift
Bruno Pantaleão Gonçalves 8c46161ff0 Replace usage of UIApplication.shared by URLOpener class (#3961)
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->

## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->

## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->

## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#

## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-12 15:41:49 +01:00

141 lines
4.5 KiB
Swift

import Shared
import SwiftUI
@available(iOS 17.0, *)
struct DownloadManagerView: View {
@Environment(\.dismiss) private var dismiss
@StateObject var viewModel: DownloadManagerViewModel
@State private var shareWrapper: ShareWrapper?
init(viewModel: DownloadManagerViewModel) {
self._viewModel = .init(wrappedValue: viewModel)
}
var body: some View {
VStack(spacing: .zero) {
closeButton
content
Spacer()
}
.onDisappear {
viewModel.cancelDownload()
// For mac the file should remain in the download folder to keep expected behavior
if !Current.isCatalyst {
viewModel.deleteFile()
}
}
.onChange(of: viewModel.finished) { _, newValue in
if newValue, Current.isCatalyst {
URLOpener.shared.open(AppConstants.DownloadsDirectory, options: [:], completionHandler: nil)
}
}
}
@ViewBuilder
private var content: some View {
if viewModel.finished {
successView
} else if viewModel.failed {
fileCard
failedCard
} else {
HAProgressView(style: .large)
.padding(Spaces.four)
Text(verbatim: L10n.DownloadManager.Downloading.title)
.font(.title.bold())
fileCard
Text(viewModel.progress)
.animation(.easeInOut(duration: 1), value: viewModel.progress)
}
}
private var closeButton: some View {
HStack {
Button(action: {
dismiss()
}, label: {
Image(systemSymbol: .xmarkCircleFill)
.font(.title)
.foregroundStyle(
Color(uiColor: .systemBackground),
.gray.opacity(0.5)
)
})
.buttonStyle(.plain)
.frame(maxWidth: .infinity, alignment: .trailing)
.padding()
}
}
private var successView: some View {
VStack(spacing: Spaces.three) {
Image(systemSymbol: .checkmark)
.foregroundStyle(.green)
.font(.system(size: 100))
.symbolEffect(
.bounce,
options: .nonRepeating
)
Text(verbatim: L10n.DownloadManager.Finished.title)
.font(.title.bold())
if let url = viewModel.lastURLCreated {
if Current.isCatalyst {
Button {
URLOpener.shared.open(AppConstants.DownloadsDirectory, options: [:], completionHandler: nil)
} label: {
Label(viewModel.fileName, systemSymbol: .folder)
}
.buttonStyle(.primaryButton)
} else {
ShareLink(viewModel.fileName, item: url)
.lineLimit(1)
.truncationMode(.middle)
.padding()
.foregroundStyle(.white)
.background(Color.haPrimary)
.clipShape(RoundedRectangle(cornerRadius: CornerRadiusSizes.oneAndHalf))
.padding()
.onAppear {
shareWrapper = .init(url: url)
}
.sheet(item: $shareWrapper, onDismiss: {}, content: { data in
ActivityViewController(shareWrapper: data)
})
}
}
}
}
private var fileCard: some View {
HStack {
Image(systemSymbol: .docZipper)
Text(viewModel.fileName)
}
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(.gray.opacity(0.5))
.clipShape(RoundedRectangle(cornerRadius: CornerRadiusSizes.oneAndHalf))
.padding()
}
private var failedCard: some View {
Text(viewModel.errorMessage)
.frame(maxWidth: .infinity, alignment: .leading)
.multilineTextAlignment(.leading)
.padding()
.background(.red.opacity(0.5))
.clipShape(RoundedRectangle(cornerRadius: CornerRadiusSizes.oneAndHalf))
.padding()
}
}
#Preview {
if #available(iOS 17.0, *) {
DownloadManagerView(viewModel: .init())
} else {
Text("Hey there")
}
}