@adminide-stack/yantra-mobile 12.0.108-alpha.0 → 12.0.109-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/compute.js +57 -1
- package/lib/compute.js.map +1 -1
- package/lib/config/env-config.js +8 -0
- package/lib/config/env-config.js.map +1 -1
- package/lib/features/apps/AppsCatalog.js +10 -0
- package/lib/features/apps/AppsCatalog.js.map +1 -1
- package/lib/features/apps/appArt.js +2 -1
- package/lib/features/apps/appArt.js.map +1 -1
- package/lib/features/apps/mobileAppCatalog.js +11 -0
- package/lib/features/apps/mobileAppCatalog.js.map +1 -1
- package/lib/features/apps/nativeAppHandoff.js +2 -1
- package/lib/features/apps/nativeAppHandoff.js.map +1 -1
- package/lib/features/health/healthSyncStore.js +7 -1
- package/lib/features/health/healthSyncStore.js.map +1 -1
- package/lib/features/messaging/NewGroupScreen.js.map +1 -1
- package/lib/features/messaging/useChatViewer.js +3 -2
- package/lib/features/messaging/useChatViewer.js.map +1 -1
- package/lib/features/webbuilder/WebBuilderExperience.js +474 -0
- package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -0
- package/lib/features/webbuilder/brandKitStorage.js +69 -0
- package/lib/features/webbuilder/brandKitStorage.js.map +1 -0
- package/lib/features/webbuilder/buildFragments.js +360 -0
- package/lib/features/webbuilder/buildFragments.js.map +1 -0
- package/lib/features/webbuilder/components/BottomTabs.js +65 -0
- package/lib/features/webbuilder/components/BottomTabs.js.map +1 -0
- package/lib/features/webbuilder/components/BrandKitSheet.js +197 -0
- package/lib/features/webbuilder/components/BrandKitSheet.js.map +1 -0
- package/lib/features/webbuilder/components/CodeView.js +99 -0
- package/lib/features/webbuilder/components/CodeView.js.map +1 -0
- package/lib/features/webbuilder/components/Composer.js +217 -0
- package/lib/features/webbuilder/components/Composer.js.map +1 -0
- package/lib/features/webbuilder/components/PreviewFrame.js +72 -0
- package/lib/features/webbuilder/components/PreviewFrame.js.map +1 -0
- package/lib/features/webbuilder/components/PreviewPlaceholder.js +107 -0
- package/lib/features/webbuilder/components/PreviewPlaceholder.js.map +1 -0
- package/lib/features/webbuilder/components/PreviewScreen.js +200 -0
- package/lib/features/webbuilder/components/PreviewScreen.js.map +1 -0
- package/lib/features/webbuilder/components/ProjectChat.js +580 -0
- package/lib/features/webbuilder/components/ProjectChat.js.map +1 -0
- package/lib/features/webbuilder/components/ProjectsScreen.js +339 -0
- package/lib/features/webbuilder/components/ProjectsScreen.js.map +1 -0
- package/lib/features/webbuilder/components/PublishSheet.js +143 -0
- package/lib/features/webbuilder/components/PublishSheet.js.map +1 -0
- package/lib/features/webbuilder/components/SiteScoreSheet.js +73 -0
- package/lib/features/webbuilder/components/SiteScoreSheet.js.map +1 -0
- package/lib/features/webbuilder/components/StudioHome.js +367 -0
- package/lib/features/webbuilder/components/StudioHome.js.map +1 -0
- package/lib/features/webbuilder/components/TemplateCard.js +73 -0
- package/lib/features/webbuilder/components/TemplateCard.js.map +1 -0
- package/lib/features/webbuilder/components/TemplatesSheet.js +178 -0
- package/lib/features/webbuilder/components/TemplatesSheet.js.map +1 -0
- package/lib/features/webbuilder/components/VersionsSheet.js +57 -0
- package/lib/features/webbuilder/components/VersionsSheet.js.map +1 -0
- package/lib/features/webbuilder/components/ui.js +291 -0
- package/lib/features/webbuilder/components/ui.js.map +1 -0
- package/lib/features/webbuilder/nativeWebBuilderRegistry.js +15 -0
- package/lib/features/webbuilder/nativeWebBuilderRegistry.js.map +1 -0
- package/lib/features/webbuilder/studioCatalog.js +147 -0
- package/lib/features/webbuilder/studioCatalog.js.map +1 -0
- package/lib/features/webbuilder/webbuilderPrompts.js +42 -0
- package/lib/features/webbuilder/webbuilderPrompts.js.map +1 -0
- package/lib/features/webbuilder/webbuilderTheme.js +63 -0
- package/lib/features/webbuilder/webbuilderTheme.js.map +1 -0
- package/lib/features/webbuilder/workflow.js +540 -0
- package/lib/features/webbuilder/workflow.js.map +1 -0
- package/lib/hooks/useChatApi.js +7 -2
- package/lib/hooks/useChatApi.js.map +1 -1
- package/lib/hooks/useChatStream.js +1 -1
- package/lib/hooks/useChatStream.js.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/routes.json +106 -0
- package/lib/screens/WebBuilderNative/index.js +71 -0
- package/lib/screens/WebBuilderNative/index.js.map +1 -0
- package/lib/screens/WebBuilderNative/useCodeAssistantCatalog.js +45 -0
- package/lib/screens/WebBuilderNative/useCodeAssistantCatalog.js.map +1 -0
- package/lib/screens/WebBuilderNative/useWebBuilderGallery.js +125 -0
- package/lib/screens/WebBuilderNative/useWebBuilderGallery.js.map +1 -0
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js +408 -0
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -0
- package/lib/screens/WebBuilderNative/webbuilderTransport.js +88 -0
- package/lib/screens/WebBuilderNative/webbuilderTransport.js.map +1 -0
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NewGroupScreen.js","sources":["../../../src/features/messaging/NewGroupScreen.tsx"],"sourcesContent":["/**\n * \"New group\", WhatsApp-style: name the group and pick members from your Yantra contacts, then\n * create. The creator becomes the admin (server-side); on success the caller opens the new chat.\n */\nimport * as React from 'react';\nimport { ActivityIndicator, FlatList, Pressable, StyleSheet, Text, TextInput, View } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { Avatar, EmptyState, InlineBanner, type ChatTheme } from './ChatComponents';\nimport { TapRow } from './TapRow';\n\nexport interface GroupCandidate {\n userId: string;\n displayName: string;\n imageUri?: string | null;\n}\n\n/** WhatsApp caps a group at 1024 members; the picker enforces the same so create can't fail late. */\nexport const GROUP_MEMBER_LIMIT = 1024;\n\nexport function NewGroupScreen({\n candidates,\n theme,\n busy,\n mode = 'create',\n onCancel,\n onCreate,\n}: {\n candidates: GroupCandidate[];\n theme: ChatTheme;\n busy?: boolean;\n /** 'create' names a new group; 'add' adds members to an existing one (no name step). */\n mode?: 'create' | 'add';\n onCancel: () => void;\n /** Create the group (or add members); resolves a channel id / truthy, or null on failure. */\n onCreate: (name: string, memberIds: string[]) => Promise<string | null>;\n}) {\n const adding = mode === 'add';\n const [name, setName] = React.useState('');\n const [picked, setPicked] = React.useState<string[]>([]);\n const [query, setQuery] = React.useState('');\n const [creating, setCreating] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n\n const rows = React.useMemo(() => {\n const q = query.trim().toLowerCase();\n const seen = new Set<string>();\n return candidates.filter((c) => {\n if (!c.userId || seen.has(c.userId)) return false;\n seen.add(c.userId);\n return !q || c.displayName.toLowerCase().includes(q);\n });\n }, [candidates, query]);\n\n const toggle = (id: string) => {\n setError(null);\n setPicked((prev) => {\n if (prev.includes(id)) return prev.filter((p) => p !== id);\n if (prev.length >= GROUP_MEMBER_LIMIT) {\n setError(`A group can have up to ${GROUP_MEMBER_LIMIT} members.`);\n return prev;\n }\n return [...prev, id];\n });\n };\n\n const canCreate = (adding || name.trim().length > 0) && picked.length > 0 && !creating && !busy;\n\n const create = async () => {\n if (!canCreate) return;\n setCreating(true);\n setError(null);\n try {\n const id = await onCreate(name.trim(), picked);\n if (!id) setError(adding ? 'Could not add members. Please try again.' : 'Could not create the group. Please try again.');\n } finally {\n setCreating(false);\n }\n };\n\n return (\n <View style={[styles.fill, { backgroundColor: theme.bg }]} testID=\"chat-new-group\">\n <SafeAreaView edges={['top']} style={{ backgroundColor: theme.headerBg }}>\n <View style={[styles.header, { borderBottomColor: theme.border, flexDirection: 'row' }]}>\n <Pressable onPress={onCancel} hitSlop={10} accessibilityRole=\"button\" style={styles.headerSide}>\n <Text style={{ color: theme.accent, fontSize: 17 }}>Cancel</Text>\n </Pressable>\n <Text style={[styles.title, { color: theme.text }]}>{adding ? 'Add members' : 'New group'}</Text>\n <Pressable\n onPress={create}\n disabled={!canCreate}\n hitSlop={10}\n accessibilityRole=\"button\"\n accessibilityLabel={adding ? 'Add members' : 'Create group'}\n style={[styles.headerSide, styles.headerRight]}\n testID=\"chat-new-group-create\"\n >\n {creating ? (\n <ActivityIndicator size=\"small\" color={theme.accent} />\n ) : (\n <Text style={{ color: canCreate ? theme.accent : theme.textMuted, fontSize: 17, fontWeight: '600' }}>\n {adding ? 'Add' : 'Create'}\n </Text>\n )}\n </Pressable>\n </View>\n </SafeAreaView>\n <InlineBanner message={error} theme={theme} onDismiss={() => setError(null)} />\n {adding ? null : (\n <View style={[styles.nameRow, { backgroundColor: theme.surface, flexDirection: 'row' }]}>\n <MaterialCommunityIcons name=\"account-group\" size={22} color={theme.textMuted} />\n <TextInput\n value={name}\n onChangeText={(t) => setName(t.slice(0, 100))}\n placeholder=\"Group name\"\n placeholderTextColor={theme.textMuted}\n style={[styles.nameInput, { color: theme.text }]}\n testID=\"chat-new-group-name\"\n />\n </View>\n )}\n <View style={[styles.search, { backgroundColor: theme.surface, flexDirection: 'row' }]}>\n <MaterialCommunityIcons name=\"magnify\" size={20} color={theme.textMuted} />\n <TextInput\n value={query}\n onChangeText={setQuery}\n placeholder=\"Search contacts\"\n placeholderTextColor={theme.textMuted}\n style={[styles.searchInput, { color: theme.text }]}\n testID=\"chat-new-group-search\"\n />\n </View>\n <Text style={[styles.count, { color: theme.textMuted }]}>\n {picked.length ? `${picked.length} selected` : 'Add members'}\n </Text>\n <FlatList\n data={rows}\n keyExtractor={(c) => c.userId}\n keyboardShouldPersistTaps=\"handled\"\n ListEmptyComponent={\n <EmptyState\n icon=\"account-group-outline\"\n title=\"No contacts yet\"\n detail=\"People on Yantra Chat appear here. Invite friends from a new chat.\"\n theme={theme}\n />\n }\n renderItem={({ item }) => {\n const on = picked.includes(item.userId);\n return (\n <TapRow\n onPress={() => toggle(item.userId)}\n accessibilityRole=\"checkbox\"\n accessibilityState={{ checked: on }}\n accessibilityLabel={item.displayName}\n pressedColor={theme.surface}\n testID={`chat-new-group-${item.userId}`}\n >\n <View style={[styles.row, { flexDirection: 'row' }]}>\n <View\n style={[\n styles.check,\n on\n ? { backgroundColor: theme.accent, borderColor: theme.accent }\n : { borderColor: theme.textMuted },\n ]}\n >\n {on ? <MaterialCommunityIcons name=\"check\" size={16} color={theme.onAccent} /> : null}\n </View>\n <Avatar name={item.displayName} uri={item.imageUri} theme={theme} size={44} variant=\"initials\" />\n <Text numberOfLines={1} style={[styles.rowTitle, { color: theme.text }]}>\n {item.displayName}\n </Text>\n </View>\n </TapRow>\n );\n }}\n />\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n header: {\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 12,\n minHeight: 52,\n borderBottomWidth: StyleSheet.hairlineWidth,\n },\n headerSide: { width: 72 },\n headerRight: { alignItems: 'flex-end' },\n title: { fontSize: 17, fontWeight: '600' },\n nameRow: { alignItems: 'center', margin: 12, marginBottom: 6, paddingHorizontal: 12, height: 48, borderRadius: 10 },\n nameInput: { flex: 1, marginLeft: 10, fontSize: 17, paddingVertical: 0 },\n search: {\n alignItems: 'center',\n marginHorizontal: 12,\n marginBottom: 4,\n borderRadius: 10,\n paddingHorizontal: 10,\n height: 36,\n },\n searchInput: { flex: 1, marginLeft: 8, fontSize: 16, paddingVertical: 0 },\n count: { fontSize: 12, fontWeight: '600', marginHorizontal: 18, marginTop: 8, marginBottom: 2, textTransform: 'uppercase' },\n row: { alignItems: 'center', paddingHorizontal: 16, paddingVertical: 8 },\n check: {\n width: 22,\n height: 22,\n borderRadius: 11,\n borderWidth: 1.5,\n alignItems: 'center',\n justifyContent: 'center',\n marginRight: 14,\n },\n rowTitle: { flex: 1, fontSize: 17, marginLeft: 12 },\n});\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"NewGroupScreen.js","sources":["../../../src/features/messaging/NewGroupScreen.tsx"],"sourcesContent":["/**\n * \"New group\", WhatsApp-style: name the group and pick members from your Yantra contacts, then\n * create. The creator becomes the admin (server-side); on success the caller opens the new chat.\n */\nimport * as React from 'react';\nimport { ActivityIndicator, FlatList, Pressable, StyleSheet, Text, TextInput, View } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { Avatar, EmptyState, InlineBanner, type ChatTheme } from './ChatComponents';\nimport { TapRow } from './TapRow';\n\nexport interface GroupCandidate {\n userId: string;\n displayName: string;\n imageUri?: string | null;\n}\n\n/** WhatsApp caps a group at 1024 members; the picker enforces the same so create can't fail late. */\nexport const GROUP_MEMBER_LIMIT = 1024;\n\nexport function NewGroupScreen({\n candidates,\n theme,\n busy,\n mode = 'create',\n onCancel,\n onCreate,\n}: {\n candidates: GroupCandidate[];\n theme: ChatTheme;\n busy?: boolean;\n /** 'create' names a new group; 'add' adds members to an existing one (no name step). */\n mode?: 'create' | 'add';\n onCancel: () => void;\n /** Create the group (or add members); resolves a channel id / truthy, or null on failure. */\n onCreate: (name: string, memberIds: string[]) => Promise<string | null>;\n}) {\n const adding = mode === 'add';\n const [name, setName] = React.useState('');\n const [picked, setPicked] = React.useState<string[]>([]);\n const [query, setQuery] = React.useState('');\n const [creating, setCreating] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n\n const rows = React.useMemo(() => {\n const q = query.trim().toLowerCase();\n const seen = new Set<string>();\n return candidates.filter((c) => {\n if (!c.userId || seen.has(c.userId)) return false;\n seen.add(c.userId);\n return !q || c.displayName.toLowerCase().includes(q);\n });\n }, [candidates, query]);\n\n const toggle = (id: string) => {\n setError(null);\n setPicked((prev) => {\n if (prev.includes(id)) return prev.filter((p) => p !== id);\n if (prev.length >= GROUP_MEMBER_LIMIT) {\n setError(`A group can have up to ${GROUP_MEMBER_LIMIT} members.`);\n return prev;\n }\n return [...prev, id];\n });\n };\n\n const canCreate = (adding || name.trim().length > 0) && picked.length > 0 && !creating && !busy;\n\n const create = async () => {\n if (!canCreate) return;\n setCreating(true);\n setError(null);\n try {\n const id = await onCreate(name.trim(), picked);\n if (!id)\n setError(\n adding\n ? 'Could not add members. Please try again.'\n : 'Could not create the group. Please try again.',\n );\n } finally {\n setCreating(false);\n }\n };\n\n return (\n <View style={[styles.fill, { backgroundColor: theme.bg }]} testID=\"chat-new-group\">\n <SafeAreaView edges={['top']} style={{ backgroundColor: theme.headerBg }}>\n <View style={[styles.header, { borderBottomColor: theme.border, flexDirection: 'row' }]}>\n <Pressable onPress={onCancel} hitSlop={10} accessibilityRole=\"button\" style={styles.headerSide}>\n <Text style={{ color: theme.accent, fontSize: 17 }}>Cancel</Text>\n </Pressable>\n <Text style={[styles.title, { color: theme.text }]}>{adding ? 'Add members' : 'New group'}</Text>\n <Pressable\n onPress={create}\n disabled={!canCreate}\n hitSlop={10}\n accessibilityRole=\"button\"\n accessibilityLabel={adding ? 'Add members' : 'Create group'}\n style={[styles.headerSide, styles.headerRight]}\n testID=\"chat-new-group-create\"\n >\n {creating ? (\n <ActivityIndicator size=\"small\" color={theme.accent} />\n ) : (\n <Text\n style={{\n color: canCreate ? theme.accent : theme.textMuted,\n fontSize: 17,\n fontWeight: '600',\n }}\n >\n {adding ? 'Add' : 'Create'}\n </Text>\n )}\n </Pressable>\n </View>\n </SafeAreaView>\n <InlineBanner message={error} theme={theme} onDismiss={() => setError(null)} />\n {adding ? null : (\n <View style={[styles.nameRow, { backgroundColor: theme.surface, flexDirection: 'row' }]}>\n <MaterialCommunityIcons name=\"account-group\" size={22} color={theme.textMuted} />\n <TextInput\n value={name}\n onChangeText={(t) => setName(t.slice(0, 100))}\n placeholder=\"Group name\"\n placeholderTextColor={theme.textMuted}\n style={[styles.nameInput, { color: theme.text }]}\n testID=\"chat-new-group-name\"\n />\n </View>\n )}\n <View style={[styles.search, { backgroundColor: theme.surface, flexDirection: 'row' }]}>\n <MaterialCommunityIcons name=\"magnify\" size={20} color={theme.textMuted} />\n <TextInput\n value={query}\n onChangeText={setQuery}\n placeholder=\"Search contacts\"\n placeholderTextColor={theme.textMuted}\n style={[styles.searchInput, { color: theme.text }]}\n testID=\"chat-new-group-search\"\n />\n </View>\n <Text style={[styles.count, { color: theme.textMuted }]}>\n {picked.length ? `${picked.length} selected` : 'Add members'}\n </Text>\n <FlatList\n data={rows}\n keyExtractor={(c) => c.userId}\n keyboardShouldPersistTaps=\"handled\"\n ListEmptyComponent={\n <EmptyState\n icon=\"account-group-outline\"\n title=\"No contacts yet\"\n detail=\"People on Yantra Chat appear here. Invite friends from a new chat.\"\n theme={theme}\n />\n }\n renderItem={({ item }) => {\n const on = picked.includes(item.userId);\n return (\n <TapRow\n onPress={() => toggle(item.userId)}\n accessibilityRole=\"checkbox\"\n accessibilityState={{ checked: on }}\n accessibilityLabel={item.displayName}\n pressedColor={theme.surface}\n testID={`chat-new-group-${item.userId}`}\n >\n <View style={[styles.row, { flexDirection: 'row' }]}>\n <View\n style={[\n styles.check,\n on\n ? { backgroundColor: theme.accent, borderColor: theme.accent }\n : { borderColor: theme.textMuted },\n ]}\n >\n {on ? (\n <MaterialCommunityIcons name=\"check\" size={16} color={theme.onAccent} />\n ) : null}\n </View>\n <Avatar\n name={item.displayName}\n uri={item.imageUri}\n theme={theme}\n size={44}\n variant=\"initials\"\n />\n <Text numberOfLines={1} style={[styles.rowTitle, { color: theme.text }]}>\n {item.displayName}\n </Text>\n </View>\n </TapRow>\n );\n }}\n />\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n header: {\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 12,\n minHeight: 52,\n borderBottomWidth: StyleSheet.hairlineWidth,\n },\n headerSide: { width: 72 },\n headerRight: { alignItems: 'flex-end' },\n title: { fontSize: 17, fontWeight: '600' },\n nameRow: { alignItems: 'center', margin: 12, marginBottom: 6, paddingHorizontal: 12, height: 48, borderRadius: 10 },\n nameInput: { flex: 1, marginLeft: 10, fontSize: 17, paddingVertical: 0 },\n search: {\n alignItems: 'center',\n marginHorizontal: 12,\n marginBottom: 4,\n borderRadius: 10,\n paddingHorizontal: 10,\n height: 36,\n },\n searchInput: { flex: 1, marginLeft: 8, fontSize: 16, paddingVertical: 0 },\n count: {\n fontSize: 12,\n fontWeight: '600',\n marginHorizontal: 18,\n marginTop: 8,\n marginBottom: 2,\n textTransform: 'uppercase',\n },\n row: { alignItems: 'center', paddingHorizontal: 16, paddingVertical: 8 },\n check: {\n width: 22,\n height: 22,\n borderRadius: 11,\n borderWidth: 1.5,\n alignItems: 'center',\n justifyContent: 'center',\n marginRight: 14,\n },\n rowTitle: { flex: 1, fontSize: 17, marginLeft: 12 },\n});\n"],"names":[],"mappings":"wXAiBO,MAAM,kBAAqB,GAAA;AAC3B,SAAS,cAAe,CAAA;AAAA,EAC7B,UAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAO,GAAA,QAAA;AAAA,EACP,QAAA;AAAA,EACA;AACF,CASG,EAAA;AACD,EAAA,MAAM,SAAS,IAAS,KAAA,KAAA;AACxB,EAAA,MAAM,CAAC,IAAM,EAAA,OAAO,CAAI,GAAA,KAAA,CAAM,SAAS,EAAE,CAAA;AACzC,EAAA,MAAM,CAAC,MAAQ,EAAA,SAAS,IAAI,KAAM,CAAA,QAAA,CAAmB,EAAE,CAAA;AACvD,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,CAAI,GAAA,KAAA,CAAM,SAAS,EAAE,CAAA;AAC3C,EAAA,MAAM,CAAC,QAAU,EAAA,WAAW,CAAI,GAAA,KAAA,CAAM,SAAS,KAAK,CAAA;AACpD,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,CAAI,GAAA,KAAA,CAAM,SAAwB,IAAI,CAAA;AAC5D,EAAM,MAAA,IAAA,GAAO,KAAM,CAAA,OAAA,CAAQ,MAAM;AAC/B,IAAA,MAAM,CAAI,GAAA,KAAA,CAAM,IAAK,EAAA,CAAE,WAAY,EAAA;AACnC,IAAM,MAAA,IAAA,uBAAW,GAAY,EAAA;AAC7B,IAAO,OAAA,UAAA,CAAW,OAAO,CAAK,CAAA,KAAA;AAC5B,MAAI,IAAA,CAAC,EAAE,MAAU,IAAA,IAAA,CAAK,IAAI,CAAE,CAAA,MAAM,GAAU,OAAA,KAAA;AAC5C,MAAK,IAAA,CAAA,GAAA,CAAI,EAAE,MAAM,CAAA;AACjB,MAAA,OAAO,CAAC,CAAK,IAAA,CAAA,CAAE,YAAY,WAAY,EAAA,CAAE,SAAS,CAAC,CAAA;AAAA,KACpD,CAAA;AAAA,GACA,EAAA,CAAC,UAAY,EAAA,KAAK,CAAC,CAAA;AACtB,EAAM,MAAA,MAAA,GAAS,CAAC,EAAe,KAAA;AAC7B,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,SAAA,CAAU,CAAQ,IAAA,KAAA;AAChB,MAAI,IAAA,IAAA,CAAK,SAAS,EAAE,CAAA,SAAU,IAAK,CAAA,MAAA,CAAO,CAAK,CAAA,KAAA,CAAA,KAAM,EAAE,CAAA;AACvD,MAAI,IAAA,IAAA,CAAK,UAAU,kBAAoB,EAAA;AACrC,QAAS,QAAA,CAAA,CAAA,uBAAA,EAA0B,kBAAkB,CAAW,SAAA,CAAA,CAAA;AAChE,QAAO,OAAA,IAAA;AAAA;AAET,MAAO,OAAA,CAAC,GAAG,IAAA,EAAM,EAAE,CAAA;AAAA,KACpB,CAAA;AAAA,GACH;AACA,EAAA,MAAM,SAAa,GAAA,CAAA,MAAA,IAAU,IAAK,CAAA,IAAA,EAAO,CAAA,MAAA,GAAS,CAAM,KAAA,MAAA,CAAO,MAAS,GAAA,CAAA,IAAK,CAAC,QAAA,IAAY,CAAC,IAAA;AAC3F,EAAA,MAAM,SAAS,YAAY;AACzB,IAAA,IAAI,CAAC,SAAW,EAAA;AAChB,IAAA,WAAA,CAAY,IAAI,CAAA;AAChB,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAI,IAAA;AACF,MAAA,MAAM,KAAK,MAAM,QAAA,CAAS,IAAK,CAAA,IAAA,IAAQ,MAAM,CAAA;AAC7C,MAAA,IAAI,CAAC,EAAA,EAAa,QAAA,CAAA,MAAA,GAAS,6CAA6C,+CAA+C,CAAA;AAAA,KACvH,SAAA;AACA,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA;AACnB,GACF;AACA,EAAA,uBAAQ,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,IAAM,EAAA;AAAA,IAChC,iBAAiB,KAAM,CAAA;AAAA,GACxB,CAAG,EAAA,MAAA,EAAO,gBACD,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,YAAa,EAAA,EAAA,KAAA,EAAO,CAAC,KAAK,GAAG,KAAO,EAAA;AAAA,MAC3C,iBAAiB,KAAM,CAAA;AAAA,OAEb,QAAC,kBAAA,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,MAAQ,EAAA;AAAA,MACrC,mBAAmB,KAAM,CAAA,MAAA;AAAA,MACzB,aAAe,EAAA;AAAA,KAChB,CACa,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,SAAU,EAAA,EAAA,OAAA,EAAS,QAAU,EAAA,OAAA,EAAS,EAAI,EAAA,iBAAA,EAAkB,QAAS,EAAA,KAAA,EAAO,MAAO,CAAA,UAAA,EAChF,QAAC,kBAAA,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA;AAAA,QACzB,OAAO,KAAM,CAAA,MAAA;AAAA,QACb,QAAU,EAAA;AAAA,OACZ,EAAG,oBAAM,CACC,EAAA,CAAA;AAAA,sBACC,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,KAAO,EAAA;AAAA,QACtC,OAAO,KAAM,CAAA;AAAA,OACd,CAAA,EAAI,QAAS,EAAA,MAAA,GAAA,aAAA,GAAgB,WAAY,EAAA,CAAA;AAAA,sBAC7B,GAAA,CAAA,SAAA,EAAA,EAAU,OAAS,EAAA,MAAA,EAAQ,UAAU,CAAC,SAAA,EAAW,OAAS,EAAA,EAAA,EAAI,mBAAkB,QAAS,EAAA,kBAAA,EAAoB,MAAS,GAAA,aAAA,GAAgB,gBAAgB,KAAO,EAAA,CAAC,MAAO,CAAA,UAAA,EAAY,OAAO,WAAW,CAAA,EAAG,MAAO,EAAA,uBAAA,EACzM,qCAAY,GAAA,CAAA,iBAAA,EAAA,EAAkB,IAAK,EAAA,OAAA,EAAQ,OAAO,KAAM,CAAA,MAAA,EAAQ,CAAK,mBAAA,GAAA,CAAC,QAAK,KAAO,EAAA;AAAA,QAC/F,KAAO,EAAA,SAAA,GAAY,KAAM,CAAA,MAAA,GAAS,KAAM,CAAA,SAAA;AAAA,QACxC,QAAU,EAAA,EAAA;AAAA,QACV,UAAY,EAAA;AAAA,OAES,EAAA,QAAA,EAAA,MAAA,GAAS,KAAQ,GAAA,QAAA,EACtB,CACR,EAAA;AAAA,KAAA,EACJ,CACJ,EAAA,CAAA;AAAA,oBACA,GAAA,CAAC,gBAAa,OAAS,EAAA,KAAA,EAAO,OAAc,SAAW,EAAA,MAAM,QAAS,CAAA,IAAI,CAAG,EAAA,CAAA;AAAA,IAC5E,SAAS,IAAO,mBAAA,IAAA,CAAC,QAAK,KAAO,EAAA,CAAC,OAAO,OAAS,EAAA;AAAA,MACrD,iBAAiB,KAAM,CAAA,OAAA;AAAA,MACvB,aAAe,EAAA;AAAA,KAChB,CACe,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,0BAAuB,IAAK,EAAA,eAAA,EAAgB,MAAM,EAAI,EAAA,KAAA,EAAO,MAAM,SAAW,EAAA,CAAA;AAAA,sBAC/E,GAAA,CAAC,aAAU,KAAO,EAAA,IAAA,EAAM,cAAc,CAAK,CAAA,KAAA,OAAA,CAAQ,EAAE,KAAM,CAAA,CAAA,EAAG,GAAG,CAAC,CAAA,EAAG,aAAY,YAAa,EAAA,oBAAA,EAAsB,MAAM,SAAW,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,SAAW,EAAA;AAAA,QAC3K,OAAO,KAAM,CAAA;AAAA,OACd,CAAG,EAAA,MAAA,EAAO,qBAAsB,EAAA;AAAA,KACvB,EAAA,CAAA;AAAA,oBACH,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,MAAQ,EAAA;AAAA,MACnC,iBAAiB,KAAM,CAAA,OAAA;AAAA,MACvB,aAAe,EAAA;AAAA,KAChB,CACW,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,0BAAuB,IAAK,EAAA,SAAA,EAAU,MAAM,EAAI,EAAA,KAAA,EAAO,MAAM,SAAW,EAAA,CAAA;AAAA,sBACxE,GAAA,CAAA,SAAA,EAAA,EAAU,KAAO,EAAA,KAAA,EAAO,cAAc,QAAU,EAAA,WAAA,EAAY,iBAAkB,EAAA,oBAAA,EAAsB,KAAM,CAAA,SAAA,EAAW,KAAO,EAAA,CAAC,OAAO,WAAa,EAAA;AAAA,QAC1J,OAAO,KAAM,CAAA;AAAA,OACd,CAAG,EAAA,MAAA,EAAO,uBAAwB,EAAA;AAAA,KAC7B,EAAA,CAAA;AAAA,oBACC,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,KAAO,EAAA;AAAA,MAClC,OAAO,KAAM,CAAA;AAAA,KACd,GACY,QAAO,EAAA,MAAA,CAAA,MAAA,GAAS,GAAG,MAAO,CAAA,MAAM,cAAc,aACnD,EAAA,CAAA;AAAA,oBACA,GAAA,CAAC,YAAS,IAAM,EAAA,IAAA,EAAM,cAAc,CAAK,CAAA,KAAA,CAAA,CAAE,MAAQ,EAAA,yBAAA,EAA0B,SAAU,EAAA,kBAAA,sBAAqB,UAAW,EAAA,EAAA,IAAA,EAAK,yBAAwB,KAAM,EAAA,iBAAA,EAAkB,QAAO,oEAAqE,EAAA,KAAA,EAAc,CAAI,EAAA,UAAA,EAAY,CAAC;AAAA,MAC7R;AAAA,KACI,KAAA;AACJ,MAAA,MAAM,EAAK,GAAA,MAAA,CAAO,QAAS,CAAA,IAAA,CAAK,MAAM,CAAA;AACtC,MAAO,uBAAA,GAAA,CAAC,MAAO,EAAA,EAAA,OAAA,EAAS,MAAM,MAAA,CAAO,KAAK,MAAM,CAAA,EAAG,iBAAkB,EAAA,UAAA,EAAW,kBAAoB,EAAA;AAAA,QAClG,OAAS,EAAA;AAAA,SACR,kBAAoB,EAAA,IAAA,CAAK,WAAa,EAAA,YAAA,EAAc,MAAM,OAAS,EAAA,MAAA,EAAQ,CAAkB,eAAA,EAAA,IAAA,CAAK,MAAM,CACrF,CAAA,EAAA,QAAA,kBAAA,IAAA,CAAC,QAAK,KAAO,EAAA,CAAC,OAAO,GAAK,EAAA;AAAA,QAC5C,aAAe,EAAA;AAAA,OAChB,CACuB,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,OAAO,EAAK,GAAA;AAAA,UACrD,iBAAiB,KAAM,CAAA,MAAA;AAAA,UACvB,aAAa,KAAM,CAAA;AAAA,SACjB,GAAA;AAAA,UACF,aAAa,KAAM,CAAA;AAAA,SACpB,CAAA,EAC0B,QAAK,EAAA,EAAA,mBAAA,GAAA,CAAC,sBAAuB,EAAA,EAAA,IAAA,EAAK,OAAQ,EAAA,IAAA,EAAM,EAAI,EAAA,KAAA,EAAO,KAAM,CAAA,QAAA,EAAU,IAAK,IACrF,EAAA,CAAA;AAAA,wBACC,GAAA,CAAA,MAAA,EAAA,EAAO,IAAM,EAAA,IAAA,CAAK,WAAa,EAAA,GAAA,EAAK,IAAK,CAAA,QAAA,EAAU,KAAc,EAAA,IAAA,EAAM,EAAI,EAAA,OAAA,EAAQ,UAAW,EAAA,CAAA;AAAA,4BAC9F,IAAK,EAAA,EAAA,aAAA,EAAe,GAAG,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,UACrE,OAAO,KAAM,CAAA;AAAA,SACd,CAC0B,EAAA,QAAA,EAAA,IAAA,CAAK,WACV,EAAA;AAAA,OAAA,EACJ,CACJ,EAAA,CAAA;AAAA,KACjB,EAAA;AAAA,GACC,EAAA,CAAA;AACR;AACA,MAAM,MAAA,GAAS,WAAW,MAAO,CAAA;AAAA,EAC/B,IAAM,EAAA;AAAA,IACJ,IAAM,EAAA;AAAA,GACR;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,eAAA;AAAA,IAChB,iBAAmB,EAAA,EAAA;AAAA,IACnB,SAAW,EAAA,EAAA;AAAA,IACX,mBAAmB,UAAW,CAAA;AAAA,GAChC;AAAA,EACA,UAAY,EAAA;AAAA,IACV,KAAO,EAAA;AAAA,GACT;AAAA,EACA,WAAa,EAAA;AAAA,IACX,UAAY,EAAA;AAAA,GACd;AAAA,EACA,KAAO,EAAA;AAAA,IACL,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,OAAS,EAAA;AAAA,IACP,UAAY,EAAA,QAAA;AAAA,IACZ,MAAQ,EAAA,EAAA;AAAA,IACR,YAAc,EAAA,CAAA;AAAA,IACd,iBAAmB,EAAA,EAAA;AAAA,IACnB,MAAQ,EAAA,EAAA;AAAA,IACR,YAAc,EAAA;AAAA,GAChB;AAAA,EACA,SAAW,EAAA;AAAA,IACT,IAAM,EAAA,CAAA;AAAA,IACN,UAAY,EAAA,EAAA;AAAA,IACZ,QAAU,EAAA,EAAA;AAAA,IACV,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,UAAY,EAAA,QAAA;AAAA,IACZ,gBAAkB,EAAA,EAAA;AAAA,IAClB,YAAc,EAAA,CAAA;AAAA,IACd,YAAc,EAAA,EAAA;AAAA,IACd,iBAAmB,EAAA,EAAA;AAAA,IACnB,MAAQ,EAAA;AAAA,GACV;AAAA,EACA,WAAa,EAAA;AAAA,IACX,IAAM,EAAA,CAAA;AAAA,IACN,UAAY,EAAA,CAAA;AAAA,IACZ,QAAU,EAAA,EAAA;AAAA,IACV,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,KAAO,EAAA;AAAA,IACL,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,gBAAkB,EAAA,EAAA;AAAA,IAClB,SAAW,EAAA,CAAA;AAAA,IACX,YAAc,EAAA,CAAA;AAAA,IACd,aAAe,EAAA;AAAA,GACjB;AAAA,EACA,GAAK,EAAA;AAAA,IACH,UAAY,EAAA,QAAA;AAAA,IACZ,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,KAAO,EAAA;AAAA,IACL,KAAO,EAAA,EAAA;AAAA,IACP,MAAQ,EAAA,EAAA;AAAA,IACR,YAAc,EAAA,EAAA;AAAA,IACd,WAAa,EAAA,GAAA;AAAA,IACb,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,QAAA;AAAA,IAChB,WAAa,EAAA;AAAA,GACf;AAAA,EACA,QAAU,EAAA;AAAA,IACR,IAAM,EAAA,CAAA;AAAA,IACN,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA;AAEhB,CAAC,CAAA"}
|
|
@@ -8,6 +8,7 @@ import {useEffect,useMemo}from'react';import {useSelector,useDispatch}from'react
|
|
|
8
8
|
function useChatViewer() {
|
|
9
9
|
var _a, _b;
|
|
10
10
|
const authUser = useSelector(userSelector);
|
|
11
|
+
const rehydrated = useSelector((state) => state._persist ? Boolean(state._persist.rehydrated) : true);
|
|
11
12
|
const dispatch = useDispatch();
|
|
12
13
|
const storedUserId = (authUser == null ? void 0 : authUser.id) || null;
|
|
13
14
|
const auth0Id = (authUser == null ? void 0 : authUser.authUserId) || null;
|
|
@@ -15,7 +16,7 @@ function useChatViewer() {
|
|
|
15
16
|
variables: {
|
|
16
17
|
auth0Id
|
|
17
18
|
},
|
|
18
|
-
skip: Boolean(storedUserId) || !auth0Id,
|
|
19
|
+
skip: !rehydrated || Boolean(storedUserId) || !auth0Id,
|
|
19
20
|
fetchPolicy: "network-only"
|
|
20
21
|
});
|
|
21
22
|
const recoveredUserId = ((_b = (_a = account.data) == null ? void 0 : _a.currentUser) == null ? void 0 : _b.id) || null;
|
|
@@ -37,7 +38,7 @@ function useChatViewer() {
|
|
|
37
38
|
phoneE164: membership.phoneE164,
|
|
38
39
|
registrationStatus
|
|
39
40
|
} : null, [userId, displayName, avatarUrl, membership.phoneE164, registrationStatus]);
|
|
40
|
-
const ready = Boolean(authUser) && !membership.loading && !account.loading;
|
|
41
|
+
const ready = Boolean(authUser) && rehydrated && !membership.loading && !account.loading;
|
|
41
42
|
const accountError = !auth0Id ? "You are signed out. Sign in again to use Chat." : account.error ? `Could not load your account: ${account.error.message}` : "Could not load your account.";
|
|
42
43
|
const error = membership.error || (!viewer && ready ? accountError : null);
|
|
43
44
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatViewer.js","sources":["../../../src/features/messaging/useChatViewer.ts"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { gql, useQuery } from '@apollo/client';\nimport type { IUserState } from '@adminide-stack/core';\nimport { Store, setUserAccountDetails, userSelector } from '@adminide-stack/user-auth0-client';\nimport { pickAuthPicture, pickPrimaryDisplayName } from '../../utils/authUserDisplay';\nimport type { ChatViewer, ChatRegistrationStatus } from './chatHost';\nimport { useYantraChatMembership } from './useYantraChatMembership';\nimport { YANTRA_CHAT_ORG_SLUG } from './yantraChatOrg';\n\nexport interface ChatViewerState {\n viewer: ChatViewer | null;\n error: string | null;\n ready: boolean;\n needsRegistration: boolean;\n membershipLoading: boolean;\n registerForChat: (phoneE164: string) => Promise<string>;\n refreshMembership: () => Promise<void>;\n}\n\n/**\n * The account id for the signed-in Auth0 user. The Login screen stores it in `user.id`, and the\n * store is persisted - so a session restored without it (an older build, or a lookup that failed\n * at login) keeps `id: ''` for good. Chat asks the server instead of failing.\n */\nconst VIEWER_ACCOUNT_QUERY = gql`\n query ChatViewerAccount($auth0Id: String!) {\n currentUser(auth0Id: $auth0Id) {\n id\n }\n }\n`;\n\nexport function useChatViewer(): ChatViewerState {\n const authUser = useSelector<Store.Auth, IUserState>(userSelector);\n const dispatch = useDispatch();\n const storedUserId = authUser?.id || null;\n const auth0Id = (authUser as { authUserId?: string | null } | undefined)?.authUserId || null;\n\n const account = useQuery<{ currentUser?: { id?: string | null } | null }>(VIEWER_ACCOUNT_QUERY, {\n variables: { auth0Id },\n skip: Boolean(storedUserId) || !auth0Id,\n fetchPolicy: 'network-only',\n });\n const recoveredUserId = account.data?.currentUser?.id || null;\n\n // Repair the store, so every screen reading `user.id` (not only Chat) gets the account.\n useEffect(() => {\n if (!storedUserId && recoveredUserId) dispatch(setUserAccountDetails({ id: recoveredUserId }));\n }, [storedUserId, recoveredUserId, dispatch]);\n\n const userId = storedUserId || recoveredUserId;\n const displayName = useMemo(() => pickPrimaryDisplayName(authUser), [authUser]);\n const avatarUrl = useMemo(() => pickAuthPicture(authUser), [authUser]);\n\n const membership = useYantraChatMembership(userId, displayName);\n\n const registrationStatus: ChatRegistrationStatus = membership.phoneE164\n ? 'registered'\n : membership.loading\n ? 'registering'\n : 'not-registered';\n\n const viewer = useMemo<ChatViewer | null>(\n () =>\n userId\n ? {\n userId,\n displayName,\n avatarUrl,\n orgName: YANTRA_CHAT_ORG_SLUG,\n phoneE164: membership.phoneE164,\n registrationStatus,\n }\n : null,\n [userId, displayName, avatarUrl, membership.phoneE164, registrationStatus],\n );\n\n const ready = Boolean(authUser) && !membership.loading && !account.loading;\n\n const accountError = !auth0Id\n ? 'You are signed out. Sign in again to use Chat.'\n : account.error\n ? `Could not load your account: ${account.error.message}`\n : 'Could not load your account.';\n const error = membership.error || (!viewer && ready ? accountError : null);\n\n return {\n viewer,\n error,\n ready,\n needsRegistration: membership.needsRegistration,\n membershipLoading: membership.loading,\n registerForChat: membership.register,\n refreshMembership: membership.refresh,\n };\n}\n"],"names":[],"mappings":"2aAwBA,MAAM,oBAAuB,GAAA,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAOtB,SAAS,aAAiC,GAAA;AA/BjD,EAAA,IAAA,EAAA,EAAA,EAAA;AAgCE,EAAM,MAAA,QAAA,GAAW,YAAoC,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"useChatViewer.js","sources":["../../../src/features/messaging/useChatViewer.ts"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { gql, useQuery } from '@apollo/client';\nimport type { IUserState } from '@adminide-stack/core';\nimport { Store, setUserAccountDetails, userSelector } from '@adminide-stack/user-auth0-client';\nimport { pickAuthPicture, pickPrimaryDisplayName } from '../../utils/authUserDisplay';\nimport type { ChatViewer, ChatRegistrationStatus } from './chatHost';\nimport { useYantraChatMembership } from './useYantraChatMembership';\nimport { YANTRA_CHAT_ORG_SLUG } from './yantraChatOrg';\n\nexport interface ChatViewerState {\n viewer: ChatViewer | null;\n error: string | null;\n ready: boolean;\n needsRegistration: boolean;\n membershipLoading: boolean;\n registerForChat: (phoneE164: string) => Promise<string>;\n refreshMembership: () => Promise<void>;\n}\n\n/**\n * The account id for the signed-in Auth0 user. The Login screen stores it in `user.id`, and the\n * store is persisted - so a session restored without it (an older build, or a lookup that failed\n * at login) keeps `id: ''` for good. Chat asks the server instead of failing.\n */\nconst VIEWER_ACCOUNT_QUERY = gql`\n query ChatViewerAccount($auth0Id: String!) {\n currentUser(auth0Id: $auth0Id) {\n id\n }\n }\n`;\n\nexport function useChatViewer(): ChatViewerState {\n const authUser = useSelector<Store.Auth, IUserState>(userSelector);\n // The store is restored from disk after launch (redux-persist, no gate in front of the UI):\n // until then `user` is the empty initial state, which must not read as \"no account\".\n const rehydrated = useSelector((state: { _persist?: { rehydrated?: boolean } }) =>\n state._persist ? Boolean(state._persist.rehydrated) : true,\n );\n const dispatch = useDispatch();\n const storedUserId = authUser?.id || null;\n const auth0Id = (authUser as { authUserId?: string | null } | undefined)?.authUserId || null;\n\n const account = useQuery<{ currentUser?: { id?: string | null } | null }>(VIEWER_ACCOUNT_QUERY, {\n variables: { auth0Id },\n skip: !rehydrated || Boolean(storedUserId) || !auth0Id,\n fetchPolicy: 'network-only',\n });\n const recoveredUserId = account.data?.currentUser?.id || null;\n\n // Repair the store, so every screen reading `user.id` (not only Chat) gets the account.\n useEffect(() => {\n if (!storedUserId && recoveredUserId) dispatch(setUserAccountDetails({ id: recoveredUserId }));\n }, [storedUserId, recoveredUserId, dispatch]);\n\n const userId = storedUserId || recoveredUserId;\n const displayName = useMemo(() => pickPrimaryDisplayName(authUser), [authUser]);\n const avatarUrl = useMemo(() => pickAuthPicture(authUser), [authUser]);\n\n const membership = useYantraChatMembership(userId, displayName);\n\n const registrationStatus: ChatRegistrationStatus = membership.phoneE164\n ? 'registered'\n : membership.loading\n ? 'registering'\n : 'not-registered';\n\n const viewer = useMemo<ChatViewer | null>(\n () =>\n userId\n ? {\n userId,\n displayName,\n avatarUrl,\n orgName: YANTRA_CHAT_ORG_SLUG,\n phoneE164: membership.phoneE164,\n registrationStatus,\n }\n : null,\n [userId, displayName, avatarUrl, membership.phoneE164, registrationStatus],\n );\n\n const ready = Boolean(authUser) && rehydrated && !membership.loading && !account.loading;\n\n const accountError = !auth0Id\n ? 'You are signed out. Sign in again to use Chat.'\n : account.error\n ? `Could not load your account: ${account.error.message}`\n : 'Could not load your account.';\n const error = membership.error || (!viewer && ready ? accountError : null);\n\n return {\n viewer,\n error,\n ready,\n needsRegistration: membership.needsRegistration,\n membershipLoading: membership.loading,\n registerForChat: membership.register,\n refreshMembership: membership.refresh,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
import {jsxs,jsx,Fragment}from'react/jsx-runtime';import {useMemo,useState,useCallback,useRef,useEffect}from'react';import {StyleSheet,Keyboard,BackHandler,View,Text,Share,Platform,ActionSheetIOS,Alert,Linking}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {GestureHandlerRootView}from'react-native-gesture-handler';import {useSafeInsets}from'../canvas/withRemoteSafeArea.js';import {useAppTheme}from'../../theme/AppThemeProvider.js';import {Tap,DIM}from'../inbox/components/Tap.js';import {isBareSeed,studioTurnText,brandBriefBlock,siteScoreTurn}from'./studioCatalog.js';import {useBrandKit}from'./brandKitStorage.js';import {wakePreviewPrompt}from'./webbuilderPrompts.js';import {webbuilderTheme}from'./webbuilderTheme.js';import {BrandKitSheet}from'./components/BrandKitSheet.js';import {CodeView}from'./components/CodeView.js';import {ProjectChat}from'./components/ProjectChat.js';import {PreviewScreen}from'./components/PreviewScreen.js';import {PublishSheet}from'./components/PublishSheet.js';import {BOTTOM_TABS_SPACE,BottomTabs}from'./components/BottomTabs.js';import {SiteScoreSheet}from'./components/SiteScoreSheet.js';import {ProjectsScreen}from'./components/ProjectsScreen.js';import {TemplatesSheet}from'./components/TemplatesSheet.js';import {StudioHome}from'./components/StudioHome.js';import {VersionsSheet}from'./components/VersionsSheet.js';import {IconButton,Toast}from'./components/ui.js';var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
+
var __spreadValues = (a, b) => {
|
|
7
|
+
for (var prop in b || (b = {}))
|
|
8
|
+
if (__hasOwnProp.call(b, prop))
|
|
9
|
+
__defNormalProp(a, prop, b[prop]);
|
|
10
|
+
if (__getOwnPropSymbols)
|
|
11
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
12
|
+
if (__propIsEnum.call(b, prop))
|
|
13
|
+
__defNormalProp(a, prop, b[prop]);
|
|
14
|
+
}
|
|
15
|
+
return a;
|
|
16
|
+
};
|
|
17
|
+
const TOAST_MS = 2400;
|
|
18
|
+
const PUBLISH_WATCH_MS = 10 * 60 * 1e3;
|
|
19
|
+
function WebBuilderExperience({
|
|
20
|
+
isDark: hostIsDark,
|
|
21
|
+
onExit,
|
|
22
|
+
projects,
|
|
23
|
+
projectsLoading = false,
|
|
24
|
+
projectsError = null,
|
|
25
|
+
onRefreshProjects,
|
|
26
|
+
projectsHasMore = false,
|
|
27
|
+
onLoadMoreProjects,
|
|
28
|
+
templates,
|
|
29
|
+
templatesLoading = false,
|
|
30
|
+
templatesError = null,
|
|
31
|
+
onReloadTemplates,
|
|
32
|
+
startBlocked = null,
|
|
33
|
+
startNotice = null,
|
|
34
|
+
activeChannelId,
|
|
35
|
+
onOpenProject,
|
|
36
|
+
onCloseProject,
|
|
37
|
+
onStartProject,
|
|
38
|
+
builds,
|
|
39
|
+
buildsLoading = false,
|
|
40
|
+
building = null,
|
|
41
|
+
publishing: publishingOnChat = false,
|
|
42
|
+
hostChat,
|
|
43
|
+
onPublish,
|
|
44
|
+
onResumePreview,
|
|
45
|
+
initialAgentSeed = null
|
|
46
|
+
}) {
|
|
47
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
48
|
+
const appTheme = useAppTheme();
|
|
49
|
+
const isDark = hostIsDark != null ? hostIsDark : appTheme.isDark;
|
|
50
|
+
const theme = useMemo(() => webbuilderTheme(isDark), [isDark]);
|
|
51
|
+
const insets = useSafeInsets();
|
|
52
|
+
const project = useMemo(() => {
|
|
53
|
+
var _a2;
|
|
54
|
+
return (_a2 = projects.find((p) => p.channelId === activeChannelId)) != null ? _a2 : null;
|
|
55
|
+
}, [projects, activeChannelId]);
|
|
56
|
+
const [draft, setDraft] = useState("");
|
|
57
|
+
const [template, setTemplate] = useState(null);
|
|
58
|
+
const [templatesOpen, setTemplatesOpen] = useState(false);
|
|
59
|
+
const [scoreOpen, setScoreOpen] = useState(false);
|
|
60
|
+
const [homeTab, setHomeTab] = useState("create");
|
|
61
|
+
const {
|
|
62
|
+
brand,
|
|
63
|
+
saveBrand
|
|
64
|
+
} = useBrandKit();
|
|
65
|
+
const [brandOpen, setBrandOpen] = useState(false);
|
|
66
|
+
const pickTemplate = useCallback((picked) => {
|
|
67
|
+
setTemplate(picked);
|
|
68
|
+
setTemplatesOpen(false);
|
|
69
|
+
setHomeTab("create");
|
|
70
|
+
setDraft((prev) => isBareSeed(prev) && picked.chatPrompt ? picked.chatPrompt : prev);
|
|
71
|
+
}, []);
|
|
72
|
+
const startSite = useCallback((start, files) => {
|
|
73
|
+
const brief = start.brief.trim() || (start.template ? start.template.chatPrompt || start.template.title : "");
|
|
74
|
+
if (!brief && !(files == null ? void 0 : files.length)) return;
|
|
75
|
+
onStartProject(__spreadValues(__spreadValues({
|
|
76
|
+
text: studioTurnText({
|
|
77
|
+
brief,
|
|
78
|
+
brandBlock: brandBriefBlock(brand),
|
|
79
|
+
referenceUrl: start.referenceUrl
|
|
80
|
+
}),
|
|
81
|
+
template: start.template
|
|
82
|
+
}, start.referenceUrl ? {
|
|
83
|
+
referenceUrl: start.referenceUrl
|
|
84
|
+
} : {}), (files == null ? void 0 : files.length) ? {
|
|
85
|
+
attachments: files
|
|
86
|
+
} : {}));
|
|
87
|
+
setDraft("");
|
|
88
|
+
setTemplate(null);
|
|
89
|
+
}, [onStartProject, brand]);
|
|
90
|
+
const handedOff = useRef(false);
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (handedOff.current || !initialAgentSeed || startBlocked) return;
|
|
93
|
+
handedOff.current = true;
|
|
94
|
+
startSite({
|
|
95
|
+
brief: initialAgentSeed.text,
|
|
96
|
+
template: null
|
|
97
|
+
}, initialAgentSeed.files);
|
|
98
|
+
}, [initialAgentSeed, startBlocked, startSite]);
|
|
99
|
+
const [selectedKey, setSelectedKey] = useState(null);
|
|
100
|
+
useEffect(() => setSelectedKey(null), [activeChannelId]);
|
|
101
|
+
const latest = (_a = builds[0]) != null ? _a : null;
|
|
102
|
+
const build = useMemo(() => {
|
|
103
|
+
var _a2;
|
|
104
|
+
return selectedKey ? (_a2 = builds.find((b) => b.key === selectedKey)) != null ? _a2 : latest : latest;
|
|
105
|
+
}, [builds, selectedKey, latest]);
|
|
106
|
+
const siteTitle = (project == null ? void 0 : project.title) || (build == null ? void 0 : build.title) || null;
|
|
107
|
+
const [previewNonce, setPreviewNonce] = useState(0);
|
|
108
|
+
const seenBuildAt = useRef({
|
|
109
|
+
key: null,
|
|
110
|
+
at: 0
|
|
111
|
+
});
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
var _a2, _b2;
|
|
114
|
+
const key = (_a2 = build == null ? void 0 : build.key) != null ? _a2 : null;
|
|
115
|
+
const at = (_b2 = build == null ? void 0 : build.updatedAt) != null ? _b2 : 0;
|
|
116
|
+
const seen = seenBuildAt.current;
|
|
117
|
+
if (key && key === seen.key && at > seen.at) setPreviewNonce((n) => n + 1);
|
|
118
|
+
seenBuildAt.current = {
|
|
119
|
+
key,
|
|
120
|
+
at
|
|
121
|
+
};
|
|
122
|
+
}, [build == null ? void 0 : build.key, build == null ? void 0 : build.updatedAt]);
|
|
123
|
+
const [toast, setToast] = useState(null);
|
|
124
|
+
const toastTimer = useRef(null);
|
|
125
|
+
const showToast = useCallback((message) => {
|
|
126
|
+
if (toastTimer.current) clearTimeout(toastTimer.current);
|
|
127
|
+
setToast(message);
|
|
128
|
+
toastTimer.current = setTimeout(() => setToast(null), TOAST_MS);
|
|
129
|
+
}, []);
|
|
130
|
+
useEffect(() => () => toastTimer.current ? clearTimeout(toastTimer.current) : void 0, []);
|
|
131
|
+
const [mode, setMode] = useState("chat");
|
|
132
|
+
useEffect(() => setMode("chat"), [activeChannelId]);
|
|
133
|
+
const sendToAgent = useCallback((text, files) => {
|
|
134
|
+
const words = text.trim();
|
|
135
|
+
if (!words || !hostChat) return;
|
|
136
|
+
const turn = build || /^build\b/i.test(words) ? words : `Build me: ${words}`;
|
|
137
|
+
hostChat.send(turn, files, build);
|
|
138
|
+
setMode("chat");
|
|
139
|
+
}, [hostChat, build]);
|
|
140
|
+
const openChat = useCallback(() => {
|
|
141
|
+
Keyboard.dismiss();
|
|
142
|
+
setMode("chat");
|
|
143
|
+
}, []);
|
|
144
|
+
const [waking, setWaking] = useState(false);
|
|
145
|
+
const wokenFor = useRef(null);
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
wokenFor.current = null;
|
|
148
|
+
}, [build == null ? void 0 : build.key]);
|
|
149
|
+
const wakePreview = useCallback(() => {
|
|
150
|
+
if (!build || waking || wokenFor.current === build.key) return;
|
|
151
|
+
wokenFor.current = build.key;
|
|
152
|
+
setWaking(true);
|
|
153
|
+
const resume = onResumePreview ? onResumePreview(build) : Promise.resolve("failed");
|
|
154
|
+
resume.catch(() => "failed").then((outcome) => {
|
|
155
|
+
if (outcome === "ok") setPreviewNonce((n) => n + 1);
|
|
156
|
+
else hostChat == null ? void 0 : hostChat.send(wakePreviewPrompt(build), void 0, build);
|
|
157
|
+
}).finally(() => setWaking(false));
|
|
158
|
+
}, [build, waking, onResumePreview, hostChat]);
|
|
159
|
+
const [publishOpen, setPublishOpen] = useState(false);
|
|
160
|
+
const [versionsOpen, setVersionsOpen] = useState(false);
|
|
161
|
+
const [publishStarted, setPublishStarted] = useState(null);
|
|
162
|
+
useEffect(() => setPublishStarted(null), [activeChannelId]);
|
|
163
|
+
useEffect(() => {
|
|
164
|
+
if (!publishStarted) return;
|
|
165
|
+
const target = builds.find((b) => b.key === publishStarted.key);
|
|
166
|
+
if ((target == null ? void 0 : target.liveUrl) && target.liveUrl !== publishStarted.live) {
|
|
167
|
+
setPublishStarted(null);
|
|
168
|
+
showToast("Your site is live");
|
|
169
|
+
}
|
|
170
|
+
}, [builds, publishStarted, showToast]);
|
|
171
|
+
const publishing = publishingOnChat || Boolean(publishStarted && Date.now() - publishStarted.at < PUBLISH_WATCH_MS);
|
|
172
|
+
const publish = useCallback(async (target, projectName) => {
|
|
173
|
+
if (!onPublish) return {
|
|
174
|
+
ok: false,
|
|
175
|
+
message: "Publishing is not available here."
|
|
176
|
+
};
|
|
177
|
+
const result = await onPublish(target, projectName);
|
|
178
|
+
if (result.ok) {
|
|
179
|
+
setPublishStarted({
|
|
180
|
+
key: target.key,
|
|
181
|
+
live: target.liveUrl,
|
|
182
|
+
at: Date.now()
|
|
183
|
+
});
|
|
184
|
+
showToast("Publishing started");
|
|
185
|
+
}
|
|
186
|
+
return result;
|
|
187
|
+
}, [onPublish, showToast]);
|
|
188
|
+
const back = useCallback(() => {
|
|
189
|
+
if (activeChannelId && mode !== "chat") {
|
|
190
|
+
setMode("chat");
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (activeChannelId) {
|
|
194
|
+
onCloseProject();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (homeTab === "projects") {
|
|
198
|
+
setHomeTab("create");
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
onExit();
|
|
202
|
+
}, [mode, activeChannelId, homeTab, onCloseProject, onExit]);
|
|
203
|
+
useEffect(() => {
|
|
204
|
+
const sub = BackHandler.addEventListener("hardwareBackPress", () => {
|
|
205
|
+
back();
|
|
206
|
+
return true;
|
|
207
|
+
});
|
|
208
|
+
return () => sub.remove();
|
|
209
|
+
}, [back]);
|
|
210
|
+
const live = (_c = (_b = build == null ? void 0 : build.liveUrl) != null ? _b : project == null ? void 0 : project.liveUrl) != null ? _c : null;
|
|
211
|
+
let statusText = "New";
|
|
212
|
+
let statusTone = theme.muted;
|
|
213
|
+
if (building || (hostChat == null ? void 0 : hostChat.busy)) {
|
|
214
|
+
statusText = "Working\u2026";
|
|
215
|
+
statusTone = theme.accent;
|
|
216
|
+
} else if (live) {
|
|
217
|
+
statusText = "Live";
|
|
218
|
+
statusTone = theme.good;
|
|
219
|
+
} else if (build) {
|
|
220
|
+
statusText = "Not published";
|
|
221
|
+
}
|
|
222
|
+
const floating = {
|
|
223
|
+
backgroundColor: theme.card,
|
|
224
|
+
borderColor: theme.border,
|
|
225
|
+
shadowColor: theme.isDark ? "#000" : "#1c1917"
|
|
226
|
+
};
|
|
227
|
+
let publishLabel = "Publish";
|
|
228
|
+
if (publishing) publishLabel = "Publishing\u2026";
|
|
229
|
+
const shareUrl = live || (build == null ? void 0 : build.previewUrl) || null;
|
|
230
|
+
const shareSite = () => {
|
|
231
|
+
if (shareUrl) Share.share({
|
|
232
|
+
message: shareUrl,
|
|
233
|
+
url: shareUrl
|
|
234
|
+
}).catch(() => void 0);
|
|
235
|
+
};
|
|
236
|
+
const openMore = () => {
|
|
237
|
+
const actions = [];
|
|
238
|
+
if (mode !== "chat") actions.push({
|
|
239
|
+
label: "Back to the chat",
|
|
240
|
+
run: () => setMode("chat")
|
|
241
|
+
});
|
|
242
|
+
if ((build == null ? void 0 : build.previewUrl) && mode !== "preview") {
|
|
243
|
+
actions.push({
|
|
244
|
+
label: "Open preview",
|
|
245
|
+
run: () => setMode("preview")
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
if ((build == null ? void 0 : build.files) && mode !== "code") actions.push({
|
|
249
|
+
label: "View code",
|
|
250
|
+
run: () => setMode("code")
|
|
251
|
+
});
|
|
252
|
+
if (builds.length > 1) actions.push({
|
|
253
|
+
label: "Versions",
|
|
254
|
+
run: () => setVersionsOpen(true)
|
|
255
|
+
});
|
|
256
|
+
if (build == null ? void 0 : build.sandboxId) {
|
|
257
|
+
actions.push({
|
|
258
|
+
label: live ? "Publish an update" : "Publish",
|
|
259
|
+
run: () => setPublishOpen(true)
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
if (build == null ? void 0 : build.previewUrl) {
|
|
263
|
+
const url = live || build.previewUrl;
|
|
264
|
+
actions.push({
|
|
265
|
+
label: "Open in browser",
|
|
266
|
+
run: () => Linking.openURL(url).catch(() => void 0)
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
if (!actions.length) return;
|
|
270
|
+
if (Platform.OS === "ios") {
|
|
271
|
+
ActionSheetIOS.showActionSheetWithOptions({
|
|
272
|
+
options: [...actions.map((a) => a.label), "Cancel"],
|
|
273
|
+
cancelButtonIndex: actions.length
|
|
274
|
+
}, (index) => {
|
|
275
|
+
var _a2;
|
|
276
|
+
return (_a2 = actions[index]) == null ? void 0 : _a2.run();
|
|
277
|
+
});
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
Alert.alert(siteTitle || "Project", void 0, [...actions.map((a) => ({
|
|
281
|
+
text: a.label,
|
|
282
|
+
onPress: a.run
|
|
283
|
+
})), {
|
|
284
|
+
text: "Cancel",
|
|
285
|
+
style: "cancel"
|
|
286
|
+
}]);
|
|
287
|
+
};
|
|
288
|
+
return /* @__PURE__ */ jsxs(GestureHandlerRootView, { style: [styles.fill, {
|
|
289
|
+
backgroundColor: theme.screen
|
|
290
|
+
}], children: [
|
|
291
|
+
activeChannelId ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
292
|
+
/* @__PURE__ */ jsxs(View, { style: [styles.projectHead, {
|
|
293
|
+
paddingTop: insets.top + 6
|
|
294
|
+
}], children: [
|
|
295
|
+
/* @__PURE__ */ jsx(Tap, { onPress: back, accessibilityRole: "button", accessibilityLabel: mode === "chat" ? "Back to Web Builder" : "Back to the chat", style: [styles.roundBtn, floating], pressedStyle: DIM, testID: "webbuilder-back", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chevron-left", size: 28, color: theme.ink }) }),
|
|
296
|
+
mode === "chat" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
297
|
+
/* @__PURE__ */ jsxs(View, { style: [styles.titlePill, floating], children: [
|
|
298
|
+
/* @__PURE__ */ jsx(Text, { style: [styles.pillTitle, {
|
|
299
|
+
color: theme.ink
|
|
300
|
+
}], numberOfLines: 1, children: siteTitle || "New app" }),
|
|
301
|
+
/* @__PURE__ */ jsx(Text, { style: [styles.pillStatus, {
|
|
302
|
+
color: statusTone
|
|
303
|
+
}], numberOfLines: 1, children: statusText })
|
|
304
|
+
] }),
|
|
305
|
+
/* @__PURE__ */ jsx(View, { style: styles.headSpacer }),
|
|
306
|
+
/* @__PURE__ */ jsxs(View, { style: [styles.actionPill, floating], children: [
|
|
307
|
+
/* @__PURE__ */ jsx(Tap, { onPress: shareSite, disabled: !shareUrl, accessibilityRole: "button", accessibilityLabel: "Share", style: [styles.pillBtn, !shareUrl && styles.disabled], pressedStyle: DIM, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "share-outline", size: 24, color: theme.ink }) }),
|
|
308
|
+
/* @__PURE__ */ jsx(Tap, { onPress: openMore, accessibilityRole: "button", accessibilityLabel: "More", style: styles.pillBtn, pressedStyle: DIM, testID: "webbuilder-more", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "dots-horizontal", size: 24, color: theme.ink }) })
|
|
309
|
+
] })
|
|
310
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
311
|
+
/* @__PURE__ */ jsx(Text, { style: [styles.centerTitle, {
|
|
312
|
+
color: theme.ink
|
|
313
|
+
}], numberOfLines: 1, children: mode === "code" ? "Code" : siteTitle || "Preview" }),
|
|
314
|
+
/* @__PURE__ */ jsxs(View, { style: [styles.actionPill, floating], children: [
|
|
315
|
+
/* @__PURE__ */ jsx(Tap, { onPress: shareSite, disabled: !shareUrl, accessibilityRole: "button", accessibilityLabel: "Share", style: [styles.pillBtn, !shareUrl && styles.disabled], pressedStyle: DIM, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "share-outline", size: 24, color: theme.ink }) }),
|
|
316
|
+
/* @__PURE__ */ jsx(Tap, { onPress: openMore, accessibilityRole: "button", accessibilityLabel: "More", style: styles.pillBtn, pressedStyle: DIM, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "dots-horizontal", size: 24, color: theme.ink }) })
|
|
317
|
+
] })
|
|
318
|
+
] })
|
|
319
|
+
] }),
|
|
320
|
+
mode === "chat" ? /* @__PURE__ */ jsx(ProjectChat, { messages: (_d = hostChat == null ? void 0 : hostChat.messages) != null ? _d : [], streaming: (_e = hostChat == null ? void 0 : hostChat.streaming) != null ? _e : null, busy: Boolean(hostChat == null ? void 0 : hostChat.busy), error: (_f = hostChat == null ? void 0 : hostChat.error) != null ? _f : null, connected: Boolean(hostChat == null ? void 0 : hostChat.connected), building, build, siteTitle: siteTitle || "Your site", onSend: (text) => sendToAgent(text), onOpenPreview: () => setMode("preview"), onPublish: () => setPublishOpen(true), theme, bottomInset: insets.bottom }) : null,
|
|
321
|
+
mode === "preview" ? /* @__PURE__ */ jsx(PreviewScreen, { build, building, loading: buildsLoading, previewNonce, onReload: () => setPreviewNonce((n) => n + 1), onHome: () => setPreviewNonce((n) => n + 1), onWake: wakePreview, waking: waking || Boolean(hostChat == null ? void 0 : hostChat.busy), onPublish: () => setPublishOpen(true), publishLabel, error: (_g = hostChat == null ? void 0 : hostChat.error) != null ? _g : null, theme, bottomInset: insets.bottom }) : null,
|
|
322
|
+
mode === "code" ? /* @__PURE__ */ jsx(View, { style: [styles.fill, {
|
|
323
|
+
backgroundColor: theme.card,
|
|
324
|
+
paddingBottom: insets.bottom
|
|
325
|
+
}], children: /* @__PURE__ */ jsx(CodeView, { files: (_h = build == null ? void 0 : build.files) != null ? _h : null, theme, onAsk: openChat }) }) : null
|
|
326
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
327
|
+
/* @__PURE__ */ jsx(View, { style: [styles.header, styles.headerBare, {
|
|
328
|
+
paddingTop: insets.top + 4,
|
|
329
|
+
borderBottomColor: "transparent"
|
|
330
|
+
}], children: /* @__PURE__ */ jsx(IconButton, { icon: "arrow-left", label: "Leave Web Builder", onPress: back, theme, testID: "webbuilder-back" }) }),
|
|
331
|
+
/* @__PURE__ */ jsx(View, { style: styles.fill, children: homeTab === "create" ? /* @__PURE__ */ jsx(StudioHome, { draft, onDraft: setDraft, template, onClearTemplate: () => setTemplate(null), onBrowseTemplates: () => setTemplatesOpen(true), brand, onBrand: () => setBrandOpen(true), onSiteScore: () => setScoreOpen(true), onStart: startSite, connecting: startBlocked, startNotice, theme, bottomInset: BOTTOM_TABS_SPACE + insets.bottom }) : /* @__PURE__ */ jsx(ProjectsScreen, { projects, loading: projectsLoading, error: projectsError, hasMore: projectsHasMore, onRefresh: onRefreshProjects, onLoadMore: onLoadMoreProjects, onOpen: (p) => onOpenProject(p.channelId), onNewProject: () => setHomeTab("create"), topInset: 4, bottomInset: BOTTOM_TABS_SPACE + insets.bottom, theme }) }),
|
|
332
|
+
/* @__PURE__ */ jsx(BottomTabs, { tab: homeTab, onTab: setHomeTab, theme, bottomInset: insets.bottom })
|
|
333
|
+
] }),
|
|
334
|
+
/* @__PURE__ */ jsx(TemplatesSheet, { visible: templatesOpen, onClose: () => setTemplatesOpen(false), templates, loading: templatesLoading, error: templatesError, onReload: onReloadTemplates, selectedId: (_i = template == null ? void 0 : template.id) != null ? _i : null, onPick: pickTemplate, theme }),
|
|
335
|
+
/* @__PURE__ */ jsx(SiteScoreSheet, { visible: scoreOpen, onClose: () => setScoreOpen(false), blocked: startBlocked, onCheck: (url) => {
|
|
336
|
+
setScoreOpen(false);
|
|
337
|
+
onStartProject({
|
|
338
|
+
text: siteScoreTurn(url),
|
|
339
|
+
template: null,
|
|
340
|
+
agent: true
|
|
341
|
+
});
|
|
342
|
+
}, theme }),
|
|
343
|
+
/* @__PURE__ */ jsx(BrandKitSheet, { visible: brandOpen, brand, onSave: saveBrand, onClose: () => setBrandOpen(false), theme }),
|
|
344
|
+
/* @__PURE__ */ jsx(PublishSheet, { visible: publishOpen, build, publishing, onPublish: onPublish ? publish : void 0, onClose: () => setPublishOpen(false), theme }),
|
|
345
|
+
/* @__PURE__ */ jsx(VersionsSheet, { visible: versionsOpen, builds, selectedKey, onSelect: (picked) => {
|
|
346
|
+
setSelectedKey(picked.key === (latest == null ? void 0 : latest.key) ? null : picked.key);
|
|
347
|
+
setVersionsOpen(false);
|
|
348
|
+
}, onClose: () => setVersionsOpen(false), theme }),
|
|
349
|
+
/* @__PURE__ */ jsx(Toast, { message: toast, theme, bottom: insets.bottom + 80 })
|
|
350
|
+
] });
|
|
351
|
+
}
|
|
352
|
+
const styles = StyleSheet.create({
|
|
353
|
+
fill: {
|
|
354
|
+
flex: 1
|
|
355
|
+
},
|
|
356
|
+
header: {
|
|
357
|
+
flexDirection: "row",
|
|
358
|
+
alignItems: "center",
|
|
359
|
+
gap: 6,
|
|
360
|
+
paddingHorizontal: 8,
|
|
361
|
+
paddingBottom: 8,
|
|
362
|
+
borderBottomWidth: StyleSheet.hairlineWidth
|
|
363
|
+
},
|
|
364
|
+
headerBare: {
|
|
365
|
+
paddingBottom: 0
|
|
366
|
+
},
|
|
367
|
+
projectHead: {
|
|
368
|
+
flexDirection: "row",
|
|
369
|
+
alignItems: "center",
|
|
370
|
+
gap: 10,
|
|
371
|
+
paddingHorizontal: 14,
|
|
372
|
+
paddingBottom: 10
|
|
373
|
+
},
|
|
374
|
+
roundBtn: {
|
|
375
|
+
width: 52,
|
|
376
|
+
height: 52,
|
|
377
|
+
borderRadius: 26,
|
|
378
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
379
|
+
alignItems: "center",
|
|
380
|
+
justifyContent: "center",
|
|
381
|
+
shadowOpacity: 0.08,
|
|
382
|
+
shadowRadius: 12,
|
|
383
|
+
shadowOffset: {
|
|
384
|
+
width: 0,
|
|
385
|
+
height: 4
|
|
386
|
+
},
|
|
387
|
+
elevation: 3
|
|
388
|
+
},
|
|
389
|
+
titlePill: {
|
|
390
|
+
flexShrink: 1,
|
|
391
|
+
maxWidth: "58%",
|
|
392
|
+
height: 52,
|
|
393
|
+
paddingHorizontal: 18,
|
|
394
|
+
borderRadius: 26,
|
|
395
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
396
|
+
justifyContent: "center",
|
|
397
|
+
shadowOpacity: 0.08,
|
|
398
|
+
shadowRadius: 12,
|
|
399
|
+
shadowOffset: {
|
|
400
|
+
width: 0,
|
|
401
|
+
height: 4
|
|
402
|
+
},
|
|
403
|
+
elevation: 3
|
|
404
|
+
},
|
|
405
|
+
pillTitle: {
|
|
406
|
+
fontSize: 16,
|
|
407
|
+
fontWeight: "700",
|
|
408
|
+
letterSpacing: -0.2
|
|
409
|
+
},
|
|
410
|
+
pillStatus: {
|
|
411
|
+
fontSize: 12,
|
|
412
|
+
fontWeight: "600",
|
|
413
|
+
marginTop: 1
|
|
414
|
+
},
|
|
415
|
+
headSpacer: {
|
|
416
|
+
flex: 1
|
|
417
|
+
},
|
|
418
|
+
actionPill: {
|
|
419
|
+
flexDirection: "row",
|
|
420
|
+
alignItems: "center",
|
|
421
|
+
height: 52,
|
|
422
|
+
paddingHorizontal: 8,
|
|
423
|
+
borderRadius: 26,
|
|
424
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
425
|
+
shadowOpacity: 0.08,
|
|
426
|
+
shadowRadius: 12,
|
|
427
|
+
shadowOffset: {
|
|
428
|
+
width: 0,
|
|
429
|
+
height: 4
|
|
430
|
+
},
|
|
431
|
+
elevation: 3
|
|
432
|
+
},
|
|
433
|
+
pillBtn: {
|
|
434
|
+
width: 42,
|
|
435
|
+
height: 42,
|
|
436
|
+
borderRadius: 21,
|
|
437
|
+
alignItems: "center",
|
|
438
|
+
justifyContent: "center"
|
|
439
|
+
},
|
|
440
|
+
centerTitle: {
|
|
441
|
+
flex: 1,
|
|
442
|
+
textAlign: "center",
|
|
443
|
+
fontSize: 18,
|
|
444
|
+
fontWeight: "700"
|
|
445
|
+
},
|
|
446
|
+
headerText: {
|
|
447
|
+
flex: 1,
|
|
448
|
+
flexDirection: "row",
|
|
449
|
+
alignItems: "center",
|
|
450
|
+
gap: 8,
|
|
451
|
+
minWidth: 0
|
|
452
|
+
},
|
|
453
|
+
headerTitle: {
|
|
454
|
+
flexShrink: 1,
|
|
455
|
+
fontSize: 17,
|
|
456
|
+
fontWeight: "700",
|
|
457
|
+
letterSpacing: -0.2
|
|
458
|
+
},
|
|
459
|
+
publish: {
|
|
460
|
+
minHeight: 34,
|
|
461
|
+
paddingHorizontal: 16,
|
|
462
|
+
borderRadius: 17,
|
|
463
|
+
alignItems: "center",
|
|
464
|
+
justifyContent: "center",
|
|
465
|
+
marginRight: 4
|
|
466
|
+
},
|
|
467
|
+
publishLabel: {
|
|
468
|
+
fontSize: 14,
|
|
469
|
+
fontWeight: "700"
|
|
470
|
+
},
|
|
471
|
+
disabled: {
|
|
472
|
+
opacity: 0.35
|
|
473
|
+
}
|
|
474
|
+
});export{WebBuilderExperience,WebBuilderExperience as default};//# sourceMappingURL=WebBuilderExperience.js.map
|