Say it in icons, and put the whole backend behind four tabs
Six things Bryan asked for, which turned out to be one change: the app had no icon set, so every one of them was blocked on having somewhere for icons to come from. That somewhere is dev-updater's arrangement, ported: a Nerd Fonts subset committed as an asset, drawn as text. `Gear.kt`'s hand-drawn canvas gear argued against icon fonts because a system font may not have the glyph and whoever gets the empty box is never the person who wrote it. The objection is right about *relying* on a system font and the answer is to ship the glyph, so the file is gone and its reasoning is restated in `NerdIcons.kt` rather than deleted -- otherwise the next reader re-derives it. `md-cog` and `md-refresh` are dev-updater's own codepoints, because a cog means the same thing in both apps. The root screen's four words under the title are now four tabs, and the two that act on the whole screen -- settings and refresh -- moved up onto the title row as glyphs. That row's old comment recorded that a fifth word would have had nowhere to go; tabs also say something the words did not, which is that sessions, import, models and setups are four views of one backend rather than four errands. Refresh feeds whichever tab is showing. Import, models and setups lose their headings and their Back buttons, since the tab row is now both. Usage is a dialog. It is checked *against* what you were reading -- "can I start this" is asked with the transcript still on screen -- and it had no navigation of its own, so the only thing its Back could mean was "put this away". The button that opens it is a chart glyph coloured by the worst of the machine's windows, so the row says whether the limits are worth opening before anybody opens them. One `quotaColor` now colours every bar that measures a quota: blue, yellow at 75%, red at 95%. The session bar escalates where it used to sit blue at every level, and the dialog's thresholds moved out of it. A download keeps plain blue at every value -- it has no limit to approach, and colouring it like one would say the opposite of what is happening. States that are not measurements take the ordinary control colour, since blue is the low end of this scale and would read as "checked, and fine" about a machine nobody could reach. Send and stop are the filled paper plane and the filled square. Send keeps the word "Queue" while a turn is in flight, because that is what pressing it then does, and an icon that does two things while looking identical would promise something immediate and do something that waits. Looked at on the emulator: all six glyphs render, the tabs and the system back gesture between them, the dialog over a live session, and the bar bands at 82% and 97% forced through a scratch build, since this account is at 72/31/5 and would only ever have shown blue.
This commit is contained in:
1 parent
ba71c798f5
commit
ff39ef5cf9
17 files changed
+627
-310
No files matched your search
@@ -16,37 +16,27 @@ import androidx.compose.ui.unit.dp
|
||||
import com.example.wgapplink.localNetworkAllowed
|
||||
|
||||
/**
|
||||
* One `when` rather than a navigation library: four screens, with the list as the root and the back
|
||||
* button the only other way between them.
|
||||
* One `when` rather than a navigation library: a handful of screens, with [Screen.Main] as the root
|
||||
* and the back button the only other way between them.
|
||||
*
|
||||
* Import, models and setups are not here any more. They are tabs inside [MainScreen] -- four views
|
||||
* of the same backend, none of them a step down from another -- and what is left in this `when` is
|
||||
* only what genuinely is a step down: one session, spawning one, and settings.
|
||||
*/
|
||||
private sealed class Screen {
|
||||
data object SessionList : Screen()
|
||||
data object Main : Screen()
|
||||
|
||||
data class Session(val summary: SessionSummary) : Screen()
|
||||
|
||||
data object Spawn : Screen()
|
||||
|
||||
/** Continuing a session the machine already had, rather than starting an empty one. */
|
||||
data object Import : Screen()
|
||||
|
||||
/**
|
||||
* Reached from a session rather than from the list, because usage belongs to the provider
|
||||
* running that session and not to the app. It carries the session back with it so Back returns
|
||||
* where it came from -- see [Screen.Session].
|
||||
*/
|
||||
data class Usage(val from: SessionSummary) : Screen()
|
||||
|
||||
/**
|
||||
* What can be changed about one session. Carries the session back with it for the same reason
|
||||
* [Screen.Usage] does, and carries it *out* renamed, so the session behind it shows the new
|
||||
* name without waiting for a list refresh.
|
||||
* What can be changed about one session. Carries the session back with it so Back returns where
|
||||
* it came from, and carries it *out* renamed, so the session behind it shows the new name
|
||||
* without waiting for a list refresh.
|
||||
*/
|
||||
data class SessionSettings(val from: SessionSummary) : Screen()
|
||||
|
||||
data object Models : Screen()
|
||||
|
||||
data object Setups : Screen()
|
||||
|
||||
data object Settings : Screen()
|
||||
}
|
||||
|
||||
@@ -58,7 +48,7 @@ private sealed class Screen {
|
||||
fun AppRoot(settingsVersion: Int) {
|
||||
val context = LocalContext.current
|
||||
var settings by remember(settingsVersion) { mutableStateOf(loadServerSettings(context)) }
|
||||
var screen by remember { mutableStateOf<Screen>(Screen.SessionList) }
|
||||
var screen by remember { mutableStateOf<Screen>(Screen.Main) }
|
||||
// Bumped whenever another screen changes something the list shows, so
|
||||
// returning to it refetches instead of showing a stale list.
|
||||
var reloadToken by remember { mutableIntStateOf(0) }
|
||||
@@ -86,7 +76,7 @@ fun AppRoot(settingsVersion: Int) {
|
||||
existing = null,
|
||||
onSaved = { saved ->
|
||||
settings = saved
|
||||
screen = Screen.SessionList
|
||||
screen = Screen.Main
|
||||
},
|
||||
onBack = null,
|
||||
)
|
||||
@@ -97,32 +87,32 @@ fun AppRoot(settingsVersion: Int) {
|
||||
// reached by the system back gesture or a screen's own Back button.
|
||||
// Every leaf screen can have changed something the list shows, so it
|
||||
// always refetches.
|
||||
val goToList = {
|
||||
val goToMain = {
|
||||
reloadToken++
|
||||
screen = Screen.SessionList
|
||||
screen = Screen.Main
|
||||
}
|
||||
if (screen !is Screen.SessionList) {
|
||||
BackHandler(onBack = goToList)
|
||||
if (screen !is Screen.Main) {
|
||||
BackHandler(onBack = goToMain)
|
||||
}
|
||||
|
||||
when (val here = screen) {
|
||||
is Screen.SessionList ->
|
||||
SessionListScreen(
|
||||
is Screen.Main ->
|
||||
MainScreen(
|
||||
settings = current,
|
||||
reloadToken = reloadToken,
|
||||
onOpen = { screen = Screen.Session(it) },
|
||||
onSpawn = { screen = Screen.Spawn },
|
||||
onImport = { screen = Screen.Import },
|
||||
onModels = { screen = Screen.Models },
|
||||
onSetups = { screen = Screen.Setups },
|
||||
onImported = { imported ->
|
||||
reloadToken++
|
||||
screen = Screen.Session(imported)
|
||||
},
|
||||
onSettings = { screen = Screen.Settings },
|
||||
)
|
||||
is Screen.Session ->
|
||||
SessionScreen(
|
||||
settings = current,
|
||||
summary = here.summary,
|
||||
onBack = goToList,
|
||||
onUsage = { screen = Screen.Usage(here.summary) },
|
||||
onBack = goToMain,
|
||||
onSettings = { screen = Screen.SessionSettings(here.summary) },
|
||||
)
|
||||
is Screen.Spawn ->
|
||||
@@ -132,23 +122,7 @@ fun AppRoot(settingsVersion: Int) {
|
||||
reloadToken++
|
||||
screen = Screen.Session(spawned)
|
||||
},
|
||||
onBack = goToList,
|
||||
)
|
||||
is Screen.Import ->
|
||||
ImportScreen(
|
||||
settings = current,
|
||||
onImported = { imported ->
|
||||
reloadToken++
|
||||
screen = Screen.Session(imported)
|
||||
},
|
||||
onBack = goToList,
|
||||
)
|
||||
is Screen.Usage ->
|
||||
UsageScreen(
|
||||
settings = current,
|
||||
// Back to the session it was opened from, not to the list: this is a step down
|
||||
// from that session, so stepping back is the one thing Back can mean here.
|
||||
onBack = { screen = Screen.Session(here.from) },
|
||||
onBack = goToMain,
|
||||
)
|
||||
is Screen.SessionSettings ->
|
||||
SessionSettingsScreen(
|
||||
@@ -162,16 +136,14 @@ fun AppRoot(settingsVersion: Int) {
|
||||
},
|
||||
onBack = { screen = Screen.Session(here.from) },
|
||||
)
|
||||
is Screen.Models -> ModelsScreen(settings = current, onBack = goToList)
|
||||
is Screen.Setups -> SetupsScreen(settings = current, onBack = goToList)
|
||||
is Screen.Settings ->
|
||||
SettingsScreen(
|
||||
existing = current,
|
||||
onSaved = { saved ->
|
||||
settings = saved
|
||||
goToList()
|
||||
goToMain()
|
||||
},
|
||||
onBack = goToList,
|
||||
onBack = goToMain,
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user