mirror of
https://github.com/home-assistant/iOS.git
synced 2026-06-18 02:46:38 -05:00
<!-- 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>
141 lines
4.5 KiB
Swift
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")
|
|
}
|
|
}
|