wip
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { invoke } from '@tauri-apps/api/core';
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
import { listen } from '@tauri-apps/api/event';
|
import { listen } from '@tauri-apps/api/event';
|
||||||
import { open } from '@tauri-apps/plugin-dialog';
|
import { open } from '@tauri-apps/plugin-dialog';
|
||||||
@@ -8,6 +8,7 @@ import "./App.css";
|
|||||||
|
|
||||||
const FILE_STORAGE = 'launcher-settings.json';
|
const FILE_STORAGE = 'launcher-settings.json';
|
||||||
const GAME_DIR_KEY = 'game-directory';
|
const GAME_DIR_KEY = 'game-directory';
|
||||||
|
const CHECKING_PEERS_TIMEOUT_MS = 5000;
|
||||||
|
|
||||||
// enum with install status
|
// enum with install status
|
||||||
enum InstallStatus {
|
enum InstallStatus {
|
||||||
@@ -38,11 +39,45 @@ const App = () => {
|
|||||||
const [gameItems, setGameItems] = useState<Game[]>([]);
|
const [gameItems, setGameItems] = useState<Game[]>([]);
|
||||||
const [searchTerm, setSearchTerm] = useState('');
|
const [searchTerm, setSearchTerm] = useState('');
|
||||||
const [gameDir, setGameDir] = useState('');
|
const [gameDir, setGameDir] = useState('');
|
||||||
|
const checkingPeersTimeouts = useRef<Record<string, ReturnType<typeof setTimeout>>>({});
|
||||||
|
|
||||||
const filteredGames = gameItems.filter(item =>
|
const filteredGames = gameItems.filter(item =>
|
||||||
item.name.toLowerCase().includes(searchTerm.toLowerCase())
|
item.name.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const clearCheckingPeersTimeout = (gameId: string) => {
|
||||||
|
const timeoutId = checkingPeersTimeouts.current[gameId];
|
||||||
|
if (timeoutId !== undefined) {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
delete checkingPeersTimeouts.current[gameId];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const scheduleCheckingPeersFallback = (gameId: string, fallbackMessage?: string, fallbackLevel?: StatusLevel) => {
|
||||||
|
clearCheckingPeersTimeout(gameId);
|
||||||
|
checkingPeersTimeouts.current[gameId] = setTimeout(() => {
|
||||||
|
setGameItems(prev => prev.map(item => {
|
||||||
|
if (item.id !== gameId || item.install_status !== InstallStatus.CheckingPeers) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
install_status: item.installed ? InstallStatus.Installed : InstallStatus.NotInstalled,
|
||||||
|
status_message: fallbackMessage ?? 'No peers currently have this game.',
|
||||||
|
status_level: fallbackLevel ?? 'error',
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
delete checkingPeersTimeouts.current[gameId];
|
||||||
|
}, CHECKING_PEERS_TIMEOUT_MS);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
Object.values(checkingPeersTimeouts.current).forEach(clearTimeout);
|
||||||
|
checkingPeersTimeouts.current = {};
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
const getInitialGameDir = async () => {
|
const getInitialGameDir = async () => {
|
||||||
// update game directory from storage (if exists)
|
// update game directory from storage (if exists)
|
||||||
// only if it's not already set
|
// only if it's not already set
|
||||||
@@ -60,6 +95,7 @@ const App = () => {
|
|||||||
const unlisten = await listen('game-download-failed', (event) => {
|
const unlisten = await listen('game-download-failed', (event) => {
|
||||||
const game_id = event.payload as string;
|
const game_id = event.payload as string;
|
||||||
console.log(`❌ game-download-failed ${game_id} event received`);
|
console.log(`❌ game-download-failed ${game_id} event received`);
|
||||||
|
clearCheckingPeersTimeout(game_id);
|
||||||
setGameItems(prev => prev.map(item => item.id === game_id
|
setGameItems(prev => prev.map(item => item.id === game_id
|
||||||
? {
|
? {
|
||||||
...item,
|
...item,
|
||||||
@@ -85,6 +121,7 @@ const App = () => {
|
|||||||
const unlisten = await listen('game-no-peers', (event) => {
|
const unlisten = await listen('game-no-peers', (event) => {
|
||||||
const game_id = event.payload as string;
|
const game_id = event.payload as string;
|
||||||
console.log(`⚠️ game-no-peers ${game_id} event received`);
|
console.log(`⚠️ game-no-peers ${game_id} event received`);
|
||||||
|
clearCheckingPeersTimeout(game_id);
|
||||||
setGameItems(prev => prev.map(item => item.id === game_id
|
setGameItems(prev => prev.map(item => item.id === game_id
|
||||||
? {
|
? {
|
||||||
...item,
|
...item,
|
||||||
@@ -107,6 +144,7 @@ const App = () => {
|
|||||||
const unlisten = await listen('game-unpack-finished', (event) => {
|
const unlisten = await listen('game-unpack-finished', (event) => {
|
||||||
const game_id = event.payload as string;
|
const game_id = event.payload as string;
|
||||||
console.log(`🗲 game-unpack-finished ${game_id} event received`);
|
console.log(`🗲 game-unpack-finished ${game_id} event received`);
|
||||||
|
clearCheckingPeersTimeout(game_id);
|
||||||
setGameItems(prev => prev.map(item => item.id === game_id
|
setGameItems(prev => prev.map(item => item.id === game_id
|
||||||
? {
|
? {
|
||||||
...item,
|
...item,
|
||||||
@@ -183,6 +221,7 @@ const App = () => {
|
|||||||
const unlisten_game_download_begin = await listen('game-download-begin', (event) => {
|
const unlisten_game_download_begin = await listen('game-download-begin', (event) => {
|
||||||
const game_id = event.payload as string;
|
const game_id = event.payload as string;
|
||||||
console.log(`🗲 game-download-begin ${game_id} event received`);
|
console.log(`🗲 game-download-begin ${game_id} event received`);
|
||||||
|
clearCheckingPeersTimeout(game_id);
|
||||||
setGameItems(prev => prev.map(item => item.id === game_id
|
setGameItems(prev => prev.map(item => item.id === game_id
|
||||||
? {
|
? {
|
||||||
...item,
|
...item,
|
||||||
@@ -197,6 +236,7 @@ const App = () => {
|
|||||||
const unlisten_game_download_finished = await listen('game-download-finished', (event) => {
|
const unlisten_game_download_finished = await listen('game-download-finished', (event) => {
|
||||||
const game_id = event.payload as string;
|
const game_id = event.payload as string;
|
||||||
console.log(`🗲 game-download-finished ${game_id} event received`);
|
console.log(`🗲 game-download-finished ${game_id} event received`);
|
||||||
|
clearCheckingPeersTimeout(game_id);
|
||||||
setGameItems(prev => prev.map(item => item.id === game_id
|
setGameItems(prev => prev.map(item => item.id === game_id
|
||||||
? {
|
? {
|
||||||
...item,
|
...item,
|
||||||
@@ -247,15 +287,21 @@ const App = () => {
|
|||||||
const success = await invoke('install_game', { id });
|
const success = await invoke('install_game', { id });
|
||||||
if (success) {
|
if (success) {
|
||||||
console.log(`✅ Game install for id=${id} started...`);
|
console.log(`✅ Game install for id=${id} started...`);
|
||||||
|
let fallbackMessage: string | undefined;
|
||||||
|
let fallbackLevel: StatusLevel | undefined;
|
||||||
// update install status in gameItems for this game
|
// update install status in gameItems for this game
|
||||||
setGameItems(prev => prev.map(item => item.id === id
|
setGameItems(prev => prev.map(item => {
|
||||||
? {
|
if (item.id === id) {
|
||||||
|
fallbackMessage = item.status_message;
|
||||||
|
fallbackLevel = item.status_level;
|
||||||
|
return {
|
||||||
...item,
|
...item,
|
||||||
install_status: InstallStatus.CheckingPeers,
|
install_status: InstallStatus.CheckingPeers,
|
||||||
status_message: undefined,
|
};
|
||||||
status_level: undefined,
|
|
||||||
}
|
}
|
||||||
: item));
|
return item;
|
||||||
|
}));
|
||||||
|
scheduleCheckingPeersFallback(id, fallbackMessage, fallbackLevel);
|
||||||
} else {
|
} else {
|
||||||
// game is already being installed
|
// game is already being installed
|
||||||
console.warn(`🚧 Game with id=${id} is already being installed`);
|
console.warn(`🚧 Game with id=${id} is already being installed`);
|
||||||
@@ -271,15 +317,21 @@ const App = () => {
|
|||||||
const success = await invoke('update_game', { id });
|
const success = await invoke('update_game', { id });
|
||||||
if (success) {
|
if (success) {
|
||||||
console.log(`✅ Game update for id=${id} started...`);
|
console.log(`✅ Game update for id=${id} started...`);
|
||||||
|
let fallbackMessage: string | undefined;
|
||||||
|
let fallbackLevel: StatusLevel | undefined;
|
||||||
// update install status in gameItems for this game
|
// update install status in gameItems for this game
|
||||||
setGameItems(prev => prev.map(item => item.id === id
|
setGameItems(prev => prev.map(item => {
|
||||||
? {
|
if (item.id === id) {
|
||||||
|
fallbackMessage = item.status_message;
|
||||||
|
fallbackLevel = item.status_level;
|
||||||
|
return {
|
||||||
...item,
|
...item,
|
||||||
install_status: InstallStatus.CheckingPeers,
|
install_status: InstallStatus.CheckingPeers,
|
||||||
status_message: undefined,
|
};
|
||||||
status_level: undefined,
|
|
||||||
}
|
}
|
||||||
: item));
|
return item;
|
||||||
|
}));
|
||||||
|
scheduleCheckingPeersFallback(id, fallbackMessage, fallbackLevel);
|
||||||
} else {
|
} else {
|
||||||
// game is already being installed/updated
|
// game is already being installed/updated
|
||||||
console.warn(`🚧 Game with id=${id} is already being updated`);
|
console.warn(`🚧 Game with id=${id} is already being updated`);
|
||||||
|
|||||||
Reference in New Issue
Block a user