diff --git a/src/Jotunheimr/UserBundle/Resources/public/css/layout.css b/src/Jotunheimr/UserBundle/Resources/public/css/layout.css index 819feb6..633ae54 100644 --- a/src/Jotunheimr/UserBundle/Resources/public/css/layout.css +++ b/src/Jotunheimr/UserBundle/Resources/public/css/layout.css @@ -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; diff --git a/src/Mine/SeekerBundle/Resources/public/css/style.homepage.css b/src/Mine/SeekerBundle/Resources/public/css/style.homepage.css index 7d3003a..b550122 100644 --- a/src/Mine/SeekerBundle/Resources/public/css/style.homepage.css +++ b/src/Mine/SeekerBundle/Resources/public/css/style.homepage.css @@ -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; diff --git a/src/Mine/SeekerBundle/Resources/public/js/mine-user-list.js b/src/Mine/SeekerBundle/Resources/public/js/mine-user-list.js index a843c84..ef5d3cc 100644 --- a/src/Mine/SeekerBundle/Resources/public/js/mine-user-list.js +++ b/src/Mine/SeekerBundle/Resources/public/js/mine-user-list.js @@ -5,6 +5,7 @@ import MineUserList from './mine-user-list/app'; let mineUserList = document.getElementById('mine-user-list'); ReactDOM.render( - , + , mineUserList ); diff --git a/src/Mine/SeekerBundle/Resources/public/js/mine-user-list/app.js b/src/Mine/SeekerBundle/Resources/public/js/mine-user-list/app.js index ef4aa2e..6fb238f 100644 --- a/src/Mine/SeekerBundle/Resources/public/js/mine-user-list/app.js +++ b/src/Mine/SeekerBundle/Resources/public/js/mine-user-list/app.js @@ -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 ? - 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(
- {this.getProfilePicture(item.id)} +
+ {this.getProfilePicture(item.id)} +

{item.name}

-

{item.online ? 'online' : 'offline'}

- +
) }) : ''; @@ -122,8 +149,12 @@ class MineUserList extends React.Component { this.state.requests.size > 0 ? this.state.requests.forEach((item) => { req.push(
-

{item.username} challenged you!

-
) }) @@ -134,8 +165,18 @@ class MineUserList extends React.Component {
{req}
+
+
+ + +
+
- {users} + {users.length ? users : 'There is no users w/ this search results..'}
); diff --git a/src/Mine/SeekerBundle/Resources/views/Game/index.html.twig b/src/Mine/SeekerBundle/Resources/views/Game/index.html.twig index c8747c7..cf6ef4e 100644 --- a/src/Mine/SeekerBundle/Resources/views/Game/index.html.twig +++ b/src/Mine/SeekerBundle/Resources/views/Game/index.html.twig @@ -63,8 +63,12 @@ {% block body %}
+

Users

{% if is_granted("IS_AUTHENTICATED_REMEMBERED") %} -
+
+
{% endif %}

Used technologies

@@ -96,6 +100,7 @@ {% block stylesheets %} {{ parent() }} + diff --git a/src/Mine/SeekerBundle/Topic/UserListTopic.php b/src/Mine/SeekerBundle/Topic/UserListTopic.php index cb80851..31c2506 100644 --- a/src/Mine/SeekerBundle/Topic/UserListTopic.php +++ b/src/Mine/SeekerBundle/Topic/UserListTopic.php @@ -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 *