mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
feat: update visibility selector style (#441)
This commit is contained in:
@ -17,14 +17,12 @@ interface Props {
|
|||||||
placeholder: string;
|
placeholder: string;
|
||||||
fullscreen: boolean;
|
fullscreen: boolean;
|
||||||
tools?: ReactNode;
|
tools?: ReactNode;
|
||||||
onPaste: (event: React.ClipboardEvent) => void;
|
|
||||||
onFocus: () => void;
|
|
||||||
onContentChange: (content: string) => void;
|
onContentChange: (content: string) => void;
|
||||||
|
onPaste: (event: React.ClipboardEvent) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line react/display-name
|
const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef<EditorRefActions>) {
|
||||||
const Editor = forwardRef((props: Props, ref: React.ForwardedRef<EditorRefActions>) => {
|
const { className, initialContent, placeholder, fullscreen, onPaste, onContentChange: handleContentChangeCallback } = props;
|
||||||
const { className, initialContent, placeholder, fullscreen, onPaste, onFocus, onContentChange: handleContentChangeCallback } = props;
|
|
||||||
const editorRef = useRef<HTMLTextAreaElement>(null);
|
const editorRef = useRef<HTMLTextAreaElement>(null);
|
||||||
const refresh = useRefresh();
|
const refresh = useRefresh();
|
||||||
|
|
||||||
@ -106,7 +104,6 @@ const Editor = forwardRef((props: Props, ref: React.ForwardedRef<EditorRefAction
|
|||||||
ref={editorRef}
|
ref={editorRef}
|
||||||
onPaste={onPaste}
|
onPaste={onPaste}
|
||||||
onInput={handleEditorInput}
|
onInput={handleEditorInput}
|
||||||
onFocus={onFocus}
|
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -33,9 +33,9 @@ const setEditingMemoVisibilityCache = (visibility: Visibility) => {
|
|||||||
interface State {
|
interface State {
|
||||||
fullscreen: boolean;
|
fullscreen: boolean;
|
||||||
isUploadingResource: boolean;
|
isUploadingResource: boolean;
|
||||||
shouldShowEmojiPicker: boolean;
|
|
||||||
resourceList: Resource[];
|
resourceList: Resource[];
|
||||||
hasFocused: boolean;
|
shouldShowEmojiPicker: boolean;
|
||||||
|
isEditorFocused: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MemoEditor: React.FC = () => {
|
const MemoEditor: React.FC = () => {
|
||||||
@ -49,7 +49,7 @@ const MemoEditor: React.FC = () => {
|
|||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
shouldShowEmojiPicker: false,
|
shouldShowEmojiPicker: false,
|
||||||
resourceList: [],
|
resourceList: [],
|
||||||
hasFocused: false,
|
isEditorFocused: false,
|
||||||
});
|
});
|
||||||
const [allowSave, setAllowSave] = useState<boolean>(false);
|
const [allowSave, setAllowSave] = useState<boolean>(false);
|
||||||
const prevGlobalStateRef = useRef(editorState);
|
const prevGlobalStateRef = useRef(editorState);
|
||||||
@ -57,6 +57,12 @@ const MemoEditor: React.FC = () => {
|
|||||||
const tagSeletorRef = useRef<HTMLDivElement>(null);
|
const tagSeletorRef = useRef<HTMLDivElement>(null);
|
||||||
const editorFontStyle = user?.setting.editorFontStyle || "normal";
|
const editorFontStyle = user?.setting.editorFontStyle || "normal";
|
||||||
const mobileEditorStyle = user?.setting.mobileEditorStyle || "normal";
|
const mobileEditorStyle = user?.setting.mobileEditorStyle || "normal";
|
||||||
|
const memoVisibilityOptionSelectorItems = VISIBILITY_SELECTOR_ITEMS.map((item) => {
|
||||||
|
return {
|
||||||
|
value: item.value,
|
||||||
|
text: t(`memo.visibility.${toLower(item.value)}`),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const { editingMemoIdCache, editingMemoVisibilityCache } = storage.get(["editingMemoIdCache", "editingMemoVisibilityCache"]);
|
const { editingMemoIdCache, editingMemoVisibilityCache } = storage.get(["editingMemoIdCache", "editingMemoVisibilityCache"]);
|
||||||
@ -364,6 +370,27 @@ const MemoEditor: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleMemoVisibilityOptionChanged = async (value: string) => {
|
||||||
|
const visibilityValue = value as Visibility;
|
||||||
|
editorStateService.setMemoVisibility(visibilityValue);
|
||||||
|
setEditingMemoVisibilityCache(visibilityValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEditorFocus = () => {
|
||||||
|
editorRef.current?.focus();
|
||||||
|
setState({
|
||||||
|
...state,
|
||||||
|
isEditorFocused: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEditorBlur = () => {
|
||||||
|
setState({
|
||||||
|
...state,
|
||||||
|
isEditorFocused: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const isEditing = Boolean(editorState.editMemoId && editorState.editMemoId !== UNKNOWN_ID);
|
const isEditing = Boolean(editorState.editMemoId && editorState.editMemoId !== UNKNOWN_ID);
|
||||||
|
|
||||||
const editorConfig = useMemo(
|
const editorConfig = useMemo(
|
||||||
@ -373,55 +400,35 @@ const MemoEditor: React.FC = () => {
|
|||||||
placeholder: t("editor.placeholder"),
|
placeholder: t("editor.placeholder"),
|
||||||
fullscreen: state.fullscreen,
|
fullscreen: state.fullscreen,
|
||||||
onContentChange: handleContentChange,
|
onContentChange: handleContentChange,
|
||||||
|
onPaste: handlePasteEvent,
|
||||||
}),
|
}),
|
||||||
[state.fullscreen, i18n.language, editorFontStyle]
|
[state.fullscreen, i18n.language, editorFontStyle]
|
||||||
);
|
);
|
||||||
|
|
||||||
const memoVisibilityOptionSelectorItems = VISIBILITY_SELECTOR_ITEMS.map((item) => {
|
|
||||||
return {
|
|
||||||
value: item.value,
|
|
||||||
text: t(`memo.visibility.${toLower(item.value)}`),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleMemoVisibilityOptionChanged = async (value: string) => {
|
|
||||||
const visibilityValue = value as Visibility;
|
|
||||||
editorStateService.setMemoVisibility(visibilityValue);
|
|
||||||
setEditingMemoVisibilityCache(visibilityValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleEditorFocus = () => {
|
|
||||||
setState({
|
|
||||||
...state,
|
|
||||||
hasFocused: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`memo-editor-container ${mobileEditorStyle} ${isEditing ? "edit-ing" : ""} ${state.fullscreen ? "fullscreen" : ""}`}
|
className={`memo-editor-container ${mobileEditorStyle} ${isEditing ? "edit-ing" : ""} ${state.fullscreen ? "fullscreen" : ""}`}
|
||||||
|
tabIndex={0}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
onDrop={handleDropEvent}
|
onDrop={handleDropEvent}
|
||||||
|
onFocus={handleEditorFocus}
|
||||||
|
onBlur={handleEditorBlur}
|
||||||
>
|
>
|
||||||
<div className={`tip-container ${isEditing ? "" : "!hidden"}`}>
|
<div className="editor-header-container">
|
||||||
<span className="tip-text">{t("editor.editing")}</span>
|
<Selector
|
||||||
<button className="cancel-btn" onClick={handleCancelEdit}>
|
className={`visibility-selector ${state.isEditorFocused || allowSave ? "" : "!hidden"}`}
|
||||||
{t("common.cancel")}
|
value={editorState.memoVisibility}
|
||||||
</button>
|
dataSource={memoVisibilityOptionSelectorItems}
|
||||||
</div>
|
handleValueChanged={handleMemoVisibilityOptionChanged}
|
||||||
<Editor ref={editorRef} {...editorConfig} onPaste={handlePasteEvent} onFocus={handleEditorFocus} />
|
/>
|
||||||
<div className={`visibility-selector-container ${state.hasFocused || allowSave ? "" : "!hidden"}`}>
|
<div className={`editing-container ${isEditing ? "" : "!hidden"}`}>
|
||||||
<div className="memo-visibility-selector">
|
<span className="tip-text">{t("editor.editing")}</span>
|
||||||
<label className="form-label selector">
|
<button className="cancel-btn" onClick={handleCancelEdit}>
|
||||||
<Selector
|
{t("common.cancel")}
|
||||||
className="w-36"
|
</button>
|
||||||
value={editorState.memoVisibility}
|
|
||||||
dataSource={memoVisibilityOptionSelectorItems}
|
|
||||||
handleValueChanged={handleMemoVisibilityOptionChanged}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Editor ref={editorRef} {...editorConfig} />
|
||||||
<div className="common-tools-wrapper">
|
<div className="common-tools-wrapper">
|
||||||
<div className="common-tools-container">
|
<div className="common-tools-container">
|
||||||
<div className="action-btn tag-action">
|
<div className="action-btn tag-action">
|
||||||
|
@ -10,8 +10,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
> .common-editor-inputer {
|
> .common-editor-inputer {
|
||||||
@apply w-full h-full mt-1 mb-1 text-base resize-none overflow-x-hidden overflow-y-auto bg-transparent whitespace-pre-wrap;
|
@apply w-full h-full mt-2 mb-1 text-base resize-none overflow-x-hidden overflow-y-auto bg-transparent whitespace-pre-wrap;
|
||||||
min-height: 40px;
|
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
.pretty-scroll-bar(2px, 0);
|
.pretty-scroll-bar(2px, 0);
|
||||||
|
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
@apply relative w-full min-h-screen mx-auto flex flex-col justify-start items-center pb-8;
|
@apply relative w-full min-h-screen mx-auto flex flex-col justify-start items-center pb-8;
|
||||||
|
|
||||||
> .page-header {
|
> .page-header {
|
||||||
@apply sticky top-0 z-10 max-w-2xl w-full min-h-full flex flex-row justify-between items-center px-4 sm:pr-6 pt-6 mb-2;
|
@apply sticky top-0 z-10 max-w-2xl w-full min-h-full flex flex-row justify-between backdrop-blur-sm items-center px-4 sm:pr-6 pt-6 mb-2;
|
||||||
background-color: #f6f5f4;
|
|
||||||
|
|
||||||
> .title-container {
|
> .title-container {
|
||||||
@apply flex flex-row justify-start items-center;
|
@apply flex flex-row justify-start items-center;
|
||||||
|
@ -50,20 +50,32 @@
|
|||||||
border-color: @text-blue;
|
border-color: @text-blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .tip-container {
|
> .editor-header-container {
|
||||||
@apply mb-1 w-full flex flex-row justify-start items-center text-xs leading-6;
|
@apply w-full flex flex-row justify-between items-center;
|
||||||
|
|
||||||
> .tip-text {
|
> .visibility-selector {
|
||||||
@apply text-gray-400 mr-2;
|
@apply h-7;
|
||||||
|
|
||||||
|
> .current-value-container {
|
||||||
|
@apply rounded-full;
|
||||||
|
|
||||||
|
> .value-text {
|
||||||
|
@apply text-sm w-full;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .cancel-btn {
|
> .editing-container {
|
||||||
@apply px-2 border rounded-full leading-5 text-blue-600 hover:border-blue-600;
|
@apply mb-1 flex flex-row justify-start items-center text-xs leading-6;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .visibility-selector-container{
|
> .tip-text {
|
||||||
@apply w-full border-b py-2;
|
@apply text-gray-400 mr-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .cancel-btn {
|
||||||
|
@apply px-2 border rounded-full leading-5 text-blue-600 hover:border-blue-600;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .memo-editor {
|
> .memo-editor {
|
||||||
|
Reference in New Issue
Block a user