@@ -22,7 +22,11 @@ import {
2222
2323import { combineEpics , ofType } from 'redux-observable' ;
2424
25- import { parseCommaSeparatedList } from '@/src/utils/app/common' ;
25+ import {
26+ doesHaveDotsInTheEnd ,
27+ isEntityNameOnSameLevelUnique ,
28+ parseCommaSeparatedList ,
29+ } from '@/src/utils/app/common' ;
2630import { constructPath } from '@/src/utils/app/file' ;
2731import {
2832 getActionsAddFoldersFromFolderId ,
@@ -50,6 +54,7 @@ import { UISelectors } from '@/src/store/ui/ui.selectors';
5054
5155import { DEFAULT_CONVERSATION_NAME } from '@/src/constants/default-ui-settings' ;
5256
57+ import { ImportExportActions } from '../actions' ;
5358import { AuthSelectors } from '../auth/auth.selectors' ;
5459import { ModelsSelectors } from '../models/models.selectors' ;
5560import { OverlayActions } from './overlay.reducers' ;
@@ -59,12 +64,18 @@ import {
5964 ChatOverlayOptions ,
6065 CreateConversationRequest ,
6166 CreateConversationResponse ,
67+ CreatePlaybackConversationRequest ,
68+ CreatePlaybackConversationResponse ,
69+ DeleteConversationRequest ,
70+ ExportConversationRequest ,
6271 Feature ,
6372 GetConversationsResponse ,
6473 GetMessagesResponse ,
6574 OverlayEvents ,
6675 OverlayRequest ,
6776 OverlayRequests ,
77+ RenameConversationRequest ,
78+ RenameConversationResponse ,
6879 Role ,
6980 SelectConversationRequest ,
7081 SelectConversationResponse ,
@@ -117,6 +128,47 @@ export const postMessageMapperEpic: AppEpic = (_, state$) =>
117128 } ) ,
118129 ) ;
119130 }
131+ case OverlayRequests . deleteConversation : {
132+ const options = payload as DeleteConversationRequest ;
133+
134+ return of (
135+ OverlayActions . deleteConversation ( {
136+ requestId,
137+ id : options . id ,
138+ } ) ,
139+ ) ;
140+ }
141+ case OverlayRequests . renameConversation : {
142+ const options = payload as RenameConversationRequest ;
143+
144+ return of (
145+ OverlayActions . renameConversation ( {
146+ requestId,
147+ id : options . id ,
148+ newName : options . newName ,
149+ } ) ,
150+ ) ;
151+ }
152+ case OverlayRequests . createPlaybackConversation : {
153+ const options = payload as CreatePlaybackConversationRequest ;
154+
155+ return of (
156+ OverlayActions . createPlaybackConversation ( {
157+ requestId,
158+ id : options . id ,
159+ } ) ,
160+ ) ;
161+ }
162+ case OverlayRequests . exportConversation : {
163+ const options = payload as ExportConversationRequest ;
164+
165+ return of (
166+ OverlayActions . exportConversation ( {
167+ requestId,
168+ id : options . id ,
169+ } ) ,
170+ ) ;
171+ }
120172 case OverlayRequests . setOverlayOptions : {
121173 const options = payload as ChatOverlayOptions ;
122174
@@ -301,6 +353,230 @@ const createConversationEffectEpic: AppEpic = (action$, state$) =>
301353 } ) ,
302354 ) ;
303355
356+ const deleteConversationEpic : AppEpic = ( action$ , state$ ) =>
357+ action$ . pipe (
358+ ofType ( OverlayActions . deleteConversation . type ) ,
359+ switchMap ( ( { payload : { requestId, id } } ) => {
360+ const hostDomain = OverlaySelectors . selectHostDomain ( state$ . value ) ;
361+ const conversation = ConversationsSelectors . selectConversation (
362+ state$ . value ,
363+ id ,
364+ ) ;
365+
366+ if ( ! conversation ) {
367+ console . warn ( `[Overlay] Conversation not exists with id '${ id } '` ) ;
368+
369+ return EMPTY ;
370+ }
371+
372+ return concat (
373+ of (
374+ ConversationsActions . deleteConversations ( {
375+ conversationIds : [ conversation . id ] ,
376+ } ) ,
377+ ) ,
378+ of (
379+ OverlayActions . sendPMResponse ( {
380+ type : OverlayRequests . deleteConversation ,
381+ requestParams : {
382+ requestId,
383+ hostDomain,
384+ } ,
385+ } ) ,
386+ ) ,
387+ ) ;
388+ } ) ,
389+ ) ;
390+
391+ const createPlaybackConversationEpic : AppEpic = ( action$ , state$ ) =>
392+ action$ . pipe (
393+ ofType ( OverlayActions . createPlaybackConversation . type ) ,
394+ switchMap ( ( { payload } ) => {
395+ const conversation = ConversationsSelectors . selectConversation (
396+ state$ . value ,
397+ payload . id ,
398+ ) ;
399+
400+ if ( ! conversation ) {
401+ console . warn (
402+ `[Overlay] Conversation not exists with id '${ payload . id } '` ,
403+ ) ;
404+
405+ return EMPTY ;
406+ }
407+
408+ return concat (
409+ of ( ConversationsActions . createNewPlaybackConversation ( conversation ) ) ,
410+ of ( OverlayActions . createPlaybackConversationEffect ( payload ) ) ,
411+ ) ;
412+ } ) ,
413+ ) ;
414+
415+ const createPlaybackConversationEffectEpic : AppEpic = ( action$ , state$ ) =>
416+ action$ . pipe (
417+ ofType ( OverlayActions . createPlaybackConversationEffect . type ) ,
418+ switchMap ( ( { payload : { requestId } } ) => {
419+ return action$ . pipe (
420+ ofType ( ConversationsActions . saveNewConversationSuccess . type ) ,
421+ takeUntil ( timer ( 10000 ) ) ,
422+ filter ( Boolean ) ,
423+ mergeMap ( ( { payload : { newConversation } } ) => {
424+ const hostDomain = OverlaySelectors . selectHostDomain ( state$ . value ) ;
425+
426+ const { bucket, parentPath } = splitEntityId ( newConversation . id ) ;
427+ const resultConversation = {
428+ ...newConversation ,
429+ bucket,
430+ parentPath,
431+ } ;
432+
433+ return concat (
434+ of ( UIActions . setScrollToEntityId ( newConversation . id ) ) ,
435+ of (
436+ OverlayActions . sendPMResponse ( {
437+ type : OverlayRequests . createPlaybackConversation ,
438+ requestParams : {
439+ requestId,
440+ hostDomain,
441+ payload : {
442+ conversation : resultConversation ,
443+ } as CreatePlaybackConversationResponse ,
444+ } ,
445+ } ) ,
446+ ) ,
447+ ) ;
448+ } ) ,
449+ ) ;
450+ } ) ,
451+ ) ;
452+
453+ const renameConversationEpic : AppEpic = ( action$ , state$ ) =>
454+ action$ . pipe (
455+ ofType ( OverlayActions . renameConversation . type ) ,
456+ switchMap ( ( { payload } ) => {
457+ const conversations = ConversationsSelectors . selectConversations (
458+ state$ . value ,
459+ ) ;
460+ const conversation = ConversationsSelectors . selectConversation (
461+ state$ . value ,
462+ payload . id ,
463+ ) ;
464+
465+ if ( ! conversation ) {
466+ console . warn (
467+ `[Overlay] Conversation not exists with id '${ payload . id } '` ,
468+ ) ;
469+
470+ return EMPTY ;
471+ }
472+
473+ if (
474+ ! isEntityNameOnSameLevelUnique (
475+ payload . newName ,
476+ conversation ,
477+ conversations ,
478+ ) ||
479+ doesHaveDotsInTheEnd ( payload . newName )
480+ ) {
481+ console . warn (
482+ '[Overlay] Conversation rename failed because new name is invalid' ,
483+ ) ;
484+
485+ return EMPTY ;
486+ }
487+
488+ return concat (
489+ of (
490+ ConversationsActions . updateConversation ( {
491+ id : conversation . id ,
492+ values : { name : payload . newName , isNameChanged : true } ,
493+ } ) ,
494+ ) ,
495+ of ( OverlayActions . renameConversationEffect ( payload ) ) ,
496+ ) ;
497+ } ) ,
498+ ) ;
499+
500+ const renameConversationEffectEpic : AppEpic = ( action$ , state$ ) =>
501+ action$ . pipe (
502+ ofType ( OverlayActions . renameConversationEffect . type ) ,
503+ switchMap ( ( { payload : { requestId } } ) => {
504+ return action$ . pipe (
505+ ofType ( ConversationsActions . updateConversationSuccess . type ) ,
506+ takeUntil ( timer ( 10000 ) ) ,
507+ filter ( Boolean ) ,
508+ mergeMap ( ( { payload : { id } } ) => {
509+ const conversation = ConversationsSelectors . selectConversation (
510+ state$ . value ,
511+ id ,
512+ ) ;
513+
514+ if ( ! conversation ) return EMPTY ;
515+
516+ const hostDomain = OverlaySelectors . selectHostDomain ( state$ . value ) ;
517+
518+ const { bucket, parentPath } = splitEntityId ( conversation . id ) ;
519+ const resultConversation = {
520+ ...conversation ,
521+ bucket,
522+ parentPath,
523+ } ;
524+
525+ return concat (
526+ of ( UIActions . setScrollToEntityId ( conversation . id ) ) ,
527+ of (
528+ OverlayActions . sendPMResponse ( {
529+ type : OverlayRequests . renameConversation ,
530+ requestParams : {
531+ requestId,
532+ hostDomain,
533+ payload : {
534+ conversation : resultConversation ,
535+ } as RenameConversationResponse ,
536+ } ,
537+ } ) ,
538+ ) ,
539+ ) ;
540+ } ) ,
541+ ) ;
542+ } ) ,
543+ ) ;
544+
545+ const exportConversationEpic : AppEpic = ( action$ , state$ ) =>
546+ action$ . pipe (
547+ ofType ( OverlayActions . exportConversation . type ) ,
548+ switchMap ( ( { payload : { requestId, id } } ) => {
549+ const hostDomain = OverlaySelectors . selectHostDomain ( state$ . value ) ;
550+ const conversation = ConversationsSelectors . selectConversation (
551+ state$ . value ,
552+ id ,
553+ ) ;
554+
555+ if ( ! conversation ) {
556+ console . warn ( `[Overlay] Conversation not exists with id '${ id } '` ) ;
557+
558+ return EMPTY ;
559+ }
560+
561+ return concat (
562+ of (
563+ ImportExportActions . exportConversation ( {
564+ conversationId : conversation . id ,
565+ } ) ,
566+ ) ,
567+ of (
568+ OverlayActions . sendPMResponse ( {
569+ type : OverlayRequests . exportConversation ,
570+ requestParams : {
571+ requestId,
572+ hostDomain,
573+ } ,
574+ } ) ,
575+ ) ,
576+ ) ;
577+ } ) ,
578+ ) ;
579+
304580const selectConversationEpic : AppEpic = ( action$ , state$ ) =>
305581 action$ . pipe (
306582 ofType ( OverlayActions . selectConversation . type ) ,
@@ -710,6 +986,12 @@ export const OverlayEpics = combineEpics(
710986 createConversationEpic ,
711987 createConversationEffectEpic ,
712988 selectConversationEpic ,
989+ deleteConversationEpic ,
990+ createPlaybackConversationEpic ,
991+ createPlaybackConversationEffectEpic ,
992+ exportConversationEpic ,
993+ renameConversationEpic ,
994+ renameConversationEffectEpic ,
713995
714996 initOverlayEpic ,
715997 sendPMEventEpic ,
0 commit comments