fix(header): fix userIcon
This commit is contained in:
@@ -17,8 +17,10 @@ import {
|
|||||||
useComputedColorScheme,
|
useComputedColorScheme,
|
||||||
useMantineColorScheme,
|
useMantineColorScheme,
|
||||||
} from "@mantine/core"
|
} from "@mantine/core"
|
||||||
|
import Avvvatars from "avvvatars-react"
|
||||||
|
|
||||||
import { useDisclosure, useMediaQuery } from "@mantine/hooks"
|
import { useDisclosure, useMediaQuery } from "@mantine/hooks"
|
||||||
import { IconLogout, IconMoon, IconSun, IconUser } from "@tabler/icons-react"
|
import { IconLogout, IconMoon, IconSun } from "@tabler/icons-react"
|
||||||
import cx from "clsx"
|
import cx from "clsx"
|
||||||
import { Suspense, useEffect, useMemo, useState } from "react"
|
import { Suspense, useEffect, useMemo, useState } from "react"
|
||||||
import actionToggleClasses from "./ActionToggle.module.css"
|
import actionToggleClasses from "./ActionToggle.module.css"
|
||||||
@@ -33,6 +35,103 @@ import { ClientIcon } from "./components/ClientIcon"
|
|||||||
import { LinksGroup } from "./components/NavbarLinks"
|
import { LinksGroup } from "./components/NavbarLinks"
|
||||||
import { useAppLayoutStore } from "./store"
|
import { useAppLayoutStore } from "./store"
|
||||||
|
|
||||||
|
const COMPOUND_SURNAMES = new Set([
|
||||||
|
"欧阳",
|
||||||
|
"太史",
|
||||||
|
"端木",
|
||||||
|
"上官",
|
||||||
|
"司马",
|
||||||
|
"东方",
|
||||||
|
"独孤",
|
||||||
|
"南宫",
|
||||||
|
"万俟",
|
||||||
|
"闻人",
|
||||||
|
"夏侯",
|
||||||
|
"诸葛",
|
||||||
|
"尉迟",
|
||||||
|
"公羊",
|
||||||
|
"赫连",
|
||||||
|
"澹台",
|
||||||
|
"皇甫",
|
||||||
|
"宗政",
|
||||||
|
"濮阳",
|
||||||
|
"公冶",
|
||||||
|
"太叔",
|
||||||
|
"申屠",
|
||||||
|
"公孙",
|
||||||
|
"慕容",
|
||||||
|
"仲孙",
|
||||||
|
"钟离",
|
||||||
|
"长孙",
|
||||||
|
"宇文",
|
||||||
|
"司徒",
|
||||||
|
"鲜于",
|
||||||
|
"司空",
|
||||||
|
"闾丘",
|
||||||
|
"子车",
|
||||||
|
"亓官",
|
||||||
|
"司寇",
|
||||||
|
"巫马",
|
||||||
|
"公西",
|
||||||
|
"颛孙",
|
||||||
|
"壤驷",
|
||||||
|
"公良",
|
||||||
|
"漆雕",
|
||||||
|
"乐正",
|
||||||
|
"宰父",
|
||||||
|
"谷梁",
|
||||||
|
"拓跋",
|
||||||
|
"轩辕",
|
||||||
|
"令狐",
|
||||||
|
"段干",
|
||||||
|
"百里",
|
||||||
|
"呼延",
|
||||||
|
"东郭",
|
||||||
|
"南门",
|
||||||
|
"羊舌",
|
||||||
|
"微生",
|
||||||
|
"梁丘",
|
||||||
|
"左丘",
|
||||||
|
"东门",
|
||||||
|
"西门",
|
||||||
|
"南荣",
|
||||||
|
"第五",
|
||||||
|
])
|
||||||
|
|
||||||
|
function isChineseName(value: string) {
|
||||||
|
return /[\u4e00-\u9fff]/.test(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAvatarDisplayValue(rawValue?: string | null) {
|
||||||
|
const value = rawValue?.trim() ?? ""
|
||||||
|
|
||||||
|
if (!value) return "-"
|
||||||
|
|
||||||
|
if (isChineseName(value)) {
|
||||||
|
const normalized = value.replace(/[\s·•・・]/g, "")
|
||||||
|
if (normalized.length <= 1) return normalized
|
||||||
|
|
||||||
|
const surnameLength =
|
||||||
|
normalized.length >= 3 && COMPOUND_SURNAMES.has(normalized.slice(0, 2))
|
||||||
|
? 2
|
||||||
|
: 1
|
||||||
|
const givenName = normalized.slice(surnameLength)
|
||||||
|
|
||||||
|
if (!givenName) return normalized.slice(-1)
|
||||||
|
if (givenName.length <= 2) return givenName
|
||||||
|
return givenName.slice(-2)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tokens = value.split(/[\s-_]+/).filter(Boolean)
|
||||||
|
if (tokens.length >= 2) {
|
||||||
|
return `${tokens[0][0] ?? ""}${tokens[tokens.length - 1][0] ?? ""}`
|
||||||
|
.trim()
|
||||||
|
.toUpperCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.slice(0, 2).toUpperCase()
|
||||||
|
}
|
||||||
|
|
||||||
export default function AppLayout({
|
export default function AppLayout({
|
||||||
menu,
|
menu,
|
||||||
children,
|
children,
|
||||||
@@ -144,6 +243,10 @@ export default function AppLayout({
|
|||||||
}
|
}
|
||||||
const matches = useMediaQuery("(min-width: 48em)")
|
const matches = useMediaQuery("(min-width: 48em)")
|
||||||
const userName = usePermissionStore((s) => s.user_name)
|
const userName = usePermissionStore((s) => s.user_name)
|
||||||
|
const avatarDisplayValue = useMemo(
|
||||||
|
() => getAvatarDisplayValue(userName),
|
||||||
|
[userName]
|
||||||
|
)
|
||||||
|
|
||||||
return isClient ? (
|
return isClient ? (
|
||||||
withoutLayout ? (
|
withoutLayout ? (
|
||||||
@@ -199,10 +302,9 @@ export default function AppLayout({
|
|||||||
<Menu shadow="md" width={220}>
|
<Menu shadow="md" width={220}>
|
||||||
<Menu.Target>
|
<Menu.Target>
|
||||||
<UnstyledButton>
|
<UnstyledButton>
|
||||||
<IconUser
|
<Avvvatars
|
||||||
style={{ display: "block" }}
|
value={userName || "-"}
|
||||||
size={22}
|
displayValue={avatarDisplayValue}
|
||||||
stroke={1.5}
|
|
||||||
/>
|
/>
|
||||||
</UnstyledButton>
|
</UnstyledButton>
|
||||||
</Menu.Target>
|
</Menu.Target>
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
"@tiptap/react": "^3.15.3",
|
"@tiptap/react": "^3.15.3",
|
||||||
"@tiptap/starter-kit": "^3.15.3",
|
"@tiptap/starter-kit": "^3.15.3",
|
||||||
"@tmcw/togeojson": "^7.1.2",
|
"@tmcw/togeojson": "^7.1.2",
|
||||||
|
"avvvatars-react": "^0.4.2",
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"dayjs": "^1.11.18",
|
"dayjs": "^1.11.18",
|
||||||
|
|||||||
Reference in New Issue
Block a user