mirror of
https://github.com/TuringSoftware/CrystalFetch.git
synced 2024-09-20 15:05:59 +08:00
156 lines
6.5 KiB
Swift
156 lines
6.5 KiB
Swift
//
|
|
// Copyright © 2023 Turing Software, LLC. All rights reserved.
|
|
//
|
|
// 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
|
|
|
|
struct BuildConfigView: View {
|
|
let build: UUPBuilds.Build
|
|
|
|
@EnvironmentObject private var worker: Worker
|
|
@AppStorage("LastSelectedLocale") private var lastSelectedLocale: String?
|
|
@State private var selectedLocale: String = ""
|
|
@State private var selectedEditions = Set<String>()
|
|
@State private var isTermsAgreed: Bool = false
|
|
@State private var isConfirmCancelShown: Bool = false
|
|
@State private var details = BuildDetails.empty
|
|
@State private var edition = BuildEditions.empty
|
|
@State private var isDownloadCompleted: Bool = false
|
|
|
|
var body: some View {
|
|
VStack {
|
|
ScrollView {
|
|
Form {
|
|
Section {
|
|
HStack {
|
|
Label("Channel", systemImage: "shippingbox")
|
|
Spacer()
|
|
Text(details.ring.prettyRing)
|
|
}
|
|
HStack {
|
|
Label("Build", systemImage: "number")
|
|
Spacer()
|
|
Text(details.build)
|
|
}
|
|
HStack {
|
|
Label("Created", systemImage: "calendar")
|
|
Spacer()
|
|
Text(DateFormatter.localizedString(from: details.created, dateStyle: .long, timeStyle: .short))
|
|
}
|
|
}.padding(.bottom, 5)
|
|
Section("Language") {
|
|
Picker("", selection: $selectedLocale) {
|
|
ForEach(details.languages) { language in
|
|
Text(language.display).tag(language.code)
|
|
}
|
|
}.onChange(of: selectedLocale) { newValue in
|
|
worker.refreshDetails(uuid: build.uuid, language: newValue) {
|
|
details = $0
|
|
edition = $1
|
|
selectedEditions.removeAll()
|
|
selectedEditions.formUnion(edition.editions.map({ $0.code }))
|
|
lastSelectedLocale = newValue
|
|
}
|
|
}
|
|
}
|
|
Section("Editions") {
|
|
ForEach(edition.editions) { edition in
|
|
Toggle(edition.display, isOn: Binding<Bool>(get: {
|
|
selectedEditions.contains(edition.code)
|
|
}, set: { newValue in
|
|
if newValue {
|
|
selectedEditions.insert(edition.code)
|
|
} else {
|
|
selectedEditions.remove(edition.code)
|
|
}
|
|
}))
|
|
}
|
|
}
|
|
}.disabled(worker.isBusy)
|
|
}
|
|
Spacer()
|
|
HStack {
|
|
// SwiftUI BUG: ProgressView cannot go to indeterminate mode and back
|
|
if let progress = worker.progress {
|
|
ProgressView(value: progress) {
|
|
|
|
} currentValueLabel: {
|
|
Text(worker.progressStatus ?? "")
|
|
}
|
|
} else {
|
|
ProgressView(value: nil as Float?) {
|
|
|
|
} currentValueLabel: {
|
|
Text(worker.progressStatus ?? "")
|
|
}
|
|
}
|
|
}
|
|
HStack {
|
|
Toggle("I agree that I have a valid license to use this product.", isOn: $isTermsAgreed)
|
|
.disabled(worker.isBusy)
|
|
Spacer()
|
|
if worker.isBusy {
|
|
Button(role: .cancel) {
|
|
isConfirmCancelShown.toggle()
|
|
} label: {
|
|
Text("Cancel")
|
|
}.keyboardShortcut(.cancelAction)
|
|
.confirmationDialog("Are you sure you want to stop the process?", isPresented: $isConfirmCancelShown) {
|
|
Button("Stop", role: .destructive) {
|
|
worker.stop()
|
|
}
|
|
Button("Cancel", role: .cancel) {
|
|
isConfirmCancelShown = false
|
|
}
|
|
}
|
|
} else {
|
|
Button {
|
|
worker.download(uuid: build.uuid, language: selectedLocale, editions: Array(selectedEditions))
|
|
} label: {
|
|
Text("Download…")
|
|
}.disabled(!isTermsAgreed)
|
|
}
|
|
}
|
|
|
|
}.padding()
|
|
.navigationTitle(build.title)
|
|
.navigationSubtitle(build.arch.prettyArch)
|
|
.onAppear {
|
|
worker.refreshDetails(uuid: build.uuid) {
|
|
details = $0
|
|
edition = $1
|
|
selectedEditions.removeAll()
|
|
selectedEditions.formUnion(edition.editions.map({ $0.code }))
|
|
if let lastSelectedLocale = lastSelectedLocale {
|
|
selectedLocale = lastSelectedLocale
|
|
}
|
|
}
|
|
}
|
|
.onChange(of: worker.completedDownloadUrl) { newValue in
|
|
if newValue != nil {
|
|
isDownloadCompleted = true
|
|
}
|
|
}
|
|
.fileMover(isPresented: $isDownloadCompleted, file: worker.completedDownloadUrl) { result in
|
|
switch result {
|
|
case .success(let success):
|
|
worker.finalize(isoUrl: worker.completedDownloadUrl!, destinationUrl: success)
|
|
case .failure(let failure):
|
|
worker.lastSeenError = Worker.ErrorMessage(message: failure.localizedDescription)
|
|
}
|
|
}
|
|
}
|
|
}
|