From 787e908ba894b2a482c74c0415b53ffe42e955ea Mon Sep 17 00:00:00 2001 From: patttterson <49377371+patttterson@users.noreply.github.com> Date: Sun, 3 May 2026 20:07:47 -0700 Subject: [PATCH 1/2] feat: group installed games --- .../composables/GameSelectionComposable.ts | 17 +++- .../game-selection/GameSelectionList.vue | 32 ++++++- src/r2mm/manager/SteamLibraryScanner.ts | 86 +++++++++++++++++++ 3 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 src/r2mm/manager/SteamLibraryScanner.ts diff --git a/src/components/composables/GameSelectionComposable.ts b/src/components/composables/GameSelectionComposable.ts index c84fac4c5..af758d9e3 100644 --- a/src/components/composables/GameSelectionComposable.ts +++ b/src/components/composables/GameSelectionComposable.ts @@ -10,12 +10,14 @@ import ProviderUtils from '../../providers/generic/ProviderUtils'; import R2Error from '../../model/errors/R2Error'; import { getStore } from '../../providers/generic/store/StoreProvider'; import { State } from '../../store'; +import { getInstalledSteamAppIds } from '../../r2mm/manager/SteamLibraryScanner'; export function useGameSelectionComposable() { const store = getStore(); const router = useRouter(); const favourites = ref([]); + const installedAppIds = ref>(new Set()); const selectedGame = ref(null); const selectedPlatform = ref(null); const filterText = ref(''); @@ -66,10 +68,21 @@ export function useGameSelectionComposable() { .filter((value: Game) => favourites.value.includes(value.settingsIdentifier)); }); + const installedGameList = computed(() => { + return filteredGameList.value + .filter((value: Game) => !hiddenGameList.value.includes(value)) + .filter((value: Game) => value.storePlatformMetadata.some( + p => [Platform.STEAM, Platform.STEAM_DIRECT].includes(p.storePlatform) + && p.storeIdentifier != null + && installedAppIds.value.has(String(p.storeIdentifier)) + )); + }); + const nonFavouriteGameList = computed(() => { return filteredGameList.value .filter((value: Game) => !hiddenGameList.value.includes(value)) - .filter((value: Game) => !favourites.value.includes(value.settingsIdentifier)); + .filter((value: Game) => !favourites.value.includes(value.settingsIdentifier)) + .filter((value: Game) => !installedGameList.value.includes(value)); }); function isFavourited(game: Game): boolean { @@ -145,6 +158,7 @@ export function useGameSelectionComposable() { settings.value = await ManagerSettings.getSingleton(GameManager.defaultGame); const globalSettings = settings.value.getContext().global; favourites.value = globalSettings.favouriteGames || []; + installedAppIds.value = await getInstalledSteamAppIds(); const lastGame = GameManager.findByFolderName(globalSettings.lastSelectedGame); if (lastGame) markAsSelectedGame(lastGame); @@ -190,6 +204,7 @@ export function useGameSelectionComposable() { isSettingDefaultPlatform, hiddenGameList, favouriteGameList, + installedGameList, nonFavouriteGameList, isFavourited, isGameSelected, diff --git a/src/components/game-selection/GameSelectionList.vue b/src/components/game-selection/GameSelectionList.vue index c50da063a..8093fe088 100644 --- a/src/components/game-selection/GameSelectionList.vue +++ b/src/components/game-selection/GameSelectionList.vue @@ -13,6 +13,15 @@ @click="markAsSelectedGame(game)" @toggle-favourite="toggleFavourite(game)" /> + -