mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-03 00:33:49 +03:00
reloading user profile on update
This commit is contained in:
parent
9c37711bbf
commit
eea19d43c2
@ -3,8 +3,12 @@ import { HydraApi } from "@main/services/hydra-api";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import mime from "mime";
|
import mime from "mime";
|
||||||
|
import { UserProfile } from "@types";
|
||||||
|
|
||||||
const patchUserProfile = (displayName: string, profileImageUrl?: string) => {
|
const patchUserProfile = async (
|
||||||
|
displayName: string,
|
||||||
|
profileImageUrl?: string
|
||||||
|
) => {
|
||||||
if (profileImageUrl) {
|
if (profileImageUrl) {
|
||||||
return HydraApi.patch("/profile", {
|
return HydraApi.patch("/profile", {
|
||||||
displayName,
|
displayName,
|
||||||
@ -21,10 +25,9 @@ const updateProfile = async (
|
|||||||
_event: Electron.IpcMainInvokeEvent,
|
_event: Electron.IpcMainInvokeEvent,
|
||||||
displayName: string,
|
displayName: string,
|
||||||
newProfileImagePath: string | null
|
newProfileImagePath: string | null
|
||||||
): Promise<any> => {
|
): Promise<UserProfile | null> => {
|
||||||
if (!newProfileImagePath) {
|
if (!newProfileImagePath) {
|
||||||
patchUserProfile(displayName);
|
return (await patchUserProfile(displayName)).data;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const stats = fs.statSync(newProfileImagePath);
|
const stats = fs.statSync(newProfileImagePath);
|
||||||
@ -51,8 +54,7 @@ const updateProfile = async (
|
|||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(profileImageUrl);
|
return (await patchUserProfile(displayName, profileImageUrl)).data;
|
||||||
patchUserProfile(displayName, profileImageUrl);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
registerEvent("updateProfile", updateProfile);
|
registerEvent("updateProfile", updateProfile);
|
||||||
|
2
src/renderer/src/declaration.d.ts
vendored
2
src/renderer/src/declaration.d.ts
vendored
@ -125,7 +125,7 @@ declare global {
|
|||||||
updateProfile: (
|
updateProfile: (
|
||||||
displayName: string,
|
displayName: string,
|
||||||
newProfileImagePath: string | null
|
newProfileImagePath: string | null
|
||||||
) => Promise<void>;
|
) => Promise<UserProfile | null>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -47,11 +47,38 @@ export function useUserDetails() {
|
|||||||
});
|
});
|
||||||
}, [dispatch]);
|
}, [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 {
|
return {
|
||||||
userDetails,
|
userDetails,
|
||||||
updateUser,
|
updateUser,
|
||||||
signOut,
|
signOut,
|
||||||
clearUser,
|
clearUser,
|
||||||
|
patchUser,
|
||||||
profileBackground,
|
profileBackground,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,7 @@ export function UserContent({
|
|||||||
}: ProfileContentProps) {
|
}: ProfileContentProps) {
|
||||||
const { t, i18n } = useTranslation("user_profile");
|
const { t, i18n } = useTranslation("user_profile");
|
||||||
|
|
||||||
const { userDetails, profileBackground, signOut, updateUser } =
|
const { userDetails, profileBackground, signOut } = useUserDetails();
|
||||||
useUserDetails();
|
|
||||||
|
|
||||||
const [showEditProfileModal, setShowEditProfileModal] = useState(false);
|
const [showEditProfileModal, setShowEditProfileModal] = useState(false);
|
||||||
|
|
||||||
@ -72,7 +71,6 @@ export function UserContent({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdateUserProfile = async () => {
|
const handleUpdateUserProfile = async () => {
|
||||||
updateUser();
|
|
||||||
updateUserProfile();
|
updateUserProfile();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Button, Modal, TextField } from "@renderer/components";
|
import { Button, Modal, TextField } from "@renderer/components";
|
||||||
import { UserProfile } from "@types";
|
import { UserProfile } from "@types";
|
||||||
import * as styles from "./user.css";
|
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 { SPACING_UNIT } from "@renderer/theme.css";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useToast } from "@renderer/hooks";
|
import { useToast, useUserDetails } from "@renderer/hooks";
|
||||||
|
|
||||||
export interface UserEditProfileModalProps {
|
export interface UserEditProfileModalProps {
|
||||||
userProfile: UserProfile;
|
userProfile: UserProfile;
|
||||||
@ -22,6 +22,9 @@ export const UserEditProfileModal = ({
|
|||||||
const [displayName, setDisplayName] = useState(userProfile.displayName);
|
const [displayName, setDisplayName] = useState(userProfile.displayName);
|
||||||
const [newImagePath, setNewImagePath] = useState<string | null>(null);
|
const [newImagePath, setNewImagePath] = useState<string | null>(null);
|
||||||
const [newImageBase64, setNewImageBase64] = useState<string | null>(null);
|
const [newImageBase64, setNewImageBase64] = useState<string | null>(null);
|
||||||
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
|
|
||||||
|
const { patchUser } = useUserDetails();
|
||||||
|
|
||||||
const { showSuccessToast, showErrorToast } = useToast();
|
const { showSuccessToast, showErrorToast } = useToast();
|
||||||
|
|
||||||
@ -48,16 +51,19 @@ export const UserEditProfileModal = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveProfile = async () => {
|
const handleSaveProfile = async () => {
|
||||||
window.electron
|
setIsSaving(true);
|
||||||
.updateProfile(displayName, newImagePath)
|
patchUser(displayName, newImagePath)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
updateUser();
|
updateUser();
|
||||||
setNewImagePath(null);
|
setNewImagePath(null);
|
||||||
showSuccessToast("Sucesso");
|
showSuccessToast("Salvo com sucesso");
|
||||||
onClose();
|
onClose();
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
showErrorToast("Erro");
|
showErrorToast("Tente novamente");
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setIsSaving(false);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
@ -71,7 +77,7 @@ export const UserEditProfileModal = ({
|
|||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
gap: `${SPACING_UNIT * 3}px`,
|
gap: `${SPACING_UNIT * 3}px`,
|
||||||
width: "300px",
|
width: "350px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
@ -87,6 +93,9 @@ export const UserEditProfileModal = ({
|
|||||||
) : (
|
) : (
|
||||||
<PersonIcon size={72} />
|
<PersonIcon size={72} />
|
||||||
)}
|
)}
|
||||||
|
<div className={styles.editProfileImageBadge}>
|
||||||
|
<PencilIcon size={16} />
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
@ -95,8 +104,12 @@ export const UserEditProfileModal = ({
|
|||||||
containerProps={{ style: { width: "100%" } }}
|
containerProps={{ style: { width: "100%" } }}
|
||||||
onChange={(e) => setDisplayName(e.target.value)}
|
onChange={(e) => setDisplayName(e.target.value)}
|
||||||
/>
|
/>
|
||||||
<Button style={{ alignSelf: "end" }} onClick={handleSaveProfile}>
|
<Button
|
||||||
Salvar{" "}
|
disabled={isSaving}
|
||||||
|
style={{ alignSelf: "end" }}
|
||||||
|
onClick={handleSaveProfile}
|
||||||
|
>
|
||||||
|
{isSaving ? "Salvando..." : "Salvar"}
|
||||||
</Button>
|
</Button>
|
||||||
</section>
|
</section>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -38,19 +38,22 @@ export const profileAvatarContainer = style({
|
|||||||
export const profileAvatarEditContainer = style({
|
export const profileAvatarEditContainer = style({
|
||||||
width: "128px",
|
width: "128px",
|
||||||
height: "128px",
|
height: "128px",
|
||||||
borderRadius: "50%",
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
|
borderRadius: "50%",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
backgroundColor: vars.color.background,
|
backgroundColor: vars.color.background,
|
||||||
position: "relative",
|
position: "relative",
|
||||||
overflow: "hidden",
|
|
||||||
border: `solid 1px ${vars.color.border}`,
|
border: `solid 1px ${vars.color.border}`,
|
||||||
boxShadow: "0px 0px 5px 0px rgba(0, 0, 0, 0.7)",
|
boxShadow: "0px 0px 5px 0px rgba(0, 0, 0, 0.7)",
|
||||||
|
cursor: "pointer",
|
||||||
});
|
});
|
||||||
|
|
||||||
export const profileAvatar = style({
|
export const profileAvatar = style({
|
||||||
height: "100%",
|
height: "100%",
|
||||||
|
aspectRatio: 1,
|
||||||
|
borderRadius: "50%",
|
||||||
|
overflow: "hidden",
|
||||||
objectFit: "cover",
|
objectFit: "cover",
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -158,3 +161,17 @@ export const gameInformation = style({
|
|||||||
export const profileHeaderSkeleton = style({
|
export const profileHeaderSkeleton = style({
|
||||||
height: "200px",
|
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",
|
||||||
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user