From 63c5332b967e93f597ee1863383f7643e69d956e Mon Sep 17 00:00:00 2001 From: Futa Arai Date: Mon, 24 Apr 2023 12:25:08 +0000 Subject: [PATCH 1/4] refs 121002: show alert when trying to reload or move to different page when commenting --- apps/app/src/components/PageComment/CommentEditor.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/app/src/components/PageComment/CommentEditor.tsx b/apps/app/src/components/PageComment/CommentEditor.tsx index 06a65733c67..59ee53de4c6 100644 --- a/apps/app/src/components/PageComment/CommentEditor.tsx +++ b/apps/app/src/components/PageComment/CommentEditor.tsx @@ -16,14 +16,13 @@ import { useCurrentUser, useIsSlackConfigured, useIsUploadableFile, useIsUploadableImage, } from '~/stores/context'; -import { useSWRxSlackChannels, useIsSlackEnabled } from '~/stores/editor'; +import { useSWRxSlackChannels, useIsSlackEnabled, useIsEnabledUnsavedWarning } from '~/stores/editor'; import { useCurrentPagePath } from '~/stores/page'; import { CustomNavTab } from '../CustomNavigation/CustomNav'; import { NotAvailableForGuest } from '../NotAvailableForGuest'; import Editor from '../PageEditor/Editor'; - import { CommentPreview } from './CommentPreview'; import styles from './CommentEditor.module.scss'; @@ -70,6 +69,7 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => { const { data: isSlackConfigured } = useIsSlackConfigured(); const { data: isUploadableFile } = useIsUploadableFile(); const { data: isUploadableImage } = useIsUploadableImage(); + const { mutate: mutateIsEnabledUnsavedWarning } = useIsEnabledUnsavedWarning(); const [isReadyToUse, setIsReadyToUse] = useState(!isForNewComment); const [comment, setComment] = useState(commentBody ?? ''); @@ -237,7 +237,10 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => { ); }, []); - const onChangeHandler = useCallback((newValue: string) => setComment(newValue), []); + const onChangeHandler = useCallback((newValue: string, isClean: boolean) => { + setComment(newValue); + mutateIsEnabledUnsavedWarning(!isClean); + }, [mutateIsEnabledUnsavedWarning]); const renderReady = () => { const commentPreview = getCommentHtml(); From b5aaa651e7198e50fcd6caabcb81337adfbf9a45 Mon Sep 17 00:00:00 2001 From: Futa Arai Date: Tue, 25 Apr 2023 14:14:12 +0000 Subject: [PATCH 2/4] refs 121002: apply feedback --- .../components/PageComment/CommentEditor.tsx | 21 ++++++++++++++---- apps/app/src/stores/comment.tsx | 22 +++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/apps/app/src/components/PageComment/CommentEditor.tsx b/apps/app/src/components/PageComment/CommentEditor.tsx index 59ee53de4c6..18962a7af59 100644 --- a/apps/app/src/components/PageComment/CommentEditor.tsx +++ b/apps/app/src/components/PageComment/CommentEditor.tsx @@ -11,7 +11,7 @@ import * as toastr from 'toastr'; import { apiPostForm } from '~/client/util/apiv1-client'; import { IEditorMethods } from '~/interfaces/editor-methods'; -import { useSWRxPageComment } from '~/stores/comment'; +import { useSWRxPageComment, useSWRxEditingCommentsNum } from '~/stores/comment'; import { useCurrentUser, useIsSlackConfigured, useIsUploadableFile, useIsUploadableImage, @@ -70,12 +70,17 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => { const { data: isUploadableFile } = useIsUploadableFile(); const { data: isUploadableImage } = useIsUploadableImage(); const { mutate: mutateIsEnabledUnsavedWarning } = useIsEnabledUnsavedWarning(); + const { + increment: incrementEditingCommentsNum, + decrement: decrementEditingCommentsNum, + } = useSWRxEditingCommentsNum(); const [isReadyToUse, setIsReadyToUse] = useState(!isForNewComment); const [comment, setComment] = useState(commentBody ?? ''); const [activeTab, setActiveTab] = useState('comment_editor'); const [error, setError] = useState(); const [slackChannels, setSlackChannels] = useState(''); + const [incremented, setIncremented] = useState(false); const editorRef = useRef(null); @@ -102,7 +107,7 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => { setSlackChannels(slackChannels); }, []); - const initializeEditor = useCallback(() => { + const initializeEditor = useCallback(async() => { setComment(''); setActiveTab('comment_editor'); setError(undefined); @@ -110,7 +115,11 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => { // reset value if (editorRef.current == null) { return } editorRef.current.setValue(''); - }, [initializeSlackEnabled]); + const editingCommentsNum = await decrementEditingCommentsNum(); + if (editingCommentsNum === 0) { + mutateIsEnabledUnsavedWarning(false); // must be after clearing comment or else onChange will override bool + } + }, [initializeSlackEnabled, mutateIsEnabledUnsavedWarning, decrementEditingCommentsNum]); const cancelButtonClickedHandler = useCallback(() => { // change state to not ready @@ -239,8 +248,12 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => { const onChangeHandler = useCallback((newValue: string, isClean: boolean) => { setComment(newValue); + if (!isClean && !incremented) { + incrementEditingCommentsNum(); + setIncremented(true); + } mutateIsEnabledUnsavedWarning(!isClean); - }, [mutateIsEnabledUnsavedWarning]); + }, [mutateIsEnabledUnsavedWarning, incrementEditingCommentsNum, incremented]); const renderReady = () => { const commentPreview = getCommentHtml(); diff --git a/apps/app/src/stores/comment.tsx b/apps/app/src/stores/comment.tsx index 0cce2b94a1e..d8f8dcc10d6 100644 --- a/apps/app/src/stores/comment.tsx +++ b/apps/app/src/stores/comment.tsx @@ -5,6 +5,8 @@ import { apiGet, apiPost } from '~/client/util/apiv1-client'; import { ICommentHasIdList, ICommentPostArgs } from '../interfaces/comment'; +import { useStaticSWR } from './use-static-swr'; + type IResponseComment = { comments: ICommentHasIdList, ok: boolean, @@ -62,3 +64,23 @@ export const useSWRxPageComment = (pageId: Nullable): SWRResponse, + decrement(): Promise, +} + +export const useSWRxEditingCommentsNum = (): SWRResponse & EditingCommentsNumOperation => { + const swrResponse = useStaticSWR('editingCommentsNum', undefined, { fallbackData: 0 }); + + return { + ...swrResponse, + increment: () => swrResponse.mutate(swrResponse.data ? swrResponse.data + 1 : 1), + decrement: () => { + if (swrResponse.data != null && swrResponse.data > 0) { + return swrResponse.mutate(swrResponse.data - 1); + } + return swrResponse.mutate(0); + }, + }; +}; From 0547da33b0d889a1d0b55ee881b34386bd0b6ed3 Mon Sep 17 00:00:00 2001 From: Futa Arai Date: Fri, 28 Apr 2023 00:56:13 +0000 Subject: [PATCH 3/4] refs 121002: initialize editor on cancel --- apps/app/src/components/PageComment/CommentEditor.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/app/src/components/PageComment/CommentEditor.tsx b/apps/app/src/components/PageComment/CommentEditor.tsx index 18962a7af59..67381e43d05 100644 --- a/apps/app/src/components/PageComment/CommentEditor.tsx +++ b/apps/app/src/components/PageComment/CommentEditor.tsx @@ -128,10 +128,12 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => { setIsReadyToUse(false); } + initializeEditor(); + if (onCancelButtonClicked != null) { onCancelButtonClicked(); } - }, [isForNewComment, onCancelButtonClicked]); + }, [isForNewComment, onCancelButtonClicked, initializeEditor]); const postCommentHandler = useCallback(async() => { try { From b432da9fe5ba033c8a8818e87331382be0c72731 Mon Sep 17 00:00:00 2001 From: Futa Arai Date: Fri, 28 Apr 2023 10:29:30 +0000 Subject: [PATCH 4/4] refs 121002: refactor --- apps/app/src/stores/comment.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/app/src/stores/comment.tsx b/apps/app/src/stores/comment.tsx index d8f8dcc10d6..a97f7840b0d 100644 --- a/apps/app/src/stores/comment.tsx +++ b/apps/app/src/stores/comment.tsx @@ -75,12 +75,10 @@ export const useSWRxEditingCommentsNum = (): SWRResponse & Editin return { ...swrResponse, - increment: () => swrResponse.mutate(swrResponse.data ? swrResponse.data + 1 : 1), + increment: () => swrResponse.mutate((swrResponse.data ?? 0) + 1), decrement: () => { - if (swrResponse.data != null && swrResponse.data > 0) { - return swrResponse.mutate(swrResponse.data - 1); - } - return swrResponse.mutate(0); + const newValue = (swrResponse.data ?? 0) - 1; + return swrResponse.mutate(Math.max(0, newValue)); }, }; };