feat: adding local file protocol

This commit is contained in:
Chubby Granny Chaser 2024-06-19 09:48:11 +01:00
parent 1ef8e3fce3
commit 1fb1c9e81a
No known key found for this signature in database
10 changed files with 42 additions and 54 deletions

View file

@ -6,7 +6,7 @@
<title>Hydra</title>
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://cdn.losbroxas.org https://steamcdn-a.akamaihd.net https://shared.akamai.steamstatic.com https://cdn.cloudflare.steamstatic.com https://cdn2.steamgriddb.com https://cdn.akamai.steamstatic.com; media-src 'self' data: https://cdn.losbroxas.org https://steamcdn-a.akamaihd.net https://cdn.cloudflare.steamstatic.com https://cdn2.steamgriddb.com https://cdn.akamai.steamstatic.com https://shared.akamai.steamstatic.com;"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: local: https://cdn.losbroxas.org https://steamcdn-a.akamaihd.net https://shared.akamai.steamstatic.com https://cdn.cloudflare.steamstatic.com https://cdn2.steamgriddb.com https://cdn.akamai.steamstatic.com; media-src 'self' data: https://cdn.losbroxas.org https://steamcdn-a.akamaihd.net https://cdn.cloudflare.steamstatic.com https://cdn2.steamgriddb.com https://cdn.akamai.steamstatic.com https://shared.akamai.steamstatic.com;"
/>
</head>
<body style="background-color: #1c1c1c">

View file

@ -96,7 +96,6 @@ declare global {
/* Misc */
openExternal: (src: string) => Promise<void>;
imagePathToBase64: (filePath: string) => Promise<string>;
getVersion: () => Promise<string>;
ping: () => string;
getDefaultDownloadsPath: () => Promise<string>;

View file

@ -17,7 +17,7 @@ const MAX_MINUTES_TO_SHOW_IN_PLAYTIME = 120;
export interface ProfileContentProps {
userProfile: UserProfile;
updateUserProfile: () => void;
updateUserProfile: () => Promise<void>;
}
export function UserContent({
@ -70,10 +70,6 @@ export function UserContent({
navigate("/");
};
const handleUpdateUserProfile = async () => {
updateUserProfile();
};
const isMe = userDetails?.id == userProfile.id;
const profileContentBoxBackground = useMemo(() => {
@ -87,7 +83,7 @@ export function UserContent({
<UserEditProfileModal
visible={showEditProfileModal}
onClose={() => setShowEditProfileModal(false)}
updateUser={handleUpdateUserProfile}
updateUserProfile={updateUserProfile}
userProfile={userProfile}
/>

View file

@ -1,33 +1,36 @@
import { Button, Modal, TextField } from "@renderer/components";
import { UserProfile } from "@types";
import * as styles from "./user.css";
import { PencilIcon, PersonIcon } from "@primer/octicons-react";
import { DeviceCameraIcon, PersonIcon } from "@primer/octicons-react";
import { SPACING_UNIT } from "@renderer/theme.css";
import { useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { useToast, useUserDetails } from "@renderer/hooks";
export interface UserEditProfileModalProps {
userProfile: UserProfile;
visible: boolean;
onClose: () => void;
updateUser: () => Promise<void>;
updateUserProfile: () => Promise<void>;
}
export const UserEditProfileModal = ({
userProfile,
visible,
onClose,
updateUser,
updateUserProfile,
}: UserEditProfileModalProps) => {
const [displayName, setDisplayName] = useState(userProfile.displayName);
const [displayName, setDisplayName] = useState("");
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();
useEffect(() => {
setDisplayName(userProfile.displayName);
}, [userProfile.displayName]);
const handleChangeProfileAvatar = async () => {
const { filePaths } = await window.electron.showOpenDialog({
properties: ["openFile"],
@ -42,19 +45,16 @@ export const UserEditProfileModal = ({
if (filePaths && filePaths.length > 0) {
const path = filePaths[0];
window.electron.imagePathToBase64(path).then((base64) => {
setNewImageBase64(base64);
});
setNewImagePath(path);
}
};
const handleSaveProfile = async () => {
setIsSaving(true);
patchUser(displayName, newImagePath)
.then(() => {
updateUser();
.then(async () => {
await updateUserProfile();
showSuccessToast("Salvo com sucesso");
cleanFormAndClose();
})
@ -69,7 +69,6 @@ export const UserEditProfileModal = ({
const resetModal = () => {
setDisplayName(userProfile.displayName);
setNewImagePath(null);
setNewImageBase64(null);
};
const cleanFormAndClose = () => {
@ -77,6 +76,12 @@ export const UserEditProfileModal = ({
onClose();
};
const avatarUrl = useMemo(() => {
if (newImagePath) return `local:${newImagePath}`;
if (userProfile.profileImageUrl) return userProfile.profileImageUrl;
return null;
}, [newImagePath, userProfile.profileImageUrl]);
return (
<>
<Modal
@ -84,7 +89,8 @@ export const UserEditProfileModal = ({
title="Editar Perfil"
onClose={cleanFormAndClose}
>
<section
<form
onSubmit={handleSaveProfile}
style={{
display: "flex",
flexDirection: "column",
@ -95,20 +101,21 @@ export const UserEditProfileModal = ({
}}
>
<button
type="button"
className={styles.profileAvatarEditContainer}
onClick={handleChangeProfileAvatar}
>
{newImageBase64 || userProfile.profileImageUrl ? (
{avatarUrl ? (
<img
className={styles.profileAvatar}
alt={userProfile.displayName}
src={newImageBase64 ?? userProfile.profileImageUrl ?? ""}
src={avatarUrl}
/>
) : (
<PersonIcon size={96} />
)}
<div className={styles.editProfileImageBadge}>
<PencilIcon size={16} />
<DeviceCameraIcon size={16} />
</div>
</button>
@ -121,11 +128,11 @@ export const UserEditProfileModal = ({
<Button
disabled={isSaving}
style={{ alignSelf: "end" }}
onClick={handleSaveProfile}
type="submit"
>
{isSaving ? "Salvando..." : "Salvar"}
{isSaving ? "Salvando" : "Salvar"}
</Button>
</section>
</form>
</Modal>
</>
);

View file

@ -16,7 +16,7 @@ export const User = () => {
const dispatch = useAppDispatch();
const getUserProfile = useCallback(() => {
window.electron.getUser(userId!).then((userProfile) => {
return window.electron.getUser(userId!).then((userProfile) => {
if (userProfile) {
dispatch(setHeaderTitle(userProfile.displayName));
setUserProfile(userProfile);
@ -28,9 +28,7 @@ export const User = () => {
getUserProfile();
}, [getUserProfile]);
const handleUpdateProfile = () => {
getUserProfile();
};
console.log(userProfile);
return (
<SkeletonTheme baseColor={vars.color.background} highlightColor="#444">
@ -38,7 +36,7 @@ export const User = () => {
{userProfile ? (
<UserContent
userProfile={userProfile}
updateUserProfile={handleUpdateProfile}
updateUserProfile={getUserProfile}
/>
) : (
<UserSkeleton />