Skip to content

Commit

Permalink
feat: main editor support fullscreen
Browse files Browse the repository at this point in the history
  • Loading branch information
whatwewant committed Apr 30, 2024
1 parent ad775c4 commit a4c6fcc
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 14 deletions.
68 changes: 63 additions & 5 deletions web/src/components/Dialog/BaseDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CssVarsProvider } from "@mui/joy";
import classNames from "classnames";
import { useEffect, useRef } from "react";
import { useEffect, useRef, useState } from "react";
import { createRoot } from "react-dom/client";
import { Provider } from "react-redux";
import { ANIMATION_DURATION } from "@/helpers/consts";
Expand All @@ -14,6 +14,8 @@ interface DialogConfig {
className?: string;
containerClassName?: string;
clickSpaceDestroy?: boolean;
//
isFullscreen?: boolean;
}

interface Props extends DialogConfig, DialogProps {
Expand All @@ -26,6 +28,15 @@ const BaseDialog: React.FC<Props> = (props: Props) => {
const dialogContainerRef = useRef<HTMLDivElement>(null);
const dialogIndex = dialogStore.state.dialogStack.findIndex((item) => item === dialogName);

const style: React.CSSProperties | undefined = !props.isFullscreen ? undefined : {
position: 'fixed',
top: 0,
left: 0,
width: '100%',
height: '100%',
borderRadius: 0,
};

useEffect(() => {
dialogStore.pushDialogStack(dialogName);
const handleKeyDown = (event: KeyboardEvent) => {
Expand Down Expand Up @@ -58,7 +69,12 @@ const BaseDialog: React.FC<Props> = (props: Props) => {

return (
<div className={classNames("dialog-wrapper", className)} onMouseDown={handleSpaceClicked}>
<div ref={dialogContainerRef} className={classNames("dialog-container", containerClassName)} onMouseDown={(e) => e.stopPropagation()}>
<div
ref={dialogContainerRef}
className={classNames("dialog-container", containerClassName)}
onMouseDown={(e) => e.stopPropagation()}
style={style}
>
{children}
</div>
</div>
Expand All @@ -75,6 +91,8 @@ export function generateDialog<T extends DialogProps>(
document.body.append(tempDiv);
document.body.style.overflow = "hidden";



setTimeout(() => {
tempDiv.firstElementChild?.classList.add("showup");
}, 0);
Expand All @@ -95,6 +113,7 @@ export function generateDialog<T extends DialogProps>(
},
};


const dialogProps = {
...props,
destroy: cbs.destroy,
Expand All @@ -104,9 +123,12 @@ export function generateDialog<T extends DialogProps>(
const Fragment = (
<Provider store={store}>
<CssVarsProvider theme={theme}>
<BaseDialog destroy={cbs.destroy} hide={cbs.hide} clickSpaceDestroy={true} {...config}>
<DialogComponent {...dialogProps} />
</BaseDialog>
<XDialog
DialogComponent={DialogComponent}
config={config}
props={dialogProps}
cbs={cbs}
/>
</CssVarsProvider>
</Provider>
);
Expand All @@ -115,3 +137,39 @@ export function generateDialog<T extends DialogProps>(

return cbs;
}

interface XDialogProps<T> {
DialogComponent: React.FC<T>,
//
config: DialogConfig,
props?: Omit<T, "destroy" | "hide">,
//
cbs: DialogCallback,
}

function XDialog<T = any>(props: XDialogProps<T>) {
const DialogComponent = props.DialogComponent as any;

const [isFullscreen, setIsFullscreen] = useState(false);

const onFullscreenToggle = () => {
setIsFullscreen(!isFullscreen);
};


return (
<BaseDialog
destroy={props.cbs.destroy}
hide={props.cbs.hide}
clickSpaceDestroy={true}
{...props.config}
isFullscreen={isFullscreen}
>
<DialogComponent
{...props.props}
isFullscreen={isFullscreen}
onFullscreenToggle={onFullscreenToggle}
/>
</BaseDialog>
);
}
5 changes: 4 additions & 1 deletion web/src/components/MemoEditor/Editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,12 @@ const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef<
return (
<div
className={classNames(
"flex flex-col justify-start items-start relative w-full h-auto max-h-[256px] bg-inherit dark:text-gray-300",
"flex flex-col justify-start items-start relative w-full h-auto min-h-[56px] bg-inherit dark:text-gray-300",
className,
)}
style={{
flex: 1,
}}
>
<textarea
className="w-full h-full my-1 text-base resize-none overflow-x-hidden overflow-y-auto bg-transparent outline-none whitespace-pre-wrap word-break"
Expand Down
41 changes: 33 additions & 8 deletions web/src/components/MemoEditor/MemoEditorDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IconButton } from "@mui/joy";
import { useEffect } from "react";
import { useCallback, useEffect, useState } from "react";
import { useGlobalStore, useTagStore } from "@/store/module";
import { MemoRelation } from "@/types/proto/api/v2/memo_relation_service";
import MemoEditorV1 from ".";
Expand All @@ -10,9 +10,12 @@ interface Props extends DialogProps {
memoId?: number;
cacheKey?: string;
relationList?: MemoRelation[];
//
isFullscreen?: boolean;
onFullscreenToggle?: () => void;
}

const MemoEditorDialog: React.FC<Props> = ({ memoId, cacheKey, relationList, destroy }: Props) => {
const MemoEditorDialog: React.FC<Props> = ({ memoId, cacheKey, relationList, destroy, isFullscreen, onFullscreenToggle }: Props) => {
const globalStore = useGlobalStore();
const tagStore = useTagStore();
const { systemStatus } = globalStore.state;
Expand All @@ -26,27 +29,49 @@ const MemoEditorDialog: React.FC<Props> = ({ memoId, cacheKey, relationList, des
};

return (
<>
<div
className="memo-editor-dialog-wrapper w-full"
style={{
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
}}
>
<div className="w-full flex flex-row justify-between items-center mb-2">
<div className="flex flex-row justify-start items-center">
<img className="w-6 h-auto rounded-full shadow" src={systemStatus.customizedProfile.logoUrl} alt="" />
<p className="ml-1 text-lg opacity-80 dark:text-gray-300">{systemStatus.customizedProfile.name}</p>
</div>
<IconButton size="sm" onClick={handleCloseBtnClick}>
<Icon.X className="w-5 h-auto" />
</IconButton>
<div>
<IconButton size="sm" onClick={onFullscreenToggle}>
{isFullscreen ? <Icon.Minimize2 className="w-5 h-auto" /> : <Icon.Maximize2 className="w-5 h-auto" />}
</IconButton>
<IconButton size="sm" onClick={handleCloseBtnClick}>
<Icon.X className="w-5 h-auto" />
</IconButton>
</div>
</div>
<div className="flex flex-col justify-start items-start max-w-full w-[36rem]">
<div
className="flex flex-col justify-start items-start max-w-full w-full"
style={{
flex: 1,
}}
>
<MemoEditorV1
className="border-none !p-0 -mb-2"
style={{
// minHeight: '60vh',
flex: 1,
}}
cacheKey={`memo-editor-${cacheKey || memoId}`}
memoId={memoId}
relationList={relationList}
onConfirm={handleCloseBtnClick}
autoFocus
/>
</div>
</>
</div>
);
};

Expand Down
2 changes: 2 additions & 0 deletions web/src/components/MemoEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { MemoEditorContext } from "./types";

interface Props {
className?: string;
style?: React.CSSProperties;
editorClassName?: string;
cacheKey?: string;
memoId?: number;
Expand Down Expand Up @@ -394,6 +395,7 @@ const MemoEditor = (props: Props) => {
className={`${
className ?? ""
} relative w-full flex flex-col justify-start items-start bg-white dark:bg-zinc-800 px-4 pt-4 rounded-lg border border-gray-200 dark:border-zinc-700`}
style={props.style}
tabIndex={0}
onKeyDown={handleKeyDown}
onDrop={handleDropEvent}
Expand Down
6 changes: 6 additions & 0 deletions web/src/less/base-dialog.less
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@

> .dialog-container {
@apply max-w-full shadow flex flex-col justify-start items-start bg-white dark:bg-zinc-800 dark:text-gray-300 p-4 rounded-lg;
// width: 100%;
min-width: 800px;
@media screen and (max-width: 768px) {
width: 100%;
min-width: 100%;
}

> .dialog-header-container {
@apply flex flex-row justify-between items-center w-full mb-4;
Expand Down

0 comments on commit a4c6fcc

Please sign in to comment.