@adminide-stack/yantra-mobile 12.0.136 → 12.0.137
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/lib/features/apps/AppsCatalog.js +3 -3
- package/lib/features/apps/AppsCatalog.js.map +1 -1
- package/lib/features/apps/appLabelText.js +9 -0
- package/lib/features/apps/appLabelText.js.map +1 -0
- package/lib/features/dictate/DictateExperience.js +48 -25
- package/lib/features/dictate/DictateExperience.js.map +1 -1
- package/lib/features/dictate/backgroundRecording.js +15 -0
- package/lib/features/dictate/backgroundRecording.js.map +1 -0
- package/lib/features/dictate/components/DictationList.js.map +1 -1
- package/lib/features/dictate/components/NoteView.js +3 -1
- package/lib/features/dictate/components/NoteView.js.map +1 -1
- package/lib/features/dictate/components/RecordPanel.js +33 -4
- package/lib/features/dictate/components/RecordPanel.js.map +1 -1
- package/lib/features/dictate/dictateClient.js +7 -2
- package/lib/features/dictate/dictateClient.js.map +1 -1
- package/lib/features/dictate/dictationStore.js.map +1 -1
- package/lib/features/dictate/useDictationRecorder.js +48 -14
- package/lib/features/dictate/useDictationRecorder.js.map +1 -1
- package/lib/screens/DictateNative/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {jsxs,jsx,Fragment}from'react/jsx-runtime';import React__default,{useEffect,useState,useMemo,useCallback}from'react';import {useColorScheme,useWindowDimensions,InteractionManager,View,StyleSheet,Pressable,Text,TextInput,ScrollView}from'react-native';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {Image}from'expo-image';import {v4}from'uuid';import {config}from'../../config/env-config.js';import {preloadNativeWebBuilderExperience}from'../webbuilder/nativeWebBuilderRegistry.js';import {mobileTokens}from'../../theme/mobileTokens.js';import {useChatMutations}from'../../hooks/useChatApi.js';import {resolveSurfaceUrl}from'./resolveSurfaceUrl.js';import {useAppFavorites}from'./appFavorites.js';import {APP_ART}from'./appArt.js';import {filterMobileApps,MOBILE_APP_CATALOG,APP_GROUP_ART}from'./mobileAppCatalog.js';var __defProp = Object.defineProperty;
|
|
1
|
+
import {jsxs,jsx,Fragment}from'react/jsx-runtime';import React__default,{useEffect,useState,useMemo,useCallback}from'react';import {useColorScheme,useWindowDimensions,InteractionManager,View,StyleSheet,Pressable,Text,TextInput,ScrollView}from'react-native';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {Image}from'expo-image';import {v4}from'uuid';import {config}from'../../config/env-config.js';import {preloadNativeWebBuilderExperience}from'../webbuilder/nativeWebBuilderRegistry.js';import {mobileTokens}from'../../theme/mobileTokens.js';import {useChatMutations}from'../../hooks/useChatApi.js';import {resolveSurfaceUrl}from'./resolveSurfaceUrl.js';import {useAppFavorites}from'./appFavorites.js';import {APP_ART}from'./appArt.js';import {appLabelTextProps}from'./appLabelText.js';import {filterMobileApps,MOBILE_APP_CATALOG,APP_GROUP_ART}from'./mobileAppCatalog.js';var __defProp = Object.defineProperty;
|
|
2
2
|
var __defProps = Object.defineProperties;
|
|
3
3
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
@@ -368,9 +368,9 @@ const AppCard = React__default.memo(function AppCard2({
|
|
|
368
368
|
}) => [styles.heart, pressed && styles.heartPressed], children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: favorite ? "heart" : "heart-outline", size: 16, color: favorite ? "#fb7185" : "#ffffff" }) })
|
|
369
369
|
] }),
|
|
370
370
|
/* @__PURE__ */ jsxs(View, { style: styles.cardBody, children: [
|
|
371
|
-
/* @__PURE__ */ jsx(Text, { style: [styles.cardTitle, {
|
|
371
|
+
/* @__PURE__ */ jsx(Text, __spreadProps(__spreadValues({ style: [styles.cardTitle, {
|
|
372
372
|
color: theme.foreground
|
|
373
|
-
}],
|
|
373
|
+
}] }, appLabelTextProps(app.label)), { children: app.label })),
|
|
374
374
|
/* @__PURE__ */ jsx(Text, { style: [styles.cardCaption, {
|
|
375
375
|
color: theme.muted
|
|
376
376
|
}], numberOfLines: 1, children: app.group })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppsCatalog.js","sources":["../../../src/features/apps/AppsCatalog.tsx"],"sourcesContent":["/**\n * Full-screen Apps catalog: All / Favorites tabs, search, then a flat grid of\n * poster cards (square artwork tile, bold name, group caption) - the\n * game-launcher layout, so 30 apps scan as one dense wall instead of six\n * short sections. Tapping a card opens its native surface or a new chat.\n *\n * Tile artwork comes from `appArt.ts` (bundled 480px illustrations, one per\n * app). A tile without artwork falls back to the group's poster color with\n * the app glyph centered and a large faded copy bleeding off the corner.\n */\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n InteractionManager,\n Pressable,\n ScrollView,\n StyleSheet,\n Text,\n TextInput,\n View,\n useColorScheme,\n useWindowDimensions,\n} from 'react-native';\nimport {\n CommonActions,\n useNavigation,\n useRoute,\n type NavigationProp,\n type ParamListBase,\n type RouteProp,\n} from '@react-navigation/native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { Image } from 'expo-image';\nimport { v4 as uuidv4 } from 'uuid';\nimport { config } from '../../config/env-config';\nimport { preloadNativeWebBuilderExperience } from '../webbuilder/nativeWebBuilderRegistry';\nimport { mobileTokens } from '../../theme/mobileTokens';\nimport { useChatMutations } from '../../hooks/useChatApi';\nimport { resolveSurfaceUrl } from './resolveSurfaceUrl';\nimport { useAppFavorites } from './appFavorites';\nimport { APP_ART } from './appArt';\nimport {\n APP_GROUP_ART,\n filterMobileApps,\n MOBILE_APP_CATALOG,\n type AppsTab,\n type MobileAppItem,\n} from './mobileAppCatalog';\n\nconst H_PAD = 16;\nconst GAP = 12;\n/** Narrowest card that still fits a 2-line name; more columns on wider screens. */\nconst MIN_CARD = 104;\n\ninterface CardTheme {\n surface: string;\n border: string;\n foreground: string;\n muted: string;\n pressed: string;\n}\n\nfunction buildChannelTitle(channelId: string): string {\n return `chat-channel-${channelId}`;\n}\n\nexport function AppsCatalog({ orgName: orgNameProp }: { orgName?: string | null }) {\n const navigation = useNavigation<NavigationProp<ParamListBase>>();\n const route = useRoute<RouteProp<Record<string, { orgName?: string | null } | undefined>, string>>();\n const colorScheme = useColorScheme();\n const isDark = colorScheme === 'dark';\n const { createChannel } = useChatMutations();\n const { width: screenWidth } = useWindowDimensions();\n // Someone browsing the apps may open Web Builder next: load its code once this screen\n // has settled, so it opens without the loading spinner.\n useEffect(() => {\n const task = InteractionManager.runAfterInteractions(() => {\n preloadNativeWebBuilderExperience().catch(() => undefined);\n });\n return () => task.cancel();\n }, []);\n const [query, setQuery] = useState('');\n const [tab, setTab] = useState<AppsTab>('all');\n const { favorites, toggle: toggleFavorite } = useAppFavorites();\n\n const orgName = useMemo(() => {\n if (typeof orgNameProp === 'string' && orgNameProp.trim()) return orgNameProp.trim();\n const raw = (route?.params?.orgName as string | undefined) ?? '';\n return typeof raw === 'string' && raw.trim() ? raw.trim() : null;\n }, [orgNameProp, route?.params?.orgName]);\n\n const apps = useMemo(() => filterMobileApps(MOBILE_APP_CATALOG, query, tab, favorites), [favorites, query, tab]);\n const columns = Math.max(3, Math.min(6, Math.floor((screenWidth - H_PAD * 2 + GAP) / (MIN_CARD + GAP))));\n const cardWidth = Math.floor((screenWidth - H_PAD * 2 - GAP * (columns - 1)) / columns);\n\n const muted = isDark ? '#94a3b8' : mobileTokens.color.textMuted;\n const foreground = isDark ? '#e2e8f0' : mobileTokens.color.text;\n const surface = isDark ? '#111827' : mobileTokens.color.surface;\n const screenBg = isDark ? '#0f172a' : mobileTokens.color.bg;\n const borderColor = isDark ? 'rgba(148,163,184,0.22)' : mobileTokens.color.border;\n const fieldBg = isDark ? '#1e293b' : mobileTokens.color.surface;\n const cardTheme: CardTheme = {\n surface,\n border: borderColor,\n foreground,\n muted,\n pressed: isDark ? 'rgba(148,163,184,0.10)' : 'rgba(15,23,42,0.05)',\n };\n const segmentBg = isDark ? 'rgba(148,163,184,0.12)' : mobileTokens.color.surface;\n const segmentActiveBg = isDark ? 'rgba(148,163,184,0.24)' : mobileTokens.color.surface;\n const emptyMarkBg = isDark ? 'rgba(234,88,12,0.22)' : mobileTokens.color.primarySoft;\n\n const openApp = useCallback(\n (app: MobileAppItem) => {\n const channelId = uuidv4();\n const params: Record<string, unknown> = {\n orgName: orgName ?? undefined,\n channelId,\n appTitle: app.label,\n };\n\n if (app.nativeRoute === 'characters-native') {\n // Same wiring as AppsMenu: the tile opens the self-contained native\n // character studio (never a chat with the tile's prompt). The host\n // contributes only the session token + subgraph endpoint, built in\n // the screen, so no manifest/handoff params are needed here.\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.CharactersNative',\n params,\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'canvas-native') {\n // Web canvas opens the boards grid first. Do not mint a chat\n // channelId here — that id is not an index row, and passing it\n // looks like a deep link into a board that does not exist.\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.CanvasNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Canvas' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'chat-native') {\n // Opens the conversation list. Deliberately no channelId: the\n // uuid minted above is an AI-chat channel, not a messenger\n // channel, and passing it would read as a deep link into a\n // thread that does not exist.\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.ChatNative',\n params: { orgName: orgName ?? undefined },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'billing-native') {\n navigation.navigate('MainStack.Billing', { orgName: orgName ?? undefined });\n return;\n }\n\n if (app.nativeRoute === 'shopping-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.ShoppingNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Shop' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'travel-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.TravelNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Travel' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'job-search-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.JobSearchNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Job Search' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'resume-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.ResumeNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Resume' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'inbox-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.InboxNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Inbox' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'study-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.StudyNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Study' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'local-services-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.LocalServicesNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Local Services' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'movies-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.MoviesNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Movies' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'dictate-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.DictateNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Dictate' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'expenses-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.ExpensesNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Expenses' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'webbuilder-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.WebBuilderNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Web Builder' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'design-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.DesignNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Design' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'webbuilder') {\n const surfaceUrl = resolveSurfaceUrl(app, config);\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.WebBuilder',\n params: surfaceUrl ? { ...params, url: surfaceUrl } : params,\n }),\n );\n return;\n }\n\n void createChannel({\n id: channelId,\n title: buildChannelTitle(channelId),\n isShared: false,\n sharedSlug: null,\n isArchived: false,\n isPinned: false,\n model: null,\n systemPrompt: null,\n orgName,\n }).catch((err) => {\n console.error('[AppsCatalog] createChannel failed:', err);\n });\n\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.Chat',\n params: {\n ...params,\n initialQuery: app.prompt,\n initialMode: 'chat',\n },\n }),\n );\n },\n [createChannel, navigation, orgName],\n );\n\n const emptyState =\n tab === 'favorites' && !query.trim()\n ? {\n icon: 'heart-outline' as const,\n title: 'No favorites yet',\n hint: 'Tap the heart on any app to keep it here.',\n }\n : {\n icon: 'magnify' as const,\n title: 'No apps match that search',\n hint: tab === 'favorites' ? 'Try All apps, or a shorter name.' : 'Try a shorter name.',\n };\n\n return (\n <View style={[styles.root, { backgroundColor: screenBg }]}>\n <View style={[styles.segment, { backgroundColor: segmentBg, borderColor }]} accessibilityRole=\"tablist\">\n {(\n [\n { key: 'all', label: 'All apps' },\n { key: 'favorites', label: 'Favorites' },\n ] as const\n ).map(({ key, label }) => {\n const selected = tab === key;\n return (\n <Pressable\n key={key}\n onPress={() => setTab(key)}\n accessibilityRole=\"tab\"\n accessibilityState={{ selected }}\n style={[\n styles.segmentItem,\n selected && [styles.segmentItemActive, { backgroundColor: segmentActiveBg }],\n ]}\n >\n <Text\n style={[\n styles.segmentLabel,\n { color: selected ? foreground : muted },\n selected && styles.segmentLabelActive,\n ]}\n >\n {label}\n </Text>\n </Pressable>\n );\n })}\n </View>\n <View style={[styles.searchWrap, { backgroundColor: fieldBg, borderColor }]}>\n <MaterialCommunityIcons name=\"magnify\" size={18} color={muted} />\n <TextInput\n value={query}\n onChangeText={setQuery}\n placeholder=\"Search apps\"\n placeholderTextColor={muted}\n autoCorrect={false}\n autoCapitalize=\"none\"\n clearButtonMode=\"while-editing\"\n style={[styles.searchInput, { color: foreground }]}\n />\n </View>\n <ScrollView keyboardShouldPersistTaps=\"handled\" contentContainerStyle={styles.list}>\n {apps.length === 0 ? (\n <View style={styles.empty}>\n <View style={[styles.emptyMark, { backgroundColor: emptyMarkBg }]}>\n <MaterialCommunityIcons\n name={emptyState.icon}\n size={26}\n color={mobileTokens.color.primary}\n />\n </View>\n <Text style={[styles.emptyTitle, { color: foreground }]}>{emptyState.title}</Text>\n <Text style={[styles.emptyHint, { color: muted }]}>{emptyState.hint}</Text>\n </View>\n ) : (\n <View style={[styles.grid, { gap: GAP }]}>\n {apps.map((app) => (\n <AppCard\n key={app.key}\n app={app}\n width={cardWidth}\n theme={cardTheme}\n favorite={favorites.has(app.key)}\n onOpen={openApp}\n onToggleFavorite={toggleFavorite}\n />\n ))}\n </View>\n )}\n </ScrollView>\n </View>\n );\n}\n\nconst AppCard = React.memo(function AppCard({\n app,\n width,\n theme,\n favorite,\n onOpen,\n onToggleFavorite,\n}: {\n app: MobileAppItem;\n width: number;\n theme: CardTheme;\n favorite: boolean;\n onOpen: (app: MobileAppItem) => void;\n onToggleFavorite: (key: string) => void;\n}) {\n const poster = APP_GROUP_ART[app.group];\n const artwork = APP_ART[app.key];\n // Glyph scales with the tile so a 3-column phone and a 5-column tablet read alike.\n const glyph = Math.round(width * 0.36);\n const echo = Math.round(width * 0.95);\n return (\n <Pressable\n onPress={() => onOpen(app)}\n accessibilityRole=\"button\"\n accessibilityLabel={`${app.label}, ${app.group}`}\n accessibilityHint=\"Opens the app\"\n style={({ pressed }) => [\n styles.card,\n { width, backgroundColor: theme.surface, borderColor: theme.border },\n pressed && { backgroundColor: theme.pressed, transform: [{ scale: 0.97 }] },\n ]}\n >\n <View style={[styles.tile, { backgroundColor: poster.base }]}>\n {artwork ? (\n <Image\n source={artwork}\n style={StyleSheet.absoluteFill}\n contentFit=\"cover\"\n transition={120}\n accessibilityIgnoresInvertColors\n />\n ) : (\n <>\n <View\n style={[\n styles.tileHighlight,\n { width: width * 0.9, height: width * 0.9, borderRadius: width },\n ]}\n />\n <MaterialCommunityIcons\n name={app.icon}\n size={echo}\n color={poster.glow}\n style={[styles.tileEcho, { right: -echo * 0.28, bottom: -echo * 0.3 }]}\n />\n <MaterialCommunityIcons name={app.icon} size={glyph} color=\"#ffffff\" style={styles.tileGlyph} />\n </>\n )}\n <Pressable\n onPress={() => onToggleFavorite(app.key)}\n hitSlop={8}\n accessibilityRole=\"button\"\n accessibilityLabel={\n favorite ? `Remove ${app.label} from favorites` : `Add ${app.label} to favorites`\n }\n accessibilityState={{ selected: favorite }}\n style={({ pressed }) => [styles.heart, pressed && styles.heartPressed]}\n >\n <MaterialCommunityIcons\n name={favorite ? 'heart' : 'heart-outline'}\n size={16}\n color={favorite ? '#fb7185' : '#ffffff'}\n />\n </Pressable>\n </View>\n <View style={styles.cardBody}>\n <Text style={[styles.cardTitle, { color: theme.foreground }]} numberOfLines={2}>\n {app.label}\n </Text>\n <Text style={[styles.cardCaption, { color: theme.muted }]} numberOfLines={1}>\n {app.group}\n </Text>\n </View>\n </Pressable>\n );\n});\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1,\n },\n segment: {\n flexDirection: 'row',\n alignSelf: 'center',\n marginTop: 12,\n padding: 4,\n borderRadius: mobileTokens.radius.pill,\n borderWidth: 1,\n minWidth: 240,\n maxWidth: 320,\n width: '70%',\n },\n segmentItem: {\n flex: 1,\n minHeight: 36,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: mobileTokens.radius.pill,\n },\n segmentItemActive: {\n ...mobileTokens.shadow.card,\n },\n segmentLabel: {\n fontSize: 15,\n fontWeight: '600',\n },\n segmentLabelActive: {\n fontWeight: '700',\n },\n searchWrap: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n marginHorizontal: H_PAD,\n marginTop: 12,\n marginBottom: 4,\n borderWidth: 1,\n borderRadius: mobileTokens.radius.md,\n paddingHorizontal: 12,\n minHeight: 44,\n },\n searchInput: {\n flex: 1,\n fontSize: 15,\n paddingVertical: 8,\n },\n list: {\n paddingHorizontal: H_PAD,\n paddingTop: 12,\n paddingBottom: 32,\n },\n grid: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n alignItems: 'stretch',\n },\n card: {\n borderRadius: mobileTokens.radius.lg,\n borderWidth: 1,\n overflow: 'hidden',\n },\n tile: {\n aspectRatio: 1,\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n },\n tileHighlight: {\n position: 'absolute',\n top: '-45%',\n left: '-35%',\n backgroundColor: 'rgba(255,255,255,0.12)',\n },\n tileEcho: {\n position: 'absolute',\n opacity: 0.28,\n },\n tileGlyph: {\n textShadowColor: 'rgba(15,23,42,0.28)',\n textShadowOffset: { width: 0, height: 2 },\n textShadowRadius: 6,\n },\n heart: {\n position: 'absolute',\n top: 8,\n right: 8,\n width: 32,\n height: 32,\n borderRadius: 16,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'rgba(15,23,42,0.36)',\n },\n heartPressed: {\n backgroundColor: 'rgba(15,23,42,0.55)',\n },\n cardBody: {\n paddingHorizontal: 10,\n paddingTop: 10,\n paddingBottom: 12,\n gap: 3,\n },\n cardTitle: {\n fontSize: 14,\n fontWeight: '700',\n lineHeight: 18,\n // Two lines reserved so every row lines up whether a name wraps or not.\n minHeight: 36,\n },\n cardCaption: {\n fontSize: 11,\n fontWeight: '600',\n letterSpacing: 0.8,\n textTransform: 'uppercase',\n },\n empty: {\n alignItems: 'center',\n paddingTop: 56,\n paddingHorizontal: 32,\n gap: 6,\n },\n emptyMark: {\n width: 56,\n height: 56,\n borderRadius: 28,\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: 8,\n },\n emptyTitle: {\n fontSize: 16,\n fontWeight: '700',\n },\n emptyHint: {\n fontSize: 14,\n textAlign: 'center',\n lineHeight: 20,\n },\n});\n"],"names":["_a","uuidv4","React","AppCard"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AppsCatalog.js","sources":["../../../src/features/apps/AppsCatalog.tsx"],"sourcesContent":["/**\n * Full-screen Apps catalog: All / Favorites tabs, search, then a flat grid of\n * poster cards (square artwork tile, bold name, group caption) - the\n * game-launcher layout, so 30 apps scan as one dense wall instead of six\n * short sections. Tapping a card opens its native surface or a new chat.\n *\n * Tile artwork comes from `appArt.ts` (bundled 480px illustrations, one per\n * app). A tile without artwork falls back to the group's poster color with\n * the app glyph centered and a large faded copy bleeding off the corner.\n */\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n InteractionManager,\n Pressable,\n ScrollView,\n StyleSheet,\n Text,\n TextInput,\n View,\n useColorScheme,\n useWindowDimensions,\n} from 'react-native';\nimport {\n CommonActions,\n useNavigation,\n useRoute,\n type NavigationProp,\n type ParamListBase,\n type RouteProp,\n} from '@react-navigation/native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { Image } from 'expo-image';\nimport { v4 as uuidv4 } from 'uuid';\nimport { config } from '../../config/env-config';\nimport { preloadNativeWebBuilderExperience } from '../webbuilder/nativeWebBuilderRegistry';\nimport { mobileTokens } from '../../theme/mobileTokens';\nimport { useChatMutations } from '../../hooks/useChatApi';\nimport { resolveSurfaceUrl } from './resolveSurfaceUrl';\nimport { useAppFavorites } from './appFavorites';\nimport { APP_ART } from './appArt';\nimport { appLabelTextProps } from './appLabelText';\nimport {\n APP_GROUP_ART,\n filterMobileApps,\n MOBILE_APP_CATALOG,\n type AppsTab,\n type MobileAppItem,\n} from './mobileAppCatalog';\n\nconst H_PAD = 16;\nconst GAP = 12;\n/** Narrowest card that still fits a 2-line name; more columns on wider screens. */\nconst MIN_CARD = 104;\n\ninterface CardTheme {\n surface: string;\n border: string;\n foreground: string;\n muted: string;\n pressed: string;\n}\n\nfunction buildChannelTitle(channelId: string): string {\n return `chat-channel-${channelId}`;\n}\n\nexport function AppsCatalog({ orgName: orgNameProp }: { orgName?: string | null }) {\n const navigation = useNavigation<NavigationProp<ParamListBase>>();\n const route = useRoute<RouteProp<Record<string, { orgName?: string | null } | undefined>, string>>();\n const colorScheme = useColorScheme();\n const isDark = colorScheme === 'dark';\n const { createChannel } = useChatMutations();\n const { width: screenWidth } = useWindowDimensions();\n // Someone browsing the apps may open Web Builder next: load its code once this screen\n // has settled, so it opens without the loading spinner.\n useEffect(() => {\n const task = InteractionManager.runAfterInteractions(() => {\n preloadNativeWebBuilderExperience().catch(() => undefined);\n });\n return () => task.cancel();\n }, []);\n const [query, setQuery] = useState('');\n const [tab, setTab] = useState<AppsTab>('all');\n const { favorites, toggle: toggleFavorite } = useAppFavorites();\n\n const orgName = useMemo(() => {\n if (typeof orgNameProp === 'string' && orgNameProp.trim()) return orgNameProp.trim();\n const raw = (route?.params?.orgName as string | undefined) ?? '';\n return typeof raw === 'string' && raw.trim() ? raw.trim() : null;\n }, [orgNameProp, route?.params?.orgName]);\n\n const apps = useMemo(() => filterMobileApps(MOBILE_APP_CATALOG, query, tab, favorites), [favorites, query, tab]);\n const columns = Math.max(3, Math.min(6, Math.floor((screenWidth - H_PAD * 2 + GAP) / (MIN_CARD + GAP))));\n const cardWidth = Math.floor((screenWidth - H_PAD * 2 - GAP * (columns - 1)) / columns);\n\n const muted = isDark ? '#94a3b8' : mobileTokens.color.textMuted;\n const foreground = isDark ? '#e2e8f0' : mobileTokens.color.text;\n const surface = isDark ? '#111827' : mobileTokens.color.surface;\n const screenBg = isDark ? '#0f172a' : mobileTokens.color.bg;\n const borderColor = isDark ? 'rgba(148,163,184,0.22)' : mobileTokens.color.border;\n const fieldBg = isDark ? '#1e293b' : mobileTokens.color.surface;\n const cardTheme: CardTheme = {\n surface,\n border: borderColor,\n foreground,\n muted,\n pressed: isDark ? 'rgba(148,163,184,0.10)' : 'rgba(15,23,42,0.05)',\n };\n const segmentBg = isDark ? 'rgba(148,163,184,0.12)' : mobileTokens.color.surface;\n const segmentActiveBg = isDark ? 'rgba(148,163,184,0.24)' : mobileTokens.color.surface;\n const emptyMarkBg = isDark ? 'rgba(234,88,12,0.22)' : mobileTokens.color.primarySoft;\n\n const openApp = useCallback(\n (app: MobileAppItem) => {\n const channelId = uuidv4();\n const params: Record<string, unknown> = {\n orgName: orgName ?? undefined,\n channelId,\n appTitle: app.label,\n };\n\n if (app.nativeRoute === 'characters-native') {\n // Same wiring as AppsMenu: the tile opens the self-contained native\n // character studio (never a chat with the tile's prompt). The host\n // contributes only the session token + subgraph endpoint, built in\n // the screen, so no manifest/handoff params are needed here.\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.CharactersNative',\n params,\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'canvas-native') {\n // Web canvas opens the boards grid first. Do not mint a chat\n // channelId here — that id is not an index row, and passing it\n // looks like a deep link into a board that does not exist.\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.CanvasNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Canvas' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'chat-native') {\n // Opens the conversation list. Deliberately no channelId: the\n // uuid minted above is an AI-chat channel, not a messenger\n // channel, and passing it would read as a deep link into a\n // thread that does not exist.\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.ChatNative',\n params: { orgName: orgName ?? undefined },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'billing-native') {\n navigation.navigate('MainStack.Billing', { orgName: orgName ?? undefined });\n return;\n }\n\n if (app.nativeRoute === 'shopping-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.ShoppingNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Shop' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'travel-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.TravelNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Travel' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'job-search-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.JobSearchNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Job Search' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'resume-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.ResumeNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Resume' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'inbox-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.InboxNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Inbox' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'study-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.StudyNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Study' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'local-services-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.LocalServicesNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Local Services' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'movies-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.MoviesNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Movies' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'dictate-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.DictateNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Dictate' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'expenses-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.ExpensesNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Expenses' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'webbuilder-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.WebBuilderNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Web Builder' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'design-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.DesignNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Design' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'webbuilder') {\n const surfaceUrl = resolveSurfaceUrl(app, config);\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.WebBuilder',\n params: surfaceUrl ? { ...params, url: surfaceUrl } : params,\n }),\n );\n return;\n }\n\n void createChannel({\n id: channelId,\n title: buildChannelTitle(channelId),\n isShared: false,\n sharedSlug: null,\n isArchived: false,\n isPinned: false,\n model: null,\n systemPrompt: null,\n orgName,\n }).catch((err) => {\n console.error('[AppsCatalog] createChannel failed:', err);\n });\n\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.Chat',\n params: {\n ...params,\n initialQuery: app.prompt,\n initialMode: 'chat',\n },\n }),\n );\n },\n [createChannel, navigation, orgName],\n );\n\n const emptyState =\n tab === 'favorites' && !query.trim()\n ? {\n icon: 'heart-outline' as const,\n title: 'No favorites yet',\n hint: 'Tap the heart on any app to keep it here.',\n }\n : {\n icon: 'magnify' as const,\n title: 'No apps match that search',\n hint: tab === 'favorites' ? 'Try All apps, or a shorter name.' : 'Try a shorter name.',\n };\n\n return (\n <View style={[styles.root, { backgroundColor: screenBg }]}>\n <View style={[styles.segment, { backgroundColor: segmentBg, borderColor }]} accessibilityRole=\"tablist\">\n {(\n [\n { key: 'all', label: 'All apps' },\n { key: 'favorites', label: 'Favorites' },\n ] as const\n ).map(({ key, label }) => {\n const selected = tab === key;\n return (\n <Pressable\n key={key}\n onPress={() => setTab(key)}\n accessibilityRole=\"tab\"\n accessibilityState={{ selected }}\n style={[\n styles.segmentItem,\n selected && [styles.segmentItemActive, { backgroundColor: segmentActiveBg }],\n ]}\n >\n <Text\n style={[\n styles.segmentLabel,\n { color: selected ? foreground : muted },\n selected && styles.segmentLabelActive,\n ]}\n >\n {label}\n </Text>\n </Pressable>\n );\n })}\n </View>\n <View style={[styles.searchWrap, { backgroundColor: fieldBg, borderColor }]}>\n <MaterialCommunityIcons name=\"magnify\" size={18} color={muted} />\n <TextInput\n value={query}\n onChangeText={setQuery}\n placeholder=\"Search apps\"\n placeholderTextColor={muted}\n autoCorrect={false}\n autoCapitalize=\"none\"\n clearButtonMode=\"while-editing\"\n style={[styles.searchInput, { color: foreground }]}\n />\n </View>\n <ScrollView keyboardShouldPersistTaps=\"handled\" contentContainerStyle={styles.list}>\n {apps.length === 0 ? (\n <View style={styles.empty}>\n <View style={[styles.emptyMark, { backgroundColor: emptyMarkBg }]}>\n <MaterialCommunityIcons\n name={emptyState.icon}\n size={26}\n color={mobileTokens.color.primary}\n />\n </View>\n <Text style={[styles.emptyTitle, { color: foreground }]}>{emptyState.title}</Text>\n <Text style={[styles.emptyHint, { color: muted }]}>{emptyState.hint}</Text>\n </View>\n ) : (\n <View style={[styles.grid, { gap: GAP }]}>\n {apps.map((app) => (\n <AppCard\n key={app.key}\n app={app}\n width={cardWidth}\n theme={cardTheme}\n favorite={favorites.has(app.key)}\n onOpen={openApp}\n onToggleFavorite={toggleFavorite}\n />\n ))}\n </View>\n )}\n </ScrollView>\n </View>\n );\n}\n\nconst AppCard = React.memo(function AppCard({\n app,\n width,\n theme,\n favorite,\n onOpen,\n onToggleFavorite,\n}: {\n app: MobileAppItem;\n width: number;\n theme: CardTheme;\n favorite: boolean;\n onOpen: (app: MobileAppItem) => void;\n onToggleFavorite: (key: string) => void;\n}) {\n const poster = APP_GROUP_ART[app.group];\n const artwork = APP_ART[app.key];\n // Glyph scales with the tile so a 3-column phone and a 5-column tablet read alike.\n const glyph = Math.round(width * 0.36);\n const echo = Math.round(width * 0.95);\n return (\n <Pressable\n onPress={() => onOpen(app)}\n accessibilityRole=\"button\"\n accessibilityLabel={`${app.label}, ${app.group}`}\n accessibilityHint=\"Opens the app\"\n style={({ pressed }) => [\n styles.card,\n { width, backgroundColor: theme.surface, borderColor: theme.border },\n pressed && { backgroundColor: theme.pressed, transform: [{ scale: 0.97 }] },\n ]}\n >\n <View style={[styles.tile, { backgroundColor: poster.base }]}>\n {artwork ? (\n <Image\n source={artwork}\n style={StyleSheet.absoluteFill}\n contentFit=\"cover\"\n transition={120}\n accessibilityIgnoresInvertColors\n />\n ) : (\n <>\n <View\n style={[\n styles.tileHighlight,\n { width: width * 0.9, height: width * 0.9, borderRadius: width },\n ]}\n />\n <MaterialCommunityIcons\n name={app.icon}\n size={echo}\n color={poster.glow}\n style={[styles.tileEcho, { right: -echo * 0.28, bottom: -echo * 0.3 }]}\n />\n <MaterialCommunityIcons name={app.icon} size={glyph} color=\"#ffffff\" style={styles.tileGlyph} />\n </>\n )}\n <Pressable\n onPress={() => onToggleFavorite(app.key)}\n hitSlop={8}\n accessibilityRole=\"button\"\n accessibilityLabel={\n favorite ? `Remove ${app.label} from favorites` : `Add ${app.label} to favorites`\n }\n accessibilityState={{ selected: favorite }}\n style={({ pressed }) => [styles.heart, pressed && styles.heartPressed]}\n >\n <MaterialCommunityIcons\n name={favorite ? 'heart' : 'heart-outline'}\n size={16}\n color={favorite ? '#fb7185' : '#ffffff'}\n />\n </Pressable>\n </View>\n <View style={styles.cardBody}>\n <Text style={[styles.cardTitle, { color: theme.foreground }]} {...appLabelTextProps(app.label)}>\n {app.label}\n </Text>\n <Text style={[styles.cardCaption, { color: theme.muted }]} numberOfLines={1}>\n {app.group}\n </Text>\n </View>\n </Pressable>\n );\n});\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1,\n },\n segment: {\n flexDirection: 'row',\n alignSelf: 'center',\n marginTop: 12,\n padding: 4,\n borderRadius: mobileTokens.radius.pill,\n borderWidth: 1,\n minWidth: 240,\n maxWidth: 320,\n width: '70%',\n },\n segmentItem: {\n flex: 1,\n minHeight: 36,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: mobileTokens.radius.pill,\n },\n segmentItemActive: {\n ...mobileTokens.shadow.card,\n },\n segmentLabel: {\n fontSize: 15,\n fontWeight: '600',\n },\n segmentLabelActive: {\n fontWeight: '700',\n },\n searchWrap: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n marginHorizontal: H_PAD,\n marginTop: 12,\n marginBottom: 4,\n borderWidth: 1,\n borderRadius: mobileTokens.radius.md,\n paddingHorizontal: 12,\n minHeight: 44,\n },\n searchInput: {\n flex: 1,\n fontSize: 15,\n paddingVertical: 8,\n },\n list: {\n paddingHorizontal: H_PAD,\n paddingTop: 12,\n paddingBottom: 32,\n },\n grid: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n alignItems: 'stretch',\n },\n card: {\n borderRadius: mobileTokens.radius.lg,\n borderWidth: 1,\n overflow: 'hidden',\n },\n tile: {\n aspectRatio: 1,\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n },\n tileHighlight: {\n position: 'absolute',\n top: '-45%',\n left: '-35%',\n backgroundColor: 'rgba(255,255,255,0.12)',\n },\n tileEcho: {\n position: 'absolute',\n opacity: 0.28,\n },\n tileGlyph: {\n textShadowColor: 'rgba(15,23,42,0.28)',\n textShadowOffset: { width: 0, height: 2 },\n textShadowRadius: 6,\n },\n heart: {\n position: 'absolute',\n top: 8,\n right: 8,\n width: 32,\n height: 32,\n borderRadius: 16,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'rgba(15,23,42,0.36)',\n },\n heartPressed: {\n backgroundColor: 'rgba(15,23,42,0.55)',\n },\n cardBody: {\n paddingHorizontal: 10,\n paddingTop: 10,\n paddingBottom: 12,\n gap: 3,\n },\n cardTitle: {\n fontSize: 14,\n fontWeight: '700',\n lineHeight: 18,\n // Two lines reserved so every row lines up whether a name wraps or not.\n minHeight: 36,\n },\n cardCaption: {\n fontSize: 11,\n fontWeight: '600',\n letterSpacing: 0.8,\n textTransform: 'uppercase',\n },\n empty: {\n alignItems: 'center',\n paddingTop: 56,\n paddingHorizontal: 32,\n gap: 6,\n },\n emptyMark: {\n width: 56,\n height: 56,\n borderRadius: 28,\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: 8,\n },\n emptyTitle: {\n fontSize: 16,\n fontWeight: '700',\n },\n emptyHint: {\n fontSize: 14,\n textAlign: 'center',\n lineHeight: 20,\n },\n});\n"],"names":["_a","uuidv4","React","AppCard"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appLabelText.js","sources":["../../../src/features/apps/appLabelText.ts"],"sourcesContent":["/**\n * How an app's name sits on a narrow tile. A name with a space wraps at the\n * space onto a second line. A one-word name longer than the tile is wide\n * (\"Spreadsheets\" on a 3-column phone) would otherwise break mid-word\n * (\"Spreadsheet\" / \"s\"), so it keeps one line and shrinks to fit instead.\n */\nexport type AppLabelTextProps =\n | { numberOfLines: 2 }\n | { numberOfLines: 1; adjustsFontSizeToFit: true; minimumFontScale: number };\n\nexport function appLabelTextProps(label: string): AppLabelTextProps {\n return /\\s/.test(label.trim())\n ? { numberOfLines: 2 }\n : { numberOfLines: 1, adjustsFontSizeToFit: true, minimumFontScale: 0.75 };\n}\n"],"names":[],"mappings":"AAaO,SAAS,kBAAkB,KAAkC,EAAA;AAClE,EAAA,OAAO,IAAK,CAAA,IAAA,CAAK,KAAM,CAAA,IAAA,EAAM,CAAI,GAAA;AAAA,IAC/B,aAAe,EAAA;AAAA,GACb,GAAA;AAAA,IACF,aAAe,EAAA,CAAA;AAAA,IACf,oBAAsB,EAAA,IAAA;AAAA,IACtB,gBAAkB,EAAA;AAAA,GACpB;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import {useMemo,useState,useRef,useCallback,useEffect}from'react';import {Alert,BackHandler,Share,View,StyleSheet,ScrollView,Text,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
2
|
var __defProps = Object.defineProperties;
|
|
3
3
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
@@ -59,12 +59,16 @@ function DictateExperience({
|
|
|
59
59
|
tokenRef.current = token;
|
|
60
60
|
const agent = useMemo(() => deps != null ? deps : {
|
|
61
61
|
exec: (connector, action, params, options) => {
|
|
62
|
-
const
|
|
62
|
+
const {
|
|
63
|
+
current
|
|
64
|
+
} = tokenRef;
|
|
63
65
|
if (!current) return Promise.reject(new Error("Network request failed: not signed in yet"));
|
|
64
66
|
return createRemoteConnectorExec(current, indexUrl)(connector, action, params, options);
|
|
65
67
|
},
|
|
66
68
|
upload: (uri) => {
|
|
67
|
-
const
|
|
69
|
+
const {
|
|
70
|
+
current
|
|
71
|
+
} = tokenRef;
|
|
68
72
|
if (!current) return Promise.reject(new Error("Network request failed: not signed in yet"));
|
|
69
73
|
return createRemoteUploadMedia(current, indexUrl)(uri);
|
|
70
74
|
}
|
|
@@ -179,7 +183,9 @@ function DictateExperience({
|
|
|
179
183
|
style: "cancel"
|
|
180
184
|
}, {
|
|
181
185
|
text: "Write the note",
|
|
182
|
-
onPress: () =>
|
|
186
|
+
onPress: () => {
|
|
187
|
+
void done();
|
|
188
|
+
}
|
|
183
189
|
}, {
|
|
184
190
|
text: "Discard",
|
|
185
191
|
style: "destructive",
|
|
@@ -218,7 +224,8 @@ function DictateExperience({
|
|
|
218
224
|
}, [open]);
|
|
219
225
|
const remove = useCallback(() => {
|
|
220
226
|
if (!open) return;
|
|
221
|
-
|
|
227
|
+
const removed = open.note ? "The note and transcript are removed from this phone." : "The recording is removed from this phone.";
|
|
228
|
+
Alert.alert("Delete this dictation?", removed, [{
|
|
222
229
|
text: "Cancel",
|
|
223
230
|
style: "cancel"
|
|
224
231
|
}, {
|
|
@@ -236,23 +243,17 @@ function DictateExperience({
|
|
|
236
243
|
}]);
|
|
237
244
|
}, [open, store, refresh]);
|
|
238
245
|
const title = screen.kind === "note" ? "Note" : "Dictate";
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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, {
|
|
246
|
+
let body;
|
|
247
|
+
if (screen.kind === "note" && open) {
|
|
248
|
+
body = /* @__PURE__ */ jsx(NoteView, { record: open, stage: (_b = stages[open.id]) != null ? _b : null, theme, bottomInset: insets.bottom, onRetry: () => {
|
|
249
|
+
void write(open);
|
|
250
|
+
} });
|
|
251
|
+
} else if (screen.kind === "record" && recorder.phase !== "idle") {
|
|
252
|
+
body = /* @__PURE__ */ jsx(View, { style: styles.recordBody, children: /* @__PURE__ */ jsx(RecordingPanel, { theme, phase: recorder.phase, pauseReason: recorder.pauseReason, elapsedMs: recorder.elapsedMs, level: recorder.level, noInput: recorder.noInput, onPause: recorder.pause, onResume: recorder.resume, onDone: () => {
|
|
253
|
+
void done();
|
|
254
|
+
}, onDiscard: discard }) });
|
|
255
|
+
} else {
|
|
256
|
+
body = /* @__PURE__ */ jsxs(ScrollView, { contentContainerStyle: [styles.home, {
|
|
256
257
|
paddingBottom: 24 + insets.bottom
|
|
257
258
|
}], children: [
|
|
258
259
|
/* @__PURE__ */ jsx(Text, { style: [styles.lead, {
|
|
@@ -261,7 +262,9 @@ function DictateExperience({
|
|
|
261
262
|
/* @__PURE__ */ jsx(Text, { style: [styles.leadDetail, {
|
|
262
263
|
color: theme.muted
|
|
263
264
|
}], 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: () =>
|
|
265
|
+
/* @__PURE__ */ jsx(StartPanel, { theme, starting, recordsInBackground: recorder.recordsInBackground, onStart: () => {
|
|
266
|
+
void start();
|
|
267
|
+
} }),
|
|
265
268
|
error ? /* @__PURE__ */ jsx(Text, { style: [styles.error, {
|
|
266
269
|
color: theme.crit
|
|
267
270
|
}], children: error }) : null,
|
|
@@ -272,7 +275,9 @@ function DictateExperience({
|
|
|
272
275
|
/* @__PURE__ */ jsx(Text, { style: [styles.bannerText, {
|
|
273
276
|
color: theme.crit
|
|
274
277
|
}], children: "Microphone access is off for Yantra." }),
|
|
275
|
-
/* @__PURE__ */ jsx(Tap, { onPress: () =>
|
|
278
|
+
/* @__PURE__ */ jsx(Tap, { onPress: () => {
|
|
279
|
+
void Linking.openSettings();
|
|
280
|
+
}, accessibilityRole: "button", style: [styles.bannerAction, {
|
|
276
281
|
backgroundColor: theme.card,
|
|
277
282
|
borderColor: theme.border
|
|
278
283
|
}], pressedStyle: DIM, children: /* @__PURE__ */ jsx(Text, { style: [styles.bannerActionText, {
|
|
@@ -301,7 +306,25 @@ function DictateExperience({
|
|
|
301
306
|
kind: "note",
|
|
302
307
|
id: r.id
|
|
303
308
|
}) })
|
|
304
|
-
] })
|
|
309
|
+
] });
|
|
310
|
+
}
|
|
311
|
+
return /* @__PURE__ */ jsxs(View, { style: [styles.screen, {
|
|
312
|
+
backgroundColor: theme.screen,
|
|
313
|
+
paddingTop: insets.top
|
|
314
|
+
}], children: [
|
|
315
|
+
/* @__PURE__ */ jsxs(View, { style: [styles.header, {
|
|
316
|
+
borderBottomColor: theme.border
|
|
317
|
+
}], children: [
|
|
318
|
+
/* @__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 }) }),
|
|
319
|
+
/* @__PURE__ */ jsx(Text, { style: [styles.headerTitle, {
|
|
320
|
+
color: theme.ink
|
|
321
|
+
}], children: title }),
|
|
322
|
+
/* @__PURE__ */ jsxs(View, { style: styles.headerActions, children: [
|
|
323
|
+
(open == null ? void 0 : open.note) ? /* @__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 }) }) : null,
|
|
324
|
+
open && !stages[open.id] ? /* @__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 }) }) : null
|
|
325
|
+
] })
|
|
326
|
+
] }),
|
|
327
|
+
body
|
|
305
328
|
] });
|
|
306
329
|
}
|
|
307
330
|
const styles = StyleSheet.create({
|
|
@@ -1 +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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"}
|
|
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({\n isDark: hostDark,\n token,\n indexUrl,\n sessionError,\n onRetrySession,\n onExit,\n deps,\n store: injectedStore,\n}: 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;\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;\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, {\n status: 'ready',\n note: written.note,\n transcript: written.transcript,\n model: written.model,\n error: undefined,\n });\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 {\n text: 'Write the note',\n onPress: () => {\n void done();\n },\n },\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 const removed = open.note\n ? 'The note and transcript are removed from this phone.'\n : 'The recording is removed from this phone.';\n Alert.alert('Delete this dictation?', removed, [\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 // The note, the live recording, or the home list - whichever screen is open.\n let body: React.ReactNode;\n if (screen.kind === 'note' && open) {\n body = (\n <NoteView\n record={open}\n stage={stages[open.id] ?? null}\n theme={theme}\n bottomInset={insets.bottom}\n onRetry={() => {\n void write(open);\n }}\n />\n );\n } else if (screen.kind === 'record' && recorder.phase !== 'idle') {\n body = (\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 noInput={recorder.noInput}\n onPause={recorder.pause}\n onResume={recorder.resume}\n onDone={() => {\n void done();\n }}\n onDiscard={discard}\n />\n </View>\n );\n } else {\n body = (\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\n theme={theme}\n starting={starting}\n recordsInBackground={recorder.recordsInBackground}\n onStart={() => {\n void start();\n }}\n />\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 }]}>\n Microphone access is off for Yantra.\n </Text>\n <Tap\n onPress={() => {\n void Linking.openSettings();\n }}\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\n onPress={onRetrySession}\n accessibilityRole=\"button\"\n style={[styles.banner, { backgroundColor: theme.recSoft }]}\n pressedStyle={DIM}\n >\n <Text style={[styles.bannerText, { color: theme.crit }]}>\n Not connected, so notes cannot be written yet. Tap to retry.\n </Text>\n </Tap>\n ) : null}\n <View\n style={[\n styles.banner,\n {\n backgroundColor: theme.warnSoft,\n borderColor: theme.warnBorder,\n borderWidth: StyleSheet.hairlineWidth,\n },\n ]}\n >\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 }\n\n return (\n <View style={[styles.screen, { backgroundColor: theme.screen, paddingTop: insets.top }]}>\n <View style={[styles.header, { borderBottomColor: theme.border }]}>\n <Tap\n onPress={back}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Back\"\n style={styles.headerButton}\n pressedStyle={DIM}\n >\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 <Tap\n onPress={share}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Share the note\"\n style={styles.headerButton}\n pressedStyle={DIM}\n >\n <MaterialCommunityIcons name=\"export-variant\" size={22} color={theme.ink} />\n </Tap>\n ) : null}\n {/* Any dictation can go, note or not; just not while its note is being written. */}\n {open && !stages[open.id] ? (\n <Tap\n onPress={remove}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Delete\"\n style={styles.headerButton}\n pressedStyle={DIM}\n >\n <MaterialCommunityIcons name=\"trash-can-outline\" size={22} color={theme.ink} />\n </Tap>\n ) : null}\n </View>\n </View>\n\n {body}\n </View>\n );\n}\n\nexport default DictateExperience;\n\nconst styles = StyleSheet.create({\n screen: { flex: 1 },\n header: {\n height: 52,\n flexDirection: 'row',\n alignItems: 'center',\n paddingHorizontal: 4,\n borderBottomWidth: StyleSheet.hairlineWidth,\n },\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: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 10,\n borderRadius: 12,\n paddingHorizontal: 12,\n paddingVertical: 10,\n marginBottom: 12,\n },\n bannerText: { flex: 1, fontSize: 13, lineHeight: 18 },\n bannerAction: {\n paddingHorizontal: 12,\n paddingVertical: 7,\n borderRadius: 999,\n borderWidth: StyleSheet.hairlineWidth,\n },\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,15 @@
|
|
|
1
|
+
import {requireOptionalNativeModule}from'expo-modules-core';let cached;
|
|
2
|
+
function backgroundRecordingNative() {
|
|
3
|
+
if (cached === void 0) {
|
|
4
|
+
try {
|
|
5
|
+
cached = requireOptionalNativeModule("YantraBackgroundRecording");
|
|
6
|
+
} catch (e) {
|
|
7
|
+
cached = null;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return cached;
|
|
11
|
+
}
|
|
12
|
+
const BACKGROUND_NOTICE = {
|
|
13
|
+
title: "Dictating",
|
|
14
|
+
text: "Yantra is recording your dictation. Tap to return."
|
|
15
|
+
};export{BACKGROUND_NOTICE,backgroundRecordingNative};//# sourceMappingURL=backgroundRecording.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backgroundRecording.js","sources":["../../../src/features/dictate/backgroundRecording.ts"],"sourcesContent":["/**\n * The app's background-recording module (portable-devices/mobile/modules/\n * yantra-background-recording), which keeps a dictation going when Yantra\n * leaves the screen, the way a call does:\n * - iOS: the binary declares the `audio` background mode; iOS shows its own\n * recording indicator. The module also reports interruptions (a phone call,\n * another app recording), which expo-audio does not.\n * - Android: a microphone foreground service with an ongoing notification,\n * without which Android gives a backgrounded app only silence.\n *\n * Optional on purpose: an over-the-air JS update can reach a binary built\n * before the module existed. That reads as \"not supported\", and Dictate\n * pauses when it leaves the screen, as before.\n */\nimport { requireOptionalNativeModule } from 'expo-modules-core';\n\nexport type InterruptionEvent = { state: 'began' } | { state: 'ended'; shouldResume: boolean };\n\nexport interface BackgroundRecordingNative {\n /** The binary may keep recording in the background. */\n readonly supported: boolean;\n /** Android starts the microphone service (title and text show in its notification); iOS has nothing to start. */\n start(title: string, text: string): Promise<void>;\n stop(): Promise<void>;\n addListener(event: 'onInterruption', listener: (event: InterruptionEvent) => void): { remove(): void };\n}\n\nlet cached: BackgroundRecordingNative | null | undefined;\n\nexport function backgroundRecordingNative(): BackgroundRecordingNative | null {\n if (cached === undefined) {\n try {\n cached = requireOptionalNativeModule<BackgroundRecordingNative>('YantraBackgroundRecording');\n } catch {\n cached = null;\n }\n }\n return cached;\n}\n\n/** What the Android notification says while a dictation records in the background. */\nexport const BACKGROUND_NOTICE = { title: 'Dictating', text: 'Yantra is recording your dictation. Tap to return.' };\n"],"names":[],"mappings":"4DA+BA,IAAI,MAAA;AACG,SAAS,yBAA8D,GAAA;AAC5E,EAAA,IAAI,WAAW,MAAW,EAAA;AACxB,IAAI,IAAA;AACF,MAAA,MAAA,GAAS,4BAAuD,2BAA2B,CAAA;AAAA,KACrF,CAAA,OAAA,CAAA,EAAA;AACN,MAAS,MAAA,GAAA,IAAA;AAAA;AACX;AAEF,EAAO,OAAA,MAAA;AACT;AAGO,MAAM,iBAAoB,GAAA;AAAA,EAC/B,KAAO,EAAA,WAAA;AAAA,EACP,IAAM,EAAA;AACR"}
|
|
@@ -1 +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')
|
|
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')\n 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 (\n <Text style={[styles.empty, { color: theme.faint }]}>\n Your dictations stay on this phone and show up here.\n </Text>\n );\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={[\n styles.row,\n i > 0 && { borderTopColor: theme.border, borderTopWidth: StyleSheet.hairlineWidth },\n ]}\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)]\n .filter(Boolean)\n .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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"}
|