@adminide-stack/yantra-mobile 12.0.136-alpha.1 → 12.0.136

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 (37) hide show
  1. package/lib/compute.js +51 -1
  2. package/lib/compute.js.map +1 -1
  3. package/lib/features/apps/AppsCatalog.js +10 -0
  4. package/lib/features/apps/AppsCatalog.js.map +1 -1
  5. package/lib/features/apps/mobileAppCatalog.js +9 -0
  6. package/lib/features/apps/mobileAppCatalog.js.map +1 -1
  7. package/lib/features/apps/nativeSurfaceTwin.js +1 -0
  8. package/lib/features/apps/nativeSurfaceTwin.js.map +1 -1
  9. package/lib/features/devices/bodyComposition.js +116 -0
  10. package/lib/features/devices/bodyComposition.js.map +1 -0
  11. package/lib/features/devices/readings.js.map +1 -1
  12. package/lib/features/devices/session.js +22 -2
  13. package/lib/features/devices/session.js.map +1 -1
  14. package/lib/features/dictate/DictateExperience.js +387 -0
  15. package/lib/features/dictate/DictateExperience.js.map +1 -0
  16. package/lib/features/dictate/components/DictationList.js +110 -0
  17. package/lib/features/dictate/components/DictationList.js.map +1 -0
  18. package/lib/features/dictate/components/NoteView.js +330 -0
  19. package/lib/features/dictate/components/NoteView.js.map +1 -0
  20. package/lib/features/dictate/components/RecordPanel.js +218 -0
  21. package/lib/features/dictate/components/RecordPanel.js.map +1 -0
  22. package/lib/features/dictate/dictateClient.js +98 -0
  23. package/lib/features/dictate/dictateClient.js.map +1 -0
  24. package/lib/features/dictate/dictateTheme.js +46 -0
  25. package/lib/features/dictate/dictateTheme.js.map +1 -0
  26. package/lib/features/dictate/dictationStore.js +107 -0
  27. package/lib/features/dictate/dictationStore.js.map +1 -0
  28. package/lib/features/dictate/noteText.js +35 -0
  29. package/lib/features/dictate/noteText.js.map +1 -0
  30. package/lib/features/dictate/useDictationRecorder.js +121 -0
  31. package/lib/features/dictate/useDictationRecorder.js.map +1 -0
  32. package/lib/routes.json +50 -0
  33. package/lib/screens/Devices/index.js +205 -3
  34. package/lib/screens/Devices/index.js.map +1 -1
  35. package/lib/screens/DictateNative/index.js +36 -0
  36. package/lib/screens/DictateNative/index.js.map +1 -0
  37. package/package.json +4 -4
@@ -0,0 +1,387 @@
1
+ import {jsxs,jsx,Fragment}from'react/jsx-runtime';import {useMemo,useState,useRef,useCallback,useEffect}from'react';import {Alert,BackHandler,Share,View,StyleSheet,Text,ScrollView,Linking}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {useSafeInsets}from'../canvas/withRemoteSafeArea.js';import {createRemoteUploadMedia,createRemoteConnectorExec}from'../canvas/videoEditor/remoteMediaClient.js';import {useAppTheme}from'../../theme/AppThemeProvider.js';import {Tap,DIM}from'../inbox/components/Tap.js';import {DictationList}from'./components/DictationList.js';import {NoteView}from'./components/NoteView.js';import {RecordingPanel,StartPanel}from'./components/RecordPanel.js';import {writeNoteFromRecording,dictateErrorText}from'./dictateClient.js';import {dictateTheme}from'./dictateTheme.js';import {createDictationStore}from'./dictationStore.js';import {noteToText}from'./noteText.js';import {useDictationRecorder,MicrophoneDeniedError}from'./useDictationRecorder.js';var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __restKey = (key) => typeof key === "symbol" ? key : key + "";
21
+ var __objRest = (source, exclude) => {
22
+ var target = {};
23
+ for (var prop in source)
24
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
+ target[prop] = source[prop];
26
+ if (source != null && __getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(source)) {
28
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
+ target[prop] = source[prop];
30
+ }
31
+ return target;
32
+ };
33
+ const PREVIEW_NOTICE = "Preview: dictate made-up visits only. Real patient information needs your practice\u2019s HIPAA agreement with Yantra first.";
34
+ function DictateExperience({
35
+ isDark: hostDark,
36
+ token,
37
+ indexUrl,
38
+ sessionError,
39
+ onRetrySession,
40
+ onExit,
41
+ deps,
42
+ store: injectedStore
43
+ }) {
44
+ var _a, _b;
45
+ const appTheme = useAppTheme();
46
+ const theme = useMemo(() => dictateTheme(hostDark != null ? hostDark : appTheme.isDark), [hostDark, appTheme.isDark]);
47
+ const insets = useSafeInsets();
48
+ const store = useMemo(() => injectedStore != null ? injectedStore : createDictationStore(), [injectedStore]);
49
+ const recorder = useDictationRecorder();
50
+ const [screen, setScreen] = useState({
51
+ kind: "home"
52
+ });
53
+ const [records, setRecords] = useState([]);
54
+ const [stages, setStages] = useState({});
55
+ const [starting, setStarting] = useState(false);
56
+ const [error, setError] = useState(null);
57
+ const [micDenied, setMicDenied] = useState(false);
58
+ const tokenRef = useRef(token);
59
+ tokenRef.current = token;
60
+ const agent = useMemo(() => deps != null ? deps : {
61
+ exec: (connector, action, params, options) => {
62
+ const current = tokenRef.current;
63
+ if (!current) return Promise.reject(new Error("Network request failed: not signed in yet"));
64
+ return createRemoteConnectorExec(current, indexUrl)(connector, action, params, options);
65
+ },
66
+ upload: (uri) => {
67
+ const current = tokenRef.current;
68
+ if (!current) return Promise.reject(new Error("Network request failed: not signed in yet"));
69
+ return createRemoteUploadMedia(current, indexUrl)(uri);
70
+ }
71
+ }, [deps, indexUrl]);
72
+ const refresh = useCallback(async () => setRecords(await store.list()), [store]);
73
+ useEffect(() => {
74
+ void (async () => {
75
+ for (const r of await store.list()) {
76
+ if (r.status === "writing") await store.update(r.id, {
77
+ status: r.audioUri ? "saved" : "failed"
78
+ });
79
+ }
80
+ await refresh();
81
+ })();
82
+ }, [store, refresh]);
83
+ const write = useCallback(async (record) => {
84
+ var _b2;
85
+ if (!record.audioUri) return;
86
+ setStages((s) => __spreadProps(__spreadValues({}, s), {
87
+ [record.id]: "uploading"
88
+ }));
89
+ await store.update(record.id, {
90
+ status: "writing",
91
+ error: void 0
92
+ });
93
+ await refresh();
94
+ try {
95
+ const written = await writeNoteFromRecording(record.audioUri, agent, {}, (stage) => setStages((s) => __spreadProps(__spreadValues({}, s), {
96
+ [record.id]: stage
97
+ })));
98
+ await store.update(record.id, {
99
+ status: "ready",
100
+ note: written.note,
101
+ transcript: written.transcript,
102
+ model: written.model,
103
+ error: void 0
104
+ });
105
+ await store.dropAudio(record.id);
106
+ } catch (err) {
107
+ await store.update(record.id, {
108
+ status: "failed",
109
+ error: dictateErrorText(err)
110
+ });
111
+ } finally {
112
+ setStages((_a2) => {
113
+ var _c = _a2, {
114
+ [_b2 = record.id]: _done
115
+ } = _c, rest = __objRest(_c, [
116
+ __restKey(_b2)
117
+ ]);
118
+ return rest;
119
+ });
120
+ await refresh();
121
+ }
122
+ }, [agent, store, refresh]);
123
+ const start = useCallback(async () => {
124
+ setError(null);
125
+ setStarting(true);
126
+ try {
127
+ await recorder.start();
128
+ setMicDenied(false);
129
+ setScreen({
130
+ kind: "record"
131
+ });
132
+ } catch (err) {
133
+ if (err instanceof MicrophoneDeniedError) setMicDenied(true);
134
+ else setError("The microphone could not start. Try again.");
135
+ } finally {
136
+ setStarting(false);
137
+ }
138
+ }, [recorder]);
139
+ const done = useCallback(async () => {
140
+ const out = await recorder.finish();
141
+ if (!out) {
142
+ setScreen({
143
+ kind: "home"
144
+ });
145
+ setError("The recording could not be saved. Try again.");
146
+ return;
147
+ }
148
+ const record = await store.keepRecording(out.uri, out.durationMs);
149
+ await refresh();
150
+ setScreen({
151
+ kind: "note",
152
+ id: record.id
153
+ });
154
+ void write(record);
155
+ }, [recorder, store, refresh, write]);
156
+ const discard = useCallback(() => {
157
+ Alert.alert("Discard this dictation?", "The recording is deleted and no note is written.", [{
158
+ text: "Keep dictating",
159
+ style: "cancel"
160
+ }, {
161
+ text: "Discard",
162
+ style: "destructive",
163
+ onPress: () => {
164
+ void (async () => {
165
+ const out = await recorder.finish();
166
+ if (out) await store.discardRecording(out.uri);
167
+ setScreen({
168
+ kind: "home"
169
+ });
170
+ })();
171
+ }
172
+ }]);
173
+ }, [recorder, store]);
174
+ const back = useCallback(() => {
175
+ if (screen.kind === "record") {
176
+ if (recorder.phase === "recording") recorder.pause();
177
+ Alert.alert("Stop dictating?", "Write the note from what you have recorded, or discard it.", [{
178
+ text: "Keep dictating",
179
+ style: "cancel"
180
+ }, {
181
+ text: "Write the note",
182
+ onPress: () => void done()
183
+ }, {
184
+ text: "Discard",
185
+ style: "destructive",
186
+ onPress: () => {
187
+ void (async () => {
188
+ const out = await recorder.finish();
189
+ if (out) await store.discardRecording(out.uri);
190
+ setScreen({
191
+ kind: "home"
192
+ });
193
+ })();
194
+ }
195
+ }]);
196
+ return true;
197
+ }
198
+ if (screen.kind === "note") {
199
+ setScreen({
200
+ kind: "home"
201
+ });
202
+ return true;
203
+ }
204
+ onExit();
205
+ return true;
206
+ }, [screen.kind, recorder, done, store, onExit]);
207
+ useEffect(() => {
208
+ const sub = BackHandler.addEventListener("hardwareBackPress", back);
209
+ return () => sub.remove();
210
+ }, [back]);
211
+ const open = screen.kind === "note" ? (_a = records.find((r) => r.id === screen.id)) != null ? _a : null : null;
212
+ const share = useCallback(() => {
213
+ if (!(open == null ? void 0 : open.note)) return;
214
+ void Share.share({
215
+ title: open.note.title,
216
+ message: noteToText(open.note)
217
+ });
218
+ }, [open]);
219
+ const remove = useCallback(() => {
220
+ if (!open) return;
221
+ Alert.alert("Delete this dictation?", "The note and transcript are removed from this phone.", [{
222
+ text: "Cancel",
223
+ style: "cancel"
224
+ }, {
225
+ text: "Delete",
226
+ style: "destructive",
227
+ onPress: () => {
228
+ void (async () => {
229
+ await store.remove(open.id);
230
+ await refresh();
231
+ setScreen({
232
+ kind: "home"
233
+ });
234
+ })();
235
+ }
236
+ }]);
237
+ }, [open, store, refresh]);
238
+ const title = screen.kind === "note" ? "Note" : "Dictate";
239
+ return /* @__PURE__ */ jsxs(View, { style: [styles.screen, {
240
+ backgroundColor: theme.screen,
241
+ paddingTop: insets.top
242
+ }], children: [
243
+ /* @__PURE__ */ jsxs(View, { style: [styles.header, {
244
+ borderBottomColor: theme.border
245
+ }], children: [
246
+ /* @__PURE__ */ jsx(Tap, { onPress: back, accessibilityRole: "button", accessibilityLabel: "Back", style: styles.headerButton, pressedStyle: DIM, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chevron-left", size: 28, color: theme.ink }) }),
247
+ /* @__PURE__ */ jsx(Text, { style: [styles.headerTitle, {
248
+ color: theme.ink
249
+ }], children: title }),
250
+ /* @__PURE__ */ jsx(View, { style: styles.headerActions, children: (open == null ? void 0 : open.note) ? /* @__PURE__ */ jsxs(Fragment, { children: [
251
+ /* @__PURE__ */ jsx(Tap, { onPress: share, accessibilityRole: "button", accessibilityLabel: "Share the note", style: styles.headerButton, pressedStyle: DIM, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "export-variant", size: 22, color: theme.ink }) }),
252
+ /* @__PURE__ */ jsx(Tap, { onPress: remove, accessibilityRole: "button", accessibilityLabel: "Delete", style: styles.headerButton, pressedStyle: DIM, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "trash-can-outline", size: 22, color: theme.ink }) })
253
+ ] }) : null })
254
+ ] }),
255
+ screen.kind === "note" && open ? /* @__PURE__ */ jsx(NoteView, { record: open, stage: (_b = stages[open.id]) != null ? _b : null, theme, bottomInset: insets.bottom, onRetry: () => void write(open) }) : screen.kind === "record" && recorder.phase !== "idle" ? /* @__PURE__ */ jsx(View, { style: styles.recordBody, children: /* @__PURE__ */ jsx(RecordingPanel, { theme, phase: recorder.phase, pauseReason: recorder.pauseReason, elapsedMs: recorder.elapsedMs, level: recorder.level, onPause: recorder.pause, onResume: recorder.resume, onDone: () => void done(), onDiscard: discard }) }) : /* @__PURE__ */ jsxs(ScrollView, { contentContainerStyle: [styles.home, {
256
+ paddingBottom: 24 + insets.bottom
257
+ }], children: [
258
+ /* @__PURE__ */ jsx(Text, { style: [styles.lead, {
259
+ color: theme.ink
260
+ }], children: "Dictate a visit" }),
261
+ /* @__PURE__ */ jsx(Text, { style: [styles.leadDetail, {
262
+ color: theme.muted
263
+ }], children: "Speak your note. Yantra writes it up as a SOAP note and lists what to check before you use it." }),
264
+ /* @__PURE__ */ jsx(StartPanel, { theme, starting, onStart: () => void start() }),
265
+ error ? /* @__PURE__ */ jsx(Text, { style: [styles.error, {
266
+ color: theme.crit
267
+ }], children: error }) : null,
268
+ micDenied ? /* @__PURE__ */ jsxs(View, { style: [styles.banner, {
269
+ backgroundColor: theme.recSoft
270
+ }], children: [
271
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "microphone-off", size: 18, color: theme.crit }),
272
+ /* @__PURE__ */ jsx(Text, { style: [styles.bannerText, {
273
+ color: theme.crit
274
+ }], children: "Microphone access is off for Yantra." }),
275
+ /* @__PURE__ */ jsx(Tap, { onPress: () => void Linking.openSettings(), accessibilityRole: "button", style: [styles.bannerAction, {
276
+ backgroundColor: theme.card,
277
+ borderColor: theme.border
278
+ }], pressedStyle: DIM, children: /* @__PURE__ */ jsx(Text, { style: [styles.bannerActionText, {
279
+ color: theme.ink
280
+ }], children: "Open Settings" }) })
281
+ ] }) : null,
282
+ sessionError ? /* @__PURE__ */ jsx(Tap, { onPress: onRetrySession, accessibilityRole: "button", style: [styles.banner, {
283
+ backgroundColor: theme.recSoft
284
+ }], pressedStyle: DIM, children: /* @__PURE__ */ jsx(Text, { style: [styles.bannerText, {
285
+ color: theme.crit
286
+ }], children: "Not connected, so notes cannot be written yet. Tap to retry." }) }) : null,
287
+ /* @__PURE__ */ jsxs(View, { style: [styles.banner, {
288
+ backgroundColor: theme.warnSoft,
289
+ borderColor: theme.warnBorder,
290
+ borderWidth: StyleSheet.hairlineWidth
291
+ }], children: [
292
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "shield-alert-outline", size: 18, color: theme.warnInk }),
293
+ /* @__PURE__ */ jsx(Text, { style: [styles.bannerText, {
294
+ color: theme.warnInk
295
+ }], children: PREVIEW_NOTICE })
296
+ ] }),
297
+ /* @__PURE__ */ jsx(Text, { style: [styles.sectionLabel, {
298
+ color: theme.muted
299
+ }], children: "RECENT" }),
300
+ /* @__PURE__ */ jsx(DictationList, { records, theme, onOpen: (r) => setScreen({
301
+ kind: "note",
302
+ id: r.id
303
+ }) })
304
+ ] })
305
+ ] });
306
+ }
307
+ const styles = StyleSheet.create({
308
+ screen: {
309
+ flex: 1
310
+ },
311
+ header: {
312
+ height: 52,
313
+ flexDirection: "row",
314
+ alignItems: "center",
315
+ paddingHorizontal: 4,
316
+ borderBottomWidth: StyleSheet.hairlineWidth
317
+ },
318
+ headerButton: {
319
+ width: 44,
320
+ height: 44,
321
+ alignItems: "center",
322
+ justifyContent: "center"
323
+ },
324
+ headerTitle: {
325
+ flex: 1,
326
+ fontSize: 17,
327
+ fontWeight: "600"
328
+ },
329
+ headerActions: {
330
+ flexDirection: "row",
331
+ alignItems: "center"
332
+ },
333
+ home: {
334
+ paddingHorizontal: 16,
335
+ paddingTop: 20
336
+ },
337
+ lead: {
338
+ fontSize: 24,
339
+ fontWeight: "700"
340
+ },
341
+ leadDetail: {
342
+ marginTop: 6,
343
+ fontSize: 15,
344
+ lineHeight: 21
345
+ },
346
+ error: {
347
+ textAlign: "center",
348
+ fontSize: 13,
349
+ marginBottom: 8
350
+ },
351
+ banner: {
352
+ flexDirection: "row",
353
+ alignItems: "center",
354
+ gap: 10,
355
+ borderRadius: 12,
356
+ paddingHorizontal: 12,
357
+ paddingVertical: 10,
358
+ marginBottom: 12
359
+ },
360
+ bannerText: {
361
+ flex: 1,
362
+ fontSize: 13,
363
+ lineHeight: 18
364
+ },
365
+ bannerAction: {
366
+ paddingHorizontal: 12,
367
+ paddingVertical: 7,
368
+ borderRadius: 999,
369
+ borderWidth: StyleSheet.hairlineWidth
370
+ },
371
+ bannerActionText: {
372
+ fontSize: 13,
373
+ fontWeight: "600"
374
+ },
375
+ sectionLabel: {
376
+ marginTop: 12,
377
+ marginBottom: 8,
378
+ fontSize: 12,
379
+ fontWeight: "700",
380
+ letterSpacing: 0.8
381
+ },
382
+ recordBody: {
383
+ flex: 1,
384
+ justifyContent: "center",
385
+ paddingHorizontal: 16
386
+ }
387
+ });export{DictateExperience,PREVIEW_NOTICE,DictateExperience as default};//# sourceMappingURL=DictateExperience.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DictateExperience.js","sources":["../../../src/features/dictate/DictateExperience.tsx"],"sourcesContent":["/**\n * Dictate: a clinician speaks a visit note; Yantra writes it up as a SOAP note\n * with the points to check before it is used.\n *\n * Record (screen kept awake, paused honestly if the app leaves the screen) ->\n * the recording is kept on the phone at once -> uploaded and handed to\n * YANTRA_MEETINGS_CLINICAL_NOTE (medical speech-to-text, then the note) ->\n * the note is saved on the phone and the recording deleted. A note that could\n * not be written keeps its recording for Retry, across restarts.\n *\n * The host screen passes the session (token + surface index URL); everything\n * else - the recorder, the store, the agent calls - lives here.\n */\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { Alert, BackHandler, Linking, ScrollView, Share, StyleSheet, Text, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { useSafeInsets } from '../canvas/withRemoteSafeArea';\nimport { createRemoteConnectorExec, createRemoteUploadMedia } from '../canvas/videoEditor/remoteMediaClient';\nimport { useAppTheme } from '../../theme/AppThemeProvider';\nimport { DIM, Tap } from '../inbox/components/Tap';\nimport { DictationList } from './components/DictationList';\nimport { NoteView } from './components/NoteView';\nimport { RecordingPanel, StartPanel } from './components/RecordPanel';\nimport { dictateErrorText, writeNoteFromRecording, type DictateDeps, type DictateStage } from './dictateClient';\nimport { dictateTheme } from './dictateTheme';\nimport { createDictationStore, type DictationStore } from './dictationStore';\nimport { noteToText } from './noteText';\nimport type { DictationRecord } from './types';\nimport { MicrophoneDeniedError, useDictationRecorder } from './useDictationRecorder';\n\nexport interface DictateExperienceProps {\n isDark?: boolean;\n token?: string | null;\n /** The surface index URL; the agent (uploads, the note) is derived from it. */\n indexUrl: string;\n sessionError?: string | null;\n onRetrySession?: () => void;\n onExit: () => void;\n /** Tests and previews inject these; the app builds them from the session. */\n deps?: DictateDeps;\n store?: DictationStore;\n}\n\ntype Screen = { kind: 'home' } | { kind: 'record' } | { kind: 'note'; id: string };\n\nexport const PREVIEW_NOTICE =\n 'Preview: dictate made-up visits only. Real patient information needs your practice’s HIPAA agreement with Yantra first.';\n\nexport function DictateExperience({ isDark: hostDark, token, indexUrl, sessionError, onRetrySession, onExit, deps, store: injectedStore }: DictateExperienceProps) {\n const appTheme = useAppTheme();\n const theme = useMemo(() => dictateTheme(hostDark ?? appTheme.isDark), [hostDark, appTheme.isDark]);\n const insets = useSafeInsets();\n const store = useMemo(() => injectedStore ?? createDictationStore(), [injectedStore]);\n const recorder = useDictationRecorder();\n const [screen, setScreen] = useState<Screen>({ kind: 'home' });\n const [records, setRecords] = useState<DictationRecord[]>([]);\n const [stages, setStages] = useState<Record<string, DictateStage>>({});\n const [starting, setStarting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [micDenied, setMicDenied] = useState(false);\n\n const tokenRef = useRef(token);\n tokenRef.current = token;\n const agent = useMemo<DictateDeps>(\n () =>\n deps ?? {\n exec: (connector, action, params, options) => {\n const current = tokenRef.current;\n if (!current) return Promise.reject(new Error('Network request failed: not signed in yet'));\n return createRemoteConnectorExec(current, indexUrl)(connector, action, params, options);\n },\n upload: (uri) => {\n const current = tokenRef.current;\n if (!current) return Promise.reject(new Error('Network request failed: not signed in yet'));\n return createRemoteUploadMedia(current, indexUrl)(uri);\n },\n },\n [deps, indexUrl],\n );\n\n const refresh = useCallback(async () => setRecords(await store.list()), [store]);\n\n // A note being written when the app last closed never finished: offer it again.\n useEffect(() => {\n void (async () => {\n for (const r of await store.list()) {\n if (r.status === 'writing') await store.update(r.id, { status: r.audioUri ? 'saved' : 'failed' });\n }\n await refresh();\n })();\n }, [store, refresh]);\n\n const write = useCallback(\n async (record: DictationRecord) => {\n if (!record.audioUri) return;\n setStages((s) => ({ ...s, [record.id]: 'uploading' }));\n await store.update(record.id, { status: 'writing', error: undefined });\n await refresh();\n try {\n const written = await writeNoteFromRecording(record.audioUri, agent, {}, (stage) =>\n setStages((s) => ({ ...s, [record.id]: stage })),\n );\n await store.update(record.id, { status: 'ready', note: written.note, transcript: written.transcript, model: written.model, error: undefined });\n await store.dropAudio(record.id);\n } catch (err) {\n await store.update(record.id, { status: 'failed', error: dictateErrorText(err) });\n } finally {\n setStages(({ [record.id]: _done, ...rest }) => rest);\n await refresh();\n }\n },\n [agent, store, refresh],\n );\n\n const start = useCallback(async () => {\n setError(null);\n setStarting(true);\n try {\n await recorder.start();\n setMicDenied(false);\n setScreen({ kind: 'record' });\n } catch (err) {\n // A declined microphone is not an error to retry: it is a setting, so offer the way there.\n if (err instanceof MicrophoneDeniedError) setMicDenied(true);\n else setError('The microphone could not start. Try again.');\n } finally {\n setStarting(false);\n }\n }, [recorder]);\n\n const done = useCallback(async () => {\n const out = await recorder.finish();\n if (!out) {\n setScreen({ kind: 'home' });\n setError('The recording could not be saved. Try again.');\n return;\n }\n const record = await store.keepRecording(out.uri, out.durationMs);\n await refresh();\n setScreen({ kind: 'note', id: record.id });\n void write(record);\n }, [recorder, store, refresh, write]);\n\n const discard = useCallback(() => {\n Alert.alert('Discard this dictation?', 'The recording is deleted and no note is written.', [\n { text: 'Keep dictating', style: 'cancel' },\n {\n text: 'Discard',\n style: 'destructive',\n onPress: () => {\n void (async () => {\n const out = await recorder.finish();\n if (out) await store.discardRecording(out.uri);\n setScreen({ kind: 'home' });\n })();\n },\n },\n ]);\n }, [recorder, store]);\n\n const back = useCallback(() => {\n if (screen.kind === 'record') {\n if (recorder.phase === 'recording') recorder.pause();\n Alert.alert('Stop dictating?', 'Write the note from what you have recorded, or discard it.', [\n { text: 'Keep dictating', style: 'cancel' },\n { text: 'Write the note', onPress: () => void done() },\n {\n text: 'Discard',\n style: 'destructive',\n onPress: () => {\n void (async () => {\n const out = await recorder.finish();\n if (out) await store.discardRecording(out.uri);\n setScreen({ kind: 'home' });\n })();\n },\n },\n ]);\n return true;\n }\n if (screen.kind === 'note') {\n setScreen({ kind: 'home' });\n return true;\n }\n onExit();\n return true;\n }, [screen.kind, recorder, done, store, onExit]);\n\n useEffect(() => {\n const sub = BackHandler.addEventListener('hardwareBackPress', back);\n return () => sub.remove();\n }, [back]);\n\n const open = screen.kind === 'note' ? records.find((r) => r.id === screen.id) ?? null : null;\n\n const share = useCallback(() => {\n if (!open?.note) return;\n void Share.share({ title: open.note.title, message: noteToText(open.note) });\n }, [open]);\n\n const remove = useCallback(() => {\n if (!open) return;\n Alert.alert('Delete this dictation?', 'The note and transcript are removed from this phone.', [\n { text: 'Cancel', style: 'cancel' },\n {\n text: 'Delete',\n style: 'destructive',\n onPress: () => {\n void (async () => {\n await store.remove(open.id);\n await refresh();\n setScreen({ kind: 'home' });\n })();\n },\n },\n ]);\n }, [open, store, refresh]);\n\n const title = screen.kind === 'note' ? 'Note' : 'Dictate';\n\n return (\n <View style={[styles.screen, { backgroundColor: theme.screen, paddingTop: insets.top }]}>\n <View style={[styles.header, { borderBottomColor: theme.border }]}>\n <Tap onPress={back} accessibilityRole=\"button\" accessibilityLabel=\"Back\" style={styles.headerButton} pressedStyle={DIM}>\n <MaterialCommunityIcons name=\"chevron-left\" size={28} color={theme.ink} />\n </Tap>\n <Text style={[styles.headerTitle, { color: theme.ink }]}>{title}</Text>\n <View style={styles.headerActions}>\n {open?.note ? (\n <>\n <Tap onPress={share} accessibilityRole=\"button\" accessibilityLabel=\"Share the note\" style={styles.headerButton} pressedStyle={DIM}>\n <MaterialCommunityIcons name=\"export-variant\" size={22} color={theme.ink} />\n </Tap>\n <Tap onPress={remove} accessibilityRole=\"button\" accessibilityLabel=\"Delete\" style={styles.headerButton} pressedStyle={DIM}>\n <MaterialCommunityIcons name=\"trash-can-outline\" size={22} color={theme.ink} />\n </Tap>\n </>\n ) : null}\n </View>\n </View>\n\n {screen.kind === 'note' && open ? (\n <NoteView record={open} stage={stages[open.id] ?? null} theme={theme} bottomInset={insets.bottom} onRetry={() => void write(open)} />\n ) : screen.kind === 'record' && recorder.phase !== 'idle' ? (\n <View style={styles.recordBody}>\n <RecordingPanel\n theme={theme}\n phase={recorder.phase}\n pauseReason={recorder.pauseReason}\n elapsedMs={recorder.elapsedMs}\n level={recorder.level}\n onPause={recorder.pause}\n onResume={recorder.resume}\n onDone={() => void done()}\n onDiscard={discard}\n />\n </View>\n ) : (\n <ScrollView contentContainerStyle={[styles.home, { paddingBottom: 24 + insets.bottom }]}>\n <Text style={[styles.lead, { color: theme.ink }]}>Dictate a visit</Text>\n <Text style={[styles.leadDetail, { color: theme.muted }]}>\n Speak your note. Yantra writes it up as a SOAP note and lists what to check before you use it.\n </Text>\n <StartPanel theme={theme} starting={starting} onStart={() => void start()} />\n {error ? <Text style={[styles.error, { color: theme.crit }]}>{error}</Text> : null}\n {micDenied ? (\n <View style={[styles.banner, { backgroundColor: theme.recSoft }]}>\n <MaterialCommunityIcons name=\"microphone-off\" size={18} color={theme.crit} />\n <Text style={[styles.bannerText, { color: theme.crit }]}>Microphone access is off for Yantra.</Text>\n <Tap\n onPress={() => void Linking.openSettings()}\n accessibilityRole=\"button\"\n style={[styles.bannerAction, { backgroundColor: theme.card, borderColor: theme.border }]}\n pressedStyle={DIM}\n >\n <Text style={[styles.bannerActionText, { color: theme.ink }]}>Open Settings</Text>\n </Tap>\n </View>\n ) : null}\n {sessionError ? (\n <Tap onPress={onRetrySession} accessibilityRole=\"button\" style={[styles.banner, { backgroundColor: theme.recSoft }]} pressedStyle={DIM}>\n <Text style={[styles.bannerText, { color: theme.crit }]}>Not connected, so notes cannot be written yet. Tap to retry.</Text>\n </Tap>\n ) : null}\n <View style={[styles.banner, { backgroundColor: theme.warnSoft, borderColor: theme.warnBorder, borderWidth: StyleSheet.hairlineWidth }]}>\n <MaterialCommunityIcons name=\"shield-alert-outline\" size={18} color={theme.warnInk} />\n <Text style={[styles.bannerText, { color: theme.warnInk }]}>{PREVIEW_NOTICE}</Text>\n </View>\n <Text style={[styles.sectionLabel, { color: theme.muted }]}>RECENT</Text>\n <DictationList records={records} theme={theme} onOpen={(r) => setScreen({ kind: 'note', id: r.id })} />\n </ScrollView>\n )}\n </View>\n );\n}\n\nexport default DictateExperience;\n\nconst styles = StyleSheet.create({\n screen: { flex: 1 },\n header: { height: 52, flexDirection: 'row', alignItems: 'center', paddingHorizontal: 4, borderBottomWidth: StyleSheet.hairlineWidth },\n headerButton: { width: 44, height: 44, alignItems: 'center', justifyContent: 'center' },\n headerTitle: { flex: 1, fontSize: 17, fontWeight: '600' },\n headerActions: { flexDirection: 'row', alignItems: 'center' },\n home: { paddingHorizontal: 16, paddingTop: 20 },\n lead: { fontSize: 24, fontWeight: '700' },\n leadDetail: { marginTop: 6, fontSize: 15, lineHeight: 21 },\n error: { textAlign: 'center', fontSize: 13, marginBottom: 8 },\n banner: { flexDirection: 'row', alignItems: 'center', gap: 10, borderRadius: 12, paddingHorizontal: 12, paddingVertical: 10, marginBottom: 12 },\n bannerText: { flex: 1, fontSize: 13, lineHeight: 18 },\n bannerAction: { paddingHorizontal: 12, paddingVertical: 7, borderRadius: 999, borderWidth: StyleSheet.hairlineWidth },\n bannerActionText: { fontSize: 13, fontWeight: '600' },\n sectionLabel: { marginTop: 12, marginBottom: 8, fontSize: 12, fontWeight: '700', letterSpacing: 0.8 },\n recordBody: { flex: 1, justifyContent: 'center', paddingHorizontal: 16 },\n});\n"],"names":["_b","_a"],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ import {jsx,jsxs}from'react/jsx-runtime';import {Text,StyleSheet,View}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {Tap,DIM}from'../../inbox/components/Tap.js';import {formatDuration}from'../noteText.js';import {dictationDate}from'./NoteView.js';function statusOf(record, theme) {
2
+ var _a;
3
+ if (record.status === "ready") {
4
+ return ((_a = record.note) == null ? void 0 : _a.to_verify.length) ? {
5
+ label: `${record.note.to_verify.length} to check`,
6
+ ink: theme.warnInk,
7
+ bg: theme.warnSoft
8
+ } : null;
9
+ }
10
+ if (record.status === "failed" || record.status === "saved") return {
11
+ label: "No note yet",
12
+ ink: theme.crit,
13
+ bg: theme.recSoft
14
+ };
15
+ return {
16
+ label: "Writing\u2026",
17
+ ink: theme.accent,
18
+ bg: theme.accentSoft
19
+ };
20
+ }
21
+ function DictationList({
22
+ records,
23
+ theme,
24
+ onOpen
25
+ }) {
26
+ if (!records.length) {
27
+ return /* @__PURE__ */ jsx(Text, { style: [styles.empty, {
28
+ color: theme.faint
29
+ }], children: "Your dictations stay on this phone and show up here." });
30
+ }
31
+ return /* @__PURE__ */ jsx(View, { style: [styles.list, {
32
+ backgroundColor: theme.card,
33
+ borderColor: theme.border
34
+ }], children: records.map((record, i) => {
35
+ var _a, _b;
36
+ const status = statusOf(record, theme);
37
+ return /* @__PURE__ */ jsxs(Tap, { onPress: () => onOpen(record), accessibilityRole: "button", style: [styles.row, i > 0 && {
38
+ borderTopColor: theme.border,
39
+ borderTopWidth: StyleSheet.hairlineWidth
40
+ }], pressedStyle: {
41
+ backgroundColor: theme.chip
42
+ }, children: [
43
+ /* @__PURE__ */ jsx(View, { style: [styles.icon, {
44
+ backgroundColor: theme.accentSoft
45
+ }], children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "file-document-outline", size: 18, color: theme.accent }) }),
46
+ /* @__PURE__ */ jsxs(View, { style: styles.text, children: [
47
+ /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: [styles.title, {
48
+ color: theme.ink
49
+ }], children: (_b = (_a = record.note) == null ? void 0 : _a.title) != null ? _b : "Dictation" }),
50
+ /* @__PURE__ */ jsx(Text, { style: [styles.sub, {
51
+ color: theme.faint
52
+ }], children: [dictationDate(record.createdAt), formatDuration(record.durationMs)].filter(Boolean).join(" \xB7 ") })
53
+ ] }),
54
+ status ? /* @__PURE__ */ jsx(View, { style: [styles.pill, {
55
+ backgroundColor: status.bg
56
+ }], children: /* @__PURE__ */ jsx(Text, { style: [styles.pillText, {
57
+ color: status.ink
58
+ }], children: status.label }) }) : null,
59
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chevron-right", size: 20, color: theme.faint, style: DIM })
60
+ ] }, record.id);
61
+ }) });
62
+ }
63
+ const styles = StyleSheet.create({
64
+ empty: {
65
+ fontSize: 13,
66
+ textAlign: "center",
67
+ paddingVertical: 12,
68
+ paddingHorizontal: 24,
69
+ lineHeight: 19
70
+ },
71
+ list: {
72
+ borderRadius: 14,
73
+ borderWidth: StyleSheet.hairlineWidth,
74
+ overflow: "hidden"
75
+ },
76
+ row: {
77
+ flexDirection: "row",
78
+ alignItems: "center",
79
+ paddingHorizontal: 12,
80
+ paddingVertical: 12,
81
+ gap: 10
82
+ },
83
+ icon: {
84
+ width: 34,
85
+ height: 34,
86
+ borderRadius: 10,
87
+ alignItems: "center",
88
+ justifyContent: "center"
89
+ },
90
+ text: {
91
+ flex: 1
92
+ },
93
+ title: {
94
+ fontSize: 15,
95
+ fontWeight: "600"
96
+ },
97
+ sub: {
98
+ marginTop: 2,
99
+ fontSize: 12
100
+ },
101
+ pill: {
102
+ paddingHorizontal: 8,
103
+ paddingVertical: 3,
104
+ borderRadius: 999
105
+ },
106
+ pillText: {
107
+ fontSize: 11,
108
+ fontWeight: "600"
109
+ }
110
+ });export{DictationList};//# sourceMappingURL=DictationList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DictationList.js","sources":["../../../../src/features/dictate/components/DictationList.tsx"],"sourcesContent":["/** Earlier dictations on this phone, newest first: title (or length), when, and where the note stands. */\nimport React from 'react';\nimport { StyleSheet, Text, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { DIM, Tap } from '../../inbox/components/Tap';\nimport { formatDuration } from '../noteText';\nimport type { DictateTheme } from '../dictateTheme';\nimport type { DictationRecord } from '../types';\nimport { dictationDate } from './NoteView';\n\nfunction statusOf(record: DictationRecord, theme: DictateTheme): { label: string; ink: string; bg: string } | null {\n if (record.status === 'ready') {\n return record.note?.to_verify.length\n ? { label: `${record.note.to_verify.length} to check`, ink: theme.warnInk, bg: theme.warnSoft }\n : null;\n }\n if (record.status === 'failed' || record.status === 'saved') return { label: 'No note yet', ink: theme.crit, bg: theme.recSoft };\n return { label: 'Writing…', ink: theme.accent, bg: theme.accentSoft };\n}\n\nexport function DictationList({\n records,\n theme,\n onOpen,\n}: {\n records: DictationRecord[];\n theme: DictateTheme;\n onOpen: (record: DictationRecord) => void;\n}) {\n if (!records.length) {\n return <Text style={[styles.empty, { color: theme.faint }]}>Your dictations stay on this phone and show up here.</Text>;\n }\n return (\n <View style={[styles.list, { backgroundColor: theme.card, borderColor: theme.border }]}>\n {records.map((record, i) => {\n const status = statusOf(record, theme);\n return (\n <Tap\n key={record.id}\n onPress={() => onOpen(record)}\n accessibilityRole=\"button\"\n style={[styles.row, i > 0 && { borderTopColor: theme.border, borderTopWidth: StyleSheet.hairlineWidth }]}\n pressedStyle={{ backgroundColor: theme.chip }}\n >\n <View style={[styles.icon, { backgroundColor: theme.accentSoft }]}>\n <MaterialCommunityIcons name=\"file-document-outline\" size={18} color={theme.accent} />\n </View>\n <View style={styles.text}>\n <Text numberOfLines={1} style={[styles.title, { color: theme.ink }]}>\n {record.note?.title ?? 'Dictation'}\n </Text>\n <Text style={[styles.sub, { color: theme.faint }]}>\n {[dictationDate(record.createdAt), formatDuration(record.durationMs)].filter(Boolean).join(' · ')}\n </Text>\n </View>\n {status ? (\n <View style={[styles.pill, { backgroundColor: status.bg }]}>\n <Text style={[styles.pillText, { color: status.ink }]}>{status.label}</Text>\n </View>\n ) : null}\n <MaterialCommunityIcons name=\"chevron-right\" size={20} color={theme.faint} style={DIM} />\n </Tap>\n );\n })}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n empty: { fontSize: 13, textAlign: 'center', paddingVertical: 12, paddingHorizontal: 24, lineHeight: 19 },\n list: { borderRadius: 14, borderWidth: StyleSheet.hairlineWidth, overflow: 'hidden' },\n row: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 12, paddingVertical: 12, gap: 10 },\n icon: { width: 34, height: 34, borderRadius: 10, alignItems: 'center', justifyContent: 'center' },\n text: { flex: 1 },\n title: { fontSize: 15, fontWeight: '600' },\n sub: { marginTop: 2, fontSize: 12 },\n pill: { paddingHorizontal: 8, paddingVertical: 3, borderRadius: 999 },\n pillText: { fontSize: 11, fontWeight: '600' },\n});\n"],"names":[],"mappings":"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"}