Add feed sidebar

This commit is contained in:
Jon Staab 2024-05-06 10:26:43 -07:00
parent 54663d8062
commit b0107bf89b
6 changed files with 60 additions and 28 deletions

View File

@ -1,4 +1,7 @@
<script lang="ts"> <script lang="ts">
import cx from 'classnames'
import {equals} from 'ramda'
import {fly} from 'src/util/transition'
import {toggleTheme, theme} from "src/partials/state" import {toggleTheme, theme} from "src/partials/state"
import MenuItem from "src/partials/MenuItem.svelte" import MenuItem from "src/partials/MenuItem.svelte"
import FlexColumn from "src/partials/FlexColumn.svelte" import FlexColumn from "src/partials/FlexColumn.svelte"
@ -7,8 +10,9 @@
import PersonHandle from "src/app/shared/PersonHandle.svelte" import PersonHandle from "src/app/shared/PersonHandle.svelte"
import MenuDesktopItem from "src/app/MenuDesktopItem.svelte" import MenuDesktopItem from "src/app/MenuDesktopItem.svelte"
import MenuDesktopSecondary from "src/app/MenuDesktopSecondary.svelte" import MenuDesktopSecondary from "src/app/MenuDesktopSecondary.svelte"
import {slowConnections} from "src/app/state" import {feed, slowConnections} from "src/app/state"
import {router} from "src/app/util/router" import {router} from "src/app/util/router"
import {feedFromEvent} from 'src/domain'
import { import {
env, env,
user, user,
@ -19,8 +23,11 @@
sessions, sessions,
displayPerson, displayPerson,
displayPubkey, displayPubkey,
userFeeds,
} from "src/engine" } from "src/engine"
const {page} = router
const closeSubMenu = () => { const closeSubMenu = () => {
subMenu = null subMenu = null
} }
@ -35,9 +42,27 @@
} }
let subMenu let subMenu
$: isFeedPage = $page.path === "/notes"
</script> </script>
<div class="fixed bottom-0 left-0 top-0 z-nav w-72 bg-tinted-700 transition-colors"> {#if isFeedPage && $userFeeds.length > 0}
<div in:fly={{x: -100, duration: 200}} class="fixed bottom-0 left-72 top-0 w-60 bg-tinted-700 transition-colors text-lg pt-[5.75rem]">
{#each $userFeeds as event}
{@const thisFeed = feedFromEvent(event)}
<MenuDesktopItem isActive={equals(thisFeed.data, $feed)} on:click={() => feed.set(thisFeed.data)}>
{thisFeed.name}
</MenuDesktopItem>
{/each}
<div class="absolute bottom-0 w-full px-7 py-4 h-20 staatliches">
<Anchor href="/feeds">Manage Feeds</Anchor>
</div>
</div>
{/if}
<div
class="fixed bottom-0 left-0 top-0 z-nav w-72 bg-tinted-700 transition-colors"
class:bg-tinted-800={isFeedPage}>
<Anchor external class="mb-4 mt-4 flex items-center gap-2 px-6" href="https://coracle.tools"> <Anchor external class="mb-4 mt-4 flex items-center gap-2 px-6" href="https://coracle.tools">
<img <img
alt="App Logo" alt="App Logo"
@ -45,9 +70,9 @@
? import.meta.env.VITE_APP_WORDMARK_DARK ? import.meta.env.VITE_APP_WORDMARK_DARK
: import.meta.env.VITE_APP_WORDMARK_LIGHT} /> : import.meta.env.VITE_APP_WORDMARK_LIGHT} />
</Anchor> </Anchor>
<MenuDesktopItem path="/notes">Feed</MenuDesktopItem> <MenuDesktopItem path="/notes" isActive={$page.path.startsWith("/notes")} isAlt={isFeedPage}>Feed</MenuDesktopItem>
{#if !$env.FORCE_GROUP && $env.PLATFORM_RELAYS.length === 0} {#if !$env.FORCE_GROUP && $env.PLATFORM_RELAYS.length === 0}
<MenuDesktopItem path="/settings/relays"> <MenuDesktopItem path="/settings/relays" isActive={$page.path.startsWith("/settings/relays")} isAlt={isFeedPage}>
<div class="relative inline-block"> <div class="relative inline-block">
Relays Relays
{#if $slowConnections.length > 0} {#if $slowConnections.length > 0}
@ -56,7 +81,7 @@
</div> </div>
</MenuDesktopItem> </MenuDesktopItem>
{/if} {/if}
<MenuDesktopItem path="/notifications" disabled={!$canSign}> <MenuDesktopItem path="/notifications" disabled={!$canSign} isActive={$page.path.startsWith("/notifications")} isAlt={isFeedPage}>
<div class="relative inline-block"> <div class="relative inline-block">
Notifications Notifications
{#if $hasNewNotifications} {#if $hasNewNotifications}
@ -64,7 +89,7 @@
{/if} {/if}
</div> </div>
</MenuDesktopItem> </MenuDesktopItem>
<MenuDesktopItem path="/channels" disabled={!$canSign}> <MenuDesktopItem path="/channels" disabled={!$canSign} isActive={$page.path.startsWith("/channels")} isAlt={isFeedPage}>
<div class="relative inline-block"> <div class="relative inline-block">
Messages Messages
{#if $hasNewMessages} {#if $hasNewMessages}
@ -72,12 +97,12 @@
{/if} {/if}
</div> </div>
</MenuDesktopItem> </MenuDesktopItem>
<MenuDesktopItem path="/events">Calendar</MenuDesktopItem> <MenuDesktopItem path="/events" isActive={$page.path.startsWith("/events")} isAlt={isFeedPage}>Calendar</MenuDesktopItem>
{#if $env.ENABLE_MARKET} {#if $env.ENABLE_MARKET}
<MenuDesktopItem path="/listings">Market</MenuDesktopItem> <MenuDesktopItem path="/listings" isActive={$page.path.startsWith("/listings")} isAlt={isFeedPage}>Market</MenuDesktopItem>
{/if} {/if}
{#if !$env.FORCE_GROUP} {#if !$env.FORCE_GROUP}
<MenuDesktopItem path="/groups">Groups</MenuDesktopItem> <MenuDesktopItem path="/groups" isActive={$page.path.startsWith("/groups")} isAlt={isFeedPage}>Groups</MenuDesktopItem>
{/if} {/if}
<FlexColumn small class="absolute bottom-0 w-72"> <FlexColumn small class="absolute bottom-0 w-72">
<Anchor <Anchor
@ -160,7 +185,7 @@
</MenuItem> </MenuItem>
</MenuDesktopSecondary> </MenuDesktopSecondary>
{/if} {/if}
<div class="cursor-pointer border-t border-solid border-neutral-600 px-7 pb-4 pt-3"> <div class="cursor-pointer border-t border-solid border-neutral-600 px-7 py-4 h-20">
{#if $pubkey} {#if $pubkey}
<Anchor class="flex items-center gap-2" on:click={() => setSubMenu("account")}> <Anchor class="flex items-center gap-2" on:click={() => setSubMenu("account")}>
<PersonCircle class="h-10 w-10" pubkey={$pubkey} /> <PersonCircle class="h-10 w-10" pubkey={$pubkey} />

View File

@ -3,28 +3,26 @@
import {elasticOut} from "svelte/easing" import {elasticOut} from "svelte/easing"
import {fly} from "src/util/transition" import {fly} from "src/util/transition"
import Anchor from "src/partials/Anchor.svelte" import Anchor from "src/partials/Anchor.svelte"
import {router} from "src/app/util/router"
export let path = null export let path = null
export let isAlt = false
export let isActive = false
const {page} = router $: className = cx("relative staatliches h-12 block transition-all", $$props.class, {
$: isActive = path && $page?.path.startsWith(path)
$: className = cx("relative staatliches h-12 block transition-all", {
"text-3xl text-accent": isActive, "text-3xl text-accent": isActive,
"text-2xl text-tinted-400 hover:text-tinted-100 hover:bg-tinted-800": "text-2xl text-tinted-400 hover:text-tinted-100": !isActive,
!isActive, "hover:bg-tinted-800": !isActive && !isAlt,
"hover:bg-tinted-700": !isActive && isAlt,
}) })
</script> </script>
<Anchor {...$$props} randomizeKey class={className} href={path} on:click> <Anchor {...$$props} randomizeKey class={className} href={path} on:click>
<div class="absolute left-8 flex gap-5 whitespace-nowrap pt-2" class:-right-6={isActive}> <div class="absolute left-6 flex gap-5 whitespace-nowrap pt-2" class:-right-6={isActive}>
<slot /> <slot />
{#if isActive} {#if isActive}
<div <div
in:fly|local={{x: 50, duration: 1000, easing: elasticOut}} in:fly|local={{x: 50, duration: 1000, easing: elasticOut}}
class="relative top-4 h-px w-full bg-accent" /> class="relative top-4 h-px w-full bg-accent mr-3" />
{/if} {/if}
</div> </div>
</Anchor> </Anchor>

View File

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import cx from 'classnames'
import {reverse} from "ramda" import {reverse} from "ramda"
import logger from "src/util/logger" import logger from "src/util/logger"
import Modal from "src/partials/Modal.svelte" import Modal from "src/partials/Modal.svelte"
@ -57,8 +58,11 @@
{#key $stateKey} {#key $stateKey}
<div <div
id="page" id="page"
class="relative pb-32 text-neutral-100 lg:ml-60 lg:pt-16" class={cx("relative pb-32 text-neutral-100 lg:pt-16", {
class:pointer-events-none={$menuIsOpen}> 'lg:ml-60': $page?.path !== "/notes",
'lg:ml-[33rem]': $page?.path === "/notes",
'pointer-events-none': $menuIsOpen,
})}>
{#if $page} {#if $page}
{@const promise = router.getMatch($page.path).route.component} {@const promise = router.getMatch($page.path).route.component}
{#key router.getKey($page)} {#key router.getKey($page)}

View File

@ -53,6 +53,7 @@
const update = async opts => { const update = async opts => {
limit = 0 limit = 0
feed = opts.feed
start(opts) start(opts)
if (feedLoader.compiler.canCompile(opts.feed)) { if (feedLoader.compiler.canCompile(opts.feed)) {

View File

@ -3,6 +3,7 @@ import {uniq} from "ramda"
import {hash} from "hurdak" import {hash} from "hurdak"
import {writable} from "@welshman/lib" import {writable} from "@welshman/lib"
import {ConnectionStatus, NetworkContext} from "@welshman/net" import {ConnectionStatus, NetworkContext} from "@welshman/net"
import type {Feed} from "@welshman/feeds"
import {warn} from "src/util/logger" import {warn} from "src/util/logger"
import {userKinds} from "src/util/nostr" import {userKinds} from "src/util/nostr"
import {router} from "src/app/util/router" import {router} from "src/app/util/router"
@ -29,6 +30,8 @@ export const menuIsOpen = writable(false)
export const searchTerm = writable("") export const searchTerm = writable("")
export const feed = writable<Feed>(null)
// Redact long strings, especially hex and bech32 keys which are 64 and 63 // Redact long strings, especially hex and bech32 keys which are 64 and 63
// characters long, respectively. Put the threshold a little lower in case // characters long, respectively. Put the threshold a little lower in case
// someone accidentally enters a key with the last few digits missing // someone accidentally enters a key with the last few digits missing

View File

@ -1,17 +1,18 @@
<script lang="ts"> <script lang="ts">
import {Scope, makeScopeFeed, makeRelayFeed, makeIntersectionFeed} from "@welshman/feeds" import {Scope, makeScopeFeed, makeRelayFeed, makeIntersectionFeed} from "@welshman/feeds"
import type {Feed as TFeed} from "@welshman/feeds"
import Anchor from "src/partials/Anchor.svelte" import Anchor from "src/partials/Anchor.svelte"
import Feed from "src/app/shared/Feed.svelte" import Feed from "src/app/shared/Feed.svelte"
import {router} from "src/app/util/router" import {router} from "src/app/util/router"
import {feed} from 'src/app/state'
import {session} from "src/engine" import {session} from "src/engine"
export let relays = [] export let relays = []
export let feed: TFeed = makeScopeFeed(Scope.Follows)
if (relays.length > 0) { feed.set(
feed = makeIntersectionFeed(makeRelayFeed(...relays), feed) relays.length > 0
} ? makeIntersectionFeed(makeRelayFeed(...relays), makeScopeFeed(Scope.Follows))
: makeScopeFeed(Scope.Follows)
)
const showLogin = () => router.at("login").open() const showLogin = () => router.at("login").open()
@ -27,4 +28,4 @@
</div> </div>
{/if} {/if}
<Feed skipCache showControls showGroup {feed} /> <Feed skipCache showControls showGroup bind:feed={$feed} />