Public Access
Notes: plain text notes on the SD card, with an editor that saves by itself (#19)
The Notes App lists the files of /notes by their first line, newest first: n starts a note, Enter opens it, r renames its file, d deletes it after asking, s sorts by name. A new note's file is named after its first line. The editor wraps at spaces, 38 columns by 8 rows; Fn+arrows move through the wrapped text, Ctrl+A and Ctrl+E go to the ends of the line. There is no save key: the note is written five seconds after the last key, on Back, on leaving the App, when the screen turns off and before the device powers off. A save writes a temporary file and puts it in the note's place; a save cut short is put back, or offered, the next time. A note is up to 16 KB, held in one buffer reserved when it's opened: the file is read straight into it and typing never makes it grow. A failed allocation aborts on this device, and with IRC connected the largest free block is about 31 KB: a first version that copied the note once on loading restarted the device when a full note was opened with IRC connected. Editing files of any size is #47. The Storage App's text viewer gets `e`, which edits a text file up to 16 KB with the same editor unless the file is read-only. 439 host tests. Checked on the device: docs/milestones/F1.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
@@ -51,6 +51,7 @@ void StorageApp::onExit() {
|
||||
ops_.cancel();
|
||||
wait_ = Wait::None;
|
||||
}
|
||||
noteEditor_.close(); // saves
|
||||
viewer_.close();
|
||||
wantList_ = false;
|
||||
loaded_ = false;
|
||||
@@ -105,7 +106,8 @@ void StorageApp::update(uint32_t nowMs) {
|
||||
wantList_ = present;
|
||||
clip_ = Item();
|
||||
if (view_ == View::Viewer) viewer_.close();
|
||||
if (view_ == View::Details || view_ == View::Name || view_ == View::Viewer) view_ = View::Browse;
|
||||
if (view_ == View::Editor) noteEditor_.close();
|
||||
if (view_ == View::Details || view_ == View::Name || view_ == View::Viewer || view_ == View::Editor) view_ = View::Browse;
|
||||
requestRedraw();
|
||||
}
|
||||
if (wantList_ && present && wait_ == Wait::None && !ops_.busy() && ops_.list(want_).empty()) {
|
||||
@@ -114,6 +116,7 @@ void StorageApp::update(uint32_t nowMs) {
|
||||
waitSinceMs_ = nowMs;
|
||||
}
|
||||
if (view_ == View::Viewer && viewer_.update(nowMs)) requestRedraw();
|
||||
if (view_ == View::Editor && noteEditor_.update(nowMs)) requestRedraw();
|
||||
FileOps::Status s;
|
||||
if (wait_ != Wait::None && ops_.finished(s)) {
|
||||
onFinished(s);
|
||||
@@ -280,6 +283,32 @@ bool StorageApp::onKey(const KeyEvent& e) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (view_ == View::Editor) {
|
||||
if (!noteEditor_.onKey(e)) {
|
||||
std::string name = baseName(noteEditor_.path());
|
||||
noteEditor_.close();
|
||||
view_ = View::Browse;
|
||||
open(cwd_, name); // its size and date have changed
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (view_ == View::Viewer && viewer_.showingText() && e.key == Key::Char && (e.ch == 'e' || e.ch == 'E')) {
|
||||
// Edit it (Q146), if the rules and its size allow.
|
||||
std::string path = viewer_.path(), why = ops_.whyReadOnly(path, false);
|
||||
if (why.empty() && viewer_.size() > notes::NoteText::kMaxBytes) why = "Too big to edit: 16 KB at most";
|
||||
if (why.empty()) {
|
||||
viewer_.close();
|
||||
why = noteEditor_.open(path);
|
||||
if (why.empty()) view_ = View::Editor;
|
||||
else {
|
||||
view_ = View::Browse;
|
||||
say(why);
|
||||
}
|
||||
} else {
|
||||
viewer_.say(why);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (view_ == View::Viewer) {
|
||||
if (!viewer_.onKey(e)) {
|
||||
viewer_.close();
|
||||
@@ -453,6 +482,7 @@ void StorageApp::draw(Canvas& c) {
|
||||
return;
|
||||
case View::Maintenance: maintenance_.draw(c); return;
|
||||
case View::Viewer: viewer_.draw(c); return;
|
||||
case View::Editor: noteEditor_.draw(c); return;
|
||||
case View::Details: {
|
||||
std::vector<std::string> lines;
|
||||
auto measure = widgets::bodyMeasure(c);
|
||||
|
||||
Reference in New Issue
Block a user