11'use client' ;
22
33import React , {
4- FC , Fragment , MouseEventHandler , useCallback , useEffect , useMemo , useRef , useState
4+ ClipboardEventHandler ,
5+ FC ,
6+ Fragment ,
7+ MouseEventHandler ,
8+ useCallback ,
9+ useEffect ,
10+ useMemo ,
11+ useRef ,
12+ ClipboardEvent ,
13+ useState ,
514} from 'react' ;
615import dayjs from 'dayjs' ;
716import { Integrations } from '@gitroom/frontend/components/launches/calendar.context' ;
@@ -47,6 +56,9 @@ import { weightedLength } from '@gitroom/helpers/utils/count.length';
4756import { uniqBy } from 'lodash' ;
4857import { Select } from '@gitroom/react/form/select' ;
4958import { useClickOutside } from '@gitroom/frontend/components/layout/click.outside' ;
59+ import { useUppyUploader } from '@gitroom/frontend/components/media/new.uploader' ;
60+ import { LoadingComponent } from '@gitroom/frontend/components/layout/loading' ;
61+ import { DropFiles } from '@gitroom/frontend/components/layout/drop.files' ;
5062
5163function countCharacters ( text : string , type : string ) : number {
5264 if ( type !== 'x' ) {
@@ -69,6 +81,8 @@ export const AddEditModal: FC<{
6981} > = ( props ) => {
7082 const { date, integrations : ints , reopenModal, mutate, onlyValues } = props ;
7183 const [ customer , setCustomer ] = useState ( '' ) ;
84+ const [ loading , setLoading ] = useState ( false ) ;
85+ const [ uploading , setUploading ] = useState ( false ) ;
7286
7387 // selected integrations to allow edit
7488 const [ selectedIntegrations , setSelectedIntegrations ] = useStateCallback <
@@ -265,12 +279,14 @@ export const AddEditModal: FC<{
265279 const schedule = useCallback (
266280 ( type : 'draft' | 'now' | 'schedule' | 'delete' ) => async ( ) => {
267281 if ( type === 'delete' ) {
282+ setLoading ( true ) ;
268283 if (
269284 ! ( await deleteDialog (
270285 'Are you sure you want to delete this post?' ,
271286 'Yes, delete it!'
272287 ) )
273288 ) {
289+ setLoading ( false ) ;
274290 return ;
275291 }
276292 await fetch ( `/posts/${ existingData . group } ` , {
@@ -341,6 +357,7 @@ export const AddEditModal: FC<{
341357 }
342358 }
343359
360+ setLoading ( true ) ;
344361 await fetch ( '/posts' , {
345362 method : 'POST' ,
346363 body : JSON . stringify ( {
@@ -377,6 +394,68 @@ export const AddEditModal: FC<{
377394 ]
378395 ) ;
379396
397+ const uppy = useUppyUploader ( {
398+ onUploadSuccess : ( ) => {
399+ /**empty**/
400+ } ,
401+ allowedFileTypes : 'image/*,video/mp4' ,
402+ } ) ;
403+
404+ const pasteImages = useCallback (
405+ ( index : number , currentValue : any [ ] , isFile ?: boolean ) => {
406+ return async ( event : ClipboardEvent < HTMLDivElement > | File [ ] ) => {
407+ // @ts -ignore
408+ const clipboardItems = isFile
409+ ? // @ts -ignore
410+ event . map ( ( p ) => ( { kind : 'file' , getAsFile : ( ) => p } ) )
411+ : // @ts -ignore
412+ event . clipboardData ?. items ; // Ensure clipboardData is available
413+ if ( ! clipboardItems ) {
414+ return ;
415+ }
416+
417+ const files : File [ ] = [ ] ;
418+
419+ // @ts -ignore
420+ for ( const item of clipboardItems ) {
421+ console . log ( item ) ;
422+ if ( item . kind === 'file' ) {
423+ const file = item . getAsFile ( ) ;
424+ if ( file ) {
425+ const isImage = file . type . startsWith ( 'image/' ) ;
426+ const isVideo = file . type . startsWith ( 'video/' ) ;
427+ if ( isImage || isVideo ) {
428+ files . push ( file ) ; // Collect images or videos
429+ }
430+ }
431+ }
432+ }
433+ if ( files . length === 0 ) {
434+ return ;
435+ }
436+
437+ setUploading ( true ) ;
438+ const lastValues = [ ...currentValue ] ;
439+ for ( const file of files ) {
440+ uppy . addFile ( file ) ;
441+ const upload = await uppy . upload ( ) ;
442+ uppy . clear ( ) ;
443+ if ( upload ?. successful ?. length ) {
444+ lastValues . push ( upload ?. successful [ 0 ] ?. response ?. body ?. saved ! ) ;
445+ changeImage ( index ) ( {
446+ target : {
447+ name : 'image' ,
448+ value : [ ...lastValues ] ,
449+ } ,
450+ } ) ;
451+ }
452+ }
453+ setUploading ( false ) ;
454+ } ;
455+ } ,
456+ [ changeImage ]
457+ ) ;
458+
380459 const getPostsMarketplace = useCallback ( async ( ) => {
381460 return (
382461 await fetch ( `/posts/marketplace/${ existingData ?. posts ?. [ 0 ] ?. id } ` )
@@ -427,6 +506,11 @@ export const AddEditModal: FC<{
427506 'flex flex-col md:flex-row p-[10px] rounded-[4px] bg-primary gap-[20px]'
428507 ) }
429508 >
509+ { uploading && (
510+ < div className = "absolute left-0 top-0 w-full h-full bg-black/40 z-[600] flex justify-center items-center" >
511+ < LoadingComponent width = { 100 } height = { 100 } />
512+ </ div >
513+ ) }
430514 < div
431515 className = { clsx (
432516 'flex flex-col gap-[16px] transition-all duration-700 whitespace-nowrap' ,
@@ -534,23 +618,28 @@ export const AddEditModal: FC<{
534618 < div >
535619 < div className = "flex gap-[4px]" >
536620 < div className = "flex-1 editor text-textColor" >
537- < Editor
538- order = { index }
539- height = { value . length > 1 ? 150 : 250 }
540- commands = {
541- [
542- // ...commands
543- // .getCommands()
544- // .filter((f) => f.name === 'image'),
545- // newImage,
546- // postSelector(dateState),
547- ]
548- }
549- value = { p . content }
550- preview = "edit"
551- // @ts -ignore
552- onChange = { changeValue ( index ) }
553- />
621+ < DropFiles
622+ onDrop = { pasteImages ( index , p . image || [ ] , true ) }
623+ >
624+ < Editor
625+ order = { index }
626+ height = { value . length > 1 ? 150 : 250 }
627+ commands = {
628+ [
629+ // ...commands
630+ // .getCommands()
631+ // .filter((f) => f.name === 'image'),
632+ // newImage,
633+ // postSelector(dateState),
634+ ]
635+ }
636+ value = { p . content }
637+ preview = "edit"
638+ onPaste = { pasteImages ( index , p . image || [ ] ) }
639+ // @ts -ignore
640+ onChange = { changeValue ( index ) }
641+ />
642+ </ DropFiles >
554643
555644 { showError &&
556645 ( ! p . content || p . content . length < 6 ) && (
@@ -649,6 +738,7 @@ export const AddEditModal: FC<{
649738 className = "rounded-[4px] relative group"
650739 disabled = {
651740 selectedIntegrations . length === 0 ||
741+ loading ||
652742 ! canSendForPublication
653743 }
654744 >
@@ -678,7 +768,11 @@ export const AddEditModal: FC<{
678768 </ svg >
679769 < div
680770 onClick = { postNow }
681- className = "hidden group-hover:flex hover:flex flex-col justify-center absolute left-0 top-[100%] w-full h-[40px] bg-customColor22 border border-tableBorder"
771+ className = { clsx (
772+ 'hidden group-hover:flex hover:flex flex-col justify-center absolute left-0 top-[100%] w-full h-[40px] bg-customColor22 border border-tableBorder' ,
773+ loading &&
774+ 'cursor-not-allowed pointer-events-none opacity-50'
775+ ) }
682776 >
683777 Post now
684778 </ div >
0 commit comments