forked from coracle/flotilla
Spruce up home page navigation
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import {sortBy} from "@welshman/lib"
|
|
||||||
import {displayRelayUrl, GROUP_META} from "@welshman/util"
|
import {displayRelayUrl, GROUP_META} from "@welshman/util"
|
||||||
import {load} from "@welshman/app"
|
import {load} from "@welshman/app"
|
||||||
import {fly} from "@lib/transition"
|
import {fly} from "@lib/transition"
|
||||||
@@ -18,14 +17,12 @@
|
|||||||
import ChannelName from "@app/components/ChannelName.svelte"
|
import ChannelName from "@app/components/ChannelName.svelte"
|
||||||
import MenuSpaceRoomItem from "@app/components/MenuSpaceRoomItem.svelte"
|
import MenuSpaceRoomItem from "@app/components/MenuSpaceRoomItem.svelte"
|
||||||
import {
|
import {
|
||||||
getMembershipRoomsByUrl,
|
|
||||||
getMembershipUrls,
|
getMembershipUrls,
|
||||||
hasMembershipUrl,
|
hasMembershipUrl,
|
||||||
userMembership,
|
userMembership,
|
||||||
memberships,
|
memberships,
|
||||||
channelsByUrl,
|
deriveUserRooms,
|
||||||
GENERAL,
|
deriveOtherRooms,
|
||||||
displayChannel,
|
|
||||||
} from "@app/state"
|
} from "@app/state"
|
||||||
import {deriveNotification, THREAD_FILTERS} from "@app/notifications"
|
import {deriveNotification, THREAD_FILTERS} from "@app/notifications"
|
||||||
import {pushModal} from "@app/modal"
|
import {pushModal} from "@app/modal"
|
||||||
@@ -35,6 +32,8 @@
|
|||||||
|
|
||||||
const threadsPath = makeSpacePath(url, "threads")
|
const threadsPath = makeSpacePath(url, "threads")
|
||||||
const threadsNotification = deriveNotification(threadsPath, THREAD_FILTERS, url)
|
const threadsNotification = deriveNotification(threadsPath, THREAD_FILTERS, url)
|
||||||
|
const userRooms = deriveUserRooms(url)
|
||||||
|
const otherRooms = deriveOtherRooms(url)
|
||||||
|
|
||||||
const openMenu = () => {
|
const openMenu = () => {
|
||||||
showMenu = true
|
showMenu = true
|
||||||
@@ -62,25 +61,9 @@
|
|||||||
let showMenu = false
|
let showMenu = false
|
||||||
let replaceState = false
|
let replaceState = false
|
||||||
let element: Element
|
let element: Element
|
||||||
let userRooms: string[] = []
|
|
||||||
let otherRooms: string[] = []
|
|
||||||
|
|
||||||
$: members = $memberships.filter(l => hasMembershipUrl(l, url)).map(l => l.event.pubkey)
|
$: members = $memberships.filter(l => hasMembershipUrl(l, url)).map(l => l.event.pubkey)
|
||||||
|
|
||||||
$: {
|
|
||||||
userRooms = [GENERAL, ...getMembershipRoomsByUrl(url, $userMembership)]
|
|
||||||
otherRooms = []
|
|
||||||
|
|
||||||
for (const channel of $channelsByUrl.get(url) || []) {
|
|
||||||
if (!userRooms.includes(channel.room)) {
|
|
||||||
otherRooms.push(channel.room)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
userRooms = sortBy(room => displayChannel(url, room), userRooms)
|
|
||||||
otherRooms = sortBy(room => displayChannel(url, room), otherRooms)
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
replaceState = Boolean(element.closest(".drawer"))
|
replaceState = Boolean(element.closest(".drawer"))
|
||||||
load({relays: [url], filters: [{kinds: [GROUP_META]}]})
|
load({relays: [url], filters: [{kinds: [GROUP_META]}]})
|
||||||
@@ -137,23 +120,25 @@
|
|||||||
</SecondaryNavItem>
|
</SecondaryNavItem>
|
||||||
<div class="h-2" />
|
<div class="h-2" />
|
||||||
<SecondaryNavHeader>Your Rooms</SecondaryNavHeader>
|
<SecondaryNavHeader>Your Rooms</SecondaryNavHeader>
|
||||||
{#each userRooms as room, i (room)}
|
{#each $userRooms as room, i (room)}
|
||||||
<MenuSpaceRoomItem {url} {room} />
|
<MenuSpaceRoomItem {url} {room} />
|
||||||
{/each}
|
{/each}
|
||||||
{#if otherRooms.length > 0}
|
{#if $otherRooms.length > 0}
|
||||||
<div class="h-2" />
|
<div class="h-2" />
|
||||||
<SecondaryNavHeader>
|
<SecondaryNavHeader>
|
||||||
{#if userRooms.length > 0}
|
{#if $userRooms.length > 0}
|
||||||
Other Rooms
|
Other Rooms
|
||||||
{:else}
|
{:else}
|
||||||
Rooms
|
Rooms
|
||||||
{/if}
|
{/if}
|
||||||
</SecondaryNavHeader>
|
</SecondaryNavHeader>
|
||||||
{/if}
|
{/if}
|
||||||
{#each otherRooms as room, i (room)}
|
{#each $otherRooms as room, i (room)}
|
||||||
<SecondaryNavItem href={makeSpacePath(url, room)}>
|
<SecondaryNavItem href={makeSpacePath(url, room)}>
|
||||||
<Icon icon="hashtag" />
|
<Icon icon="hashtag" />
|
||||||
<ChannelName {url} {room} />
|
<div class="min-w-0 overflow-hidden text-ellipsis">
|
||||||
|
<ChannelName {url} {room} />
|
||||||
|
</div>
|
||||||
</SecondaryNavItem>
|
</SecondaryNavItem>
|
||||||
{/each}
|
{/each}
|
||||||
<SecondaryNavItem on:click={addRoom}>
|
<SecondaryNavItem on:click={addRoom}>
|
||||||
|
|||||||
@@ -14,5 +14,7 @@
|
|||||||
|
|
||||||
<SecondaryNavItem href={path} notification={$notification}>
|
<SecondaryNavItem href={path} notification={$notification}>
|
||||||
<Icon icon="hashtag" />
|
<Icon icon="hashtag" />
|
||||||
<ChannelName {url} {room} />
|
<div class="min-w-0 overflow-hidden text-ellipsis">
|
||||||
|
<ChannelName {url} {room} />
|
||||||
|
</div>
|
||||||
</SecondaryNavItem>
|
</SecondaryNavItem>
|
||||||
|
|||||||
@@ -605,6 +605,9 @@ export const displayChannel = (url: string, room: string) => {
|
|||||||
return channelsById.get().get(makeChannelId(url, room))?.name || room
|
return channelsById.get().get(makeChannelId(url, room))?.name || room
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const roomComparator = (url: string) => (room: string) =>
|
||||||
|
displayChannel(url, room).toLowerCase()
|
||||||
|
|
||||||
// User stuff
|
// User stuff
|
||||||
|
|
||||||
export const userSettings = withGetter(
|
export const userSettings = withGetter(
|
||||||
@@ -633,6 +636,20 @@ export const userMembership = withGetter(
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const deriveUserRooms = (url: string) =>
|
||||||
|
derived(userMembership, $userMembership => [
|
||||||
|
GENERAL,
|
||||||
|
...sortBy(roomComparator(url), getMembershipRoomsByUrl(url, $userMembership)),
|
||||||
|
])
|
||||||
|
|
||||||
|
export const deriveOtherRooms = (url: string) =>
|
||||||
|
derived([deriveUserRooms(url), channelsByUrl], ([$userRooms, $channelsByUrl]) =>
|
||||||
|
sortBy(
|
||||||
|
roomComparator(url),
|
||||||
|
($channelsByUrl.get(url) || []).filter(c => !$userRooms.includes(c.room)).map(c => c.room),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
// Other utils
|
// Other utils
|
||||||
|
|
||||||
export const encodeRelay = (url: string) => encodeURIComponent(normalizeRelayUrl(url))
|
export const encodeRelay = (url: string) => encodeURIComponent(normalizeRelayUrl(url))
|
||||||
|
|||||||
@@ -10,11 +10,13 @@
|
|||||||
import ChannelName from "@app/components/ChannelName.svelte"
|
import ChannelName from "@app/components/ChannelName.svelte"
|
||||||
import RelayName from "@app/components/RelayName.svelte"
|
import RelayName from "@app/components/RelayName.svelte"
|
||||||
import RelayDescription from "@app/components/RelayDescription.svelte"
|
import RelayDescription from "@app/components/RelayDescription.svelte"
|
||||||
import {decodeRelay, channelsByUrl} from "@app/state"
|
import {decodeRelay, deriveUserRooms, deriveOtherRooms} from "@app/state"
|
||||||
import {makeChatPath, makeRoomPath, makeSpacePath} from "@app/routes"
|
import {makeChatPath, makeRoomPath, makeSpacePath} from "@app/routes"
|
||||||
|
|
||||||
const url = decodeRelay($page.params.relay)
|
const url = decodeRelay($page.params.relay)
|
||||||
const relay = deriveRelay(url)
|
const relay = deriveRelay(url)
|
||||||
|
const userRooms = deriveUserRooms(url)
|
||||||
|
const otherRooms = deriveOtherRooms(url)
|
||||||
|
|
||||||
$: pubkey = $relay?.profile?.pubkey
|
$: pubkey = $relay?.profile?.pubkey
|
||||||
</script>
|
</script>
|
||||||
@@ -89,18 +91,26 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-3 gap-2">
|
<div class="grid grid-cols-3 gap-2">
|
||||||
<Link
|
<Link href={makeSpacePath(url, "threads")} class="btn btn-primary justify-start border-none">
|
||||||
href={makeSpacePath(url, "threads")}
|
|
||||||
class="bg-alt btn btn-neutral justify-start border-none">
|
|
||||||
<Icon icon="notes-minimalistic" /> Threads
|
<Icon icon="notes-minimalistic" /> Threads
|
||||||
</Link>
|
</Link>
|
||||||
{#each $channelsByUrl.get(url) || [] as channel (channel.room)}
|
{#each $userRooms as room (room)}
|
||||||
<Link
|
<Link
|
||||||
href={makeRoomPath(url, channel.room)}
|
href={makeRoomPath(url, room)}
|
||||||
|
class="btn btn-neutral flex-nowrap justify-start whitespace-nowrap border-none">
|
||||||
|
<Icon icon="hashtag" />
|
||||||
|
<div class="min-w-0 overflow-hidden text-ellipsis">
|
||||||
|
<ChannelName {url} {room} />
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
{/each}
|
||||||
|
{#each $otherRooms as room (room)}
|
||||||
|
<Link
|
||||||
|
href={makeRoomPath(url, room)}
|
||||||
class="bg-alt btn btn-neutral flex-nowrap justify-start whitespace-nowrap border-none">
|
class="bg-alt btn btn-neutral flex-nowrap justify-start whitespace-nowrap border-none">
|
||||||
<Icon icon="hashtag" />
|
<Icon icon="hashtag" />
|
||||||
<div class="min-w-0 overflow-hidden text-ellipsis">
|
<div class="min-w-0 overflow-hidden text-ellipsis">
|
||||||
<ChannelName {...channel} />
|
<ChannelName {url} {room} />
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
Reference in New Issue
Block a user