# Dotoist Manual

> Dotoist — Task Manager, Simple. A ridiculously fast, light and powerful task
> manager that lives in your browser and syncs with your own blog.
> No Big Tech account, no third-party cloud.
>
> Live app: <https://dotoist.com/>

## Contents

- [Getting started](#getting-started)
- [Sync and settings](#sync-and-settings)
- [Views](#views)
- [Tasks](#tasks)
- [Notes](#notes)
- [Trash](#trash)
- [Reminders](#reminders)
- [Search, filters and sorting](#search-filters-and-sorting)
- [Keyboard shortcuts](#keyboard-shortcuts)
- [Command palette](#command-palette)
- [Time tracker](#time-tracker)
- [Import and export](#import-and-export)
- [Installing the app](#installing-the-app)
- [Hosting it yourself](#hosting-it-yourself)
- [Data and privacy](#data-and-privacy)
- [FAQ](#faq)

## Getting started

1. Open <https://dotoist.com/> in any modern browser.
2. On your first visit a Welcome dialog introduces the app — press
   **Set up sync** to connect right away, or **Start organizing** to
   explore first (you can re-read this manual any time from the
   sidebar → Manual link).
3. You start with one list, **General**, holding a single **Example Task** with every field filled in — open it, then delete it when ready.
3. Click the menu button (top left) to open the sidebar — or on touch screens,
   drag right starting in the left half (this also works in Board view when
   the columns are scrolled fully left) — then **Create new list** for your own categories.
4. Type in the **Add a task** bar and press Enter. Done — that is 90% of the app.

Everything is saved automatically in your browser as you type.

## Sync and settings

By default your data lives only in this browser. **Sync & Settings** (button
at the bottom of the sidebar, or the status pill in the top bar) syncs it
with your own blog — no third party involved:

1. Open Sync & Settings, enter your email address and press
   **Email me a code**. The blog emails you a one-time 6-digit code
   (valid 15 minutes; first use creates a sync-only account for that
   address — no password, no blog access). The dialog then reveals the
   code field ("Code sent to you@…") — wrong address? Press
   **Different email** to go back and fix it.
2. Enter the code and press **Connect** — this browser links itself and pulls
   your data. Then press **Sync now** in the top bar.
3. From then on: changes upload automatically a few seconds after you make
   them, and the app pulls on launch, when the tab regains focus, and when
   you come back online.

How it works and what to expect:

- The synced copy lives in your blog's database — only matching email-code
  holders can see their own copy. Each connected browser holds its own token;
  Disconnect (or deleting the token on the server) cuts that device off.
- Merging is per item: edits made on one device at a time always merge
  cleanly. Reordering a list, or both devices marking the same task complete,
  never counts as a conflict.
- Deletes sync too. The navbar pill shows `Not synced yet`, `Syncing…`,
  or `Synced Xs ago`.
- If the same task, list, note, trash item, time record, or label was edited
  on two devices between syncs (or edited on one side and deleted on the
  other), the newest version applies immediately — then a dialog shows each
  conflict with a field-by-field diff (due date/time shown as one "Due" row;
  hover any value for the full text) so you can keep your version or take
  the server's. The choice is per whole item, pre-selected to whatever is showing
  now. **Later** dismisses the dialog without changing the applied version
  (it stays queued until you review it or the next sync). Plain settings
  (label renames, your name, Home layout) always take the newest version
  without asking.
- Disconnecting keeps a full copy on that device; connecting again merges it.
- **Pull to refresh**: on touch devices, drag down from the very top of any
  page and release to force a sync.
- Sync tab → **History** shows a log of recent sync events (pushes, pulls, conflicts, errors).
- The dialog is split into tabs: **Sync** (token, name, sync controls),
  **Labels** (rename + custom labels), **Home** (which Home sections
   show), **Options** (show completed, dark mode), and **Data**
   (JSON backups). Your **name** is used in the Home greeting and synced
   across devices. The **Notify** button in the Sync tab subscribes that
   device for push notifications; **Test** next to it sends a test push
   to all your subscribed devices so you can verify delivery.

## Views

| View | What it is for |
| ---- | -------------- |
| **Home** | Greeting, stat cards (open / overdue / due today / completed / tracked today), today's weather, a daily quote (tap refresh for a new one), a Pinned notes section (editable inline), a Notifications section for fired reminders, and sections: Overdue, Today's tasks, Highest priority first, Heavy lifting. The Home sidebar row carries a red badge counting unseen notifications — tapping Home marks them read. Which sections appear is configurable under Sync & Settings → Home. |
| **List** | One category at a time: add bar with quick presets, open tasks, collapsible Completed section. |
| **Board** | Kanban columns — one per list. Drag tasks between columns, add per column, reorder columns by their grip. |
| **Calendar** | Month grid with task chips, a Year overview with busy dots, and a day agenda with its own add box. Drag a task onto a day to reschedule it. |
| **Time** | Stopwatch per task (play / pause / stop). The timer survives reloads. |
| **Notes** | Pinned quick notes: title + text, label colors, pinning, and a flag to show a note on Home. |
| **Trash** | Deleted tasks and notes, restorable or deletable forever. The Trash button is the delete icon next to Sync & Settings at the bottom of the sidebar. |

Switch views from the sidebar, the command palette, or press `g` then `h` / `b` / `c` / `t` / `n` (Notes) / `r` (Trash).

## Tasks

- **Create**: the add bar (or per-column / agenda boxes), the Home **New**
  button, the `n` key, or the command palette (`Ctrl+K`).
- **Complete**: the circle on the row, or select it and press `x`. Completed-by-mistake items can be undone from the toast popup; deleted items go to [Trash](#trash) and can be restored from there.
- **Details**: click a row (or select + `Enter`) for notes, due date + time, repeat rules, label, weight, priority, external reference (URL or ticket number), list assignment and subtasks. Clicking a task selects it (subtle highlight) and opens its details — clicking anywhere else deselects it again. On mobile the panel slides up as a bottom sheet. Everything saves as you type; **Save** closes the panel and forces a sync push, while **Mark complete** toggles completion.
- **Rename inline**: double-click the title.
- **Labels**: tap the label dot on the row. Labels carry your own names, and
  you can add fully custom labels too (Sync & Settings → Labels, e.g.
  red for Home, blue for Work, a new teal for Side projects). Any label can
  be deleted when no task uses it (otherwise the app tells you to change
  those tasks first); built-ins can be restored with Reset. Custom labels
  and names sync, export and import alongside everything else.
  **Weight / Priority**: tap the badges on the row.
- **Move**: drag onto another task, board column, sidebar list or the empty list area — or the move button on the row (desktop), or the List selector in details.
- **Repeat**: daily, weekly (optionally on chosen weekdays), monthly, yearly, or custom "every N days/weeks/months/years". Repeating tasks appear on every matching day in the Calendar (computed forever — daily ones show every day at their time; picking Daily hides the date field and keeps only the time). Completing a dated repeating task schedules the next occurrence and resets its subtasks.
- **Subtasks**: in the details panel, with a `done/total` progress badge on the row.
  The first few subtasks also show under the task title everywhere — tap one to toggle it.
- **Delete**: the trash icon on the row, `Del` on a selected task, or the list
  menu's Delete options. Deleted tasks are not gone — they move to
  [Trash](#trash), with an undo toast right after.

## Notes

Keep-style quick notes for anything that is not a task. Open **Notes** from
the sidebar (`g` then `n`):

- **Create**: title + text at the top, pick a label color, press Add note
  (or the palette's New note command). The text box starts tall (160px) and
  stays resizable.
- **Organize**: tap the pin to keep a note on top (Pinned section). Tap the
  color dot on any note row to recolor it without opening it. Search filters
  notes by title and text.
- **Show on Home**: tap the home icon and the note appears in the Pinned
  notes section on Home — **before** Notifications — where both title and
  text stay editable inline.
- **Edit**: click a note row for the full editor (title, text, color, pin,
  show-on-home, delete).
- Notes sync, export and import alongside everything else.

## Trash

Deleting a task (single, completed-bulk, or a whole list's tasks) or a note
moves it to **Trash** instead of erasing it — open it via the delete icon
next to Sync & Settings at the bottom of the sidebar:

- Each entry shows what it was and when it was deleted, with **Restore**
  (tasks return to their list, or General if that list is gone) and
  **Delete forever**.
- **Empty trash** permanently deletes everything after a confirmation (still
  undoable from the toast right after).
- The trash holds the last 300 deleted items; older ones fall off automatically.

## Reminders

Open Details → Reminder and pick how far in advance: 1 or 5 or 30 minutes,
1 or 3 hours, or 1 day. The reminder counts back from the due date + time
(a dateless time defaults to 9:00 AM); without a due date there is nothing
to count back from.

Connect the app (the same **Connect** as sync) and reminders run in the
background — no extra setup. Each reminder has two legs: a push
notification to every subscribed device (tap **Notify** in Sync &
Settings, then **Test** to verify it arrives — pushes reach the device
even when the app is closed), and an email from the blog (its scheduler
reads the synced state, so reminders arrive even when the app is closed
— as long as the device synced after you set them). Editing the task updates the reminder;
completing or deleting the task, or switching the reminder off, cancels it.
Moving the due date moves the reminder with it, and completing a repeating
task carries the reminder to the next occurrence.

Once a reminder's time passes it also shows up in the **Notifications**
section on Home — the Home sidebar row carries a red unread badge, and
tapping Home marks everything read and clears the app-icon badge.

Timed tasks are timezone-aware: a due time entered in one timezone shows
converted to local time on your other devices (e.g. 5:00 PM entered in
Istanbul shows as 5:30 PM in Tehran) and reminders fire at the same moment
everywhere. Date-only tasks stay on the same calendar day on all devices.
Tasks created before this behavior need one re-save of their date/time on
the device where the time is correct.

## Search, filters and sorting

- **Search** (`/`): matches titles, notes, references and subtasks across every view. Searching from Home jumps straight to Board results. Notes have their own search box on the Notes page.
- **Filters**: label, weight and priority in the sidebar. Active filters show as removable chips on every view.
- **Sorting**: My order (manual drag order), Date, Priority & weight, Title — from the sort button in the top bar.

## Keyboard shortcuts

Shortcuts work when you are not typing in a field. Press `?` anywhere to see this list.

| Keys | Action |
| ---- | ------ |
| `Ctrl+K` (or `Cmd+K`) | Command palette |
| `/` | Focus search |
| `n` | New task |
| `j` / `k` | Select next / previous task |
| `Up` / `Down` | Move selection (once a task is selected) |
| `Enter` | Open selected task |
| `x` | Complete / reopen selected task |
| `Del` | Delete selected task (undoable). On Mac this is the Delete key (sends Backspace). On Windows/Linux only the Delete key deletes — Backspace does not. |
| `g` then `h` | Go to Home |
| `g` then `b` | Go to Board |
| `g` then `c` | Go to Calendar |
| `g` then `t` | Go to Time tracker |
| `g` then `n` | Go to Notes |
| `g` then `r` | Go to Trash |
| `g` then `1`–`9` | Jump to list by position |
| `u` | Show / hide completed tasks |
| `d` | Toggle dark mode |
| `?` | Shortcut help |
| `Esc` | Close panel / dialog |

## Command palette

Press `Ctrl+K` (or `Cmd+K` on Mac) — it works even while typing. Start typing to filter:

- **Commands**: jump to any view (including Notes and Trash), new task / new note / new list, sorting, theme, import / export, this manual.
- **Lists**: jump straight to a list.
- **Tasks**: jump straight to a task's details.

`Up`/`Down` + `Enter` to run, `Esc` to close.

## Time tracker

1. Pick a task from the searchable list (each shows its total tracked time).
   (On desktop, the timer button on a task row jumps here pre-selecting it.)
2. Press play. Pause holds the clock, stop saves a record.
3. Records group under Today / Previously and can be deleted (undoable).
   **Copy day** next to Today copies the whole day as text, e.g.
   `5h - Write report` per line.
4. The running timer keeps going across page reloads — the total on Home counts it live.

## Import and export

- **Export** (Sync & Settings → Data → Export): downloads `dotoist-export-YYYY-MM-DD.json` with lists, tasks, notes, trash, time records and labels. Back these up — your data lives in this browser plus, if enabled, your blog sync copy.
- **Import** (same tab, multi-select): accepts Dotoist exports
  (appended as new lists; notes and trash merge by id, so re-importing your own backup is a no-op instead of doubling everything).

## Installing the app

Dotoist is installable (PWA) and works offline once installed:

- **Desktop Chrome / Edge**: install icon in the address bar, or menu → Save and share → Install.
- **Android Chrome**: menu → Install app / Add to Home screen.
- **iPhone / iPad**: Share → Add to Home Screen for a fullscreen icon on your home screen.

Installing requires the hosted `https://` address — it does not work from a downloaded `file://` copy.

## Hosting it yourself

Dotoist is a static frontend plus a small sync API on this blog. Fork it and
host the frontend anywhere — it works fully offline out of the box:

1. **Fork** the repo at <https://github.com/arazgray/dotoist> (or download it).
2. **Serve it**: in your fork go to Settings → Pages → Deploy from a branch
   → `main`, folder `/ (root)`. Your copy lives at
   `https://<you>.github.io/dotoist/`. Any static host works the same.
3. **Use it as-is** — lists, tasks, notes, calendar, time tracking, local
   reminders and JSON backup all work immediately with no server.
4. **Blog sync + email reminders** need the Laravel side of this repo
   (`/api/dotoist/*` routes, `dotoist:*` tables, the `dotoist:reminders` schedule).
   Point the frontend at your blog by setting `DOTOIST_API_BASE` in `app.js`
   (same-origin by default), create a token with
   `php artisan dotoist:token you@example.com` to mint one manually, but the
   normal path needs no server access: Sync & Settings → email → code →
   Connect.

Bump the release trio as usual (`?v=` stamps in `index.html`,
`APP_VERSION`, `version.json` — all the same `1.0-<unix time>`) so
installed copies pick up the update.

That is all — sync data moves only between your browser and your own blog;
there is still no third party involved.

## Data and privacy

- All data lives in your browser's `localStorage` (`dotoist-v1`): lists, tasks, notes, trash, time records, view, filters, label names, your name, Home layout and panel sizes. Sync metadata (`dotoist-sync`: sync token, account email, last-synced snapshot + revision), sync history (`dotoist-sync-log`), notification read state (`dotoist-notif-seen`), shown-notification state (`dotoist-notify-last`), push subscription flag (`dotoist-push-sub`), welcome seen flag (`dotoist-welcomed`), theme (`dotoist-theme`) and weather location (`dotoist-loc`, 7-day cache) are stored separately. With blog sync enabled, the canonical copy lives in your blog's database.
- If a save ever fails validation (corrupted data), the app keeps a timestamped backup copy in your browser and starts fresh instead of breaking.
- The network requests the app itself makes: the blog sync API (only when you connect + sync), reminder emails sent by the blog scheduler, and the Home weather card (Open-Meteo, BigDataCloud, ipapi.co for location fallback). Fonts and icons ship with the app and work offline. Nothing else ever leaves your device.

## FAQ

**I lost my tasks after clearing browser data — can I get them back?**
Only from a JSON export or your blog sync copy (re-connect re-pulls it). Export regularly.

**Does it sync between phone and desktop?**
Yes — via Sync & Settings (blog sync). Run email → code → Connect on each
device and both stay merged.
Tokens are long-lived; disconnect a browser or revoke its token on the
server to cut a device off.

**Can I share a list with someone?**
Not yet — export the JSON and send them the file; they can import it.

**Sync keeps saying the token was rejected, or says "Sync failed".**
In Sync & Settings, request a fresh email code (`Email me a code`), enter
it and press Connect, then Sync now from the top bar. If no email arrives,
check spam and confirm you typed the address correctly. Make sure the blog is reachable
(ad-blockers sometimes block API calls) and check the exact reason under
Sync → History. That History page also has a **Copy diagnostics** button:
if sync looks wrong, open it right after the failure and send the text — it
shows connection state, revisions, last sync and recent events.

**I set a Reminder but nothing notified me.**
Only tasks with Details → Reminder set notify — dateless tasks need a due
date first. The push leg needs **Notify** tapped in Sync & Settings on that
device (use the **Test** button next to it to verify delivery; a blocked
permission must be re-allowed in the browser's site settings, and push
needs `https://`). The email leg needs the device to have synced after the reminder
was set, and the blog scheduler to be running (`dotoist:reminders` every
minute). Reminder errors and sync events show inside Sync & Settings and
under Sync → History.

**The weather card is empty.**
It needs location permission (or IP-based fallback) and internet. Everything else works offline.

**Does the Update button refresh the styles (CSS) too?**
Yes. Update unregisters the offline worker, wipes the whole offline cache
(styles included), and reloads with a one-time URL so no cached page can
survive — then the page pulls its stylesheet, script and fonts under fresh
per-release URLs. The only requirement is that a release bumps those URLs,
which is part of the normal release step.

**My phone shows an old version of the app.**
Open the app with internet — it checks for updates on launch and shows an
**Update** button when one is ready. To force it any time: sidebar bottom row
→ **Update** wipes the offline cache and reloads the newest version. If the
update toast keeps coming back instead of finishing, it escalates by itself:
after two tries the button becomes **Full refresh**, which does the same
cache wipe. Every step is logged under Sync → History. If it
stays stuck (iOS has no hard-refresh), remove the home-screen icon and re-add it.

**Where do I report a bug or ask for a feature?**
Open an issue at <https://github.com/arazgray/dotoist/issues>.
