mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-28 23:01:29 +00:00
Fix views inconsistencies
This commit is contained in:
@@ -95,7 +95,8 @@ if (! function_exists('makeFieldLinks')) {
|
||||
if ($i > 7) {
|
||||
break;
|
||||
}
|
||||
$newArr[] = '<a href="'.url('/'.ucfirst($type).'?'.$field.'='.urlencode($ta)).'" title="'.$ta.'">'.$ta.'</a>';
|
||||
$escaped = e($ta);
|
||||
$newArr[] = '<a href="'.url('/'.ucfirst($type).'?'.$field.'='.urlencode($ta)).'" title="'.$escaped.'">'.$escaped.'</a>';
|
||||
$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
|
||||
|
||||
@@ -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('<iframe width="%d" height="%d" src="%s"></iframe>', Settings::settingValue('trailers_size_x'), Settings::settingValue('trailers_size_y'), $trailer);
|
||||
$mov['trailer'] = sprintf('<iframe width="%d" height="%d" src="%s"></iframe>', 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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<string|null, never>
|
||||
*/
|
||||
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<bool, never>
|
||||
*/
|
||||
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));
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user