From ebeb4a22415cb54fb5a6c0c43b6dd30d88a0188b Mon Sep 17 00:00:00 2001 From: Coki <92775570+HashCookie@users.noreply.github.com> Date: Sat, 23 Nov 2024 20:41:24 +0800 Subject: [PATCH] feat: fix bug to prevent shared content from being overridden by example content (#169) * chore: update casbin dependency to version 5.36.0 * feat: enhance shared content loading --- app/components/editor/hooks/useIndex.tsx | 48 ++++++++++++------------ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/app/components/editor/hooks/useIndex.tsx b/app/components/editor/hooks/useIndex.tsx index 2c903f1..a49aff5 100644 --- a/app/components/editor/hooks/useIndex.tsx +++ b/app/components/editor/hooks/useIndex.tsx @@ -1,4 +1,4 @@ -import React, { isValidElement, ReactNode, useEffect, useState } from 'react'; +import React, { isValidElement, ReactNode, useEffect, useRef, useState } from 'react'; import { defaultCustomConfig, defaultEnforceContext, example, ModelKind } from '@/app/components/editor/casbin-mode/example'; import { ShareFormat } from '@/app/components/editor/hooks/useShareInfo'; import { defaultEnforceContextData } from '@/app/components/editor/hooks/useSetupEnforceContext'; @@ -13,6 +13,10 @@ export default function useIndex() { const [customConfig, setCustomConfig] = useState(''); const [share, setShare] = useState(''); const [enforceContextData, setEnforceContextData] = useState(new Map(defaultEnforceContextData)); + const loadState = useRef<{ + loadedHash?: string; + content?: ShareFormat; + }>({}); function setPolicyPersistent(text: string): void { setPolicy(text); @@ -35,45 +39,38 @@ export default function useIndex() { setEnforceContextData(new Map(map)); } + // Load shared content from dpaste.com useEffect(() => { const hash = window.location.hash.slice(1); - if (hash) { + if (hash && hash !== loadState.current.loadedHash) { + loadState.current.loadedHash = hash; setEcho(
Loading Shared Content...
); fetch(`https://dpaste.com/${hash}.txt`) .then((resp) => { - if (!resp.ok) { - throw new Error(`HTTP error! status: ${resp.status}`); - } - return resp.text(); + return resp.ok ? resp.text() : Promise.reject(`HTTP error: ${resp.status}`); }) .then((content) => { - const sharedContent = JSON.parse(content) as ShareFormat; - // Use empty string as default value with type checking - setPolicyPersistent(sharedContent.policy ?? ''); - setModelTextPersistent(sharedContent.model ?? ''); - setCustomConfigPersistent(sharedContent.customConfig ?? ''); - setRequestPersistent(sharedContent.request ?? ''); - // Make sure it's a valid ModelKind type - if (sharedContent.modelKind && example[sharedContent.modelKind as ModelKind]) { - setModelKind(sharedContent.modelKind as ModelKind); - } else { - setModelKind('basic'); // Use Default - } - window.location.hash = ''; // prevent duplicate load + const parsed = JSON.parse(content) as ShareFormat; + loadState.current.content = parsed; + const newModelKind = parsed?.modelKind && parsed.modelKind in example ? (parsed.modelKind as ModelKind) : 'basic'; + setModelKind(newModelKind); setEcho(
Shared Content Loaded.
); }) - .catch(() => { - setEcho(
Failed to load Shared Content.
); + .catch((error) => { + return setEcho(
Failed to load: {error}
); }); } }, []); + // Set the editor content based on the shared content useEffect(() => { - setPolicy(example[modelKind].policy); - setModelText(example[modelKind].model); - setRequest(example[modelKind].request); - setCustomConfig(defaultCustomConfig); + const shared = loadState.current.content; + setPolicy(shared?.policy ?? example[modelKind].policy); + setModelText(shared?.model ?? example[modelKind].model); + setRequest(shared?.request ?? example[modelKind].request); + setCustomConfig(shared?.customConfig ?? defaultCustomConfig); setEnforceContextData(new Map(Object.entries(JSON.parse(example[modelKind].enforceContext || defaultEnforceContext)))); + loadState.current.content = undefined; }, [modelKind]); function handleShare(v: ReactNode | string) { @@ -85,6 +82,7 @@ export default function useIndex() { setEcho(
{`Shared at ${currentPath}#${v}`}
); } } + return { modelKind, setModelKind, modelText, setModelText, policy, setPolicy, request, setRequest, echo, setEcho, requestResult, setRequestResult, customConfig, setCustomConfig, share, setShare,