mirror of
https://github.com/coracle-social/flotilla.git
synced 2025-12-11 11:27:03 +00:00
Re-work relays page
This commit is contained in:
16
src/app.css
16
src/app.css
@@ -51,16 +51,20 @@
|
||||
--secondary: oklch(var(--s));
|
||||
}
|
||||
|
||||
.bg-alt, .bg-alt .bg-alt .bg-alt {
|
||||
@apply bg-base-100;
|
||||
}
|
||||
|
||||
.bg-alt .bg-alt, .bg-alt .bg-alt .bg-alt .bg-alt {
|
||||
@apply bg-base-300;
|
||||
}
|
||||
|
||||
.card2 {
|
||||
@apply text-ellipsis rounded-box bg-base-100 p-6 text-base-content;
|
||||
@apply text-ellipsis rounded-box p-6 text-base-content;
|
||||
}
|
||||
|
||||
.card2.card2-sm {
|
||||
@apply rounded-box bg-base-100 p-4 text-base-content;
|
||||
}
|
||||
|
||||
.card2.card2-alt {
|
||||
@apply bg-base-300;
|
||||
@apply p-4 text-base-content;
|
||||
}
|
||||
|
||||
.column {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {uniqBy, sleep, chunk, equals, choice} from "@welshman/lib"
|
||||
import {DELETE, REACTION, getPubkeyTagValues, createEvent, displayProfile} from "@welshman/util"
|
||||
import {uniqBy, sleep, chunk, equals, choice, append} from "@welshman/lib"
|
||||
import {DELETE, MUTES, FOLLOWS, REACTION, getPubkeyTagValues, createEvent, displayProfile} from "@welshman/util"
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import type {SubscribeRequestWithHandlers} from "@welshman/net"
|
||||
import {
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
loadMutes,
|
||||
getFollows,
|
||||
tagEvent,
|
||||
tagPubkey,
|
||||
tagReactionTo,
|
||||
} from "@welshman/app"
|
||||
import {tagRoom, MEMBERSHIPS, INDEXER_RELAYS} from "@app/state"
|
||||
@@ -110,6 +111,19 @@ export const removeSpaceMembership = (url: string) =>
|
||||
export const removeRoomMembership = (url: string, room: string) =>
|
||||
updateList(MEMBERSHIPS, (tags: string[][]) => tags.filter(t => !equals(tagRoom(room, url), t)))
|
||||
|
||||
|
||||
export const unfollowPerson = (pubkey: string) =>
|
||||
updateList(FOLLOWS, tags => tags.filter(t => t[1] !== pubkey))
|
||||
|
||||
export const followPerson = (pubkey: string) =>
|
||||
updateList(FOLLOWS, tags => append(tagPubkey(pubkey), tags))
|
||||
|
||||
export const unmutePerson = (pubkey: string) =>
|
||||
updateList(MUTES, tags => tags.filter(t => t[1] !== pubkey))
|
||||
|
||||
export const mutePerson = (pubkey: string) =>
|
||||
updateList(MUTES, tags => append(tagPubkey(pubkey), tags))
|
||||
|
||||
// Actions
|
||||
|
||||
export const publishReaction = ({relays, event, content, tags = []}: {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import {onMount} from 'svelte'
|
||||
import {getAddress, Address} from "@welshman/util"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import NoteCard from "@app/components/NoteCard.svelte"
|
||||
@@ -13,25 +12,18 @@
|
||||
const event = deriveEvent(idOrAddress, relays)
|
||||
|
||||
let element: Element
|
||||
let bgClass = "bg-base-300"
|
||||
|
||||
$: address = $event ? getAddress($event) : ""
|
||||
$: isGroup = address.match(/^(34550|35834):/)
|
||||
|
||||
onMount(() => {
|
||||
if (element.closest('.bg-base-300')) {
|
||||
bgClass = 'bg-base-100'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<button class="block text-left my-2 max-w-full" bind:this={element} on:click|stopPropagation>
|
||||
{#if $event}
|
||||
<NoteCard event={$event} class="p-4 rounded-box {bgClass}">
|
||||
<NoteCard event={$event} class="p-4 rounded-box bg-alt">
|
||||
<slot name="note-content" event={$event} {depth} />
|
||||
</NoteCard>
|
||||
{:else}
|
||||
<div class="p-4 rounded-box {bgClass}">
|
||||
<div class="p-4 rounded-box">
|
||||
<Spinner loading>Loading event...</Spinner>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
50
src/app/components/RelayAdd.svelte
Normal file
50
src/app/components/RelayAdd.svelte
Normal file
@@ -0,0 +1,50 @@
|
||||
<script lang="ts">
|
||||
import {onMount} from 'svelte'
|
||||
import type {Readable} from 'svelte/store'
|
||||
import {relaySearch} from "@welshman/app"
|
||||
import {createScroller} from "@lib/html"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import RelayItem from "@app/components/RelayItem.svelte"
|
||||
import {discoverRelays} from "@app/state"
|
||||
|
||||
export let mode: string
|
||||
export let relays: Readable<string[]>
|
||||
|
||||
const addRelay = (url: string) => null
|
||||
|
||||
let term = ""
|
||||
let limit = 20
|
||||
let element: Element
|
||||
|
||||
onMount(() => {
|
||||
const sub = discoverRelays()
|
||||
const scroller = createScroller({
|
||||
delay: 300,
|
||||
element: element.closest('.modal-box')!,
|
||||
onScroll: () => {
|
||||
limit += 20
|
||||
},
|
||||
})
|
||||
|
||||
return () => {
|
||||
sub.close()
|
||||
scroller.stop()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="column gap-2" bind:this={element}>
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<Icon icon="magnifer" />
|
||||
<input bind:value={term} class="grow" type="text" placeholder="Search for relays..." />
|
||||
</label>
|
||||
{#each $relaySearch.searchValues(term).filter(url => !$relays.includes(url)).slice(0, limit) as url (url)}
|
||||
<RelayItem {url}>
|
||||
<Button class="btn btn-outline btn-sm flex items-center" on:click={() => addRelay(url)}>
|
||||
<Icon icon="add-circle" />
|
||||
Add Relay
|
||||
</Button>
|
||||
</RelayItem>
|
||||
{/each}
|
||||
</div>
|
||||
40
src/app/components/RelayItem.svelte
Normal file
40
src/app/components/RelayItem.svelte
Normal file
@@ -0,0 +1,40 @@
|
||||
<script lang="ts">
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import {displayUrl} from '@welshman/lib'
|
||||
import {displayRelayUrl} from '@welshman/util'
|
||||
import {deriveRelay} from '@welshman/app'
|
||||
|
||||
export let url
|
||||
|
||||
const relay = deriveRelay(url)
|
||||
|
||||
$: connections = $relay?.stats?.connect_count || 0
|
||||
</script>
|
||||
|
||||
<div class="card2 card2-sm bg-alt column gap-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<Icon icon="remote-controller-minimalistic" />
|
||||
{displayRelayUrl(url)}
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
{#if $relay?.profile?.description}
|
||||
<p>{$relay?.profile.description}</p>
|
||||
{/if}
|
||||
<span class="flex items-center gap-1 text-sm">
|
||||
{#if $relay?.profile?.contact}
|
||||
<Link external class="underline" href={$relay.profile.contact}
|
||||
>{displayUrl($relay.profile.contact)}</Link>
|
||||
•
|
||||
{/if}
|
||||
{#if $relay?.profile?.supported_nips}
|
||||
<span class="cursor-pointer underline tooltip" data-tip="NIPs supported: {$relay.profile.supported_nips.join(", ")}">
|
||||
{$relay.profile.supported_nips.length} NIPs
|
||||
</span>
|
||||
•
|
||||
{/if}
|
||||
Connected {connections} {connections === 1 ? 'time' : 'times'}
|
||||
</span>
|
||||
</div>
|
||||
3
src/assets/icons/Alt Arrow Up.svg
Normal file
3
src/assets/icons/Alt Arrow Up.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19 15L12 9L5 15" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 215 B |
4
src/assets/icons/Inbox.svg
Normal file
4
src/assets/icons/Inbox.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C22 4.92893 22 7.28595 22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12Z" stroke="#1C274C" stroke-width="1.5"/>
|
||||
<path d="M2 13H5.16026C6.06543 13 6.51802 13 6.91584 13.183C7.31367 13.3659 7.60821 13.7096 8.19729 14.3968L8.80271 15.1032C9.39179 15.7904 9.68633 16.1341 10.0842 16.317C10.482 16.5 10.9346 16.5 11.8397 16.5H12.1603C13.0654 16.5 13.518 16.5 13.9158 16.317C14.3137 16.1341 14.6082 15.7904 15.1973 15.1032L15.8027 14.3968C16.3918 13.7096 16.6863 13.3659 17.0842 13.183C17.482 13 17.9346 13 18.8397 13H22" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 873 B |
6
src/assets/icons/Mailbox.svg
Normal file
6
src/assets/icons/Mailbox.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.5 22V20M14.5 22V20" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M11 20V20.75H11.75V20H11ZM14 19.25C13.5858 19.25 13.25 19.5858 13.25 20C13.25 20.4142 13.5858 20.75 14 20.75V19.25ZM17.5 5.25C17.0858 5.25 16.75 5.58579 16.75 6C16.75 6.41421 17.0858 6.75 17.5 6.75V5.25ZM7 5.25C6.58579 5.25 6.25 5.58579 6.25 6C6.25 6.41421 6.58579 6.75 7 6.75V5.25ZM9 19.25C8.58579 19.25 8.25 19.5858 8.25 20C8.25 20.4142 8.58579 20.75 9 20.75V19.25ZM15 20.75C15.4142 20.75 15.75 20.4142 15.75 20C15.75 19.5858 15.4142 19.25 15 19.25V20.75ZM10.25 11.25V20H11.75V11.25H10.25ZM11 19.25H4.23256V20.75H11V19.25ZM2.75 17.3953V11.25H1.25V17.3953H2.75ZM4.23256 19.25C3.51806 19.25 2.75 18.5323 2.75 17.3953H1.25C1.25 19.1354 2.48104 20.75 4.23256 20.75V19.25ZM6.5 6.75C8.46677 6.75 10.25 8.65209 10.25 11.25H11.75C11.75 8.04892 9.50379 5.25 6.5 5.25V6.75ZM6.5 5.25C3.49621 5.25 1.25 8.04892 1.25 11.25H2.75C2.75 8.65209 4.53323 6.75 6.5 6.75V5.25ZM21.25 11.25V17.4253H22.75V11.25H21.25ZM19.7931 19.25H14V20.75H19.7931V19.25ZM21.25 17.4253C21.25 18.5457 20.4934 19.25 19.7931 19.25V20.75C21.5305 20.75 22.75 19.1488 22.75 17.4253H21.25ZM22.75 11.25C22.75 8.04892 20.5038 5.25 17.5 5.25V6.75C19.4668 6.75 21.25 8.65209 21.25 11.25H22.75ZM7 6.75H18V5.25H7V6.75ZM9 20.75H15V19.25H9V20.75Z" fill="#1C274C"/>
|
||||
<path d="M5 16H8" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M16 9.88432V5.41121M16 5.41121V2.63519C16 2.39905 16.1676 2.19612 16.3994 2.15144L16.8855 2.05779C17.4738 1.94443 18.0821 1.99855 18.6412 2.214L18.7203 2.24451C19.2746 2.4581 19.8807 2.498 20.4582 2.35891C20.7343 2.2924 21 2.50168 21 2.78573V5.00723C21 5.2442 20.8376 5.45031 20.6073 5.5058L20.5407 5.52184C19.9095 5.67387 19.247 5.63026 18.6412 5.39679C18.0821 5.18135 17.4738 5.12722 16.8855 5.24058L16 5.41121Z" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
27
src/lib/components/Collapse.svelte
Normal file
27
src/lib/components/Collapse.svelte
Normal file
@@ -0,0 +1,27 @@
|
||||
<script lang="ts">
|
||||
import {slide} from '@lib/transition'
|
||||
import Icon from '@lib/components/Icon.svelte'
|
||||
|
||||
const toggle = () => {
|
||||
isOpen = !isOpen
|
||||
}
|
||||
|
||||
let isOpen = false
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-4 relative {$$props.class}">
|
||||
<button
|
||||
type="button"
|
||||
class="absolute top-8 right-8 cursor-pointer w-4 h-4 transition-all"
|
||||
class:rotate-90={!isOpen}
|
||||
on:click={toggle}>
|
||||
<Icon icon="alt-arrow-down" />
|
||||
</button>
|
||||
<slot name="title" />
|
||||
<slot name="description" />
|
||||
{#if isOpen}
|
||||
<div transition:slide>
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -19,6 +19,7 @@
|
||||
import AddCircle from "@assets/icons/Add Circle.svg?dataurl"
|
||||
import AltArrowDown from "@assets/icons/Alt Arrow Down.svg?dataurl"
|
||||
import AltArrowRight from "@assets/icons/Alt Arrow Right.svg?dataurl"
|
||||
import AltArrowUp from "@assets/icons/Alt Arrow Up.svg?dataurl"
|
||||
import AltArrowLeft from "@assets/icons/Alt Arrow Left.svg?dataurl"
|
||||
import ArrowRight from "@assets/icons/Arrow Right.svg?dataurl"
|
||||
import Bag from "@assets/icons/Bag.svg?dataurl"
|
||||
@@ -41,6 +42,7 @@
|
||||
import Hashtag from "@assets/icons/Hashtag.svg?dataurl"
|
||||
import HandPills from "@assets/icons/Hand Pills.svg?dataurl"
|
||||
import HomeSmile from "@assets/icons/Home Smile.svg?dataurl"
|
||||
import Inbox from "@assets/icons/Inbox.svg?dataurl"
|
||||
import InfoCircle from "@assets/icons/Info Circle.svg?dataurl"
|
||||
import InfoSquare from "@assets/icons/Info Square.svg?dataurl"
|
||||
import Key from "@assets/icons/Key.svg?dataurl"
|
||||
@@ -48,6 +50,7 @@
|
||||
import Login from "@assets/icons/Login.svg?dataurl"
|
||||
import Login2 from "@assets/icons/Login 2.svg?dataurl"
|
||||
import Magnifer from "@assets/icons/Magnifer.svg?dataurl"
|
||||
import Mailbox from "@assets/icons/Mailbox.svg?dataurl"
|
||||
import MapPoint from "@assets/icons/Map Point.svg?dataurl"
|
||||
import MenuDots from "@assets/icons/Menu Dots.svg?dataurl"
|
||||
import NotesMinimalistic from "@assets/icons/Notes Minimalistic.svg?dataurl"
|
||||
@@ -86,6 +89,7 @@
|
||||
"add-circle": AddCircle,
|
||||
"alt-arrow-down": AltArrowDown,
|
||||
"alt-arrow-right": AltArrowRight,
|
||||
"alt-arrow-up": AltArrowUp,
|
||||
"alt-arrow-left": AltArrowLeft,
|
||||
"arrow-right": ArrowRight,
|
||||
bag: Bag,
|
||||
@@ -108,6 +112,7 @@
|
||||
hashtag: Hashtag,
|
||||
"hand-pills": HandPills,
|
||||
"home-smile": HomeSmile,
|
||||
"inbox": Inbox,
|
||||
"info-circle": InfoCircle,
|
||||
"info-square": InfoSquare,
|
||||
key: Key,
|
||||
@@ -115,6 +120,7 @@
|
||||
login: Login,
|
||||
"login-2": Login2,
|
||||
magnifer: Magnifer,
|
||||
mailbox: Mailbox,
|
||||
"map-point": MapPoint,
|
||||
"menu-dots": MenuDots,
|
||||
"notes-minimalistic": NotesMinimalistic,
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
export let props = {}
|
||||
</script>
|
||||
|
||||
<div class="modal-box" transition:fly={{duration: 100}}>
|
||||
<div class="modal-box bg-alt" transition:fly={{duration: 100}}>
|
||||
<svelte:component this={component} {...props} />
|
||||
</div>
|
||||
|
||||
@@ -1,92 +1,114 @@
|
||||
<script lang="ts">
|
||||
import {onMount} from "svelte"
|
||||
import {derived} from "svelte/store"
|
||||
import {uniq} from "@welshman/lib"
|
||||
import {displayRelayUrl} from "@welshman/util"
|
||||
import type {Readable} from 'svelte/store'
|
||||
import {relaySearch, getRelayUrls, userRelaySelections, userInboxRelaySelections, getReadRelayUrls, getWriteRelayUrls} from "@welshman/app"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import {INDEXER_RELAYS, discoverRelays} from "@app/state"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Collapse from "@lib/components/Collapse.svelte"
|
||||
import RelayItem from "@app/components/RelayItem.svelte"
|
||||
import RelayAdd from "@app/components/RelayAdd.svelte"
|
||||
import {pushModal} from '@app/modal'
|
||||
|
||||
const readRelayUrls = derived(userRelaySelections, getReadRelayUrls)
|
||||
const writeRelayUrls = derived(userRelaySelections, getWriteRelayUrls)
|
||||
const inboxRelayUrls = derived(userInboxRelaySelections, getRelayUrls)
|
||||
|
||||
const removeRelay = (url: string) => null
|
||||
const addRelay = (mode: string, relays: Readable<string[]>) =>
|
||||
pushModal(RelayAdd, {mode, relays})
|
||||
|
||||
const addRelay = (url: string) => null
|
||||
const removeReadRelay = (url: string) => null
|
||||
|
||||
let term = ""
|
||||
let currentRelayUrls: string[] = []
|
||||
const removeWriteRelay = (url: string) => null
|
||||
|
||||
$: currentRelayUrls = uniq([
|
||||
...currentRelayUrls,
|
||||
...getRelayUrls($userRelaySelections),
|
||||
...getRelayUrls($userInboxRelaySelections),
|
||||
]).sort()
|
||||
|
||||
onMount(() => {
|
||||
const sub = discoverRelays()
|
||||
|
||||
return () => sub.close()
|
||||
})
|
||||
const removeInboxRelay = (url: string) => null
|
||||
</script>
|
||||
|
||||
<div class="content column gap-4">
|
||||
<h1 class="superheading mt-20">Relays</h1>
|
||||
<p class="text-center">Get connected with the nostr network</p>
|
||||
{#each currentRelayUrls as url}
|
||||
{@const read = $readRelayUrls.includes(url)}
|
||||
{@const write = $writeRelayUrls.includes(url)}
|
||||
{@const inbox = $inboxRelayUrls.includes(url)}
|
||||
<div class="card2 card2-sm flex flex-col gap-2 overflow-visible">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<Icon icon="remote-controller-minimalistic" />
|
||||
{displayRelayUrl(url)}
|
||||
</div>
|
||||
<Button class="flex items-center" on:click={() => removeRelay(url)}>
|
||||
<Icon icon="close-circle" />
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex gap-3">
|
||||
<div
|
||||
class="tooltip tooltip-right"
|
||||
data-tip="Notes for you will {read ? '' : 'not'} be sent here.">
|
||||
<Button class="btn btn-sm btn-{read ? 'primary' : 'neutral'}">
|
||||
Read
|
||||
<Collapse class="card2 bg-alt column gap-4">
|
||||
<h2 slot="title" class="text-xl flex items-center gap-3">
|
||||
<Icon icon="earth" />
|
||||
Broadcast Relays
|
||||
</h2>
|
||||
<p slot="description" class="text-sm">
|
||||
These relays will be advertised on your profile as places where you send your public
|
||||
notes. Be sure to select relays that will accept your notes, and which will let people
|
||||
who follow you read them.
|
||||
</p>
|
||||
<div class="column gap-2">
|
||||
{#each $writeRelayUrls.sort() as url (url)}
|
||||
<RelayItem {url}>
|
||||
<Button
|
||||
class="flex items-center tooltip"
|
||||
data-tip="Stop using this relay"
|
||||
on:click={() => removeWriteRelay(url)}>
|
||||
<Icon icon="close-circle" />
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
class="tooltip tooltip-right"
|
||||
data-tip="Notes you publish will {write ? '' : 'not'} be sent here.">
|
||||
<Button class="btn btn-sm btn-{write ? 'primary' : 'neutral'}">
|
||||
Write
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
class="tooltip tooltip-right"
|
||||
data-tip="Direct messages will {inbox ? '' : 'not'} be sent here.">
|
||||
<Button class="btn btn-sm btn-{inbox ? 'primary' : 'neutral'}">
|
||||
Inbox
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<Icon icon="magnifer" />
|
||||
<input bind:value={term} class="grow" type="text" placeholder="Search for relays..." />
|
||||
</label>
|
||||
{#each $relaySearch.searchValues(term).filter(url => !currentRelayUrls.includes(url)) as url (url)}
|
||||
<div class="card2 card2-sm flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<Icon icon="remote-controller-minimalistic" />
|
||||
{displayRelayUrl(url)}
|
||||
</div>
|
||||
<Button class="flex items-center" on:click={() => addRelay(url)}>
|
||||
</RelayItem>
|
||||
{:else}
|
||||
<p class="text-center text-sm">No relays found</p>
|
||||
{/each}
|
||||
<Button class="btn btn-primary mt-2" on:click={() => addRelay('write', writeRelayUrls)}>
|
||||
<Icon icon="add-circle" />
|
||||
Add Relay
|
||||
</Button>
|
||||
</div>
|
||||
{/each}
|
||||
</Collapse>
|
||||
<Collapse class="card2 bg-alt column gap-4">
|
||||
<h2 slot="title" class="text-xl flex items-center gap-3">
|
||||
<Icon icon="inbox" />
|
||||
Inbox Relays
|
||||
</h2>
|
||||
<p slot="description" class="text-sm">
|
||||
These relays will be advertised on your profile as places where other people should
|
||||
send notes intended for you. Be sure to select relays that will accept notes that
|
||||
tag you.
|
||||
</p>
|
||||
<div class="column gap-2">
|
||||
{#each $readRelayUrls.sort() as url (url)}
|
||||
<RelayItem {url}>
|
||||
<Button
|
||||
class="flex items-center tooltip"
|
||||
data-tip="Stop using this relay"
|
||||
on:click={() => removeReadRelay(url)}>
|
||||
<Icon icon="close-circle" />
|
||||
</Button>
|
||||
</RelayItem>
|
||||
{:else}
|
||||
<p class="text-center text-sm">No relays found</p>
|
||||
{/each}
|
||||
<Button class="btn btn-primary mt-2" on:click={() => addRelay('read', readRelayUrls)}>
|
||||
<Icon icon="add-circle" />
|
||||
Add Relay
|
||||
</Button>
|
||||
</div>
|
||||
</Collapse>
|
||||
<Collapse class="card2 bg-alt column gap-4">
|
||||
<h2 slot="title" class="text-xl flex items-center gap-3">
|
||||
<Icon icon="mailbox" />
|
||||
Messaging Relays
|
||||
</h2>
|
||||
<p slot="description" class="text-sm">
|
||||
These relays will be advertised on your profile as places you use to send and
|
||||
receive direct messages. Be sure to select relays that will accept your messages
|
||||
and messages from people you'd like to be in contact with.
|
||||
</p>
|
||||
<div class="column gap-2">
|
||||
{#each $inboxRelayUrls.sort() as url (url)}
|
||||
<RelayItem {url}>
|
||||
<Button
|
||||
class="flex items-center tooltip"
|
||||
data-tip="Stop using this relay"
|
||||
on:click={() => removeInboxRelay(url)}>
|
||||
<Icon icon="close-circle" />
|
||||
</Button>
|
||||
</RelayItem>
|
||||
{:else}
|
||||
<p class="text-center text-sm">No relays found</p>
|
||||
{/each}
|
||||
<Button class="btn btn-primary mt-2" on:click={() => addRelay('inbox', inboxRelayUrls)}>
|
||||
<Icon icon="add-circle" />
|
||||
Add Relay
|
||||
</Button>
|
||||
</div>
|
||||
</Collapse>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user