Variety of bug fixes (#432)

* Fix #414

* Implement #268

* Add #269
This commit is contained in:
DecDuck
2026-06-21 20:07:59 +10:00
committed by GitHub
parent cbecd1161d
commit 38c11567ef
5 changed files with 97 additions and 38 deletions
+6 -1
View File
@@ -9,7 +9,12 @@ export const updateUser = async () => {
const user = useUser();
if (user.value === null) return;
user.value = await $dropFetch<UserModel | null>("/api/v1/user");
user.value = await $dropFetch<UserModel | null>("/api/v1/user", {
// Forward headers manually when called outside a component
headers: import.meta.server
? useRequestHeaders(["cookie", "authorization"])
: undefined,
});
};
export async function completeSignin() {
+3
View File
@@ -547,6 +547,9 @@
"sources": {
"create": "Create source",
"createDesc": "Drop will use this source to access your game library, and make them available.",
"deleteButton": "Delete source",
"deleteDesc": "Deleting \"{0}\" will cascade delete the library, all of its games, all of their versions, and all of their metadata. This action cannot be undone.",
"deleteTitle": "Delete library source?",
"desc": "Configure your library sources, where Drop will look for new games and versions to import.",
"documentationLink": "Documentation {arrow}",
"edit": "Edit source",
+43 -6
View File
@@ -126,8 +126,9 @@
</div>
<div
class="sticky top-0 z-40 flex items-center gap-x-6 bg-zinc-900 px-4 py-4 shadow-sm sm:px-6 lg:hidden"
class="sticky top-0 z-40 lg:pl-20 border-b border-zinc-800 bg-zinc-950 shadow-sm"
>
<div class="flex items-center gap-x-4 px-4 py-2 sm:px-6 lg:px-8">
<button
type="button"
class="-m-2.5 p-2.5 text-zinc-400 lg:hidden"
@@ -136,6 +137,39 @@
<span class="sr-only">{{ $t("header.openSidebar") }}</span>
<Bars3Icon class="h-6 w-6" aria-hidden="true" />
</button>
<div class="flex-1" />
<ol class="inline-flex items-center gap-3">
<li>
<Menu as="div" class="relative inline-block">
<MenuButton>
<UserHeaderWidget :notifications="unreadNotifications.length">
<BellIcon class="h-5" />
</UserHeaderWidget>
</MenuButton>
<transition
enter-active-class="transition ease-out duration-100"
enter-from-class="transform opacity-0 scale-95"
enter-to-class="transform opacity-100 scale-100"
leave-active-class="transition ease-in duration-75"
leave-from-class="transform opacity-100 scale-100"
leave-to-class="transform opacity-0 scale-95"
>
<MenuItems
class="absolute right-0 top-10 z-50 w-96 focus:outline-none shadow-md"
>
<UserHeaderNotificationWidgetPanel
:notifications="unreadNotifications"
/>
</MenuItems>
</transition>
</Menu>
</li>
<UserHeaderUserWidget />
</ol>
</div>
</div>
<main class="lg:pl-20 min-h-screen bg-zinc-900 flex flex-col">
@@ -156,6 +190,9 @@ import {
DialogPanel,
TransitionChild,
TransitionRoot,
Menu,
MenuButton,
MenuItems,
} from "@headlessui/vue";
import {
Bars3Icon,
@@ -168,7 +205,7 @@ import {
} from "@heroicons/vue/24/outline";
import type { NavigationItem } from "~/composables/types";
import { useCurrentNavigationIndex } from "~/composables/current-page-engine";
import { ArrowLeftIcon } from "@heroicons/vue/16/solid";
import { ArrowLeftIcon, BellIcon } from "@heroicons/vue/16/solid";
import { XMarkIcon } from "@heroicons/vue/24/solid";
import type { Settings } from "~/server/internal/utils/types";
@@ -219,10 +256,10 @@ const navigation: Array<NavigationItem & { icon: Component }> = [
},
];
// const notifications = useNotifications();
// const unreadNotifications = computed(() =>
// notifications.value.filter((e) => !e.read)
// );
const notifications = useNotifications();
const unreadNotifications = computed(() =>
notifications.value.filter((e) => !e.read),
);
const currentNavigationIndex = useCurrentNavigationIndex(navigation);
+1 -2
View File
@@ -2,14 +2,13 @@ const whitelistedPrefixes = ["/auth", "/api", "/setup"];
const requireAdmin = ["/admin"];
export default defineNuxtRouteMiddleware(async (to, _from) => {
if (import.meta.server) return;
const error = useError();
if (error.value !== undefined) return;
if (whitelistedPrefixes.findIndex((e) => to.fullPath.startsWith(e)) != -1)
return;
const user = useUser();
if (user === undefined) {
if (user.value === undefined) {
await updateUser();
}
if (!user.value) {
+17 -2
View File
@@ -347,10 +347,20 @@ function edit(index: number) {
actionSourceOpen.value = true;
}
async function deleteSource(index: number) {
function deleteSource(index: number) {
const source = sources.value[index];
if (!source) return;
createModal(
ModalType.Confirmation,
{
title: t("library.admin.sources.deleteTitle"),
description: t("library.admin.sources.deleteDesc", [source.name]),
buttonText: t("library.admin.sources.deleteButton"),
},
async (event, close) => {
if (event !== "confirm") return close();
try {
await $dropFetch("/api/v1/admin/library/sources", {
method: "DELETE",
@@ -369,8 +379,13 @@ async function deleteSource(index: number) {
},
(_, c) => c(),
);
return close();
}
sources.value.splice(index, 1);
const currentIndex = sources.value.findIndex((s) => s.id === source.id);
if (currentIndex !== -1) sources.value.splice(currentIndex, 1);
close();
},
);
}
</script>