2022-02-04 03:12:00 +00:00
|
|
|
import { useEffect, useReducer, useState } from "react";
|
|
|
|
import "./App.css";
|
2022-01-13 03:28:45 +00:00
|
|
|
import {
|
|
|
|
PageDirection,
|
2022-02-16 00:43:57 +00:00
|
|
|
getPredefinedBootstrapNodes,
|
2022-01-13 03:28:45 +00:00
|
|
|
Waku,
|
|
|
|
WakuMessage,
|
2022-02-04 03:12:00 +00:00
|
|
|
} from "js-waku";
|
|
|
|
import handleCommand from "./command";
|
|
|
|
import Room from "./Room";
|
|
|
|
import { WakuContext } from "./WakuContext";
|
|
|
|
import { ThemeProvider } from "@livechat/ui-kit";
|
|
|
|
import { generate } from "server-name-generator";
|
|
|
|
import { Message } from "./Message";
|
2022-02-16 00:43:57 +00:00
|
|
|
import { Fleet } from "js-waku/lib/discovery/predefined";
|
2021-04-14 04:44:12 +00:00
|
|
|
|
2021-05-03 21:53:26 +00:00
|
|
|
const themes = {
|
|
|
|
AuthorName: {
|
|
|
|
css: {
|
2022-02-04 03:12:00 +00:00
|
|
|
fontSize: "1.1em",
|
2021-05-03 21:53:26 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
Message: {
|
|
|
|
css: {
|
2022-02-04 03:12:00 +00:00
|
|
|
margin: "0em",
|
|
|
|
padding: "0em",
|
|
|
|
fontSize: "0.83em",
|
2021-05-03 21:53:26 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
MessageText: {
|
|
|
|
css: {
|
2022-02-04 03:12:00 +00:00
|
|
|
margin: "0em",
|
|
|
|
padding: "0.1em",
|
|
|
|
paddingLeft: "1em",
|
|
|
|
fontSize: "1.1em",
|
2021-05-03 21:53:26 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
MessageGroup: {
|
|
|
|
css: {
|
2022-02-04 03:12:00 +00:00
|
|
|
margin: "0em",
|
|
|
|
padding: "0.2em",
|
2021-05-03 21:53:26 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2022-02-04 03:12:00 +00:00
|
|
|
export const ChatContentTopic = "/toy-chat/2/huilong/proto";
|
2021-04-21 05:51:52 +00:00
|
|
|
|
2021-05-17 06:19:50 +00:00
|
|
|
async function retrieveStoreMessages(
|
|
|
|
waku: Waku,
|
2021-05-28 06:31:08 +00:00
|
|
|
setArchivedMessages: (value: Message[]) => void
|
2021-05-17 06:19:50 +00:00
|
|
|
): Promise<number> {
|
|
|
|
const callback = (wakuMessages: WakuMessage[]): void => {
|
2021-05-28 06:31:08 +00:00
|
|
|
const messages: Message[] = [];
|
|
|
|
wakuMessages
|
|
|
|
.map((wakuMsg) => Message.fromWakuMessage(wakuMsg))
|
|
|
|
.forEach((message) => {
|
|
|
|
if (message) {
|
|
|
|
messages.push(message);
|
|
|
|
}
|
|
|
|
});
|
2021-05-17 06:19:50 +00:00
|
|
|
setArchivedMessages(messages);
|
|
|
|
};
|
|
|
|
|
2021-08-26 01:50:20 +00:00
|
|
|
const startTime = new Date();
|
|
|
|
// Only retrieve a week of history
|
|
|
|
startTime.setTime(Date.now() - 1000 * 60 * 60 * 24 * 7);
|
|
|
|
|
|
|
|
const endTime = new Date();
|
|
|
|
|
2021-08-04 02:35:47 +00:00
|
|
|
try {
|
|
|
|
const res = await waku.store.queryHistory([ChatContentTopic], {
|
|
|
|
pageSize: 5,
|
2021-10-04 01:21:13 +00:00
|
|
|
pageDirection: PageDirection.FORWARD,
|
2021-08-26 01:50:20 +00:00
|
|
|
timeFilter: {
|
|
|
|
startTime,
|
|
|
|
endTime,
|
|
|
|
},
|
2021-08-04 02:35:47 +00:00
|
|
|
callback,
|
|
|
|
});
|
2021-05-17 06:19:50 +00:00
|
|
|
|
2021-08-04 02:35:47 +00:00
|
|
|
return res.length;
|
2021-09-02 05:01:52 +00:00
|
|
|
} catch (e) {
|
2022-02-04 03:12:00 +00:00
|
|
|
console.log("Failed to retrieve messages", e);
|
2021-08-04 02:35:47 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2021-05-17 06:19:50 +00:00
|
|
|
}
|
|
|
|
|
2021-04-22 00:39:05 +00:00
|
|
|
export default function App() {
|
2021-07-29 06:30:06 +00:00
|
|
|
const [messages, dispatchMessages] = useReducer(reduceMessages, []);
|
2021-07-15 04:11:00 +00:00
|
|
|
const [waku, setWaku] = useState<Waku | undefined>(undefined);
|
|
|
|
const [nick, setNick] = useState<string>(() => {
|
2022-02-04 03:12:00 +00:00
|
|
|
const persistedNick = window.localStorage.getItem("nick");
|
2021-06-04 05:15:07 +00:00
|
|
|
return persistedNick !== null ? persistedNick : generate();
|
|
|
|
});
|
2022-01-06 06:40:40 +00:00
|
|
|
const [historicalMessagesRetrieved, setHistoricalMessagesRetrieved] =
|
|
|
|
useState(false);
|
2021-06-04 05:15:07 +00:00
|
|
|
|
|
|
|
useEffect(() => {
|
2022-02-04 03:12:00 +00:00
|
|
|
localStorage.setItem("nick", nick);
|
2021-06-04 05:15:07 +00:00
|
|
|
}, [nick]);
|
2021-04-19 01:34:13 +00:00
|
|
|
|
2021-04-21 06:11:07 +00:00
|
|
|
useEffect(() => {
|
2021-07-28 01:42:42 +00:00
|
|
|
initWaku(setWaku)
|
2022-02-04 03:12:00 +00:00
|
|
|
.then(() => console.log("Waku init done"))
|
|
|
|
.catch((e) => console.log("Waku init failed ", e));
|
2021-07-28 01:42:42 +00:00
|
|
|
}, []);
|
2021-06-04 05:20:36 +00:00
|
|
|
|
|
|
|
useEffect(() => {
|
2021-07-15 04:08:07 +00:00
|
|
|
if (!waku) return;
|
2021-07-29 06:30:06 +00:00
|
|
|
// Let's retrieve previous messages before listening to new messages
|
|
|
|
if (!historicalMessagesRetrieved) return;
|
2021-06-04 05:20:36 +00:00
|
|
|
|
2021-05-10 02:38:27 +00:00
|
|
|
const handleRelayMessage = (wakuMsg: WakuMessage) => {
|
2022-02-04 03:12:00 +00:00
|
|
|
console.log("Message received: ", wakuMsg);
|
2021-05-28 06:31:08 +00:00
|
|
|
const msg = Message.fromWakuMessage(wakuMsg);
|
|
|
|
if (msg) {
|
2021-07-29 06:30:06 +00:00
|
|
|
dispatchMessages([msg]);
|
2021-04-30 05:25:58 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-07-15 04:08:07 +00:00
|
|
|
waku.relay.addObserver(handleRelayMessage, [ChatContentTopic]);
|
2021-06-04 05:20:36 +00:00
|
|
|
|
2021-07-15 04:09:58 +00:00
|
|
|
return function cleanUp() {
|
|
|
|
waku?.relay.deleteObserver(handleRelayMessage, [ChatContentTopic]);
|
|
|
|
};
|
2021-07-29 06:30:06 +00:00
|
|
|
}, [waku, historicalMessagesRetrieved]);
|
2021-06-04 05:20:36 +00:00
|
|
|
|
|
|
|
useEffect(() => {
|
2021-07-15 04:08:07 +00:00
|
|
|
if (!waku) return;
|
2021-07-29 06:30:06 +00:00
|
|
|
if (historicalMessagesRetrieved) return;
|
2021-06-04 05:20:36 +00:00
|
|
|
|
2021-09-02 05:01:52 +00:00
|
|
|
const retrieveMessages = async () => {
|
2022-01-30 10:56:21 +00:00
|
|
|
await waku.waitForRemotePeer();
|
2022-02-02 04:12:08 +00:00
|
|
|
console.log(`Retrieving archived messages`);
|
2021-09-02 05:01:52 +00:00
|
|
|
|
|
|
|
try {
|
|
|
|
retrieveStoreMessages(waku, dispatchMessages).then((length) => {
|
|
|
|
console.log(`Messages retrieved:`, length);
|
|
|
|
setHistoricalMessagesRetrieved(true);
|
|
|
|
});
|
|
|
|
} catch (e) {
|
|
|
|
console.log(`Error encountered when retrieving archived messages`, e);
|
2021-07-29 06:30:06 +00:00
|
|
|
}
|
2021-08-05 06:28:05 +00:00
|
|
|
};
|
|
|
|
|
2021-09-02 05:01:52 +00:00
|
|
|
retrieveMessages();
|
2021-07-29 06:30:06 +00:00
|
|
|
}, [waku, historicalMessagesRetrieved]);
|
2021-04-21 05:51:52 +00:00
|
|
|
|
2021-04-21 06:11:07 +00:00
|
|
|
return (
|
2021-04-27 04:39:34 +00:00
|
|
|
<div
|
|
|
|
className="chat-app"
|
2022-02-04 03:12:00 +00:00
|
|
|
style={{ height: "100vh", width: "100vw", overflow: "hidden" }}
|
2021-04-27 04:39:34 +00:00
|
|
|
>
|
2021-07-15 04:08:07 +00:00
|
|
|
<WakuContext.Provider value={{ waku: waku }}>
|
2021-05-03 21:53:26 +00:00
|
|
|
<ThemeProvider theme={themes}>
|
2021-04-29 06:13:09 +00:00
|
|
|
<Room
|
|
|
|
nick={nick}
|
2021-07-29 06:30:06 +00:00
|
|
|
messages={messages}
|
2021-04-29 06:13:09 +00:00
|
|
|
commandHandler={(input: string) => {
|
2022-02-02 04:12:08 +00:00
|
|
|
handleCommand(input, waku, setNick).then(
|
|
|
|
({ command, response }) => {
|
|
|
|
const commandMessages = response.map((msg) => {
|
|
|
|
return Message.fromUtf8String(command, msg);
|
|
|
|
});
|
|
|
|
dispatchMessages(commandMessages);
|
|
|
|
}
|
|
|
|
);
|
2021-04-29 06:13:09 +00:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</ThemeProvider>
|
2021-04-26 07:33:12 +00:00
|
|
|
</WakuContext.Provider>
|
2021-04-21 06:11:07 +00:00
|
|
|
</div>
|
|
|
|
);
|
2021-04-14 04:44:12 +00:00
|
|
|
}
|
2021-04-27 01:00:09 +00:00
|
|
|
|
2021-07-28 01:42:42 +00:00
|
|
|
async function initWaku(setter: (waku: Waku) => void) {
|
2021-04-27 01:05:35 +00:00
|
|
|
try {
|
|
|
|
const waku = await Waku.create({
|
2021-06-08 12:01:48 +00:00
|
|
|
libp2p: {
|
|
|
|
config: {
|
|
|
|
pubsub: {
|
|
|
|
enabled: true,
|
|
|
|
emitSelf: true,
|
|
|
|
},
|
2021-04-27 01:05:35 +00:00
|
|
|
},
|
|
|
|
},
|
2022-01-13 03:28:45 +00:00
|
|
|
bootstrap: {
|
2022-03-09 07:38:28 +00:00
|
|
|
peers: getPredefinedBootstrapNodes(selectFleetEnv()),
|
2022-01-13 03:28:45 +00:00
|
|
|
},
|
2021-04-27 01:05:35 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
setter(waku);
|
|
|
|
} catch (e) {
|
2022-02-04 03:12:00 +00:00
|
|
|
console.log("Issue starting waku ", e);
|
2021-04-27 01:05:35 +00:00
|
|
|
}
|
|
|
|
}
|
2021-05-18 03:47:16 +00:00
|
|
|
|
2021-07-28 01:42:42 +00:00
|
|
|
function selectFleetEnv() {
|
2021-05-18 03:47:16 +00:00
|
|
|
// Works with react-scripts
|
2022-02-04 03:12:00 +00:00
|
|
|
if (process?.env?.NODE_ENV === "development") {
|
2022-02-16 00:43:57 +00:00
|
|
|
return Fleet.Test;
|
2021-05-18 03:47:16 +00:00
|
|
|
} else {
|
2022-02-16 00:43:57 +00:00
|
|
|
return Fleet.Prod;
|
2021-05-18 03:47:16 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-29 06:30:06 +00:00
|
|
|
|
|
|
|
function reduceMessages(state: Message[], newMessages: Message[]) {
|
|
|
|
return state.concat(newMessages);
|
|
|
|
}
|