mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-02 16:23:48 +03:00
Merge pull request #976 from hydralauncher/feat/update-typing-to-match-get-me
feat: update typing to match get me
This commit is contained in:
commit
09d0e5b4ef
@ -1,32 +1,14 @@
|
|||||||
import { registerEvent } from "../register-event";
|
import { registerEvent } from "../register-event";
|
||||||
import * as Sentry from "@sentry/electron/main";
|
import * as Sentry from "@sentry/electron/main";
|
||||||
import { HydraApi, logger } from "@main/services";
|
import { HydraApi } from "@main/services";
|
||||||
import { UserProfile } from "@types";
|
import { ProfileVisibility, UserDetails } from "@types";
|
||||||
import { userAuthRepository } from "@main/repository";
|
import { userAuthRepository } from "@main/repository";
|
||||||
import { steamUrlBuilder, UserNotLoggedInError } from "@shared";
|
import { UserNotLoggedInError } from "@shared";
|
||||||
import { steamGamesWorker } from "@main/workers";
|
|
||||||
|
|
||||||
const getSteamGame = async (objectId: string) => {
|
|
||||||
try {
|
|
||||||
const steamGame = await steamGamesWorker.run(Number(objectId), {
|
|
||||||
name: "getById",
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
title: steamGame.name,
|
|
||||||
iconUrl: steamUrlBuilder.icon(objectId, steamGame.clientIcon),
|
|
||||||
};
|
|
||||||
} catch (err) {
|
|
||||||
logger.error("Failed to get Steam game", err);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const getMe = async (
|
const getMe = async (
|
||||||
_event: Electron.IpcMainInvokeEvent
|
_event: Electron.IpcMainInvokeEvent
|
||||||
): Promise<UserProfile | null> => {
|
): Promise<UserDetails | null> => {
|
||||||
return HydraApi.get(`/profile/me`)
|
return HydraApi.get<UserDetails>(`/profile/me`)
|
||||||
.then(async (me) => {
|
.then(async (me) => {
|
||||||
userAuthRepository.upsert(
|
userAuthRepository.upsert(
|
||||||
{
|
{
|
||||||
@ -38,17 +20,6 @@ const getMe = async (
|
|||||||
["id"]
|
["id"]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (me.currentGame) {
|
|
||||||
const steamGame = await getSteamGame(me.currentGame.objectId);
|
|
||||||
|
|
||||||
if (steamGame) {
|
|
||||||
me.currentGame = {
|
|
||||||
...me.currentGame,
|
|
||||||
...steamGame,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Sentry.setUser({ id: me.id, username: me.username });
|
Sentry.setUser({ id: me.id, username: me.username });
|
||||||
|
|
||||||
return me;
|
return me;
|
||||||
@ -61,7 +32,13 @@ const getMe = async (
|
|||||||
const loggedUser = await userAuthRepository.findOne({ where: { id: 1 } });
|
const loggedUser = await userAuthRepository.findOne({ where: { id: 1 } });
|
||||||
|
|
||||||
if (loggedUser) {
|
if (loggedUser) {
|
||||||
return { ...loggedUser, id: loggedUser.userId };
|
return {
|
||||||
|
...loggedUser,
|
||||||
|
id: loggedUser.userId,
|
||||||
|
username: "",
|
||||||
|
bio: "",
|
||||||
|
profileVisibility: "PUBLIC" as ProfileVisibility,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -6,6 +6,7 @@ import { uploadGamesBatch } from "./library-sync";
|
|||||||
import { clearGamesRemoteIds } from "./library-sync/clear-games-remote-id";
|
import { clearGamesRemoteIds } from "./library-sync/clear-games-remote-id";
|
||||||
import { logger } from "./logger";
|
import { logger } from "./logger";
|
||||||
import { UserNotLoggedInError } from "@shared";
|
import { UserNotLoggedInError } from "@shared";
|
||||||
|
import { omit } from "lodash-es";
|
||||||
|
|
||||||
interface HydraApiOptions {
|
interface HydraApiOptions {
|
||||||
needsAuth: boolean;
|
needsAuth: boolean;
|
||||||
@ -96,11 +97,14 @@ export class HydraApi {
|
|||||||
this.instance.interceptors.response.use(
|
this.instance.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
logger.log(" ---- RESPONSE -----");
|
logger.log(" ---- RESPONSE -----");
|
||||||
|
const data = Array.isArray(response.data)
|
||||||
|
? response.data
|
||||||
|
: omit(response.data, ["username", "accessToken", "refreshToken"]);
|
||||||
logger.log(
|
logger.log(
|
||||||
response.status,
|
response.status,
|
||||||
response.config.method,
|
response.config.method,
|
||||||
response.config.url,
|
response.config.url,
|
||||||
response.data
|
data
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
@ -166,7 +170,10 @@ export class HydraApi {
|
|||||||
this.userAuth.authToken = accessToken;
|
this.userAuth.authToken = accessToken;
|
||||||
this.userAuth.expirationTimestamp = tokenExpirationTimestamp;
|
this.userAuth.expirationTimestamp = tokenExpirationTimestamp;
|
||||||
|
|
||||||
logger.log("Token refreshed", this.userAuth);
|
logger.log(
|
||||||
|
"Token refreshed. New expiration:",
|
||||||
|
this.userAuth.expirationTimestamp
|
||||||
|
);
|
||||||
|
|
||||||
userAuthRepository.upsert(
|
userAuthRepository.upsert(
|
||||||
{
|
{
|
||||||
|
@ -105,7 +105,7 @@ export function GameDetailsContextProvider({
|
|||||||
setShopDetails(appDetailsResult.value);
|
setShopDetails(appDetailsResult.value);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
appDetailsResult.value!.content_descriptors.ids.includes(
|
appDetailsResult.value?.content_descriptors.ids.includes(
|
||||||
SteamContentDescriptor.AdultOnlySexualContent
|
SteamContentDescriptor.AdultOnlySexualContent
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
3
src/renderer/src/declaration.d.ts
vendored
3
src/renderer/src/declaration.d.ts
vendored
@ -23,6 +23,7 @@ import type {
|
|||||||
GameStats,
|
GameStats,
|
||||||
TrendingGame,
|
TrendingGame,
|
||||||
UserStats,
|
UserStats,
|
||||||
|
UserDetails,
|
||||||
} from "@types";
|
} from "@types";
|
||||||
import type { DiskSpace } from "check-disk-space";
|
import type { DiskSpace } from "check-disk-space";
|
||||||
|
|
||||||
@ -153,7 +154,7 @@ declare global {
|
|||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
|
|
||||||
/* Profile */
|
/* Profile */
|
||||||
getMe: () => Promise<UserProfile | null>;
|
getMe: () => Promise<UserDetails | null>;
|
||||||
undoFriendship: (userId: string) => Promise<void>;
|
undoFriendship: (userId: string) => Promise<void>;
|
||||||
updateProfile: (
|
updateProfile: (
|
||||||
updateProfile: UpdateProfileRequest
|
updateProfile: UpdateProfileRequest
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
|
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
|
||||||
import { UserFriendModalTab } from "@renderer/pages/shared-modals/user-friend-modal";
|
import { UserFriendModalTab } from "@renderer/pages/shared-modals/user-friend-modal";
|
||||||
import type { FriendRequest, UserProfile } from "@types";
|
import type { FriendRequest, UserDetails } from "@types";
|
||||||
|
|
||||||
export interface UserDetailsState {
|
export interface UserDetailsState {
|
||||||
userDetails: UserProfile | null;
|
userDetails: UserDetails | null;
|
||||||
profileBackground: null | string;
|
profileBackground: null | string;
|
||||||
friendRequests: FriendRequest[];
|
friendRequests: FriendRequest[];
|
||||||
isFriendsModalVisible: boolean;
|
isFriendsModalVisible: boolean;
|
||||||
@ -24,7 +24,7 @@ export const userDetailsSlice = createSlice({
|
|||||||
name: "user-details",
|
name: "user-details",
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
setUserDetails: (state, action: PayloadAction<UserProfile | null>) => {
|
setUserDetails: (state, action: PayloadAction<UserDetails | null>) => {
|
||||||
state.userDetails = action.payload;
|
state.userDetails = action.payload;
|
||||||
},
|
},
|
||||||
setProfileBackground: (state, action: PayloadAction<string | null>) => {
|
setProfileBackground: (state, action: PayloadAction<string | null>) => {
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
import type {
|
import type {
|
||||||
FriendRequestAction,
|
FriendRequestAction,
|
||||||
UpdateProfileRequest,
|
UpdateProfileRequest,
|
||||||
UserProfile,
|
UserDetails,
|
||||||
} from "@types";
|
} from "@types";
|
||||||
import { UserFriendModalTab } from "@renderer/pages/shared-modals/user-friend-modal";
|
import { UserFriendModalTab } from "@renderer/pages/shared-modals/user-friend-modal";
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ export function useUserDetails() {
|
|||||||
}, [clearUserDetails]);
|
}, [clearUserDetails]);
|
||||||
|
|
||||||
const updateUserDetails = useCallback(
|
const updateUserDetails = useCallback(
|
||||||
async (userDetails: UserProfile) => {
|
async (userDetails: UserDetails) => {
|
||||||
dispatch(setUserDetails(userDetails));
|
dispatch(setUserDetails(userDetails));
|
||||||
|
|
||||||
if (userDetails.profileImageUrl) {
|
if (userDetails.profileImageUrl) {
|
||||||
@ -83,7 +83,10 @@ export function useUserDetails() {
|
|||||||
const patchUser = useCallback(
|
const patchUser = useCallback(
|
||||||
async (values: UpdateProfileRequest) => {
|
async (values: UpdateProfileRequest) => {
|
||||||
const response = await window.electron.updateProfile(values);
|
const response = await window.electron.updateProfile(values);
|
||||||
return updateUserDetails(response);
|
return updateUserDetails({
|
||||||
|
...response,
|
||||||
|
username: userDetails?.username || "",
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[updateUserDetails]
|
[updateUserDetails]
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useState } from "react";
|
||||||
import type { HowLongToBeatCategory, SteamAppDetails } from "@types";
|
import type { HowLongToBeatCategory, SteamAppDetails } from "@types";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Button } from "@renderer/components";
|
import { Button } from "@renderer/components";
|
||||||
@ -9,7 +9,7 @@ import { useFormat } from "@renderer/hooks";
|
|||||||
import { DownloadIcon, PeopleIcon } from "@primer/octicons-react";
|
import { DownloadIcon, PeopleIcon } from "@primer/octicons-react";
|
||||||
|
|
||||||
export function Sidebar() {
|
export function Sidebar() {
|
||||||
const [_howLongToBeat, setHowLongToBeat] = useState<{
|
const [_howLongToBeat, _setHowLongToBeat] = useState<{
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
data: HowLongToBeatCategory[] | null;
|
data: HowLongToBeatCategory[] | null;
|
||||||
}>({ isLoading: true, data: null });
|
}>({ isLoading: true, data: null });
|
||||||
@ -17,27 +17,26 @@ export function Sidebar() {
|
|||||||
const [activeRequirement, setActiveRequirement] =
|
const [activeRequirement, setActiveRequirement] =
|
||||||
useState<keyof SteamAppDetails["pc_requirements"]>("minimum");
|
useState<keyof SteamAppDetails["pc_requirements"]>("minimum");
|
||||||
|
|
||||||
const { gameTitle, shopDetails, objectID, stats } =
|
const { gameTitle, shopDetails, stats } = useContext(gameDetailsContext);
|
||||||
useContext(gameDetailsContext);
|
|
||||||
|
|
||||||
const { t } = useTranslation("game_details");
|
const { t } = useTranslation("game_details");
|
||||||
|
|
||||||
const { numberFormatter } = useFormat();
|
const { numberFormatter } = useFormat();
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
if (objectID) {
|
// if (objectID) {
|
||||||
setHowLongToBeat({ isLoading: true, data: null });
|
// setHowLongToBeat({ isLoading: true, data: null });
|
||||||
|
|
||||||
window.electron
|
// window.electron
|
||||||
.getHowLongToBeat(objectID, "steam", gameTitle)
|
// .getHowLongToBeat(objectID, "steam", gameTitle)
|
||||||
.then((howLongToBeat) => {
|
// .then((howLongToBeat) => {
|
||||||
setHowLongToBeat({ isLoading: false, data: howLongToBeat });
|
// setHowLongToBeat({ isLoading: false, data: howLongToBeat });
|
||||||
})
|
// })
|
||||||
.catch(() => {
|
// .catch(() => {
|
||||||
setHowLongToBeat({ isLoading: false, data: null });
|
// setHowLongToBeat({ isLoading: false, data: null });
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}, [objectID, gameTitle]);
|
// }, [objectID, gameTitle]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className={styles.contentSidebar}>
|
<aside className={styles.contentSidebar}>
|
||||||
|
@ -190,23 +190,34 @@ export interface UserProfileCurrentGame extends Omit<GameRunning, "objectID"> {
|
|||||||
sessionDurationInSeconds: number;
|
sessionDurationInSeconds: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ProfileVisibility = "PUBLIC" | "PRIVATE" | "FRIENDS";
|
||||||
|
|
||||||
|
export interface UserDetails {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
displayName: string;
|
||||||
|
profileImageUrl: string | null;
|
||||||
|
profileVisibility: ProfileVisibility;
|
||||||
|
bio: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface UserProfile {
|
export interface UserProfile {
|
||||||
id: string;
|
id: string;
|
||||||
displayName: string;
|
displayName: string;
|
||||||
profileImageUrl: string | null;
|
profileImageUrl: string | null;
|
||||||
profileVisibility: "PUBLIC" | "PRIVATE" | "FRIENDS";
|
profileVisibility: ProfileVisibility;
|
||||||
totalPlayTimeInSeconds: number;
|
|
||||||
libraryGames: UserGame[];
|
libraryGames: UserGame[];
|
||||||
recentGames: UserGame[];
|
recentGames: UserGame[];
|
||||||
friends: UserFriend[];
|
friends: UserFriend[];
|
||||||
totalFriends: number;
|
totalFriends: number;
|
||||||
relation: UserRelation | null;
|
relation: UserRelation | null;
|
||||||
currentGame: UserProfileCurrentGame | null;
|
currentGame: UserProfileCurrentGame | null;
|
||||||
|
bio: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateProfileRequest {
|
export interface UpdateProfileRequest {
|
||||||
displayName?: string;
|
displayName?: string;
|
||||||
profileVisibility?: "PUBLIC" | "PRIVATE" | "FRIENDS";
|
profileVisibility?: ProfileVisibility;
|
||||||
profileImageUrl?: string | null;
|
profileImageUrl?: string | null;
|
||||||
bio?: string;
|
bio?: string;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user