mirror of
https://github.com/HDInnovations/UNIT3D-Community-Edition.git
synced 2026-02-05 03:00:52 -06:00
Merge pull request #2255 from Roardom/add-user-uploads
(Refactor) split user torrents into history and uploads
This commit is contained in:
@@ -1239,6 +1239,29 @@ class UserController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get A Users Uploads Table.
|
||||
*/
|
||||
public function uploads(Request $request, string $username): \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
{
|
||||
$user = User::where('username', '=', $username)->firstOrFail();
|
||||
|
||||
\abort_unless($request->user()->group->is_modo || $request->user()->id == $user->id, 403);
|
||||
$hisUpl = History::where('user_id', '=', $user->id)->sum('actual_uploaded');
|
||||
$hisUplCre = History::where('user_id', '=', $user->id)->sum('uploaded');
|
||||
$hisDownl = History::where('user_id', '=', $user->id)->sum('actual_downloaded');
|
||||
$hisDownlCre = History::where('user_id', '=', $user->id)->sum('downloaded');
|
||||
|
||||
return \view('user.private.uploads', [
|
||||
'route' => 'uploads',
|
||||
'user' => $user,
|
||||
'his_upl' => $hisUpl,
|
||||
'his_upl_cre' => $hisUplCre,
|
||||
'his_downl' => $hisDownl,
|
||||
'his_downl_cre' => $hisDownlCre,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get A Users Graveyard Resurrections.
|
||||
*/
|
||||
|
||||
@@ -44,16 +44,12 @@ class UserTorrents extends Component
|
||||
|
||||
public string $downloaded = 'any';
|
||||
|
||||
public string $hasHistory = 'any';
|
||||
|
||||
public array $status = [];
|
||||
|
||||
public string $sortField = 'created_at';
|
||||
|
||||
public string $sortDirection = 'desc';
|
||||
|
||||
public $unapprovedOnTop = true;
|
||||
|
||||
public $showMorePrecision = false;
|
||||
|
||||
protected $queryString = [
|
||||
@@ -69,9 +65,7 @@ class UserTorrents extends Component
|
||||
'immune' => ['except' => 'any'],
|
||||
'uploaded' => ['except' => 'any'],
|
||||
'downloaded' => ['except' => 'any'],
|
||||
'hasHistory' => ['except' => 'any'],
|
||||
'status' => ['except' => []],
|
||||
'unapprovedOnTop' => ['except' => true],
|
||||
'showMorePrecision' => ['except' => false],
|
||||
];
|
||||
|
||||
@@ -97,8 +91,14 @@ class UserTorrents extends Component
|
||||
|
||||
final public function getHistoryProperty(): \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||
{
|
||||
return History::rightJoin('torrents', 'history.torrent_id', '=', 'torrents.id')
|
||||
return History::query()
|
||||
->join('torrents', fn ($join) => $join
|
||||
->on('history.torrent_id', '=', 'torrents.id')
|
||||
->where('history.created_at', '>=', $this->user->created_at) // Unneeded, but increases performance
|
||||
->where('history.user_id', '=', $this->user->id)
|
||||
)
|
||||
->select(
|
||||
'history.torrent_id',
|
||||
'history.agent',
|
||||
'history.uploaded',
|
||||
'history.downloaded',
|
||||
@@ -112,7 +112,6 @@ class UserTorrents extends Component
|
||||
'history.immune',
|
||||
'history.hitrun',
|
||||
'history.prewarn',
|
||||
'torrents.id',
|
||||
'torrents.name',
|
||||
'torrents.seeders',
|
||||
'torrents.leechers',
|
||||
@@ -121,24 +120,12 @@ class UserTorrents extends Component
|
||||
'torrents.user_id',
|
||||
'torrents.status',
|
||||
)
|
||||
->when(
|
||||
$this->uploaded === 'include',
|
||||
fn ($query) => $query->selectRaw('COALESCE(history.created_at, NOW()) as created_at'),
|
||||
fn ($query) => $query->selectRaw('COALESCE(history.created_at, torrents.created_at) as created_at')
|
||||
)
|
||||
->selectRaw('IF(torrents.user_id = ?, 1, 0) AS uploader', [$this->user->id])
|
||||
->selectRaw('history.active AND history.seeder AS seeding')
|
||||
->selectRaw('history.active AND NOT history.seeder AS leeching')
|
||||
->selectRaw('TIMESTAMPDIFF(SECOND, history.created_at, history.completed_at) AS leechtime')
|
||||
->selectRaw('CAST(history.uploaded AS float) / CAST((history.downloaded + 1) AS float) AS ratio')
|
||||
->selectRaw('CAST(history.actual_uploaded AS float) / CAST((history.actual_downloaded + 1) AS float) AS actual_ratio')
|
||||
->where(fn ($query) => $query
|
||||
->where('history.user_id', '=', $this->user->id)
|
||||
->orWhere(fn ($query) => $query
|
||||
->where('torrents.user_id', '=', $this->user->id)
|
||||
->whereNull('history.user_id')
|
||||
)
|
||||
)
|
||||
->when($this->name, fn ($query) => $query
|
||||
->where('name', 'like', '%'.str_replace(' ', '%', $this->name).'%')
|
||||
)
|
||||
@@ -166,14 +153,11 @@ class UserTorrents extends Component
|
||||
->when($this->hitrun === 'exclude', fn ($query) => $query->where(fn ($query) => $query->where('hitrun', '=', 0)->orWhereNull('hitrun')))
|
||||
->when($this->immune === 'include', fn ($query) => $query->where('immune', '=', 1))
|
||||
->when($this->immune === 'exclude', fn ($query) => $query->where(fn ($query) => $query->where('immune', '=', 0)->orWhereNull('immune')))
|
||||
->when($this->hasHistory === 'include', fn ($query) => $query->whereNotNull('history.updated_at'))
|
||||
->when($this->hasHistory === 'exclude', fn ($query) => $query->whereNull('history.updated_at'))
|
||||
->when($this->uploaded === 'include', fn ($query) => $query->where('torrents.user_id', '=', $this->user->id))
|
||||
->when($this->uploaded === 'exclude', fn ($query) => $query->where('torrents.user_id', '<>', $this->user->id))
|
||||
->when($this->downloaded === 'include', fn ($query) => $query->where('history.actual_downloaded', '>', 0))
|
||||
->when($this->downloaded === 'exclude', fn ($query) => $query->where('history.actual_downloaded', '=', 0))
|
||||
->when(! empty($this->status), fn ($query) => $query->whereIntegerInRaw('status', $this->status))
|
||||
->when($this->unapprovedOnTop, fn ($query) => $query->orderByRaw('IF(status = 1, 1, 0)'))
|
||||
->orderBy($this->sortField, $this->sortDirection)
|
||||
->paginate($this->perPage);
|
||||
}
|
||||
|
||||
104
app/Http/Livewire/UserUploads.php
Normal file
104
app/Http/Livewire/UserUploads.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/**
|
||||
* NOTICE OF LICENSE.
|
||||
*
|
||||
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
|
||||
* The details is bundled with this project in the file LICENSE.txt.
|
||||
*
|
||||
* @project UNIT3D Community Edition
|
||||
*
|
||||
* @author Roardom <roardom@protonmail.com>
|
||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
|
||||
*/
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Models\Torrent;
|
||||
use App\Models\User;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
class UserUploads extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
public ?\Illuminate\Contracts\Auth\Authenticatable $user = null;
|
||||
|
||||
public int $perPage = 25;
|
||||
|
||||
public string $name = '';
|
||||
|
||||
public string $personalRelease = 'any';
|
||||
|
||||
public array $status = [];
|
||||
|
||||
public string $sortField = 'created_at';
|
||||
|
||||
public string $sortDirection = 'desc';
|
||||
|
||||
public $showMorePrecision = false;
|
||||
|
||||
protected $queryString = [
|
||||
'perPage' => ['except' => ''],
|
||||
'name' => ['except' => ''],
|
||||
'personalRelease' => ['except' => 'any'],
|
||||
'sortField' => ['except' => 'created_at'],
|
||||
'sortDirection' => ['except' => 'desc'],
|
||||
'status' => ['except' => []],
|
||||
];
|
||||
|
||||
final public function mount($userId): void
|
||||
{
|
||||
$this->user = User::find($userId);
|
||||
}
|
||||
|
||||
final public function paginationView(): string
|
||||
{
|
||||
return 'vendor.pagination.livewire-pagination';
|
||||
}
|
||||
|
||||
final public function updatedPage(): void
|
||||
{
|
||||
$this->emit('paginationChanged');
|
||||
}
|
||||
|
||||
final public function updatingSearch(): void
|
||||
{
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
final public function getUploadsProperty(): \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||
{
|
||||
return Torrent::query()
|
||||
->withCount('thanks')
|
||||
->withSum('tips', 'cost')
|
||||
->where('created_at', '>=', $this->user->created_at) // Unneeded, but increases performances
|
||||
->where('user_id', '=', $this->user->id)
|
||||
->when($this->name, fn ($query) => $query
|
||||
->where('name', 'like', '%'.str_replace(' ', '%', $this->name).'%')
|
||||
)
|
||||
->when(! empty($this->status), fn ($query) => $query->whereIntegerInRaw('status', $this->status))
|
||||
->when($this->personalRelease === 'include', fn ($query) => $query->where('personal_release', '=', 1))
|
||||
->when($this->personalRelease === 'exclude', fn ($query) => $query->where('personal_release', '=', 0))
|
||||
->orderBy($this->sortField, $this->sortDirection)
|
||||
->paginate($this->perPage);
|
||||
}
|
||||
|
||||
final public function render(): \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Contracts\Foundation\Application
|
||||
{
|
||||
return \view('livewire.user-uploads', [
|
||||
'uploads' => $this->uploads,
|
||||
]);
|
||||
}
|
||||
|
||||
final public function sortBy($field): void
|
||||
{
|
||||
if ($this->sortField === $field) {
|
||||
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
$this->sortDirection = 'asc';
|
||||
}
|
||||
|
||||
$this->sortField = $field;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
@import 'components/quick_search';
|
||||
@import 'components/user-active';
|
||||
@import 'components/user-torrents';
|
||||
@import 'components/user-uploads';
|
||||
@import 'layout/header';
|
||||
@import 'layout/secondary-nav';
|
||||
@import 'layout/top_nav';
|
||||
|
||||
61
resources/sass/components/_user-uploads.scss
Normal file
61
resources/sass/components/_user-uploads.scss
Normal file
@@ -0,0 +1,61 @@
|
||||
.user-uploads__name-header,
|
||||
.user-uploads__size-header,
|
||||
.user-uploads__seeders-header,
|
||||
.user-uploads__leechers-header,
|
||||
.user-uploads__times-header,
|
||||
.user-uploads__tips-header,
|
||||
.user-uploads__thanks-header,
|
||||
.user-uploads__created-at-header,
|
||||
.user-uploads__personal-release-header,
|
||||
.user-uploads__status-header {
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.user-uploads__name,
|
||||
.user-uploads__size,
|
||||
.user-uploads__seeders,
|
||||
.user-uploads__leechers,
|
||||
.user-uploads__times,
|
||||
.user-uploads__tips,
|
||||
.user-uploads__thanks,
|
||||
.user-uploads__created-at {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-uploads__personal-release,
|
||||
.user-uploads__status {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.user-uploads__size-header,
|
||||
.user-uploads__seeders-header,
|
||||
.user-uploads__leechers-header,
|
||||
.user-uploads__times-header,
|
||||
.user-uploads__size,
|
||||
.user-uploads__seeders,
|
||||
.user-uploads__leechers,
|
||||
.user-uploads__times {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.user-uploads__personal-release-header,
|
||||
.user-uploads__status-header,
|
||||
.user-uploads__persona-release,
|
||||
.user-uploads__status {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.user-uploads__name {
|
||||
font-weight: bolder;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.user-uploads__checkbox {
|
||||
all: revert !important;
|
||||
}
|
||||
|
||||
.user-uploads__checkbox:indeterminate {
|
||||
all: revert !important;
|
||||
}
|
||||
@@ -108,18 +108,6 @@
|
||||
{{ __('torrent.downloaded') }}
|
||||
</label>
|
||||
</span>
|
||||
<span class="badge-user">
|
||||
<label style="user-select: none" class="inline" x-data="{ state: @entangle('hasHistory'), ...ternaryCheckbox() }">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="user-torrents__checkbox"
|
||||
x-init="updateTernaryCheckboxProperties($el, state)"
|
||||
x-on:click="state = getNextTernaryCheckboxState(state); updateTernaryCheckboxProperties($el, state)"
|
||||
x-bind:checked="state === 'include'"
|
||||
>
|
||||
Has history
|
||||
</label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-0 mt-5 form-group fatten-me">
|
||||
@@ -162,12 +150,6 @@
|
||||
Show more precision
|
||||
</label>
|
||||
</span>
|
||||
<span class="badge-user">
|
||||
<label class="inline">
|
||||
<input type="checkbox" class="user-torrents__checkbox" wire:model="unapprovedOnTop">
|
||||
Unapproved on top
|
||||
</label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -259,26 +241,26 @@
|
||||
@foreach ($histories as $history)
|
||||
<tr>
|
||||
<td>
|
||||
<a class="user-torrents__name" href="{{ route('torrent', ['id' => $history->id]) }}">
|
||||
<a class="user-torrents__name" href="{{ route('torrent', ['id' => $history->torrent_id]) }}">
|
||||
{{ $history->name }}
|
||||
</a>
|
||||
</td>
|
||||
<td class="user-torrents__seeders">
|
||||
<a href="{{ route('peers', ['id' => $history->id]) }}">
|
||||
<a href="{{ route('peers', ['id' => $history->torrent_id]) }}">
|
||||
<span class='text-green'>
|
||||
{{ $history->seeders }}
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="user-torrents__leechers">
|
||||
<a href="{{ route('peers', ['id' => $history->id]) }}">
|
||||
<a href="{{ route('peers', ['id' => $history->torrent_id]) }}">
|
||||
<span class='text-red'>
|
||||
{{ $history->leechers }}
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="user-torrents__times">
|
||||
<a href="{{ route('history', ['id' => $history->id]) }}">
|
||||
<a href="{{ route('history', ['id' => $history->torrent_id]) }}">
|
||||
<span class='text-orange'>
|
||||
{{ $history->times_completed }}
|
||||
</span>
|
||||
@@ -343,26 +325,36 @@
|
||||
</td>
|
||||
@if ($showMorePrecision)
|
||||
<td class="user-torrents__leechtime">
|
||||
@if ($history->actual_uploaded === null)
|
||||
@if ($history->leechtime === null)
|
||||
N/A
|
||||
@else
|
||||
{{ App\Helpers\StringHelper::timeElapsed($history->leechtime) }}
|
||||
@endif
|
||||
</td>
|
||||
<td class="user-torrents__seedtime">
|
||||
<span class="{{ $history->seedtime < config('hitrun.seedtime') ? 'text-red' : 'text-green' }}">
|
||||
{{ App\Helpers\StringHelper::timeElapsed($history->seedtime) }}
|
||||
<span class="{{ ($history->seedtime ?? 0) < config('hitrun.seedtime') ? 'text-red' : 'text-green' }}">
|
||||
@if ($history->seedtime === null)
|
||||
N/A
|
||||
@else
|
||||
{{ App\Helpers\StringHelper::timeElapsed($history->seedtime) }}
|
||||
@endif
|
||||
</span>
|
||||
</td>
|
||||
<td class="user-torrents__created-at">
|
||||
@if ($history->updated_at === null)
|
||||
<em title="Uploaded date">{{ $history->created_at ?? 'N/A' }}</em>
|
||||
@else
|
||||
<time datetime="{{ $history->created_at ?? 0}}">
|
||||
{{ $history->created_at ?? 'N/A' }}
|
||||
@endif
|
||||
</time>
|
||||
</td>
|
||||
<td class="user-torrents__updated-at">
|
||||
<time datetime="{{ $history->updated_at ?? 0}}">
|
||||
{{ $history->updated_at ?? 'N/A' }}
|
||||
</time>
|
||||
</td>
|
||||
<td class="user-torrents__completed-at">
|
||||
<time datetime="{{ $history->completed_at ?? 0}}">
|
||||
{{ $history->completed_at ?? 'N/A' }}
|
||||
</time>
|
||||
</td>
|
||||
<td class="user-torrents__updated-at">{{ $history->updated_at ?? 'N/A' }}</td>
|
||||
<td class="user-torrents__complated-at">{{ $history->completed_at ?? 'N/A' }}</td>
|
||||
@else
|
||||
<td class="user-torrents__leechtime">
|
||||
@if ($history->leechtime === null)
|
||||
@@ -381,13 +373,7 @@
|
||||
@endif
|
||||
</td>
|
||||
<td class="user-torrents__created-at">
|
||||
@if ($history->updated_at === null)
|
||||
<em title="Uploaded date">
|
||||
{{ $history->created_at === null ? 'N/A' : \explode(" ", $history->created_at)[0] }}
|
||||
</em>
|
||||
@else
|
||||
{{ $history->created_at === null ? 'N/A' : \explode(" ", $history->created_at)[0] }}
|
||||
@endif
|
||||
{{ $history->created_at === null ? 'N/A' : \explode(" ", $history->created_at)[0] }}
|
||||
</td>
|
||||
<td class="user-torrents__updated-at">
|
||||
{{ $history->updated_at === null ? 'N/A' : \explode(" ", $history->updated_at)[0] }}
|
||||
|
||||
214
resources/views/livewire/user-uploads.blade.php
Normal file
214
resources/views/livewire/user-uploads.blade.php
Normal file
@@ -0,0 +1,214 @@
|
||||
<div>
|
||||
<div class="container well search mt-5">
|
||||
<div class="form-horizontal form-condensed form-torrent-search form-bordered">
|
||||
<div class="mx-0 mt-5 form-group fatten-me">
|
||||
<label for="name" class="mt-5 col-sm-1 label label-default fatten-me">{{ __('torrent.name') }}</label>
|
||||
<div class="col-sm-9 fatten-me">
|
||||
<input type="text" class="form-control" id="name" wire:model="name" placeholder="{{ __('torrent.name') }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mx-0 mt-5 form-group fatten-me">
|
||||
<div class="mt-5 col-sm-1 label label-default fatten-me">
|
||||
{{ __('torrent.filters') }}
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<span class="badge-user">
|
||||
<label style="user-select: none" class="inline" x-data="{ state: @entangle('personalRelease'), ...ternaryCheckbox() }">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="user-uploads__checkbox"
|
||||
x-init="updateTernaryCheckboxProperties($el, state)"
|
||||
x-on:click="state = getNextTernaryCheckboxState(state); updateTernaryCheckboxProperties($el, state)"
|
||||
x-bind:checked="state === 'include'"
|
||||
>
|
||||
{{ __('torrent.personal-release') }}
|
||||
</label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-0 mt-5 form-group fatten-me">
|
||||
<div class="mt-5 col-sm-1 label label-default fatten-me">
|
||||
{{ __('torrent.moderation') }}
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<span class="badge-user">
|
||||
<label class="inline">
|
||||
<input type="checkbox" class="user-uploads__checkbox" wire:model="status" value="0">
|
||||
{{ __('torrent.pending') }}
|
||||
</label>
|
||||
</span>
|
||||
<span class="badge-user">
|
||||
<label class="inline">
|
||||
<input type="checkbox" class="user-uploads__checkbox" wire:model="status" value="1">
|
||||
{{ __('torrent.approved') }}
|
||||
</label>
|
||||
</span>
|
||||
<span class="badge-user">
|
||||
<label class="inline">
|
||||
<input type="checkbox" class="user-uploads__checkbox" wire:model="status" value="2">
|
||||
{{ __('torrent.rejected') }}
|
||||
</label>
|
||||
</span>
|
||||
<span class="badge-user">
|
||||
<label class="inline">
|
||||
<input type="checkbox" class="user-uploads__checkbox" wire:model="status" value="3">
|
||||
Postponed
|
||||
</label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-0 mt-5 form-group fatten-me">
|
||||
<div class="mt-5 col-sm-1 label label-default fatten-me">Options</div>
|
||||
<div class="col-sm-10">
|
||||
<span class="badge-user">
|
||||
<label class="inline">
|
||||
<input type="checkbox" class="user-uploads__checkbox" wire:model="showMorePrecision">
|
||||
Show more precision
|
||||
</label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-condensed table-striped table-bordered">
|
||||
<thead>
|
||||
<th class="user-uploads__name-header" wire:click="sortBy('name')" role="columnheader button">
|
||||
{{ __('torrent.name') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'name'])
|
||||
</th>
|
||||
<th class="user-uploads__size-header" wire:click="sortBy('size')" role="columnheader button">
|
||||
{{ __('torrent.size') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'size'])
|
||||
</th>
|
||||
<th class="user-uploads__seeders-header" wire:click="sortBy('seeders')" role="columnheader button" title="{{ __('torrent.seeders') }}">
|
||||
<i class="fas fa-arrow-alt-circle-up"></i>
|
||||
@include('livewire.includes._sort-icon', ['field' => 'seeders'])
|
||||
</th>
|
||||
<th class="user-uploads__leechers-header" wire:click="sortBy('leechers')" role="columnheader button" title="{{ __('torrent.leechers') }}">
|
||||
<i class="fas fa-arrow-alt-circle-down"></i>
|
||||
@include('livewire.includes._sort-icon', ['field' => 'leechers'])
|
||||
</th>
|
||||
<th class="user-uploads__times-header" wire:click="sortBy('times_completed')" role="columnheader button" title="{{ __('torrent.completed') }}">
|
||||
<i class="fas fa-check-circle"></i>
|
||||
@include('livewire.includes._sort-icon', ['field' => 'times_completed'])
|
||||
</th>
|
||||
<th class="user-uploads__tips-header" wire:click="sortBy('tips_sum_cost')" role="columnheader button" title="{{ __('bon.tips') }}">
|
||||
<i class="fas fa-coins"></i>
|
||||
@include('livewire.includes._sort-icon', ['field' => 'tips_sum_cost'])
|
||||
</th>
|
||||
<th class="user-uploads__thanks-header" wire:click="sortBy('thanks_count')" role="columnheader button" title="{{ __('torrent.thanks') }}">
|
||||
<i class="fas fa-heart"></i>
|
||||
@include('livewire.includes._sort-icon', ['field' => 'thanks_count'])
|
||||
</th>
|
||||
<th class="user-uploads__created-at-header" wire:click="sortBy('created_at')" role="columnheader button">
|
||||
{{ __('torrent.uploaded') }}
|
||||
@include('livewire.includes._sort-icon', ['field' => 'created_at'])
|
||||
</th>
|
||||
<th class="user-uploads__personal-release-header" wire:click="sortBy('personal_release')" role="columnheader button" title="{{ __('torrent.personal-release') }}">
|
||||
<i class="fas fa-user-plus"></i>
|
||||
@include('livewire.includes._sort-icon', ['field' => 'status'])
|
||||
</th>
|
||||
<th class="user-uploads__status-header" wire:click="sortBy('status')" role="columnheader button" title="{{ __('torrent.approved') }}">
|
||||
<i class="fas fa-tasks"></i>
|
||||
@include('livewire.includes._sort-icon', ['field' => 'status'])
|
||||
</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($uploads as $torrent)
|
||||
<tr>
|
||||
<td>
|
||||
@if ($torrent->internal)
|
||||
<i class="{{ config('other.font-awesome') }} fa-magic" style="color: #baaf92;"></i>
|
||||
@endif
|
||||
<a class="user-uploads__name" href="{{ route('torrent', ['id' => $torrent->id]) }}">
|
||||
{{ $torrent->name }}
|
||||
</a>
|
||||
</td>
|
||||
<td class="user-uploads__size">
|
||||
{{ App\Helpers\StringHelper::formatBytes($torrent->size) }}
|
||||
</td>
|
||||
<td class="user-uploads__seeders">
|
||||
<a href="{{ route('peers', ['id' => $torrent->id]) }}">
|
||||
<span class='text-green'>
|
||||
{{ $torrent->seeders }}
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="user-uploads__leechers">
|
||||
<a href="{{ route('peers', ['id' => $torrent->id]) }}">
|
||||
<span class='text-red'>
|
||||
{{ $torrent->leechers }}
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="user-uploads__times">
|
||||
<a href="{{ route('history', ['id' => $torrent->id]) }}">
|
||||
<span class='text-orange'>
|
||||
{{ $torrent->times_completed }}
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="user-uploads__tips">
|
||||
{{ $torrent->tips_sum_cost ?? 0 }}
|
||||
</td>
|
||||
<td class="user-uploads__thanks">
|
||||
{{ $torrent->thanks_count ?? 0 }}
|
||||
</td>
|
||||
<td class="user-uploads__created-at">
|
||||
<time datetime="{{ $torrent->created_at }}">
|
||||
@if ($showMorePrecision)
|
||||
{{ $torrent->created_at ?? 'N/A' }}
|
||||
@else
|
||||
{{ $torrent->created_at === null ? 'N/A' : \explode(" ", $torrent->created_at)[0] }}
|
||||
@endif
|
||||
</time>
|
||||
</td>
|
||||
<td class="user-uploads__personal-release">
|
||||
@if ($torrent->personal_release === 1)
|
||||
<i class="{{ config('other.font-awesome') }} fa-check text-green" title="Immune"></i>
|
||||
@else
|
||||
<i class="{{ config('other.font-awesome') }} fa-times text-red" title="Not immune"></i>
|
||||
@endif
|
||||
</td>
|
||||
<td class="user-uploads__status">
|
||||
@switch($torrent->status)
|
||||
@case(0)
|
||||
<span title="{{ __('torrent.pending') }}" class="{{ config('other.font-awesome') }} fa-tasks text-orange"></span>
|
||||
@break
|
||||
@case(1)
|
||||
<span title="{{ __('torrent.approved') }}" class="{{ config('other.font-awesome') }} fa-check text-green"></span>
|
||||
@break
|
||||
@case(2)
|
||||
<span title="{{ __('torrent.rejected') }}" class ="{{ config('other.font-awesome') }} fa-times text-red"></span>
|
||||
@break
|
||||
@case(3)
|
||||
<span title="Postponed" class ="{{ config('other.font-awesome') }} fa-hourglass text-red"></span>
|
||||
@break
|
||||
@endswitch
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="text-center">
|
||||
{{ $uploads->links() }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script nonce="{{ HDVinnie\SecureHeaders\SecureHeaders::nonce('script') }}">
|
||||
function ternaryCheckbox() {
|
||||
return {
|
||||
updateTernaryCheckboxProperties(el, state) {
|
||||
el.indeterminate = (state === 'exclude');
|
||||
el.checked = (state === 'include');
|
||||
},
|
||||
getNextTernaryCheckboxState(state) {
|
||||
return (state === 'include') ? 'exclude' : (state === 'exclude' ? 'any' : 'include');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
@@ -231,13 +231,13 @@
|
||||
</ul>
|
||||
<ul class="top-nav__ratio-bar" x-bind:class="expanded && 'mobile'">
|
||||
<li class="ratio-bar__uploaded" title="{{ __('common.upload') }}">
|
||||
<a href="{{ route('user_torrents', ['username' => auth()->user()->username, 'uploaded' => 'include']) }}">
|
||||
<a href="{{ route('user_uploads', ['username' => auth()->user()->username]) }}">
|
||||
<i class="{{ config('other.font-awesome') }} fa-arrow-up"></i>
|
||||
{{ auth()->user()->getUploaded() }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="ratio-bar__downloaded" title="{{ __('common.download') }}">
|
||||
<a href="{{ route('user_torrents', ['username' => auth()->user()->username, 'uploaded' => 'exclude']) }}">
|
||||
<a href="{{ route('user_torrents', ['username' => auth()->user()->username, 'downloaded' => 'include']) }}">
|
||||
<i class="{{ config('other.font-awesome') }} fa-arrow-down"></i>
|
||||
{{ auth()->user()->getDownloaded() }}
|
||||
</a>
|
||||
@@ -391,7 +391,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route('user_torrents', ['username' => auth()->user()->username, 'uploaded' => 'include']) }}">
|
||||
<a href="{{ route('user_uploads', ['username' => auth()->user()->username]) }}">
|
||||
<i class="{{ config('other.font-awesome') }} fa-upload"></i>
|
||||
{{ __('user.my-uploads') }}
|
||||
</a>
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
<li class="nav-tab-menu">
|
||||
@if ($isProfileOwner || $isModo)
|
||||
<a
|
||||
class="{{ Route::is('user_torrents', 'user_active', 'user_resurrections', 'user_requested') ? 'nav-tab--active__link' : 'nav-tab__link' }}"
|
||||
class="{{ Route::is('user_torrents', 'user_uploads', 'user_active', 'user_resurrections', 'user_requested') ? 'nav-tab--active__link' : 'nav-tab__link' }}"
|
||||
href="{{ route('user_torrents', ['username' => $user->username]) }}"
|
||||
>
|
||||
{{ __('torrent.torrents') }}
|
||||
@@ -200,7 +200,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-tabV2">
|
||||
<a class="nav-tab__link" href="{{ route('user_torrents', ['username' => $user->username, 'uploaded' => 'include']) }}">
|
||||
<a class="nav-tab__link" href="{{ route('user_uploads', ['username' => $user->username]) }}">
|
||||
{{ __('user.uploads') }}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
45
resources/views/user/private/uploads.blade.php
Normal file
45
resources/views/user/private/uploads.blade.php
Normal file
@@ -0,0 +1,45 @@
|
||||
@extends('layout.default')
|
||||
|
||||
@section('title')
|
||||
<title>{{ $user->username }} {{ __('user.uploads') }} - {{ config('other.title') }}</title>
|
||||
@endsection
|
||||
|
||||
@section('breadcrumbs')
|
||||
<li class="breadcrumbV2">
|
||||
<a href="{{ route('users.show', ['username' => $user->username]) }}" class="breadcrumb__link">
|
||||
{{ $user->username }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="breadcrumb--active">
|
||||
{{ __('user.uploads') }}
|
||||
</li>
|
||||
@endsection
|
||||
|
||||
@section('nav-tabs')
|
||||
@include('user.buttons.user')
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid">
|
||||
<div class="block">
|
||||
<div class="button-holder some-padding">
|
||||
<div class="button-left">
|
||||
|
||||
</div>
|
||||
<div class="button-right">
|
||||
<span class="badge-user"><strong>{{ __('user.total-download') }}:</strong>
|
||||
<span class="badge-extra text-red">{{ App\Helpers\StringHelper::formatBytes($his_downl, 2) }}</span>
|
||||
<span class="badge-extra text-orange" data-toggle="tooltip"
|
||||
data-original-title="{{ __('user.credited-download') }}">{{ App\Helpers\StringHelper::formatBytes($his_downl_cre, 2) }}</span>
|
||||
</span>
|
||||
<span class="badge-user"><strong>{{ __('user.total-upload') }}:</strong>
|
||||
<span class="badge-extra text-green">{{ App\Helpers\StringHelper::formatBytes($his_upl, 2) }}</span>
|
||||
<span class="badge-extra text-blue" data-toggle="tooltip"
|
||||
data-original-title="{{ __('user.credited-upload') }}">{{ App\Helpers\StringHelper::formatBytes($his_upl_cre, 2) }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="some-padding">
|
||||
@livewire('user-uploads', ['userId' => $user->id])
|
||||
</div>
|
||||
@endsection
|
||||
@@ -306,6 +306,7 @@ Route::group(['middleware' => 'language'], function () {
|
||||
Route::get('/{username}/active', [App\Http\Controllers\UserController::class, 'active'])->name('user_active');
|
||||
Route::get('/{username}/activeByClient/{ip}/{port}', [App\Http\Controllers\UserController::class, 'activeByClient'])->name('user_active_by_client');
|
||||
Route::get('/{username}/torrents', [App\Http\Controllers\UserController::class, 'torrents'])->name('user_torrents');
|
||||
Route::get('/{username}/uploads', [App\Http\Controllers\UserController::class, 'uploads'])->name('user_uploads');
|
||||
Route::get('/{username}/topics', [App\Http\Controllers\UserController::class, 'topics'])->name('user_topics');
|
||||
Route::get('/{username}/posts', [App\Http\Controllers\UserController::class, 'posts'])->name('user_posts');
|
||||
Route::get('/{username}/followers', [App\Http\Controllers\UserController::class, 'followers'])->name('user_followers');
|
||||
|
||||
Reference in New Issue
Block a user