Add Komga connection setting

This commit is contained in:
2025-10-16 00:05:47 +02:00
parent 68ec11afea
commit d987dd0ebb
4 changed files with 86 additions and 2 deletions

View File

@@ -12,3 +12,17 @@
--mangacover-width-sm: 180px; --mangacover-width-sm: 180px;
--mangacover-height-sm: 260px; --mangacover-height-sm: 260px;
} }
@keyframes shake {
0% { transform: translate(1px, 1px) rotate(0deg); }
10% { transform: translate(-1px, -2px) rotate(-1deg); }
20% { transform: translate(-3px, 0px) rotate(1deg); }
30% { transform: translate(3px, 2px) rotate(0deg); }
40% { transform: translate(1px, -1px) rotate(1deg); }
50% { transform: translate(-1px, 2px) rotate(-1deg); }
60% { transform: translate(-3px, 1px) rotate(0deg); }
70% { transform: translate(3px, 1px) rotate(-1deg); }
80% { transform: translate(-1px, -1px) rotate(1deg); }
90% { transform: translate(1px, 2px) rotate(0deg); }
100% { transform: translate(1px, -2px) rotate(-1deg); }
}

View File

@@ -0,0 +1,49 @@
<template>
<UModal v-bind="$props" title="Connect Komga">
<template #body>
<UFormField label="URL">
<UInput v-model="requestData.url" placeholder="https://" class="w-full" :disabled="busy" />
</UFormField>
<UFormField label="Username">
<UInput v-model="requestData.username" class="w-full" :disabled="busy" />
</UFormField>
<UFormField label="Password">
<UInput v-model="requestData.password" type="password" class="w-full" :disabled="busy" />
</UFormField>
<UButton icon="i-lucide-link" :class="['mt-2 float-right', success == false ? 'animate-[shake_0.2s] bg-error' : '' ]" :loading="busy" :disabled="busy || !allowSend" @click="connect">Connect</UButton>
</template>
</UModal>
</template>
<script setup lang="ts">
import type { components } from '#open-fetch-schemas/api';
type CreateLibraryConnectorRecord = components['schemas']['CreateLibraryConnectorRecord'];
const { $api } = useNuxtApp();
const requestData = ref<CreateLibraryConnectorRecord>({
libraryType: 'Komga',
url: '',
username: '',
password: ''
});
const allowSend = computed(() => requestData.value.url && requestData.value.username && requestData.value.password);
const busy = ref<boolean>(false);
const success = ref<boolean | undefined>(undefined);
const emit = defineEmits<{ close: [boolean] }>()
const connect = async () => {
busy.value = true;
try {
await $api("/v2/LibraryConnector", { method: "PUT", body: requestData.value });
await refreshNuxtData(FetchKeys.Libraries.All);
emit('close', false);
success.value = true;
}catch {
success.value = false;
setTimeout(() => success.value = undefined, 200);
}finally {
busy.value = false;
}
}
</script>

View File

@@ -4,4 +4,5 @@ export const FetchKeys = {
Manga: { All: 'Manga', Id: (id: string) => `Manga/${id}` }, Manga: { All: 'Manga', Id: (id: string) => `Manga/${id}` },
MangaConnector: { Id: (id: string) => `MangaConnector/${id}`, All: 'MangaConnector' }, MangaConnector: { Id: (id: string) => `MangaConnector/${id}`, All: 'MangaConnector' },
Metadata: { Fetchers: 'Metadata', Links: 'Metadata/Links', Manga: (mangaId: string) => `Metadata/Links/${mangaId}` }, Metadata: { Fetchers: 'Metadata', Links: 'Metadata/Links', Manga: (mangaId: string) => `Metadata/Links/${mangaId}` },
Libraries: { All: 'Libraries', Id: (id: string) => `Libraries/${id}` },
}; };

View File

@@ -6,7 +6,14 @@
<h1>Libraries</h1> <h1>Libraries</h1>
</template> </template>
<template #footer> <template #footer>
<UButton icon="i-lucide-plus" class="w-fit" @click="addLibraryModal.open()">Add</UButton> <div class="flex flex-row gap-2">
<UButton icon="i-lucide-plus" class="w-fit" @click="addLibraryModal.open()">Add</UButton>
<UTooltip :text="komgaConnected ? 'Disconnect Komga' : 'Connect Komga'">
<UButton :icon="komgaConnected ? 'i-lucide-unlink' : 'i-lucide-link'" class="w-fit" @click="onKomgaClick"
>Komga</UButton
>
</UTooltip>
</div>
</template> </template>
<FileLibraries /> <FileLibraries />
</UCard> </UCard>
@@ -27,12 +34,14 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { LazyAddLibraryModal } from '#components'; import { LazyAddLibraryModal, LazyKomgaModal } from '#components';
import FileLibraries from '~/components/FileLibraries.vue'; import FileLibraries from '~/components/FileLibraries.vue';
import { refreshNuxtData } from '#app'; import { refreshNuxtData } from '#app';
const overlay = useOverlay(); const overlay = useOverlay();
const { $api } = useNuxtApp();
const addLibraryModal = overlay.create(LazyAddLibraryModal); const addLibraryModal = overlay.create(LazyAddLibraryModal);
const komgaModal = overlay.create(LazyKomgaModal);
const config = useRuntimeConfig(); const config = useRuntimeConfig();
const apiUrl = ref(config.public.openFetch.api.baseURL); const apiUrl = ref(config.public.openFetch.api.baseURL);
@@ -52,5 +61,16 @@ const cleanUpDatabase = async () => {
cleanUpDatabaseBusy.value = false; cleanUpDatabaseBusy.value = false;
}; };
const { data: libraries } = useApi('/v2/LibraryConnector', { key: FetchKeys.Libraries.All });
const komgaConnected = computed(() => libraries.value?.find((l) => l.type === "Komga")?.key);
const onKomgaClick = async () => {
if (!komgaConnected.value) {
komgaModal.open();
}else{
await $api("/v2/LibraryConnector/{LibraryConnectorId}", { method: "DELETE", path: { LibraryConnectorId: komgaConnected.value } });
await refreshNuxtData(FetchKeys.Libraries.All);
}
};
useHead({ title: 'Settings' }); useHead({ title: 'Settings' });
</script> </script>