Voice chips directly under the summary (before the long sections): every position further down fell off-screen and read as 'missing'; saved-report path keeps them under the report; dedupe with the bottom block
This commit is contained in:
parent
104aaa4d66
commit
1f688e79bc
1 changed files with 60 additions and 22 deletions
|
|
@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.heightIn
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
|
|
@ -853,6 +854,43 @@ fun DetailScreen(state: DesktopState) {
|
|||
Text(it, style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.primary)
|
||||
}
|
||||
// Voice controls FIRST under the summary — before the long
|
||||
// sections. Every time they sat further down (page bottom,
|
||||
// then below the bullets) they fell off-screen and read as
|
||||
// "missing". They act on this summary; they live here.
|
||||
run {
|
||||
val report = detail.reportText
|
||||
val hasTranscript = detail.transcript != null ||
|
||||
(report != null && !report.contains("_No transcript available._"))
|
||||
val remoteKnown = state.remoteIdFor(detail.file) != null
|
||||
val sumBusy = detail.jobs.firstOrNull { it.jobType == "summarize" }
|
||||
?.status in setOf("queued", "running")
|
||||
val voicesEnabled = remoteKnown && hasTranscript && !sumBusy
|
||||
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||
Text("Re-summarize in the voice of",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
SUMMARIZE_PERSONAS.forEach { (label, tone) ->
|
||||
FilterChip(
|
||||
selected = sumTone == tone,
|
||||
enabled = voicesEnabled,
|
||||
onClick = {
|
||||
sumTone = tone
|
||||
state.summarize(tone)
|
||||
},
|
||||
label = { Text(label) },
|
||||
)
|
||||
}
|
||||
}
|
||||
if (!voicesEnabled && !remoteKnown) {
|
||||
Text("Summarize unlocks once this file is uploaded (press Transcribe).",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.height(4.dp))
|
||||
// Full structured sections (key points, decisions, action
|
||||
// items, questions, details) right on screen — the saved
|
||||
// .md report had them but the live view showed only the
|
||||
|
|
@ -878,38 +916,38 @@ fun DetailScreen(state: DesktopState) {
|
|||
Spacer(Modifier.height(4.dp))
|
||||
}
|
||||
}
|
||||
// Voice controls sit directly under the summary — they act on it,
|
||||
// and at the page bottom (below a long transcript) they read as
|
||||
// gone. Hoisted above the transcript section; same conditions.
|
||||
// Re-transcribe + summarize progress (the chips themselves live
|
||||
// under the summary for the live path; this block also covers a
|
||||
// file opened as a saved report with no live summary object).
|
||||
if (detail.transcript != null || detail.reportText != null) {
|
||||
// Honest labels: "Re-…" only when that output actually exists.
|
||||
val report = detail.reportText
|
||||
val hasTranscript = detail.transcript != null ||
|
||||
(report != null && !report.contains("_No transcript available._"))
|
||||
val hasSummary = detail.summary != null ||
|
||||
(report?.contains("## Summary") == true)
|
||||
val remoteKnown = state.remoteIdFor(detail.file) != null
|
||||
// A voice chip IS the action: clicking one re-summarizes in
|
||||
// that voice immediately — no separate Re-summarize button.
|
||||
val sumBusy = detail.jobs.firstOrNull { it.jobType == "summarize" }
|
||||
?.status in setOf("queued", "running")
|
||||
val voicesEnabled = remoteKnown && hasTranscript && !sumBusy
|
||||
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||
Text(if (hasSummary) "Re-summarize in the voice of"
|
||||
else "Summarize in the voice of",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
SUMMARIZE_PERSONAS.forEach { (label, tone) ->
|
||||
FilterChip(
|
||||
selected = sumTone == tone,
|
||||
enabled = voicesEnabled,
|
||||
onClick = {
|
||||
sumTone = tone
|
||||
state.summarize(tone)
|
||||
},
|
||||
label = { Text(label) },
|
||||
)
|
||||
if (detail.transcript == null) {
|
||||
// Saved-report path: chips here, same rules.
|
||||
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||
Text(if (hasSummary) "Re-summarize in the voice of"
|
||||
else "Summarize in the voice of",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
SUMMARIZE_PERSONAS.forEach { (label, tone) ->
|
||||
FilterChip(
|
||||
selected = sumTone == tone,
|
||||
enabled = voicesEnabled,
|
||||
onClick = {
|
||||
sumTone = tone
|
||||
state.summarize(tone)
|
||||
},
|
||||
label = { Text(label) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue