11import AppPreviewCard from "@/components/marketplace/app/app-preview-card" ;
2+ import { DraggableItem } from "@/components/misc/draggable-item" ;
23import { EditorContext } from "@/components/providers/editor-context-provider" ;
3- import { DragEventTypeEnum } from "@/lib/enums" ;
44import { useScreenSize } from "@/lib/hooks/use-screen-size" ;
55import { useTabViewManager } from "@/lib/hooks/use-tab-view-manager" ;
6- import { AppDragData , AppViewConfig } from "@/lib/types" ;
6+ import {
7+ AppDragData ,
8+ AppViewConfig ,
9+ DragData ,
10+ ExtensionApp ,
11+ } from "@/lib/types" ;
12+ import { useDraggable } from "@dnd-kit/core" ;
713import { Button } from "@heroui/react" ;
8- import { useContext } from "react" ;
14+ import { useContext , useEffect , useState } from "react" ;
915import { v4 } from "uuid" ;
1016
1117export default function AppExplorer ( ) {
1218 const editorContext = useContext ( EditorContext ) ;
1319
20+ const extensions = editorContext ?. persistSettings ?. extensions ?? [ ] ;
21+
22+ const previews = extensions . map ( ( ext , index ) => (
23+ < DraggableAppPreviewCard key = { index } ext = { ext } />
24+ ) ) ;
25+
26+ return (
27+ < div className = "grid h-full grid-rows-[max-content_auto_max-content] gap-y-2" >
28+ < p className = "text-center" > Tap or drag an extension to open it.</ p >
29+
30+ < div className = "grid h-fit max-h-full w-full grid-cols-2 gap-2 overflow-x-hidden overflow-y-auto px-4" >
31+ { previews }
32+ </ div >
33+ < div className = "flex flex-col gap-y-1 px-4 pb-2" >
34+ < Button
35+ color = "secondary"
36+ onPress = { ( ) => {
37+ editorContext ?. setEditorStates ( ( prev ) => ( {
38+ ...prev ,
39+ isMarketplaceOpen : true ,
40+ } ) ) ;
41+ } }
42+ >
43+ Explorer Community Workflows/Apps
44+ </ Button >
45+ </ div >
46+ </ div >
47+ ) ;
48+ }
49+
50+ function DraggableAppPreviewCard ( { ext } : { ext : ExtensionApp } ) {
51+ const editorContext = useContext ( EditorContext ) ;
52+
1453 const { createAppViewInCanvasView } = useTabViewManager ( ) ;
1554 const { isLandscape } = useScreenSize ( ) ;
55+ const { setNodeRef, listeners, isDragging } = useDraggable ( {
56+ id : `draggable-app-${ ext . config . id } ` ,
57+ data : {
58+ type : "app" ,
59+ data : {
60+ app : ext ,
61+ } as AppDragData ,
62+ } as DragData ,
63+ } ) ;
1664
17- const extensions = editorContext ?. persistSettings ?. extensions ?? [ ] ;
65+ const [ isDragFinished , setIsDragFinished ] = useState ( false ) ;
1866
19- const previews = extensions . map ( ( ext , index ) => (
20- < div
21- key = { index }
22- className = "w-full h-fit"
23- draggable
24- onDragStart = { ( e ) => {
25- editorContext ?. setEditorStates ( ( prev ) => ( {
26- ...prev ,
27- isDraggingOverCanvas : true ,
28- } ) ) ;
29- e . dataTransfer . setData (
30- `application/${ DragEventTypeEnum . App . toLowerCase ( ) } ` ,
31- JSON . stringify ( {
32- app : ext ,
33- } as AppDragData ) ,
34- ) ;
35- } }
36- onDragEnd = { ( ) => {
37- editorContext ?. setEditorStates ( ( prev ) => ( {
38- ...prev ,
39- isDraggingOverCanvas : false ,
40- } ) ) ;
41- } }
67+ useEffect ( ( ) => {
68+ if ( isDragging ) {
69+ setIsDragFinished ( false ) ;
70+ } else {
71+ // Delay 200ms and then set isDragFinished to true,
72+ // so the app preview button is not triggered via a press event.
73+ setTimeout ( ( ) => {
74+ setIsDragFinished ( true ) ;
75+ } , 200 ) ;
76+ }
77+ } , [ isDragging ] ) ;
78+
79+ return (
80+ < DraggableItem
81+ className = "h-fit w-full"
82+ ref = { setNodeRef }
83+ listeners = { listeners }
4284 >
4385 < AppPreviewCard
4486 extension = { ext }
4587 isShowInstalledChip = { false }
4688 isShowUninstallButton = { false }
4789 isShowUseButton
4890 isShowCompatibleChip = { false }
91+ isShowContextMenu = { false }
92+ isDisableButtonPress = { ! isDragFinished }
4993 onPress = { ( ext ) => {
5094 const config : AppViewConfig = {
5195 app : ext . config . id ,
@@ -62,30 +106,8 @@ export default function AppExplorer() {
62106 } ) ) ;
63107 }
64108 } }
109+ listeners = { listeners }
65110 />
66- </ div >
67- ) ) ;
68-
69- return (
70- < div className = "h-full grid grid-rows-[max-content_auto_max-content] gap-y-2" >
71- < p className = "text-center" > Tap or drag an extension to open it.</ p >
72-
73- < div className = "grid grid-cols-2 gap-2 h-fit w-full max-h-full overflow-y-auto overflow-x-hidden px-4" >
74- { previews }
75- </ div >
76- < div className = "flex flex-col gap-y-1 px-4 pb-2" >
77- < Button
78- color = "secondary"
79- onPress = { ( ) => {
80- editorContext ?. setEditorStates ( ( prev ) => ( {
81- ...prev ,
82- isMarketplaceOpen : true ,
83- } ) ) ;
84- } }
85- >
86- Explorer Community Workflows/Apps
87- </ Button >
88- </ div >
89- </ div >
111+ </ DraggableItem >
90112 ) ;
91113}
0 commit comments