in apps/chat/src/store/conversations/conversations.epics.ts [625:825]
messagesStack: excludeSystemMessages(conversation.messages),
activePlaybackIndex: 0,
isPlayback: true,
},
isReplay: false,
isPlayback: true,
});
return of(
ConversationsActions.saveNewConversation({
newConversation,
}),
);
}),
);
const duplicateConversationEpic: AppEpic = (action$, state$) =>
action$.pipe(
filter(ConversationsActions.duplicateConversation.match),
concatMap(({ payload }) =>
forkJoin({
conversation: getOrUploadConversation(payload, state$.value).pipe(
map((data) => data.conversation),
),
}),
),
concatMap(({ conversation }) => {
if (!conversation) {
return of(
UIActions.showErrorToast(
translate(
'It looks like this conversation has been deleted. Please reload the page',
),
),
);
}
const conversations = ConversationsSelectors.selectConversations(
state$.value,
);
const conversationFolderId = isEntityIdExternal(conversation)
? getConversationRootId() // duplicate external entities in the root only
: conversation.folderId;
const newConversation: Conversation = regenerateConversationId({
...omit(conversation, ['publicationInfo']),
...resetShareEntity,
folderId: conversationFolderId,
name: generateNextName(
DEFAULT_CONVERSATION_NAME,
conversation.name,
conversations.filter((c) => c.folderId === conversationFolderId), // only root conversations for external entities
),
lastActivityDate: Date.now(),
});
return concat(
// optimistic update to reserve conversation id
of(
ConversationsActions.addConversations({
conversations: [newConversation],
}),
),
of(
ConversationsActions.saveNewConversation({
newConversation,
selectedIdToReplaceWithNewOne: conversation.id,
}),
),
);
}),
);
const createNewConversationsSuccessEpic: AppEpic = (action$) =>
action$.pipe(
filter(ConversationsActions.createNewConversations.match),
switchMap(() => of(ConversationsActions.resetChosenConversations())),
);
const saveNewConversationEpic: AppEpic = (action$) =>
action$.pipe(
filter(ConversationsActions.saveNewConversation.match),
mergeMap(({ payload }) =>
ConversationService.createConversation(payload.newConversation).pipe(
switchMap(() =>
of(ConversationsActions.saveNewConversationSuccess(payload)),
),
catchError((err) => {
console.error(err);
return of(
UIActions.showErrorToast(
translate(
'An error occurred while saving the conversation. Most likely the conversation already exists. Please refresh the page.',
),
),
);
}),
),
),
);
const deleteFolderEpic: AppEpic = (action$, state$) =>
action$.pipe(
filter(ConversationsActions.deleteFolder.match),
switchMap(({ payload }) =>
forkJoin({
folderId: of(payload.folderId),
conversations: ConversationService.getConversations(
payload.folderId,
true,
).pipe(
catchError((err) => {
console.error('Error during delete folder:', err);
return of([]);
}),
),
folders: of(ConversationsSelectors.selectFolders(state$.value)),
}),
),
switchMap(({ folderId, conversations, folders }) => {
const actions: Observable<AnyAction>[] = [];
const localConversations =
ConversationsSelectors.selectLocalConversations(state$.value); // TODO: remove in https://github.com/epam/ai-dial-chat/issues/2651
const conversationIds = [...conversations, ...localConversations].map(
(conv) => conv.id,
);
if (conversationIds.length) {
actions.push(
of(ConversationsActions.deleteConversations({ conversationIds })),
);
} else
actions.push(
of(
ConversationsActions.deleteConversationsComplete({
conversationIds: new Set([]),
}),
),
);
return concat(
of(
ConversationsActions.setFolders({
folders: folders.filter(
(folder) =>
folder.id !== folderId && !folder.id.startsWith(`${folderId}/`),
),
}),
),
...actions,
);
}),
);
const updateFolderEpic: AppEpic = (action$, state$) =>
action$.pipe(
filter(ConversationsActions.updateFolder.match),
switchMap(({ payload }) => {
const folder = getFolderFromId(payload.folderId, FolderType.Chat);
const newFolder = addGeneratedFolderId({ ...folder, ...payload.values });
if (payload.folderId === newFolder.id) {
return EMPTY;
}
return ConversationService.getConversations(payload.folderId, true).pipe(
switchMap((conversations) => {
const updateFolderId = updateMovedFolderId.bind(
null,
payload.folderId,
newFolder.id,
);
const updateEntityId = updateMovedEntityId.bind(
null,
payload.folderId,
newFolder.id,
);
const folders = ConversationsSelectors.selectFolders(state$.value);
const allConversations = ConversationsSelectors.selectConversations(
state$.value,
);
const openedFoldersIds = UISelectors.selectOpenedFoldersIds(
FeatureType.Chat,
)(state$.value);
const selectedConversationsIds =
ConversationsSelectors.selectSelectedConversationsIds(state$.value);
const { updatedFolders, updatedOpenedFoldersIds } =
updateEntitiesFoldersAndIds(
conversations,
folders,
updateFolderId,
openedFoldersIds,
);
const updatedConversations = combineEntities(
allConversations.map((conv) =>
regenerateConversationId({