mirror of https://github.com/buster-so/buster.git
Merge pull request #811 from buster-so/big-nate-bus-1676-add-undo-redo
Big nate bus 1676 add undo redo
This commit is contained in:
commit
1dcd2c92d5
|
@ -36,6 +36,7 @@ import { useBusterNotifications } from '@/context/BusterNotifications';
|
|||
import { useGetChatId } from '@/context/Chats/useGetChatId';
|
||||
import { useReportPageExport } from '@/context/Reports/useReportPageExport';
|
||||
import { useMemoizedFn } from '@/hooks/useMemoizedFn';
|
||||
import { useIsMac } from '@/hooks/usePlatform';
|
||||
import { useEditorContext } from '@/layouts/AssetContainer/ReportAssetContainer';
|
||||
import { canEdit, getIsEffectiveOwner } from '@/lib/share';
|
||||
|
||||
|
@ -386,28 +387,41 @@ const useDownloadPdfSelectMenu = ({
|
|||
};
|
||||
|
||||
const useUndoRedo = (): IDropdownItems => {
|
||||
const { editor, setEditor } = useEditorContext();
|
||||
return createDropdownItems([
|
||||
{
|
||||
label: 'Undo',
|
||||
value: 'undo',
|
||||
icon: <Undo />,
|
||||
onClick: () => {
|
||||
console.log('Undo');
|
||||
console.log(editor);
|
||||
// editor?.tf.undo();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
value: 'redo',
|
||||
icon: <Redo />,
|
||||
onClick: () => {
|
||||
console.log('Redo');
|
||||
// editor?.tf.redo();
|
||||
},
|
||||
},
|
||||
]);
|
||||
const { editor } = useEditorContext();
|
||||
const isMac = useIsMac();
|
||||
const getEditor = () => {
|
||||
if (!editor?.current) {
|
||||
console.warn('Editor is not defined');
|
||||
return;
|
||||
}
|
||||
return editor?.current;
|
||||
};
|
||||
return useMemo(
|
||||
() =>
|
||||
createDropdownItems([
|
||||
{
|
||||
label: 'Undo',
|
||||
value: 'undo',
|
||||
shortcut: isMac ? '⌘+Z' : 'Ctrl+Z',
|
||||
icon: <Undo />,
|
||||
onClick: () => {
|
||||
const editorInstance = getEditor();
|
||||
editorInstance?.undo();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
value: 'redo',
|
||||
shortcut: isMac ? '⌘+⇧+Z' : 'Ctrl+⇧+Z',
|
||||
icon: <Redo />,
|
||||
onClick: () => {
|
||||
const editorInstance = getEditor();
|
||||
editorInstance?.redo();
|
||||
},
|
||||
},
|
||||
]),
|
||||
[isMac]
|
||||
);
|
||||
};
|
||||
|
||||
const useDuplicateReportSelectMenu = ({ reportId }: { reportId: string }): IDropdownItem => {
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
import { useMemo } from 'react';
|
||||
import { isServer } from '@/lib/window';
|
||||
|
||||
/**
|
||||
* Hook to detect if the user is on a Mac system
|
||||
* @returns {boolean} true if the user is on a Mac, false otherwise (Windows, Linux, etc.)
|
||||
*/
|
||||
export const useIsMac = (): boolean => {
|
||||
return useMemo(() => {
|
||||
if (isServer) {
|
||||
return false; // Server-side rendering fallback
|
||||
}
|
||||
|
||||
// Check the user agent for Mac indicators
|
||||
const userAgent = window.navigator.userAgent.toLowerCase();
|
||||
|
||||
return userAgent.includes('macintosh') || userAgent.includes('mac os');
|
||||
}, []);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to detect if the user is on a Windows system
|
||||
* @returns {boolean} true if the user is on Windows, false otherwise
|
||||
*/
|
||||
export const useIsWindows = (): boolean => {
|
||||
return useMemo(() => {
|
||||
if (isServer) {
|
||||
return false; // Server-side rendering fallback
|
||||
}
|
||||
|
||||
// Check the user agent for Windows indicators
|
||||
const userAgent = window.navigator.userAgent.toLowerCase();
|
||||
return userAgent.includes('windows');
|
||||
}, []);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to get the platform type
|
||||
* @returns {'mac' | 'windows' | 'other'} the detected platform
|
||||
*/
|
||||
export const usePlatform = (): 'mac' | 'windows' | 'other' => {
|
||||
return useMemo(() => {
|
||||
if (typeof window === 'undefined') {
|
||||
return 'other'; // Server-side rendering fallback
|
||||
}
|
||||
|
||||
const userAgent = window.navigator.userAgent.toLowerCase();
|
||||
|
||||
if (userAgent.includes('macintosh') || userAgent.includes('mac os')) {
|
||||
return 'mac';
|
||||
}
|
||||
|
||||
if (userAgent.includes('windows')) {
|
||||
return 'windows';
|
||||
}
|
||||
|
||||
return 'other';
|
||||
}, []);
|
||||
};
|
||||
|
||||
export const useBrowser = (): 'chrome' | 'firefox' | 'safari' | 'edge' | 'other' => {
|
||||
return useMemo(() => {
|
||||
if (isServer) {
|
||||
return 'other'; // Server-side rendering fallback
|
||||
}
|
||||
|
||||
const userAgent = window.navigator.userAgent.toLowerCase();
|
||||
|
||||
if (userAgent.includes('chrome')) {
|
||||
return 'chrome';
|
||||
}
|
||||
|
||||
if (userAgent.includes('firefox')) {
|
||||
return 'firefox';
|
||||
}
|
||||
|
||||
if (userAgent.includes('safari')) {
|
||||
return 'safari';
|
||||
}
|
||||
|
||||
if (userAgent.includes('edge')) {
|
||||
return 'edge';
|
||||
}
|
||||
|
||||
return 'other';
|
||||
}, []);
|
||||
};
|
|
@ -5,13 +5,8 @@ import { useMemoizedFn } from '@/hooks/useMemoizedFn';
|
|||
|
||||
const useReportAssetContext = () => {
|
||||
const [forceUpdate, startForceUpdate] = useTransition();
|
||||
const [hasEditor, setHasEditor] = useState(false);
|
||||
const [versionHistoryMode, setVersionHistoryMode] = useState<number | false>(false);
|
||||
const editor = useRef<BusterReportEditor | null>(null);
|
||||
const undo = useRef<(() => void) | null>(null);
|
||||
const redo = useRef<(() => void) | null>(null);
|
||||
|
||||
console.log('hasEditor', editor.current, !!undo.current, !!redo.current, hasEditor, forceUpdate);
|
||||
|
||||
const openReportVersionHistoryMode = useMemoizedFn((versionNumber: number) => {
|
||||
setVersionHistoryMode(versionNumber);
|
||||
|
@ -21,19 +16,13 @@ const useReportAssetContext = () => {
|
|||
setVersionHistoryMode(false);
|
||||
});
|
||||
|
||||
const setEditor = useMemoizedFn((editor: BusterReportEditor) => {
|
||||
if (!editor) {
|
||||
const setEditor = useMemoizedFn((editorInstance: BusterReportEditor) => {
|
||||
if (!editorInstance) {
|
||||
return;
|
||||
}
|
||||
|
||||
editor.current = editor;
|
||||
undo.current = editor.undo;
|
||||
redo.current = editor.redo;
|
||||
|
||||
startForceUpdate(() => {
|
||||
setHasEditor(true);
|
||||
console.log('setEditor2', editor.current);
|
||||
console.log('editor.current', editor.current);
|
||||
editor.current = editorInstance;
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -42,7 +31,7 @@ const useReportAssetContext = () => {
|
|||
closeVersionHistoryMode,
|
||||
versionHistoryMode,
|
||||
setEditor,
|
||||
hasEditor,
|
||||
forceUpdate,
|
||||
editor,
|
||||
};
|
||||
};
|
||||
|
@ -84,13 +73,13 @@ export const useReportVersionHistoryMode = () => {
|
|||
};
|
||||
|
||||
const stableSetEditorSelector = (x: ReturnType<typeof useReportAssetContext>) => x.setEditor;
|
||||
const stableHasEditorSelector = (x: ReturnType<typeof useReportAssetContext>) => x.hasEditor;
|
||||
const stableForceUpdateSelector = (x: ReturnType<typeof useReportAssetContext>) => x.forceUpdate;
|
||||
export const useEditorContext = () => {
|
||||
const hasEditor = useContextSelector(ReportAssetContext, stableHasEditorSelector);
|
||||
const forceUpdate = useContextSelector(ReportAssetContext, stableForceUpdateSelector);
|
||||
const setEditor = useContextSelector(ReportAssetContext, stableSetEditorSelector);
|
||||
const editor = useContextSelector(
|
||||
ReportAssetContext,
|
||||
useCallback((x) => x.editor, [hasEditor])
|
||||
useCallback((x) => x.editor, [forceUpdate])
|
||||
);
|
||||
|
||||
if (!setEditor) {
|
||||
|
|
Loading…
Reference in New Issue