mirror of
https://github.com/coracle-social/flotilla.git
synced 2025-12-10 10:57:04 +00:00
Replace bunker with claim on alerts page
This commit is contained in:
@@ -372,12 +372,11 @@ export type AlertParams = {
|
|||||||
feed: Feed
|
feed: Feed
|
||||||
cron: string
|
cron: string
|
||||||
email: string
|
email: string
|
||||||
bunker: string
|
|
||||||
secret: string
|
|
||||||
description: string
|
description: string
|
||||||
|
claims: Record<string, string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const makeAlert = async ({cron, email, feed, bunker, secret, description}: AlertParams) => {
|
export const makeAlert = async ({cron, email, feed, claims, description}: AlertParams) => {
|
||||||
const tags = [
|
const tags = [
|
||||||
["feed", JSON.stringify(feed)],
|
["feed", JSON.stringify(feed)],
|
||||||
["cron", cron],
|
["cron", cron],
|
||||||
@@ -394,8 +393,8 @@ export const makeAlert = async ({cron, email, feed, bunker, secret, description}
|
|||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
|
||||||
if (bunker) {
|
for (const [relay, claim] of Object.entries(claims)) {
|
||||||
tags.push(["nip46", secret, bunker])
|
tags.push(["claim", relay, claim])
|
||||||
}
|
}
|
||||||
|
|
||||||
return makeEvent(ALERT, {
|
return makeEvent(ALERT, {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
import {randomInt, displayList, TIMEZONE, identity} from "@welshman/lib"
|
import {randomInt, displayList, TIMEZONE, identity} from "@welshman/lib"
|
||||||
import {displayRelayUrl, getTagValue, THREAD, MESSAGE, EVENT_TIME, COMMENT} from "@welshman/util"
|
import {displayRelayUrl, getTagValue, THREAD, MESSAGE, EVENT_TIME, COMMENT} from "@welshman/util"
|
||||||
import type {Filter} from "@welshman/util"
|
import type {Filter} from "@welshman/util"
|
||||||
import type {Nip46ResponseWithResult} from "@welshman/signer"
|
|
||||||
import {makeIntersectionFeed, makeRelayFeed, feedFromFilters} from "@welshman/feeds"
|
import {makeIntersectionFeed, makeRelayFeed, feedFromFilters} from "@welshman/feeds"
|
||||||
import {pubkey} from "@welshman/app"
|
import {pubkey} from "@welshman/app"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
@@ -12,13 +11,10 @@
|
|||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||||
import InfoBunker from "@app/components/InfoBunker.svelte"
|
|
||||||
import BunkerConnect, {BunkerConnectController} from "@app/components/BunkerConnect.svelte"
|
|
||||||
import {alerts, getMembershipUrls, getMembershipRoomsByUrl, userMembership} from "@app/state"
|
import {alerts, getMembershipUrls, getMembershipRoomsByUrl, userMembership} from "@app/state"
|
||||||
import {loadAlertStatuses} from "@app/requests"
|
import {loadAlertStatuses, requestRelayClaims} from "@app/requests"
|
||||||
import {publishAlert} from "@app/commands"
|
import {publishAlert} from "@app/commands"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
import {pushModal} from "@app/modal"
|
|
||||||
|
|
||||||
const timezoneOffset = parseInt(TIMEZONE.slice(3)) / 100
|
const timezoneOffset = parseInt(TIMEZONE.slice(3)) / 100
|
||||||
const minute = randomInt(0, 59)
|
const minute = randomInt(0, 59)
|
||||||
@@ -30,36 +26,12 @@
|
|||||||
let cron = WEEKLY
|
let cron = WEEKLY
|
||||||
let email = $alerts.map(a => getTagValue("email", a.tags)).filter(identity)[0] || ""
|
let email = $alerts.map(a => getTagValue("email", a.tags)).filter(identity)[0] || ""
|
||||||
let relay = ""
|
let relay = ""
|
||||||
let bunker = ""
|
|
||||||
let secret = ""
|
|
||||||
let notifyThreads = true
|
let notifyThreads = true
|
||||||
let notifyCalendar = true
|
let notifyCalendar = true
|
||||||
let notifyChat = false
|
let notifyChat = false
|
||||||
let showBunker = false
|
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
||||||
const controller = new BunkerConnectController({
|
|
||||||
onNostrConnect: (response: Nip46ResponseWithResult) => {
|
|
||||||
bunker = controller.broker.getBunkerUrl()
|
|
||||||
secret = controller.broker.params.clientSecret
|
|
||||||
showBunker = false
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const connectBunker = () => {
|
|
||||||
showBunker = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const hideBunker = () => {
|
|
||||||
showBunker = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const clearBunker = () => {
|
|
||||||
bunker = ""
|
|
||||||
secret = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
if (!email.includes("@")) {
|
if (!email.includes("@")) {
|
||||||
return pushToast({
|
return pushToast({
|
||||||
@@ -108,10 +80,11 @@
|
|||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const claims = await requestRelayClaims([relay])
|
||||||
const cadence = cron?.endsWith("1") ? "Weekly" : "Daily"
|
const cadence = cron?.endsWith("1") ? "Weekly" : "Daily"
|
||||||
const description = `${cadence} alert for ${displayList(display)} on ${displayRelayUrl(relay)}, sent via email.`
|
const description = `${cadence} alert for ${displayList(display)} on ${displayRelayUrl(relay)}, sent via email.`
|
||||||
const feed = makeIntersectionFeed(feedFromFilters(filters), makeRelayFeed(relay))
|
const feed = makeIntersectionFeed(feedFromFilters(filters), makeRelayFeed(relay))
|
||||||
const thunk = await publishAlert({cron, email, feed, bunker, secret, description})
|
const thunk = await publishAlert({cron, email, feed, claims, description})
|
||||||
|
|
||||||
await thunk.result
|
await thunk.result
|
||||||
await loadAlertStatuses($pubkey!)
|
await loadAlertStatuses($pubkey!)
|
||||||
@@ -130,13 +103,6 @@
|
|||||||
Add an Alert
|
Add an Alert
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
{#if showBunker}
|
|
||||||
<div class="card2 flex flex-col items-center gap-4 bg-base-300">
|
|
||||||
<p>Scan using a nostr signer, or click to copy.</p>
|
|
||||||
<BunkerConnect {controller} />
|
|
||||||
<Button class="btn btn-neutral btn-sm" onclick={hideBunker}>Cancel</Button>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<FieldInline>
|
<FieldInline>
|
||||||
{#snippet label()}
|
{#snippet label()}
|
||||||
<p>Email Address*</p>
|
<p>Email Address*</p>
|
||||||
@@ -192,38 +158,12 @@
|
|||||||
</div>
|
</div>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</FieldInline>
|
</FieldInline>
|
||||||
<div class="card2 flex flex-col gap-3 bg-base-300">
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<strong>Connect a Bunker</strong>
|
|
||||||
<span class="flex items-center gap-2 text-sm" class:text-primary={bunker}>
|
|
||||||
{#if bunker}
|
|
||||||
<Icon icon="check-circle" size={5} />
|
|
||||||
Connected
|
|
||||||
{:else}
|
|
||||||
<Icon icon="close-circle" size={5} />
|
|
||||||
Not Connected
|
|
||||||
{/if}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<p class="text-sm">
|
|
||||||
Required for receiving alerts about spaces with access controls. You can get one from your
|
|
||||||
<Button class="text-primary" onclick={() => pushModal(InfoBunker)}>remote signer app</Button
|
|
||||||
>.
|
|
||||||
</p>
|
|
||||||
{#if bunker}
|
|
||||||
<Button class="btn btn-neutral btn-sm flex-grow" onclick={clearBunker}>Disconnect</Button>
|
|
||||||
{:else}
|
|
||||||
<Button class="btn btn-primary btn-sm w-full flex-grow" onclick={connectBunker}
|
|
||||||
>Connect</Button>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button class="btn btn-link" onclick={back}>
|
<Button class="btn btn-link" onclick={back}>
|
||||||
<Icon icon="alt-arrow-left" />
|
<Icon icon="alt-arrow-left" />
|
||||||
Go back
|
Go back
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="submit" class="btn btn-primary" disabled={loading || showBunker}>
|
<Button type="submit" class="btn btn-primary" disabled={loading}>
|
||||||
<Spinner {loading}>Confirm</Spinner>
|
<Spinner {loading}>Confirm</Spinner>
|
||||||
<Icon icon="alt-arrow-right" />
|
<Icon icon="alt-arrow-right" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -13,12 +13,17 @@ import {
|
|||||||
sortBy,
|
sortBy,
|
||||||
assoc,
|
assoc,
|
||||||
now,
|
now,
|
||||||
|
removeNil,
|
||||||
|
isNotNil,
|
||||||
|
filterVals,
|
||||||
|
fromPairs,
|
||||||
} from "@welshman/lib"
|
} from "@welshman/lib"
|
||||||
import {
|
import {
|
||||||
MESSAGE,
|
MESSAGE,
|
||||||
DELETE,
|
DELETE,
|
||||||
THREAD,
|
THREAD,
|
||||||
EVENT_TIME,
|
EVENT_TIME,
|
||||||
|
AUTH_INVITE,
|
||||||
COMMENT,
|
COMMENT,
|
||||||
matchFilters,
|
matchFilters,
|
||||||
getTagValues,
|
getTagValues,
|
||||||
@@ -430,3 +435,20 @@ export const discoverRelays = (lists: List[]) =>
|
|||||||
.filter(isShareableRelayUrl)
|
.filter(isShareableRelayUrl)
|
||||||
.map(url => loadRelay(url)),
|
.map(url => loadRelay(url)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const requestRelayClaim = async (url: string) => {
|
||||||
|
const relay = await loadRelay(url)
|
||||||
|
const authors = removeNil([relay?.profile?.self, relay?.profile?.pubkey])
|
||||||
|
const filters = [{kinds: [AUTH_INVITE], authors, limit: 1}]
|
||||||
|
const events = await load({filters, relays: [url]})
|
||||||
|
|
||||||
|
if (events.length > 0) {
|
||||||
|
return getTagValue("claim", events[0].tags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const requestRelayClaims = async (urls: string[]) =>
|
||||||
|
filterVals(
|
||||||
|
isNotNil,
|
||||||
|
fromPairs(await Promise.all(urls.map(async url => [url, await requestRelayClaim(url)]))),
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user