From 56c0b7f3ec9ca23498e74686ef5e01aa4a0ccc6d Mon Sep 17 00:00:00 2001
From: wnhlee <2wheeh@gmail.com>
Date: Wed, 20 Mar 2024 22:27:44 +0900
Subject: [PATCH] feat: add EditableContext
---
.../components/review/client/review-title.tsx | 4 ++
ui/src/context/editor/editable-context.tsx | 50 +++++++++++++++++++
.../hooks/review/use-update-review-button.ts | 3 ++
3 files changed, 57 insertions(+)
create mode 100644 ui/src/context/editor/editable-context.tsx
diff --git a/ui/src/components/review/client/review-title.tsx b/ui/src/components/review/client/review-title.tsx
index 6ef98248..f9dc31f3 100644
--- a/ui/src/components/review/client/review-title.tsx
+++ b/ui/src/components/review/client/review-title.tsx
@@ -7,6 +7,7 @@ import { useDebouncedCallback } from '@/hooks/common/use-debounced-callback';
import { MAX_TITLE_LENGTH } from '@/lib/constants/review';
import { MAX_MOVIE_NAME_LENGTH } from '@/lib/constants/common';
import { normalizeWhitespace } from '@/lib/utils/common/normalizeWhitespace';
+import { useEditable } from '@/context/editor/editable-context';
export default function ReviewTitle({
placeholder,
@@ -40,6 +41,8 @@ export default function ReviewTitle({
setValue(newText);
};
+ const { isEditable } = useEditable() ?? {};
+
return (
);
}
diff --git a/ui/src/context/editor/editable-context.tsx b/ui/src/context/editor/editable-context.tsx
new file mode 100644
index 00000000..c5f79860
--- /dev/null
+++ b/ui/src/context/editor/editable-context.tsx
@@ -0,0 +1,50 @@
+'use client';
+
+import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';
+import { useEditorRef } from '@/context/editor/editor-ref-context';
+
+interface ContextShape {
+ isEditable: boolean;
+ authorId: string;
+ setIsEditable?: (isEditable: boolean) => void;
+}
+
+const EditableContext = createContext(null);
+
+export function EditableProvider({
+ children,
+ authorId,
+}: {
+ children: ReactNode;
+ authorId: string;
+}) {
+ const { editorRef } = useEditorRef() ?? {};
+
+ if (!editorRef) {
+ throw new Error('EditableProvider must be used within a EditorProvider');
+ }
+
+ const editor = editorRef.current;
+
+ const [isEditable, _setIsEditable] = useState(() => (editor ? editor.isEditable() : false));
+
+ useEffect(
+ () =>
+ editor?.registerEditableListener((editable) => {
+ _setIsEditable(editable);
+ }),
+ [editor]
+ );
+
+ const setIsEditable = (isEditable: boolean) => editor?.setEditable(isEditable);
+
+ return (
+
+ {children}
+
+ );
+}
+
+export function useEditable() {
+ return useContext(EditableContext);
+}
diff --git a/ui/src/hooks/review/use-update-review-button.ts b/ui/src/hooks/review/use-update-review-button.ts
index b7f9e673..fecca318 100644
--- a/ui/src/hooks/review/use-update-review-button.ts
+++ b/ui/src/hooks/review/use-update-review-button.ts
@@ -4,12 +4,14 @@ import { useReview } from '@/context/review/review-context';
import { useToast } from '@/context/common/toast-context';
import { useApiError } from '@/hooks/common/use-api-error';
import { updateReview } from '@/lib/apis/review/client';
+import { useEditable } from '@/context/editor/editable-context';
export function useUpdateReivewButton() {
const router = useRouter();
const { id } = useParams();
const { emitToast } = useToast();
+ const { setIsEditable } = useEditable() ?? {};
const { disabled, setDisabled, validateAndGetData } = useReview();
const { handleApiError } = useApiError();
@@ -23,6 +25,7 @@ export function useUpdateReivewButton() {
try {
await updateReview(Number(id), data);
+ setIsEditable?.(false);
emitToast('리뷰 수정 완료', 'success');
router.refresh();
} catch (error) {