feat: Willkommensnotiz fuer frisch angelegte Workspaces
Ein neu angelegter Workspace bekommt eine Willkommen.md mit einer Kurzanleitung: was ein Workspace ist, dass Unterordner funktionieren, wozu .dionotes da ist und wo der Knopf zum Neu-Einlesen sitzt. Sie wird direkt im Editor geoeffnet, statt den Nutzer vor eine leere Flaeche zu setzen. Nur bei einem leeren Ordner. Wer einen Ordner voller Notizen importiert, will keine fremde Datei dazwischen - er kennt das Programm dann meist schon. Die Pruefung liegt vor dem Anlegen von .dionotes, denn danach ist der Ordner nie mehr leer; genau diesen Fehler hat der Test beim ersten Anlauf gefunden. Damit die Notiz angezeigt werden kann, gibt es jetzt die geoeffnete Notiz als eigenen Context - getrennt vom Workspace, weil sie sich aendert, ohne dass der Workspace wechselt. Der Editor laedt ihren Inhalt beim Wechsel nach, auf einem eigenen Thread. Dadurch schrumpft das TODO im Notiz-Baum auf eine Zeile, die gleich mit erledigt ist: Ein Klick auf eine Datei oeffnet sie und markiert sie in der Leiste. Die dafuer vorhandene CSS-Regel .file-selector.active hat damit wieder einen Nutzer. Ausdruecklich nicht dabei: Speichern, Autosave, der Umgang mit ungesicherten Aenderungen. Der Editor zeigt den Inhalt, Aenderungen landen bisher nirgends - das gehoert zum Notiz-Handling und steht als TODO im Code.
This commit is contained in:
@@ -24,14 +24,35 @@ pub fn Home() -> Element {
|
||||
|
||||
#[component]
|
||||
pub fn Editor() -> Element {
|
||||
let note = use_context::<Signal<Option<PathBuf>>>();
|
||||
let mut source = use_signal(String::new);
|
||||
|
||||
// Beim Wechsel der Notiz den Inhalt nachladen — auf einem eigenen Thread,
|
||||
// damit eine große Datei auf langsamem Laufwerk nicht die Oberfläche hält.
|
||||
use_effect(move || {
|
||||
let path = note.read().clone();
|
||||
spawn(async move {
|
||||
let text = match path {
|
||||
Some(path) => tokio::task::spawn_blocking(move || {
|
||||
std::fs::read_to_string(path).unwrap_or_default()
|
||||
})
|
||||
.await
|
||||
.unwrap_or_default(),
|
||||
None => String::new(),
|
||||
};
|
||||
source.set(text);
|
||||
});
|
||||
});
|
||||
|
||||
rsx! {
|
||||
CodeEditor {
|
||||
class: "editor-class",
|
||||
value: source(),
|
||||
language: Language::Markdown,
|
||||
theme: Theme::CATPPUCCIN_MOCHA,
|
||||
// TODO: Änderungen landen bisher nirgends. Speichern, Autosave und
|
||||
// der Umgang mit ungesicherten Änderungen gehören zum
|
||||
// Notiz-Handling und damit in den nächsten Effort.
|
||||
oninput: move |value| source.set(value),
|
||||
}
|
||||
}
|
||||
@@ -119,9 +140,12 @@ fn TreeLevel(nodes: Vec<TreeNode>, expanded: Signal<HashSet<PathBuf>>, depth: us
|
||||
|
||||
#[component]
|
||||
fn TreeEntry(node: TreeNode, mut expanded: Signal<HashSet<PathBuf>>, depth: usize) -> Element {
|
||||
let mut note = use_context::<Signal<Option<PathBuf>>>();
|
||||
let navigator = use_navigator();
|
||||
let path = node.path().to_path_buf();
|
||||
let name = node.name().to_string();
|
||||
let is_open = expanded.read().contains(&path);
|
||||
let is_current = note.read().as_deref() == Some(path.as_path());
|
||||
|
||||
match node {
|
||||
TreeNode::Folder { children, .. } => {
|
||||
@@ -144,15 +168,20 @@ fn TreeEntry(node: TreeNode, mut expanded: Signal<HashSet<PathBuf>>, depth: usiz
|
||||
}
|
||||
}
|
||||
}
|
||||
TreeNode::File { .. } => rsx! {
|
||||
// TODO: Klick öffnet die Notiz im Editor. Gehört zum Notiz-Handling
|
||||
// und damit in den nächsten Effort, nicht in diese Map.
|
||||
button {
|
||||
class: "file-selector",
|
||||
style: "--depth: {depth}",
|
||||
span { class: "tree-caret" }
|
||||
"{name}"
|
||||
TreeNode::File { .. } => {
|
||||
let opened = path.clone();
|
||||
rsx! {
|
||||
button {
|
||||
class: if is_current { "file-selector active" } else { "file-selector" },
|
||||
style: "--depth: {depth}",
|
||||
onclick: move |_| {
|
||||
note.set(Some(opened.clone()));
|
||||
navigator.push(Route::Editor {});
|
||||
},
|
||||
span { class: "tree-caret" }
|
||||
"{name}"
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user