mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
feat: adding local file protocol
This commit is contained in:
parent
1ef8e3fce3
commit
1fb1c9e81a
10 changed files with 42 additions and 54 deletions
|
@ -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">
|
||||
|
|
1
src/renderer/src/declaration.d.ts
vendored
1
src/renderer/src/declaration.d.ts
vendored
|
@ -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>;
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
|
||||
|
|
|
@ -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>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -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 />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue