11<template >
22 <div >
3- <div
4- class =" relative mb-3 transition-transform duration-300 hover:scale-105 active:scale-95"
5- >
3+ <div class =" mb-3 inline-flex gap-x-2" >
64 <div
7- class =" pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3 "
5+ class =" relative transition-transform duration-300 hover:scale-105 active:scale-95 "
86 >
9- <MagnifyingGlassIcon class =" h-5 w-5 text-zinc-400" aria-hidden =" true" />
7+ <div
8+ class =" pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3"
9+ >
10+ <MagnifyingGlassIcon
11+ class =" h-5 w-5 text-zinc-400"
12+ aria-hidden =" true"
13+ />
14+ </div >
15+ <input
16+ type =" text"
17+ v-model =" searchQuery"
18+ class =" block w-full rounded-lg border-0 bg-zinc-800/50 py-2 pl-10 pr-3 text-zinc-100 placeholder:text-zinc-500 focus:bg-zinc-800 focus:ring-2 focus:ring-inset focus:ring-blue-500 sm:text-sm sm:leading-6"
19+ placeholder =" Search library..."
20+ />
1021 </div >
11- <input
12- type = " text "
13- v-model = " searchQuery "
14- class = " block w-full rounded-lg border-0 bg-zinc-800/50 py-2 pl-10 pr-3 text-zinc-100 placeholder:text-zinc-500 focus:bg-zinc-800 focus:ring-2 focus:ring-inset focus:ring-blue-500 sm:text-sm sm:leading-6 "
15- placeholder = " Search library... "
16- / >
22+ <button
23+ @click = " () => calculateGames(true) "
24+ class = " p-1 flex items-center justify-center transition-transform duration-300 size-10 hover:scale-110 active:scale-90 rounded-lg bg-zinc-800/50 text-zinc-100 "
25+ >
26+ < ArrowPathIcon class = " size-4 " />
27+ </ button >
1728 </div >
1829
1930 <TransitionGroup name =" list" tag =" ul" class =" flex flex-col gap-y-1.5" >
6071</template >
6172
6273<script setup lang="ts">
63- import { MagnifyingGlassIcon } from " @heroicons/vue/20/solid" ;
74+ import { ArrowPathIcon , MagnifyingGlassIcon } from " @heroicons/vue/20/solid" ;
6475import { invoke } from " @tauri-apps/api/core" ;
6576import { GameStatusEnum , type Game , type GameStatus } from " ~/types" ;
6677import { TransitionGroup } from " vue" ;
@@ -76,7 +87,7 @@ const gameStatusTextStyle: { [key in GameStatusEnum]: string } = {
7687 [GameStatusEnum .Updating ]: " text-blue-500" ,
7788 [GameStatusEnum .Uninstalling ]: " text-zinc-100" ,
7889 [GameStatusEnum .SetupRequired ]: " text-yellow-500" ,
79- [GameStatusEnum .PartiallyInstalled ]: " text-gray-600"
90+ [GameStatusEnum .PartiallyInstalled ]: " text-gray-600" ,
8091};
8192const gameStatusText: { [key in GameStatusEnum ]: string } = {
8293 [GameStatusEnum .Remote ]: " Not installed" ,
@@ -87,7 +98,7 @@ const gameStatusText: { [key in GameStatusEnum]: string } = {
8798 [GameStatusEnum .Uninstalling ]: " Uninstalling..." ,
8899 [GameStatusEnum .SetupRequired ]: " Setup required" ,
89100 [GameStatusEnum .Running ]: " Running" ,
90- [GameStatusEnum .PartiallyInstalled ]: " Partially installed"
101+ [GameStatusEnum .PartiallyInstalled ]: " Partially installed" ,
91102};
92103
93104const router = useRouter ();
@@ -101,16 +112,20 @@ const icons: { [key: string]: string } = {};
101112
102113const rawGames: Ref <Game [], Game []> = ref ([]);
103114
104- async function calculateGames() {
105- rawGames .value = await invoke (" fetch_library" );
106- for (const game of rawGames .value ) {
115+ async function calculateGames(clearAll = false ) {
116+ if (clearAll ) rawGames .value = [];
117+ // If we update immediately, the navigation gets re-rendered before we
118+ // add all the necessary state, and it freaks tf out
119+ const newGames = await invoke <typeof rawGames .value >(" fetch_library" );
120+ for (const game of newGames ) {
107121 if (games [game .id ]) continue ;
108122 games [game .id ] = await useGame (game .id );
109123 }
110- for (const game of rawGames . value ) {
124+ for (const game of newGames ) {
111125 if (icons [game .id ]) continue ;
112126 icons [game .id ] = await useObject (game .mIconObjectId );
113127 }
128+ rawGames .value = newGames ;
114129}
115130
116131await calculateGames ();
0 commit comments