Files
flotilla/src/app/components/PrimaryNav.svelte
2024-08-14 13:38:55 -07:00

92 lines
3.2 KiB
Svelte

<style>
.z-nav-active {
-webkit-mask-image: url("/nav-active.svg");
mask-image: url("/nav-active.svg");
}
</style>
<script lang="ts">
import {page} from "$app/stores"
import {goto} from '$app/navigation'
import {derived} from 'svelte/store'
import {tweened} from 'svelte/motion'
import {quintOut} from 'svelte/easing'
import {identity, nth} from '@welshman/lib'
import Icon from "@lib/components/Icon.svelte"
import PrimaryNavItem from "@lib/components/PrimaryNavItem.svelte"
import SpaceAdd from '@app/components/SpaceAdd.svelte'
import {session} from "@app/base"
import {userProfile, userGroupsByNom, makeGroupId, loadGroup, deriveProfile, qualifiedGroupsById, splitGroupId} from "@app/state"
import {pushModal} from "@app/modal"
import {getPrimaryNavItemIndex} from "@app/routes"
const activeOffset = tweened(-44, {
duration: 300,
easing: quintOut
})
const addSpace = () => pushModal(SpaceAdd)
const gotoHome = () => goto("/home")
const gotoSpaces = () => goto("/spaces")
const gotoSpace = (nom: string) => goto(`/spaces/${nom}`)
const gotoSettings = () => goto("/settings")
let element: HTMLElement
// Set the active highlight element to the offset of the nav item we're focused on
$: {
if (element) {
const index = getPrimaryNavItemIndex($page)
const navItems: any = Array.from(element.querySelectorAll('.z-nav-item') || [])
activeOffset.set(navItems[index].offsetTop - 44)
}
}
</script>
<div class="relative w-14 bg-base-100" bind:this={element}>
<div class="absolute z-nav-active ml-2 h-[144px] w-12 bg-base-300" style={`top: ${$activeOffset}px`} />
<div class="flex h-full flex-col justify-between">
<div>
<PrimaryNavItem title={$userProfile?.name} on:click={gotoHome}>
<div class="!flex w-10 items-center justify-center rounded-full border border-solid border-base-300">
{#if $userProfile?.picture}
<img alt="" src={$userProfile.picture} />
{:else}
<Icon icon="user-rounded" size={7} />
{/if}
</div>
</PrimaryNavItem>
{#each $userGroupsByNom.entries() as [nom, qualifiedGroups] (nom)}
{@const qualifiedGroup = qualifiedGroups[0]}
<PrimaryNavItem title={qualifiedGroup?.group.name} on:click={() => gotoSpace(nom)}>
<div class="w-10 rounded-full border border-solid border-base-300">
<img alt={qualifiedGroup?.group.name} src={qualifiedGroup?.group.picture} />
</div>
</PrimaryNavItem>
{/each}
<PrimaryNavItem title="Add Space" on:click={addSpace}>
<div class="!flex w-10 items-center justify-center">
<Icon size={7} icon="add-circle" />
</div>
</PrimaryNavItem>
<PrimaryNavItem title="Browse Spaces" on:click={gotoSpaces}>
<div class="!flex w-10 items-center justify-center">
<Icon size={6} icon="compass-big" />
</div>
</PrimaryNavItem>
</div>
<div>
<PrimaryNavItem title="Settings" on:click={gotoSettings}>
<div class="!flex w-10 items-center justify-center">
<Icon size={7} icon="settings" />
</div>
</PrimaryNavItem>
</div>
</div>
</div>