diff --git a/README.md b/README.md index e683f68b..3e1cff1b 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,18 @@ -
+# memos -+ + +A lightweight, self-hosted memo hub. Open Source and Free forever. + +Live Demo • +Discuss in Telegram / Discord + +
-- Live Demo • - Discuss in Telegram / Discord -
- ![demo](https://usememos.com/demo.webp) ## Key points @@ -39,7 +41,7 @@ Contributions are what make the open-source community such an amazing place to l -Here are some products made by our community: +--- - [Moe Memos](https://memos.moe/) - Third party client for iOS and Android - [lmm214/memos-bber](https://github.com/lmm214/memos-bber) - Chrome extension diff --git a/web/index.html b/web/index.html index 6a5e4e56..eb4c54c9 100644 --- a/web/index.html +++ b/web/index.html @@ -2,7 +2,7 @@ - + diff --git a/web/public/logo.png b/web/public/logo.png deleted file mode 100644 index b4b2cad0..00000000 Binary files a/web/public/logo.png and /dev/null differ diff --git a/web/public/logo.webp b/web/public/logo.webp new file mode 100644 index 00000000..b17f939b Binary files /dev/null and b/web/public/logo.webp differ diff --git a/web/public/manifest.json b/web/public/manifest.json index aff5fe88..74794c0b 100644 --- a/web/public/manifest.json +++ b/web/public/manifest.json @@ -4,8 +4,8 @@ "description": "usememos/memos", "icons": [ { - "src": "/logo.png", - "type": "image/png", + "src": "/logo.webp", + "type": "image/webp", "sizes": "520x520" } ], diff --git a/web/src/App.tsx b/web/src/App.tsx index 1e090b4f..359b7769 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -53,7 +53,7 @@ const App = () => { // dynamic update metadata with customized profile. document.title = systemStatus.customizedProfile.name; const link = document.querySelector("link[rel~='icon']") as HTMLLinkElement; - link.href = systemStatus.customizedProfile.logoUrl || "/logo.png"; + link.href = systemStatus.customizedProfile.logoUrl || "/logo.webp"; }, [systemStatus]); useEffect(() => { diff --git a/web/src/components/AboutSiteDialog.tsx b/web/src/components/AboutSiteDialog.tsx index a7c24fea..528106b1 100644 --- a/web/src/components/AboutSiteDialog.tsx +++ b/web/src/components/AboutSiteDialog.tsx @@ -31,8 +31,8 @@ const AboutSiteDialog: React.FC{systemStatus.customizedProfile.name}
{systemStatus.customizedProfile.description || t("slogan")}
diff --git a/web/src/pages/ResourcesDashboard.tsx b/web/src/pages/ResourcesDashboard.tsx index 739053f2..0a00d431 100644 --- a/web/src/pages/ResourcesDashboard.tsx +++ b/web/src/pages/ResourcesDashboard.tsx @@ -3,6 +3,7 @@ import copy from "copy-to-clipboard"; import { useEffect, useMemo, useState } from "react"; import { toast } from "react-hot-toast"; import { useTranslation } from "react-i18next"; +import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts"; import useLoading from "@/hooks/useLoading"; import { useResourceStore } from "@/store/module"; import { getResourceUrl } from "@/utils/resource"; @@ -16,7 +17,6 @@ import { showCommonDialog } from "@/components/Dialog/CommonDialog"; import showChangeResourceFilenameDialog from "@/components/ChangeResourceFilenameDialog"; import showPreviewImageDialog from "@/components/PreviewImageDialog"; import showCreateResourceDialog from "@/components/CreateResourceDialog"; -import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts"; const ResourcesDashboard = () => { const { t } = useTranslation(); @@ -52,53 +52,6 @@ const ResourcesDashboard = () => { setSelectedList(selectedList.filter((resId) => resId !== resourceId)); }; - const handleDeleteUnusedResourcesBtnClick = async () => { - let warningText = t("resources.warning-text-unused"); - await loadAllResources((allResources: Resource[]) => { - const unusedResources = allResources.filter((resource) => { - if (resource.linkedMemoAmount === 0) { - warningText = warningText + `\n- ${resource.filename}`; - return true; - } - return false; - }); - if (unusedResources.length === 0) { - toast.success(t("resources.no-unused-resources")); - return; - } - showCommonDialog({ - title: t("resources.delete-resource"), - content: warningText, - style: "warning", - dialogName: "delete-unused-resources", - onConfirm: async () => { - for (const resource of unusedResources) { - await resourceStore.deleteResourceById(resource.id); - } - }, - }); - }); - }; - - const handleDeleteSelectedBtnClick = () => { - if (selectedList.length == 0) { - toast.error(t("resources.no-files-selected")); - } else { - const warningText = t("resources.warning-text"); - showCommonDialog({ - title: t("resources.delete-resource"), - content: warningText, - style: "warning", - dialogName: "delete-resource-dialog", - onConfirm: async () => { - selectedList.map(async (resourceId: ResourceId) => { - await resourceStore.deleteResourceById(resourceId); - }); - }, - }); - } - }; - const handleStyleChangeBtnClick = (listStyle: "GRID" | "TABLE") => { setListStyle(listStyle); setSelectedList([]); @@ -125,6 +78,53 @@ const ResourcesDashboard = () => { }); }; + const handleDeleteUnusedResourcesBtnClick = async () => { + let warningText = t("resources.warning-text-unused"); + const allResources = await fetchAllResources(); + const unusedResources = allResources.filter((resource) => { + if (resource.linkedMemoAmount === 0) { + warningText = warningText + `\n- ${resource.filename}`; + return true; + } + return false; + }); + if (unusedResources.length === 0) { + toast.success(t("resources.no-unused-resources")); + return; + } + + showCommonDialog({ + title: t("resources.delete-resource"), + content: warningText, + style: "warning", + dialogName: "delete-unused-resources", + onConfirm: async () => { + for (const resource of unusedResources) { + await resourceStore.deleteResourceById(resource.id); + } + }, + }); + }; + + const handleDeleteSelectedBtnClick = () => { + if (selectedList.length == 0) { + toast.error(t("resources.no-files-selected")); + } else { + const warningText = t("resources.warning-text"); + showCommonDialog({ + title: t("resources.delete-resource"), + content: warningText, + style: "warning", + dialogName: "delete-resource-dialog", + onConfirm: async () => { + selectedList.map(async (resourceId: ResourceId) => { + await resourceStore.deleteResourceById(resourceId); + }); + }, + }); + } + }; + const handlePreviewBtnClick = (resource: Resource) => { const resourceUrl = getResourceUrl(resource); if (resource.type.startsWith("image")) { @@ -157,30 +157,30 @@ const ResourcesDashboard = () => { } }; - const loadAllResources = async (resolve: (allResources: Resource[]) => void) => { - if (!isComplete) { - loadingState.setLoading(); - try { - const allResources = await resourceStore.fetchResourceList(); - loadingState.setFinish(); - setIsComplete(true); - resolve(allResources); - } catch (error: any) { - console.error(error); - toast.error(error.response.data.message); - } - } else { - resolve(resources); + const fetchAllResources = async () => { + if (isComplete) { + return resources; + } + + loadingState.setLoading(); + try { + const allResources = await resourceStore.fetchResourceList(); + loadingState.setFinish(); + setIsComplete(true); + return allResources; + } catch (error: any) { + console.error(error); + toast.error(error.response.data.message); + return resources; } }; const handleSearchResourceInputChange = async (query: string) => { // to prevent first tiger when page is loaded if (query === queryText) return; - await loadAllResources(() => { - setQueryText(query); - setSelectedList([]); - }); + await fetchAllResources(); + setQueryText(query); + setSelectedList([]); }; const resourceList = useMemo( diff --git a/web/src/store/module/global.ts b/web/src/store/module/global.ts index d59ec806..e1492c23 100644 --- a/web/src/store/module/global.ts +++ b/web/src/store/module/global.ts @@ -16,7 +16,7 @@ export const initialGlobalState = async () => { additionalScript: "", customizedProfile: { name: "memos", - logoUrl: "/logo.png", + logoUrl: "/logo.webp", description: "", locale: "en", appearance: "system", @@ -41,7 +41,7 @@ export const initialGlobalState = async () => { ...data, customizedProfile: { name: customizedProfile.name || "memos", - logoUrl: customizedProfile.logoUrl || "/logo.png", + logoUrl: customizedProfile.logoUrl || "/logo.webp", description: customizedProfile.description, locale: customizedProfile.locale || "en", appearance: customizedProfile.appearance || "system", diff --git a/web/src/store/reducer/global.ts b/web/src/store/reducer/global.ts index d1a005b0..72b2514a 100644 --- a/web/src/store/reducer/global.ts +++ b/web/src/store/reducer/global.ts @@ -24,7 +24,7 @@ const globalSlice = createSlice({ additionalScript: "", customizedProfile: { name: "memos", - logoUrl: "/logo.png", + logoUrl: "/logo.webp", description: "", locale: "en", appearance: "system",