fix text selection in chat
fix auto-scrolling in chat
This commit is contained in:
parent
b53ff19876
commit
69552fbf10
|
@ -3,18 +3,27 @@
|
|||
* @flow
|
||||
*/
|
||||
|
||||
import React, { useRef, useLayoutEffect } from 'react';
|
||||
import React, {
|
||||
useRef, useLayoutEffect, useState, useEffect,
|
||||
} from 'react';
|
||||
import useStayScrolled from 'react-stay-scrolled';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { MAX_CHAT_MESSAGES } from '../core/constants';
|
||||
import type { State } from '../reducers';
|
||||
import ChatInput from './ChatInput';
|
||||
import { saveSelection, restoreSelection } from '../utils/storeSelection';
|
||||
import { colorFromText, splitCoordsInString } from '../core/utils';
|
||||
|
||||
|
||||
function ChatMessage({ name, text, country }) {
|
||||
if (!name || !text) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const msgText = text.trim();
|
||||
let className = 'msg';
|
||||
const isInfo = (name === 'info');
|
||||
let className = 'msg';
|
||||
if (isInfo) {
|
||||
className += ' info';
|
||||
} else if (text.charAt(0) === '>') {
|
||||
|
@ -27,6 +36,7 @@ function ChatMessage({ name, text, country }) {
|
|||
{
|
||||
(!isInfo)
|
||||
&& (
|
||||
<span>
|
||||
<img
|
||||
alt=""
|
||||
title={country}
|
||||
|
@ -36,11 +46,6 @@ function ChatMessage({ name, text, country }) {
|
|||
e.target.src = './cf/xx.gif';
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
(!isInfo)
|
||||
&& (
|
||||
<span
|
||||
className="chatname"
|
||||
style={{
|
||||
|
@ -49,6 +54,7 @@ function ChatMessage({ name, text, country }) {
|
|||
>
|
||||
|
||||
{name}
|
||||
</span>
|
||||
:
|
||||
</span>
|
||||
)
|
||||
|
@ -73,6 +79,7 @@ function ChatMessage({ name, text, country }) {
|
|||
|
||||
const Chat = ({ chatMessages, chatChannel }) => {
|
||||
const listRef = useRef();
|
||||
const [selection, setSelection] = useState(null);
|
||||
const { stayScrolled } = useStayScrolled(listRef, {
|
||||
initialScroll: Infinity,
|
||||
});
|
||||
|
@ -81,11 +88,23 @@ const Chat = ({ chatMessages, chatChannel }) => {
|
|||
|
||||
useLayoutEffect(() => {
|
||||
stayScrolled();
|
||||
}, [channelMessages.length]);
|
||||
}, [channelMessages.slice(-1)]);
|
||||
|
||||
useEffect(() => {
|
||||
if (channelMessages.length === MAX_CHAT_MESSAGES) {
|
||||
restoreSelection(selection);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
|
||||
<ul className="chatarea" ref={listRef} style={{ flexGrow: 1 }}>
|
||||
<ul
|
||||
className="chatarea"
|
||||
ref={listRef}
|
||||
style={{ flexGrow: 1 }}
|
||||
onMouseUp={() => { setSelection(saveSelection); }}
|
||||
role="presentation"
|
||||
>
|
||||
{
|
||||
channelMessages.map((message) => (
|
||||
<ChatMessage
|
||||
|
|
|
@ -91,3 +91,4 @@ export const MONTH = 30 * DAY;
|
|||
|
||||
// available Chat Channels
|
||||
export const CHAT_CHANNELS = ['en', 'int'];
|
||||
export const MAX_CHAT_MESSAGES = 100;
|
||||
|
|
|
@ -44,6 +44,8 @@ async function exportVox(
|
|||
canvas,
|
||||
centerPoint,
|
||||
) {
|
||||
// TODO deactivated cause its not finished
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { size: canvasSize, colors } = canvas;
|
||||
// round to chunk with its -x and -y corner closest to centerPoint
|
||||
const [xc,, yc] = centerPoint.map((z) => {
|
||||
|
@ -94,6 +96,8 @@ async function exportVox(
|
|||
// 4 * 256 palette content (rgba * 256 colors)
|
||||
const rgbaChunkSize = 4 * 256;
|
||||
const rgbaChunkLength = 4 + 4 + 4 + rgbaChunkSize;
|
||||
// TODO deactivated cause its not finished
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const rgbaPadding = [256, 256, 256, 256];
|
||||
// Main Chunk
|
||||
// 4 bytes MAIN
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/* @flow */
|
||||
|
||||
import { MAX_CHAT_MESSAGES } from '../core/constants';
|
||||
|
||||
import type { Action } from '../actions/types';
|
||||
|
||||
|
||||
|
@ -127,7 +129,7 @@ export default function user(
|
|||
} = action;
|
||||
const chatMessages = state.chatMessages.slice();
|
||||
let channelMessages = chatMessages[channel];
|
||||
if (channelMessages.length > 50) {
|
||||
if (channelMessages.length > MAX_CHAT_MESSAGES) {
|
||||
channelMessages = channelMessages.slice(-50);
|
||||
}
|
||||
channelMessages = channelMessages.concat([
|
||||
|
|
27
src/utils/storeSelection.js
Normal file
27
src/utils/storeSelection.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
export function saveSelection() {
|
||||
if (window.getSelection) {
|
||||
const sel = window.getSelection();
|
||||
if (sel.getRangeAt && sel.rangeCount) {
|
||||
return sel.getRangeAt(0);
|
||||
}
|
||||
} else if (document.selection && document.selection.createRange) {
|
||||
return document.selection.createRange();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function restoreSelection(range) {
|
||||
if (range) {
|
||||
if (window.getSelection) {
|
||||
const sel = window.getSelection();
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
} else if (document.selection && range.select) {
|
||||
range.select();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user