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:
@@ -204,6 +204,7 @@ void FileViewer::close() {
|
||||
file_.reset();
|
||||
pager_.reset();
|
||||
confirm_.reset();
|
||||
message_.clear();
|
||||
std::vector<std::string>().swap(shown_);
|
||||
std::vector<std::string>().swap(details_);
|
||||
packets_.setCount(0);
|
||||
@@ -216,6 +217,11 @@ void FileViewer::show(Mode mode) {
|
||||
rowsFrom_ = -1;
|
||||
}
|
||||
|
||||
void FileViewer::say(const std::string& text) {
|
||||
message_ = text;
|
||||
messageMs_ = millis();
|
||||
}
|
||||
|
||||
std::string FileViewer::title() const { return files::fitName(files::baseName(path_), 24); }
|
||||
|
||||
void FileViewer::scroll(int lines) {
|
||||
@@ -314,6 +320,10 @@ bool FileViewer::onKey(const KeyEvent& e) {
|
||||
}
|
||||
|
||||
bool FileViewer::update(uint32_t) {
|
||||
if (!message_.empty() && millis() - messageMs_ >= 4000) {
|
||||
message_.clear();
|
||||
return true;
|
||||
}
|
||||
if (!scan_) return false;
|
||||
if (scan_->done && !scanShown_) {
|
||||
scanShown_ = true;
|
||||
@@ -387,6 +397,7 @@ void FileViewer::draw(Canvas& c) {
|
||||
}
|
||||
right = formatBytes(size_);
|
||||
keys = std::string("Tab: ") + (mode_ != base_ ? "back" : mode_ == Mode::Text ? "hex" : "text") + " t: top b: end";
|
||||
if (mode_ == Mode::Text) keys += " e: edit";
|
||||
break;
|
||||
}
|
||||
case Mode::Gpx: {
|
||||
@@ -452,7 +463,8 @@ void FileViewer::draw(Canvas& c) {
|
||||
c.setTextDatum(top_right);
|
||||
c.drawString(right.c_str(), area.w - 3, area.y + 1);
|
||||
c.setTextDatum(top_left);
|
||||
c.drawString(keys.c_str(), 4, area.y + area.h - 9);
|
||||
if (!message_.empty()) c.setTextColor(theme::kWarning);
|
||||
c.drawString(message_.empty() ? keys.c_str() : message_.c_str(), 4, area.y + area.h - 9);
|
||||
}
|
||||
|
||||
} // namespace roro
|
||||
|
||||
Reference in New Issue
Block a user