mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
chore: update some detail styles (#2168)
* chore: update some detail styls * chore: update
This commit is contained in:
@ -10,6 +10,7 @@ Discuss in <a href="https://discord.gg/tfPJa4UmAv">Discord</a> / <a href="https:
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="https://github.com/usememos/memos/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/usememos/memos?logo=github" /></a>
|
<a href="https://github.com/usememos/memos/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/usememos/memos?logo=github" /></a>
|
||||||
|
<a href="https://hub.docker.com/r/neosmemo/memos"><img alt="Docker pull" src="https://img.shields.io/docker/pulls/neosmemo/memos.svg"/></a>
|
||||||
<a href="https://discord.gg/tfPJa4UmAv"><img alt="Discord" src="https://img.shields.io/badge/discord-chat-5865f2?logo=discord&logoColor=f5f5f5" /></a>
|
<a href="https://discord.gg/tfPJa4UmAv"><img alt="Discord" src="https://img.shields.io/badge/discord-chat-5865f2?logo=discord&logoColor=f5f5f5" /></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
|
import { Button } from "@mui/joy";
|
||||||
|
import { DefaultColorPalette } from "@mui/joy/styles/types";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
import Icon from "../Icon";
|
import Icon from "../Icon";
|
||||||
import { generateDialog } from "./BaseDialog";
|
import { generateDialog } from "./BaseDialog";
|
||||||
import "@/less/common-dialog.less";
|
import "@/less/common-dialog.less";
|
||||||
|
|
||||||
type DialogStyle = "info" | "warning";
|
|
||||||
|
|
||||||
interface Props extends DialogProps {
|
interface Props extends DialogProps {
|
||||||
title: string;
|
title: string;
|
||||||
content: string;
|
content: string;
|
||||||
style?: DialogStyle;
|
style?: DefaultColorPalette;
|
||||||
closeBtnText?: string;
|
closeBtnText?: string;
|
||||||
confirmBtnText?: string;
|
confirmBtnText?: string;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
@ -18,7 +18,7 @@ interface Props extends DialogProps {
|
|||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
title: "",
|
title: "",
|
||||||
content: "",
|
content: "",
|
||||||
style: "info",
|
style: "neutral",
|
||||||
closeBtnText: "common.close",
|
closeBtnText: "common.close",
|
||||||
confirmBtnText: "common.confirm",
|
confirmBtnText: "common.confirm",
|
||||||
onClose: () => null,
|
onClose: () => null,
|
||||||
@ -54,13 +54,13 @@ const CommonDialog: React.FC<Props> = (props: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="dialog-content-container">
|
<div className="dialog-content-container">
|
||||||
<p className="content-text">{content}</p>
|
<p className="content-text">{content}</p>
|
||||||
<div className="btns-container">
|
<div className="mt-4 w-full flex flex-row justify-end items-center gap-2">
|
||||||
<span className="btn cancel-btn" onClick={handleCloseBtnClick}>
|
<Button color="neutral" variant="plain" onClick={handleCloseBtnClick}>
|
||||||
{closeBtnText}
|
{closeBtnText}
|
||||||
</span>
|
</Button>
|
||||||
<span className={`btn confirm-btn ${style}`} onClick={handleConfirmBtnClick}>
|
<Button color={style} onClick={handleConfirmBtnClick}>
|
||||||
{confirmBtnText}
|
{confirmBtnText}
|
||||||
</span>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@ -71,7 +71,7 @@ interface CommonDialogProps {
|
|||||||
title: string;
|
title: string;
|
||||||
content: string;
|
content: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
style?: DialogStyle;
|
style?: DefaultColorPalette;
|
||||||
dialogName: string;
|
dialogName: string;
|
||||||
closeBtnText?: string;
|
closeBtnText?: string;
|
||||||
confirmBtnText?: string;
|
confirmBtnText?: string;
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { NavLink, useLocation } from "react-router-dom";
|
import { NavLink, useLocation } from "react-router-dom";
|
||||||
import { useGlobalStore, useLayoutStore, useUserStore } from "@/store/module";
|
import { useLayoutStore, useUserStore } from "@/store/module";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
import { resolution } from "@/utils/layout";
|
import { resolution } from "@/utils/layout";
|
||||||
import Icon from "./Icon";
|
import Icon from "./Icon";
|
||||||
import UpgradeVersionView from "./UpgradeVersionBanner";
|
|
||||||
import UserBanner from "./UserBanner";
|
import UserBanner from "./UserBanner";
|
||||||
|
|
||||||
|
interface NavLinkItem {
|
||||||
|
id: string;
|
||||||
|
path: string;
|
||||||
|
title: string;
|
||||||
|
icon: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const globalStore = useGlobalStore();
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const layoutStore = useLayoutStore();
|
const layoutStore = useLayoutStore();
|
||||||
const showHeader = layoutStore.state.showHeader;
|
const showHeader = layoutStore.state.showHeader;
|
||||||
@ -29,6 +34,53 @@ const Header = () => {
|
|||||||
handleWindowResize();
|
handleWindowResize();
|
||||||
}, [location]);
|
}, [location]);
|
||||||
|
|
||||||
|
const homeNavLink: NavLinkItem = {
|
||||||
|
id: "header-home",
|
||||||
|
path: "/",
|
||||||
|
title: t("common.home"),
|
||||||
|
icon: <Icon.Home className="mr-3 w-6 h-auto opacity-70" />,
|
||||||
|
};
|
||||||
|
const dailyReviewNavLink: NavLinkItem = {
|
||||||
|
id: "header-daily-review",
|
||||||
|
path: "/review",
|
||||||
|
title: t("daily-review.title"),
|
||||||
|
icon: <Icon.Calendar className="mr-3 w-6 h-auto opacity-70" />,
|
||||||
|
};
|
||||||
|
const exploreNavLink: NavLinkItem = {
|
||||||
|
id: "header-explore",
|
||||||
|
path: "/explore",
|
||||||
|
title: t("common.explore"),
|
||||||
|
icon: <Icon.Hash className="mr-3 w-6 h-auto opacity-70" />,
|
||||||
|
};
|
||||||
|
const resourcesNavLink: NavLinkItem = {
|
||||||
|
id: "header-resources",
|
||||||
|
path: "/resources",
|
||||||
|
title: t("common.resources"),
|
||||||
|
icon: <Icon.Paperclip className="mr-3 w-6 h-auto opacity-70" />,
|
||||||
|
};
|
||||||
|
const archivedNavLink: NavLinkItem = {
|
||||||
|
id: "header-archived",
|
||||||
|
path: "/archived",
|
||||||
|
title: t("common.archived"),
|
||||||
|
icon: <Icon.Archive className="mr-3 w-6 h-auto opacity-70" />,
|
||||||
|
};
|
||||||
|
const settingNavLink: NavLinkItem = {
|
||||||
|
id: "header-setting",
|
||||||
|
path: "/setting",
|
||||||
|
title: t("common.settings"),
|
||||||
|
icon: <Icon.Settings className="mr-3 w-6 h-auto opacity-70" />,
|
||||||
|
};
|
||||||
|
const authNavLink: NavLinkItem = {
|
||||||
|
id: "header-auth",
|
||||||
|
path: "/auth",
|
||||||
|
title: t("common.sign-in"),
|
||||||
|
icon: <Icon.LogIn className="mr-3 w-6 h-auto opacity-70" />,
|
||||||
|
};
|
||||||
|
|
||||||
|
const navLinks: NavLinkItem[] = !isVisitorMode
|
||||||
|
? [homeNavLink, dailyReviewNavLink, exploreNavLink, resourcesNavLink, archivedNavLink, settingNavLink]
|
||||||
|
: [exploreNavLink, authNavLink];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`fixed sm:sticky top-0 left-0 w-full sm:w-56 h-full shrink-0 pointer-events-none sm:pointer-events-auto z-10 ${
|
className={`fixed sm:sticky top-0 left-0 w-full sm:w-56 h-full shrink-0 pointer-events-none sm:pointer-events-auto z-10 ${
|
||||||
@ -48,122 +100,23 @@ const Header = () => {
|
|||||||
>
|
>
|
||||||
<UserBanner />
|
<UserBanner />
|
||||||
<div className="w-full px-2 py-2 flex flex-col justify-start items-start shrink-0 space-y-2">
|
<div className="w-full px-2 py-2 flex flex-col justify-start items-start shrink-0 space-y-2">
|
||||||
{!isVisitorMode && (
|
{navLinks.map((navLink) => (
|
||||||
<>
|
<NavLink
|
||||||
<NavLink
|
key={navLink.id}
|
||||||
to="/"
|
to={navLink.path}
|
||||||
id="header-home"
|
id={navLink.id}
|
||||||
className={({ isActive }) =>
|
className={({ isActive }) =>
|
||||||
classNames(
|
classNames(
|
||||||
"px-4 pr-5 py-2 rounded-full border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-600 dark:hover:bg-zinc-700",
|
"px-4 pr-5 py-2 rounded-full border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-600 dark:hover:bg-zinc-700",
|
||||||
isActive ? "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600" : "border-transparent"
|
isActive ? "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600" : "border-transparent"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<Icon.Home className="mr-3 w-6 h-auto opacity-70" /> {t("common.home")}
|
{navLink.icon} {navLink.title}
|
||||||
</>
|
</>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<NavLink
|
))}
|
||||||
to="/review"
|
|
||||||
id="header-review"
|
|
||||||
className={({ isActive }) =>
|
|
||||||
classNames(
|
|
||||||
"px-4 pr-5 py-2 rounded-full border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-600 dark:hover:bg-zinc-700",
|
|
||||||
isActive ? "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600" : "border-transparent"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<>
|
|
||||||
<Icon.Calendar className="mr-3 w-6 h-auto opacity-70" /> {t("daily-review.title")}
|
|
||||||
</>
|
|
||||||
</NavLink>
|
|
||||||
<NavLink
|
|
||||||
to="/resources"
|
|
||||||
id="header-resources"
|
|
||||||
className={({ isActive }) =>
|
|
||||||
classNames(
|
|
||||||
"px-4 pr-5 py-2 rounded-full border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-600 dark:hover:bg-zinc-700",
|
|
||||||
isActive ? "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600" : "border-transparent"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<>
|
|
||||||
<Icon.Paperclip className="mr-3 w-6 h-auto opacity-70" /> {t("common.resources")}
|
|
||||||
</>
|
|
||||||
</NavLink>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{!globalStore.getDisablePublicMemos() && (
|
|
||||||
<>
|
|
||||||
<NavLink
|
|
||||||
to="/explore"
|
|
||||||
id="header-explore"
|
|
||||||
className={({ isActive }) =>
|
|
||||||
classNames(
|
|
||||||
"px-4 pr-5 py-2 rounded-full border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-600 dark:hover:bg-zinc-700",
|
|
||||||
isActive ? "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600" : "border-transparent"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<>
|
|
||||||
<Icon.Hash className="mr-3 w-6 h-auto opacity-70" /> {t("common.explore")}
|
|
||||||
</>
|
|
||||||
</NavLink>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!isVisitorMode && (
|
|
||||||
<>
|
|
||||||
<NavLink
|
|
||||||
to="/archived"
|
|
||||||
id="header-archived"
|
|
||||||
className={({ isActive }) =>
|
|
||||||
classNames(
|
|
||||||
"px-4 pr-5 py-2 rounded-full border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-600 dark:hover:bg-zinc-700",
|
|
||||||
isActive ? "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600" : "border-transparent"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<>
|
|
||||||
<Icon.Archive className="mr-3 w-6 h-auto opacity-70" /> {t("common.archived")}
|
|
||||||
</>
|
|
||||||
</NavLink>
|
|
||||||
<NavLink
|
|
||||||
to="/setting"
|
|
||||||
id="header-setting"
|
|
||||||
className={({ isActive }) =>
|
|
||||||
classNames(
|
|
||||||
"px-4 pr-5 py-2 rounded-full border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-600 dark:hover:bg-zinc-700",
|
|
||||||
isActive ? "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600" : "border-transparent"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<>
|
|
||||||
<Icon.Settings className="mr-3 w-6 h-auto opacity-70" /> {t("common.settings")}
|
|
||||||
</>
|
|
||||||
</NavLink>
|
|
||||||
<UpgradeVersionView />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{isVisitorMode && (
|
|
||||||
<>
|
|
||||||
<NavLink
|
|
||||||
to="/auth"
|
|
||||||
id="header-auth"
|
|
||||||
className={({ isActive }) =>
|
|
||||||
classNames(
|
|
||||||
"px-4 pr-5 py-2 rounded-full border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-600 dark:hover:bg-zinc-700",
|
|
||||||
isActive ? "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600" : "border-transparent"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<>
|
|
||||||
<Icon.LogIn className="mr-3 w-6 h-auto opacity-70" /> {t("common.sign-in")}
|
|
||||||
</>
|
|
||||||
</NavLink>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Divider, Tooltip } from "@mui/joy";
|
import { Divider } from "@mui/joy";
|
||||||
import { isEqual, uniqWith } from "lodash-es";
|
import { isEqual, uniqWith } from "lodash-es";
|
||||||
import { memo, useEffect, useRef, useState } from "react";
|
import { memo, useEffect, useRef, useState } from "react";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
@ -31,7 +31,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Memo: React.FC<Props> = (props: Props) => {
|
const Memo: React.FC<Props> = (props: Props) => {
|
||||||
const { memo, showCreator, showFull, showVisibility, showRelatedMemos, lazyRendering } = props;
|
const { memo, showCreator, showFull, showRelatedMemos, lazyRendering } = props;
|
||||||
const { i18n } = useTranslation();
|
const { i18n } = useTranslation();
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const filterStore = useFilterStore();
|
const filterStore = useFilterStore();
|
||||||
@ -243,15 +243,6 @@ const Memo: React.FC<Props> = (props: Props) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMemoVisibilityClick = (visibility: Visibility) => {
|
|
||||||
const currVisibilityQuery = filterStore.getState().visibility;
|
|
||||||
if (currVisibilityQuery === visibility) {
|
|
||||||
filterStore.setMemoVisibilityFilter(undefined);
|
|
||||||
} else {
|
|
||||||
filterStore.setMemoVisibilityFilter(visibility);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={`memo-wrapper ${"memos-" + memo.id} ${memo.pinned && !readonly ? "pinned" : ""}`} ref={memoContainerRef}>
|
<div className={`memo-wrapper ${"memos-" + memo.id} ${memo.pinned && !readonly ? "pinned" : ""}`} ref={memoContainerRef}>
|
||||||
@ -271,17 +262,6 @@ const Memo: React.FC<Props> = (props: Props) => {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="btns-container space-x-2">
|
<div className="btns-container space-x-2">
|
||||||
{showVisibility && memo.visibility !== "PRIVATE" && (
|
|
||||||
<Tooltip title={t(`memo.visibility.${memo.visibility.toLowerCase() as Lowercase<typeof memo.visibility>}`)} placement="top">
|
|
||||||
<div onClick={() => handleMemoVisibilityClick(memo.visibility)}>
|
|
||||||
{memo.visibility === "PUBLIC" ? (
|
|
||||||
<Icon.Globe2 className="w-4 h-auto cursor-pointer rounded text-green-600" />
|
|
||||||
) : (
|
|
||||||
<Icon.Users className="w-4 h-auto cursor-pointer rounded text-gray-500 dark:text-gray-400" />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
{memo.pinned && <Icon.Bookmark className="w-4 h-auto rounded text-green-600" />}
|
{memo.pinned && <Icon.Bookmark className="w-4 h-auto rounded text-green-600" />}
|
||||||
{!readonly && (
|
{!readonly && (
|
||||||
<>
|
<>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Button, Input } from "@mui/joy";
|
import { Button, Dropdown, Input, Menu, MenuButton } from "@mui/joy";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
import * as api from "@/helpers/api";
|
import * as api from "@/helpers/api";
|
||||||
@ -6,7 +6,7 @@ import { useUserStore } from "@/store/module";
|
|||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
import showChangeMemberPasswordDialog from "../ChangeMemberPasswordDialog";
|
import showChangeMemberPasswordDialog from "../ChangeMemberPasswordDialog";
|
||||||
import { showCommonDialog } from "../Dialog/CommonDialog";
|
import { showCommonDialog } from "../Dialog/CommonDialog";
|
||||||
import Dropdown from "../kit/Dropdown";
|
import Icon from "../Icon";
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
createUserUsername: string;
|
createUserUsername: string;
|
||||||
@ -163,8 +163,11 @@ const PreferencesSection = () => {
|
|||||||
{currentUser?.id === user.id ? (
|
{currentUser?.id === user.id ? (
|
||||||
<span>{t("common.yourself")}</span>
|
<span>{t("common.yourself")}</span>
|
||||||
) : (
|
) : (
|
||||||
<Dropdown
|
<Dropdown>
|
||||||
actions={
|
<MenuButton size="sm">
|
||||||
|
<Icon.MoreVertical className="w-4 h-auto" />
|
||||||
|
</MenuButton>
|
||||||
|
<Menu>
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
className="w-full text-left text-sm whitespace-nowrap leading-6 py-1 px-3 cursor-pointer rounded hover:bg-gray-100 dark:hover:bg-zinc-600"
|
className="w-full text-left text-sm whitespace-nowrap leading-6 py-1 px-3 cursor-pointer rounded hover:bg-gray-100 dark:hover:bg-zinc-600"
|
||||||
@ -196,8 +199,8 @@ const PreferencesSection = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
}
|
</Menu>
|
||||||
/>
|
</Dropdown>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -53,7 +53,7 @@ const MyAccountSection = () => {
|
|||||||
<p className="title-text">Open ID</p>
|
<p className="title-text">Open ID</p>
|
||||||
<div className="w-full flex flex-row justify-start items-center">
|
<div className="w-full flex flex-row justify-start items-center">
|
||||||
<Input className="grow mr-2" value={user.openId} readOnly />
|
<Input className="grow mr-2" value={user.openId} readOnly />
|
||||||
<Button className="shrink-0" color="warning" onClick={handleResetOpenIdBtnClick}>
|
<Button className="shrink-0" color="neutral" variant="outlined" onClick={handleResetOpenIdBtnClick}>
|
||||||
<Icon.RefreshCw className="h-4 w-4" />
|
<Icon.RefreshCw className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,7 +38,7 @@ const UserBanner = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="flex flex-row justify-between items-center relative w-full h-auto px-2 flex-nowrap shrink-0">
|
<div className="flex flex-row justify-between items-center relative w-full h-auto px-2 flex-nowrap shrink-0">
|
||||||
<Dropdown
|
<Dropdown
|
||||||
className="w-full"
|
className="w-auto"
|
||||||
trigger={
|
trigger={
|
||||||
<div className="px-4 py-2 max-w-full flex flex-row justify-start items-center cursor-pointer rounded-lg hover:shadow hover:bg-white dark:hover:bg-zinc-700">
|
<div className="px-4 py-2 max-w-full flex flex-row justify-start items-center cursor-pointer rounded-lg hover:shadow hover:bg-white dark:hover:bg-zinc-700">
|
||||||
<UserAvatar avatarUrl={user?.avatarUrl} />
|
<UserAvatar avatarUrl={user?.avatarUrl} />
|
||||||
|
@ -5,10 +5,6 @@ export function convertToMillis(localSetting: LocalSetting) {
|
|||||||
return hoursToMillis;
|
return hoursToMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNowTimeStamp(): number {
|
|
||||||
return Date.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getTimeStampByDate(t: Date | number | string): number {
|
export function getTimeStampByDate(t: Date | number | string): number {
|
||||||
if (typeof t === "string") {
|
if (typeof t === "string") {
|
||||||
t = t.replaceAll("-", "/");
|
t = t.replaceAll("-", "/");
|
||||||
@ -113,7 +109,6 @@ export function getDateString(t?: Date | number | string, locale = i18n.language
|
|||||||
* - "x months ago"
|
* - "x months ago"
|
||||||
* - "last year"
|
* - "last year"
|
||||||
* - "x years ago"
|
* - "x years ago"
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
export const getRelativeTimeString = (time: number, locale = i18n.language, formatStyle: "long" | "short" | "narrow" = "long"): string => {
|
export const getRelativeTimeString = (time: number, locale = i18n.language, formatStyle: "long" | "short" | "narrow" = "long"): string => {
|
||||||
const pastTimeMillis = Date.now() - time;
|
const pastTimeMillis = Date.now() - time;
|
||||||
|
@ -2,21 +2,6 @@ export const isNullorUndefined = (value: any) => {
|
|||||||
return value === null || value === undefined;
|
return value === null || value === undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getOSVersion(): "Windows" | "MacOS" | "Linux" | "Unknown" {
|
|
||||||
const appVersion = navigator.userAgent;
|
|
||||||
let detectedOS: "Windows" | "MacOS" | "Linux" | "Unknown" = "Unknown";
|
|
||||||
|
|
||||||
if (appVersion.indexOf("Win") != -1) {
|
|
||||||
detectedOS = "Windows";
|
|
||||||
} else if (appVersion.indexOf("Mac") != -1) {
|
|
||||||
detectedOS = "MacOS";
|
|
||||||
} else if (appVersion.indexOf("Linux") != -1) {
|
|
||||||
detectedOS = "Linux";
|
|
||||||
}
|
|
||||||
|
|
||||||
return detectedOS;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getElementBounding = (element: HTMLElement, relativeEl?: HTMLElement) => {
|
export const getElementBounding = (element: HTMLElement, relativeEl?: HTMLElement) => {
|
||||||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
|
||||||
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
|
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
|
||||||
@ -67,14 +52,6 @@ export const getElementBounding = (element: HTMLElement, relativeEl?: HTMLElemen
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parseHTMLToRawText = (htmlStr: string): string => {
|
|
||||||
const tempEl = document.createElement("div");
|
|
||||||
tempEl.className = "memo-content-text";
|
|
||||||
tempEl.innerHTML = htmlStr;
|
|
||||||
const text = tempEl.innerText;
|
|
||||||
return text;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function absolutifyLink(rel: string): string {
|
export function absolutifyLink(rel: string): string {
|
||||||
const anchor = document.createElement("a");
|
const anchor = document.createElement("a");
|
||||||
anchor.setAttribute("href", rel);
|
anchor.setAttribute("href", rel);
|
||||||
@ -107,11 +84,6 @@ export const formatBytes = (bytes: number) => {
|
|||||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getContentQueryParam = (): string | undefined => {
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
return urlParams.get("content") ?? undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const clearContentQueryParam = () => {
|
export const clearContentQueryParam = () => {
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
urlParams.delete("content");
|
urlParams.delete("content");
|
||||||
|
@ -4,7 +4,6 @@ import ArchivedMemo from "@/components/ArchivedMemo";
|
|||||||
import Empty from "@/components/Empty";
|
import Empty from "@/components/Empty";
|
||||||
import MemoFilter from "@/components/MemoFilter";
|
import MemoFilter from "@/components/MemoFilter";
|
||||||
import MobileHeader from "@/components/MobileHeader";
|
import MobileHeader from "@/components/MobileHeader";
|
||||||
import SearchBar from "@/components/SearchBar";
|
|
||||||
import useLoading from "@/hooks/useLoading";
|
import useLoading from "@/hooks/useLoading";
|
||||||
import { useFilterStore, useMemoStore } from "@/store/module";
|
import { useFilterStore, useMemoStore } from "@/store/module";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
@ -40,9 +39,6 @@ const Archived = () => {
|
|||||||
<section className="w-full min-h-full flex flex-col md:flex-row justify-start items-start px-4 sm:px-2 sm:pt-4 pb-8 bg-zinc-100 dark:bg-zinc-800">
|
<section className="w-full min-h-full flex flex-col md:flex-row justify-start items-start px-4 sm:px-2 sm:pt-4 pb-8 bg-zinc-100 dark:bg-zinc-800">
|
||||||
<MobileHeader showSearch={false} />
|
<MobileHeader showSearch={false} />
|
||||||
<div className="archived-memo-page">
|
<div className="archived-memo-page">
|
||||||
<div className="mb-2 mt-2 w-full">
|
|
||||||
<SearchBar />
|
|
||||||
</div>
|
|
||||||
<MemoFilter />
|
<MemoFilter />
|
||||||
{loadingState.isLoading ? (
|
{loadingState.isLoading ? (
|
||||||
<div className="tip-text-container">
|
<div className="tip-text-container">
|
||||||
|
@ -19,15 +19,13 @@ import { findNearestLanguageMatch, useTranslate } from "@/utils/i18n";
|
|||||||
const DailyReview = () => {
|
const DailyReview = () => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const memoStore = useMemoStore();
|
const memoStore = useMemoStore();
|
||||||
const memos = memoStore.state.memos;
|
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const { localSetting } = userStore.state.user as User;
|
const { localSetting } = userStore.state.user as User;
|
||||||
const [currentDateStamp, setCurrentDateStamp] = useState(getDateStampByDate(getNormalizedDateString()));
|
const [currentDateStamp, setCurrentDateStamp] = useState(getDateStampByDate(getNormalizedDateString()));
|
||||||
const [showDatePicker, toggleShowDatePicker] = useToggle(false);
|
const [showDatePicker, toggleShowDatePicker] = useToggle(false);
|
||||||
const memosElRef = useRef<HTMLDivElement>(null);
|
const memosElRef = useRef<HTMLDivElement>(null);
|
||||||
const currentDate = new Date(currentDateStamp);
|
const currentDate = new Date(currentDateStamp);
|
||||||
const dailyMemos = memos
|
const dailyMemos = memoStore.state.memos
|
||||||
.filter((m) => {
|
.filter((m) => {
|
||||||
const displayTimestamp = getTimeStampByDate(m.displayTs);
|
const displayTimestamp = getTimeStampByDate(m.displayTs);
|
||||||
const currentDateStampWithOffset = currentDateStamp + convertToMillis(localSetting);
|
const currentDateStampWithOffset = currentDateStamp + convertToMillis(localSetting);
|
||||||
|
@ -5,17 +5,15 @@ import Empty from "@/components/Empty";
|
|||||||
import Memo from "@/components/Memo";
|
import Memo from "@/components/Memo";
|
||||||
import MemoFilter from "@/components/MemoFilter";
|
import MemoFilter from "@/components/MemoFilter";
|
||||||
import MobileHeader from "@/components/MobileHeader";
|
import MobileHeader from "@/components/MobileHeader";
|
||||||
import SearchBar from "@/components/SearchBar";
|
|
||||||
import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts";
|
import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts";
|
||||||
import useLoading from "@/hooks/useLoading";
|
import useLoading from "@/hooks/useLoading";
|
||||||
import { TAG_REG } from "@/labs/marked/parser";
|
import { TAG_REG } from "@/labs/marked/parser";
|
||||||
import { useFilterStore, useGlobalStore, useMemoStore } from "@/store/module";
|
import { useFilterStore, useMemoStore } from "@/store/module";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
|
|
||||||
const Explore = () => {
|
const Explore = () => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const globalStore = useGlobalStore();
|
|
||||||
const filterStore = useFilterStore();
|
const filterStore = useFilterStore();
|
||||||
const memoStore = useMemoStore();
|
const memoStore = useMemoStore();
|
||||||
const filter = filterStore.state;
|
const filter = filterStore.state;
|
||||||
@ -91,11 +89,6 @@ const Explore = () => {
|
|||||||
return (
|
return (
|
||||||
<section className="w-full max-w-3xl min-h-full flex flex-col justify-start items-center px-4 sm:px-2 sm:pt-4 pb-8 bg-zinc-100 dark:bg-zinc-800">
|
<section className="w-full max-w-3xl min-h-full flex flex-col justify-start items-center px-4 sm:px-2 sm:pt-4 pb-8 bg-zinc-100 dark:bg-zinc-800">
|
||||||
<MobileHeader showSearch={false} />
|
<MobileHeader showSearch={false} />
|
||||||
{globalStore.isDev() && (
|
|
||||||
<div className="mb-4 mt-2 w-full">
|
|
||||||
<SearchBar />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{!loadingState.isLoading && (
|
{!loadingState.isLoading && (
|
||||||
<main className="relative w-full h-auto flex flex-col justify-start items-start">
|
<main className="relative w-full h-auto flex flex-col justify-start items-start">
|
||||||
<MemoFilter />
|
<MemoFilter />
|
||||||
|
Reference in New Issue
Block a user