chore: update user store

pull/2683/head
Steven 1 year ago
parent f48ff102c9
commit 6fac116d8c

@ -1,6 +1,6 @@
import { Button } from "@mui/joy"; import { Button, Input } from "@mui/joy";
import { isEqual } from "lodash-es"; import { isEqual } from "lodash-es";
import { useEffect, useState } from "react"; import { useState } from "react";
import { toast } from "react-hot-toast"; import { toast } from "react-hot-toast";
import { convertFileToBase64 } from "@/helpers/utils"; import { convertFileToBase64 } from "@/helpers/utils";
import useCurrentUser from "@/hooks/useCurrentUser"; import useCurrentUser from "@/hooks/useCurrentUser";
@ -31,10 +31,6 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
email: currentUser.email, email: currentUser.email,
}); });
useEffect(() => {
// do nth
}, []);
const handleCloseBtnClick = () => { const handleCloseBtnClick = () => {
destroy(); destroy();
}; };
@ -97,18 +93,18 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
try { try {
const updateMask = []; const updateMask = [];
if (!isEqual(currentUser.avatarUrl, state.avatarUrl)) { if (!isEqual(currentUser.name.replace(UserNamePrefix, ""), state.username)) {
updateMask.push("avatar_url"); updateMask.push("username");
} }
if (!isEqual(currentUser.nickname, state.nickname)) { if (!isEqual(currentUser.nickname, state.nickname)) {
updateMask.push("nickname"); updateMask.push("nickname");
} }
if (!isEqual(currentUser.name.replace(UserNamePrefix, ""), state.username)) {
updateMask.push("username");
}
if (!isEqual(currentUser.email, state.email)) { if (!isEqual(currentUser.email, state.email)) {
updateMask.push("email"); updateMask.push("email");
} }
if (!isEqual(currentUser.avatarUrl, state.avatarUrl)) {
updateMask.push("avatar_url");
}
await userStore.updateUser( await userStore.updateUser(
UserPb.fromPartial({ UserPb.fromPartial({
name: currentUser.name, name: currentUser.name,
@ -123,7 +119,7 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
handleCloseBtnClick(); handleCloseBtnClick();
} catch (error: any) { } catch (error: any) {
console.error(error); console.error(error);
toast.error(error.response.data.error); toast.error(error.details);
} }
}; };
@ -139,7 +135,7 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
<div className="w-full flex flex-row justify-start items-center"> <div className="w-full flex flex-row justify-start items-center">
<span className="text-sm mr-2">{t("common.avatar")}</span> <span className="text-sm mr-2">{t("common.avatar")}</span>
<label className="relative cursor-pointer hover:opacity-80"> <label className="relative cursor-pointer hover:opacity-80">
<UserAvatar className="!w-12 !h-12" avatarUrl={state.avatarUrl} /> <UserAvatar className="!w-10 !h-10" avatarUrl={state.avatarUrl} />
<input type="file" accept="image/*" className="absolute invisible w-full h-full inset-0" onChange={handleAvatarChanged} /> <input type="file" accept="image/*" className="absolute invisible w-full h-full inset-0" onChange={handleAvatarChanged} />
</label> </label>
{state.avatarUrl && ( {state.avatarUrl && (
@ -155,19 +151,19 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
</div> </div>
<p className="text-sm"> <p className="text-sm">
{t("common.username")} {t("common.username")}
<span className="text-sm text-gray-400 ml-1">{t("setting.account-section.username-note")}</span> <span className="text-sm text-gray-400 ml-1">({t("setting.account-section.username-note")})</span>
</p> </p>
<input type="text" className="input-text" value={state.username} onChange={handleUsernameChanged} /> <Input className="w-full" value={state.username} onChange={handleUsernameChanged} />
<p className="text-sm"> <p className="text-sm">
{t("common.nickname")} {t("common.nickname")}
<span className="text-sm text-gray-400 ml-1">{t("setting.account-section.nickname-note")}</span> <span className="text-sm text-gray-400 ml-1">({t("setting.account-section.nickname-note")})</span>
</p> </p>
<input type="text" className="input-text" value={state.nickname} onChange={handleNicknameChanged} /> <Input className="w-full" value={state.nickname} onChange={handleNicknameChanged} />
<p className="text-sm"> <p className="text-sm">
{t("common.email")} {t("common.email")}
<span className="text-sm text-gray-400 ml-1">{t("setting.account-section.email-note")}</span> <span className="text-sm text-gray-400 ml-1">({t("setting.account-section.email-note")})</span>
</p> </p>
<input type="text" className="input-text" value={state.email} onChange={handleEmailChanged} /> <Input className="w-full" type="email" value={state.email} onChange={handleEmailChanged} />
<div className="w-full flex flex-row justify-end items-center pt-4 space-x-2"> <div className="w-full flex flex-row justify-end items-center pt-4 space-x-2">
<Button color="neutral" variant="plain" onClick={handleCloseBtnClick}> <Button color="neutral" variant="plain" onClick={handleCloseBtnClick}>
{t("common.cancel")} {t("common.cancel")}

@ -1,8 +1,8 @@
import { useUserStore } from "@/store/v1"; import { extractUsernameFromName, useUserStore } from "@/store/v1";
const useCurrentUser = () => { const useCurrentUser = () => {
const userStore = useUserStore(); const userStore = useUserStore();
return userStore.getUserByUsername(userStore.currentUser?.username || ""); return userStore.getUserByUsername(extractUsernameFromName(userStore.currentUser) || "");
}; };
export default useCurrentUser; export default useCurrentUser;

@ -6,7 +6,8 @@ import { UserNamePrefix, extractUsernameFromName } from "./resourceName";
interface State { interface State {
userMapByUsername: Record<string, User>; userMapByUsername: Record<string, User>;
currentUser?: User; // The name of current user. Format: `users/${username}`
currentUser?: string;
userSetting?: UserSetting; userSetting?: UserSetting;
} }
@ -75,8 +76,14 @@ export const useUserStore = create(
throw new Error("User not found"); throw new Error("User not found");
} }
const userMap = get().userMapByUsername; const userMap = get().userMapByUsername;
if (user.name !== updatedUser.name) {
delete userMap[extractUsernameFromName(user.name)];
}
userMap[updatedUser.username] = updatedUser; userMap[updatedUser.username] = updatedUser;
set({ userMapByUsername: userMap }); set({ userMapByUsername: userMap });
if (user.name === get().currentUser) {
set({ currentUser: updatedUser.name });
}
return updatedUser; return updatedUser;
}, },
deleteUser: async (name: string) => { deleteUser: async (name: string) => {
@ -95,7 +102,7 @@ export const useUserStore = create(
} }
const userMap = get().userMapByUsername; const userMap = get().userMapByUsername;
userMap[user.username] = user; userMap[user.username] = user;
set({ currentUser: user, userMapByUsername: userMap }); set({ currentUser: user.name, userMapByUsername: userMap });
const { setting } = await userServiceClient.getUserSetting({}); const { setting } = await userServiceClient.getUserSetting({});
set({ set({
userSetting: UserSetting.fromPartial({ userSetting: UserSetting.fromPartial({
@ -105,9 +112,6 @@ export const useUserStore = create(
}); });
return user; return user;
}, },
setCurrentUser: (user: User) => {
set({ currentUser: user });
},
updateUserSetting: async (userSetting: Partial<UserSetting>, updateMask: string[]) => { updateUserSetting: async (userSetting: Partial<UserSetting>, updateMask: string[]) => {
const { setting: updatedUserSetting } = await userServiceClient.updateUserSetting({ const { setting: updatedUserSetting } = await userServiceClient.updateUserSetting({
setting: userSetting, setting: userSetting,

Loading…
Cancel
Save