mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-26 12:21:03 +00:00
122 lines
3.4 KiB
TypeScript
122 lines
3.4 KiB
TypeScript
import { createSlice } from "@reduxjs/toolkit";
|
|
import type { PayloadAction } from "@reduxjs/toolkit";
|
|
import type { DownloadProgress, GameShop } from "@types";
|
|
|
|
export interface ExtractionInfo {
|
|
visibleId: string;
|
|
progress: number;
|
|
}
|
|
|
|
export interface DownloadState {
|
|
lastPacket: DownloadProgress | null;
|
|
gameId: string | null;
|
|
gamesWithDeletionInProgress: string[];
|
|
extraction: ExtractionInfo | null;
|
|
peakSpeeds: Record<string, number>;
|
|
speedHistory: Record<string, number[]>;
|
|
}
|
|
|
|
const initialState: DownloadState = {
|
|
lastPacket: null,
|
|
gameId: null,
|
|
gamesWithDeletionInProgress: [],
|
|
extraction: null,
|
|
peakSpeeds: {},
|
|
speedHistory: {},
|
|
};
|
|
|
|
export const downloadSlice = createSlice({
|
|
name: "download",
|
|
initialState,
|
|
reducers: {
|
|
setLastPacket: (state, action: PayloadAction<DownloadProgress | null>) => {
|
|
state.lastPacket = action.payload;
|
|
|
|
// Ensure payload exists and has a valid gameId before accessing
|
|
const payload = action.payload;
|
|
if (!state.gameId && payload?.gameId) {
|
|
state.gameId = payload.gameId;
|
|
}
|
|
|
|
// Track peak speed and speed history atomically when packet arrives
|
|
if (payload?.gameId && payload.downloadSpeed != null) {
|
|
const { gameId, downloadSpeed } = payload;
|
|
|
|
// Update peak speed if this is higher
|
|
const currentPeak = state.peakSpeeds[gameId] || 0;
|
|
if (downloadSpeed > currentPeak) {
|
|
state.peakSpeeds[gameId] = downloadSpeed;
|
|
}
|
|
|
|
// Update speed history for chart
|
|
if (!state.speedHistory[gameId]) {
|
|
state.speedHistory[gameId] = [];
|
|
}
|
|
state.speedHistory[gameId].push(downloadSpeed);
|
|
// Keep only last 120 entries
|
|
if (state.speedHistory[gameId].length > 120) {
|
|
state.speedHistory[gameId].shift();
|
|
}
|
|
}
|
|
},
|
|
clearDownload: (state) => {
|
|
state.lastPacket = null;
|
|
state.gameId = null;
|
|
},
|
|
setGameDeleting: (state, action: PayloadAction<string>) => {
|
|
if (
|
|
!state.gamesWithDeletionInProgress.includes(action.payload) &&
|
|
action.payload
|
|
) {
|
|
state.gamesWithDeletionInProgress.push(action.payload);
|
|
}
|
|
},
|
|
removeGameFromDeleting: (state, action: PayloadAction<string>) => {
|
|
const index = state.gamesWithDeletionInProgress.indexOf(action.payload);
|
|
if (index >= 0) state.gamesWithDeletionInProgress.splice(index, 1);
|
|
},
|
|
setExtractionProgress: (
|
|
state,
|
|
action: PayloadAction<{
|
|
shop: GameShop;
|
|
objectId: string;
|
|
progress: number;
|
|
}>
|
|
) => {
|
|
const { shop, objectId, progress } = action.payload;
|
|
state.extraction = {
|
|
visibleId: `${shop}:${objectId}`,
|
|
progress,
|
|
};
|
|
},
|
|
clearExtraction: (state) => {
|
|
state.extraction = null;
|
|
},
|
|
updatePeakSpeed: (
|
|
state,
|
|
action: PayloadAction<{ gameId: string; speed: number }>
|
|
) => {
|
|
const { gameId, speed } = action.payload;
|
|
const currentPeak = state.peakSpeeds[gameId] || 0;
|
|
if (speed > currentPeak) {
|
|
state.peakSpeeds[gameId] = speed;
|
|
}
|
|
},
|
|
clearPeakSpeed: (state, action: PayloadAction<string>) => {
|
|
state.peakSpeeds[action.payload] = 0;
|
|
state.speedHistory[action.payload] = [];
|
|
},
|
|
},
|
|
});
|
|
|
|
export const {
|
|
setLastPacket,
|
|
clearDownload,
|
|
setGameDeleting,
|
|
removeGameFromDeleting,
|
|
setExtractionProgress,
|
|
clearExtraction,
|
|
updatePeakSpeed,
|
|
clearPeakSpeed,
|
|
} = downloadSlice.actions;
|