Movie search done

This commit is contained in:
Aleksi Lassila
2023-06-15 14:39:21 +03:00
parent e41b030d45
commit fe422a72b6
14 changed files with 178 additions and 19 deletions

1
src/lib/constants.ts Normal file
View File

@@ -0,0 +1 @@
export const TMDB_IMAGES = 'https://www.themoviedb.org/t/p/original';

View File

@@ -179,3 +179,28 @@ export interface Poster {
vote_count: number;
width: number;
}
export interface MultiSearchResponse {
page: number;
results: MultiSearchResult[];
total_pages: number;
total_results: number;
}
export interface MultiSearchResult {
adult: boolean;
backdrop_path?: string;
id: number;
title: string;
original_language: string;
original_title: string;
overview: string;
poster_path?: string;
media_type: string;
genre_ids: number[];
popularity: number;
release_date: string;
video: boolean;
vote_average: number;
vote_count: number;
}

View File

@@ -1,7 +1,7 @@
<script>
import '../app.css';
import { setClient } from 'svelte-apollo';
import Navbar from './components/Navbar.svelte';
import Navbar from './components/Navbar/Navbar.svelte';
</script>
<div class="app">

View File

@@ -3,6 +3,7 @@
import type { PageData } from './$types';
import ResourceDetails from './components/ResourceDetails/ResourceDetails.svelte';
import ResourceDetailsControls from './ResourceDetailsControls.svelte';
import { TMDB_IMAGES } from '$lib/constants';
export let data: PageData;
let movies = data.showcases;
@@ -18,9 +19,7 @@
{:else}
<div
class="bg-cover bg-center"
style={"background-image: url('https://www.themoviedb.org/t/p/original/" +
movie.backdrop_path +
"')"}
style={"background-image: url('" + TMDB_IMAGES + movie.backdrop_path + "')"}
>
<div class="p-8 flex flex-col gap-6 backdrop-blur-xl bg-[#000000dd]">
<h1 class="uppercase tracking-widest font-bold">Continue Watching</h1>

View File

@@ -0,0 +1,3 @@
<div class="text-zinc-300 hover:text-zinc-50 cursor-pointer p-1" on:click>
<slot />
</div>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import classNames from 'classnames';
import { createEventDispatcher } from 'svelte';
const dispatcher = createEventDispatcher();
export let visible = false;
export let close: () => void;
</script>
<div
class={classNames('fixed inset-0 bg-[#00000088] justify-center items-center z-20', {
hidden: !visible,
flex: visible
})}
on:click|self={close}
>
<slot />
</div>

View File

@@ -0,0 +1,9 @@
<!--<script lang="ts">-->
<!-- export let close: () => void;-->
<!--</script>-->
<div
class="max-w-3xl self-start mt-[10vh] bg-[#33333388] backdrop-blur-xl rounded overflow-hidden flex flex-col flex-1 mx-4 sm:mx-16 lg:mx-24 drop-shadow-xl"
>
<slot />
</div>

View File

@@ -2,11 +2,15 @@
import { MagnifyingGlass, Person } from 'radix-icons-svelte';
import classNames from 'classnames';
import { page } from '$app/stores';
import TitleSearchModal from './TitleSearchModal.svelte';
import IconButton from '../IconButton.svelte';
let y = 0;
let transparent = true;
let baseStyle = '';
let isSearchVisible = false;
function getLinkStyle(path) {
return $page.url.pathname === path ? 'text-amber-200' : 'hover:text-zinc-50 cursor-pointer';
}
@@ -40,12 +44,14 @@
<a href="/sources" class={$page && getLinkStyle('/sources')}>Sources</a>
<a href="/settings" class={$page && getLinkStyle('/settings')}>Settings</a>
</div>
<div class="flex gap-2">
<div class="p-2 cursor-pointer text-zinc-200 hover:text-zinc-50">
<div class="flex gap-2 items-center">
<IconButton on:click={() => (isSearchVisible = true)}>
<MagnifyingGlass size="20" />
</div>
<div class="p-2 cursor-pointer text-zinc-200 hover:text-zinc-50">
</IconButton>
<IconButton>
<Person size="20" />
</div>
</IconButton>
</div>
</div>
<TitleSearchModal bind:visible={isSearchVisible} />

View File

@@ -0,0 +1,97 @@
<script lang="ts">
import Modal from '../Modal/Modal.svelte';
import ModalContent from '../Modal/ModalContent.svelte';
import { Cross1, Cross2, MagnifyingGlass } from 'radix-icons-svelte';
import IconButton from '../IconButton.svelte';
import { TmdbApi } from '$lib/tmdb-api';
import type { MultiSearchResponse } from '$lib/tmdb-api';
import { TMDB_IMAGES } from '$lib/constants';
import { onMount } from 'svelte';
export let visible = false;
let searchValue = '';
export let close = () => {
visible = false;
searchValue = '';
fetching = false;
results = null;
if (timeout) clearTimeout(timeout);
timeout = undefined;
};
let timeout;
let fetching = false;
let results: MultiSearchResponse['results'] | null = null;
const searchTimeout = () => {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
searchMovie(searchValue);
}, 700);
};
const searchMovie = (query: string) => {
fetching = true;
TmdbApi.get<MultiSearchResponse>('/search/movie', {
params: {
query
}
})
.then((res) => {
if (res.data) results = res.data.results;
})
.finally(() => (fetching = false));
};
onMount(() => {
searchValue = 'incepti';
searchMovie('incepti');
});
$: console.log(results);
</script>
<Modal {visible} {close}>
<ModalContent {close}>
<div class="flex text-zinc-200 items-center p-3 px-5 gap-4 border-b border-zinc-700">
<MagnifyingGlass size="20" class="text-zinc-400" />
<input
bind:value={searchValue}
on:input={searchTimeout}
type="text"
class="flex-1 bg-transparent font-light outline-none"
placeholder="Search for Movies and Shows..."
/>
<IconButton on:click={close}>
<Cross2 size="20" />
</IconButton>
</div>
{#if !results || searchValue === ''}
<div class="text-sm text-zinc-200 opacity-50 font-light p-4">No recent searches</div>
{:else if results?.length === 0 && !fetching}
<div class="text-sm text-zinc-200 opacity-50 font-light p-4">No search results</div>
{:else}
<div class="py-2">
{#each results.filter((m) => m).slice(0, 5) as result}
<div
class="flex px-4 py-2 gap-4 hover:bg-highlight-dim cursor-pointer"
on:click={() => window.open('/movie/' + result.id)}
>
<div
style={"background-image: url('" + TMDB_IMAGES + result.poster_path + "');"}
class="bg-center bg-cover w-16 h-24 rounded-sm"
/>
<div class="flex-1 flex flex-col gap-1">
<div class="flex gap-2">
<div class="font-normal tracking-wide">{result.original_title}</div>
<div class="text-zinc-400">
{new Date(result.release_date).getFullYear()}
</div>
</div>
<div class="text-sm text-zinc-300 line-clamp-3">{result.overview}</div>
</div>
</div>
{/each}
</div>
{/if}
</ModalContent>
</Modal>

View File

@@ -4,6 +4,7 @@
import { onMount } from 'svelte';
import classNames from 'classnames';
import { fade } from 'svelte/transition';
import { TMDB_IMAGES } from '$lib/constants';
export let resource: MovieResource;
export let trailer = true;
@@ -62,9 +63,7 @@
<div
class="h-screen w-screen bg-center bg-cover relative overflow-hidden"
style={"background-image: url('https://www.themoviedb.org/t/p/original" +
remoteResource.backdrop_path +
"')"}
style={"background-image: url('" + TMDB_IMAGES + remoteResource.backdrop_path + "')"}
>
<div class="youtube-container absolute h-full scale-[150%] hidden sm:block">
{#if video.key}

View File

@@ -2,6 +2,7 @@
import type { TmdbMovieFull } from '$lib/tmdb-api';
import { formatGenres, getRuntime } from '$lib/utils';
import classNames from 'classnames';
import { TMDB_IMAGES } from '$lib/constants';
export let tmdbMovie: TmdbMovieFull;
@@ -14,8 +15,7 @@
}
const backdropUrl =
'https://www.themoviedb.org/t/p/original' +
tmdbMovie.images.backdrops.filter((b) => b.iso_639_1 === 'en')[0].file_path;
TMDB_IMAGES + tmdbMovie.images.backdrops.filter((b) => b.iso_639_1 === 'en')[0].file_path;
</script>
<div

View File

@@ -1,6 +1,7 @@
<script lang="ts">
import { TmdbApi } from '$lib/tmdb-api';
import { onMount } from 'svelte';
import { TMDB_IMAGES } from '$lib/constants';
export let tmdbId;
export let progress = 0;
@@ -16,7 +17,7 @@
TmdbApi.get('/' + type + '/' + tmdbId)
.then((res) => res.data)
.then((data: any) => {
bg = 'https://www.themoviedb.org/t/p/original/' + data.poster_path;
bg = TMDB_IMAGES + data.poster_path;
title = data.title;
});
});

View File

@@ -2,6 +2,7 @@
import type { PageData } from './$types';
import SmallHorizontalPoster from '../components/SmallHorizontalPoster/SmallHorizontalPoster.svelte';
import type { TmdbMovieFull } from '$lib/tmdb-api';
import { TMDB_IMAGES } from '$lib/constants.js';
export let data: PageData;
console.log(data);
@@ -25,9 +26,7 @@
const headerStyle = 'uppercase tracking-widest font-bold text-center mt-2';
</script>
<div
style="background-image: url('https://www.themoviedb.org/t/p/original/vvjYv7bSWerbsi0LsMjLnTVOX7c.jpg')"
>
<div style={"background-image: url('" + TMDB_IMAGES + "/vvjYv7bSWerbsi0LsMjLnTVOX7c.jpg')"}>
<div class="py-24 backdrop-blur-2xl bg-darken px-8 flex flex-col gap-4">
<!-- Contains all the titles available locally, the ones already watched previously (greyed out at the-->
<!-- bottom), and the ones that are in some sort of watchlist and not available via any source.-->

View File

@@ -8,7 +8,8 @@ export default {
display: ['Inter', 'system', 'sans-serif']
},
colors: {
darken: '#070501bf'
darken: '#070501bf',
'highlight-dim': '#fde68a20'
}
}
},