diff --git a/public/locales/az/gamepage.json b/public/locales/az/gamepage.json index c9193db0e2..c5d6bdfab3 100644 --- a/public/locales/az/gamepage.json +++ b/public/locales/az/gamepage.json @@ -59,6 +59,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Sevimlilərdən Sil", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/be/gamepage.json b/public/locales/be/gamepage.json index 3c4b74a5ae..4e4885511f 100644 --- a/public/locales/be/gamepage.json +++ b/public/locales/be/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Выдаліць з абранага", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/bg/gamepage.json b/public/locales/bg/gamepage.json index aebaadb060..d70b52c4e0 100644 --- a/public/locales/bg/gamepage.json +++ b/public/locales/bg/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Премахване от любимите", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/bs/gamepage.json b/public/locales/bs/gamepage.json index e0050aa966..0943b10b98 100644 --- a/public/locales/bs/gamepage.json +++ b/public/locales/bs/gamepage.json @@ -59,6 +59,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Otkloni iz favorita", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/ca/gamepage.json b/public/locales/ca/gamepage.json index 2a61fc3d55..1e7441d8fa 100644 --- a/public/locales/ca/gamepage.json +++ b/public/locales/ca/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Treu dels preferits", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/cs/gamepage.json b/public/locales/cs/gamepage.json index a2abeb2969..276c7e701c 100644 --- a/public/locales/cs/gamepage.json +++ b/public/locales/cs/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Odebrat z oblíbených", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/de/gamepage.json b/public/locales/de/gamepage.json index df6a30b395..956bbd668e 100644 --- a/public/locales/de/gamepage.json +++ b/public/locales/de/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Aus Favoriten entfernen", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/el/gamepage.json b/public/locales/el/gamepage.json index ac0fb49539..d2076e3361 100644 --- a/public/locales/el/gamepage.json +++ b/public/locales/el/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Κατάργηση από τα Αγαπημένα", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/en/gamepage.json b/public/locales/en/gamepage.json index 3d0d8149c8..73a584e37e 100644 --- a/public/locales/en/gamepage.json +++ b/public/locales/en/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Remove From Favourites", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/es/gamepage.json b/public/locales/es/gamepage.json index 24022efc3f..e24810320d 100644 --- a/public/locales/es/gamepage.json +++ b/public/locales/es/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Remover de Favoritos", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/et/gamepage.json b/public/locales/et/gamepage.json index 875bcf12ad..9f8f5c6864 100644 --- a/public/locales/et/gamepage.json +++ b/public/locales/et/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Eemalda lemmikutest", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/eu/gamepage.json b/public/locales/eu/gamepage.json index 73c8d26e21..d880d5490e 100644 --- a/public/locales/eu/gamepage.json +++ b/public/locales/eu/gamepage.json @@ -59,6 +59,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Kendu gogokoenetik", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/fa/gamepage.json b/public/locales/fa/gamepage.json index 7f48df6950..7984fbaf2f 100644 --- a/public/locales/fa/gamepage.json +++ b/public/locales/fa/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "حذف کردن از مورد علاقه ها", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/fi/gamepage.json b/public/locales/fi/gamepage.json index e7e871ad71..4ac674798f 100644 --- a/public/locales/fi/gamepage.json +++ b/public/locales/fi/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Remove From Favourites", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/fr/gamepage.json b/public/locales/fr/gamepage.json index 6a2f5224e2..a4aa511945 100644 --- a/public/locales/fr/gamepage.json +++ b/public/locales/fr/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Retirer des favoris", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/gl/gamepage.json b/public/locales/gl/gamepage.json index 788d433b63..1cc2202341 100644 --- a/public/locales/gl/gamepage.json +++ b/public/locales/gl/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Remove From Favourites", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/hr/gamepage.json b/public/locales/hr/gamepage.json index 9fe9bea02e..e59fc730d7 100644 --- a/public/locales/hr/gamepage.json +++ b/public/locales/hr/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Makni iz omiljenih", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/hu/gamepage.json b/public/locales/hu/gamepage.json index ff72c46887..b68c327624 100644 --- a/public/locales/hu/gamepage.json +++ b/public/locales/hu/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Eltávolítás a kedvencekből", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/id/gamepage.json b/public/locales/id/gamepage.json index 9c31184903..a64a5d5d97 100644 --- a/public/locales/id/gamepage.json +++ b/public/locales/id/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Hapus Dari Favorit", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/it/gamepage.json b/public/locales/it/gamepage.json index 7311f192c2..8dcf7f7cd4 100644 --- a/public/locales/it/gamepage.json +++ b/public/locales/it/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Rimuovi Dai Preferiti", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/ja/gamepage.json b/public/locales/ja/gamepage.json index b4c4d2dbf3..5bda113efd 100644 --- a/public/locales/ja/gamepage.json +++ b/public/locales/ja/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Remove From Favourites", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/ko/gamepage.json b/public/locales/ko/gamepage.json index 386d576fdf..060433aecc 100644 --- a/public/locales/ko/gamepage.json +++ b/public/locales/ko/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "즐겨찾기에서 제거", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/ml/gamepage.json b/public/locales/ml/gamepage.json index 817cd94676..4d15755827 100644 --- a/public/locales/ml/gamepage.json +++ b/public/locales/ml/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Remove From Favourites", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/nb_NO/gamepage.json b/public/locales/nb_NO/gamepage.json index bf993b28dc..381f6d50c3 100644 --- a/public/locales/nb_NO/gamepage.json +++ b/public/locales/nb_NO/gamepage.json @@ -59,6 +59,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Fjern fra favoritter", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/nl/gamepage.json b/public/locales/nl/gamepage.json index 3f046eb686..b16cf8a60c 100644 --- a/public/locales/nl/gamepage.json +++ b/public/locales/nl/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Remove From Favourites", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/pl/gamepage.json b/public/locales/pl/gamepage.json index 6299348dca..16fb24f919 100644 --- a/public/locales/pl/gamepage.json +++ b/public/locales/pl/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Usuń z ulubionych", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/pt/gamepage.json b/public/locales/pt/gamepage.json index 62fa094f7c..77bcb9b0b2 100644 --- a/public/locales/pt/gamepage.json +++ b/public/locales/pt/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Remove From Favourites", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/pt_BR/gamepage.json b/public/locales/pt_BR/gamepage.json index a5b9b95627..c17ac887ac 100644 --- a/public/locales/pt_BR/gamepage.json +++ b/public/locales/pt_BR/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Remover dos favoritos", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/ro/gamepage.json b/public/locales/ro/gamepage.json index c042a1b91d..1bbdaa4f7a 100644 --- a/public/locales/ro/gamepage.json +++ b/public/locales/ro/gamepage.json @@ -59,6 +59,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Eliminați din Favorite", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/ru/gamepage.json b/public/locales/ru/gamepage.json index a6bf884e6c..a771f65428 100644 --- a/public/locales/ru/gamepage.json +++ b/public/locales/ru/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Удалить из избранного", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/sk/gamepage.json b/public/locales/sk/gamepage.json index 6f05f0984d..5c97a4aa7d 100644 --- a/public/locales/sk/gamepage.json +++ b/public/locales/sk/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Odstrániť z obľúbených", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/sv/gamepage.json b/public/locales/sv/gamepage.json index 46f079bc88..4ef13bc5f7 100644 --- a/public/locales/sv/gamepage.json +++ b/public/locales/sv/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Ta bort från Favoriter", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/ta/gamepage.json b/public/locales/ta/gamepage.json index a150dd188b..bfd5a8cd4a 100644 --- a/public/locales/ta/gamepage.json +++ b/public/locales/ta/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Remove From Favourites", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/tr/gamepage.json b/public/locales/tr/gamepage.json index 670fb84414..432a9d57f7 100644 --- a/public/locales/tr/gamepage.json +++ b/public/locales/tr/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Favorilerden Kaldır", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/uk/gamepage.json b/public/locales/uk/gamepage.json index 17e48aaed2..b9f15afa52 100644 --- a/public/locales/uk/gamepage.json +++ b/public/locales/uk/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Видалити зі вподобань", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/vi/gamepage.json b/public/locales/vi/gamepage.json index e3af2a6deb..e5db087978 100644 --- a/public/locales/vi/gamepage.json +++ b/public/locales/vi/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "Xóa khỏi mục ưa thích", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/zh_Hans/gamepage.json b/public/locales/zh_Hans/gamepage.json index ca0cf7dfff..4609072929 100644 --- a/public/locales/zh_Hans/gamepage.json +++ b/public/locales/zh_Hans/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "从收藏夹移除", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/public/locales/zh_Hant/gamepage.json b/public/locales/zh_Hant/gamepage.json index 4e52729ba8..92b222fd2e 100644 --- a/public/locales/zh_Hant/gamepage.json +++ b/public/locales/zh_Hant/gamepage.json @@ -58,6 +58,7 @@ "remove": "Remove from Queue" }, "remove_from_favourites": "自我的最愛移除", + "remove_from_recent": "Remove From Recent", "run-exe-first": "Run Installer First", "running-setup": "Running Setup", "sideload": { diff --git a/src/backend/api/library.ts b/src/backend/api/library.ts index 39812c52b4..7077ac70bc 100644 --- a/src/backend/api/library.ts +++ b/src/backend/api/library.ts @@ -51,6 +51,16 @@ export const handleInstallGame = (callback: any) => export const handleRefreshLibrary = (callback: any) => ipcRenderer.on('refreshLibrary', callback) +export const removeRecentGame = async (appName: string) => + ipcRenderer.invoke('removeRecent', appName) +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const handleRecentGamesChanged = (callback: any) => { + ipcRenderer.on('recentGamesChanged', callback) + return () => { + ipcRenderer.removeListener('recentGamesChanged', callback) + } +} + export const addNewApp = (args: SideloadGame) => ipcRenderer.send('addNewApp', args) diff --git a/src/backend/main.ts b/src/backend/main.ts index 52bfe1660d..1d5726c8f0 100644 --- a/src/backend/main.ts +++ b/src/backend/main.ts @@ -128,6 +128,7 @@ import { runOnceWhenOnline } from './online_monitor' import { showDialogBoxModalAuto } from './dialog/dialog' +import { addRecentGame, getRecentGames } from './recent_games' import { addNewApp, appLogFileLocation, @@ -280,10 +281,8 @@ async function createWindow(): Promise { const gotTheLock = app.requestSingleInstanceLock() let openUrlArgument = '' -const contextMenu = () => { - const recentGames: Array = - (configStore.get('games.recent', []) as Array) || [] - const recentsMenu = recentGames.map((game) => { +const contextMenu = async () => { + const recentsMenu = (await getRecentGames({ limited: true })).map((game) => { return { click: function () { handleProtocol(mainWindow, [`heroic://launch/${game.appName}`]) @@ -483,7 +482,7 @@ if (!gotTheLock) { mainWindow.show() }) - appIcon.setContextMenu(contextMenu()) + appIcon.setContextMenu(await contextMenu()) appIcon.setToolTip('Heroic') ipcMain.on('changeLanguage', async (event, language: string) => { logInfo(['Changing Language to:', language], { @@ -491,7 +490,7 @@ if (!gotTheLock) { }) await i18next.changeLanguage(language) gameInfoStore.clear() - appIcon.setContextMenu(contextMenu()) + appIcon.setContextMenu(await contextMenu()) }) ipcMain.addListener('changeTrayColor', () => { @@ -500,7 +499,7 @@ if (!gotTheLock) { const { darkTrayIcon } = await GlobalConfig.get().getSettings() const trayIcon = darkTrayIcon ? iconDark : iconLight appIcon.setImage(trayIcon) - appIcon.setContextMenu(contextMenu()) + appIcon.setContextMenu(await contextMenu()) }, 500) }) @@ -559,10 +558,6 @@ ipcMain.on('unlock', () => { } }) -ipcMain.handle('kill', async (event, appName, runner) => { - return getGame(appName, runner).stop() -}) - ipcMain.handle('checkDiskSpace', async (event, folder: string) => { const parent = getFirstExistingParentPath(folder) return new Promise((res) => { @@ -965,11 +960,6 @@ ipcMain.on('logInfo', (e, info) => logInfo(info, { prefix: LogPrefix.Frontend }) ) -type RecentGame = { - appName: string - title: string -} - let powerDisplayId: number | null ipcMain.handle( @@ -977,14 +967,11 @@ ipcMain.handle( async (event, { appName, launchArguments, runner }: LaunchParams) => { const window = BrowserWindow.getAllWindows()[0] const isSideloaded = runner === 'sideload' - const recentGames = - (configStore.get('games.recent') as Array) || [] const extGame = getGame(appName, runner) const game = isSideloaded ? getAppInfo(appName) : extGame.getGameInfo() const { title } = game - const { minimizeOnLaunch, maxRecentGames: MAX_RECENT_GAMES = 5 } = - await GlobalConfig.get().getSettings() + const { minimizeOnLaunch } = await GlobalConfig.get().getSettings() const startPlayingDate = new Date() @@ -996,25 +983,7 @@ ipcMain.handle( prefix: LogPrefix.Backend }) - if (recentGames.length) { - let updatedRecentGames = recentGames.filter( - (a) => a.appName && a.appName !== game.app_name - ) - if (updatedRecentGames.length > MAX_RECENT_GAMES) { - const newArr = [] - for (let i = 0; i <= MAX_RECENT_GAMES; i++) { - newArr.push(updatedRecentGames[i]) - } - updatedRecentGames = newArr - } - if (updatedRecentGames.length === MAX_RECENT_GAMES) { - updatedRecentGames.pop() - } - updatedRecentGames.unshift({ appName: game.app_name, title }) - configStore.set('games.recent', updatedRecentGames) - } else { - configStore.set('games.recent', [{ appName: game.app_name, title }]) - } + addRecentGame(game) window.webContents.send('setGameStatus', { appName, diff --git a/src/backend/recent_games.ts b/src/backend/recent_games.ts new file mode 100644 index 0000000000..079b0a8f07 --- /dev/null +++ b/src/backend/recent_games.ts @@ -0,0 +1,50 @@ +import { GameInfo, RecentGame } from 'common/types' +import { BrowserWindow, ipcMain } from 'electron' +import { GlobalConfig } from './config' +import { configStore } from './constants' + +const getRecentGames = async (options?: { limited: boolean }) => { + const games = configStore.get('games.recent', []) as Array + if (options?.limited) { + const { maxRecentGames: MAX_RECENT_GAMES = 5 } = + await GlobalConfig.get().getSettings() + return games.slice(0, MAX_RECENT_GAMES) + } else { + return games + } +} + +const addRecentGame = async (game: GameInfo) => { + const games = await getRecentGames() + + // update list + const updatedList = games.filter( + (a) => a.appName && a.appName !== game.app_name + ) + updatedList.unshift({ appName: game.app_name, title: game.title }) + + // store + configStore.set('games.recent', updatedList) + + // emit + const window = BrowserWindow.getAllWindows()[0] + window.webContents.send('recentGamesChanged', updatedList) +} + +const removeRecentGame = async (appName: string) => { + const games = await getRecentGames() + + if (games.length) { + const updatedList = games.filter((a) => a.appName && a.appName !== appName) + configStore.set('games.recent', updatedList) + + const window = BrowserWindow.getAllWindows()[0] + window.webContents.send('recentGamesChanged', updatedList) + } +} + +ipcMain.handle('removeRecent', async (_event, appName: string) => { + removeRecentGame(appName) +}) + +export { getRecentGames, addRecentGame, removeRecentGame } diff --git a/src/common/types.ts b/src/common/types.ts index 58b1c4581e..151fb13849 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -500,6 +500,11 @@ export interface Tools { runner: Runner } +export type RecentGame = { + appName: string + title: string +} + export interface DMQueueElement { params: InstallParams status?: 'done' | 'error' | 'abort' diff --git a/src/frontend/helpers/library.ts b/src/frontend/helpers/library.ts index 410241f7e1..80d2b3ea5d 100644 --- a/src/frontend/helpers/library.ts +++ b/src/frontend/helpers/library.ts @@ -9,7 +9,6 @@ import { import { TFunction } from 'react-i18next' import { getGameInfo, sendKill } from './index' -import { configStore } from './electronStores' import { DialogModalOptions } from 'frontend/types' const storage: Storage = window.localStorage @@ -233,32 +232,12 @@ const updateGame = window.api.updateGame // }) // } -type RecentGame = { - appName: string - title: string -} - -function getRecentGames(libraries: GameInfo[]): GameInfo[] { - const recentGames = - (configStore.get('games.recent', []) as Array) || [] - - return libraries.filter((game: GameInfo) => - recentGames.some((recent) => { - if (!recent || !game) { - return false - } - return recent.appName === game.app_name - }) - ) -} - export const epicCategories = ['all', 'legendary', 'epic'] export const gogCategories = ['all', 'gog'] export const sideloadedCategories = ['all', 'sideload'] export { handleStopInstallation, - getRecentGames, install, launch, repair, diff --git a/src/frontend/screens/Library/components/GameCard/index.tsx b/src/frontend/screens/Library/components/GameCard/index.tsx index 74ab1e2c63..464a01d8db 100644 --- a/src/frontend/screens/Library/components/GameCard/index.tsx +++ b/src/frontend/screens/Library/components/GameCard/index.tsx @@ -47,6 +47,7 @@ interface Card { runner: Runner installedPlatform: string | undefined forceCard?: boolean + isRecent: boolean } const GameCard = ({ @@ -62,7 +63,8 @@ const GameCard = ({ buttonClick, forceCard, runner, - installedPlatform + installedPlatform, + isRecent = false }: Card) => { const [progress, previousProgress] = hasProgress(appName) const [showUninstallModal, setShowUninstallModal] = useState(false) @@ -275,6 +277,11 @@ const GameCard = ({ label: t('button.remove_from_favourites', 'Remove From Favourites'), onclick: () => favouriteGames.remove(appName), show: isFavouriteGame + }, + { + label: t('button.remove_from_recent', 'Remove From Recent'), + onclick: async () => window.api.removeRecentGame(appName), + show: isRecent } ] diff --git a/src/frontend/screens/Library/components/GamesList/index.tsx b/src/frontend/screens/Library/components/GamesList/index.tsx index be9c48621c..33168c28bf 100644 --- a/src/frontend/screens/Library/components/GamesList/index.tsx +++ b/src/frontend/screens/Library/components/GamesList/index.tsx @@ -15,6 +15,7 @@ interface Props { gameInfo: GameInfo ) => void onlyInstalled?: boolean + isRecent?: boolean } export const GamesList = ({ @@ -22,7 +23,8 @@ export const GamesList = ({ layout = 'grid', handleGameCardClick, isFirstLane = false, - onlyInstalled = false + onlyInstalled = false, + isRecent = false }: Props): JSX.Element => { const { gameUpdates } = useContext(ContextProvider) const { t } = useTranslation() @@ -85,6 +87,7 @@ export const GamesList = ({ } forceCard={layout === 'grid'} installedPlatform={platform} + isRecent={isRecent} /> ) })} diff --git a/src/frontend/screens/Library/components/RecentlyPlayed/index.tsx b/src/frontend/screens/Library/components/RecentlyPlayed/index.tsx index 2078a54564..22a800d0d2 100644 --- a/src/frontend/screens/Library/components/RecentlyPlayed/index.tsx +++ b/src/frontend/screens/Library/components/RecentlyPlayed/index.tsx @@ -1,48 +1,65 @@ import React, { useContext, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' -import { getRecentGames } from 'frontend/helpers/library' import ContextProvider from 'frontend/state/ContextProvider' -import { GameInfo, GameStatus, Runner } from 'common/types' +import { AppSettings, GameInfo, RecentGame, Runner } from 'common/types' import { GamesList } from '../GamesList' +import { configStore } from 'frontend/helpers/electronStores' interface Props { handleModal: (appName: string, runner: Runner, gameInfo: GameInfo) => void onlyInstalled: boolean } +function getRecentGames(libraries: GameInfo[], limit: number): GameInfo[] { + const recentGames = + (configStore.get('games.recent', []) as Array) || [] + + const games: GameInfo[] = [] + + for (const recent of recentGames) { + const found = libraries.find( + (game: GameInfo) => game.app_name === recent.appName + ) + if (found) { + games.push(found) + if (games.length === limit) break + } + } + + return games +} + export default function RecentlyPlayed({ handleModal, onlyInstalled }: Props) { const { t } = useTranslation() const { epic, gog, sideloadedLibrary } = useContext(ContextProvider) const [recentGames, setRecentGames] = useState([]) - const loadRecentGames = () => { - const newRecentGames = getRecentGames([ - ...epic.library, - ...gog.library, - ...sideloadedLibrary - ]) + const loadRecentGames = async () => { + const { maxRecentGames }: AppSettings = await window.api.requestSettings( + 'default' + ) + const newRecentGames = getRecentGames( + [...epic.library, ...gog.library, ...sideloadedLibrary], + maxRecentGames + ) setRecentGames(newRecentGames) } useEffect(() => { loadRecentGames() - }, [epic.library, gog.library]) - const onGameStatusUpdates = async (_e: Event, { status }: GameStatus) => { - if (status === 'playing') { + const onRecentGamesUpdated = () => { loadRecentGames() } - } - useEffect(() => { - const setGameStatusRemoveListener = - window.api.handleSetGameStatus(onGameStatusUpdates) + const recentGamesChangedRemoveListener = + window.api.handleRecentGamesChanged(onRecentGamesUpdated) return () => { - setGameStatusRemoveListener() + recentGamesChangedRemoveListener() } - }) + }, []) if (!recentGames.length) { return null @@ -56,6 +73,7 @@ export default function RecentlyPlayed({ handleModal, onlyInstalled }: Props) { isFirstLane handleGameCardClick={handleModal} onlyInstalled={onlyInstalled} + isRecent={true} /> )