Lots of layout changes
This commit is contained in:
@@ -1 +1,8 @@
|
||||
export const trailingSlash = 'never'
|
||||
|
||||
/** @type {import('./$types').PageServerLoad} */
|
||||
export const load = ({ url }) => {
|
||||
return {
|
||||
url: url.pathname,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<script>
|
||||
import '../app.css'
|
||||
import '@fortawesome/fontawesome-free/css/all.min.css'
|
||||
import Navbar from '$lib/components/utility/navbar.svelte'
|
||||
import AlertBox from '$lib/components/utility/alertBox.svelte'
|
||||
import { page } from '$app/stores'
|
||||
import { newestAlert } from '$lib/stores/alertStore.js'
|
||||
import SubLayouts from './subLayouts.svelte'
|
||||
import { newestAlert, backgroundImage } from '$lib/utils/stores.js'
|
||||
import { fade } from 'svelte/transition'
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
export let data
|
||||
|
||||
let alertBox
|
||||
$: addAlert($newestAlert)
|
||||
|
||||
@@ -16,35 +17,27 @@
|
||||
}
|
||||
|
||||
// Might want to change this functionallity to a fetch/preload/await for the image
|
||||
const backgroundImage = 'https://www.gstatic.com/youtube/media/ytm/images/sbg/wsbg@4000x2250.png' // <-- Default youtube music background
|
||||
const ytBg = 'https://www.gstatic.com/youtube/media/ytm/images/sbg/wsbg@4000x2250.png' // <-- Default youtube music background
|
||||
let loaded = false
|
||||
onMount(() => (loaded = true))
|
||||
</script>
|
||||
|
||||
<main class="h-screen font-notoSans text-white">
|
||||
<div class="fixed isolate -z-10 h-full w-full bg-black">
|
||||
<div class="no-scrollbar h-screen font-notoSans text-white">
|
||||
<div class="fixed isolate -z-10 h-full w-screen bg-black">
|
||||
<!-- This whole bg is a complete copy of ytmusic, design own at some point (Place for customization w/ album art etc?) (EDIT: Ok, it looks SICK with album art!) -->
|
||||
<div id="background-gradient" class="absolute z-10 h-1/2 w-full bg-cover" />
|
||||
{#if loaded}
|
||||
<!-- May want to add a small blur filter in the event that the album/song image is below a certain resolution -->
|
||||
<img id="background-image" src={backgroundImage} alt="" class="h-1/2 w-full object-cover blur-xl" in:fade={{ duration: 1000 }} />
|
||||
{#key $backgroundImage}
|
||||
<!-- May want to add a small blur filter in the event that the album/song image is below a certain resolution -->
|
||||
<img id="background-image" src={$backgroundImage ? $backgroundImage : ytBg} alt="" class="absolute h-1/2 w-full object-cover blur-lg" transition:fade={{ duration: 1000 }} />
|
||||
{/key}
|
||||
{/if}
|
||||
</div>
|
||||
{#if $page.url.pathname === '/login'}
|
||||
<slot />
|
||||
{:else}
|
||||
<div class="grid h-full grid-cols-[5rem_auto]">
|
||||
<div class="h-full bg-slate-600" />
|
||||
<div class="grid h-full grid-rows-[4rem_auto] gap-8">
|
||||
<Navbar />
|
||||
<div class="no-scrollbar overflow-y-scroll">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AlertBox bind:this={alertBox} />
|
||||
{/if}
|
||||
</main>
|
||||
<SubLayouts currentPage={data.url}>
|
||||
<slot slot="innerContent" />
|
||||
</SubLayouts>
|
||||
<AlertBox bind:this={alertBox} />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#background-gradient {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { SECRET_INTERNAL_API_KEY } from '$env/static/private'
|
||||
export const prerender = false
|
||||
|
||||
/** @type {import('./$types').PageServerLoad} */
|
||||
export const load = async ({ locals, fetch }) => {
|
||||
export const load = async ({ locals, fetch, url }) => {
|
||||
const recommendationResponse = await fetch(`/api/user/recommendations?userId=${locals.userId}&limit=10`, {
|
||||
headers: {
|
||||
apikey: SECRET_INTERNAL_API_KEY,
|
||||
@@ -13,6 +13,7 @@ export const load = async ({ locals, fetch }) => {
|
||||
const { recommendations, errors } = recommendationsData
|
||||
|
||||
return {
|
||||
url: url.pathname,
|
||||
user: locals.user,
|
||||
recommendations,
|
||||
fetchingErrors: errors,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script>
|
||||
import { onMount } from 'svelte'
|
||||
import { newestAlert } from '$lib/stores/alertStore.js'
|
||||
import { newestAlert } from '$lib/utils/stores.js'
|
||||
import ScrollableCardMenu from '$lib/components/media/scrollableCardMenu.svelte'
|
||||
|
||||
export let data
|
||||
@@ -25,7 +25,7 @@
|
||||
<p class="text-neutral-400">Click the menu in the top left corner and go to Settings > Connections to link to your accounts</p>
|
||||
</main>
|
||||
{:else}
|
||||
<main id="recommendations-wrapper" class="h-screen px-8">
|
||||
<main id="recommendations-wrapper" class="h-[200vh] w-full">
|
||||
<ScrollableCardMenu header={'Listen Again'} cardDataList={data.recommendations} />
|
||||
</main>
|
||||
{/if}
|
||||
|
||||
1
src/routes/library/+page.svelte
Normal file
1
src/routes/library/+page.svelte
Normal file
@@ -0,0 +1 @@
|
||||
<h1>This is where library items will go</h1>
|
||||
@@ -2,7 +2,7 @@
|
||||
import { enhance } from '$app/forms'
|
||||
import { goto } from '$app/navigation'
|
||||
import { fade } from 'svelte/transition'
|
||||
import { newestAlert } from '$lib/stores/alertStore.js'
|
||||
import { newestAlert } from '$lib/utils/stores.js'
|
||||
|
||||
export let data
|
||||
|
||||
@@ -77,11 +77,7 @@
|
||||
Sign In
|
||||
<i class="fa-solid fa-right-to-bracket ml-1" />
|
||||
</button>
|
||||
<button
|
||||
formaction="?/newUser"
|
||||
class="h-12 w-1/3 rounded-md transition-all active:scale-[97%]"
|
||||
style="background-color: {formMode === 'newUser' ? 'var(--lazuli-primary)' : '#262626'};"
|
||||
>
|
||||
<button formaction="?/newUser" class="h-12 w-1/3 rounded-md transition-all active:scale-[97%]" style="background-color: {formMode === 'newUser' ? 'var(--lazuli-primary)' : '#262626'};">
|
||||
Create New User
|
||||
<i class="fa-solid fa-user-plus ml-1" />
|
||||
</button>
|
||||
|
||||
1
src/routes/playlist/+page.svelte
Normal file
1
src/routes/playlist/+page.svelte
Normal file
@@ -0,0 +1 @@
|
||||
<main>Hello this is where playlist go</main>
|
||||
@@ -4,7 +4,7 @@
|
||||
import { JellyfinUtils } from '$lib/utils/utils'
|
||||
import Services from '$lib/services.json'
|
||||
import JellyfinAuthBox from './jellyfinAuthBox.svelte'
|
||||
import { newestAlert } from '$lib/stores/alertStore.js'
|
||||
import { newestAlert } from '$lib/utils/stores.js'
|
||||
import IconButton from '$lib/components/utility/iconButton.svelte'
|
||||
import Toggle from '$lib/components/utility/toggle.svelte'
|
||||
|
||||
|
||||
72
src/routes/subLayouts.svelte
Normal file
72
src/routes/subLayouts.svelte
Normal file
@@ -0,0 +1,72 @@
|
||||
<script>
|
||||
export let currentPage
|
||||
|
||||
import Navbar from '$lib/components/utility/navbar.svelte'
|
||||
import { fly } from 'svelte/transition'
|
||||
|
||||
const contentTabs = {
|
||||
Home: '/',
|
||||
Artists: '/artist',
|
||||
Playlists: '/playlist',
|
||||
Libray: '/library',
|
||||
}
|
||||
|
||||
let previousPage = currentPage
|
||||
let direction = 1
|
||||
$: calculateDirection(currentPage)
|
||||
|
||||
const calculateDirection = (newPage) => {
|
||||
const contentLinks = Object.values(contentTabs)
|
||||
const newPageIndex = contentLinks.indexOf(newPage)
|
||||
const previousPageIndex = contentLinks.indexOf(previousPage)
|
||||
if (newPageIndex > previousPageIndex) {
|
||||
direction = 1
|
||||
} else {
|
||||
direction = -1
|
||||
}
|
||||
previousPage = currentPage
|
||||
}
|
||||
|
||||
let activeTab, indicatorBar, tabList
|
||||
$: calculateBar(activeTab)
|
||||
|
||||
const calculateBar = (activeTab) => {
|
||||
if (activeTab) {
|
||||
const listRect = tabList.getBoundingClientRect()
|
||||
const tabRec = activeTab.getBoundingClientRect()
|
||||
indicatorBar.style.top = `${listRect.height}px`
|
||||
if (direction === 1) {
|
||||
indicatorBar.style.right = `${listRect.right - tabRec.right}px`
|
||||
setTimeout(() => (indicatorBar.style.left = `${tabRec.left - listRect.left}px`), 350)
|
||||
} else {
|
||||
indicatorBar.style.left = `${tabRec.left - listRect.left}px`
|
||||
setTimeout(() => (indicatorBar.style.right = `${listRect.right - tabRec.right}px`), 350)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if Object.values(contentTabs).includes(currentPage)}
|
||||
<Navbar />
|
||||
<div class="flex justify-center py-4">
|
||||
<h1 bind:this={tabList} class="relative flex justify-center gap-12 text-lg">
|
||||
{#each Object.entries(contentTabs) as [header, page]}
|
||||
{#if currentPage === page}
|
||||
<span bind:this={activeTab} class="pointer-events-none">{header}</span>
|
||||
{:else}
|
||||
<a class="text-neutral-400 hover:text-lazuli-primary" href={page}>{header}</a>
|
||||
{/if}
|
||||
{/each}
|
||||
<div bind:this={indicatorBar} class="absolute h-0.5 bg-lazuli-primary transition-all duration-300 ease-in-out" />
|
||||
</h1>
|
||||
</div>
|
||||
<div class="overflow-x-hidden px-8 sm:px-32">
|
||||
{#key previousPage}
|
||||
<div in:fly={{ x: 200 * direction, duration: 300, delay: 300 }} out:fly={{ x: -200 * direction, duration: 300 }}>
|
||||
<slot name="innerContent" />
|
||||
</div>
|
||||
{/key}
|
||||
</div>
|
||||
{:else}
|
||||
<slot name="innerContent" />
|
||||
{/if}
|
||||
Reference in New Issue
Block a user