Merge pull request #23 from WardPearce/update/ui-routes
Update/UI routes
@@ -26,6 +26,7 @@
|
||||
- Audio only mode.
|
||||
- Playlists.
|
||||
- PWA support.
|
||||
- YT path redirects (So your redirect plugins should still work!)
|
||||
|
||||
# Todo
|
||||
- Localization.
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"@types/human-number": "^1.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
||||
"@typescript-eslint/parser": "^7.0.0",
|
||||
"@vite-pwa/sveltekit": "^0.4.0",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-svelte": "^2.35.1",
|
||||
@@ -30,8 +31,7 @@
|
||||
"svelte-check": "^3.6.0",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^5.0.3",
|
||||
"vite-plugin-pwa": "^0.19.7"
|
||||
"vite": "^5.0.3"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
<link rel="stylesheet" href="%sveltekit.assets%/style.css">
|
||||
<meta name="description" content="Modern material design for Invidious.">
|
||||
<meta name="keywords" content="invidious,materialious,proxy,youtube,yt,theme,interface,modern">
|
||||
<meta name="theme-color" content="#141316">
|
||||
<title>Materialious</title>
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
|
||||
<body data-sveltekit-preload-data="hover" style="background-color: rgb(20, 19, 22)">
|
||||
<body data-sveltekit-preload-data="hover" style="background-color: #141316">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export function numberWithCommas(number: number) {
|
||||
}
|
||||
|
||||
export function cleanNumber(number: number): string {
|
||||
return humanNumber(number, (number: number) => Number.parseFloat(number.toString()).toFixed(1));
|
||||
return humanNumber(number, (number: number) => Number.parseFloat(number.toString()).toFixed(1)).replace('.0', '');
|
||||
}
|
||||
|
||||
export function videoLength(lengthSeconds: number): string {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import 'material-dynamic-colors';
|
||||
import { onMount } from 'svelte';
|
||||
import { get } from 'svelte/store';
|
||||
import { pwaInfo } from 'virtual:pwa-info';
|
||||
import {
|
||||
activePage,
|
||||
auth,
|
||||
@@ -189,8 +190,14 @@
|
||||
loadNotifications().catch(() => auth.set(null));
|
||||
}
|
||||
});
|
||||
|
||||
$: webManifestLink = pwaInfo ? pwaInfo.webManifest.linkTag : '';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
{@html webManifestLink}
|
||||
</svelte:head>
|
||||
|
||||
<nav class="left m l small">
|
||||
<header></header>
|
||||
{#each pages as page}
|
||||
@@ -225,18 +232,29 @@
|
||||
class="button circle large transparent"
|
||||
>
|
||||
<i>code</i>
|
||||
<div class="tooltip bottom">Star us on Github!</div>
|
||||
</a>
|
||||
{#if isLoggedIn}
|
||||
<button class="circle large transparent" data-ui="#dialog-notifications"
|
||||
><i>notifications</i></button
|
||||
>
|
||||
><i>notifications</i>
|
||||
<div class="tooltip bottom">Notifications</div>
|
||||
</button>
|
||||
{/if}
|
||||
<button class="circle large transparent" data-ui="#dialog-settings"><i>settings</i></button>
|
||||
<button class="circle large transparent" data-ui="#dialog-settings">
|
||||
<i>settings</i>
|
||||
<div class="tooltip bottom">Settings</div>
|
||||
</button>
|
||||
|
||||
{#if !isLoggedIn}
|
||||
<button on:click={login} class="circle large transparent"><i>login</i></button>
|
||||
<button on:click={login} class="circle large transparent">
|
||||
<i>login</i>
|
||||
<div class="tooltip bottom">Login</div>
|
||||
</button>
|
||||
{:else}
|
||||
<button on:click={logout} class="circle large transparent"><i>logout</i></button>
|
||||
<button on:click={logout} class="circle large transparent">
|
||||
<i>logout</i>
|
||||
<div class="tooltip bottom">Logout</div>
|
||||
</button>
|
||||
{/if}
|
||||
</nav>
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import { error } from '@sveltejs/kit';
|
||||
|
||||
export async function load({ url }) {
|
||||
const playlistId = url.searchParams.get('list');
|
||||
if (playlistId) {
|
||||
goto(`/playlist/${playlistId}`);
|
||||
} else {
|
||||
error(404);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import { error } from '@sveltejs/kit';
|
||||
|
||||
export async function load({ url }) {
|
||||
const videoId = url.searchParams.get('v');
|
||||
const playlistId = url.searchParams.get('list');
|
||||
if (videoId) {
|
||||
let goToUrl = `/watch/${videoId}`;
|
||||
|
||||
if (playlistId) {
|
||||
goToUrl += `?playlist=${playlistId}`;
|
||||
}
|
||||
goto(goToUrl);
|
||||
} else {
|
||||
error(404);
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
import { cleanNumber, numberWithCommas } from '$lib/misc.js';
|
||||
import { onMount } from 'svelte';
|
||||
import { get } from 'svelte/store';
|
||||
import { activePage, playerListenByDefault } from '../../../store.js';
|
||||
import { activePage, auth, playerListenByDefault } from '../../../store.js';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -106,17 +106,24 @@
|
||||
</div>
|
||||
</nav>
|
||||
</a>
|
||||
<button
|
||||
on:click={toggleSubscribed}
|
||||
class:inverse-surface={!data.subscribed}
|
||||
class:border={data.subscribed}
|
||||
>
|
||||
{#if !data.subscribed}
|
||||
{#if $auth}
|
||||
<button
|
||||
on:click={toggleSubscribed}
|
||||
class:inverse-surface={!data.subscribed}
|
||||
class:border={data.subscribed}
|
||||
>
|
||||
{#if !data.subscribed}
|
||||
Subscribe
|
||||
{:else}
|
||||
Unsubscribe
|
||||
{/if}
|
||||
</button>
|
||||
{:else}
|
||||
<button class="inverse-surface" disabled>
|
||||
Subscribe
|
||||
{:else}
|
||||
Unsubscribe
|
||||
{/if}
|
||||
</button>
|
||||
<div class="tooltip">Login required</div>
|
||||
</button>
|
||||
{/if}
|
||||
</nav>
|
||||
</div>
|
||||
<div class="s12 m12 l4 video-actions">
|
||||
@@ -194,7 +201,13 @@
|
||||
<button disabled class="border no-margin">
|
||||
<i>add</i>
|
||||
<span>Playlist</span>
|
||||
<div class="tooltip">Login required</div>
|
||||
<div class="tooltip">
|
||||
{#if $auth}
|
||||
No playlists
|
||||
{:else}
|
||||
Login required
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 665 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 680 B |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 889 B |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 744 B |
|
After Width: | Height: | Size: 1018 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 744 B |
|
After Width: | Height: | Size: 1018 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.6 KiB |