Files
Termind/TFM/Features/Keychain/KeyExportDetailView.swift

77 lines
3.4 KiB
Swift

// SPDX-FileCopyrightText: 2026 Kaede Akino
// SPDX-License-Identifier: GPL-3.0-only
import SwiftUI
import TermindApplication
import TermindDomain
import TermindPresentation
struct KeyExportDetailView: View {
let keyID: SSHKeyRef.ID
@Environment(AppModel.self) private var app
@Environment(WindowModel.self) private var window
@State private var model: KeyExportModel?
var body: some View {
VaultDetailScaffold(
title: AppStrings.Keychain.exportToHost, symbol: "square.and.arrow.up", close: window.closeVaultWork
) {
if let model {
if model.journey.isPresented {
journey(model)
} else {
KeyExportForm(model: model)
}
} else {
ContentUnavailableView(AppStrings.Keychain.keyUnavailable.swiftUIKey, systemImage: "key.slash")
}
} footer: {
HStack {
if model?.phase == .exporting {
ProgressView().controlSize(.small)
Text(AppStrings.KeyExport.exporting).font(.caption)
}
Spacer()
Button(
model?.didExport == true ? AppStrings.Common.done.swiftUIKey : AppStrings.Common.cancel.swiftUIKey,
action: window.closeVaultWork)
if let model, case .failed = model.phase, model.journey.isPresented {
Button(AppStrings.Common.edit.swiftUIKey) { model.editOptions() }
}
if let model, !model.didExport, !model.journey.isPresented {
Button(AppStrings.KeyExport.exportAndAttach.swiftUIKey) { model.start() }
.buttonStyle(.borderedProminent).keyboardShortcut(.defaultAction)
.disabled(!model.canStart)
}
}.padding(Metrics.Space.l)
}
.task(id: keyID) {
model?.cancel()
model = app.hostLibrary.key(keyID).map {
KeyExportModel(key: $0, library: app.hostLibrary, services: app.connections.keyExportServices())
}
}
.onDisappear { model?.cancel() }
}
private func journey(_ model: KeyExportModel) -> some View {
let promptID = model.authenticationPrompt?.id
let operationID = model.operationID
return ConnectionJourneyView(
journey: model.journey, authenticationPrompt: model.authenticationPrompt,
hostKey: model.connection.pendingHostKey,
submitAuthentication: { identity, username, password, passphrase, key, save in
guard let promptID else { return }
model.submitAuthentication(
promptID: promptID, identityID: identity, username: username, password: password,
passphrase: passphrase, keyID: key, save: save)
},
continueHostKey: { model.acceptHostKey($0, operationID: operationID, remember: false) },
trustHostKey: { model.acceptHostKey($0, operationID: operationID, remember: true) },
denyHostKey: window.closeVaultWork, retry: model.retry, cancel: window.closeVaultWork,
securityKeySigning: model.connection.securityKeySigning,
keyboardAuthentication: model.connection.keyboardAuthentication,
cancelKeyboardAuthentication: window.closeVaultWork, isEmbedded: true)
}
}