update: all in one user avatar

This commit is contained in:
Zhang Minghan 2023-12-23 23:26:03 +08:00
parent abff5b9821
commit a82c5be593
6 changed files with 60 additions and 9 deletions

View File

@ -268,3 +268,17 @@ input[type="number"] {
} }
} }
} }
.avatar {
display: flex;
width: 2.5rem;
height: 2.5rem;
border-radius: var(--radius);
text-align: center;
p {
margin: auto;
color: hsl(var(--text));
transform: translateY(-1px);
}
}

View File

@ -0,0 +1,37 @@
import { deeptrainApiEndpoint, useDeeptrain } from "@/utils/env.ts";
import { ImgHTMLAttributes, useMemo } from "react";
export interface AvatarProps extends ImgHTMLAttributes<HTMLElement> {
username: string;
}
function Avatar({ username, ...props }: AvatarProps) {
const code = useMemo(
() => (username.length > 0 ? username[0].toUpperCase() : "A"),
[username],
);
const color = useMemo(() => {
const colors = [
"bg-red-500",
"bg-yellow-500",
"bg-green-500",
"bg-blue-500",
"bg-indigo-500",
"bg-purple-500",
"bg-pink-500",
];
const index = code.charCodeAt(0) % colors.length;
return colors[index];
}, [username]);
return useDeeptrain ? (
<img {...props} src={`${deeptrainApiEndpoint}/avatar/${username}`} alt="" />
) : (
<div {...props} className={`avatar ${color}`}>
<p>{code}</p>
</div>
);
}
export default Avatar;

View File

@ -16,8 +16,8 @@ import ModeToggle from "@/components/ThemeProvider.tsx";
import router from "@/router.tsx"; import router from "@/router.tsx";
import MenuBar from "./MenuBar.tsx"; import MenuBar from "./MenuBar.tsx";
import { getMemory } from "@/utils/memory.ts"; import { getMemory } from "@/utils/memory.ts";
import { deeptrainApiEndpoint } from "@/utils/env.ts";
import { goAuth } from "@/utils/app.ts"; import { goAuth } from "@/utils/app.ts";
import Avatar from "@/components/Avatar.tsx";
function NavMenu() { function NavMenu() {
const username = useSelector(selectUsername); const username = useSelector(selectUsername);
@ -26,7 +26,7 @@ function NavMenu() {
<div className={`avatar`}> <div className={`avatar`}>
<MenuBar> <MenuBar>
<Button variant={`ghost`} size={`icon`}> <Button variant={`ghost`} size={`icon`}>
<img src={`${deeptrainApiEndpoint}/avatar/${username}`} alt="" /> <Avatar username={username} />
</Button> </Button>
</MenuBar> </MenuBar>
</div> </div>

View File

@ -41,8 +41,8 @@ import { getSharedLink, shareConversation } from "@/api/sharing.ts";
import { Input } from "@/components/ui/input.tsx"; import { Input } from "@/components/ui/input.tsx";
import MenuBar from "@/components/app/MenuBar.tsx"; import MenuBar from "@/components/app/MenuBar.tsx";
import { Separator } from "@/components/ui/separator.tsx"; import { Separator } from "@/components/ui/separator.tsx";
import { deeptrainApiEndpoint } from "@/utils/env.ts";
import { goAuth } from "@/utils/app.ts"; import { goAuth } from "@/utils/app.ts";
import Avatar from "@/components/Avatar.tsx";
type Operation = { type Operation = {
target: ConversationInstance | null; target: ConversationInstance | null;
@ -325,7 +325,7 @@ function SidebarMenu() {
<Separator orientation={`horizontal`} className={`mb-2`} /> <Separator orientation={`horizontal`} className={`mb-2`} />
<MenuBar className={`menu-bar`}> <MenuBar className={`menu-bar`}>
<Button variant={`ghost`} className={`sidebar-wrapper`}> <Button variant={`ghost`} className={`sidebar-wrapper`}>
<img src={`${deeptrainApiEndpoint}/avatar/${username}`} alt="" /> <Avatar username={username} />
<span className={`username`}>{username}</span> <span className={`username`}>{username}</span>
<MoreHorizontal className={`h-4 w-4`} /> <MoreHorizontal className={`h-4 w-4`} />
</Button> </Button>

View File

@ -12,7 +12,7 @@ import router from "@/router.tsx";
import { useToast } from "@/components/ui/use-toast.ts"; import { useToast } from "@/components/ui/use-toast.ts";
import { sharingEvent } from "@/events/sharing.ts"; import { sharingEvent } from "@/events/sharing.ts";
import { Message } from "@/api/types.ts"; import { Message } from "@/api/types.ts";
import { deeptrainApiEndpoint } from "@/utils/env.ts"; import Avatar from "@/components/Avatar.tsx";
type SharingFormProps = { type SharingFormProps = {
refer?: string; refer?: string;
@ -33,7 +33,7 @@ function SharingForm({ refer, data }: SharingFormProps) {
<div className={`sharing-container`}> <div className={`sharing-container`}>
<div className={`header`}> <div className={`header`}>
<div className={`user`}> <div className={`user`}>
<img src={`${deeptrainApiEndpoint}/avatar/${data.username}`} alt="" /> <Avatar username={data.username} />
<span>{data.username}</span> <span>{data.username}</span>
</div> </div>
<div className={`name`}>{data.name}</div> <div className={`name`}>{data.name}</div>

View File

@ -119,11 +119,11 @@ func SignUp(c *gin.Context, form RegisterForm) (string, error) {
return "", errors.New("invalid username/password/email format") return "", errors.New("invalid username/password/email format")
} }
if !IsUserExist(db, username) { if IsUserExist(db, username) {
return "", fmt.Errorf("username is already taken, please try another one username (your current username: %s)", username) return "", fmt.Errorf("username is already taken, please try another one username (your current username: %s)", username)
} }
if !IsEmailExist(db, email) { if IsEmailExist(db, email) {
return "", fmt.Errorf("email is already taken, please try another one email (your current email: %s)", email) return "", fmt.Errorf("email is already taken, please try another one email (your current email: %s)", email)
} }
@ -170,7 +170,7 @@ func Login(c *gin.Context, form LoginForm) (string, error) {
if err := db.QueryRow(` if err := db.QueryRow(`
SELECT auth.id, auth.username, auth.password FROM auth SELECT auth.id, auth.username, auth.password FROM auth
WHERE (auth.username = ? OR auth.email = ?) AND auth.password = ? WHERE (auth.username = ? OR auth.email = ?) AND auth.password = ?
`, username, hash).Scan(&user.ID, &user.Username, &user.Password); err != nil { `, username, username, hash).Scan(&user.ID, &user.Username, &user.Password); err != nil {
return "", errors.New("invalid username or password") return "", errors.New("invalid username or password")
} }