Migrate more stuff

This commit is contained in:
Jon Staab
2025-02-03 16:37:14 -08:00
parent 0f705c459a
commit 8d3433b167
150 changed files with 2001 additions and 1205 deletions
+6 -1
View File
@@ -1,7 +1,12 @@
<script lang="ts">
import {page} from "$app/stores"
interface Props {
children?: import("svelte").Snippet
}
let {children}: Props = $props()
</script>
{#key $page.params.relay}
<slot />
{@render children?.()}
{/key}
+10 -3
View File
@@ -1,4 +1,6 @@
<script lang="ts">
import {run} from "svelte/legacy"
import {onMount} from "svelte"
import {page} from "$app/stores"
import {ago, MONTH} from "@welshman/lib"
@@ -15,6 +17,11 @@
import {decodeRelay, userRoomsByUrl} from "@app/state"
import {pullConservatively} from "@app/requests"
import {notifications} from "@app/notifications"
interface Props {
children?: import("svelte").Snippet
}
let {children}: Props = $props()
const url = decodeRelay($page.params.relay)
@@ -37,11 +44,11 @@
}
// We have to watch this one, since on mobile the badge will be visible when active
$: {
run(() => {
if ($notifications.has($page.url.pathname)) {
setChecked($page.url.pathname)
}
}
})
onMount(() => {
checkConnection()
@@ -77,6 +84,6 @@
</SecondaryNav>
<Page>
{#key $page.url.pathname}
<slot />
{@render children?.()}
{/key}
</Page>
+26 -20
View File
@@ -39,31 +39,37 @@
const addRoom = () => pushModal(RoomCreate, {url})
let relayAdminEvents: TrustedEvent[] = []
let relayAdminEvents: TrustedEvent[] = $state([])
$: pubkey = $relay?.profile?.pubkey
let pubkey = $derived($relay?.profile?.pubkey)
</script>
<div class="relative flex flex-col">
<PageBar>
<div slot="icon" class="center">
<Icon icon="home-smile" />
</div>
<strong slot="title">Home</strong>
<div slot="action" class="row-2">
{#if !$userRoomsByUrl.has(url)}
<Button class="btn btn-primary btn-sm" on:click={joinSpace}>
<Icon icon="login-2" />
Join Space
</Button>
{:else if pubkey}
<Link class="btn btn-primary btn-sm" href={makeChatPath([pubkey])}>
<Icon icon="letter" />
Contact Owner
</Link>
{/if}
<MenuSpaceButton {url} />
</div>
{#snippet icon()}
<div class="center">
<Icon icon="home-smile" />
</div>
{/snippet}
{#snippet title()}
<strong>Home</strong>
{/snippet}
{#snippet action()}
<div class="row-2">
{#if !$userRoomsByUrl.has(url)}
<Button class="btn btn-primary btn-sm" on:click={joinSpace}>
<Icon icon="login-2" />
Join Space
</Button>
{:else if pubkey}
<Link class="btn btn-primary btn-sm" href={makeChatPath([pubkey])}>
<Icon icon="letter" />
Contact Owner
</Link>
{/if}
<MenuSpaceButton {url} />
</div>
{/snippet}
</PageBar>
<div class="col-2 p-2">
<div class="card2 bg-alt col-4 text-left">
+46 -39
View File
@@ -1,4 +1,5 @@
<script lang="ts">
import {readable} from "svelte/store"
import {onMount, onDestroy} from "svelte"
import {page} from "$app/stores"
import type {Readable} from "svelte/store"
@@ -70,7 +71,7 @@
const replyTo = (event: TrustedEvent) => {
parent = event
compose.focus()
compose?.focus()
}
const clearParent = () => {
@@ -107,25 +108,23 @@
}
const scrollToNewMessages = () =>
newMessages.scrollIntoView({behavior: "smooth", block: "center"})
newMessages?.scrollIntoView({behavior: "smooth", block: "center"})
const scrollToBottom = () => element.scrollTo({top: 0, behavior: "smooth"})
const scrollToBottom = () => element?.scrollTo({top: 0, behavior: "smooth"})
let parent: TrustedEvent | undefined
let loading = true
let element: HTMLElement
let newMessages: HTMLElement
let loading = $state(true)
let parent: TrustedEvent | undefined = $state()
let element: HTMLElement | undefined = $state()
let newMessages: HTMLElement | undefined = $state()
let newMessagesSeen = false
let showFixedNewMessages = false
let showScrollButton = false
let showFixedNewMessages = $state(false)
let showScrollButton = $state(false)
let cleanup: () => void
let events: Readable<TrustedEvent[]>
let compose: ChannelCompose
let elements: any[] = []
$: {
elements = []
let events: Readable<TrustedEvent[]> = $state(readable([]))
let compose: ChannelCompose | undefined = $state()
const elements = $derived.by(() => {
const elements = []
const seen = new Set()
let previousDate
@@ -170,11 +169,13 @@
elements.reverse()
setTimeout(onScroll, 100)
}
return elements
})
onMount(() => {
;({events, cleanup} = makeFeed({
element,
element: element!,
relays: [url],
feedFilters: [filter],
subscriptionFilters: [{kinds: [DELETE, REACTION, MESSAGE], "#h": [room], since: now()}],
@@ -193,32 +194,38 @@
<div class="saib relative flex h-full flex-col">
<PageBar>
<div slot="icon" class="center">
<Icon icon="hashtag" />
</div>
<strong slot="title">
<ChannelName {url} {room} />
</strong>
<div slot="action" class="row-2">
{#if room !== GENERAL}
{#if $userRoomsByUrl.get(url)?.has(room)}
<Button class="btn btn-neutral btn-sm" on:click={leaveRoom}>
<Icon icon="arrows-a-logout-2" />
Leave Room
</Button>
{:else}
<Button class="btn btn-neutral btn-sm" on:click={joinRoom}>
<Icon icon="login-2" />
Join Room
</Button>
{#snippet icon()}
<div class="center">
<Icon icon="hashtag" />
</div>
{/snippet}
{#snippet title()}
<strong>
<ChannelName {url} {room} />
</strong>
{/snippet}
{#snippet action()}
<div class="row-2">
{#if room !== GENERAL}
{#if $userRoomsByUrl.get(url)?.has(room)}
<Button class="btn btn-neutral btn-sm" on:click={leaveRoom}>
<Icon icon="arrows-a-logout-2" />
Leave Room
</Button>
{:else}
<Button class="btn btn-neutral btn-sm" on:click={joinRoom}>
<Icon icon="login-2" />
Join Room
</Button>
{/if}
{/if}
{/if}
<MenuSpaceButton {url} />
</div>
<MenuSpaceButton {url} />
</div>
{/snippet}
</PageBar>
<div
class="scroll-container -mt-2 flex flex-grow flex-col-reverse overflow-y-auto overflow-x-hidden py-2"
on:scroll={onScroll}
onscroll={onScroll}
bind:this={element}>
{#each elements as { type, id, value, showPubkey } (id)}
{#if type === "new-messages"}
+28 -20
View File
@@ -30,28 +30,30 @@
parseInt(event.tags.find(t => t[0] === "start")?.[1] || "")
const limit = 5
let loading = true
let loading = $state(true)
type Item = {
event: TrustedEvent
dateDisplay?: string
}
$: items = sortBy(e => -getStart(e), $events)
.reduce<Item[]>((r, event) => {
const end = getEnd(event)
const start = getStart(event)
let items = $derived(
sortBy(e => -getStart(e), $events)
.reduce<Item[]>((r, event) => {
const end = getEnd(event)
const start = getStart(event)
if (isNaN(start) || isNaN(end)) return r
if (isNaN(start) || isNaN(end)) return r
const prevDateDisplay =
r.length > 0 ? formatTimestampAsDate(getStart(last(r).event)) : undefined
const newDateDisplay = formatTimestampAsDate(start)
const dateDisplay = prevDateDisplay === newDateDisplay ? undefined : newDateDisplay
const prevDateDisplay =
r.length > 0 ? formatTimestampAsDate(getStart(last(r).event)) : undefined
const newDateDisplay = formatTimestampAsDate(start)
const dateDisplay = prevDateDisplay === newDateDisplay ? undefined : newDateDisplay
return [...r, {event, dateDisplay}]
}, [])
.slice(0, limit)
return [...r, {event, dateDisplay}]
}, [])
.slice(0, limit),
)
onMount(() => {
const sub = subscribe({filters: [{kinds, since: ago(30)}]})
@@ -72,13 +74,19 @@
<div class="relative flex h-screen flex-col">
<PageBar>
<div slot="icon" class="center">
<Icon icon="calendar-minimalistic" />
</div>
<strong slot="title">Calendar</strong>
<div slot="action" class="md:hidden">
<MenuSpaceButton {url} />
</div>
{#snippet icon()}
<div class="center">
<Icon icon="calendar-minimalistic" />
</div>
{/snippet}
{#snippet title()}
<strong>Calendar</strong>
{/snippet}
{#snippet action()}
<div class="md:hidden">
<MenuSpaceButton {url} />
</div>
{/snippet}
</PageBar>
<div class="flex flex-grow flex-col gap-2 overflow-auto p-2">
{#each items as { event, dateDisplay }, i (event.id)}
+28 -29
View File
@@ -59,32 +59,25 @@
})
let limit = 10
let loading = true
let unmounted = false
let element: Element
let loading = $state(true)
let element: Element | undefined = $state()
let scroller: Scroller
onMount(() => {
// Element is frequently not defined. I don't know why
sleep(1000).then(() => {
if (!unmounted) {
scroller = createScroller({
element,
delay: 300,
threshold: 3000,
onScroll: () => {
limit += 10
scroller = createScroller({
element: element!,
delay: 300,
threshold: 3000,
onScroll: () => {
limit += 10
if ($events.length - limit < 10) {
ctrl.load(50)
}
},
})
}
if ($events.length - limit < 10) {
ctrl.load(50)
}
},
})
return () => {
unmounted = true
scroller?.stop()
setChecked($page.url.pathname)
}
@@ -93,17 +86,23 @@
<div class="relative flex h-screen flex-col" bind:this={element}>
<PageBar>
<div slot="icon" class="center">
<Icon icon="notes-minimalistic" />
</div>
<strong slot="title">Threads</strong>
<div slot="action" class="row-2">
<Button class="btn btn-primary btn-sm" on:click={createThread}>
{#snippet icon()}
<div class="center">
<Icon icon="notes-minimalistic" />
Create a Thread
</Button>
<MenuSpaceButton {url} />
</div>
</div>
{/snippet}
{#snippet title()}
<strong>Threads</strong>
{/snippet}
{#snippet action()}
<div class="row-2">
<Button class="btn btn-primary btn-sm" on:click={createThread}>
<Icon icon="notes-minimalistic" />
Create a Thread
</Button>
<MenuSpaceButton {url} />
</div>
{/snippet}
</PageBar>
<div class="flex flex-grow flex-col gap-2 overflow-auto p-2">
{#each $events as event (event.id)}
@@ -37,10 +37,10 @@
showAll = true
}
let showAll = false
let showReply = false
let showAll = $state(false)
let showReply = $state(false)
$: title = $event?.tags.find(nthEq(0, "title"))?.[1] || ""
let title = $derived($event?.tags.find(nthEq(0, "title"))?.[1] || "")
onMount(() => {
const sub = subscribe({relays: [url], filters})
@@ -93,16 +93,22 @@
{/await}
{/if}
<PageBar class="mx-0">
<div slot="icon">
<Button class="btn btn-neutral btn-sm" on:click={back}>
<Icon icon="alt-arrow-left" />
Go back
</Button>
</div>
<h1 slot="title" class="text-xl">{title}</h1>
<div slot="action">
<MenuSpaceButton {url} />
</div>
{#snippet icon()}
<div>
<Button class="btn btn-neutral btn-sm" on:click={back}>
<Icon icon="alt-arrow-left" />
Go back
</Button>
</div>
{/snippet}
{#snippet title()}
<h1 class="text-xl">{title}</h1>
{/snippet}
{#snippet action()}
<div>
<MenuSpaceButton {url} />
</div>
{/snippet}
</PageBar>
</div>
{#if showReply}