Skip to content

Commit

Permalink
Merge pull request #16 from waku-org/weboko/follow-up-2
Browse files Browse the repository at this point in the history
feat: add ability to subscribe to custom contentTopic + other stuff
  • Loading branch information
weboko authored Dec 2, 2023
2 parents daca898 + 8dfa550 commit 226e332
Show file tree
Hide file tree
Showing 21 changed files with 548 additions and 250 deletions.
59 changes: 42 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"@waku/rln": "0.1.1-7e8cb89",
"@waku/rln": "0.1.1-60a5070",
"@waku/utils": "^0.0.12",
"ethers": "^5.7.2",
"next": "13.5.6",
Expand Down
File renamed without changes.
24 changes: 24 additions & 0 deletions src/app/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Block, BlockTypes } from "@/components/Block";
import { Title } from "@/components/Title";
import { Button } from "@/components/Button";

type HeaderProps = {
children?: React.ReactNode;
onWalletConnect?: () => void;
}

export const Header: React.FunctionComponent<HeaderProps> = (props) => {
return (
<>
<Block className="mb-5" type={BlockTypes.FlexHorizontal}>
<Title>Waku</Title>
{props.onWalletConnect && (
<Button onClick={props.onWalletConnect}>
Connect Wallet
</Button>
)}
</Block>
{props.children}
</>
);
};
File renamed without changes.
File renamed without changes.
12 changes: 12 additions & 0 deletions src/app/components/Menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Link from "next/link";
import { Block } from "@/components/Block";

export const Menu: React.FunctionComponent<{}> = () => {
return (
<Block className="m-5 flex text-lg">
<p className="mr-5">{">"}</p>
<p className="mr-5"><Link href="/">Chat</Link></p>
<p><Link href="/keystore">Keystore</Link></p>
</Block>
);
};
162 changes: 162 additions & 0 deletions src/app/components/Waku.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import React from "react";
import { Block } from "@/components/Block";
import { Subtitle } from "@/components/Subtitle";
import { Button } from "@/components/Button";
import { MessageContent } from "@/hooks";

type WakuProps = {
onSend: (nick: string, text: string) => Promise<void>;
activeContentTopic: string;
messages: MessageContent[];
onActiveContentTopicChange: (contentTopic: string) => void;
}

export const Waku: React.FunctionComponent<WakuProps> = (props) => {
const {
nick,
text,
onNickChange,
onMessageChange,
resetText,
} = useMessage();
const {
contentTopic,
onContentTopicChange,
} = useContentTopic(props.activeContentTopic);

const onSendClick = async () => {
await props.onSend(nick, text);
resetText();
};

const renderedMessages = React.useMemo(
() => props.messages.map(renderMessage),
[props.messages]
);

return (
<Block className="mt-10 flex flex-col md:flex-row lg:flex-row">
<Block>
<Block>
<Subtitle>
Waku
</Subtitle>
<label
htmlFor="contentTopic-input"
className="block mb-2 mt-2 text-sm font-medium text-gray-900 dark:text-white"
>
Content topic
</label>
<input
type="text"
id="contentTopic-input"
value={contentTopic}
onChange={onContentTopicChange}
className="w-96 mr-2 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
/>
<Button className="mt-1" onClick={() => { props.onActiveContentTopicChange(contentTopic); }}>Change</Button>
</Block>

<Block className="mt-4 mr-10 min-w-fit">
<label
htmlFor="nick-input"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
>
Your nickname
</label>
<input
type="text"
id="nick-input"
placeholder="Choose a nickname"
value={nick}
onChange={onNickChange}
className="w-96 mr-2 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
/>
</Block>

<Block className="mt-4">
<Block className="mb-2">
<label
htmlFor="message-input"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
>
Message
</label>
<textarea
id="message-input"
value={text}
onChange={onMessageChange}
placeholder="Text your message here"
className="w-96 h-60 mr-2 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
/>
</Block>
<Button onClick={onSendClick}>Send</Button>
</Block>
</Block>

<Block className="max-w-screen-md mt-10 md:mt-0">
<p className="text-l mb-4">Messages</p>
<div>
<ul>{renderedMessages}</ul>
</div>
</Block>
</Block>
);
};

function useContentTopic(globalContentTopic: string) {
const [contentTopic, setContentTopic] = React.useState<string>(globalContentTopic);

React.useEffect(() => {
setContentTopic(globalContentTopic);
}, [globalContentTopic]);

const onContentTopicChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
setContentTopic(e.currentTarget.value || "");
};

return {
contentTopic,
onContentTopicChange,
};
}

function useMessage() {
const [nick, setNick] = React.useState<string>("");
const [text, setText] = React.useState<string>("");

const onNickChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
setNick(e.currentTarget.value || "");
};

const onMessageChange = (e: React.SyntheticEvent<HTMLTextAreaElement>) => {
setText(e.currentTarget.value || "");
};

const resetText = () => {
setText("");
};

return {
nick,
text,
resetText,
onNickChange,
onMessageChange,
};
}

function renderMessage(content: MessageContent) {
return (
<li key={`${content.nick}-${content.timestamp}-${content.text}`} className="mb-4">
<p>
<span className="text-lg">{content.nick}</span>
<span className="text-sm font-bold">
({(new Date(content.timestamp)).toDateString()})
</span>
:
</p>
<p className="break-words">{content.text}</p>
</li>
);
}
Binary file modified src/app/favicon.ico
Binary file not shown.
23 changes: 0 additions & 23 deletions src/app/home/components/Header.tsx

This file was deleted.

Loading

0 comments on commit 226e332

Please sign in to comment.