add new websocket topic - userList - and handle it
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -35,6 +35,5 @@ phpunit-report/*
|
|||||||
/src/Mine/SeekerBundle/Resources/public/js/src/
|
/src/Mine/SeekerBundle/Resources/public/js/src/
|
||||||
|
|
||||||
nohup.out
|
nohup.out
|
||||||
src/Mine/SeekerBundle/Resources/public/js/index.js
|
src/Mine/SeekerBundle/Resources/public/js/build/
|
||||||
src/Mine/SeekerBundle/Resources/public/js/index.min.js
|
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
|
|||||||
@@ -33,14 +33,24 @@ class GameController extends Controller
|
|||||||
// dump($response->getErrorExplanation());
|
// dump($response->getErrorExplanation());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return $this->render('MineSeekerBundle:Game:index.html.twig');
|
return $this->render('MineSeekerBundle:Game:index.html.twig', array(
|
||||||
|
'env' => $this->container->getParameter('kernel.environment'),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function playAction(Request $request)
|
public function playAction(Request $request)
|
||||||
{
|
{
|
||||||
return $this->render('MineSeekerBundle:Game:play.html.twig', array(
|
return $this->render('MineSeekerBundle:Game:play.html.twig', array(
|
||||||
'env' => $this->container->getParameter('kernel.environment'),
|
'env' => $this->container->getParameter('kernel.environment'),
|
||||||
'ssl' => $request->isSecure() ? 'true' : 'false'
|
'ssl' => $request->isSecure() ? 'true' : 'false',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rePlayAction(Request $request)
|
||||||
|
{
|
||||||
|
return $this->render('MineSeekerBundle:Game:play.html.twig', array(
|
||||||
|
'env' => $this->container->getParameter('kernel.environment'),
|
||||||
|
'ssl' => $request->isSecure() ? 'true' : 'false',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Topic Configuration
|
# MineSeeker Topic Configuration
|
||||||
mineseeker_topic:
|
mineseeker_topic:
|
||||||
channel: mineseeker/channel/{game}
|
channel: mineseeker/channel/{game}
|
||||||
handler:
|
handler:
|
||||||
@@ -7,6 +7,12 @@ mineseeker_topic:
|
|||||||
# method:
|
# method:
|
||||||
# path: '[a-z1-9A-Z]+'
|
# path: '[a-z1-9A-Z]+'
|
||||||
|
|
||||||
|
# UserList Topic Configuration
|
||||||
|
userList_topic:
|
||||||
|
channel: mineseeker/userList
|
||||||
|
handler:
|
||||||
|
callback: 'userlist.topic'
|
||||||
|
|
||||||
# Remote Procedure Call Configuration
|
# Remote Procedure Call Configuration
|
||||||
mineseeker_rpc:
|
mineseeker_rpc:
|
||||||
channel: mineseeker-rpc/{method}
|
channel: mineseeker-rpc/{method}
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ MineSeekerBundle_gamePlayWId:
|
|||||||
defaults: { _controller: MineSeekerBundle:Game:play }
|
defaults: { _controller: MineSeekerBundle:Game:play }
|
||||||
schemes: [https]
|
schemes: [https]
|
||||||
|
|
||||||
|
MineSeekerBundle_gameReplay:
|
||||||
|
path: /re-play/{gameAssoc}
|
||||||
|
defaults: { _controller: MineSeekerBundle:Game:rePlay }
|
||||||
|
schemes: [https]
|
||||||
|
|
||||||
MineSeekerBundle_slack:
|
MineSeekerBundle_slack:
|
||||||
path: /slack
|
path: /slack
|
||||||
defaults: { _controller: MineSeekerBundle:Game:slack }
|
defaults: { _controller: MineSeekerBundle:Game:slack }
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ services:
|
|||||||
arguments:
|
arguments:
|
||||||
ping: '@gos_web_socket.pdo.periodic_ping'
|
ping: '@gos_web_socket.pdo.periodic_ping'
|
||||||
|
|
||||||
mineseeker.topic_sample_service:
|
mineseeker.game_service:
|
||||||
class: Mine\SeekerBundle\Topic\MineseekerTopic
|
class: Mine\SeekerBundle\Topic\MineseekerTopic
|
||||||
tags:
|
tags:
|
||||||
- { name: gos_web_socket.topic }
|
- { name: gos_web_socket.topic }
|
||||||
@@ -35,7 +35,16 @@ services:
|
|||||||
doctrine: '@doctrine.orm.entity_manager'
|
doctrine: '@doctrine.orm.entity_manager'
|
||||||
requestStack: '@request_stack'
|
requestStack: '@request_stack'
|
||||||
|
|
||||||
mineseeker.rpc_sample_service:
|
mineseeker.user_list_service:
|
||||||
|
class: Mine\SeekerBundle\Topic\UserListTopic
|
||||||
|
tags:
|
||||||
|
- { name: gos_web_socket.topic }
|
||||||
|
arguments:
|
||||||
|
clientManipulator: "@gos_web_socket.websocket.client_manipulator"
|
||||||
|
doctrine: '@doctrine.orm.entity_manager'
|
||||||
|
requestStack: '@request_stack'
|
||||||
|
|
||||||
|
mineseeker.game_rpc_service:
|
||||||
class: Mine\SeekerBundle\Rpc\MineseekerRpc
|
class: Mine\SeekerBundle\Rpc\MineseekerRpc
|
||||||
tags:
|
tags:
|
||||||
- { name: gos_web_socket.rpc }
|
- { name: gos_web_socket.rpc }
|
||||||
|
|||||||
@@ -141,6 +141,59 @@ header section div.buttons > a.small:hover {
|
|||||||
transition: all 250ms ease-in-out;
|
transition: all 250ms ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main .user-list-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
main .user-list-container .user-friend {
|
||||||
|
width: 15%;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main .user-list-container .user-friend h1 {
|
||||||
|
display: block;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
main .user-list-container .user-friend img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
main .user-list-container .user-friend button {
|
||||||
|
background: #83aed9;
|
||||||
|
display: inline-block;
|
||||||
|
font: bold 22px 'Rajdhani', sans-serif;
|
||||||
|
border: 1px solid #6890ba;
|
||||||
|
color: #FFFFFF;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
-webkit-box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
|
||||||
|
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
|
||||||
|
-webkit-transition: all 250ms ease-in-out;
|
||||||
|
-moz-transition: all 250ms ease-in-out;
|
||||||
|
-o-transition: all 250ms ease-in-out;
|
||||||
|
transition: all 250ms ease-in-out;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
main .user-list-container .user-friend button:hover {
|
||||||
|
background: #86b5e1;
|
||||||
|
border: 1px solid #658fb8;
|
||||||
|
color: #FFFFFF;
|
||||||
|
|
||||||
|
-webkit-box-shadow: 0 7px 15px rgba(0, 0, 0, 0.2);
|
||||||
|
box-shadow: 0 7px 15px rgba(0, 0, 0, 0.2);
|
||||||
|
-webkit-transition: all 250ms ease-in-out;
|
||||||
|
-moz-transition: all 250ms ease-in-out;
|
||||||
|
-o-transition: all 250ms ease-in-out;
|
||||||
|
transition: all 250ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@media screen and (max-width: 1100px) {
|
@media screen and (max-width: 1100px) {
|
||||||
header section {
|
header section {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -166,11 +219,6 @@ header section div.buttons > a.small:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 500px) {
|
@media screen and (max-width: 500px) {
|
||||||
/*header {*/
|
|
||||||
/*min-height: 100%;*/
|
|
||||||
/*height: auto;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
header section {
|
header section {
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ import React from 'react';
|
|||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import MineSeeker from './mine-seeker/app';
|
import MineSeeker from './mine-seeker/app';
|
||||||
|
|
||||||
|
let mineWrapper = document.getElementById('mine-wrapper');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<MineSeeker env={document.getElementById('mine-wrapper').dataset.env}
|
<MineSeeker env={mineWrapper.dataset.env}
|
||||||
gameId={document.getElementById('mine-wrapper').dataset.gameId}
|
gameId={mineWrapper.dataset.gameId}
|
||||||
ssl={document.getElementById('mine-wrapper').dataset.ssl}/>,
|
ssl={mineWrapper.dataset.ssl}/>,
|
||||||
document.getElementById('mine-wrapper')
|
mineWrapper
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Grid from './grid/grid';
|
import Grid from './grid/grid';
|
||||||
import GridControl from './grid/grid-control';
|
import GridControl from './grid/grid-control';
|
||||||
|
import MineServices from '../mine-system/mine-services';
|
||||||
|
|
||||||
class MineSeeker extends React.Component {
|
class MineSeeker extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
let gameAssoc = props.gameId !== '' ? props.gameId : this.makeGameAssoc(50);
|
let services = new MineServices();
|
||||||
|
let gameAssoc = props.gameId !== '' ? props.gameId : services.randomString(50);
|
||||||
let channel = "mineseeker/channel/" + gameAssoc;
|
let channel = "mineseeker/channel/" + gameAssoc;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
@@ -19,19 +21,11 @@ class MineSeeker extends React.Component {
|
|||||||
createGrid: false,
|
createGrid: false,
|
||||||
stepCache: [],
|
stepCache: [],
|
||||||
connectionLost: false,
|
connectionLost: false,
|
||||||
end: false
|
end: false,
|
||||||
|
replay: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
makeGameAssoc(len) {
|
|
||||||
let text = "";
|
|
||||||
let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
currectGridSize() {
|
currectGridSize() {
|
||||||
let $field = $('#mine-wrapper .grid');
|
let $field = $('#mine-wrapper .grid');
|
||||||
$field.height($field.width());
|
$field.height($field.width());
|
||||||
@@ -76,8 +70,19 @@ class MineSeeker extends React.Component {
|
|||||||
* @param payload
|
* @param payload
|
||||||
*/
|
*/
|
||||||
makeGameStart(payload) {
|
makeGameStart(payload) {
|
||||||
/** every time the blue starts */
|
let steps = JSON.parse(Base64.decode(payload.steps));
|
||||||
this.refs.gridControl.refs.userControl.setState({activePlayer: 1});
|
|
||||||
|
if (steps.length) {
|
||||||
|
steps.forEach((item) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.refs.gridControl.refs.userControl.setState({bombSelected: item.wBomb});
|
||||||
|
this.makePointsCalcAndStep([item.row, item.col]);
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
/** every time the blue starts when it is not a continued game */
|
||||||
|
this.refs.gridControl.refs.userControl.setState({activePlayer: 1});
|
||||||
|
}
|
||||||
|
|
||||||
/** Set up player names w/ server data */
|
/** Set up player names w/ server data */
|
||||||
this.refs.gridControl.refs.userControl.refs.red.setState({
|
this.refs.gridControl.refs.userControl.refs.red.setState({
|
||||||
@@ -234,6 +239,20 @@ class MineSeeker extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clickRestorePlayer(data) {
|
||||||
|
this.refs.gridControl.setState({
|
||||||
|
overlay: true,
|
||||||
|
overlayTitle: "We are waiting for your opponent...",
|
||||||
|
overlaySubTitle: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
this.refs.gridControl.state.webPlayer = data[0];
|
||||||
|
|
||||||
|
if (data[1].userCnt === 2) {
|
||||||
|
this.makeGameStart(data[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wSubscribe(payload, rpcUsers = null) {
|
wSubscribe(payload, rpcUsers = null) {
|
||||||
this.state.env === 'dev' && console.info(
|
this.state.env === 'dev' && console.info(
|
||||||
(typeof payload.user !== 'undefined' ? payload.user : 'user') + " has been subscribed to the channel!"
|
(typeof payload.user !== 'undefined' ? payload.user : 'user') + " has been subscribed to the channel!"
|
||||||
@@ -241,28 +260,44 @@ class MineSeeker extends React.Component {
|
|||||||
|
|
||||||
let firstUser = !rpcUsers;
|
let firstUser = !rpcUsers;
|
||||||
|
|
||||||
this.refs.gridControl.state.webPlayer === null && this.refs.gridControl.setState({
|
/** is it a REPLAY */
|
||||||
webPlayer: payload.user === payload.users.blue ||
|
if (this.state.replay) {
|
||||||
(
|
this.refs.gridControl.setState({
|
||||||
firstUser && payload.users.blueAnon !== '' ||
|
overlay: true,
|
||||||
!firstUser && (rpcUsers.blueAnon === '' && rpcUsers.blue === '')
|
overlayTitle: "Which player has been you, in this game?",
|
||||||
)
|
overlaySubTitle: <div>
|
||||||
? 'blue' : 'red'
|
<button onClick={this.clickRestorePlayer.bind(this, ['blue', payload])}>
|
||||||
});
|
I was the BLUE, man!
|
||||||
|
</button>
|
||||||
|
<button onClick={this.clickRestorePlayer.bind(this, ['red', payload])} target="_blank">
|
||||||
|
I was RED, obviously!
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.refs.gridControl.state.webPlayer === null && this.refs.gridControl.setState({
|
||||||
|
webPlayer: payload.user === payload.users.blue ||
|
||||||
|
(
|
||||||
|
firstUser && payload.users.blueAnon !== '' ||
|
||||||
|
!firstUser && (rpcUsers.blueAnon === '' && rpcUsers.blue === '')
|
||||||
|
)
|
||||||
|
? 'blue' : 'red'
|
||||||
|
});
|
||||||
|
|
||||||
|
/** every user has been came */
|
||||||
|
if (
|
||||||
|
payload.userCnt === 2 &&
|
||||||
|
(
|
||||||
|
!this.state.connectionLost ||
|
||||||
|
this.state.connectionLost && false === this.refs.gridControl.refs.userControl.state.activePlayer && !this.state.end
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
this.makeGameStart(payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** rwd */
|
/** rwd */
|
||||||
(900 > $(document).width()) && this.currectGridSize();
|
(900 > $(document).width()) && this.currectGridSize();
|
||||||
|
|
||||||
/** every user has been came */
|
|
||||||
if (
|
|
||||||
payload.userCnt === 2 &&
|
|
||||||
(
|
|
||||||
!this.state.connectionLost ||
|
|
||||||
this.state.connectionLost && false === this.refs.gridControl.refs.userControl.state.activePlayer && !this.state.end
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
this.makeGameStart(payload);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wUnsubscribe(payload) {
|
wUnsubscribe(payload) {
|
||||||
@@ -400,8 +435,21 @@ class MineSeeker extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregistered
|
||||||
|
* http://mine.dev/re-play/I1Bx9UHZP5CWDnTZHpJqGTlkzehblfsbfz4A4xYaH9HFhBK2aN
|
||||||
|
*
|
||||||
|
* Registered
|
||||||
|
* http://mine.dev/re-play/km10oOgM7Xh37vJ8PFjaRRePrHpDkZFDJgxLhNc6hkTYyLyPKD
|
||||||
|
*/
|
||||||
|
|
||||||
/** After rendering */
|
/** After rendering */
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
/** is it a REPLAY */
|
||||||
|
window.location.pathname.indexOf('re-play') > 0
|
||||||
|
? this.setState({replay: true})
|
||||||
|
: this.setState({replay: false});
|
||||||
|
|
||||||
this.connectWithWebsocket();
|
this.connectWithWebsocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
class MineServices extends React.Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
randomString(len) {
|
||||||
|
let text = "";
|
||||||
|
let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MineServices;
|
||||||
10
src/Mine/SeekerBundle/Resources/public/js/mine-user-list.js
Normal file
10
src/Mine/SeekerBundle/Resources/public/js/mine-user-list.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import MineUserList from './mine-user-list/app';
|
||||||
|
|
||||||
|
let mineUserList = document.getElementById('mine-user-list');
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<MineUserList env={mineUserList.dataset.env}/>,
|
||||||
|
mineUserList
|
||||||
|
);
|
||||||
142
src/Mine/SeekerBundle/Resources/public/js/mine-user-list/app.js
Normal file
142
src/Mine/SeekerBundle/Resources/public/js/mine-user-list/app.js
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import MineServices from '../mine-system/mine-services';
|
||||||
|
|
||||||
|
class MineUserList extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
let services = new MineServices();
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
env: props.env,
|
||||||
|
services: services,
|
||||||
|
session: null,
|
||||||
|
users: [],
|
||||||
|
requests: new Map(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshUserList(payload) {
|
||||||
|
let webUsers = JSON.parse(Base64.decode(payload.users)),
|
||||||
|
users = new Map();
|
||||||
|
|
||||||
|
webUsers.forEach((item) => {
|
||||||
|
if (!users.has(item.email)) {
|
||||||
|
users.set(item.email, item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState({users: users});
|
||||||
|
}
|
||||||
|
|
||||||
|
connectWithWebsocket() {
|
||||||
|
let websocket = WS.connect(
|
||||||
|
this.state.env === 'dev'
|
||||||
|
? "ws://mine.dev:6450"
|
||||||
|
: (this.state.ssl === 'true' ? "wss" : "ws") + "://www.mineseeker.ninja:6450/"
|
||||||
|
);
|
||||||
|
|
||||||
|
websocket.on("socket/connect", (session) => {
|
||||||
|
this.state.env === 'dev' && console.info("Successfully connected to the Server!");
|
||||||
|
this.state.session = session;
|
||||||
|
|
||||||
|
session.subscribe(
|
||||||
|
'mineseeker/userList',
|
||||||
|
(uri, payload, log) => {
|
||||||
|
/** refresh list */
|
||||||
|
if (typeof payload.users !== 'undefined') {
|
||||||
|
this.refreshUserList(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** communication */
|
||||||
|
if (typeof payload.gameAssoc !== 'undefined') {
|
||||||
|
switch (payload.type) {
|
||||||
|
case 'REQ':
|
||||||
|
let req = this.state.requests;
|
||||||
|
|
||||||
|
if (!req.has(payload.username)) {
|
||||||
|
req.set(payload.username, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({reqests: req});
|
||||||
|
break;
|
||||||
|
case 'RESP':
|
||||||
|
window.location.href = window.location.origin + '/re-play/' + payload.gameAssoc;
|
||||||
|
break;
|
||||||
|
case 'GAME':
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
websocket.on("socket/disconnect", (error) => {
|
||||||
|
this.state.env === 'dev' && console.error("Disconnected for " + error.reason + " with code " + error.code);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.connectWithWebsocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
getProfilePicture(id) {
|
||||||
|
return <img src={"http://graph.facebook.com/" + id + "/picture?type=square&width=100&height=100"}
|
||||||
|
alt="Facebook profile"/>;
|
||||||
|
}
|
||||||
|
|
||||||
|
clickChallengeFriend(username) {
|
||||||
|
this.state.session.publish('mineseeker/userList', {
|
||||||
|
'type': 'REQ',
|
||||||
|
'username': username,
|
||||||
|
'gameAssoc': this.state.services.randomString(50)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
clickChallengeAccepted(data) {
|
||||||
|
this.state.session.publish('mineseeker/userList', {
|
||||||
|
'type': 'RESP',
|
||||||
|
'username': data[0],
|
||||||
|
'gameAssoc': data[1]
|
||||||
|
});
|
||||||
|
|
||||||
|
window.location.href = window.location.origin + '/re-play/' + data[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let users = [];
|
||||||
|
let req = [];
|
||||||
|
|
||||||
|
this.state.users.size > 0
|
||||||
|
? this.state.users.forEach((item) => {
|
||||||
|
users.push(<div key={this.state.services.randomString(50)} className="user-friend">
|
||||||
|
{this.getProfilePicture(item.id)}
|
||||||
|
<h1>{item.name}</h1>
|
||||||
|
<h2>{item.online ? 'online' : 'offline'}</h2>
|
||||||
|
<button onClick={this.clickChallengeFriend.bind(this, item.username)}>Challenge</button>
|
||||||
|
</div>)
|
||||||
|
})
|
||||||
|
: '';
|
||||||
|
|
||||||
|
this.state.requests.size > 0
|
||||||
|
? this.state.requests.forEach((item) => {
|
||||||
|
req.push(<div key={this.state.services.randomString(50)} className="user-friend">
|
||||||
|
<h1>{item.username} <strong>challenged you</strong>!</h1>
|
||||||
|
<button onClick={this.clickChallengeAccepted.bind(this, [item.username, item.gameAssoc])}>Accept</button>
|
||||||
|
</div>)
|
||||||
|
})
|
||||||
|
: '';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="user-request-container">
|
||||||
|
{req}
|
||||||
|
</div>
|
||||||
|
<div className="user-list-container">
|
||||||
|
{users}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MineUserList;
|
||||||
@@ -63,6 +63,9 @@
|
|||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="txt">
|
<div class="txt">
|
||||||
|
{% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}
|
||||||
|
<div id="mine-user-list" data-env="{{ env }}"></div>
|
||||||
|
{% endif %}
|
||||||
<div class="technologies">
|
<div class="technologies">
|
||||||
<h1>Used technologies</h1>
|
<h1>Used technologies</h1>
|
||||||
<img src="{{ asset('bundles/mineseeker/images/technologies/websocket.png') }}" alt="Used Websocket"
|
<img src="{{ asset('bundles/mineseeker/images/technologies/websocket.png') }}" alt="Used Websocket"
|
||||||
@@ -107,11 +110,31 @@
|
|||||||
{% block javascripts %}
|
{% block javascripts %}
|
||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/JQuery-Snowfall/1.7.4/snowfall.jquery.min.js"
|
{% if is_granted("IS_AUTHENTICATED_REMEMBERED") and app.user.facebookAccessToken is defined %}
|
||||||
type="text/javascript"></script>
|
{% if env == 'dev' %}
|
||||||
<script type="text/javascript">
|
{% javascripts filter='?uglifyjs2'
|
||||||
$(function () {
|
'@GosWebSocketBundle/Resources/public/js/vendor/autobahn.min.js'
|
||||||
$(document).snowfall({deviceorientation: true, round: true, minSize: 5, maxSize: 8});
|
'@GosWebSocketBundle/Resources/public/js/gos_web_socket_client.js'
|
||||||
});
|
'@MineSeekerBundle/Resources/public/js/node/js-base64/base64.min.js'
|
||||||
</script>
|
'@MineSeekerBundle/Resources/public/js/build/mine-user-list/index.js' %}
|
||||||
|
<script type="text/javascript" src="{{ asset_url }}"></script>
|
||||||
|
{% endjavascripts %}
|
||||||
|
{% else %}
|
||||||
|
{% javascripts filter='?uglifyjs2'
|
||||||
|
'@GosWebSocketBundle/Resources/public/js/vendor/autobahn.min.js'
|
||||||
|
'@GosWebSocketBundle/Resources/public/js/gos_web_socket_client.js'
|
||||||
|
'@MineSeekerBundle/Resources/public/js/node/js-base64/base64.min.js'
|
||||||
|
'@MineSeekerBundle/Resources/public/js/build/mine-user-list/index.min.js' %}
|
||||||
|
<script type="text/javascript" src="{{ asset_url }}"></script>
|
||||||
|
{% endjavascripts %}
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/JQuery-Snowfall/1.7.4/snowfall.jquery.min.js"
|
||||||
|
type="text/javascript"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function () {
|
||||||
|
$(document).snowfall({deviceorientation: true, round: true, minSize: 5, maxSize: 8});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -20,7 +20,8 @@
|
|||||||
<meta property="og:type" content="website"/>
|
<meta property="og:type" content="website"/>
|
||||||
<meta property="og:title" content="Your friend challenges YOU!"/>
|
<meta property="og:title" content="Your friend challenges YOU!"/>
|
||||||
<meta property="og:description" content="Do you accept the challenge?"/>
|
<meta property="og:description" content="Do you accept the challenge?"/>
|
||||||
<meta property="og:image" content="{{ app.request.getSchemeAndHttpHost() }}{{ asset('bundles/mineseeker/images/mine-1600x627.png') }}"/>
|
<meta property="og:image"
|
||||||
|
content="{{ app.request.getSchemeAndHttpHost() }}{{ asset('bundles/mineseeker/images/mine-1600x627.png') }}"/>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block stylesheets %}
|
{% block stylesheets %}
|
||||||
@@ -46,7 +47,7 @@
|
|||||||
'@GosWebSocketBundle/Resources/public/js/gos_web_socket_client.js'
|
'@GosWebSocketBundle/Resources/public/js/gos_web_socket_client.js'
|
||||||
'@MineSeekerBundle/Resources/public/js/node/howler/dist/howler.min.js'
|
'@MineSeekerBundle/Resources/public/js/node/howler/dist/howler.min.js'
|
||||||
'@MineSeekerBundle/Resources/public/js/node/js-base64/base64.min.js'
|
'@MineSeekerBundle/Resources/public/js/node/js-base64/base64.min.js'
|
||||||
'@MineSeekerBundle/Resources/public/js/index.js' %}
|
'@MineSeekerBundle/Resources/public/js/build/mine-seeker/index.js' %}
|
||||||
<script type="text/javascript" src="{{ asset_url }}"></script>
|
<script type="text/javascript" src="{{ asset_url }}"></script>
|
||||||
{% endjavascripts %}
|
{% endjavascripts %}
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -55,7 +56,7 @@
|
|||||||
'@GosWebSocketBundle/Resources/public/js/gos_web_socket_client.js'
|
'@GosWebSocketBundle/Resources/public/js/gos_web_socket_client.js'
|
||||||
'@MineSeekerBundle/Resources/public/js/node/howler/dist/howler.min.js'
|
'@MineSeekerBundle/Resources/public/js/node/howler/dist/howler.min.js'
|
||||||
'@MineSeekerBundle/Resources/public/js/node/js-base64/base64.min.js'
|
'@MineSeekerBundle/Resources/public/js/node/js-base64/base64.min.js'
|
||||||
'@MineSeekerBundle/Resources/public/js/index.min.js' %}
|
'@MineSeekerBundle/Resources/public/js/build/mine-seeker/index.min.js' %}
|
||||||
<script type="text/javascript" src="{{ asset_url }}"></script>
|
<script type="text/javascript" src="{{ asset_url }}"></script>
|
||||||
{% endjavascripts %}
|
{% endjavascripts %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1,14 +1,22 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.fbAsyncInit = function () {
|
$(function () {
|
||||||
FB.init({
|
window.fbAsyncInit = function () {
|
||||||
appId: '{{ facebook_api }}',
|
FB.init({
|
||||||
xfbml: true,
|
appId: '{{ facebook_api }}',
|
||||||
cookie: true,
|
xfbml: true,
|
||||||
status: true,
|
cookie: true,
|
||||||
oauth: true,
|
status: true,
|
||||||
version: '{{ facebook_api_version }}'
|
version: '{{ facebook_api_version }}',
|
||||||
});
|
|
||||||
};
|
});
|
||||||
|
|
||||||
|
/** trigger jQuery when Facebook SKD loads */
|
||||||
|
$(document).trigger('fb-load');
|
||||||
|
// $(document).bind('fb-load', function () {
|
||||||
|
// TODO
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
(function (d, s, id) {
|
(function (d, s, id) {
|
||||||
var js, fjs = d.getElementsByTagName(s)[0];
|
var js, fjs = d.getElementsByTagName(s)[0];
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ class MineseekerTopic implements TopicInterface
|
|||||||
'channel' => $topic->getId(),
|
'channel' => $topic->getId(),
|
||||||
'user' => $userName,
|
'user' => $userName,
|
||||||
'userCnt' => $topic->count(),
|
'userCnt' => $topic->count(),
|
||||||
'users' => $users
|
'users' => $users,
|
||||||
|
'steps' => $this->getSteps($topic),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,6 +181,28 @@ class MineseekerTopic implements TopicInterface
|
|||||||
$this->em->flush();
|
$this->em->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getSteps($topic)
|
||||||
|
{
|
||||||
|
$this->reConnect();
|
||||||
|
$gameAssoc = explode('/', $topic->getId())[2];
|
||||||
|
|
||||||
|
$playedGame = $this->em
|
||||||
|
->getRepository('MineSeekerBundle:PlayedGame')
|
||||||
|
->findOneByGameAssoc($gameAssoc);
|
||||||
|
|
||||||
|
$steps = array();
|
||||||
|
|
||||||
|
foreach ($playedGame->getStep()->toArray() as $item) {
|
||||||
|
$steps[] = array(
|
||||||
|
'row' => $item->getRow(),
|
||||||
|
'col' => $item->getCol(),
|
||||||
|
'wBomb' => $item->getWBomb(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base64_encode(json_encode($steps));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Control all users in a channel
|
* Control all users in a channel
|
||||||
*
|
*
|
||||||
@@ -300,7 +323,7 @@ class MineseekerTopic implements TopicInterface
|
|||||||
$connection->close();
|
$connection->close();
|
||||||
$connection->connect();
|
$connection->connect();
|
||||||
}
|
}
|
||||||
} catch(PDOException $ex) {
|
} catch (PDOException $ex) {
|
||||||
throw PDOException::class;
|
throw PDOException::class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
192
src/Mine/SeekerBundle/Topic/UserListTopic.php
Normal file
192
src/Mine/SeekerBundle/Topic/UserListTopic.php
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Mine\SeekerBundle\Topic;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Driver\PDOException;
|
||||||
|
use Doctrine\ORM\EntityManager;
|
||||||
|
use Gos\Bundle\WebSocketBundle\Client\ClientManipulatorInterface;
|
||||||
|
use Gos\Bundle\WebSocketBundle\Topic\TopicInterface;
|
||||||
|
use Gos\Bundle\WebSocketBundle\Router\WampRequest;
|
||||||
|
use Ratchet\ConnectionInterface;
|
||||||
|
use Ratchet\Wamp\Topic;
|
||||||
|
use Symfony\Component\HttpFoundation\RequestStack;
|
||||||
|
|
||||||
|
class UserListTopic implements TopicInterface
|
||||||
|
{
|
||||||
|
/** @var ClientManipulatorInterface */
|
||||||
|
protected $clientManipulator;
|
||||||
|
|
||||||
|
/** @var EntityManager */
|
||||||
|
protected $em;
|
||||||
|
|
||||||
|
/** @var RequestStack */
|
||||||
|
protected $requestStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MineseekerTopic constructor.
|
||||||
|
*
|
||||||
|
* @param $clientManipulator ClientManipulatorInterface
|
||||||
|
* @param EntityManager $entityManager
|
||||||
|
* @param RequestStack $requestStack
|
||||||
|
*/
|
||||||
|
public function __construct(ClientManipulatorInterface $clientManipulator, EntityManager $entityManager, RequestStack $requestStack)
|
||||||
|
{
|
||||||
|
$this->clientManipulator = $clientManipulator;
|
||||||
|
$this->em = $entityManager;
|
||||||
|
$this->requestStack = $requestStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will receive any Subscription requests for this topic.
|
||||||
|
*
|
||||||
|
* @param ConnectionInterface $connection
|
||||||
|
* @param Topic $topic
|
||||||
|
* @param WampRequest $request
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function onSubscribe(ConnectionInterface $connection, Topic $topic, WampRequest $request)
|
||||||
|
{
|
||||||
|
/** this will broadcast the message to ALL subscribers of this topic. */
|
||||||
|
$user = $this->clientManipulator->getClient($connection);
|
||||||
|
$userName = is_string($user) ? $user : $user->getUsername();
|
||||||
|
|
||||||
|
/** @var array Find all users online and offline $users */
|
||||||
|
$users = $this->findAllUsers($topic);
|
||||||
|
|
||||||
|
$topic->broadcast([
|
||||||
|
'userTopicId' => $connection->resourceId,
|
||||||
|
'channel' => $topic->getId(),
|
||||||
|
'user' => $userName,
|
||||||
|
'userCnt' => $topic->count(),
|
||||||
|
'users' => base64_encode(json_encode($users))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will receive any UnSubscription requests for this topic.
|
||||||
|
*
|
||||||
|
* @param ConnectionInterface $connection
|
||||||
|
* @param Topic $topic
|
||||||
|
* @param WampRequest $request
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function onUnSubscribe(ConnectionInterface $connection, Topic $topic, WampRequest $request)
|
||||||
|
{
|
||||||
|
/** this will broadcast the message to ALL subscribers of this topic. */
|
||||||
|
$topic->broadcast(['msg' => $connection->resourceId . " has left " . $topic->getId()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will receive any Publish requests for this topic.
|
||||||
|
*
|
||||||
|
* @param ConnectionInterface $connection
|
||||||
|
* @param Topic $topic
|
||||||
|
* @param WampRequest $request
|
||||||
|
* @param $event
|
||||||
|
* @param array $exclude
|
||||||
|
* @param array $eligible
|
||||||
|
* @return mixed|void
|
||||||
|
* @internal param Topic $Topic
|
||||||
|
* @internal param array $eligibles
|
||||||
|
*/
|
||||||
|
public function onPublish(ConnectionInterface $connection, Topic $topic, WampRequest $request, $event, array $exclude, array $eligible)
|
||||||
|
{
|
||||||
|
$user = $this->clientManipulator->getClient($connection);
|
||||||
|
$userName = is_string($user) ? $user : $user->getUsername();
|
||||||
|
$reqUser = $this->clientManipulator->findByUsername($topic, $event['username']);
|
||||||
|
|
||||||
|
/** user is still online */
|
||||||
|
if (false !== $reqUser) {
|
||||||
|
$topic->broadcast(
|
||||||
|
array(
|
||||||
|
'type' => $event['type'],
|
||||||
|
'username' => $userName,
|
||||||
|
'gameAssoc' => $event['gameAssoc'],
|
||||||
|
),
|
||||||
|
array(),
|
||||||
|
array(
|
||||||
|
$reqUser['connection']->WAMP->sessionId
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like RPC is will use to prefix the channel
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'userlist.topic';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all users online/offline
|
||||||
|
*
|
||||||
|
* @param $topic
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function findAllUsers($topic)
|
||||||
|
{
|
||||||
|
$usersOnline = array();
|
||||||
|
$usersOffline = array();
|
||||||
|
|
||||||
|
$this->reConnect();
|
||||||
|
$userRepo = $this->em->getRepository('JotunheimrUserBundle:User');
|
||||||
|
|
||||||
|
$usersMax = 10;
|
||||||
|
foreach ($this->clientManipulator->getAll($topic) as $item) {
|
||||||
|
if (!$usersMax) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $userRepo->findOneByEmail(
|
||||||
|
$item['client']->getEmail()
|
||||||
|
);
|
||||||
|
|
||||||
|
$usersOnline[] = array(
|
||||||
|
'id' => $user->getFacebookId(),
|
||||||
|
'name' => $user->getRealName(),
|
||||||
|
'email' => $user->getEmail(),
|
||||||
|
'username' => $user->getUsername(),
|
||||||
|
'online' => true
|
||||||
|
);
|
||||||
|
|
||||||
|
$usersMax--;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($userRepo->findBy(array(), array(), 20) as $item) {
|
||||||
|
$exists = is_numeric(array_search($item->getEmail(), array_column($usersOnline, 'email')));
|
||||||
|
|
||||||
|
if (!$exists) {
|
||||||
|
$usersOffline[] = array(
|
||||||
|
'id' => $item->getFacebookId(),
|
||||||
|
'name' => $item->getRealName(),
|
||||||
|
'email' => $item->getEmail(),
|
||||||
|
'username' => $item->getUsername(),
|
||||||
|
'online' => false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_merge($usersOnline, $usersOffline);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle prod MySQL timeout
|
||||||
|
*/
|
||||||
|
private function reConnect()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$connection = $this->em->getConnection();
|
||||||
|
|
||||||
|
if (false === $connection->ping()) {
|
||||||
|
$connection->close();
|
||||||
|
$connection->connect();
|
||||||
|
}
|
||||||
|
} catch (PDOException $ex) {
|
||||||
|
throw PDOException::class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var webpack = require("webpack");
|
let webpack = require("webpack");
|
||||||
process.env.NODE_ENV = 'production';
|
process.env.NODE_ENV = 'production';
|
||||||
var isProd = (process.env.NODE_ENV === 'production');
|
let isProd = (process.env.NODE_ENV === 'production');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conditionally return a list of plugins to use based on the current environment.
|
* Conditionally return a list of plugins to use based on the current environment.
|
||||||
@@ -10,7 +10,7 @@ var isProd = (process.env.NODE_ENV === 'production');
|
|||||||
* @returns {Array}
|
* @returns {Array}
|
||||||
*/
|
*/
|
||||||
function getPlugins() {
|
function getPlugins() {
|
||||||
var plugins = [];
|
let plugins = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Always expose NODE_ENV to webpack, you can now use `process.env.NODE_ENV`
|
* Always expose NODE_ENV to webpack, you can now use `process.env.NODE_ENV`
|
||||||
@@ -33,10 +33,14 @@ function getPlugins() {
|
|||||||
return plugins;
|
return plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = module.exports = {
|
const config = {
|
||||||
|
module: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mineSeekerConfig = Object.assign({}, config, {
|
||||||
entry: './web/bundles/mineseeker/js/mine-seeker.js',
|
entry: './web/bundles/mineseeker/js/mine-seeker.js',
|
||||||
output: {
|
output: {
|
||||||
path: './src/Mine/SeekerBundle/Resources/public/js',
|
path: './src/Mine/SeekerBundle/Resources/public/js/build/mine-seeker/',
|
||||||
filename: 'index.min.js'
|
filename: 'index.min.js'
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
@@ -50,8 +54,30 @@ const config = module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
plugins: getPlugins()
|
});
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = config;
|
let mineUserListConfig = Object.assign({}, config, {
|
||||||
|
entry: './web/bundles/mineseeker/js/mine-user-list.js',
|
||||||
|
output: {
|
||||||
|
path: './src/Mine/SeekerBundle/Resources/public/js/build/mine-user-list/',
|
||||||
|
filename: 'index.min.js'
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
loaders: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
loader: 'babel',
|
||||||
|
query: {
|
||||||
|
presets: ['es2015', 'react']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
mineSeekerConfig,
|
||||||
|
mineUserListConfig,
|
||||||
|
];
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const config = module.exports = {
|
const config = {
|
||||||
|
module: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mineSeekerConfig = Object.assign({}, config, {
|
||||||
entry: './web/bundles/mineseeker/js/mine-seeker.js',
|
entry: './web/bundles/mineseeker/js/mine-seeker.js',
|
||||||
output: {
|
output: {
|
||||||
path: './src/Mine/SeekerBundle/Resources/public/js',
|
path: './src/Mine/SeekerBundle/Resources/public/js/build/mine-seeker/',
|
||||||
filename: 'index.js'
|
filename: 'index.js'
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
@@ -18,6 +22,29 @@ const config = module.exports = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
module.exports = config;
|
let mineUserListConfig = Object.assign({}, config, {
|
||||||
|
entry: './web/bundles/mineseeker/js/mine-user-list.js',
|
||||||
|
output: {
|
||||||
|
path: './src/Mine/SeekerBundle/Resources/public/js/build/mine-user-list/',
|
||||||
|
filename: 'index.js'
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
loaders: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
loader: 'babel',
|
||||||
|
query: {
|
||||||
|
presets: ['es2015', 'react']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
mineSeekerConfig,
|
||||||
|
mineUserListConfig,
|
||||||
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user