Skip to content

Commit

Permalink
fix copy input / scribble bug; allow multiple default values
Browse files Browse the repository at this point in the history
  • Loading branch information
thecodingwizard committed Aug 23, 2023
1 parent ff2ac69 commit 73cdded
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 17 deletions.
15 changes: 6 additions & 9 deletions src/components/RealtimeEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,13 @@ const WEBSOCKET_SERVER = SHOULD_USE_DEV_YJS_SERVER

const RealtimeEditor = ({
onMount,
/**
* Warning: with the current implementation (EditorContext.doNotInitializeCodeRef),
* only one realtime editor can have defaultValue (the main code editor).
*/
defaultValue,
yjsDocumentId,
useEditorWithVim = false,
dataTestId = '',
...props
}: RealtimeEditorProps): JSX.Element => {
const { doNotInitializeCodeRef } = useEditorContext();
const { doNotInitializeTheseFileIdsRef } = useEditorContext();
const [editor, setEditor] =
useState<monaco.editor.IStandaloneCodeEditor | null>(null);
const { userData, firebaseUser } = useUserContext();
Expand Down Expand Up @@ -126,17 +122,18 @@ const RealtimeEditor = ({
);
provider.on('sync', (isSynced: boolean) => {
// Handle file initialization
// We need to check for doNotInitializeCodeRef.current here
// We need to check for doNotInitializeTheseFileIdsRef.current here
// to make sure we're the client that's supposed to initialize the document.
// This is to prevent multiple clients from initializing the document when the language changes.
// See EditorContext.tsx for more information
if (isSynced && defaultValue && !doNotInitializeCodeRef.current) {
if (isSynced && !doNotInitializeTheseFileIdsRef.current[yjsDocumentId]) {
const isInitializedMap = ydocument.getMap('isInitialized');
if (!isInitializedMap.get('isInitialized')) {
isInitializedMap.set('isInitialized', true);
if (monacoText.length === 0) monacoText.insert(0, defaultValue ?? '');
if (monacoText.length === 0 && defaultValue)
monacoText.insert(0, defaultValue ?? '');
}
doNotInitializeCodeRef.current = true;
doNotInitializeTheseFileIdsRef.current[yjsDocumentId] = true;
}
setIsSynced(isSynced);
setLoading(false);
Expand Down
16 changes: 8 additions & 8 deletions src/context/EditorContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,19 @@ export type EditorContextType = {
fileData: FileData;
updateFileData: (firebaseUpdateData: Partial<FileData>) => Promise<any>;
/**
* Maps YJS File ID ==> true / false
* If file ID is not in the map, assume it's false
*
* If true, this client should NOT initialize the code if it's empty.
* This solves the bug that if multiple people are on the same document,
* and the document changes languages, every client will try to initialize
* the code (resuting in multiple templates being inserted).
*
* Instead, after the file is loaded & synced, doNotInitializeCode is set
* Instead, after the file is loaded & synced, doNotInitializeTheseFileIds is set
* to true. Then, if the language is changed, the client who triggered the
* language change (and only that client) will have this set to false.
*
* Note that with our current implementation, only one defaultValue will work
* (ie. you can only have one RealtimeEdtior component with a defaultValue)
*/
doNotInitializeCodeRef: MutableRefObject<boolean>;
doNotInitializeTheseFileIdsRef: MutableRefObject<Record<string, boolean>>;
};

const EditorContext = createContext<EditorContextType | null>(null);
Expand Down Expand Up @@ -92,7 +92,7 @@ export function EditorProvider({
const { userData } = useUserContext();
const [fileData, setFileData] = useState<FileData | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const doNotInitializeCodeRef = useRef<boolean>(false);
const doNotInitializeTheseFileIdsRef = useRef<Record<string, boolean>>({});

useEffect(() => {
setLoading(true);
Expand Down Expand Up @@ -132,8 +132,8 @@ export function EditorProvider({
);

const editorContextValue = useMemo(() => {
return { fileData, updateFileData, doNotInitializeCodeRef };
}, [fileData, updateFileData, doNotInitializeCodeRef]);
return { fileData, updateFileData, doNotInitializeTheseFileIdsRef };
}, [fileData, updateFileData, doNotInitializeTheseFileIdsRef]);

if (loading) {
return <>{loadingUI}</>;
Expand Down

0 comments on commit 73cdded

Please sign in to comment.