Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,18 @@ jobs:
exit 1
fi
echo "No conflict markers."

sync-server:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install dependencies
run: pip install flask flask-cors

- name: Sync server tests
run: python -m unittest sync-server/test_server.py -v
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.claude
__pycache__/
21 changes: 13 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ making changes, edit `index.html` directly.

## Running the checks

There is no test suite to run locally. CI validates:
There is no test suite yet. To try a change, serve the repo root with any static
server (for example `python3 -m http.server`) and open it in a browser. CI checks:

- `index.html` and `docs/index.html` are valid HTML (via `htmlhint`)
- `manifest.json` is valid JSON
- the version string in `index.html` matches the cache name in `sw.js`
- `.nojekyll` is present, so GitHub Pages serves the site as is
- there are no broken symlinks
- there are no leftover merge conflict markers

Before submitting a PR, verify those things pass by checking the CI output.
Before submitting a PR, check that CI passes.

## What to contribute

Expand All @@ -33,9 +35,11 @@ Before submitting a PR, verify those things pass by checking the CI output.

## What is out of scope

- Server-side features. Everything runs in the browser. There is no server, no account
and no analytics — that is a deliberate constraint.
- Third-party API integrations that require keys or accounts.
- Server-side features the app depends on. Everything runs in the browser, with no
account and no analytics, and that is a deliberate constraint. The self-hosted sync
server and the bring-your-own-key AI features are opt-in extras behind Developer Mode,
and the app must keep working fully without them.
- Integrations that need a key or account for core features.
- Framework migrations. The single-file architecture is intentional.

## Style
Expand All @@ -44,4 +48,5 @@ Match the surrounding code. Comments explain *why*, particularly where something
non-obvious has been done for a specific reason (PWA quirks, iOS Safari workarounds,
etc.).

Keep the file self-contained. Do not add external script or style dependencies.
Keep the file self-contained. The only external scripts are ZXing (barcodes) and
Tesseract.js (label OCR); please don't add more.
63 changes: 36 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Macro Tracker
# Macrolog

A mobile-first progressive web app (PWA) for tracking daily calories and macronutrients. No account, no backend, no app store — install it directly from the browser.
A free, mobile-first progressive web app (PWA) for tracking daily calories and macronutrients. No account, no ads, no app store: install it straight from the browser.

**Live app:** https://macroslog.co.uk/
**Beta channel:** https://beta.macroslog.co.uk/ (new features land here first)
**Docs:** https://macroslog.co.uk/docs/

---
Expand All @@ -11,14 +12,26 @@ A mobile-first progressive web app (PWA) for tracking daily calories and macronu

| Feature | Detail |
|---|---|
| Barcode scanning | Camera scan → Open Food Facts lookup → log with weight |
| Food search | Text search across millions of Open Food Facts products |
| Manual entry | Add custom foods to a personal local database |
| Recipe builder | Compose recipes from ingredients, log by weight or portion |
| Daily dashboard | Progress rings for kcal, protein, carbs, fat, and fibre vs targets |
| History | Browse any past day's food log |
| Offline support | Service worker caches the app and barcode lookups for offline use |
| Data export | Full JSON export of all logged data |
| Barcode scanning | Camera scan, Open Food Facts lookup, log by weight |
| Food search | Open Food Facts and USDA FoodData Central |
| Nutrition label scanning | Photograph a label and the values are read with on-device OCR |
| Custom foods and quick add | Save your own foods, or log raw macros |
| Recipes | Build from ingredients, log by weight or portion |
| Today dashboard | Calories ring, protein, carbs, fat and fibre against your targets, plus a sugar limit |
| Water, exercise, weight and notes | Daily cards on the Today page |
| History and trends | Calendar of past days, trend charts and a macro history view |
| Fasting | Intermittent fasting timer with presets |
| Setup wizard | Suggests targets from your stats, activity, goal and diet type |
| Appearance | Dark, light or auto, plus which tabs and Today sections to show |
| Offline | The service worker caches the app and food lookups |
| Your data | JSON export and import, CSV exports of food and weight logs |

### Developer features (opt-in)

Turn on **Developer Mode** at the bottom of **Settings** to show:

- **Sync server:** a small self-hosted Flask server (`sync-server/`) that keeps your log in sync between your phone, tablet and computer. See [the developer docs](https://macroslog.co.uk/docs/developer.html).
- **AI features:** describe a meal in words to log it, plus daily and weekly summaries, using your own Claude, Gemini or OpenAI key. The key stays on your device and requests go straight to the provider.

---

Expand All @@ -27,40 +40,36 @@ A mobile-first progressive web app (PWA) for tracking daily calories and macronu
On **iOS (Safari):** Share → Add to Home Screen.
On **Android (Chrome):** browser menu → Install app.

The app launches in full-screen standalone mode with no browser chrome.
The app launches full screen with no browser chrome.

---

## Default targets
## Targets

| Macro | Default |
|---|---|
| Calories | 2750 kcal |
| Protein | 134 g |
| Carbs | 430 g |
| Fat | 55 g |

Adjust in the Settings tab. Changes are stored locally.
On first launch the setup wizard suggests targets. Until then the defaults are 2500 kcal, 60 g protein, 310 g carbs, 85 g fat, 30 g fibre and a 60 g sugar limit. Change them any time from the Today page or Settings.

---

## Storage

All data lives in `localStorage` — no server, no account. Use **Settings → Export JSON** to back up or migrate your data.
All data lives in the browser's `localStorage`. There is no server copy unless you run your own sync server, so use **Settings → Data → Export JSON** to back up or move your data.

---

## Tech stack

- Pure HTML + CSS + Vanilla JS — zero npm dependencies, no build step
- Service Worker for offline caching and PWA installation
- Web App Manifest for installability
- [Open Food Facts API](https://world.openfoodfacts.org/) — free, no API key required
- [ZXing JS](https://github.com/zxing-js/library) via unpkg for barcode decoding
- Plain HTML, CSS and JavaScript in a single `index.html`: no npm dependencies, no build step
- Service worker (`sw.js`) for offline use and installation
- [Open Food Facts](https://world.openfoodfacts.org/) and [USDA FoodData Central](https://fdc.nal.usda.gov/) for food data, no API key needed
- [ZXing](https://github.com/zxing-js/library) for barcode decoding and [Tesseract.js](https://github.com/naptha/tesseract.js) for label OCR, both from CDNs
- Hosted on GitHub Pages

See [CONTRIBUTING.md](CONTRIBUTING.md) to get involved.

---

## License

Data from Open Food Facts is available under [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/).
Macrolog is free software under the [GNU General Public License v3.0 or later](LICENSE).

Food data from Open Food Facts is available under the [Open Database License](https://opendatacommons.org/licenses/odbl/1-0/). USDA FoodData Central data is in the public domain.
111 changes: 107 additions & 4 deletions docs/changelog.html
Original file line number Diff line number Diff line change
Expand Up @@ -224,14 +224,73 @@ <h1>Macrolog</h1>
<h1 class="page-title">Changelog</h1>
<p class="page-subtitle">A history of every update to Macrolog.</p>

<!-- ── v2026-09-02.2 (Scan modal fix) ── -->
<!-- ── Beta: two-way sync ── -->
<div class="release">
<div class="release-dot"></div>
<div class="release-header">
<span class="release-version">Beta</span>
<span class="release-date">6 October 2026</span>
</div>
<div class="release-body">
<div class="change-group">
<div class="change-group-label">New</div>
<ul class="changes">
<li><strong>Two-way sync</strong> — every device pointed at your sync server shares one log. Changes merge entry by entry, sync a few seconds after each change, and a sync that would delete a large part of your log asks first</li>
<li><strong>Sync server</strong> — new <code>/sync/state</code> endpoint with revision checks, atomic writes and tests</li>
</ul>
</div>
</div>
</div>

<!-- ── v2026-10-06.2 (Chart labels, tour, History button, small fixes) ── -->
<div class="release">
<div class="release-dot latest"></div>
<div class="release-header">
<span class="release-version">v2026-09-02.2</span>
<span class="release-date">2 September 2026</span>
<span class="release-version">v2026-10-06.2</span>
<span class="release-date">6 October 2026</span>
<span class="release-badge">Latest</span>
</div>
<div class="release-body">
<div class="change-group">
<div class="change-group-label">Fixed</div>
<ul class="changes">
<li><strong>Chart dates</strong> — the dates under the Trends and Macro History charts were cut off and now show in full</li>
<li><strong>Trends axis labels</strong> — the kg and kcal labels no longer overlap the top axis values, and the first and last bars no longer cover the axis numbers</li>
<li><strong>First-run tour</strong> — steps whose target isn't on screen now show the tip in the middle instead of pointing at the top corner</li>
<li><strong>Ko-fi card</strong> — on tablets and larger screens it sits above the bottom navigation instead of behind it</li>
<li><strong>History calendar</strong> — the "Jump to Today" button was hidden behind the bottom navigation, so tapping it opened Settings instead</li>
<li><strong>Additional Nutrients</strong> — the section in Manual and Quick Add now collapses when you tap its heading; it stays open by default</li>
<li><strong>Food names</strong> — names in the macro breakdown popup are now shown as plain text, so a product name containing HTML can't change the page</li>
<li><strong>Docs What's New</strong> — the update cards now appear in Chrome; they stayed hidden because the reveal never triggered</li>
</ul>
</div>
</div>
</div>

<!-- ── v2026-10-06.1 (Custom foods seeding fix) ── -->
<div class="release">
<div class="release-dot"></div>
<div class="release-header">
<span class="release-version">v2026-10-06.1</span>
<span class="release-date">6 October 2026</span>
</div>
<div class="release-body">
<div class="change-group">
<div class="change-group-label">Fixed</div>
<ul class="changes">
<li><strong>Custom foods</strong> — new installs no longer start with a set of pre-filled custom foods, and foods you delete from your list no longer reappear the next time the app opens</li>
</ul>
</div>
</div>
</div>

<!-- ── v2026-09-02.2 (Scan modal fix) ── -->
<div class="release">
<div class="release-dot"></div>
<div class="release-header">
<span class="release-version">v2026-09-02.2</span>
<span class="release-date">7 September 2026</span>
</div>
<div class="release-body">
<div class="change-group">
<div class="change-group-label">Fixed</div>
Expand All @@ -242,6 +301,50 @@ <h1 class="page-title">Changelog</h1>
</div>
</div>

<!-- ── Docs feature guides ── -->
<div class="release">
<div class="release-dot"></div>
<div class="release-header">
<span class="release-version">Docs</span>
<span class="release-date">7 September 2026</span>
</div>
<div class="release-body">
<div class="change-group">
<div class="change-group-label">Docs</div>
<ul class="changes">
<li><strong>Feature guides</strong> — new pages for recipes, installing, appearance, trends, the barcode scanner, nutrition label scanning and custom foods</li>
<li><strong>Developer &amp; AI guide</strong> — sync server setup, remote access options and AI features in one place</li>
</ul>
</div>
</div>
</div>

<!-- ── v2026-09-03.8 (beta) ── -->
<div class="release">
<div class="release-dot"></div>
<div class="release-header">
<span class="release-version">v2026-09-03.8 (beta)</span>
<span class="release-date">3 September 2026</span>
</div>
<div class="release-body">
<div class="change-group">
<div class="change-group-label">New</div>
<ul class="changes">
<li><strong>Recipe drafts</strong> — save a recipe as a draft before it's finished, and delete drafts you no longer need</li>
</ul>
</div>
<div class="change-group">
<div class="change-group-label">Fixed</div>
<ul class="changes">
<li><strong>Status bar colour</strong> — follows the selected style and is never purple</li>
<li><strong>Bold nav</strong> — the floating nav hides behind open popups, the setup wizard and the on-screen keyboard</li>
<li><strong>Gradient style</strong> — glass styling now covers every page, with a stronger gradient in light mode</li>
<li><strong>Water buttons</strong> — use the selected style's colours</li>
</ul>
</div>
</div>
</div>

<!-- ── v2026-09-02.1 (Docs redesign) ── -->
<div class="release">
<div class="release-dot"></div>
Expand Down Expand Up @@ -270,7 +373,7 @@ <h1 class="page-title">Changelog</h1>
<div class="change-group">
<div class="change-group-label">New</div>
<ul class="changes">
<li><strong>/beta/ build</strong> — separate beta PWA at <code>/beta/</code> with all 7 UI themes</li>
<li><strong>Beta channel</strong> — separate beta PWA at <a href="https://beta.macroslog.co.uk">beta.macroslog.co.uk</a> with all 7 UI themes</li>
<li><strong>7 visual styles</strong> — Current (default), Bold (neon-green, giant kcal, floating pill nav), Gradient (purple-to-teal glassmorphism), Zen (minimal, ring hidden, lightweight number), Soft (warm cream/terracotta, pill-everything), Editorial (clinical blue, sharp 4px corners), Retro (terminal green-on-black / amber-on-cream)</li>
<li>Style selector in Settings → Appearance; persists in localStorage; orthogonal to dark/light/auto colour mode</li>
</ul>
Expand Down
Loading
Loading