From a212169022845410681c504fe8355e0ca279fafb Mon Sep 17 00:00:00 2001 From: Valerie Date: Thu, 21 Jul 2022 15:22:00 -0400 Subject: [PATCH] channels and router fix --- packages/renderer/src/pages/Chat.tsx | 82 ++----------------- packages/renderer/src/pages/Message.tsx | 67 +++++++++++++++ .../server/public/migrations/3-channels.sql | 14 ++++ packages/server/src/db/migrate.ts | 2 +- packages/server/src/db/query.ts | 18 ++-- .../server/src/db/snippets/channel/list.sql | 1 + packages/server/src/index.ts | 2 + packages/server/src/router.ts | 15 +++- packages/server/src/routers/message.ts | 29 +++++++ packages/server/src/routers/root.ts | 25 +----- scripts/watch.js | 2 +- 11 files changed, 149 insertions(+), 108 deletions(-) create mode 100644 packages/renderer/src/pages/Message.tsx create mode 100644 packages/server/public/migrations/3-channels.sql create mode 100644 packages/server/src/db/snippets/channel/list.sql create mode 100644 packages/server/src/routers/message.ts diff --git a/packages/renderer/src/pages/Chat.tsx b/packages/renderer/src/pages/Chat.tsx index 735ebe2..ddf8ba1 100644 --- a/packages/renderer/src/pages/Chat.tsx +++ b/packages/renderer/src/pages/Chat.tsx @@ -2,20 +2,10 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import TimeAgo from 'react-timeago'; import { v4 } from 'uuid'; import { registerRouter, router, send, unregisterRouter } from '../lib/api'; +import type { IMessage} from './Message'; +import { Message } from './Message'; -const firstLineIndent = '10px'; -const multiLineIndent = '16px'; -const rightMessagePagging = '16px'; - -interface Message { - text: string; - from: string; - timestamp: number; - // nid: number; - uid: string; -} - -function createMessage(from: string, text: string, t = 0): Message { +function createMessage(from: string, text: string, t = 0): IMessage { return { text, from, @@ -24,33 +14,18 @@ function createMessage(from: string, text: string, t = 0): Message { }; } -const mockMessages: Message[] = [ - // createMessage('Bob', 'Hey', 55), - // createMessage('Alice', 'Hello', 50), - // createMessage('Bob', 'What up', 45), - // createMessage('Alice', 'nm UUU', 40), - // createMessage('Bob', 'Hey', 35), - // createMessage('Alice', 'Hello', 30), - // createMessage('Bob', 'What up', 25), - // createMessage('Alice', 'nm UUU', 20), - // createMessage('Bob', 'Hey', 15), - // createMessage('Alice', 'Hello', 10), - // createMessage('Bob', 'What up', 5), - // createMessage('Alice', 'This is what a really long message could possibly look like, if a person decided to write a really long essay. This is what a really long message could possibly look like, if a person decided to write a really long essay. This is what a really long message could possibly look like, if a person decided to write a really long essay. This is what a really long message could possibly look like, if a person decided to write a really long essay.'), -]; - export default () => { - const [messages, setMessages] = useState(mockMessages); + const [messages, setMessages] = useState([]); const [hist, setHist] = useState(false); const textBoxRef = useRef(null); useEffect(() => { const actions = router({ - message(data: Message) { + message(data: IMessage) { setMessages([...messages, data]); }, - recent(data: { messages: Message[] }) { + 'message:recent'(data: { messages: IMessage[] }) { setMessages([...data.messages, ...messages]); }, }); @@ -63,14 +38,14 @@ export default () => { useEffect(() => { if(!hist) { console.log('sending recents request'); - send('recent'); + send('message:recent'); setHist(true); } }, [hist]); const sendMessage = useCallback(() => { if(textBoxRef.current === null) return; - send('message', createMessage('Val', textBoxRef.current.innerText)); + send('message:message', createMessage('Val', textBoxRef.current.innerText)); textBoxRef.current.innerText = ''; }, []); @@ -105,46 +80,7 @@ export default () => { width: '100%', }}> {messages.map(message => ( -
- - u === 'second' ? 'Just Now' : ('' + t + u[0])} - > - - -
- {message.from} -
-
- {message.text} -
-
-
+ ))} diff --git a/packages/renderer/src/pages/Message.tsx b/packages/renderer/src/pages/Message.tsx new file mode 100644 index 0000000..5670464 --- /dev/null +++ b/packages/renderer/src/pages/Message.tsx @@ -0,0 +1,67 @@ +import TimeAgo from 'react-timeago'; + +export interface IMessage { + uid: string; + timestamp: number; + from: string; + text: string; +} + +interface MessageProps { + message: IMessage +} + +const firstLineIndent = '10px'; +const multiLineIndent = '16px'; +const rightMessagePagging = '16px'; + +export function Message({ + message, +}: MessageProps) { + + + return ( + <> +
+ + u === 'second' ? 'Just Now' : ('' + t + u[0])} + > + + +
+ {message.from} +
+
+ {message.text} +
+
+
+ + ); +} \ No newline at end of file diff --git a/packages/server/public/migrations/3-channels.sql b/packages/server/public/migrations/3-channels.sql new file mode 100644 index 0000000..23af524 --- /dev/null +++ b/packages/server/public/migrations/3-channels.sql @@ -0,0 +1,14 @@ + +CREATE TABLE `channels` (`id` int(11) NOT NULL AUTO_INCREMENT, `name` TINYTEXT NOT NULL, `uid` TINYTEXT NOT NULL UNIQUE, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +INSERT INTO channels (name, uid) VALUES ('General', UUID()); + +ALTER TABLE `messages` ADD COLUMN `channel_uid` TINYTEXT NOT NULL AFTER `t_sent`; + +UPDATE messages SET channel_uid = (SELECT uid FROM channels) where messages.channel_uid = ''; + +ALTER TABLE `messages` CHANGE `channel_uid` `channel_uid` varchar(36) COLLATE 'utf8mb4_general_ci' NOT NULL AFTER `t_sent`; + +ALTER TABLE `channels` CHANGE `uid` `uid` varchar(36) COLLATE 'utf8mb4_general_ci' NOT NULL AFTER `name`; + +ALTER TABLE messages ADD CONSTRAINT fk_channel_uid FOREIGN KEY (channel_uid) REFERENCES channels(uid); \ No newline at end of file diff --git a/packages/server/src/db/migrate.ts b/packages/server/src/db/migrate.ts index a60803b..2e052d0 100644 --- a/packages/server/src/db/migrate.ts +++ b/packages/server/src/db/migrate.ts @@ -96,7 +96,7 @@ export async function update() { console.log('database up to date!'); } else { const difference = expectedVersion - currentVersion; - process.stdout.write(`database ${difference} version${difference !== 1 ? 's' : ''} behind`); + console.log(`database ${difference} version${difference !== 1 ? 's' : ''} behind`); // console.log(`${currentVersion} >>> ${expectedVersion}`); const neededMigrations = migrations.filter(m => m.version > currentVersion); let completedMigrations = 0; diff --git a/packages/server/src/db/query.ts b/packages/server/src/db/query.ts index cfb0caf..294910a 100644 --- a/packages/server/src/db/query.ts +++ b/packages/server/src/db/query.ts @@ -3,14 +3,20 @@ import { connection } from './migrate'; -export default async function(a: any, ...opts: any[]): Promise { +export default async function(a: any, ...opts: any[]): Promise { const b64 = a.split('base64,')[1]; const text = Buffer.from(b64, 'base64').toString(); - return await new Promise((resolve, reject) => { - connection.query(text, [...opts], (err, results) => { - if(!err) return resolve(results); - console.error(err); + try { + return await new Promise((resolve, reject) => { + connection.query(text, [...opts], (err, results) => { + if(!err) return resolve(results); + console.error(err.errno, err.sqlMessage); + console.error(err.sql); + reject(err); + }); }); - }); + } catch(e) { + return null; + } // console.log(...opts) } \ No newline at end of file diff --git a/packages/server/src/db/snippets/channel/list.sql b/packages/server/src/db/snippets/channel/list.sql new file mode 100644 index 0000000..e30fc6c --- /dev/null +++ b/packages/server/src/db/snippets/channel/list.sql @@ -0,0 +1 @@ +SELECT (name, uid) FROM channels; \ No newline at end of file diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 9579d83..0f8305f 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -17,7 +17,9 @@ wss.on('connection', (ws) => { } const {action, data} = message; try { + console.log(action, data); const _return = await (router(action, data) as unknown as Promise); + console.log(_return); if(_return) { ws.send(JSON.stringify(_return)); } diff --git a/packages/server/src/router.ts b/packages/server/src/router.ts index 5aa4ad8..722816c 100644 --- a/packages/server/src/router.ts +++ b/packages/server/src/router.ts @@ -1,19 +1,26 @@ export default function router(routes: any) { + for(const routeName in routes) { const route = routes[routeName]; - if(typeof route === 'object') { - for(const suffix in route) { + if('routes' in route) { + for(const suffix of route.routes) { const combinedRouteName = routeName + ':' + suffix; - routes[combinedRouteName] = route[suffix]; + routes[combinedRouteName] = (_: never, ...args: any[]) => route(suffix, args); } delete routes[routeName]; } } - return function(route: any, data: any) { + + const sendFn = function(route: any, data: any) { + console.log(routes); if(route in routes) { return routes[route](data); } else { console.warn(`route <${route}> not found`); + console.trace(); } }; + + sendFn.routes = Object.keys(routes); + return sendFn; } \ No newline at end of file diff --git a/packages/server/src/routers/message.ts b/packages/server/src/routers/message.ts new file mode 100644 index 0000000..b7ee42f --- /dev/null +++ b/packages/server/src/routers/message.ts @@ -0,0 +1,29 @@ +import { broadcast } from '..'; +import query from '../db/query'; +import router from '../router'; +import newMessage from '../db/snippets/message/new.sql'; +import recentMessages from '../db/snippets/message/recent.sql'; + +export default router({ + async message(data: any) { + const failed = null === await query(newMessage, data.text, data.from, data.uid, data.timestamp); + if(failed) return; + broadcast('message:message', data); + }, + async recent() { + console.log('got recents request'); + const messages = await query(recentMessages); + if(messages === null) return; + return { + action: 'message:recent', + data: { + messages: messages.map(v => ({ + from: v.from, + uid: v.uid, + timestamp: v.t_sent * 1000, + text: v.text, + })), + }, + }; + }, +}); \ No newline at end of file diff --git a/packages/server/src/routers/root.ts b/packages/server/src/routers/root.ts index 683d7ce..67fd916 100644 --- a/packages/server/src/routers/root.ts +++ b/packages/server/src/routers/root.ts @@ -1,30 +1,9 @@ import router from '../router'; -import { broadcast } from '../index'; -import query from '../db/query'; -import newMessage from '../db/snippets/message/new.sql'; -import recentMessages from '../db/snippets/message/recent.sql'; +import message from './message'; export default router({ up() { console.log(Date.now()); }, - message(data: any) { - query(newMessage, data.text, data.from, data.uid, data.timestamp); - broadcast('message', data); - }, - async recent() { - console.log('got recents request'); - const messages = await query(recentMessages); - return { - action: 'recent', - data: { - messages: messages.map(v => ({ - from: v.from, - uid: v.uid, - timestamp: v.t_sent * 1000, - text: v.text, - })), - }, - }; - }, + message: message, }); \ No newline at end of file diff --git a/scripts/watch.js b/scripts/watch.js index 2b97f30..3036964 100644 --- a/scripts/watch.js +++ b/scripts/watch.js @@ -66,7 +66,7 @@ const setupServerPackageWatcher = () => { if (!data) return; const mayIgnore = stderrFilterPatterns.some((r) => r.test(data)); if (mayIgnore) return; - logger.error(data, {timestamp: true}); + data.split('\n').forEach(d => logger.error(d, {timestamp: true})); }); /** Stops the watch script when the application has been quit */