Handle chat response (#147)

This commit is contained in:
Szymon Szlachtowicz 2021-12-06 23:31:53 +01:00 committed by GitHub
parent 6338c79af0
commit 3c9d514b92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 46 additions and 23 deletions

View File

@ -76,7 +76,7 @@ function DragDiv() {
<ReactChat <ReactChat
theme={theme ? lightTheme : darkTheme} theme={theme ? lightTheme : darkTheme}
communityKey={ communityKey={
"0x02516353a03fc3892d268a72f4c4b2b0fad179702a996a87346407139949767ba7" "0x022213984be07b1fa120ccd4dcbad161036d651e69dbaf04e45e5c5009e815d86b"
} }
fetchMetadata={fetchMetadata} fetchMetadata={fetchMetadata}
/> />

View File

@ -46,6 +46,7 @@
"dependencies": { "dependencies": {
"emoji-mart": "^3.0.1", "emoji-mart": "^3.0.1",
"html-entities": "^2.3.2", "html-entities": "^2.3.2",
"js-sha3": "^0.8.0",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-is": "^17.0.2", "react-is": "^17.0.2",

View File

@ -108,7 +108,7 @@ export function ChatInput({ reply, setReply }: ChatInputProps) {
e.preventDefault(); e.preventDefault();
(e.target as HTMLDivElement).style.height = "40px"; (e.target as HTMLDivElement).style.height = "40px";
setInputHeight(40); setInputHeight(40);
sendMessage(content, imageUint); sendMessage(content, imageUint, reply?.id);
setImageUint(undefined); setImageUint(undefined);
setClearComponent(""); setClearComponent("");
if (inputRef.current) { if (inputRef.current) {

View File

@ -31,6 +31,7 @@ type ChatUiMessageProps = {
setImage: (img: string) => void; setImage: (img: string) => void;
setLink: (link: string) => void; setLink: (link: string) => void;
setReply: (val: Reply | undefined) => void; setReply: (val: Reply | undefined) => void;
quote?: ChatMessage;
}; };
function ChatUiMessage({ function ChatUiMessage({
@ -40,6 +41,7 @@ function ChatUiMessage({
setImage, setImage,
setLink, setLink,
setReply, setReply,
quote,
}: ChatUiMessageProps) { }: ChatUiMessageProps) {
const { contacts } = useMessengerContext(); const { contacts } = useMessengerContext();
const contact = useMemo( const contact = useMemo(
@ -60,14 +62,14 @@ function ChatUiMessage({
)} )}
<MessageWrapper className={`${mentioned && "mention"}`}> <MessageWrapper className={`${mentioned && "mention"}`}>
{message.quote && ( {quote && (
<QuoteWrapper> <QuoteWrapper>
<QuoteSvg width={22} height={25} /> <QuoteSvg width={22} height={25} />
<QuoteAuthor> <QuoteAuthor>
{" "} {" "}
<UserIcon memberView={true} /> {message.quote.author} <UserIcon memberView={true} /> {quote.sender}
</QuoteAuthor> </QuoteAuthor>
<Quote>{message.quote.content} </Quote> <Quote>{quote.content} </Quote>
</QuoteWrapper> </QuoteWrapper>
)} )}
<UserMessageWrapper> <UserMessageWrapper>
@ -114,7 +116,11 @@ function ChatUiMessage({
</ReactionBtn> </ReactionBtn>
<ReactionBtn <ReactionBtn
onClick={() => onClick={() =>
setReply({ sender: message.sender, content: message.content }) setReply({
sender: message.sender,
content: message.content,
id: message.id,
})
} }
> >
<ReplySvg width={22} height={22} /> <ReplySvg width={22} height={22} />
@ -171,13 +177,14 @@ export function ChatMessages({ setReply }: ChatMessagesProps) {
)} )}
{shownMessages.map((message, idx) => ( {shownMessages.map((message, idx) => (
<ChatUiMessage <ChatUiMessage
key={message.date.getTime().toString() + message.content} key={message.id}
message={message} message={message}
idx={idx} idx={idx}
prevMessage={shownMessages[idx - 1]} prevMessage={shownMessages[idx - 1]}
setLink={setLink} setLink={setLink}
setImage={setImage} setImage={setImage}
setReply={setReply} setReply={setReply}
quote={shownMessages.find((msg) => msg.id == message?.responseTo)}
/> />
))} ))}
</MessagesWrapper> </MessagesWrapper>

View File

@ -26,7 +26,8 @@ export type MessengerType = {
messages: ChatMessage[]; messages: ChatMessage[];
sendMessage: ( sendMessage: (
messageText?: string | undefined, messageText?: string | undefined,
image?: Uint8Array | undefined image?: Uint8Array | undefined,
responseTo?: string
) => Promise<void>; ) => Promise<void>;
notifications: { [chatId: string]: number }; notifications: { [chatId: string]: number };
clearNotifications: (id: string) => void; clearNotifications: (id: string) => void;
@ -199,7 +200,7 @@ export function useMessenger(
}, [messenger, community]); }, [messenger, community]);
const sendMessage = useCallback( const sendMessage = useCallback(
async (messageText?: string, image?: Uint8Array) => { async (messageText?: string, image?: Uint8Array, responseTo?: string) => {
let content; let content;
if (messageText) { if (messageText) {
content = { content = {
@ -218,7 +219,7 @@ export function useMessenger(
if (activeChannel.type === "group") { if (activeChannel.type === "group") {
await groupChat?.sendMessage(activeChannel.id, content); await groupChat?.sendMessage(activeChannel.id, content);
} else { } else {
await messenger?.sendMessage(activeChannel.id, content); await messenger?.sendMessage(activeChannel.id, content, responseTo);
} }
} }
}, },

View File

@ -1,4 +1,5 @@
export type Reply = { export type Reply = {
sender: string; sender: string;
content: string; content: string;
id: string;
}; };

View File

@ -1,3 +1,4 @@
import { keccak256 } from "js-sha3";
import { ApplicationMetadataMessage, utils } from "status-communities/dist/cjs"; import { ApplicationMetadataMessage, utils } from "status-communities/dist/cjs";
import { uintToImgUrl } from "../utils"; import { uintToImgUrl } from "../utils";
@ -7,23 +8,22 @@ export class ChatMessage {
date: Date; date: Date;
sender: string; sender: string;
image?: string; image?: string;
quote?: { responseTo?: string;
author: string; id: string;
content: string;
};
constructor( constructor(
content: string, content: string,
date: Date, date: Date,
sender: string, sender: string,
image?: string, image?: string,
quote?: { author: string; content: string } responseTo?: string
) { ) {
this.content = content; this.content = content;
this.date = date; this.date = date;
this.sender = sender; this.sender = sender;
this.image = image; this.image = image;
this.quote = quote; this.responseTo = responseTo;
this.id = keccak256(date.getTime().toString() + content);
} }
public static fromMetadataMessage( public static fromMetadataMessage(
@ -41,7 +41,13 @@ export class ChatMessage {
image = uintToImgUrl(msg.chatMessage?.image.payload); image = uintToImgUrl(msg.chatMessage?.image.payload);
} }
const sender = utils.bufToHex(msg.signer); const sender = utils.bufToHex(msg.signer);
return new ChatMessage(content, date, sender, image); return new ChatMessage(
content,
date,
sender,
image,
msg.chatMessage.responseTo
);
} else { } else {
return undefined; return undefined;
} }

View File

@ -33,14 +33,15 @@ export class Chat {
return idToContentTopic(this.id); return idToContentTopic(this.id);
} }
public createMessage(content: Content): ChatMessage { public createMessage(content: Content, responseTo?: string): ChatMessage {
const { timestamp, clock } = this._nextClockAndTimestamp(); const { timestamp, clock } = this._nextClockAndTimestamp();
const message = ChatMessage.createMessage( const message = ChatMessage.createMessage(
clock, clock,
timestamp, timestamp,
this.id, this.id,
content content,
responseTo
); );
this._updateClockFromMessage(message); this._updateClockFromMessage(message);

View File

@ -100,11 +100,15 @@ export class Messenger {
/** /**
* Sends a message on the given chat Id. * Sends a message on the given chat Id.
*/ */
public async sendMessage(chatId: string, content: Content): Promise<void> { public async sendMessage(
chatId: string,
content: Content,
responseTo?: string
): Promise<void> {
const chat = this.chatsById.get(chatId); const chat = this.chatsById.get(chatId);
if (!chat) throw `Failed to send message, chat not joined: ${chatId}`; if (!chat) throw `Failed to send message, chat not joined: ${chatId}`;
const chatMessage = chat.createMessage(content); const chatMessage = chat.createMessage(content, responseTo);
const appMetadataMessage = ApplicationMetadataMessage.create( const appMetadataMessage = ApplicationMetadataMessage.create(
chatMessage.encode(), chatMessage.encode(),

View File

@ -75,7 +75,8 @@ export class ChatMessage {
clock: number, clock: number,
timestamp: number, timestamp: number,
chatId: string, chatId: string,
content: Content content: Content,
responseTo?: string
): ChatMessage { ): ChatMessage {
let sticker, let sticker,
image, image,
@ -117,7 +118,7 @@ export class ChatMessage {
timestamp, //ms? timestamp, //ms?
text, text,
/** Id of the message that we are replying to */ /** Id of the message that we are replying to */
responseTo: "", responseTo: responseTo ?? "",
/** Ens name of the sender */ /** Ens name of the sender */
ensName: "", ensName: "",
/** Public Key of the community (TBC) **/ /** Public Key of the community (TBC) **/

View File

@ -288,6 +288,7 @@ __metadata:
emoji-mart: ^3.0.1 emoji-mart: ^3.0.1
eslint: ^7.32.0 eslint: ^7.32.0
html-entities: ^2.3.2 html-entities: ^2.3.2
js-sha3: ^0.8.0
jsdom: ^16.7.0 jsdom: ^16.7.0
jsdom-global: ^3.0.2 jsdom-global: ^3.0.2
mocha: ^9.0.3 mocha: ^9.0.3