From 379bce6f9e4fbe035e86baa43d52d115c541f5b2 Mon Sep 17 00:00:00 2001 From: Kieran Date: Mon, 26 Jun 2023 12:29:12 +0100 Subject: [PATCH] Dm fixes fixes #586 --- packages/app/src/Element/DmWindow.tsx | 7 +++-- packages/app/src/Element/WriteMessage.tsx | 5 ++-- packages/app/src/Pages/ChatPage.css | 3 -- packages/app/src/Pages/ChatPage.tsx | 15 ---------- packages/app/src/Pages/MessagesPage.tsx | 8 ++++-- packages/app/src/SnortUtils/index.ts | 10 ++++++- packages/app/src/chat/nip4.ts | 34 +++++++++++++---------- packages/app/src/index.tsx | 7 +---- packages/system/src/nostr-system.ts | 4 ++- 9 files changed, 43 insertions(+), 50 deletions(-) delete mode 100644 packages/app/src/Pages/ChatPage.css delete mode 100644 packages/app/src/Pages/ChatPage.tsx diff --git a/packages/app/src/Element/DmWindow.tsx b/packages/app/src/Element/DmWindow.tsx index 5821845e2..84e26413d 100644 --- a/packages/app/src/Element/DmWindow.tsx +++ b/packages/app/src/Element/DmWindow.tsx @@ -8,11 +8,12 @@ import NoteToSelf from "Element/NoteToSelf"; import useLogin from "Hooks/useLogin"; import WriteMessage from "Element/WriteMessage"; import { Chat, ChatType, useChatSystem } from "chat"; +import { Nip4ChatSystem } from "chat/nip4"; export default function DmWindow({ id }: { id: string }) { const pubKey = useLogin().publicKey; const dms = useChatSystem(); - const chat = dms.find(a => a.id === id); + const chat = dms.find(a => a.id === id) ?? Nip4ChatSystem.createChatObj(id, []); function sender() { if (id === pubKey) { @@ -24,7 +25,7 @@ export default function DmWindow({ id }: { id: string }) { if (chat?.profile) { return ; } - return ; + return ; } return ( @@ -34,7 +35,7 @@ export default function DmWindow({ id }: { id: string }) {
{chat && }
- +
); diff --git a/packages/app/src/Element/WriteMessage.tsx b/packages/app/src/Element/WriteMessage.tsx index 490009ce3..1a3c5941b 100644 --- a/packages/app/src/Element/WriteMessage.tsx +++ b/packages/app/src/Element/WriteMessage.tsx @@ -7,9 +7,9 @@ import useFileUpload from "Upload"; import { openFile } from "SnortUtils"; import Textarea from "./Textarea"; import { System } from "index"; -import { useChatSystem } from "chat"; +import { Chat } from "chat"; -export default function WriteMessage({ chatId }: { chatId: string }) { +export default function WriteMessage({ chat }: { chat: Chat }) { const [msg, setMsg] = useState(""); const [sending, setSending] = useState(false); const [uploading, setUploading] = useState(false); @@ -17,7 +17,6 @@ export default function WriteMessage({ chatId }: { chatId: string }) { const [error, setError] = useState(""); const publisher = useEventPublisher(); const uploader = useFileUpload(); - const chat = useChatSystem().find(a => a.id === chatId); async function attachFile() { try { diff --git a/packages/app/src/Pages/ChatPage.css b/packages/app/src/Pages/ChatPage.css deleted file mode 100644 index f13af8dfa..000000000 --- a/packages/app/src/Pages/ChatPage.css +++ /dev/null @@ -1,3 +0,0 @@ -.chat-page { - height: calc(100vh - 57px); -} diff --git a/packages/app/src/Pages/ChatPage.tsx b/packages/app/src/Pages/ChatPage.tsx deleted file mode 100644 index d1f3e6910..000000000 --- a/packages/app/src/Pages/ChatPage.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import DmWindow from "Element/DmWindow"; -import { useParams } from "react-router-dom"; -import { bech32ToHex } from "SnortUtils"; - -import "./ChatPage.css"; - -export default function ChatPage() { - const { id } = useParams(); - - return ( -
- -
- ); -} diff --git a/packages/app/src/Pages/MessagesPage.tsx b/packages/app/src/Pages/MessagesPage.tsx index 2c52f3b20..a9cdaf4dd 100644 --- a/packages/app/src/Pages/MessagesPage.tsx +++ b/packages/app/src/Pages/MessagesPage.tsx @@ -1,12 +1,12 @@ import React, { useMemo, useState } from "react"; import { FormattedMessage, useIntl } from "react-intl"; -import { useNavigate } from "react-router-dom"; +import { useNavigate, useParams } from "react-router-dom"; import { NostrPrefix } from "@snort/system"; import { useUserProfile } from "@snort/system-react"; import UnreadCount from "Element/UnreadCount"; import ProfileImage, { getDisplayName } from "Element/ProfileImage"; -import { hexToBech32 } from "SnortUtils"; +import { hexToBech32, parseId } from "SnortUtils"; import NoteToSelf from "Element/NoteToSelf"; import useModeration from "Hooks/useModeration"; import useLogin from "Hooks/useLogin"; @@ -29,7 +29,9 @@ export default function MessagesPage() { const login = useLogin(); const { formatMessage } = useIntl(); const navigate = useNavigate(); - const [chat, setChat] = useState(); + const { id } = useParams(); + const parsedId = parseId(id ?? ""); + const [chat, setChat] = useState(id ? parsedId : undefined); const pageWidth = usePageWidth(); const chats = useChatSystem(); diff --git a/packages/app/src/SnortUtils/index.ts b/packages/app/src/SnortUtils/index.ts index b06510ca9..70be24653 100644 --- a/packages/app/src/SnortUtils/index.ts +++ b/packages/app/src/SnortUtils/index.ts @@ -107,7 +107,7 @@ export function profileLink(hex: HexKey, relays?: Array | string) { * Convert hex to bech32 */ export function hexToBech32(hrp: string, hex?: string) { - if (typeof hex !== "string" || hex.length === 0 || hex.length % 2 !== 0) { + if (typeof hex !== "string" || hex.length === 0 || hex.length % 2 !== 0 || !isHex(hex)) { return ""; } @@ -173,6 +173,14 @@ export function deepClone(obj: T) { } } +export function isHex(s: string) { + // 48-57 = 0-9 + // 65-90 = A-Z + // 97-122 = a-z + return [...s] + .map(v => v.charCodeAt(0)) + .every(v => (v >= 48 && v <= 57) || (v >= 65 && v <= 90) || v >= 97 || v <= 122); +} /** * Simple debounce */ diff --git a/packages/app/src/chat/nip4.ts b/packages/app/src/chat/nip4.ts index 49b033d94..48871ed61 100644 --- a/packages/app/src/chat/nip4.ts +++ b/packages/app/src/chat/nip4.ts @@ -40,25 +40,29 @@ export class Nip4ChatSystem extends ExternalStore> implements ChatSy listChats(): Chat[] { const myDms = this.#nip4Events(); - return dedupe(myDms.map(a => a.pubkey)).map(a => { + return dedupe(myDms.map(a => chatTo(a))).map(a => { const messages = myDms.filter(b => chatTo(b) === a || b.pubkey === a); - const last = lastReadInChat(a); - return { - type: ChatType.DirectMessage, - id: a, - unread: messages.reduce((acc, v) => (v.created_at > last ? acc++ : acc), 0), - lastMessage: messages.reduce((acc, v) => (v.created_at > acc ? v.created_at : acc), 0), - messages, - createMessage: (msg, pub) => { - return pub.sendDm(msg, a); - }, - sendMessage: (ev: NostrEvent, system: SystemInterface) => { - system.BroadcastEvent(ev); - }, - } as Chat; + return Nip4ChatSystem.createChatObj(a, messages); }); } + static createChatObj(id: string, messages: Array) { + const last = lastReadInChat(id); + return { + type: ChatType.DirectMessage, + id, + unread: messages.reduce((acc, v) => (v.created_at > last ? acc++ : acc), 0), + lastMessage: messages.reduce((acc, v) => (v.created_at > acc ? v.created_at : acc), 0), + messages, + createMessage: (msg, pub) => { + return pub.sendDm(msg, id); + }, + sendMessage: (ev: NostrEvent, system: SystemInterface) => { + system.BroadcastEvent(ev); + }, + } as Chat; + } + #nip4Events() { return this.#cache.snapshot().filter(a => a.kind === EventKind.DirectMessage); } diff --git a/packages/app/src/index.tsx b/packages/app/src/index.tsx index 348ad87cb..105766f18 100644 --- a/packages/app/src/index.tsx +++ b/packages/app/src/index.tsx @@ -21,7 +21,6 @@ import SettingsPage, { SettingsRoutes } from "Pages/SettingsPage"; import ErrorPage from "Pages/ErrorPage"; import VerificationPage from "Pages/Verification"; import MessagesPage from "Pages/MessagesPage"; -import ChatPage from "Pages/ChatPage"; import DonatePage from "Pages/DonatePage"; import HashTagsPage from "Pages/HashTagsPage"; import SearchPage from "Pages/SearchPage"; @@ -123,13 +122,9 @@ export const router = createBrowserRouter([ element: , }, { - path: "/messages", + path: "/messages/:id?", element: , }, - { - path: "/messages/:id", - element: , - }, { path: "/donate", element: , diff --git a/packages/system/src/nostr-system.ts b/packages/system/src/nostr-system.ts index b4dc744b7..38a3e7bb9 100644 --- a/packages/system/src/nostr-system.ts +++ b/packages/system/src/nostr-system.ts @@ -244,7 +244,9 @@ export class NostrSystem extends ExternalStore implements System */ BroadcastEvent(ev: NostrEvent) { for (const [, s] of this.#sockets) { - s.SendEvent(ev); + if (!s.Ephemeral) { + s.SendEvent(ev); + } } }