Offline
Write now, reconcile later.
Offline support is not a cache in front of a web app: the phone holds the library, and the server is the second copy it agrees with when there is a network. Here is exactly how the two catch up.
A memo written in a tunnel
It is an ordinary memo with a small queued dot. Because a memo is one editable document, "pending" is a dirty flag on the row plus a delete tombstone — not an operation log that has to be replayed in a particular order.
Its text, its files, its tags and its place are all on the phone. A memo written at 08:00 keeps 08:00 when it finally reaches the server, not the time the upload succeeded.
What a sync does
- Push, oldest edit first. Files upload, the local markers in the text become real attachment links, then the memo itself goes up. Queued reactions follow the memos they belong to.
- Pull from a cursor. The app asks for everything updated since the last sync, page by page, and writes it into local SQLite.
- Local wins. A memo with queued edits is skipped by the pull and is not touched until its own edit has been pushed. The server never silently overwrites what you just wrote.
A refusal is not a retry loop: if the server rejects a memo, the text stays on the device, the reason is recorded in it, and it waits until you edit it again. A network error leaves the queue untouched.
Files and threads fill in behind the text
Text comes first, so the feed is readable long before every picture is. Then the files are copied into the app's cache, newest memos first, within a per-sync budget of 200 files or 60 MB. Anything over 64 MB is fetched when you open it. Settings shows how much of the library is mirrored, and the next sync continues where the last one stopped.
Comment threads fill in the same way. The memo list already says which memos have one, so only those threads are fetched, newest first, a few per sync.
Turning Everything offline off switches to a lighter mode: thumbnails only, and a file is kept once you open it.
Deletions, once a day
An incremental pull cannot see something that stopped existing, so once a day — and on every manual refresh — the app reads the server's list and drops the local memos it no longer has. Comments live under their parent and the sweep never touches them.
Archived memos are absent from the mirror by design, because the server only lists them when asked. Restore one in the web UI and it comes back on the next sync.
Delete is archive, unless you say otherwise
By default deleting a memo archives it on the server: it disappears from the app and stays recoverable in the Memos web UI. A setting switches the action to a permanent delete.
The choice is captured per memo when you delete it, so changing the setting later never rewrites a delete that was already queued.
One password, one token
Memos access tokens last fifteen minutes and the refresh token arrives in a header no mobile HTTP client will replay for you. So MyMemos signs in once with your password and immediately mints its own personal access token, which does not expire. That token is what the app stores — the password is never written anywhere.
Signing out revokes the token on the server, so nothing of the app lingers in the web UI's access-token list.
Nothing else goes anywhere
The app talks to your instance and, when you open the place picker, to tile.openstreetmap.org for map tiles. No analytics, no crash reporting, no Google-hosted endpoint, no second account.
Cleartext HTTP is allowed app-wide so a LAN instance works; anything reachable from the outside should be https.