mirror of
https://github.com/C9Glax/tranga-website.git
synced 2025-10-16 18:30:47 +02:00
Add Kavita setting
This commit is contained in:
@@ -14,15 +14,37 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes shake {
|
@keyframes shake {
|
||||||
0% { transform: translate(1px, 1px) rotate(0deg); }
|
0% {
|
||||||
10% { transform: translate(-1px, -2px) rotate(-1deg); }
|
transform: translate(1px, 1px) rotate(0deg);
|
||||||
20% { transform: translate(-3px, 0px) rotate(1deg); }
|
}
|
||||||
30% { transform: translate(3px, 2px) rotate(0deg); }
|
10% {
|
||||||
40% { transform: translate(1px, -1px) rotate(1deg); }
|
transform: translate(-1px, -2px) rotate(-1deg);
|
||||||
50% { transform: translate(-1px, 2px) rotate(-1deg); }
|
}
|
||||||
60% { transform: translate(-3px, 1px) rotate(0deg); }
|
20% {
|
||||||
70% { transform: translate(3px, 1px) rotate(-1deg); }
|
transform: translate(-3px, 0px) rotate(1deg);
|
||||||
80% { transform: translate(-1px, -1px) rotate(1deg); }
|
}
|
||||||
90% { transform: translate(1px, 2px) rotate(0deg); }
|
30% {
|
||||||
100% { transform: translate(1px, -2px) rotate(-1deg); }
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
51
website/app/components/KavitaModal.vue
Normal file
51
website/app/components/KavitaModal.vue
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<UModal v-bind="$props" title="Connect Kavita">
|
||||||
|
<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: 'Kavita', 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>
|
@@ -10,7 +10,14 @@
|
|||||||
<UFormField label="Password">
|
<UFormField label="Password">
|
||||||
<UInput v-model="requestData.password" type="password" class="w-full" :disabled="busy" />
|
<UInput v-model="requestData.password" type="password" class="w-full" :disabled="busy" />
|
||||||
</UFormField>
|
</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>
|
<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>
|
</template>
|
||||||
</UModal>
|
</UModal>
|
||||||
</template>
|
</template>
|
||||||
@@ -20,30 +27,25 @@ import type { components } from '#open-fetch-schemas/api';
|
|||||||
type CreateLibraryConnectorRecord = components['schemas']['CreateLibraryConnectorRecord'];
|
type CreateLibraryConnectorRecord = components['schemas']['CreateLibraryConnectorRecord'];
|
||||||
const { $api } = useNuxtApp();
|
const { $api } = useNuxtApp();
|
||||||
|
|
||||||
const requestData = ref<CreateLibraryConnectorRecord>({
|
const requestData = ref<CreateLibraryConnectorRecord>({ libraryType: 'Komga', url: '', username: '', password: '' });
|
||||||
libraryType: 'Komga',
|
|
||||||
url: '',
|
|
||||||
username: '',
|
|
||||||
password: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
const allowSend = computed(() => requestData.value.url && requestData.value.username && requestData.value.password);
|
const allowSend = computed(() => requestData.value.url && requestData.value.username && requestData.value.password);
|
||||||
|
|
||||||
const busy = ref<boolean>(false);
|
const busy = ref<boolean>(false);
|
||||||
const success = ref<boolean | undefined>(undefined);
|
const success = ref<boolean | undefined>(undefined);
|
||||||
const emit = defineEmits<{ close: [boolean] }>()
|
const emit = defineEmits<{ close: [boolean] }>();
|
||||||
const connect = async () => {
|
const connect = async () => {
|
||||||
busy.value = true;
|
busy.value = true;
|
||||||
try {
|
try {
|
||||||
await $api("/v2/LibraryConnector", { method: "PUT", body: requestData.value });
|
await $api('/v2/LibraryConnector', { method: 'PUT', body: requestData.value });
|
||||||
await refreshNuxtData(FetchKeys.Libraries.All);
|
await refreshNuxtData(FetchKeys.Libraries.All);
|
||||||
emit('close', false);
|
emit('close', false);
|
||||||
success.value = true;
|
success.value = true;
|
||||||
} catch {
|
} catch {
|
||||||
success.value = false;
|
success.value = false;
|
||||||
setTimeout(() => success.value = undefined, 200);
|
setTimeout(() => (success.value = undefined), 200);
|
||||||
} finally {
|
} finally {
|
||||||
busy.value = false;
|
busy.value = false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@@ -9,9 +9,18 @@
|
|||||||
<div class="flex flex-row gap-2">
|
<div class="flex flex-row gap-2">
|
||||||
<UButton icon="i-lucide-plus" class="w-fit" @click="addLibraryModal.open()">Add</UButton>
|
<UButton icon="i-lucide-plus" class="w-fit" @click="addLibraryModal.open()">Add</UButton>
|
||||||
<UTooltip :text="komgaConnected ? 'Disconnect Komga' : 'Connect Komga'">
|
<UTooltip :text="komgaConnected ? 'Disconnect Komga' : 'Connect Komga'">
|
||||||
<UButton :icon="komgaConnected ? 'i-lucide-unlink' : 'i-lucide-link'" class="w-fit" @click="onKomgaClick"
|
<UButton
|
||||||
>Komga</UButton
|
:icon="komgaConnected ? 'i-lucide-unlink' : 'i-lucide-link'"
|
||||||
>
|
class="w-fit"
|
||||||
|
label="Komga"
|
||||||
|
@click="onKomgaClick" />
|
||||||
|
</UTooltip>
|
||||||
|
<UTooltip :text="kavitaConnected ? 'Disconnect Kavita' : 'Connect Kavita'">
|
||||||
|
<UButton
|
||||||
|
:icon="kavitaConnected ? 'i-lucide-unlink' : 'i-lucide-link'"
|
||||||
|
class="w-fit"
|
||||||
|
label="Kavita"
|
||||||
|
@click="onKavitaClick" />
|
||||||
</UTooltip>
|
</UTooltip>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -34,7 +43,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { LazyAddLibraryModal, LazyKomgaModal } from '#components';
|
import { LazyAddLibraryModal, LazyKavitaModal, 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();
|
||||||
@@ -42,6 +51,7 @@ const { $api } = useNuxtApp();
|
|||||||
|
|
||||||
const addLibraryModal = overlay.create(LazyAddLibraryModal);
|
const addLibraryModal = overlay.create(LazyAddLibraryModal);
|
||||||
const komgaModal = overlay.create(LazyKomgaModal);
|
const komgaModal = overlay.create(LazyKomgaModal);
|
||||||
|
const kavitaModal = overlay.create(LazyKavitaModal);
|
||||||
|
|
||||||
const config = useRuntimeConfig();
|
const config = useRuntimeConfig();
|
||||||
const apiUrl = ref(config.public.openFetch.api.baseURL);
|
const apiUrl = ref(config.public.openFetch.api.baseURL);
|
||||||
@@ -62,12 +72,21 @@ const cleanUpDatabase = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { data: libraries } = useApi('/v2/LibraryConnector', { key: FetchKeys.Libraries.All });
|
const { data: libraries } = useApi('/v2/LibraryConnector', { key: FetchKeys.Libraries.All });
|
||||||
const komgaConnected = computed(() => libraries.value?.find((l) => l.type === "Komga")?.key);
|
const komgaConnected = computed(() => libraries.value?.find((l) => l.type === 'Komga')?.key);
|
||||||
const onKomgaClick = async () => {
|
const onKomgaClick = async () => {
|
||||||
if (!komgaConnected.value) {
|
if (!komgaConnected.value) {
|
||||||
komgaModal.open();
|
komgaModal.open();
|
||||||
} else {
|
} else {
|
||||||
await $api("/v2/LibraryConnector/{LibraryConnectorId}", { method: "DELETE", path: { LibraryConnectorId: komgaConnected.value } });
|
await $api('/v2/LibraryConnector/{LibraryConnectorId}', { method: 'DELETE', path: { LibraryConnectorId: komgaConnected.value } });
|
||||||
|
await refreshNuxtData(FetchKeys.Libraries.All);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const kavitaConnected = computed(() => libraries.value?.find((l) => l.type === 'Kavita')?.key);
|
||||||
|
const onKavitaClick = async () => {
|
||||||
|
if (!kavitaConnected.value) {
|
||||||
|
kavitaModal.open();
|
||||||
|
} else {
|
||||||
|
await $api('/v2/LibraryConnector/{LibraryConnectorId}', { method: 'DELETE', path: { LibraryConnectorId: kavitaConnected.value } });
|
||||||
await refreshNuxtData(FetchKeys.Libraries.All);
|
await refreshNuxtData(FetchKeys.Libraries.All);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user