1
1
'use client' ;
2
2
3
3
import 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 ,
5
14
} from 'react' ;
6
15
import dayjs from 'dayjs' ;
7
16
import { Integrations } from '@gitroom/frontend/components/launches/calendar.context' ;
@@ -47,6 +56,9 @@ import { weightedLength } from '@gitroom/helpers/utils/count.length';
47
56
import { uniqBy } from 'lodash' ;
48
57
import { Select } from '@gitroom/react/form/select' ;
49
58
import { 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' ;
50
62
51
63
function countCharacters ( text : string , type : string ) : number {
52
64
if ( type !== 'x' ) {
@@ -69,6 +81,8 @@ export const AddEditModal: FC<{
69
81
} > = ( props ) => {
70
82
const { date, integrations : ints , reopenModal, mutate, onlyValues } = props ;
71
83
const [ customer , setCustomer ] = useState ( '' ) ;
84
+ const [ loading , setLoading ] = useState ( false ) ;
85
+ const [ uploading , setUploading ] = useState ( false ) ;
72
86
73
87
// selected integrations to allow edit
74
88
const [ selectedIntegrations , setSelectedIntegrations ] = useStateCallback <
@@ -265,12 +279,14 @@ export const AddEditModal: FC<{
265
279
const schedule = useCallback (
266
280
( type : 'draft' | 'now' | 'schedule' | 'delete' ) => async ( ) => {
267
281
if ( type === 'delete' ) {
282
+ setLoading ( true ) ;
268
283
if (
269
284
! ( await deleteDialog (
270
285
'Are you sure you want to delete this post?' ,
271
286
'Yes, delete it!'
272
287
) )
273
288
) {
289
+ setLoading ( false ) ;
274
290
return ;
275
291
}
276
292
await fetch ( `/posts/${ existingData . group } ` , {
@@ -341,6 +357,7 @@ export const AddEditModal: FC<{
341
357
}
342
358
}
343
359
360
+ setLoading ( true ) ;
344
361
await fetch ( '/posts' , {
345
362
method : 'POST' ,
346
363
body : JSON . stringify ( {
@@ -377,6 +394,68 @@ export const AddEditModal: FC<{
377
394
]
378
395
) ;
379
396
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
+
380
459
const getPostsMarketplace = useCallback ( async ( ) => {
381
460
return (
382
461
await fetch ( `/posts/marketplace/${ existingData ?. posts ?. [ 0 ] ?. id } ` )
@@ -427,6 +506,11 @@ export const AddEditModal: FC<{
427
506
'flex flex-col md:flex-row p-[10px] rounded-[4px] bg-primary gap-[20px]'
428
507
) }
429
508
>
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
+ ) }
430
514
< div
431
515
className = { clsx (
432
516
'flex flex-col gap-[16px] transition-all duration-700 whitespace-nowrap' ,
@@ -534,23 +618,28 @@ export const AddEditModal: FC<{
534
618
< div >
535
619
< div className = "flex gap-[4px]" >
536
620
< 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 >
554
643
555
644
{ showError &&
556
645
( ! p . content || p . content . length < 6 ) && (
@@ -649,6 +738,7 @@ export const AddEditModal: FC<{
649
738
className = "rounded-[4px] relative group"
650
739
disabled = {
651
740
selectedIntegrations . length === 0 ||
741
+ loading ||
652
742
! canSendForPublication
653
743
}
654
744
>
@@ -678,7 +768,11 @@ export const AddEditModal: FC<{
678
768
</ svg >
679
769
< div
680
770
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
+ ) }
682
776
>
683
777
Post now
684
778
</ div >
0 commit comments