feat: sync force-quit Flow teardown and polish macOS local ASR UX

End Live Activities and release the audio session synchronously on
applicationWillTerminate, and continue macOS local-model install,
onboarding, and settings polish on this branch.
This commit is contained in:
Rocky
2026-07-09 17:13:07 +08:00
parent 200265fbd6
commit dcb66a9849
34 changed files with 1936 additions and 340 deletions
@@ -25,7 +25,7 @@ public enum LocalASRModelInstallState {
let base = URL(fileURLWithPath: manualMLXPath ?? "", isDirectory: true)
guard fileManager.fileExists(atPath: base.path) else { return false }
return required.allSatisfy { fileManager.fileExists(atPath: base.appendingPathComponent($0).path) }
case .archive:
case .archive, .repository:
guard let relative = model.installRelativePath,
let layout = model.layout,
let baseName = model.archiveBaseName else { return false }
@@ -41,7 +41,7 @@ public enum LocalASRModelInstallState {
_ model: LocalASRModelDefinition,
fileManager: FileManager = .default
) -> URL? {
guard model.installKind == .archive,
guard model.installKind == .archive || model.installKind == .repository,
let relative = model.installRelativePath,
let baseName = model.archiveBaseName else { return nil }
return installDirectory(for: relative, fileManager: fileManager)
@@ -98,6 +98,11 @@ public enum LocalASRModelInstallState {
let tokens = layout.tokens else { return false }
return fileManager.fileExists(atPath: root.appendingPathComponent(onnx).path)
&& fileManager.fileExists(atPath: root.appendingPathComponent(tokens).path)
case .sherpaParaformer:
guard let paraformer = layout.paraformerModel,
let tokens = layout.tokens else { return false }
return fileManager.fileExists(atPath: root.appendingPathComponent(paraformer).path)
&& fileManager.fileExists(atPath: root.appendingPathComponent(tokens).path)
default:
return false
}