-
Tag a card with #einkauf or #shopping to mark it as a shopping-list candidate. Open the header's menu → Einkaufsliste to pick which one is the currently active list — only one at a time is mirrored to the phone.
+
Tag a card with #einkauf or #shopping to mark it as a shopping-list candidate. Open the header's menu → Shopping list to pick which one is the currently active list — only one at a time is mirrored to the phone.
The active card's body is pushed to the relay on every sync tick. On your phone, open <your-relay>/shopping and log in with your relay credentials. The page shows only the unchecked - [ ] items as tappable rows. Tapping an item flips it to - [x] on the relay in-place; the next client tick pulls that back and updates the local card.
Editing stays in hyprcrd — the phone can only check/uncheck, never change text. That keeps conflict handling trivial (last-writer wins by timestamp).
| trigger tags | #einkauf or #shopping — either counts |
- | pick active | header menu → Einkaufsliste → radio select → Save |
+ | pick active | header menu → Shopping list → radio select → Save |
| phone URL | https://<relay>/shopping — session-auth, mobile layout |
| sync cadence | piggybacks on the shared sync tick (see Settings → Relay) |
diff --git a/public/js/modules/shopping.js b/public/js/modules/shopping.js
index 4eedffc..57c81ce 100644
--- a/public/js/modules/shopping.js
+++ b/public/js/modules/shopping.js
@@ -56,14 +56,14 @@ function openDialog() {
panel.innerHTML = `
@@ -91,8 +91,9 @@ function openDialog() {
if (!candidates.length) {
list.innerHTML = `
- Keine Karten mit dem Tag #einkauf.
- Lege eine Karte mit Checkbox-Items an und gib ihr den Tag, dann erscheint sie hier.
+ No cards tagged #einkauf or
+ #shopping yet. Create a card with checkbox items
+ and add one of those tags — it'll show up here.
`;
} else {
list.innerHTML = candidates.map(c => {
@@ -104,14 +105,14 @@ function openDialog() {
${esc(c.title || '(untitled)')}
-
${open} offen · ${items.length} gesamt
+
${open} open · ${items.length} total
`;
}).join('');
// "No active" option — explicit way to stop syncing.
list.insertAdjacentHTML('beforeend', `
`);
list.querySelectorAll('input[name="shopping-active"]').forEach(r => {
r.addEventListener('change', () => { selectedId = r.value || null; });
diff --git a/relay/inc/routes/shopping.php b/relay/inc/routes/shopping.php
index ec27062..e7ce13b 100644
--- a/relay/inc/routes/shopping.php
+++ b/relay/inc/routes/shopping.php
@@ -133,12 +133,12 @@ if ($route === '/shopping' && $method === 'GET') {
$userLabel = htmlspecialchars($sessionTenant['username'], ENT_QUOTES);
?>
-
+
-
Einkaufsliste
+
Shopping list