mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-02 16:23:48 +03:00
Merge pull request #977 from hydralauncher/feat/polling-from-sync
feat: polling from sync
This commit is contained in:
commit
43bc0cb08f
@ -59,6 +59,7 @@ import "./profile/update-friend-request";
|
|||||||
import "./profile/update-profile";
|
import "./profile/update-profile";
|
||||||
import "./profile/process-profile-image";
|
import "./profile/process-profile-image";
|
||||||
import "./profile/send-friend-request";
|
import "./profile/send-friend-request";
|
||||||
|
import "./profile/sync-friend-requests";
|
||||||
import { isPortableVersion } from "@main/helpers";
|
import { isPortableVersion } from "@main/helpers";
|
||||||
|
|
||||||
ipcMain.handle("ping", () => "pong");
|
ipcMain.handle("ping", () => "pong");
|
||||||
|
9
src/main/events/profile/sync-friend-requests.ts
Normal file
9
src/main/events/profile/sync-friend-requests.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { registerEvent } from "../register-event";
|
||||||
|
import { HydraApi } from "@main/services";
|
||||||
|
import { FriendRequestSync } from "@types";
|
||||||
|
|
||||||
|
const syncFriendRequests = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||||
|
return HydraApi.get<FriendRequestSync>(`/profile/friend-requests/sync`);
|
||||||
|
};
|
||||||
|
|
||||||
|
registerEvent("syncFriendRequests", syncFriendRequests);
|
@ -2,7 +2,7 @@ import { registerEvent } from "../register-event";
|
|||||||
|
|
||||||
import type { StartGameDownloadPayload } from "@types";
|
import type { StartGameDownloadPayload } from "@types";
|
||||||
import { getFileBase64 } from "@main/helpers";
|
import { getFileBase64 } from "@main/helpers";
|
||||||
import { DownloadManager } from "@main/services";
|
import { DownloadManager, HydraApi, logger } from "@main/services";
|
||||||
|
|
||||||
import { Not } from "typeorm";
|
import { Not } from "typeorm";
|
||||||
import { steamGamesWorker } from "@main/workers";
|
import { steamGamesWorker } from "@main/workers";
|
||||||
@ -101,6 +101,17 @@ const startGameDownload = async (
|
|||||||
|
|
||||||
createGame(updatedGame!).catch(() => {});
|
createGame(updatedGame!).catch(() => {});
|
||||||
|
|
||||||
|
HydraApi.post(
|
||||||
|
"/games/download",
|
||||||
|
{
|
||||||
|
objectId: updatedGame!.objectID,
|
||||||
|
shop: updatedGame!.shop,
|
||||||
|
},
|
||||||
|
{ needsAuth: false }
|
||||||
|
).catch((err) => {
|
||||||
|
logger.error("Failed to create game download", err);
|
||||||
|
});
|
||||||
|
|
||||||
await DownloadManager.cancelDownload(updatedGame!.id);
|
await DownloadManager.cancelDownload(updatedGame!.id);
|
||||||
await DownloadManager.startDownload(updatedGame!);
|
await DownloadManager.startDownload(updatedGame!);
|
||||||
|
|
||||||
|
@ -1,20 +1,8 @@
|
|||||||
import { Game } from "@main/entity";
|
import { Game } from "@main/entity";
|
||||||
import { HydraApi } from "../hydra-api";
|
import { HydraApi } from "../hydra-api";
|
||||||
import { gameRepository } from "@main/repository";
|
import { gameRepository } from "@main/repository";
|
||||||
import { logger } from "../logger";
|
|
||||||
|
|
||||||
export const createGame = async (game: Game) => {
|
export const createGame = async (game: Game) => {
|
||||||
HydraApi.post(
|
|
||||||
"/games/download",
|
|
||||||
{
|
|
||||||
objectId: game.objectID,
|
|
||||||
shop: game.shop,
|
|
||||||
},
|
|
||||||
{ needsAuth: false }
|
|
||||||
).catch((err) => {
|
|
||||||
logger.error("Failed to create game download", err);
|
|
||||||
});
|
|
||||||
|
|
||||||
return HydraApi.post(`/profile/games`, {
|
return HydraApi.post(`/profile/games`, {
|
||||||
objectId: game.objectID,
|
objectId: game.objectID,
|
||||||
playTimeInMilliseconds: Math.trunc(game.playTimeInMilliseconds),
|
playTimeInMilliseconds: Math.trunc(game.playTimeInMilliseconds),
|
||||||
|
@ -150,6 +150,7 @@ contextBridge.exposeInMainWorld("electron", {
|
|||||||
processProfileImage: (imagePath: string) =>
|
processProfileImage: (imagePath: string) =>
|
||||||
ipcRenderer.invoke("processProfileImage", imagePath),
|
ipcRenderer.invoke("processProfileImage", imagePath),
|
||||||
getFriendRequests: () => ipcRenderer.invoke("getFriendRequests"),
|
getFriendRequests: () => ipcRenderer.invoke("getFriendRequests"),
|
||||||
|
syncFriendRequests: () => ipcRenderer.invoke("syncFriendRequests"),
|
||||||
updateFriendRequest: (userId: string, action: FriendRequestAction) =>
|
updateFriendRequest: (userId: string, action: FriendRequestAction) =>
|
||||||
ipcRenderer.invoke("updateFriendRequest", userId, action),
|
ipcRenderer.invoke("updateFriendRequest", userId, action),
|
||||||
sendFriendRequest: (userId: string) =>
|
sendFriendRequest: (userId: string) =>
|
||||||
|
@ -43,7 +43,7 @@ export function App() {
|
|||||||
isFriendsModalVisible,
|
isFriendsModalVisible,
|
||||||
friendRequetsModalTab,
|
friendRequetsModalTab,
|
||||||
friendModalUserId,
|
friendModalUserId,
|
||||||
fetchFriendRequests,
|
syncFriendRequests,
|
||||||
hideFriendsModal,
|
hideFriendsModal,
|
||||||
} = useUserDetails();
|
} = useUserDetails();
|
||||||
|
|
||||||
@ -105,22 +105,22 @@ export function App() {
|
|||||||
fetchUserDetails().then((response) => {
|
fetchUserDetails().then((response) => {
|
||||||
if (response) {
|
if (response) {
|
||||||
updateUserDetails(response);
|
updateUserDetails(response);
|
||||||
fetchFriendRequests();
|
syncFriendRequests();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [fetchUserDetails, fetchFriendRequests, updateUserDetails, dispatch]);
|
}, [fetchUserDetails, syncFriendRequests, updateUserDetails, dispatch]);
|
||||||
|
|
||||||
const onSignIn = useCallback(() => {
|
const onSignIn = useCallback(() => {
|
||||||
fetchUserDetails().then((response) => {
|
fetchUserDetails().then((response) => {
|
||||||
if (response) {
|
if (response) {
|
||||||
updateUserDetails(response);
|
updateUserDetails(response);
|
||||||
fetchFriendRequests();
|
syncFriendRequests();
|
||||||
showSuccessToast(t("successfully_signed_in"));
|
showSuccessToast(t("successfully_signed_in"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [
|
}, [
|
||||||
fetchUserDetails,
|
fetchUserDetails,
|
||||||
fetchFriendRequests,
|
syncFriendRequests,
|
||||||
t,
|
t,
|
||||||
showSuccessToast,
|
showSuccessToast,
|
||||||
updateUserDetails,
|
updateUserDetails,
|
||||||
|
@ -15,15 +15,15 @@ export function SidebarProfile() {
|
|||||||
|
|
||||||
const { t } = useTranslation("sidebar");
|
const { t } = useTranslation("sidebar");
|
||||||
|
|
||||||
const { userDetails, friendRequests, showFriendsModal, fetchFriendRequests } =
|
const {
|
||||||
useUserDetails();
|
userDetails,
|
||||||
|
friendRequestCount,
|
||||||
|
showFriendsModal,
|
||||||
|
syncFriendRequests,
|
||||||
|
} = useUserDetails();
|
||||||
|
|
||||||
const { gameRunning } = useAppSelector((state) => state.gameRunning);
|
const { gameRunning } = useAppSelector((state) => state.gameRunning);
|
||||||
|
|
||||||
const receivedRequests = useMemo(() => {
|
|
||||||
return friendRequests.filter((request) => request.type === "RECEIVED");
|
|
||||||
}, [friendRequests]);
|
|
||||||
|
|
||||||
const handleProfileClick = () => {
|
const handleProfileClick = () => {
|
||||||
if (userDetails === null) {
|
if (userDetails === null) {
|
||||||
window.electron.openAuthWindow();
|
window.electron.openAuthWindow();
|
||||||
@ -35,7 +35,7 @@ export function SidebarProfile() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
pollingInterval.current = setInterval(() => {
|
pollingInterval.current = setInterval(() => {
|
||||||
fetchFriendRequests();
|
syncFriendRequests();
|
||||||
}, LONG_POLLING_INTERVAL);
|
}, LONG_POLLING_INTERVAL);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
@ -43,7 +43,7 @@ export function SidebarProfile() {
|
|||||||
clearInterval(pollingInterval.current);
|
clearInterval(pollingInterval.current);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [fetchFriendRequests]);
|
}, [syncFriendRequests]);
|
||||||
|
|
||||||
const friendsButton = useMemo(() => {
|
const friendsButton = useMemo(() => {
|
||||||
if (!userDetails) return null;
|
if (!userDetails) return null;
|
||||||
@ -57,16 +57,16 @@ export function SidebarProfile() {
|
|||||||
}
|
}
|
||||||
title={t("friends")}
|
title={t("friends")}
|
||||||
>
|
>
|
||||||
{receivedRequests.length > 0 && (
|
{friendRequestCount > 0 && (
|
||||||
<small className={styles.friendsButtonBadge}>
|
<small className={styles.friendsButtonBadge}>
|
||||||
{receivedRequests.length > 99 ? "99+" : receivedRequests.length}
|
{friendRequestCount > 99 ? "99+" : friendRequestCount}
|
||||||
</small>
|
</small>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<PeopleIcon size={16} />
|
<PeopleIcon size={16} />
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}, [userDetails, t, receivedRequests, showFriendsModal]);
|
}, [userDetails, t, friendRequestCount, showFriendsModal]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.profileContainer}>
|
<div className={styles.profileContainer}>
|
||||||
|
2
src/renderer/src/declaration.d.ts
vendored
2
src/renderer/src/declaration.d.ts
vendored
@ -24,6 +24,7 @@ import type {
|
|||||||
TrendingGame,
|
TrendingGame,
|
||||||
UserStats,
|
UserStats,
|
||||||
UserDetails,
|
UserDetails,
|
||||||
|
FriendRequestSync,
|
||||||
} from "@types";
|
} from "@types";
|
||||||
import type { DiskSpace } from "check-disk-space";
|
import type { DiskSpace } from "check-disk-space";
|
||||||
|
|
||||||
@ -164,6 +165,7 @@ declare global {
|
|||||||
path: string
|
path: string
|
||||||
) => Promise<{ imagePath: string; mimeType: string }>;
|
) => Promise<{ imagePath: string; mimeType: string }>;
|
||||||
getFriendRequests: () => Promise<FriendRequest[]>;
|
getFriendRequests: () => Promise<FriendRequest[]>;
|
||||||
|
syncFriendRequests: () => Promise<FriendRequestSync>;
|
||||||
updateFriendRequest: (
|
updateFriendRequest: (
|
||||||
userId: string,
|
userId: string,
|
||||||
action: FriendRequestAction
|
action: FriendRequestAction
|
||||||
|
@ -6,6 +6,7 @@ export interface UserDetailsState {
|
|||||||
userDetails: UserDetails | null;
|
userDetails: UserDetails | null;
|
||||||
profileBackground: null | string;
|
profileBackground: null | string;
|
||||||
friendRequests: FriendRequest[];
|
friendRequests: FriendRequest[];
|
||||||
|
friendRequestCount: number;
|
||||||
isFriendsModalVisible: boolean;
|
isFriendsModalVisible: boolean;
|
||||||
friendRequetsModalTab: UserFriendModalTab | null;
|
friendRequetsModalTab: UserFriendModalTab | null;
|
||||||
friendModalUserId: string;
|
friendModalUserId: string;
|
||||||
@ -15,6 +16,7 @@ const initialState: UserDetailsState = {
|
|||||||
userDetails: null,
|
userDetails: null,
|
||||||
profileBackground: null,
|
profileBackground: null,
|
||||||
friendRequests: [],
|
friendRequests: [],
|
||||||
|
friendRequestCount: 0,
|
||||||
isFriendsModalVisible: false,
|
isFriendsModalVisible: false,
|
||||||
friendRequetsModalTab: null,
|
friendRequetsModalTab: null,
|
||||||
friendModalUserId: "",
|
friendModalUserId: "",
|
||||||
@ -33,6 +35,9 @@ export const userDetailsSlice = createSlice({
|
|||||||
setFriendRequests: (state, action: PayloadAction<FriendRequest[]>) => {
|
setFriendRequests: (state, action: PayloadAction<FriendRequest[]>) => {
|
||||||
state.friendRequests = action.payload;
|
state.friendRequests = action.payload;
|
||||||
},
|
},
|
||||||
|
setFriendRequestCount: (state, action: PayloadAction<number>) => {
|
||||||
|
state.friendRequestCount = action.payload;
|
||||||
|
},
|
||||||
setFriendsModalVisible: (
|
setFriendsModalVisible: (
|
||||||
state,
|
state,
|
||||||
action: PayloadAction<{ initialTab: UserFriendModalTab; userId: string }>
|
action: PayloadAction<{ initialTab: UserFriendModalTab; userId: string }>
|
||||||
@ -52,6 +57,7 @@ export const {
|
|||||||
setUserDetails,
|
setUserDetails,
|
||||||
setProfileBackground,
|
setProfileBackground,
|
||||||
setFriendRequests,
|
setFriendRequests,
|
||||||
|
setFriendRequestCount,
|
||||||
setFriendsModalVisible,
|
setFriendsModalVisible,
|
||||||
setFriendsModalHidden,
|
setFriendsModalHidden,
|
||||||
} = userDetailsSlice.actions;
|
} = userDetailsSlice.actions;
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
setFriendRequests,
|
setFriendRequests,
|
||||||
setFriendsModalVisible,
|
setFriendsModalVisible,
|
||||||
setFriendsModalHidden,
|
setFriendsModalHidden,
|
||||||
|
setFriendRequestCount,
|
||||||
} from "@renderer/features";
|
} from "@renderer/features";
|
||||||
import type {
|
import type {
|
||||||
FriendRequestAction,
|
FriendRequestAction,
|
||||||
@ -21,6 +22,7 @@ export function useUserDetails() {
|
|||||||
userDetails,
|
userDetails,
|
||||||
profileBackground,
|
profileBackground,
|
||||||
friendRequests,
|
friendRequests,
|
||||||
|
friendRequestCount,
|
||||||
isFriendsModalVisible,
|
isFriendsModalVisible,
|
||||||
friendModalUserId,
|
friendModalUserId,
|
||||||
friendRequetsModalTab,
|
friendRequetsModalTab,
|
||||||
@ -95,11 +97,21 @@ export function useUserDetails() {
|
|||||||
return window.electron
|
return window.electron
|
||||||
.getFriendRequests()
|
.getFriendRequests()
|
||||||
.then((friendRequests) => {
|
.then((friendRequests) => {
|
||||||
|
syncFriendRequests();
|
||||||
dispatch(setFriendRequests(friendRequests));
|
dispatch(setFriendRequests(friendRequests));
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const syncFriendRequests = useCallback(async () => {
|
||||||
|
return window.electron
|
||||||
|
.syncFriendRequests()
|
||||||
|
.then((sync) => {
|
||||||
|
dispatch(setFriendRequestCount(sync.friendRequestCount));
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
const showFriendsModal = useCallback(
|
const showFriendsModal = useCallback(
|
||||||
(initialTab: UserFriendModalTab, userId: string) => {
|
(initialTab: UserFriendModalTab, userId: string) => {
|
||||||
dispatch(setFriendsModalVisible({ initialTab, userId }));
|
dispatch(setFriendsModalVisible({ initialTab, userId }));
|
||||||
@ -143,6 +155,7 @@ export function useUserDetails() {
|
|||||||
userDetails,
|
userDetails,
|
||||||
profileBackground,
|
profileBackground,
|
||||||
friendRequests,
|
friendRequests,
|
||||||
|
friendRequestCount,
|
||||||
friendRequetsModalTab,
|
friendRequetsModalTab,
|
||||||
isFriendsModalVisible,
|
isFriendsModalVisible,
|
||||||
friendModalUserId,
|
friendModalUserId,
|
||||||
@ -155,6 +168,7 @@ export function useUserDetails() {
|
|||||||
patchUser,
|
patchUser,
|
||||||
sendFriendRequest,
|
sendFriendRequest,
|
||||||
fetchFriendRequests,
|
fetchFriendRequests,
|
||||||
|
syncFriendRequests,
|
||||||
updateFriendRequestState,
|
updateFriendRequestState,
|
||||||
blockUser,
|
blockUser,
|
||||||
unblockUser,
|
unblockUser,
|
||||||
|
@ -170,6 +170,10 @@ export interface UserBlocks {
|
|||||||
blocks: UserFriend[];
|
blocks: UserFriend[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface FriendRequestSync {
|
||||||
|
friendRequestCount: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface FriendRequest {
|
export interface FriendRequest {
|
||||||
id: string;
|
id: string;
|
||||||
displayName: string;
|
displayName: string;
|
||||||
|
Loading…
Reference in New Issue
Block a user