mirror of
https://github.com/HDInnovations/UNIT3D-Community-Edition.git
synced 2026-05-03 16:59:32 -05:00
(Fix) Slow online users section on home page 🐛
This commit is contained in:
@@ -22,6 +22,7 @@ use App\Models\Topic;
|
||||
use App\Models\Article;
|
||||
use App\Models\Torrent;
|
||||
use App\Models\Bookmark;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\FreeleechToken;
|
||||
use App\Models\FeaturedTorrent;
|
||||
@@ -107,7 +108,14 @@ class HomeController extends Controller
|
||||
});
|
||||
|
||||
// Online Block
|
||||
$users = new User();
|
||||
$users = User::with('group', 'privacy')
|
||||
->withCount([
|
||||
'warnings' => function (Builder $query) {
|
||||
$query->whereNotNull('torrent')->where('active', '1');
|
||||
}
|
||||
])
|
||||
->where('last_action', '>', now()->subMinutes(5))
|
||||
->get();
|
||||
|
||||
$groups = cache()->remember('user-groups', $expiresAt, function () {
|
||||
return Group::select(['name', 'color', 'effect', 'icon'])->oldest('position')->get();
|
||||
|
||||
+1
-1
@@ -60,8 +60,8 @@ class Kernel extends HttpKernel
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\App\Http\Middleware\UpdateLastAction::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:60,1',
|
||||
'bindings',
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* NOTICE OF LICENSE.
|
||||
*
|
||||
* UNIT3D is open-sourced software licensed under the GNU General Public License v3.0
|
||||
* The details is bundled with this project in the file LICENSE.txt.
|
||||
*
|
||||
* @project UNIT3D
|
||||
*
|
||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
|
||||
* @author HDVinnie
|
||||
*/
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class UpdateLastAction
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (!$user = $request->user()) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
$user->last_action = now();
|
||||
$user->save();
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -689,6 +689,16 @@ class User extends Authenticatable
|
||||
return $this->hasMany(FreeleechToken::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has many warnings.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function warnings()
|
||||
{
|
||||
return $this->hasMany(Warning::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Users username as slug.
|
||||
*
|
||||
|
||||
@@ -13,74 +13,19 @@
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
trait UsersOnlineTrait
|
||||
{
|
||||
public function allOnline()
|
||||
{
|
||||
return $this->all()->filter->isOnline();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user is online.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOnline()
|
||||
{
|
||||
return cache()->has($this->getCacheKey());
|
||||
}
|
||||
|
||||
public function leastRecentOnline()
|
||||
{
|
||||
return $this->allOnline()
|
||||
->sortBy(function ($user) {
|
||||
return $user->getCachedAt();
|
||||
});
|
||||
}
|
||||
|
||||
public function mostRecentOnline()
|
||||
{
|
||||
return $this->allOnline()
|
||||
->sortByDesc(function ($user) {
|
||||
return $user->getCachedAt();
|
||||
});
|
||||
}
|
||||
|
||||
public function getCachedAt()
|
||||
{
|
||||
if (empty($cache = cache()->get($this->getCacheKey()))) {
|
||||
return 0;
|
||||
if (!$this->last_action) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $cache['cachedAt'];
|
||||
}
|
||||
|
||||
public function setCache($seconds = 300)
|
||||
{
|
||||
return cache()->put(
|
||||
$this->getCacheKey(),
|
||||
$this->getCacheContent(),
|
||||
$seconds
|
||||
);
|
||||
}
|
||||
|
||||
public function getCacheContent()
|
||||
{
|
||||
if (! empty($cache = cache()->get($this->getCacheKey()))) {
|
||||
return $cache;
|
||||
}
|
||||
$cachedAt = Carbon::now();
|
||||
|
||||
return [
|
||||
'cachedAt' => $cachedAt,
|
||||
'user' => $this,
|
||||
];
|
||||
}
|
||||
|
||||
public function pullCache()
|
||||
{
|
||||
cache()->pull($this->getCacheKey());
|
||||
}
|
||||
|
||||
public function getCacheKey()
|
||||
{
|
||||
return sprintf('%s-%s', 'UserOnline', $this->id);
|
||||
return $this->last_action->gt(now()->subMinutes(5));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddLastActionToUsersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dateTime('last_action')->after('last_login')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('last_action');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3,36 +3,37 @@
|
||||
<div class="panel panel-chat shoutbox">
|
||||
<div class="panel-heading">
|
||||
<h4>@lang('blocks.users-online')
|
||||
<span class="label label-default">{{ $users->allOnline()->count() }}</span>
|
||||
<span class="label label-default">{{ $users->count() }}</span>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
@foreach ($users->mostRecentOnline() as $user)
|
||||
@if($user->hidden == 1 || !$user->isVisible($user,'other','show_online'))
|
||||
<span class="badge-user text-orange text-bold" style="margin-bottom: 10px;">
|
||||
<i class="{{ config('other.font-awesome') }} fa-user-ninja"></i> {{ strtoupper(trans('common.hidden')) }}
|
||||
@if (auth()->user()->group->is_modo)
|
||||
<a href="{{ route('profile', ['username' => $user->username, 'id' => $user->id]) }}">
|
||||
{{ $user->username }}
|
||||
@if ($user->getWarning() > 0)
|
||||
<i class="{{ config('other.font-awesome') }} fa-exclamation-circle text-orange" aria-hidden="true"
|
||||
data-toggle="tooltip" data-original-title="@lang('common.active-warning')"></i>
|
||||
@endif
|
||||
</a>
|
||||
@endif
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ route('profile', ['username' => $user->username, 'id' => $user->id]) }}">
|
||||
<span class="badge-user text-bold" style="color:{{ $user->group->color }}; background-image:{{ $user->group->effect }}; margin-bottom: 10px;">
|
||||
<i class="{{ $user->group->icon }}" data-toggle="tooltip" data-original-title="{{ $user->group->name }}"></i>
|
||||
@foreach ($users as $user)
|
||||
@if (!$user->isVisible($user, 'other', 'show_online'))
|
||||
<span class="badge-user text-orange text-bold" style="margin-bottom: 10px;">
|
||||
<i class="{{ config('other.font-awesome') }} fa-user-ninja"></i> {{ strtoupper(trans('common.hidden')) }}
|
||||
@if (auth()->user()->group->is_modo)
|
||||
<a href="{{ route('profile', ['username' => $user->username, 'id' => $user->id]) }}">
|
||||
{{ $user->username }}
|
||||
@if ($user->getWarning() > 0)
|
||||
@if ($user->warnings_count > 0)
|
||||
<i class="{{ config('other.font-awesome') }} fa-exclamation-circle text-orange" aria-hidden="true"
|
||||
data-toggle="tooltip" data-original-title="@lang('common.active-warning')"></i>
|
||||
@endif
|
||||
</span>
|
||||
</a>
|
||||
@endif
|
||||
</a>
|
||||
@endif
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ route('profile', ['username' => $user->username, 'id' => $user->id]) }}">
|
||||
<span class="badge-user text-bold" style="color:{{ $user->group->color }}; background-image:{{ $user->group->effect }}; margin-bottom: 10px;">
|
||||
<i class="{{ $user->group->icon }}" data-toggle="tooltip" data-original-title="{{ $user->group->name }}"></i>
|
||||
{{ $user->username }}
|
||||
@if ($user->warnings_count > 0)
|
||||
<i class="{{ config('other.font-awesome') }} fa-exclamation-circle text-orange" aria-hidden="true"
|
||||
data-toggle="tooltip" data-original-title="@lang('common.active-warning')"></i>
|
||||
@endif
|
||||
</span>
|
||||
</a>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
|
||||
Reference in New Issue
Block a user