From 193c280358212da94a3fa79bb906e4e994fa917c Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Tue, 3 Dec 2024 23:03:48 -0500 Subject: [PATCH 01/25] fix: eager loading regression from #2908 - category was duplicated awhile back in https://github.com/HDInnovations/UNIT3D-Community-Edition/pull/2908 --- app/Http/Controllers/Staff/ModerationController.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Staff/ModerationController.php b/app/Http/Controllers/Staff/ModerationController.php index d91005aa53..c36a31585c 100644 --- a/app/Http/Controllers/Staff/ModerationController.php +++ b/app/Http/Controllers/Staff/ModerationController.php @@ -48,15 +48,15 @@ public function index(): \Illuminate\Contracts\View\Factory|\Illuminate\View\Vie return view('Staff.moderation.index', [ 'current' => now(), 'pending' => Torrent::withoutGlobalScope(ApprovedScope::class) - ->with(['user.group', 'category', 'type', 'resolution', 'category']) + ->with(['user.group', 'category', 'type', 'resolution']) ->where('status', '=', Torrent::PENDING) ->get(), 'postponed' => Torrent::withoutGlobalScope(ApprovedScope::class) - ->with(['user.group', 'moderated.group', 'category', 'type', 'resolution', 'category']) + ->with(['user.group', 'moderated.group', 'category', 'type', 'resolution']) ->where('status', '=', Torrent::POSTPONED) ->get(), 'rejected' => Torrent::withoutGlobalScope(ApprovedScope::class) - ->with(['user.group', 'moderated.group', 'category', 'type', 'resolution', 'category']) + ->with(['user.group', 'moderated.group', 'category', 'type', 'resolution']) ->where('status', '=', Torrent::REJECTED) ->get(), ]); From e6dd5cf410b0b3591e01ef274fc3eac26a93f6c9 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Thu, 5 Dec 2024 19:37:42 -0500 Subject: [PATCH 02/25] add: new pending torrents page - this is a new pending torrents page for all users to view. Useful for uploaders not wanting to dupe a pending or postponed upload. --- .../Controllers/TorrentPendingController.php | 34 ++++++++++ resources/sass/pages/_torrents.scss | 17 +++++ resources/views/partials/top_nav.blade.php | 6 ++ resources/views/torrent/pending.blade.php | 68 +++++++++++++++++++ routes/web.php | 1 + 5 files changed, 126 insertions(+) create mode 100644 app/Http/Controllers/TorrentPendingController.php create mode 100644 resources/views/torrent/pending.blade.php diff --git a/app/Http/Controllers/TorrentPendingController.php b/app/Http/Controllers/TorrentPendingController.php new file mode 100644 index 0000000000..79a6232556 --- /dev/null +++ b/app/Http/Controllers/TorrentPendingController.php @@ -0,0 +1,34 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Http\Controllers; + +use App\Models\Scopes\ApprovedScope; +use App\Models\Torrent; + +class TorrentPendingController extends Controller +{ + public function index(): \Illuminate\Contracts\View\Factory|\Illuminate\View\View + { + return view('torrent.pending', [ + 'torrents' => Torrent::withoutGlobalScope(ApprovedScope::class) + ->with(['category', 'type', 'resolution']) + ->where('status', '=', Torrent::PENDING) + ->orWhere('status', '=', Torrent::POSTPONED) + ->get(), + ]); + } +} diff --git a/resources/sass/pages/_torrents.scss b/resources/sass/pages/_torrents.scss index ac9e277b14..047fc16f20 100644 --- a/resources/sass/pages/_torrents.scss +++ b/resources/sass/pages/_torrents.scss @@ -1074,3 +1074,20 @@ th.similar-torrents__type { grid-template-columns: 13% 0.5fr 1fr 0.5fr 0.5fr 1fr 0.5fr 1fr; } } + +/* Torrent Moderation */ +.torrent--approved { + color: green; +} + +.torrent--pending { + color: yellow; +} + +.torrent--postponed { + color: orange; +} + +.torrent--rejected { + color: red; +} diff --git a/resources/views/partials/top_nav.blade.php b/resources/views/partials/top_nav.blade.php index 7e43bd1c29..8dc96273a1 100755 --- a/resources/views/partials/top_nav.blade.php +++ b/resources/views/partials/top_nav.blade.php @@ -25,6 +25,12 @@ {{ __('torrent.torrents') }} +
  • + + + {{ __('common.pending-torrents') }} + +
  • diff --git a/resources/views/torrent/pending.blade.php b/resources/views/torrent/pending.blade.php new file mode 100644 index 0000000000..aec752b987 --- /dev/null +++ b/resources/views/torrent/pending.blade.php @@ -0,0 +1,68 @@ +@extends('layout.default') + +@section('title') + {{ __('common.pending-torrents') }} - {{ config('other.title') }} +@endsection + +@section('meta') + +@endsection + +@section('breadcrumbs') +
  • +@endsection + +@section('main') +
    +

    {{ __('common.pending-torrents') }}

    +
    + + + + + + + + + + + + + + @foreach ($torrents as $torrent) + + + + + + + + + + @endforeach + +
    {{ __('torrent.name') }}{{ __('torrent.category') }}{{ __('torrent.type') }}{{ __('torrent.resolution') }}{{ __('torrent.size') }}{{ __('torrent.created_at') }}{{ __('torrent.status') }}
    {{ $torrent->name }}{{ $torrent->category->name }}{{ $torrent->type->name }}{{ $torrent->resolution->name ?? 'No Res' }}{{ $torrent->getSize() }}{{ $torrent->created_at->diffForHumans() }} + @switch($torrent->status) + @case(\App\Models\Torrent::PENDING) + + {{ __('torrent.pending') }} + + + @break + @case(\App\Models\Torrent::POSTPONED) + + {{ __('torrent.postponed') }} + + + @break + @default + + {{ __('common.unknown') }} + + @endswitch +
    +
    +
    +@endsection diff --git a/routes/web.php b/routes/web.php index 5e04b8dbe3..cc0c69985a 100644 --- a/routes/web.php +++ b/routes/web.php @@ -265,6 +265,7 @@ Route::post('/{id}/reseed', [App\Http\Controllers\ReseedController::class, 'store'])->name('reseed')->whereNumber('id'); Route::get('/similar/{category_id}.{tmdb}', [App\Http\Controllers\SimilarTorrentController::class, 'show'])->name('torrents.similar')->whereNumber('category_id'); Route::patch('/similar/{category}.{tmdbId}', [App\Http\Controllers\SimilarTorrentController::class, 'update'])->name('torrents.similar.update'); + Route::get('pending', [App\Http\Controllers\TorrentPendingController::class, 'index'])->name('torrents.pending'); }); Route::prefix('torrent')->group(function (): void { From 4230d62df060dff5594769f9a986101c58ea6618 Mon Sep 17 00:00:00 2001 From: Jay Sizzla Date: Mon, 9 Dec 2024 16:46:33 +0000 Subject: [PATCH 03/25] Add latest Torrent and Request comments to home page --- app/Http/Controllers/HomeController.php | 12 ++++ ...3_add_index_on_created_at_for_comments.php | 35 ++++++++++ lang/en/blocks.php | 3 + .../views/blocks/latest_comments.blade.php | 18 +++++ .../torrent/comment-listing.blade.php | 70 +++++++++++++++++++ resources/views/home/index.blade.php | 1 + 6 files changed, 139 insertions(+) create mode 100644 database/migrations/2024_12_09_175613_add_index_on_created_at_for_comments.php create mode 100644 resources/views/blocks/latest_comments.blade.php create mode 100644 resources/views/components/torrent/comment-listing.blade.php diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index d41a5d7792..710c3b6a43 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -17,6 +17,7 @@ namespace App\Http\Controllers; use App\Models\Article; +use App\Models\Comment; use App\Models\FeaturedTorrent; use App\Models\Group; use App\Models\Poll; @@ -104,6 +105,17 @@ public function index(Request $request): \Illuminate\Contracts\View\Factory|\Ill ->take(5) ->get(), ), + 'comments' => cache()->remember( + 'latest_comments', + $expiresAt, + fn () => Comment::query() + ->with('user', 'user.group', 'commentable') + ->whereHasMorph('commentable', [\App\Models\Torrent::class]) + ->orWhereHasMorph('commentable', [\App\Models\TorrentRequest::class]) + ->latest() + ->take(5) + ->get(), + ), 'featured' => cache()->remember( 'latest_featured', $expiresAt, diff --git a/database/migrations/2024_12_09_175613_add_index_on_created_at_for_comments.php b/database/migrations/2024_12_09_175613_add_index_on_created_at_for_comments.php new file mode 100644 index 0000000000..4b1c0ba8be --- /dev/null +++ b/database/migrations/2024_12_09_175613_add_index_on_created_at_for_comments.php @@ -0,0 +1,35 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class () extends Migration { + public function up(): void + { + Schema::table('comments', function (Blueprint $table) { + $table->index('created_at'); + }); + } + + public function down(): void + { + Schema::table('comments', function (Blueprint $table) { + $table->dropIndex(['created_at']); + }); + } +}; diff --git a/lang/en/blocks.php b/lang/en/blocks.php index 437877b2fd..3820c48840 100644 --- a/lang/en/blocks.php +++ b/lang/en/blocks.php @@ -34,6 +34,9 @@ // Latest Topics 'latest-topics' => 'Latest Topics', + // Latest Comments + 'latest-comments' => 'Latest Comments', + // Users Online 'active-in-last' => 'Active in last', 'users-online' => 'Users Online', diff --git a/resources/views/blocks/latest_comments.blade.php b/resources/views/blocks/latest_comments.blade.php new file mode 100644 index 0000000000..000ea8a977 --- /dev/null +++ b/resources/views/blocks/latest_comments.blade.php @@ -0,0 +1,18 @@ +
    +

    + + {{ __('blocks.latest-comments') }} + +

    +
    +
      + @forelse ($comments as $comment) +
    • + +
    • + @empty + No comments. + @endforelse +
    +
    +
    diff --git a/resources/views/components/torrent/comment-listing.blade.php b/resources/views/components/torrent/comment-listing.blade.php new file mode 100644 index 0000000000..cb2cbf409b --- /dev/null +++ b/resources/views/components/torrent/comment-listing.blade.php @@ -0,0 +1,70 @@ +@props([ + 'comment', +]) + +
    +
    + + + + On + + @switch($comment->commentable_type) + @case(\App\Models\Torrent::class) + {{ __('torrent.torrent') }} + + {{ $comment->commentable->name }} + + + @break + @case(\App\Models\TorrentRequest::class) + {{ __('request.request') }} + + {{ $comment->commentable->name }} + + + @break + @default + {{ __('common.unknown') }} + @endswitch + +
    + +
    + @joypixels($comment->getContentHtml()) +
    +
    diff --git a/resources/views/home/index.blade.php b/resources/views/home/index.blade.php index 9c774ffad5..078fb54b61 100644 --- a/resources/views/home/index.blade.php +++ b/resources/views/home/index.blade.php @@ -18,5 +18,6 @@ @livewire('top-users') @include('blocks.latest_topics') @include('blocks.latest_posts') + @include('blocks.latest_comments') @include('blocks.online') @endsection From 68e9e5125c600409ef27e4e2e9053267b74fd38f Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Mon, 9 Dec 2024 18:45:49 +0000 Subject: [PATCH 04/25] PHP Style Change (Laravel Pint CI) --- ...2024_12_09_175613_add_index_on_created_at_for_comments.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/database/migrations/2024_12_09_175613_add_index_on_created_at_for_comments.php b/database/migrations/2024_12_09_175613_add_index_on_created_at_for_comments.php index 4b1c0ba8be..aca0e4a9d3 100644 --- a/database/migrations/2024_12_09_175613_add_index_on_created_at_for_comments.php +++ b/database/migrations/2024_12_09_175613_add_index_on_created_at_for_comments.php @@ -21,14 +21,14 @@ return new class () extends Migration { public function up(): void { - Schema::table('comments', function (Blueprint $table) { + Schema::table('comments', function (Blueprint $table): void { $table->index('created_at'); }); } public function down(): void { - Schema::table('comments', function (Blueprint $table) { + Schema::table('comments', function (Blueprint $table): void { $table->dropIndex(['created_at']); }); } From db9cf0e8cc6a36cc57bb6dc02fbec0ab7cb101c0 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Wed, 11 Dec 2024 01:00:28 -0500 Subject: [PATCH 05/25] fix: UserResource --- app/Http/Resources/UserResource.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Resources/UserResource.php b/app/Http/Resources/UserResource.php index 4d081d7404..4b0dd07d0e 100644 --- a/app/Http/Resources/UserResource.php +++ b/app/Http/Resources/UserResource.php @@ -35,8 +35,8 @@ public function toArray($request): array 'downloaded' => str_replace("\u{00A0}", ' ', $this->formatted_downloaded), 'ratio' => $this->formatted_ratio, 'buffer' => str_replace("\u{00A0}", ' ', $this->formatted_buffer), - 'seeding' => \count($this->seedingTorrents) ? $this->seedingTorrents : 0, - 'leeching' => \count($this->leechingTorrents) ? $this->leechingTorrents : 0, + 'seeding' => \count($this->seedingTorrents), + 'leeching' => \count($this->leechingTorrents), 'seedbonus' => $this->seedbonus, 'hit_and_runs' => $this->hitandruns, ]; From 56f99aff18635b9c5100d55622c8235e339cfa05 Mon Sep 17 00:00:00 2001 From: Jay Sizzla Date: Fri, 13 Dec 2024 13:11:04 +0000 Subject: [PATCH 06/25] Only show title when the user is not set to anonymous --- resources/views/components/torrent/comment-listing.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/components/torrent/comment-listing.blade.php b/resources/views/components/torrent/comment-listing.blade.php index cb2cbf409b..8d7247818c 100644 --- a/resources/views/components/torrent/comment-listing.blade.php +++ b/resources/views/components/torrent/comment-listing.blade.php @@ -58,7 +58,7 @@ class="{{ config('other.font-awesome') }} fa-circle text-red" - @if (! empty($comment->user->title)) + @if (! empty($comment->user->title) && ! $comment->anon)

    {{ $comment->user->title }}

    From 97b058872c4a47cfcf763503c9fccf1c733afdc1 Mon Sep 17 00:00:00 2001 From: Roardom Date: Sun, 8 Dec 2024 00:24:02 +0000 Subject: [PATCH 07/25] fix: only show year in similar torrent deletion --- app/Http/Livewire/SimilarTorrent.php | 6 +++--- app/Models/Movie.php | 2 +- app/Models/Tv.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/Http/Livewire/SimilarTorrent.php b/app/Http/Livewire/SimilarTorrent.php index 60d4be435a..f5fe5b3890 100644 --- a/app/Http/Livewire/SimilarTorrent.php +++ b/app/Http/Livewire/SimilarTorrent.php @@ -423,9 +423,9 @@ final public function deleteRecords(): void $names = []; $users = []; $title = match (true) { - $this->category->movie_meta => ($movie = Movie::find($this->tmdbId))->title.' ('.$movie->release_date.')', - $this->category->tv_meta => ($tv = Tv::find($this->tmdbId))->name.' ('.$tv->first_air_date.')', - $this->category->game_meta => ($game = Game::find($this->igdbId))->name.' ('.$game->first_release_date.')', + $this->category->movie_meta => ($movie = Movie::find($this->tmdbId))->title.' ('.$movie->release_date->format('Y').')', + $this->category->tv_meta => ($tv = Tv::find($this->tmdbId))->name.' ('.$tv->first_air_date->format('Y').')', + $this->category->game_meta => ($game = Game::find($this->igdbId))->name.' ('.$game->first_release_date->format('Y').')', default => $torrents->pluck('name')->join(', '), }; diff --git a/app/Models/Movie.php b/app/Models/Movie.php index e8083f3a90..c7339f0328 100644 --- a/app/Models/Movie.php +++ b/app/Models/Movie.php @@ -37,7 +37,7 @@ * @property string|null $overview * @property string|null $popularity * @property string|null $poster - * @property string|null $release_date + * @property \Illuminate\Support\Carbon|null $release_date * @property string|null $revenue * @property string|null $runtime * @property string|null $status diff --git a/app/Models/Tv.php b/app/Models/Tv.php index c25166a6d7..02681745d5 100644 --- a/app/Models/Tv.php +++ b/app/Models/Tv.php @@ -36,11 +36,11 @@ * @property int|null $count_total_episodes * @property int|null $number_of_seasons * @property string|null $episode_run_time - * @property string|null $first_air_date + * @property \Illuminate\Support\Carbon|null $first_air_date * @property string|null $status * @property string|null $homepage * @property int|null $in_production - * @property string|null $last_air_date + * @property \Illuminate\Support\Carbon|null $last_air_date * @property string|null $next_episode_to_air * @property string|null $origin_country * @property string|null $original_language From 6a34d7609c38830b1fad2db68ae97c0c87228198 Mon Sep 17 00:00:00 2001 From: Roardom Date: Mon, 16 Dec 2024 10:21:36 +0000 Subject: [PATCH 08/25] fix: conversation delete button The `$user` variable in the for loop here is overwriting the existing `$user` variable used for the delete conversation form. We need to choose a different variable name. --- resources/views/user/conversations/show.blade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/views/user/conversations/show.blade.php b/resources/views/user/conversations/show.blade.php index 11a5605222..2bc8e7cb03 100644 --- a/resources/views/user/conversations/show.blade.php +++ b/resources/views/user/conversations/show.blade.php @@ -70,9 +70,9 @@ class="breadcrumb__link"

    {{ __('common.users') }}

      - @foreach ($conversation->users as $user) + @foreach ($conversation->users as $conversationUser)
    • - +
    • @endforeach
    From 1e342d98fee17bf0bf3bf9046989c9a3d4027252 Mon Sep 17 00:00:00 2001 From: Roardom Date: Tue, 3 Dec 2024 01:38:26 +0000 Subject: [PATCH 09/25] add: edit forum permissions when creating/editing group --- .../Controllers/Staff/GroupController.php | 38 ++-- app/Http/Requests/Staff/StoreGroupRequest.php | 90 +++++--- .../Requests/Staff/UpdateGroupRequest.php | 90 +++++--- .../js/components/alpine/checkboxGrid.js | 12 +- resources/views/Staff/group/create.blade.php | 207 +++++++++++++----- resources/views/Staff/group/edit.blade.php | 186 +++++++++++----- .../Controllers/Staff/GroupControllerTest.php | 88 +++++--- 7 files changed, 495 insertions(+), 216 deletions(-) diff --git a/app/Http/Controllers/Staff/GroupController.php b/app/Http/Controllers/Staff/GroupController.php index 1dc02d6239..e9ebc2f9d0 100644 --- a/app/Http/Controllers/Staff/GroupController.php +++ b/app/Http/Controllers/Staff/GroupController.php @@ -19,9 +19,8 @@ use App\Http\Controllers\Controller; use App\Http\Requests\Staff\StoreGroupRequest; use App\Http\Requests\Staff\UpdateGroupRequest; -use App\Models\Forum; +use App\Models\ForumCategory; use App\Models\Group; -use App\Models\ForumPermission; use App\Services\Unit3dAnnounce; use Illuminate\Support\Str; @@ -45,7 +44,14 @@ public function index(): \Illuminate\Contracts\View\Factory|\Illuminate\View\Vie */ public function create(): \Illuminate\Contracts\View\Factory|\Illuminate\View\View { - return view('Staff.group.create'); + return view('Staff.group.create', [ + 'forumCategories' => ForumCategory::query() + ->with([ + 'forums' => fn ($query) => $query->orderBy('position') + ]) + ->orderBy('position') + ->get(), + ]); } /** @@ -53,17 +59,9 @@ public function create(): \Illuminate\Contracts\View\Factory|\Illuminate\View\Vi */ public function store(StoreGroupRequest $request): \Illuminate\Http\RedirectResponse { - $group = Group::create(['slug' => Str::slug($request->name)] + $request->validated()); - - foreach (Forum::pluck('id') as $collection) { - ForumPermission::create([ - 'forum_id' => $collection, - 'group_id' => $group->id, - 'read_topic' => false, - 'reply_topic' => false, - 'start_topic' => false, - ]); - } + $group = Group::create(['slug' => Str::slug($request->validated('group.name'))] + $request->validated('group')); + + $group->permissions()->upsert($request->validated('permissions'), ['forum_id', 'group_id']); Unit3dAnnounce::addGroup($group); @@ -77,7 +75,13 @@ public function store(StoreGroupRequest $request): \Illuminate\Http\RedirectResp public function edit(Group $group): \Illuminate\Contracts\View\Factory|\Illuminate\View\View { return view('Staff.group.edit', [ - 'group' => $group, + 'group' => $group, + 'forumCategories' => ForumCategory::query() + ->with([ + 'forums' => fn ($query) => $query->orderBy('position') + ]) + ->orderBy('position') + ->get(), ]); } @@ -86,7 +90,9 @@ public function edit(Group $group): \Illuminate\Contracts\View\Factory|\Illumina */ public function update(UpdateGroupRequest $request, Group $group): \Illuminate\Http\RedirectResponse { - $group->update(['slug' => Str::slug($request->name)] + $request->validated()); + $group->update(['slug' => Str::slug($request->validated('group.name'))] + $request->validated('group')); + + $group->permissions()->upsert($request->validated('permissions'), ['forum_id', 'group_id']); cache()->forget('group:'.$group->id); diff --git a/app/Http/Requests/Staff/StoreGroupRequest.php b/app/Http/Requests/Staff/StoreGroupRequest.php index 11a5e520a0..e5c63ccfeb 100644 --- a/app/Http/Requests/Staff/StoreGroupRequest.php +++ b/app/Http/Requests/Staff/StoreGroupRequest.php @@ -38,149 +38,173 @@ public function authorize(Request $request): bool public function rules(Request $request): array { return [ - 'name' => [ + 'group.name' => [ 'required', 'string', - 'unique:groups', + 'unique:groups,name', ], - 'position' => [ + 'group.position' => [ 'required', 'integer', ], - 'level' => [ + 'group.level' => [ 'required', 'integer', ], - 'download_slots' => [ + 'group.download_slots' => [ 'nullable', 'integer', ], - 'description' => [ + 'group.description' => [ 'nullable', ], - 'color' => [ + 'group.color' => [ 'required', ], - 'icon' => [ + 'group.icon' => [ 'required', ], - 'effect' => [ + 'group.effect' => [ 'sometimes', ], - 'is_uploader' => [ + 'group.is_uploader' => [ 'required', 'boolean', ], - 'is_internal' => [ + 'group.is_internal' => [ 'required', 'boolean', ], - 'is_editor' => [ + 'group.is_editor' => [ 'required', 'boolean', ], - 'is_torrent_modo' => [ + 'group.is_torrent_modo' => [ 'required', 'boolean', ], - 'is_modo' => [ + 'group.is_modo' => [ 'required', 'boolean', ], - 'is_admin' => [ + 'group.is_admin' => [ 'required', 'boolean', ], - 'is_owner' => [ + 'group.is_owner' => [ 'required', 'boolean', ], - 'is_trusted' => [ + 'group.is_trusted' => [ 'required', 'boolean', ], - 'is_immune' => [ + 'group.is_immune' => [ 'required', 'boolean', ], - 'is_freeleech' => [ + 'group.is_freeleech' => [ 'required', 'boolean', ], - 'is_double_upload' => [ + 'group.is_double_upload' => [ 'required', 'boolean', ], - 'is_incognito' => [ + 'group.is_incognito' => [ 'required', 'boolean', ], - 'can_chat' => [ + 'group.can_chat' => [ 'required', 'boolean', ], - 'can_comment' => [ + 'group.can_comment' => [ 'required', 'boolean', ], - 'can_invite' => [ + 'group.can_invite' => [ 'required', 'boolean', ], - 'can_request' => [ + 'group.can_request' => [ 'required', 'boolean', ], - 'can_upload' => [ + 'group.can_upload' => [ 'required', 'boolean', ], - 'autogroup' => [ + 'group.autogroup' => [ 'required', 'boolean', ], - 'min_uploaded' => [ + 'group.min_uploaded' => [ Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', ], 'prohibited'), ], - 'min_ratio' => [ + 'group.min_ratio' => [ Rule::when($request->boolean('autogroup'), [ 'sometimes', 'min:0', 'max:99.99', ], 'prohibited'), ], - 'min_age' => [ + 'group.min_age' => [ Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', ], 'prohibited'), ], - 'min_avg_seedtime' => [ + 'group.min_avg_seedtime' => [ Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', ], 'prohibited'), ], - 'min_seedsize' => [ + 'group.min_seedsize' => [ Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', ], 'prohibited'), ], - 'min_uploads' => [ + 'group.min_uploads' => [ Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', ], 'prohibited'), ], + 'permissions' => [ + 'required', + 'array', + ], + 'permissions.*' => [ + 'required', + 'array:forum_id,read_topic,reply_topic,start_topic', + ], + 'permissions.*.forum_id' => [ + 'required', + 'exists:forums,id', + ], + 'permissions.*.read_topic' => [ + 'required', + 'boolean', + ], + 'permissions.*.reply_topic' => [ + 'required', + 'boolean', + ], + 'permissions.*.start_topic' => [ + 'required', + 'boolean', + ], ]; } } diff --git a/app/Http/Requests/Staff/UpdateGroupRequest.php b/app/Http/Requests/Staff/UpdateGroupRequest.php index bc59cd071e..f7fce5250d 100644 --- a/app/Http/Requests/Staff/UpdateGroupRequest.php +++ b/app/Http/Requests/Staff/UpdateGroupRequest.php @@ -42,151 +42,175 @@ public function rules(Request $request): array $group = $request->route('group'); return [ - 'name' => [ + 'group.name' => [ Rule::when(! $group->system_required, [ 'required', 'string', ]), - Rule::prohibitedIf($group->system_required && $request->name !== $group->name), + Rule::prohibitedIf($group->system_required && $request->group->name !== $group->name), ], - 'position' => [ + 'group.position' => [ 'required', 'integer', ], - 'level' => [ + 'group.level' => [ 'required', 'integer', ], - 'download_slots' => [ + 'group.download_slots' => [ 'nullable', 'integer', ], - 'description' => [ + 'group.description' => [ 'nullable', ], - 'color' => [ + 'group.color' => [ 'required', ], - 'icon' => [ + 'group.icon' => [ 'required', ], - 'effect' => [ + 'group.effect' => [ 'sometimes', ], - 'is_uploader' => [ + 'group.is_uploader' => [ 'required', 'boolean', ], - 'is_internal' => [ + 'group.is_internal' => [ 'required', 'boolean', ], - 'is_editor' => [ + 'group.is_editor' => [ 'required', 'boolean', ], - 'is_torrent_modo' => [ + 'group.is_torrent_modo' => [ 'required', 'boolean', ], - 'is_modo' => [ + 'group.is_modo' => [ 'required', 'boolean', ], - 'is_admin' => [ + 'group.is_admin' => [ 'required', 'boolean', ], - 'is_owner' => [ + 'group.is_owner' => [ 'required', 'boolean', ], - 'is_trusted' => [ + 'group.is_trusted' => [ 'required', 'boolean', ], - 'is_immune' => [ + 'group.is_immune' => [ 'required', 'boolean', ], - 'is_freeleech' => [ + 'group.is_freeleech' => [ 'required', 'boolean', ], - 'is_double_upload' => [ + 'group.is_double_upload' => [ 'required', 'boolean', ], - 'is_incognito' => [ + 'group.is_incognito' => [ 'required', 'boolean', ], - 'can_chat' => [ + 'group.can_chat' => [ 'required', 'boolean', ], - 'can_comment' => [ + 'group.can_comment' => [ 'required', 'boolean', ], - 'can_invite' => [ + 'group.can_invite' => [ 'required', 'boolean', ], - 'can_request' => [ + 'group.can_request' => [ 'required', 'boolean', ], - 'can_upload' => [ + 'group.can_upload' => [ 'required', 'boolean', ], - 'autogroup' => [ + 'group.autogroup' => [ 'required', 'boolean', ], - 'min_uploaded' => [ + 'group.min_uploaded' => [ Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', ], 'nullable'), ], - 'min_ratio' => [ + 'group.min_ratio' => [ Rule::when($request->boolean('autogroup'), [ 'sometimes', 'min:0', 'max:99.99', ], 'nullable'), ], - 'min_age' => [ + 'group.min_age' => [ Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', ], 'nullable'), ], - 'min_avg_seedtime' => [ + 'group.min_avg_seedtime' => [ Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', ], 'nullable'), ], - 'min_seedsize' => [ + 'group.min_seedsize' => [ Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', ], 'nullable'), ], - 'min_uploads' => [ + 'group.min_uploads' => [ Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', ], 'nullable'), ], + 'permissions' => [ + 'required', + 'array', + ], + 'permissions.*' => [ + 'required', + 'array:forum_id,read_topic,reply_topic,start_topic', + ], + 'permissions.*.forum_id' => [ + 'required', + 'exists:forums,id', + ], + 'permissions.*.read_topic' => [ + 'required', + 'boolean', + ], + 'permissions.*.reply_topic' => [ + 'required', + 'boolean', + ], + 'permissions.*.start_topic' => [ + 'required', + 'boolean', + ], ]; } diff --git a/resources/js/components/alpine/checkboxGrid.js b/resources/js/components/alpine/checkboxGrid.js index 262a68a1b6..f7e8b54eb9 100644 --- a/resources/js/components/alpine/checkboxGrid.js +++ b/resources/js/components/alpine/checkboxGrid.js @@ -16,14 +16,16 @@ document.addEventListener('alpine:init', () => { ['x-bind:style']() { return { cursor: 'pointer', + userSelect: 'none', }; }, }, rowHeader: { ['x-on:click']() { + let rowspan = Number(this.$el.rowSpan); let rowIndex = this.$el.parentElement.sectionRowIndex + 1; let cells = this.$root.querySelectorAll( - `tbody tr:nth-child(${rowIndex}) td > input[type="checkbox"]`, + `tbody tr:nth-child(n + ${rowIndex}):nth-child(-n + ${rowIndex + (rowspan ? rowspan - 1 : 0)}) td > input[type="checkbox"]`, ); if (Array.from(cells).some((el) => el.checked)) { @@ -35,8 +37,16 @@ document.addEventListener('alpine:init', () => { ['x-bind:style']() { return { cursor: 'pointer', + userSelect: 'none', }; }, }, + cell: { + ['x-on:click.self']() { + let checkbox = this.$el.querySelector('input[type="checkbox"'); + + checkbox.checked = !checkbox.checked; + }, + }, })); }); diff --git a/resources/views/Staff/group/create.blade.php b/resources/views/Staff/group/create.blade.php index 3c807066af..4607b547ca 100644 --- a/resources/views/Staff/group/create.blade.php +++ b/resources/views/Staff/group/create.blade.php @@ -25,7 +25,13 @@
    @csrf

    - + @@ -35,7 +41,7 @@ id="description" class="form__text" type="text" - name="description" + name="group[description]" placeholder=" " />

    - +

    @@ -63,7 +75,7 @@ class="form__text" id="download_slots" class="form__text" type="text" - name="download_slots" + name="group[download_slots]" placeholder=" " />

    - +

    - + @@ -87,7 +111,7 @@ class="form__text" id="effect" class="form__text" type="text" - name="effect" + name="group[effect]" value="none" placeholder="GIF Effect" /> @@ -96,44 +120,44 @@ class="form__text"

    - +

    - +

    - +

    - + @@ -141,165 +165,165 @@ class="form__checkbox"

    - +

    - +

    - +

    - +

    - +

    - +

    - +

    - +

    - +

    - +

    - +

    - +

    - +

    - +

    - +

    +
    + +
    + + + + + + + + + + + + @foreach ($forumCategories as $forumCategory) + @foreach ($forumCategory->forums as $forum) + + @if ($loop->first) + + @else + + @endif + + + + + + + @endforeach + @endforeach + +
    Forum CategoryForumRead topicsStart new topicReply to topics
    + {{ $forum->category->name }} + + {{ $forum->name }} + + + + + + + + + + +
    +
    +

    +
    + +
    + + + + + + + + + + + + @foreach ($forumCategories as $forumCategory) + @foreach ($forumCategory->forums as $forum) + + @if ($loop->first) + + @else + + @endif + + + + + + + @endforeach + @endforeach + +
    Forum CategoryForumRead topicsStart new topicReply to topics
    + {{ $forum->category->name }} + + {{ $forum->name }} + + + + permissions->where('forum_id', '=', $forum->id)->first()?->read_topic) + /> + + + permissions->where('forum_id', '=', $forum->id)->first()?->start_topic) + /> + + + permissions->where('forum_id', '=', $forum->id)->first()?->reply_topic) + /> +
    +
    +

    diff --git a/resources/views/forum/topic/show.blade.php b/resources/views/forum/topic/show.blade.php index cf2e2544f2..5ac191839f 100644 --- a/resources/views/forum/topic/show.blade.php +++ b/resources/views/forum/topic/show.blade.php @@ -47,7 +47,7 @@ class="breadcrumb__link" @csrf - @livewire('bbcode-input', ['name' => 'content', 'label' => __('forum.post') ]) + @livewire('bbcode-input', ['name' => 'content', 'label' => __('forum.post')])