cursedbelt 5.77.0 → 5.78.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/react/canvas-hud/CanvasToolbar.d.ts +1 -1
  2. package/dist/react/components/DataTable/TableFilterBuilder.d.ts.map +1 -1
  3. package/dist/react/components/DataTable/TableFilterBuilder.js +2 -2
  4. package/dist/react/components/DataTable/TableFilterBuilder.js.map +1 -1
  5. package/dist/react/components/ListToolbar.d.ts +2 -2
  6. package/dist/react/components/ListToolbar.d.ts.map +1 -1
  7. package/dist/react/components/ListToolbar.js +1 -1
  8. package/dist/react/hooks/useOutsidePress.d.ts.map +1 -1
  9. package/dist/react/hooks/useOutsidePress.js +18 -3
  10. package/dist/react/hooks/useOutsidePress.js.map +1 -1
  11. package/dist/react/hooks/useScrollMemory.d.ts +4 -3
  12. package/dist/react/hooks/useScrollMemory.d.ts.map +1 -1
  13. package/dist/react/hooks/useScrollMemory.js +16 -2
  14. package/dist/react/hooks/useScrollMemory.js.map +1 -1
  15. package/dist/react/media/FocusViewer.d.ts +8 -1
  16. package/dist/react/media/FocusViewer.d.ts.map +1 -1
  17. package/dist/react/media/FocusViewer.js +174 -10
  18. package/dist/react/media/FocusViewer.js.map +1 -1
  19. package/dist/react/media/focusViewer.css +31 -0
  20. package/dist/react/media/gifClip.d.ts +46 -0
  21. package/dist/react/media/gifClip.d.ts.map +1 -0
  22. package/dist/react/media/gifClip.js +74 -0
  23. package/dist/react/media/gifClip.js.map +1 -0
  24. package/dist/react/media/gifEncode.d.ts +46 -0
  25. package/dist/react/media/gifEncode.d.ts.map +1 -0
  26. package/dist/react/media/gifEncode.js +288 -0
  27. package/dist/react/media/gifEncode.js.map +1 -0
  28. package/dist/react/media/gifRecord.d.ts +26 -0
  29. package/dist/react/media/gifRecord.d.ts.map +1 -0
  30. package/dist/react/media/gifRecord.js +93 -0
  31. package/dist/react/media/gifRecord.js.map +1 -0
  32. package/dist/scripts/guardrailsEnforce.d.ts.map +1 -1
  33. package/dist/styles-areas/analytics.css +9 -9
  34. package/dist/styles-areas/data-table.css +10 -10
  35. package/dist/styles-areas/media.css +2 -2
  36. package/package.json +3 -3
  37. package/scripts/guardrailsEnforce.spec.ts +10 -0
  38. package/scripts/guardrailsEnforce.ts +4 -1
  39. package/scripts/styleAreas.ts +3 -1
  40. package/src/react/canvas-hud/CanvasToolbar.tsx +1 -1
  41. package/src/react/components/DataTable/TableFilterBuilder.tsx +9 -13
  42. package/src/react/components/DataTable/tableSystem.spec.tsx +15 -7
  43. package/src/react/components/ListToolbar.tsx +2 -2
  44. package/src/react/hooks/useOutsidePress.spec.tsx +20 -0
  45. package/src/react/hooks/useOutsidePress.ts +17 -2
  46. package/src/react/hooks/useScrollMemory.spec.tsx +45 -2
  47. package/src/react/hooks/useScrollMemory.ts +20 -5
  48. package/src/react/media/FocusViewer.tsx +322 -25
  49. package/src/react/media/focusViewer.css +31 -0
  50. package/src/react/media/gifClip.ts +90 -0
  51. package/src/react/media/gifEncode.spec.ts +213 -0
  52. package/src/react/media/gifEncode.ts +298 -0
  53. package/src/react/media/gifRecord.ts +103 -0
  54. package/src/styles-areas/analytics.css +9 -9
  55. package/src/styles-areas/data-table.css +10 -10
  56. package/src/styles-areas/media.css +2 -2
@@ -3,7 +3,7 @@ export interface CanvasToolbarProps {
3
3
  /** The left half: what the canvas shows (a reach, a layer switch). Hidden while the bar is
4
4
  * under 768px wide when `compactFilters` is given — five stops beside the tools would scroll out of a thumb's sight. */
5
5
  filters?: ReactNode;
6
- /** The same choice as a phone wants it, usually the OS picker (`NativeSelect`): shown only while
6
+ /** The same choice as a phone wants it, usually one `SelectField`: shown only while
7
7
  * the bar is under 768px wide, on row two beside the legend. */
8
8
  compactFilters?: ReactNode;
9
9
  /** A key or chip strip (houses, layers, tags): ONE line that scrolls inside itself, its ends
@@ -1 +1 @@
1
- {"version":3,"file":"TableFilterBuilder.d.ts","sourceRoot":"","sources":["../../../../src/react/components/DataTable/TableFilterBuilder.tsx"],"names":[],"mappings":"AAOA,OAAO,EAOL,KAAK,WAAW,EAIjB,MAAM,kBAAkB,CAAC;AAI1B,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,wBAAwB,EAAE,CAAC;IACpC,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,KAAK,EACL,QAAQ,EACR,SAAS,EACT,WAAmB,GACpB,EAAE,uBAAuB,sCAmMzB"}
1
+ {"version":3,"file":"TableFilterBuilder.d.ts","sourceRoot":"","sources":["../../../../src/react/components/DataTable/TableFilterBuilder.tsx"],"names":[],"mappings":"AAOA,OAAO,EAOL,KAAK,WAAW,EAIjB,MAAM,kBAAkB,CAAC;AAI1B,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,wBAAwB,EAAE,CAAC;IACpC,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,KAAK,EACL,QAAQ,EACR,SAAS,EACT,WAAmB,GACpB,EAAE,uBAAuB,sCA+LzB"}
@@ -4,8 +4,8 @@ import { useState } from 'react';
4
4
  import { cn } from '../../lib/cn.js';
5
5
  import { Button } from '../Button.js';
6
6
  import { Input } from '../Input.js';
7
- import { NativeSelect } from '../NativeSelect.js';
8
7
  import { Popover } from '../Popover.js';
8
+ import { SelectField } from '../SelectField.js';
9
9
  import { countActiveConditions, describeFilterQuery, EMPTY_FILTER_QUERY, FILTER_OP_LABELS, newCondition, newGroup, VALUELESS_OPS, } from './filterQuery.js';
10
10
  import { Surface } from '../Surface.js';
11
11
  import { RAW_BUTTON } from '../../lib/cn.js';
@@ -77,7 +77,7 @@ export function TableFilterBuilder({ columns, value, onChange, className, defaul
77
77
  // On a phone the row wraps: column and condition on the first line, the
78
78
  // value and × on the second. One line squeezed the column select to
79
79
  // nothing and pushed × off the popover (forge task 2593).
80
- className: 'flex items-center gap-1.5 max-sm:flex-wrap', children: [_jsx("span", { className: 'w-12 shrink-0 text-right text-caption font-semibold uppercase tracking-wide text-muted-foreground', children: conditionIndex === 0 ? 'Where' : 'and' }), _jsx(NativeSelect, { size: 'sm', "aria-label": 'Column', className: 'min-w-0 flex-1', wrapperClassName: 'min-w-0 flex-1 max-sm:min-w-24', value: condition.column, options: columns.map((c) => ({ value: c.key, label: c.label })), onChange: (e) => patchGroup(group.id, (list) => list.map((c) => (c.id === condition.id ? { ...c, column: e.target.value } : c))) }), _jsx(NativeSelect, { size: 'sm', "aria-label": 'Condition', className: 'min-w-0', wrapperClassName: 'w-40 shrink-0 max-sm:w-auto max-sm:min-w-32 max-sm:flex-1', value: condition.op, options: OP_OPTIONS, onChange: (e) => patchGroup(group.id, (list) => list.map((c) => c.id === condition.id ? { ...c, op: e.target.value } : c)) }), VALUELESS_OPS.has(condition.op) ? (_jsx("span", { "aria-hidden": true, className: 'w-36 shrink-0 max-sm:hidden' })) : (_jsx(Input, { "aria-label": 'Value', className: 'h-8 w-36 shrink-0 max-sm:ml-13.5 max-sm:w-auto max-sm:min-w-0 max-sm:flex-1', value: condition.value, placeholder: 'value', onChange: (e) => patchGroup(group.id, (list) => list.map((c) => (c.id === condition.id ? { ...c, value: e.target.value } : c))) })), _jsx("button", {
80
+ className: 'flex items-center gap-1.5 max-sm:flex-wrap', children: [_jsx("span", { className: 'w-12 shrink-0 text-right text-caption font-semibold uppercase tracking-wide text-muted-foreground', children: conditionIndex === 0 ? 'Where' : 'and' }), _jsx(SelectField, { size: 'sm', "aria-label": 'Column', className: 'min-w-0 flex-1 max-sm:min-w-24', value: condition.column, options: columns.map((c) => ({ value: c.key, label: c.label })), onValueChange: (column) => patchGroup(group.id, (list) => list.map((c) => (c.id === condition.id ? { ...c, column } : c))) }), _jsx(SelectField, { size: 'sm', "aria-label": 'Condition', className: 'w-40 min-w-0 shrink-0 max-sm:w-auto max-sm:min-w-32 max-sm:flex-1', value: condition.op, options: OP_OPTIONS, onValueChange: (op) => patchGroup(group.id, (list) => list.map((c) => (c.id === condition.id ? { ...c, op: op } : c))) }), VALUELESS_OPS.has(condition.op) ? (_jsx("span", { "aria-hidden": true, className: 'w-36 shrink-0 max-sm:hidden' })) : (_jsx(Input, { "aria-label": 'Value', className: 'h-8 w-36 shrink-0 max-sm:ml-13.5 max-sm:w-auto max-sm:min-w-0 max-sm:flex-1', value: condition.value, placeholder: 'value', onChange: (e) => patchGroup(group.id, (list) => list.map((c) => (c.id === condition.id ? { ...c, value: e.target.value } : c))) })), _jsx("button", {
81
81
  // guardrails-ignore no-raw-action-button: removes a filter row, mutates no record.
82
82
  type: 'button', "aria-label": `Remove condition ${conditionIndex + 1}`, onClick: () => {
83
83
  const remaining = group.conditions.filter((c) => c.id !== condition.id);
@@ -1 +1 @@
1
- {"version":3,"file":"TableFilterBuilder.js","sourceRoot":"","sources":["../../../../src/react/components/DataTable/TableFilterBuilder.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TableFilterBuilder.js","sourceRoot":"","sources":["../../../../src/react/components/DataTable/TableFilterBuilder.tsx"],"names":[],"mappings":"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"}
@@ -31,7 +31,7 @@ export interface ListToolbarProps {
31
31
  chipsAllLabel?: string;
32
32
  /** Any further FILTER controls — they sit left, after the chips. */
33
33
  filters?: ReactNode;
34
- /** The sort control (a `NativeSelect`, a `ChoiceMenu`, …). Right-hand cluster. */
34
+ /** The sort control (a `SelectField`, a `ChoiceMenu`, …). Right-hand cluster. */
35
35
  sort?: ReactNode;
36
36
  /** The density/view-mode control — normally a `TableViewToggle`. Right-hand cluster. */
37
37
  view?: ReactNode;
@@ -91,7 +91,7 @@ export interface ListToolbarProps {
91
91
  * chips={buckets}
92
92
  * chipValue={filter}
93
93
  * onChipChange={(v) => setFilter(typeof v === 'string' ? v : null)}
94
- * sort={<NativeSelect size='sm' aria-label='Sort the queue' … />}
94
+ * sort={<SelectField size='sm' aria-label='Sort the queue' … />}
95
95
  * view={<TableViewToggle value={view.mode} onChange={view.setMode} />}
96
96
  * />
97
97
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ListToolbar.d.ts","sourceRoot":"","sources":["../../../src/react/components/ListToolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGxE,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACrC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IACzD,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oEAAoE;IACpE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,kFAAkF;IAClF,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,wFAAwF;IACxF,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,KAAK,EACL,SAAgB,EAChB,YAAY,EACZ,UAAkB,EAClB,aAAa,EACb,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,SAAS,GACV,EAAE,gBAAgB,+BAsDlB"}
1
+ {"version":3,"file":"ListToolbar.d.ts","sourceRoot":"","sources":["../../../src/react/components/ListToolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGxE,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACrC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IACzD,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oEAAoE;IACpE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,iFAAiF;IACjF,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,wFAAwF;IACxF,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,KAAK,EACL,SAAgB,EAChB,YAAY,EACZ,UAAkB,EAClB,aAAa,EACb,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,SAAS,GACV,EAAE,gBAAgB,+BAsDlB"}
@@ -54,7 +54,7 @@ import { SearchInput } from './SearchInput.js';
54
54
  * chips={buckets}
55
55
  * chipValue={filter}
56
56
  * onChipChange={(v) => setFilter(typeof v === 'string' ? v : null)}
57
- * sort={<NativeSelect size='sm' aria-label='Sort the queue' … />}
57
+ * sort={<SelectField size='sm' aria-label='Sort the queue' … />}
58
58
  * view={<TableViewToggle value={view.mode} onChange={view.setMode} />}
59
59
  * />
60
60
  */
@@ -1 +1 @@
1
- {"version":3,"file":"useOutsidePress.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useOutsidePress.ts"],"names":[],"mappings":"AAEA,KAAK,YAAY,GAAG;IAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,sBAAsB;IACrC,+BAA+B;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,+EAA+E;IAC/E,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IACjC,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,aAAa,CAAC;CACpC;AAiBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,SAAS,EACT,MAAW,EACX,MAAM,EAAE,aAAoB,EAC5B,KAAa,EACb,QAAkB,GACnB,EAAE,sBAAsB,GAAG;IAAE,cAAc,EAAE,MAAM,IAAI,CAAC;IAAC,oBAAoB,EAAE,MAAM,IAAI,CAAA;CAAE,CAuF3F"}
1
+ {"version":3,"file":"useOutsidePress.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useOutsidePress.ts"],"names":[],"mappings":"AAEA,KAAK,YAAY,GAAG;IAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,sBAAsB;IACrC,+BAA+B;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,+EAA+E;IAC/E,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IACjC,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,aAAa,CAAC;CACpC;AAiBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,SAAS,EACT,MAAW,EACX,MAAM,EAAE,aAAoB,EAC5B,KAAa,EACb,QAAkB,GACnB,EAAE,sBAAsB,GAAG;IAAE,cAAc,EAAE,MAAM,IAAI,CAAC;IAAC,oBAAoB,EAAE,MAAM,IAAI,CAAA;CAAE,CAsG3F"}
@@ -84,8 +84,24 @@ export function useOutsidePress({ open, onDismiss, inside = [], escape: closeOnE
84
84
  swallowUntil = Date.now() + 1000;
85
85
  decideLater(target);
86
86
  };
87
+ // `click` mode: where the press BEGAN. A Radix Select opens on the pointerdown and makes the
88
+ // page inert, so that same press's release — and the click it makes — land on `<html>`; read
89
+ // as outside, it shut the filter builder the moment its Column picker opened (forge task
90
+ // 3064). A click whose press began inside (in the DOM, or this panel's React tree — the
91
+ // panel's `onPointerDownCapture` runs after this capture listener) is inside.
92
+ let pressBegan = null;
93
+ const onPressBegins = (event) => {
94
+ pressInsideRef.current = false;
95
+ pressBegan = event.target instanceof Node ? event.target : null;
96
+ };
87
97
  const onClick = (event) => {
88
98
  const target = event.target instanceof Node ? event.target : null;
99
+ if (decideOn === 'click') {
100
+ const began = pressBegan;
101
+ pressBegan = null;
102
+ if (began && (pressInsideRef.current || isInside(began) || onAnotherLayer(began)))
103
+ return;
104
+ }
89
105
  if (decideOn === 'pointerdown') {
90
106
  if (Date.now() < swallowUntil) {
91
107
  swallowUntil = 0;
@@ -108,13 +124,12 @@ export function useOutsidePress({ open, onDismiss, inside = [], escape: closeOnE
108
124
  latest.current.onDismiss();
109
125
  };
110
126
  document.addEventListener('click', onClick, true);
111
- if (decideOn === 'pointerdown')
112
- document.addEventListener('pointerdown', onPointerDown, true);
127
+ document.addEventListener('pointerdown', decideOn === 'pointerdown' ? onPointerDown : onPressBegins, true);
113
128
  if (closeOnEscape)
114
129
  document.addEventListener('keydown', onKeyDown);
115
130
  return () => {
116
131
  document.removeEventListener('click', onClick, true);
117
- document.removeEventListener('pointerdown', onPointerDown, true);
132
+ document.removeEventListener('pointerdown', decideOn === 'pointerdown' ? onPointerDown : onPressBegins, true);
118
133
  document.removeEventListener('keydown', onKeyDown);
119
134
  for (const timer of timers)
120
135
  clearTimeout(timer);
@@ -1 +1 @@
1
- {"version":3,"file":"useOutsidePress.js","sourceRoot":"","sources":["../../../src/react/hooks/useOutsidePress.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useOutsidePress.js","sourceRoot":"","sources":["../../../src/react/hooks/useOutsidePress.ts"],"names":[],"mappings":"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"}
@@ -52,9 +52,10 @@ export interface ScrollMemoryOptions {
52
52
  */
53
53
  enabled?: boolean;
54
54
  /**
55
- * How long a restore waits for the page to grow tall enough before settling as close as it
56
- * got. Default 3000ms — a reload, where only the first page of a list exists, needs a few
57
- * pages' round trips.
55
+ * How long a restore waits for the page to GROW before settling as close as it got — counted
56
+ * from the last time it grew, so a list paging itself down keeps being followed (up to 20s in
57
+ * all). Default 3000ms — a reload, where only the first page of a list exists, needs a few
58
+ * pages' round trips, each of which must land within it.
58
59
  */
59
60
  deadlineMs?: number;
60
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollMemory.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useScrollMemory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAA2B,MAAM,OAAO,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,IAAI,CA0BzF;AAwED,oGAAoG;AACpG,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC;AAEzG,MAAM,WAAW,mBAAmB;IAClC,mEAAmE;IACnE,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAmDD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIzD"}
1
+ {"version":3,"file":"useScrollMemory.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useScrollMemory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAA2B,MAAM,OAAO,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,IAAI,CA0BzF;AAwED,oGAAoG;AACpG,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC;AAEzG,MAAM,WAAW,mBAAmB;IAClC,mEAAmE;IACnE,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAqDD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIzD"}
@@ -122,6 +122,8 @@ function begin(scroller, location, last, deadlineMs) {
122
122
  };
123
123
  }
124
124
  const RESTORE_DEADLINE_MS = 3_000;
125
+ /** The longest a restore keeps following a page that is still growing — the viewer can always take it back sooner. */
126
+ const RESTORE_CEILING_MS = 20_000;
125
127
  /**
126
128
  * How long a landed restore holds its target against a scroll the viewer did not make. Long
127
129
  * enough for a list to finish settling (the late move in forge task 2784 came inside 800ms, under
@@ -215,7 +217,14 @@ function file(id, y) {
215
217
  * cancel that reports nothing. `settled` is called once, when it lands or gives up.
216
218
  */
217
219
  function restore(scroller, target, deadlineMs, settled) {
218
- const deadline = performance.now() + deadlineMs;
220
+ // 🔴 The deadline is for a page that has STOPPED growing, not a stopwatch from the start (forge
221
+ // task 3069): flix's phone grid, reloaded and coming back to 30,000px, pages itself down one round
222
+ // trip at a time, and with eight browsers sharing the Mac those trips took longer than 3s in all.
223
+ // The restore gave up at 29,731px while the pages were still arriving — a slow phone network is
224
+ // the same case. Each time the page grows the wait starts again, up to RESTORE_CEILING_MS.
225
+ const started = performance.now();
226
+ let deadline = started + deadlineMs;
227
+ let lastRoom = -1;
219
228
  let frame = 0;
220
229
  let holdTimer;
221
230
  let phase = 'waiting';
@@ -252,7 +261,12 @@ function restore(scroller, target, deadlineMs, settled) {
252
261
  }
253
262
  // Short of it: go as far as the page allows — that is what asks an infinite list for more.
254
263
  scroller.set(Math.max(0, room));
255
- if (performance.now() >= deadline) {
264
+ const now = performance.now();
265
+ if (room > lastRoom) {
266
+ lastRoom = room;
267
+ deadline = Math.min(now + deadlineMs, started + Math.max(deadlineMs, RESTORE_CEILING_MS));
268
+ }
269
+ if (now >= deadline) {
256
270
  finish();
257
271
  settled('deadline');
258
272
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollMemory.js","sourceRoot":"","sources":["../../../src/react/hooks/useScrollMemory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useScrollMemory.js","sourceRoot":"","sources":["../../../src/react/hooks/useScrollMemory.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import "./focusViewer.css";
2
+ import { type GifSection } from "./gifClip.js";
2
3
  /**
3
4
  * One still already kept beside this video.
4
5
  *
@@ -45,6 +46,12 @@ export interface FocusViewerProps {
45
46
  }) => Promise<FocusSaveResult | void> | FocusSaveResult | void;
46
47
  /** An arbitrary control in the action row — collections puts its folder picker here. */
47
48
  destination?: React.ReactNode;
49
+ /**
50
+ * Keep a looping GIF of a section. OMIT IT and "Make a GIF" still works — it downloads the
51
+ * file instead, because a GIF needs no store to be useful the way a filed still does.
52
+ * `destination` applies to it as it does to a snapshot.
53
+ */
54
+ onSaveGif?: (gif: Blob, meta: GifSection) => Promise<FocusSaveResult | void> | FocusSaveResult | void;
48
55
  /**
49
56
  * How tall, in CSS pixels, the picture in the host's own player was when this opened.
50
57
  *
@@ -67,5 +74,5 @@ export interface FocusViewerProps {
67
74
  atSeconds: number;
68
75
  }) => void;
69
76
  }
70
- export declare function FocusViewer({ videoUrl, title, startAt, durationSeconds, snapshots, onSaveSnapshot, destination, matchHeight, videoId, onClose, }: FocusViewerProps): React.ReactNode;
77
+ export declare function FocusViewer({ videoUrl, title, startAt, durationSeconds, snapshots, onSaveSnapshot, destination, onSaveGif, matchHeight, videoId, onClose, }: FocusViewerProps): React.ReactNode;
71
78
  //# sourceMappingURL=FocusViewer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FocusViewer.d.ts","sourceRoot":"","sources":["../../../src/react/media/FocusViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAC;AAoG3B;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,+DAA+D;IAC/D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,6FAA6F;AAC7F,MAAM,WAAW,eAAe;IAC/B,8CAA8C;IAC9C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAChC,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yFAAyF;IACzF,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,kFAAkF;IAClF,SAAS,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACrC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAChB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,KAEvB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,eAAe,GAAG,IAAI,CAAC;IAC9D,wFAAwF;IACxF,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wFAAwF;IACxF,OAAO,EAAE,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAClD;AAQD,wBAAgB,WAAW,CAAC,EAC3B,QAAQ,EACR,KAAK,EACL,OAAW,EACX,eAAe,EACf,SAAc,EACd,cAAc,EACd,WAAW,EACX,WAAW,EACX,OAAO,EACP,OAAO,GACP,EAAE,gBAAgB,GAAG,KAAK,CAAC,SAAS,CAqxBpC"}
1
+ {"version":3,"file":"FocusViewer.d.ts","sourceRoot":"","sources":["../../../src/react/media/FocusViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAC;AAgE3B,OAAO,EAMN,KAAK,UAAU,EAIf,MAAM,cAAc,CAAC;AAuDtB;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,+DAA+D;IAC/D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,6FAA6F;AAC7F,MAAM,WAAW,eAAe;IAC/B,8CAA8C;IAC9C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAChC,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yFAAyF;IACzF,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,kFAAkF;IAClF,SAAS,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACrC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAChB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,KAEvB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,eAAe,GAAG,IAAI,CAAC;IAC9D,wFAAwF;IACxF,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,CACX,GAAG,EAAE,IAAI,EACT,IAAI,EAAE,UAAU,KAEZ,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,eAAe,GAAG,IAAI,CAAC;IAC9D;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wFAAwF;IACxF,OAAO,EAAE,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAClD;AAQD,wBAAgB,WAAW,CAAC,EAC3B,QAAQ,EACR,KAAK,EACL,OAAW,EACX,eAAe,EACf,SAAc,EACd,cAAc,EACd,WAAW,EACX,SAAS,EACT,WAAW,EACX,OAAO,EACP,OAAO,GACP,EAAE,gBAAgB,GAAG,KAAK,CAAC,SAAS,CAwgCpC"}
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import "./focusViewer.css";
3
3
  /**
4
4
  * The focus viewer — look closely at PART of a video, and keep what you find.
@@ -18,6 +18,10 @@ import "./focusViewer.css";
18
18
  * which is the correct surface for a host with nowhere to put one.
19
19
  * · `destination` — an arbitrary node in the action row, for a host that wants to choose
20
20
  * WHERE (collections offers its folder picker there; binary-server offers nothing).
21
+ * · `onSaveGif` — where a looping GIF of a section goes. Unlike a snapshot, a GIF is
22
+ * offered to EVERY host: without a store it downloads to the device (owner, 2026-10-11:
23
+ * *"In collections and the cb media player in general allow making a looping gif out of a
24
+ * section of a video"* — "in general" is binary-server too, which keeps no stills).
21
25
  * Everything else — geometry, gestures, keyboard, the canvas capture — is the same code for
22
26
  * every consumer, which is the entire point of the lift.
23
27
  *
@@ -51,7 +55,7 @@ import "./focusViewer.css";
51
55
  import { useCallback, useEffect, useRef, useState } from "react";
52
56
  import { Alert } from "../components/Alert.js";
53
57
  import { Button } from "../components/Button.js";
54
- import { NativeSelect } from "../components/NativeSelect.js";
58
+ import { SelectField } from "../components/SelectField.js";
55
59
  import { Tooltip } from "../components/Tooltip.js";
56
60
  import { MediaResizeBar, MediaResizeCorner, useMediaResize } from "./MediaResize.js";
57
61
  import { FOCUS_HEIGHT_KEY } from "./stageResize.js";
@@ -59,9 +63,23 @@ import { PictureControls } from "./PictureControls.js";
59
63
  import { handOffPlayhead } from "./playheadHandoff.js";
60
64
  import { isPlayPauseSpace } from "./playerSpaceKey.js";
61
65
  import { PLAYBACK_RATES } from "./VideoPlayer.js";
66
+ import { clampGifSection, formatGifBytes, formatGifTime, GIF_FRAME_RATES, GIF_WIDTHS, gifFileName, gifSectionAt, MAX_GIF_SECONDS, } from "./gifClip.js";
62
67
  import { FULL_REGION, MAX_ZOOM, composeSelection, fillRegion, fitBox, isFullRegion, normalizeRect, panRegion, regionAtZoom, regionLayout, regionPixels, regionZoom, stageAspectFor, zoomRegion, } from "./videoRegion.js";
63
68
  import { NO_ENHANCE, UPSCALE_FACTORS, filterString, isEnhanced, readEnhance, snapshotSize, writeEnhance, } from "./videoEnhance.js";
64
69
  import { cn, RAW_BUTTON } from '../lib/cn.js';
70
+ /**
71
+ * The GIF recorder and its encoder, fetched the first time the GIF panel opens — they are this
72
+ * feature's bytes, and a gallery that never makes a GIF should not carry them. Kept once
73
+ * fetched; a failed fetch is forgotten so the next press asks again.
74
+ */
75
+ let gifRecorder = null;
76
+ function loadGifRecorder() {
77
+ gifRecorder ??= import("./gifRecord.js").catch((error) => {
78
+ gifRecorder = null;
79
+ throw error;
80
+ });
81
+ return gifRecorder;
82
+ }
65
83
  /** `m:ss`, or `h:mm:ss` past the hour. Local so this module has no app dependency. */
66
84
  function formatDuration(seconds) {
67
85
  if (!Number.isFinite(seconds) || seconds < 0)
@@ -77,7 +95,7 @@ function formatDuration(seconds) {
77
95
  const ZOOM_STEP = 1.25;
78
96
  /** One frame at 30 fps — see `stepFrame` for why this is a constant and not measured. */
79
97
  const FRAME_STEP_SECONDS = 1 / 30;
80
- export function FocusViewer({ videoUrl, title, startAt = 0, durationSeconds, snapshots = [], onSaveSnapshot, destination, matchHeight, videoId, onClose, }) {
98
+ export function FocusViewer({ videoUrl, title, startAt = 0, durationSeconds, snapshots = [], onSaveSnapshot, destination, onSaveGif, matchHeight, videoId, onClose, }) {
81
99
  const videoRef = useRef(null);
82
100
  const viewportRef = useRef(null);
83
101
  /*
@@ -122,6 +140,19 @@ export function FocusViewer({ videoUrl, title, startAt = 0, durationSeconds, sna
122
140
  const [busy, setBusy] = useState(false);
123
141
  const [error, setError] = useState(null);
124
142
  const [note, setNote] = useState(null);
143
+ /*
144
+ * ── A section, as a looping GIF ────────────────────────────────────────────────────
145
+ * Null while the GIF panel is shut. Open, it is the section the GIF will hold, and while
146
+ * `loopSection` is on the picture plays only that section, round and round — the preview
147
+ * IS the GIF, before a frame is encoded.
148
+ */
149
+ const [gif, setGif] = useState(null);
150
+ const [loopSection, setLoopSection] = useState(true);
151
+ const [gifFps, setGifFps] = useState(15);
152
+ const [gifWidth, setGifWidth] = useState(480);
153
+ /** `[done, total]` frames while one is being made. */
154
+ const [gifProgress, setGifProgress] = useState(null);
155
+ const gifAbort = useRef(null);
125
156
  /**
126
157
  * Keep the measured viewport current.
127
158
  *
@@ -252,6 +283,111 @@ export function FocusViewer({ videoUrl, title, startAt = 0, durationSeconds, sna
252
283
  if (wasPlaying)
253
284
  void video.play().catch(() => undefined);
254
285
  }, []);
286
+ /**
287
+ * Play the GIF's section on a loop while it is being chosen.
288
+ *
289
+ * Checked every animation frame rather than on `timeupdate`, which fires about four times
290
+ * a second and would let the picture run a quarter-second past the end before snapping
291
+ * back — a preview that shows frames the GIF will not have. Only while PLAYING: a paused
292
+ * scrub or frame-step outside the section is the person looking for a new end, and must not
293
+ * be yanked back. Stands down while a GIF is being made, whose seeks are its own.
294
+ */
295
+ useEffect(() => {
296
+ if (!gif || !loopSection || gifProgress)
297
+ return;
298
+ let raf = 0;
299
+ const check = () => {
300
+ const video = videoRef.current;
301
+ if (video && !video.paused && !scrubbing.current) {
302
+ const t = video.currentTime;
303
+ if (t >= gif.endSeconds || t < gif.startSeconds - 0.05)
304
+ video.currentTime = gif.startSeconds;
305
+ }
306
+ raf = requestAnimationFrame(check);
307
+ };
308
+ raf = requestAnimationFrame(check);
309
+ return () => cancelAnimationFrame(raf);
310
+ }, [gif, loopSection, gifProgress]);
311
+ /** Close the GIF panel, stopping a GIF still being made. */
312
+ const closeGif = () => {
313
+ gifAbort.current?.abort();
314
+ setGif(null);
315
+ };
316
+ /** Mark where the GIF starts or ends at the playhead — the `I` and `O` keys, as in an editor. */
317
+ const markGif = (end) => {
318
+ const at = videoRef.current?.currentTime ?? position;
319
+ const total = duration || videoRef.current?.duration || 0;
320
+ // Fetched while the section is chosen, so "Save GIF" does not wait on the network.
321
+ void loadGifRecorder().catch(() => undefined);
322
+ setGif((current) => {
323
+ if (!current)
324
+ return gifSectionAt(at, total);
325
+ const length = current.endSeconds - current.startSeconds;
326
+ return end === "start"
327
+ ? // A start past the old end keeps the section's length rather than collapsing it.
328
+ clampGifSection({ startSeconds: at, endSeconds: at >= current.endSeconds ? at + length : current.endSeconds }, total, "start")
329
+ : clampGifSection({ startSeconds: current.startSeconds, endSeconds: at }, total, "end");
330
+ });
331
+ };
332
+ /**
333
+ * Make the GIF: seek through the section, encode what is ON SCREEN — the zoomed area and
334
+ * the picture adjustments, exactly as a snapshot takes them — and save or download it.
335
+ */
336
+ const makeGif = async (how) => {
337
+ const video = videoRef.current;
338
+ if (!video || !gif)
339
+ return;
340
+ const abort = new AbortController();
341
+ gifAbort.current = abort;
342
+ setError(null);
343
+ setNote(null);
344
+ setGifProgress([0, 1]);
345
+ try {
346
+ const crop = regionPixels(shown, { width: video.videoWidth, height: video.videoHeight });
347
+ if (!crop)
348
+ throw new Error("The video has not decoded a frame yet.");
349
+ // 🔴 A failed fetch here is almost always a deploy since this page opened — the chunk
350
+ // was renamed — and says so, rather than reloading away the section being made.
351
+ const { recordGifClip } = await loadGifRecorder().catch(() => {
352
+ throw new Error("This app was updated since the page opened — reload it to make a GIF.");
353
+ });
354
+ const blob = await recordGifClip(video, {
355
+ ...gif,
356
+ fps: gifFps,
357
+ width: gifWidth,
358
+ crop,
359
+ ...(isEnhanced(enhance) ? { filter: filterString(enhance) } : {}),
360
+ onProgress: (done, total) => setGifProgress([done, total]),
361
+ signal: abort.signal,
362
+ });
363
+ const weight = formatGifBytes(blob.size);
364
+ if (how === "save" && onSaveGif) {
365
+ const saved = (await onSaveGif(blob, gif)) ?? {};
366
+ setNote(saved.message
367
+ ? `${saved.message} (${weight} GIF)`
368
+ : saved.duplicate
369
+ ? "That exact GIF was already saved — nothing added."
370
+ : `GIF saved — ${weight}.`);
371
+ }
372
+ else {
373
+ downloadBlob(blob, gifFileName(title, gif.startSeconds));
374
+ setNote(`GIF downloaded — ${weight}.`);
375
+ }
376
+ }
377
+ catch (err) {
378
+ if (err instanceof DOMException && err.name === "AbortError")
379
+ setNote("GIF cancelled.");
380
+ else
381
+ setError(err instanceof Error ? err.message : "The GIF could not be made.");
382
+ }
383
+ finally {
384
+ if (gifAbort.current === abort)
385
+ gifAbort.current = null;
386
+ setGifProgress(null);
387
+ }
388
+ };
389
+ // A GIF still being made is stopped when the viewer goes.
390
+ useEffect(() => () => gifAbort.current?.abort(), []);
255
391
  /**
256
392
  * Drag the timeline to skip around LIVE.
257
393
  *
@@ -496,7 +632,11 @@ export function FocusViewer({ videoUrl, title, startAt = 0, durationSeconds, sna
496
632
  event.altKey ||
497
633
  event.shiftKey)
498
634
  return;
499
- if (event.key === "ArrowRight") {
635
+ if (gif && !gifProgress && (event.key === "i" || event.key === "o")) {
636
+ event.preventDefault();
637
+ markGif(event.key === "i" ? "start" : "end");
638
+ }
639
+ else if (event.key === "ArrowRight") {
500
640
  event.preventDefault();
501
641
  stepFrame(1);
502
642
  }
@@ -587,12 +727,12 @@ export function FocusViewer({ videoUrl, title, startAt = 0, durationSeconds, sna
587
727
  }, onKeyDown: beginScrub, onKeyUp: endScrub,
588
728
  // Pause for the duration of a drag — see `beginScrub` for why playback and a
589
729
  // drag otherwise fight over `currentTime`.
590
- onPointerDown: beginScrub, step: 0.02, type: "range", value: position }), _jsxs("span", { className: "inspector__time", children: [formatDuration(position) || "0:00", " / ", formatDuration(duration) || "0:00"] }), _jsxs("label", { className: "inspector__speed", htmlFor: "inspector-speed", children: [_jsx("span", { className: "sr-only", children: "Playback speed" }), _jsx(NativeSelect, { id: "inspector-speed", className: "w-auto", onChange: (event) => {
591
- const next = Number(event.target.value);
730
+ onPointerDown: beginScrub, step: 0.02, type: "range", value: position }), _jsxs("span", { className: "inspector__time", children: [formatDuration(position) || "0:00", " / ", formatDuration(duration) || "0:00"] }), _jsxs("label", { className: "inspector__speed", htmlFor: "inspector-speed", children: [_jsx("span", { className: "sr-only", children: "Playback speed" }), _jsx(SelectField, { id: "inspector-speed", className: "w-auto", onValueChange: (value) => {
731
+ const next = Number(value);
592
732
  setRate(next);
593
733
  if (videoRef.current)
594
734
  videoRef.current.playbackRate = next;
595
- }, size: "sm", value: rate, children: PLAYBACK_RATES.map((option) => (_jsxs("option", { value: option, children: [option, "\u00D7"] }, option))) })] })] }), _jsxs("div", { className: "inspector__tools", children: [_jsx(Button, { onClick: () => setRegion((current) => zoomRegion(current, 1 / ZOOM_STEP)), tooltip: "Wider", variant: "secondary", children: "\uFF0D" }), _jsxs("label", { className: "inspector__zoom", children: [_jsx("span", { className: "sr-only", children: "Zoom" }), _jsx(Tooltip, { content: "How close in you are looking", children: _jsx("input", {
735
+ }, options: PLAYBACK_RATES.map((option) => ({ value: String(option), label: `${option}×` })), size: "sm", value: String(rate) })] })] }), _jsxs("div", { className: "inspector__tools", children: [_jsx(Button, { onClick: () => setRegion((current) => zoomRegion(current, 1 / ZOOM_STEP)), tooltip: "Wider", variant: "secondary", children: "\uFF0D" }), _jsxs("label", { className: "inspector__zoom", children: [_jsx("span", { className: "sr-only", children: "Zoom" }), _jsx(Tooltip, { content: "How close in you are looking", children: _jsx("input", {
596
736
  // guardrails-ignore no-raw-inputs: sibling of the transport — see above
597
737
  max: MAX_ZOOM, min: 1, onChange: (event) => setRegion((current) => regionAtZoom(current, Number(event.target.value))), step: 0.1, type: "range", value: Math.min(zoom, MAX_ZOOM), "aria-label": "How close in you are looking" }) }), _jsxs("span", { className: "inspector__time", children: [zoom.toFixed(1), "\u00D7"] })] }), _jsx(Button, { onClick: () => setRegion((current) => zoomRegion(current, ZOOM_STEP)), tooltip: "Closer, on the middle of what you are looking at", variant: "secondary", children: "\uFF0B" }), _jsx(Button, { onClick: () => setSelecting((on) => !on), tooltip: selecting
598
738
  ? "Stop selecting — a drag pans instead"
@@ -605,9 +745,20 @@ export function FocusViewer({ videoUrl, title, startAt = 0, durationSeconds, sna
605
745
  // Upscale is this surface's own concern, which is why Reset is overridden
606
746
  // here rather than the control being taught about it.
607
747
  setUpscale(1);
608
- }, resettable: isEnhanced(enhance) || upscale !== 1, value: enhance, children: onSaveSnapshot ? (_jsxs("label", { className: "picture__slider", htmlFor: "inspector-upscale", children: [_jsx("span", { children: "Save at" }), _jsx(NativeSelect, { id: "inspector-upscale", className: "w-auto", onChange: (event) => setUpscale(Number(event.target.value)), size: "sm", value: upscale, children: UPSCALE_FACTORS.map((factor) => (_jsxs("option", { value: factor, children: [factor, "\u00D7 ", factor === 1 ? "(as-is)" : "upscaled"] }, factor))) })] })) : null }), onSaveSnapshot ? (_jsxs("div", { className: "inspector__save", children: [_jsx(Button, { disabled: busy, onClick: () => void takeSnapshot(false), tooltip: isFullRegion(region)
609
- ? "Save this frame as a picture"
610
- : "Save just the part you are looking at", variant: "primary", children: isFullRegion(region) ? "Snapshot this frame" : "Snapshot this area" }), isFullRegion(region) ? null : (_jsx(Button, { disabled: busy, onClick: () => void takeSnapshot(true), tooltip: "Save the whole frame, ignoring the area you selected", variant: "secondary", children: "Snapshot whole frame" })), destination] })) : null, error ? _jsx(Alert, { tone: "error", children: error }) : null, note && !error ? _jsx(Alert, { tone: "success", children: note }) : null, snapshots.length > 0 ? (_jsxs("div", { className: "inspector__strip", children: [_jsx("p", { className: "inspector__striphead", children: "Stills from this video \u2014 click one to jump to that moment" }), _jsx("ul", { className: "inspector__stills", children: snapshots.map((still) => (_jsx("li", { children: _jsx(SnapshotChip, { onJump: () => seekTo(still.atSeconds ?? 0), still: still }) }, still.id))) })] })) : null] }));
748
+ }, resettable: isEnhanced(enhance) || upscale !== 1, value: enhance, children: onSaveSnapshot ? (_jsxs("label", { className: "picture__slider", htmlFor: "inspector-upscale", children: [_jsx("span", { children: "Save at" }), _jsx(SelectField, { id: "inspector-upscale", className: "w-auto", onValueChange: (value) => setUpscale(Number(value)), options: UPSCALE_FACTORS.map((factor) => ({
749
+ value: String(factor),
750
+ label: `${factor}× ${factor === 1 ? "(as-is)" : "upscaled"}`,
751
+ })), size: "sm", value: String(upscale) })] })) : null }), _jsxs("div", { className: "inspector__save", children: [onSaveSnapshot ? (_jsxs(_Fragment, { children: [_jsx(Button, { disabled: busy, onClick: () => void takeSnapshot(false), tooltip: isFullRegion(region)
752
+ ? "Save this frame as a picture"
753
+ : "Save just the part you are looking at", variant: "primary", children: isFullRegion(region) ? "Snapshot this frame" : "Snapshot this area" }), isFullRegion(region) ? null : (_jsx(Button, { disabled: busy, onClick: () => void takeSnapshot(true), tooltip: "Save the whole frame, ignoring the area you selected", variant: "secondary", children: "Snapshot whole frame" }))] })) : null, _jsx(Button, { "aria-expanded": gif !== null, disabled: gifProgress !== null, onClick: () => (gif ? closeGif() : markGif("start")), tooltip: gif
754
+ ? "Put the GIF away"
755
+ : "Turn a few seconds of this video into a looping GIF, starting here", variant: gif ? "primary" : "secondary", children: "Make a GIF" }), onSaveSnapshot || onSaveGif ? destination : null] }), gif ? (_jsxs("section", { "aria-label": "Make a GIF", className: "inspector__gif", children: [_jsxs("div", { className: "inspector__gifrange", children: [_jsx(Button, { disabled: gifProgress !== null, onClick: () => markGif("start"), tooltip: "Start the GIF at the playhead (I)", variant: "secondary", children: "Start here" }), _jsxs("span", { className: "inspector__gifspan", children: [_jsx("span", { children: formatGifTime(gif.startSeconds) }), _jsx("span", { "aria-hidden": "true", children: "\u2013" }), _jsx("span", { children: formatGifTime(gif.endSeconds) }), _jsxs("span", { className: "inspector__time", children: [(gif.endSeconds - gif.startSeconds).toFixed(1), " s", gif.endSeconds - gif.startSeconds >= MAX_GIF_SECONDS - 0.05 ? " · the longest a GIF can be" : ""] })] }), _jsx(Button, { disabled: gifProgress !== null, onClick: () => markGif("end"), tooltip: `End the GIF at the playhead (O) — up to ${MAX_GIF_SECONDS} s`, variant: "secondary", children: "End here" }), _jsx(Button, { "aria-pressed": loopSection, disabled: gifProgress !== null, onClick: () => setLoopSection((on) => !on), tooltip: loopSection
756
+ ? "Playing only the section, on a loop — press to play the whole video again"
757
+ : "Play only the section, on a loop, the way the GIF will", variant: loopSection ? "primary" : "ghost", children: "Loop section" })] }), _jsxs("div", { className: "inspector__gifout", children: [_jsxs("label", { className: "picture__slider", htmlFor: "inspector-gif-fps", children: [_jsx("span", { children: "Smoothness" }), _jsx(SelectField, { id: "inspector-gif-fps", className: "w-auto", disabled: gifProgress !== null, onValueChange: (value) => setGifFps(Number(value)), options: GIF_FRAME_RATES.map((fps) => ({ value: String(fps), label: `${fps} fps` })), size: "sm", value: String(gifFps) })] }), _jsxs("label", { className: "picture__slider", htmlFor: "inspector-gif-width", children: [_jsx("span", { children: "Width" }), _jsx(SelectField, { id: "inspector-gif-width", className: "w-auto", disabled: gifProgress !== null, onValueChange: (value) => setGifWidth(Number(value)), options: GIF_WIDTHS.map((width) => ({ value: String(width), label: `${width} px` })), size: "sm", value: String(gifWidth) })] }), gifProgress ? (_jsxs(_Fragment, { children: [_jsxs("span", { "aria-live": "polite", className: "inspector__time", children: ["Making the GIF \u2014 frame ", gifProgress[0], " of ", gifProgress[1]] }), _jsx(Button, { onClick: () => gifAbort.current?.abort(), tooltip: "Stop making this GIF", variant: "ghost", children: "Cancel" })] })) : (_jsxs(_Fragment, { children: [onSaveGif ? (_jsx(Button, { onClick: () => void makeGif("save"), tooltip: isFullRegion(region)
758
+ ? "Save the section as a looping GIF beside this video"
759
+ : "Save the section as a looping GIF — just the part you are looking at", variant: "primary", children: "Save GIF" })) : null, _jsx(Button, { onClick: () => void makeGif("download"), tooltip: isFullRegion(region)
760
+ ? "Download the section as a looping GIF"
761
+ : "Download the section as a looping GIF — just the part you are looking at", variant: onSaveGif ? "secondary" : "primary", children: onSaveGif ? "Download" : "Download GIF" })] }))] })] })) : null, error ? _jsx(Alert, { tone: "error", children: error }) : null, note && !error ? _jsx(Alert, { tone: "success", children: note }) : null, snapshots.length > 0 ? (_jsxs("div", { className: "inspector__strip", children: [_jsx("p", { className: "inspector__striphead", children: "Stills from this video \u2014 click one to jump to that moment" }), _jsx("ul", { className: "inspector__stills", children: snapshots.map((still) => (_jsx("li", { children: _jsx(SnapshotChip, { onJump: () => seekTo(still.atSeconds ?? 0), still: still }) }, still.id))) })] })) : null] }));
611
762
  }
612
763
  /**
613
764
  * One still in the strip. Its thumbnail is fetched lazily and per item, exactly like a
@@ -646,4 +797,17 @@ function marqueeStyle(rect) {
646
797
  height: `${box.h * 100}%`,
647
798
  };
648
799
  }
800
+ /** Hand a made file to the browser's own download — the GIF of a host with no store. */
801
+ function downloadBlob(blob, name) {
802
+ const url = URL.createObjectURL(blob);
803
+ const link = document.createElement("a");
804
+ link.href = url;
805
+ link.download = name;
806
+ link.rel = "noopener";
807
+ document.body.append(link);
808
+ link.click();
809
+ link.remove();
810
+ // After the click has been handed to the browser; revoking at once cancels it in Safari.
811
+ setTimeout(() => URL.revokeObjectURL(url), 30_000);
812
+ }
649
813
  //# sourceMappingURL=FocusViewer.js.map