mirror of
https://github.com/usememos/memos.git
synced 2024-12-20 01:31:29 +03:00
feat: float mobile editor (#234)
* feat: float mobile editor * fix: fix pr comment * lint: fix golangci-lint
This commit is contained in:
parent
02c26d5bb4
commit
7a6eb53e0f
@ -14,6 +14,8 @@ const (
|
|||||||
UserSettingMemoVisibilityKey UserSettingKey = "memoVisibility"
|
UserSettingMemoVisibilityKey UserSettingKey = "memoVisibility"
|
||||||
// UserSettingEditorFontStyleKey is the key type for editor font style.
|
// UserSettingEditorFontStyleKey is the key type for editor font style.
|
||||||
UserSettingEditorFontStyleKey UserSettingKey = "editorFontStyle"
|
UserSettingEditorFontStyleKey UserSettingKey = "editorFontStyle"
|
||||||
|
// UserSettingEditorFontStyleKey is the key type for mobile editor style.
|
||||||
|
UserSettingMobileEditorStyleKey UserSettingKey = "mobileEditorStyle"
|
||||||
)
|
)
|
||||||
|
|
||||||
// String returns the string format of UserSettingKey type.
|
// String returns the string format of UserSettingKey type.
|
||||||
@ -25,14 +27,17 @@ func (key UserSettingKey) String() string {
|
|||||||
return "memoVisibility"
|
return "memoVisibility"
|
||||||
case UserSettingEditorFontStyleKey:
|
case UserSettingEditorFontStyleKey:
|
||||||
return "editorFontFamily"
|
return "editorFontFamily"
|
||||||
|
case UserSettingMobileEditorStyleKey:
|
||||||
|
return "mobileEditorStyle"
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
UserSettingLocaleValue = []string{"en", "zh", "vi"}
|
UserSettingLocaleValue = []string{"en", "zh", "vi"}
|
||||||
UserSettingMemoVisibilityValue = []Visibility{Privite, Protected, Public}
|
UserSettingMemoVisibilityValue = []Visibility{Privite, Protected, Public}
|
||||||
UserSettingEditorFontStyleValue = []string{"normal", "mono"}
|
UserSettingEditorFontStyleValue = []string{"normal", "mono"}
|
||||||
|
UserSettingMobileEditorStyleValue = []string{"normal", "float"}
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserSetting struct {
|
type UserSetting struct {
|
||||||
@ -100,6 +105,23 @@ func (upsert UserSettingUpsert) Validate() error {
|
|||||||
if invalid {
|
if invalid {
|
||||||
return fmt.Errorf("invalid user setting editor font style value")
|
return fmt.Errorf("invalid user setting editor font style value")
|
||||||
}
|
}
|
||||||
|
} else if upsert.Key == UserSettingMobileEditorStyleKey {
|
||||||
|
mobileEditorStyleValue := "normal"
|
||||||
|
err := json.Unmarshal([]byte(upsert.Value), &mobileEditorStyleValue)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to unmarshal user setting mobile editor style")
|
||||||
|
}
|
||||||
|
|
||||||
|
invalid := true
|
||||||
|
for _, value := range UserSettingMobileEditorStyleValue {
|
||||||
|
if mobileEditorStyleValue == value {
|
||||||
|
invalid = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if invalid {
|
||||||
|
return fmt.Errorf("invalid user setting mobile editor style value")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("invalid user setting key")
|
return fmt.Errorf("invalid user setting key")
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ const MemoEditor = () => {
|
|||||||
const prevGlobalStateRef = useRef(editorState);
|
const prevGlobalStateRef = useRef(editorState);
|
||||||
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";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editorState.markMemoId && editorState.markMemoId !== UNKNOWN_ID) {
|
if (editorState.markMemoId && editorState.markMemoId !== UNKNOWN_ID) {
|
||||||
@ -280,7 +281,7 @@ const MemoEditor = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`memo-editor-container ${isEditing ? "edit-ing" : ""} ${state.fullscreen ? "fullscreen" : ""}`}>
|
<div className={`memo-editor-container ${mobileEditorStyle} ${isEditing ? "edit-ing" : ""} ${state.fullscreen ? "fullscreen" : ""}`}>
|
||||||
<div className={`tip-container ${isEditing ? "" : "!hidden"}`}>
|
<div className={`tip-container ${isEditing ? "" : "!hidden"}`}>
|
||||||
<span className="tip-text">{t("editor.editing")}</span>
|
<span className="tip-text">{t("editor.editing")}</span>
|
||||||
<button className="cancel-btn" onClick={handleCancelEditingBtnClick}>
|
<button className="cancel-btn" onClick={handleCancelEditingBtnClick}>
|
||||||
|
@ -31,6 +31,17 @@ const editorFontStyleSelectorItems = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const mobileEditorStyleSelectorItems = [
|
||||||
|
{
|
||||||
|
text: "Normal",
|
||||||
|
value: "normal",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Float",
|
||||||
|
value: "float",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const PreferencesSection = () => {
|
const PreferencesSection = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { setting } = useAppSelector((state) => state.user.user as User);
|
const { setting } = useAppSelector((state) => state.user.user as User);
|
||||||
@ -54,6 +65,10 @@ const PreferencesSection = () => {
|
|||||||
await userService.upsertUserSetting("editorFontStyle", value);
|
await userService.upsertUserSetting("editorFontStyle", value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleMobileEditorStyleChanged = async (value: string) => {
|
||||||
|
await userService.upsertUserSetting("mobileEditorStyle", value);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="section-container preferences-section-container">
|
<div className="section-container preferences-section-container">
|
||||||
<p className="title-text">{t("common.basic")}</p>
|
<p className="title-text">{t("common.basic")}</p>
|
||||||
@ -80,6 +95,15 @@ const PreferencesSection = () => {
|
|||||||
handleValueChanged={handleEditorFontStyleChanged}
|
handleValueChanged={handleEditorFontStyleChanged}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
<label className="form-label selector">
|
||||||
|
<span className="normal-text">{t("setting.preference-section.mobile-editor-style")}</span>
|
||||||
|
<Selector
|
||||||
|
className="ml-2 w-32"
|
||||||
|
value={setting.mobileEditorStyle}
|
||||||
|
dataSource={mobileEditorStyleSelectorItems}
|
||||||
|
handleValueChanged={handleMobileEditorStyleChanged}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -25,6 +25,15 @@
|
|||||||
border-color: @text-blue;
|
border-color: @text-blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.float {
|
||||||
|
width: calc(100% - 2rem);
|
||||||
|
@apply fixed bottom-4 sm:relative sm:bottom-0 sm:w-full;
|
||||||
|
|
||||||
|
& .emoji-picker-react {
|
||||||
|
@apply bottom-16 sm:bottom-auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> .tip-container {
|
> .tip-container {
|
||||||
@apply mb-1 w-full flex flex-row justify-start items-center text-xs leading-6;
|
@apply mb-1 w-full flex flex-row justify-start items-center text-xs leading-6;
|
||||||
|
|
||||||
|
@ -109,7 +109,8 @@
|
|||||||
},
|
},
|
||||||
"preference-section": {
|
"preference-section": {
|
||||||
"default-memo-visibility": "Default memo visibility",
|
"default-memo-visibility": "Default memo visibility",
|
||||||
"editor-font-style": "Editor font style"
|
"editor-font-style": "Editor font style",
|
||||||
|
"mobile-editor-style": "Mobile editor style"
|
||||||
},
|
},
|
||||||
"member-section": {
|
"member-section": {
|
||||||
"create-a-member": "Create a member"
|
"create-a-member": "Create a member"
|
||||||
|
@ -109,7 +109,8 @@
|
|||||||
},
|
},
|
||||||
"preference-section": {
|
"preference-section": {
|
||||||
"default-memo-visibility": "Chế độ memo mặc định",
|
"default-memo-visibility": "Chế độ memo mặc định",
|
||||||
"editor-font-style": "Thay đổi font cho trình soạn thảo"
|
"editor-font-style": "Thay đổi font cho trình soạn thảo",
|
||||||
|
"mobile-editor-style": "Vị trí editor trên mobile"
|
||||||
},
|
},
|
||||||
"member-section": {
|
"member-section": {
|
||||||
"create-a-member": "Tạo thành viên"
|
"create-a-member": "Tạo thành viên"
|
||||||
|
@ -109,7 +109,8 @@
|
|||||||
},
|
},
|
||||||
"preference-section": {
|
"preference-section": {
|
||||||
"default-memo-visibility": "默认 Memo 可见性",
|
"default-memo-visibility": "默认 Memo 可见性",
|
||||||
"editor-font-style": "编辑器字体样式"
|
"editor-font-style": "编辑器字体样式",
|
||||||
|
"mobile-editor-style": "Mobile editor style"
|
||||||
},
|
},
|
||||||
"member-section": {
|
"member-section": {
|
||||||
"create-a-member": "创建成员"
|
"create-a-member": "创建成员"
|
||||||
|
@ -8,6 +8,7 @@ const defauleSetting: Setting = {
|
|||||||
locale: "en",
|
locale: "en",
|
||||||
memoVisibility: "PRIVATE",
|
memoVisibility: "PRIVATE",
|
||||||
editorFontStyle: "normal",
|
editorFontStyle: "normal",
|
||||||
|
mobileEditorStyle: "normal",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const convertResponseModelUser = (user: User): User => {
|
export const convertResponseModelUser = (user: User): User => {
|
||||||
|
1
web/src/types/modules/setting.d.ts
vendored
1
web/src/types/modules/setting.d.ts
vendored
@ -2,6 +2,7 @@ interface Setting {
|
|||||||
locale: Locale;
|
locale: Locale;
|
||||||
memoVisibility: Visibility;
|
memoVisibility: Visibility;
|
||||||
editorFontStyle: "normal" | "mono";
|
editorFontStyle: "normal" | "mono";
|
||||||
|
mobileEditorStyle: "normal" | "float";
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UserLocaleSetting {
|
interface UserLocaleSetting {
|
||||||
|
Loading…
Reference in New Issue
Block a user