Merge pull request #1311 from hydralauncher/feat/achievements-points

feat: achievements points
This commit is contained in:
Zamitto 2024-12-23 19:53:09 -03:00 committed by GitHub
commit dfb50e9a06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 64 additions and 138 deletions

View File

@ -1,6 +1,6 @@
{
"name": "hydralauncher",
"version": "3.0.8",
"version": "3.1.0",
"description": "Hydra",
"main": "./out/main/index.js",
"author": "Los Broxas",

View File

@ -34,7 +34,7 @@ class HttpDownloader:
download = self.aria2.get_download(self.download.gid)
response = {
'folderName': str(download.dir) + "/" + download.name,
'folderName': download.name,
'fileSize': download.total_length,
'progress': download.completed_length / download.total_length if download.total_length else 0,
'downloadSpeed': download.download_speed,

View File

@ -124,8 +124,6 @@ def action():
action = data.get('action')
game_id = data.get('game_id')
print(data)
if action == 'start':
url = data.get('url')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,6 +1,7 @@
import { HydraApi } from "@main/services";
import { registerEvent } from "../register-event";
import type { GameArtifact, GameShop } from "@types";
import { SubscriptionRequiredError } from "@shared";
const getGameArtifacts = async (
_event: Electron.IpcMainInvokeEvent,
@ -13,8 +14,16 @@ const getGameArtifacts = async (
});
return HydraApi.get<GameArtifact[]>(
`/profile/games/artifacts?${params.toString()}`
);
`/profile/games/artifacts?${params.toString()}`,
{},
{ needsSubscription: true }
).catch((err) => {
if (err instanceof SubscriptionRequiredError) {
return [];
}
throw err;
});
};
registerEvent("getGameArtifacts", getGameArtifacts);

View File

@ -9,7 +9,6 @@ import { RealDebridClient } from "./services/download/real-debrid";
import { HydraApi } from "./services/hydra-api";
import { uploadGamesBatch } from "./services/library-sync";
import { Aria2 } from "./services/aria2";
import { PythonRPC } from "./services/python-rpc";
const loadState = async (userPreferences: UserPreferences | null) => {
import("./events");
@ -43,11 +42,7 @@ const loadState = async (userPreferences: UserPreferences | null) => {
},
});
if (nextQueueItem?.game.status === "active") {
DownloadManager.startRPC(nextQueueItem.game, seedList);
} else {
PythonRPC.spawn();
}
await DownloadManager.startRPC(nextQueueItem?.game, seedList);
startMainLoop();
};

View File

@ -24,23 +24,19 @@ import { logger } from "../logger";
export class DownloadManager {
private static downloadingGameId: number | null = null;
public static startRPC(game: Game, initialSeeding?: Game[]) {
if (game && game.status === "active") {
PythonRPC.spawn(
{
game_id: game.id,
url: game.uri!,
save_path: game.downloadPath!,
},
initialSeeding?.map((game) => ({
game_id: game.id,
url: game.uri!,
save_path: game.downloadPath!,
}))
);
public static async startRPC(game?: Game, initialSeeding?: Game[]) {
PythonRPC.spawn(
game?.status === "active"
? await this.getDownloadPayload(game).catch(() => undefined)
: undefined,
initialSeeding?.map((game) => ({
game_id: game.id,
url: game.uri!,
save_path: game.downloadPath!,
}))
);
this.downloadingGameId = game.id;
}
this.downloadingGameId = game?.id ?? null;
}
private static async getDownloadStatus() {
@ -226,7 +222,9 @@ export class DownloadManager {
WindowManager.mainWindow?.setProgressBar(-1);
this.downloadingGameId = null;
if (gameId === this.downloadingGameId) {
this.downloadingGameId = null;
}
}
static async resumeSeeding(game: Game) {
@ -245,7 +243,7 @@ export class DownloadManager {
});
}
static async startDownload(game: Game) {
private static async getDownloadPayload(game: Game) {
switch (game.downloader) {
case Downloader.Gofile: {
const id = game!.uri!.split("/").pop();
@ -253,56 +251,58 @@ export class DownloadManager {
const token = await GofileApi.authorize();
const downloadLink = await GofileApi.getDownloadLink(id!);
await PythonRPC.rpc.post("/action", {
return {
action: "start",
game_id: game.id,
url: downloadLink,
save_path: game.downloadPath,
save_path: game.downloadPath!,
header: `Cookie: accountToken=${token}`,
});
break;
};
}
case Downloader.PixelDrain: {
const id = game!.uri!.split("/").pop();
await PythonRPC.rpc.post("/action", {
return {
action: "start",
game_id: game.id,
url: `https://pixeldrain.com/api/file/${id}?download`,
save_path: game.downloadPath,
});
break;
save_path: game.downloadPath!,
};
}
case Downloader.Qiwi: {
const downloadUrl = await QiwiApi.getDownloadUrl(game.uri!);
await PythonRPC.rpc.post("/action", {
return {
action: "start",
game_id: game.id,
url: downloadUrl,
save_path: game.downloadPath,
});
break;
save_path: game.downloadPath!,
};
}
case Downloader.Torrent:
await PythonRPC.rpc.post("/action", {
return {
action: "start",
game_id: game.id,
url: game.uri,
save_path: game.downloadPath,
});
break;
url: game.uri!,
save_path: game.downloadPath!,
};
case Downloader.RealDebrid: {
const downloadUrl = await RealDebridClient.getDownloadUrl(game.uri!);
await PythonRPC.rpc.post("/action", {
return {
action: "start",
game_id: game.id,
url: downloadUrl,
save_path: game.downloadPath,
});
url: downloadUrl!,
save_path: game.downloadPath!,
};
}
}
}
static async startDownload(game: Game) {
const payload = await this.getDownloadPayload(game);
await PythonRPC.rpc.post("/action", payload);
this.downloadingGameId = game.id;
}

View File

@ -18,8 +18,12 @@ export function AchievementList({ achievements }: AchievementListProps) {
return (
<ul className={styles.list}>
{achievements.map((achievement, index) => (
<li key={index} className={styles.listItem} style={{ display: "flex" }}>
{achievements.map((achievement) => (
<li
key={achievement.name}
className={styles.listItem}
style={{ display: "flex" }}
>
<img
className={styles.listItemImage({
unlocked: achievement.unlocked,
@ -72,7 +76,7 @@ export function AchievementList({ achievements }: AchievementListProps) {
<p style={{ fontSize: "1.1em" }}>???</p>
</button>
)}
{achievement.unlockTime && (
{achievement.unlockTime != null && (
<div
title={t("unlocked_at", {
date: formatDateTime(achievement.unlockTime),

View File

@ -154,7 +154,7 @@ export function Sidebar() {
<div>
<p>{achievement.displayName}</p>
<small>
{achievement.unlockTime &&
{achievement.unlockTime != null &&
formatDateTime(achievement.unlockTime)}
</small>
</div>
@ -203,7 +203,7 @@ export function Sidebar() {
<div>
<p>{achievement.displayName}</p>
<small>
{achievement.unlockTime &&
{achievement.unlockTime != null &&
formatDateTime(achievement.unlockTime)}
</small>
</div>

View File

@ -13,8 +13,7 @@ import { settingsContext } from "@renderer/context";
import { downloadSourcesTable } from "@renderer/dexie";
import { downloadSourcesWorker } from "@renderer/workers";
import { useNavigate } from "react-router-dom";
import { clearFilters } from "@renderer/features";
import { setFilters } from "@renderer/features";
import { setFilters, clearFilters } from "@renderer/features";
export function SettingsDownloadSources() {
const [showAddDownloadSourceModal, setShowAddDownloadSourceModal] =

View File

@ -1,79 +0,0 @@
import { SPACING_UNIT, vars } from "../../../theme.css";
import { style } from "@vanilla-extract/css";
export const friendListDisplayName = style({
fontWeight: "bold",
fontSize: vars.size.body,
textAlign: "left",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
});
export const friendListContainer = style({
display: "flex",
gap: `${SPACING_UNIT * 3}px`,
alignItems: "center",
borderRadius: "4px",
border: `solid 1px ${vars.color.border}`,
width: "100%",
height: "54px",
minHeight: "54px",
transition: "all ease 0.2s",
position: "relative",
":hover": {
backgroundColor: "rgba(255, 255, 255, 0.15)",
},
});
export const friendListButton = style({
display: "flex",
alignItems: "center",
position: "absolute",
cursor: "pointer",
height: "100%",
width: "100%",
flexDirection: "row",
color: vars.color.body,
gap: `${SPACING_UNIT + SPACING_UNIT / 2}px`,
padding: `0 ${SPACING_UNIT}px`,
});
export const friendRequestItem = style({
color: vars.color.body,
":hover": {
backgroundColor: "rgba(255, 255, 255, 0.15)",
},
});
export const acceptRequestButton = style({
cursor: "pointer",
color: vars.color.body,
width: "28px",
height: "28px",
":hover": {
color: vars.color.success,
},
});
export const cancelRequestButton = style({
cursor: "pointer",
color: vars.color.body,
width: "28px",
height: "28px",
":hover": {
color: vars.color.danger,
},
});
export const friendCodeButton = style({
color: vars.color.body,
cursor: "pointer",
display: "flex",
gap: `${SPACING_UNIT / 2}px`,
alignItems: "center",
transition: "all ease 0.2s",
":hover": {
color: vars.color.muted,
},
});

View File

@ -13,7 +13,7 @@ export class UserNotLoggedInError extends Error {
export class SubscriptionRequiredError extends Error {
constructor() {
super("user does not have hydra cloud subscription");
this.name = "UserWithoutCloudSubscriptionError";
this.name = "SubscriptionRequiredError";
}
}