multichannels
parent
7d3c72eb81
commit
ce85d50098
|
|
@ -12,7 +12,7 @@ export const channelContext = createContext<{
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const [channel, setChannel] = useState<string>(null);
|
const [channel, setChannel] = useState<string | null>(null);
|
||||||
|
|
||||||
const channelContextValue = { channel, setChannel };
|
const channelContextValue = { channel, setChannel };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useContext, useEffect, useRef, useState } from 'react';
|
||||||
import { registerRouter, router, send, unregisterRouter } from '../lib/api';
|
import { registerRouter, router, send, unregisterRouter } from '../lib/api';
|
||||||
|
import { channelContext } from './App';
|
||||||
|
|
||||||
function useRouter(actions: Function | object, deps: any[]) {
|
function useRouter(actions: Function | object, deps: any[]) {
|
||||||
const _router = typeof actions === 'object' ? router(actions) : actions;
|
const _router = typeof actions === 'object' ? router(actions) : actions;
|
||||||
|
|
@ -31,6 +32,7 @@ function Hashmark() {
|
||||||
export default function Channels() {
|
export default function Channels() {
|
||||||
|
|
||||||
const [channels, setChannels] = useState<IChannel[]>([]);
|
const [channels, setChannels] = useState<IChannel[]>([]);
|
||||||
|
const {channel, setChannel} = useContext(channelContext);
|
||||||
|
|
||||||
const { send } = useRouter({
|
const { send } = useRouter({
|
||||||
'channels:list'(data: IChannel[]) {
|
'channels:list'(data: IChannel[]) {
|
||||||
|
|
@ -48,6 +50,12 @@ export default function Channels() {
|
||||||
}
|
}
|
||||||
}, [channels]);
|
}, [channels]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(channels.length === 0) return;
|
||||||
|
if(channel !== null) return;
|
||||||
|
setChannel(channels[0].uid);
|
||||||
|
}, [channel, channels]);
|
||||||
|
|
||||||
const textbox = useRef<HTMLInputElement>(null);
|
const textbox = useRef<HTMLInputElement>(null);
|
||||||
const add = useCallback(() => {
|
const add = useCallback(() => {
|
||||||
if(textbox.current === null) return;
|
if(textbox.current === null) return;
|
||||||
|
|
@ -59,11 +67,15 @@ export default function Channels() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<br></br>
|
<br></br>
|
||||||
{channels.map(channel => (
|
{channels.map(c => (
|
||||||
<div key={channel.uid} style={{
|
<div key={c.uid} style={{
|
||||||
margin: '8px 0px',
|
margin: '8px 0px',
|
||||||
|
color: channel === c.uid ? 'cyan' : 'inherit',
|
||||||
|
cursor: 'pointer',
|
||||||
|
}} onClick={() => {
|
||||||
|
setChannel(c.uid);
|
||||||
}}>
|
}}>
|
||||||
<Hashmark></Hashmark>{channel.name}
|
<Hashmark></Hashmark>{c.name} {c.uid.substring(0, 4)}
|
||||||
<a style={{ color: 'rgba(0, 100, 200, 1)', marginLeft: '8px', fontSize: '10px' }} href="#" onClick={() => {}}>Delete</a>
|
<a style={{ color: 'rgba(0, 100, 200, 1)', marginLeft: '8px', fontSize: '10px' }} href="#" onClick={() => {}}>Delete</a>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,18 @@
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useContext, useEffect, useRef, useState } from 'react';
|
||||||
import TimeAgo from 'react-timeago';
|
import TimeAgo from 'react-timeago';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
import { registerRouter, router, send, unregisterRouter } from '../lib/api';
|
import { registerRouter, router, send, unregisterRouter } from '../lib/api';
|
||||||
|
import { channelContext } from './App';
|
||||||
import type { IMessage} from './Message';
|
import type { IMessage} from './Message';
|
||||||
import { Message } from './Message';
|
import { Message } from './Message';
|
||||||
|
|
||||||
function createMessage(from: string, text: string, t = 0): IMessage {
|
function createMessage(from: string, text: string, channel: string, t = 0): IMessage {
|
||||||
return {
|
return {
|
||||||
text,
|
text,
|
||||||
from,
|
from,
|
||||||
timestamp: Date.now() - t * 1000,
|
timestamp: Date.now() - t * 1000,
|
||||||
uid: v4(),
|
uid: v4(),
|
||||||
|
channel,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -19,14 +21,15 @@ export default () => {
|
||||||
const [hist, setHist] = useState(false);
|
const [hist, setHist] = useState(false);
|
||||||
|
|
||||||
const textBoxRef = useRef<HTMLDivElement>(null);
|
const textBoxRef = useRef<HTMLDivElement>(null);
|
||||||
|
const { channel, setChannel } = useContext(channelContext);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const actions = router({
|
const actions = router({
|
||||||
message(data: IMessage) {
|
'message:message'(data: IMessage) {
|
||||||
setMessages([...messages, data]);
|
setMessages([...messages, data]);
|
||||||
},
|
},
|
||||||
'message:recent'(data: { messages: IMessage[] }) {
|
'message:recent'(data: { messages: IMessage[] }) {
|
||||||
setMessages([...data.messages, ...messages]);
|
setMessages(data.messages);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
registerRouter(actions);
|
registerRouter(actions);
|
||||||
|
|
@ -36,18 +39,16 @@ export default () => {
|
||||||
}, [messages]);
|
}, [messages]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if(!hist) {
|
|
||||||
console.log('sending recents request');
|
console.log('sending recents request');
|
||||||
send('message:recent');
|
send('message:recent', { channel });
|
||||||
setHist(true);
|
}, [channel]);
|
||||||
}
|
|
||||||
}, [hist]);
|
|
||||||
|
|
||||||
const sendMessage = useCallback(() => {
|
const sendMessage = useCallback(() => {
|
||||||
if(textBoxRef.current === null) return;
|
if(textBoxRef.current === null) return;
|
||||||
send('message:message', createMessage('Val', textBoxRef.current.innerText));
|
if(channel === null) return;
|
||||||
|
send('message:message', createMessage('Val', textBoxRef.current.innerText, channel));
|
||||||
textBoxRef.current.innerText = '';
|
textBoxRef.current.innerText = '';
|
||||||
}, []);
|
}, [channel]);
|
||||||
|
|
||||||
const keyDown = useCallback((evt: any) => {
|
const keyDown = useCallback((evt: any) => {
|
||||||
console.log(evt);
|
console.log(evt);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ export interface IMessage {
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
from: string;
|
from: string;
|
||||||
text: string;
|
text: string;
|
||||||
|
channel: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MessageProps {
|
interface MessageProps {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
INSERT INTO messages
|
INSERT INTO messages
|
||||||
(`text`, `from`, `uid`, `t_sent`)
|
(`text`, `from`, `uid`, `t_sent`, channel_uid)
|
||||||
VALUES (
|
VALUES (
|
||||||
?,
|
?,
|
||||||
?,
|
?,
|
||||||
?,
|
?,
|
||||||
UNIX_TIMESTAMP()
|
/* UNIX_TIMESTAMP(), */
|
||||||
|
?,
|
||||||
|
?
|
||||||
)
|
)
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
SELECT * FROM messages
|
SELECT * FROM messages
|
||||||
|
WHERE channel_uid=?
|
||||||
ORDER BY t_sent
|
ORDER BY t_sent
|
||||||
LIMIT 100;
|
LIMIT 100;
|
||||||
|
|
@ -6,13 +6,20 @@ import { broadcast, reply } from '../lib/WebSocketServer';
|
||||||
|
|
||||||
export default router({
|
export default router({
|
||||||
async message(data: any) {
|
async message(data: any) {
|
||||||
const failed = null === await query(newMessage, data.text, data.from, data.uid, data.timestamp);
|
const failed = null === await query(
|
||||||
|
newMessage,
|
||||||
|
data.text,
|
||||||
|
data.from,
|
||||||
|
data.uid,
|
||||||
|
data.timestamp,
|
||||||
|
data.channel,
|
||||||
|
);
|
||||||
if(failed) return;
|
if(failed) return;
|
||||||
return broadcast(data);
|
return broadcast(data);
|
||||||
},
|
},
|
||||||
async recent() {
|
async recent(data: any) {
|
||||||
console.log('got recents request');
|
console.log('got recents request ch', data.channel);
|
||||||
const messages = await query(recentMessages);
|
const messages = await query(recentMessages, data.channel);
|
||||||
if(messages === null) return;
|
if(messages === null) return;
|
||||||
return reply({
|
return reply({
|
||||||
messages: messages.map(v => ({
|
messages: messages.map(v => ({
|
||||||
|
|
|
||||||
Reference in New Issue