Desktop: live progress bar + % on the detail screen; openDetail polls running jobs
This commit is contained in:
parent
1460d767f7
commit
f73f12056f
2 changed files with 28 additions and 2 deletions
|
|
@ -711,12 +711,29 @@ class DesktopState(private val appDir: File = defaultAppDir()) {
|
||||||
// file looks empty and the summary appears unreachable.
|
// file looks empty and the summary appears unreachable.
|
||||||
val saved = runCatching { reportFile(file).readText() }.getOrNull()
|
val saved = runCatching { reportFile(file).readText() }.getOrNull()
|
||||||
val mapping = loadMapping(file)
|
val mapping = loadMapping(file)
|
||||||
_detail.value = DetailUi(
|
val d = DetailUi(
|
||||||
file = file, reportText = saved,
|
file = file, reportText = saved,
|
||||||
remoteId = mapping?.recordingId,
|
remoteId = mapping?.recordingId,
|
||||||
overrideModel = mapping?.model,
|
overrideModel = mapping?.model,
|
||||||
)
|
)
|
||||||
|
_detail.value = d
|
||||||
go(Screen.DETAIL)
|
go(Screen.DETAIL)
|
||||||
|
// If the file is mid-pipeline (pump running, or reprocess started
|
||||||
|
// elsewhere), show live stage/progress instead of a stale report.
|
||||||
|
val remoteId = d.remoteId ?: return
|
||||||
|
pollJob = scope.launch {
|
||||||
|
while (true) {
|
||||||
|
val jobs = runCatching { parseJobs(provider.fetchJobs(remoteId)) }
|
||||||
|
.getOrNull().orEmpty()
|
||||||
|
if (_detail.value?.file != file) break
|
||||||
|
d.jobs = jobs
|
||||||
|
jobLabel(jobs)?.let { d.busy = it } ?: run { d.busy = null }
|
||||||
|
_detail.value = d.copy()
|
||||||
|
val active = jobs.any { it.status == "running" || it.status == "queued" }
|
||||||
|
if (!active) break
|
||||||
|
delay(2000)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setOverride(model: String?) {
|
fun setOverride(model: String?) {
|
||||||
|
|
|
||||||
|
|
@ -305,17 +305,26 @@ fun DetailScreen(state: DesktopState) {
|
||||||
}
|
}
|
||||||
val tJob = detail.jobs.firstOrNull { it.jobType == "transcribe" }
|
val tJob = detail.jobs.firstOrNull { it.jobType == "transcribe" }
|
||||||
tJob?.let {
|
tJob?.let {
|
||||||
|
val running = it.status == "running"
|
||||||
val label = when {
|
val label = when {
|
||||||
it.status == "succeeded" -> "Transcribed"
|
it.status == "succeeded" -> "Transcribed"
|
||||||
it.status == "failed" -> "Failed"
|
it.status == "failed" -> "Failed"
|
||||||
it.stage == "loading-model" -> "Loading model…"
|
it.stage == "loading-model" -> "Loading model…"
|
||||||
|
running && it.progress != null -> "Transcribing… ${it.progress}%"
|
||||||
it.stage == "transcribing" -> "Transcribing…"
|
it.stage == "transcribing" -> "Transcribing…"
|
||||||
it.status == "running" -> "Working… (attempt ${it.attempt}/${it.maxAttempts})"
|
running -> "Working… (attempt ${it.attempt}/${it.maxAttempts})"
|
||||||
else -> "Queued"
|
else -> "Queued"
|
||||||
}
|
}
|
||||||
Text(label, style = MaterialTheme.typography.bodyMedium,
|
Text(label, style = MaterialTheme.typography.bodyMedium,
|
||||||
color = if (it.status == "failed") MaterialTheme.colorScheme.error
|
color = if (it.status == "failed") MaterialTheme.colorScheme.error
|
||||||
else MaterialTheme.colorScheme.primary)
|
else MaterialTheme.colorScheme.primary)
|
||||||
|
if (running && it.progress != null) {
|
||||||
|
Spacer(Modifier.height(4.dp))
|
||||||
|
LinearProgressIndicator(
|
||||||
|
progress = { it.progress / 100f },
|
||||||
|
modifier = Modifier.fillMaxWidth().height(4.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
detail.error?.let {
|
detail.error?.let {
|
||||||
Text(it, color = MaterialTheme.colorScheme.error)
|
Text(it, color = MaterialTheme.colorScheme.error)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue