Lint, rename chat compose stuff
This commit is contained in:
parent
4ad67921a0
commit
339e53e506
26 changed files with 94 additions and 131 deletions
|
|
@ -105,7 +105,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.link-content {
|
.link-content {
|
||||||
@apply inline-block max-w-full overflow-hidden text-ellipsis whitespace-nowrap rounded bg-neutral px-1 text-sm text-neutral-content no-underline;
|
@apply max-w-full overflow-hidden text-ellipsis whitespace-nowrap rounded bg-neutral px-1 text-neutral-content no-underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.link-content.link-content-selected {
|
.link-content.link-content-selected {
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,18 @@
|
||||||
import {uniqBy, equals, uniq, now, choice} from "@welshman/lib"
|
import {uniqBy, sleep, chunk, equals, choice} from "@welshman/lib"
|
||||||
import {getRelayTagValues, createEvent, displayProfile} from "@welshman/util"
|
import {getPubkeyTagValues, createEvent, displayProfile} from "@welshman/util"
|
||||||
import {PublishStatus} from "@welshman/net"
|
import type {SubscribeRequestWithHandlers} from "@welshman/net"
|
||||||
import {
|
import {
|
||||||
pubkey,
|
pubkey,
|
||||||
repository,
|
repository,
|
||||||
load,
|
|
||||||
makeThunk,
|
makeThunk,
|
||||||
publishThunk,
|
publishThunk,
|
||||||
loadProfile,
|
loadProfile,
|
||||||
profilesByPubkey,
|
profilesByPubkey,
|
||||||
relaySelectionsByPubkey,
|
relaySelectionsByPubkey,
|
||||||
loadRelaySelections,
|
|
||||||
getWriteRelayUrls,
|
getWriteRelayUrls,
|
||||||
loadFollows,
|
loadFollows,
|
||||||
loadMutes,
|
loadMutes,
|
||||||
|
followsByPubkey,
|
||||||
} from "@welshman/app"
|
} from "@welshman/app"
|
||||||
import {MEMBERSHIPS, INDEXER_RELAYS} from "@app/state"
|
import {MEMBERSHIPS, INDEXER_RELAYS} from "@app/state"
|
||||||
|
|
||||||
|
|
@ -49,8 +48,32 @@ export const makeIMeta = (url: string, data: Record<string, string>) => [
|
||||||
|
|
||||||
// Loaders
|
// Loaders
|
||||||
|
|
||||||
export const loadUserData = (pubkey: string, hints: string[] = []) =>
|
export const loadUserData = (
|
||||||
Promise.all([loadProfile(pubkey), loadFollows(pubkey), loadMutes(pubkey)])
|
pubkey: string,
|
||||||
|
request: Partial<SubscribeRequestWithHandlers> = {},
|
||||||
|
) => {
|
||||||
|
const promise = Promise.all([
|
||||||
|
loadProfile(pubkey, request),
|
||||||
|
loadFollows(pubkey, request),
|
||||||
|
loadMutes(pubkey, request),
|
||||||
|
])
|
||||||
|
|
||||||
|
// Load followed profiles slowly in the background without clogging other stuff up
|
||||||
|
promise.then(async () => {
|
||||||
|
const followsList = followsByPubkey.get().get(pubkey)
|
||||||
|
const follows = getPubkeyTagValues(followsList?.event.tags || [])
|
||||||
|
|
||||||
|
for (const pubkeys of chunk(50, follows)) {
|
||||||
|
await sleep(300)
|
||||||
|
|
||||||
|
for (const pubkey of pubkeys) {
|
||||||
|
loadProfile(pubkey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return promise
|
||||||
|
}
|
||||||
|
|
||||||
// Updates
|
// Updates
|
||||||
|
|
||||||
|
|
@ -73,10 +96,14 @@ export const addSpaceMembership = (url: string) =>
|
||||||
updateList(MEMBERSHIPS, (tags: string[][]) => uniqBy(t => t.join(""), [...tags, ["r", url]]))
|
updateList(MEMBERSHIPS, (tags: string[][]) => uniqBy(t => t.join(""), [...tags, ["r", url]]))
|
||||||
|
|
||||||
export const addRoomMembership = (url: string, topic: string) =>
|
export const addRoomMembership = (url: string, topic: string) =>
|
||||||
updateList(MEMBERSHIPS, (tags: string[][]) => uniqBy(t => t.join(""), [...tags, ["t", topic, url]]))
|
updateList(MEMBERSHIPS, (tags: string[][]) =>
|
||||||
|
uniqBy(t => t.join(""), [...tags, ["t", topic, url]]),
|
||||||
|
)
|
||||||
|
|
||||||
export const removeSpaceMembership = (url: string) =>
|
export const removeSpaceMembership = (url: string) =>
|
||||||
updateList(MEMBERSHIPS, (tags: string[][]) => tags.filter(t => !equals(["r", url], t) && t[2] !== url))
|
updateList(MEMBERSHIPS, (tags: string[][]) =>
|
||||||
|
tags.filter(t => !equals(["r", url], t) && t[2] !== url),
|
||||||
|
)
|
||||||
|
|
||||||
export const removeRoomMembership = (url: string, topic: string) =>
|
export const removeRoomMembership = (url: string, topic: string) =>
|
||||||
updateList(MEMBERSHIPS, (tags: string[][]) => tags.filter(t => !equals(["t", topic, url], t)))
|
updateList(MEMBERSHIPS, (tags: string[][]) => tags.filter(t => !equals(["t", topic, url], t)))
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,12 @@
|
||||||
export let selected: NodeViewProps["selected"]
|
export let selected: NodeViewProps["selected"]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<NodeViewWrapper class="inline">
|
<NodeViewWrapper class="inline-block">
|
||||||
<Link
|
<Link
|
||||||
external
|
external
|
||||||
href={node.attrs.url}
|
href={node.attrs.url}
|
||||||
class={cx("link-content", {"link-content-selected": selected})}>
|
class={cx("link-content", {"link-content-selected": selected})}>
|
||||||
<Icon icon="link-round" size={3} class="inline-block translate-y-px" />
|
<Icon icon="link-round" size={3} class="inline-block" />
|
||||||
{displayUrl(node.attrs.url)}
|
{displayUrl(node.attrs.url)}
|
||||||
</Link>
|
</Link>
|
||||||
</NodeViewWrapper>
|
</NodeViewWrapper>
|
||||||
|
|
@ -65,10 +65,10 @@
|
||||||
data-theme={$theme}
|
data-theme={$theme}
|
||||||
bind:this={element}
|
bind:this={element}
|
||||||
transition:slide|local={{duration: 100}}
|
transition:slide|local={{duration: 100}}
|
||||||
class="mt-2 flex max-h-[350px] flex-col overflow-y-auto overflow-x-hidden shadow-xl">
|
class="mt-2 max-h-[350px] overflow-y-auto overflow-x-hidden shadow-xl">
|
||||||
{#if term && allowCreate}
|
{#if term && allowCreate}
|
||||||
<button
|
<button
|
||||||
class="white-space-nowrap min-w-0 cursor-pointer overflow-hidden text-ellipsis px-4 py-2 text-left transition-colors hover:bg-primary hover:text-primary-content"
|
class="white-space-nowrap block w-full min-w-0 cursor-pointer overflow-x-hidden text-ellipsis px-4 py-2 text-left transition-colors hover:bg-primary hover:text-primary-content"
|
||||||
on:mousedown|preventDefault
|
on:mousedown|preventDefault
|
||||||
on:click|preventDefault={() => select(term)}>
|
on:click|preventDefault={() => select(term)}>
|
||||||
Use "<svelte:component this={component} value={term} />"
|
Use "<svelte:component this={component} value={term} />"
|
||||||
|
|
@ -76,7 +76,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
{#each items as value, i (value)}
|
{#each items as value, i (value)}
|
||||||
<button
|
<button
|
||||||
class="white-space-nowrap min-w-0 cursor-pointer overflow-hidden text-ellipsis px-4 py-2 text-left transition-colors hover:bg-primary hover:text-primary-content"
|
class="white-space-nowrap block w-full min-w-0 cursor-pointer overflow-x-hidden text-ellipsis px-4 py-2 text-left transition-colors hover:bg-primary hover:text-primary-content"
|
||||||
class:bg-primary={index === i}
|
class:bg-primary={index === i}
|
||||||
class:text-primary-content={index === i}
|
class:text-primary-content={index === i}
|
||||||
on:mousedown|preventDefault
|
on:mousedown|preventDefault
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import cx from "classnames"
|
|
||||||
import type {NodeViewProps} from "@tiptap/core"
|
|
||||||
import {NodeViewWrapper} from "svelte-tiptap"
|
|
||||||
import Link from "@lib/components/Link.svelte"
|
|
||||||
|
|
||||||
export let node: NodeViewProps["node"]
|
|
||||||
export let selected: NodeViewProps["selected"]
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<NodeViewWrapper class="inline">
|
|
||||||
<Link
|
|
||||||
external
|
|
||||||
href="https://coracle.social/topics/{node.attrs.topic.toLowerCase()}"
|
|
||||||
class={cx("link-content", {"link-content-selected": selected})}>
|
|
||||||
#{node.attrs.topic}
|
|
||||||
</Link>
|
|
||||||
</NodeViewWrapper>
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
export let value
|
|
||||||
</script>
|
|
||||||
|
|
||||||
#{value}
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {displayRelayUrl} from "@welshman/util"
|
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import Link from "@lib/components/Link.svelte"
|
import Link from "@lib/components/Link.svelte"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
|
||||||
import {clip} from "@app/toast"
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="column gap-4">
|
<div class="column gap-4">
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
const onSuccess = async (session: Session, relays: string[] = []) => {
|
const onSuccess = async (session: Session, relays: string[] = []) => {
|
||||||
addSession(session)
|
addSession(session)
|
||||||
|
|
||||||
await loadUserData(session.pubkey, relays)
|
await loadUserData(session.pubkey, {relays})
|
||||||
|
|
||||||
pushToast({message: "Successfully logged in!"})
|
pushToast({message: "Successfully logged in!"})
|
||||||
clearModal()
|
clearModal()
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,15 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {goto} from "$app/navigation"
|
import {goto} from "$app/navigation"
|
||||||
import {append, remove} from "@welshman/lib"
|
|
||||||
import {displayRelayUrl} from "@welshman/util"
|
import {displayRelayUrl} from "@welshman/util"
|
||||||
import {deriveRelay} from "@welshman/app"
|
|
||||||
import Field from "@lib/components/Field.svelte"
|
import Field from "@lib/components/Field.svelte"
|
||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import {pushModal} from "@app/modal"
|
|
||||||
import {pushToast} from "@app/toast"
|
|
||||||
import {addRoomMembership} from "@app/commands"
|
import {addRoomMembership} from "@app/commands"
|
||||||
import {makeSpacePath} from '@app/routes'
|
import {makeSpacePath} from "@app/routes"
|
||||||
|
|
||||||
export let url
|
export let url
|
||||||
|
|
||||||
const relay = deriveRelay(url)
|
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
||||||
const tryCreate = async () => {
|
const tryCreate = async () => {
|
||||||
|
|
@ -39,9 +33,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form class="column gap-4" on:submit|preventDefault={create}>
|
<form class="column gap-4" on:submit|preventDefault={create}>
|
||||||
<h1 class="heading">
|
<h1 class="heading">Create a Room</h1>
|
||||||
Create a Room
|
|
||||||
</h1>
|
|
||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
On <span class="text-primary">{displayRelayUrl(url)}</span>
|
On <span class="text-primary">{displayRelayUrl(url)}</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,13 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {append, remove} from "@welshman/lib"
|
|
||||||
import {displayRelayUrl} from "@welshman/util"
|
import {displayRelayUrl} from "@welshman/util"
|
||||||
import {deriveRelay} from "@welshman/app"
|
|
||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import {pushModal, clearModal} from "@app/modal"
|
import {clearModal} from "@app/modal"
|
||||||
import {pushToast} from "@app/toast"
|
|
||||||
import {addSpaceMembership} from "@app/commands"
|
import {addSpaceMembership} from "@app/commands"
|
||||||
|
|
||||||
export let url
|
export let url
|
||||||
|
|
||||||
const relay = deriveRelay(url)
|
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
||||||
const tryJoin = async () => {
|
const tryJoin = async () => {
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,16 @@ import {
|
||||||
FileUploadExtension,
|
FileUploadExtension,
|
||||||
} from "nostr-editor"
|
} from "nostr-editor"
|
||||||
import type {StampedEvent} from "@welshman/util"
|
import type {StampedEvent} from "@welshman/util"
|
||||||
import {signer, topicSearch, profileSearch} from "@welshman/app"
|
import {signer, profileSearch} from "@welshman/app"
|
||||||
import {LinkExtension, asInline, createSuggestions} from "@lib/tiptap"
|
import {LinkExtension, asInline, createSuggestions} from "@lib/tiptap"
|
||||||
import GroupComposeMention from "@app/components/GroupComposeMention.svelte"
|
import ChatComposeMention from "@app/components/ChatComposeMention.svelte"
|
||||||
import GroupComposeTopic from "@app/components/GroupComposeTopic.svelte"
|
import ChatComposeEvent from "@app/components/ChatComposeEvent.svelte"
|
||||||
import GroupComposeEvent from "@app/components/GroupComposeEvent.svelte"
|
import ChatComposeImage from "@app/components/ChatComposeImage.svelte"
|
||||||
import GroupComposeImage from "@app/components/GroupComposeImage.svelte"
|
import ChatComposeBolt11 from "@app/components/ChatComposeBolt11.svelte"
|
||||||
import GroupComposeBolt11 from "@app/components/GroupComposeBolt11.svelte"
|
import ChatComposeVideo from "@app/components/ChatComposeVideo.svelte"
|
||||||
import GroupComposeVideo from "@app/components/GroupComposeVideo.svelte"
|
import ChatComposeLink from "@app/components/ChatComposeLink.svelte"
|
||||||
import GroupComposeLink from "@app/components/GroupComposeLink.svelte"
|
import ChatComposeSuggestions from "@app/components/ChatComposeSuggestions.svelte"
|
||||||
import GroupComposeSuggestions from "@app/components/GroupComposeSuggestions.svelte"
|
import ChatSuggestionProfile from "@app/components/ChatSuggestionProfile.svelte"
|
||||||
import GroupComposeTopicSuggestion from "@app/components/GroupComposeTopicSuggestion.svelte"
|
|
||||||
import GroupComposeProfileSuggestion from "@app/components/GroupComposeProfileSuggestion.svelte"
|
|
||||||
import {getPubkeyHints} from "@app/commands"
|
import {getPubkeyHints} from "@app/commands"
|
||||||
|
|
||||||
export const addFile = (editor: Editor) => editor.chain().selectFiles().run()
|
export const addFile = (editor: Editor) => editor.chain().selectFiles().run()
|
||||||
|
|
@ -74,13 +72,13 @@ export const getChatEditorOptions = ({uploading, sendMessage}: ChatComposeEditor
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
LinkExtension.extend({
|
LinkExtension.extend({
|
||||||
addNodeView: () => SvelteNodeViewRenderer(GroupComposeLink),
|
addNodeView: () => SvelteNodeViewRenderer(ChatComposeLink),
|
||||||
}),
|
}),
|
||||||
Bolt11Extension.extend(
|
Bolt11Extension.extend(
|
||||||
asInline({addNodeView: () => SvelteNodeViewRenderer(GroupComposeBolt11)}),
|
asInline({addNodeView: () => SvelteNodeViewRenderer(ChatComposeBolt11)}),
|
||||||
),
|
),
|
||||||
NProfileExtension.extend({
|
NProfileExtension.extend({
|
||||||
addNodeView: () => SvelteNodeViewRenderer(GroupComposeMention),
|
addNodeView: () => SvelteNodeViewRenderer(ChatComposeMention),
|
||||||
addProseMirrorPlugins() {
|
addProseMirrorPlugins() {
|
||||||
return [
|
return [
|
||||||
createSuggestions({
|
createSuggestions({
|
||||||
|
|
@ -94,21 +92,19 @@ export const getChatEditorOptions = ({uploading, sendMessage}: ChatComposeEditor
|
||||||
|
|
||||||
return props.command({pubkey, nprofile, relays})
|
return props.command({pubkey, nprofile, relays})
|
||||||
},
|
},
|
||||||
suggestionComponent: GroupComposeProfileSuggestion,
|
suggestionComponent: ChatSuggestionProfile,
|
||||||
suggestionsComponent: GroupComposeSuggestions,
|
suggestionsComponent: ChatComposeSuggestions,
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
NEventExtension.extend(
|
NEventExtension.extend(asInline({addNodeView: () => SvelteNodeViewRenderer(ChatComposeEvent)})),
|
||||||
asInline({addNodeView: () => SvelteNodeViewRenderer(GroupComposeEvent)}),
|
NAddrExtension.extend(asInline({addNodeView: () => SvelteNodeViewRenderer(ChatComposeEvent)})),
|
||||||
),
|
|
||||||
NAddrExtension.extend(asInline({addNodeView: () => SvelteNodeViewRenderer(GroupComposeEvent)})),
|
|
||||||
ImageExtension.extend(
|
ImageExtension.extend(
|
||||||
asInline({addNodeView: () => SvelteNodeViewRenderer(GroupComposeImage)}),
|
asInline({addNodeView: () => SvelteNodeViewRenderer(ChatComposeImage)}),
|
||||||
).configure({defaultUploadUrl: "https://nostr.build", defaultUploadType: "nip96"}),
|
).configure({defaultUploadUrl: "https://nostr.build", defaultUploadType: "nip96"}),
|
||||||
VideoExtension.extend(
|
VideoExtension.extend(
|
||||||
asInline({addNodeView: () => SvelteNodeViewRenderer(GroupComposeVideo)}),
|
asInline({addNodeView: () => SvelteNodeViewRenderer(ChatComposeVideo)}),
|
||||||
).configure({defaultUploadUrl: "https://nostr.build", defaultUploadType: "nip96"}),
|
).configure({defaultUploadUrl: "https://nostr.build", defaultUploadType: "nip96"}),
|
||||||
FileUploadExtension.configure({
|
FileUploadExtension.configure({
|
||||||
immediateUpload: false,
|
immediateUpload: false,
|
||||||
|
|
@ -136,19 +132,17 @@ export const getChatViewOptions = (content: string) => ({
|
||||||
Paragraph,
|
Paragraph,
|
||||||
Text,
|
Text,
|
||||||
LinkExtension.extend({
|
LinkExtension.extend({
|
||||||
addNodeView: () => SvelteNodeViewRenderer(GroupComposeLink),
|
addNodeView: () => SvelteNodeViewRenderer(ChatComposeLink),
|
||||||
}),
|
}),
|
||||||
Bolt11Extension.extend(
|
Bolt11Extension.extend(
|
||||||
asInline({addNodeView: () => SvelteNodeViewRenderer(GroupComposeBolt11)}),
|
asInline({addNodeView: () => SvelteNodeViewRenderer(ChatComposeBolt11)}),
|
||||||
),
|
),
|
||||||
NProfileExtension.extend({
|
NProfileExtension.extend({
|
||||||
addNodeView: () => SvelteNodeViewRenderer(GroupComposeMention),
|
addNodeView: () => SvelteNodeViewRenderer(ChatComposeMention),
|
||||||
}),
|
}),
|
||||||
NEventExtension.extend(
|
NEventExtension.extend(asInline({addNodeView: () => SvelteNodeViewRenderer(ChatComposeEvent)})),
|
||||||
asInline({addNodeView: () => SvelteNodeViewRenderer(GroupComposeEvent)}),
|
NAddrExtension.extend(asInline({addNodeView: () => SvelteNodeViewRenderer(ChatComposeEvent)})),
|
||||||
),
|
ImageExtension.extend(asInline({addNodeView: () => SvelteNodeViewRenderer(ChatComposeImage)})),
|
||||||
NAddrExtension.extend(asInline({addNodeView: () => SvelteNodeViewRenderer(GroupComposeEvent)})),
|
VideoExtension.extend(asInline({addNodeView: () => SvelteNodeViewRenderer(ChatComposeVideo)})),
|
||||||
ImageExtension.extend(asInline({addNodeView: () => SvelteNodeViewRenderer(GroupComposeImage)})),
|
|
||||||
VideoExtension.extend(asInline({addNodeView: () => SvelteNodeViewRenderer(GroupComposeVideo)})),
|
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {nip19} from 'nostr-tools'
|
import {nip19} from "nostr-tools"
|
||||||
import type {Page} from "@sveltejs/kit"
|
import type {Page} from "@sveltejs/kit"
|
||||||
import {userMembership, decodeNEvent} from "@app/state"
|
import {userMembership, decodeNEvent} from "@app/state"
|
||||||
|
|
||||||
|
|
@ -6,7 +6,7 @@ export const makeSpacePath = (url: string, extra = "") => {
|
||||||
let path = `/spaces/${nip19.nrelayEncode(url)}`
|
let path = `/spaces/${nip19.nrelayEncode(url)}`
|
||||||
|
|
||||||
if (extra) {
|
if (extra) {
|
||||||
path += '/' + extra
|
path += "/" + extra
|
||||||
}
|
}
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
@ -20,10 +20,11 @@ export const getPrimaryNavItemIndex = ($page: Page) => {
|
||||||
switch (getPrimaryNavItem($page)) {
|
switch (getPrimaryNavItem($page)) {
|
||||||
case "discover":
|
case "discover":
|
||||||
return urls.length + 2
|
return urls.length + 2
|
||||||
case "spaces":
|
case "spaces": {
|
||||||
const routeUrl = decodeNEvent($page.params.nrelay)
|
const routeUrl = decodeNEvent($page.params.nrelay)
|
||||||
|
|
||||||
return urls.findIndex(url => url === routeUrl) + 1
|
return urls.findIndex(url => url === routeUrl) + 1
|
||||||
|
}
|
||||||
case "settings":
|
case "settings":
|
||||||
return urls.length + 3
|
return urls.length + 3
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,10 @@
|
||||||
import {nip19} from 'nostr-tools'
|
import {nip19} from "nostr-tools"
|
||||||
import type {FuseResult} from "fuse.js"
|
|
||||||
import {get, derived, writable} from "svelte/store"
|
import {get, derived, writable} from "svelte/store"
|
||||||
import type {Maybe} from "@welshman/lib"
|
import type {Maybe} from "@welshman/lib"
|
||||||
import {
|
import {setContext, max, groupBy, pushToMapKey, nthEq} from "@welshman/lib"
|
||||||
setContext,
|
|
||||||
max,
|
|
||||||
between,
|
|
||||||
groupBy,
|
|
||||||
pushToMapKey,
|
|
||||||
nthEq,
|
|
||||||
stripProtocol,
|
|
||||||
indexBy,
|
|
||||||
uniq,
|
|
||||||
} from "@welshman/lib"
|
|
||||||
import {
|
import {
|
||||||
getIdFilters,
|
getIdFilters,
|
||||||
getIdentifier,
|
|
||||||
normalizeRelayUrl,
|
|
||||||
RELAYS,
|
RELAYS,
|
||||||
APP_DATA,
|
|
||||||
REACTION,
|
REACTION,
|
||||||
ZAP_RESPONSE,
|
ZAP_RESPONSE,
|
||||||
getRelayTagValues,
|
getRelayTagValues,
|
||||||
|
|
@ -29,21 +15,16 @@ import type {TrustedEvent} from "@welshman/util"
|
||||||
import {
|
import {
|
||||||
pubkey,
|
pubkey,
|
||||||
repository,
|
repository,
|
||||||
createSearch,
|
|
||||||
load,
|
load,
|
||||||
subscribe,
|
subscribe,
|
||||||
collection,
|
collection,
|
||||||
loadRelay,
|
loadRelay,
|
||||||
relaysByPubkey,
|
|
||||||
loadProfile,
|
loadProfile,
|
||||||
profilesByPubkey,
|
profilesByPubkey,
|
||||||
loadRelaySelections,
|
|
||||||
getWriteRelayUrls,
|
|
||||||
getDefaultAppContext,
|
getDefaultAppContext,
|
||||||
getDefaultNetContext,
|
getDefaultNetContext,
|
||||||
makeRouter,
|
makeRouter,
|
||||||
} from "@welshman/app"
|
} from "@welshman/app"
|
||||||
import type {Relay} from "@welshman/app"
|
|
||||||
import type {SubscribeRequestWithHandlers} from "@welshman/net"
|
import type {SubscribeRequestWithHandlers} from "@welshman/net"
|
||||||
import {deriveEvents, deriveEventsMapped, withGetter} from "@welshman/store"
|
import {deriveEvents, deriveEventsMapped, withGetter} from "@welshman/store"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@
|
||||||
freshness,
|
freshness,
|
||||||
storageAdapters,
|
storageAdapters,
|
||||||
} from "@welshman/app"
|
} from "@welshman/app"
|
||||||
import type {PublishStatusData, PublishStatusDataByUrlById} from "@welshman/app"
|
import * as app from "@welshman/app"
|
||||||
import {createEventStore, adapter} from "@welshman/store"
|
import {createEventStore} from "@welshman/store"
|
||||||
import ModalBox from "@lib/components/ModalBox.svelte"
|
import ModalBox from "@lib/components/ModalBox.svelte"
|
||||||
import Toast from "@app/components/Toast.svelte"
|
import Toast from "@app/components/Toast.svelte"
|
||||||
import Landing from "@app/components/Landing.svelte"
|
import Landing from "@app/components/Landing.svelte"
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
Object.assign(window, {get, state})
|
Object.assign(window, {get, ...app, ...state})
|
||||||
|
|
||||||
ready = db
|
ready = db
|
||||||
? Promise.resolve()
|
? Promise.resolve()
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import Masonry from "svelte-bricks"
|
import Masonry from "svelte-bricks"
|
||||||
import {displayRelayUrl} from "@welshman/util"
|
import {displayRelayUrl} from "@welshman/util"
|
||||||
import {load, relaySearch} from "@welshman/app"
|
import {relaySearch} from "@welshman/app"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import {makeSpacePath} from "@app/routes"
|
import {makeSpacePath} from "@app/routes"
|
||||||
import {userMembership, discoverRelays} from "@app/state"
|
import {userMembership, discoverRelays} from "@app/state"
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h2 class="card-title justify-center">{displayRelayUrl(relay.url)}</h2>
|
<h2 class="card-title justify-center">{displayRelayUrl(relay.url)}</h2>
|
||||||
{#if relay.profile?.description}
|
{#if relay.profile?.description}
|
||||||
<p class="py-4 text-sm text-center">{relay.profile.description}</p>
|
<p class="py-4 text-center text-sm">{relay.profile.description}</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import {readable} from "svelte/store"
|
import {readable} from "svelte/store"
|
||||||
import {displayRelayUrl, isShareableRelayUrl} from "@welshman/util"
|
import {displayRelayUrl} from "@welshman/util"
|
||||||
import type {SignedEvent} from "@welshman/util"
|
import {relaySearch} from "@welshman/app"
|
||||||
import {subscribe, loadRelay, relaySearch} from "@welshman/app"
|
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import {INDEXER_RELAYS, discoverRelays} from "@app/state"
|
import {INDEXER_RELAYS, discoverRelays} from "@app/state"
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {nip19} from 'nostr-tools'
|
|
||||||
import {page} from "$app/stores"
|
import {page} from "$app/stores"
|
||||||
import {sort} from '@welshman/lib'
|
import {sort} from "@welshman/lib"
|
||||||
import {displayRelayUrl} from '@welshman/util'
|
import {displayRelayUrl} from "@welshman/util"
|
||||||
import {fly} from "@lib/transition"
|
import {fly} from "@lib/transition"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import Page from "@lib/components/Page.svelte"
|
import Page from "@lib/components/Page.svelte"
|
||||||
|
|
@ -104,7 +103,8 @@
|
||||||
{#each rooms as topic, i (topic)}
|
{#each rooms as topic, i (topic)}
|
||||||
<div transition:fly|local={{delay: 250 + i * 50}}>
|
<div transition:fly|local={{delay: 250 + i * 50}}>
|
||||||
<SecondaryNavItem href={makeSpacePath(url, topic)}>
|
<SecondaryNavItem href={makeSpacePath(url, topic)}>
|
||||||
<Icon icon="hashtag" /> {topic}
|
<Icon icon="hashtag" />
|
||||||
|
{topic}
|
||||||
</SecondaryNavItem>
|
</SecondaryNavItem>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@
|
||||||
import {subscribe, formatTimestampAsDate} from "@welshman/app"
|
import {subscribe, formatTimestampAsDate} from "@welshman/app"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import GroupNote from "@app/components/GroupNote.svelte"
|
import ChatMessage from "@app/components/ChatMessage.svelte"
|
||||||
import GroupCompose from "@app/components/GroupCompose.svelte"
|
import ChatCompose from "@app/components/ChatCompose.svelte"
|
||||||
import {deriveChat, userMembership, MESSAGE, REPLY} from "@app/state"
|
import {deriveChat, MESSAGE, REPLY} from "@app/state"
|
||||||
|
|
||||||
const {url, topic} = $page.params
|
const {url, topic} = $page.params
|
||||||
const chat = deriveChat(url)
|
const chat = deriveChat(url)
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const since = now() - 30
|
const since = now() - 30
|
||||||
const kinds = [MESSAGE, REPLY]
|
const kinds = [MESSAGE, REPLY]
|
||||||
const filter = topic ? {kinds, since, "#t": [topic]} : {kinds, since} as Filter
|
const filter = topic ? {kinds, since, "#t": [topic]} : ({kinds, since} as Filter)
|
||||||
const sub = subscribe({filters: [filter], relays: [url]})
|
const sub = subscribe({filters: [filter], relays: [url]})
|
||||||
|
|
||||||
return () => sub.close()
|
return () => sub.close()
|
||||||
|
|
@ -87,7 +87,7 @@
|
||||||
<div class="h-px flex-grow bg-base-content opacity-25" />
|
<div class="h-px flex-grow bg-base-content opacity-25" />
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<GroupNote event={assertEvent(value)} {showPubkey} />
|
<ChatMessage event={assertEvent(value)} {showPubkey} />
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
<p class="flex h-10 items-center justify-center py-20">
|
<p class="flex h-10 items-center justify-center py-20">
|
||||||
|
|
@ -100,5 +100,5 @@
|
||||||
</Spinner>
|
</Spinner>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<GroupCompose {url} {topic} />
|
<ChatCompose {url} {topic} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue