From 6536ca084fa301224097e93d9818840e855e6614 Mon Sep 17 00:00:00 2001 From: Ticruz Date: Tue, 19 Nov 2024 23:39:45 +0100 Subject: [PATCH] Creation and Submission delay and status (#457) * add cancelable delay to reply and create note * final tweaks * remove note state from event object * clearInterval on store * format and check * missing a status or a callback * missing import * use thunk for NoteCreate * use thunks in replies * migrate from publishes * rebase and check * - get rid of context in Note - slider to define send_delay * bring the check back * use @welshman/app thunks store * remove callback addToContext * remove LOCAL_RELAY from statuses * sign event before sending * delay configuration in seconds * remove grouphints store * loading indicator until event is signed --- .env | 1 + src/app/MenuDesktop.svelte | 14 +++-- src/app/shared/Note.svelte | 74 ++++++++++++----------- src/app/shared/NoteActions.svelte | 8 +-- src/app/shared/NotePending.svelte | 91 +++++++++++++++++++++++++++++ src/app/shared/NoteReply.svelte | 33 ++++++----- src/app/shared/PersonCircles.svelte | 3 +- src/app/shared/PublishCard.svelte | 49 +++++++++------- src/app/views/NoteCreate.svelte | 60 +++++++++++++++---- src/app/views/Publishes.svelte | 32 +++++----- src/app/views/UserSettings.svelte | 13 ++++- src/engine/state.ts | 41 +++++-------- src/partials/ThunkStatus.svelte | 21 +++++++ src/partials/Toast.svelte | 35 ++++++++--- src/util/misc.ts | 9 ++- 15 files changed, 334 insertions(+), 150 deletions(-) create mode 100644 src/app/shared/NotePending.svelte create mode 100644 src/partials/ThunkStatus.svelte diff --git a/.env b/.env index 56207e237..557e9097e 100644 --- a/.env +++ b/.env @@ -8,6 +8,7 @@ VITE_INDEXER_RELAYS=wss://relay.nostr.band,wss://purplepag.es,wss://relay.damus. VITE_DEFAULT_FOLLOWS=fe7f6bc6f7338b76bbf80db402ade65953e20b2f23e66e898204b63cc42539a3,f4db5270bd991b17bea1e6d035f45dee392919c29474bbac10342d223c74e0d0,180a6d42c7d64f8c3958d9d10dd5a4117eaaacea8e7f980781e9a53136cf5693,7bdef7be22dd8e59f4600e044aa53a1cf975a9dc7d27df5833bc77db784a5805,676ffea2ec31426a906d7795d7ebae2ba5e61f0b9fa815995b4a299dd085d510,4d5ce768123563bc583697db5e84841fb528f7b708d966f2e546286ce3c72077,eab0e756d32b80bcd464f3d844b8040303075a13eabc3599a762c9ac7ab91f4f,04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9,85080d3bad70ccdcd7f74c29a44f55bb85cbcd3dd0cbb957da1d215bdb931204,74ffc51cc30150cf79b6cb316d3a15cf332ab29a38fec9eb484ab1551d6d1856,93518f91dfa51d8acf39217cdcd3d2ccd178433cb9e72368544aacd7412cb50c,f728d9e6e7048358e70930f5ca64b097770d989ccd86854fe618eda9c8a38106,91c9a5e1a9744114c6fe2d61ae4de82629eaaa0fb52f48288093c7e7e036f832,83e818dfbeccea56b0f551576b3fd39a7a50e1d8159343500368fa085ccd964b,090254801a7e8e5085b02e711622f0dfa1a85503493af246aa42af08f5e4d2df,472f440f29ef996e92a186b8d320ff180c855903882e59d50de1b8bd5669301e,7b3f7803750746f455413a221f80965eecb69ef308f2ead1da89cc2c8912e968,330fb1431ff9d8c250706bbcdc016d5495a3f744e047a408173e92ae7ee42dac,c4eabae1be3cf657bc1855ee05e69de9f059cb7a059227168b80b89761cbc4e0,a4cb51f4618cfcd16b2d3171c466179bed8e197c43b8598823b04de266cef110,f9acb0b034c4c1177e985f14639f317ef0fedee7657c060b146ee790024317ec,6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93,e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411,6389be6491e7b693e9f368ece88fcd145f07c068d2c1bbae4247b9b5ef439d32,e1ff3bfdd4e40315959b08b4fcc8245eaa514637e1d4ec2ae166b743341be1af,38dbb9b07d93861d40620ad62d44b1a8e8785df0997eeb4454f12d217048cd5c,064de2497ce621aee2a5b4b926a08b1ca01bce9da85b0c714e883e119375140c,aa5e6ccfc7cb7c3431d12b0ea4b83e5b35427602522080a6a8618950527f811b,97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322,676ffea2ec31426a906d7795d7ebae2ba5e61f0b9fa815995b4a299dd085d510,f783ba3b12b91e375aba6594015b90bd95f7e132b03cc8c4c52ce0a7c36aab52,9a4acdeb978565e27490dca65c83e9f65745eaec1d9a0405a52d198c1489913b,e5177ebf513530c2d0924083b64b7eadd7fb85efcc3e4dfb55c73a924c901ca7,5b0183ab6c3e322bf4d41c6b3aef98562a144847b7499543727c5539a114563e,958b754a1d3de5b5eca0fe31d2d555f451325f8498a83da1997b7fcd5c39e88c,5c508c34f58866ec7341aaf10cc1af52e9232bb9f859c8103ca5ecf2aa93bf78,26bd32c67232bdf16d05e763ec67d883015eb99fd1269025224c20c6cfdb0158,d307643547703537dfdef811c3dea96f1f9e84c8249e200353425924a9908cf8,604e96e099936a104883958b040b47672e0f048c98ac793f37ffe4c720279eb2,90b9bec74789688e515125596ab6350bfe646176ac75742275063922c5fea010,baf27a4cc4da49913e7fdecc951fd3b971c9279959af62b02b761a043c33384c,2edbcea694d164629854a52583458fd6d965b161e3c48b57d3aff01940558884,82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2,66bd8fed3590f2299ef0128f58d67879289e6a99a660e83ead94feab7606fd17,eeb11961b25442b16389fe6c7ebea9adf0ac36dd596816ea7119e521b8821b9e,61066504617ee79387021e18c89fb79d1ddbc3e7bff19cf2298f40466f8715e9,1bc70a0148b3f316da33fe3c89f23e3e71ac4ff998027ec712b905cd24f6a411,a9434ee165ed01b286becfc2771ef1705d3537d051b387288898cc00d5c885be,ee6ea13ab9fe5c4a68eaf9b1a34fe014a66b40117c50ee2a614f4cda959b6e74,7bdef7be22dd8e59f4600e044aa53a1cf975a9dc7d27df5833bc77db784a5805,1577e4599dd10c863498fe3c20bd82aafaf829a595ce83c5cf8ac3463531b09b,1739d937dc8c0c7370aa27585938c119e25c41f6c441a5d34c6d38503e3136ef,fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52,cc8d072efdcc676fcbac14f6cd6825edc3576e55eb786a2a975ee034a6a026cb,d91191e30e00444b942c0e82cad470b32af171764c2275bee0bd99377efd4075,3335d373e6c1b5bc669b4b1220c08728ea8ce622e5a7cfeeb4c0001d91ded1de,0b118e40d6f3dfabb17f21a94a647701f140d8b063a9e84fe6e483644edc09cb,b83a28b7e4e5d20bd960c5faeb6625f95529166b8bdb045d42634a2f35919450,958b754a1d3de5b5eca0fe31d2d555f451325f8498a83da1997b7fcd5c39e88c,a4cb51f4618cfcd16b2d3171c466179bed8e197c43b8598823b04de266cef110,e56e7b4326618f3d626c0e398f5082c3b16732e469e0a048b7ddb544c2be294a,011c1b374c12fbd3633e98957d3c46bed67983abecef50706c73a77c171d0d2c,b9e76546ba06456ed301d9e52bc49fa48e70a6bf2282be7a1ae72947612023dc,b708f7392f588406212c3882e7b3bc0d9b08d62f95fa170d099127ece2770e5e,5c508c34f58866ec7341aaf10cc1af52e9232bb9f859c8103ca5ecf2aa93bf78,baf27a4cc4da49913e7fdecc951fd3b971c9279959af62b02b761a043c33384c,2edbcea694d164629854a52583458fd6d965b161e3c48b57d3aff01940558884,0fecf65daa26faf3f668e8143325a4c199a040b6345ed40a08614d7dd85b1823,1bc70a0148b3f316da33fe3c89f23e3e71ac4ff998027ec712b905cd24f6a411,f783ba3b12b91e375aba6594015b90bd95f7e132b03cc8c4c52ce0a7c36aab52,3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24,82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2,3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d,ee11a5dff40c19a555f41fe42b48f00e618c91225622ae37b6c2bb67b76c4e49,eab0e756d32b80bcd464f3d844b8040303075a13eabc3599a762c9ac7ab91f4f,58c741aa630c2da35a56a77c1d05381908bd10504fdd2d8b43f725efa6d23196,84dee6e676e5bb67b4ad4e042cf70cbd8681155db535942fcc6a0533858a7240,33bd77e5394520747faae1394a4af5fa47f404389676375b6dc7be865ed81452,21335073401a310cc9179fe3a77e9666710cfdf630dfd840f972c183a244b1ad,36732cc35fe56185af1b11160a393d6c73a1fe41ddf1184c10394c28ca5d627b,3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d,fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52,32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245,63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed,97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322,00000000827ffaa94bfea288c3dfce4422c794fbb96625b6b31e9049f729d700,3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24,e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411,82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2,e8ed3798c6ffebffa08501ac39e271662bfd160f688f94c45d692d8767dd345a,c5fb6ecc876e0458e3eca9918e370cbcd376901c58460512fe537a46e58c38bb,40b9c85fffeafc1cadf8c30a4e5c88660ff6e4971a0dc723d5ab674b5e61b451,a3eb29554bd27fca7f53f66272e4bb59d066f2f31708cf341540cb4729fbd841,460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c,0000005f87f64341c212cc93d6c266c03ae752c02660e78a6da1424f7b05c470,d61f3bc5b3eb4400efdae6169a5c17cabf3246b514361de939ce4a1a0da6ef4a,1739d937dc8c0c7370aa27585938c119e25c41f6c441a5d34c6d38503e3136ef,7adb520c3ac7cb6dc8253508df0ce1d975da49fefda9b5c956744a049d230ace,3335d373e6c1b5bc669b4b1220c08728ea8ce622e5a7cfeeb4c0001d91ded1de,266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5,17717ad4d20e2a425cda0a2195624a0a4a73c4f6975f16b1593fc87fa46f2d58,af9d70407464247d19fd243cf1bee81e6df1e639217dc66366bf37aa42d05d35,ddf03aca85ade039e6742d5bef3df352df199d0d31e22b9858e7eda85cb3bbbe,d36e8083fa7b36daee646cb8b3f99feaa3d89e5a396508741f003e21ac0b6bec,7fa56f5d6962ab1e3cd424e758c3002b8665f7b0d8dcee9fe9e288d7751ac194,cc8d072efdcc676fcbac14f6cd6825edc3576e55eb786a2a975ee034a6a026cb,d91191e30e00444b942c0e82cad470b32af171764c2275bee0bd99377efd4075,3d842afecd5e293f28b6627933704a3fb8ce153aa91d790ab11f6a752d44a42d,79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6,17538dc2a62769d09443f18c37cbe358fab5bbf981173542aa7c5ff171ed77c4,ff27d01cb1e56fb58580306c7ba76bb037bf211c5b573c56e4e70ca858755af0,8fb140b4e8ddef97ce4b821d247278a1a4353362623f64021484b372f948000c,27797bd4e5ee52db0a197668c92b9a3e7e237e1f9fa73a10c38d731c294cfc9a,7cc328a08ddb2afdf9f9be77beff4c83489ff979721827d628a542f32a247c0e,c35ff8c340449f0d68af1aec4844bb44a9c0b8c1dd4f4d4efbc65e12039a348a,1bc70a0148b3f316da33fe3c89f23e3e71ac4ff998027ec712b905cd24f6a411,fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52,3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d,0b118e40d6f3dfabb17f21a94a647701f140d8b063a9e84fe6e483644edc09cb,2edbcea694d164629854a52583458fd6d965b161e3c48b57d3aff01940558884,1739d937dc8c0c7370aa27585938c119e25c41f6c441a5d34c6d38503e3136ef,eab0e756d32b80bcd464f3d844b8040303075a13eabc3599a762c9ac7ab91f4f,dace63b00c42e6e017d00dd190a9328386002ff597b841eb5ef91de4f1ce8491,76c71aae3a491f1d9eec47cba17e229cda4113a0bbb6e6ae1776d7643e29cafa,266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5,d91191e30e00444b942c0e82cad470b32af171764c2275bee0bd99377efd4075,7a3288f5b2a382317ddcbab9c0b6e9a22a999a064dfb9b7284508a0da3fa9114,6a72db8ef3f3b9ee5ecd808ed6d0631d1e4dda5c5dadf07887104d33957eba48 VITE_ONBOARDING_LISTS="30000:97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322:3121977322800018,30000:97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322:680038570738458,30000:97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322:33178290670580934,30000:97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322:49330924355910266,30000:97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322:9358486925304412,30000:97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322:3151213286926533" VITE_NIP96_URLS=https://nostr.build,https://nostrcheck.me,https://sove.rent,https://void.cat +VITE_BLOSSOM_URLS=https://cdn.satellite.earth,https://blossom.hzrd149.com,https://blossom.f7z.io,https://void.cat VITE_IMGPROXY_URL=https://imgproxy.coracle.social VITE_DUFFLEPUD_URL=https://dufflepud.onrender.com VITE_PLATFORM_ZAP_SPLIT=0 diff --git a/src/app/MenuDesktop.svelte b/src/app/MenuDesktop.svelte index 3c7b9459c..89b1509e8 100644 --- a/src/app/MenuDesktop.svelte +++ b/src/app/MenuDesktop.svelte @@ -1,6 +1,6 @@ + +
+ {#if thunk && (isPending || isCompleted)} +
+ {#if isPending} + Publishing... + {total - pendings} of {total} relays + {:else} + Published to {success}/{total} ({failed} failed, {timeout} timed out) + See details + {/if} + {:else if $userSettings.send_delay > 0} + Sending reply in {event.created_at + + Math.ceil($userSettings.send_delay / 1000) - + $timestamp1} seconds + + + {/if} +
diff --git a/src/app/shared/NoteReply.svelte b/src/app/shared/NoteReply.svelte index 732829a8c..ce1da39c5 100644 --- a/src/app/shared/NoteReply.svelte +++ b/src/app/shared/NoteReply.svelte @@ -1,24 +1,23 @@
- {#each pubkeys.slice(0, 15) as pubkey (pubkey)} + {#each uniq(pubkeys).slice(0, 15) as pubkey (pubkey)}
diff --git a/src/app/shared/PublishCard.svelte b/src/app/shared/PublishCard.svelte index 273b0a5f6..c2b103441 100644 --- a/src/app/shared/PublishCard.svelte +++ b/src/app/shared/PublishCard.svelte @@ -1,28 +1,35 @@ {#await promise} @@ -50,7 +57,7 @@
- Kind {event.kind}, published {formatTimestamp(pub.created_at)} + Kind {event.kind}, published {formatTimestamp(thunk.event.created_at)} open(event)}>View Note
diff --git a/src/app/views/NoteCreate.svelte b/src/app/views/NoteCreate.svelte index d0834a649..f46742948 100644 --- a/src/app/views/NoteCreate.svelte +++ b/src/app/views/NoteCreate.svelte @@ -1,11 +1,15 @@ + +
+ Published to {total - pending}/{total} relays. + View details +
diff --git a/src/partials/Toast.svelte b/src/partials/Toast.svelte index ed8daefb9..aa8aa930f 100644 --- a/src/partials/Toast.svelte +++ b/src/partials/Toast.svelte @@ -11,7 +11,7 @@ timeout = 5, ...opts }) => { - toast.set({id, type, theme, ...opts}) + toast.set({id, type, theme, timeout, ...opts}) if (timeout) { setTimeout(() => { @@ -26,7 +26,9 @@ export const showWarning = (message, opts = {}) => showToast({message, theme: "warning", ...opts}) - export const showPublishInfo = (pub, opts = {}) => showToast({pub, type: "publish", ...opts}) + export const showPublishInfo = (thunk: Thunk, opts = {}) => { + showToast({thunk, type: "publish", ...opts}) + } window.addEventListener("online", () => { if (get(toast)?.id === "offline") { @@ -40,9 +42,12 @@ {#if $toast} - {#key "key"} + {#key $toast.id}
{#if $toast.type === "text"} {$toast.message} + {:else if $toast.type === "delay"} + Sending in {timeLeft} seconds... + { + $toast.onCancel() + toast.set(null) + }}>Cancel {:else if $toast.type === "publish"} - {@const {status, request} = $toast.pub} - {@const total = request.relays.length} - {@const pending = Array.from(status.values()).filter(s => s === "pending").length} - Published to {total - pending}/{total} relays. - View details + {/if}
toast.set(null)}> diff --git a/src/util/misc.ts b/src/util/misc.ts index 4d002d574..04350a592 100644 --- a/src/util/misc.ts +++ b/src/util/misc.ts @@ -1,11 +1,18 @@ import {throttle} from "throttle-debounce" -import {writable} from "svelte/store" +import {derived, writable, type Readable} from "svelte/store" import {now, stripProtocol, isPojo, first, sleep} from "@welshman/lib" import {pluck, fromPairs, last, identity, sum, is} from "ramda" import {Storage, ensurePlural, seconds, tryFunc, round} from "hurdak" import Fuse from "fuse.js" import logger from "src/util/logger" +export const timestamp1: Readable = derived([], (_, set) => { + const interval = setInterval(() => { + set(Math.floor(Date.now() / 1000)) + }, 1000) + return () => clearInterval(interval) +}) + export const secondsToDate = ts => new Date(parseInt(ts) * 1000) export const dateToSeconds = date => Math.round(date.valueOf() / 1000)