cordova v22.7.23-35
Valerie 2022-07-22 20:29:24 -04:00
parent 916c8ac3c8
commit 2e89be3b84
5 changed files with 90 additions and 51 deletions

View File

@ -32,8 +32,13 @@ const connect = async () => {
socket.addEventListener('message', (event) => { socket.addEventListener('message', (event) => {
const {action, data} = JSON.parse(event.data); const {action, data} = JSON.parse(event.data);
console.log('[IN]', action, data); console.log('[IN]', action, data);
for(const router of routers) { const routeFound = routers
router(action, data); .map(router => router(action, data))
.reduce((a, b) => a + b, 0);
if(routeFound === 0) {
console.warn(`route <${action}> not found`);
} else {
console.log(`routed to ${routeFound} elements`);
} }
}); });
@ -63,21 +68,12 @@ export async function send(action: string, data?: any) {
} }
export function router(routes: any) { export function router(routes: any) {
for(const routeName in routes) {
const route = routes[routeName];
if(typeof route === 'object') {
for(const suffix in route) {
const combinedRouteName = routeName + ':' + suffix;
routes[combinedRouteName] = route[suffix];
}
delete routes[routeName];
}
}
return function(route: string, data: any) { return function(route: string, data: any) {
if(route in routes) { if(route in routes) {
routes[route](data); routes[route](data);
return true;
} else { } else {
console.warn(`route <${route}> not found`); return false;
} }
}; };
} }

View File

@ -0,0 +1,16 @@
import { useEffect } from 'react';
import { registerRouter, router, send, unregisterRouter } from './api';
export function useAPI(actions: Function | object, deps: any[]) {
const _router = typeof actions === 'object' ? router(actions) : actions;
useEffect(() => {
registerRouter(_router);
return () => {
unregisterRouter(_router);
};
}, deps);
return {
send: send,
};
}

View File

@ -1,20 +1,7 @@
import { useCallback, useContext, useEffect, useRef, useState } from 'react'; import { useCallback, useContext, useEffect, useRef, useState } from 'react';
import { registerRouter, router, send, unregisterRouter } from '../lib/api';
import { channelContext } from './App'; import { channelContext } from './App';
import { useAPI } from '../lib/useRouter';
function useRouter(actions: Function | object, deps: any[]) { import type { IMessage } from './Message';
const _router = typeof actions === 'object' ? router(actions) : actions;
useEffect(() => {
registerRouter(_router);
return () => {
unregisterRouter(_router);
};
}, deps);
return {
send: send,
};
}
interface IChannel { interface IChannel {
uid: string; uid: string;
@ -29,12 +16,19 @@ function Hashmark() {
}}>#</span>; }}>#</span>;
} }
interface IUnreads {
[uid: string]: number
}
export default function Channels() { export default function Channels() {
const [channels, setChannels] = useState<IChannel[]>([]); const [channels, setChannels] = useState<IChannel[]>([]);
const {channel, setChannel} = useContext(channelContext); const {channel, setChannel} = useContext(channelContext);
const { send } = useRouter({ const [unreads, setUnreads] = useState<IUnreads>({});
const { send } = useAPI({
'channels:list'(data: IChannel[]) { 'channels:list'(data: IChannel[]) {
// console.log(data) // console.log(data)
setChannels(data); setChannels(data);
@ -42,7 +36,18 @@ export default function Channels() {
'channel:add'(channel: IChannel) { 'channel:add'(channel: IChannel) {
setChannels([...channels, channel]); setChannels([...channels, channel]);
}, },
}, [channels]); 'message:message'(message: IMessage) {
if(channel === message.channel) return;
setUnreads({
...unreads,
[message.channel]: (unreads[message.channel] ?? 0) + 1,
});
},
}, [channels, unreads]);
useEffect(() => {
console.log('unreads', unreads);
}, [unreads]);
useEffect(() => { useEffect(() => {
if(channels.length === 0) { if(channels.length === 0) {
@ -56,6 +61,14 @@ export default function Channels() {
setChannel(channels[0].uid); setChannel(channels[0].uid);
}, [channel, channels]); }, [channel, channels]);
useEffect(() => {
if(!channel) return;
setUnreads({
...unreads,
[channel]: 0,
});
}, [channel]);
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;
@ -75,8 +88,20 @@ export default function Channels() {
}} onClick={() => { }} onClick={() => {
setChannel(c.uid); setChannel(c.uid);
}}> }}>
<Hashmark></Hashmark>{c.name} <Hashmark></Hashmark>
<a style={{ color: 'rgba(0, 100, 200, 1)', marginLeft: '8px', fontSize: '10px' }} href="#" onClick={() => {}}>Delete</a> {(c.uid in unreads) && (unreads[c.uid] > 0) && (
<span style={{ paddingRight: '8px' }}>({unreads[c.uid]})</span>
)}
<span style={{
fontWeight: (unreads[c.uid] ?? 0) > 0 ? 'bold' : '300',
}}>
{c.name}
</span>
<a style={{
color: 'rgba(0, 100, 200, 1)',
marginLeft: '8px',
fontSize: '10px',
}} href="#" onClick={() => {}}>Delete</a>
</div> </div>
))} ))}
<Hashmark></Hashmark><input <Hashmark></Hashmark><input

View File

@ -1,12 +1,12 @@
import { useCallback, useContext, useEffect, useRef, useState } from 'react'; import { useCallback, useContext, useEffect, useRef, useState } from 'react';
import TimeAgo from 'react-timeago';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { registerRouter, router, send, unregisterRouter } from '../lib/api'; import { useAPI } from '../lib/useRouter';
import { channelContext } from './App'; 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, channel: string, t = 0): IMessage { function createMessage(from: string, text: string,
channel: string, t = 0): IMessage {
return { return {
text, text,
from, from,
@ -23,19 +23,15 @@ export default () => {
const textBoxRef = useRef<HTMLDivElement>(null); const textBoxRef = useRef<HTMLDivElement>(null);
const { channel, setChannel } = useContext(channelContext); const { channel, setChannel } = useContext(channelContext);
useEffect(() => { const { send } = useAPI({
const actions = router({ 'message:message'(data: IMessage) {
'message:message'(data: IMessage) { if(data.channel !== channel) return;
setMessages([...messages, data]);
}, setMessages([...messages, data]);
'message:recent'(data: { messages: IMessage[] }) { },
setMessages(data.messages); 'message:recent'(data: { messages: IMessage[] }) {
}, setMessages(data.messages);
}); },
registerRouter(actions);
return () => {
unregisterRouter(actions);
};
}, [messages]); }, [messages]);
useEffect(() => { useEffect(() => {
@ -46,12 +42,18 @@ export default () => {
const sendMessage = useCallback(() => { const sendMessage = useCallback(() => {
if(textBoxRef.current === null) return; if(textBoxRef.current === null) return;
if(channel === null) return; if(channel === null) return;
send('message:message', createMessage('Val', textBoxRef.current.innerText, channel)); send(
'message:message',
createMessage(
'Val',
textBoxRef.current.innerText,
channel,
),
);
textBoxRef.current.innerText = ''; textBoxRef.current.innerText = '';
}, [channel]); }, [channel]);
const keyDown = useCallback((evt: any) => { const keyDown = useCallback((evt: any) => {
console.log(evt);
if(evt.key === 'Enter') { if(evt.key === 'Enter') {
sendMessage(); sendMessage();
} }

View File

@ -25,7 +25,7 @@ export default router({
messages: messages.map(v => ({ messages: messages.map(v => ({
from: v.from, from: v.from,
uid: v.uid, uid: v.uid,
timestamp: v.t_sent * 1000, timestamp: v.t_sent,
text: v.text, text: v.text,
})), })),
}); });