@retor/react-native 0.4.0 → 0.4.1
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.
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +52 -9
- package/dist/index.mjs +52 -9
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -17,6 +17,8 @@ interface RetorTag {
|
|
|
17
17
|
tagType?: string;
|
|
18
18
|
iconName?: string;
|
|
19
19
|
objectId?: string;
|
|
20
|
+
/** 0..1 position along the parent line. Set on notes; computed from index for control tags. */
|
|
21
|
+
progress?: number;
|
|
20
22
|
}
|
|
21
23
|
interface RetorLine {
|
|
22
24
|
_id: string;
|
|
@@ -91,6 +93,10 @@ interface RetorBridgeContextValue {
|
|
|
91
93
|
lines: RetorLine[];
|
|
92
94
|
activeLineId: string | null;
|
|
93
95
|
activeLine: RetorLine | null;
|
|
96
|
+
/** Notes for the active line, pushed by the bridge from Convex. */
|
|
97
|
+
lineNotes: RetorTag[];
|
|
98
|
+
/** Notes injected by the consumer via the <Notes> sentinel. */
|
|
99
|
+
externalNotes: RetorTag[];
|
|
94
100
|
isAddNoteOpen: boolean;
|
|
95
101
|
addNoteTagId: string | null;
|
|
96
102
|
controls: ViewerHandle;
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ interface RetorTag {
|
|
|
17
17
|
tagType?: string;
|
|
18
18
|
iconName?: string;
|
|
19
19
|
objectId?: string;
|
|
20
|
+
/** 0..1 position along the parent line. Set on notes; computed from index for control tags. */
|
|
21
|
+
progress?: number;
|
|
20
22
|
}
|
|
21
23
|
interface RetorLine {
|
|
22
24
|
_id: string;
|
|
@@ -91,6 +93,10 @@ interface RetorBridgeContextValue {
|
|
|
91
93
|
lines: RetorLine[];
|
|
92
94
|
activeLineId: string | null;
|
|
93
95
|
activeLine: RetorLine | null;
|
|
96
|
+
/** Notes for the active line, pushed by the bridge from Convex. */
|
|
97
|
+
lineNotes: RetorTag[];
|
|
98
|
+
/** Notes injected by the consumer via the <Notes> sentinel. */
|
|
99
|
+
externalNotes: RetorTag[];
|
|
94
100
|
isAddNoteOpen: boolean;
|
|
95
101
|
addNoteTagId: string | null;
|
|
96
102
|
controls: ViewerHandle;
|
package/dist/index.js
CHANGED
|
@@ -75,6 +75,8 @@ var fallback = {
|
|
|
75
75
|
lines: [],
|
|
76
76
|
activeLineId: null,
|
|
77
77
|
activeLine: null,
|
|
78
|
+
lineNotes: [],
|
|
79
|
+
externalNotes: [],
|
|
78
80
|
isAddNoteOpen: false,
|
|
79
81
|
addNoteTagId: null,
|
|
80
82
|
controls: noopHandle,
|
|
@@ -213,6 +215,7 @@ var Viewer = (0, import_react2.forwardRef)(function Viewer2({ projectId, id = "d
|
|
|
213
215
|
const [isPlaying, setIsPlaying] = (0, import_react2.useState)(false);
|
|
214
216
|
const [isAddNoteOpen, setIsAddNoteOpen] = (0, import_react2.useState)(false);
|
|
215
217
|
const [addNoteTagId, setAddNoteTagId] = (0, import_react2.useState)(null);
|
|
218
|
+
const [lineNotes, setLineNotes] = (0, import_react2.useState)([]);
|
|
216
219
|
const uri = (0, import_react2.useMemo)(() => `${baseUrl}/p/${projectId}?vanilla=true`, [baseUrl, projectId]);
|
|
217
220
|
const send = (0, import_react2.useCallback)((type, payload) => {
|
|
218
221
|
const message = JSON.stringify({ source: "retor-host", type, payload });
|
|
@@ -302,9 +305,13 @@ var Viewer = (0, import_react2.forwardRef)(function Viewer2({ projectId, id = "d
|
|
|
302
305
|
progress: snap.progress,
|
|
303
306
|
distanceFromStart: snap.distanceFromStart
|
|
304
307
|
};
|
|
305
|
-
onNoteSubmitRef.current
|
|
308
|
+
if (onNoteSubmitRef.current) {
|
|
309
|
+
onNoteSubmitRef.current(payload);
|
|
310
|
+
} else {
|
|
311
|
+
send("note-submit", payload);
|
|
312
|
+
}
|
|
306
313
|
setIsAddNoteOpen(false);
|
|
307
|
-
}, []);
|
|
314
|
+
}, [send]);
|
|
308
315
|
const handleMessage = (0, import_react2.useCallback)(
|
|
309
316
|
(event) => {
|
|
310
317
|
let data = null;
|
|
@@ -335,6 +342,7 @@ var Viewer = (0, import_react2.forwardRef)(function Viewer2({ projectId, id = "d
|
|
|
335
342
|
case "line-close":
|
|
336
343
|
setActiveLineId(null);
|
|
337
344
|
setIsPlaying(false);
|
|
345
|
+
setLineNotes([]);
|
|
338
346
|
onLineClose?.();
|
|
339
347
|
break;
|
|
340
348
|
case "line-progress": {
|
|
@@ -346,6 +354,14 @@ var Viewer = (0, import_react2.forwardRef)(function Viewer2({ projectId, id = "d
|
|
|
346
354
|
onLineProgress?.(payload);
|
|
347
355
|
break;
|
|
348
356
|
}
|
|
357
|
+
case "line-notes": {
|
|
358
|
+
const payload = data.payload;
|
|
359
|
+
setLineNotes(payload.notes ?? []);
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
362
|
+
case "request-add-note":
|
|
363
|
+
openAddNote();
|
|
364
|
+
break;
|
|
349
365
|
case "autoplay-state": {
|
|
350
366
|
const payload = data.payload;
|
|
351
367
|
setIsPlaying(!!payload.playing);
|
|
@@ -355,18 +371,21 @@ var Viewer = (0, import_react2.forwardRef)(function Viewer2({ projectId, id = "d
|
|
|
355
371
|
onMessage?.(data.type, data.payload);
|
|
356
372
|
}
|
|
357
373
|
},
|
|
358
|
-
[notes, send, onInit, onLineOpen, onLineClose, onLineProgress, onMessage]
|
|
374
|
+
[notes, send, onInit, onLineOpen, onLineClose, onLineProgress, onMessage, openAddNote]
|
|
359
375
|
);
|
|
360
376
|
const activeLine = (0, import_react2.useMemo)(
|
|
361
377
|
() => lines.find((l) => l._id === activeLineId) ?? null,
|
|
362
378
|
[lines, activeLineId]
|
|
363
379
|
);
|
|
380
|
+
const externalNotes = (0, import_react2.useMemo)(() => notes ?? [], [notes]);
|
|
364
381
|
const ctxValue = (0, import_react2.useMemo)(
|
|
365
382
|
() => ({
|
|
366
383
|
project,
|
|
367
384
|
lines,
|
|
368
385
|
activeLineId,
|
|
369
386
|
activeLine,
|
|
387
|
+
lineNotes,
|
|
388
|
+
externalNotes,
|
|
370
389
|
isAddNoteOpen,
|
|
371
390
|
addNoteTagId,
|
|
372
391
|
controls,
|
|
@@ -374,7 +393,7 @@ var Viewer = (0, import_react2.forwardRef)(function Viewer2({ projectId, id = "d
|
|
|
374
393
|
closeAddNote,
|
|
375
394
|
submitNote
|
|
376
395
|
}),
|
|
377
|
-
[project, lines, activeLineId, activeLine, isAddNoteOpen, addNoteTagId, controls, openAddNote, closeAddNote, submitNote]
|
|
396
|
+
[project, lines, activeLineId, activeLine, lineNotes, externalNotes, isAddNoteOpen, addNoteTagId, controls, openAddNote, closeAddNote, submitNote]
|
|
378
397
|
);
|
|
379
398
|
const progressCtx = (0, import_react2.useMemo)(
|
|
380
399
|
() => ({ progress, closestTagId, targetPosition, distanceFromStart, isPlaying }),
|
|
@@ -557,6 +576,24 @@ var import_react_native5 = require("react-native");
|
|
|
557
576
|
var import_bottom_sheet3 = require("@gorhom/bottom-sheet");
|
|
558
577
|
var import_react_native_svg = __toESM(require("react-native-svg"));
|
|
559
578
|
var import_lucide_react_native2 = require("lucide-react-native");
|
|
579
|
+
|
|
580
|
+
// src/lineProgress.ts
|
|
581
|
+
function mergeLineTagsByProgress(controls, notes) {
|
|
582
|
+
const sortedControls = [...controls].sort((a, b) => (a.index ?? 0) - (b.index ?? 0));
|
|
583
|
+
const lastIdx = Math.max(1, sortedControls.length - 1);
|
|
584
|
+
const merged = [];
|
|
585
|
+
for (const c of sortedControls) {
|
|
586
|
+
const idx = c.index ?? 0;
|
|
587
|
+
merged.push({ ...c, _isNote: false, progress: idx / lastIdx });
|
|
588
|
+
}
|
|
589
|
+
for (const n of notes) {
|
|
590
|
+
merged.push({ ...n, _isNote: true, progress: n.progress ?? 0 });
|
|
591
|
+
}
|
|
592
|
+
merged.sort((a, b) => a.progress - b.progress);
|
|
593
|
+
return merged;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
// src/LineDetailSheet.tsx
|
|
560
597
|
var renderBackdrop2 = (props) => /* @__PURE__ */ import_react6.default.createElement(
|
|
561
598
|
import_bottom_sheet3.BottomSheetBackdrop,
|
|
562
599
|
{
|
|
@@ -648,14 +685,20 @@ function AutoplayButton() {
|
|
|
648
685
|
)), isPlaying ? /* @__PURE__ */ import_react6.default.createElement(import_lucide_react_native2.Pause, { size: 11, color: "white", fill: "white" }) : /* @__PURE__ */ import_react6.default.createElement(import_lucide_react_native2.Play, { size: 11, color: "white", fill: "white", style: { marginLeft: 1 } }));
|
|
649
686
|
}
|
|
650
687
|
function LineTagList({ children, listHeader }) {
|
|
651
|
-
const { activeLine } = useRetorBridge();
|
|
688
|
+
const { activeLine, lineNotes, externalNotes } = useRetorBridge();
|
|
652
689
|
const { closestTagId } = useRetorProgress();
|
|
653
690
|
const scrollRef = (0, import_react6.useRef)(null);
|
|
654
691
|
const offsetsRef = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
|
|
655
|
-
const tags = (0, import_react6.useMemo)(
|
|
656
|
-
|
|
657
|
-
[
|
|
658
|
-
|
|
692
|
+
const tags = (0, import_react6.useMemo)(() => {
|
|
693
|
+
if (!activeLine) return [];
|
|
694
|
+
const controls = (activeLine.tags ?? []).filter(
|
|
695
|
+
(t) => t.name && t.name.trim().length > 0
|
|
696
|
+
);
|
|
697
|
+
const allNotes = [...lineNotes, ...externalNotes].filter(
|
|
698
|
+
(n) => n.name && n.name.trim().length > 0
|
|
699
|
+
);
|
|
700
|
+
return mergeLineTagsByProgress(controls, allNotes);
|
|
701
|
+
}, [activeLine, lineNotes, externalNotes]);
|
|
659
702
|
(0, import_react6.useEffect)(() => {
|
|
660
703
|
offsetsRef.current = /* @__PURE__ */ new Map();
|
|
661
704
|
}, [activeLine?._id]);
|
package/dist/index.mjs
CHANGED
|
@@ -22,6 +22,8 @@ var fallback = {
|
|
|
22
22
|
lines: [],
|
|
23
23
|
activeLineId: null,
|
|
24
24
|
activeLine: null,
|
|
25
|
+
lineNotes: [],
|
|
26
|
+
externalNotes: [],
|
|
25
27
|
isAddNoteOpen: false,
|
|
26
28
|
addNoteTagId: null,
|
|
27
29
|
controls: noopHandle,
|
|
@@ -169,6 +171,7 @@ var Viewer = forwardRef(function Viewer2({ projectId, id = "default", baseUrl =
|
|
|
169
171
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
170
172
|
const [isAddNoteOpen, setIsAddNoteOpen] = useState(false);
|
|
171
173
|
const [addNoteTagId, setAddNoteTagId] = useState(null);
|
|
174
|
+
const [lineNotes, setLineNotes] = useState([]);
|
|
172
175
|
const uri = useMemo2(() => `${baseUrl}/p/${projectId}?vanilla=true`, [baseUrl, projectId]);
|
|
173
176
|
const send = useCallback((type, payload) => {
|
|
174
177
|
const message = JSON.stringify({ source: "retor-host", type, payload });
|
|
@@ -258,9 +261,13 @@ var Viewer = forwardRef(function Viewer2({ projectId, id = "default", baseUrl =
|
|
|
258
261
|
progress: snap.progress,
|
|
259
262
|
distanceFromStart: snap.distanceFromStart
|
|
260
263
|
};
|
|
261
|
-
onNoteSubmitRef.current
|
|
264
|
+
if (onNoteSubmitRef.current) {
|
|
265
|
+
onNoteSubmitRef.current(payload);
|
|
266
|
+
} else {
|
|
267
|
+
send("note-submit", payload);
|
|
268
|
+
}
|
|
262
269
|
setIsAddNoteOpen(false);
|
|
263
|
-
}, []);
|
|
270
|
+
}, [send]);
|
|
264
271
|
const handleMessage = useCallback(
|
|
265
272
|
(event) => {
|
|
266
273
|
let data = null;
|
|
@@ -291,6 +298,7 @@ var Viewer = forwardRef(function Viewer2({ projectId, id = "default", baseUrl =
|
|
|
291
298
|
case "line-close":
|
|
292
299
|
setActiveLineId(null);
|
|
293
300
|
setIsPlaying(false);
|
|
301
|
+
setLineNotes([]);
|
|
294
302
|
onLineClose?.();
|
|
295
303
|
break;
|
|
296
304
|
case "line-progress": {
|
|
@@ -302,6 +310,14 @@ var Viewer = forwardRef(function Viewer2({ projectId, id = "default", baseUrl =
|
|
|
302
310
|
onLineProgress?.(payload);
|
|
303
311
|
break;
|
|
304
312
|
}
|
|
313
|
+
case "line-notes": {
|
|
314
|
+
const payload = data.payload;
|
|
315
|
+
setLineNotes(payload.notes ?? []);
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
case "request-add-note":
|
|
319
|
+
openAddNote();
|
|
320
|
+
break;
|
|
305
321
|
case "autoplay-state": {
|
|
306
322
|
const payload = data.payload;
|
|
307
323
|
setIsPlaying(!!payload.playing);
|
|
@@ -311,18 +327,21 @@ var Viewer = forwardRef(function Viewer2({ projectId, id = "default", baseUrl =
|
|
|
311
327
|
onMessage?.(data.type, data.payload);
|
|
312
328
|
}
|
|
313
329
|
},
|
|
314
|
-
[notes, send, onInit, onLineOpen, onLineClose, onLineProgress, onMessage]
|
|
330
|
+
[notes, send, onInit, onLineOpen, onLineClose, onLineProgress, onMessage, openAddNote]
|
|
315
331
|
);
|
|
316
332
|
const activeLine = useMemo2(
|
|
317
333
|
() => lines.find((l) => l._id === activeLineId) ?? null,
|
|
318
334
|
[lines, activeLineId]
|
|
319
335
|
);
|
|
336
|
+
const externalNotes = useMemo2(() => notes ?? [], [notes]);
|
|
320
337
|
const ctxValue = useMemo2(
|
|
321
338
|
() => ({
|
|
322
339
|
project,
|
|
323
340
|
lines,
|
|
324
341
|
activeLineId,
|
|
325
342
|
activeLine,
|
|
343
|
+
lineNotes,
|
|
344
|
+
externalNotes,
|
|
326
345
|
isAddNoteOpen,
|
|
327
346
|
addNoteTagId,
|
|
328
347
|
controls,
|
|
@@ -330,7 +349,7 @@ var Viewer = forwardRef(function Viewer2({ projectId, id = "default", baseUrl =
|
|
|
330
349
|
closeAddNote,
|
|
331
350
|
submitNote
|
|
332
351
|
}),
|
|
333
|
-
[project, lines, activeLineId, activeLine, isAddNoteOpen, addNoteTagId, controls, openAddNote, closeAddNote, submitNote]
|
|
352
|
+
[project, lines, activeLineId, activeLine, lineNotes, externalNotes, isAddNoteOpen, addNoteTagId, controls, openAddNote, closeAddNote, submitNote]
|
|
334
353
|
);
|
|
335
354
|
const progressCtx = useMemo2(
|
|
336
355
|
() => ({ progress, closestTagId, targetPosition, distanceFromStart, isPlaying }),
|
|
@@ -518,6 +537,24 @@ import {
|
|
|
518
537
|
} from "@gorhom/bottom-sheet";
|
|
519
538
|
import Svg, { Circle } from "react-native-svg";
|
|
520
539
|
import { ArrowDown as ArrowDown2, ArrowUp as ArrowUp2, Pause, Play, Plus } from "lucide-react-native";
|
|
540
|
+
|
|
541
|
+
// src/lineProgress.ts
|
|
542
|
+
function mergeLineTagsByProgress(controls, notes) {
|
|
543
|
+
const sortedControls = [...controls].sort((a, b) => (a.index ?? 0) - (b.index ?? 0));
|
|
544
|
+
const lastIdx = Math.max(1, sortedControls.length - 1);
|
|
545
|
+
const merged = [];
|
|
546
|
+
for (const c of sortedControls) {
|
|
547
|
+
const idx = c.index ?? 0;
|
|
548
|
+
merged.push({ ...c, _isNote: false, progress: idx / lastIdx });
|
|
549
|
+
}
|
|
550
|
+
for (const n of notes) {
|
|
551
|
+
merged.push({ ...n, _isNote: true, progress: n.progress ?? 0 });
|
|
552
|
+
}
|
|
553
|
+
merged.sort((a, b) => a.progress - b.progress);
|
|
554
|
+
return merged;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// src/LineDetailSheet.tsx
|
|
521
558
|
var renderBackdrop2 = (props) => /* @__PURE__ */ React6.createElement(
|
|
522
559
|
BottomSheetBackdrop2,
|
|
523
560
|
{
|
|
@@ -609,14 +646,20 @@ function AutoplayButton() {
|
|
|
609
646
|
)), isPlaying ? /* @__PURE__ */ React6.createElement(Pause, { size: 11, color: "white", fill: "white" }) : /* @__PURE__ */ React6.createElement(Play, { size: 11, color: "white", fill: "white", style: { marginLeft: 1 } }));
|
|
610
647
|
}
|
|
611
648
|
function LineTagList({ children, listHeader }) {
|
|
612
|
-
const { activeLine } = useRetorBridge();
|
|
649
|
+
const { activeLine, lineNotes, externalNotes } = useRetorBridge();
|
|
613
650
|
const { closestTagId } = useRetorProgress();
|
|
614
651
|
const scrollRef = useRef3(null);
|
|
615
652
|
const offsetsRef = useRef3(/* @__PURE__ */ new Map());
|
|
616
|
-
const tags = useMemo4(
|
|
617
|
-
|
|
618
|
-
[
|
|
619
|
-
|
|
653
|
+
const tags = useMemo4(() => {
|
|
654
|
+
if (!activeLine) return [];
|
|
655
|
+
const controls = (activeLine.tags ?? []).filter(
|
|
656
|
+
(t) => t.name && t.name.trim().length > 0
|
|
657
|
+
);
|
|
658
|
+
const allNotes = [...lineNotes, ...externalNotes].filter(
|
|
659
|
+
(n) => n.name && n.name.trim().length > 0
|
|
660
|
+
);
|
|
661
|
+
return mergeLineTagsByProgress(controls, allNotes);
|
|
662
|
+
}, [activeLine, lineNotes, externalNotes]);
|
|
620
663
|
useEffect3(() => {
|
|
621
664
|
offsetsRef.current = /* @__PURE__ */ new Map();
|
|
622
665
|
}, [activeLine?._id]);
|