@adminide-stack/yantra-mobile 12.0.133 → 12.0.135
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/features/apps/nativeAppHandoff.js +26 -2
- package/lib/features/apps/nativeAppHandoff.js.map +1 -1
- package/lib/features/chat/askUser.js +8 -1
- package/lib/features/chat/askUser.js.map +1 -1
- package/lib/features/chat/toolActivity.js +4 -2
- package/lib/features/chat/toolActivity.js.map +1 -1
- package/lib/features/webbuilder/components/ProjectChat.js +4 -1
- package/lib/features/webbuilder/components/ProjectChat.js.map +1 -1
- package/lib/hooks/useCdecliChannel.js +1 -1
- package/lib/hooks/useCdecliChannel.js.map +1 -1
- package/lib/hooks/useChatStream.js +15 -1
- package/lib/hooks/useChatStream.js.map +1 -1
- package/lib/screens/Chat/index.js +23 -2
- package/lib/screens/Chat/index.js.map +1 -1
- package/lib/screens/ChatHistory/index.js +18 -5
- package/lib/screens/ChatHistory/index.js.map +1 -1
- package/lib/screens/Home/components/ChatHistoryLanding.js +4 -2
- package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -1
- package/lib/screens/WebBuilderNative/runningBuilds.js +4 -1
- package/lib/screens/WebBuilderNative/runningBuilds.js.map +1 -1
- package/lib/screens/WebBuilderNative/siteLane.js +5 -0
- package/lib/screens/WebBuilderNative/siteLane.js.map +1 -0
- package/lib/screens/WebBuilderNative/useWebBuilderGallery.js +42 -2
- package/lib/screens/WebBuilderNative/useWebBuilderGallery.js.map +1 -1
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js +54 -15
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
- package/lib/screens/WebBuilderNative/useWebBuilderJobs.js +1 -0
- package/lib/screens/WebBuilderNative/useWebBuilderJobs.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useWebBuilderGallery.js","sources":["../../../src/screens/WebBuilderNative/useWebBuilderGallery.ts"],"sourcesContent":["/**\n * Projects - the web surface's gallery hydrate, on the host, made fast.\n *\n * Same rule as the web (`realServices` gallery load): page the person's AI\n * assistant chats 10 at a time, newest first, and keep a chat only if its posts\n * hold a build. What makes it quick on a phone:\n *\n * - The last list paints at once: kept in memory across visits and on disk for a\n * cold start (per workspace).\n * - Reads go through the Apollo cache first. The app's type policies\n * (`graphql/typePolicies.ts`) keep `channelsByUser` as one merged list per\n * workspace and `messages` per channel, so a cached page is complete and\n * paints without the network.\n * - The refresh re-reads a chat's thread only when the chat changed\n * (`updatedAt`); an unchanged chat keeps the project it already gave. What each\n * chat gave (a project, or none for a plain chat) is saved with the list, so a\n * cold start re-reads only the chats that changed, not every chat again.\n * - A changed chat shows at once from its last post when that is a build; its\n * thread read then fills in the cover and the name. Thread reads run a few at a\n * time and each project appears as soon as it is known, newest first.\n * - A name, once known, is kept: a read that only yields the placeholder\n * (\"Generated Page\") never replaces it.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useApolloClient, type ApolloClient, type FetchPolicy } from '@apollo/client';\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport { GetChannelsByUserWithLastMessageDocument, MessagesDocument } from 'common/graphql';\nimport { getHistoryChannelsQueryVariables, getThreadMessagesQueryVariables } from '../../hooks/useChatApi';\nimport {\n isGenericTitle,\n lastMessageHasCover,\n projectFromPosts,\n type ChannelLike,\n} from '../../features/webbuilder/buildFragments';\nimport type { WebBuilderProject } from '../../features/webbuilder/types';\nimport { WEBBUILDER_PROJECTS_SNAPSHOT_KEY } from './webbuilderSnapshotKey';\n\n/** The web gallery's page size (`GALLERY_PAGE_SIZE`). */\nexport const GALLERY_PAGE_SIZE = 10;\n/** Keep paging (up to this many pages per load) while pages yield too few projects to fill the screen. */\nconst MIN_FILL = 8;\nconst MAX_PAGES_PER_LOAD = 4;\n/** Thread reads in flight at once: enough to be quick, few enough to keep the app responsive. */\nconst READ_CONCURRENCY = 4;\nconst SNAPSHOT_KEY = WEBBUILDER_PROJECTS_SNAPSHOT_KEY;\nconst SNAPSHOT_MAX = 40;\n/** Chats remembered with their stamp (plain chats included: each would otherwise be re-read). */\nconst KNOWN_MAX = 300;\n\ntype Loose = Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n/** What a chat last gave: its project (or none) at the `updatedAt` it was read for. */\ninterface Known {\n stamp: string;\n project: WebBuilderProject | null;\n}\n\n/** Per-workspace memory: survives leaving and reopening Web Builder in one app run. */\nconst memory = new Map<string, { projects: WebBuilderProject[]; known: Map<string, Known> }>();\n\nexport interface WebBuilderGallery {\n projects: WebBuilderProject[];\n loading: boolean;\n loadingMore: boolean;\n hasMore: boolean;\n error: string | null;\n refresh: () => void;\n loadMore: () => void;\n /** Put (or update) one site - the open one, as its posts change. */\n upsert: (project: WebBuilderProject) => void;\n}\n\nfunction sortProjects(list: Iterable<WebBuilderProject>): WebBuilderProject[] {\n return [...list].sort((a, b) => b.updatedAt - a.updatedAt);\n}\n\nfunction stampOf(channel: ChannelLike): string {\n return String(channel.updatedAt ?? channel.createdAt ?? '');\n}\n\ninterface Snapshot {\n projects: WebBuilderProject[];\n /** `[channelId, stamp, project | null]`: what each chat gave at the `updatedAt` it was read for. */\n known: Array<[string, string, WebBuilderProject | null]>;\n}\n\nasync function readSnapshot(org: string): Promise<{ projects: WebBuilderProject[]; known: Map<string, Known> }> {\n try {\n const raw = await AsyncStorage.getItem(`${SNAPSHOT_KEY}:${org}`);\n const parsed = raw ? (JSON.parse(raw) as Partial<Snapshot> | WebBuilderProject[]) : {};\n // An older snapshot is the bare projects list.\n const saved: Partial<Snapshot> = Array.isArray(parsed) ? { projects: parsed } : parsed;\n const projects = Array.isArray(saved.projects) ? saved.projects.filter((p) => p?.channelId && p.title) : [];\n const known = new Map<string, Known>();\n for (const row of Array.isArray(saved.known) ? saved.known : []) {\n if (Array.isArray(row) && typeof row[0] === 'string' && typeof row[1] === 'string') {\n known.set(row[0], { stamp: row[1], project: row[2] ?? null });\n }\n }\n return { projects, known };\n } catch {\n return { projects: [], known: new Map() };\n }\n}\n\nfunction writeSnapshot(org: string, projects: WebBuilderProject[], known: Map<string, Known>): void {\n const snapshot: Snapshot = {\n projects: projects.slice(0, SNAPSHOT_MAX),\n known: [...known].slice(-KNOWN_MAX).map(([id, k]) => [id, k.stamp, k.project]),\n };\n AsyncStorage.setItem(`${SNAPSHOT_KEY}:${org}`, JSON.stringify(snapshot)).catch(() => undefined);\n}\n\n/** A read that only found the placeholder name keeps the name the site already had. */\nfunction keepKnownName(next: WebBuilderProject | null, prior: WebBuilderProject | null | undefined) {\n if (!next || !prior || !isGenericTitle(next.title) || isGenericTitle(prior.title)) return next;\n return { ...next, title: prior.title };\n}\n\n/** Runs `work` over `items`, at most `limit` at a time. */\nasync function eachLimited<T>(items: T[], limit: number, work: (item: T) => Promise<void>): Promise<void> {\n let next = 0;\n const lane = async (): Promise<void> => {\n while (next < items.length) {\n const item = items[next];\n next += 1;\n // eslint-disable-next-line no-await-in-loop -- one lane works through its share in order\n await work(item);\n }\n };\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, lane));\n}\n\nasync function readChannels(\n client: ApolloClient<object>,\n orgName: string,\n skip: number,\n fetchPolicy: FetchPolicy,\n): Promise<ChannelLike[]> {\n const result = await client.query({\n query: GetChannelsByUserWithLastMessageDocument,\n variables: getHistoryChannelsQueryVariables(orgName, { limit: GALLERY_PAGE_SIZE, skip }),\n fetchPolicy,\n errorPolicy: 'all',\n // Same slot as chat history: the type policy merges both into one list.\n context: { cacheKey: 'chat-history-channels-list' },\n });\n return (((result.data as Loose)?.channelsByUser ?? []) as ChannelLike[]).filter((c) => c?.id);\n}\n\nexport function useWebBuilderGallery(orgName: string, cdnOrigin: string): WebBuilderGallery {\n const client = useApolloClient();\n const remembered = orgName ? memory.get(orgName) : undefined;\n const [projects, setProjects] = useState<WebBuilderProject[]>(() => remembered?.projects ?? []);\n const [loading, setLoading] = useState(false);\n const [loadingMore, setLoadingMore] = useState(false);\n const [hasMore, setHasMore] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const skipRef = useRef(0);\n const busyRef = useRef(false);\n const runRef = useRef(0);\n const knownRef = useRef<Map<string, Known>>(remembered?.known ?? new Map());\n\n // Keep memory and the disk snapshot in step with what is shown.\n useEffect(() => {\n if (!orgName) return;\n memory.set(orgName, { projects, known: knownRef.current });\n if (projects.length) writeSnapshot(orgName, projects, knownRef.current);\n }, [orgName, projects]);\n\n // A cold start paints the last list from disk, and takes what each chat gave with it,\n // so the first load re-reads only the chats that changed since (it waits for this).\n const hydratedRef = useRef<Promise<void>>(Promise.resolve());\n useEffect(() => {\n if (!orgName || memory.get(orgName)?.projects.length) return undefined;\n let live = true;\n hydratedRef.current = readSnapshot(orgName)\n .then((saved) => {\n if (!live) return;\n saved.known.forEach((k, id) => {\n if (!knownRef.current.has(id)) knownRef.current.set(id, k);\n });\n if (saved.projects.length) setProjects((prev) => (prev.length ? prev : saved.projects));\n })\n .catch(() => undefined);\n return () => {\n live = false;\n };\n }, [orgName]);\n\n const projectFor = useCallback(\n async (channel: ChannelLike, fetchPolicy: FetchPolicy): Promise<WebBuilderProject | null> => {\n const id = channel.id ?? '';\n if (!id) return null;\n // The web skips the thread read when the last post already has the screenshot.\n // Only with a real name: the last post alone has no brief to name the site from.\n if (lastMessageHasCover(channel)) {\n const fromLast = projectFromPosts(channel, [channel.lastMessage], cdnOrigin);\n if (fromLast && !isGenericTitle(fromLast.title)) return fromLast;\n }\n const result = await client.query({\n query: MessagesDocument,\n variables: getThreadMessagesQueryVariables(id),\n fetchPolicy,\n errorPolicy: 'all',\n context: { cacheKey: `messages-list:${id}` },\n });\n const posts = ((result.data as Loose)?.messages?.data ?? []) as unknown[];\n const withLast = channel.lastMessage ? [...posts, channel.lastMessage] : posts;\n return projectFromPosts(channel, withLast, cdnOrigin);\n },\n [client, cdnOrigin],\n );\n\n const load = useCallback(\n async (mode: 'reset' | 'more') => {\n if (!orgName || busyRef.current) return;\n busyRef.current = true;\n await hydratedRef.current;\n const run = runRef.current + 1;\n runRef.current = run;\n const stale = () => runRef.current !== run;\n const known = knownRef.current;\n const seen = new Set<string>();\n const put = (project: WebBuilderProject | null, channelId: string) => {\n if (stale()) return;\n setProjects((prev) => {\n const byId = new Map(prev.map((p) => [p.channelId, p]));\n if (project) byId.set(channelId, project);\n else byId.delete(channelId);\n return sortProjects(byId.values());\n });\n };\n\n if (mode === 'reset') {\n skipRef.current = 0;\n setLoading(projects.length === 0);\n } else {\n setLoadingMore(true);\n }\n setError(null);\n\n try {\n // 1. From the cache: instant when the type policies already hold the list.\n if (mode === 'reset') {\n const cached = await readChannels(client, orgName, 0, 'cache-only').catch(() => []);\n await eachLimited(cached, READ_CONCURRENCY, async (channel) => {\n const id = channel.id ?? '';\n if (known.has(id)) return;\n const project = await projectFor(channel, 'cache-only').catch(() => null);\n if (project) {\n known.set(id, { stamp: stampOf(channel), project });\n put(project, id);\n }\n });\n if (!stale() && projects.length === 0 && known.size) setLoading(false);\n }\n\n // 2. From the network: the list, then only the threads that changed.\n let more = false;\n const tally = { found: 0 };\n for (let page = 0; page < MAX_PAGES_PER_LOAD; page += 1) {\n // eslint-disable-next-line no-await-in-loop -- pages are sequential by design\n const channels = await readChannels(client, orgName, skipRef.current, 'network-only');\n if (stale()) return;\n skipRef.current += channels.length;\n more = channels.length >= GALLERY_PAGE_SIZE;\n // eslint-disable-next-line no-await-in-loop\n await eachLimited(channels, READ_CONCURRENCY, async (channel) => {\n const id = channel.id ?? '';\n seen.add(id);\n const stamp = stampOf(channel);\n const prior = known.get(id);\n // Unchanged: keep what it gave - unless that is still the placeholder name.\n const unnamed = Boolean(prior?.project && isGenericTitle(prior.project.title));\n if (prior && prior.stamp === stamp && !unnamed) {\n if (prior.project) tally.found += 1;\n return;\n }\n // Show it now from its last post when that is a build; the read fills in the rest.\n const quick = channel.lastMessage\n ? keepKnownName(projectFromPosts(channel, [channel.lastMessage], cdnOrigin), prior?.project)\n : null;\n if (quick) put(quick, id);\n const read = await projectFor(channel, 'network-only').catch(() => prior?.project ?? null);\n const project = keepKnownName(read, prior?.project ?? quick);\n known.set(id, { stamp, project });\n if (project) tally.found += 1;\n put(project, id);\n });\n if (!more || tally.found >= MIN_FILL) break;\n }\n if (stale()) return;\n if (mode === 'reset') {\n // A chat no longer in the first pages (deleted, moved) drops off the list.\n setProjects((prev) =>\n prev.filter((p) => seen.has(p.channelId) || p.updatedAt > Date.now() - 60_000),\n );\n }\n setHasMore(more);\n } catch (err) {\n console.warn('[WebBuilderNative] could not load projects:', err);\n if (!stale()) setError('Check your connection and try again.');\n } finally {\n busyRef.current = false;\n if (!stale()) {\n setLoading(false);\n setLoadingMore(false);\n }\n }\n },\n // `projects.length` only steers the first spinner; reading it stale is harmless.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [client, orgName, projectFor],\n );\n\n useEffect(() => {\n load('reset').catch(() => undefined);\n }, [load]);\n\n const refresh = useCallback(() => {\n busyRef.current = false;\n load('reset').catch(() => undefined);\n }, [load]);\n const loadMore = useCallback(() => {\n if (hasMore) load('more').catch(() => undefined);\n }, [hasMore, load]);\n\n const upsert = useCallback((project: WebBuilderProject) => {\n setProjects((prev) => {\n const existing = prev.find((p) => p.channelId === project.channelId);\n if (\n existing &&\n existing.title === project.title &&\n existing.coverUrl === project.coverUrl &&\n existing.liveUrl === project.liveUrl &&\n existing.updatedAt === project.updatedAt\n ) {\n return prev;\n }\n return sortProjects([project, ...prev.filter((p) => p.channelId !== project.channelId)]);\n });\n }, []);\n\n return { projects, loading, loadingMore, hasMore, error, refresh, loadMore, upsert };\n}\n"],"names":["_a"],"mappings":";;;;;;;;;;;;;;;;;;;AAiCO,MAAM,iBAAoB,GAAA;AAEjC,MAAM,QAAW,GAAA,CAAA;AACjB,MAAM,kBAAqB,GAAA,CAAA;AAE3B,MAAM,gBAAmB,GAAA,CAAA;AACzB,MAAM,YAAe,GAAA,gCAAA;AACrB,MAAM,YAAe,GAAA,EAAA;AAYrB,MAAM,MAAA,uBAAa,GAGhB,EAAA;AAYH,SAAS,aAAa,IAAwD,EAAA;AAC5E,EAAO,OAAA,CAAC,GAAG,IAAI,CAAE,CAAA,IAAA,CAAK,CAAC,CAAA,EAAG,CAAM,KAAA,CAAA,CAAE,SAAY,GAAA,CAAA,CAAE,SAAS,CAAA;AAC3D;AACA,SAAS,QAAQ,OAA8B,EAAA;AAtE/C,EAAA,IAAA,EAAA,EAAA,EAAA;AAuEE,EAAA,OAAO,QAAO,EAAQ,GAAA,CAAA,EAAA,GAAA,OAAA,CAAA,SAAA,KAAR,YAAqB,OAAQ,CAAA,SAAA,KAA7B,YAA0C,EAAE,CAAA;AAC5D;AAMA,eAAe,aAAa,GAGzB,EAAA;AAjFH,EAAA,IAAA,EAAA;AAkFE,EAAI,IAAA;AACF,IAAM,MAAA,GAAA,GAAM,MAAM,YAAa,CAAA,OAAA,CAAQ,GAAG,YAAY,CAAA,CAAA,EAAI,GAAG,CAAE,CAAA,CAAA;AAC/D,IAAA,MAAM,SAAS,GAAM,GAAA,IAAA,CAAK,KAAM,CAAA,GAAG,IAA+C,EAAC;AAEnF,IAAA,MAAM,KAA2B,GAAA,KAAA,CAAM,OAAQ,CAAA,MAAM,CAAI,GAAA;AAAA,MACvD,QAAU,EAAA;AAAA,KACR,GAAA,MAAA;AACJ,IAAA,MAAM,QAAW,GAAA,KAAA,CAAM,OAAQ,CAAA,KAAA,CAAM,QAAQ,CAAI,GAAA,KAAA,CAAM,QAAS,CAAA,MAAA,CAAO,QAAK,CAAG,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,CAAA,CAAA,SAAA,KAAa,CAAE,CAAA,KAAK,IAAI,EAAC;AACxG,IAAM,MAAA,KAAA,uBAAY,GAAmB,EAAA;AACrC,IAAW,KAAA,MAAA,GAAA,IAAO,MAAM,OAAQ,CAAA,KAAA,CAAM,KAAK,CAAI,GAAA,KAAA,CAAM,KAAQ,GAAA,EAAI,EAAA;AAC/D,MAAA,IAAI,KAAM,CAAA,OAAA,CAAQ,GAAG,CAAA,IAAK,OAAO,GAAA,CAAI,CAAC,CAAA,KAAM,QAAY,IAAA,OAAO,GAAI,CAAA,CAAC,MAAM,QAAU,EAAA;AAClF,QAAM,KAAA,CAAA,GAAA,CAAI,GAAI,CAAA,CAAC,CAAG,EAAA;AAAA,UAChB,KAAA,EAAO,IAAI,CAAC,CAAA;AAAA,UACZ,OAAS,EAAA,CAAA,EAAA,GAAA,GAAA,CAAI,CAAC,CAAA,KAAL,IAAU,GAAA,EAAA,GAAA;AAAA,SACpB,CAAA;AAAA;AACH;AAEF,IAAO,OAAA;AAAA,MACL,QAAA;AAAA,MACA;AAAA,KACF;AAAA,GACM,CAAA,OAAA,CAAA,EAAA;AACN,IAAO,OAAA;AAAA,MACL,UAAU,EAAC;AAAA,MACX,KAAA,sBAAW,GAAI;AAAA,KACjB;AAAA;AAEJ;AACA,SAAS,aAAA,CAAc,GAAa,EAAA,QAAA,EAA+B,KAAiC,EAAA;AAClG,EAAA,MAAM,QAAqB,GAAA;AAAA,IACzB,QAAU,EAAA,QAAA,CAAS,KAAM,CAAA,CAAA,EAAG,YAAY,CAAA;AAAA,IACxC,KAAA,EAAO,CAAC,GAAG,KAAK,EAAE,KAAM,CAAA,IAAU,CAAE,CAAA,GAAA,CAAI,CAAC,CAAC,EAAA,EAAI,CAAC,CAAM,KAAA,CAAC,IAAI,CAAE,CAAA,KAAA,EAAO,CAAE,CAAA,OAAO,CAAC;AAAA,GAC/E;AACA,EAAA,YAAA,CAAa,OAAQ,CAAA,CAAA,EAAG,YAAY,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,EAAI,IAAK,CAAA,SAAA,CAAU,QAAQ,CAAC,CAAE,CAAA,KAAA,CAAM,MAAM,MAAS,CAAA;AAChG;AAGA,SAAS,aAAA,CAAc,MAAgC,KAA6C,EAAA;AAClG,EAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,KAAA,IAAS,CAAC,cAAA,CAAe,IAAK,CAAA,KAAK,CAAK,IAAA,cAAA,CAAe,KAAM,CAAA,KAAK,GAAU,OAAA,IAAA;AAC1F,EAAA,OAAO,iCACF,IADE,CAAA,EAAA;AAAA,IAEL,OAAO,KAAM,CAAA;AAAA,GACf,CAAA;AACF;AAGA,eAAe,WAAA,CAAe,KAAY,EAAA,KAAA,EAAe,IAAiD,EAAA;AACxG,EAAA,IAAI,IAAO,GAAA,CAAA;AACX,EAAA,MAAM,OAAO,YAA2B;AACtC,IAAO,OAAA,IAAA,GAAO,MAAM,MAAQ,EAAA;AAC1B,MAAM,MAAA,IAAA,GAAO,MAAM,IAAI,CAAA;AACvB,MAAQ,IAAA,IAAA,CAAA;AAER,MAAA,MAAM,KAAK,IAAI,CAAA;AAAA;AACjB,GACF;AACA,EAAM,MAAA,OAAA,CAAQ,GAAI,CAAA,KAAA,CAAM,IAAK,CAAA;AAAA,IAC3B,MAAQ,EAAA,IAAA,CAAK,GAAI,CAAA,KAAA,EAAO,MAAM,MAAM;AAAA,GACtC,EAAG,IAAI,CAAC,CAAA;AACV;AACA,eAAe,YAAa,CAAA,MAAA,EAA8B,OAAiB,EAAA,IAAA,EAAc,WAAkD,EAAA;AA9I3I,EAAA,IAAA,EAAA,EAAA,EAAA;AA+IE,EAAM,MAAA,MAAA,GAAS,MAAM,MAAA,CAAO,KAAM,CAAA;AAAA,IAChC,KAAO,EAAA,wCAAA;AAAA,IACP,SAAA,EAAW,iCAAiC,OAAS,EAAA;AAAA,MACnD,KAAO,EAAA,iBAAA;AAAA,MACP;AAAA,KACD,CAAA;AAAA,IACD,WAAA;AAAA,IACA,WAAa,EAAA,KAAA;AAAA;AAAA,IAEb,OAAS,EAAA;AAAA,MACP,QAAU,EAAA;AAAA;AACZ,GACD,CAAA;AACD,EAAU,OAAA,CAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,MAAA,CAAO,IAAP,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAuB,cAAvB,KAAA,IAAA,GAAA,EAAA,GAAyC,EAAsB,EAAA,MAAA,CAAO,CAAK,CAAA,KAAA,CAAA,IAAA,IAAA,GAAA,MAAA,GAAA,CAAA,CAAG,EAAE,CAAA;AAC5F;AACgB,SAAA,oBAAA,CAAqB,SAAiB,SAAsC,EAAA;AA9J5F,EAAA,IAAA,EAAA;AA+JE,EAAA,MAAM,SAAS,eAAgB,EAAA;AAC/B,EAAA,MAAM,UAAa,GAAA,OAAA,GAAU,MAAO,CAAA,GAAA,CAAI,OAAO,CAAI,GAAA,MAAA;AACnD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAA8B,MAAG;AAjKnE,IAAAA,IAAAA,GAAAA;AAiKsE,IAAA,OAAA,CAAAA,GAAA,GAAA,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,QAAZ,KAAA,IAAA,GAAAA,MAAwB,EAAC;AAAA,GAAC,CAAA;AAC9F,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,KAAK,CAAA;AACpD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAwB,IAAI,CAAA;AACtD,EAAM,MAAA,OAAA,GAAU,OAAO,CAAC,CAAA;AACxB,EAAM,MAAA,OAAA,GAAU,OAAO,KAAK,CAAA;AAC5B,EAAM,MAAA,MAAA,GAAS,OAAO,CAAC,CAAA;AACvB,EAAA,MAAM,WAAW,MAA2B,CAAA,CAAA,EAAA,GAAA,UAAA,IAAA,IAAA,GAAA,MAAA,GAAA,UAAA,CAAY,UAAZ,IAAqB,GAAA,EAAA,mBAAA,IAAI,KAAK,CAAA;AAG1E,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAS,EAAA;AACd,IAAA,MAAA,CAAO,IAAI,OAAS,EAAA;AAAA,MAClB,QAAA;AAAA,MACA,OAAO,QAAS,CAAA;AAAA,KACjB,CAAA;AACD,IAAA,IAAI,SAAS,MAAQ,EAAA,aAAA,CAAc,OAAS,EAAA,QAAA,EAAU,SAAS,OAAO,CAAA;AAAA,GACrE,EAAA,CAAC,OAAS,EAAA,QAAQ,CAAC,CAAA;AAItB,EAAA,MAAM,WAAc,GAAA,MAAA,CAAsB,OAAQ,CAAA,OAAA,EAAS,CAAA;AAC3D,EAAA,SAAA,CAAU,MAAM;AAxLlB,IAAAA,IAAAA,GAAAA;AAyLI,IAAI,IAAA,CAAC,OAAWA,KAAAA,CAAAA,GAAAA,GAAA,MAAO,CAAA,GAAA,CAAI,OAAO,CAAA,KAAlB,IAAAA,GAAAA,MAAAA,GAAAA,GAAAA,CAAqB,QAAS,CAAA,MAAA,CAAA,EAAe,OAAA,MAAA;AAC7D,IAAA,IAAI,IAAO,GAAA,IAAA;AACX,IAAA,WAAA,CAAY,OAAU,GAAA,YAAA,CAAa,OAAO,CAAA,CAAE,KAAK,CAAS,KAAA,KAAA;AACxD,MAAA,IAAI,CAAC,IAAM,EAAA;AACX,MAAA,KAAA,CAAM,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA,EAAG,EAAO,KAAA;AAC7B,QAAI,IAAA,CAAC,QAAS,CAAA,OAAA,CAAQ,GAAI,CAAA,EAAE,GAAY,QAAA,CAAA,OAAA,CAAQ,GAAI,CAAA,EAAA,EAAI,CAAC,CAAA;AAAA,OAC1D,CAAA;AACD,MAAI,IAAA,KAAA,CAAM,SAAS,MAAQ,EAAA,WAAA,CAAY,UAAQ,IAAK,CAAA,MAAA,GAAS,IAAO,GAAA,KAAA,CAAM,QAAQ,CAAA;AAAA,KACnF,CAAA,CAAE,KAAM,CAAA,MAAM,MAAS,CAAA;AACxB,IAAA,OAAO,MAAM;AACX,MAAO,IAAA,GAAA,KAAA;AAAA,KACT;AAAA,GACF,EAAG,CAAC,OAAO,CAAC,CAAA;AACZ,EAAA,MAAM,UAAa,GAAA,WAAA,CAAY,OAAO,OAAA,EAAsB,WAAgE,KAAA;AAtM9H,IAAA,IAAAA,GAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAuMI,IAAA,MAAM,EAAKA,GAAAA,CAAAA,GAAAA,GAAA,OAAQ,CAAA,EAAA,KAAR,OAAAA,GAAc,GAAA,EAAA;AACzB,IAAI,IAAA,CAAC,IAAW,OAAA,IAAA;AAGhB,IAAI,IAAA,mBAAA,CAAoB,OAAO,CAAG,EAAA;AAChC,MAAA,MAAM,WAAW,gBAAiB,CAAA,OAAA,EAAS,CAAC,OAAQ,CAAA,WAAW,GAAG,SAAS,CAAA;AAC3E,MAAA,IAAI,YAAY,CAAC,cAAA,CAAe,QAAS,CAAA,KAAK,GAAU,OAAA,QAAA;AAAA;AAE1D,IAAM,MAAA,MAAA,GAAS,MAAM,MAAA,CAAO,KAAM,CAAA;AAAA,MAChC,KAAO,EAAA,gBAAA;AAAA,MACP,SAAA,EAAW,gCAAgC,EAAE,CAAA;AAAA,MAC7C,WAAA;AAAA,MACA,WAAa,EAAA,KAAA;AAAA,MACb,OAAS,EAAA;AAAA,QACP,QAAA,EAAU,iBAAiB,EAAE,CAAA;AAAA;AAC/B,KACD,CAAA;AACD,IAAM,MAAA,KAAA,GAAA,CAAU,wBAAO,IAAP,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAuB,aAAvB,IAAiC,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,KAAjC,YAAyC,EAAC;AAC1D,IAAM,MAAA,QAAA,GAAW,QAAQ,WAAc,GAAA,CAAC,GAAG,KAAO,EAAA,OAAA,CAAQ,WAAW,CAAI,GAAA,KAAA;AACzE,IAAO,OAAA,gBAAA,CAAiB,OAAS,EAAA,QAAA,EAAU,SAAS,CAAA;AAAA,GACnD,EAAA,CAAC,MAAQ,EAAA,SAAS,CAAC,CAAA;AACtB,EAAA,MAAM,IAAO,GAAA,WAAA;AAAA,IAAY,OAAO,IAA2B,KAAA;AACzD,MAAI,IAAA,CAAC,OAAW,IAAA,OAAA,CAAQ,OAAS,EAAA;AACjC,MAAA,OAAA,CAAQ,OAAU,GAAA,IAAA;AAClB,MAAA,MAAM,WAAY,CAAA,OAAA;AAClB,MAAM,MAAA,GAAA,GAAM,OAAO,OAAU,GAAA,CAAA;AAC7B,MAAA,MAAA,CAAO,OAAU,GAAA,GAAA;AACjB,MAAM,MAAA,KAAA,GAAQ,MAAM,MAAA,CAAO,OAAY,KAAA,GAAA;AACvC,MAAA,MAAM,QAAQ,QAAS,CAAA,OAAA;AACvB,MAAM,MAAA,IAAA,uBAAW,GAAY,EAAA;AAC7B,MAAM,MAAA,GAAA,GAAM,CAAC,OAAA,EAAmC,SAAsB,KAAA;AACpE,QAAA,IAAI,OAAS,EAAA;AACb,QAAA,WAAA,CAAY,CAAQ,IAAA,KAAA;AAClB,UAAM,MAAA,IAAA,GAAO,IAAI,GAAA,CAAI,IAAK,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAC,CAAE,CAAA,SAAA,EAAW,CAAC,CAAC,CAAC,CAAA;AACpD,UAAA,IAAI,OAAS,EAAA,IAAA,CAAK,GAAI,CAAA,SAAA,EAAW,OAAO,CAAA;AAAA,eAAO,IAAA,CAAK,OAAO,SAAS,CAAA;AACpE,UAAO,OAAA,YAAA,CAAa,IAAK,CAAA,MAAA,EAAQ,CAAA;AAAA,SAClC,CAAA;AAAA,OACH;AACA,MAAA,IAAI,SAAS,OAAS,EAAA;AACpB,QAAA,OAAA,CAAQ,OAAU,GAAA,CAAA;AAClB,QAAW,UAAA,CAAA,QAAA,CAAS,WAAW,CAAC,CAAA;AAAA,OAC3B,MAAA;AACL,QAAA,cAAA,CAAe,IAAI,CAAA;AAAA;AAErB,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAI,IAAA;AAEF,QAAA,IAAI,SAAS,OAAS,EAAA;AACpB,UAAM,MAAA,MAAA,GAAS,MAAM,YAAA,CAAa,MAAQ,EAAA,OAAA,EAAS,CAAG,EAAA,YAAY,CAAE,CAAA,KAAA,CAAM,MAAM,EAAE,CAAA;AAClF,UAAA,MAAM,WAAY,CAAA,MAAA,EAAQ,gBAAkB,EAAA,OAAM,OAAW,KAAA;AAxPrE,YAAAA,IAAAA,GAAAA;AAyPU,YAAA,MAAM,EAAKA,GAAAA,CAAAA,GAAAA,GAAA,OAAQ,CAAA,EAAA,KAAR,OAAAA,GAAc,GAAA,EAAA;AACzB,YAAI,IAAA,KAAA,CAAM,GAAI,CAAA,EAAE,CAAG,EAAA;AACnB,YAAM,MAAA,OAAA,GAAU,MAAM,UAAW,CAAA,OAAA,EAAS,YAAY,CAAE,CAAA,KAAA,CAAM,MAAM,IAAI,CAAA;AACxE,YAAA,IAAI,OAAS,EAAA;AACX,cAAA,KAAA,CAAM,IAAI,EAAI,EAAA;AAAA,gBACZ,KAAA,EAAO,QAAQ,OAAO,CAAA;AAAA,gBACtB;AAAA,eACD,CAAA;AACD,cAAA,GAAA,CAAI,SAAS,EAAE,CAAA;AAAA;AACjB,WACD,CAAA;AACD,UAAI,IAAA,CAAC,OAAW,IAAA,QAAA,CAAS,WAAW,CAAK,IAAA,KAAA,CAAM,IAAM,EAAA,UAAA,CAAW,KAAK,CAAA;AAAA;AAIvE,QAAA,IAAI,IAAO,GAAA,KAAA;AACX,QAAA,MAAM,KAAQ,GAAA;AAAA,UACZ,KAAO,EAAA;AAAA,SACT;AACA,QAAA,KAAA,IAAS,IAAO,GAAA,CAAA,EAAG,IAAO,GAAA,kBAAA,EAAoB,QAAQ,CAAG,EAAA;AAEvD,UAAA,MAAM,WAAW,MAAM,YAAA,CAAa,QAAQ,OAAS,EAAA,OAAA,CAAQ,SAAS,cAAc,CAAA;AACpF,UAAA,IAAI,OAAS,EAAA;AACb,UAAA,OAAA,CAAQ,WAAW,QAAS,CAAA,MAAA;AAC5B,UAAA,IAAA,GAAO,SAAS,MAAU,IAAA,iBAAA;AAE1B,UAAA,MAAM,WAAY,CAAA,QAAA,EAAU,gBAAkB,EAAA,OAAM,OAAW,KAAA;AAnRvE,YAAA,IAAAA,GAAA,EAAA,EAAA;AAoRU,YAAA,MAAM,EAAKA,GAAAA,CAAAA,GAAAA,GAAA,OAAQ,CAAA,EAAA,KAAR,OAAAA,GAAc,GAAA,EAAA;AACzB,YAAA,IAAA,CAAK,IAAI,EAAE,CAAA;AACX,YAAM,MAAA,KAAA,GAAQ,QAAQ,OAAO,CAAA;AAC7B,YAAM,MAAA,KAAA,GAAQ,KAAM,CAAA,GAAA,CAAI,EAAE,CAAA;AAE1B,YAAM,MAAA,OAAA,GAAU,SAAQ,KAAO,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,KAAA,CAAA,OAAA,KAAW,eAAe,KAAM,CAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAC7E,YAAA,IAAI,KAAS,IAAA,KAAA,CAAM,KAAU,KAAA,KAAA,IAAS,CAAC,OAAS,EAAA;AAC9C,cAAI,IAAA,KAAA,CAAM,OAAS,EAAA,KAAA,CAAM,KAAS,IAAA,CAAA;AAClC,cAAA;AAAA;AAGF,YAAA,MAAM,KAAQ,GAAA,OAAA,CAAQ,WAAc,GAAA,aAAA,CAAc,iBAAiB,OAAS,EAAA,CAAC,OAAQ,CAAA,WAAW,CAAG,EAAA,SAAS,CAAG,EAAA,KAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,KAAA,CAAO,OAAO,CAAI,GAAA,IAAA;AACjI,YAAI,IAAA,KAAA,EAAW,GAAA,CAAA,KAAA,EAAO,EAAE,CAAA;AACxB,YAAA,MAAM,OAAO,MAAM,UAAA,CAAW,SAAS,cAAc,CAAA,CAAE,MAAM,MAAG;AAjS1E,cAAAA,IAAAA,GAAAA;AAiS6E,cAAA,OAAA,CAAAA,GAAA,GAAA,KAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,KAAA,CAAO,OAAP,KAAA,IAAA,GAAAA,GAAkB,GAAA,IAAA;AAAA,aAAI,CAAA;AACzF,YAAA,MAAM,UAAU,aAAc,CAAA,IAAA,EAAA,CAAM,EAAO,GAAA,KAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,KAAA,CAAA,OAAA,KAAP,YAAkB,KAAK,CAAA;AAC3D,YAAA,KAAA,CAAM,IAAI,EAAI,EAAA;AAAA,cACZ,KAAA;AAAA,cACA;AAAA,aACD,CAAA;AACD,YAAI,IAAA,OAAA,QAAe,KAAS,IAAA,CAAA;AAC5B,YAAA,GAAA,CAAI,SAAS,EAAE,CAAA;AAAA,WAChB,CAAA;AACD,UAAA,IAAI,CAAC,IAAA,IAAQ,KAAM,CAAA,KAAA,IAAS,QAAU,EAAA;AAAA;AAExC,QAAA,IAAI,OAAS,EAAA;AACb,QAAA,IAAI,SAAS,OAAS,EAAA;AAEpB,UAAA,WAAA,CAAY,CAAQ,IAAA,KAAA,IAAA,CAAK,MAAO,CAAA,CAAA,CAAA,KAAK,KAAK,GAAI,CAAA,CAAA,CAAE,SAAS,CAAA,IAAK,EAAE,SAAY,GAAA,IAAA,CAAK,GAAI,EAAA,GAAI,GAAM,CAAC,CAAA;AAAA;AAElG,QAAA,UAAA,CAAW,IAAI,CAAA;AAAA,eACR,GAAK,EAAA;AACZ,QAAQ,OAAA,CAAA,IAAA,CAAK,+CAA+C,GAAG,CAAA;AAC/D,QAAA,IAAI,CAAC,KAAA,EAAS,EAAA,QAAA,CAAS,sCAAsC,CAAA;AAAA,OAC7D,SAAA;AACA,QAAA,OAAA,CAAQ,OAAU,GAAA,KAAA;AAClB,QAAI,IAAA,CAAC,OAAS,EAAA;AACZ,UAAA,UAAA,CAAW,KAAK,CAAA;AAChB,UAAA,cAAA,CAAe,KAAK,CAAA;AAAA;AACtB;AACF,KACF;AAAA;AAAA;AAAA,IAGA,CAAC,MAAQ,EAAA,OAAA,EAAS,UAAU;AAAA,GAAC;AAC7B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAA,CAAK,OAAO,CAAA,CAAE,KAAM,CAAA,MAAM,MAAS,CAAA;AAAA,GACrC,EAAG,CAAC,IAAI,CAAC,CAAA;AACT,EAAM,MAAA,OAAA,GAAU,YAAY,MAAM;AAChC,IAAA,OAAA,CAAQ,OAAU,GAAA,KAAA;AAClB,IAAA,IAAA,CAAK,OAAO,CAAA,CAAE,KAAM,CAAA,MAAM,MAAS,CAAA;AAAA,GACrC,EAAG,CAAC,IAAI,CAAC,CAAA;AACT,EAAM,MAAA,QAAA,GAAW,YAAY,MAAM;AACjC,IAAA,IAAI,SAAc,IAAA,CAAA,MAAM,CAAE,CAAA,KAAA,CAAM,MAAM,MAAS,CAAA;AAAA,GAC9C,EAAA,CAAC,OAAS,EAAA,IAAI,CAAC,CAAA;AAClB,EAAM,MAAA,MAAA,GAAS,WAAY,CAAA,CAAC,OAA+B,KAAA;AACzD,IAAA,WAAA,CAAY,CAAQ,IAAA,KAAA;AAClB,MAAA,MAAM,WAAW,IAAK,CAAA,IAAA,CAAK,OAAK,CAAE,CAAA,SAAA,KAAc,QAAQ,SAAS,CAAA;AACjE,MAAA,IAAI,YAAY,QAAS,CAAA,KAAA,KAAU,OAAQ,CAAA,KAAA,IAAS,SAAS,QAAa,KAAA,OAAA,CAAQ,QAAY,IAAA,QAAA,CAAS,YAAY,OAAQ,CAAA,OAAA,IAAW,QAAS,CAAA,SAAA,KAAc,QAAQ,SAAW,EAAA;AAC9K,QAAO,OAAA,IAAA;AAAA;AAET,MAAA,OAAO,YAAa,CAAA,CAAC,OAAS,EAAA,GAAG,IAAK,CAAA,MAAA,CAAO,CAAK,CAAA,KAAA,CAAA,CAAE,SAAc,KAAA,OAAA,CAAQ,SAAS,CAAC,CAAC,CAAA;AAAA,KACtF,CAAA;AAAA,GACH,EAAG,EAAE,CAAA;AACL,EAAO,OAAA;AAAA,IACL,QAAA;AAAA,IACA,OAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACF;AACF"}
|
|
1
|
+
{"version":3,"file":"useWebBuilderGallery.js","sources":["../../../src/screens/WebBuilderNative/useWebBuilderGallery.ts"],"sourcesContent":["/**\n * Projects - the web surface's gallery hydrate, on the host, made fast.\n *\n * Same rule as the web (`realServices` gallery load): page the person's AI\n * assistant chats 10 at a time, newest first, and keep a chat only if its posts\n * hold a build. What makes it quick on a phone:\n *\n * - The last list paints at once: kept in memory across visits and on disk for a\n * cold start (per workspace).\n * - Reads go through the Apollo cache first. The app's type policies\n * (`graphql/typePolicies.ts`) keep `channelsByUser` as one merged list per\n * workspace and `messages` per channel, so a cached page is complete and\n * paints without the network.\n * - The refresh re-reads a chat's thread only when the chat changed\n * (`updatedAt`); an unchanged chat keeps the project it already gave. What each\n * chat gave (a project, or none for a plain chat) is saved with the list, so a\n * cold start re-reads only the chats that changed, not every chat again.\n * - A changed chat shows at once from its last post when that is a build; its\n * thread read then fills in the cover and the name. Thread reads run a few at a\n * time and each project appears as soon as it is known, newest first.\n * - A name, once known, is kept: a read that only yields the placeholder\n * (\"Generated Page\") never replaces it.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useApolloClient, type ApolloClient, type FetchPolicy } from '@apollo/client';\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport { GetChannelsByUserWithLastMessageDocument, MessagesDocument } from 'common/graphql';\nimport { getHistoryChannelsQueryVariables, getThreadMessagesQueryVariables } from '../../hooks/useChatApi';\nimport {\n isGenericTitle,\n lastMessageHasCover,\n projectFromPosts,\n type ChannelLike,\n} from '../../features/webbuilder/buildFragments';\nimport type { WebBuilderProject } from '../../features/webbuilder/types';\nimport { WEBBUILDER_PROJECTS_SNAPSHOT_KEY } from './webbuilderSnapshotKey';\n\n/** The web gallery's page size (`GALLERY_PAGE_SIZE`). */\nexport const GALLERY_PAGE_SIZE = 10;\n/** Keep paging (up to this many pages per load) while pages yield too few projects to fill the screen. */\nconst MIN_FILL = 8;\nconst MAX_PAGES_PER_LOAD = 4;\n/** Thread reads in flight at once: enough to be quick, few enough to keep the app responsive. */\nconst READ_CONCURRENCY = 4;\nconst SNAPSHOT_KEY = WEBBUILDER_PROJECTS_SNAPSHOT_KEY;\nconst SNAPSHOT_MAX = 40;\n/** Chats remembered with their stamp (plain chats included: each would otherwise be re-read). */\nconst KNOWN_MAX = 300;\n\ntype Loose = Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n/** What a chat last gave: its project (or none) at the `updatedAt` it was read for. */\ninterface Known {\n stamp: string;\n project: WebBuilderProject | null;\n}\n\n/** Per-workspace memory: survives leaving and reopening Web Builder in one app run. */\nconst memory = new Map<string, { projects: WebBuilderProject[]; known: Map<string, Known> }>();\n\nexport interface WebBuilderGallery {\n projects: WebBuilderProject[];\n loading: boolean;\n loadingMore: boolean;\n hasMore: boolean;\n error: string | null;\n refresh: () => void;\n loadMore: () => void;\n /** Put (or update) one site - the open one, as its posts change. */\n upsert: (project: WebBuilderProject) => void;\n}\n\nfunction sortProjects(list: Iterable<WebBuilderProject>): WebBuilderProject[] {\n return [...list].sort((a, b) => b.updatedAt - a.updatedAt);\n}\n\nfunction stampOf(channel: ChannelLike): string {\n return String(channel.updatedAt ?? channel.createdAt ?? '');\n}\n\ninterface Snapshot {\n projects: WebBuilderProject[];\n /** `[channelId, stamp, project | null]`: what each chat gave at the `updatedAt` it was read for. */\n known: Array<[string, string, WebBuilderProject | null]>;\n}\n\nasync function readSnapshot(org: string): Promise<{ projects: WebBuilderProject[]; known: Map<string, Known> }> {\n try {\n const raw = await AsyncStorage.getItem(`${SNAPSHOT_KEY}:${org}`);\n const parsed = raw ? (JSON.parse(raw) as Partial<Snapshot> | WebBuilderProject[]) : {};\n // An older snapshot is the bare projects list.\n const saved: Partial<Snapshot> = Array.isArray(parsed) ? { projects: parsed } : parsed;\n const projects = Array.isArray(saved.projects) ? saved.projects.filter((p) => p?.channelId && p.title) : [];\n const known = new Map<string, Known>();\n for (const row of Array.isArray(saved.known) ? saved.known : []) {\n if (Array.isArray(row) && typeof row[0] === 'string' && typeof row[1] === 'string') {\n known.set(row[0], { stamp: row[1], project: row[2] ?? null });\n }\n }\n return { projects, known };\n } catch {\n return { projects: [], known: new Map() };\n }\n}\n\nfunction writeSnapshot(org: string, projects: WebBuilderProject[], known: Map<string, Known>): void {\n const snapshot: Snapshot = {\n projects: projects.slice(0, SNAPSHOT_MAX),\n known: [...known].slice(-KNOWN_MAX).map(([id, k]) => [id, k.stamp, k.project]),\n };\n AsyncStorage.setItem(`${SNAPSHOT_KEY}:${org}`, JSON.stringify(snapshot)).catch(() => undefined);\n}\n\n/**\n * Every chat Web Builder has listed as a site, in any workspace: this run's\n * memory, then the snapshots on disk. Chat history opens these in Web Builder.\n */\nexport async function knownWebBuilderProjectIds(): Promise<Set<string>> {\n const ids = new Set<string>();\n const add = (projects: WebBuilderProject[], known: Map<string, Known>) => {\n for (const p of projects) ids.add(p.channelId);\n known.forEach((k, id) => {\n if (k.project) ids.add(id);\n });\n };\n memory.forEach((entry) => add(entry.projects, entry.known));\n try {\n const prefix = `${SNAPSHOT_KEY}:`;\n const keys = (await AsyncStorage.getAllKeys()).filter((key) => key.startsWith(prefix));\n for (const key of keys) {\n // eslint-disable-next-line no-await-in-loop -- a handful of workspaces at most\n const saved = await readSnapshot(key.slice(prefix.length));\n add(saved.projects, saved.known);\n }\n } catch {\n // No snapshots: memory is all there is.\n }\n return ids;\n}\n\n/** Whether a chat's posts hold a build - the gallery's own test for \"this chat is a site\". */\nexport async function channelHoldsBuild(client: ApolloClient<unknown>, channelId: string): Promise<boolean> {\n try {\n const result = await client.query({\n query: MessagesDocument,\n variables: getThreadMessagesQueryVariables(channelId),\n fetchPolicy: 'cache-first',\n errorPolicy: 'all',\n context: { cacheKey: `messages-list:${channelId}` },\n });\n const posts = ((result.data as Loose)?.messages?.data ?? []) as unknown[];\n return projectFromPosts({ id: channelId }, posts) !== null;\n } catch {\n return false;\n }\n}\n\n/** A read that only found the placeholder name keeps the name the site already had. */\nfunction keepKnownName(next: WebBuilderProject | null, prior: WebBuilderProject | null | undefined) {\n if (!next || !prior || !isGenericTitle(next.title) || isGenericTitle(prior.title)) return next;\n return { ...next, title: prior.title };\n}\n\n/** Runs `work` over `items`, at most `limit` at a time. */\nasync function eachLimited<T>(items: T[], limit: number, work: (item: T) => Promise<void>): Promise<void> {\n let next = 0;\n const lane = async (): Promise<void> => {\n while (next < items.length) {\n const item = items[next];\n next += 1;\n // eslint-disable-next-line no-await-in-loop -- one lane works through its share in order\n await work(item);\n }\n };\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, lane));\n}\n\nasync function readChannels(\n client: ApolloClient<object>,\n orgName: string,\n skip: number,\n fetchPolicy: FetchPolicy,\n): Promise<ChannelLike[]> {\n const result = await client.query({\n query: GetChannelsByUserWithLastMessageDocument,\n variables: getHistoryChannelsQueryVariables(orgName, { limit: GALLERY_PAGE_SIZE, skip }),\n fetchPolicy,\n errorPolicy: 'all',\n // Same slot as chat history: the type policy merges both into one list.\n context: { cacheKey: 'chat-history-channels-list' },\n });\n return (((result.data as Loose)?.channelsByUser ?? []) as ChannelLike[]).filter((c) => c?.id);\n}\n\nexport function useWebBuilderGallery(orgName: string, cdnOrigin: string): WebBuilderGallery {\n const client = useApolloClient();\n const remembered = orgName ? memory.get(orgName) : undefined;\n const [projects, setProjects] = useState<WebBuilderProject[]>(() => remembered?.projects ?? []);\n const [loading, setLoading] = useState(false);\n const [loadingMore, setLoadingMore] = useState(false);\n const [hasMore, setHasMore] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const skipRef = useRef(0);\n const busyRef = useRef(false);\n const runRef = useRef(0);\n const knownRef = useRef<Map<string, Known>>(remembered?.known ?? new Map());\n\n // Keep memory and the disk snapshot in step with what is shown.\n useEffect(() => {\n if (!orgName) return;\n memory.set(orgName, { projects, known: knownRef.current });\n if (projects.length) writeSnapshot(orgName, projects, knownRef.current);\n }, [orgName, projects]);\n\n // A cold start paints the last list from disk, and takes what each chat gave with it,\n // so the first load re-reads only the chats that changed since (it waits for this).\n const hydratedRef = useRef<Promise<void>>(Promise.resolve());\n useEffect(() => {\n if (!orgName || memory.get(orgName)?.projects.length) return undefined;\n let live = true;\n hydratedRef.current = readSnapshot(orgName)\n .then((saved) => {\n if (!live) return;\n saved.known.forEach((k, id) => {\n if (!knownRef.current.has(id)) knownRef.current.set(id, k);\n });\n if (saved.projects.length) setProjects((prev) => (prev.length ? prev : saved.projects));\n })\n .catch(() => undefined);\n return () => {\n live = false;\n };\n }, [orgName]);\n\n const projectFor = useCallback(\n async (channel: ChannelLike, fetchPolicy: FetchPolicy): Promise<WebBuilderProject | null> => {\n const id = channel.id ?? '';\n if (!id) return null;\n // The web skips the thread read when the last post already has the screenshot.\n // Only with a real name: the last post alone has no brief to name the site from.\n if (lastMessageHasCover(channel)) {\n const fromLast = projectFromPosts(channel, [channel.lastMessage], cdnOrigin);\n if (fromLast && !isGenericTitle(fromLast.title)) return fromLast;\n }\n const result = await client.query({\n query: MessagesDocument,\n variables: getThreadMessagesQueryVariables(id),\n fetchPolicy,\n errorPolicy: 'all',\n context: { cacheKey: `messages-list:${id}` },\n });\n const posts = ((result.data as Loose)?.messages?.data ?? []) as unknown[];\n const withLast = channel.lastMessage ? [...posts, channel.lastMessage] : posts;\n return projectFromPosts(channel, withLast, cdnOrigin);\n },\n [client, cdnOrigin],\n );\n\n const load = useCallback(\n async (mode: 'reset' | 'more') => {\n if (!orgName || busyRef.current) return;\n busyRef.current = true;\n await hydratedRef.current;\n const run = runRef.current + 1;\n runRef.current = run;\n const stale = () => runRef.current !== run;\n const known = knownRef.current;\n const seen = new Set<string>();\n const put = (project: WebBuilderProject | null, channelId: string) => {\n if (stale()) return;\n setProjects((prev) => {\n const byId = new Map(prev.map((p) => [p.channelId, p]));\n if (project) byId.set(channelId, project);\n else byId.delete(channelId);\n return sortProjects(byId.values());\n });\n };\n\n if (mode === 'reset') {\n skipRef.current = 0;\n setLoading(projects.length === 0);\n } else {\n setLoadingMore(true);\n }\n setError(null);\n\n try {\n // 1. From the cache: instant when the type policies already hold the list.\n if (mode === 'reset') {\n const cached = await readChannels(client, orgName, 0, 'cache-only').catch(() => []);\n await eachLimited(cached, READ_CONCURRENCY, async (channel) => {\n const id = channel.id ?? '';\n if (known.has(id)) return;\n const project = await projectFor(channel, 'cache-only').catch(() => null);\n if (project) {\n known.set(id, { stamp: stampOf(channel), project });\n put(project, id);\n }\n });\n if (!stale() && projects.length === 0 && known.size) setLoading(false);\n }\n\n // 2. From the network: the list, then only the threads that changed.\n let more = false;\n const tally = { found: 0 };\n for (let page = 0; page < MAX_PAGES_PER_LOAD; page += 1) {\n // eslint-disable-next-line no-await-in-loop -- pages are sequential by design\n const channels = await readChannels(client, orgName, skipRef.current, 'network-only');\n if (stale()) return;\n skipRef.current += channels.length;\n more = channels.length >= GALLERY_PAGE_SIZE;\n // eslint-disable-next-line no-await-in-loop\n await eachLimited(channels, READ_CONCURRENCY, async (channel) => {\n const id = channel.id ?? '';\n seen.add(id);\n const stamp = stampOf(channel);\n const prior = known.get(id);\n // Unchanged: keep what it gave - unless that is still the placeholder name.\n const unnamed = Boolean(prior?.project && isGenericTitle(prior.project.title));\n if (prior && prior.stamp === stamp && !unnamed) {\n if (prior.project) tally.found += 1;\n return;\n }\n // Show it now from its last post when that is a build; the read fills in the rest.\n const quick = channel.lastMessage\n ? keepKnownName(projectFromPosts(channel, [channel.lastMessage], cdnOrigin), prior?.project)\n : null;\n if (quick) put(quick, id);\n const read = await projectFor(channel, 'network-only').catch(() => prior?.project ?? null);\n const project = keepKnownName(read, prior?.project ?? quick);\n known.set(id, { stamp, project });\n if (project) tally.found += 1;\n put(project, id);\n });\n if (!more || tally.found >= MIN_FILL) break;\n }\n if (stale()) return;\n if (mode === 'reset') {\n // A chat no longer in the first pages (deleted, moved) drops off the list.\n setProjects((prev) =>\n prev.filter((p) => seen.has(p.channelId) || p.updatedAt > Date.now() - 60_000),\n );\n }\n setHasMore(more);\n } catch (err) {\n console.warn('[WebBuilderNative] could not load projects:', err);\n if (!stale()) setError('Check your connection and try again.');\n } finally {\n busyRef.current = false;\n if (!stale()) {\n setLoading(false);\n setLoadingMore(false);\n }\n }\n },\n // `projects.length` only steers the first spinner; reading it stale is harmless.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [client, orgName, projectFor],\n );\n\n useEffect(() => {\n load('reset').catch(() => undefined);\n }, [load]);\n\n const refresh = useCallback(() => {\n busyRef.current = false;\n load('reset').catch(() => undefined);\n }, [load]);\n const loadMore = useCallback(() => {\n if (hasMore) load('more').catch(() => undefined);\n }, [hasMore, load]);\n\n const upsert = useCallback((project: WebBuilderProject) => {\n setProjects((prev) => {\n const existing = prev.find((p) => p.channelId === project.channelId);\n if (\n existing &&\n existing.title === project.title &&\n existing.coverUrl === project.coverUrl &&\n existing.liveUrl === project.liveUrl &&\n existing.updatedAt === project.updatedAt\n ) {\n return prev;\n }\n return sortProjects([project, ...prev.filter((p) => p.channelId !== project.channelId)]);\n });\n }, []);\n\n return { projects, loading, loadingMore, hasMore, error, refresh, loadMore, upsert };\n}\n"],"names":["_a"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {useRef,useState,useMemo,useEffect,useCallback}from'react';import {useAiCodeDeployToCloudflareMutation}from'common/graphql';import {v4}from'uuid';import {useCdecliConnection}from'../../contexts/CdecliConnectionContext.js';import {useChatStream}from'../../hooks/useChatStream.js';import {useHostChatChannel}from'../../hooks/useHostChatChannel.js';import {config}from'../../config/env-config.js';import {useChatMessages}from'../../hooks/useChatApi.js';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';import {useCanvasSession}from'../../features/canvas/useCanvasSession.js';import {tokenClaims}from'../../features/canvas/sessionIdentity.js';import {buildsFromPosts,hasWorkflowPosts,projectFromPosts,turnState,pendingWork,transcriptFromPosts,stripAgentNote,displayAgentText}from'../../features/webbuilder/buildFragments.js';import {WEBBUILDER_CHAT_SKILL,buildTriggerParams,templateRemixNote,newObjectId}from'../../features/webbuilder/workflow.js';import {useWebBuilderGallery}from'./useWebBuilderGallery.js';import {agentEditNote,agentPublishMessage}from'../../features/webbuilder/webbuilderPrompts.js';import {useCodeAssistantCatalog}from'./useCodeAssistantCatalog.js';import {uploadAttachment,triggerBuild,createSandboxRouter,directSandboxRun,restoreSandbox}from'./webbuilderTransport.js';import {useSandboxProxyApi}from'./sandboxProxyApi.js';import {useSandboxKeepAlive}from'./useSandboxKeepAlive.js';import {pendingAskUser}from'../../features/chat/askUser.js';import {useRunningBuilds,markBuildDone}from'./runningBuilds.js';import {undoLastChange,redoChange}from'./versionUndo.js';import {WEBBUILDER_EXPORT_ZIP_ACTION,exportZipParams,exportZipUrl}from'../../features/webbuilder/exportCode.js';import {useRestoredSandboxes,applyRestored}from'./useRestoredSandboxes.js';import {useWebBuilderJobs}from'./useWebBuilderJobs.js';var __defProp = Object.defineProperty;
|
|
1
|
+
import {useRef,useState,useMemo,useEffect,useCallback}from'react';import {useAiCodeDeployToCloudflareMutation}from'common/graphql';import {v4}from'uuid';import {useCdecliConnection}from'../../contexts/CdecliConnectionContext.js';import {useChatStream}from'../../hooks/useChatStream.js';import {useHostChatChannel}from'../../hooks/useHostChatChannel.js';import {config}from'../../config/env-config.js';import {useChatMessages}from'../../hooks/useChatApi.js';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';import {useCanvasSession}from'../../features/canvas/useCanvasSession.js';import {tokenClaims}from'../../features/canvas/sessionIdentity.js';import {buildsFromPosts,hasWorkflowPosts,projectFromPosts,turnState,pendingWork,transcriptFromPosts,stripAgentNote,displayAgentText}from'../../features/webbuilder/buildFragments.js';import {WEBBUILDER_CHAT_SKILL,buildTriggerParams,templateRemixNote,newObjectId}from'../../features/webbuilder/workflow.js';import {useWebBuilderGallery}from'./useWebBuilderGallery.js';import {agentEditNote,agentPublishMessage}from'../../features/webbuilder/webbuilderPrompts.js';import {useCodeAssistantCatalog}from'./useCodeAssistantCatalog.js';import {uploadAttachment,triggerBuild,createSandboxRouter,directSandboxRun,restoreSandbox}from'./webbuilderTransport.js';import {useSandboxProxyApi}from'./sandboxProxyApi.js';import {useSandboxKeepAlive}from'./useSandboxKeepAlive.js';import {pendingAskUser}from'../../features/chat/askUser.js';import {runningBuild,useRunningBuilds,markBuildDone}from'./runningBuilds.js';import {isAgentSite}from'./siteLane.js';import {undoLastChange,redoChange}from'./versionUndo.js';import {WEBBUILDER_EXPORT_ZIP_ACTION,exportZipParams,exportZipUrl}from'../../features/webbuilder/exportCode.js';import {useRestoredSandboxes,applyRestored}from'./useRestoredSandboxes.js';import {useWebBuilderJobs}from'./useWebBuilderJobs.js';var __defProp = Object.defineProperty;
|
|
2
2
|
var __defProps = Object.defineProperties;
|
|
3
3
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
@@ -29,7 +29,7 @@ function failureText(error) {
|
|
|
29
29
|
return "The build didn't start. Try again.";
|
|
30
30
|
}
|
|
31
31
|
function useWebBuilderHost(routeOrg) {
|
|
32
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
32
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
33
33
|
const {
|
|
34
34
|
orgName,
|
|
35
35
|
projectId: appProjectId
|
|
@@ -67,6 +67,7 @@ function useWebBuilderHost(routeOrg) {
|
|
|
67
67
|
setActiveChannelId: setCdecliChannel
|
|
68
68
|
} = cdecli;
|
|
69
69
|
const [agentChannelId, setAgentChannelId] = useState(() => v4());
|
|
70
|
+
const pendingAskRef = useRef(null);
|
|
70
71
|
const agentChannels = useRef(/* @__PURE__ */ new Set());
|
|
71
72
|
const unsavedAgentChannels = useRef(/* @__PURE__ */ new Set());
|
|
72
73
|
const pendingAgentTurn = useRef(null);
|
|
@@ -93,7 +94,25 @@ function useWebBuilderHost(routeOrg) {
|
|
|
93
94
|
};
|
|
94
95
|
}, [cdecli.channelConnected, cdecli.accountId, cdecli.persistenceMode, cdecli.recoverAgentAuth]);
|
|
95
96
|
const chat = useChatStream(agentChannelId, chatRouting);
|
|
96
|
-
const
|
|
97
|
+
const streamOnSite = activeChannelId !== null && agentChannelId === activeChannelId;
|
|
98
|
+
const workflowPosts = hasWorkflowPosts(posts);
|
|
99
|
+
const agentLane = activeChannelId !== null && isAgentSite({
|
|
100
|
+
rememberedAgent: agentChannels.current.has(activeChannelId),
|
|
101
|
+
runLane: (_b = runningBuild(activeChannelId)) == null ? void 0 : _b.lane,
|
|
102
|
+
postCount: posts.length,
|
|
103
|
+
workflowPosts,
|
|
104
|
+
streamMessages: streamOnSite ? chat.messages.length : 0
|
|
105
|
+
});
|
|
106
|
+
if (__DEV__ && activeChannelId) {
|
|
107
|
+
console.log("[WebBuilderNative] lane", {
|
|
108
|
+
channel: activeChannelId,
|
|
109
|
+
agentLane,
|
|
110
|
+
posts: posts.length,
|
|
111
|
+
workflowPosts,
|
|
112
|
+
streamMessages: streamOnSite ? chat.messages.length : null,
|
|
113
|
+
streaming: chat.isLoading || chat.isStreaming
|
|
114
|
+
});
|
|
115
|
+
}
|
|
97
116
|
const agentBusy = agentLane && (chat.isLoading || chat.isStreaming);
|
|
98
117
|
const jobs = useWebBuilderJobs(effectiveOrg);
|
|
99
118
|
const agentJob = useRef(null);
|
|
@@ -206,7 +225,7 @@ function useWebBuilderHost(routeOrg) {
|
|
|
206
225
|
}, [turn, state, postBuilds, jobs]);
|
|
207
226
|
const heardRef = useRef(null);
|
|
208
227
|
if (turn) {
|
|
209
|
-
const prev = ((
|
|
228
|
+
const prev = ((_c = heardRef.current) == null ? void 0 : _c.startedAt) === turn.startedAt ? heardRef.current : null;
|
|
210
229
|
heardRef.current = {
|
|
211
230
|
startedAt: turn.startedAt,
|
|
212
231
|
watching: state !== null,
|
|
@@ -371,10 +390,10 @@ ${templateRemixNote(request.template)}` : request.text,
|
|
|
371
390
|
const closeProject = useCallback(() => setActiveChannelId(null), []);
|
|
372
391
|
const work = useMemo(() => pendingWork(posts), [posts]);
|
|
373
392
|
const running = Boolean(turn && turn.channelId === activeChannelId);
|
|
374
|
-
const startedAt = (
|
|
375
|
-
const progress = (
|
|
393
|
+
const startedAt = (_d = turn == null ? void 0 : turn.startedAt) != null ? _d : 0;
|
|
394
|
+
const progress = (_e = state == null ? void 0 : state.progress) != null ? _e : null;
|
|
376
395
|
const runningBuilds = useRunningBuilds();
|
|
377
|
-
const openRun = (
|
|
396
|
+
const openRun = (_f = runningBuilds.find((r) => r.channelId === activeChannelId)) != null ? _f : null;
|
|
378
397
|
const openRunState = useMemo(() => openRun && posts.length ? turnState(posts, openRun.startedAt) : null, [openRun, posts]);
|
|
379
398
|
const watchingLive = agentBusy || running;
|
|
380
399
|
useEffect(() => {
|
|
@@ -406,7 +425,24 @@ ${templateRemixNote(request.template)}` : request.text,
|
|
|
406
425
|
}
|
|
407
426
|
return rows.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
408
427
|
}, [projects, runningBuilds, effectiveOrg]);
|
|
428
|
+
const pendingAsk = useMemo(() => {
|
|
429
|
+
var _a2;
|
|
430
|
+
return pendingAskUser([...streamOnSite && chat.messages.length ? chat.messages : transcriptFromPosts(posts).map((m) => ({
|
|
431
|
+
role: m.role,
|
|
432
|
+
content: m.content
|
|
433
|
+
})), ...streamOnSite && ((_a2 = chat.response) == null ? void 0 : _a2.trim()) ? [{
|
|
434
|
+
role: "assistant",
|
|
435
|
+
content: chat.response
|
|
436
|
+
}] : []]);
|
|
437
|
+
}, [streamOnSite, chat.messages, chat.response, posts]);
|
|
438
|
+
pendingAskRef.current = pendingAsk;
|
|
409
439
|
const building = useMemo(() => {
|
|
440
|
+
if (agentBusy && pendingAsk) {
|
|
441
|
+
return {
|
|
442
|
+
statusText: "Waiting for your answer\u2026",
|
|
443
|
+
startedAt: startedAt || Date.now()
|
|
444
|
+
};
|
|
445
|
+
}
|
|
410
446
|
if (agentBusy) return {
|
|
411
447
|
statusText: "Building with the agent\u2026",
|
|
412
448
|
startedAt: startedAt || Date.now()
|
|
@@ -425,7 +461,7 @@ ${templateRemixNote(request.template)}` : request.text,
|
|
|
425
461
|
statusText: progress || fallback,
|
|
426
462
|
startedAt: startedAt || Date.now()
|
|
427
463
|
};
|
|
428
|
-
}, [agentBusy, running, work, turn == null ? void 0 : turn.mode, progress, startedAt, openRun, openRunState, openRunPending]);
|
|
464
|
+
}, [agentBusy, pendingAsk, running, work, turn == null ? void 0 : turn.mode, progress, startedAt, openRun, openRunState, openRunPending]);
|
|
429
465
|
const messages = useMemo(() => {
|
|
430
466
|
const rows = transcriptFromPosts(posts).map((m) => ({
|
|
431
467
|
id: m.id,
|
|
@@ -446,6 +482,13 @@ ${templateRemixNote(request.template)}` : request.text,
|
|
|
446
482
|
var _a2, _b2, _c2;
|
|
447
483
|
const channelId = activeChannelId;
|
|
448
484
|
if (!channelId) return;
|
|
485
|
+
if (pendingAskRef.current) {
|
|
486
|
+
pendingAskRef.current = null;
|
|
487
|
+
chat.sendMessage(text, attachments, agentChannelId || channelId, false, void 0, {
|
|
488
|
+
answersAsk: true
|
|
489
|
+
}).catch(() => void 0);
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
449
492
|
const workflowReady = Boolean((_a2 = catalog.defaults) == null ? void 0 : _a2.formExtensionId);
|
|
450
493
|
if (agentLane || !workflowReady) {
|
|
451
494
|
const note = target ? `
|
|
@@ -481,7 +524,7 @@ ${agentEditNote(target)}` : "";
|
|
|
481
524
|
edit: target != null ? target : null,
|
|
482
525
|
attachments
|
|
483
526
|
}).catch(() => void 0);
|
|
484
|
-
}, [activeChannelId, agentLane, agentChannelId, catalog.defaults, builds, activeProject == null ? void 0 : activeProject.title, runTurn, sendAgentTurn]);
|
|
527
|
+
}, [activeChannelId, agentLane, agentChannelId, catalog.defaults, builds, activeProject == null ? void 0 : activeProject.title, runTurn, sendAgentTurn, chat]);
|
|
485
528
|
const agentMessages = useMemo(() => chat.messages.map((m, index) => ({
|
|
486
529
|
id: `${m.role}-${index}`,
|
|
487
530
|
role: m.role,
|
|
@@ -504,10 +547,6 @@ ${agentEditNote(target)}` : "";
|
|
|
504
547
|
}];
|
|
505
548
|
}, [openRunPending, openRun]);
|
|
506
549
|
const openRunStreaming = openRunPending ? (openRunState == null ? void 0 : openRunState.progress) || "Building your site\u2026" : null;
|
|
507
|
-
const pendingAsk = useMemo(() => pendingAskUser(agentLane && chat.messages.length ? chat.messages : transcriptFromPosts(posts).map((m) => ({
|
|
508
|
-
role: m.role,
|
|
509
|
-
content: m.content
|
|
510
|
-
}))), [agentLane, chat.messages, posts]);
|
|
511
550
|
const hostChat = useMemo(() => agentLane ? {
|
|
512
551
|
messages: withOpenRun(agentMessages.length ? agentMessages : messages),
|
|
513
552
|
streaming: chat.response ? displayAgentText(chat.response) : openRunStreaming,
|
|
@@ -537,8 +576,8 @@ ${agentEditNote(target)}` : "";
|
|
|
537
576
|
}), [activeChannelId, token, indexUrl, sandboxApi]);
|
|
538
577
|
const keepAlive = useSandboxKeepAlive({
|
|
539
578
|
run: token || activeChannelId ? sandboxCall : null,
|
|
540
|
-
sandboxId: (
|
|
541
|
-
live: activeChannelId !== null && Boolean((
|
|
579
|
+
sandboxId: (_g = builds[0]) == null ? void 0 : _g.sandboxId,
|
|
580
|
+
live: activeChannelId !== null && Boolean((_h = builds[0]) == null ? void 0 : _h.sandboxId)
|
|
542
581
|
});
|
|
543
582
|
const {
|
|
544
583
|
noteActivity
|