Releases: Nihmar/Niman
Releases · Nihmar/Niman
Release list
Say what the note carries.
Performance
- perf(editor): a caret move lays out the rows it touched, not the table (#494)
- perf(editor): live tables keep a row's measurements across revisions (#494)
- perf(markdown): a note's bytes are decoded once, not judged and decoded again
- perf(update): the installer is hashed off the UI isolate (#495)
- perf(spellcheck): the dictionary loads off the frame, so opening a note does not pay for it (#453)
- perf(markdown): a plain line's scan state is shared, and the fixture is built by the block (#346)
- perf(frames): a frame that misses outside the two panes is named for the shell (#324)
- perf(editor): the keystroke path rebuilds the tab row once, reads the settings at once, looks its parse cache up by shape, and times no frame unless asked (#362)
Features
- feat(frontmatter): the panel is the note's head, closed until it is opened (#157)
- feat(links): a panel lists the notes and headings while a wikilink is typed (#475)
- feat(templates): a template's mistakes are marked, and the fix is one tap (#71)
- feat(links): a ctrl+click on a dead wikilink creates and opens its note (#477)
- feat(templates): a template's placeholder syntax is checked, and a typo is named (#71)
- feat(frontmatter): show the note's fields in the live editor too, above the note (#157)
- feat(frontmatter): show a note's fields in the read pane, raw YAML a toggle away (#157)
- feat(settings): the source editor's face is a setting, monospace by default (#259)
- feat(sync): a self-signed destination is trusted once, by fingerprint (#454)
- feat(i18n): the strings the UI still wrote in English live in the locales (#381)
- feat(checklist): a tick carries down the branch (#326)
- feat(i18n): the welcome deck and the guided tour speak every locale (#308)
Fixes
- fix(ci): the release reads the keystore secret the repository has (#393)
- fix(index): a moved note reads its relative links from where it is now
- fix(index): a Markdown href is indexed as it is opened
- fix(i18n): the replace summary counts notes by the language's plural rule
- fix(ui): a failed index rebuild says so in the language
- fix(i18n): the problem count takes the word count's plural rule in lv, mk, sl
- fix(i18n): the new keys use each file's own words
- fix(i18n): the certificate dialog says one certificate, in every language
- fix(frontmatter): an edit keeps the comment that is the entry's own
- fix(templates): a note that fails to be created gives its counter back
- fix(reminders): a slow desktop show is not posted a second time
- fix(reminders): a desktop reminder is shown once per task and moment
- fix(links): keys typed while a note is read share that read
- fix(links): a name the panel cannot write takes no slot of it
- fix(links): a path is read from the note it is written in
- fix(links): a backslash in a link separates its folders
- fix(editor): the link panel does not open on a line whose tokens are unread (#494)
- fix(editor): the link panel closes when the text is replaced under it (#494)
- fix(editor): live tables measure again once the note's tokens have landed (#494)
- fix(markdown): an edit that ends a footnote body keeps what its lines still hold
- fix(sync): a body copy ends on every way out of a download
- fix(ui): a widget target that a failed save blocks says so
- fix(library): the staged file's delete after the guarded rename has a timeout
- fix(import): an entry with no content is skipped, not written as an empty file
- fix(import): a Notion entry is inflated in chunks that stop at the budget
- fix(ui): the sidebar tooltip names the key bound to the sidebar now
- fix(i18n): the history-off notice sends the user to the real section
- fix(i18n): the keys nothing reads leave the contract and every locale
- fix(i18n): the problem count follows each language's own plural
- fix(i18n): the wikilink panel and the checker speak the app's language
- fix(i18n): the keys added since v0.1.3 are translated
- fix(editor): live tables measure a revision once, not every word (#494)
- fix(editor): the typewriter row light follows a wrapped row's piece (#494)
- fix(editor): no link panel inside fenced code, inline code or maths
- fix(editor): the link panel closes with the text it was opened on
- fix(links): a book form completed is not offered again over its number
- fix(editor): a wrapped row's handles, panel and hints use the caret's piece
- fix(frontmatter): an edit keeps the entry's indent, anchor and comment
- fix(templates): a closing braces pair with nothing open is text
- fix(templates): a counter is reserved once the name is known
- fix(reminders): a reminder that failed to show is retried
- fix(reminders): a desktop reminder is once per moment, not per id
- fix(update): a cut-off download keeps no installer name, and a silent body fails (#495)
- fix(sync): a stopped merge cannot leave its fetched temp behind
- fix(sync): a stalled body cannot throw out of the run
- fix(links): the
%q%query runs only when the prefix rows leave room - fix(links): a target's headings are read once, off the UI isolate
- fix(links): the panel offers only targets the parser reads back
- fix(links): a reserved device stem finds the note it made
- fix(links): a relative link resolves against the library root
- fix(library): a rebuild in flight is not started a second time
- fix(library): every way out of a library saves the open notes first
- fix(spellcheck): the settings rows outlive a dictionary reload
- fix(files): a case-only rename walks the folder off the UI isolate
- fix(import): a Notion entry is bounded by the bytes it really expands to
- fix(library): the staged rename in a copy gets the guarded rename's grace
- fix(reading): a position is dropped only when the library saw the book leave
- fix(library): a failed open closes the index connection
- fix(markdown): the binary test decodes natively before it walks
- fix(markdown): only a footnote's body holds an indented line
- fix(search): Replace all leaves a binary note as it is
- fix(ui): a title bar that goes away withdraws its caption buttons
- fix(spellcheck): a spelling pass is always the current engine's
- fix(watcher): a restarted watch has the library walked at once
- fix(workspace): a tab's missing mark stays until its note is back
- fix(files): a free name is one no entry of any kind holds
- fix(files): a rename in a case-sensitive folder never takes another note
- fix(files): a sanitized name never ends with a dot or a space
- fix(markdown): a setext heading is the paragraph its underline closes
- fix(markdown): a quoted item on any line carries its own nested items
- fix(markdown): a task box behind quote marks is found on its raw line
- fix(editor): in source, a wide table's caret is drawn on its paragraph
- fix(editor): a caret in a wrapped row's room is drawn at its cell's edge
- fix(editor): live splits a table row into the table model's cells
- fix(editor): a wrapped table cell breaks between its words, marks or not
- fix(links): the panel completes only with rows that answer the link
- fix(links): a completion replaces the whole target of a closed link
- fix(links): only typing opens the wikilink panel
- fix(reminders): a desktop reminder is shown once for its moment
- fix(templates): the checker reports what the engine leaves standing
- fix(templates): the checker reads a brace pair only inside its window
- fix(sync): a redirect target's refused certificate names its own host
- fix(sync): a forgotten certificate is not trusted from the screen's memory
- fix(sync): the guard before a write judges the doubt by the listing now
- fix(sync): a local state file that does not parse is not uploaded
- fix(markdown): a byte that is not UTF-8 is read as the character it is
- fix(frontmatter): a list edit keeps the items it did not touch
- fix(frontmatter): an entry's lines are where YAML says they are
- fix(frontmatter): a value is quoted whenever YAML would read it otherwise
- fix(templates): counters are reserved under the creation's guard
- fix(templates): a counter file that cannot be read is not an empty one
- fix(library): an empty index opens on its tree, resumed or not
- fix(links): the suggester qualifies a name other notes share
- fix(sync): the body timeout bounds a silence, not the transfer
- fix(sync): a weak ETag is planned as no guard
- fix(packaging): the Linux tarball ships the niman command the docs name (#233)
- fix(editor): a .txt is opened on its own, and a note stays a .md (#233)
- fix(read): one press brings the preview up on a huge note (#432)
- fix(drop): a dropped file opens and a dropped folder is imported (#224)
- fix(windows): the runner answers the caption hit test, so hovering maximise opens Snap Layouts (#169)
- fix(markdown): the read view draws
[-]as text, not a checkbox (#233) - fix(library): a damaged index is rebuilt in place, not forgotten (#368)
- fix(ci): the sync e2e fakes the first-run deck so a fresh runner cannot hide the shell (#363)
- fix(markdown): the four parity gaps between live, the read view and the export (#361)
- fix(scripts): an unknown apk flavor is refused with the usage instead of a bogus path (#393)
- fix(sync): a manual sync joining a run counts one failure (#391)
- fix(sync): an untrusted certificate is its own WebDAV failure, naming the host (#366)
- fix(export): the folder export walk does not follow symbolic links (#390)
- fix(editor): a Markdown reference link opens from the source editor (#417)
- fix(workspace): a note deleted outside the app keeps its tab, flagged (#372)
- fix(editor): no formatting key and app command answer the same chord (#370)
- fix(ci): the format gate, hunspell and the WebDAV flow run on every pull request (#363)
- fix(templates): a counter hands out distinct numbers and +1d is a calendar day (#359)
- fix(library): a watcher resubscribes when its stream ends, and a burst past the caps ships in bounded batches (#389)
- fix(tree): the sort direction is part of the row cache key (#371)
- fix(sync): the...
Say what a frame costs.
Performance
- perf(frames): the read pane reports what a frame costs it (#316)
- perf(session): the index connection is asked for before the rest of the open (#315)
- perf(frames): the index opens with the library, and a frame names its parts (#315, #316)
- perf(editor): a keystroke's frame reports its parts (#316)
- perf(startup): the first frame's known costs, split in the log (#315)
Fixes
- fix(files): a write no longer needs the directory the app was started from (#319)
- fix(todo): a token suggestion lands in the description when it is clicked (#311)
- fix(db): one app database connection, and one migrator per file (#312)
Other
- chore(release): 0.1.3
- docs(agents): no co-author trailers in commits
Full Changelog: v0.1.2...v0.1.3
Let's go to the mall!
Features
- feat(note): the ⋮ turns a list into a shopping list, and back (#309)
- feat(list): the shopping-list subtype, with a quantity per item (#309)
- feat(list): the add row scrolls the list to the new item (#309)
- feat(list): an item is deleted from the row, and Undo puts it back (#309)
Other
- chore(release): 0.1.2
- docs(list): the list notes guide, and the pages that pointed elsewhere (#309)
- docs(design): the list notes mockups (#309)
Full Changelog: v0.1.1...v0.1.2
Show me around.
Features
- feat(welcome): the guided tour, pointing at the real controls (#266)
- feat(welcome): the deck itself, and the gate that shows it once (#266)
- feat(welcome): the first-run state, and the editors the answer seeds (#266)
Fixes
- fix(db): the v31 upgrade is a row value, not a column default
- fix(welcome): the read-only deck closes, and the gate says what failed
- fix(tour): the offer is spent when shown, and a finished tour starts over
- fix(tour): the card fits a phone, and the wide note pane is a target
Other
- chore(release): 0.1.1
- test(welcome): the headless boot gates on the first run (#266)
- docs(welcome): the first run, as built (#266)
- docs(welcome): the plan, agreed — deck before the picker, the cheatsheet as playground, sync and tasks as pages
Full Changelog: v0.1.0...v0.1.1
Notes in, notes out.
Features
- feat(import): a Notion export becomes a browsable, linked folder (#25)
- feat(share): what another Android app shares lands in Niman (#40)
- feat(index): a full scan reconciles one directory at a time (#302)
- feat(index): a library walk that yields a directory at a time (#302)
- feat(export): a note's PDF asks before the pages are drawn (#63)
- feat(export): stop an EPUB export, and log what its math did (#303)
- feat(export): a book without metadata asks before it starts (#303, E3)
- feat(export): a folder's book is anchored to index.md, dated by published (#303)
- feat(export): a book's cover and metadata come from the frontmatter (#303)
- feat(export): a note, a folder, the library as EPUB (#303)
- feat(export): a note's PDF says it is running, and can be stopped (#63)
- feat(export): a note's PDF from the Android WebView (#63)
- feat(export): a folder of PDFs, printed by the browser (#63)
- feat(export): a note as a PDF (#63)
- feat(export): find and run the desktop PDF engine (#63)
- feat(export): the outcome offers Show in folder on a desktop
- feat(export): a folder or the library as one zip (#24)
- feat(export): a note saved as Markdown or an HTML page (#24)
- feat(export): a note's pictures, gathered for its page (#24)
- feat(export): a note as one self-contained HTML page (#24)
- feat(export): formulas as inline SVG for an exported page (#24)
- feat(dock): drag the right dock's edge to resize it (#297)
- feat(settings): choose which #72 rules a tidy applies
- feat(tree): desktop rows and row menu drawn for a pointer (#296)
- feat(markdown): the tidy applies the #72 rules
Fixes
- fix(ci): the release takes the official APK by name, not by a shell variable
- fix(update): a release carries the official APK and nothing else (#81)
- fix(export): a Chromium is an engine under any of its names (#63)
- fix(export): a rastered page breaks between lines, not through one (#63)
- fix(editor): a live table's row never wraps off its columns (#303)
- fix(editor): Ctrl+F and Ctrl+H work in the single-file editor (#77)
- fix(epub): the reader gets a chapter's math back (#303, #280)
- fix(export): a note's EPUB says it is working while it builds (#303)
- fix(export): the free-name probe is awaited, off the UI isolate (#24)
- fix(export): the raster fallback guards its view and its empty page (#63)
- fix(export): the engine's output is bounded, and its lookup timed (#63)
- fix(export): one page per note, and a book that counts chapters (#303)
- fix(export): one picture table, and SVG declared where drawn (#303)
- fix(export): a broken byte in one note no longer fails the folder (#24)
- fix(export): the EPUB package names its chapters as IRIs (#303)
- fix(export): a note link with no page to point at is text (#24, #303)
- fix(export): a failed engine's fallback keeps progress and cancel (#63)
- fix(export): a book without index.md says so in the log (#303)
- fix(export): a folder with no notes is refused, not an empty book (#303)
- fix(export): a chapter with an embed or an open callout is XHTML (#303)
- fix(export): the raster PDF's xref names the object at its offset (#63)
- fix(export): Android's WebView can print (#63)
- fix(export): the print page carries picture URLs, not base64 (#63)
- fix(export): a picture that will not decode is not the export's failure (#63)
- fix(export): the raster fallback draws pictures, one page at a time (#63)
- fix(export): cancellation and timeouts the review found (#24, #63)
- fix(export): the note export review points (#24, #63)
- fix(export): a PDF keeps its pictures, on an A4 sheet (#63)
- fix(export): the PDF review points (#63)
- fix(export): print the page on A4 with 18 mm margins (#63)
- fix(markdown): five columns after a list marker are code (#72)
- fix(markdown): a link in a list item is not a task box (#72)
- fix(markdown): a fence's language keeps its own punctuation (#72)
- fix(live): the touch handles and menu wait for their line's layout
- fix(live): an inline formula with spaces in its source reveals
- fix(shell): a re-index closes the tabs of the notes it pruned
- fix(live): a revealed mark starts on the note's margin, not left of the text
- fix(ci): the testing APK was never published
Other
- chore(release): 0.1.0 re-cut
- chore(release): 0.1.0
- docs: catch the guides up with what 0.0.10 shipped
- chore(release): 0.0.10
- test(import): wait on the import's result, not on a timer (#25)
- docs(import): the Notion export, and the vault you open instead (#25)
- docs(share): where a share lands, on the platform page and the quick note (#40)
- refactor(index): the pending-link queue needs no index of its own
- docs(index): the scan a directory at a time, its numbers and its decisions (#302)
- chore(editor): log a live table's measured columns
- docs(export): the plan matches the code, and the pages say what is (#24, #63, #303)
- refactor(export): split the tree export and the book's package (S2)
- style(tests): quote the two test names the linter flagged
- docs(export): the PDF as it is now (#63, #24)
- build(android): pin the PDF writer's package against R8 (#63)
- docs(agents): the integration suite runs once a feature is finished
- docs(export): the PDF as it prints and draws (#63)
- docs(export): the user guide, and 1.3 ticked off (#24)
- docs(export): tick off the sources and the single note (#24)
- docs(export): the plan for #24 and #63
- refactor(links): one rule for what a wikilink shows (#24)
- refactor(markdown): share the inline syntaxes beyond GFM (#24)
- docs(markdown): the tidy's header says which rules are switches (#72)
- docs(markdown): where a missing closing fence goes, and why (#72)
Full Changelog: v0.0.9...v0.1.0
A homegrown editor, and a lot more to play with.
Performance
- perf(index): a long note's save hands the index its tags and links
- perf(index): a save's reindex takes the digest the write made
- perf(surface): a huge note's height map asks a line only when a frame reaches it
- perf(outline): the dock builds the headings on screen, not all of them
- perf(load): a note is shown before its words are counted
- perf(markdown): a note's lines are views of the text it was read from
- perf(markdown): prefix sums keep their values unboxed
- perf(load): a note is read, split and counted in one isolate, and handed over
- perf(scanner): the block list is shared chunk by chunk, and moved a chunk at a time
- perf(read): the read pane keeps its heights across a hand-over
- perf(buffer): a snapshot shares the note's lines, chunk by chunk
- perf(read): the read pane takes the blocks the editor already has
- perf(save): a large note is read back into the index once it is left alone
- perf(index): a note's tags and links are read by the unified engine, where they can be
- perf(scanner): an edit that changes the rest of the note pays a budget, and the rest is carried on
- perf(scanner): an edit is rescanned from where it is to where the note agrees again
- perf(live): the reveal frame is flat in the note, and under 3 ms
- perf(scanner): the rebuild starts inside the block, and checks its work
- perf(read): the read pane stops rescanning a note's definitions
- perf(note): a reload, a list check and a kind edit stop reading the note
- perf(stats): the word count follows the edits and the outline the blocks
- perf(save): a huge note is handed over in slices, not joined
- perf(editor): a format command is run over the lines it touches
- perf(save): a huge note waits for a real pause before it is saved
- perf(markdown): a keystroke no longer moves the note's whole block list
- perf(read): a long note's first look is scanned in an isolate
- perf(markdown): the document's definitions are scanned line by line
- perf(editor): the tokenizer carries the block state, and tokenizes only the lines drawn
- perf(stats): the word count scans instead of matching, and a huge note waits for a pause
- perf(markdown): a long code block is drawn in pieces in the read view
- perf(markdown): the preview reads the editor's lines instead of its text
- perf(index): the index writes off the UI isolate, and one reindex per note at a time
- perf(history): decide a snapshot from the manifest before reading the note
- perf(markdown): an Enter no longer rebuilds the note's prefix sums
- perf(editor): the legacy highlighter reads the note segment by segment
- perf(ui): a note opens without filling the legacy editor it does not show
- perf(markdown): the platform holds a window of the note, not the note
- perf(markdown): a keystroke no longer costs the note
- perf(test): a shared machine holds the backstop, not the ceiling
- perf(markdown): the block scan's flush is O(change) now, not O(blocks)
Features
- feat(todo): a reminder warns where it is set (#95)
- feat(ui): a title too long for its room scrolls itself (#287)
- feat(ui): draw the changelog's bullets as the Markdown they are
- feat(editor): colour a template's commands in the source
- feat(library): forget the library that is open, from a menu you can see
- feat(epub): select part of a paragraph, and annotate just that (#283)
- feat(ui): a PDF or a book marks where it was annotated (#285)
- feat(annotations): where a file was annotated, read from its companions (#285)
- feat(ui): annotate a PDF or a book without leaving it (#284)
- feat(annotations): a file's companion notes, found and written (#284)
- feat(settings): an annotations folder for the notes annotating a file (#284)
- feat(ui): the row of a PDF or a book copies a link to its place (#282)
- feat(ui): a link into a PDF or a book opens it at its place (#282)
- feat(links): a Markdown link reaches any file, its path percent-decoded (#282)
- feat(ui): a book or a PDF opens where it was left (#281)
- feat(reading): a library keeps where each book and PDF was left (#281)
- feat(epub): books have a theme, font and text size of their own (#280)
- feat(ui): an attachment on screen offers none of the editor's controls (#280)
- feat(ui): EPUBs open in the note pane (#280)
- feat(ui): pictures and PDFs open in the note pane
- feat(editor): todo.txt and done.txt are coloured as task lists
- feat(editor): a note edited and closed has its Markdown tidied
- feat(search): the index keeps the words of a note, not its text
- feat(editor): the desktop menu's submenus open beside it, on hover
- feat(markdown): callouts are read in every mode (#279)
- feat(markdown): ==highlight== is read in every mode (#279)
- feat(live): the keyboard alone leaves a table
- feat(settings): a new theme opens in the editor
- feat(editor): brackets are typed in pairs
- feat(settings): move a theme in and out of the app as a file
- feat(settings): edit a theme's colors, in place, on the app itself
- feat(settings): make, copy, rename and delete themes of one's own
- feat(settings): the app's look has a Themes page of its own
- feat(theme): a theme is a value the app wears, not just a palette
- feat(editor): the context menu grouped by what the writer is doing (#260)
- feat(live): Tab goes from cell to cell in a table (#261)
- feat(ui): a Markdown cheatsheet, written beside shown (#265)
- feat(live): a table is edited as a table: its menu and its + handles (#261)
- feat(editor): insert a table from the toolbar and the context menu (#262)
- feat(editor): a checkbox list button, beside the other lists (#263)
- feat(markdown): source, live and the read view keep the line at the top
- feat(read): the read view is moved with the keyboard
- feat(live): a table stays a grid while it is written in, as Obsidian's
- feat(live): a table is drawn as the read view's grid, over its own source
- feat(live): definitions take no room, and the note ends with its footnotes
- feat(live): an HTML block is drawn in a code block's box, as in the read view
- feat(live): a quote's content is drawn as the blocks it is, as in the read view
- feat(live): code is coloured by its fence's language, as in the read view
- feat(live): a code block is a box, as in the read view
- feat(journal): the calendar lists the tasks due on the day (#7)
- feat(journal): today's entry from the app icon, the tray and the command line (#7)
- feat(journal): the calendar, in the side panel and on its own screen (#7)
- feat(journal): Settings → Library → Journal (#7)
- feat(journal): the strip over an entry (#7)
- feat(journal): today's entry, opened or made, and the entries around it (#7)
- feat(journal): the journal's settings, and a day's entry path (#7)
- feat(read): the read view's checkbox ticks the note
- feat(live): the checkbox ticks where it is drawn
- feat(live): a format inside another is drawn as both
- feat(todo): on a desktop, due date and reminder are picked in the dialog (#268)
- feat(todo): the task description wraps and grows downward (#267)
- feat(settings): Commands says it is the palette's reference, and leads to the keys (#264)
- feat(sync): the personal dictionary travels, merged word by word
- feat(sync): library settings merge key by key; counters keep the highest
- feat(settings): how a library looks stays on each device
- feat(todo): swipe a task to the left to delete it, after confirming
- feat(sync): a note with no common version merges difference by difference
- feat(markdown): the editor's reading of a note can be handed over whole
- feat(sync): todo.txt and done.txt merge task by task, never asking
- feat(todo): a task is deleted from its edit dialog, or a right-click
- feat(live): inline formulas are typeset in the room their source takes
- feat(live): display formulas are typeset and pictures drawn while the caret is elsewhere
- feat(live): bullets, numbers, checkboxes, quote bars and rules are drawn where their markers were
- feat(markdown): , and are read as the formats they are
- feat(markdown): the surface publishes the formats on at the caret
- feat(wysiwyg): live draws the WYSIWYG pane behind the unified flag
- feat(live): the reveal follows the word the caret is in
- feat(live): the caret's line shows its markers, and nothing else does
- feat(source): the source view is coloured by the read view's engine
- feat(markdown): source mode's colours from the read view's engine
- feat(markdown): a run knows its markers from its text
- feat(spellcheck): Windows spellchecks with the system's own checker
- feat(tree): a right click on the tree's empty space creates at the root
- feat(editor): Tab goes from the find field to the replace field and back
- feat(editor): the page keys walk a find bar's results, as the legacy bar's did
- feat(markdown): the source surface to a screen reader
- feat(markdown): heading sections fold on the source surface
- feat(markdown): typewriter mode and the Zen caret on the source surface
- feat(markdown): Ctrl+click opens a link on the source surface
- feat(markdown): find and replace on the source surface
- feat(markdown): the source surface underlines misspelled words
- feat(markdown): the source surface's context menu
- feat(desktop): the Windows tray menu wears the app's theme
- feat(markdown): select by touch — a long press, two handles, and the toolbar
- feat(markdown): lists carry on, Tab indents, and the page keys page
- feat(ui): the source pane is the unified surface behind the flag
- feat(markdown): a hidden bullet leaves an indent behind
- feat(markdown): MarkdownSurface, where source and live are one widget
- feat(markdown): a hidden marker takes no room, and a heading is a heading
- feat(markdown): the markers go invisible, and nothing moves
- feat(markdown): onChanged, which is what the shell needs and all it needs
- feat(markdown): a tap, two taps, three taps
- feat(markdown): the clipboard, and why the connection has no paste hook
- feat(markdown): the motions that need the layout, ...
v0.0.8
Features
- feat(phone): no keys named where there is no keyboard to press them
- feat(palette): the palette answers with settings too
- feat(editor): Tidy the Markdown
- feat(desktop): close to tray, and a tray menu worth having
- feat(ui): tabs are dragged — reorder, move between panes, drop to split
- feat(editor): remappable formatting shortcuts in both editors
- feat(palette): the phone's palette apart from the library search
- feat(palette): pinned commands
- feat(settings): a Commands page, listing what the palette can run and when
- feat(ui): the library switcher as a floating window, with Close library
- feat(ui): Settings as a floating window on a wide window
- feat(editor): typewriter mode from the note's ⋮ menu
- feat(ui): the preview in Zen mode, with its eye in the bar
- feat(editor): typewriter mode lights the row being written
- feat(ui): list notes, voice notes and the Todo list keep to the column
- feat(workspace): a middle click or a double click opens a note beside
- feat(editor): icons on the context menu's clipboard rows too
- feat(ui): drop Markdown files and folders on the window
- feat(packaging): Markdown files open in Niman
- feat(ui): open the file a launch asks for
- feat(core): one Niman per desktop session
- feat(editor): open a Markdown file outside any library
- feat(editor): typewriter mode — the line being written stays in the middle
- feat(settings): a typewriter mode setting for the library
- feat(ui): Zen mode on the desktop
- feat(settings): change, clear and restore the keyboard shortcuts
- feat(settings): a key map of the user's own, kept on this device
- feat(ui): the command palette — commands and notes in one search
- feat(library): find notes by name
- feat(ui): the right dock, with the note's outline, tags and history
- feat(workspace): the dock's state, and a handle on the note beside it
- feat(workspace): where the note on screen is left is kept as it moves
- feat(workspace): the phone's open-notes switcher
- feat(workspace): the window splits into two panes, each with its tabs
- feat(workspace): focus a pane, split with a tab, open beside
- feat(workspace): tabs on the desktop, one pane
- feat(ui): a tab row for the open notes, and a place for it in the title bar
- feat(editor): a note view hands in where it was left, and lands there
- feat(workspace): the shell keeps the workspace current
- feat(workspace): the open notes' model, kept per device
- feat(editor): the formatting actions on right-click, in both editors
- feat(editor): one row above the note, with the note menu at its end
- feat(settings): two columns on a wide window
- feat(editor): the note is a centred column, on by default
- feat(desktop): the rail is 48 px and icons only, with its way out at the foot
Fixes
- fix(ci): run the headless integration tests under xvfb-run
- fix(integration): the three E2E tests pass and run on every PR
- fix(widget): the "+" dialog reads on a dark theme
- fix(tray): the menu appears on Linux
- fix(desktop): a drop that brings nothing says so, and leaves a trace
- fix(palette): the pointer selects, and a chosen key beats the formatting
- fix(desktop): a second launch reaches the running Niman again
- fix(wysiwyg): a section break reads as a line, not a box of hyphens
- fix(wysiwyg): a note whose list items wrap opens as a note again
- fix(widget): the beta channel finds its placed widgets again
- fix(widget): tapping a todo on the widget completes it again
- fix(ui): the Todo column leaves the filter bar its line
- fix(settings): the search finds a command's keys by the command's name
- fix(editor): the phone's selection menu goes when you tap elsewhere
- fix(ui): tabs and the status row hold up in a narrow pane
- fix(settings): a remapped key runs once, and the editors do not hear it
- fix(editor): Ctrl+Z on a note just opened no longer empties it
- fix(windows): carry the Visual C++ runtime with the bundle
- fix(todo): the overdue reminder line reads true on a desktop
- fix(spellcheck): the panel opens at once on any note
- fix(update): stopping the scheduler cancels its first check
- fix(sync): a full sync waits out a backoff and names a stuck file
- fix(sync): a 207 that says "not there" is not a file
- fix(editor): let Esc out of the WYSIWYG editor
- fix(shell): take the focus back when it falls to nothing
- fix(workspace): the tabs head the panes where there is no title bar of ours
- fix(editor): the buffer is never saved over a file that did not load
- fix(editor): a file that is not text says so instead of opening as one
Other
- chore(release): 0.0.8
- docs: the palette answers with settings too
- test(format): a #tag is never turned into a heading
- refactor(ui): the library folder picker and name dialog on their own
- refactor(ui): a slim title bar for a window showing one thing
- test(workspace): #23's acceptance criteria, and the tab keys in the editors
- refactor(settings): every row stacks label, description and control
Full Changelog: v0.0.7...v0.0.8
v0.0.7
Features
- feat(windows): the app draws its own title bar
- feat(editor): Enter carries a list on in the source editor
- feat(editor): one Tools button, and the list count behind it
- feat(editor): count a list in the WYSIWYG document
- feat(editor): find the list to count and place the block under it
- feat(editor): count the values of a list into checklist rows
- feat(ui): settings search with area breadcrumbs (issue #104)
- feat(ui): a note opens as a page, not a tab
- feat(settings): the row that turns the automatic trash empty on (#79)
- feat(trash): empty the trash of what has waited too long, if asked (#79)
- feat(core): count the isolate jobs in flight, and warn on a stuck one
- feat(tree): open a note in the file manager or its default app
- feat(update): disable update management in testing builds (issue #106)
- feat(android): beta flavor (testing build) with a separate application ID (issue #106)
Fixes
- fix(wysiwyg): the clipboard carries Markdown, not stripped text
- fix(wysiwyg): the context menu opens at the right-click
- fix(editor): the right-click menu's items reach the editor again
- fix(editor): Ctrl+Arrow and Ctrl+Shift+Arrow move and select by word
- fix(wysiwyg): Ctrl+V no longer crashes the app on Windows
- fix(wysiwyg): a nested list keeps its nesting
- fix(ui): the status row keeps its height without the editor switch
- fix(preview): a loose task list keeps its boxes
- fix(wysiwyg): an ordered list keeps its numbers
- fix(ui): no editor switch when there is no editor on screen
- fix(wysiwyg): a loose list keeps its checkboxes and its blank lines
- fix(ui): the editor switch reads as a control, and stops moving the count
- fix(build): restore the official APK after the channel flavors
- fix(ui): the FAB's list-note label cannot run past the screen edge
- fix(settings): two search results no longer share one identity
- fix(trash): cut the path the way the library spells it
- fix(ui): the find button keeps the keyboard up (issue #131)
- fix(ui): undo a delete, WebDAV buttons, honest FAB (issue #131)
- fix(build): restore the official APK after the channel flavors
- fix(search): keep the mode row inside a phone width
- fix(i18n): the trash and the row menu say it in the user's language
- fix(i18n): the editor's status row speaks the user's language
- fix(i18n): the FAB's own tooltip speaks the user's language
- fix(ui): the FAB menu names its actions
- fix(ui): the row menu says what it acts on, and groups what it offers
- fix(editor): the find button keeps its slot in preview-only mode
- fix(editor): the preview toggle keeps its place when fullscreen appears
- fix(settings): re-read the library's settings when they change elsewhere
- fix(quick-note): say so when the quick note is set outside the settings
- fix(settings): do not create a folder inside a setting's phantom default (#94)
- fix(linux): leave the process before the EGL driver tears itself down (#108)
- fix(sync): copy an attachment in when the rename will not return
- fix(sync): own the download's sink, and close it before the rename
- fix(sync): land an attachment without an isolate
- fix(sync): turn the sync glyph wherever a run is in flight
- fix(desktop): keep the editor header's actions at the right edge
Other
- release: 0.0.7+4
- docs: the Android release key is real, and the build number matters
- docs: the 0.0.8 desktop mockups live in the repo
- docs: every platform ships every feature, in the same round
- release: 0.0.7
- docs: a loose sublist is the linter's to settle, not the codec's
- docs: point the Enter comments at the change that made them
- docs: record the WYSIWYG alternatives measured against flutter_quill
- docs: how to read a plugin-registrant build failure
- docs: the Tools button and the list count
- i18n: the strings the editor tools sheet and the list count need
- docs: drop the UI mockups, the work they described is in
- refactor(ui): the settings keys live in one place
- refactor(ui): the editor switch names its destination (issue #131)
- refactor(ui): folder subtitles, updates version (issue #104)
- refactor(ui): tasks colored by kind, one pill shape (issue #131)
- refactor(ui): the trash rejoins the family (issue #131)
- refactor(ui): finish the settings areas (issue #104)
- refactor(ui): settings home with sub-screens (issue #104)
- docs: the mockups for the rest of the Android UI pass
- chore(test): tolerate the models screen's teardown on Windows
- refactor(ui): one dialog for "which folder?"
- style(ui): one icon weight per list, filled only for a state
- chore(test): reformat three unit tests
- build(windows): the testing APK builds from a Windows host too
- refactor(note): following a link leaves the note view (#100)
- refactor(shell): the tree's sort chevron joins the tree's own file (#100)
- refactor(shell): what a row-menu choice does leaves the shell too (#100)
- refactor(shell): making a note or a folder becomes a flow (#100)
- refactor(shell): the tree row's context menu leaves the shell (#100)
- refactor(shell): the two layouts move out behind explicit props (#100)
- refactor(shell): the preview's controls and the note's header become widgets (#100)
- refactor(shell): the tab navigation and the Search tab leave the shell (#100)
- refactor(shell): the tree footer becomes a widget of its own (#100)
- refactor(shell): the library's settings become one value, not fourteen fields (#100)
- refactor(shell): the sync surfaces move out into their own actions (#100)
- refactor(shell): the home-screen widgets move out into their own flow (#100)
- docs(trash): the automatic empty, and what it leaves alone (#79)
- docs(settings): where the folder settings put a folder, and when (#94)
- docs(platforms): note how the Linux build exits, and why (#108)
- docs(sync): describe the Windows workaround, and correct what it is not
- docs: document the Android testing build (issue #106)
Full Changelog: v0.0.6...v0.0.7
v0.0.6
Features
- feat(history): restore part of a version, not only the whole of it (#67)
- feat(l10n): the selective restore's labels, in every locale (#67)
- feat(history): write a restored text that is neither side's (#67)
- feat(diff): lay the two texts out in columns when there is room (#67)
- feat(sync): merge conflicted notes region by region (#17, #67)
- feat(sync): merge non-overlapping edits without asking (#17)
- feat(diff): three-way line merge over the agreed version (#17, #67)
- feat(sync): trigger settings and the queue in the UI (#18, #19)
- feat(transcription): follow a clip renamed or deleted while it transcribes
- feat(transcription): write transcripts into notes nobody has open
- feat(transcription): ask what a transcript does to a written description
- feat(spellcheck): per-library personal dictionary (issue #60)
- feat(transcription): Transcribe action on audio note clips
- feat(transcription): app-wide transcription queue
- feat(transcription): convert WAV clips to 16 kHz mono for whisper
- feat(sync): automatic triggers with backoff and pause (#18, #19)
- feat(sync): quick sync of queued paths, hints settled by every run (#18, #19)
- feat(sync): NoteOps reports changed paths for the sync queue (#19)
- feat(sync): WebDAV settings, status and whole-file conflicts (#11, #28)
- feat(transcription): settings section and models page, in every locale
- feat(transcription): model catalog, downloads and settings store
- feat(sync): engine applies the plan against WebDAV and the library (#14, #15, #16)
- feat(sync): pure reconcile over disk, remote and agreed row (#12)
- feat(sync): schema v22 sync state, store and secure password (#12, #19)
- feat(sync): WebDAV client, multistatus parser and capability probe (#10)
- feat: pause a voice recording, and save it without a stutter (issue #56)
- feat: translate the note history strings in every locale (issue #55)
- feat: note history screens, diff view and note menu (issues #55, #67)
- feat: redesign the voice note as voice-message bubbles (issue #56)
- feat: line diff engine for history and sync (issue #67)
- feat: read WAV clip lengths off the UI isolate (issue #56)
- feat: library-wide replace keeps a history version per rewritten note (issue #13)
- feat: read the quote above a voice clip as its title (issue #56)
- feat: .history/ versions with snapshot policy, rotation and pins (issue #13)
- feat: editor saves go through NoteOps.saveNote (issue #13)
Fixes
- fix(android): pin the reminder's app mark against resource shrinking
- fix(sync): follow a server mounted under a reverse proxy prefix
- fix(android): the reminder notification wears the app mark, not an alarm
- fix(android): publish the voice-note launcher shortcut (#91)
- fix(test): close the second database handle in the v20→v21 migration test
- fix(transcription): resume model downloads cut off in the background
- fix(l10n): wrong terms in older translations
- fix: stream a picked image into the library instead of reading it whole
- fix: stream a recorded clip into the library instead of freezing the UI (issue #56)
- fix: history rows count against the current note; empty notes keep no version (issue #55)
- fix: portable audio clip paths and repro test teardown on Windows
- fix: translate the voice note and update strings in every locale
- fix: translate the attachments folder setting in every locale
Other
- ci(android): do not let
yessink the NDK step it feeds - ci(android): fetch the beta NDK whisper.cpp needs before building
- release: 0.0.6
- docs(sync): the diff views as they were built, not as they were planned
- test(sync): end-to-end scenarios over the fake server, and one on a device (#20)
- docs: where a transcript lands, and what happens to a closed note
- refactor(transcription): the progress estimate as its own class
- docs: the Transcribe action, and the spike through the app's conversion
- docs(agents): rebuild after commits on Linux hosts only
- docs: transcription models, downloads and settings
- docs: whisper_ggml spike tool and phase 0 findings
- build: ship the Android APK as 64-bit only
- build: add whisper_ggml for on-device transcription
- docs(sync): settle sync tables, probe, client and queue design
- test: drop redundant default reasons in the history widget test
- refactor: move recording and busy state out of the voice note view
- docs: note history for users, settings reference and architecture (issue #55)
- docs: history reasons replace and unknown, editor-only NoteOps path
- docs: note history and WebDAV sync design (issues #9, #13)
Full Changelog: v0.0.5...v0.0.6
v0.0.5
Features
- feat: install the downloaded APK on Android (issue #81)
Other
- chore: release 0.0.5
Full Changelog: v0.0.4...v0.0.5