Use community api (#84)

This commit is contained in:
Szymon Szlachtowicz 2021-10-19 13:12:44 +02:00 committed by GitHub
parent e8a754f418
commit bb710034c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 111 additions and 42 deletions

View File

@ -1,4 +1,4 @@
import { community, lightTheme, ReactChat } from "@dappconnect/react-chat";
import { lightTheme, ReactChat } from "@dappconnect/react-chat";
import React, { useRef, useState } from "react";
import ReactDOM from "react-dom";
import styled from "styled-components";
@ -65,7 +65,9 @@ function DragDiv() {
<FloatingDiv className={showChat ? "" : "hide"}>
<ReactChat
theme={lightTheme}
community={community}
communityKey={
"0x0262c65c881f5a9f79343a26faaa02aad3af7c533d9445fb1939ed11b8bf4d2abd"
}
fetchMetadata={fetchMetadata}
/>
</FloatingDiv>

View File

@ -1,7 +1,7 @@
import React, { useEffect } from "react";
import styled from "styled-components";
import { ChannelData, channels } from "../../helpers/channelsMock";
import { ChannelData } from "../../helpers/channelsMock";
import { Channel } from "./Channel";
@ -9,7 +9,8 @@ interface ChannelsProps {
notifications: { [id: string]: number };
clearNotifications: (id: string) => void;
onCommunityClick: (val: ChannelData) => void;
activeChannelId: number;
activeChannelId: string;
channels: ChannelData[];
}
export function Channels({
@ -17,6 +18,7 @@ export function Channels({
onCommunityClick,
clearNotifications,
activeChannelId,
channels,
}: ChannelsProps) {
useEffect(() => {
const channel = channels.find((channel) => channel.id === activeChannelId);

View File

@ -1,9 +1,9 @@
import React, { useState } from "react";
import React, { useEffect, useMemo, useState } from "react";
import styled from "styled-components";
import { useNarrow } from "../contexts/narrowProvider";
import { ChannelData, channels } from "../helpers/channelsMock";
import { CommunityData } from "../helpers/communityMock";
import { ChannelData } from "../helpers/channelsMock";
import { uintToImgUrl } from "../helpers/uintToImgUrl";
import { useMessenger } from "../hooks/useMessenger";
import { Metadata } from "../models/Metadata";
import { Theme } from "../styles/themes";
@ -16,12 +16,16 @@ import { CommunityModal } from "./Modals/CommunityModal";
interface ChatProps {
theme: Theme;
community: CommunityData;
communityKey: string;
fetchMetadata?: (url: string) => Promise<Metadata | undefined>;
}
export function Chat({ theme, community, fetchMetadata }: ChatProps) {
const [activeChannel, setActiveChannel] = useState<ChannelData>(channels[0]);
export function Chat({ theme, communityKey, fetchMetadata }: ChatProps) {
const [activeChannel, setActiveChannel] = useState<ChannelData>({
id: "",
name: "",
description: "",
});
const [showMembers, setShowMembers] = useState(true);
const [showChannels, setShowChannels] = useState(true);
const narrow = useNarrow();
@ -34,24 +38,67 @@ export function Chat({ theme, community, fetchMetadata }: ChatProps) {
clearNotifications,
loadNextDay,
loadingMessages,
} = useMessenger(
activeChannel.name,
channels.map((channel) => channel.name)
);
community,
} = useMessenger(activeChannel?.id ?? "", communityKey);
const [isModalVisible, setIsModalVisible] = useState(false);
const showModal = () => setIsModalVisible(true);
const communityData = useMemo(() => {
if (community?.description) {
return {
id: 1,
name: community.description.identity?.displayName ?? "",
icon: uintToImgUrl(
community.description?.identity?.images?.thumbnail.payload ??
new Uint8Array()
),
members: 0,
membersList: [],
description: community.description.identity?.description ?? "",
};
} else {
return {
id: 1,
name: "",
icon: "",
members: 0,
membersList: [],
description: "",
};
}
}, [community]);
const channels = useMemo(() => {
console.log(community?.chats);
if (community?.chats) {
return Array.from(community.chats.values()).map((chat) => {
return {
id: chat.id,
name: chat.communityChat?.identity?.displayName ?? "",
description: chat.communityChat?.identity?.description ?? "",
};
});
} else {
return [];
}
}, [community]);
useEffect(() => {
if (channels.length > 0) setActiveChannel(channels[0]);
}, [channels]);
return (
<ChatWrapper>
{showChannels && !narrow && (
<ChannelsWrapper>
<StyledCommunity onClick={showModal} community={community} />
<StyledCommunity onClick={showModal} community={communityData} />
<Channels
notifications={notifications}
clearNotifications={clearNotifications}
onCommunityClick={(e) => setActiveChannel(e)}
activeChannelId={activeChannel.id}
activeChannelId={activeChannel?.id ?? ""}
channels={channels}
/>
</ChannelsWrapper>
)}
@ -66,25 +113,26 @@ export function Chat({ theme, community, fetchMetadata }: ChatProps) {
activeChannelId={activeChannel.id}
onClick={() => setShowMembers(!showMembers)}
showMembers={showMembers}
community={community}
community={communityData}
showCommunity={!showChannels}
loadNextDay={() => loadNextDay(activeChannel.name)}
onCommunityClick={showModal}
fetchMetadata={fetchMetadata}
loadingMessages={loadingMessages}
clearNotifications={clearNotifications}
channels={channels}
/>
{showMembers && !narrow && (
<Members community={community} setShowChannels={setShowChannels} />
<Members community={communityData} setShowChannels={setShowChannels} />
)}
<CommunityModal
isVisible={isModalVisible}
onClose={() => setIsModalVisible(false)}
icon={community.icon}
name={community.name}
icon={communityData.icon}
name={communityData.name}
subtitle="Public Community"
description={community.description}
publicKey="0xD95DBdaB08A9FED2D71ac9C3028AAc40905d8CF3"
description={communityData.description}
publicKey={communityKey}
/>
</ChatWrapper>
);

View File

@ -31,12 +31,13 @@ interface ChatBodyProps {
showCommunity: boolean;
notifications: { [id: string]: number };
setActiveChannel: (val: ChannelData) => void;
activeChannelId: number;
activeChannelId: string;
loadNextDay: () => void;
onCommunityClick: () => void;
fetchMetadata?: (url: string) => Promise<Metadata | undefined>;
loadingMessages: boolean;
clearNotifications: (id: string) => void;
channels: ChannelData[];
}
export function ChatBody({
@ -57,6 +58,7 @@ export function ChatBody({
fetchMetadata,
loadingMessages,
clearNotifications,
channels,
}: ChatBodyProps) {
const narrow = useNarrow();
const [showChannelsList, setShowChannelsList] = useState(false);
@ -137,6 +139,7 @@ export function ChatBody({
{showChannelsList && narrow && (
<NarrowChannels
channels={channels}
community={community.name}
notifications={notifications}
setActiveChannel={setActiveChannel}

View File

@ -10,9 +10,10 @@ interface NarrowChannelsProps {
community: string;
notifications: { [id: string]: number };
setActiveChannel: (val: ChannelData) => void;
activeChannelId: number;
activeChannelId: string;
setShowChannels: (val: boolean) => void;
clearNotifications: (id: string) => void;
channels: ChannelData[];
}
export function NarrowChannels({
@ -22,6 +23,7 @@ export function NarrowChannels({
activeChannelId,
setShowChannels,
clearNotifications,
channels,
}: NarrowChannelsProps) {
return (
<ListWrapper>
@ -34,6 +36,7 @@ export function NarrowChannels({
setShowChannels(false);
}}
activeChannelId={activeChannelId}
channels={channels}
/>
</ListWrapper>
);

View File

@ -3,7 +3,6 @@ import { ThemeProvider } from "styled-components";
import styled from "styled-components";
import { NarrowProvider } from "../contexts/narrowProvider";
import { CommunityData } from "../helpers/communityMock";
import { Metadata } from "../models/Metadata";
import { GlobalStyle } from "../styles/GlobalStyle";
import { Theme } from "../styles/themes";
@ -12,11 +11,15 @@ import { Chat } from "./Chat";
interface ReactChatProps {
theme: Theme;
community: CommunityData;
communityKey: string;
fetchMetadata?: (url: string) => Promise<Metadata | undefined>;
}
export function ReactChat({ theme, community, fetchMetadata }: ReactChatProps) {
export function ReactChat({
theme,
communityKey,
fetchMetadata,
}: ReactChatProps) {
const ref = useRef<HTMLHeadingElement>(null);
return (
<ThemeProvider theme={theme}>
@ -24,7 +27,7 @@ export function ReactChat({ theme, community, fetchMetadata }: ReactChatProps) {
<Wrapper ref={ref}>
<GlobalStyle />
<Chat
community={community}
communityKey={communityKey}
fetchMetadata={fetchMetadata}
theme={theme}
/>

View File

@ -1,9 +1,8 @@
export type ChannelData = {
id: number;
id: string;
name: string;
description: string;
icon?: string;
notifications?: number;
isMuted?: boolean;
};

View File

@ -1,7 +1,7 @@
// import { StoreCodec } from "js-waku";
import { StoreCodec } from "js-waku";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Identity, Messenger } from "status-communities/dist/cjs";
import { Community, Identity, Messenger } from "status-communities/dist/cjs";
import { ApplicationMetadataMessage } from "status-communities/dist/cjs";
import { uintToImgUrl } from "../helpers/uintToImgUrl";
@ -32,11 +32,12 @@ function binarySetInsert<T>(
return arr;
}
export function useMessenger(chatId: string, chatIdList: string[]) {
export function useMessenger(chatId: string, communityKey: string) {
const [messenger, setMessenger] = useState<Messenger | undefined>(undefined);
const [messages, setMessages] = useState<{ [chatId: string]: ChatMessage[] }>(
{}
);
const [community, setCommunity] = useState<Community | undefined>(undefined);
const [notifications, setNotifications] = useState<{
[chatId: string]: number;
}>({});
@ -105,7 +106,7 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
const loadNextDay = useCallback(
async (id: string) => {
if (messenger) {
const endTime = lastLoadTime.current[id];
const endTime = lastLoadTime.current[id] ?? new Date();
const startTime = new Date(endTime.getTime() - _MS_PER_DAY);
const timeDiff = Math.floor(
(new Date().getTime() - endTime.getTime()) / _MS_PER_DAY
@ -139,6 +140,7 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
const createMessenger = async () => {
// Test password for now
// Need design for password input
let identity = await loadIdentity("test");
if (!identity) {
identity = Identity.generate();
@ -164,16 +166,20 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
}
);
});
await Promise.all(
chatIdList.map(async (id) => {
await messenger.joinChatById(id);
lastLoadTime.current[id] = new Date();
messenger.addObserver(
(msg, date) => addNewMessage(msg, id, date),
id
const community = await Community.instantiateCommunity(
communityKey,
messenger.waku
);
clearNotifications(id);
setCommunity(community);
await Promise.all(
Array.from(community.chats.values()).map(async (chat) => {
await messenger.joinChat(chat);
lastLoadTime.current[chat.id] = new Date();
messenger.addObserver(
(msg, date) => addNewMessage(msg, chat.id, date),
chat.id
);
clearNotifications(chat.id);
})
);
setMessenger(messenger);
@ -182,8 +188,10 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
}, []);
useEffect(() => {
if (messenger) {
chatIdList.forEach(loadNextDay);
if (messenger && community?.chats) {
Array.from(community?.chats.values()).forEach(({ id }) =>
loadNextDay(id)
);
}
}, [messenger]);
@ -224,5 +232,6 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
loadNextDay,
lastMessage,
loadingMessages,
community,
};
}