reloading user profile on update

This commit is contained in:
Zamitto 2024-06-18 13:50:31 -03:00
parent 9c37711bbf
commit eea19d43c2
6 changed files with 78 additions and 21 deletions

View File

@ -3,8 +3,12 @@ import { HydraApi } from "@main/services/hydra-api";
import axios from "axios";
import fs from "node:fs";
import mime from "mime";
import { UserProfile } from "@types";
const patchUserProfile = (displayName: string, profileImageUrl?: string) => {
const patchUserProfile = async (
displayName: string,
profileImageUrl?: string
) => {
if (profileImageUrl) {
return HydraApi.patch("/profile", {
displayName,
@ -21,10 +25,9 @@ const updateProfile = async (
_event: Electron.IpcMainInvokeEvent,
displayName: string,
newProfileImagePath: string | null
): Promise<any> => {
): Promise<UserProfile | null> => {
if (!newProfileImagePath) {
patchUserProfile(displayName);
return;
return (await patchUserProfile(displayName)).data;
}
const stats = fs.statSync(newProfileImagePath);
@ -51,8 +54,7 @@ const updateProfile = async (
return undefined;
});
console.log(profileImageUrl);
patchUserProfile(displayName, profileImageUrl);
return (await patchUserProfile(displayName, profileImageUrl)).data;
};
registerEvent("updateProfile", updateProfile);

View File

@ -125,7 +125,7 @@ declare global {
updateProfile: (
displayName: string,
newProfileImagePath: string | null
) => Promise<void>;
) => Promise<UserProfile | null>;
}
interface Window {

View File

@ -47,11 +47,38 @@ export function useUserDetails() {
});
}, [dispatch]);
const patchUser = useCallback(
async (displayName: string, imageProfileUrl: string | null) => {
return window.electron
.updateProfile(displayName, imageProfileUrl)
.then(async (userDetails) => {
if (userDetails) {
dispatch(setUserDetails(userDetails));
if (userDetails.profileImageUrl) {
const output = await average(userDetails.profileImageUrl, {
amount: 1,
format: "hex",
});
dispatch(
setProfileBackground(
`linear-gradient(135deg, ${darkenColor(output as string, 0.6)}, ${darkenColor(output as string, 0.7)})`
)
);
}
}
});
},
[dispatch]
);
return {
userDetails,
updateUser,
signOut,
clearUser,
patchUser,
profileBackground,
};
}

View File

@ -26,8 +26,7 @@ export function UserContent({
}: ProfileContentProps) {
const { t, i18n } = useTranslation("user_profile");
const { userDetails, profileBackground, signOut, updateUser } =
useUserDetails();
const { userDetails, profileBackground, signOut } = useUserDetails();
const [showEditProfileModal, setShowEditProfileModal] = useState(false);
@ -72,7 +71,6 @@ export function UserContent({
};
const handleUpdateUserProfile = async () => {
updateUser();
updateUserProfile();
};

View File

@ -1,10 +1,10 @@
import { Button, Modal, TextField } from "@renderer/components";
import { UserProfile } from "@types";
import * as styles from "./user.css";
import { PersonIcon } from "@primer/octicons-react";
import { PencilIcon, PersonIcon } from "@primer/octicons-react";
import { SPACING_UNIT } from "@renderer/theme.css";
import { useState } from "react";
import { useToast } from "@renderer/hooks";
import { useToast, useUserDetails } from "@renderer/hooks";
export interface UserEditProfileModalProps {
userProfile: UserProfile;
@ -22,6 +22,9 @@ export const UserEditProfileModal = ({
const [displayName, setDisplayName] = useState(userProfile.displayName);
const [newImagePath, setNewImagePath] = useState<string | null>(null);
const [newImageBase64, setNewImageBase64] = useState<string | null>(null);
const [isSaving, setIsSaving] = useState(false);
const { patchUser } = useUserDetails();
const { showSuccessToast, showErrorToast } = useToast();
@ -48,16 +51,19 @@ export const UserEditProfileModal = ({
};
const handleSaveProfile = async () => {
window.electron
.updateProfile(displayName, newImagePath)
setIsSaving(true);
patchUser(displayName, newImagePath)
.then(() => {
updateUser();
setNewImagePath(null);
showSuccessToast("Sucesso");
showSuccessToast("Salvo com sucesso");
onClose();
})
.catch(() => {
showErrorToast("Erro");
showErrorToast("Tente novamente");
})
.finally(() => {
setIsSaving(false);
});
};
return (
@ -71,7 +77,7 @@ export const UserEditProfileModal = ({
justifyContent: "center",
alignItems: "center",
gap: `${SPACING_UNIT * 3}px`,
width: "300px",
width: "350px",
}}
>
<button
@ -87,6 +93,9 @@ export const UserEditProfileModal = ({
) : (
<PersonIcon size={72} />
)}
<div className={styles.editProfileImageBadge}>
<PencilIcon size={16} />
</div>
</button>
<TextField
@ -95,8 +104,12 @@ export const UserEditProfileModal = ({
containerProps={{ style: { width: "100%" } }}
onChange={(e) => setDisplayName(e.target.value)}
/>
<Button style={{ alignSelf: "end" }} onClick={handleSaveProfile}>
Salvar{" "}
<Button
disabled={isSaving}
style={{ alignSelf: "end" }}
onClick={handleSaveProfile}
>
{isSaving ? "Salvando..." : "Salvar"}
</Button>
</section>
</Modal>

View File

@ -38,19 +38,22 @@ export const profileAvatarContainer = style({
export const profileAvatarEditContainer = style({
width: "128px",
height: "128px",
borderRadius: "50%",
display: "flex",
borderRadius: "50%",
justifyContent: "center",
alignItems: "center",
backgroundColor: vars.color.background,
position: "relative",
overflow: "hidden",
border: `solid 1px ${vars.color.border}`,
boxShadow: "0px 0px 5px 0px rgba(0, 0, 0, 0.7)",
cursor: "pointer",
});
export const profileAvatar = style({
height: "100%",
aspectRatio: 1,
borderRadius: "50%",
overflow: "hidden",
objectFit: "cover",
});
@ -158,3 +161,17 @@ export const gameInformation = style({
export const profileHeaderSkeleton = style({
height: "200px",
});
export const editProfileImageBadge = style({
width: "28px",
height: "28px",
borderRadius: "50%",
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundColor: vars.color.muted,
position: "absolute",
bottom: "0px",
right: "0px",
zIndex: "1",
});