diff --git a/src/components/Hero.jsx b/src/components/Hero.jsx
index 76620d7..52670ad 100644
--- a/src/components/Hero.jsx
+++ b/src/components/Hero.jsx
@@ -3,7 +3,7 @@ import { ethers, BigNumber } from 'ethers';
import { useAccount, useContractReads, useContractRead, usePrepareContractWrite, useContractWrite, useWaitForTransaction, erc721ABI } from 'wagmi';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import debounce from 'lodash';
-import { StatsPanel } from './Panels';
+import { StatsPanel, TrollboxPanel } from './Panels';
import MainABI from '../abi/main.json';
import '../styles/hero.css';
@@ -357,6 +357,10 @@ export function Hero(props) {
bombsAssembled={options.bombsAssembled}
bombsExploded={options.bombsExploded}
/>
+
)
}
diff --git a/src/components/Panels.jsx b/src/components/Panels.jsx
index 0902ef5..52ee8ad 100644
--- a/src/components/Panels.jsx
+++ b/src/components/Panels.jsx
@@ -1,4 +1,5 @@
-import React from 'react';
+import React, { useEffect, useState } from 'react';
+import useWebSocket, { ReadyState } from 'react-use-websocket';
import Unaboomer from '../img/unaboomer.png';
@@ -53,4 +54,108 @@ export class StatsPanel extends React.Component {
>
)
}
+}
+
+export function TrollboxPanel(props) {
+ const [showChat, setShowChat] = useState(false);
+ const [history, setHistory] = useState(() => {
+ const saved = localStorage.getItem('trollboxHistory');
+ return saved || JSON.stringify([])
+ });
+
+ const { sendJsonMessage, readyState } = useWebSocket(props.ws, {
+ onOpen: () => {
+ console.log('WebSocket connection established.');
+ },
+ onMessage: (msg) => {
+ console.log(JSON.parse(msg.data))
+ let h = JSON.parse(history);
+ if (h.length > 500) {
+ h = h.splice(-500);
+ }
+ h.push(JSON.parse(msg.data));
+ setHistory(JSON.stringify(h));
+ },
+ shouldReconnect: () => true
+ });
+
+
+ useEffect(() => {
+ localStorage.setItem('trollboxHistory', history);
+ }, [history]);
+
+ const connectionStatus = {
+ [ReadyState.CONNECTING]: 'Connecting',
+ [ReadyState.OPEN]: 'Open',
+ [ReadyState.CLOSING]: 'Closing',
+ [ReadyState.CLOSED]: 'Closed',
+ [ReadyState.UNINSTANTIATED]: 'Uninstantiated',
+ }[readyState];
+
+ function send(event) {
+ const message = (new FormData(event.target)).get("message");
+ if (message) {
+ sendJsonMessage({
+ from: props.address,
+ date: new Date(),
+ message
+ })
+ }
+ event.target.reset();
+ return false;
+ }
+
+ return (
+ <>
+ {props.ws && props.address && (
+
+ {readyState == ReadyState.OPEN && showChat && (
+ <>
+
+
+
+ {JSON.parse(history).length > 0 && JSON.parse(history).map((message, idx) => (
+ -
+
+
+ {message.from.slice(-6)}
+
+ :
+ {message.message}
+
+ {new Date(message.date).getMonth() + 1}/
+ {new Date(message.date).getDate()} @
+ {new Date(message.date).getUTCHours()}:
+ {new Date(message.date).getUTCMinutes()} UTC
+
+
+ ))}
+
+
+ >
+ )}
+
+ {readyState == ReadyState.OPEN && !showChat && (
+
+ )}
+
+ {readyState == ReadyState.CONNECTING && (
+
connecting to trollbox...
+ )}
+
+ )}
+ >
+ )
}
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index fec2789..5d61014 100644
--- a/src/index.js
+++ b/src/index.js
@@ -38,7 +38,10 @@ ReactDOM.createRoot(document.getElementById("root")).render(
-
+
);
diff --git a/src/styles/hero.css b/src/styles/hero.css
index 4328f66..30265fa 100644
--- a/src/styles/hero.css
+++ b/src/styles/hero.css
@@ -83,7 +83,7 @@ button.doThing:disabled {
left: 0;
background-color: #231f20;
text-align: left;
- width: 30%;
+ width: 20%;
margin: 0;
max-height: 400px;
overflow-y: auto;
@@ -93,4 +93,63 @@ button.doThing:disabled {
min-width: 300px;
border-right: 4px solid #f9f9f9;
border-top: 4px solid #f9f9f9;
+}
+
+#trollbox {
+ position: fixed;
+ bottom: 0;
+ right: 0;
+ background-color: black;
+ text-align: left;
+ width: 40%;
+ margin: 0;
+ max-height: 400px;
+ overflow-y: auto;
+ word-wrap: break-word;
+ display: flex;
+ flex-direction: column-reverse;
+ min-width: 400px;
+ border-left: 4px solid #f9f9f9;
+ border-top: 4px solid #f9f9f9;
+}
+
+@media (max-width: 600px) {
+ #statsbox {
+ min-width: 300px;
+ }
+ #trollbox {
+ min-width: 200px;
+ }
+ .messageDate {
+ display: none;
+ }
+}
+
+#trollbox ul li, #trollbox span, #trollbox a {
+ list-style-type: none;
+ /* font-family: monospace; */
+}
+
+#trollbox form {
+ margin: .8em 0;
+}
+
+#trollbox form input[type="text"] {
+ width: 60%;
+}
+
+.fromAddress {
+ margin: 4px 4px 0 0;
+}
+
+.messageLine {
+ width: 100%;
+ flex-direction: column-reverse;
+}
+
+.messageDate {
+ font-size: 8px;
+ float: right;
+ line-height: 1em;
+ padding-right: 8px;
}
\ No newline at end of file