From 50cf141dac3dccba24a12f2ca7fa3fd1275b1c47 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Sun, 27 Apr 2025 23:21:51 +0700 Subject: [PATCH] feat: convert comments into one post --- .../components/launches/add.edit.model.tsx | 28 +++++++++++++++++++ .../src/components/launches/editor.tsx | 13 +++++++-- .../src/components/launches/merge.post.tsx | 19 +++++++++++++ .../providers/high.order.provider.tsx | 27 ++++++++++++++++++ 4 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 apps/frontend/src/components/launches/merge.post.tsx diff --git a/apps/frontend/src/components/launches/add.edit.model.tsx b/apps/frontend/src/components/launches/add.edit.model.tsx index 554bfd7c..5cca3a2d 100644 --- a/apps/frontend/src/components/launches/add.edit.model.tsx +++ b/apps/frontend/src/components/launches/add.edit.model.tsx @@ -59,6 +59,7 @@ import { DropFiles } from '@gitroom/frontend/components/layout/drop.files'; import { SelectCustomer } from '@gitroom/frontend/components/launches/select.customer'; import { TagsComponent } from './tags.component'; import { RepeatComponent } from '@gitroom/frontend/components/launches/repeat.component'; +import { MergePost } from '@gitroom/frontend/components/launches/merge.post'; function countCharacters(text: string, type: string): number { if (type !== 'x') { @@ -136,6 +137,27 @@ export const AddEditModal: FC<{ // hook to test if the top editor should be hidden const showHide = useHideTopEditor(); + // merge all posts and delete all the comments + const merge = useCallback(() => { + setValue( + value.reduce( + (all, current) => { + all[0].content = all[0].content + current.content + '\n'; + all[0].image = [...all[0].image, ...(current.image || [])]; + + return all; + }, + [ + { + content: '', + id: value[0].id, + image: [] as { id: string; path: string }[], + }, + ] + ) + ); + }, [value]); + const [showError, setShowError] = useState(false); // are we in edit mode? @@ -659,6 +681,7 @@ Here are the things you can do: order={index} height={value.length > 1 ? 150 : 250} value={p.content} + totalPosts={value.length} preview="edit" onPaste={pasteImages(index, p.image || [])} // @ts-ignore @@ -729,6 +752,11 @@ Here are the things you can do: ))} + {value.length > 1 && ( +
+ +
+ )} ) : null} diff --git a/apps/frontend/src/components/launches/editor.tsx b/apps/frontend/src/components/launches/editor.tsx index 63d59c1e..fe022144 100644 --- a/apps/frontend/src/components/launches/editor.tsx +++ b/apps/frontend/src/components/launches/editor.tsx @@ -15,13 +15,19 @@ import { SignatureBox } from '@gitroom/frontend/components/signature'; export const Editor = forwardRef< RefMDEditor, - MDEditorProps & { order: number; currentWatching: string; isGlobal: boolean } + MDEditorProps & { + order: number; + currentWatching: string; + isGlobal: boolean; + totalPosts: number; + } >( ( props: MDEditorProps & { order: number; currentWatching: string; isGlobal: boolean; + totalPosts: number; }, ref: React.ForwardedRef ) => { @@ -36,7 +42,7 @@ export const Editor = forwardRef< content: props.value, order: props.order, allowAddContent: props?.value?.length === 0, - }) + }), }); useCopilotAction({ @@ -97,7 +103,8 @@ export const Editor = forwardRef< disableBranding={true} ref={newRef} className={clsx( - '!min-h-40 !max-h-80 p-2 overflow-x-hidden scrollbar scrollbar-thumb-[#612AD5] bg-customColor2 outline-none' + '!min-h-40 p-2 overflow-x-hidden scrollbar scrollbar-thumb-[#612AD5] bg-customColor2 outline-none', + props.totalPosts > 1 && '!max-h-80' )} value={props.value} onChange={(e) => { diff --git a/apps/frontend/src/components/launches/merge.post.tsx b/apps/frontend/src/components/launches/merge.post.tsx new file mode 100644 index 00000000..119094cb --- /dev/null +++ b/apps/frontend/src/components/launches/merge.post.tsx @@ -0,0 +1,19 @@ +import { Button } from '@gitroom/react/form/button'; +import { deleteDialog } from '@gitroom/react/helpers/delete.dialog'; +import { FC, useCallback } from 'react'; + +export const MergePost: FC<{merge: () => void}> = (props) => { + const { merge } = props; + + const notReversible = useCallback(async () => { + if (await deleteDialog('Are you sure you want to merge all comments into one post? This action is not reversible.', 'Yes')) { + merge(); + } + }, [merge]); + + return ( + + ); +}; diff --git a/apps/frontend/src/components/launches/providers/high.order.provider.tsx b/apps/frontend/src/components/launches/providers/high.order.provider.tsx index 9c5bd66b..9010519b 100644 --- a/apps/frontend/src/components/launches/providers/high.order.provider.tsx +++ b/apps/frontend/src/components/launches/providers/high.order.provider.tsx @@ -43,6 +43,7 @@ import { DropFiles } from '@gitroom/frontend/components/layout/drop.files'; import { useFetch } from '@gitroom/helpers/utils/custom.fetch'; import useSWR from 'swr'; import { InternalChannels } from '@gitroom/frontend/components/launches/internal.channels'; +import { MergePost } from '@gitroom/frontend/components/launches/merge.post'; // Simple component to change back to settings on after changing tab export const SetTab: FC<{ changeTab: () => void }> = (props) => { @@ -176,6 +177,26 @@ export const withProvider = function ( [InPlaceValue] ); + const merge = useCallback(() => { + setInPlaceValue( + InPlaceValue.reduce( + (all, current) => { + all[0].content = all[0].content + current.content + '\n'; + all[0].image = [...all[0].image, ...(current.image || [])]; + + return all; + }, + [ + { + content: '', + id: InPlaceValue[0].id, + image: [] as { id: string; path: string }[], + }, + ] + ) + ); + }, [InPlaceValue]); + const changeImage = useCallback( (index: number) => (newValue: { @@ -464,6 +485,7 @@ export const withProvider = function ( order={index} height={InPlaceValue.length > 1 ? 200 : 250} value={val.content} + totalPosts={InPlaceValue.length} commands={[ // ...commands // .getCommands() @@ -545,6 +567,11 @@ export const withProvider = function ( ))} + {InPlaceValue.length > 1 && ( +
+ +
+ )} , document.querySelector('#renderEditor')!