Added login, home page & more

This commit is contained in:
WardPearce
2024-03-09 20:20:01 +13:00
parent dd14a18eaa
commit 651bfae924
9 changed files with 131 additions and 8 deletions
+22
View File
@@ -9,6 +9,8 @@
"version": "0.0.1",
"dependencies": {
"beercss": "^3.5.1",
"event-source-polyfill": "^1.0.31",
"eventsource": "^2.0.2",
"human-number": "^2.0.4",
"plyr": "^3.7.8",
"svelte-persisted-store": "^0.9.1"
@@ -18,6 +20,7 @@
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@types/eslint": "^8.56.0",
"@types/event-source-polyfill": "^1.0.5",
"@types/human-number": "^1.0.2",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
@@ -928,6 +931,12 @@
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
},
"node_modules/@types/event-source-polyfill": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/event-source-polyfill/-/event-source-polyfill-1.0.5.tgz",
"integrity": "sha512-iaiDuDI2aIFft7XkcwMzDWLqo7LVDixd2sR6B4wxJut9xcp/Ev9bO4EFg4rm6S9QxATLBj5OPxdeocgmhjwKaw==",
"dev": true
},
"node_modules/@types/human-number": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/human-number/-/human-number-1.0.2.tgz",
@@ -1953,6 +1962,19 @@
"node": ">=0.10.0"
}
},
"node_modules/event-source-polyfill": {
"version": "1.0.31",
"resolved": "https://registry.npmjs.org/event-source-polyfill/-/event-source-polyfill-1.0.31.tgz",
"integrity": "sha512-4IJSItgS/41IxN5UVAVuAyczwZF7ZIEsM1XAoUzIHA6A+xzusEZUutdXz2Nr+MQPLxfTiCvqE79/C8HT8fKFvA=="
},
"node_modules/eventsource": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz",
"integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+3
View File
@@ -16,6 +16,7 @@
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@types/eslint": "^8.56.0",
"@types/event-source-polyfill": "^1.0.5",
"@types/human-number": "^1.0.2",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
@@ -33,6 +34,8 @@
"type": "module",
"dependencies": {
"beercss": "^3.5.1",
"event-source-polyfill": "^1.0.31",
"eventsource": "^2.0.2",
"human-number": "^2.0.4",
"plyr": "^3.7.8",
"svelte-persisted-store": "^0.9.1"
+5
View File
@@ -11,6 +11,11 @@ export async function getTrending(): Promise<Video[]> {
return await resp.json();
}
export async function getPopular(): Promise<Video[]> {
const resp = await fetch(buildPath('popular'));
return await resp.json();
}
export async function getVideo(videoId: string): Promise<VideoPlay> {
const resp = await fetch(buildPath(`videos/${videoId}`));
return await resp.json();
+54 -5
View File
@@ -1,12 +1,14 @@
<script lang="ts">
import { getSearchSuggestions } from '$lib/Api/index';
import { buildPath, getSearchSuggestions } from '$lib/Api/index';
import Logo from '$lib/Logo.svelte';
import 'beercss';
import { EventSourcePolyfill } from 'event-source-polyfill';
import 'material-dynamic-colors';
import { onMount } from 'svelte';
import { get } from 'svelte/store';
import {
activePage,
auth,
darkMode,
interfaceSearchSuggestions,
playerAlwaysLoop,
@@ -46,10 +48,19 @@
clearTimeout(debounceTimer);
debounceTimer = setTimeout(async () => {
if (event.target.value === '') {
suggestionsForSearch = [];
return;
}
suggestionsForSearch = (await getSearchSuggestions(event.target.value)).suggestions;
}, 250);
};
let isLoggedIn = false;
auth.subscribe((value) => {
isLoggedIn = value !== null;
});
const pages = [
{
icon: 'home',
@@ -105,6 +116,21 @@
}
});
function login() {
const path = new URL(`${import.meta.env.VITE_DEFAULT_INVIDIOUS_INSTANCE}/authorize_token`);
path.search = new URLSearchParams({
scopes: 'scopes=:feed,:subscriptions*,:playlists*,:history*',
callback_url: `${import.meta.env.VITE_DEFAULT_FRONTEND_URL}/auth`,
expire: '2629800'
}).toString();
document.location.href = path.toString();
}
function logout() {
auth.set(null);
}
onMount(async () => {
const isDark = get(darkMode);
@@ -128,6 +154,14 @@
if (themeHex) {
await ui('theme', themeHex);
}
if (isLoggedIn) {
const notifications = new EventSourcePolyfill(buildPath('auth/notifications?topics=ucid'), {
headers: { Authentication: `Bearer ${get(auth)?.token}` },
withCredentials: true
});
notifications.addEventListener('notice', (event) => console.log(event));
}
});
</script>
@@ -142,7 +176,7 @@
</nav>
<nav class="top">
<button class="circle large transparent s m l small-margin" data-ui="#dialog-expanded"
<button class="circle large transparent s m l small-margin" data-ui="#dia1-expanded"
><i>menu</i></button
>
@@ -171,11 +205,26 @@
{/if}
</div>
<div class="max"></div>
<button class="circle large transparent" data-ui="#dialog-notifications"
><i>notifications</i></button
<a
href="https://github.com/WardPearce/Materialious"
target="_blank"
rel="noopener noreferrer"
class="button circle large transparent"
>
<i>code</i>
</a>
{#if isLoggedIn}
<button class="circle large transparent" data-ui="#dialog-notifications"
><i>notifications</i></button
>
{/if}
<button class="circle large transparent" data-ui="#dialog-settings"><i>settings</i></button>
<button class="circle large transparent"><i>login</i></button>
{#if !isLoggedIn}
<button on:click={login} class="circle large transparent"><i>login</i></button>
{:else}
<button on:click={logout} class="circle large transparent"><i>logout</i></button>
{/if}
</nav>
<dialog class="right" id="dialog-settings">
+20 -1
View File
@@ -1,5 +1,24 @@
<script lang="ts">
import { activePage } from '../store';
import PageLoading from '$lib/PageLoading.svelte';
import Thumbnail from '$lib/Thumbnail.svelte';
import { activePage } from '../store.js';
export let data;
activePage.set('home');
</script>
{#if data}
<div class="page right active">
<div class="space"></div>
<div class="grid">
{#each data.popular as video}
<div class="s12 m6 l2">
<Thumbnail {video} />
</div>
{/each}
</div>
</div>
{:else}
<PageLoading />
{/if}
+7
View File
@@ -0,0 +1,7 @@
import { getPopular } from '$lib/Api/index.js';
export async function load({ params }) {
return {
popular: await getPopular()
};
}
+18
View File
@@ -0,0 +1,18 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import PageLoading from '$lib/PageLoading.svelte';
import { onMount } from 'svelte';
import { auth } from '../../store';
onMount(() => {
auth.set({
username: $page.url.searchParams.get('username') as string,
token: $page.url.searchParams.get('token') as string
});
goto('/');
});
</script>
<PageLoading />
+2 -2
View File
@@ -8,7 +8,7 @@ export const themeColor: Writable<null | string> = persisted("themeColor", null)
export const activePage: Writable<string | null> = writable("home");
export const playerAutoPlay = persisted("autoPlay", false);
export const playerAutoPlay = persisted("autoPlay", true);
export const playerAlwaysLoop = persisted("alwaysLoop", false);
export const playerProxyVideos = persisted("proxyVideos", false);
export const playerListenByDefault = persisted("listenByDefault", false);
@@ -17,4 +17,4 @@ export const playerDash = persisted("dash", true);
export const interfaceSearchSuggestions = persisted("searchSuggestions", true);
export const authToken = persisted("authToken", "");
export const auth: Writable<null | { username: string, token: string; }> = persisted("authToken", null);