@messenger-box/tailwind-ui-inbox 10.0.3-alpha.144 → 10.0.3-alpha.158

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 (66) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/lib/components/AIAgent/AIAgent.d.ts.map +1 -1
  3. package/lib/components/AIAgent/AIAgent.js +1 -55
  4. package/lib/components/AIAgent/AIAgent.js.map +1 -1
  5. package/lib/components/InboxMessage/message-widgets/ErrorFixCard.d.ts +1 -2
  6. package/lib/components/InboxMessage/message-widgets/ErrorFixCard.d.ts.map +1 -1
  7. package/lib/components/InboxMessage/message-widgets/ErrorFixCard.js.map +1 -1
  8. package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.d.ts +2 -2
  9. package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.d.ts.map +1 -1
  10. package/lib/components/ModelConfigPanel.d.ts +11 -0
  11. package/lib/components/ModelConfigPanel.d.ts.map +1 -1
  12. package/lib/components/ModelConfigPanel.js +29 -2
  13. package/lib/components/ModelConfigPanel.js.map +1 -1
  14. package/lib/components/filler-components/RightSiderBar.d.ts +1 -28
  15. package/lib/components/filler-components/RightSiderBar.d.ts.map +1 -1
  16. package/lib/components/filler-components/RightSiderBar.js +531 -458
  17. package/lib/components/filler-components/RightSiderBar.js.map +1 -1
  18. package/lib/container/Inbox.js +1 -1
  19. package/lib/container/Inbox.js.map +1 -1
  20. package/lib/container/ServiceInbox.js +1 -1
  21. package/lib/container/ServiceInbox.js.map +1 -1
  22. package/lib/container/TestInboxWithAiLoader.d.ts.map +1 -1
  23. package/lib/container/TestInboxWithAiLoader.js +1 -11
  24. package/lib/container/TestInboxWithAiLoader.js.map +1 -1
  25. package/lib/container/ThreadMessages.js +1 -1
  26. package/lib/container/ThreadMessages.js.map +1 -1
  27. package/lib/container/ThreadMessagesInbox.js +1 -1
  28. package/lib/container/ThreadMessagesInbox.js.map +1 -1
  29. package/lib/container/Threads.js +1 -1
  30. package/lib/container/Threads.js.map +1 -1
  31. package/lib/hooks/index.d.ts +0 -1
  32. package/lib/hooks/index.d.ts.map +1 -1
  33. package/lib/hooks/usePersistentModelConfig.d.ts +1 -0
  34. package/lib/hooks/usePersistentModelConfig.d.ts.map +1 -1
  35. package/lib/hooks/usePersistentModelConfig.js +1 -0
  36. package/lib/hooks/usePersistentModelConfig.js.map +1 -1
  37. package/lib/index.js +1 -1
  38. package/lib/module.js +1 -1
  39. package/lib/module.js.map +1 -1
  40. package/lib/templates/InboxWithAi.d.ts.map +1 -1
  41. package/lib/templates/InboxWithAi.js +2 -15
  42. package/lib/templates/InboxWithAi.js.map +1 -1
  43. package/lib/templates/InboxWithAi.tsx +2 -24
  44. package/package.json +4 -4
  45. package/src/components/AIAgent/AIAgent.tsx +3 -54
  46. package/src/components/InboxMessage/message-widgets/ErrorFixCard.tsx +1 -2
  47. package/src/components/InboxMessage/message-widgets/ModernMessageGroup.tsx +2 -2
  48. package/src/components/ModelConfigPanel.tsx +59 -0
  49. package/src/components/filler-components/RightSiderBar.tsx +570 -566
  50. package/src/container/TestInboxWithAiLoader.tsx +0 -8
  51. package/src/hooks/index.ts +0 -1
  52. package/src/hooks/usePersistentModelConfig.ts +2 -0
  53. package/src/templates/InboxWithAi.tsx +2 -24
  54. package/lib/components/live-code-editor/hybrid-live-editor.js +0 -68
  55. package/lib/components/live-code-editor/hybrid-live-editor.js.map +0 -1
  56. package/lib/components/live-code-editor/live-code-editor.js +0 -207
  57. package/lib/components/live-code-editor/live-code-editor.js.map +0 -1
  58. package/lib/hooks/use-file-sync.d.ts +0 -16
  59. package/lib/hooks/use-file-sync.d.ts.map +0 -1
  60. package/lib/hooks/use-file-sync.js +0 -63
  61. package/lib/hooks/use-file-sync.js.map +0 -1
  62. package/lib/utils/utils.js +0 -3
  63. package/lib/utils/utils.js.map +0 -1
  64. package/lib/xstate/rightSidebar.machine.js +0 -325
  65. package/lib/xstate/rightSidebar.machine.js.map +0 -1
  66. package/src/hooks/use-file-sync.ts +0 -91
@@ -1,459 +1,532 @@
1
- import*as React from'react';import {HybridLiveEditor}from'../live-code-editor/hybrid-live-editor.js';import {useOnChatMessageAddedSubscription}from'common/graphql';import {PostTypeEnum,RoomType}from'common';import {useMachine}from'@xstate/react';import {fromPromise}from'xstate';import {rightSidebarMachine}from'../../xstate/rightSidebar.machine.js';const RightSidebarFillComponent = props => {
2
- const {
3
- channelId,
4
- detailSidebarOptions,
5
- windowWidth,
6
- windowHeight,
7
- activeTab,
8
- messages,
9
- selectedPost,
10
- setIsLoading,
11
- isLoading,
12
- handleSendMessage,
13
- handleRecreateSandbox,
14
- isMinimized,
15
- isCreatingSandbox,
16
- setIsCreatingSandbox
17
- } = props;
18
- const hybridLiveEditorRef = React.useRef(null);
19
- const previewIframeRef = React.useRef(null);
20
- const previewIframeContainerRef = React.useRef(null);
21
- // State for subscription data
22
- const [subscriptionData, setSubscriptionData] = React.useState(null);
23
- // XState machine for sidebar state
24
- const [state, send] = useMachine(rightSidebarMachine.provide({
25
- actors: {
26
- recreateSandbox: fromPromise(async ({
27
- input
28
- }) => {
29
- const {
30
- id
31
- } = input;
32
- if (handleRecreateSandbox) {
33
- await handleRecreateSandbox(id);
34
- }
35
- return {
36
- success: true
37
- };
38
- })
39
- }
40
- }), {
41
- input: {
42
- channelId: channelId || '',
43
- isMinimized: !!isMinimized,
44
- windowWidth,
45
- windowHeight,
46
- isLoading: !!isLoading,
47
- activeFragment: null,
48
- currentFiles: {},
49
- canvasLayers: [],
50
- previewStatus: null
51
- }
52
- });
53
- const activeFragment = state.context.activeFragment;
54
- const currentFiles = state.context.currentFiles;
55
- state.context.canvasLayers;
56
- const previewStatus = state.context.previewStatus;
57
- // const [isLoading, setIsLoading] = React.useState(false);
58
- const {
59
- data: chatMessageAddedData
60
- } = useOnChatMessageAddedSubscription({
61
- variables: {
62
- channelId: channelId?.toString() || ''
63
- },
64
- skip: !channelId
65
- });
66
- // Component mount tracking
67
- React.useMemo(() => `right-sidebar-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, []);
68
- const handleCopyToClipboard = React.useCallback(text => {
69
- navigator.clipboard.writeText(text);
70
- }, []);
71
- const handleFileUpdate = React.useCallback(async (filePath, content) => {
72
- // TODO: Implement file update logic for the channel
73
- console.log('File update:', {
74
- filePath,
75
- content
76
- });
77
- }, []);
78
- // Create complete file context by merging currentFiles with activeFragment files
79
- const completeFileContext = React.useMemo(() => {
80
- if (!activeFragment?.files) {
81
- console.log('📂 Using currentFiles as complete context (no activeFragment.files)');
82
- return currentFiles;
83
- }
84
- // Merge currentFiles with activeFragment files, giving priority to activeFragment files
85
- const merged = {
86
- ...currentFiles
87
- };
88
- // Override with activeFragment files (these are the most recent changes)
89
- Object.entries(activeFragment.files).forEach(([path, content]) => {
90
- merged[path] = content;
91
- });
92
- // Validate file context integrity
93
- const hasPackageJson = 'package.json' in merged;
94
- const hasMainFiles = Object.keys(merged).some(path => path.includes('index.') || path.includes('main.') || path.includes('App.') || path.includes('src/'));
95
- console.log('📂 Complete file context created:', {
96
- currentFilesCount: Object.keys(currentFiles).length,
97
- activeFragmentFilesCount: Object.keys(activeFragment.files).length,
98
- mergedFilesCount: Object.keys(merged).length,
99
- hasPackageJson,
100
- hasMainFiles,
101
- activeFragmentFiles: Object.keys(activeFragment.files),
102
- allFiles: Object.keys(merged),
103
- validation: {
104
- isComplete: hasPackageJson && hasMainFiles,
105
- missingPackageJson: !hasPackageJson,
106
- missingMainFiles: !hasMainFiles
107
- }
108
- });
109
- if (!hasPackageJson) {
110
- console.warn('⚠️ File context missing package.json - this may cause issues in sandbox');
111
- }
112
- if (!hasMainFiles) {
113
- console.warn('⚠️ File context missing main application files - this may cause issues in sandbox');
114
- }
115
- return merged;
116
- }, [currentFiles, activeFragment?.files]);
117
- // Determine if we should show preview or editor based on activeTab
118
- const isPreviewMode = activeTab === 'preview';
119
- // Turn on loader when new data is about to be processed
120
- React.useEffect(() => {
121
- if (chatMessageAddedData?.chatMessageAdded || selectedPost) ;
122
- }, [chatMessageAddedData, selectedPost, send, setIsLoading]);
123
- // Handle subscription data updates - prefer response update structure like use-ai-messages.ts
124
- React.useEffect(() => {
125
- if (chatMessageAddedData?.chatMessageAdded || selectedPost) {
126
- // Prefer explicitly selected post to ensure UI updates when it changes
127
- const message = selectedPost || chatMessageAddedData?.chatMessageAdded;
128
- // Extract strictly from message.propsConfiguration (fragment only)
129
- let extracted = null;
130
- let fragmentSource = null;
131
- try {
132
- // 1) Preferred: contents.props.fragment
133
- const cfg = message.propsConfiguration || {};
134
- const contents = cfg.contents || cfg.content || {};
135
- if (contents?.props?.fragment) {
136
- const frag = contents.props.fragment;
137
- extracted = {
138
- sandboxUrl: frag.sandboxUrl || frag.url,
139
- sandboxId: frag.sandboxId,
140
- projectId: cfg.projectId || contents.projectId || frag.projectId,
141
- modelConfig: cfg.modelConfig || contents.modelConfig || frag.modelConfig,
142
- files: frag.files || {},
143
- canvasLayers: contents.canvasLayers || cfg.canvasLayers || frag.canvasLayers,
144
- summary: contents.summary || cfg.summary || frag.summary,
145
- title: frag.title || contents.title || cfg.title,
146
- isError: frag.isError
147
- };
148
- fragmentSource = 'propsConfiguration.contents.props.fragment';
149
- }
150
- // 2) Fallback: contents.fragment
151
- if (!extracted && contents?.fragment) {
152
- const frag = contents.fragment;
153
- extracted = {
154
- sandboxUrl: frag.sandboxUrl || frag.url,
155
- sandboxId: frag.sandboxId,
156
- projectId: cfg.projectId || contents.projectId || frag.projectId,
157
- modelConfig: cfg.modelConfig || contents.modelConfig || frag.modelConfig,
158
- files: frag.files || {},
159
- canvasLayers: contents.canvasLayers || cfg.canvasLayers || frag.canvasLayers,
160
- summary: contents.summary || cfg.summary || frag.summary,
161
- title: frag.title || contents.title || cfg.title,
162
- isError: frag.isError
163
- };
164
- fragmentSource = 'propsConfiguration.contents.fragment';
165
- }
166
- // 3) Fallback: propsConfiguration.fragment (top-level)
167
- if (!extracted && cfg?.fragment) {
168
- const frag = cfg.fragment;
169
- extracted = {
170
- sandboxUrl: frag.sandboxUrl || frag.url,
171
- sandboxId: frag.sandboxId,
172
- projectId: cfg.projectId || frag.projectId,
173
- modelConfig: cfg.modelConfig || frag.modelConfig,
174
- files: frag.files || {},
175
- canvasLayers: cfg.canvasLayers || frag.canvasLayers,
176
- summary: cfg.summary || frag.summary,
177
- title: frag.title || cfg.title,
178
- isError: frag.isError
179
- };
180
- fragmentSource = 'propsConfiguration.fragment';
181
- }
182
- } catch (error) {
183
- console.error('Error extracting response from message:', error);
184
- }
185
- // console.log('Extracted response fragment source:', fragmentSource);
186
- // console.log('Extracted response:', extracted);
187
- if (extracted && (extracted.sandboxUrl || extracted.url)) {
188
- console.log('✅ Processing response update:', extracted);
189
- // Update subscription data snapshot
190
- setSubscriptionData(extracted);
191
- // Build active fragment
192
- const fragment = {
193
- id: message.id,
194
- sandboxUrl: extracted.sandboxUrl || extracted.url,
195
- sandboxId: extracted.sandboxId,
196
- title: extracted.title || 'Generated Code',
197
- files: extracted.files || {},
198
- projectId: extracted.projectId,
199
- modelConfig: extracted.modelConfig,
200
- canvasLayers: extracted.canvasLayers,
201
- summary: extracted.summary,
202
- isError: extracted.isError
203
- };
204
- // If canvasLayers missing but present in summary, attempt to extract like use-ai-messages
205
- if ((!fragment.canvasLayers || !Array.isArray(fragment.canvasLayers)) && fragment.summary) {
206
- try {
207
- const match = fragment.summary.match(/<canvas_layers>([\s\S]*?)<\/canvas_layers>/);
208
- if (match) {
209
- const parsed = JSON.parse(match[1]);
210
- if (Array.isArray(parsed)) {
211
- fragment.canvasLayers = parsed;
212
- }
213
- }
214
- } catch (e) {
215
- console.warn('Failed to parse canvas layers from summary:', e);
216
- }
217
- }
218
- console.log('✅ Setting active fragment via XState:', fragment);
219
- send({
220
- type: 'SET_FRAGMENT',
221
- fragment
222
- });
223
- // setIsLoading?.(false);
224
- //send({ type: 'SET_LOADING', isLoading: false });
225
- } else {
226
- console.log('❌ No valid response found in message');
227
- // setIsLoading?.(false);
228
- // send({ type: 'SET_LOADING', isLoading: false });
229
- }
230
- }
231
- }, [chatMessageAddedData, selectedPost, send, setIsLoading]);
232
- // When switching tabs or when sandbox changes, show loader until ready
233
- // React.useEffect(() => {
234
- // if (isPreviewMode) {
235
- // if (activeFragment?.sandboxUrl) {
236
- // // setIsLoading(true);
237
- // }
238
- // } else {
239
- // // In code view, briefly show loader while editor reacts to new files
240
- // // setIsLoading(true);
241
- // const timeoutId = setTimeout(() => setIsLoading(false), 400);
242
- // return () => clearTimeout(timeoutId);
243
- // }
244
- // }, [isPreviewMode, activeFragment?.sandboxUrl, completeFileContext]);
245
- // Cleanup iframe resources on unmount to prevent renderer leaks in Chrome
246
- React.useEffect(() => {
247
- return () => {
248
- try {
249
- if (previewIframeRef.current) {
250
- previewIframeRef.current.src = 'about:blank';
251
- }
252
- } catch (e) {
253
- // no-op
254
- }
255
- };
256
- }, []);
257
- React.useEffect(() => {
258
- const handleVisualEditorMessage = event => {
259
- // Handle AI changes
260
- if (event.data.type === 'VISUAL_EDITOR_CHANGES') {
261
- console.log('visual_editor_changes....', event.data.message);
262
- if (handleSendMessage && event.data.message) {
263
- // Call aiHandleSend directly - this is the handleSend function from AIAgent
264
- handleSendMessage({
265
- channelId,
266
- type: RoomType.Aiassistant,
267
- postData: {
268
- // postId: postId,
269
- type: PostTypeEnum.Aiassistant,
270
- content: event.data.message
271
- }
272
- });
273
- } else {
274
- console.warn('⚠️ handleSendMessage not available or no message provided');
275
- }
276
- }
277
- };
278
- window.addEventListener('message', handleVisualEditorMessage);
279
- return () => window.removeEventListener('message', handleVisualEditorMessage);
280
- }, [handleSendMessage, channelId]);
281
- React.useCallback(async id => {
282
- if (id) {
283
- console.log('recreate sandbox id....', id);
284
- setIsLoading?.(true);
285
- send({
286
- type: 'SET_LOADING',
287
- isLoading: true
288
- });
289
- try {
290
- send({
291
- type: 'RECREATE_SANDBOX',
292
- id
293
- });
294
- } catch (e) {
295
- console.error('Error recreating sandbox:', e);
296
- setIsLoading?.(false);
297
- send({
298
- type: 'SET_LOADING',
299
- isLoading: false
300
- });
301
- }
302
- }
303
- }, [send, setIsLoading]);
304
- // Track if we've already attempted recreate for a given sandbox URL
305
- React.useRef({});
306
- // Probe sandbox URL via XState actor
307
- React.useEffect(() => {
308
- const url = activeFragment?.sandboxUrl;
309
- if (url) {
310
- send({
311
- type: 'PROBE',
312
- url,
313
- fragmentId: activeFragment?.id
314
- });
315
- }
316
- }, [activeFragment?.sandboxUrl, activeFragment?.id, send]);
317
- // Prefer using external loading when provided; otherwise fall back to machine state
318
- const derivedIsLoading = typeof isLoading === 'boolean' ? isLoading : state.context.isLoading;
319
- // Sync external loading prop with machine's loading state (no-op if setter not provided)
320
- // React.useEffect(() => {
321
- // console.log(
322
- // 'isLoading....',
323
- // isLoading,
324
- // ' state.context.isLoading',
325
- // state.context.isLoading,
326
- // ' previewStatus',
327
- // previewStatus,
328
- // );
329
- // if (!state.context.isLoading) {
330
- // setIsLoading?.(!!state.context.isLoading);
331
- // }
332
- // }, [state.context.isLoading, setIsLoading, isLoading]);
333
- return React.createElement("div", {
334
- ref: previewIframeContainerRef,
335
- className: "right-sidebar-content h-full flex flex-col"
336
- }, React.createElement("div", {
337
- className: "flex-1 overflow-hidden",
338
- style: {
339
- minHeight: windowHeight - 140
340
- }
341
- }, isPreviewMode ?
342
- // Preview Mode - Show sandbox iframe or fallback
343
- (() => {
344
- if (activeFragment?.sandboxUrl) {
345
- return React.createElement("div", {
346
- className: "w-full h-full relative",
347
- style: {
348
- width: isMinimized ? windowWidth * 0.8 + 'px' : '100%',
349
- height: windowHeight - 140,
350
- backgroundColor: '#f0f0f0'
351
- }
352
- }, !previewStatus ? React.createElement("iframe", {
353
- key: activeFragment.sandboxUrl,
354
- ref: previewIframeRef,
355
- src: activeFragment.sandboxUrl,
356
- className: "w-full w-fit h-full h-fit border border-gray-200 rounded-md bg-white shadow-sm",
357
- title: "Live Preview",
358
- sandbox: "allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-orientation-lock allow-pointer-lock allow-presentation allow-storage-access-by-user-activation allow-top-navigation-by-user-activation",
359
- loading: "lazy",
360
- onLoad: () => {
361
- console.log('🎯 Iframe loaded successfully');
362
- setIsLoading?.(false);
363
- setIsCreatingSandbox?.(false);
364
- send({
365
- type: 'SET_LOADING',
366
- isLoading: false
367
- });
368
- },
369
- onError: e => {
370
- console.error('❌ Iframe error:', e);
371
- setIsLoading?.(false);
372
- send({
373
- type: 'SET_LOADING',
374
- isLoading: false
375
- });
376
- },
377
- style: {
378
- // maxHeight: windowHeight - 140,
379
- // width: isMinimized ? windowWidth * 0.82 + 'px' : '100%',
380
- //padding: isMinimized ? '10px' : '0px',
381
- }
382
- }) : React.createElement("div", {
383
- className: "absolute inset-0 bg-white/60 flex items-center justify-center z-20"
384
- }, handleRecreateSandbox && React.createElement(React.Fragment, null, derivedIsLoading || isCreatingSandbox ? React.createElement("div", {
385
- className: "flex flex-col items-center justify-center gap-2"
386
- }, React.createElement("div", {
387
- className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"
388
- }), React.createElement("p", {
389
- className: "text-xs text-blue-700"
390
- }, "Recreating...")) : React.createElement("div", {
391
- className: "flex flex-col items-center justify-center gap-2"
392
- }, React.createElement("div", {
393
- className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"
394
- }), React.createElement("p", {
395
- className: "text-sm text-muted-foreground"
396
- }, isLoading ? 'Recreating...' : 'Refresh', ' ')))), React.createElement("div", {
397
- className: "absolute top-2 right-2 bg-green-100 text-green-800 px-2 py-1 rounded text-xs z-10"
398
- }, "Live Preview"), derivedIsLoading || isCreatingSandbox && React.createElement(React.Fragment, null, React.createElement("div", {
399
- className: "absolute inset-0 bg-white/60 flex items-center justify-center z-20"
400
- }, React.createElement("div", {
401
- className: "animate-spin rounded-full h-12 w-12 border-4 border-blue-500 border-t-transparent"
402
- })), React.createElement("div", {
403
- className: "absolute top-2 left-2 bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs z-30"
404
- }, "Loading...")));
405
- } else {
406
- return React.createElement("div", {
407
- className: "h-full flex items-center justify-center text-gray-500 border border-gray-200 rounded-md bg-gray-50 ",
408
- style: {
409
- width: '100%',
410
- height: '80vh'
411
- }
412
- }, React.createElement("div", {
413
- className: "text-center space-y-3"
414
- }, React.createElement("p", {
415
- className: "font-medium"
416
- }, "No preview available"), React.createElement("div", {
417
- className: "flex flex-col items-center justify-center space-y-3"
418
- }, derivedIsLoading || isCreatingSandbox ? React.createElement("div", {
419
- className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"
420
- }) : React.createElement("div", {
421
- className: "w-8 h-8 bg-gray-300 rounded-full"
422
- }), React.createElement("p", {
423
- className: "text-sm text-gray-400"
424
- }, derivedIsLoading || isCreatingSandbox ? 'Generating code...' : 'Waiting for code generation...'))));
425
- }
426
- })() :
427
- // Code Editor Mode - Show files from subscription or fallback
428
- React.createElement("div", {
429
- className: "h-full w-full relative",
430
- style: {
431
- minHeight: windowHeight - 140,
432
- height: windowHeight - 140,
433
- width: isMinimized ? windowWidth * 0.9 + 'px' : '100%'
434
- }
435
- }, React.createElement(HybridLiveEditor, {
436
- ref: hybridLiveEditorRef,
437
- projectId: activeFragment?.projectId || channelId,
438
- fragmentId: activeFragment?.id || activeTab || 'default',
439
- files: Object.keys(completeFileContext).length > 0 ? completeFileContext : {},
440
- sandboxUrl: activeFragment?.sandboxUrl,
441
- onCopyToClipboard: handleCopyToClipboard,
442
- onFileUpdate: handleFileUpdate,
443
- readOnly: !activeFragment?.id,
444
- autoSave: false,
445
- debounceMs: 500,
446
- //className={`h-full w-[100%] h-[75vh] border-b border-gray-200 rounded-md bg-white shadow-sm overflow-hidden`}
447
- className: "h-full w-full"
448
- }), derivedIsLoading && React.createElement(React.Fragment, null, React.createElement("div", {
449
- className: "absolute inset-0 bg-white/60 flex items-center justify-center z-20"
450
- }, React.createElement("div", {
451
- className: "animate-spin rounded-full h-12 w-12 border-4 border-blue-500 border-t-transparent"
452
- })), React.createElement("div", {
453
- className: "absolute top-4 right-4 bg-blue-100 border border-blue-400 text-blue-700 px-3 py-2 rounded text-sm z-30"
454
- }, React.createElement("div", {
455
- className: "flex items-center gap-2"
456
- }, React.createElement("div", {
457
- className: "animate-spin rounded-full h-4 w-4 border-b-2 border-blue-500"
458
- }), "Processing..."))))));
1
+ import*as React from'react';// import { HybridLiveEditor, HybridLiveEditorRef } from '../live-code-editor/hybrid-live-editor';
2
+ // import { useOnChatMessageAddedSubscription } from 'common/graphql';
3
+ // import { AiAgentMessageRole, ICreateChannelInput, PostTypeEnum, RoomType } from 'common';
4
+ // import { Sandbox } from '@e2b/code-interpreter';
5
+ // import { useMachine } from '@xstate/react';
6
+ // import { fromPromise } from 'xstate';
7
+ // import { rightSidebarMachine } from '../../xstate';
8
+ // type RightSidebarProps = {
9
+ // channelId: string;
10
+ // detailSidebarOptions: {
11
+ // isMobileView: boolean;
12
+ // isSmallTabletView: boolean;
13
+ // isTabletView: boolean;
14
+ // isDesktopView: boolean;
15
+ // isLargeDesktopView: boolean;
16
+ // isSmallScreen: boolean;
17
+ // [key: string]: any;
18
+ // };
19
+ // windowWidth: number;
20
+ // windowHeight: number;
21
+ // activeTab?: string;
22
+ // selectedPost?: any;
23
+ // messages?: any[];
24
+ // setIsLoading?: (isLoading: boolean) => void;
25
+ // handleSendMessage?: (createChannelInput: ICreateChannelInput) => void;
26
+ // handleRecreateSandbox?: (messageId: string) => void | Promise<any>;
27
+ // isMinimized?: boolean;
28
+ // isLoading?: boolean;
29
+ // isCreatingSandbox?: boolean;
30
+ // setIsCreatingSandbox?: (isCreatingSandbox: boolean) => void;
31
+ // [key: string]: any;
32
+ // };
33
+ // export const RightSidebarFillComponent = (props: RightSidebarProps) => {
34
+ // const {
35
+ // channelId,
36
+ // detailSidebarOptions,
37
+ // windowWidth,
38
+ // windowHeight,
39
+ // activeTab,
40
+ // messages,
41
+ // selectedPost,
42
+ // setIsLoading,
43
+ // isLoading,
44
+ // handleSendMessage,
45
+ // handleRecreateSandbox,
46
+ // isMinimized,
47
+ // isCreatingSandbox,
48
+ // setIsCreatingSandbox,
49
+ // } = props;
50
+ // const hybridLiveEditorRef = React.useRef<HybridLiveEditorRef>(null);
51
+ // const previewIframeRef = React.useRef<HTMLIFrameElement>(null);
52
+ // const previewIframeContainerRef = React.useRef<HTMLIFrameElement>(null);
53
+ // // State for subscription data
54
+ // const [subscriptionData, setSubscriptionData] = React.useState<any>(null);
55
+ // // XState machine for sidebar state
56
+ // const [state, send] = useMachine(
57
+ // rightSidebarMachine.provide({
58
+ // actors: {
59
+ // recreateSandbox: fromPromise(async ({ input }) => {
60
+ // const { id } = input as { id: string };
61
+ // if (handleRecreateSandbox) {
62
+ // await handleRecreateSandbox(id);
63
+ // }
64
+ // return { success: true } as const;
65
+ // }),
66
+ // },
67
+ // }),
68
+ // {
69
+ // input: {
70
+ // channelId: channelId || '',
71
+ // isMinimized: !!isMinimized,
72
+ // windowWidth,
73
+ // windowHeight,
74
+ // isLoading: !!isLoading,
75
+ // activeFragment: null,
76
+ // currentFiles: {},
77
+ // canvasLayers: [],
78
+ // previewStatus: null,
79
+ // },
80
+ // },
81
+ // );
82
+ // const activeFragment = state.context.activeFragment;
83
+ // const currentFiles = state.context.currentFiles;
84
+ // const canvasLayers = state.context.canvasLayers as any[];
85
+ // const previewStatus = state.context.previewStatus as { code?: number; message?: string; status?: string } | null;
86
+ // // const [isLoading, setIsLoading] = React.useState(false);
87
+ // const { data: chatMessageAddedData } = useOnChatMessageAddedSubscription({
88
+ // variables: { channelId: channelId?.toString() || '' },
89
+ // skip: !channelId,
90
+ // });
91
+ // // Component mount tracking
92
+ // const componentId = React.useMemo(
93
+ // () => `right-sidebar-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
94
+ // [],
95
+ // );
96
+ // const handleCopyToClipboard = React.useCallback((text: string) => {
97
+ // navigator.clipboard.writeText(text);
98
+ // }, []);
99
+ // const handleFileUpdate = React.useCallback(async (filePath: string, content: string) => {
100
+ // // TODO: Implement file update logic for the channel
101
+ // console.log('File update:', { filePath, content });
102
+ // }, []);
103
+ // // Create complete file context by merging currentFiles with activeFragment files
104
+ // const completeFileContext = React.useMemo(() => {
105
+ // if (!activeFragment?.files) {
106
+ // console.log('📂 Using currentFiles as complete context (no activeFragment.files)');
107
+ // return currentFiles;
108
+ // }
109
+ // // Merge currentFiles with activeFragment files, giving priority to activeFragment files
110
+ // const merged = { ...currentFiles };
111
+ // // Override with activeFragment files (these are the most recent changes)
112
+ // Object.entries(activeFragment.files).forEach(([path, content]) => {
113
+ // merged[path] = content as string;
114
+ // });
115
+ // // Validate file context integrity
116
+ // const hasPackageJson = 'package.json' in merged;
117
+ // const hasMainFiles = Object.keys(merged).some(
118
+ // (path) =>
119
+ // path.includes('index.') || path.includes('main.') || path.includes('App.') || path.includes('src/'),
120
+ // );
121
+ // console.log('📂 Complete file context created:', {
122
+ // currentFilesCount: Object.keys(currentFiles).length,
123
+ // activeFragmentFilesCount: Object.keys(activeFragment.files).length,
124
+ // mergedFilesCount: Object.keys(merged).length,
125
+ // hasPackageJson,
126
+ // hasMainFiles,
127
+ // activeFragmentFiles: Object.keys(activeFragment.files),
128
+ // allFiles: Object.keys(merged),
129
+ // validation: {
130
+ // isComplete: hasPackageJson && hasMainFiles,
131
+ // missingPackageJson: !hasPackageJson,
132
+ // missingMainFiles: !hasMainFiles,
133
+ // },
134
+ // });
135
+ // if (!hasPackageJson) {
136
+ // console.warn('⚠️ File context missing package.json - this may cause issues in sandbox');
137
+ // }
138
+ // if (!hasMainFiles) {
139
+ // console.warn('⚠️ File context missing main application files - this may cause issues in sandbox');
140
+ // }
141
+ // return merged;
142
+ // }, [currentFiles, activeFragment?.files]);
143
+ // // Determine if we should show preview or editor based on activeTab
144
+ // const isPreviewMode = activeTab === 'preview';
145
+ // // Turn on loader when new data is about to be processed
146
+ // React.useEffect(() => {
147
+ // if (chatMessageAddedData?.chatMessageAdded || selectedPost) {
148
+ // // sync external loader
149
+ // // setIsLoading?.(false);
150
+ // // send({ type: 'SET_LOADING', isLoading: false });
151
+ // }
152
+ // }, [chatMessageAddedData, selectedPost, send, setIsLoading]);
153
+ // // Handle subscription data updates - prefer response update structure like use-ai-messages.ts
154
+ // React.useEffect(() => {
155
+ // if (chatMessageAddedData?.chatMessageAdded || selectedPost) {
156
+ // // Prefer explicitly selected post to ensure UI updates when it changes
157
+ // const message = selectedPost || chatMessageAddedData?.chatMessageAdded;
158
+ // // Extract strictly from message.propsConfiguration (fragment only)
159
+ // let extracted: any = null;
160
+ // let fragmentSource:
161
+ // | 'propsConfiguration.contents.props.fragment'
162
+ // | 'propsConfiguration.contents.fragment'
163
+ // | 'propsConfiguration.fragment'
164
+ // | null = null;
165
+ // try {
166
+ // // 1) Preferred: contents.props.fragment
167
+ // const cfg: any = message.propsConfiguration || {};
168
+ // const contents: any = cfg.contents || cfg.content || {};
169
+ // if (contents?.props?.fragment) {
170
+ // const frag = contents.props.fragment;
171
+ // extracted = {
172
+ // sandboxUrl: frag.sandboxUrl || frag.url,
173
+ // sandboxId: frag.sandboxId,
174
+ // projectId: cfg.projectId || contents.projectId || frag.projectId,
175
+ // modelConfig: cfg.modelConfig || contents.modelConfig || frag.modelConfig,
176
+ // files: frag.files || {},
177
+ // canvasLayers: contents.canvasLayers || cfg.canvasLayers || frag.canvasLayers,
178
+ // summary: contents.summary || cfg.summary || frag.summary,
179
+ // title: frag.title || contents.title || cfg.title,
180
+ // isError: frag.isError,
181
+ // };
182
+ // fragmentSource = 'propsConfiguration.contents.props.fragment';
183
+ // }
184
+ // // 2) Fallback: contents.fragment
185
+ // if (!extracted && contents?.fragment) {
186
+ // const frag = contents.fragment;
187
+ // extracted = {
188
+ // sandboxUrl: frag.sandboxUrl || frag.url,
189
+ // sandboxId: frag.sandboxId,
190
+ // projectId: cfg.projectId || contents.projectId || frag.projectId,
191
+ // modelConfig: cfg.modelConfig || contents.modelConfig || frag.modelConfig,
192
+ // files: frag.files || {},
193
+ // canvasLayers: contents.canvasLayers || cfg.canvasLayers || frag.canvasLayers,
194
+ // summary: contents.summary || cfg.summary || frag.summary,
195
+ // title: frag.title || contents.title || cfg.title,
196
+ // isError: frag.isError,
197
+ // };
198
+ // fragmentSource = 'propsConfiguration.contents.fragment';
199
+ // }
200
+ // // 3) Fallback: propsConfiguration.fragment (top-level)
201
+ // if (!extracted && cfg?.fragment) {
202
+ // const frag = cfg.fragment;
203
+ // extracted = {
204
+ // sandboxUrl: frag.sandboxUrl || frag.url,
205
+ // sandboxId: frag.sandboxId,
206
+ // projectId: cfg.projectId || frag.projectId,
207
+ // modelConfig: cfg.modelConfig || frag.modelConfig,
208
+ // files: frag.files || {},
209
+ // canvasLayers: cfg.canvasLayers || frag.canvasLayers,
210
+ // summary: cfg.summary || frag.summary,
211
+ // title: frag.title || cfg.title,
212
+ // isError: frag.isError,
213
+ // };
214
+ // fragmentSource = 'propsConfiguration.fragment';
215
+ // }
216
+ // } catch (error) {
217
+ // console.error('Error extracting response from message:', error);
218
+ // }
219
+ // // console.log('Extracted response fragment source:', fragmentSource);
220
+ // // console.log('Extracted response:', extracted);
221
+ // if (extracted && (extracted.sandboxUrl || extracted.url)) {
222
+ // console.log('✅ Processing response update:', extracted);
223
+ // // Update subscription data snapshot
224
+ // setSubscriptionData(extracted);
225
+ // // Build active fragment
226
+ // const fragment = {
227
+ // id: message.id,
228
+ // sandboxUrl: extracted.sandboxUrl || extracted.url,
229
+ // sandboxId: extracted.sandboxId,
230
+ // title: extracted.title || 'Generated Code',
231
+ // files: extracted.files || {},
232
+ // projectId: extracted.projectId,
233
+ // modelConfig: extracted.modelConfig,
234
+ // canvasLayers: extracted.canvasLayers,
235
+ // summary: extracted.summary,
236
+ // isError: extracted.isError,
237
+ // };
238
+ // // If canvasLayers missing but present in summary, attempt to extract like use-ai-messages
239
+ // if ((!fragment.canvasLayers || !Array.isArray(fragment.canvasLayers)) && fragment.summary) {
240
+ // try {
241
+ // const match = (fragment.summary as string).match(/<canvas_layers>([\s\S]*?)<\/canvas_layers>/);
242
+ // if (match) {
243
+ // const parsed = JSON.parse(match[1]);
244
+ // if (Array.isArray(parsed)) {
245
+ // fragment.canvasLayers = parsed;
246
+ // }
247
+ // }
248
+ // } catch (e) {
249
+ // console.warn('Failed to parse canvas layers from summary:', e);
250
+ // }
251
+ // }
252
+ // console.log('✅ Setting active fragment via XState:', fragment);
253
+ // send({ type: 'SET_FRAGMENT', fragment });
254
+ // // setIsLoading?.(false);
255
+ // //send({ type: 'SET_LOADING', isLoading: false });
256
+ // } else {
257
+ // console.log('❌ No valid response found in message');
258
+ // // setIsLoading?.(false);
259
+ // // send({ type: 'SET_LOADING', isLoading: false });
260
+ // }
261
+ // }
262
+ // }, [chatMessageAddedData, selectedPost, send, setIsLoading]);
263
+ // // When switching tabs or when sandbox changes, show loader until ready
264
+ // // React.useEffect(() => {
265
+ // // if (isPreviewMode) {
266
+ // // if (activeFragment?.sandboxUrl) {
267
+ // // // setIsLoading(true);
268
+ // // }
269
+ // // } else {
270
+ // // // In code view, briefly show loader while editor reacts to new files
271
+ // // // setIsLoading(true);
272
+ // // const timeoutId = setTimeout(() => setIsLoading(false), 400);
273
+ // // return () => clearTimeout(timeoutId);
274
+ // // }
275
+ // // }, [isPreviewMode, activeFragment?.sandboxUrl, completeFileContext]);
276
+ // // Cleanup iframe resources on unmount to prevent renderer leaks in Chrome
277
+ // React.useEffect(() => {
278
+ // return () => {
279
+ // try {
280
+ // if (previewIframeRef.current) {
281
+ // previewIframeRef.current.src = 'about:blank';
282
+ // }
283
+ // } catch (e) {
284
+ // // no-op
285
+ // }
286
+ // };
287
+ // }, []);
288
+ // React.useEffect(() => {
289
+ // const handleVisualEditorMessage = (event: MessageEvent) => {
290
+ // // Handle AI changes
291
+ // if (event.data.type === 'VISUAL_EDITOR_CHANGES') {
292
+ // console.log('visual_editor_changes....', event.data.message);
293
+ // if (handleSendMessage && event.data.message) {
294
+ // // Call aiHandleSend directly - this is the handleSend function from AIAgent
295
+ // handleSendMessage({
296
+ // channelId,
297
+ // type: RoomType.Aiassistant,
298
+ // postData: {
299
+ // // postId: postId,
300
+ // type: PostTypeEnum.Aiassistant,
301
+ // content: event.data.message,
302
+ // },
303
+ // });
304
+ // } else {
305
+ // console.warn('⚠️ handleSendMessage not available or no message provided');
306
+ // }
307
+ // }
308
+ // };
309
+ // window.addEventListener('message', handleVisualEditorMessage);
310
+ // return () => window.removeEventListener('message', handleVisualEditorMessage);
311
+ // }, [handleSendMessage, channelId]);
312
+ // const recreateSandboxHandler = React.useCallback(
313
+ // async (id: string) => {
314
+ // if (id) {
315
+ // console.log('recreate sandbox id....', id);
316
+ // setIsLoading?.(true);
317
+ // send({ type: 'SET_LOADING', isLoading: true });
318
+ // try {
319
+ // send({ type: 'RECREATE_SANDBOX', id });
320
+ // } catch (e: any) {
321
+ // console.error('Error recreating sandbox:', e);
322
+ // setIsLoading?.(false);
323
+ // send({ type: 'SET_LOADING', isLoading: false });
324
+ // }
325
+ // }
326
+ // },
327
+ // [send, setIsLoading],
328
+ // );
329
+ // // Track if we've already attempted recreate for a given sandbox URL
330
+ // const recreateAttemptedByUrlRef = React.useRef<Record<string, boolean>>({});
331
+ // // Probe sandbox URL via XState actor
332
+ // React.useEffect(() => {
333
+ // const url = activeFragment?.sandboxUrl;
334
+ // if (url) {
335
+ // send({ type: 'PROBE', url, fragmentId: activeFragment?.id });
336
+ // }
337
+ // }, [activeFragment?.sandboxUrl, activeFragment?.id, send]);
338
+ // // Prefer using external loading when provided; otherwise fall back to machine state
339
+ // const derivedIsLoading = (typeof isLoading === 'boolean' ? isLoading : state.context.isLoading) as boolean;
340
+ // // Sync external loading prop with machine's loading state (no-op if setter not provided)
341
+ // // React.useEffect(() => {
342
+ // // console.log(
343
+ // // 'isLoading....',
344
+ // // isLoading,
345
+ // // ' state.context.isLoading',
346
+ // // state.context.isLoading,
347
+ // // ' previewStatus',
348
+ // // previewStatus,
349
+ // // );
350
+ // // if (!state.context.isLoading) {
351
+ // // setIsLoading?.(!!state.context.isLoading);
352
+ // // }
353
+ // // }, [state.context.isLoading, setIsLoading, isLoading]);
354
+ // return (
355
+ // <div ref={previewIframeContainerRef} className="right-sidebar-content h-full flex flex-col">
356
+ // <div className="flex-1 overflow-hidden" style={{ minHeight: windowHeight - 140 }}>
357
+ // {isPreviewMode ? (
358
+ // // Preview Mode - Show sandbox iframe or fallback
359
+ // (() => {
360
+ // if (activeFragment?.sandboxUrl) {
361
+ // return (
362
+ // <div
363
+ // className="w-full h-full relative"
364
+ // style={{
365
+ // width: isMinimized ? windowWidth * 0.8 + 'px' : '100%',
366
+ // height: windowHeight - 140,
367
+ // backgroundColor: '#f0f0f0',
368
+ // }}
369
+ // >
370
+ // {!previewStatus ? (
371
+ // <iframe
372
+ // key={activeFragment.sandboxUrl}
373
+ // ref={previewIframeRef}
374
+ // src={activeFragment.sandboxUrl}
375
+ // className="w-full w-fit h-full h-fit border border-gray-200 rounded-md bg-white shadow-sm"
376
+ // title="Live Preview"
377
+ // sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-orientation-lock allow-pointer-lock allow-presentation allow-storage-access-by-user-activation allow-top-navigation-by-user-activation"
378
+ // loading="lazy"
379
+ // onLoad={() => {
380
+ // console.log('🎯 Iframe loaded successfully');
381
+ // setIsLoading?.(false);
382
+ // setIsCreatingSandbox?.(false);
383
+ // send({ type: 'SET_LOADING', isLoading: false });
384
+ // }}
385
+ // onError={(e) => {
386
+ // console.error('❌ Iframe error:', e);
387
+ // setIsLoading?.(false);
388
+ // send({ type: 'SET_LOADING', isLoading: false });
389
+ // }}
390
+ // style={
391
+ // {
392
+ // // maxHeight: windowHeight - 140,
393
+ // // width: isMinimized ? windowWidth * 0.82 + 'px' : '100%',
394
+ // //padding: isMinimized ? '10px' : '0px',
395
+ // }
396
+ // }
397
+ // />
398
+ // ) : (
399
+ // <div className="absolute inset-0 bg-white/60 flex items-center justify-center z-20">
400
+ // {handleRecreateSandbox && (
401
+ // <>
402
+ // {derivedIsLoading || isCreatingSandbox ? (
403
+ // <div className="flex flex-col items-center justify-center gap-2">
404
+ // <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"></div>
405
+ // <p className="text-xs text-blue-700">Recreating...</p>
406
+ // </div>
407
+ // ) : (
408
+ // <div className="flex flex-col items-center justify-center gap-2">
409
+ // <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"></div>
410
+ // <p className="text-sm text-muted-foreground">
411
+ // {isLoading ? 'Recreating...' : 'Refresh'}{' '}
412
+ // {/* Sandbox is not available. */}
413
+ // </p>
414
+ // {/* <button
415
+ // type="button"
416
+ // className="themed-button focus-themed px-3 py-1.5 text-xs"
417
+ // onClick={() =>
418
+ // recreateSandboxHandler(activeFragment?.id)
419
+ // }
420
+ // >
421
+ // Recreate
422
+ // </button> */}
423
+ // </div>
424
+ // )}
425
+ // </>
426
+ // )}
427
+ // </div>
428
+ // )}
429
+ // <div className="absolute top-2 right-2 bg-green-100 text-green-800 px-2 py-1 rounded text-xs z-10">
430
+ // Live Preview
431
+ // </div>
432
+ // {derivedIsLoading ||
433
+ // (isCreatingSandbox && (
434
+ // <>
435
+ // <div className="absolute inset-0 bg-white/60 flex items-center justify-center z-20">
436
+ // <div className="animate-spin rounded-full h-12 w-12 border-4 border-blue-500 border-t-transparent"></div>
437
+ // </div>
438
+ // <div className="absolute top-2 left-2 bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs z-30">
439
+ // Loading...
440
+ // </div>
441
+ // </>
442
+ // ))}
443
+ // </div>
444
+ // );
445
+ // } else {
446
+ // return (
447
+ // <div
448
+ // className="h-full flex items-center justify-center text-gray-500 border border-gray-200 rounded-md bg-gray-50 "
449
+ // style={{ width: '100%', height: '80vh' }}
450
+ // >
451
+ // <div className="text-center space-y-3">
452
+ // <p className="font-medium">No preview available</p>
453
+ // <div className="flex flex-col items-center justify-center space-y-3">
454
+ // {derivedIsLoading || isCreatingSandbox ? (
455
+ // <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"></div>
456
+ // ) : (
457
+ // <div className="w-8 h-8 bg-gray-300 rounded-full"></div>
458
+ // )}
459
+ // <p className="text-sm text-gray-400">
460
+ // {derivedIsLoading || isCreatingSandbox
461
+ // ? 'Generating code...'
462
+ // : 'Waiting for code generation...'}
463
+ // </p>
464
+ // </div>
465
+ // </div>
466
+ // </div>
467
+ // );
468
+ // }
469
+ // })()
470
+ // ) : (
471
+ // // Code Editor Mode - Show files from subscription or fallback
472
+ // <div
473
+ // className="h-full w-full relative"
474
+ // style={{
475
+ // minHeight: windowHeight - 140,
476
+ // height: windowHeight - 140,
477
+ // width: isMinimized ? windowWidth * 0.9 + 'px' : '100%',
478
+ // }}
479
+ // >
480
+ // <HybridLiveEditor
481
+ // ref={hybridLiveEditorRef}
482
+ // projectId={activeFragment?.projectId || channelId}
483
+ // fragmentId={activeFragment?.id || activeTab || 'default'}
484
+ // files={Object.keys(completeFileContext).length > 0 ? completeFileContext : {}}
485
+ // sandboxUrl={activeFragment?.sandboxUrl}
486
+ // onCopyToClipboard={handleCopyToClipboard}
487
+ // onFileUpdate={handleFileUpdate}
488
+ // readOnly={!activeFragment?.id}
489
+ // autoSave={false}
490
+ // debounceMs={500}
491
+ // //className={`h-full w-[100%] h-[75vh] border-b border-gray-200 rounded-md bg-white shadow-sm overflow-hidden`}
492
+ // className="h-full w-full"
493
+ // />
494
+ // {derivedIsLoading && (
495
+ // <>
496
+ // <div className="absolute inset-0 bg-white/60 flex items-center justify-center z-20">
497
+ // <div className="animate-spin rounded-full h-12 w-12 border-4 border-blue-500 border-t-transparent"></div>
498
+ // </div>
499
+ // <div className="absolute top-4 right-4 bg-blue-100 border border-blue-400 text-blue-700 px-3 py-2 rounded text-sm z-30">
500
+ // <div className="flex items-center gap-2">
501
+ // <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-500"></div>
502
+ // Processing...
503
+ // </div>
504
+ // </div>
505
+ // </>
506
+ // )}
507
+ // </div>
508
+ // )}
509
+ // </div>
510
+ // {/* <div className="p-2 border-t bg-gray-50 text-xs text-gray-500">
511
+ // <div className="flex justify-between">
512
+ // <span>Mobile: {detailSidebarOptions.isMobileView ? 'Yes' : 'No'}</span>
513
+ // <span>Desktop: {detailSidebarOptions.isDesktopView ? 'Yes' : 'No'}</span>
514
+ // {activeFragment && (
515
+ // <span className="text-green-600">{activeFragment.isError ? 'Error' : 'Ready'}</span>
516
+ // )}
517
+ // </div>
518
+ // {activeFragment && (
519
+ // <div className="mt-1 text-xs">
520
+ // <span className="text-gray-400">Files: {Object.keys(completeFileContext).length}</span>
521
+ // {canvasLayers.length > 0 && (
522
+ // <span className="ml-2 text-gray-400">Layers: {canvasLayers.length}</span>
523
+ // )}
524
+ // </div>
525
+ // )}
526
+ // </div> */}
527
+ // </div>
528
+ // );
529
+ // };
530
+ const RightSidebarFillComponent = props => {
531
+ return React.createElement(React.Fragment, null);
459
532
  };export{RightSidebarFillComponent};//# sourceMappingURL=RightSiderBar.js.map