Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
danon committed Oct 3, 2024
1 parent 43c4a3c commit c6946ea
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 105 deletions.
4 changes: 2 additions & 2 deletions app/Http/Controllers/Forum/BaseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ private function globalViewers(): View
{
/** @var Renderer $renderer */
$renderer = app(Renderer::class);
return $renderer->render('Online w serwisie', requestUri:null);
return $renderer->render('/', local:false);
}

private function localViewers(): View
{
/** @var Renderer $renderer */
$renderer = app(Renderer::class);
return $renderer->render('Aktualnie na tej stronie', requestUri:$this->request->getRequestUri());
return $renderer->render($this->request->getRequestUri(), local:true);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/HomeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private function globalViewers(): View
{
/** @var Renderer $renderer */
$renderer = app(Renderer::class);
return $renderer->render('Użytkownicy online', requestUri:null);
return $renderer->render('/', local:false);
}

private function flags(): array
Expand Down
110 changes: 25 additions & 85 deletions app/Services/Session/Renderer.php
Original file line number Diff line number Diff line change
@@ -1,110 +1,50 @@
<?php
namespace Coyote\Services\Session;

use Coyote\Session;
use Illuminate\Database;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Query\Expression;
use Coyote\Domain\Online\FakeSessionRepository;
use Coyote\Domain\Online\ViewersStore;
use Illuminate\Http\Request;
use Illuminate\Support;
use Illuminate\View\View;

class Renderer
{
const USER = 'Użytkownik';

public function __construct(
private Database\Connection $db,
private Registered $registered,
private Request $request)
private FakeSessionRepository $session,
private ViewersStore $store,
private Request $request,
)
{
}

public function render(string $title, ?string $requestUri): View
public function render(string $requestUri, bool $local): View
{
$collection = $this->data($requestUri);

$total = $collection->sum('count');
$guests = $collection->where('user_id', null)->sum('count');
$registered = $total - $guests;
$robots = $collection->filter(fn($item) => $item->robot)->sum('count');

$guests -= $robots;
$total -= $robots;

$collection = $this->map($collection);

if ($this->request->user()) {
if (!$collection->contains('user_id', $this->request->user()->id)) {
$collection->push(new Session(['user_id' => $this->request->user()->id, 'path' => $requestUri]));
$total++;
$registered++;
}
} else if ($collection->count() === 0) {
// we keep session in redis but also - list of online users - in postgres.
// we refresh table every 1 minute, so info about user's current page might be sometimes outdated.
$total++;
$guests++;
}

$collection = $this->unique($collection);
$collection = $this->registered->setup($collection);

$groups = [self::USER => []];
foreach ($collection->groupBy('group') as $name => $users) {
if ($name === '') {
$name = self::USER;
} else if (!isset($groups[$name])) {
$groups[$name] = [];
}
foreach ($users as $user) {
if ($user['user_id'] !== null) {
$groups[$name][] = $this->makeProfileLink($user['user_id'], $user['name']);
}
}
$sessions = $this->session->sessionsIn($requestUri);
if ($this->isUserLogged()) {
$sessions = $sessions->coalesceUser($this->loggedUserId());
} else {
$sessions = $sessions->coalesceGuest();
}
$viewers = $this->store->viewers($sessions);

unset($groups[self::USER]);
ksort($groups);

$viewersCount = $viewers->guestsCount + \count($viewers->users);
return view('components.viewers', [
'isLocalViewers' => $requestUri !== null,
'title' => $title,
'groups' => $requestUri === null ? $groups : [],
'total' => $total,
'guests' => $guests,
'registered' => $registered,
'local' => $local,
'guestsCount' => $viewers->guestsCount,
'usersCount' => \count($viewers->users),
'title' => $local
? 'Aktualnie na tej stronie'
: "$viewersCount użytkowników online",
'users' => $viewers->users,
]);
}

private function data(?string $requestUri): Support\Collection
{
return $this
->db
->table('sessions')
->when($requestUri !== null, fn(Builder $builder) => $builder
->where('path', 'LIKE', \mb_strToLower(\strTok($requestUri, '?')) . '%'))
->groupBy(['user_id', 'robot'])
->get(['user_id', 'robot', new Expression('COUNT(*)')]);
}

private function map(Support\Collection $collection): Support\Collection
{
return $collection->map(fn($item) => new Session((array)$item));
}

private function makeProfileLink(int $userId, string $userName): string
private function isUserLogged(): bool
{
return link_to_route('profile', $userName, [$userId], ['data-user-id' => $userId]);
return !!$this->request->user();
}

private function unique(Support\Collection $sessions): Support\Collection
private function loggedUserId()
{
$guests = $sessions->filter(fn(Session $item) => $item->userId === null);
$sessions
->filter(fn(Session $item) => $item->userId !== null)
->unique('user_id')
->each(fn(Session $item) => $guests->push($item));
return $guests;
return $this->request->user()->id;
}
}
57 changes: 57 additions & 0 deletions resources/feature/viewersOnline/viewers-online.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@mixin dark {
body.theme-dark & {
@content;
}
}

@mixin light {
body.theme-light & {
@content;
}
}

.viewers-online {
.viewer-pill {
padding: 4px;
overflow: hidden;
border-radius: 21px;
align-items: center;

@include dark {
background: #2e2e2e;
border: 1px solid #383838;
}

@include light {
background: white;
border: 1px solid #dedede;
}

.viewer-pill-title {
padding-left: 6px;
padding-right: 14px;
font-size: 0.8em;
line-height: 1.3em;
}
}

.viewers-users-group {
margin-left: -6px;
}

.viewers-users {
max-width: 90%;

.viewers-user {
border-radius: 32px;
overflow: hidden;
margin-right: -12px;
@include dark {
border: 1px solid #444;
}
@include light {
border: 1px solid #dedede;
}
}
}
}
1 change: 1 addition & 0 deletions resources/sass/core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
@import "pages/wiki";

@import "../feature/stickyAside/sticky-aside";
@import "../feature/viewersOnline/viewers-online";
@import "../js/components/defaultAvatar";

@import "../../node_modules/@riddled/4play/src/style";
Expand Down
51 changes: 34 additions & 17 deletions resources/views/components/viewers.twig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="box">
<h4 class="heading">
{% if isLocalViewers %}
{% if local %}
<i class="fas fa-eye fa-fw"></i>
{% else %}
<i class="fas fa-users fa-fw"></i>
Expand All @@ -9,20 +9,37 @@
</h4>
</div>

<ul class="side-menu">
<li>
<p class="side-menu-item mb-0">
{{ registered }} użytkowników, {{ guests }} gości
<div class="viewers-online">
<div class="mb-2">
<p class="mb-0">
{{ guestsCount }} niezalogowanych, {{ usersCount }} zalogowanych
</p>
</li>
{% for name, group in groups %}
{% if group|length > 0 %}
<li>
<p class="side-menu-item mb-0">
{{ name }}:
{{ group|join(', ')|raw }}
</p>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
<div class="mb-2 viewers-users-group">
{% for user in users %}
{% if user.groupName %}
<div class="viewer-pill d-inline-flex mb-1">
<div class="d-inline-block" style="width:32px; border-radius:16px; overflow:hidden;" title="{{ user.name }}">
{{ user_avatar(user.avatarUrl, user.name) }}
</div>
<span class="viewer-pill-title">
<b>{{ user.name }}</b>
<br>
<small>{{ user.groupName }}</small>
</span>
</div>
{% endif %}
{% endfor %}
</div>
{% if local %}
<div class="viewers-users">
{% for user in users %}
{% if not user.groupName %}
<div class="viewers-user d-inline-block mb-1" style="width:32px;" title="{{ user.name }}">
{{ user_avatar(user.avatarUrl, user.name) }}
</div>
{% endif %}
{% endfor %}
</div>
{% endif %}
</div>

0 comments on commit c6946ea

Please sign in to comment.