add search box to user list
This commit is contained in:
@@ -251,6 +251,11 @@ main div.txt {
|
||||
margin: 50px auto 0 auto;
|
||||
}
|
||||
|
||||
main .txt h1 {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
main div.txt h2 {
|
||||
margin: 0 0 50px 0;
|
||||
}
|
||||
@@ -276,10 +281,6 @@ main .technologies img {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
main .technologies h1 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
footer {
|
||||
background: #414040;
|
||||
width: 100%;
|
||||
@@ -320,7 +321,7 @@ footer nav ul li a:hover {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1100px) {
|
||||
@media screen and (max-width: 1200px) {
|
||||
header section #id_welcome {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
@@ -143,14 +143,22 @@ header section div.buttons > a.small:hover {
|
||||
|
||||
main .user-list-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
main .user-list-container .user-friend {
|
||||
background: #ccc;
|
||||
width: 15%;
|
||||
min-width: 145px;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
margin: 5px;
|
||||
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
main .user-list-container .user-friend h1 {
|
||||
@@ -171,13 +179,12 @@ main .user-list-container .user-friend button {
|
||||
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;
|
||||
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
main .user-list-container .user-friend button:hover {
|
||||
@@ -185,16 +192,80 @@ main .user-list-container .user-friend button:hover {
|
||||
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;
|
||||
}
|
||||
|
||||
main .user-list-container .user-friend button.button-offline {
|
||||
background: #a1a1a1;
|
||||
border: 1px solid #929292;
|
||||
|
||||
@media screen and (max-width: 1100px) {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
main .user-list-container .user-friend button.button-offline:hover {
|
||||
background: #a1a1a1;
|
||||
border: 1px solid #929292;
|
||||
}
|
||||
|
||||
main .user-list-filter form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
main .user-list-filter input {
|
||||
border: 1px solid #ccc;
|
||||
border-right: 0;
|
||||
min-width: 300px;
|
||||
padding: 10px;
|
||||
|
||||
-webkit-border-top-left-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
-webkit-border-bottom-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
|
||||
main .user-list-filter button {
|
||||
background: #ccc;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border: 0;
|
||||
color: #fff;
|
||||
|
||||
-webkit-border-top-right-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
-webkit-border-bottom-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
|
||||
main .user-request-container .user-friend {
|
||||
background: #ff0000;
|
||||
width: 150px;
|
||||
color: #403f3f;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
main .user-request-container h1 {
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
main .user-request-container button {
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
color: #ff0000;
|
||||
border: 0;
|
||||
padding: 5px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
header section {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
@@ -5,6 +5,7 @@ import MineUserList from './mine-user-list/app';
|
||||
let mineUserList = document.getElementById('mine-user-list');
|
||||
|
||||
ReactDOM.render(
|
||||
<MineUserList env={mineUserList.dataset.env}/>,
|
||||
<MineUserList env={mineUserList.dataset.env}
|
||||
webPlayerName={mineUserList.dataset.webPlayerName}/>,
|
||||
mineUserList
|
||||
);
|
||||
|
||||
@@ -9,10 +9,12 @@ class MineUserList extends React.Component {
|
||||
|
||||
this.state = {
|
||||
env: props.env,
|
||||
webPlayerName: props.webPlayerName,
|
||||
services: services,
|
||||
session: null,
|
||||
users: [],
|
||||
requests: new Map(),
|
||||
search: '',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,7 +23,7 @@ class MineUserList extends React.Component {
|
||||
users = new Map();
|
||||
|
||||
webUsers.forEach((item) => {
|
||||
if (!users.has(item.email)) {
|
||||
if (!users.has(item.email) && item.username !== this.state.webPlayerName) {
|
||||
users.set(item.email, item);
|
||||
}
|
||||
});
|
||||
@@ -52,10 +54,14 @@ class MineUserList extends React.Component {
|
||||
if (typeof payload.gameAssoc !== 'undefined') {
|
||||
switch (payload.type) {
|
||||
case 'REQ':
|
||||
let req = this.state.requests;
|
||||
let req = this.state.requests,
|
||||
user = JSON.parse(Base64.decode(payload.user));
|
||||
|
||||
if (!req.has(payload.username)) {
|
||||
req.set(payload.username, payload);
|
||||
if (!req.has(user.username)) {
|
||||
req.set(user.username, {
|
||||
'gameAssoc': payload.gameAssoc,
|
||||
'user': user,
|
||||
});
|
||||
}
|
||||
|
||||
this.setState({reqests: req});
|
||||
@@ -63,7 +69,7 @@ class MineUserList extends React.Component {
|
||||
case 'RESP':
|
||||
window.location.href = window.location.origin + '/re-play/' + payload.gameAssoc;
|
||||
break;
|
||||
case 'GAME':
|
||||
case 'SEARCH':
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -81,27 +87,44 @@ class MineUserList extends React.Component {
|
||||
|
||||
getProfilePicture(id) {
|
||||
return id !== null ?
|
||||
<img src={"http://graph.facebook.com/" + id + "/picture?type=square&width=100&height=100"}
|
||||
<img src={"http://graph.facebook.com/" + id + "/picture?type=square&width=130&height=130"}
|
||||
alt="Facebook profile"/> :
|
||||
"";
|
||||
}
|
||||
|
||||
clickChallengeFriend(username) {
|
||||
this.state.session.publish('mineseeker/userList', {
|
||||
'type': 'REQ',
|
||||
'username': username,
|
||||
'gameAssoc': this.state.services.randomString(50)
|
||||
});
|
||||
clickChallengeFriend(isOnline, username) {
|
||||
if (isOnline) {
|
||||
this.state.session.publish('mineseeker/userList', {
|
||||
'type': 'REQ',
|
||||
'username': username,
|
||||
'gameAssoc': this.state.services.randomString(50)
|
||||
});
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
clickChallengeAccepted(data) {
|
||||
clickChallengeAccepted(username, gameAssoc) {
|
||||
this.state.session.publish('mineseeker/userList', {
|
||||
'type': 'RESP',
|
||||
'username': data[0],
|
||||
'gameAssoc': data[1]
|
||||
'username': username,
|
||||
'gameAssoc': gameAssoc
|
||||
});
|
||||
|
||||
window.location.href = window.location.origin + '/re-play/' + data[1];
|
||||
window.location.href = window.location.origin + '/re-play/' + gameAssoc;
|
||||
}
|
||||
|
||||
onChangeSearch(event) {
|
||||
this.setState({search: event.target.value});
|
||||
}
|
||||
|
||||
handleSubmit(event) {
|
||||
this.state.session.publish('mineseeker/userList', {
|
||||
'type': 'SEARCH',
|
||||
'username': this.state.search
|
||||
});
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -111,10 +134,14 @@ class MineUserList extends React.Component {
|
||||
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)}
|
||||
<div className="img">
|
||||
{this.getProfilePicture(item.id)}
|
||||
</div>
|
||||
<h1>{item.name}</h1>
|
||||
<h2>{item.online ? 'online' : 'offline'}</h2>
|
||||
<button onClick={this.clickChallengeFriend.bind(this, item.username)}>Challenge</button>
|
||||
<button className={item.online ? 'button-online' : 'button-offline'}
|
||||
onClick={this.clickChallengeFriend.bind(this, item.online, item.username)}>
|
||||
{item.online ? 'Challenge' : 'Offline'}
|
||||
</button>
|
||||
</div>)
|
||||
})
|
||||
: '';
|
||||
@@ -122,8 +149,12 @@ class MineUserList extends React.Component {
|
||||
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
|
||||
<div className="img">
|
||||
{this.getProfilePicture(item.user.id)}
|
||||
</div>
|
||||
<h1>{item.user.name} <br/><strong>challenged you</strong>!</h1>
|
||||
<button onClick={this.clickChallengeAccepted.bind(this, item.user.username, item.gameAssoc)}>
|
||||
Accept
|
||||
</button>
|
||||
</div>)
|
||||
})
|
||||
@@ -134,8 +165,18 @@ class MineUserList extends React.Component {
|
||||
<div className="user-request-container">
|
||||
{req}
|
||||
</div>
|
||||
<div className="user-list-filter">
|
||||
<form onSubmit={this.handleSubmit.bind(this)}>
|
||||
<input type="text"
|
||||
onChange={this.onChangeSearch.bind(this)}
|
||||
value={this.state.search}
|
||||
autoFocus="autoFocus"
|
||||
placeholder="Search users..."/>
|
||||
<button type="submit"><i className="fa fa-search"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
<div className="user-list-container">
|
||||
{users}
|
||||
{users.length ? users : 'There is no users w/ this search results..'}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -63,8 +63,12 @@
|
||||
|
||||
{% block body %}
|
||||
<div class="txt">
|
||||
<h1>Users</h1>
|
||||
{% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}
|
||||
<div id="mine-user-list" data-env="{{ env }}"></div>
|
||||
<div id="mine-user-list"
|
||||
data-env="{{ env }}"
|
||||
data-web-player-name="{{ app.user.username is defined ? app.user.username : '' }}">
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="technologies">
|
||||
<h1>Used technologies</h1>
|
||||
@@ -96,6 +100,7 @@
|
||||
{% block stylesheets %}
|
||||
{{ parent() }}
|
||||
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Rajdhani:300,400,500,600,700&subset=latin-ext"
|
||||
rel="stylesheet">
|
||||
|
||||
|
||||
@@ -93,21 +93,43 @@ class UserListTopic implements TopicInterface
|
||||
{
|
||||
$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
|
||||
)
|
||||
);
|
||||
if ($event['type'] === 'REQ' || $event['type'] === 'RESP') {
|
||||
$reqUser = $this->clientManipulator->findByUsername($topic, $event['username']);
|
||||
|
||||
/** user is still online */
|
||||
if (false !== $reqUser) {
|
||||
$topic->broadcast(
|
||||
array(
|
||||
'type' => $event['type'],
|
||||
'user' => $this->findUser($topic, $userName),
|
||||
'gameAssoc' => $event['gameAssoc'],
|
||||
),
|
||||
array(),
|
||||
array(
|
||||
$reqUser['connection']->WAMP->sessionId
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($event['type'] === 'SEARCH') {
|
||||
$reqUser = $this->clientManipulator->findByUsername($topic, $userName);
|
||||
|
||||
/** user is still online */
|
||||
if (false !== $reqUser) {
|
||||
$topic->broadcast(
|
||||
array(
|
||||
'type' => $event['type'],
|
||||
'users' => $this->findUsersForSearch($topic, $event['username']),
|
||||
'gameAssoc' => true,
|
||||
),
|
||||
array(),
|
||||
array(
|
||||
$reqUser['connection']->WAMP->sessionId,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +143,62 @@ class UserListTopic implements TopicInterface
|
||||
return 'userlist.topic';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $topic
|
||||
* @param $username
|
||||
* @return array
|
||||
*/
|
||||
private function findUser($topic, $username)
|
||||
{
|
||||
$this->reConnect();
|
||||
$userRepo = $this->em->getRepository('JotunheimrUserBundle:User');
|
||||
$user = $userRepo->findOneByUsername($username);
|
||||
$currentOnline = $this->clientManipulator->findByUsername($topic, $username)['client'];
|
||||
|
||||
return base64_encode(json_encode(array(
|
||||
'id' => $user->getFacebookId(),
|
||||
'name' => $user->getRealName(),
|
||||
'email' => $user->getEmail(),
|
||||
'username' => $user->getUsername(),
|
||||
'online' => $currentOnline !== null
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $topic
|
||||
* @param $username
|
||||
* @return array
|
||||
*/
|
||||
private function findUsersForSearch($topic, $username)
|
||||
{
|
||||
$this->reConnect();
|
||||
$userRepo = $this->em->getRepository('JotunheimrUserBundle:User');
|
||||
$users = $userRepo
|
||||
->createQueryBuilder('o')
|
||||
->where('o.username LIKE :username')
|
||||
->andWhere('o.realName LIKE :realname')
|
||||
->setParameter('username', "%{$username}%")
|
||||
->setParameter('realname', "%{$username}%")
|
||||
->setMaxResults(10)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
$usersAvailable = array();
|
||||
|
||||
foreach ($users as $item) {
|
||||
$usersAvailable[] = array(
|
||||
'id' => $item->getFacebookId(),
|
||||
'name' => $item->getRealName(),
|
||||
'email' => $item->getEmail(),
|
||||
'username' => $item->getUsername(),
|
||||
'online' => $this->clientManipulator->findByUsername($topic, $item->getUsername())['client'] !== null
|
||||
);
|
||||
}
|
||||
|
||||
return base64_encode(json_encode(
|
||||
$usersAvailable
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all users online/offline
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user