@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.
Files changed (83) hide show
  1. package/lib/compute.js +57 -1
  2. package/lib/compute.js.map +1 -1
  3. package/lib/config/env-config.js +8 -0
  4. package/lib/config/env-config.js.map +1 -1
  5. package/lib/features/apps/AppsCatalog.js +10 -0
  6. package/lib/features/apps/AppsCatalog.js.map +1 -1
  7. package/lib/features/apps/appArt.js +2 -1
  8. package/lib/features/apps/appArt.js.map +1 -1
  9. package/lib/features/apps/mobileAppCatalog.js +11 -0
  10. package/lib/features/apps/mobileAppCatalog.js.map +1 -1
  11. package/lib/features/apps/nativeAppHandoff.js +2 -1
  12. package/lib/features/apps/nativeAppHandoff.js.map +1 -1
  13. package/lib/features/health/healthSyncStore.js +7 -1
  14. package/lib/features/health/healthSyncStore.js.map +1 -1
  15. package/lib/features/messaging/NewGroupScreen.js.map +1 -1
  16. package/lib/features/messaging/useChatViewer.js +3 -2
  17. package/lib/features/messaging/useChatViewer.js.map +1 -1
  18. package/lib/features/webbuilder/WebBuilderExperience.js +474 -0
  19. package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -0
  20. package/lib/features/webbuilder/brandKitStorage.js +69 -0
  21. package/lib/features/webbuilder/brandKitStorage.js.map +1 -0
  22. package/lib/features/webbuilder/buildFragments.js +360 -0
  23. package/lib/features/webbuilder/buildFragments.js.map +1 -0
  24. package/lib/features/webbuilder/components/BottomTabs.js +65 -0
  25. package/lib/features/webbuilder/components/BottomTabs.js.map +1 -0
  26. package/lib/features/webbuilder/components/BrandKitSheet.js +197 -0
  27. package/lib/features/webbuilder/components/BrandKitSheet.js.map +1 -0
  28. package/lib/features/webbuilder/components/CodeView.js +99 -0
  29. package/lib/features/webbuilder/components/CodeView.js.map +1 -0
  30. package/lib/features/webbuilder/components/Composer.js +217 -0
  31. package/lib/features/webbuilder/components/Composer.js.map +1 -0
  32. package/lib/features/webbuilder/components/PreviewFrame.js +72 -0
  33. package/lib/features/webbuilder/components/PreviewFrame.js.map +1 -0
  34. package/lib/features/webbuilder/components/PreviewPlaceholder.js +107 -0
  35. package/lib/features/webbuilder/components/PreviewPlaceholder.js.map +1 -0
  36. package/lib/features/webbuilder/components/PreviewScreen.js +200 -0
  37. package/lib/features/webbuilder/components/PreviewScreen.js.map +1 -0
  38. package/lib/features/webbuilder/components/ProjectChat.js +580 -0
  39. package/lib/features/webbuilder/components/ProjectChat.js.map +1 -0
  40. package/lib/features/webbuilder/components/ProjectsScreen.js +339 -0
  41. package/lib/features/webbuilder/components/ProjectsScreen.js.map +1 -0
  42. package/lib/features/webbuilder/components/PublishSheet.js +143 -0
  43. package/lib/features/webbuilder/components/PublishSheet.js.map +1 -0
  44. package/lib/features/webbuilder/components/SiteScoreSheet.js +73 -0
  45. package/lib/features/webbuilder/components/SiteScoreSheet.js.map +1 -0
  46. package/lib/features/webbuilder/components/StudioHome.js +367 -0
  47. package/lib/features/webbuilder/components/StudioHome.js.map +1 -0
  48. package/lib/features/webbuilder/components/TemplateCard.js +73 -0
  49. package/lib/features/webbuilder/components/TemplateCard.js.map +1 -0
  50. package/lib/features/webbuilder/components/TemplatesSheet.js +178 -0
  51. package/lib/features/webbuilder/components/TemplatesSheet.js.map +1 -0
  52. package/lib/features/webbuilder/components/VersionsSheet.js +57 -0
  53. package/lib/features/webbuilder/components/VersionsSheet.js.map +1 -0
  54. package/lib/features/webbuilder/components/ui.js +291 -0
  55. package/lib/features/webbuilder/components/ui.js.map +1 -0
  56. package/lib/features/webbuilder/nativeWebBuilderRegistry.js +15 -0
  57. package/lib/features/webbuilder/nativeWebBuilderRegistry.js.map +1 -0
  58. package/lib/features/webbuilder/studioCatalog.js +147 -0
  59. package/lib/features/webbuilder/studioCatalog.js.map +1 -0
  60. package/lib/features/webbuilder/webbuilderPrompts.js +42 -0
  61. package/lib/features/webbuilder/webbuilderPrompts.js.map +1 -0
  62. package/lib/features/webbuilder/webbuilderTheme.js +63 -0
  63. package/lib/features/webbuilder/webbuilderTheme.js.map +1 -0
  64. package/lib/features/webbuilder/workflow.js +540 -0
  65. package/lib/features/webbuilder/workflow.js.map +1 -0
  66. package/lib/hooks/useChatApi.js +7 -2
  67. package/lib/hooks/useChatApi.js.map +1 -1
  68. package/lib/hooks/useChatStream.js +1 -1
  69. package/lib/hooks/useChatStream.js.map +1 -1
  70. package/lib/index.js +1 -1
  71. package/lib/index.js.map +1 -1
  72. package/lib/routes.json +106 -0
  73. package/lib/screens/WebBuilderNative/index.js +71 -0
  74. package/lib/screens/WebBuilderNative/index.js.map +1 -0
  75. package/lib/screens/WebBuilderNative/useCodeAssistantCatalog.js +45 -0
  76. package/lib/screens/WebBuilderNative/useCodeAssistantCatalog.js.map +1 -0
  77. package/lib/screens/WebBuilderNative/useWebBuilderGallery.js +125 -0
  78. package/lib/screens/WebBuilderNative/useWebBuilderGallery.js.map +1 -0
  79. package/lib/screens/WebBuilderNative/useWebBuilderHost.js +408 -0
  80. package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -0
  81. package/lib/screens/WebBuilderNative/webbuilderTransport.js +88 -0
  82. package/lib/screens/WebBuilderNative/webbuilderTransport.js.map +1 -0
  83. 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":"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"}
@@ -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;AACjE,EAAA,MAAM,WAAW,WAAY,EAAA;AAC7B,EAAM,MAAA,YAAA,GAAA,CAAe,qCAAU,EAAM,KAAA,IAAA;AACrC,EAAM,MAAA,OAAA,GAAA,CAAW,qCAED,UAAc,KAAA,IAAA;AAC9B,EAAM,MAAA,OAAA,GAAU,SAIb,oBAAsB,EAAA;AAAA,IACvB,SAAW,EAAA;AAAA,MACT;AAAA,KACF;AAAA,IACA,IAAM,EAAA,OAAA,CAAQ,YAAY,CAAA,IAAK,CAAC,OAAA;AAAA,IAChC,WAAa,EAAA;AAAA,GACd,CAAA;AACD,EAAA,MAAM,oBAAkB,EAAQ,GAAA,CAAA,EAAA,GAAA,OAAA,CAAA,IAAA,KAAR,IAAc,GAAA,MAAA,GAAA,EAAA,CAAA,WAAA,KAAd,mBAA2B,EAAM,KAAA,IAAA;AAGzD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAA,IAAgB,eAAiB,EAAA,QAAA,CAAS,qBAAsB,CAAA;AAAA,MACnE,EAAI,EAAA;AAAA,KACL,CAAC,CAAA;AAAA,GACD,EAAA,CAAC,YAAc,EAAA,eAAA,EAAiB,QAAQ,CAAC,CAAA;AAC5C,EAAA,MAAM,SAAS,YAAgB,IAAA,eAAA;AAC/B,EAAM,MAAA,WAAA,GAAc,QAAQ,MAAM,sBAAA,CAAuB,QAAQ,CAAG,EAAA,CAAC,QAAQ,CAAC,CAAA;AAC9E,EAAM,MAAA,SAAA,GAAY,QAAQ,MAAM,eAAA,CAAgB,QAAQ,CAAG,EAAA,CAAC,QAAQ,CAAC,CAAA;AACrE,EAAM,MAAA,UAAA,GAAa,uBAAwB,CAAA,MAAA,EAAQ,WAAW,CAAA;AAC9D,EAAA,MAAM,qBAA6C,UAAW,CAAA,SAAA,GAAY,YAAe,GAAA,UAAA,CAAW,UAAU,aAAgB,GAAA,gBAAA;AAC9H,EAAM,MAAA,MAAA,GAAS,OAA2B,CAAA,MAAM,MAAS,GAAA;AAAA,IACvD,MAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAS,EAAA,oBAAA;AAAA,IACT,WAAW,UAAW,CAAA,SAAA;AAAA,IACtB;AAAA,GACF,GAAI,MAAM,CAAC,MAAA,EAAQ,aAAa,SAAW,EAAA,UAAA,CAAW,SAAW,EAAA,kBAAkB,CAAC,CAAA;AACpF,EAAM,MAAA,KAAA,GAAQ,QAAQ,QAAQ,CAAA,IAAK,CAAC,UAAW,CAAA,OAAA,IAAW,CAAC,OAAQ,CAAA,OAAA;AACnE,EAAM,MAAA,YAAA,GAAe,CAAC,OAAA,GAAU,gDAAmD,GAAA,OAAA,CAAQ,QAAQ,CAAgC,6BAAA,EAAA,OAAA,CAAQ,KAAM,CAAA,OAAO,CAAK,CAAA,GAAA,8BAAA;AAC7J,EAAA,MAAM,QAAQ,UAAW,CAAA,KAAA,KAAU,CAAC,MAAA,IAAU,QAAQ,YAAe,GAAA,IAAA,CAAA;AACrE,EAAO,OAAA;AAAA,IACL,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,mBAAmB,UAAW,CAAA,iBAAA;AAAA,IAC9B,mBAAmB,UAAW,CAAA,OAAA;AAAA,IAC9B,iBAAiB,UAAW,CAAA,QAAA;AAAA,IAC5B,mBAAmB,UAAW,CAAA;AAAA,GAChC;AACF"}
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":"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;AAGjE,EAAM,MAAA,UAAA,GAAa,WAAY,CAAA,CAAC,KAI1B,KAAA,KAAA,CAAM,QAAW,GAAA,OAAA,CAAQ,KAAM,CAAA,QAAA,CAAS,UAAU,CAAA,GAAI,IAAI,CAAA;AAChE,EAAA,MAAM,WAAW,WAAY,EAAA;AAC7B,EAAM,MAAA,YAAA,GAAA,CAAe,qCAAU,EAAM,KAAA,IAAA;AACrC,EAAM,MAAA,OAAA,GAAA,CAAW,qCAED,UAAc,KAAA,IAAA;AAC9B,EAAM,MAAA,OAAA,GAAU,SAIb,oBAAsB,EAAA;AAAA,IACvB,SAAW,EAAA;AAAA,MACT;AAAA,KACF;AAAA,IACA,MAAM,CAAC,UAAA,IAAc,OAAQ,CAAA,YAAY,KAAK,CAAC,OAAA;AAAA,IAC/C,WAAa,EAAA;AAAA,GACd,CAAA;AACD,EAAA,MAAM,oBAAkB,EAAQ,GAAA,CAAA,EAAA,GAAA,OAAA,CAAA,IAAA,KAAR,IAAc,GAAA,MAAA,GAAA,EAAA,CAAA,WAAA,KAAd,mBAA2B,EAAM,KAAA,IAAA;AAGzD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAA,IAAgB,eAAiB,EAAA,QAAA,CAAS,qBAAsB,CAAA;AAAA,MACnE,EAAI,EAAA;AAAA,KACL,CAAC,CAAA;AAAA,GACD,EAAA,CAAC,YAAc,EAAA,eAAA,EAAiB,QAAQ,CAAC,CAAA;AAC5C,EAAA,MAAM,SAAS,YAAgB,IAAA,eAAA;AAC/B,EAAM,MAAA,WAAA,GAAc,QAAQ,MAAM,sBAAA,CAAuB,QAAQ,CAAG,EAAA,CAAC,QAAQ,CAAC,CAAA;AAC9E,EAAM,MAAA,SAAA,GAAY,QAAQ,MAAM,eAAA,CAAgB,QAAQ,CAAG,EAAA,CAAC,QAAQ,CAAC,CAAA;AACrE,EAAM,MAAA,UAAA,GAAa,uBAAwB,CAAA,MAAA,EAAQ,WAAW,CAAA;AAC9D,EAAA,MAAM,qBAA6C,UAAW,CAAA,SAAA,GAAY,YAAe,GAAA,UAAA,CAAW,UAAU,aAAgB,GAAA,gBAAA;AAC9H,EAAM,MAAA,MAAA,GAAS,OAA2B,CAAA,MAAM,MAAS,GAAA;AAAA,IACvD,MAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAS,EAAA,oBAAA;AAAA,IACT,WAAW,UAAW,CAAA,SAAA;AAAA,IACtB;AAAA,GACF,GAAI,MAAM,CAAC,MAAA,EAAQ,aAAa,SAAW,EAAA,UAAA,CAAW,SAAW,EAAA,kBAAkB,CAAC,CAAA;AACpF,EAAM,MAAA,KAAA,GAAQ,QAAQ,QAAQ,CAAA,IAAK,cAAc,CAAC,UAAA,CAAW,OAAW,IAAA,CAAC,OAAQ,CAAA,OAAA;AACjF,EAAM,MAAA,YAAA,GAAe,CAAC,OAAA,GAAU,gDAAmD,GAAA,OAAA,CAAQ,QAAQ,CAAgC,6BAAA,EAAA,OAAA,CAAQ,KAAM,CAAA,OAAO,CAAK,CAAA,GAAA,8BAAA;AAC7J,EAAA,MAAM,QAAQ,UAAW,CAAA,KAAA,KAAU,CAAC,MAAA,IAAU,QAAQ,YAAe,GAAA,IAAA,CAAA;AACrE,EAAO,OAAA;AAAA,IACL,MAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,mBAAmB,UAAW,CAAA,iBAAA;AAAA,IAC9B,mBAAmB,UAAW,CAAA,OAAA;AAAA,IAC9B,iBAAiB,UAAW,CAAA,QAAA;AAAA,IAC5B,mBAAmB,UAAW,CAAA;AAAA,GAChC;AACF"}
@@ -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