Skip to content

Commit

Permalink
Merge pull request #245 from vtm9/master
Browse files Browse the repository at this point in the history
Improve langs dropdown-selector in gameTab
  • Loading branch information
vtm9 committed Jan 11, 2018
2 parents 0681d10 + 997bb95 commit 76b956d
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 32 deletions.
21 changes: 12 additions & 9 deletions assets/js/widgets/components/LangSelector.jsx
@@ -1,10 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import languages from '../config/languages';
import Gon from 'Gon';

const LangSelector = ({ currentLangKey, onChange }) => {
const options = _.filter(_.keys(languages), key => key !== currentLangKey);
const languages = Gon.getAsset('langs');

const LangSelector = ({ currentLangSlug, onChange }) => {

const [[currentLang, ...other], otherLangs] = _.partition(languages, lang => lang.slug === currentLangSlug);
return (
<div className="dropdown">
<button
Expand All @@ -15,19 +18,19 @@ const LangSelector = ({ currentLangKey, onChange }) => {
aria-haspopup="true"
aria-expanded="false"
>
{languages[currentLangKey]}
{currentLang.name}
</button>
<div className="dropdown-menu" aria-labelledby="dropdownLangButton">
{_.map(options, langKey => (
{_.map(otherLangs, ({ slug, name }) => (
<button
className="dropdown-item"
href="#"
key={langKey}
key={slug}
onClick={() => {
onChange(langKey);
onChange(slug);
}}
>
{languages[langKey]}
{name}
</button>
))}
</div>
Expand All @@ -36,7 +39,7 @@ const LangSelector = ({ currentLangKey, onChange }) => {
};

LangSelector.propTypes = {
currentLangKey: PropTypes.string.isRequired,
currentLangSlug: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
};

Expand Down
11 changes: 6 additions & 5 deletions assets/js/widgets/containers/Editor.jsx
@@ -1,12 +1,14 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Gon from 'Gon';
import AceEditor from 'react-ace';
import 'brace';
import 'brace/mode/javascript';
import 'brace/mode/ruby';
import 'brace/mode/elixir';
import 'brace/theme/solarized_dark';
import languages from '../config/languages';
// import languages from '../config/languages';
const languages = Gon.getAsset('langs');

const selectionBlockStyle = {
position: 'absolute',
Expand All @@ -21,7 +23,7 @@ class Editor extends Component {
value: PropTypes.string,
name: PropTypes.string.isRequired,
editable: PropTypes.bool,
lang: PropTypes.string.isRequired,
syntax: PropTypes.string,
onChange: PropTypes.func,
allowCopy: PropTypes.bool,
}
Expand All @@ -30,7 +32,7 @@ class Editor extends Component {
value: '',
editable: false,
onChange: null,
lang: _.values(languages)[0],
syntax: 'javascript',
allowCopy: true,
}

Expand All @@ -39,11 +41,10 @@ class Editor extends Component {
value,
name,
editable,
lang,
syntax,
onChange,
allowCopy,
} = this.props;
const syntax = languages[lang];

return (
<div style={{ position: 'relative' }}>
Expand Down
6 changes: 3 additions & 3 deletions assets/js/widgets/containers/GameStatusTab.jsx
Expand Up @@ -76,10 +76,10 @@ class GameStatusTab extends Component {
type="button"
disabled
>
{languages[leftEditorLang]}
{leftEditorLang.name}
</button>
) : (
<LangSelector currentLangKey={leftEditorLang} onChange={this.props.setLang} />
<LangSelector currentLangSlug={leftEditorLang.slug} onChange={this.props.setLang} />
)}
{!canCheckResult ? null : (
<button
Expand Down Expand Up @@ -169,7 +169,7 @@ const mapStateToProps = (state) => {

const mapDispatchToProps = dispatch => ({
checkResult: () => dispatch(checkGameResult()),
setLang: langKey => dispatch(sendEditorLang(langKey)),
setLang: langSlug => dispatch(sendEditorLang(langSlug)),
});

export default connect(mapStateToProps, mapDispatchToProps)(GameStatusTab);
5 changes: 2 additions & 3 deletions assets/js/widgets/containers/GameWidget.jsx
Expand Up @@ -38,7 +38,6 @@ class GameWidget extends Component {
} = this.props;
// FIXME: currentUser shouldn't return {} for spectator
const isPlayer = currentUser.type !== userTypes.spectator;
console.log(isPlayer, currentUser, currentUser.type , userTypes.spectator)
const editable = isPlayer;
const editorState = leftEditor;
const onChange = isPlayer ?
Expand All @@ -48,7 +47,7 @@ class GameWidget extends Component {
return {
onChange,
editable,
lang: editorState.currentLang,
syntax: _.get(editorState, ['currentLang', 'name'], 'javascript'),
value: editorState.value,
name: 'left-editor',
};
Expand All @@ -62,7 +61,7 @@ class GameWidget extends Component {
onChange: _.noop,
editable: false,
allowCopy: false,
lang: editorState.currentLang,
syntax: _.get(editorState, ['currentLang', 'name'], 'javascript'),
value: editorState.value,
name: 'right-editor',
};
Expand Down
35 changes: 24 additions & 11 deletions assets/js/widgets/middlewares/Game.js
@@ -1,11 +1,13 @@
import socket from '../../socket';
import _ from 'lodash';
import Gon from 'Gon';
import socket from '../../socket';
import { EditorActions, GameActions } from '../redux/Actions';
import { currentUserIdSelector } from '../selectors/user';
import { editorsSelector } from '../redux/EditorRedux';
import userTypes from '../config/userTypes';
import * as actions from '../actions';

const languages = Gon.getAsset('langs');
const gameId = Gon.getAsset('game_id');
const channelName = `game:${gameId}`;
const channel = socket.channel(channelName);
Expand All @@ -24,6 +26,9 @@ const initGameChannel = (dispatch) => {
task,
} = response;

const firstEditorLang = _.find(languages, { slug: first_player_editor_lang });
const secondEditorLang = _.find(languages, { slug: second_player_editor_lang });

const users = [{
id: first_player.id,
name: first_player.name,
Expand All @@ -45,14 +50,14 @@ const initGameChannel = (dispatch) => {
dispatch(EditorActions.updateEditorData(
first_player.id,
first_player_editor_text,
first_player_editor_lang,
firstEditorLang,
));

if (second_player.id) {
dispatch(EditorActions.updateEditorData(
second_player.id,
second_player_editor_text,
second_player_editor_lang,
secondEditorLang,
));
}

Expand Down Expand Up @@ -82,12 +87,14 @@ export const sendGiveUp = () => {
channel.push('give_up');
};

export const sendEditorLang = lang => (dispatch, getState) => {
export const sendEditorLang = langSlug => (dispatch, getState) => {
const state = getState();
const userId = currentUserIdSelector(state);
dispatch(EditorActions.updateEditorLang(userId, lang));
const editorLang = _.find(languages, { slug: langSlug });

channel.push('editor:lang', { lang });
dispatch(EditorActions.updateEditorLang(userId, editorLang));

channel.push('editor:lang', { lang: langSlug });
};

export const editorReady = () => (dispatch) => {
Expand All @@ -96,8 +103,9 @@ export const editorReady = () => (dispatch) => {
dispatch(EditorActions.updateEditorText(userId, editorText));
});

channel.on('editor:lang', ({ user_id: userId, lang }) => {
dispatch(EditorActions.updateEditorLang(userId, lang));
channel.on('editor:lang', ({ user_id: userId, lang: langSlug }) => {
const editorLang = _.find(languages, { slug: langSlug });
dispatch(EditorActions.updateEditorLang(userId, editorLang));
});

channel.on('user:joined', ({
Expand All @@ -110,6 +118,11 @@ export const editorReady = () => (dispatch) => {
second_player_editor_text,
second_player_editor_lang,
}) => {

//TODO: Add strong refactoring
const firstEditorLang = _.find(languages, { slug: first_player_editor_lang });
const secondEditorLang = _.find(languages, { slug: second_player_editor_lang });

dispatch(GameActions.updateStatus({ status, winner }));

dispatch(actions.updateUsers([{
Expand All @@ -127,14 +140,14 @@ export const editorReady = () => (dispatch) => {
dispatch(EditorActions.updateEditorData(
first_player.id,
first_player_editor_text,
first_player_editor_lang,
firstEditorLang,
));

if (second_player.id) {
dispatch(EditorActions.updateEditorData(
second_player.id,
second_player_editor_text,
second_player_editor_lang,
secondEditorLang,
));
}
});
Expand All @@ -156,7 +169,7 @@ export const checkGameResult = () => (dispatch, getState) => {

const payload = {
editor_text: currentUserEditor.value,
lang: currentUserEditor.currentLang,
lang: currentUserEditor.currentLang.slug,
};

channel.push('check_result', payload)
Expand Down
2 changes: 2 additions & 0 deletions lib/mix/tasks/upload_langs.ex
Expand Up @@ -10,8 +10,10 @@ defmodule Mix.Tasks.UploadLangs do

def run(_) do
{:ok, _started} = Application.ensure_all_started(:codebattle)

spec_filepath = Path.join(File.cwd!, "priv/repo/seeds/langs.yml")
%{langs: langs} = YamlElixir.read_from_file spec_filepath, atoms: true

for lang_data <- langs do
language = case Repo.get_by(Language, slug: lang_data.slug) do
nil -> %Language{slug: lang_data.slug}
Expand Down
2 changes: 1 addition & 1 deletion priv/repo/seeds/langs.yml
Expand Up @@ -6,7 +6,7 @@
:extension: rb
:docker_image: "codebattle/ruby:2.5.0"
:solution_template: "def solution()\n\nend"
- :name: js
- :name: javascript
:slug: js
:version: 9.3.0
:extension: js
Expand Down

0 comments on commit 76b956d

Please sign in to comment.