mirror of
https://github.com/usememos/memos.git
synced 2025-11-10 01:10:52 +08:00
* Add retry wait for telegram.GetUpdates * Add support to set telegram robot token from UI * Change validator of UserSettingTelegramUserID * Add support to set telegram user id from UI * Fix typescript check * Add validator for SystemSettingTelegramRobotTokenName * Optimize error notice while config telegram params * Change for review * Fix telegram user id could not be empty * Fix telegram robot could not be empty * Fix for eslint (again) * Update web/src/components/Settings/SystemSection.tsx --------- Co-authored-by: Athurg Feng <athurg@gooth.org> Co-authored-by: boojack <stevenlgtm@gmail.com>
178 lines
6.4 KiB
TypeScript
178 lines
6.4 KiB
TypeScript
import { Input, Button, Divider, Switch, Option, Select } from "@mui/joy";
|
|
import { useEffect, useState } from "react";
|
|
import { toast } from "react-hot-toast";
|
|
import { getMyselfUser } from "@/helpers/api";
|
|
import React from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { useGlobalStore, useUserStore } from "@/store/module";
|
|
import { VISIBILITY_SELECTOR_ITEMS } from "@/helpers/consts";
|
|
import AppearanceSelect from "../AppearanceSelect";
|
|
import LocaleSelect from "../LocaleSelect";
|
|
import "@/less/settings/preferences-section.less";
|
|
|
|
const PreferencesSection = () => {
|
|
const { t } = useTranslation();
|
|
const globalStore = useGlobalStore();
|
|
const userStore = useUserStore();
|
|
const { appearance, locale } = globalStore.state;
|
|
const { setting, localSetting } = userStore.state.user as User;
|
|
const [telegramUserId, setTelegramUserId] = useState<string>("");
|
|
const visibilitySelectorItems = VISIBILITY_SELECTOR_ITEMS.map((item) => {
|
|
return {
|
|
value: item.value,
|
|
text: t(`memo.visibility.${item.text.toLowerCase()}`),
|
|
};
|
|
});
|
|
|
|
useEffect(() => {
|
|
getMyselfUser().then(
|
|
({
|
|
data: {
|
|
data: { userSettingList: userSettingList },
|
|
},
|
|
}) => {
|
|
const telegramUserIdSetting = userSettingList.find((setting: any) => setting.key === "telegram-user-id");
|
|
if (telegramUserIdSetting) {
|
|
setTelegramUserId(JSON.parse(telegramUserIdSetting.value));
|
|
}
|
|
}
|
|
);
|
|
}, []);
|
|
|
|
const dailyReviewTimeOffsetOptions: number[] = [...Array(24).keys()];
|
|
|
|
const handleLocaleSelectChange = async (locale: Locale) => {
|
|
await userStore.upsertUserSetting("locale", locale);
|
|
globalStore.setLocale(locale);
|
|
};
|
|
|
|
const handleAppearanceSelectChange = async (appearance: Appearance) => {
|
|
await userStore.upsertUserSetting("appearance", appearance);
|
|
globalStore.setAppearance(appearance);
|
|
};
|
|
|
|
const handleDefaultMemoVisibilityChanged = async (value: string) => {
|
|
await userStore.upsertUserSetting("memo-visibility", value);
|
|
};
|
|
|
|
const handleDoubleClickEnabledChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
userStore.upsertLocalSetting({ ...localSetting, enableDoubleClickEditing: event.target.checked });
|
|
};
|
|
|
|
const handleDailyReviewTimeOffsetChanged = (value: number) => {
|
|
userStore.upsertLocalSetting({ ...localSetting, dailyReviewTimeOffset: value });
|
|
};
|
|
|
|
//enableAutoCollapse
|
|
const handleAutoCollapseChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
userStore.upsertLocalSetting({ ...localSetting, enableAutoCollapse: event.target.checked });
|
|
};
|
|
|
|
const handleSaveTelegramUserId = async () => {
|
|
try {
|
|
await userStore.upsertUserSetting("telegram-user-id", telegramUserId);
|
|
toast.success(t("common.dialog.success"));
|
|
} catch (error: any) {
|
|
console.error(error);
|
|
toast.error(error.response.data.message);
|
|
return;
|
|
}
|
|
};
|
|
|
|
const handleTelegramUserIdChanged = async (value: string) => {
|
|
setTelegramUserId(value);
|
|
};
|
|
|
|
return (
|
|
<div className="section-container preferences-section-container">
|
|
<p className="title-text">{t("common.basic")}</p>
|
|
<div className="form-label selector">
|
|
<span className="text-sm">{t("common.language")}</span>
|
|
<LocaleSelect value={locale} onChange={handleLocaleSelectChange} />
|
|
</div>
|
|
<div className="form-label selector">
|
|
<span className="text-sm">{t("setting.preference-section.theme")}</span>
|
|
<AppearanceSelect value={appearance} onChange={handleAppearanceSelectChange} />
|
|
</div>
|
|
<p className="title-text">{t("setting.preference")}</p>
|
|
<div className="form-label selector">
|
|
<span className="text-sm break-keep text-ellipsis overflow-hidden">{t("setting.preference-section.default-memo-visibility")}</span>
|
|
<Select
|
|
className="!min-w-fit"
|
|
value={setting.memoVisibility}
|
|
onChange={(_, visibility) => {
|
|
if (visibility) {
|
|
handleDefaultMemoVisibilityChanged(visibility);
|
|
}
|
|
}}
|
|
>
|
|
{visibilitySelectorItems.map((item) => (
|
|
<Option key={item.value} value={item.value}>
|
|
{item.text}
|
|
</Option>
|
|
))}
|
|
</Select>
|
|
</div>
|
|
<div className="form-label selector">
|
|
<span className="text-sm break-keep text-ellipsis overflow-hidden">{t("setting.preference-section.daily-review-time-offset")}</span>
|
|
<span className="w-auto inline-flex">
|
|
<Select
|
|
placeholder="hh"
|
|
className="!min-w-fit"
|
|
value={localSetting.dailyReviewTimeOffset}
|
|
onChange={(_, value) => {
|
|
if (value !== null) {
|
|
handleDailyReviewTimeOffsetChanged(value);
|
|
}
|
|
}}
|
|
slotProps={{
|
|
listbox: {
|
|
sx: {
|
|
maxHeight: "15rem",
|
|
overflow: "auto",
|
|
},
|
|
},
|
|
}}
|
|
>
|
|
{dailyReviewTimeOffsetOptions.map((item) => (
|
|
<Option key={item} value={item} className="whitespace-nowrap">
|
|
{item.toString().padStart(2, "0")}
|
|
</Option>
|
|
))}
|
|
</Select>
|
|
</span>
|
|
</div>
|
|
|
|
<label className="form-label selector">
|
|
<span className="text-sm break-keep">{t("setting.preference-section.enable-double-click")}</span>
|
|
<Switch className="ml-2" checked={localSetting.enableDoubleClickEditing} onChange={handleDoubleClickEnabledChanged} />
|
|
</label>
|
|
|
|
<label className="form-label selector">
|
|
<span className="normal-text">{t("setting.preference-section.auto-collapse")}</span>
|
|
<Switch className="ml-2" checked={localSetting.enableAutoCollapse} onChange={handleAutoCollapseChanged} />
|
|
</label>
|
|
|
|
<Divider className="!mt-3 !my-4" />
|
|
|
|
<div className="form-label">
|
|
<div className="flex flex-row items-center">
|
|
<span className="text-sm mr-1">{t("setting.preference-section.telegram-user-id")}</span>
|
|
</div>
|
|
<Button onClick={handleSaveTelegramUserId}>{t("common.save")}</Button>
|
|
</div>
|
|
<Input
|
|
className="w-full"
|
|
sx={{
|
|
fontFamily: "monospace",
|
|
fontSize: "14px",
|
|
}}
|
|
value={telegramUserId}
|
|
onChange={(event) => handleTelegramUserIdChanged(event.target.value)}
|
|
placeholder={t("setting.preference-section.telegram-user-id-placeholder")}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PreferencesSection;
|