fix(hls): stick the upload counter + flip past tense between uploads
Two related UX issues on the HLS publish progress screen: 1. The Uploading PhaseRow's label used a fallback of `stringResource(hls_state_uploading_format, 0, 0)` whenever state wasn't Uploading, so the row flickered back to "Uploading 0 of 0" during the Transcoding phase between rendition uploads. The counter appeared to reset mid-flow even though every upload was succeeding. 2. With the counter now persisted, it still read "Uploading 2 of 5" while we were actually transcoding the next rendition — the count was right but the verb tense implied an upload was in flight when none was. Persist lastDone + lastTotal in the composable via remember so the counter reads monotonically across state transitions, and split the label into two semantic variants: - "Uploading %s (%d of %d)" — present tense, only when an upload is actually in flight (state is HlsPublishState.Uploading). The %d is the pre-incremented in-flight index. - "Uploaded %d of %d" — past tense, used both in the gap between uploads (transcoding next rendition) and in the done/checkmark state. The %d is the last observed in-flight index, which after the lambda returns corresponds to the count that has actually finished. - "Upload" — only the pre-first-upload idle state. Also add a progressFraction that falls back to lastDone/lastTotal so the progress bar under the row sticks too, matching the label. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+41
-16
@@ -67,7 +67,9 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@@ -508,27 +510,50 @@ private fun ProgressBody(
|
||||
|
||||
HorizontalDivider(modifier = Modifier.padding(vertical = 12.dp))
|
||||
|
||||
val uploadingFraction =
|
||||
(state as? HlsPublishState.Uploading)?.let { up ->
|
||||
if (up.total == 0) 0f else up.done.toFloat() / up.total
|
||||
// Persist the last-observed upload count across transitions so the Uploading row
|
||||
// doesn't flicker back to "0 of 0" whenever state flips to Transcoding (between
|
||||
// renditions) or Publishing (after the last upload). The counter should read
|
||||
// monotonically: 1 of N → 2 of N → … → N of N as uploads actually complete.
|
||||
var lastDone by remember { mutableIntStateOf(0) }
|
||||
var lastTotal by remember { mutableIntStateOf(0) }
|
||||
LaunchedEffect(state) {
|
||||
if (state is HlsPublishState.Uploading) {
|
||||
lastDone = state.done
|
||||
lastTotal = state.total
|
||||
}
|
||||
}
|
||||
|
||||
val uploadingFraction =
|
||||
if (lastTotal > 0) lastDone.toFloat() / lastTotal else null
|
||||
val uploadingLabel =
|
||||
when (state) {
|
||||
is HlsPublishState.Uploading -> {
|
||||
if (state.currentLabel.isNotBlank()) {
|
||||
stringResource(
|
||||
R.string.hls_state_uploading_with_label_format,
|
||||
state.currentLabel,
|
||||
state.done,
|
||||
state.total,
|
||||
)
|
||||
} else {
|
||||
stringResource(R.string.hls_state_uploading_format, state.done, state.total)
|
||||
}
|
||||
when {
|
||||
// Currently in flight: present-tense, file label in the line.
|
||||
state is HlsPublishState.Uploading && state.currentLabel.isNotBlank() -> {
|
||||
stringResource(
|
||||
R.string.hls_state_uploading_with_label_format,
|
||||
state.currentLabel,
|
||||
state.done,
|
||||
state.total,
|
||||
)
|
||||
}
|
||||
|
||||
// Currently in flight, no file label (unreachable in practice — orchestrator
|
||||
// always sets a label — but kept for completeness).
|
||||
state is HlsPublishState.Uploading -> {
|
||||
stringResource(R.string.hls_state_uploading_format, state.done, state.total)
|
||||
}
|
||||
|
||||
// Between uploads or after all uploads finish: past-tense, monotonic count.
|
||||
// The last uploaded file's index sticks on screen while the transcoder
|
||||
// works on the next rendition, and lands on "Uploaded N of N" when the row
|
||||
// flips to its checkmark/done state.
|
||||
lastTotal > 0 -> {
|
||||
stringResource(R.string.hls_state_uploaded_format, lastDone, lastTotal)
|
||||
}
|
||||
|
||||
// Nothing has started uploading yet (very beginning of publish flow).
|
||||
else -> {
|
||||
stringResource(R.string.hls_state_uploading_format, 0, 0)
|
||||
stringResource(R.string.hls_state_uploading_idle)
|
||||
}
|
||||
}
|
||||
PhaseRow(
|
||||
|
||||
@@ -2106,8 +2106,10 @@
|
||||
<string name="hls_publish_button">Publish HD video</string>
|
||||
<string name="hls_publishing_header_format">Publishing “%1$s”…</string>
|
||||
<string name="hls_state_transcoding_format">Transcoding %1$s</string>
|
||||
<string name="hls_state_uploading_idle">Upload</string>
|
||||
<string name="hls_state_uploading_format">Uploading %1$d of %2$d</string>
|
||||
<string name="hls_state_uploading_with_label_format">Uploading %1$s (%2$d of %3$d)</string>
|
||||
<string name="hls_state_uploaded_format">Uploaded %1$d of %2$d</string>
|
||||
<string name="hls_state_publishing">Publishing event…</string>
|
||||
<string name="hls_state_success_title">Video published</string>
|
||||
<string name="hls_state_success_body">Your HD video is live on Nostr.</string>
|
||||
|
||||
Reference in New Issue
Block a user