Skip to content

Commit

Permalink
feat: ui improvements
Browse files Browse the repository at this point in the history
BEGIN_COMMIT_OVERRIDE
feat: add library filtering
feat: add library filtering
chore: format
refactor: use locals for DB and BACKEND_URL
fix: add comet and all-debrid
fix: add notifications
fix: check for updates
feat: show request button in ui
chore: format
END_COMMIT_OVERRIDE
  • Loading branch information
AyushSehrawat authored Aug 9, 2024
1 parent 08b31b3 commit ad8a9ba
Show file tree
Hide file tree
Showing 22 changed files with 478 additions and 141 deletions.
10 changes: 7 additions & 3 deletions src/app.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
import type { Kysely } from 'kysely';
import type { DB } from './types';

declare global {
namespace App {
// interface Error {}
// interface Locals {}
interface Locals {
BACKEND_URL: string;
db: Kysely<DB>;
}
// interface PageData {}
// interface PageState {}
// interface Platform {}
Expand Down
10 changes: 9 additions & 1 deletion src/hooks.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ import { redirect, error } from '@sveltejs/kit';
import { sequence } from '@sveltejs/kit/hooks';
import { env } from '$env/dynamic/private';
const BACKEND_URL = env.BACKEND_URL || 'http://127.0.0.1:8080';
import { db } from '$lib/server/db';

const setLocals: Handle = async ({ event, resolve }) => {
event.locals.BACKEND_URL = BACKEND_URL;
event.locals.db = db;

return resolve(event);
};

const onboarding: Handle = async ({ event, resolve }) => {
if (!event.url.pathname.startsWith('/onboarding') && event.request.method === 'GET') {
Expand All @@ -21,4 +29,4 @@ const onboarding: Handle = async ({ event, resolve }) => {
return resolve(event);
};

export const handle = sequence(onboarding);
export const handle = sequence(setLocals, onboarding);
12 changes: 9 additions & 3 deletions src/lib/components/home-items.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import { Star, CalendarDays, Clapperboard, MoveUpRight } from 'lucide-svelte';
import ItemRequest from './item-request.svelte';
import { roundOff } from '$lib/helpers';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -25,8 +26,7 @@

<div class="no-scrollbar flex flex-wrap overflow-x-auto px-1 lg:p-0">
{#each data.results as item}
<a
href="/{type}/{item.id}"
<div
class="group relative mb-2 flex w-1/2 flex-shrink-0 flex-col gap-2 rounded-lg p-2 sm:w-1/4 lg:w-1/6 xl:p-[.4rem]"
>
<div class="relative aspect-[1/1.5] w-full overflow-hidden rounded-lg">
Expand All @@ -44,8 +44,14 @@
{roundOff(item.vote_average)}
</span>
</div>
<a
href="/{type}/{item.id}"
class="absolute inset-0 hidden flex-col justify-end from-zinc-900/70 p-2 group-hover:flex group-hover:bg-gradient-to-t"
>
<ItemRequest data={item} {type} />
</a>
</div>
</a>
</div>
{/each}
</div>
</div>
Expand Down
54 changes: 54 additions & 0 deletions src/lib/components/item-request.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<script lang="ts">
import * as AlertDialog from '$lib/components/ui/alert-dialog';
import { Button } from '$lib/components/ui/button';
import { toast } from 'svelte-sonner';
import { invalidateAll } from '$app/navigation';
import { getExternalID } from '$lib/tmdb';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export let data: any;
export let type: string;
async function requestItem(id: number) {
const externalIds = await getExternalID(fetch, type, id);
const response = await fetch(`/api/media/${externalIds.imdb_id}`, {
method: 'POST'
});
if (response.ok) {
toast.success('Media requested successfully');
invalidateAll();
} else {
toast.error('An error occurred while requesting the media');
}
}
</script>

<AlertDialog.Root>
<AlertDialog.Trigger asChild let:builder>
<Button
on:click={(e) => {
e.preventDefault();
e.stopPropagation();
}}
variant="outline"
size="sm"
builders={[builder]}>Request</Button
>
</AlertDialog.Trigger>
<AlertDialog.Content>
<AlertDialog.Header>
<AlertDialog.Title
>Requesting {data.title || data.name || data.original_name}</AlertDialog.Title
>
</AlertDialog.Header>
<AlertDialog.Footer>
<AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
<AlertDialog.Action
on:click={async () => {
await requestItem(data.id);
}}>Continue</AlertDialog.Action
>
</AlertDialog.Footer>
</AlertDialog.Content>
</AlertDialog.Root>
147 changes: 146 additions & 1 deletion src/lib/forms/general-form.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
import NumberField from './components/number-field.svelte';
import CheckboxField from './components/checkbox-field.svelte';
import GroupCheckboxField from './components/group-checkbox-field.svelte';
import { Loader2 } from 'lucide-svelte';
import ArrayField from './components/array-field.svelte';
import { Loader2, Trash2, Plus } from 'lucide-svelte';
import { Separator } from '$lib/components/ui/separator';
import { Input } from '$lib/components/ui/input';
export let data: SuperValidated<Infer<GeneralSettingsSchema>>;
export let actionUrl: string = '?/default';
Expand All @@ -31,6 +33,16 @@
} else if ($message) {
toast.error($message);
}
function addField(name: string) {
// @ts-expect-error eslint-disable-next-line
$formData[name] = [...$formData[name], ''];
}
function removeField(name: string, index: number) {
// @ts-expect-error eslint-disable-next-line
$formData[name] = $formData[name].filter((_, i) => i !== index);
}
</script>

<form method="POST" action={actionUrl} use:enhance class="my-8 flex flex-col gap-2">
Expand Down Expand Up @@ -79,6 +91,8 @@
fieldDescription="Filesize in MB. Set to -1 for no limit"
/>

<TextField {form} name="database_host" fieldDescription="Database connection string" {formData} />

<GroupCheckboxField
fieldTitle="Downloaders"
fieldDescription="Enable only one downloader at a time"
Expand All @@ -90,6 +104,13 @@
{formData}
isForGroup={true}
/>
<CheckboxField
{form}
name="alldebrid_enabled"
label="All-Debrid"
{formData}
isForGroup={true}
/>
<CheckboxField {form} name="torbox_enabled" label="Torbox" {formData} isForGroup={true} />
</GroupCheckboxField>

Expand All @@ -115,12 +136,136 @@
{/if}
{/if}

{#if $formData.alldebrid_enabled}
<div transition:slide>
<TextField {form} name="alldebrid_api_key" {formData} isProtected={true} />
</div>

<div transition:slide>
<CheckboxField
{form}
name="alldebrid_proxy_enabled"
label="All-Debrid Proxy"
{formData}
fieldDescription="Use proxy for All-Debrid API"
/>
</div>

{#if $formData.alldebrid_proxy_enabled}
<div transition:slide>
<TextField {form} name="alldebrid_proxy_url" {formData} />
</div>
{/if}
{/if}

{#if $formData.torbox_enabled}
<div transition:slide>
<TextField {form} name="torbox_api_key" {formData} />
</div>
{/if}

<CheckboxField {form} name="notifications_enabled" label="Notifications" {formData} />

{#if $formData.notifications_enabled}
<div transition:slide>
<TextField {form} name="notifications_title" {formData} />
</div>

<div transition:slide>
<ArrayField {form} name="notifications_on_item_type" {formData}>
{#each $formData.notifications_on_item_type as _, i}
<Form.ElementField {form} name="notifications_on_item_type[{i}]">
<Form.Control let:attrs>
<div class="flex items-center gap-2">
<Input
type="text"
spellcheck="false"
autocomplete="false"
{...attrs}
bind:value={$formData.notifications_on_item_type[i]}
/>

<div class="flex items-center gap-2">
<Form.Button
type="button"
size="sm"
variant="destructive"
on:click={() => {
removeField('notifications_on_item_type', i);
}}
>
<Trash2 class="h-4 w-4" />
</Form.Button>
</div>
</div>
</Form.Control>
</Form.ElementField>
{/each}

<div class="flex w-full items-center justify-between gap-2">
<p class="text-sm text-muted-foreground">Add notifications type</p>
<Form.Button
type="button"
size="sm"
variant="outline"
on:click={() => {
addField('notifications_on_item_type');
}}
>
<Plus class="h-4 w-4" />
</Form.Button>
</div>
</ArrayField>
</div>

<div transition:slide>
<ArrayField {form} name="notifications_service_urls" {formData}>
{#each $formData.notifications_service_urls as _, i}
<Form.ElementField {form} name="notifications_service_urls[{i}]">
<Form.Control let:attrs>
<div class="flex items-center gap-2">
<Input
type="text"
spellcheck="false"
autocomplete="false"
{...attrs}
bind:value={$formData.notifications_service_urls[i]}
/>

<div class="flex items-center gap-2">
<Form.Button
type="button"
size="sm"
variant="destructive"
on:click={() => {
removeField('notifications_service_urls', i);
}}
>
<Trash2 class="h-4 w-4" />
</Form.Button>
</div>
</div>
</Form.Control>
</Form.ElementField>
{/each}

<div class="flex w-full items-center justify-between gap-2">
<p class="text-sm text-muted-foreground">Add notification service urls</p>
<Form.Button
type="button"
size="sm"
variant="outline"
on:click={() => {
addField('notifications_service_urls');
}}
>
<Plus class="h-4 w-4" />
</Form.Button>
</div>
</ArrayField>
</div>
{/if}

<Separator class="mt-4" />
<div class="flex w-full justify-end">
<Form.Button disabled={$delayed} type="submit" size="sm" class="w-full lg:max-w-max">
Expand Down
Loading

0 comments on commit ad8a9ba

Please sign in to comment.