diff --git a/app/Extensions/helper/helpers.php b/app/Extensions/helper/helpers.php index 8550d9477..96c012bce 100644 --- a/app/Extensions/helper/helpers.php +++ b/app/Extensions/helper/helpers.php @@ -95,7 +95,8 @@ if (! function_exists('makeFieldLinks')) { if ($i > 7) { break; } - $newArr[] = ''.$ta.''; + $escaped = e($ta); + $newArr[] = ''.$escaped.''; $i++; } @@ -693,6 +694,54 @@ if (! function_exists('formatBytes')) { } } +if (! function_exists('formatDate')) { + /** + * Format a date as Y-m-d (house date style). + */ + function formatDate(Carbon|DateTimeInterface|string|null $date): string + { + if ($date === null || $date === '') { + return ''; + } + + $date = $date instanceof DateTimeInterface ? $date : Carbon::parse($date); + + return $date->format('Y-m-d'); + } +} + +if (! function_exists('formatDateTime')) { + /** + * Format a date as Y-m-d H:i (house datetime style). + */ + function formatDateTime(Carbon|DateTimeInterface|string|null $date): string + { + if ($date === null || $date === '') { + return ''; + } + + $date = $date instanceof DateTimeInterface ? $date : Carbon::parse($date); + + return $date->format('Y-m-d H:i'); + } +} + +if (! function_exists('formatDateTimeSeconds')) { + /** + * Format a date as Y-m-d H:i:s (house datetime style with seconds). + */ + function formatDateTimeSeconds(Carbon|DateTimeInterface|string|null $date): string + { + if ($date === null || $date === '') { + return ''; + } + + $date = $date instanceof DateTimeInterface ? $date : Carbon::parse($date); + + return $date->format('Y-m-d H:i:s'); + } +} + if (! function_exists('csp_nonce')) { /** * Generate a CSP nonce for inline scripts diff --git a/app/Http/Controllers/DetailsController.php b/app/Http/Controllers/DetailsController.php index 0905c077f..473c8d9ff 100644 --- a/app/Http/Controllers/DetailsController.php +++ b/app/Http/Controllers/DetailsController.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace App\Http\Controllers; +use App\Models\Country; use App\Models\DnzbFailure; use App\Models\Predb; use App\Models\Release; @@ -109,7 +110,7 @@ class DetailsController extends BasePageController if (Settings::settingValue('trailers_display')) { $trailer = empty($mov['trailer']) ? $this->movieService->getTrailer($data['imdbid']) : $mov['trailer']; if ($trailer) { - $mov['trailer'] = sprintf('', Settings::settingValue('trailers_size_x'), Settings::settingValue('trailers_size_y'), $trailer); + $mov['trailer'] = sprintf('', Settings::settingValue('trailers_size_x'), Settings::settingValue('trailers_size_y'), e($trailer)); } } } @@ -158,6 +159,20 @@ class DetailsController extends BasePageController $pre = Predb::getForRelease($data['predb_id']); + // Resolve AniDB country code to a Country model/name here so the view stays query-free + $anidbCountryCode = null; + if (is_object($AniDBAPIArray)) { + $anidbCountryCode = $AniDBAPIArray->country ?? null; + } elseif (is_array($AniDBAPIArray)) { + $anidbCountryCode = $AniDBAPIArray['country'] ?? null; + } + $anidbCountryModel = null; + $anidbCountryName = null; + if (! empty($anidbCountryCode)) { + $anidbCountryModel = Country::query()->find($anidbCountryCode); + $anidbCountryName = $anidbCountryModel->name ?? $anidbCountryCode; + } + $this->viewData = array_merge($this->viewData, [ 'release' => $data, 'reVideo' => $reVideo, @@ -166,6 +181,8 @@ class DetailsController extends BasePageController 'show' => $showInfo, 'movie' => $mov, 'anidb' => $AniDBAPIArray, + 'anidbCountryModel' => $anidbCountryModel, + 'anidbCountryName' => $anidbCountryName, 'music' => $mus, 'con' => $con, 'game' => $game, diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index c121f66a3..007b36777 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -181,6 +181,11 @@ class ProfileController extends BasePageController } } + // Keep the composer's cached per-user data in sync with theme changes + if ($request->hasAny(['theme_preference', 'color_scheme'])) { + Cache::forget('composer_user_'.$userid); + } + // Update timezone preference if ($request->has('timezone')) { $timezoneValue = $request->input('timezone'); @@ -305,6 +310,9 @@ class ProfileController extends BasePageController } $user->save(); + // Keep the composer's cached per-user data in sync with theme changes + Cache::forget('composer_user_'.$user->id); + return response()->json([ 'success' => true, 'theme_preference' => $user->theme_preference, diff --git a/app/Models/Content.php b/app/Models/Content.php index 65ccb52ab..ccad39a0e 100644 --- a/app/Models/Content.php +++ b/app/Models/Content.php @@ -6,6 +6,7 @@ namespace App\Models; use App\Enums\UserRole; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; /** @@ -201,4 +202,56 @@ class Content extends Model { return $this->contenttype === self::TYPE_INDEX; } + + /** + * Resolve the content URL: external URLs are used as-is (domains without + * protocol get https://), internal paths are prefixed with the site URL. + * + * @return Attribute + */ + protected function resolvedUrl(): Attribute + { + return Attribute::make( + get: function (): ?string { + $url = $this->url; + + if (empty($url)) { + return null; + } + + if (str_starts_with($url, 'http://') || str_starts_with($url, 'https://')) { + return $url; + } + + // Domain pattern without protocol (e.g. google.com, chatgpt.ai) + if (! str_starts_with($url, '/') && preg_match('/^[a-zA-Z0-9][a-zA-Z0-9-]*\.[a-zA-Z]{2,}/', $url)) { + return 'https://'.$url; + } + + return url($url); + } + ); + } + + /** + * Whether the content URL points to an external site. + * + * @return Attribute + */ + protected function isExternalUrl(): Attribute + { + return Attribute::make( + get: function (): bool { + $url = $this->url; + + if (empty($url)) { + return false; + } + + return str_starts_with($url, 'http://') + || str_starts_with($url, 'https://') + || (! str_starts_with($url, '/') && preg_match('/^[a-zA-Z0-9][a-zA-Z0-9-]*\.[a-zA-Z]{2,}/', $url)); + } + ); + } } diff --git a/app/View/Composers/AdminDataComposer.php b/app/View/Composers/AdminDataComposer.php index a28ea2e61..a71453c4f 100644 --- a/app/View/Composers/AdminDataComposer.php +++ b/app/View/Composers/AdminDataComposer.php @@ -38,6 +38,8 @@ class AdminDataComposer 'loggedin' => $user !== null, 'isadmin' => $isNntmuxUser && $user->hasRole('Admin'), 'ismod' => $isNntmuxUser && $user->hasRole('Moderator'), + 'userTheme' => $isNntmuxUser ? ($user->theme_preference ?? 'light') : 'light', + 'userColorScheme' => $isNntmuxUser ? ($user->color_scheme ?? 'blue') : 'blue', ]); } diff --git a/app/View/Composers/GlobalDataComposer.php b/app/View/Composers/GlobalDataComposer.php index 118741a6c..7ea20dd14 100644 --- a/app/View/Composers/GlobalDataComposer.php +++ b/app/View/Composers/GlobalDataComposer.php @@ -97,12 +97,16 @@ class GlobalDataComposer 'ismod' => $userdata->hasRole('Moderator'), 'parentcatlist' => $parentcatlist, 'header_menu_cat' => request()->input('t', ''), + 'userTheme' => $userdata->theme_preference ?? 'light', + 'userColorScheme' => $userdata->color_scheme ?? 'blue', ]); } else { $viewData = array_merge($viewData, [ 'isadmin' => false, 'ismod' => false, 'loggedin' => false, + 'userTheme' => 'light', + 'userColorScheme' => 'blue', ]); } diff --git a/resources/views/admin/anidb/edit.blade.php b/resources/views/admin/anidb/edit.blade.php index 64d8db1aa..94603c4a2 100644 --- a/resources/views/admin/anidb/edit.blade.php +++ b/resources/views/admin/anidb/edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -130,8 +130,7 @@ @if($hasCover) {{ $anime['title'] }} + class="max-w-full h-auto mx-auto rounded shadow-lg max-h-[400px]"> @else
@@ -257,6 +256,6 @@
-
+
@endsection diff --git a/resources/views/admin/anidb/index.blade.php b/resources/views/admin/anidb/index.blade.php index 2e16a4296..c7934136e 100644 --- a/resources/views/admin/anidb/index.blade.php +++ b/resources/views/admin/anidb/index.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -43,20 +43,17 @@
-
- - - - - - - - - - - - - + + + Cover + Title + Type + Start Date + End Date + Rating + Actions + + @forelse($anidblist as $anime) @empty + @php + $anidbEmptyTitle = $animetitle ? 'No anime found for "'.$animetitle.'"' : 'No anime available'; + @endphp - @endforelse - -
CoverTitleTypeStart DateEnd DateRatingActions
@@ -123,28 +120,22 @@
- @if($animetitle) -
- -

No anime found for "{{ $animetitle }}"

- +
+ + @if($animetitle) + Clear search and view all - - @else -
- -

No anime available

-
- @endif + @endif +
-
+
@@ -157,7 +148,7 @@
-
+
{{-- Styles moved to resources/css/csp-safe.css --}} diff --git a/resources/views/admin/anidb/remove.blade.php b/resources/views/admin/anidb/remove.blade.php index e2ff73cc3..f507423a9 100644 --- a/resources/views/admin/anidb/remove.blade.php +++ b/resources/views/admin/anidb/remove.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -111,7 +111,7 @@ @endif
-
+
@endsection diff --git a/resources/views/admin/blacklist/edit.blade.php b/resources/views/admin/blacklist/edit.blade.php index 73bdc1077..4bedd0712 100644 --- a/resources/views/admin/blacklist/edit.blade.php +++ b/resources/views/admin/blacklist/edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -177,7 +177,7 @@
-
+
{{-- Scripts moved to resources/js/csp-safe.js --}} diff --git a/resources/views/admin/books/edit.blade.php b/resources/views/admin/books/edit.blade.php index 4c8626384..bee816438 100644 --- a/resources/views/admin/books/edit.blade.php +++ b/resources/views/admin/books/edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -185,7 +185,7 @@
-
+
{{-- Scripts moved to resources/js/csp-safe.js --}} diff --git a/resources/views/admin/books/index.blade.php b/resources/views/admin/books/index.blade.php index 9eae83d41..c0b3c1de9 100644 --- a/resources/views/admin/books/index.blade.php +++ b/resources/views/admin/books/index.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -16,20 +16,17 @@
-
- - - - - - - - - - - - - + + + Cover + Title + Author + Publisher + Published + Created + Actions + + @forelse($bookList as $book) @endforelse - -
CoverTitleAuthorPublisherPublishedCreatedActions
@@ -37,6 +34,7 @@ {{ $book->title }} @else
@@ -68,7 +66,7 @@ @endif
- {{ $book->created_at ? $book->created_at->format('Y-m-d') : '—' }} + {{ $book->created_at ? formatDate($book->created_at) : '—' }}
-
+
{{ $bookList->links() }}
-
+
@endsection diff --git a/resources/views/admin/comments/index.blade.php b/resources/views/admin/comments/index.blade.php index fea8d2226..e247e9ccc 100644 --- a/resources/views/admin/comments/index.blade.php +++ b/resources/views/admin/comments/index.blade.php @@ -83,7 +83,7 @@
-
{{ $comment->created_at ? $comment->created_at->format('Y-m-d') : '—' }}
+
{{ $comment->created_at ? formatDate($comment->created_at) : '—' }}
{{ $comment->created_at ? $comment->created_at->format('H:i:s') : '' }}
diff --git a/resources/views/admin/console/edit.blade.php b/resources/views/admin/console/edit.blade.php index 3d3f2d462..36e9898ec 100644 --- a/resources/views/admin/console/edit.blade.php +++ b/resources/views/admin/console/edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -236,7 +236,7 @@
-
+
{{-- Scripts moved to resources/js/csp-safe.js --}} diff --git a/resources/views/admin/console/index.blade.php b/resources/views/admin/console/index.blade.php index 6e6f4eadc..d2704c6a2 100644 --- a/resources/views/admin/console/index.blade.php +++ b/resources/views/admin/console/index.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -16,20 +16,17 @@
-
- - - - - - - - - - - - - + + + Cover + Title + Platform + Publisher + Release Date + ESRB + Actions + + @forelse($consoleList as $console) @endforelse - -
CoverTitlePlatformPublisherRelease DateESRBActions
@@ -120,14 +117,12 @@
-
+
{{ $consoleList->links() }}
-
+
@endsection diff --git a/resources/views/admin/content/add.blade.php b/resources/views/admin/content/add.blade.php index 7719b1f20..cde59daa3 100644 --- a/resources/views/admin/content/add.blade.php +++ b/resources/views/admin/content/add.blade.php @@ -6,7 +6,7 @@ $isEditing = filled($contentId); @endphp
-
+

@@ -182,7 +182,7 @@

-
+
@endsection diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index f6483f439..c2f502ee8 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -18,7 +18,7 @@ data-refresh-interval="{{ 60 * 1000 }}">
-
+

Admin Dashboard

@@ -31,7 +31,7 @@

Auto-refreshes every minute

-
+
@@ -230,8 +230,8 @@

{{ $registrationStatus['active_period']->name }}

- {{ $registrationStatus['active_period']->starts_at->format('Y-m-d H:i') }} to - {{ $registrationStatus['active_period']->ends_at->format('Y-m-d H:i') }} + {{ formatDateTime($registrationStatus['active_period']->starts_at) }} to + {{ formatDateTime($registrationStatus['active_period']->ends_at) }}

This window is active on the public registration form right now.

@@ -240,8 +240,8 @@

{{ $nextRegistrationPeriod->name }}

- {{ $nextRegistrationPeriod->starts_at->format('Y-m-d H:i') }} to - {{ $nextRegistrationPeriod->ends_at->format('Y-m-d H:i') }} + {{ formatDateTime($nextRegistrationPeriod->starts_at) }} to + {{ formatDateTime($nextRegistrationPeriod->ends_at) }}

The next temporary public signup window is already scheduled.

@@ -510,7 +510,7 @@ @endif - +
@endsection diff --git a/resources/views/admin/games/edit.blade.php b/resources/views/admin/games/edit.blade.php index e4a6b62d4..3780dc230 100644 --- a/resources/views/admin/games/edit.blade.php +++ b/resources/views/admin/games/edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+

@@ -209,6 +209,6 @@

-
+
@endsection diff --git a/resources/views/admin/games/index.blade.php b/resources/views/admin/games/index.blade.php index 983b4b76c..e3e741ec5 100644 --- a/resources/views/admin/games/index.blade.php +++ b/resources/views/admin/games/index.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -65,21 +65,18 @@ @if(!empty($gamelist) && count($gamelist) > 0) -
- - - - - - - - - - - - - - + + + ID + Title + Publisher + Genre + ESRB + Release Date + Cover + Actions + + @foreach($gamelist as $game) @endforeach - -
IDTitlePublisherGenreESRBRelease DateCoverActions
@@ -124,22 +121,14 @@
-
+ @else -
- -

- @if(!empty($lastSearch)) - No games found matching "{{ $lastSearch }}". - @else - No games found in the database. - @endif -

-
+ @php + $gamesEmptyMessage = ! empty($lastSearch) ? 'No games found matching "'.$lastSearch.'".' : 'No games found in the database.'; + @endphp + @endif -
+
@endsection diff --git a/resources/views/admin/gdpr/index.blade.php b/resources/views/admin/gdpr/index.blade.php index 3ee63bb90..a29076ab3 100644 --- a/resources/views/admin/gdpr/index.blade.php +++ b/resources/views/admin/gdpr/index.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+

@@ -51,24 +51,21 @@

-
- - - - - - - - - - - - - + + + ID + Requested + User + Type + Status + Completed + Actions + + @forelse($requests as $gdprRequest) - + - + @endforelse - -
IDRequestedUserTypeStatusCompletedActions
#{{ $gdprRequest->id }}{{ $gdprRequest->created_at?->format('Y-m-d H:i') }}{{ formatDateTime($gdprRequest->created_at) }}
{{ $gdprRequest->requester_username ?? 'N/A' }}
{{ $gdprRequest->requester_email ?? 'N/A' }}
@@ -77,7 +74,7 @@
{{ ucfirst($gdprRequest->status) }} {{ $gdprRequest->completed_at?->format('Y-m-d H:i') ?? '—' }}{{ formatDateTime($gdprRequest->completed_at) ?: '—' }} View @@ -89,23 +86,21 @@ No GDPR requests found.
-
+
{{ $requests->links() }}
-
+
-
+

Retention Summary

    @foreach($retentionPolicy['retained_records'] as $record)
  • {{ $record['table'] }}: {{ $record['reason'] }} ({{ str_replace('_', ' ', $record['erasure_action']) }})
  • @endforeach
-
+
@endsection diff --git a/resources/views/admin/gdpr/show.blade.php b/resources/views/admin/gdpr/show.blade.php index 3cd47a657..f6e32ee3e 100644 --- a/resources/views/admin/gdpr/show.blade.php +++ b/resources/views/admin/gdpr/show.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+

@@ -59,11 +59,11 @@

Created
-
{{ $gdprRequest->created_at?->format('Y-m-d H:i') }}
+
{{ formatDateTime($gdprRequest->created_at) }}
Completed
-
{{ $gdprRequest->completed_at?->format('Y-m-d H:i') ?? '—' }}
+
{{ formatDateTime($gdprRequest->completed_at) ?: '—' }}
@@ -89,7 +89,7 @@
{{ $auditLog->event }}
{{ $auditLog->description }}
-
{{ $auditLog->created_at?->format('Y-m-d H:i:s') }}
+
{{ formatDateTimeSeconds($auditLog->created_at) }}
@empty

No GDPR audit events recorded for this request yet.

@@ -137,12 +137,12 @@ @if($gdprRequest->isDownloadableExport())

Export Ready

-

The user can download this export until {{ $gdprRequest->export_expires_at?->format('Y-m-d H:i') }}.

+

The user can download this export until {{ formatDateTime($gdprRequest->export_expires_at) }}.

@endif
-
+
@endsection diff --git a/resources/views/admin/groups/bulk.blade.php b/resources/views/admin/groups/bulk.blade.php index d508991f9..1318b2c4f 100644 --- a/resources/views/admin/groups/bulk.blade.php +++ b/resources/views/admin/groups/bulk.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -175,7 +175,7 @@ @endif
-
+
@endsection diff --git a/resources/views/admin/groups/edit.blade.php b/resources/views/admin/groups/edit.blade.php index 3c8b6acca..24bc33a58 100644 --- a/resources/views/admin/groups/edit.blade.php +++ b/resources/views/admin/groups/edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -248,7 +248,7 @@
-
+
@endsection diff --git a/resources/views/admin/invitations/index.blade.php b/resources/views/admin/invitations/index.blade.php index c04ff4ca6..f4fec7f68 100644 --- a/resources/views/admin/invitations/index.blade.php +++ b/resources/views/admin/invitations/index.blade.php @@ -2,55 +2,50 @@ @section('content')
-
+ -
-
-

- {{ $title }} -

-
-
- @csrf - -
-
-
-
+ + +
+ @csrf + +
+
+
-
+
Total Invitations
{{ $stats['total'] }}
-
+
Pending
{{ $stats['pending'] }}
-
+
Used
{{ $stats['used'] }}
-
+
Expired
{{ $stats['expired'] }}
-
+
Today
{{ $stats['today'] }}
-
+
This Week
{{ $stats['this_week'] }}
-
+
This Month
{{ $stats['this_month'] }}
@@ -114,21 +109,19 @@
@csrf - - - - - - - - - - - - - + + + + + + Email + Invited By + Status + Created + Expires + Actions + + @forelse($invitations as $invitation) @endforelse - -
- - EmailInvited ByStatusCreatedExpiresActions
@@ -160,10 +153,10 @@ @endif - {{ $invitation->created_at->format('Y-m-d H:i') }} + {{ formatDateTime($invitation->created_at) }} - {{ $invitation->expires_at ? $invitation->expires_at->format('Y-m-d H:i') : 'Never' }} + {{ $invitation->expires_at ? formatDateTime($invitation->expires_at) : 'Never' }} @@ -176,9 +169,15 @@ -
+ @csrf -
@@ -192,8 +191,7 @@
+
@@ -216,30 +214,27 @@
-
+ @if(count($topInviters) > 0) -
+

Top Inviters

-
- - - - - - - - - - - - + + + Rank + Username + Email + Total Invitations + Successful + Success Rate + + @foreach($topInviters as $index => $user) @endforeach - -
RankUsernameEmailTotal InvitationsSuccessfulSuccess Rate
@@ -272,11 +267,9 @@
-
+
-
+ @endif
diff --git a/resources/views/admin/invitations/show.blade.php b/resources/views/admin/invitations/show.blade.php index 46f0675ac..b4f3bf05e 100644 --- a/resources/views/admin/invitations/show.blade.php +++ b/resources/views/admin/invitations/show.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -131,14 +131,14 @@
Created At
- {{ $invitation->created_at->format('Y-m-d H:i:s') }} + {{ formatDateTimeSeconds($invitation->created_at) }} ({{ $invitation->created_at->diffForHumans() }})
Updated At
- {{ $invitation->updated_at->format('Y-m-d H:i:s') }} + {{ formatDateTimeSeconds($invitation->updated_at) }} ({{ $invitation->updated_at->diffForHumans() }})
@@ -146,7 +146,7 @@
Expires At
@if($invitation->expires_at) - {{ $invitation->expires_at->format('Y-m-d H:i:s') }} + {{ formatDateTimeSeconds($invitation->expires_at) }} ({{ $invitation->expires_at->diffForHumans() }}) @if($invitation->expires_at->isPast()) Expired @@ -160,7 +160,7 @@
Used At
@if($invitation->used_at) - {{ $invitation->used_at->format('Y-m-d H:i:s') }} + {{ formatDateTimeSeconds($invitation->used_at) }} ({{ $invitation->used_at->diffForHumans() }}) @else Not used yet @@ -200,7 +200,7 @@
-
+
{{-- Scripts moved to resources/js/csp-safe.js --}} diff --git a/resources/views/admin/logs/index.blade.php b/resources/views/admin/logs/index.blade.php index ee710414a..ec89a68fb 100644 --- a/resources/views/admin/logs/index.blade.php +++ b/resources/views/admin/logs/index.blade.php @@ -80,7 +80,7 @@

Last Modified

-

{{ $selectedLog['modified_at']->format('Y-m-d H:i:s') }}

+

{{ formatDateTimeSeconds($selectedLog['modified_at']) }}

diff --git a/resources/views/admin/movies/add.blade.php b/resources/views/admin/movies/add.blade.php index a8dbc2ae2..ff441c25b 100644 --- a/resources/views/admin/movies/add.blade.php +++ b/resources/views/admin/movies/add.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+

@@ -98,7 +98,7 @@

-
+
@endsection diff --git a/resources/views/admin/movies/edit.blade.php b/resources/views/admin/movies/edit.blade.php index 61eba8c7c..0c6f82456 100644 --- a/resources/views/admin/movies/edit.blade.php +++ b/resources/views/admin/movies/edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+

@@ -256,14 +256,14 @@

-
+
@endsection @extends('layouts.admin') @section('content')
-
+
@@ -388,6 +388,6 @@
@endif -
+
@endsection diff --git a/resources/views/admin/music/edit.blade.php b/resources/views/admin/music/edit.blade.php index 5d3d5e70c..df45e8ad9 100644 --- a/resources/views/admin/music/edit.blade.php +++ b/resources/views/admin/music/edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+

@@ -230,6 +230,6 @@

-
+
@endsection diff --git a/resources/views/admin/music/index.blade.php b/resources/views/admin/music/index.blade.php index 15eba55fd..ac5eeeafd 100644 --- a/resources/views/admin/music/index.blade.php +++ b/resources/views/admin/music/index.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -65,22 +65,19 @@ @if(!empty($musicList) && count($musicList) > 0) -
- - - - - - - - - - - - - - - + + + ID + Title + Artist + Publisher + Year + Genre + Tracks + Cover + Actions + + @foreach($musicList as $music) @endforeach - -
IDTitleArtistPublisherYearGenreTracksCoverActions
@@ -124,9 +121,7 @@
-
+ @else
@@ -139,7 +134,7 @@

@endif -
+
@endsection diff --git a/resources/views/admin/predb/index.blade.php b/resources/views/admin/predb/index.blade.php index eea5dfcc0..14b48fe34 100644 --- a/resources/views/admin/predb/index.blade.php +++ b/resources/views/admin/predb/index.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -43,21 +43,18 @@
-
- - - - - - - - - - - - - - + + + Title + Category + Size + Files + Pre Date + Source + Status + Release + + @forelse($results as $pre) @empty + @php + $predbEmptyTitle = $lastSearch ? 'No PreDB entries found for "'.$lastSearch.'"' : 'No PreDB entries available'; + @endphp - @endforelse - -
TitleCategorySizeFilesPre DateSourceStatusRelease
@@ -127,28 +124,22 @@
- @if($lastSearch) -
- -

No PreDB entries found for "{{ $lastSearch }}"

- +
+ + @if($lastSearch) + Clear search and view all - - @else -
- -

No PreDB entries available

-
- @endif + @endif +
-
+
@@ -161,7 +152,7 @@
-
+
@if($lastSearch) diff --git a/resources/views/admin/promotions/create.blade.php b/resources/views/admin/promotions/create.blade.php index 5cd5512c8..4dee60870 100644 --- a/resources/views/admin/promotions/create.blade.php +++ b/resources/views/admin/promotions/create.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+

@@ -126,7 +126,7 @@

-
+
@endsection diff --git a/resources/views/admin/promotions/edit.blade.php b/resources/views/admin/promotions/edit.blade.php index 259d58ed8..71a45ee76 100644 --- a/resources/views/admin/promotions/edit.blade.php +++ b/resources/views/admin/promotions/edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+

@@ -88,7 +88,7 @@ -

Leave blank for no start restriction

@error('start_date') @@ -100,7 +100,7 @@ -

Leave blank for no end restriction

@error('end_date') @@ -132,7 +132,7 @@

-
+
@endsection diff --git a/resources/views/admin/promotions/index.blade.php b/resources/views/admin/promotions/index.blade.php index 63c0cb752..373522813 100644 --- a/resources/views/admin/promotions/index.blade.php +++ b/resources/views/admin/promotions/index.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -23,20 +23,17 @@ @if(count($promotions) > 0) -
- - - - - - - - - - - - - + + + Name + Applicable Roles + Additional Days + Start Date + End Date + Status + Actions + + @foreach($promotions as $promotion) @endforeach - -
NameApplicable RolesAdditional DaysStart DateEnd DateStatusActions
@@ -65,10 +62,10 @@ {{ $promotion->additional_days }} days - {{ $promotion->start_date ? $promotion->start_date->format('Y-m-d') : 'No limit' }} + {{ $promotion->start_date ? formatDate($promotion->start_date) : 'No limit' }} - {{ $promotion->end_date ? $promotion->end_date->format('Y-m-d') : 'No limit' }} + {{ $promotion->end_date ? formatDate($promotion->end_date) : 'No limit' }} @php @@ -127,9 +124,7 @@
-
+ @else
@@ -137,7 +132,7 @@

Create your first promotion to get started.

@endif -
+
@endsection diff --git a/resources/views/admin/promotions/show-statistics.blade.php b/resources/views/admin/promotions/show-statistics.blade.php index d19237f74..f0a55555b 100644 --- a/resources/views/admin/promotions/show-statistics.blade.php +++ b/resources/views/admin/promotions/show-statistics.blade.php @@ -23,7 +23,7 @@
-
+

Status

@@ -43,11 +43,11 @@

Start Date

-

{{ $promotion->start_date ? $promotion->start_date->format('Y-m-d') : 'No limit' }}

+

{{ $promotion->start_date ? formatDate($promotion->start_date) : 'No limit' }}

End Date

-

{{ $promotion->end_date ? $promotion->end_date->format('Y-m-d') : 'No limit' }}

+

{{ $promotion->end_date ? formatDate($promotion->end_date) : 'No limit' }}

@if($promotion->description) @@ -56,10 +56,10 @@

{{ $promotion->description }}

@endif -
+ -
+
@@ -75,11 +75,11 @@
- +
- +
-
+
-
+
@@ -102,9 +102,9 @@

{{ number_format($stats['total_upgrades']) }}

-
+ -
+
@@ -114,9 +114,9 @@

{{ number_format($stats['unique_users']) }}

-
+ -
+
@@ -126,9 +126,9 @@

{{ number_format($stats['total_days_added']) }}

-
+ -
+
@@ -138,12 +138,12 @@

{{ number_format($stats['roles_affected']) }}

-
+
@if(count($statsByRole) > 0) -
+

Statistics by Role @@ -181,12 +181,12 @@

-
+ @endif @if($dailyStats->isNotEmpty()) -
+

Daily Activity @@ -221,11 +221,11 @@

-
+ @endif -
+

Recent Applications @@ -266,13 +266,13 @@ days - {{ $application->previous_expiry_date ? $application->previous_expiry_date->format('Y-m-d H:i') : 'N/A' }} + {{ $application->previous_expiry_date ? formatDateTime($application->previous_expiry_date) : 'N/A' }} - {{ $application->new_expiry_date ? $application->new_expiry_date->format('Y-m-d H:i') : 'N/A' }} + {{ $application->new_expiry_date ? formatDateTime($application->new_expiry_date) : 'N/A' }} -
{{ $application->applied_at->format('Y-m-d H:i') }}
+
{{ formatDateTime($application->applied_at) }}
{{ $application->applied_at->diffForHumans() }}
@@ -291,7 +291,7 @@ {{ $applications->appends(request()->query())->links() }}

@endif -
+
@endsection diff --git a/resources/views/admin/promotions/statistics.blade.php b/resources/views/admin/promotions/statistics.blade.php index 2a6ea89dd..4ba834af4 100644 --- a/resources/views/admin/promotions/statistics.blade.php +++ b/resources/views/admin/promotions/statistics.blade.php @@ -18,7 +18,7 @@
-
+
@@ -34,11 +34,11 @@
- +
- +
-
+
-
+
@@ -61,9 +61,9 @@

{{ $overallStats['total_promotions'] }}

-
+ -
+
@@ -73,9 +73,9 @@

{{ $overallStats['active_promotions'] }}

-
+ -
+
@@ -85,9 +85,9 @@

{{ number_format($overallStats['total_applications']) }}

-
+ -
+
@@ -97,9 +97,9 @@

{{ number_format($overallStats['unique_users']) }}

-
+ -
+
@@ -109,12 +109,12 @@

{{ number_format($overallStats['total_days_added']) }}

-
+
-
+

Top Promotions by Usage @@ -142,10 +142,10 @@

@endif
-
+ -
+

Statistics by Role @@ -180,11 +180,11 @@

@endif
-
+
-
+

All Promotions Statistics @@ -245,10 +245,10 @@

-
+ -
+

Recent Promotion Activity @@ -296,7 +296,7 @@

-
+
@endsection diff --git a/resources/views/admin/regexes/category-edit.blade.php b/resources/views/admin/regexes/category-edit.blade.php index 30a582f8d..6f4a1def2 100644 --- a/resources/views/admin/regexes/category-edit.blade.php +++ b/resources/views/admin/regexes/category-edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -179,7 +179,7 @@
-
+
{{-- Scripts moved to resources/js/csp-safe.js --}} diff --git a/resources/views/admin/regexes/collection-edit.blade.php b/resources/views/admin/regexes/collection-edit.blade.php index 8665fbbe5..3ceb76f9d 100644 --- a/resources/views/admin/regexes/collection-edit.blade.php +++ b/resources/views/admin/regexes/collection-edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -154,7 +154,7 @@
-
+
{{-- Scripts moved to resources/js/csp-safe.js --}} diff --git a/resources/views/admin/regexes/collection-test.blade.php b/resources/views/admin/regexes/collection-test.blade.php index 74d0b2f9a..4d668757c 100644 --- a/resources/views/admin/regexes/collection-test.blade.php +++ b/resources/views/admin/regexes/collection-test.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -165,6 +165,6 @@ @endif
@endif -
+
@endsection diff --git a/resources/views/admin/regexes/release-naming-edit.blade.php b/resources/views/admin/regexes/release-naming-edit.blade.php index c592249fb..eb84aba1d 100644 --- a/resources/views/admin/regexes/release-naming-edit.blade.php +++ b/resources/views/admin/regexes/release-naming-edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -154,7 +154,7 @@
-
+
{{-- Scripts moved to resources/js/csp-safe.js --}} diff --git a/resources/views/admin/regexes/release-naming-test.blade.php b/resources/views/admin/regexes/release-naming-test.blade.php index 7bfb1786c..44066b971 100644 --- a/resources/views/admin/regexes/release-naming-test.blade.php +++ b/resources/views/admin/regexes/release-naming-test.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -187,6 +187,6 @@ @endif
@endif -
+
@endsection diff --git a/resources/views/admin/registrations/index.blade.php b/resources/views/admin/registrations/index.blade.php index ebbd6433b..3ef5d4bfa 100644 --- a/resources/views/admin/registrations/index.blade.php +++ b/resources/views/admin/registrations/index.blade.php @@ -77,8 +77,8 @@

{{ $registrationStatus['active_period']->name }}

- {{ $registrationStatus['active_period']->starts_at->format('Y-m-d H:i') }} to - {{ $registrationStatus['active_period']->ends_at->format('Y-m-d H:i') }} + {{ formatDateTime($registrationStatus['active_period']->starts_at) }} to + {{ formatDateTime($registrationStatus['active_period']->ends_at) }}

@else @@ -207,19 +207,16 @@

No current or upcoming open-registration periods are scheduled.

@else -
- - - - - - - - - - - - + + + Name + Status + Window + Notes + Updated By + Actions + + @foreach($currentPeriods as $period) @endforeach - -
NameStatusWindowNotesUpdated ByActions
@@ -236,8 +233,8 @@ -

{{ $period->starts_at->format('Y-m-d H:i') }}

-

to {{ $period->ends_at->format('Y-m-d H:i') }}

+

{{ formatDateTime($period->starts_at) }}

+

to {{ formatDateTime($period->ends_at) }}

{{ $period->notes ? Str::limit($period->notes, 100) : '—' }} @@ -288,9 +285,7 @@
-
+ @endif @@ -306,19 +301,16 @@

No past open-registration periods have been recorded yet.

@else -
- - - - - - - - - - - - + + + Name + Status + Window + Notes + Updated By + Actions + + @foreach($pastPeriods as $period) @endforeach - -
NameStatusWindowNotesUpdated ByActions
@@ -330,8 +322,8 @@ -

{{ $period->starts_at->format('Y-m-d H:i') }}

-

to {{ $period->ends_at->format('Y-m-d H:i') }}

+

{{ formatDateTime($period->starts_at) }}

+

to {{ formatDateTime($period->ends_at) }}

{{ $period->notes ? Str::limit($period->notes, 100) : '—' }} @@ -365,9 +357,7 @@
-
+ @endif
@@ -458,7 +448,7 @@ @if(!empty($failure['registration_status_label'])) Effective: {{ $failure['registration_status_label'] }} @endif - {{ $failure['timestamp']->format('Y-m-d H:i:s') }} + {{ formatDateTimeSeconds($failure['timestamp']) }}
@empty diff --git a/resources/views/admin/releases/failed.blade.php b/resources/views/admin/releases/failed.blade.php index a7580bb5d..f865b3e2f 100644 --- a/resources/views/admin/releases/failed.blade.php +++ b/resources/views/admin/releases/failed.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -173,18 +173,12 @@
@else -
- -

- @if(request('failrelsearch')) - No failed releases found matching "{{ request('failrelsearch') }}". - @else - No failed releases found. Great job! - @endif -

-
+ @php + $failedEmptyMessage = request('failrelsearch') ? 'No failed releases found matching "'.request('failrelsearch').'".' : 'No failed releases found. Great job!'; + @endphp + @endif -
+
@endsection diff --git a/resources/views/admin/roles/add.blade.php b/resources/views/admin/roles/add.blade.php index 3c636c932..6fe26abe1 100644 --- a/resources/views/admin/roles/add.blade.php +++ b/resources/views/admin/roles/add.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+

@@ -211,7 +211,7 @@

-
+
@endsection diff --git a/resources/views/admin/roles/edit.blade.php b/resources/views/admin/roles/edit.blade.php index 35f70d671..c7861587f 100644 --- a/resources/views/admin/roles/edit.blade.php +++ b/resources/views/admin/roles/edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+

@@ -251,7 +251,7 @@

@endif -
+
@endsection diff --git a/resources/views/admin/shows/add.blade.php b/resources/views/admin/shows/add.blade.php index 4ab64a278..a3b9d186d 100644 --- a/resources/views/admin/shows/add.blade.php +++ b/resources/views/admin/shows/add.blade.php @@ -12,7 +12,7 @@ @section('content')
-
+

@@ -123,7 +123,7 @@ class="mt-6 p-4 bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg">

@@ -159,7 +159,7 @@
-
+

@endsection diff --git a/resources/views/admin/shows/edit.blade.php b/resources/views/admin/shows/edit.blade.php index 26a8a8f58..c99a9c883 100644 --- a/resources/views/admin/shows/edit.blade.php +++ b/resources/views/admin/shows/edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -142,8 +142,7 @@ @if(!empty($show['image'])) {{ $show['title'] }} @else
@@ -223,7 +222,7 @@
-
+
@endsection diff --git a/resources/views/admin/shows/index.blade.php b/resources/views/admin/shows/index.blade.php index 7502ce1bb..5afa2c8b8 100644 --- a/resources/views/admin/shows/index.blade.php +++ b/resources/views/admin/shows/index.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -49,20 +49,17 @@
-
- - - - - - - - - - - - - + + + Cover + Title + Type + Started + IDs + Publisher + Actions + + @forelse($tvshowlist as $show) @empty + @php + $showsEmptyTitle = $showname ? 'No TV shows found for "'.$showname.'"' : 'No TV shows available'; + @endphp - @endforelse - -
CoverTitleTypeStartedIDsPublisherActions
@@ -161,28 +158,22 @@
- @if($showname) -
- -

No TV shows found for "{{ $showname }}"

- +
+ + @if($showname) + Clear search and view all - - @else -
- -

No TV shows available

-
- @endif + @endif +
-
+
@@ -195,7 +186,7 @@
-
+
{{-- Styles moved to resources/css/csp-safe.css --}} diff --git a/resources/views/admin/shows/remove.blade.php b/resources/views/admin/shows/remove.blade.php index 1ff9a6de1..16058e0f2 100644 --- a/resources/views/admin/shows/remove.blade.php +++ b/resources/views/admin/shows/remove.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -111,7 +111,7 @@ @endif
-
+
@endsection diff --git a/resources/views/admin/site/edit.blade.php b/resources/views/admin/site/edit.blade.php index 7c7cbcc3e..c7d231c94 100644 --- a/resources/views/admin/site/edit.blade.php +++ b/resources/views/admin/site/edit.blade.php @@ -26,1057 +26,34 @@
- -
-

Main Site Settings, HTML Layout, Tags

+ @include('admin.site.sections.main-settings') -
-
- - -

Displayed in the header on every public page.

-
+ @include('admin.site.sections.usenet-settings') -
- - -

Stem meta-tag appended to all page title tags.

-
+ @include('admin.site.sections.lookup-settings') -
- - -

Stem meta-description appended to all page meta description tags.

-
+ @include('admin.site.sections.language-categorization-settings') -
- - -

Stem meta-keywords appended to all page meta keyword tags.

-
+ @include('admin.site.sections.registration-settings') -
- - -

Displayed in the footer section of every public page.

-
-
- - -

The relative path to the landing page shown when a user logs in, or clicks the home link.

-
+ @include('admin.site.sections.password-settings') -
- - -

Optional URL to prepend to external links.

-
+ @include('admin.site.sections.additional-usenet-settings') -
- - -

Text displayed in the terms and conditions page. Use the rich text editor to format your content.

-
-
-
+ @include('admin.site.sections.advanced-settings') - -
-

Usenet Settings

+ @include('admin.site.sections.movie-trailer-settings') -
-
- - -

Levels deep to store the nzb Files. If you change this you must run the misc/testing/DB/nzb-reorg script!

-
+ @include('admin.site.sections.postprocessing-settings') -
- - -

The number of hours incomplete parts and binaries will be retained.

-
+ @include('admin.site.sections.nfo-processing-settings') -
- - -

The number of days releases will be retained for use throughout site. Set to 0 to disable.

-
+ @include('admin.site.sections.connection-settings') -
- - -

The number of hours releases categorized as Misc->Other will be retained. Set to 0 to disable.

-
+ @include('admin.site.sections.developer-settings') -
- - -

The number of hours releases categorized as Misc->Hashed will be retained. Set to 0 to disable.

-
- -
- - -

Default is 0 (off), which will remove parts in one go. If backfilling or importing and parts table is large, using chunks of 5000+ will speed up removal. Normal indexing is fastest with this setting at 0.

-
- -
- - -

The minimum number of files to make a release. i.e. if set to two, then releases which only contain one file will not be created.

-
- -
- - -

The minimum total size in bytes to make a release. If set to 0, then ignored.

-
- -
- - -

The maximum total size in bytes to make a release. If set to 0, then ignored. Only deletes during release creation.

-
- -
- - -

The minimum completion percent to make a release. i.e. if set to 97, then releases under 97% completion will not be created. If set to 0, then ignored.

-
- -
- - -

Whether to update download counts when someone downloads a release.

-
- -
- - -

The time in hours to check for crossposted releases - this will delete 1 of the releases if the 2 are posted by the same person in the same time period.

-
- -
- - -

The maximum number of messages to fetch at a time from the server.

-
- -
- - -

The maximum number of headers that update binaries sees as the total range. This ensures that a total of no more than this is attempted to be downloaded at one time per group.

-
- -
- - -
-
- - -
-
- - -
-
-

Scan back X (posts/days) for each new group? Can backfill to scan further.

-
- -
- - -

The target date for safe backfill. Format: YYYY-MM-DD

-
- -
- - -

Whether to disable a group automatically during backfill if the target date has been reached.

-
-
-
- - -
-

Lookup Settings

- -
-
- - -

Whether to attempt to lookup TV related ids on the web.

-
- -
- - -

Whether to attempt to lookup book information from ISBNdb, with iTunes fallback.

-
- -
- - -

Whether to attempt to lookup film information from IMDB or TheMovieDB.

-
- -
- - -

Preferred language for scraping external sources.

-
- -
- - -

Whether to attempt to lookup anime information from AniDB when processing binaries.

-
- -
- - -

Whether to attempt to lookup music information from metadata providers.

-
- -
- - -

Whether to save a preview of an audio release (requires deep rar inspection enabled).
It is advisable to specify a path to the lame binary to reduce the size of audio previews.

-
- -
- - -

Whether to attempt to lookup game information from metadata providers.

-
-
-
- - -
-

Language/Categorization Options

- -
-
- - -

Whether to send foreign movies/tv to foreign sections or not. If set to true they will go in foreign categories.

-
- -
- - -

Whether to send WEB-DL to the WEB-DL section or not. If set to true they will go in WEB-DL category, false will send them in HD TV. This will also make them inaccessible to Sickbeard and possibly Couchpotato.

-
-
-
- - -
-

User Settings

- -
-
- -
-

- Registration status, scheduled open periods, and registration activity are now managed from the dedicated registration admin page. -

- - Open Registration Admin - -
-
- -
- - -

The number of days to preserve user download history, for use when checking limits being hit. Set to zero will remove all records of what users download, but retain history of when, so that role based limits can still be applied.

-
- -
- - -

A comma separated list of IP addresses which will be excluded from user limits on number of requests and downloads per IP address. Include values for google reader and other shared services which may be being used.

-
-
-
- - - -
-

Password Settings

- -
-
- - -

Try to download the last rar or zip file? (This is good if most of the files are at the end.) Note: The first rar/zip is still downloaded.

-
- -
- - -

Whether to show passworded releases in browse, search, api and rss feeds.

-
-
-
- - -
-

Additional Usenet Settings

- -
-
- -
- - GB -
-

The maximum size in gigabytes to postprocess a release. If set to 0, then ignored.

-
- -
- -
- - MB -
-

The minimum size in megabytes to post process (additional) a release. If set to 0, then ignored.

-
-
-
- - -
-

Advanced Settings - For Advanced Users

- -
-
- - -

The maximum amount of NZB files to create on stage 5 at a time in update_releases. If more are to be created it will loop stage 5 until none remain.

-
- -
- - -

Whether to attempt to repair parts or not, increases backfill/binaries updating time.

-
- -
- - -

Whether to put unreceived parts into missed_parts table when running binaries(safe) or backfill scripts.

-
- -
- - -

The maximum amount of articles to attempt to repair at a time. If you notice that you are getting a lot of parts into the missed_parts table, it is possible that you USP is not keeping up with the requests. Try to reduce the threads to safe scripts or stop using safe scripts until improves.

-
- -
- - -

Maximum amount of times to try part repair.

-
- -
- - -

Whether to attempt to retrieve a JPG file while additional post processing, these are usually on XXX releases.

-
- -
- - -

Whether to attempt to process a video thumbnail image. You must have ffmpeg for this.

-
- -
- - -

Whether to attempt to process a video sample, these videos are very short 1-3 seconds, 100KB on average, in ogg video format. You must have ffmpeg for this.

-
- -
- - -

The maximum number of segments to download to generate the sample video file or jpg sample image. (Default 2)

-
- -
- -
- - seconds -
-

The maximum duration (in seconds) for ffmpeg to generate the sample for. (Default 5)

-
- -
- -
- - levels -
-

If a rar/zip has rar/zip inside of it, how many times should we go in those inner rar/zip files.

-
- -
- - -

You can add a regex here to set releases to potentially passworded when a file name inside a rar/zip matches this regex. You must ensure this regex is valid, a non valid regex will cause errors during processing!

-
-
-
- - -
-

Movie Trailer Settings

- -
-
- - -

Fetch and display trailers from TraktTV (Requires API key) and/or TrailerAddict on the details page?

-
- -
- -
- - px -
-

Maximum width in pixels for the trailer window. (Default: 480)

-
- -
- -
- - px -
-

Maximum height in pixels for the trailer window. (Default: 345)

-
-
-
- - -
-

Advanced - Postprocessing Settings

- -
-
- -
- - seconds -
-

How much time to wait for unrar/7zip/mediainfo/ffmpeg/avconv before killing it, set to 0 to disable. 60 is a good value. Requires the GNU Timeout path to be set.

-
- -
- -
- - seconds -
-

Maximum wall-clock seconds to spend processing a single release before skipping it. Keep this below the multiprocessing child timeout. Set to 0 to disable. Default: 120.

-
- -
- - -

Number of times a release can time out during post-processing before it is permanently deleted. Default: 3.

-
- -
- - -

Releases claimed per worker batch for passwords, previews, and media info. Larger batches reduce query overhead but increase each worker's memory and runtime. Each thread can hold one NNTP connection.

-
- -
- - -

If a part fails to download while post processing, this will retry up to the amount you set, then give up.

-
- -
- - -

This overrides the above setting if set above 1. How many parts to check for a password before giving up. This slows down post processing massively, better to leave it 1.

-
- -
- - -

The maximum amount of TV shows to processper run.

-
- -
- - -

The maximum amount of movies to process with IMDB per run.

-
- -
- - -

The maximum amount of anime to process with anidb per run.

-
- -
- - -

The maximum amount of music to process with metadata lookups per run. This does not use an NNTP connection.

-
- -
- - -

The maximum amount of games to process with metadata lookups per run. This does not use an NNTP connection.

-
- -
- - -

The maximum amount of books to process with metadata lookups per run. This does not use an NNTP connection

-
- -
- - -

The maximum number of releases to check per run (threaded script only).

-
- -
- -
- - ms -
-

Sleep time in milliseconds to wait between external metadata requests. If you thread post-proc, multiply by the number of threads. ie Postprocessing Threads = 12, sleep time = 12000

-
-
-
- - -
-

NFO Processing Settings

- -
-
- - -

Whether to attempt to retrieve an nfo file from usenet.
NOTE: disabling nfo lookups will disable movie lookups.

-
- -
- - -

The maximum amount of NFO files to process per run. This uses NNTP an connection, 1 per thread. This does not query external metadata providers.

-
- -
- -
- - GB -
-

The maximum size in gigabytes of a release to process it for NFOs. If set to 0, then ignored.

-
- -
- -
- - MB -
-

The minimum size in megabytes of a release to process it for NFOs. If set to 0, then ignored.

-
- -
- -
- - times -
-

How many times to retry when a NFO fails to download. If set to 0, we will not retry. The max is 7.

-
-
-
- - -
-

Connection Settings

- -
-
- - -

The maximum number of retry attempts to connect to nntp provider. On error, each retry takes approximately 5 seconds nntp returns reply. (Default 10)

-
- -
- - -

The time in hours to wait, since last activity, before releases without parts counts in the subject are are created.
Setting this below 2 hours could create incomplete releases.

-
- -
- - -

How many hours to wait before converting a collection into a release that is considered "stuck".
Default value is 48 hours.

-
-
-
- - -
-

Developer Settings

- -
-
- - -

For developers. Whether to log all headers that have 'yEnc' and are dropped. Logged to not_yenc/groupname.dropped.txt.

-
-
-
- - -
-

Advanced - Threaded Settings

- -
-
- - -

The number of threads for update_binaries. If you notice that you are getting a lot of parts into the missed_parts table, it is possible that you USP is not keeping up with the requests. Try to reduce the threads. At least until the cause can be determined.

-
- -
- - -

The number of threads for backfill.

-
- -
- - -

The number of threads for releases update scripts.

-
- -
- - -

Maximum simultaneous additional-processing workers and NNTP sessions. Workers reuse their process and connection across bounded batches; raise this only within CPU, memory, disk I/O, and provider connection limits.

-
- -
- - -

The number of threads for nfo postprocessing. The max is 16, if you set anything higher it will use 16.

-
- -
- - -

The number of threads for video metadata postprocessing. This includes movies, anime and tv lookups.

-
- -
- - -

The number of threads for fixReleasesNames. This includes md5, nfos, par2 and filenames.

-
-
-
+ @include('admin.site.sections.threaded-settings')
diff --git a/resources/views/admin/site/sections/additional-usenet-settings.blade.php b/resources/views/admin/site/sections/additional-usenet-settings.blade.php new file mode 100644 index 000000000..d69e5371f --- /dev/null +++ b/resources/views/admin/site/sections/additional-usenet-settings.blade.php @@ -0,0 +1,30 @@ + +
+

Additional Usenet Settings

+ +
+
+ +
+ + GB +
+

The maximum size in gigabytes to postprocess a release. If set to 0, then ignored.

+
+ +
+ +
+ + MB +
+

The minimum size in megabytes to post process (additional) a release. If set to 0, then ignored.

+
+
+
diff --git a/resources/views/admin/site/sections/advanced-settings.blade.php b/resources/views/admin/site/sections/advanced-settings.blade.php new file mode 100644 index 000000000..ec7416b6e --- /dev/null +++ b/resources/views/admin/site/sections/advanced-settings.blade.php @@ -0,0 +1,145 @@ + +
+

Advanced Settings - For Advanced Users

+ +
+
+ + +

The maximum amount of NZB files to create on stage 5 at a time in update_releases. If more are to be created it will loop stage 5 until none remain.

+
+ +
+ + +

Whether to attempt to repair parts or not, increases backfill/binaries updating time.

+
+ +
+ + +

Whether to put unreceived parts into missed_parts table when running binaries(safe) or backfill scripts.

+
+ +
+ + +

The maximum amount of articles to attempt to repair at a time. If you notice that you are getting a lot of parts into the missed_parts table, it is possible that you USP is not keeping up with the requests. Try to reduce the threads to safe scripts or stop using safe scripts until improves.

+
+ +
+ + +

Maximum amount of times to try part repair.

+
+ +
+ + +

Whether to attempt to retrieve a JPG file while additional post processing, these are usually on XXX releases.

+
+ +
+ + +

Whether to attempt to process a video thumbnail image. You must have ffmpeg for this.

+
+ +
+ + +

Whether to attempt to process a video sample, these videos are very short 1-3 seconds, 100KB on average, in ogg video format. You must have ffmpeg for this.

+
+ +
+ + +

The maximum number of segments to download to generate the sample video file or jpg sample image. (Default 2)

+
+ +
+ +
+ + seconds +
+

The maximum duration (in seconds) for ffmpeg to generate the sample for. (Default 5)

+
+ +
+ +
+ + levels +
+

If a rar/zip has rar/zip inside of it, how many times should we go in those inner rar/zip files.

+
+ +
+ + +

You can add a regex here to set releases to potentially passworded when a file name inside a rar/zip matches this regex. You must ensure this regex is valid, a non valid regex will cause errors during processing!

+
+
+
diff --git a/resources/views/admin/site/sections/connection-settings.blade.php b/resources/views/admin/site/sections/connection-settings.blade.php new file mode 100644 index 000000000..3aad0fd0f --- /dev/null +++ b/resources/views/admin/site/sections/connection-settings.blade.php @@ -0,0 +1,33 @@ + +
+

Connection Settings

+ +
+
+ + +

The maximum number of retry attempts to connect to nntp provider. On error, each retry takes approximately 5 seconds nntp returns reply. (Default 10)

+
+ +
+ + +

The time in hours to wait, since last activity, before releases without parts counts in the subject are are created.
Setting this below 2 hours could create incomplete releases.

+
+ +
+ + +

How many hours to wait before converting a collection into a release that is considered "stuck".
Default value is 48 hours.

+
+
+
diff --git a/resources/views/admin/site/sections/developer-settings.blade.php b/resources/views/admin/site/sections/developer-settings.blade.php new file mode 100644 index 000000000..992139c5b --- /dev/null +++ b/resources/views/admin/site/sections/developer-settings.blade.php @@ -0,0 +1,20 @@ + +
+

Developer Settings

+ +
+
+ + +

For developers. Whether to log all headers that have 'yEnc' and are dropped. Logged to not_yenc/groupname.dropped.txt.

+
+
+
diff --git a/resources/views/admin/site/sections/language-categorization-settings.blade.php b/resources/views/admin/site/sections/language-categorization-settings.blade.php new file mode 100644 index 000000000..07be1b6af --- /dev/null +++ b/resources/views/admin/site/sections/language-categorization-settings.blade.php @@ -0,0 +1,34 @@ + +
+

Language/Categorization Options

+ +
+
+ + +

Whether to send foreign movies/tv to foreign sections or not. If set to true they will go in foreign categories.

+
+ +
+ + +

Whether to send WEB-DL to the WEB-DL section or not. If set to true they will go in WEB-DL category, false will send them in HD TV. This will also make them inaccessible to Sickbeard and possibly Couchpotato.

+
+
+
diff --git a/resources/views/admin/site/sections/lookup-settings.blade.php b/resources/views/admin/site/sections/lookup-settings.blade.php new file mode 100644 index 000000000..b55bb5dd1 --- /dev/null +++ b/resources/views/admin/site/sections/lookup-settings.blade.php @@ -0,0 +1,118 @@ + +
+

Lookup Settings

+ +
+
+ + +

Whether to attempt to lookup TV related ids on the web.

+
+ +
+ + +

Whether to attempt to lookup book information from ISBNdb, with iTunes fallback.

+
+ +
+ + +

Whether to attempt to lookup film information from IMDB or TheMovieDB.

+
+ +
+ + +

Preferred language for scraping external sources.

+
+ +
+ + +

Whether to attempt to lookup anime information from AniDB when processing binaries.

+
+ +
+ + +

Whether to attempt to lookup music information from metadata providers.

+
+ +
+ + +

Whether to save a preview of an audio release (requires deep rar inspection enabled).
It is advisable to specify a path to the lame binary to reduce the size of audio previews.

+
+ +
+ + +

Whether to attempt to lookup game information from metadata providers.

+
+
+
diff --git a/resources/views/admin/site/sections/main-settings.blade.php b/resources/views/admin/site/sections/main-settings.blade.php new file mode 100644 index 000000000..4d7de8f15 --- /dev/null +++ b/resources/views/admin/site/sections/main-settings.blade.php @@ -0,0 +1,79 @@ + +
+

Main Site Settings, HTML Layout, Tags

+ +
+
+ + +

Displayed in the header on every public page.

+
+ +
+ + +

Stem meta-tag appended to all page title tags.

+
+ +
+ + +

Stem meta-description appended to all page meta description tags.

+
+ +
+ + +

Stem meta-keywords appended to all page meta keyword tags.

+
+ +
+ + +

Displayed in the footer section of every public page.

+
+ +
+ + +

The relative path to the landing page shown when a user logs in, or clicks the home link.

+
+ +
+ + +

Optional URL to prepend to external links.

+
+ +
+ + +

Text displayed in the terms and conditions page. Use the rich text editor to format your content.

+
+
+
diff --git a/resources/views/admin/site/sections/movie-trailer-settings.blade.php b/resources/views/admin/site/sections/movie-trailer-settings.blade.php new file mode 100644 index 000000000..baa7a0f86 --- /dev/null +++ b/resources/views/admin/site/sections/movie-trailer-settings.blade.php @@ -0,0 +1,44 @@ + +
+

Movie Trailer Settings

+ +
+
+ + +

Fetch and display trailers from TraktTV (Requires API key) and/or TrailerAddict on the details page?

+
+ +
+ +
+ + px +
+

Maximum width in pixels for the trailer window. (Default: 480)

+
+ +
+ +
+ + px +
+

Maximum height in pixels for the trailer window. (Default: 345)

+
+
+
diff --git a/resources/views/admin/site/sections/nfo-processing-settings.blade.php b/resources/views/admin/site/sections/nfo-processing-settings.blade.php new file mode 100644 index 000000000..7cf2ebf50 --- /dev/null +++ b/resources/views/admin/site/sections/nfo-processing-settings.blade.php @@ -0,0 +1,65 @@ + +
+

NFO Processing Settings

+ +
+
+ + +

Whether to attempt to retrieve an nfo file from usenet.
NOTE: disabling nfo lookups will disable movie lookups.

+
+ +
+ + +

The maximum amount of NFO files to process per run. This uses NNTP an connection, 1 per thread. This does not query external metadata providers.

+
+ +
+ +
+ + GB +
+

The maximum size in gigabytes of a release to process it for NFOs. If set to 0, then ignored.

+
+ +
+ +
+ + MB +
+

The minimum size in megabytes of a release to process it for NFOs. If set to 0, then ignored.

+
+ +
+ +
+ + times +
+

How many times to retry when a NFO fails to download. If set to 0, we will not retry. The max is 7.

+
+
+
diff --git a/resources/views/admin/site/sections/password-settings.blade.php b/resources/views/admin/site/sections/password-settings.blade.php new file mode 100644 index 000000000..479a69507 --- /dev/null +++ b/resources/views/admin/site/sections/password-settings.blade.php @@ -0,0 +1,34 @@ + +
+

Password Settings

+ +
+
+ + +

Try to download the last rar or zip file? (This is good if most of the files are at the end.) Note: The first rar/zip is still downloaded.

+
+ +
+ + +

Whether to show passworded releases in browse, search, api and rss feeds.

+
+
+
diff --git a/resources/views/admin/site/sections/postprocessing-settings.blade.php b/resources/views/admin/site/sections/postprocessing-settings.blade.php new file mode 100644 index 000000000..d0f3a7a36 --- /dev/null +++ b/resources/views/admin/site/sections/postprocessing-settings.blade.php @@ -0,0 +1,141 @@ + +
+

Advanced - Postprocessing Settings

+ +
+
+ +
+ + seconds +
+

How much time to wait for unrar/7zip/mediainfo/ffmpeg/avconv before killing it, set to 0 to disable. 60 is a good value. Requires the GNU Timeout path to be set.

+
+ +
+ +
+ + seconds +
+

Maximum wall-clock seconds to spend processing a single release before skipping it. Keep this below the multiprocessing child timeout. Set to 0 to disable. Default: 120.

+
+ +
+ + +

Number of times a release can time out during post-processing before it is permanently deleted. Default: 3.

+
+ +
+ + +

Releases claimed per worker batch for passwords, previews, and media info. Larger batches reduce query overhead but increase each worker's memory and runtime. Each thread can hold one NNTP connection.

+
+ +
+ + +

If a part fails to download while post processing, this will retry up to the amount you set, then give up.

+
+ +
+ + +

This overrides the above setting if set above 1. How many parts to check for a password before giving up. This slows down post processing massively, better to leave it 1.

+
+ +
+ + +

The maximum amount of TV shows to processper run.

+
+ +
+ + +

The maximum amount of movies to process with IMDB per run.

+
+ +
+ + +

The maximum amount of anime to process with anidb per run.

+
+ +
+ + +

The maximum amount of music to process with metadata lookups per run. This does not use an NNTP connection.

+
+ +
+ + +

The maximum amount of games to process with metadata lookups per run. This does not use an NNTP connection.

+
+ +
+ + +

The maximum amount of books to process with metadata lookups per run. This does not use an NNTP connection

+
+ +
+ + +

The maximum number of releases to check per run (threaded script only).

+
+ +
+ +
+ + ms +
+

Sleep time in milliseconds to wait between external metadata requests. If you thread post-proc, multiply by the number of threads. ie Postprocessing Threads = 12, sleep time = 12000

+
+
+
diff --git a/resources/views/admin/site/sections/registration-settings.blade.php b/resources/views/admin/site/sections/registration-settings.blade.php new file mode 100644 index 000000000..f8348e9a9 --- /dev/null +++ b/resources/views/admin/site/sections/registration-settings.blade.php @@ -0,0 +1,39 @@ + +
+

User Settings

+ +
+
+ +
+

+ Registration status, scheduled open periods, and registration activity are now managed from the dedicated registration admin page. +

+ + Open Registration Admin + +
+
+ +
+ + +

The number of days to preserve user download history, for use when checking limits being hit. Set to zero will remove all records of what users download, but retain history of when, so that role based limits can still be applied.

+
+ +
+ + +

A comma separated list of IP addresses which will be excluded from user limits on number of requests and downloads per IP address. Include values for google reader and other shared services which may be being used.

+
+
+
diff --git a/resources/views/admin/site/sections/threaded-settings.blade.php b/resources/views/admin/site/sections/threaded-settings.blade.php new file mode 100644 index 000000000..d47d34ea1 --- /dev/null +++ b/resources/views/admin/site/sections/threaded-settings.blade.php @@ -0,0 +1,69 @@ + +
+

Advanced - Threaded Settings

+ +
+
+ + +

The number of threads for update_binaries. If you notice that you are getting a lot of parts into the missed_parts table, it is possible that you USP is not keeping up with the requests. Try to reduce the threads. At least until the cause can be determined.

+
+ +
+ + +

The number of threads for backfill.

+
+ +
+ + +

The number of threads for releases update scripts.

+
+ +
+ + +

Maximum simultaneous additional-processing workers and NNTP sessions. Workers reuse their process and connection across bounded batches; raise this only within CPU, memory, disk I/O, and provider connection limits.

+
+ +
+ + +

The number of threads for nfo postprocessing. The max is 16, if you set anything higher it will use 16.

+
+ +
+ + +

The number of threads for video metadata postprocessing. This includes movies, anime and tv lookups.

+
+ +
+ + +

The number of threads for fixReleasesNames. This includes md5, nfos, par2 and filenames.

+
+
+
diff --git a/resources/views/admin/site/sections/usenet-settings.blade.php b/resources/views/admin/site/sections/usenet-settings.blade.php new file mode 100644 index 000000000..733d8aa02 --- /dev/null +++ b/resources/views/admin/site/sections/usenet-settings.blade.php @@ -0,0 +1,186 @@ + +
+

Usenet Settings

+ +
+
+ + +

Levels deep to store the nzb Files. If you change this you must run the misc/testing/DB/nzb-reorg script!

+
+ +
+ + +

The number of hours incomplete parts and binaries will be retained.

+
+ +
+ + +

The number of days releases will be retained for use throughout site. Set to 0 to disable.

+
+ +
+ + +

The number of hours releases categorized as Misc->Other will be retained. Set to 0 to disable.

+
+ +
+ + +

The number of hours releases categorized as Misc->Hashed will be retained. Set to 0 to disable.

+
+ +
+ + +

Default is 0 (off), which will remove parts in one go. If backfilling or importing and parts table is large, using chunks of 5000+ will speed up removal. Normal indexing is fastest with this setting at 0.

+
+ +
+ + +

The minimum number of files to make a release. i.e. if set to two, then releases which only contain one file will not be created.

+
+ +
+ + +

The minimum total size in bytes to make a release. If set to 0, then ignored.

+
+ +
+ + +

The maximum total size in bytes to make a release. If set to 0, then ignored. Only deletes during release creation.

+
+ +
+ + +

The minimum completion percent to make a release. i.e. if set to 97, then releases under 97% completion will not be created. If set to 0, then ignored.

+
+ +
+ + +

Whether to update download counts when someone downloads a release.

+
+ +
+ + +

The time in hours to check for crossposted releases - this will delete 1 of the releases if the 2 are posted by the same person in the same time period.

+
+ +
+ + +

The maximum number of messages to fetch at a time from the server.

+
+ +
+ + +

The maximum number of headers that update binaries sees as the total range. This ensures that a total of no more than this is attempted to be downloaded at one time per group.

+
+ +
+ + +
+
+ + +
+
+ + +
+
+

Scan back X (posts/days) for each new group? Can backfill to scan further.

+
+ +
+ + +

The target date for safe backfill. Format: YYYY-MM-DD

+
+ +
+ + +

Whether to disable a group automatically during backfill if the target date has been reached.

+
+
+
diff --git a/resources/views/admin/site/tmux-edit-content.blade.php b/resources/views/admin/site/tmux-edit-content.blade.php index 569cd1248..82b983f44 100644 --- a/resources/views/admin/site/tmux-edit-content.blade.php +++ b/resources/views/admin/site/tmux-edit-content.blade.php @@ -1,5 +1,5 @@
-
+

@@ -494,5 +494,5 @@

-
+
diff --git a/resources/views/admin/status/index.blade.php b/resources/views/admin/status/index.blade.php index 09589ee4c..13815b94c 100644 --- a/resources/views/admin/status/index.blade.php +++ b/resources/views/admin/status/index.blade.php @@ -112,7 +112,7 @@ {{ $incident->status->label() }} - {{ $incident->started_at->format('Y-m-d H:i') }} + {{ formatDateTime($incident->started_at) }} Edit @if($incident->status !== IncidentStatusEnum::Resolved) @@ -121,7 +121,13 @@ @endif -
+ @csrf @method('DELETE') diff --git a/resources/views/admin/user-role-history/index.blade.php b/resources/views/admin/user-role-history/index.blade.php index 02fb03edd..e0cb47a26 100644 --- a/resources/views/admin/user-role-history/index.blade.php +++ b/resources/views/admin/user-role-history/index.blade.php @@ -78,47 +78,24 @@
-
- - - - - - - - - - - - - - - - + + + Date + User + Old Role + New Role + Old Expiry + New Expiry + Stacked + Reason + Changed By + Actions + + @forelse($history as $record) @endforelse - -
- Date - - User - - Old Role - - New Role - - Old Expiry - - New Expiry - - Stacked - - Reason - - Changed By - - Actions -
- {{ $record->created_at->format('Y-m-d H:i:s') }} + {{ formatDateTimeSeconds($record->created_at) }} @if($record->user) @@ -148,10 +125,10 @@ @endif - {{ $record->old_expiry_date ? $record->old_expiry_date->format('Y-m-d H:i') : '-' }} + {{ $record->old_expiry_date ? formatDateTime($record->old_expiry_date) : '-' }} - {{ $record->new_expiry_date ? $record->new_expiry_date->format('Y-m-d H:i') : '-' }} + {{ $record->new_expiry_date ? formatDateTime($record->new_expiry_date) : '-' }} @if($record->is_stacked) @@ -196,9 +173,7 @@
-
+ @if($history->hasPages()) diff --git a/resources/views/admin/user-role-history/show.blade.php b/resources/views/admin/user-role-history/show.blade.php index 206fc68ed..762070dd7 100644 --- a/resources/views/admin/user-role-history/show.blade.php +++ b/resources/views/admin/user-role-history/show.blade.php @@ -101,7 +101,7 @@ @forelse($history as $record) - {{ $record->created_at->format('Y-m-d H:i:s') }} + {{ formatDateTimeSeconds($record->created_at) }} @if($record->oldRole) @@ -122,13 +122,13 @@ @endif - {{ $record->old_expiry_date ? $record->old_expiry_date->format('Y-m-d H:i') : '-' }} + {{ $record->old_expiry_date ? formatDateTime($record->old_expiry_date) : '-' }} - {{ $record->new_expiry_date ? $record->new_expiry_date->format('Y-m-d H:i') : '-' }} + {{ $record->new_expiry_date ? formatDateTime($record->new_expiry_date) : '-' }} - {{ $record->effective_date ? $record->effective_date->format('Y-m-d H:i') : '-' }} + {{ $record->effective_date ? formatDateTime($record->effective_date) : '-' }} @if($record->is_stacked) diff --git a/resources/views/admin/users/deleted.blade.php b/resources/views/admin/users/deleted.blade.php index 7b96af418..b8c084fa4 100644 --- a/resources/views/admin/users/deleted.blade.php +++ b/resources/views/admin/users/deleted.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -193,10 +193,10 @@ @endif - {{ $user->created_at ? $user->created_at->format('Y-m-d H:i') : 'N/A' }} + {{ $user->created_at ? formatDateTime($user->created_at) : 'N/A' }} - {{ $user->deleted_at ? $user->deleted_at->format('Y-m-d H:i') : 'N/A' }} + {{ $user->deleted_at ? formatDateTime($user->deleted_at) : 'N/A' }} @if($user->deleted_by === 'Self') @@ -256,13 +256,9 @@ {{ $deletedusers->links() }}
@else -
- -

No deleted users found

-

There are no soft-deleted users matching your filters.

-
+ @endif -
+
diff --git a/resources/views/admin/users/edit.blade.php b/resources/views/admin/users/edit.blade.php index 72bc47154..3ec15ef60 100644 --- a/resources/views/admin/users/edit.blade.php +++ b/resources/views/admin/users/edit.blade.php @@ -2,7 +2,7 @@ @section('content')
-
+
@@ -90,7 +90,7 @@ @if(!is_array($user) && !empty($user->pending_roles_id)) @php - $pendingRole = \Spatie\Permission\Models\Role::find($user->pending_roles_id); + $pendingRole = $user->pendingRole; @endphp
@@ -110,331 +110,9 @@
- -
-
- - @if(!empty($user->rolechangedate ?? '')) - @php - $expiryDate = \Carbon\Carbon::parse($user->rolechangedate); - $isExpired = $expiryDate->isPast(); - $daysUntilExpiry = abs($expiryDate->diffInDays(now())); - $totalHours = abs($expiryDate->diffInHours(now())); - $hoursUntilExpiry = abs($totalHours % 24); - @endphp - @if($isExpired) - - Expired - - @elseif($daysUntilExpiry <= 7) - - Expiring Soon - - @elseif($daysUntilExpiry <= 30) - - Active - - @else - - Active - - @endif - @else - - No Expiry - - @endif -
+ @include('admin.users.partials.role-expiry') - - - - - - - -
- -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
-
- - - - - -
-
- - - - - -
-
- - - - - - -
-
- - - @if(!empty($user->rolechangedate ?? '')) -
-
- -
-

- @if($isExpired) - Role expired {{ $expiryDate->diffForHumans() }} - @else - Role expires {{ $expiryDate->diffForHumans() }} - @endif -

-

- {{ $expiryDate->format('F j, Y') }} - - {{ $expiryDate->format('g:i A') }} -

- @if($daysUntilExpiry <= 7 && !$isExpired) -

- {{ $daysUntilExpiry }} day{{ $daysUntilExpiry != 1 ? 's' : '' }} and {{ $hoursUntilExpiry }} hour{{ $hoursUntilExpiry != 1 ? 's' : '' }} remaining -

- @endif -
-
-
- @else -

- - Leave empty for permanent role assignment, or use quick actions above to set an expiry date and time. -

- @endif -
- - - @if(!is_array($user)) - @php - $allPendingRoles = $user->getAllPendingStackedRoles(); - @endphp - @if($allPendingRoles->count() > 0) -
-
- - - SCHEDULED - -
- -
- @foreach($allPendingRoles as $index => $pendingRoleInfo) -
-
- - {{ $index + 1 }} - - {{ $pendingRoleInfo['role_name'] }} -
-
-
- - Starts: - - {{ $pendingRoleInfo['start_date']->format('M j, Y g:i A') }} -
- @if($pendingRoleInfo['end_date']) -
- - Ends: - - {{ $pendingRoleInfo['end_date']->format('M j, Y g:i A') }} -
- @endif -
- Time until activation: - {{ $pendingRoleInfo['start_date']->diffForHumans() }} -
-
-
- @endforeach -
- -
-

- - These roles will automatically activate in sequence as each previous role expires -

- @if(!empty($user->pending_roles_id)) - - @endif -
-
- @elseif(!empty($user->pending_roles_id) && !empty($user->pending_role_start_date)) - {{-- Fallback to old display if no history records but pending_roles_id is set --}} -
-
- - - SCHEDULED - -
- - @php - $pendingRole = \Spatie\Permission\Models\Role::find($user->pending_roles_id); - $pendingStartDate = \Carbon\Carbon::parse($user->pending_role_start_date); - $daysUntilActivation = $pendingStartDate->diffInDays(now()); - @endphp - -
-
- Will change to: - {{ $pendingRole->name ?? 'Unknown' }} -
-
- Activation date: - {{ $pendingStartDate->format('M j, Y g:i A') }} -
-
- Time until activation: - {{ $pendingStartDate->diffForHumans(['parts' => 2]) }} -
-
- -
-

- - This role will automatically activate when the current role expires -

- -
-
- @endif - @endif + @include('admin.users.partials.pending-role') @if(!is_array($user) && !empty($user->rolechangedate) && \Carbon\Carbon::parse($user->rolechangedate)->isFuture()) @@ -455,78 +133,7 @@
@endif - @if(!empty($user['id'])) - -
- - -

- Total grabs is read-only and automatically tracked -

-
- - -
-
- - -
-
- -
-
-
-

- API Requests -

-

- {{ is_array($user) ? ($user['daily_api_count'] ?? 0) : ($user->daily_api_count ?? 0) }} -

-
-
- -
-
-

- In the last 24 hours -

-
- - -
-
-
-

- Downloads -

-

- {{ is_array($user) ? ($user['daily_download_count'] ?? 0) : ($user->daily_download_count ?? 0) }} -

-
-
- -
-
-

- In the last 24 hours -

-
-
-

- - These counters show activity from the past 24 hours and are automatically updated. -

-
- @endif + @include('admin.users.partials.activity-stats')
@@ -551,160 +158,7 @@ class="w-full px-3 py-2 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 border border-gray-300 dark:border-gray-600 rounded-md focus:ring-blue-500 focus:border-blue-500">{{ is_array($user) ? ($user['notes'] ?? '') : ($user->notes ?? '') }}
- @if(!empty($user['id'])) - -
- -
-
- movieview ?? 0)) ? 'checked' : '' }} - class="h-4 w-4 text-blue-600 dark:text-blue-400 focus:ring-blue-500 border-gray-300 dark:border-gray-600 rounded"> - -
-
- musicview ?? 0)) ? 'checked' : '' }} - class="h-4 w-4 text-blue-600 dark:text-blue-400 focus:ring-blue-500 border-gray-300 dark:border-gray-600 rounded"> - -
-
- gameview ?? 0)) ? 'checked' : '' }} - class="h-4 w-4 text-blue-600 dark:text-blue-400 focus:ring-blue-500 border-gray-300 dark:border-gray-600 rounded"> - -
-
- consoleview ?? 0)) ? 'checked' : '' }} - class="h-4 w-4 text-blue-600 dark:text-blue-400 focus:ring-blue-500 border-gray-300 dark:border-gray-600 rounded"> - -
-
- bookview ?? 0)) ? 'checked' : '' }} - class="h-4 w-4 text-blue-600 dark:text-blue-400 focus:ring-blue-500 border-gray-300 dark:border-gray-600 rounded"> - -
-
-
- @endif -
- - - @if(!is_array($user)) -
passkeys->isNotEmpty()) x-data="adminUserPasskeys" @endif> -
-

- Passkeys (WebAuthn) -

- - {{ $user->passkeys->count() }} registered - -
- - @if($user->passkeys->isEmpty()) -
- This user has no registered passkeys. They can create one from their profile security settings. -
- @else -
- - - - - - - - - - - @foreach($user->passkeys as $passkey) - - - - - - - @endforeach - -
NameCreatedLast usedActions
{{ $passkey->name }}{{ optional($passkey->created_at)->diffForHumans() ?? 'Unknown' }}{{ optional($passkey->last_used_at)->diffForHumans() ?? 'Not used yet' }} -
- @csrf - @method('DELETE') - -
-
-
- @endif - - @if($user->passkeys->isNotEmpty()) -
- - -
-

- Remove all passkeys if this user lost or replaced their passkey device. -

- -
- @csrf - - -
- - -
- - -
-
-
- @endif -
- @endif + @include('admin.users.partials.view-preferences')
@@ -717,6 +171,6 @@
-
+
@endsection diff --git a/resources/views/admin/users/index.blade.php b/resources/views/admin/users/index.blade.php index 2be1c6155..1c6596106 100644 --- a/resources/views/admin/users/index.blade.php +++ b/resources/views/admin/users/index.blade.php @@ -128,7 +128,7 @@
-
+
@@ -311,7 +311,7 @@ @endif - {{ $user->created_at ? $user->created_at->format('Y-m-d') : 'N/A' }} + {{ $user->created_at ? formatDate($user->created_at) : 'N/A' }} + Grabs + + +

+ Total grabs is read-only and automatically tracked +

+
+ + +
+
+ + +
+
+ +
+
+
+

+ API Requests +

+

+ {{ is_array($user) ? ($user['daily_api_count'] ?? 0) : ($user->daily_api_count ?? 0) }} +

+
+
+ +
+
+

+ In the last 24 hours +

+
+ + +
+
+
+

+ Downloads +

+

+ {{ is_array($user) ? ($user['daily_download_count'] ?? 0) : ($user->daily_download_count ?? 0) }} +

+
+
+ +
+
+

+ In the last 24 hours +

+
+
+

+ + These counters show activity from the past 24 hours and are automatically updated. +

+
+ @endif diff --git a/resources/views/admin/users/partials/pending-role.blade.php b/resources/views/admin/users/partials/pending-role.blade.php new file mode 100644 index 000000000..664fede2d --- /dev/null +++ b/resources/views/admin/users/partials/pending-role.blade.php @@ -0,0 +1,113 @@ + + @if(!is_array($user)) + @php + $allPendingRoles = $user->getAllPendingStackedRoles(); + @endphp + @if($allPendingRoles->count() > 0) +
+
+ + + SCHEDULED + +
+ +
+ @foreach($allPendingRoles as $index => $pendingRoleInfo) +
+
+ + {{ $index + 1 }} + + {{ $pendingRoleInfo['role_name'] }} +
+
+
+ + Starts: + + {{ $pendingRoleInfo['start_date']->format('M j, Y g:i A') }} +
+ @if($pendingRoleInfo['end_date']) +
+ + Ends: + + {{ $pendingRoleInfo['end_date']->format('M j, Y g:i A') }} +
+ @endif +
+ Time until activation: + {{ $pendingRoleInfo['start_date']->diffForHumans() }} +
+
+
+ @endforeach +
+ +
+

+ + These roles will automatically activate in sequence as each previous role expires +

+ @if(!empty($user->pending_roles_id)) + + @endif +
+
+ @elseif(!empty($user->pending_roles_id) && !empty($user->pending_role_start_date)) + {{-- Fallback to old display if no history records but pending_roles_id is set --}} +
+
+ + + SCHEDULED + +
+ + @php + $pendingRole = $user->pendingRole; + $pendingStartDate = \Carbon\Carbon::parse($user->pending_role_start_date); + $daysUntilActivation = $pendingStartDate->diffInDays(now()); + @endphp + +
+
+ Will change to: + {{ $pendingRole->name ?? 'Unknown' }} +
+
+ Activation date: + {{ $pendingStartDate->format('M j, Y g:i A') }} +
+
+ Time until activation: + {{ $pendingStartDate->diffForHumans(['parts' => 2]) }} +
+
+ +
+

+ + This role will automatically activate when the current role expires +

+ +
+
+ @endif + @endif diff --git a/resources/views/admin/users/partials/role-expiry.blade.php b/resources/views/admin/users/partials/role-expiry.blade.php new file mode 100644 index 000000000..1dfeaf833 --- /dev/null +++ b/resources/views/admin/users/partials/role-expiry.blade.php @@ -0,0 +1,211 @@ + +
+
+ + @if(!empty($user->rolechangedate ?? '')) + @php + $expiryDate = \Carbon\Carbon::parse($user->rolechangedate); + $isExpired = $expiryDate->isPast(); + $daysUntilExpiry = abs($expiryDate->diffInDays(now())); + $totalHours = abs($expiryDate->diffInHours(now())); + $hoursUntilExpiry = abs($totalHours % 24); + @endphp + @if($isExpired) + + Expired + + @elseif($daysUntilExpiry <= 7) + + Expiring Soon + + @elseif($daysUntilExpiry <= 30) + + Active + + @else + + Active + + @endif + @else + + No Expiry + + @endif +
+ + + + + + + + +
+ +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + + +
+
+ + + @if(!empty($user->rolechangedate ?? '')) +
+
+ +
+

+ @if($isExpired) + Role expired {{ $expiryDate->diffForHumans() }} + @else + Role expires {{ $expiryDate->diffForHumans() }} + @endif +

+

+ {{ $expiryDate->format('F j, Y') }} + + {{ $expiryDate->format('g:i A') }} +

+ @if($daysUntilExpiry <= 7 && !$isExpired) +

+ {{ $daysUntilExpiry }} day{{ $daysUntilExpiry != 1 ? 's' : '' }} and {{ $hoursUntilExpiry }} hour{{ $hoursUntilExpiry != 1 ? 's' : '' }} remaining +

+ @endif +
+
+
+ @else +

+ + Leave empty for permanent role assignment, or use quick actions above to set an expiry date and time. +

+ @endif +
diff --git a/resources/views/admin/users/partials/view-preferences.blade.php b/resources/views/admin/users/partials/view-preferences.blade.php new file mode 100644 index 000000000..4f3d236a9 --- /dev/null +++ b/resources/views/admin/users/partials/view-preferences.blade.php @@ -0,0 +1,154 @@ + @if(!empty($user['id'])) + +
+ +
+
+ movieview ?? 0)) ? 'checked' : '' }} + class="h-4 w-4 text-blue-600 dark:text-blue-400 focus:ring-blue-500 border-gray-300 dark:border-gray-600 rounded"> + +
+
+ musicview ?? 0)) ? 'checked' : '' }} + class="h-4 w-4 text-blue-600 dark:text-blue-400 focus:ring-blue-500 border-gray-300 dark:border-gray-600 rounded"> + +
+
+ gameview ?? 0)) ? 'checked' : '' }} + class="h-4 w-4 text-blue-600 dark:text-blue-400 focus:ring-blue-500 border-gray-300 dark:border-gray-600 rounded"> + +
+
+ consoleview ?? 0)) ? 'checked' : '' }} + class="h-4 w-4 text-blue-600 dark:text-blue-400 focus:ring-blue-500 border-gray-300 dark:border-gray-600 rounded"> + +
+
+ bookview ?? 0)) ? 'checked' : '' }} + class="h-4 w-4 text-blue-600 dark:text-blue-400 focus:ring-blue-500 border-gray-300 dark:border-gray-600 rounded"> + +
+
+
+ @endif +
+ + + @if(!is_array($user)) +
passkeys->isNotEmpty()) x-data="adminUserPasskeys" @endif> +
+

+ Passkeys (WebAuthn) +

+ + {{ $user->passkeys->count() }} registered + +
+ + @if($user->passkeys->isEmpty()) +
+ This user has no registered passkeys. They can create one from their profile security settings. +
+ @else +
+ + + + + + + + + + + @foreach($user->passkeys as $passkey) + + + + + + + @endforeach + +
NameCreatedLast usedActions
{{ $passkey->name }}{{ optional($passkey->created_at)->diffForHumans() ?? 'Unknown' }}{{ optional($passkey->last_used_at)->diffForHumans() ?? 'Not used yet' }} +
+ @csrf + @method('DELETE') + +
+
+
+ @endif + + @if($user->passkeys->isNotEmpty()) +
+ + +
+

+ Remove all passkeys if this user lost or replaced their passkey device. +

+ +
+ @csrf + + +
+ + +
+ + +
+
+
+ @endif +
+ @endif diff --git a/resources/views/books/index.blade.php b/resources/views/books/index.blade.php index 6415e8b4b..8baeb2bca 100644 --- a/resources/views/books/index.blade.php +++ b/resources/views/books/index.blade.php @@ -99,6 +99,7 @@ {{ $result->title }} @else
@@ -149,15 +150,14 @@ {{ $results->links() }}
@else - -
- -

No books found

-

Try adjusting your search filters or browse all books.

- - Browse All Books - -
+ @endif
diff --git a/resources/views/components/release-results.blade.php b/resources/views/components/release-results.blade.php index 6feb093cf..099148fe7 100644 --- a/resources/views/components/release-results.blade.php +++ b/resources/views/components/release-results.blade.php @@ -46,7 +46,7 @@ $hasValidCover = $coverUrl && !str_contains($coverUrl, 'no-cover.png'); @endphp @if($hasValidCover) - query('thumbs') === '1') style="display:none" @endunless> + query('thumbs') === '1') x-cloak @endunless> Cover @endif @@ -209,7 +209,7 @@ $mHasCover = $mCoverUrl && !str_contains($mCoverUrl, 'no-cover.png'); @endphp @if($mHasCover) - query('thumbs') === '1') style="display:none" @endunless> + query('thumbs') === '1') x-cloak @endunless> Cover @endif diff --git a/resources/views/console/index.blade.php b/resources/views/console/index.blade.php index 07eba2e6a..6ce31761e 100644 --- a/resources/views/console/index.blade.php +++ b/resources/views/console/index.blade.php @@ -75,6 +75,7 @@ {{ $result->title }} @if($totalFailed > 0)
diff --git a/resources/views/details/index.blade.php b/resources/views/details/index.blade.php index 3f321f527..3accc02b7 100644 --- a/resources/views/details/index.blade.php +++ b/resources/views/details/index.blade.php @@ -18,1114 +18,39 @@
- -
-
- -
- {{ $release->searchname }} -
+ @include('details.partials.cover-actions') - -
-
-

{{ $release->searchname }}

-
- @if(!empty($totalReportCount) && $totalReportCount > 0) -
- - Reported ({{ $totalReportCount }}): {{ $allReportReasons ?? 'Unknown' }} -
- @endif - @if(!empty($failed) && $failed > 0) -
- - {{ $failed }} user{{ $failed > 1 ? 's' : '' }} reported download failure -
- @endif -
-
-
- - Download NZB - - - Add to Cart - - @if(isset($release->nfostatus) && $release->nfostatus == 1) - - @endif - @if(($release->totalpart ?? 0) > 0) - - @endif - @auth - @if(auth()->user()->hasRole('Admin') || auth()->user()->hasRole('Moderator')) - - Edit Release - - @endif - @endauth - -
- @if(!empty($originalReportData) && $originalReportData->count() > 0) -
-

- Original report -

-
- @foreach($originalReportData as $originalReport) -
-
- - {{ $originalReport->reason_label }} - - - {{ ucfirst($originalReport->status) }} · Reported {{ $originalReport->created_at->format('M d, Y H:i') }} - -
-
- {{ $originalReport->description ?: 'No additional report details were provided.' }} -
-
- @endforeach -
-
- @endif - @if(!empty($publicReportResponses) && $publicReportResponses->count() > 0) -
-

- Staff response -

-
- @foreach($publicReportResponses as $responseReport) -
-
{{ $responseReport->response }}
-
- {{ $responseReport->responded_at ? 'Responded ' . $responseReport->responded_at->format('M d, Y H:i') : 'Staff response' }} - @if($responseReport->responder) - by {{ $responseReport->responder->username }} - @endif -
-
- @endforeach -
-
- @endif -
-
-
+ @include('details.partials.preview-images') - - @php - $hasPreviewImage = isset($release->haspreview) && $release->haspreview == 1; - $hasSampleImage = isset($release->jpgstatus) && $release->jpgstatus == 1; - $previewImageUrl = $hasPreviewImage - ? getImageAssetUrl('preview', $release->guid . '_thumb', asset('assets/images/no-cover.png')) - : null; - $sampleImageUrl = $hasSampleImage - ? getImageAssetUrl('sample', $release->guid . '_thumb', asset('assets/images/no-cover.png')) - : null; - @endphp + @include('details.partials.movie-info') - @if($hasPreviewImage || $hasSampleImage) -
-

- - @if($hasPreviewImage && $hasSampleImage) - Preview & Sample Images - @elseif($hasPreviewImage) - Preview Image - @else - Sample Image - @endif -

-
- @if($hasPreviewImage) - -
-
- Preview -
-

Preview

-
- @endif + @include('details.partials.tv-info') - @if($hasSampleImage) - -
-
- Sample -
-

Sample

-
- @endif -
-
- @endif + @include('details.partials.music-info') - - @if(!empty($movie)) - @php - $movieData = is_object($movie) ? get_object_vars($movie) : $movie; - $movieTitle = $movieData['title'] ?? ($movie->title ?? null); - $movieYear = $movieData['year'] ?? ($movie->year ?? null); - $movieTagline = $movieData['tagline'] ?? ($movie->tagline ?? null); - $movieRating = $movieData['rating'] ?? ($movie->rating ?? null); - $moviePlot = $movieData['plot'] ?? ($movie->plot ?? null); - $movieGenre = $movieData['genre'] ?? ($movie->genre ?? null); - $movieDirector = $movieData['director'] ?? ($movie->director ?? null); - $movieActors = $movieData['actors'] ?? ($movie->actors ?? null); - $movieLanguage = $movieData['language'] ?? ($movie->language ?? null); - $movieTrailer = $movieData['trailer'] ?? ($movie->trailer ?? null); - @endphp -
-

- Movie Information -

-
- @if(!empty($movieTitle)) -
-
Title
-
{{ $movieTitle }}
-
- @endif - @if(!empty($movieYear)) -
-
Year
-
{{ $movieYear }}
-
- @endif - @if(!empty($movieTagline)) -
-
Tagline
-
"{{ $movieTagline }}"
-
- @endif - @if(!empty($movieRating)) -
-
IMDB Rating
-
- - - {{ $movieRating }}/10 - -
-
- @endif - @if(!empty($moviePlot)) -
-
Plot Synopsis
-
{{ $moviePlot }}
-
- @endif - @if(!empty($movieGenre)) -
-
Genre
-
{!! $movieGenre !!}
-
- @endif - @if(!empty($movieDirector)) -
-
Director
-
{!! $movieDirector !!}
-
- @endif - @if(!empty($movieActors)) -
-
Cast
-
{!! $movieActors !!}
-
- @endif - @if(!empty($movieLanguage)) -
-
Language
-
{{ $movieLanguage }}
-
- @endif -
- @if(!empty($movieTrailer)) -
-

Trailer

-
- {!! $movieTrailer !!} -
-
- @endif -
- @endif + @include('details.partials.game-info') - - @if(!empty($show)) - @php - $showData = is_object($show) ? get_object_vars($show) : $show; - $showTitle = $showData['title'] ?? ($show->title ?? null); - $showStarted = $showData['started'] ?? ($show->started ?? null); - $showTvdb = $showData['tvdb'] ?? ($show->tvdb ?? null); - @endphp -
-

- TV Show Information -

-
- @if(!empty($showTitle)) -
-
Show Title
-
{{ $showTitle }}
-
- @endif - @if(!empty($showStarted)) -
-
Started
-
{{ $showStarted }}
-
- @endif - @if(!empty($showTvdb)) -
-
TVDB
-
- - View on TVDB - -
-
- @endif -
-
- @endif + @include('details.partials.console-info') - - @if(!empty($music)) - @php - $musicData = is_object($music) ? get_object_vars($music) : $music; - $musicTitle = $musicData['title'] ?? ($music->title ?? null); - $musicArtist = $musicData['artist'] ?? ($music->artist ?? null); - $musicPublisher = $musicData['publisher'] ?? ($music->publisher ?? null); - $musicReleaseDate = $musicData['releasedate'] ?? ($music->releasedate ?? null); - $musicGenres = $musicData['genres'] ?? ($music->genres ?? null); - @endphp -
-

- Music Information -

-
- @if(!empty($musicTitle)) -
-
Album
-
{{ $musicTitle }}
-
- @endif - @if(!empty($musicArtist)) -
-
Artist
-
{{ $musicArtist }}
-
- @endif - @if(!empty($musicPublisher)) -
-
Publisher
-
{{ $musicPublisher }}
-
- @endif - @if(!empty($musicReleaseDate)) -
-
Release Date
-
{{ $musicReleaseDate }}
-
- @endif - @if(!empty($musicGenres)) -
-
Genres
-
{{ $musicGenres }}
-
- @endif -
-
- @endif + @include('details.partials.book-info') - - @if(!empty($game)) - @php - $gameData = is_object($game) ? get_object_vars($game) : $game; - $gameTitle = $gameData['title'] ?? ($game->title ?? null); - $gamePublisher = $gameData['publisher'] ?? ($game->publisher ?? null); - $gameReleaseDate = $gameData['releasedate'] ?? ($game->releasedate ?? null); - $gameGenres = $gameData['genres'] ?? ($game->genres ?? null); - @endphp -
-

- Game Information -

-
- @if(!empty($gameTitle)) -
-
Title
-
{{ $gameTitle }}
-
- @endif - @if(!empty($gamePublisher)) -
-
Publisher
-
{{ $gamePublisher }}
-
- @endif - @if(!empty($gameReleaseDate)) -
-
Release Date
-
{{ $gameReleaseDate }}
-
- @endif - @if(!empty($gameGenres)) -
-
Genres
-
{{ $gameGenres }}
-
- @endif -
-
- @endif + @include('details.partials.anime-info') - - @if(!empty($con)) - @php - $conData = is_object($con) ? get_object_vars($con) : $con; - $conTitle = $conData['title'] ?? ($con->title ?? null); - $conPublisher = $conData['publisher'] ?? ($con->publisher ?? null); - $conReleaseDate = $conData['releasedate'] ?? ($con->releasedate ?? null); - @endphp -
-

- Console Game Information -

-
- @if(!empty($conTitle)) -
-
Title
-
{{ $conTitle }}
-
- @endif - @if(!empty($conPublisher)) -
-
Publisher
-
{{ $conPublisher }}
-
- @endif - @if(!empty($conReleaseDate)) -
-
Release Date
-
{{ $conReleaseDate }}
-
- @endif -
-
- @endif + @include('details.partials.password-info') - - @if(!empty($book)) - @php - $bookData = is_object($book) ? get_object_vars($book) : $book; - $bookTitle = $bookData['title'] ?? ($book->title ?? null); - $bookAuthor = $bookData['author'] ?? ($book->author ?? null); - $bookPublisher = $bookData['publisher'] ?? ($book->publisher ?? null); - $bookPublishDate = $bookData['publishdate'] ?? ($book->publishdate ?? null); - $bookOverview = $bookData['overview'] ?? ($book->overview ?? null); - @endphp -
-

- Book Information -

-
- @if(!empty($bookTitle)) -
-
Title
-
{{ $bookTitle }}
-
- @endif - @if(!empty($bookAuthor)) -
-
Author
-
{{ $bookAuthor }}
-
- @endif - @if(!empty($bookPublisher)) -
-
Publisher
-
{{ $bookPublisher }}
-
- @endif - @if(!empty($bookPublishDate)) -
-
Published
-
{{ $bookPublishDate }}
-
- @endif - @if(!empty($bookOverview)) -
-
Overview
-
{{ $bookOverview }}
-
- @endif -
-
- @endif + @include('details.partials.media-metadata') - - @if(!empty($anidb)) - @php - $anidbData = is_object($anidb) ? get_object_vars($anidb) : $anidb; - $anidbTitle = $anidbData['title'] ?? ($anidb->title ?? null); - $anidbEnglishTitle = $anidbData['english_title'] ?? ($anidb->english_title ?? null); - $anidbOriginalTitle = $anidbData['original_title'] ?? ($anidb->original_title ?? null); - $anidbOriginalLang = $anidbData['original_lang'] ?? ($anidb->original_lang ?? null); - $anidbRomajiTitle = $anidbData['romaji_title'] ?? ($anidb->romaji_title ?? null); - $anidbHashtag = $anidbData['hashtag'] ?? ($anidb->hashtag ?? null); - $anidbType = $anidbData['type'] ?? ($anidb->type ?? null); - $anidbMediaType = $anidbData['media_type'] ?? ($anidb->media_type ?? null); - $anidbCountry = $anidbData['country'] ?? ($anidb->country ?? null); - $anidbEpisodes = $anidbData['episodes'] ?? ($anidb->episodes ?? null); - $anidbDuration = $anidbData['duration'] ?? ($anidb->duration ?? null); - $anidbStatus = $anidbData['status'] ?? ($anidb->status ?? null); - $anidbSource = $anidbData['source'] ?? ($anidb->source ?? null); - $anidbStartDate = $anidbData['startdate'] ?? ($anidb->startdate ?? null); - $anidbEndDate = $anidbData['enddate'] ?? ($anidb->enddate ?? null); - $anidbRating = $anidbData['rating'] ?? ($anidb->rating ?? null); - $anidbDescription = $anidbData['description'] ?? ($anidb->description ?? null); - $anidbCategories = $anidbData['categories'] ?? ($anidb->categories ?? null); - $anidbCreators = $anidbData['creators'] ?? ($anidb->creators ?? null); + @include('details.partials.predb-info') - // Get country name from country code - $countryName = null; - if (!empty($anidbCountry)) { - $country = \App\Models\Country::query()->find($anidbCountry); - $countryName = $country->name ?? $anidbCountry; - } - - // Format status - $statusLabels = [ - 'FINISHED' => 'Finished', - 'RELEASING' => 'Releasing', - 'NOT_YET_RELEASED' => 'Not Yet Released', - 'CANCELLED' => 'Cancelled', - 'HIATUS' => 'Hiatus', - ]; - $anidbStatusLabel = $statusLabels[$anidbStatus] ?? $anidbStatus; - - // Format source - $sourceLabels = [ - 'ORIGINAL' => 'Original', - 'MANGA' => 'Manga', - 'LIGHT_NOVEL' => 'Light Novel', - 'VISUAL_NOVEL' => 'Visual Novel', - 'VIDEO_GAME' => 'Video Game', - 'OTHER' => 'Other', - 'NOVEL' => 'Novel', - 'DOUJINSHI' => 'Doujinshi', - 'ANIME' => 'Anime', - 'WEB_MANGA' => 'Web Manga', - 'MUSIC' => 'Music', - '4_KOMA_MANGA' => '4-Koma Manga', - ]; - $anidbSourceLabel = $sourceLabels[$anidbSource] ?? $anidbSource; - @endphp -
-

- - @if($anidbMediaType === 'MANGA') - Manga Information - @else - Anime Information - @endif -

-
- @if(!empty($anidbEnglishTitle) || !empty($anidbOriginalTitle) || !empty($anidbRomajiTitle) || !empty($anidbHashtag)) -
-
Titles
-
- @if(!empty($anidbEnglishTitle)) -
- English: - {{ $anidbEnglishTitle }} -
- @endif - @if(!empty($anidbOriginalTitle) && $anidbOriginalLang === 'ja') -
- Native: - {{ $anidbOriginalTitle }} -
- @endif - @if(!empty($anidbRomajiTitle)) -
- Romaji: - {{ $anidbRomajiTitle }} -
- @elseif(!empty($anidbOriginalTitle) && $anidbOriginalLang === 'x-jat') -
- Romaji: - {{ $anidbOriginalTitle }} -
- @elseif(!empty($anidbOriginalTitle) && $anidbOriginalLang !== 'ja') -
- Original: - {{ $anidbOriginalTitle }} -
- @endif - @if(!empty($anidbHashtag)) -
- Hashtag: - {{ $anidbHashtag }} -
- @endif - @if(empty($anidbEnglishTitle) && empty($anidbOriginalTitle) && empty($anidbRomajiTitle) && !empty($anidbTitle)) -
- {{ $anidbTitle }} -
- @endif -
-
- @elseif(!empty($anidbTitle)) -
-
Title
-
{{ $anidbTitle }}
-
- @endif - @if(!empty($anidbMediaType)) -
-
Media Type
-
- - {{ $anidbMediaType === 'ANIME' ? 'Anime' : 'Manga' }} - -
-
- @endif - @if(!empty($anidbType)) -
-
Format
-
{{ ucfirst(str_replace('_', ' ', strtolower($anidbType))) }}
-
- @endif - @if(!empty($countryName)) -
-
Country
-
- - @if(!empty($country)) - {{ $countryName }} - @endif - {{ $countryName }} - -
-
- @endif - @if(!empty($anidbStatus)) -
-
Status
-
{{ $anidbStatusLabel }}
-
- @endif - @if(!empty($anidbSource)) -
-
Source
-
{{ $anidbSourceLabel }}
-
- @endif - @if(!empty($anidbEpisodes)) -
-
Episodes
-
{{ number_format($anidbEpisodes) }}
-
- @endif - @if(!empty($anidbDuration)) -
-
Duration
-
{{ $anidbDuration }} minutes
-
- @endif - @if(!empty($anidbStartDate)) -
-
Start Date
-
{{ $anidbStartDate }}
-
- @endif - @if(!empty($anidbEndDate)) -
-
End Date
-
{{ $anidbEndDate }}
-
- @endif - @if(!empty($anidbRating)) -
-
Rating
-
- - - @php - $ratingValue = is_numeric($anidbRating) ? (float)$anidbRating : 0; - // AniList rating is out of 100, convert to /10 - $displayRating = $ratingValue > 10 ? number_format($ratingValue / 10, 1) : number_format($ratingValue, 1); - @endphp - {{ $displayRating }} / 10 - -
-
- @endif - @if(!empty($anidbCategories)) -
-
Genres
-
{{ $anidbCategories }}
-
- @endif - @if(!empty($anidbCreators)) -
-
Studios
-
{{ $anidbCreators }}
-
- @endif - @if(!empty($anidbDescription)) -
-
Description
-
{{ $anidbDescription }}
-
- @endif -
- - - @php - $anilistId = $anidbData['anilist_id'] ?? ($anidb->anilist_id ?? null); - $malId = $anidbData['mal_id'] ?? ($anidb->mal_id ?? null); - @endphp - @if(!empty($anilistId) || !empty($malId)) -
-

External Links

-
- @if(!empty($anilistId)) - - View on AniList - - @endif - @if(!empty($malId)) - - View on MyAnimeList - - @endif -
-
- @endif -
- @endif - - - @if(isset($release->passwordstatus) && $release->passwordstatus > 0) -
-

- Password Protected Release -

-
-
-
Password Status
-
- @if($release->passwordstatus == 1) - - Password Unknown - - @elseif($release->passwordstatus == 2) - - Password Available - - @endif -
-
-
-
Password
-
- @if(!empty($release->password)) -
- {{ $release->password }} -
-

- - This password is embedded in the NZB file and will be automatically recognized by NZBGet or SABnzbd. -

- @else -
- None -
-

- - No password information available in the database. -

- @endif -
-
-
-
- @endif - - - @if(!empty($reVideo) || !empty($reAudio) || !empty($reSubs)) -
-

- Media Information -

- - @if(!empty($reVideo)) -
-

- Video Details -

-
-
- @if(!empty($reVideo['containerformat'])) -
-
Container Format
-
{{ $reVideo['containerformat'] }}
-
- @endif - @if(!empty($reVideo['videocodec'])) -
-
Video Codec
-
{{ $reVideo['videocodec'] }}
-
- @endif - @if(!empty($reVideo['videoformat'])) -
-
Video Format
-
{{ $reVideo['videoformat'] }}
-
- @endif - @if(!empty($reVideo['videowidth']) && !empty($reVideo['videoheight'])) -
-
Resolution
-
{{ $reVideo['videowidth'] }}x{{ $reVideo['videoheight'] }}
-
- @endif - @if(!empty($reVideo['videoaspect'])) -
-
Aspect Ratio
-
{{ $reVideo['videoaspect'] }}
-
- @endif - @if(!empty($reVideo['videoframerate'])) -
-
Frame Rate
-
{{ $reVideo['videoframerate'] }} fps
-
- @endif - @if(!empty($reVideo['videoduration'])) - @php - $durationMs = intval($reVideo['videoduration']); - $durationMinutes = $durationMs > 0 ? round($durationMs / 1000 / 60) : 0; - @endphp - @if($durationMinutes > 0) -
-
Duration
-
{{ $durationMinutes }} minutes
-
- @endif - @endif - @if(!empty($reVideo['overallbitrate'])) -
-
Bit Rate
-
{{ $reVideo['overallbitrate'] }}
-
- @endif - @if(!empty($reVideo['videolibrary'])) -
-
Encoder Library
-
{{ $reVideo['videolibrary'] }}
-
- @endif -
-
-
- @endif - - @if(!empty($reAudio)) -
-

- Audio Details -

- @foreach($reAudio as $index => $audio) -
- @if(count($reAudio) > 1) -

Track {{ $index + 1 }}

- @endif -
- @if(!empty($audio['audioformat'])) -
-
Audio Format
-
{{ $audio['audioformat'] }}
-
- @endif - @if(!empty($audio['audiocodec'])) -
-
Codec
-
{{ $audio['audiocodec'] }}
-
- @endif - @if(!empty($audio['audiochannels'])) -
-
Channels
-
{{ $audio['audiochannels'] }}
-
- @endif - @if(!empty($audio['audiobitrate'])) -
-
Bit Rate
-
{{ $audio['audiobitrate'] }}
-
- @endif - @if(!empty($audio['audiolanguage'])) -
-
Language
-
{{ $audio['audiolanguage'] }}
-
- @endif - @if(!empty($audio['audiosamplerate'])) -
-
Sample Rate
-
{{ $audio['audiosamplerate'] }} Hz
-
- @endif -
-
- @endforeach -
- @endif - - @if(!empty($reSubs)) -
-

- Subtitles -

-
-

{{ $reSubs->subs }}

-
-
- @endif -
- @endif - - - @if(!empty($predb) && is_array($predb)) -
-

- PreDB Information -

-
- @if(!empty($predb['title'])) -
-
Title
-
{{ $predb['title'] }}
-
- @endif - @if(!empty($predb['source'])) -
-
Source
-
{{ $predb['source'] }}
-
- @endif - @if(!empty($predb['predate'])) -
-
Pre Date
-
{{ $predb['predate'] }}
-
- @endif - @if(!empty($predb['category'])) -
-
Category
-
{{ $predb['category'] }}
-
- @endif -
-
- @endif - - -
-

- - Comments ({{ isset($comments) ? count($comments) : 0 }}) -

- - - @if(session('success')) -
-

- - {{ session('success') }} -

-
- @endif - - @if(session('error')) -
-

- - {{ session('error') }} -

-
- @endif - - - @auth -
-
- @csrf -
- - -
-
- -
-
-
- @else -
-

- - Please log in to add a comment. -

-
- @endauth - - - @if(isset($comments) && count($comments) > 0) -
- @foreach($comments as $comment) -
-
-
-
- {{ strtoupper(substr($comment['username'] ?? 'U', 0, 1)) }} -
-
-

{{ $comment['username'] ?? 'Anonymous' }}

-

- - {{ \Carbon\Carbon::parse($comment['created_at'])->diffForHumans() }} -

-
-
-
-

{{ $comment['text'] ?? '' }}

-
- @endforeach -
- @else -
- -

No comments yet. Be the first to comment!

-
- @endif -
+ @include('details.partials.comments')
- -
-
-

Information

-
-
-
Category
-
{{ $release->category_name ?? 'Other' }}
-
-
-
Size
-
{{ number_format($release->size / 1073741824, 2) }} GB
-
-
-
Files
-
{{ $release->totalpart ?? 0 }}
-
-
-
Added
-
{{ userDate($release->adddate, 'M d, Y H:i') }}
-
-
-
Group
-
{{ $release->group_name ?? 'Unknown' }}
-
-
-
Posted
-
{{ userDate($release->postdate, 'M d, Y H:i') }}
-
- @if(!empty($release->fromname)) -
-
Posted By
-
- - {{ $release->fromname }} - -
-
- @endif -
-
Grabs
-
{{ $release->grabs ?? 0 }}
-
- @if($release->imdbid ?? false) -
-
IMDB
-
- - View on IMDB - -
-
- @endif -
-
-
+ @include('details.partials.info-sidebar')
@endsection - - +@include('details.partials.image-modal') {{-- NFO modal is included globally via layouts.main --}} diff --git a/resources/views/details/partials/anime-info.blade.php b/resources/views/details/partials/anime-info.blade.php new file mode 100644 index 000000000..99af3aad0 --- /dev/null +++ b/resources/views/details/partials/anime-info.blade.php @@ -0,0 +1,245 @@ + + @if(!empty($anidb)) + @php + $anidbData = is_object($anidb) ? get_object_vars($anidb) : $anidb; + $anidbTitle = $anidbData['title'] ?? ($anidb->title ?? null); + $anidbEnglishTitle = $anidbData['english_title'] ?? ($anidb->english_title ?? null); + $anidbOriginalTitle = $anidbData['original_title'] ?? ($anidb->original_title ?? null); + $anidbOriginalLang = $anidbData['original_lang'] ?? ($anidb->original_lang ?? null); + $anidbRomajiTitle = $anidbData['romaji_title'] ?? ($anidb->romaji_title ?? null); + $anidbHashtag = $anidbData['hashtag'] ?? ($anidb->hashtag ?? null); + $anidbType = $anidbData['type'] ?? ($anidb->type ?? null); + $anidbMediaType = $anidbData['media_type'] ?? ($anidb->media_type ?? null); + $anidbCountry = $anidbData['country'] ?? ($anidb->country ?? null); + $anidbEpisodes = $anidbData['episodes'] ?? ($anidb->episodes ?? null); + $anidbDuration = $anidbData['duration'] ?? ($anidb->duration ?? null); + $anidbStatus = $anidbData['status'] ?? ($anidb->status ?? null); + $anidbSource = $anidbData['source'] ?? ($anidb->source ?? null); + $anidbStartDate = $anidbData['startdate'] ?? ($anidb->startdate ?? null); + $anidbEndDate = $anidbData['enddate'] ?? ($anidb->enddate ?? null); + $anidbRating = $anidbData['rating'] ?? ($anidb->rating ?? null); + $anidbDescription = $anidbData['description'] ?? ($anidb->description ?? null); + $anidbCategories = $anidbData['categories'] ?? ($anidb->categories ?? null); + $anidbCreators = $anidbData['creators'] ?? ($anidb->creators ?? null); + + // Country model/name are resolved in DetailsController + $country = $anidbCountryModel ?? null; + $countryName = $anidbCountryName ?? null; + + // Format status + $statusLabels = [ + 'FINISHED' => 'Finished', + 'RELEASING' => 'Releasing', + 'NOT_YET_RELEASED' => 'Not Yet Released', + 'CANCELLED' => 'Cancelled', + 'HIATUS' => 'Hiatus', + ]; + $anidbStatusLabel = $statusLabels[$anidbStatus] ?? $anidbStatus; + + // Format source + $sourceLabels = [ + 'ORIGINAL' => 'Original', + 'MANGA' => 'Manga', + 'LIGHT_NOVEL' => 'Light Novel', + 'VISUAL_NOVEL' => 'Visual Novel', + 'VIDEO_GAME' => 'Video Game', + 'OTHER' => 'Other', + 'NOVEL' => 'Novel', + 'DOUJINSHI' => 'Doujinshi', + 'ANIME' => 'Anime', + 'WEB_MANGA' => 'Web Manga', + 'MUSIC' => 'Music', + '4_KOMA_MANGA' => '4-Koma Manga', + ]; + $anidbSourceLabel = $sourceLabels[$anidbSource] ?? $anidbSource; + @endphp +
+

+ + @if($anidbMediaType === 'MANGA') + Manga Information + @else + Anime Information + @endif +

+
+ @if(!empty($anidbEnglishTitle) || !empty($anidbOriginalTitle) || !empty($anidbRomajiTitle) || !empty($anidbHashtag)) +
+
Titles
+
+ @if(!empty($anidbEnglishTitle)) +
+ English: + {{ $anidbEnglishTitle }} +
+ @endif + @if(!empty($anidbOriginalTitle) && $anidbOriginalLang === 'ja') +
+ Native: + {{ $anidbOriginalTitle }} +
+ @endif + @if(!empty($anidbRomajiTitle)) +
+ Romaji: + {{ $anidbRomajiTitle }} +
+ @elseif(!empty($anidbOriginalTitle) && $anidbOriginalLang === 'x-jat') +
+ Romaji: + {{ $anidbOriginalTitle }} +
+ @elseif(!empty($anidbOriginalTitle) && $anidbOriginalLang !== 'ja') +
+ Original: + {{ $anidbOriginalTitle }} +
+ @endif + @if(!empty($anidbHashtag)) +
+ Hashtag: + {{ $anidbHashtag }} +
+ @endif + @if(empty($anidbEnglishTitle) && empty($anidbOriginalTitle) && empty($anidbRomajiTitle) && !empty($anidbTitle)) +
+ {{ $anidbTitle }} +
+ @endif +
+
+ @elseif(!empty($anidbTitle)) +
+
Title
+
{{ $anidbTitle }}
+
+ @endif + @if(!empty($anidbMediaType)) +
+
Media Type
+
+ + {{ $anidbMediaType === 'ANIME' ? 'Anime' : 'Manga' }} + +
+
+ @endif + @if(!empty($anidbType)) +
+
Format
+
{{ ucfirst(str_replace('_', ' ', strtolower($anidbType))) }}
+
+ @endif + @if(!empty($countryName)) +
+
Country
+
+ + @if(!empty($country)) + {{ $countryName }} + @endif + {{ $countryName }} + +
+
+ @endif + @if(!empty($anidbStatus)) +
+
Status
+
{{ $anidbStatusLabel }}
+
+ @endif + @if(!empty($anidbSource)) +
+
Source
+
{{ $anidbSourceLabel }}
+
+ @endif + @if(!empty($anidbEpisodes)) +
+
Episodes
+
{{ number_format($anidbEpisodes) }}
+
+ @endif + @if(!empty($anidbDuration)) +
+
Duration
+
{{ $anidbDuration }} minutes
+
+ @endif + @if(!empty($anidbStartDate)) +
+
Start Date
+
{{ $anidbStartDate }}
+
+ @endif + @if(!empty($anidbEndDate)) +
+
End Date
+
{{ $anidbEndDate }}
+
+ @endif + @if(!empty($anidbRating)) +
+
Rating
+
+ + + @php + $ratingValue = is_numeric($anidbRating) ? (float)$anidbRating : 0; + // AniList rating is out of 100, convert to /10 + $displayRating = $ratingValue > 10 ? number_format($ratingValue / 10, 1) : number_format($ratingValue, 1); + @endphp + {{ $displayRating }} / 10 + +
+
+ @endif + @if(!empty($anidbCategories)) +
+
Genres
+
{{ $anidbCategories }}
+
+ @endif + @if(!empty($anidbCreators)) +
+
Studios
+
{{ $anidbCreators }}
+
+ @endif + @if(!empty($anidbDescription)) +
+
Description
+
{{ $anidbDescription }}
+
+ @endif +
+ + + @php + $anilistId = $anidbData['anilist_id'] ?? ($anidb->anilist_id ?? null); + $malId = $anidbData['mal_id'] ?? ($anidb->mal_id ?? null); + @endphp + @if(!empty($anilistId) || !empty($malId)) +
+

External Links

+
+ @if(!empty($anilistId)) + + View on AniList + + @endif + @if(!empty($malId)) + + View on MyAnimeList + + @endif +
+
+ @endif +
+ @endif diff --git a/resources/views/details/partials/book-info.blade.php b/resources/views/details/partials/book-info.blade.php new file mode 100644 index 000000000..fe774ee90 --- /dev/null +++ b/resources/views/details/partials/book-info.blade.php @@ -0,0 +1,48 @@ + + @if(!empty($book)) + @php + $bookData = is_object($book) ? get_object_vars($book) : $book; + $bookTitle = $bookData['title'] ?? ($book->title ?? null); + $bookAuthor = $bookData['author'] ?? ($book->author ?? null); + $bookPublisher = $bookData['publisher'] ?? ($book->publisher ?? null); + $bookPublishDate = $bookData['publishdate'] ?? ($book->publishdate ?? null); + $bookOverview = $bookData['overview'] ?? ($book->overview ?? null); + @endphp +
+

+ Book Information +

+
+ @if(!empty($bookTitle)) +
+
Title
+
{{ $bookTitle }}
+
+ @endif + @if(!empty($bookAuthor)) +
+
Author
+
{{ $bookAuthor }}
+
+ @endif + @if(!empty($bookPublisher)) +
+
Publisher
+
{{ $bookPublisher }}
+
+ @endif + @if(!empty($bookPublishDate)) +
+
Published
+
{{ $bookPublishDate }}
+
+ @endif + @if(!empty($bookOverview)) +
+
Overview
+
{{ $bookOverview }}
+
+ @endif +
+
+ @endif diff --git a/resources/views/details/partials/comments.blade.php b/resources/views/details/partials/comments.blade.php new file mode 100644 index 000000000..cb72c3eb6 --- /dev/null +++ b/resources/views/details/partials/comments.blade.php @@ -0,0 +1,94 @@ + +
+

+ + Comments ({{ isset($comments) ? count($comments) : 0 }}) +

+ + + @if(session('success')) +
+

+ + {{ session('success') }} +

+
+ @endif + + @if(session('error')) +
+

+ + {{ session('error') }} +

+
+ @endif + + + @auth +
+
+ @csrf +
+ + +
+
+ +
+
+
+ @else +
+

+ + Please log in to add a comment. +

+
+ @endauth + + + @if(isset($comments) && count($comments) > 0) +
+ @foreach($comments as $comment) +
+
+
+
+ {{ strtoupper(substr($comment['username'] ?? 'U', 0, 1)) }} +
+
+

{{ $comment['username'] ?? 'Anonymous' }}

+

+ + {{ \Carbon\Carbon::parse($comment['created_at'])->diffForHumans() }} +

+
+
+
+

{{ $comment['text'] ?? '' }}

+
+ @endforeach +
+ @else +
+ +

No comments yet. Be the first to comment!

+
+ @endif +
diff --git a/resources/views/details/partials/console-info.blade.php b/resources/views/details/partials/console-info.blade.php new file mode 100644 index 000000000..75f0b717b --- /dev/null +++ b/resources/views/details/partials/console-info.blade.php @@ -0,0 +1,34 @@ + + @if(!empty($con)) + @php + $conData = is_object($con) ? get_object_vars($con) : $con; + $conTitle = $conData['title'] ?? ($con->title ?? null); + $conPublisher = $conData['publisher'] ?? ($con->publisher ?? null); + $conReleaseDate = $conData['releasedate'] ?? ($con->releasedate ?? null); + @endphp +
+

+ Console Game Information +

+
+ @if(!empty($conTitle)) +
+
Title
+
{{ $conTitle }}
+
+ @endif + @if(!empty($conPublisher)) +
+
Publisher
+
{{ $conPublisher }}
+
+ @endif + @if(!empty($conReleaseDate)) +
+
Release Date
+
{{ $conReleaseDate }}
+
+ @endif +
+
+ @endif diff --git a/resources/views/details/partials/cover-actions.blade.php b/resources/views/details/partials/cover-actions.blade.php new file mode 100644 index 000000000..dc87e82d3 --- /dev/null +++ b/resources/views/details/partials/cover-actions.blade.php @@ -0,0 +1,104 @@ + +
+
+ +
+ {{ $release->searchname }} +
+ + +
+
+

{{ $release->searchname }}

+
+ @if(!empty($totalReportCount) && $totalReportCount > 0) +
+ + Reported ({{ $totalReportCount }}): {{ $allReportReasons ?? 'Unknown' }} +
+ @endif + @if(!empty($failed) && $failed > 0) +
+ + {{ $failed }} user{{ $failed > 1 ? 's' : '' }} reported download failure +
+ @endif +
+
+
+ + Download NZB + + + Add to Cart + + @if(isset($release->nfostatus) && $release->nfostatus == 1) + + @endif + @if(($release->totalpart ?? 0) > 0) + + @endif + @auth + @if(auth()->user()->hasRole('Admin') || auth()->user()->hasRole('Moderator')) + + Edit Release + + @endif + @endauth + +
+ @if(!empty($originalReportData) && $originalReportData->count() > 0) +
+

+ Original report +

+
+ @foreach($originalReportData as $originalReport) +
+
+ + {{ $originalReport->reason_label }} + + + {{ ucfirst($originalReport->status) }} · Reported {{ $originalReport->created_at->format('M d, Y H:i') }} + +
+
+ {{ $originalReport->description ?: 'No additional report details were provided.' }} +
+
+ @endforeach +
+
+ @endif + @if(!empty($publicReportResponses) && $publicReportResponses->count() > 0) +
+

+ Staff response +

+
+ @foreach($publicReportResponses as $responseReport) +
+
{{ $responseReport->response }}
+
+ {{ $responseReport->responded_at ? 'Responded ' . $responseReport->responded_at->format('M d, Y H:i') : 'Staff response' }} + @if($responseReport->responder) + by {{ $responseReport->responder->username }} + @endif +
+
+ @endforeach +
+
+ @endif +
+
+
diff --git a/resources/views/details/partials/game-info.blade.php b/resources/views/details/partials/game-info.blade.php new file mode 100644 index 000000000..973f71732 --- /dev/null +++ b/resources/views/details/partials/game-info.blade.php @@ -0,0 +1,41 @@ + + @if(!empty($game)) + @php + $gameData = is_object($game) ? get_object_vars($game) : $game; + $gameTitle = $gameData['title'] ?? ($game->title ?? null); + $gamePublisher = $gameData['publisher'] ?? ($game->publisher ?? null); + $gameReleaseDate = $gameData['releasedate'] ?? ($game->releasedate ?? null); + $gameGenres = $gameData['genres'] ?? ($game->genres ?? null); + @endphp +
+

+ Game Information +

+
+ @if(!empty($gameTitle)) +
+
Title
+
{{ $gameTitle }}
+
+ @endif + @if(!empty($gamePublisher)) +
+
Publisher
+
{{ $gamePublisher }}
+
+ @endif + @if(!empty($gameReleaseDate)) +
+
Release Date
+
{{ $gameReleaseDate }}
+
+ @endif + @if(!empty($gameGenres)) +
+
Genres
+
{{ $gameGenres }}
+
+ @endif +
+
+ @endif diff --git a/resources/views/details/partials/image-modal.blade.php b/resources/views/details/partials/image-modal.blade.php new file mode 100644 index 000000000..05329374d --- /dev/null +++ b/resources/views/details/partials/image-modal.blade.php @@ -0,0 +1,12 @@ + + diff --git a/resources/views/details/partials/info-sidebar.blade.php b/resources/views/details/partials/info-sidebar.blade.php new file mode 100644 index 000000000..eac0e5ae2 --- /dev/null +++ b/resources/views/details/partials/info-sidebar.blade.php @@ -0,0 +1,56 @@ + +
+
+

Information

+
+
+
Category
+
{{ $release->category_name ?? 'Other' }}
+
+
+
Size
+
{{ number_format($release->size / 1073741824, 2) }} GB
+
+
+
Files
+
{{ $release->totalpart ?? 0 }}
+
+
+
Added
+
{{ userDate($release->adddate, 'M d, Y H:i') }}
+
+
+
Group
+
{{ $release->group_name ?? 'Unknown' }}
+
+
+
Posted
+
{{ userDate($release->postdate, 'M d, Y H:i') }}
+
+ @if(!empty($release->fromname)) +
+
Posted By
+
+ + {{ $release->fromname }} + +
+
+ @endif +
+
Grabs
+
{{ $release->grabs ?? 0 }}
+
+ @if($release->imdbid ?? false) +
+
IMDB
+
+ + View on IMDB + +
+
+ @endif +
+
+
diff --git a/resources/views/details/partials/media-metadata.blade.php b/resources/views/details/partials/media-metadata.blade.php new file mode 100644 index 000000000..024299f04 --- /dev/null +++ b/resources/views/details/partials/media-metadata.blade.php @@ -0,0 +1,144 @@ + + @if(!empty($reVideo) || !empty($reAudio) || !empty($reSubs)) +
+

+ Media Information +

+ + @if(!empty($reVideo)) +
+

+ Video Details +

+
+
+ @if(!empty($reVideo['containerformat'])) +
+
Container Format
+
{{ $reVideo['containerformat'] }}
+
+ @endif + @if(!empty($reVideo['videocodec'])) +
+
Video Codec
+
{{ $reVideo['videocodec'] }}
+
+ @endif + @if(!empty($reVideo['videoformat'])) +
+
Video Format
+
{{ $reVideo['videoformat'] }}
+
+ @endif + @if(!empty($reVideo['videowidth']) && !empty($reVideo['videoheight'])) +
+
Resolution
+
{{ $reVideo['videowidth'] }}x{{ $reVideo['videoheight'] }}
+
+ @endif + @if(!empty($reVideo['videoaspect'])) +
+
Aspect Ratio
+
{{ $reVideo['videoaspect'] }}
+
+ @endif + @if(!empty($reVideo['videoframerate'])) +
+
Frame Rate
+
{{ $reVideo['videoframerate'] }} fps
+
+ @endif + @if(!empty($reVideo['videoduration'])) + @php + $durationMs = intval($reVideo['videoduration']); + $durationMinutes = $durationMs > 0 ? round($durationMs / 1000 / 60) : 0; + @endphp + @if($durationMinutes > 0) +
+
Duration
+
{{ $durationMinutes }} minutes
+
+ @endif + @endif + @if(!empty($reVideo['overallbitrate'])) +
+
Bit Rate
+
{{ $reVideo['overallbitrate'] }}
+
+ @endif + @if(!empty($reVideo['videolibrary'])) +
+
Encoder Library
+
{{ $reVideo['videolibrary'] }}
+
+ @endif +
+
+
+ @endif + + @if(!empty($reAudio)) +
+

+ Audio Details +

+ @foreach($reAudio as $index => $audio) +
+ @if(count($reAudio) > 1) +

Track {{ $index + 1 }}

+ @endif +
+ @if(!empty($audio['audioformat'])) +
+
Audio Format
+
{{ $audio['audioformat'] }}
+
+ @endif + @if(!empty($audio['audiocodec'])) +
+
Codec
+
{{ $audio['audiocodec'] }}
+
+ @endif + @if(!empty($audio['audiochannels'])) +
+
Channels
+
{{ $audio['audiochannels'] }}
+
+ @endif + @if(!empty($audio['audiobitrate'])) +
+
Bit Rate
+
{{ $audio['audiobitrate'] }}
+
+ @endif + @if(!empty($audio['audiolanguage'])) +
+
Language
+
{{ $audio['audiolanguage'] }}
+
+ @endif + @if(!empty($audio['audiosamplerate'])) +
+
Sample Rate
+
{{ $audio['audiosamplerate'] }} Hz
+
+ @endif +
+
+ @endforeach +
+ @endif + + @if(!empty($reSubs)) +
+

+ Subtitles +

+
+

{{ $reSubs->subs }}

+
+
+ @endif +
+ @endif diff --git a/resources/views/details/partials/movie-info.blade.php b/resources/views/details/partials/movie-info.blade.php new file mode 100644 index 000000000..352a0285c --- /dev/null +++ b/resources/views/details/partials/movie-info.blade.php @@ -0,0 +1,90 @@ + + @if(!empty($movie)) + @php + $movieData = is_object($movie) ? get_object_vars($movie) : $movie; + $movieTitle = $movieData['title'] ?? ($movie->title ?? null); + $movieYear = $movieData['year'] ?? ($movie->year ?? null); + $movieTagline = $movieData['tagline'] ?? ($movie->tagline ?? null); + $movieRating = $movieData['rating'] ?? ($movie->rating ?? null); + $moviePlot = $movieData['plot'] ?? ($movie->plot ?? null); + $movieGenre = $movieData['genre'] ?? ($movie->genre ?? null); + $movieDirector = $movieData['director'] ?? ($movie->director ?? null); + $movieActors = $movieData['actors'] ?? ($movie->actors ?? null); + $movieLanguage = $movieData['language'] ?? ($movie->language ?? null); + $movieTrailer = $movieData['trailer'] ?? ($movie->trailer ?? null); + @endphp +
+

+ Movie Information +

+
+ @if(!empty($movieTitle)) +
+
Title
+
{{ $movieTitle }}
+
+ @endif + @if(!empty($movieYear)) +
+
Year
+
{{ $movieYear }}
+
+ @endif + @if(!empty($movieTagline)) +
+
Tagline
+
"{{ $movieTagline }}"
+
+ @endif + @if(!empty($movieRating)) +
+
IMDB Rating
+
+ + + {{ $movieRating }}/10 + +
+
+ @endif + @if(!empty($moviePlot)) +
+
Plot Synopsis
+
{{ $moviePlot }}
+
+ @endif + @if(!empty($movieGenre)) +
+
Genre
+
{!! $movieGenre !!}
+
+ @endif + @if(!empty($movieDirector)) +
+
Director
+
{!! $movieDirector !!}
+
+ @endif + @if(!empty($movieActors)) +
+
Cast
+
{!! $movieActors !!}
+
+ @endif + @if(!empty($movieLanguage)) +
+
Language
+
{{ $movieLanguage }}
+
+ @endif +
+ @if(!empty($movieTrailer)) +
+

Trailer

+
+ {!! $movieTrailer !!} +
+
+ @endif +
+ @endif diff --git a/resources/views/details/partials/music-info.blade.php b/resources/views/details/partials/music-info.blade.php new file mode 100644 index 000000000..991751fea --- /dev/null +++ b/resources/views/details/partials/music-info.blade.php @@ -0,0 +1,48 @@ + + @if(!empty($music)) + @php + $musicData = is_object($music) ? get_object_vars($music) : $music; + $musicTitle = $musicData['title'] ?? ($music->title ?? null); + $musicArtist = $musicData['artist'] ?? ($music->artist ?? null); + $musicPublisher = $musicData['publisher'] ?? ($music->publisher ?? null); + $musicReleaseDate = $musicData['releasedate'] ?? ($music->releasedate ?? null); + $musicGenres = $musicData['genres'] ?? ($music->genres ?? null); + @endphp +
+

+ Music Information +

+
+ @if(!empty($musicTitle)) +
+
Album
+
{{ $musicTitle }}
+
+ @endif + @if(!empty($musicArtist)) +
+
Artist
+
{{ $musicArtist }}
+
+ @endif + @if(!empty($musicPublisher)) +
+
Publisher
+
{{ $musicPublisher }}
+
+ @endif + @if(!empty($musicReleaseDate)) +
+
Release Date
+
{{ $musicReleaseDate }}
+
+ @endif + @if(!empty($musicGenres)) +
+
Genres
+
{{ $musicGenres }}
+
+ @endif +
+
+ @endif diff --git a/resources/views/details/partials/password-info.blade.php b/resources/views/details/partials/password-info.blade.php new file mode 100644 index 000000000..c9b1356bb --- /dev/null +++ b/resources/views/details/partials/password-info.blade.php @@ -0,0 +1,46 @@ + + @if(isset($release->passwordstatus) && $release->passwordstatus > 0) +
+

+ Password Protected Release +

+
+
+
Password Status
+
+ @if($release->passwordstatus == 1) + + Password Unknown + + @elseif($release->passwordstatus == 2) + + Password Available + + @endif +
+
+
+
Password
+
+ @if(!empty($release->password)) +
+ {{ $release->password }} +
+

+ + This password is embedded in the NZB file and will be automatically recognized by NZBGet or SABnzbd. +

+ @else +
+ None +
+

+ + No password information available in the database. +

+ @endif +
+
+
+
+ @endif diff --git a/resources/views/details/partials/predb-info.blade.php b/resources/views/details/partials/predb-info.blade.php new file mode 100644 index 000000000..149476829 --- /dev/null +++ b/resources/views/details/partials/predb-info.blade.php @@ -0,0 +1,34 @@ + + @if(!empty($predb) && is_array($predb)) +
+

+ PreDB Information +

+
+ @if(!empty($predb['title'])) +
+
Title
+
{{ $predb['title'] }}
+
+ @endif + @if(!empty($predb['source'])) +
+
Source
+
{{ $predb['source'] }}
+
+ @endif + @if(!empty($predb['predate'])) +
+
Pre Date
+
{{ $predb['predate'] }}
+
+ @endif + @if(!empty($predb['category'])) +
+
Category
+
{{ $predb['category'] }}
+
+ @endif +
+
+ @endif diff --git a/resources/views/details/partials/preview-images.blade.php b/resources/views/details/partials/preview-images.blade.php new file mode 100644 index 000000000..86fd1571f --- /dev/null +++ b/resources/views/details/partials/preview-images.blade.php @@ -0,0 +1,53 @@ + + @php + $hasPreviewImage = isset($release->haspreview) && $release->haspreview == 1; + $hasSampleImage = isset($release->jpgstatus) && $release->jpgstatus == 1; + $previewImageUrl = $hasPreviewImage + ? getImageAssetUrl('preview', $release->guid . '_thumb', asset('assets/images/no-cover.png')) + : null; + $sampleImageUrl = $hasSampleImage + ? getImageAssetUrl('sample', $release->guid . '_thumb', asset('assets/images/no-cover.png')) + : null; + @endphp + + @if($hasPreviewImage || $hasSampleImage) +
+

+ + @if($hasPreviewImage && $hasSampleImage) + Preview & Sample Images + @elseif($hasPreviewImage) + Preview Image + @else + Sample Image + @endif +

+
+ @if($hasPreviewImage) + +
+
+ Preview +
+

Preview

+
+ @endif + + @if($hasSampleImage) + +
+
+ Sample +
+

Sample

+
+ @endif +
+
+ @endif diff --git a/resources/views/details/partials/tv-info.blade.php b/resources/views/details/partials/tv-info.blade.php new file mode 100644 index 000000000..e9fe2b704 --- /dev/null +++ b/resources/views/details/partials/tv-info.blade.php @@ -0,0 +1,38 @@ + + @if(!empty($show)) + @php + $showData = is_object($show) ? get_object_vars($show) : $show; + $showTitle = $showData['title'] ?? ($show->title ?? null); + $showStarted = $showData['started'] ?? ($show->started ?? null); + $showTvdb = $showData['tvdb'] ?? ($show->tvdb ?? null); + @endphp +
+

+ TV Show Information +

+
+ @if(!empty($showTitle)) +
+
Show Title
+
{{ $showTitle }}
+
+ @endif + @if(!empty($showStarted)) +
+
Started
+
{{ $showStarted }}
+
+ @endif + @if(!empty($showTvdb)) +
+
TVDB
+
+ + View on TVDB + +
+
+ @endif +
+
+ @endif diff --git a/resources/views/games/index.blade.php b/resources/views/games/index.blade.php index 761b8066c..f8be22945 100644 --- a/resources/views/games/index.blade.php +++ b/resources/views/games/index.blade.php @@ -127,6 +127,7 @@ {{ $result->title ?? $result->searchname }} @else
@@ -188,15 +189,14 @@ {{ $results->links() }}
@else - -
- -

No games found

-

Try adjusting your search filters or browse all games.

- - Browse All Games - -
+ @endif diff --git a/resources/views/layouts/admin.blade.php b/resources/views/layouts/admin.blade.php index ed3799e5b..01bdfc1fa 100644 --- a/resources/views/layouts/admin.blade.php +++ b/resources/views/layouts/admin.blade.php @@ -14,7 +14,7 @@ - + @@ -51,26 +51,18 @@

{{ $page_title ?? 'Admin Dashboard' }}

diff --git a/resources/views/layouts/main.blade.php b/resources/views/layouts/main.blade.php index f5785193d..d91f84749 100644 --- a/resources/views/layouts/main.blade.php +++ b/resources/views/layouts/main.blade.php @@ -18,8 +18,8 @@ - - + + @auth @@ -103,7 +103,7 @@ @include('partials.back-to-top') - @php $themePreference = auth()->check() ? (auth()->user()->theme_preference ?? 'light') : 'light'; @endphp + @php $themePreference = $userTheme; @endphp @guest - - -
+ @include('partials.theme-switcher', ['switcherId' => 'dropdown-theme-switcher', 'btnClass' => 'dropdown-theme-btn', 'mobile' => false])
Color Scheme - + @include('partials.scheme-switcher', ['switcherId' => 'dropdown-scheme-switcher', 'btnClass' => 'dropdown-scheme-btn', 'mobile' => false])
@@ -450,46 +398,12 @@
Theme -
- @php $mobileTheme = auth()->user()->theme_preference ?? 'light'; @endphp - - - -
+ @include('partials.theme-switcher', ['switcherId' => 'mobile-theme-switcher', 'btnClass' => 'mobile-theme-btn', 'mobile' => true])
Color Scheme -
- @php $mobileScheme = auth()->user()->color_scheme ?? 'blue'; @endphp - - - -
+ @include('partials.scheme-switcher', ['switcherId' => 'mobile-scheme-switcher', 'btnClass' => 'mobile-scheme-btn', 'mobile' => true])
@endauth diff --git a/resources/views/partials/scheme-switcher.blade.php b/resources/views/partials/scheme-switcher.blade.php new file mode 100644 index 000000000..7d2ff9517 --- /dev/null +++ b/resources/views/partials/scheme-switcher.blade.php @@ -0,0 +1,16 @@ +{{-- Shared color scheme switcher. JS hooks by button class (see alpine/stores/theme.js). Expects: $switcherId, $btnClass, $mobile (bool) --}} +@php $currentScheme = $userColorScheme ?? 'blue'; @endphp +
+ + + +
diff --git a/resources/views/partials/sidebar.blade.php b/resources/views/partials/sidebar.blade.php index 41a9462a6..167f8a0d1 100644 --- a/resources/views/partials/sidebar.blade.php +++ b/resources/views/partials/sidebar.blade.php @@ -129,30 +129,9 @@ @foreach($usefulLinks as $link)
@if($link->url) - @php - $url = $link->url; - - // Check if URL has protocol - $hasProtocol = str_starts_with($url, 'http://') || str_starts_with($url, 'https://'); - - // Check if URL is a domain pattern (e.g., google.com, chatgpt.ai) - // Pattern: contains at least one dot and doesn't start with / - $isDomain = !str_starts_with($url, '/') && preg_match('/^[a-zA-Z0-9][a-zA-Z0-9-]*\.[a-zA-Z]{2,}/', $url); - - $isExternal = $hasProtocol || $isDomain; - - // Use external URLs as-is (add https:// if domain without protocol), prepend site URL for internal paths - if ($hasProtocol) { - $linkUrl = $url; - } elseif ($isDomain) { - $linkUrl = 'https://' . $url; - } else { - $linkUrl = url($url); - } - @endphp - + @if($link->is_external_url) target="_blank" rel="noopener noreferrer" @endif>
{{ $link->title }}
@if($link->body)