diff --git a/src/app/shared/NoteOptions.svelte b/src/app/shared/NoteOptions.svelte index fbf19e31..56c7d81d 100644 --- a/src/app/shared/NoteOptions.svelte +++ b/src/app/shared/NoteOptions.svelte @@ -12,6 +12,7 @@ export let initialValues: { warning: string anonymous: boolean + delay: string } let values = initialValues @@ -26,7 +27,7 @@ const onSubmit = () => { initialValues = values - dispatch("change", values) + dispatch("change", {...values, delay: new Date(values.delay)}) setView(null) } @@ -43,6 +44,9 @@ bind:value={values.warning} placeholder="Why might people want to skip this post?" /> + + +

Enable this to create an anonymous note.

diff --git a/src/app/views/NoteCreate.svelte b/src/app/views/NoteCreate.svelte index 9a93080e..74e186f8 100644 --- a/src/app/views/NoteCreate.svelte +++ b/src/app/views/NoteCreate.svelte @@ -2,9 +2,11 @@ import {onMount} from "svelte" import {whereEq} from "ramda" import {ctx, last} from "@welshman/lib" - import {createEvent} from "@welshman/util" - import {session, tagPubkey} from "@welshman/app" + import {createEvent, DVM_REQUEST_PUBLISH_SCHEDULE, HANDLER_INFORMATION} from "@welshman/util" + import {load, repository, session, signer, tagPubkey} from "@welshman/app" import {PublishStatus} from "@welshman/net" + import {makeDvmRequest} from "@welshman/dvm" + import {deriveEvents} from "@welshman/store" import {commaFormat} from "hurdak" import {writable, type Writable} from "svelte/store" import {Editor} from "svelte-tiptap" @@ -19,10 +21,10 @@ import NoteContent from "src/app/shared/NoteContent.svelte" import NoteOptions from "src/app/shared/NoteOptions.svelte" import {getEditorOptions} from "src/app/editor" - import {drafts} from "src/app/state" import {router} from "src/app/util/router" import {currencyOptions} from "src/util/i18n" - import {getClientTags, publish, sign, tagsFromContent, userSettings} from "src/engine" + import {env, getClientTags, publish, sign, tagsFromContent, userSettings} from "src/engine" + import {drafts} from "../state" export let quote = null export let pubkey = null @@ -32,7 +34,7 @@ let wordCount: Writable let showPreview = false let signaturePending = false - + let options let editor: Editor let element: HTMLElement @@ -46,9 +48,24 @@ location: null, start: null, end: null, + delay: null, ...initialValues, } + const DVM_HANDLER_FILTER = { + kinds: [HANDLER_INFORMATION], + "#k": [DVM_REQUEST_PUBLISH_SCHEDULE.toString()], + } + const DVM_REQUEST_FILTER = {kinds: [DVM_REQUEST_PUBLISH_SCHEDULE]} + + const handlers = deriveEvents(repository, { + filters: [DVM_HANDLER_FILTER], + }) + + const requests = deriveEvents(repository, { + filters: [DVM_REQUEST_FILTER], + }) + const nsecWarning = writable(null) const setOpts = e => { @@ -82,7 +99,11 @@ tags.push(tagPubkey(quote.pubkey)) } - const template = createEvent(1, {content, tags}) + const template = createEvent(1, { + content, + tags, + created_at: opts?.delay && Math.floor(opts?.delay.getTime() / 1000), + }) const signedTemplate = await sign(template) @@ -90,40 +111,72 @@ drafts.set("notecreate", editor.getHTML()) - router.clearModals() + // if a delay is set, send the event through the DVM + if (opts?.delay) { + const dvmPubkey = $handlers[0].pubkey + const dvmContent = await $signer.nip04.encrypt( + dvmPubkey, + JSON.stringify([ + ["i", JSON.stringify(signedTemplate), "text"], + ["param", "relays", ...ctx.app.router.FromUser().getUrls()], + ]), + ) + const dvmEvent = await sign( + createEvent(DVM_REQUEST_PUBLISH_SCHEDULE, { + content: dvmContent, + tags: [["p", dvmPubkey], ["encrypted"]], + }), + ) + + const dvmRequest = makeDvmRequest({ + event: dvmEvent, + relays: env.DVM_RELAYS, + }) - const thunk = publish({ - event: signedTemplate, - relays: ctx.app.router.PublishEvent(signedTemplate).getUrls(), - delay: $userSettings.send_delay, - }) + dvmRequest.pub.emitter.on("*", (a, b, c) => { + console.log("pub", a, b, c) + }) - thunk.result.finally(() => { - charCount.set(0) - wordCount.set(0) - drafts.delete("notecreate") - }) + dvmRequest.sub.emitter.on("*", (a, b, c) => { + console.log("sub", a, b, c) + }) + } else { + router.clearModals() + + // send the event + const thunk = publish({ + event: signedTemplate, + relays: ctx.app.router.PublishEvent(signedTemplate).getUrls(), + delay: $userSettings.send_delay, + }) - if ($userSettings.send_delay > 0) { - showToast({ - id: "send-delay", - type: "delay", - timeout: $userSettings.send_delay / 1000, - onCancel: () => { - thunk.controller.abort() - router.at("notes/create").open() - }, + thunk.result.finally(() => { + charCount.set(0) + wordCount.set(0) + drafts.delete("notecreate") }) - } - thunk.status.subscribe(status => { - if ( - Object.values(status).length === thunk.request.relays.length && - Object.values(status).every(s => s.status === PublishStatus.Pending) - ) { - showPublishInfo(thunk) + if ($userSettings.send_delay > 0) { + showToast({ + id: "send-delay", + type: "delay", + timeout: $userSettings.send_delay / 1000, + onCancel: () => { + thunk.controller.abort() + router.at("notes/create").open() + }, + }) } - }) + + thunk.status.subscribe(status => { + if ( + Object.values(status).length === thunk.request.relays.length && + Object.values(status).every(s => s.status === PublishStatus.Pending) + ) { + showPublishInfo(thunk) + } + }) + } } const togglePreview = () => { @@ -144,6 +197,9 @@ } onMount(() => { + // load the latest DVM + load({filters: [DVM_REQUEST_FILTER, DVM_HANDLER_FILTER], relays: env.DVM_RELAYS}) + const options = getEditorOptions({ content: drafts.get("notecreate") || "", submit: onSubmit, @@ -223,6 +279,12 @@ disabled={$loading || signaturePending}> {#if signaturePending} + {:else if opts?.delay} + {#if new Date(opts.delay).toDateString() === new Date().toDateString()} + Scheduled for {opts.delay.toLocaleTimeString()} + {:else} + Scheduled for {opts.delay.toLocaleDateString()} at {opts.delay.toLocaleTimeString()} + {/if} {:else} Send {/if} @@ -233,11 +295,17 @@ + - + {#if $nsecWarning} nsecWarning.set(null)} onBypass={bypassNsecWarning} /> diff --git a/src/engine/state.ts b/src/engine/state.ts index cd512be3..56652d1c 100644 --- a/src/engine/state.ts +++ b/src/engine/state.ts @@ -66,6 +66,7 @@ import { APP_DATA, CLIENT_AUTH, DIRECT_MESSAGE, + DVM_REQUEST_PUBLISH_SCHEDULE, FEED, FEEDS, FOLLOWS, @@ -217,6 +218,8 @@ const unwrapper = new Worker({chunkSize: 10}) unwrapper.addGlobalHandler(async (event: TrustedEvent) => { if (event.kind === WRAP) { await ensureUnwrapped(event) + } else if (event.kind === DVM_REQUEST_PUBLISH_SCHEDULE) { + console.log("DVM_REQUEST_PUBLISH_SCHEDULE", event) } else { await ensurePlaintext(event) }