mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-18 19:23:40 +00:00
Work on making relays mute-able
This commit is contained in:
parent
a166612601
commit
3b6f1f0fa6
@ -64,8 +64,8 @@
|
||||
import PersonProfileInfo from "src/views/person/PersonProfileInfo.svelte"
|
||||
import PersonShare from "src/views/person/PersonShare.svelte"
|
||||
import AddRelay from "src/views/relays/AddRelay.svelte"
|
||||
import RelayCard from "src/views/relays/RelayCard.svelte"
|
||||
import GlobalRelays from "src/views/relays/GlobalRelays.svelte"
|
||||
import RelayModal from "src/views/relays/RelayModal.svelte"
|
||||
import MuteRelays from "src/views/relays/MuteRelays.svelte"
|
||||
|
||||
Object.assign(window, {cmd, user, keys, network, pool, sync, tables, bech32ToHex, hexToBech32})
|
||||
|
||||
@ -279,8 +279,10 @@
|
||||
<NoteCreate pubkey={$modal.pubkey} nevent={$modal.nevent} />
|
||||
{:else if $modal.type === "relay/add"}
|
||||
<AddRelay />
|
||||
{:else if $modal.type === "relays/global"}
|
||||
<GlobalRelays />
|
||||
{:else if $modal.type === "relays/mute"}
|
||||
<MuteRelays />
|
||||
{:else if $modal.type === "relays/modal"}
|
||||
<RelayModal url={$modal.url} />
|
||||
{:else if $modal.type === "onboarding"}
|
||||
<Onboarding stage={$modal.stage} />
|
||||
{:else if $modal.type === "room/edit"}
|
||||
|
@ -151,4 +151,4 @@ export const getThemeVariables = $theme =>
|
||||
|
||||
// Global relay setting
|
||||
|
||||
export const globalRelays = new WritableList([])
|
||||
export const muteRelays = new WritableList([])
|
||||
|
@ -19,6 +19,8 @@
|
||||
"py-2 px-4 rounded bg-input text-accent whitespace-nowrap border border-solid border-gray-6 hover:bg-input-hover",
|
||||
"button-circle":
|
||||
"w-10 h-10 flex justify-center items-center rounded-full bg-input text-accent whitespace-nowrap border border-solid border-gray-6 hover:bg-input-hover",
|
||||
"button-circle-dark":
|
||||
"w-10 h-10 flex justify-center items-center rounded-full bg-gray-8 text-white whitespace-nowrap border border-solid border-gray-7",
|
||||
"button-accent":
|
||||
"py-2 px-4 rounded bg-accent text-white whitespace-nowrap border border-solid border-accent-light hover:bg-accent-light",
|
||||
})
|
||||
|
@ -13,10 +13,7 @@
|
||||
let showModal = false
|
||||
|
||||
// Put previews last since we need to load them asynchronously
|
||||
const annotated = sortBy(
|
||||
({type}) => (type === "preview" ? 1 : 0),
|
||||
links.filter(url => !url.startsWith("ws")).map(annotateMedia)
|
||||
)
|
||||
const annotated = sortBy(l => (l.type === "preview" ? 1 : 0), links.map(annotateMedia))
|
||||
|
||||
const close = () => {
|
||||
onClose?.()
|
||||
|
@ -8,6 +8,7 @@
|
||||
export let theme = "dark"
|
||||
export let triggerType = "click"
|
||||
export let placement = "top"
|
||||
export let interactive = true
|
||||
|
||||
let trigger
|
||||
let tooltip
|
||||
@ -19,7 +20,7 @@
|
||||
placement: placement as Placement,
|
||||
appendTo: () => document.body,
|
||||
allowHTML: true,
|
||||
interactive: true,
|
||||
interactive,
|
||||
trigger: triggerType,
|
||||
animation: "shift-away",
|
||||
onShow: () => {
|
||||
|
@ -1,94 +1,37 @@
|
||||
<script lang="ts">
|
||||
import {find, propEq} from "ramda"
|
||||
import {onMount} from "svelte"
|
||||
import {poll, stringToHue, hsl} from "src/util/misc"
|
||||
import {displayRelay} from "src/util/nostr"
|
||||
import {between} from "hurdak/lib/hurdak"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
import Anchor from "src/partials/Anchor.svelte"
|
||||
import Feed from "src/views/feed/Feed.svelte"
|
||||
import RelayTitle from "src/views/relays/RelayTitle.svelte"
|
||||
import RelayJoin from "src/views/relays/RelayJoin.svelte"
|
||||
import {relays} from "src/agent/tables"
|
||||
import pool from "src/agent/pool"
|
||||
import user from "src/agent/user"
|
||||
import {muteRelays} from "src/app/ui"
|
||||
|
||||
export let url
|
||||
|
||||
const relay = relays.get(url) || {url}
|
||||
|
||||
let quality = null
|
||||
let message = null
|
||||
let showStatus = false
|
||||
let joined = false
|
||||
|
||||
const {relays: userRelays} = user
|
||||
|
||||
$: joined = find(propEq("url", relay.url), $userRelays)
|
||||
|
||||
onMount(() => {
|
||||
return poll(10_000, async () => {
|
||||
;[quality, message] = pool.getQuality(relay.url)
|
||||
})
|
||||
})
|
||||
|
||||
document.title = displayRelay(relay)
|
||||
</script>
|
||||
|
||||
<Content>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div class="flex items-center gap-2 text-xl">
|
||||
<i class={relay.url.startsWith("wss") ? "fa fa-lock" : "fa fa-unlock"} />
|
||||
<span class="border-b border-solid" style={`border-color: ${hsl(stringToHue(relay.url))}`}>
|
||||
{displayRelay(relay)}
|
||||
</span>
|
||||
<span
|
||||
on:mouseout={() => {
|
||||
showStatus = false
|
||||
}}
|
||||
on:mouseover={() => {
|
||||
showStatus = true
|
||||
}}
|
||||
class="h-2 w-2 cursor-pointer rounded-full bg-gray-6"
|
||||
class:bg-gray-6={message === "Not connected"}
|
||||
class:bg-danger={quality <= 0.3 && message !== "Not connected"}
|
||||
class:bg-warning={between(0.3, 0.7, quality)}
|
||||
class:bg-success={quality > 0.7} />
|
||||
<p
|
||||
class="hidden text-sm text-gray-1 transition-all sm:block"
|
||||
class:opacity-0={!showStatus}
|
||||
class:opacity-1={showStatus}>
|
||||
{message}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-3 whitespace-nowrap">
|
||||
{#if relay.contact}
|
||||
<Anchor type="button-circle" href={`mailto:${relay.contact}`}>
|
||||
<i class="fa fa-envelope" />
|
||||
</Anchor>
|
||||
{/if}
|
||||
{#if joined}
|
||||
{#if $userRelays.length > 1}
|
||||
<Anchor
|
||||
type="button"
|
||||
class="flex items-center gap-2 rounded-full"
|
||||
on:click={() => user.removeRelay(relay.url)}>
|
||||
<i class="fa fa-right-from-bracket" /> Leave
|
||||
</Anchor>
|
||||
{/if}
|
||||
{:else}
|
||||
<Anchor
|
||||
type="button"
|
||||
class="flex items-center gap-2 rounded-full"
|
||||
on:click={() => user.addRelay(relay.url)}>
|
||||
<i class="fa fa-right-to-bracket" /> Join
|
||||
</Anchor>
|
||||
{/if}
|
||||
</div>
|
||||
<RelayTitle {relay} />
|
||||
<RelayJoin {relay} />
|
||||
</div>
|
||||
{#if relay.description}
|
||||
<p>{relay.description}</p>
|
||||
{/if}
|
||||
</Content>
|
||||
<div class="border-b border-solid border-gray-6" />
|
||||
<Content>
|
||||
<Feed relays={[relay]} filter={{kinds: [1]}} />
|
||||
</Content>
|
||||
{#if $muteRelays.includes(relay.url)}
|
||||
<Content size="lg" class="text-center">
|
||||
This relay has been muted.
|
||||
<Anchor on:click={() => muteRelays.remove(relay.url)}>Unmute</Anchor>
|
||||
</Content>
|
||||
{:else}
|
||||
<Content>
|
||||
<Feed relays={[relay]} filter={{kinds: [1]}} />
|
||||
</Content>
|
||||
{/if}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import {onMount} from "svelte"
|
||||
import {objOf, partition, intersection, always, propEq, uniqBy, sortBy, prop} from "ramda"
|
||||
import {find, partition, always, propEq, uniqBy, sortBy, prop} from "ramda"
|
||||
import {fly} from "svelte/transition"
|
||||
import {quantify} from "hurdak/lib/hurdak"
|
||||
import {createScroller, now, timedelta, Cursor} from "src/util/misc"
|
||||
@ -10,7 +10,7 @@
|
||||
import Note from "src/views/notes/Note.svelte"
|
||||
import user from "src/agent/user"
|
||||
import network from "src/agent/network"
|
||||
import {modal, globalRelays} from "src/app/ui"
|
||||
import {modal, muteRelays} from "src/app/ui"
|
||||
import {mergeParents} from "src/app"
|
||||
|
||||
export let filter
|
||||
@ -89,7 +89,7 @@
|
||||
|
||||
onMount(() => {
|
||||
const sub = network.listen({
|
||||
relays,
|
||||
relays: relays.filter(url => !$muteRelays.includes(url)),
|
||||
filter: mergeFilter(filter, {since}),
|
||||
onChunk,
|
||||
})
|
||||
@ -101,7 +101,7 @@
|
||||
|
||||
// Wait for this page to load before trying again
|
||||
await network.load({
|
||||
relays: $globalRelays.length > 0 ? $globalRelays.map(objOf("url")) : relays,
|
||||
relays: relays.filter(url => !$muteRelays.includes(url)),
|
||||
filter: mergeFilter(filter, cursor.getFilter()),
|
||||
onChunk,
|
||||
})
|
||||
@ -133,7 +133,7 @@
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
{#each notes as note (note.id)}
|
||||
{#if $globalRelays.length === 0 || intersection(note.seen_on, $globalRelays)}
|
||||
{#if find(url => !$muteRelays.includes(url), note.seen_on)}
|
||||
<Note depth={2} {note} />
|
||||
{/if}
|
||||
{/each}
|
||||
|
@ -1,30 +1,27 @@
|
||||
<script lang="ts">
|
||||
import {fly} from "svelte/transition"
|
||||
import {quantify} from "hurdak/lib/hurdak"
|
||||
import Anchor from "src/partials/Anchor.svelte"
|
||||
import Popover from "src/partials/Popover.svelte"
|
||||
import user from "src/agent/user"
|
||||
import {modal, globalRelays} from "src/app/ui"
|
||||
import {modal, muteRelays} from "src/app/ui"
|
||||
|
||||
export let pubkey = null
|
||||
|
||||
const {canPublish} = user
|
||||
|
||||
const openModal = () => {
|
||||
modal.set({type: "relays/global"})
|
||||
modal.set({type: "relays/mute"})
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="fixed bottom-0 right-0 z-10 m-8 flex flex-col items-center gap-3">
|
||||
<div
|
||||
transition:fly|local={{y: 20}}
|
||||
class="transition-transform hover:scale-105 relative">
|
||||
<Anchor type="button-circle" on:click={openModal}>
|
||||
<div transition:fly|local={{y: 20}} class="relative transition-transform hover:scale-105">
|
||||
<Anchor type="button-circle-dark" on:click={openModal}>
|
||||
<i class="fa fa-filter mt-1" />
|
||||
<span class="rounded-full absolute w-5 h-5 text-xs bottom-0 right-0 bg-gray-1
|
||||
border border-solid border-gray-3 flex justify-center items-center
|
||||
-mr-1">
|
||||
{$globalRelays.length}
|
||||
<span
|
||||
class="absolute bottom-0 right-0 -mr-1 flex h-5 w-5 items-center
|
||||
justify-center rounded-full border border-solid border-gray-7 bg-gray-8
|
||||
text-xs">
|
||||
{$muteRelays.length}
|
||||
</span>
|
||||
</Anchor>
|
||||
</div>
|
||||
|
@ -464,17 +464,20 @@
|
||||
</div>
|
||||
<div on:click|stopPropagation class="flex items-center">
|
||||
{#if pool.forceUrls.length === 0}
|
||||
<div class="hidden group-hover:flex">
|
||||
<div
|
||||
class={cx("absolute top-0 right-0 m-3 sm:relative sm:m-0", {
|
||||
"hidden group-hover:flex": !showEntire,
|
||||
flex: showEntire,
|
||||
})}>
|
||||
{#each note.seen_on as url}
|
||||
<Popover triggerType="mouseenter">
|
||||
<div slot="trigger" class="p-1">
|
||||
<Popover triggerType="mouseenter" interactive={false}>
|
||||
<div slot="trigger" class="cursor-pointer p-1">
|
||||
<div
|
||||
class="h-3 w-3 rounded-full border border-solid border-gray-6"
|
||||
style={`background: ${hsl(stringToHue(url))}`} />
|
||||
</div>
|
||||
<div slot="tooltip">
|
||||
{displayRelay({url})}
|
||||
style={`background: ${hsl(stringToHue(url))}`}
|
||||
on:click={() => modal.set({type: "relays/modal", url})} />
|
||||
</div>
|
||||
<div slot="tooltip">{displayRelay({url})}</div>
|
||||
</Popover>
|
||||
{/each}
|
||||
</div>
|
||||
@ -628,9 +631,11 @@
|
||||
{/if}
|
||||
<h1 class="staatliches text-2xl">Relays</h1>
|
||||
<p>This note was found on the {quantify(note.seen_on.length, "relay")} below.</p>
|
||||
{#each note.seen_on as url}
|
||||
<RelayCard theme="black" showControls relay={{url}} />
|
||||
{/each}
|
||||
<div class="flex flex-col gap-2">
|
||||
{#each note.seen_on as url}
|
||||
<RelayCard theme="black" relay={{url}} />
|
||||
{/each}
|
||||
</div>
|
||||
<h1 class="staatliches text-2xl">Details</h1>
|
||||
<CopyValue label="Identifier" value={nevent} />
|
||||
<CopyValue label="Event ID (note)" value={bech32Note} />
|
||||
|
@ -32,7 +32,10 @@
|
||||
const {type, value} = content[i]
|
||||
|
||||
// Find links on their own line and remove them from content
|
||||
if (type === "link" || ["nostr:note", "nostr:nevent"].includes(type)) {
|
||||
if (
|
||||
(type === "link" && !value.startsWith("ws")) ||
|
||||
["nostr:note", "nostr:nevent"].includes(type)
|
||||
) {
|
||||
const prev = content[i - 1]
|
||||
const next = content[i + 1]
|
||||
|
||||
|
@ -1,18 +1,17 @@
|
||||
<script>
|
||||
import {without, pluck} from 'ramda'
|
||||
import {sortBy, identity, uniq, pluck} from 'ramda'
|
||||
import {fly} from "svelte/transition"
|
||||
import Toggle from "src/partials/Toggle.svelte"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
import RelayCard from "src/partials/RelayCard.svelte"
|
||||
import user from "src/agent/user"
|
||||
import {globalRelays} from "src/app/ui"
|
||||
import {muteRelays} from "src/app/ui"
|
||||
|
||||
const {relays} = user
|
||||
const isSelected = url => $globalRelays.length === 0 || $globalRelays.includes(url)
|
||||
const toggle = url =>
|
||||
$globalRelays.length === 0
|
||||
? globalRelays.set(without([url], pluck('url', $relays)))
|
||||
: globalRelays.toggle(url)
|
||||
const isMuted = url => $muteRelays.includes(url)
|
||||
const toggle = url => muteRelays.toggle(url)
|
||||
|
||||
$: allUrls = sortBy(identity, uniq($muteRelays.concat(pluck('url', $relays))))
|
||||
</script>
|
||||
|
||||
<div in:fly={{y: 20}}>
|
||||
@ -20,29 +19,29 @@
|
||||
<div class="flex justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="fa fa-server fa-lg" />
|
||||
<h2 class="staatliches text-2xl">Explore relays</h2>
|
||||
<h2 class="staatliches text-2xl">Mute relays</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-gray-4">
|
||||
<i class="fa fa-warning" /> Advanced Feature
|
||||
</div>
|
||||
<p>
|
||||
Select which of your relays to use to request feeds. This is separate from your main
|
||||
relay selections, and is just to help you explore what different relays have to offer.
|
||||
Some notes from other relays will be included if required for context.
|
||||
Select relays to temporarily mute. This is separate from your main relay selections,
|
||||
and is just to help you explore what different relays have to offer.
|
||||
Muted relays may sometimes still be used to load context for other notes.
|
||||
</p>
|
||||
{#if $relays.length === 0}
|
||||
{#if allUrls.length === 0}
|
||||
<div class="mt-8 flex items-center justify-center gap-2 text-center">
|
||||
<i class="fa fa-triangle-exclamation" />
|
||||
No relays connected
|
||||
</div>
|
||||
{/if}
|
||||
<div class="grid grid-cols-1 gap-4">
|
||||
{#each $relays as relay (relay.url)}
|
||||
<RelayCard {relay}>
|
||||
{#each allUrls as url}
|
||||
<RelayCard relay={{url}}>
|
||||
<div slot="controls" class="flex justify-between gap-2">
|
||||
<span>Include in feeds?</span>
|
||||
<Toggle value={isSelected(relay.url)} on:change={() => toggle(relay.url)} />
|
||||
<span>Mute this relay?</span>
|
||||
<Toggle value={isMuted(url)} on:change={() => toggle(url)} />
|
||||
</div>
|
||||
</RelayCard>
|
||||
{/each}
|
36
src/views/relays/RelayJoin.svelte
Normal file
36
src/views/relays/RelayJoin.svelte
Normal file
@ -0,0 +1,36 @@
|
||||
<script lang="ts">
|
||||
import {find, propEq} from "ramda"
|
||||
import Anchor from 'src/partials/Anchor.svelte'
|
||||
import user from "src/agent/user"
|
||||
|
||||
export let relay
|
||||
|
||||
const {relays: userRelays} = user
|
||||
|
||||
$: joined = find(propEq("url", relay.url), $userRelays)
|
||||
</script>
|
||||
|
||||
<div class="flex flex-wrap items-center gap-3 whitespace-nowrap">
|
||||
{#if relay.contact}
|
||||
<Anchor type="button-circle" href={`mailto:${relay.contact}`}>
|
||||
<i class="fa fa-envelope" />
|
||||
</Anchor>
|
||||
{/if}
|
||||
{#if joined}
|
||||
{#if $userRelays.length > 1}
|
||||
<Anchor
|
||||
type="button"
|
||||
class="flex items-center gap-2 rounded-full"
|
||||
on:click={() => user.removeRelay(relay.url)}>
|
||||
<i class="fa fa-right-from-bracket" /> Leave
|
||||
</Anchor>
|
||||
{/if}
|
||||
{:else}
|
||||
<Anchor
|
||||
type="button"
|
||||
class="flex items-center gap-2 rounded-full"
|
||||
on:click={() => user.addRelay(relay.url)}>
|
||||
<i class="fa fa-right-to-bracket" /> Join
|
||||
</Anchor>
|
||||
{/if}
|
||||
</div>
|
20
src/views/relays/RelayModal.svelte
Normal file
20
src/views/relays/RelayModal.svelte
Normal file
@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import Content from "src/partials/Content.svelte"
|
||||
import RelayTitle from "src/views/relays/RelayTitle.svelte"
|
||||
import RelayJoin from "src/views/relays/RelayJoin.svelte"
|
||||
import {relays} from "src/agent/tables"
|
||||
|
||||
export let url
|
||||
|
||||
const relay = relays.get(url) || {url}
|
||||
</script>
|
||||
|
||||
<Content>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<RelayTitle {relay} />
|
||||
<RelayJoin {relay} />
|
||||
</div>
|
||||
{#if relay.description}
|
||||
<p>{relay.description}</p>
|
||||
{/if}
|
||||
</Content>
|
44
src/views/relays/RelayTitle.svelte
Normal file
44
src/views/relays/RelayTitle.svelte
Normal file
@ -0,0 +1,44 @@
|
||||
<script lang="ts">
|
||||
import {onMount} from "svelte"
|
||||
import {between} from "hurdak/lib/hurdak"
|
||||
import {displayRelay} from "src/util/nostr"
|
||||
import {poll, stringToHue, hsl} from "src/util/misc"
|
||||
import pool from 'src/agent/pool'
|
||||
|
||||
export let relay
|
||||
|
||||
let quality = null
|
||||
let message = null
|
||||
let showStatus = false
|
||||
|
||||
onMount(() => {
|
||||
return poll(10_000, async () => {
|
||||
;[quality, message] = pool.getQuality(relay.url)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="flex items-center gap-2 text-xl">
|
||||
<i class={relay.url.startsWith("wss") ? "fa fa-lock" : "fa fa-unlock"} />
|
||||
<span class="border-b border-solid" style={`border-color: ${hsl(stringToHue(relay.url))}`}>
|
||||
{displayRelay(relay)}
|
||||
</span>
|
||||
<span
|
||||
on:mouseout={() => {
|
||||
showStatus = false
|
||||
}}
|
||||
on:mouseover={() => {
|
||||
showStatus = true
|
||||
}}
|
||||
class="h-2 w-2 cursor-pointer rounded-full bg-gray-6"
|
||||
class:bg-gray-6={message === "Not connected"}
|
||||
class:bg-danger={quality <= 0.3 && message !== "Not connected"}
|
||||
class:bg-warning={between(0.3, 0.7, quality)}
|
||||
class:bg-success={quality > 0.7} />
|
||||
<p
|
||||
class="hidden text-sm text-gray-1 transition-all sm:block"
|
||||
class:opacity-0={!showStatus}
|
||||
class:opacity-1={showStatus}>
|
||||
{message}
|
||||
</p>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user