Return from files to explorer
This commit is contained in:
1 parent
cbdd8493ed
commit
4c15150338
2 files changed
+26
-14
No files matched your search
+5
-5
@@ -214,11 +214,11 @@ be lost. The explorer draws over the session, which deliberately has no
|
|||||||
`FilesScreen` is composed **on top of** the session in the same `Box`, and
|
`FilesScreen` is composed **on top of** the session in the same `Box`, and
|
||||||
the session stays composed under it: its event stream keeps flowing, its
|
the session stays composed under it: its event stream keeps flowing, its
|
||||||
scroll position and draft stay where they were, and returning from a file
|
scroll position and draft stay where they were, and returning from a file
|
||||||
costs nothing. Back — the button and the platform gesture — clears `files`
|
costs nothing. Back — the button and the platform gesture — returns from an
|
||||||
and returns to the session from anywhere in the explorer. Directory navigation
|
open file to its containing directory, then clears `files` and returns to the
|
||||||
stays in the listing: `..` is an explicit row rather than a hidden second
|
session. Directory navigation stays in the listing: `..` is an explicit row
|
||||||
meaning for Back. An editor with unsaved changes asks before closing. "Back
|
rather than a hidden second meaning for Back. An editor with unsaved changes
|
||||||
returns; it does not exit."
|
asks before returning to the directory. "Back returns; it does not exit."
|
||||||
|
|
||||||
Rejected: a `Screen.Files` beside `Screen.Session`. Every route back from a
|
Rejected: a `Screen.Files` beside `Screen.Session`. Every route back from a
|
||||||
leaf screen goes to Main today, and a session disposed and re-created on each
|
leaf screen goes to Main today, and a session disposed and re-created on each
|
||||||
|
|||||||
@@ -54,15 +54,16 @@ data class FilesTarget(val setup: String, val setupName: String, val start: Stri
|
|||||||
private sealed class Spot(val path: String) {
|
private sealed class Spot(val path: String) {
|
||||||
class Dir(path: String) : Spot(path)
|
class Dir(path: String) : Spot(path)
|
||||||
|
|
||||||
class Doc(path: String) : Spot(path)
|
class Doc(path: String, val directory: Dir) : Spot(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The files on the machine a session runs on: browse them, read one, change one.
|
* The files on the machine a session runs on: browse them, read one, change one.
|
||||||
*
|
*
|
||||||
* Drawn **over** the session rather than instead of it (see [AppRoot]), so its event stream keeps
|
* Drawn **over** the session rather than instead of it (see [AppRoot]), so its event stream keeps
|
||||||
* flowing and coming back from a file costs nothing. Back always closes the explorer and returns to
|
* flowing and coming back from a file costs nothing. Back from a file returns to its directory;
|
||||||
* that session; directory navigation stays inside the listing, where its `..` row is explicit.
|
* back from a directory closes the explorer and returns to the session. Directory navigation stays
|
||||||
|
* inside the listing, where its `..` row is explicit.
|
||||||
*
|
*
|
||||||
* Every directory that has been visited is kept for as long as this is open; the refresh glyph is
|
* Every directory that has been visited is kept for as long as this is open; the refresh glyph is
|
||||||
* how one gets asked again on purpose, and creating something refetches the directory it was
|
* how one gets asked again on purpose, and creating something refetches the directory it was
|
||||||
@@ -88,7 +89,11 @@ fun FilesScreen(settings: ServerSettings, target: FilesTarget, onClose: () -> Un
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun back() {
|
fun back() {
|
||||||
if (editing && dirty) askUnsaved = true else onClose()
|
when {
|
||||||
|
editing && dirty -> askUnsaved = true
|
||||||
|
here is Spot.Doc -> go((here as Spot.Doc).directory)
|
||||||
|
else -> onClose()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun load(path: String, again: Boolean) {
|
suspend fun load(path: String, again: Boolean) {
|
||||||
@@ -140,7 +145,7 @@ fun FilesScreen(settings: ServerSettings, target: FilesTarget, onClose: () -> Un
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
LaunchedEffect(spot.path) { load(spot.path, again = false) }
|
LaunchedEffect(spot.path) { load(spot.path, again = false) }
|
||||||
DirectoryBody(state, onOpen = ::go)
|
DirectoryBody(state, directory = spot, onOpen = ::go)
|
||||||
}
|
}
|
||||||
is Spot.Doc ->
|
is Spot.Doc ->
|
||||||
DocPane(
|
DocPane(
|
||||||
@@ -161,7 +166,8 @@ fun FilesScreen(settings: ServerSettings, target: FilesTarget, onClose: () -> Un
|
|||||||
UnsavedDialog(
|
UnsavedDialog(
|
||||||
onDiscard = {
|
onDiscard = {
|
||||||
askUnsaved = false
|
askUnsaved = false
|
||||||
onClose()
|
val spot = here
|
||||||
|
if (spot is Spot.Doc) go(spot.directory) else onClose()
|
||||||
},
|
},
|
||||||
onCancel = { askUnsaved = false },
|
onCancel = { askUnsaved = false },
|
||||||
)
|
)
|
||||||
@@ -183,7 +189,7 @@ fun FilesScreen(settings: ServerSettings, target: FilesTarget, onClose: () -> Un
|
|||||||
load(dir.path, again = true)
|
load(dir.path, again = true)
|
||||||
// A new file has nothing to look at, so it opens where it can be filled in.
|
// A new file has nothing to look at, so it opens where it can be filled in.
|
||||||
if (!isDirectory) {
|
if (!isDirectory) {
|
||||||
go(Spot.Doc(path))
|
go(Spot.Doc(path, dir))
|
||||||
editing = true
|
editing = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +241,11 @@ private fun FilesHeader(
|
|||||||
* looks like a right one.
|
* looks like a right one.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
private fun ColumnScope.DirectoryBody(state: LoadState<Listing>, onOpen: (Spot) -> Unit) {
|
private fun ColumnScope.DirectoryBody(
|
||||||
|
state: LoadState<Listing>,
|
||||||
|
directory: Spot.Dir,
|
||||||
|
onOpen: (Spot) -> Unit,
|
||||||
|
) {
|
||||||
when (state) {
|
when (state) {
|
||||||
is LoadState.Loading -> CircularProgressIndicator(Modifier.padding(16.dp))
|
is LoadState.Loading -> CircularProgressIndicator(Modifier.padding(16.dp))
|
||||||
is LoadState.Error ->
|
is LoadState.Error ->
|
||||||
@@ -276,7 +286,9 @@ private fun ColumnScope.DirectoryBody(state: LoadState<Listing>, onOpen: (Spot)
|
|||||||
name = entry.name,
|
name = entry.name,
|
||||||
trailing = trailingOf(entry),
|
trailing = trailingOf(entry),
|
||||||
onClick = {
|
onClick = {
|
||||||
onOpen(if (entry.isDirectory) Spot.Dir(path) else Spot.Doc(path))
|
onOpen(
|
||||||
|
if (entry.isDirectory) Spot.Dir(path) else Spot.Doc(path, directory)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user