Skip to content

Commit

Permalink
feat: search component and browse rework
Browse files Browse the repository at this point in the history
chore: improve nprogress coloring
refactor: use strong typing where logic implemented
chore: add shadcn-svelte components
  • Loading branch information
Gaisberg authored and Gaisberg committed Oct 26, 2024
1 parent a4ec921 commit c118a4d
Show file tree
Hide file tree
Showing 25 changed files with 796 additions and 475 deletions.
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,29 @@
"@sveltejs/adapter-node": "^5.0.1",
"@sveltejs/kit": "^2.5.10",
"@sveltejs/vite-plugin-svelte": "^3.1.1",
"@tailwindcss/typography": "^0.5.13",
"@tailwindcss/typography": "^0.5.14",
"@types/eslint": "^8.56.10",
"@types/luxon": "^3.4.2",
"@types/nprogress": "^0.2.3",
"@types/uuid": "^9.0.8",
"@types/ws": "^8.5.12",
"autoprefixer": "^10.4.19",
"autoprefixer": "^10.4.20",
"bits-ui": "^0.21.16",
"clsx": "^2.1.1",
"eslint": "^9.4.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.39.0",
"globals": "^15.4.0",
"postcss": "^8.4.38",
"prettier": "^3.3.1",
"prettier-plugin-svelte": "^3.2.4",
"prettier-plugin-tailwindcss": "^0.5.14",
"prettier-plugin-tailwindcss": "^0.6.5",
"svelte": "^4.2.19",
"svelte-check": "^3.8.0",
"sveltekit-sse": "^0.13.5",
"tailwindcss": "^3.4.4",
"tailwind-merge": "^2.5.4",
"tailwind-variants": "^0.2.1",
"tailwindcss": "^3.4.9",
"tslib": "^2.6.3",
"typescript": "^5.4.5",
"typescript-eslint": "8.0.0-alpha.28",
Expand All @@ -47,8 +51,6 @@
"type": "module",
"dependencies": {
"@hey-api/client-fetch": "^0.4.0",
"bits-ui": "^0.21.10",
"clsx": "^2.1.1",
"cmdk-sv": "^0.0.17",
"embla-carousel-autoplay": "^8.1.5",
"embla-carousel-svelte": "^8.1.5",
Expand All @@ -60,8 +62,6 @@
"nprogress": "^0.2.0",
"svelte-sonner": "^0.3.24",
"sveltekit-superforms": "^2.14.0",
"tailwind-merge": "^2.3.0",
"tailwind-variants": "^0.2.1",
"uuid": "^9.0.1",
"vaul-svelte": "^0.3.2",
"ws": "^8.18.0",
Expand Down
43 changes: 23 additions & 20 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@
}
}

.no-scrollbar::-webkit-scrollbar {
*::-webkit-scrollbar {
display: none;
}

* {
-ms-overflow-style: none;
scrollbar-width: none;
}
150 changes: 123 additions & 27 deletions src/lib/components/header.svelte
Original file line number Diff line number Diff line change
@@ -1,44 +1,72 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { goto } from '$app/navigation';
import { browser } from '$app/environment';
import { getContext } from 'svelte';
import type { Writable } from 'svelte/store';
import type { NavItem } from '$lib/types';
import { Mountain, MoreHorizontal, Search, Film } from 'lucide-svelte';
import ThemeSwitcher from '$lib/components/theme-switcher.svelte';
import NavigationItem from '$lib/components/header-item.svelte';
import { Mountain, MoreHorizontal } from 'lucide-svelte';
import { Button } from '$lib/components/ui/button';
import { Input } from '$lib/components/ui/input';
import * as Drawer from '$lib/components/ui/drawer';
import { getContext } from 'svelte';
import { type Writable } from 'svelte/store';
import { goto } from '$app/navigation';
import { onMount, onDestroy } from 'svelte';
import { browser } from '$app/environment';
import * as Dialog from '$lib/components/ui/dialog';
import { searchContent, searchTMDB } from '$lib/utils/search';
const navItems: NavItem[] = [
{
name: 'Home',
path: '/'
},
{
name: 'Browse',
path: '/browse'
},
{
name: 'Summary',
path: '/summary'
},
{
name: 'Library',
path: '/library'
},
{
name: 'Settings',
path: '/settings'
}
{ name: 'Home', path: '/' },
{ name: 'Browse', path: '/browse' },
{ name: 'Summary', path: '/summary' },
{ name: 'Settings', path: '/settings' }
];
let showMenu: Writable<boolean> = getContext('showMenu');
let searchQuery = '';
let searchResults: Array<{
title: string;
path: string;
media_type: string;
excerpt: string;
type: 'component' | 'media' | 'action';
posterPath?: string;
}> = [];
let isSearchOpen = false;
async function handleSearch() {
if (searchQuery.trim() === '') {
searchResults = [];
return;
}
try {
searchResults = await searchContent(searchQuery);
} catch {
searchResults = [];
}
}
async function handleMediaSearch() {
try {
const tmdbResults = await searchTMDB(searchQuery);
searchResults = [...tmdbResults];
} catch {
//pass
}
}
function handleResultClick(result: (typeof searchResults)[number]) {
if (result.type === 'action') {
handleMediaSearch();
} else {
goto(result.path);
isSearchOpen = false;
}
}
let applyBackdropBlur = () => {};
onMount(async () => {
onMount(() => {
const header = document.getElementById('header');
applyBackdropBlur = () => {
Expand Down Expand Up @@ -83,9 +111,17 @@
<NavigationItem {navItem} />
{/each}
</div>
<Button variant="ghost" size="icon" on:click={() => (isSearchOpen = true)}>
<Search class="h-5 w-5" />
<span class="sr-only">Search</span>
</Button>
<ThemeSwitcher />
</nav>
<nav class="flex items-center gap-2 tracking-wider md:hidden">
<Button variant="ghost" size="icon" on:click={() => (isSearchOpen = true)}>
<Search class="h-5 w-5" />
<span class="sr-only">Search</span>
</Button>
<ThemeSwitcher />
<Drawer.Root
onClose={() => {
Expand Down Expand Up @@ -119,3 +155,63 @@
</Drawer.Root>
</nav>
</header>

<Dialog.Root bind:open={isSearchOpen}>
<Dialog.Content class="p-0 sm:max-w-[600px] [&>button]:hidden">
<div class="border-b p-4">
<div class="flex items-center">
<Input
type="text"
placeholder="Search..."
bind:value={searchQuery}
on:input={handleSearch}
class="flex-grow"
/>
</div>
</div>
{#if searchResults.length > 0}
<div class="max-h-[400px] overflow-y-auto p-4">
<ul class="space-y-4">
{#each searchResults as result}
<li>
<button
class="block w-full rounded p-2 text-left hover:bg-muted"
on:click={() => handleResultClick(result)}
>
<div class="flex items-start">
{#if result.type === 'media' && result.posterPath}
<img
src={result.posterPath}
alt={result.title}
class="mr-4 h-24 w-16 rounded object-cover"
/>
{:else if result.type === 'media'}
<div class="mr-4 flex h-24 w-16 items-center justify-center rounded bg-muted">
<Film class="h-8 w-8" />
</div>
{/if}
<div class="flex-1">
<div class="font-medium">{result.title}</div>
<div class="text-sm text-muted-foreground">{result.excerpt}</div>
<div class="test-secondary">
{result.media_type}
</div>
</div>
</div>
</button>
</li>
{/each}
</ul>
</div>
{:else if searchQuery.trim() !== ''}
<p class="text-center text-sm text-muted-foreground">No results found</p>
{/if}
</Dialog.Content>
</Dialog.Root>

<style>
:global(.backdrop) {
backdrop-filter: blur(4px);
background-color: rgba(0, 0, 0, 0.5);
}
</style>
3 changes: 0 additions & 3 deletions src/lib/components/home-items.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
</div>
<h2 class="text-xl font-medium md:text-2xl">Trending {name}</h2>
</div>
<a href="/movies" class="flex items-center gap-2 text-sm text-primary-foreground">
<MoveUpRight class="size-4" />
</a>
</div>

<div class="no-scrollbar flex flex-wrap overflow-x-auto px-1 lg:p-0">
Expand Down
16 changes: 9 additions & 7 deletions src/lib/components/item-request.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@
async function checkItemExists(id: number) {
try {
const externalIds = await getExternalID(fetch, type, id);
const response = await ItemsService.getItems({
query: {
search: externalIds.imdb_id
}
});
if (externalIds.imdb_id) {
const response = await ItemsService.getItems({
query: {
search: externalIds.imdb_id
}
});
if (response.data && response.data.items.length > 0) {
isInLibrary = true;
if (response.data && response.data.items.length > 0) {
isInLibrary = true;
}
}
} catch {
//pass
Expand Down
Loading

0 comments on commit c118a4d

Please sign in to comment.