修改默认配置
@@ -11,3 +11,6 @@ memos
|
|||||||
.dockerignore
|
.dockerignore
|
||||||
docs/
|
docs/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
memos_prod.db
|
||||||
|
memos_prod.db-shm
|
||||||
|
memos_prod.db-wal
|
||||||
|
|||||||
@@ -31,3 +31,8 @@ dist
|
|||||||
|
|
||||||
# Frontend test coverage output (Vitest + @vitest/coverage-v8).
|
# Frontend test coverage output (Vitest + @vitest/coverage-v8).
|
||||||
web/coverage/
|
web/coverage/
|
||||||
|
|
||||||
|
# Database
|
||||||
|
memos_prod.db
|
||||||
|
memos_prod.db-shm
|
||||||
|
memos_prod.db-wal
|
||||||
|
|||||||
@@ -1,3 +1,14 @@
|
|||||||
|
# anian-memos
|
||||||
|
|
||||||
|
> 基于原作者v0.29.1代码修改
|
||||||
|
|
||||||
|
#### v0.29.1-1
|
||||||
|
1. 修改默认配置
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<p><b>Featured Sponsors</b></p>
|
<p><b>Featured Sponsors</b></p>
|
||||||
<table>
|
<table>
|
||||||
|
|||||||
@@ -117,8 +117,8 @@ func EmailConfigFromInstanceSetting(setting *storepb.InstanceNotificationSetting
|
|||||||
func NewTestEmailMessage(recipientEmail, replyTo string) *email.Message {
|
func NewTestEmailMessage(recipientEmail, replyTo string) *email.Message {
|
||||||
return &email.Message{
|
return &email.Message{
|
||||||
To: []string{recipientEmail},
|
To: []string{recipientEmail},
|
||||||
Subject: "[Memos] Test email",
|
Subject: "[阿年的备忘录] 测试邮件",
|
||||||
Body: "This is a test email from your Memos notification settings.",
|
Body: "这是一封测试邮件,说明通知邮件设置已正确配置。",
|
||||||
ReplyTo: replyTo,
|
ReplyTo: replyTo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,19 +161,17 @@ func (d *EmailDispatcher) buildMemoCommentEmailMessage(message *storepb.InboxMes
|
|||||||
}
|
}
|
||||||
|
|
||||||
body := []string{
|
body := []string{
|
||||||
fmt.Sprintf("Hi %s,", displayNameForEmail(receiver)),
|
fmt.Sprintf("%s,你好:", displayNameForEmail(receiver)),
|
||||||
"",
|
"",
|
||||||
fmt.Sprintf("%s commented on your memo.", senderName),
|
fmt.Sprintf("%s 评论了你的备忘录。", senderName),
|
||||||
"",
|
"",
|
||||||
"Open in Memos:",
|
"前往查看:",
|
||||||
url,
|
url,
|
||||||
"",
|
|
||||||
"You are receiving this because you own this memo.",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &email.Message{
|
return &email.Message{
|
||||||
To: []string{receiver.Email},
|
To: []string{receiver.Email},
|
||||||
Subject: fmt.Sprintf("[Memos] %s commented on your memo", senderName),
|
Subject: fmt.Sprintf("[阿年的备忘录] %s评论了你的备忘录", senderName),
|
||||||
Body: strings.Join(body, "\n"),
|
Body: strings.Join(body, "\n"),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -193,19 +191,17 @@ func (d *EmailDispatcher) buildMemoMentionEmailMessage(message *storepb.InboxMes
|
|||||||
}
|
}
|
||||||
|
|
||||||
body := []string{
|
body := []string{
|
||||||
fmt.Sprintf("Hi %s,", displayNameForEmail(receiver)),
|
fmt.Sprintf("%s,你好:", displayNameForEmail(receiver)),
|
||||||
"",
|
"",
|
||||||
fmt.Sprintf("%s mentioned you in a memo.", senderName),
|
fmt.Sprintf("%s 在备忘录中提到了你。", senderName),
|
||||||
"",
|
"",
|
||||||
"Open in Memos:",
|
"前往查看:",
|
||||||
url,
|
url,
|
||||||
"",
|
|
||||||
"You are receiving this because you were mentioned in this memo.",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &email.Message{
|
return &email.Message{
|
||||||
To: []string{receiver.Email},
|
To: []string{receiver.Email},
|
||||||
Subject: fmt.Sprintf("[Memos] %s mentioned you in a memo", senderName),
|
Subject: fmt.Sprintf("[阿年的备忘录] %s在备忘录中提到了你", senderName),
|
||||||
Body: strings.Join(body, "\n"),
|
Body: strings.Join(body, "\n"),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ func getDeleteUserAttachmentStorageSetting(ctx context.Context, stores *store.St
|
|||||||
|
|
||||||
func getDefaultUserGeneralSetting() *v1pb.UserSetting_GeneralSetting {
|
func getDefaultUserGeneralSetting() *v1pb.UserSetting_GeneralSetting {
|
||||||
return &v1pb.UserSetting_GeneralSetting{
|
return &v1pb.UserSetting_GeneralSetting{
|
||||||
Locale: "en",
|
Locale: "zh-Hans",
|
||||||
MemoVisibility: "PRIVATE",
|
MemoVisibility: "PRIVATE",
|
||||||
Theme: "",
|
Theme: "",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ func (*RSSService) generateItemTitle(content string) string {
|
|||||||
|
|
||||||
// If title is empty, use a default
|
// If title is empty, use a default
|
||||||
if title == "" {
|
if title == "" {
|
||||||
title = "Memo"
|
title = "阿年的备忘录"
|
||||||
}
|
}
|
||||||
|
|
||||||
return title
|
return title
|
||||||
@@ -416,9 +416,9 @@ func getRSSHeading(ctx context.Context, stores *store.Store) (RSSHeading, error)
|
|||||||
}
|
}
|
||||||
if settings == nil || settings.CustomProfile == nil {
|
if settings == nil || settings.CustomProfile == nil {
|
||||||
return RSSHeading{
|
return RSSHeading{
|
||||||
Title: "Memos",
|
Title: "阿年的备忘录",
|
||||||
Description: "An open source, lightweight note-taking service. Easily capture and share your great thoughts.",
|
Description: "一日不见 如隔三秋",
|
||||||
Language: "en-us",
|
Language: "zh-Hans",
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
customProfile := settings.CustomProfile
|
customProfile := settings.CustomProfile
|
||||||
@@ -426,6 +426,6 @@ func getRSSHeading(ctx context.Context, stores *store.Store) (RSSHeading, error)
|
|||||||
return RSSHeading{
|
return RSSHeading{
|
||||||
Title: customProfile.Title,
|
Title: customProfile.Title,
|
||||||
Description: customProfile.Description,
|
Description: customProfile.Description,
|
||||||
Language: "en-us",
|
Language: "zh-Hans",
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="zh-Hans">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||||
<!-- memos.metadata.head -->
|
<!-- memos.metadata.head -->
|
||||||
<title>Memos</title>
|
<title>阿年的备忘录</title>
|
||||||
</head>
|
</head>
|
||||||
<body class="text-base w-full min-h-svh">
|
<body class="text-base w-full min-h-svh">
|
||||||
<div id="root" class="relative w-full min-h-full"></div>
|
<div id="root" class="relative w-full min-h-full"></div>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 58 KiB |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Memos",
|
"name": "阿年的备忘录",
|
||||||
"short_name": "Memos",
|
"short_name": "阿年的备忘录",
|
||||||
"description": "An open-source, self-hosted note-taking tool. Capture thoughts instantly. Own them completely.",
|
"description": "一日不见 如隔三秋",
|
||||||
"icons": [
|
"icons": [
|
||||||
{ "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" },
|
{ "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" },
|
||||||
{ "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" }
|
{ "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" }
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ export const CalendarCell = memo((props: CalendarCellProps) => {
|
|||||||
baseClasses,
|
baseClasses,
|
||||||
intensityClass,
|
intensityClass,
|
||||||
getCalendarCellStateClass(day),
|
getCalendarCellStateClass(day),
|
||||||
isInteractive ? "cursor-pointer hover:bg-muted/40 hover:border-border/30" : "cursor-default",
|
day.isToday && "underline decoration-1 underline-offset-4",
|
||||||
|
isInteractive ? "cursor-pointer hover:bg-muted/40 hover:border-border/30 hover:text-foreground" : "cursor-default",
|
||||||
);
|
);
|
||||||
|
|
||||||
const button = (
|
const button = (
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ interface Props {
|
|||||||
function MemosLogo(props: Props) {
|
function MemosLogo(props: Props) {
|
||||||
const { collapsed } = props;
|
const { collapsed } = props;
|
||||||
const { generalSetting: instanceGeneralSetting } = useInstance();
|
const { generalSetting: instanceGeneralSetting } = useInstance();
|
||||||
const title = instanceGeneralSetting.customProfile?.title || "Memos";
|
const title = instanceGeneralSetting.customProfile?.title || "阿年的备忘录";
|
||||||
const avatarUrl = instanceGeneralSetting.customProfile?.logoUrl || "/full-logo.webp";
|
const avatarUrl = instanceGeneralSetting.customProfile?.logoUrl || "/full-logo.webp";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const MobileHeader = (props: Props) => {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"sticky top-0 pt-3 pb-2 sm:pt-2 px-4 sm:px-6 sm:mb-1 bg-background bg-opacity-80 backdrop-blur-lg flex flex-row justify-between items-center w-full h-auto flex-nowrap shrink-0 z-1",
|
"sticky top-0 pt-3 pb-2 sm:pt-2 px-4 sm:px-6 sm:mb-1 bg-background bg-opacity-80 backdrop-blur-lg flex flex-row justify-between items-center w-full h-auto flex-nowrap shrink-0 z-4",
|
||||||
offsetTop > 0 && "shadow-md",
|
offsetTop > 0 && "shadow-md",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -40,12 +40,6 @@ const Navigation = (props: Props) => {
|
|||||||
title: t("common.explore"),
|
title: t("common.explore"),
|
||||||
icon: <EarthIcon className="w-6 h-auto shrink-0" />,
|
icon: <EarthIcon className="w-6 h-auto shrink-0" />,
|
||||||
};
|
};
|
||||||
const aboutNavLink: NavLinkItem = {
|
|
||||||
id: "header-about",
|
|
||||||
path: Routes.ABOUT,
|
|
||||||
title: t("common.about"),
|
|
||||||
icon: <InfoIcon className="w-6 h-auto shrink-0" />,
|
|
||||||
};
|
|
||||||
const attachmentsNavLink: NavLinkItem = {
|
const attachmentsNavLink: NavLinkItem = {
|
||||||
id: "header-attachments",
|
id: "header-attachments",
|
||||||
path: Routes.ATTACHMENTS,
|
path: Routes.ATTACHMENTS,
|
||||||
@@ -77,7 +71,7 @@ const Navigation = (props: Props) => {
|
|||||||
|
|
||||||
const primaryNavLinks: NavLinkItem[] = currentUser
|
const primaryNavLinks: NavLinkItem[] = currentUser
|
||||||
? [homeNavLink, exploreNavLink, attachmentsNavLink, inboxNavLink]
|
? [homeNavLink, exploreNavLink, attachmentsNavLink, inboxNavLink]
|
||||||
: [exploreNavLink, aboutNavLink, signInNavLink];
|
: [exploreNavLink, signInNavLink];
|
||||||
const inboxAriaLabel = unreadCount > 0 ? `${t("common.inbox")}, ${unreadCount} unread` : t("common.inbox");
|
const inboxAriaLabel = unreadCount > 0 ? `${t("common.inbox")}, ${unreadCount} unread` : t("common.inbox");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const NavigationDrawer = () => {
|
|||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const { generalSetting } = useInstance();
|
const { generalSetting } = useInstance();
|
||||||
const title = generalSetting.customProfile?.title || "Memos";
|
const title = generalSetting.customProfile?.title || "阿年的备忘录";
|
||||||
const avatarUrl = generalSetting.customProfile?.logoUrl || "/full-logo.webp";
|
const avatarUrl = generalSetting.customProfile?.logoUrl || "/full-logo.webp";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ const InstanceSection = () => {
|
|||||||
<SettingSection title={t("setting.system.label")}>
|
<SettingSection title={t("setting.system.label")}>
|
||||||
<SettingGroup title={t("common.basic")} description={t("setting.system.basic-description")}>
|
<SettingGroup title={t("common.basic")} description={t("setting.system.basic-description")}>
|
||||||
<SettingList>
|
<SettingList>
|
||||||
<SettingListItem label={t("setting.system.server-name")} description={instanceGeneralSetting.customProfile?.title || "Memos"}>
|
<SettingListItem label={t("setting.system.server-name")} description={instanceGeneralSetting.customProfile?.title || "阿年的备忘录"}>
|
||||||
<Button variant="outline" onClick={customizeDialog.open}>
|
<Button variant="outline" onClick={customizeDialog.open}>
|
||||||
{t("common.edit")}
|
{t("common.edit")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ const PreferencesSection = () => {
|
|||||||
const setting: UserSetting_GeneralSetting =
|
const setting: UserSetting_GeneralSetting =
|
||||||
generalSetting ||
|
generalSetting ||
|
||||||
create(UserSetting_GeneralSettingSchema, {
|
create(UserSetting_GeneralSettingSchema, {
|
||||||
locale: "en",
|
locale: "zh-Hans",
|
||||||
memoVisibility: "PRIVATE",
|
memoVisibility: "PRIVATE",
|
||||||
theme: "system",
|
theme: "system",
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ function UpdateCustomizedProfileDialog({ open, onOpenChange, onSuccess }: Props)
|
|||||||
|
|
||||||
const handleRestoreButtonClick = () => {
|
const handleRestoreButtonClick = () => {
|
||||||
setPartialState({
|
setPartialState({
|
||||||
title: "Memos",
|
title: "阿年的备忘录",
|
||||||
logoUrl: "/logo.webp",
|
logoUrl: "/logo.webp",
|
||||||
description: "",
|
description: "",
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -142,10 +142,6 @@ const UserMenu = (props: Props) => {
|
|||||||
<ArchiveIcon className="size-4 text-muted-foreground" />
|
<ArchiveIcon className="size-4 text-muted-foreground" />
|
||||||
{t("common.archived")}
|
{t("common.archived")}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem onClick={() => navigateTo(Routes.ABOUT)}>
|
|
||||||
<InfoIcon className="size-4 text-muted-foreground" />
|
|
||||||
{t("common.about")}
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuSub>
|
<DropdownMenuSub>
|
||||||
<DropdownMenuSubTrigger>
|
<DropdownMenuSubTrigger>
|
||||||
<GlobeIcon className="size-4 text-muted-foreground" />
|
<GlobeIcon className="size-4 text-muted-foreground" />
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ i18n
|
|||||||
},
|
},
|
||||||
fallbackLng: {
|
fallbackLng: {
|
||||||
...fallbacks,
|
...fallbacks,
|
||||||
...{ default: ["en"] },
|
...{ default: ["zh-Hans"] },
|
||||||
} as FallbackLng,
|
} as FallbackLng,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const AdminSignIn = () => {
|
|||||||
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
||||||
<div className="w-full flex flex-row justify-center items-center mb-6">
|
<div className="w-full flex flex-row justify-center items-center mb-6">
|
||||||
<img className="h-14 w-auto rounded-full shadow" src={instanceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
<img className="h-14 w-auto rounded-full shadow" src={instanceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
||||||
<p className="ml-2 text-5xl text-foreground opacity-80">{instanceGeneralSetting.customProfile?.title || "Memos"}</p>
|
<p className="ml-2 text-4xl text-foreground opacity-80">{instanceGeneralSetting.customProfile?.title || "阿年的备忘录"}</p>
|
||||||
</div>
|
</div>
|
||||||
<p className="w-full text-xl font-medium text-muted-foreground">Sign in with admin accounts</p>
|
<p className="w-full text-xl font-medium text-muted-foreground">Sign in with admin accounts</p>
|
||||||
<PasswordSignInForm />
|
<PasswordSignInForm />
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ const SignIn = () => {
|
|||||||
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
||||||
<div className="w-full flex flex-row justify-center items-center mb-6">
|
<div className="w-full flex flex-row justify-center items-center mb-6">
|
||||||
<img className="h-14 w-auto rounded-full shadow" src={instanceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
<img className="h-14 w-auto rounded-full shadow" src={instanceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
||||||
<p className="ml-2 text-5xl text-foreground opacity-80">{instanceGeneralSetting.customProfile?.title || "Memos"}</p>
|
<p className="ml-2 text-4xl text-foreground opacity-80">{instanceGeneralSetting.customProfile?.title || "阿年的备忘录"}</p>
|
||||||
</div>
|
</div>
|
||||||
{!instanceGeneralSetting.disallowPasswordAuth ? (
|
{!instanceGeneralSetting.disallowPasswordAuth ? (
|
||||||
<PasswordSignInForm redirectPath={redirectTarget} />
|
<PasswordSignInForm redirectPath={redirectTarget} />
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ const SignUp = () => {
|
|||||||
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
||||||
<div className="w-full flex flex-row justify-center items-center mb-6">
|
<div className="w-full flex flex-row justify-center items-center mb-6">
|
||||||
<img className="h-14 w-auto rounded-full shadow" src={instanceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
<img className="h-14 w-auto rounded-full shadow" src={instanceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
||||||
<p className="ml-2 text-5xl text-foreground opacity-80">{instanceGeneralSetting.customProfile?.title || "Memos"}</p>
|
<p className="ml-2 text-4xl text-foreground opacity-80">{instanceGeneralSetting.customProfile?.title || "阿年的备忘录"}</p>
|
||||||
</div>
|
</div>
|
||||||
{canUsePasswordSignUp ? (
|
{canUsePasswordSignUp ? (
|
||||||
<>
|
<>
|
||||||
|
|||||||