mirror of
https://github.com/Drop-OSS/drop.git
synced 2026-07-26 01:34:38 +10:00
feat(library): Reactive library updating
Signed-off-by: quexeky <git@quexeky.dev>
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
v-for="(nav, navIdx) in navigation"
|
v-for="(nav, navIdx) in navigation"
|
||||||
:class="[
|
:class="[
|
||||||
'transition uppercase font-display font-semibold text-md',
|
'transition uppercase font-display font-semibold text-md',
|
||||||
navIdx === currentPageIndex
|
navIdx === currentNavigation
|
||||||
? 'text-zinc-100'
|
? 'text-zinc-100'
|
||||||
: 'text-zinc-400 hover:text-zinc-200',
|
: 'text-zinc-400 hover:text-zinc-200',
|
||||||
]"
|
]"
|
||||||
@@ -78,7 +78,7 @@ const navigation: Array<NavigationItem> = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const currentPageIndex = useCurrentNavigationIndex(navigation);
|
const {currentNavigation} = useCurrentNavigationIndex(navigation);
|
||||||
|
|
||||||
const quickActions: Array<QuickActionNav> = [
|
const quickActions: Array<QuickActionNav> = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,5 +26,7 @@ export const useCurrentNavigationIndex = (
|
|||||||
currentNavigation.value = calculateCurrentNavIndex(to);
|
currentNavigation.value = calculateCurrentNavIndex(to);
|
||||||
});
|
});
|
||||||
|
|
||||||
return currentNavigation;
|
return {currentNavigation, recalculateNavigation: () => {
|
||||||
|
currentNavigation.value = calculateCurrentNavIndex(route);
|
||||||
|
}};
|
||||||
};
|
};
|
||||||
|
|||||||
+42
-32
@@ -1,28 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-row h-full">
|
<div class="flex flex-row h-full">
|
||||||
<div
|
<div class="flex-none max-h-full overflow-y-auto w-64 bg-zinc-950 px-2 py-1">
|
||||||
class="flex-none max-h-full overflow-y-auto w-64 bg-zinc-950 px-2 py-1"
|
|
||||||
>
|
|
||||||
<ul class="flex flex-col gap-y-1">
|
<ul class="flex flex-col gap-y-1">
|
||||||
<NuxtLink
|
<NuxtLink v-for="(nav, navIdx) in navigation" :key="nav.route" :class="[
|
||||||
v-for="(nav, navIdx) in navigation"
|
'transition-all duration-200 rounded-lg flex items-center py-1.5 px-3',
|
||||||
:key="nav.route"
|
navIdx === currentNavigation
|
||||||
:class="[
|
? 'bg-zinc-800 text-zinc-100'
|
||||||
'transition-all duration-200 rounded-lg flex items-center py-1.5 px-3',
|
: nav.isInstalled.value
|
||||||
navIdx === currentNavigationIndex
|
|
||||||
? 'bg-zinc-800 text-zinc-100'
|
|
||||||
: nav.isInstalled.value
|
|
||||||
? 'text-zinc-300 hover:bg-zinc-800/90 hover:text-zinc-200'
|
? 'text-zinc-300 hover:bg-zinc-800/90 hover:text-zinc-200'
|
||||||
: 'text-zinc-500 hover:bg-zinc-800/70 hover:text-zinc-300',
|
: 'text-zinc-500 hover:bg-zinc-800/70 hover:text-zinc-300',
|
||||||
]"
|
]" :href="nav.route">
|
||||||
:href="nav.route"
|
|
||||||
>
|
|
||||||
<div class="flex items-center w-full gap-x-3">
|
<div class="flex items-center w-full gap-x-3">
|
||||||
<img
|
<img class="size-6 flex-none object-cover bg-zinc-900 rounded" :src="icons[nav.id]" alt="" />
|
||||||
class="size-6 flex-none object-cover bg-zinc-900 rounded"
|
|
||||||
:src="icons[navIdx]"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
<p class="truncate text-sm font-display leading-6 flex-1">
|
<p class="truncate text-sm font-display leading-6 flex-1">
|
||||||
{{ nav.label }}
|
{{ nav.label }}
|
||||||
</p>
|
</p>
|
||||||
@@ -31,35 +20,47 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="grow overflow-y-auto">
|
<div class="grow overflow-y-auto">
|
||||||
<NuxtPage :libraryDownloadError = "libraryDownloadError" />
|
<NuxtPage :libraryDownloadError="libraryDownloadError" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
import { GameStatusEnum, type Game, type NavigationItem } from "~/types";
|
import { listen } from "@tauri-apps/api/event";
|
||||||
|
import { GameStatusEnum, type Game, type GameStatus, type NavigationItem } from "~/types";
|
||||||
|
|
||||||
let libraryDownloadError = false;
|
let libraryDownloadError = false;
|
||||||
|
|
||||||
async function calculateGames(): Promise<Game[]> {
|
const games: { [key: string]: { game: Game, status: Ref<GameStatus, GameStatus> } } = {};
|
||||||
|
const icons: { [key: string]: string } = {};
|
||||||
|
|
||||||
|
const rawGames: Ref<Game[], Game[]> = ref([])
|
||||||
|
|
||||||
|
async function calculateGames() {
|
||||||
try {
|
try {
|
||||||
return await invoke("fetch_library");
|
rawGames.value = await invoke("fetch_library");
|
||||||
|
for (const game of rawGames.value) {
|
||||||
|
if (games[game.id]) continue;
|
||||||
|
games[game.id] = await useGame(game.id);
|
||||||
|
}
|
||||||
|
for (const game of rawGames.value) {
|
||||||
|
if (icons[game.id]) continue;
|
||||||
|
icons[game.id] = await useObject(game.mIconId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
libraryDownloadError = true;
|
libraryDownloadError = true;
|
||||||
return new Array();
|
return new Array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawGames: Array<Game> = await calculateGames();
|
await calculateGames();
|
||||||
const games = await Promise.all(rawGames.map((e) => useGame(e.id)));
|
|
||||||
const icons = await Promise.all(
|
const navigation = computed(() => rawGames.value.map((game) => {
|
||||||
games.map(({ game, status }) => useObject(game.mIconId))
|
const status = games[game.id].status;
|
||||||
);
|
|
||||||
|
|
||||||
const navigation = games.map(({ game, status }) => {
|
|
||||||
const isInstalled = computed(
|
const isInstalled = computed(
|
||||||
() =>
|
() =>
|
||||||
status.value.type == GameStatusEnum.Installed ||
|
status.value.type == GameStatusEnum.Installed ||
|
||||||
@@ -71,9 +72,18 @@ const navigation = games.map(({ game, status }) => {
|
|||||||
route: `/library/${game.id}`,
|
route: `/library/${game.id}`,
|
||||||
prefix: `/library/${game.id}`,
|
prefix: `/library/${game.id}`,
|
||||||
isInstalled,
|
isInstalled,
|
||||||
|
id: game.id,
|
||||||
};
|
};
|
||||||
return item;
|
return item;
|
||||||
});
|
})
|
||||||
|
);
|
||||||
|
const { currentNavigation, recalculateNavigation } = useCurrentNavigationIndex(navigation.value);
|
||||||
|
|
||||||
|
|
||||||
|
listen("update_library", async (event) => {
|
||||||
|
console.log("Updating library");
|
||||||
|
await calculateGames()
|
||||||
|
recalculateNavigation();
|
||||||
|
})
|
||||||
|
|
||||||
const currentNavigationIndex = useCurrentNavigationIndex(navigation);
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
<ul role="list" class="-mx-2 space-y-1">
|
<ul role="list" class="-mx-2 space-y-1">
|
||||||
<li v-for="(item, itemIdx) in navigation" :key="item.prefix">
|
<li v-for="(item, itemIdx) in navigation" :key="item.prefix">
|
||||||
<NuxtLink :href="item.route" :class="[
|
<NuxtLink :href="item.route" :class="[
|
||||||
itemIdx === currentPageIndex
|
itemIdx === currentNavigation
|
||||||
? 'bg-zinc-800/50 text-zinc-100'
|
? 'bg-zinc-800/50 text-zinc-100'
|
||||||
: 'text-zinc-400 hover:bg-zinc-800/30 hover:text-zinc-200',
|
: 'text-zinc-400 hover:bg-zinc-800/30 hover:text-zinc-200',
|
||||||
'transition group flex gap-x-3 rounded-md p-2 pr-12 text-sm font-semibold leading-6',
|
'transition group flex gap-x-3 rounded-md p-2 pr-12 text-sm font-semibold leading-6',
|
||||||
]">
|
]">
|
||||||
<component :is="item.icon" :class="[
|
<component :is="item.icon" :class="[
|
||||||
itemIdx === currentPageIndex
|
itemIdx === currentNavigation
|
||||||
? 'text-zinc-100'
|
? 'text-zinc-100'
|
||||||
: 'text-zinc-400 group-hover:text-zinc-200',
|
: 'text-zinc-400 group-hover:text-zinc-200',
|
||||||
'transition h-6 w-6 shrink-0',
|
'transition h-6 w-6 shrink-0',
|
||||||
@@ -112,10 +112,10 @@ const navigation = computed(() => [
|
|||||||
const currentPlatform = platform();
|
const currentPlatform = platform();
|
||||||
|
|
||||||
// Use .value to unwrap the computed ref
|
// Use .value to unwrap the computed ref
|
||||||
const currentPageIndex = useCurrentNavigationIndex(navigation.value);
|
const {currentNavigation} = useCurrentNavigationIndex(navigation.value);
|
||||||
|
|
||||||
// Watch for navigation changes and update currentPageIndex
|
// Watch for navigation changes and update currentPageIndex
|
||||||
watch(navigation, (newNav) => {
|
watch(navigation, (newNav) => {
|
||||||
currentPageIndex.value = useCurrentNavigationIndex(newNav).value;
|
currentNavigation.value = useCurrentNavigationIndex(newNav).currentNavigation.value;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ pub fn uninstall_game(game_id: String, app_handle: AppHandle) -> Result<(), Libr
|
|||||||
Some(data) => data,
|
Some(data) => data,
|
||||||
None => return Err(LibraryError::MetaNotFound(game_id)),
|
None => return Err(LibraryError::MetaNotFound(game_id)),
|
||||||
};
|
};
|
||||||
println!("{:?}", meta);
|
|
||||||
uninstall_game_logic(meta, &app_handle);
|
uninstall_game_logic(meta, &app_handle);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ pub fn fetch_library_logic(
|
|||||||
drop(db_handle);
|
drop(db_handle);
|
||||||
cache_object("library", &games)?;
|
cache_object("library", &games)?;
|
||||||
|
|
||||||
|
|
||||||
Ok(games)
|
Ok(games)
|
||||||
}
|
}
|
||||||
pub fn fetch_library_logic_offline(
|
pub fn fetch_library_logic_offline(
|
||||||
@@ -137,7 +136,6 @@ pub fn fetch_game_logic(
|
|||||||
status,
|
status,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
cache_object(id, &data)?;
|
cache_object(id, &data)?;
|
||||||
|
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
@@ -261,8 +259,6 @@ pub fn uninstall_game_logic(meta: DownloadableMetadata, app_handle: &AppHandle)
|
|||||||
.entry(meta.clone())
|
.entry(meta.clone())
|
||||||
.and_modify(|v| *v = ApplicationTransientStatus::Uninstalling {});
|
.and_modify(|v| *v = ApplicationTransientStatus::Uninstalling {});
|
||||||
|
|
||||||
db_handle.applications.installed_game_version.remove(&meta.id);
|
|
||||||
|
|
||||||
drop(db_handle);
|
drop(db_handle);
|
||||||
|
|
||||||
let app_handle = app_handle.clone();
|
let app_handle = app_handle.clone();
|
||||||
@@ -273,6 +269,10 @@ pub fn uninstall_game_logic(meta: DownloadableMetadata, app_handle: &AppHandle)
|
|||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let mut db_handle = borrow_db_mut_checked();
|
let mut db_handle = borrow_db_mut_checked();
|
||||||
db_handle.applications.transient_statuses.remove(&meta);
|
db_handle.applications.transient_statuses.remove(&meta);
|
||||||
|
db_handle
|
||||||
|
.applications
|
||||||
|
.installed_game_version
|
||||||
|
.remove(&meta.id);
|
||||||
db_handle
|
db_handle
|
||||||
.applications
|
.applications
|
||||||
.game_statuses
|
.game_statuses
|
||||||
@@ -282,6 +282,7 @@ pub fn uninstall_game_logic(meta: DownloadableMetadata, app_handle: &AppHandle)
|
|||||||
save_db();
|
save_db();
|
||||||
|
|
||||||
debug!("uninstalled game id {}", &meta.id);
|
debug!("uninstalled game id {}", &meta.id);
|
||||||
|
app_handle.emit("update_library", {}).unwrap();
|
||||||
|
|
||||||
push_game_update(
|
push_game_update(
|
||||||
&app_handle,
|
&app_handle,
|
||||||
|
|||||||
Reference in New Issue
Block a user