Let the top level be chosen as the library root

Confirming "/" in the folder picker set an empty root, which the launch
model read as no root at all: "Open library" stayed disabled after the
question had plainly been answered, and a folder library — whose folder
is the whole library — could never be opened without first descending
into a subfolder of it. The empty string was carrying two meanings.

Record the choice as its own fact on the account (`root_chosen`, defaulted
so existing configuration loads unchanged), treat a folder endpoint as
chosen by definition, and let the launch screen say so: a folder is shown
as a LIBRARY rather than an ACCOUNT, the second question becomes an
optional "scan only a subfolder", and the library header names the folder
instead of calling it "· whole account".
This commit is contained in:
2026-09-20 00:21:13 +02:00
parent e750bcdb8c
commit 0fa9003e54
8 changed files with 218 additions and 85 deletions
+2
View File
@@ -192,6 +192,7 @@ export component AppWindow inherits Window {
in property <bool> launch-signed-in: false;
in property <string> launch-account: "";
in property <string> launch-root: "";
in property <bool> launch-endpoint-is-library: false;
in property <string> launch-server: "";
in property <string> launch-folder: "";
in property <bool> launch-busy: false;
@@ -1546,6 +1547,7 @@ in property <bool> panel-visible: true;
signed-in: root.launch-signed-in;
account: root.launch-account;
library-root: root.launch-root;
endpoint-is-library: root.launch-endpoint-is-library;
server-url: root.launch-server;
folder-path: root.launch-folder;
busy: root.launch-busy;
+20 -5
View File
@@ -77,6 +77,10 @@ export component LaunchScreen inherits Rectangle {
in property <bool> signed-in: false;
in property <string> account: "";
in property <string> library-root: "";
/// The endpoint is the whole library — a folder — so there is no root
/// to choose inside it, only, optionally, a subfolder to narrow to. A
/// server account's endpoint is the entire tree and a root is required.
in property <bool> endpoint-is-library: false;
in property <string> server-url: "";
// Two endpoints, shown together. Someone deciding between a server and a
// folder should not have to clear one field to try the other.
@@ -349,7 +353,9 @@ export component LaunchScreen inherits Rectangle {
if root.signed-in && root.browsing: VerticalLayout {
spacing: Theme.gap;
PanelHeading { text: @tr("CHOOSE LIBRARY FOLDER"); }
PanelHeading {
text: root.endpoint-is-library ? @tr("SCAN ONLY A SUBFOLDER") : @tr("CHOOSE LIBRARY FOLDER");
}
// Current location, so it is always clear what
// "Use this folder" would select.
@@ -428,22 +434,31 @@ export component LaunchScreen inherits Rectangle {
if root.signed-in && !root.browsing: VerticalLayout {
spacing: Theme.gap;
PanelHeading { text: @tr("ACCOUNT"); }
// A folder *is* the library, and saying "account" of a
// directory, then asking for a "library folder" a second
// time, reads as though the path just typed was not
// taken. A server account genuinely has both: who it is,
// and which subtree of it to catalogue.
PanelHeading { text: root.endpoint-is-library ? @tr("LIBRARY") : @tr("ACCOUNT"); }
Value { text: root.account; }
Rectangle { height: Theme.gap-sm; }
PanelHeading { text: @tr("LIBRARY FOLDER"); }
PanelHeading {
text: root.endpoint-is-library ? @tr("SCAN") : @tr("LIBRARY FOLDER");
}
HorizontalLayout {
spacing: Theme.gap;
Value {
text: root.library-root == "" ? @tr("(not chosen)") : root.library-root;
text: root.library-root == "" ? @tr("(not chosen)")
: root.library-root == "/" && root.endpoint-is-library ? @tr("The whole folder")
: root.library-root;
placeholder: root.library-root == "";
horizontal-stretch: 1;
overflow: elide;
}
FormButton {
text: @tr("Choose…");
text: root.endpoint-is-library ? @tr("Subfolder…") : @tr("Choose…");
width: 110px;
clicked => { root.choose-folder(); }
}