multichannels

cordova
Bronwen 2022-07-22 17:09:28 -04:00
parent 7d3c72eb81
commit ce85d50098
7 changed files with 47 additions and 23 deletions

View File

@ -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 };

View File

@ -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>
))} ))}

View File

@ -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);

View File

@ -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 {

View File

@ -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(), */
?,
?
) )

View File

@ -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;

View File

@ -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 => ({