fixes #586
This commit is contained in:
Kieran 2023-06-26 12:29:12 +01:00
parent 7c1d5273fc
commit 379bce6f9e
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
9 changed files with 43 additions and 50 deletions

View File

@ -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 <ProfileImage pubkey={id} className="f-grow mb10" profile={chat.profile} />;
}
return <ProfileImage pubkey={""} className="f-grow mb10" overrideUsername={chat?.id} />;
return <ProfileImage pubkey={id ?? ""} className="f-grow mb10" overrideUsername={chat?.id} />;
}
return (
@ -34,7 +35,7 @@ export default function DmWindow({ id }: { id: string }) {
<div className="flex f-col">{chat && <DmChatSelected chat={chat} />}</div>
</div>
<div>
<WriteMessage chatId={id} />
<WriteMessage chat={chat} />
</div>
</div>
);

View File

@ -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 {

View File

@ -1,3 +0,0 @@
.chat-page {
height: calc(100vh - 57px);
}

View File

@ -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 (
<div className="chat-page">
<DmWindow id={bech32ToHex(id ?? "")} />
</div>
);
}

View File

@ -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<string>();
const { id } = useParams();
const parsedId = parseId(id ?? "");
const [chat, setChat] = useState(id ? parsedId : undefined);
const pageWidth = usePageWidth();
const chats = useChatSystem();

View File

@ -107,7 +107,7 @@ export function profileLink(hex: HexKey, relays?: Array<string> | 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<T>(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
*/

View File

@ -40,23 +40,27 @@ export class Nip4ChatSystem extends ExternalStore<Array<Chat>> 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 Nip4ChatSystem.createChatObj(a, messages);
});
}
static createChatObj(id: string, messages: Array<NostrEvent>) {
const last = lastReadInChat(id);
return {
type: ChatType.DirectMessage,
id: a,
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, a);
return pub.sendDm(msg, id);
},
sendMessage: (ev: NostrEvent, system: SystemInterface) => {
system.BroadcastEvent(ev);
},
} as Chat;
});
}
#nip4Events() {

View File

@ -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: <VerificationPage />,
},
{
path: "/messages",
path: "/messages/:id?",
element: <MessagesPage />,
},
{
path: "/messages/:id",
element: <ChatPage />,
},
{
path: "/donate",
element: <DonatePage />,

View File

@ -244,9 +244,11 @@ export class NostrSystem extends ExternalStore<SystemSnapshot> implements System
*/
BroadcastEvent(ev: NostrEvent) {
for (const [, s] of this.#sockets) {
if (!s.Ephemeral) {
s.SendEvent(ev);
}
}
}
/**
* Write an event to a relay then disconnect