update wasm relay

fix dm timelines not closing
add summary to wiki edit page
This commit is contained in:
hzrd149
2024-05-23 08:16:35 -05:00
parent e4c96851a5
commit 990b1004ff
16 changed files with 63 additions and 28 deletions

View File

@@ -37,7 +37,7 @@
"@noble/hashes": "^1.3.2",
"@noble/secp256k1": "^1.7.0",
"@scure/base": "^1.1.6",
"@snort/worker-relay": "^1.0.10",
"@snort/worker-relay": "^1.1.0",
"@uiw/codemirror-theme-github": "^4.21.21",
"@uiw/react-codemirror": "^4.21.21",
"@webscopeio/react-textarea-autocomplete": "^4.9.2",

View File

@@ -1,12 +1,12 @@
import dayjs from "dayjs";
import { NostrEvent, isPTag } from "../../types/nostr-event";
import { NostrEvent } from "nostr-tools";
import { sortByDate } from "./event";
export function getDMSender(event: NostrEvent) {
return event.pubkey;
}
export function getDMRecipient(event: NostrEvent) {
const pubkey = event.tags.find(isPTag)?.[1];
const pubkey = event.tags.find((t) => t[0] === "p")?.[1];
if (!pubkey) throw new Error("Missing recipient pubkey");
return pubkey;
}
@@ -47,8 +47,8 @@ export function hasResponded(conversion: KnownConversation) {
const latestReceived = conversion.messages.find((m) => getDMSender(m) === conversion.correspondent);
const latestSent = conversion.messages.find((m) => getDMSender(m) === conversion.myself);
if (latestReceived && latestSent && latestSent.created_at > latestReceived.created_at) return false;
return true;
if (latestReceived && latestSent && latestSent.created_at > latestReceived.created_at) return true;
return false;
}
export function sortConversationsByLastReceived(conversations: KnownConversation[]) {

View File

@@ -299,6 +299,7 @@ export function ensureDTag(draft: DraftNostrEvent, d: string = nanoid()) {
}
}
/** either replaces the existing tag or adds a new one */
export function replaceOrAddSimpleTag(draft: DraftNostrEvent, tagName: string, value: string) {
if (draft.tags.some((t) => t[0] === tagName)) {
draft.tags = draft.tags.map((t) => (t[0] === tagName ? [tagName, value] : t));

View File

@@ -1,5 +1,5 @@
import { useEffect, useMemo } from "react";
import { useUnmount } from "react-use";
import { usePrevious, useUnmount } from "react-use";
import { Filter, NostrEvent } from "nostr-tools";
import timelineCacheService from "../services/timeline-cache";
@@ -21,11 +21,13 @@ export default function useTimelineLoader(
) {
const timeline = useMemo(() => timelineCacheService.createTimeline(key), [key]);
// update relays
useEffect(() => {
timeline.setRelays(relays);
timeline.triggerChunkLoad();
}, [Array.from(relays).join("|")]);
// update filters
useEffect(() => {
if (filters) {
timeline.setFilters(Array.isArray(filters) ? filters : [filters]);
@@ -34,18 +36,33 @@ export default function useTimelineLoader(
} else timeline.close();
}, [timeline, JSON.stringify(filters)]);
// update event filter
useEffect(() => {
timeline.setEventFilter(opts?.eventFilter);
}, [timeline, opts?.eventFilter]);
// update cursor
// NOTE: I don't think this is used anywhere and should be removed
useEffect(() => {
if (opts?.cursor !== undefined) {
timeline.setCursor(opts.cursor);
}
}, [timeline, opts?.cursor]);
// update custom sort
useEffect(() => {
timeline.events.customSort = opts?.customSort;
}, [timeline, opts?.customSort]);
// close the old timeline when the key changes
const oldTimeline = usePrevious(timeline);
useEffect(() => {
if (oldTimeline && oldTimeline !== timeline) {
oldTimeline.close();
}
}, [timeline, oldTimeline]);
// stop the loader when unmount
useUnmount(() => {
timeline.close();
});

View File

@@ -8,7 +8,7 @@ import NotificationsProvider from "./notifications-provider";
import { DefaultEmojiProvider, UserEmojiProvider } from "./emoji-provider";
import { AllUserSearchDirectoryProvider } from "./user-directory-provider";
import BreakpointProvider from "./breakpoint-provider";
import DecryptionProvider from "./dycryption-provider";
import DecryptionProvider from "./decryption-provider";
import DMTimelineProvider from "./dms-provider";
import PublishProvider from "./publish-provider";
import WebOfTrustProvider from "./web-of-trust-provider";

View File

@@ -27,7 +27,7 @@ class DictionaryService {
});
constructor() {
this.process = new Process("EventReactionsService", this);
this.process = new Process("DictionaryService", this);
this.process.icon = BookOpen01;
this.process.active = true;

View File

@@ -14,7 +14,7 @@ import IntersectionObserverProvider from "../../providers/local/intersection-obs
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
import TimelineActionAndStatus from "../../components/timeline-page/timeline-action-and-status";
import UserDnsIdentity from "../../components/user/user-dns-identity";
import { useDecryptionContext } from "../../providers/global/dycryption-provider";
import { useDecryptionContext } from "../../providers/global/decryption-provider";
import SendMessageForm from "./components/send-message-form";
import { groupMessages } from "../../helpers/nostr/dms";
import ThreadDrawer from "./components/thread-drawer";

View File

@@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
import { Alert, AlertDescription, AlertIcon, Button, ButtonProps } from "@chakra-ui/react";
import { UnlockIcon } from "../../../components/icons";
import { useDecryptionContainer } from "../../../providers/global/dycryption-provider";
import { useDecryptionContainer } from "../../../providers/global/decryption-provider";
import useCurrentAccount from "../../../hooks/use-current-account";
import { getDMRecipient, getDMSender } from "../../../helpers/nostr/dms";
import { NostrEvent } from "../../../types/nostr-event";

View File

@@ -8,7 +8,7 @@ import { useSigningContext } from "../../../providers/global/signing-provider";
import MagicTextArea, { RefType } from "../../../components/magic-textarea";
import { useTextAreaUploadFileWithForm } from "../../../hooks/use-textarea-upload-file";
import { DraftNostrEvent } from "../../../types/nostr-event";
import { useDecryptionContext } from "../../../providers/global/dycryption-provider";
import { useDecryptionContext } from "../../../providers/global/decryption-provider";
import useUserMailboxes from "../../../hooks/use-user-mailboxes";
import { usePublishEvent } from "../../../providers/global/publish-provider";

View File

@@ -27,7 +27,7 @@ import { Thread, useThreadsContext } from "../../../providers/local/thread-provi
import ThreadButton from "./thread-button";
import SendMessageForm from "./send-message-form";
import { groupMessages } from "../../../helpers/nostr/dms";
import { useDecryptionContext } from "../../../providers/global/dycryption-provider";
import { useDecryptionContext } from "../../../providers/global/decryption-provider";
import DirectMessageBlock from "./direct-message-block";
function MessagePreview({ message, ...props }: { message: NostrEvent } & Omit<TextProps, "children">) {

View File

@@ -18,7 +18,7 @@ import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-
import TimelineActionAndStatus from "../../components/timeline-page/timeline-action-and-status";
import { useDMTimeline } from "../../providers/global/dms-provider";
import UserName from "../../components/user/user-name";
import { useDecryptionContainer } from "../../providers/global/dycryption-provider";
import { useDecryptionContainer } from "../../providers/global/decryption-provider";
import { NostrEvent } from "../../types/nostr-event";
import { CheckIcon } from "../../components/icons";
import UserDnsIdentity from "../../components/user/user-dns-identity";

View File

@@ -19,7 +19,7 @@ import HoverLinkOverlay from "../../../components/hover-link-overlay";
import UserName from "../../../components/user/user-name";
import UserDnsIdentity from "../../../components/user/user-dns-identity";
import { nip19 } from "nostr-tools";
import { useDecryptionContainer, useDecryptionContext } from "../../../providers/global/dycryption-provider";
import { useDecryptionContainer, useDecryptionContext } from "../../../providers/global/decryption-provider";
import Timestamp from "../../../components/timestamp";
function MessagePreview({ message, pubkey }: { message: NostrEvent; pubkey: string }) {

View File

@@ -99,7 +99,7 @@ export default function CreateWikiPageView() {
<FormControl>
<FormLabel>Summary</FormLabel>
<Textarea {...register("summary", { required: true })} isRequired />
<FormHelperText>We'll never share your email.</FormHelperText>
<FormHelperText>A short summary of the page</FormHelperText>
</FormControl>
<MarkdownEditor value={getValues().content} onChange={(v) => setValue("content", v)} />
<Flex gap="2" justifyContent="flex-end">

View File

@@ -1,4 +1,15 @@
import { Button, Flex, FormControl, FormLabel, Heading, Input, Spinner, useToast } from "@chakra-ui/react";
import {
Button,
Flex,
FormControl,
FormHelperText,
FormLabel,
Heading,
Input,
Spinner,
Textarea,
useToast,
} from "@chakra-ui/react";
import { Navigate, useNavigate, useParams } from "react-router-dom";
import { useForm } from "react-hook-form";
import { NostrEvent } from "nostr-tools";
@@ -7,13 +18,13 @@ import { WIKI_RELAYS } from "../../const";
import useCacheForm from "../../hooks/use-cache-form";
import useReplaceableEvent from "../../hooks/use-replaceable-event";
import useCurrentAccount from "../../hooks/use-current-account";
import { WIKI_PAGE_KIND, getPageTitle, getPageTopic } from "../../helpers/nostr/wiki";
import { WIKI_PAGE_KIND, getPageSummary, getPageTitle, getPageTopic } from "../../helpers/nostr/wiki";
import { getSharableEventAddress } from "../../helpers/nip19";
import { usePublishEvent } from "../../providers/global/publish-provider";
import VerticalPageLayout from "../../components/vertical-page-layout";
import MarkdownEditor from "./components/markdown-editor";
import { ErrorBoundary } from "../../components/error-boundary";
import { cloneEvent } from "../../helpers/nostr/event";
import { cloneEvent, replaceOrAddSimpleTag } from "../../helpers/nostr/event";
function EditWikiPagePage({ page }: { page: NostrEvent }) {
const toast = useToast();
@@ -23,7 +34,7 @@ function EditWikiPagePage({ page }: { page: NostrEvent }) {
const topic = getPageTopic(page);
const { register, setValue, getValues, handleSubmit, watch, formState, reset } = useForm({
defaultValues: { content: page.content, title: getPageTitle(page) ?? topic },
defaultValues: { content: page.content, title: getPageTitle(page) ?? topic, summary: getPageSummary(page) },
mode: "all",
});
@@ -45,6 +56,7 @@ function EditWikiPagePage({ page }: { page: NostrEvent }) {
try {
const draft = cloneEvent(WIKI_PAGE_KIND, page);
draft.content = values.content;
replaceOrAddSimpleTag(draft, "summary", values.summary);
const pub = await publish("Publish Page", draft, WIKI_RELAYS, false);
clearFormCache();
@@ -67,6 +79,11 @@ function EditWikiPagePage({ page }: { page: NostrEvent }) {
<Input {...register("title", { required: true })} autoComplete="off" />
</FormControl>
</Flex>
<FormControl>
<FormLabel>Summary</FormLabel>
<Textarea {...register("summary", { required: true })} isRequired />
<FormHelperText>A short summary of the page</FormHelperText>
</FormControl>
<MarkdownEditor value={getValues().content} onChange={(v) => setValue("content", v)} />
<Flex gap="2" justifyContent="flex-end">
{formState.isDirty && <Button onClick={() => reset()}>Clear</Button>}

View File

@@ -2793,19 +2793,19 @@
"@noble/hashes" "~1.3.2"
"@scure/base" "~1.1.4"
"@snort/worker-relay@^1.0.10":
version "1.0.10"
resolved "https://registry.yarnpkg.com/@snort/worker-relay/-/worker-relay-1.0.10.tgz#3f79891027ec249e9722e358fc3ef59954238cc0"
integrity sha512-fmtLU+xSvThu4z5l9OqNlbX2HBBCCr9LYBEMXCPs/1llpA10euneTrsQndsrEP5dkDDn8TzMwaQIxl3OIahORQ==
"@snort/worker-relay@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@snort/worker-relay/-/worker-relay-1.1.0.tgz#b1be25b164b6f90e2c0b59ce9441cd3e316a1e67"
integrity sha512-P4U4h4zOwJ5abdjxH3eaOKy9CI8bzfcvAefYHwqGYiY+eT2UAHZYi496fXDQqjfroOrPdzoWPyLmdfdoT6+eUg==
dependencies:
"@sqlite.org/sqlite-wasm" "^3.45.1-build1"
"@sqlite.org/sqlite-wasm" "^3.45.3-build3"
eventemitter3 "^5.0.1"
uuid "^9.0.1"
"@sqlite.org/sqlite-wasm@^3.45.1-build1":
version "3.45.1-build1"
resolved "https://registry.yarnpkg.com/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.45.1-build1.tgz#648f6a0a0a4c3a67aff24b0e1331af655b86fb60"
integrity sha512-1EgshFNhVeBtZ9KtQPm3PzzJ2CtpmXAq2DAPywy7WZ3gOK6p5n8TY+M+mBMpQCF5cLqrdNFb3Kp9uNie9rUAHw==
"@sqlite.org/sqlite-wasm@^3.45.3-build3":
version "3.45.3-build3"
resolved "https://registry.yarnpkg.com/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.45.3-build3.tgz#dac928ddd009ecf27909df3ae9539c60b1aa255f"
integrity sha512-LZowRxDr6hipruNLmkLKyW+mnfWlRyynPbs+tDWJhBp305dE5wBIGtA31Gp1ZjlgLqusw7ePrdgLf6zaK1Dfzw==
"@surma/rollup-plugin-off-main-thread@^2.2.3":
version "2.2.3"