diff --git a/src/components/Chat.jsx b/src/components/Chat.jsx index bf90942..36c1fe7 100644 --- a/src/components/Chat.jsx +++ b/src/components/Chat.jsx @@ -33,13 +33,14 @@ const Chat = ({ const [nameRegExp, setNameRegExp] = useState(null); const { stayScrolled } = useStayScrolled(listRef, { initialScroll: Infinity, + inaccuracy: 10, }); const channelMessages = chatMessages[chatChannel]; useLayoutEffect(() => { stayScrolled(); - }, [channelMessages]); + }, [channelMessages.length]); useEffect(() => { if (channelMessages.length === MAX_CHAT_MESSAGES) { @@ -66,9 +67,10 @@ const Chat = ({ function handleSubmit(e) { e.preventDefault(); - if (!inputMessage) return; + const msg = inputMessage.trim(); + if (!msg) return; // send message via websocket - ProtocolClient.sendChatMessage(inputMessage, chatChannel); + ProtocolClient.sendChatMessage(msg, chatChannel); setInputMessage(''); } diff --git a/src/components/ChatMessage.jsx b/src/components/ChatMessage.jsx index 4d9a6b8..f95717f 100644 --- a/src/components/ChatMessage.jsx +++ b/src/components/ChatMessage.jsx @@ -3,8 +3,9 @@ * @flow */ import React from 'react'; +import { connect } from 'react-redux'; -import { colorFromText } from '../core/utils'; +import { colorFromText, setBrightness } from '../core/utils'; function ChatMessage({ @@ -12,6 +13,7 @@ function ChatMessage({ msgArray, country, insertText, + darkMode, }) { if (!name || !msgArray) { return null; @@ -44,7 +46,7 @@ function ChatMessage({ {txt} ); @@ -80,7 +82,7 @@ function ChatMessage({ {txt} ); @@ -92,4 +94,10 @@ function ChatMessage({ ); } -export default ChatMessage; +function mapStateToProps(state: State) { + const { style } = state.gui; + const darkMode = style.indexOf('dark') !== -1; + return { darkMode }; +} + +export default connect(mapStateToProps)(ChatMessage); diff --git a/src/core/utils.js b/src/core/utils.js index 52c960c..46f8aab 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -199,6 +199,9 @@ export function numberToString(num: number): string { return ''; } +/* + * generates a color based on a given string + */ export function numberToStringFull(num: number): string { if (num < 0) { return `${num} :-(`; @@ -226,3 +229,24 @@ export function colorFromText(str: string) { return `#${'00000'.substring(0, 6 - c.length)}${c}`; } + +/* + * sets a color into bright or dark mode + */ +export function setBrightness(hex, dark: boolean = false) { + hex = hex.replace(/^\s*#|\s*$/g, ''); + + if (hex.length === 3) { + hex = hex.replace(/(.)/g, '$1$1'); + } + + let r = Math.floor(parseInt(hex.substr(0, 2), 16) / 2); + let g = Math.floor(parseInt(hex.substr(2, 2), 16) / 2); + let b = Math.floor(parseInt(hex.substr(4, 2), 16) / 2); + if (dark) { + r += 128; + g += 128; + b += 128; + } + return `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`; +} diff --git a/src/reducers/canvas.js b/src/reducers/canvas.js index 9cba4db..0999a50 100644 --- a/src/reducers/canvas.js +++ b/src/reducers/canvas.js @@ -109,6 +109,7 @@ function getViewFromURL(canvases: Object) { canvasMaxTiledZoom: getMaxTiledZoom(canvasSize), palette: new Palette(colors, 0), clrIgnore, + selectedColor: clrIgnore, view, viewscale: scale, scale, @@ -125,6 +126,7 @@ function getViewFromURL(canvases: Object) { canvasMaxTiledZoom: getMaxTiledZoom(canvasd.size), palette: new Palette(canvasd.colors, 0), clrIgnore: canvasd.cli, + selectedColor: canvasd.cli, view: getGivenCoords(), viewscale: DEFAULT_SCALE, scale: DEFAULT_SCALE, @@ -135,7 +137,6 @@ function getViewFromURL(canvases: Object) { const initialState: CanvasState = { ...getViewFromURL(DEFAULT_CANVASES), fetchs: 0, - selectedColor: 3, isHistoricalView: false, historicalDate: null, historicalTime: null, diff --git a/src/socket/SocketServer.js b/src/socket/SocketServer.js index d0a0302..3a2f925 100644 --- a/src/socket/SocketServer.js +++ b/src/socket/SocketServer.js @@ -228,60 +228,65 @@ class SocketServer extends WebSocketEvents { } static async onTextMessage(text, ws) { - let message; - let channelId; try { - const data = JSON.parse(text); - [message, channelId] = data; - channelId = Number(channelId); - if (Number.isNaN(channelId)) { - throw new Error('NaN'); - } - } catch { - logger.warn( - `Received unparseable message from ${ws.name} on websocket: ${text}`, - ); - return; - } - - if (ws.name && message) { - const waitLeft = ws.rateLimiter.tick(); - if (waitLeft) { - ws.send(JSON.stringify([ - 'info', - // eslint-disable-next-line max-len - `You are sending messages too fast, you have to wait ${Math.floor(waitLeft / 1000)}s :(`, - 'il', - channelId, - ])); + let message; + let channelId; + try { + const data = JSON.parse(text); + [message, channelId] = data; + channelId = Number(channelId); + if (Number.isNaN(channelId)) { + throw new Error('NaN'); + } + } catch { + logger.warn( + `Received unparseable message from ${ws.name} on websocket: ${text}`, + ); return; } - const errorMsg = await chatProvider.sendMessage( - ws.user, - message, - channelId, - ); - if (!errorMsg) { - // automute on repeated message spam - if (ws.last_message && ws.last_message === message) { - ws.message_repeat += 1; - if (ws.message_repeat >= 4) { - logger.info(`User ${ws.name} got automuted`); - ChatProvider.automute(ws.name, channelId); + message = message.trim(); + + if (ws.name && message) { + const waitLeft = ws.rateLimiter.tick(); + if (waitLeft) { + ws.send(JSON.stringify([ + 'info', + // eslint-disable-next-line max-len + `You are sending messages too fast, you have to wait ${Math.floor(waitLeft / 1000)}s :(`, + 'il', + channelId, + ])); + return; + } + const errorMsg = await chatProvider.sendMessage( + ws.user, + message, + channelId, + ); + if (!errorMsg) { + // automute on repeated message spam + if (ws.last_message && ws.last_message === message) { + ws.message_repeat += 1; + if (ws.message_repeat >= 4) { + logger.info(`User ${ws.name} got automuted`); + ChatProvider.automute(ws.name, channelId); + ws.message_repeat = 0; + } + } else { ws.message_repeat = 0; + ws.last_message = message; } } else { - ws.message_repeat = 0; - ws.last_message = message; + ws.send(JSON.stringify(['info', errorMsg, 'il', channelId])); } + logger.info( + `Received chat message ${message} from ${ws.name} / ${ws.user.ip}`, + ); } else { - ws.send(JSON.stringify(['info', errorMsg, 'il', channelId])); + logger.info('Got empty message or message from unidentified ws'); } - logger.info( - `Received chat message ${message} from ${ws.name} / ${ws.user.ip}`, - ); - } else { - logger.info('Got empty message or message from unidentified ws'); + } catch { + logger.info('Got invalid ws message'); } }