make channels from array into object
This commit is contained in:
parent
ab910619f8
commit
8f24a34a1d
|
@ -90,7 +90,7 @@ export type Action =
|
|||
minecraftname: string,
|
||||
blockDm: boolean,
|
||||
canvases: Object,
|
||||
channels: Array,
|
||||
channels: Object,
|
||||
blocked: Array,
|
||||
userlvl: number,
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
import React, {
|
||||
useRef, useEffect, useState, useLayoutEffect,
|
||||
useRef, useEffect,
|
||||
} from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
|
@ -23,7 +23,6 @@ const UserContextMenu = ({
|
|||
close,
|
||||
}) => {
|
||||
const wrapperRef = useRef(null);
|
||||
const [channelArray, setChannelArray] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event) => {
|
||||
|
@ -42,20 +41,6 @@ const UserContextMenu = ({
|
|||
};
|
||||
}, [wrapperRef]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
for (let i = 0; i < channels.length; i += 1) {
|
||||
const chan = channels[i];
|
||||
/*
|
||||
* [cid, name, type, lastMessage]
|
||||
*/
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (chan[0] == cid) {
|
||||
setChannelArray(chan);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, [channels.length]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={wrapperRef}
|
||||
|
@ -68,7 +53,7 @@ const UserContextMenu = ({
|
|||
<div>
|
||||
✔✘ Mute
|
||||
</div>
|
||||
{(channelArray[2] !== 0)
|
||||
{(channels[cid][1] !== 0)
|
||||
&& (
|
||||
<div
|
||||
role="button"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import React, {
|
||||
useRef, useState, useEffect, useCallback,
|
||||
useRef, useState, useEffect, useCallback, useLayoutEffect,
|
||||
} from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { MdChat } from 'react-icons/md';
|
||||
|
@ -44,8 +44,12 @@ const ChannelDropDown = ({
|
|||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
if (show) {
|
||||
if (channels[chatChannel]) {
|
||||
const chType = (channels[chatChannel][1] === 1) ? 1 : 0;
|
||||
setType(chType);
|
||||
}
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
document.addEventListener('touchstart', handleClickOutside);
|
||||
} else {
|
||||
|
@ -55,12 +59,10 @@ const ChannelDropDown = ({
|
|||
}, [show]);
|
||||
|
||||
useEffect(() => {
|
||||
for (let i = 0; i < channels.length; i += 1) {
|
||||
if (channels[i][0] === chatChannel) {
|
||||
setChatChannelName(channels[i][1]);
|
||||
if (channels[chatChannel]) {
|
||||
setChatChannelName(channels[chatChannel][0]);
|
||||
}
|
||||
}
|
||||
}, [chatChannel, channels]);
|
||||
}, [chatChannel]);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -104,8 +106,8 @@ const ChannelDropDown = ({
|
|||
className="channeldds"
|
||||
>
|
||||
{
|
||||
channels.filter((ch) => {
|
||||
const chType = ch[2];
|
||||
Object.keys(channels).filter((cid) => {
|
||||
const chType = channels[cid][1];
|
||||
if (type === 1 && chType === 1) {
|
||||
return true;
|
||||
}
|
||||
|
@ -113,24 +115,27 @@ const ChannelDropDown = ({
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
}).map((ch) => (
|
||||
}).map((cid) => {
|
||||
const [name,, lastTs] = channels[cid];
|
||||
console.log(`name ${name} lastTC ${lastTs} compare to ${chatRead[cid]}`);
|
||||
return (
|
||||
<div
|
||||
onClick={() => setChannel(ch[0])}
|
||||
style={(ch[0] === chatChannel) ? {
|
||||
fontWeight: 'bold',
|
||||
fontSize: 17,
|
||||
} : null}
|
||||
onClick={() => setChannel(cid)}
|
||||
className={
|
||||
`chn${
|
||||
(ch[0] === chatChannel) ? ' selected' : ''
|
||||
}${
|
||||
(chatRead[ch[0]] < ch[3]) ? ' unread' : ''
|
||||
(cid === chatChannel) ? ' selected' : ''
|
||||
}`
|
||||
}
|
||||
>
|
||||
{ch[1]}
|
||||
{
|
||||
(chatRead[cid] < lastTs) ? (
|
||||
<span className="chnunread">※</span>
|
||||
) : null
|
||||
}
|
||||
{name}
|
||||
</div>
|
||||
))
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -114,16 +114,11 @@ const Chat = ({
|
|||
* set channel to first available one
|
||||
*/
|
||||
useEffect(() => {
|
||||
let i = 0;
|
||||
while (i < channels.length) {
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (channels[i][0] == chatChannel) {
|
||||
break;
|
||||
if (!channels[chatChannel]) {
|
||||
const cids = Object.keys(channels);
|
||||
if (cids.length) {
|
||||
setChannel(cids[0]);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
if (i && i === channels.length) {
|
||||
setChannel(channels[0][0]);
|
||||
}
|
||||
}, [chatChannel, channels]);
|
||||
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
*
|
||||
* @flow
|
||||
*/
|
||||
import Sequelize from 'sequelize';
|
||||
import logger from './logger';
|
||||
|
||||
import { RegUser, Message } from '../data/models';
|
||||
import { RegUser, Message, Channel } from '../data/models';
|
||||
|
||||
const MAX_BUFFER_TIME = 120000;
|
||||
|
||||
|
@ -62,6 +63,13 @@ class ChatMessageBuffer {
|
|||
uid,
|
||||
message,
|
||||
});
|
||||
Channel.update({
|
||||
lastMessage: Sequelize.literal('CURRENT_TIMESTAMP'),
|
||||
}, {
|
||||
where: {
|
||||
id: cid,
|
||||
},
|
||||
});
|
||||
const messages = this.buffer.get(cid);
|
||||
if (messages) {
|
||||
messages.push([
|
||||
|
|
|
@ -10,8 +10,7 @@ import { CHAT_CHANNELS, EVENT_USER_NAME, INFO_USER_NAME } from './constants';
|
|||
|
||||
export class ChatProvider {
|
||||
constructor() {
|
||||
this.defaultChannels = [];
|
||||
this.defaultChannelIds = [];
|
||||
this.defaultChannels = {};
|
||||
this.enChannelId = 0;
|
||||
this.intChannelId = 0;
|
||||
this.infoUserId = 1;
|
||||
|
@ -48,8 +47,6 @@ export class ChatProvider {
|
|||
|
||||
async initialize() {
|
||||
// find or create default channels
|
||||
this.defaultChannels.length = 0;
|
||||
this.defaultChannelIds.length = 0;
|
||||
for (let i = 0; i < CHAT_CHANNELS.length; i += 1) {
|
||||
const { name } = CHAT_CHANNELS[i];
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
|
@ -66,13 +63,11 @@ export class ChatProvider {
|
|||
if (name === 'en') {
|
||||
this.enChannelId = id;
|
||||
}
|
||||
this.defaultChannels.push([
|
||||
id,
|
||||
this.defaultChannels[id] = [
|
||||
name,
|
||||
type,
|
||||
lastTs,
|
||||
]);
|
||||
this.defaultChannelIds.push(id);
|
||||
];
|
||||
}
|
||||
// find or create default users
|
||||
let name = INFO_USER_NAME;
|
||||
|
@ -106,7 +101,7 @@ export class ChatProvider {
|
|||
}
|
||||
|
||||
userHasChannelAccess(user, cid, write = false) {
|
||||
if (this.defaultChannelIds.includes(cid)) {
|
||||
if (this.defaultChannels[cid]) {
|
||||
if (!write || user.regUser) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -31,10 +31,10 @@ export default async function getMe(user) {
|
|||
delete userdata.mcVerified;
|
||||
|
||||
userdata.canvases = canvases;
|
||||
userdata.channels = [
|
||||
userdata.channels = {
|
||||
...chatProvider.defaultChannels,
|
||||
...userdata.channels,
|
||||
];
|
||||
};
|
||||
|
||||
return userdata;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ class User {
|
|||
// id should stay null if unregistered
|
||||
this.id = id;
|
||||
this.ip = ip;
|
||||
this.channels = [];
|
||||
this.channels = {};
|
||||
this.channelIds = [];
|
||||
this.blocked = [];
|
||||
this.ipSub = getIPv6Subnet(ip);
|
||||
|
@ -70,12 +70,11 @@ class User {
|
|||
name = (dmu1.id === this.id) ? dmu2.name : dmu1.name;
|
||||
}
|
||||
this.channelIds.push(id);
|
||||
this.channels.push([
|
||||
id,
|
||||
this.channels[id] = [
|
||||
name,
|
||||
type,
|
||||
lastTs,
|
||||
]);
|
||||
];
|
||||
}
|
||||
}
|
||||
if (reguser.blocked) {
|
||||
|
|
|
@ -6,7 +6,21 @@ import type { Action } from '../actions/types';
|
|||
|
||||
export type ChatState = {
|
||||
inputMessage: string,
|
||||
// [[cid, name, type, lastMessage], [cid2, name2, type2, lastMessage2],...]
|
||||
/*
|
||||
* {
|
||||
* cid: [
|
||||
* name,
|
||||
* type,
|
||||
* lastTs,
|
||||
* ],
|
||||
* cid2: [
|
||||
* name,
|
||||
* type,
|
||||
* lastTs,
|
||||
* ],
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
channels: Array,
|
||||
// [[uId, userName], [userId2, userName2],...]
|
||||
blocked: Array,
|
||||
|
@ -16,7 +30,7 @@ export type ChatState = {
|
|||
|
||||
const initialState: ChatState = {
|
||||
inputMessage: '',
|
||||
channels: [],
|
||||
channels: {},
|
||||
blocked: [],
|
||||
messages: {},
|
||||
};
|
||||
|
@ -56,22 +70,19 @@ export default function chat(
|
|||
|
||||
case 'ADD_CHAT_CHANNEL': {
|
||||
const { channel } = action;
|
||||
const cid = channel[0];
|
||||
const channels = state.channels
|
||||
.filter((ch) => (ch[0] !== cid));
|
||||
channels.push(channel);
|
||||
return {
|
||||
...state,
|
||||
channels,
|
||||
channels: {
|
||||
...state.channels,
|
||||
...channel,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
case 'REMOVE_CHAT_CHANNEL': {
|
||||
const { cid } = action;
|
||||
const channels = state.channels.filter(
|
||||
// eslint-disable-next-line eqeqeq
|
||||
(chan) => (chan[0] != cid),
|
||||
);
|
||||
const channels = { ...state.channels };
|
||||
delete channels[cid];
|
||||
return {
|
||||
...state,
|
||||
channels,
|
||||
|
@ -106,7 +117,7 @@ export default function chat(
|
|||
const {
|
||||
name, text, country, channel, user,
|
||||
} = action;
|
||||
if (!state.messages[channel]) {
|
||||
if (!state.messages[channel] || !state.channels[channel]) {
|
||||
return state;
|
||||
}
|
||||
const messages = {
|
||||
|
@ -119,8 +130,19 @@ export default function chat(
|
|||
if (messages[channel].length > MAX_CHAT_MESSAGES) {
|
||||
messages[channel].shift();
|
||||
}
|
||||
|
||||
/*
|
||||
* update timestamp of last message
|
||||
*/
|
||||
const channelArray = [...state.channels[channel]];
|
||||
channelArray[2] = Date.now();
|
||||
|
||||
return {
|
||||
...state,
|
||||
channels: {
|
||||
...state.channels,
|
||||
[channel]: channelArray,
|
||||
},
|
||||
messages,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -109,9 +109,15 @@ export default function gui(
|
|||
}
|
||||
|
||||
case 'SET_CHAT_CHANNEL': {
|
||||
const { cid } = action;
|
||||
|
||||
return {
|
||||
...state,
|
||||
chatChannel: action.cid,
|
||||
chatChannel: cid,
|
||||
chatRead: {
|
||||
...state.chatRead,
|
||||
cid: Date.now(),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -139,6 +145,42 @@ export default function gui(
|
|||
};
|
||||
}
|
||||
|
||||
case 'RECEIVE_ME': {
|
||||
const { channels } = action;
|
||||
const cids = Object.keys(channels);
|
||||
const chatRead = {...state.chatRead};
|
||||
for (let i = 0; i < cids.length; i += 1) {
|
||||
const cid = cids[i];
|
||||
chatRead[cid] = 0;
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
chatRead,
|
||||
};
|
||||
}
|
||||
|
||||
case 'ADD_CHAT_CHANNEL': {
|
||||
const [cid] = Object.keys(action.channel);
|
||||
return {
|
||||
...state,
|
||||
chatRead: {
|
||||
...state.chatRead,
|
||||
[cid]: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
case 'REMOVE_CHAT_CHANNEL': {
|
||||
const { cid } = action;
|
||||
const chatRead = { ...state.chatRead };
|
||||
delete chatRead[cid];
|
||||
return {
|
||||
...state,
|
||||
chatRead,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
case 'PLACE_PIXEL': {
|
||||
let { pixelsPlaced } = state;
|
||||
pixelsPlaced += 1;
|
||||
|
|
|
@ -105,7 +105,6 @@ async function startDm(req: Request, res: Response) {
|
|||
raw: true,
|
||||
});
|
||||
const ChannelId = channel[0].id;
|
||||
const { lastMessage } = channel[0];
|
||||
|
||||
const promises = [
|
||||
UserChannel.findOrCreate({
|
||||
|
@ -127,12 +126,13 @@ async function startDm(req: Request, res: Response) {
|
|||
|
||||
// TODO: inform websocket to add channelId to user
|
||||
res.json({
|
||||
channel: [
|
||||
ChannelId,
|
||||
channel: {
|
||||
[ChannelId]: [
|
||||
userName,
|
||||
1,
|
||||
lastMessage,
|
||||
Date.now(),
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -485,6 +485,15 @@ tr:nth-child(even) {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.chn.selected, .chnunread {
|
||||
font-weight: bold;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.chnunread {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.usermessages {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
|
|
|
@ -194,7 +194,7 @@ app.get('/', async (req, res) => {
|
|||
// ip config
|
||||
// -----------------------------------------------------------------------------
|
||||
// use this if models changed:
|
||||
const promise = models.sync({ alter: { drop: true } })
|
||||
const promise = models.sync({ alter: { drop: false } })
|
||||
// const promise = models.sync()
|
||||
.catch((err) => logger.error(err.stack));
|
||||
promise.then(() => {
|
||||
|
|
Loading…
Reference in New Issue
Block a user