Private
Public Access
1
0

add search box to user list

This commit is contained in:
2017-01-26 14:18:34 +01:00
parent fe5378f69b
commit a8ac13850b
6 changed files with 247 additions and 50 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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
);

View File

@@ -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>
);

View File

@@ -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&amp;subset=latin-ext"
rel="stylesheet">

View File

@@ -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
*