Refactor useMessages (#140)

This commit is contained in:
Szymon Szlachtowicz 2021-11-29 16:35:30 +01:00 committed by GitHub
parent 593bc563f0
commit faef8d0a02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 123 additions and 82 deletions

View File

@ -0,0 +1,56 @@
import { useEffect, useMemo, useState } from "react";
import {
Contacts as ContactsClass,
Identity,
Messenger,
} from "status-communities/dist/cjs";
import { Contacts } from "../../models/Contact";
export function useContacts(
messenger: Messenger | undefined,
identity: Identity | undefined
) {
const [internalContacts, setInternalContacts] = useState<{
[id: string]: number;
}>({});
const contactsClass = useMemo(() => {
if (messenger && identity) {
const newContacts = new ContactsClass(
identity,
messenger.waku,
(id, clock) => {
setInternalContacts((prev) => {
return { ...prev, [id]: clock };
});
}
);
return newContacts;
}
}, [messenger, identity]);
const [contacts, setContacts] = useState<Contacts>({});
useEffect(() => {
const now = Date.now();
setContacts((prev) => {
const newContacts: Contacts = {};
Object.entries(internalContacts).forEach(([id, clock]) => {
newContacts[id] = {
id,
online: clock > now - 301000,
trueName: id.slice(0, 10),
isUntrustworthy: false,
blocked: false,
};
if (prev[id]) {
newContacts[id] = { ...prev[id], ...newContacts[id] };
}
});
return newContacts;
});
}, [internalContacts]);
return { contacts, setContacts, contactsClass };
}

View File

@ -1,6 +1,7 @@
// import { StoreCodec } from "js-waku"; // import { StoreCodec } from "js-waku";
import { useCallback, useEffect, useMemo, useState } from "react"; import { useCallback, useEffect, useMemo, useState } from "react";
import { import {
ApplicationMetadataMessage,
Community, Community,
Contacts as ContactsClass, Contacts as ContactsClass,
Identity, Identity,
@ -15,6 +16,7 @@ import { createCommunity } from "../../utils/createCommunity";
import { createMessenger } from "../../utils/createMessenger"; import { createMessenger } from "../../utils/createMessenger";
import { uintToImgUrl } from "../../utils/uintToImgUrl"; import { uintToImgUrl } from "../../utils/uintToImgUrl";
import { useContacts } from "./useContacts";
import { useGroupChats } from "./useGroupChats"; import { useGroupChats } from "./useGroupChats";
import { useLoadPrevDay } from "./useLoadPrevDay"; import { useLoadPrevDay } from "./useLoadPrevDay";
import { useMessages } from "./useMessages"; import { useMessages } from "./useMessages";
@ -43,6 +45,57 @@ export type MessengerType = {
createGroupChat: (members: string[]) => void; createGroupChat: (members: string[]) => void;
}; };
function useCreateMessenger(identity: Identity | undefined) {
const [messenger, setMessenger] = useState<Messenger | undefined>(undefined);
useEffect(() => {
if (identity) {
createMessenger(identity).then((e) => {
setMessenger(e);
});
}
}, [identity]);
return messenger;
}
function useCreateCommunity(
messenger: Messenger | undefined,
communityKey: string | undefined,
addMessage: (msg: ApplicationMetadataMessage, id: string, date: Date) => void,
contactsClass: ContactsClass | undefined
) {
const [community, setCommunity] = useState<Community | undefined>(undefined);
useEffect(() => {
if (messenger && communityKey && contactsClass) {
createCommunity(communityKey, addMessage, messenger).then((comm) => {
setCommunity(comm);
});
}
}, [messenger, communityKey, addMessage, contactsClass]);
const communityData = useMemo(() => {
if (community?.description) {
Object.keys(community.description.proto.members).forEach((contact) =>
contactsClass?.addContact(contact)
);
return {
id: community.publicKeyStr,
name: community.description.identity?.displayName ?? "",
icon: uintToImgUrl(
community.description?.identity?.images?.thumbnail?.payload ??
new Uint8Array()
),
members: 0,
membersList: Object.keys(community.description.proto.members),
description: community.description.identity?.description ?? "",
};
} else {
return undefined;
}
}, [community]);
return { community, communityData };
}
export function useMessenger( export function useMessenger(
communityKey: string | undefined, communityKey: string | undefined,
identity: Identity | undefined identity: Identity | undefined
@ -54,50 +107,12 @@ export function useMessenger(
type: "channel", type: "channel",
}); });
const chatId = useMemo(() => activeChannel.id, [activeChannel]); const messenger = useCreateMessenger(identity);
const [messenger, setMessenger] = useState<Messenger | undefined>(undefined); const { contacts, setContacts, contactsClass } = useContacts(
messenger,
const [internalContacts, setInternalContacts] = useState<{ identity
[id: string]: number;
}>({});
const contactsClass = useMemo(() => {
if (messenger && identity) {
const newContacts = new ContactsClass(
identity,
messenger.waku,
(id, clock) => {
setInternalContacts((prev) => {
return { ...prev, [id]: clock };
});
}
); );
return newContacts;
}
}, [messenger, identity]);
const [contacts, setContacts] = useState<Contacts>({});
useEffect(() => {
const now = Date.now();
setContacts((prev) => {
const newContacts: Contacts = {};
Object.entries(internalContacts).forEach(([id, clock]) => {
newContacts[id] = {
id,
online: clock > now - 301000,
trueName: id.slice(0, 10),
isUntrustworthy: false,
blocked: false,
};
if (prev[id]) {
newContacts[id] = { ...prev[id], ...newContacts[id] };
}
});
return newContacts;
});
}, [internalContacts]);
const { const {
addChatMessage, addChatMessage,
@ -107,24 +122,14 @@ export function useMessenger(
messages, messages,
mentions, mentions,
clearMentions, clearMentions,
} = useMessages(chatId, identity, contactsClass); } = useMessages(activeChannel.id, identity, contactsClass);
const [community, setCommunity] = useState<Community | undefined>(undefined);
useEffect(() => { const { community, communityData } = useCreateCommunity(
if (identity) { messenger,
createMessenger(identity).then((e) => { communityKey,
setMessenger(e); addMessage,
}); contactsClass
} );
}, [identity]);
useEffect(() => {
if (messenger && communityKey && contactsClass) {
createCommunity(communityKey, addMessage, messenger).then((comm) => {
setCommunity(comm);
});
}
}, [messenger, communityKey, addMessage, contactsClass]);
const [channels, setChannels] = useState<ChannelsData>({}); const [channels, setChannels] = useState<ChannelsData>({});
@ -162,27 +167,6 @@ export function useMessenger(
}); });
}, [contacts]); }, [contacts]);
const communityData = useMemo(() => {
if (community?.description) {
Object.keys(community.description.proto.members).forEach((contact) =>
contactsClass?.addContact(contact)
);
return {
id: community.publicKeyStr,
name: community.description.identity?.displayName ?? "",
icon: uintToImgUrl(
community.description?.identity?.images?.thumbnail?.payload ??
new Uint8Array()
),
members: 0,
membersList: Object.keys(community.description.proto.members),
description: community.description.identity?.description ?? "",
};
} else {
return undefined;
}
}, [community]);
const { groupChat, removeChannel, createGroupChat } = useGroupChats( const { groupChat, removeChannel, createGroupChat } = useGroupChats(
messenger, messenger,
identity, identity,
@ -193,10 +177,11 @@ export function useMessenger(
); );
const { loadPrevDay, loadingMessages } = useLoadPrevDay( const { loadPrevDay, loadingMessages } = useLoadPrevDay(
chatId, activeChannel.id,
messenger, messenger,
groupChat groupChat
); );
useEffect(() => { useEffect(() => {
if (messenger && community?.chats) { if (messenger && community?.chats) {
Array.from(community?.chats.values()).forEach(({ id }) => Array.from(community?.chats.values()).forEach(({ id }) =>