Skip to content

Commit

Permalink
remove chat list, add hover and minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
ReDBrother committed Oct 18, 2024
1 parent 2d3e650 commit fc972a3
Show file tree
Hide file tree
Showing 31 changed files with 509 additions and 436 deletions.
1 change: 1 addition & 0 deletions services/app/apps/codebattle/.eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ extends:
rules:
no-console: 0
react/prop-types: 0
react/no-unused-prop-types: 0
import/no-unresolved: 0
import/no-extraneous-dependencies:
- 2
Expand Down
6 changes: 0 additions & 6 deletions services/app/apps/codebattle/assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import {
renderUserPage,
renderUsersRating,
} from './widgets';
import renderExtensionPopup from './widgets/components/ExtensionPopup';

if (process.env.NODE_ENV === 'development') {
inspect({
Expand Down Expand Up @@ -91,7 +90,6 @@ window.addEventListener('phx:page-loading-stop', _info => NProgress.done());
liveSocket.connect();

const builderWidgetRoot = document.getElementById('builder-widget-root');
const extension = document.getElementById('extension');
const gameWidgetRoot = document.getElementById('game-widget-root');
const heatmapRoot = document.getElementById('heatmap-root');
const onlineRoot = document.getElementById('online-root');
Expand All @@ -107,10 +105,6 @@ const adminTournamentRoot = document.getElementById('tournament-admin-root');
const eventWidgetRoot = document.getElementById('event-widget');
const userPageRoot = document.getElementById('user-page-root');

if (extension) {
renderExtensionPopup(extension);
}

if (gameWidgetRoot) {
renderGameWidget(gameWidgetRoot);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';

import useHover from '../utils/useHover';

import UserInfo from './UserInfo';

function ChatUserInfo({ user, displayMenu, className = '' }) {
const [ref, hovered] = useHover();

return (
<div
ref={ref}
role="button"
tabIndex={0}
className={className}
title={user.name}
key={user.id}
data-user-id={user.id}
data-user-name={user.name}
onContextMenu={displayMenu}
onClick={displayMenu}
onKeyPress={displayMenu}
>
<UserInfo user={user} hovered={hovered} hideInfo hideOnlineIndicator />
</div>
);
}

export default ChatUserInfo;
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { memo } from 'react';

import MonacoEditor, { loader } from '@monaco-editor/react';
import PropTypes from 'prop-types';

import haskellProvider from '../config/editor/haskell';
import sassProvider from '../config/editor/sass';
Expand Down Expand Up @@ -64,4 +65,33 @@ function Editor(props) {
);
}

Editor.propTypes = {
value: PropTypes.string.isRequired,
syntax: PropTypes.string,
onChange: PropTypes.func.isRequired,
theme: PropTypes.string.isRequired,
loading: PropTypes.bool,
wordWrap: PropTypes.string,
lineNumbers: PropTypes.string,
fontSize: PropTypes.number,
editable: PropTypes.bool,
gameMode: PropTypes.string.isRequired,
checkResult: PropTypes.func.isRequired,
toggleMuteSound: PropTypes.func.isRequired,
mute: PropTypes.bool.isRequired,
userType: PropTypes.string.isRequired,
userId: PropTypes.string.isRequired,
onChangeCursorSelection: PropTypes.func.isRequired,
onChangeCursorPosition: PropTypes.func.isRequired,
};

Editor.defaultProps = {
wordWrap: 'off',
lineNumbers: 'on',
syntax: 'js',
fontSize: 16,
editable: false,
loading: false,
};

export default memo(Editor);

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';

import moment from 'moment';

function InfoMessage({ text, time }) {
return (
<div className="d-flex align-items-baseline flex-wrap">
<small className="text-muted text-small">{text}</small>
<small className="text-muted text-small ml-auto">
{time ? moment.unix(time).format('HH:mm:ss') : ''}
</small>
</div>
);
}

export default InfoMessage;
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ const getSize = ({ small = false, large = false, adaptive = false }) => {
}
};

const Loading = params => {
const size = getSize(params);
function Loading(props) {
const size = getSize(props);

return (
<div className="d-flex my-0 py-1 justify-content-center">
<ReactLoading type="spin" color="#6c757d" height={size} width={size} />
</div>
);
};
}

export default Loading;
110 changes: 57 additions & 53 deletions services/app/apps/codebattle/assets/js/widgets/components/Message.jsx
Original file line number Diff line number Diff line change
@@ -1,108 +1,112 @@
import React from 'react';

import cn from 'classnames';
import moment from 'moment';

import useHover from '../utils/useHover';

import InfoMessage from './InfoMessage';
import MessageTag from './MessageTag';
import MessageTimestamp from './MessageTimestamp';
import SystemMessage from './SystemMessage';

function MessageHeader({ name, time, hovered }) {
const playerClassName = cn(
'd-inline-block text-truncate align-top text-nowrap cb-username-max-length mr-1',
{ 'text-primary': hovered },
);

return (
<>
<span className="font-weight-bold">
<span className={playerClassName}>
{name}
</span>
</span>
<MessageTimestamp time={time} />
</>
);
}

function MessagePart({ part, index, name }) {
if (part.slice(1) === name) {
return (
<span key={index} className="font-weight-bold bg-warning">
{part}
</span>
);
}

const MessageHeader = ({ name, time }) => (
<>
<span className="font-weight-bold">
<span className="d-inline-block text-truncate align-top text-nowrap cb-username-max-length mr-1">
{name}
if (part.startsWith('@')) {
return (
<span key={index} className="font-weight-bold text-primary">
{part}
</span>
</span>
<MessageTimestamp time={time} />
</>
);
);
}

return part;
}

const Message = ({
function Message({
text = '',
name = '',
userId,
type,
time,
meta,
displayMenu,
}) => {
}) {
const [chatHeaderRef, hoveredChatHeader] = useHover();

if (!text) {
return null;
}

if (type === 'system') {
const statusClassName = cn('text-small', {
'text-danger': ['error', 'failure'].includes(meta?.status),
'text-success': meta?.status === 'success',
'text-muted': meta?.status === 'event',
});

return (
<div className="d-flex align-items-baseline flex-wrap">
<small className={statusClassName}>{text}</small>
</div>
);
return <SystemMessage text={text} meta={meta} />;
}

if (type === 'info') {
return (
<div className="d-flex align-items-baseline flex-wrap">
<small className="text-muted text-small">{text}</small>
<small className="text-muted text-small ml-auto">
{time ? moment.unix(time).format('HH:mm:ss') : ''}
</small>
</div>
);
return <InfoMessage text={text} time={time} />;
}

const parts = text.split(/(@+[-a-zA-Z0-9_]+\b)/g);

const renderMessagePart = (part, i) => {
if (part.slice(1) === name) {
return (
<span key={i} className="font-weight-bold bg-warning">
{part}
</span>
);
}
if (part.startsWith('@')) {
return (
<span key={i} className="font-weight-bold text-primary">
{part}
</span>
);
}
return part;
};

const textPartsClassNames = cn('text-break', {
'cb-private-text': meta?.type === 'private',
});

return (
<div className="d-flex align-items-baseline flex-wrap mb-1">
<span className="d-flex flex-column">
<span className="d-flex flex-column w-100">
<span
ref={chatHeaderRef}
role="button"
tabIndex={0}
title={`Message (${name})`}
className="d-flex justify-content-between"
data-user-id={userId}
data-user-name={name}
onContextMenu={displayMenu}
onClick={displayMenu}
onKeyPress={displayMenu}
>
<MessageHeader name={name} time={time} />
<MessageHeader name={name} time={time} hovered={hoveredChatHeader} />
</span>
<span>
<MessageTag messageType={meta?.type} />
<span className={textPartsClassNames}>
{parts.map((part, i) => renderMessagePart(part, i))}
{parts.map(
(part, i) => (
/* eslint-disable react/no-array-index-key */
<MessagePart key={i} part={part} index={i} name={name} />
),
)}
</span>
</span>
</span>
</div>
);
};
}

export default Message;
Loading

0 comments on commit fc972a3

Please sign in to comment.