Skip to content
Merged
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
50 changes: 14 additions & 36 deletions apps/docs/src/components/try-map/demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import {
type ShapeInput,
STAIR_MODELS,
searchShapes,
shapeOnAdd,
suggestShapes,
} from '@kept/shared';
import type {
Expand Down Expand Up @@ -63,8 +62,9 @@ import {
roomOn,
seated,
takeOff,
thingItem,
} from '../../../../web/src/map/layout';
import { matches, whereOf } from '../../../../web/src/map/list';
import { addOn, matches, offMapFor, whereOf } from '../../../../web/src/map/list';
// Inline, not imported as stylesheets: Astro would link those from every page of the site.
import mapCss from '../../../../web/src/map/map.css?inline';
// D249: the shape picker's pictures, the app's own sprite (fetched when the picker first opens).
Expand Down Expand Up @@ -594,35 +594,14 @@ export function mount(root: HTMLElement, { lang, installHref }: MountOptions): (
/** Shapes picked in this session, kept if the thing goes off the map and back on (D249). */
const chosen = new Map<string, MapModelKey>();

const chosenShape = (id: string) => chosen.get(id) ?? null;

function addThing(roomId: string, id: string) {
const x = view.things.find((t) => t.id === id);
if (!x) return;
mutate((p) => {
const room = p.rooms.find((r) => r.id === roomId);
if (!room) return;
const { model, from } = shapeOnAdd(
{ name: x.name, typeKey: x.typeKey, typeName: x.typeName, isContainer: x.isContainer },
chosen.get(x.id) ?? null,
);
const it: Item = {
id: x.id,
subject: 'thing',
roomId,
name: x.name,
shortCode: x.shortCode,
model,
x: room.w / 2 - 0.3,
z: room.d / 2 - 0.3,
rot: 0,
on: null,
parentId: x.parentId,
isContainer: x.isContainer,
quantity: x.quantity,
auto: false,
...(from === 'chosen' ? {} : { shapeFrom: from }),
};
clampIn(it, room);
p.items.push(it);
if (room) p.items.push(thingItem(x, room, chosenShape(x.id)));
});
engine?.select({ type: 'item', id: x.id });
}
Expand Down Expand Up @@ -745,6 +724,8 @@ export function mount(root: HTMLElement, { lang, installHref }: MountOptions): (
if (!host) return;
const room = plan.rooms.find((r) => r.id === host.roomId)?.name ?? '';
const things = addableOn(plan.items, host);
// #152: the room's things not on the map yet, with the shape each would get.
const offMap = offMapFor(plan, view, host, chosenShape);
const max = capacityOf(host.model);
const limited = Number.isFinite(max);
const left = roomOn(plan.items, host);
Expand All @@ -757,10 +738,14 @@ export function mount(root: HTMLElement, { lang, installHref }: MountOptions): (
: '';
const sub = (c: Item) =>
c.shortCode ? `${names[c.model]} · ${printedCode(c.shortCode)}` : names[c.model];
const group = (label: string, list: Item[], heading: boolean) =>
list.length
? `<div role="group" class="kput-section" aria-label="${esc(label)}">${heading ? `<div class="kput-head" aria-hidden="true">${esc(label)}</div>` : ''}${list.map((c) => putRow(c, sub(c))).join('')}</div>`
: '';
const body = full
? ''
: things.length
? `<div class="kput-list" role="listbox" aria-multiselectable="true" aria-label="${esc(w.put.toAdd)}">${things.map((c) => putRow(c, sub(c))).join('')}</div>
: things.length || offMap.length
? `<div class="kput-list" role="listbox" aria-multiselectable="true" aria-label="${esc(w.put.toAdd)}">${group(w.put.onMap, things, offMap.length > 0)}${group(w.put.notOnMap, offMap, true)}</div>
<div class="kput-actions"><button type="button" class="kmap-btn primary" data-put="add" disabled>${esc(w.put.pick)}</button>${btn('putcancel', w.cancel)}</div>`
: `<p class="kmap-empty">${esc(carryOf(host.model) === 'arm' ? w.put.noMonitor(room) : w.put.allOn(room))}</p>`;
const dlg = sheet(
Expand Down Expand Up @@ -798,14 +783,7 @@ export function mount(root: HTMLElement, { lang, installHref }: MountOptions): (
add?.addEventListener('click', () => {
const ids = [...picked];
dlg.close();
mutate((p) => {
const h = p.items.find((x) => x.id === id);
if (!h) return;
for (const cid of ids) {
const t = p.items.find((x) => x.id === cid);
if (t) putOn(p.items, t, h);
}
});
mutate((p) => addOn(p, view, id, ids, chosenShape));
engine?.select({ type: 'item', id });
});
dlg.querySelector<HTMLElement>('[role="option"][tabindex="0"]')?.focus();
Expand Down
15 changes: 11 additions & 4 deletions apps/docs/src/components/try-map/strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ type Words = {
left: (n: number, f: string) => string;
noMonitor: (room: string) => string;
allOn: (room: string) => string;
/** #152: Add on it's two lists. */
onMap: string;
notOnMap: string;
putN: (n: number, f: string) => string;
pick: string;
onItNow: (names: string) => string;
Expand Down Expand Up @@ -365,8 +368,10 @@ export const WORDS: Record<Lang, Words> = {
toAdd: 'Things to add on it',
full: (n, f) => (n === 1 ? 'Full: it holds one monitor.' : `Full: it holds ${f} monitors.`),
left: (n, f) => (n === 1 ? 'Room for one more.' : `Room for ${f} more.`),
noMonitor: (room) => `No monitor in ${room} is free. Put one on the map first.`,
allOn: (room) => `Everything small in ${room} is on something, or not on the map yet.`,
noMonitor: (room) => `No monitor in ${room} is free.`,
allOn: (room) => `Everything small in ${room} is on something already.`,
onMap: 'On the map',
notOnMap: 'Not on the map yet',
putN: (_n, f) => `Put ${f} on it`,
pick: 'Pick what goes on it',
onItNow: (names) => `On it now: ${names}`,
Expand Down Expand Up @@ -524,8 +529,10 @@ export const WORDS: Record<Lang, Words> = {
'مكان لـ# أخرى.',
'مكان لـ# أخرى.',
]),
noMonitor: (room) => `لا توجد شاشة متاحة في ${room}. ضع واحدة على الخريطة أولًا.`,
allOn: (room) => `كل شيء صغير في ${room} موضوع على شيء، أو ليس على الخريطة بعد.`,
noMonitor: (room) => `لا توجد شاشة متاحة في ${room}.`,
allOn: (room) => `كل شيء صغير في ${room} موضوع على شيء بالفعل.`,
onMap: 'على الخريطة',
notOnMap: 'ليست على الخريطة بعد',
putN: (n, f) =>
arPlural(n, f, [
'ضع # عليه',
Expand Down
10 changes: 9 additions & 1 deletion apps/docs/src/content/docs/users/location-map.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ The floor buttons work like a lift: **R**, **1**, **G** and so on, each named af
buttons, and step aside while a card is open. **Plan** looks straight down, with names and what's
in each shelf. Stairs on the map take you to the floor above or below.

A room opens facing the front of its screens (a monitor, a TV, a laptop), so you see them, not
their backs. Turn it another way and it opens that way next time on this device.

![Plan: the same home seen from above, each room named](../../../assets/screens/map-plan-light.webp)

![The map on a phone: the List · Grid · Map switch, the 3D and Plan buttons, and a selected thing's card at the bottom](../../../assets/screens/map-phone-light.webp)
Expand Down Expand Up @@ -159,6 +162,8 @@ A webcam is a few pixels wide at room zoom, so you don't have to drag it. In **A
3. To go the other way, select the desk or the monitor and tap **Add on it**. Pick one or several
of the room's small things that aren't on anything yet, then **Put 3 on it**. They go side by
side, not on top of each other.
The room's small things that aren't on the map yet are there too, under **Not on the map yet**,
with the shape each would get: picking one puts it on the map and on the desk in one go.
4. **Take off**, in **Put on…**, puts the thing back on the room's floor next to its holder.

![Put on… for a webcam: the room's desk and monitor, each with its picture](../../../assets/screens/map-put-on-phone-light.webp)
Expand All @@ -170,7 +175,10 @@ What can carry what:
light: small things up to 12 cm deep and 20 cm high, no wider than the screen.
- **On an arm**: a **monitor arm** stands on a desk and holds one monitor, a **dual monitor arm**
two, side by side and raised off the desk. **Add on it** on an arm lists the room's monitors
and says when the arm is full. A webcam on a monitor on an arm still works.
and says when the arm is full. A webcam on a monitor on an arm still works. An arm clamps at
the desk's back edge, the side away from the chair: in the middle, or at a back corner when the
middle is taken. Its monitors hang over the desk in front of it, and dragging it slides it along
the back.

Moving a holder moves what is on it: move the desk and its arm, the monitors and their webcam go
with it. Turn the desk and they turn with it. This is the map only: putting a webcam on a monitor
Expand Down
16 changes: 16 additions & 0 deletions apps/web/src/locales/ar/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -25137,3 +25137,19 @@ msgstr "اطلب من المالك إعداد البريد الإلكتروني.
#: src/components/reports/print-sheet.tsx
msgid "Add an email address to your account."
msgstr "أضف عنوان بريد إلكتروني إلى حسابك."

#: src/map/put-on.tsx
msgid "On the map"
msgstr "على الخريطة"

#: src/map/put-on.tsx
msgid "Not on the map yet"
msgstr "ليست على الخريطة بعد"

#: src/map/put-on.tsx
msgid "No monitor in {roomName} is free."
msgstr "لا توجد شاشة متاحة في {roomName}."

#: src/map/put-on.tsx
msgid "Everything small in {roomName} is on something already."
msgstr "كل شيء صغير في {roomName} موضوع على شيء بالفعل."
16 changes: 16 additions & 0 deletions apps/web/src/locales/de/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -25137,3 +25137,19 @@ msgstr "Bitte den Eigentümer, E-Mail einzurichten."
#: src/components/reports/print-sheet.tsx
msgid "Add an email address to your account."
msgstr "Füge deinem Konto eine E-Mail-Adresse hinzu."

#: src/map/put-on.tsx
msgid "On the map"
msgstr "Auf der Karte"

#: src/map/put-on.tsx
msgid "Not on the map yet"
msgstr "Noch nicht auf der Karte"

#: src/map/put-on.tsx
msgid "No monitor in {roomName} is free."
msgstr "Kein freier Monitor in {roomName}."

#: src/map/put-on.tsx
msgid "Everything small in {roomName} is on something already."
msgstr "Alles Kleine in {roomName} steht schon auf etwas."
16 changes: 16 additions & 0 deletions apps/web/src/locales/en/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -25137,3 +25137,19 @@ msgstr "Ask the owner to set up email."
#: src/components/reports/print-sheet.tsx
msgid "Add an email address to your account."
msgstr "Add an email address to your account."

#: src/map/put-on.tsx
msgid "On the map"
msgstr "On the map"

#: src/map/put-on.tsx
msgid "Not on the map yet"
msgstr "Not on the map yet"

#: src/map/put-on.tsx
msgid "No monitor in {roomName} is free."
msgstr "No monitor in {roomName} is free."

#: src/map/put-on.tsx
msgid "Everything small in {roomName} is on something already."
msgstr "Everything small in {roomName} is on something already."
16 changes: 16 additions & 0 deletions apps/web/src/locales/fr/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -25137,3 +25137,19 @@ msgstr "Demandez au propriétaire de configurer l’e-mail."
#: src/components/reports/print-sheet.tsx
msgid "Add an email address to your account."
msgstr "Ajoutez une adresse e-mail à votre compte."

#: src/map/put-on.tsx
msgid "On the map"
msgstr "Sur la carte"

#: src/map/put-on.tsx
msgid "Not on the map yet"
msgstr "Pas encore sur la carte"

#: src/map/put-on.tsx
msgid "No monitor in {roomName} is free."
msgstr "Aucun écran libre dans {roomName}."

#: src/map/put-on.tsx
msgid "Everything small in {roomName} is on something already."
msgstr "Tout ce qui est petit dans {roomName} est déjà posé sur quelque chose."
16 changes: 16 additions & 0 deletions apps/web/src/locales/it/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -25137,3 +25137,19 @@ msgstr "Chiedi al proprietario di configurare l'email."
#: src/components/reports/print-sheet.tsx
msgid "Add an email address to your account."
msgstr "Aggiungi un indirizzo email al tuo account."

#: src/map/put-on.tsx
msgid "On the map"
msgstr "Sulla mappa"

#: src/map/put-on.tsx
msgid "Not on the map yet"
msgstr "Non ancora sulla mappa"

#: src/map/put-on.tsx
msgid "No monitor in {roomName} is free."
msgstr "Nessun monitor libero in {roomName}."

#: src/map/put-on.tsx
msgid "Everything small in {roomName} is on something already."
msgstr "Tutto ciò che è piccolo in {roomName} è già sopra qualcosa."
6 changes: 5 additions & 1 deletion apps/web/src/map/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import {
type Room,
seated,
} from './layout';
import { matches, whereOf } from './list';
import { type ChosenShape, matches, whereOf } from './list';
import { AddOnSheet, PutOnSheet } from './put-on';
import { ShapeField, shapeInputOf } from './shapes';

Expand Down Expand Up @@ -74,6 +74,8 @@ export type CardProps = {
onPutOn: (id: string, hostId: string) => void;
onTakeOff: (id: string) => void;
onAddOn: (hostId: string, ids: string[]) => void;
/** #152: the shape a thing not on the map would get back, for Add on it. */
chosenShape?: ChosenShape;
};

function Dots({ flags }: { flags: MapAttentionKind[] }) {
Expand Down Expand Up @@ -598,6 +600,8 @@ export function MapCard(p: CardProps) {
<AddOnSheet
host={it}
plan={plan}
view={view}
chosenShape={p.chosenShape}
roomName={room?.name ?? ''}
onOpenChange={(open) => setSheet(open ? 'add' : null)}
onAdd={(ids) => {
Expand Down
Loading
Loading