mirror of
https://github.com/logos-messaging/logos-messaging-frontend.git
synced 2026-01-07 00:03:10 +00:00
allow to change pubsub topic
This commit is contained in:
parent
f510cc9881
commit
6a0a5ed31f
@ -3,12 +3,15 @@ import { Block } from "@/components/Block";
|
|||||||
import { Subtitle } from "@/components/Subtitle";
|
import { Subtitle } from "@/components/Subtitle";
|
||||||
import { Button } from "@/components/Button";
|
import { Button } from "@/components/Button";
|
||||||
import { MessageContent } from "@/hooks";
|
import { MessageContent } from "@/hooks";
|
||||||
|
import { SUPPORTED_PUBSUB_TOPICS } from "@/constants";
|
||||||
|
|
||||||
type WakuProps = {
|
type WakuProps = {
|
||||||
onSend: (nick: string, text: string) => Promise<void>;
|
onSend: (nick: string, text: string) => Promise<void>;
|
||||||
activeContentTopic: string;
|
activeContentTopic: string;
|
||||||
|
activePubsubTopic: string;
|
||||||
messages: MessageContent[];
|
messages: MessageContent[];
|
||||||
onActiveContentTopicChange: (contentTopic: string) => void;
|
onActiveContentTopicChange: (contentTopic: string) => void;
|
||||||
|
onActivePubsubTopicChange: (pubsubTopic: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Waku: React.FunctionComponent<WakuProps> = (props) => {
|
export const Waku: React.FunctionComponent<WakuProps> = (props) => {
|
||||||
@ -19,10 +22,14 @@ export const Waku: React.FunctionComponent<WakuProps> = (props) => {
|
|||||||
onMessageChange,
|
onMessageChange,
|
||||||
resetText,
|
resetText,
|
||||||
} = useMessage();
|
} = useMessage();
|
||||||
const {
|
const [
|
||||||
contentTopic,
|
contentTopic,
|
||||||
onContentTopicChange,
|
onContentTopicChange,
|
||||||
} = useContentTopic(props.activeContentTopic);
|
] = useTopic<HTMLInputElement>(props.activeContentTopic);
|
||||||
|
const [
|
||||||
|
pubsubTopic,
|
||||||
|
onPubsubTopicChange,
|
||||||
|
] = useTopic<HTMLSelectElement>(props.activePubsubTopic);
|
||||||
|
|
||||||
const onSendClick = async () => {
|
const onSendClick = async () => {
|
||||||
await props.onSend(nick, text);
|
await props.onSend(nick, text);
|
||||||
@ -38,18 +45,40 @@ export const Waku: React.FunctionComponent<WakuProps> = (props) => {
|
|||||||
<Block className="mt-10 flex flex-col md:flex-row lg:flex-row">
|
<Block className="mt-10 flex flex-col md:flex-row lg:flex-row">
|
||||||
<Block>
|
<Block>
|
||||||
<Block>
|
<Block>
|
||||||
<Subtitle>
|
<Subtitle>Chat</Subtitle>
|
||||||
Waku
|
</Block>
|
||||||
</Subtitle>
|
|
||||||
|
<Block className="mt-5">
|
||||||
<label
|
<label
|
||||||
htmlFor="contentTopic-input"
|
htmlFor="pubsubTopic"
|
||||||
className="block mb-2 mt-2 text-sm font-medium text-gray-900 dark:text-white"
|
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||||
|
>
|
||||||
|
Pubsub topic
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<select
|
||||||
|
id="pubsubTopic"
|
||||||
|
value={pubsubTopic}
|
||||||
|
onChange={onPubsubTopicChange}
|
||||||
|
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 pr-4 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"
|
||||||
|
>
|
||||||
|
{SUPPORTED_PUBSUB_TOPICS.map((v) => (
|
||||||
|
<option key={v} value={v}>{v}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
<Button className="mt-1" onClick={() => { props.onActivePubsubTopicChange(pubsubTopic); }}>Change</Button>
|
||||||
|
</Block>
|
||||||
|
|
||||||
|
<Block className="mt-5">
|
||||||
|
<label
|
||||||
|
htmlFor="contentTopic"
|
||||||
|
className="block text-sm mb-2 font-medium text-gray-900 dark:text-white"
|
||||||
>
|
>
|
||||||
Content topic
|
Content topic
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="contentTopic-input"
|
id="contentTopic"
|
||||||
value={contentTopic}
|
value={contentTopic}
|
||||||
onChange={onContentTopicChange}
|
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"
|
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"
|
||||||
@ -59,14 +88,14 @@ export const Waku: React.FunctionComponent<WakuProps> = (props) => {
|
|||||||
|
|
||||||
<Block className="mt-4 mr-10 min-w-fit">
|
<Block className="mt-4 mr-10 min-w-fit">
|
||||||
<label
|
<label
|
||||||
htmlFor="nick-input"
|
htmlFor="nick"
|
||||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||||
>
|
>
|
||||||
Your nickname
|
Your nickname
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="nick-input"
|
id="nick"
|
||||||
placeholder="Choose a nickname"
|
placeholder="Choose a nickname"
|
||||||
value={nick}
|
value={nick}
|
||||||
onChange={onNickChange}
|
onChange={onNickChange}
|
||||||
@ -74,16 +103,16 @@ export const Waku: React.FunctionComponent<WakuProps> = (props) => {
|
|||||||
/>
|
/>
|
||||||
</Block>
|
</Block>
|
||||||
|
|
||||||
<Block className="mt-4">
|
<Block className="mt-5">
|
||||||
<Block className="mb-2">
|
<Block className="mb-2">
|
||||||
<label
|
<label
|
||||||
htmlFor="message-input"
|
htmlFor="message"
|
||||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
||||||
>
|
>
|
||||||
Message
|
Message
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
id="message-input"
|
id="message"
|
||||||
value={text}
|
value={text}
|
||||||
onChange={onMessageChange}
|
onChange={onMessageChange}
|
||||||
placeholder="Text your message here"
|
placeholder="Text your message here"
|
||||||
@ -104,21 +133,22 @@ export const Waku: React.FunctionComponent<WakuProps> = (props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function useContentTopic(globalContentTopic: string) {
|
function useTopic<T>(globalTopic: string): [string, (e: React.SyntheticEvent<T>) => void] {
|
||||||
const [contentTopic, setContentTopic] = React.useState<string>(globalContentTopic);
|
const [topic, setTopic] = React.useState<string>(globalTopic);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setContentTopic(globalContentTopic);
|
setTopic(globalTopic);
|
||||||
}, [globalContentTopic]);
|
}, [globalTopic]);
|
||||||
|
|
||||||
const onContentTopicChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
|
const onTopicChange = (e: React.SyntheticEvent<T>) => {
|
||||||
setContentTopic(e.currentTarget.value || "");
|
const target = e.currentTarget as any;
|
||||||
|
setTopic(target?.value || "");
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return [
|
||||||
contentTopic,
|
topic,
|
||||||
onContentTopicChange,
|
onTopicChange,
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function useMessage() {
|
function useMessage() {
|
||||||
|
|||||||
@ -10,7 +10,9 @@ export default function Home() {
|
|||||||
messages,
|
messages,
|
||||||
debugInfo,
|
debugInfo,
|
||||||
contentTopic,
|
contentTopic,
|
||||||
onContentTopicChange
|
onContentTopicChange,
|
||||||
|
pubsubTopic,
|
||||||
|
onPubsubTopicChange
|
||||||
} = useWaku();
|
} = useWaku();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -23,6 +25,8 @@ export default function Home() {
|
|||||||
messages={messages}
|
messages={messages}
|
||||||
activeContentTopic={contentTopic}
|
activeContentTopic={contentTopic}
|
||||||
onActiveContentTopicChange={onContentTopicChange}
|
onActiveContentTopicChange={onContentTopicChange}
|
||||||
|
activePubsubTopic={pubsubTopic}
|
||||||
|
onActivePubsubTopicChange={onPubsubTopicChange}
|
||||||
/>
|
/>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,5 +1,15 @@
|
|||||||
export const CONTENT_TOPIC = "/toy-chat/2/luzhou/proto";
|
export const CONTENT_TOPIC = "/toy-chat/2/luzhou/proto";
|
||||||
export const PUBSUB_TOPIC = "/waku/2/default-waku/proto";
|
export const PUBSUB_TOPIC = "/waku/2/rs/1/0";
|
||||||
|
export const SUPPORTED_PUBSUB_TOPICS = [
|
||||||
|
"/waku/2/rs/1/0",
|
||||||
|
"/waku/2/rs/1/1",
|
||||||
|
"/waku/2/rs/1/2",
|
||||||
|
"/waku/2/rs/1/3",
|
||||||
|
"/waku/2/rs/1/4",
|
||||||
|
"/waku/2/rs/1/5",
|
||||||
|
"/waku/2/rs/1/6",
|
||||||
|
"/waku/2/rs/1/7",
|
||||||
|
];
|
||||||
|
|
||||||
export const SIGNATURE_MESSAGE =
|
export const SIGNATURE_MESSAGE =
|
||||||
"The signature of this message will be used to generate your RLN credentials. Anyone accessing it may send messages on your behalf, please only share with the RLN dApp";
|
"The signature of this message will be used to generate your RLN credentials. Anyone accessing it may send messages on your behalf, please only share with the RLN dApp";
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { CONTENT_TOPIC } from "@/constants";
|
import { CONTENT_TOPIC, PUBSUB_TOPIC } from "@/constants";
|
||||||
import { DebugInfo, Message, waku } from "@/services/waku";
|
import { DebugInfo, Message, waku } from "@/services/waku";
|
||||||
|
|
||||||
export type MessageContent = {
|
export type MessageContent = {
|
||||||
@ -10,6 +10,7 @@ export type MessageContent = {
|
|||||||
|
|
||||||
export const useWaku = () => {
|
export const useWaku = () => {
|
||||||
const [contentTopic, setContentTopic] = React.useState<string>(CONTENT_TOPIC);
|
const [contentTopic, setContentTopic] = React.useState<string>(CONTENT_TOPIC);
|
||||||
|
const [pubsubTopic, setPubsubTopic] = React.useState<string>(PUBSUB_TOPIC);
|
||||||
const [messages, setMessages] = React.useState<Map<string, MessageContent>>(new Map());
|
const [messages, setMessages] = React.useState<Map<string, MessageContent>>(new Map());
|
||||||
const [debugInfo, setDebugInfo] = React.useState<undefined | DebugInfo>();
|
const [debugInfo, setDebugInfo] = React.useState<undefined | DebugInfo>();
|
||||||
|
|
||||||
@ -58,10 +59,10 @@ export const useWaku = () => {
|
|||||||
};
|
};
|
||||||
}, [debugInfo, setDebugInfo]);
|
}, [debugInfo, setDebugInfo]);
|
||||||
|
|
||||||
const onSend = React.useCallback(
|
const onSend =
|
||||||
async (nick: string, text: string) => {
|
async (nick: string, text: string) => {
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
await waku.relay.send({
|
await waku.relay.send(pubsubTopic, {
|
||||||
version: 0,
|
version: 0,
|
||||||
timestamp,
|
timestamp,
|
||||||
contentTopic,
|
contentTopic,
|
||||||
@ -79,9 +80,7 @@ export const useWaku = () => {
|
|||||||
next.set(id, { nick, timestamp, text });
|
next.set(id, { nick, timestamp, text });
|
||||||
return next;
|
return next;
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
[setMessages]
|
|
||||||
);
|
|
||||||
|
|
||||||
const onContentTopicChange = async (nextContentTopic: string) => {
|
const onContentTopicChange = async (nextContentTopic: string) => {
|
||||||
if (nextContentTopic === contentTopic) {
|
if (nextContentTopic === contentTopic) {
|
||||||
@ -91,11 +90,22 @@ export const useWaku = () => {
|
|||||||
setContentTopic(nextContentTopic);
|
setContentTopic(nextContentTopic);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onPubsubTopicChange = async (nextPubsubTopic: string) => {
|
||||||
|
if (nextPubsubTopic === pubsubTopic) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setPubsubTopic(nextPubsubTopic);
|
||||||
|
waku.relay.changeActivePubsubTopic(nextPubsubTopic);
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
onSend,
|
onSend,
|
||||||
debugInfo,
|
debugInfo,
|
||||||
contentTopic,
|
contentTopic,
|
||||||
onContentTopicChange,
|
onContentTopicChange,
|
||||||
messages: Array.from(messages.values())
|
pubsubTopic,
|
||||||
|
onPubsubTopicChange,
|
||||||
|
messages: Array.from(messages.values()),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { PUBSUB_TOPIC } from "@/constants";
|
import { PUBSUB_TOPIC, SUPPORTED_PUBSUB_TOPICS } from "@/constants";
|
||||||
import { http } from "@/utils/http";
|
import { http } from "@/utils/http";
|
||||||
|
|
||||||
export type Message = {
|
export type Message = {
|
||||||
@ -17,6 +17,7 @@ const RELAY = "/relay/v1";
|
|||||||
const buildURL = (endpoint: string) => `${LOCAL_NODE}${endpoint}`;
|
const buildURL = (endpoint: string) => `${LOCAL_NODE}${endpoint}`;
|
||||||
|
|
||||||
class Relay {
|
class Relay {
|
||||||
|
private activePubsubTopic = SUPPORTED_PUBSUB_TOPICS[0];
|
||||||
private subscribing = false;
|
private subscribing = false;
|
||||||
private readonly subscriptionsEmitter = new EventTarget();
|
private readonly subscriptionsEmitter = new EventTarget();
|
||||||
// only one content topic subscriptions is possible now
|
// only one content topic subscriptions is possible now
|
||||||
@ -43,13 +44,13 @@ class Relay {
|
|||||||
|
|
||||||
this.subscribing = true;
|
this.subscribing = true;
|
||||||
try {
|
try {
|
||||||
await http.post(buildURL(`${RELAY}/subscriptions`), [PUBSUB_TOPIC]);
|
await http.post(buildURL(`${RELAY}/subscriptions`), SUPPORTED_PUBSUB_TOPICS);
|
||||||
|
|
||||||
this.subscriptionRoutine = window.setInterval(async () => {
|
this.subscriptionRoutine = window.setInterval(async () => {
|
||||||
await this.fetchMessages();
|
await this.fetchMessages();
|
||||||
}, 5 * SECOND);
|
}, 5 * SECOND);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to subscribe node ${PUBSUB_TOPIC}:`, error);
|
console.error(`Failed to subscribe node any of ${SUPPORTED_PUBSUB_TOPICS}:`, error);
|
||||||
}
|
}
|
||||||
this.subscribing = false;
|
this.subscribing = false;
|
||||||
}
|
}
|
||||||
@ -71,7 +72,7 @@ class Relay {
|
|||||||
|
|
||||||
private async fetchMessages(): Promise<void> {
|
private async fetchMessages(): Promise<void> {
|
||||||
const response = await http.get(
|
const response = await http.get(
|
||||||
buildURL(`${RELAY}/messages/${encodeURIComponent(PUBSUB_TOPIC)}`)
|
buildURL(`${RELAY}/messages/${encodeURIComponent(this.activePubsubTopic)}`)
|
||||||
);
|
);
|
||||||
const body: Message[] = await response.json();
|
const body: Message[] = await response.json();
|
||||||
|
|
||||||
@ -102,8 +103,12 @@ class Relay {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async send(message: Message): Promise<void> {
|
public changeActivePubsubTopic(pubsubTopic: string) {
|
||||||
await http.post(buildURL(`${RELAY}/messages/${encodeURIComponent(PUBSUB_TOPIC)}`), message);
|
this.activePubsubTopic = pubsubTopic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async send(pubsubTopic: string, message: Message): Promise<void> {
|
||||||
|
await http.post(buildURL(`${RELAY}/messages/${encodeURIComponent(pubsubTopic)}`), message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user