Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2480c5b309 | |||
| 4fc11d7329 | |||
| f3e5100d5d |
@@ -3,11 +3,10 @@
|
|||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
use App\Models\PopularDaily;
|
use App\Models\PopularDaily;
|
||||||
use App\Models\PopularWeekly;
|
|
||||||
use App\Models\PopularMonthly;
|
use App\Models\PopularMonthly;
|
||||||
|
use App\Models\PopularWeekly;
|
||||||
use Illuminate\Support\Carbon;
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
class AutoStats extends Command
|
class AutoStats extends Command
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ namespace App\Console\Commands;
|
|||||||
|
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
use App\Models\Hentai;
|
use App\Models\Hentai;
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Spatie\Sitemap\Sitemap;
|
use Spatie\Sitemap\Sitemap;
|
||||||
|
|||||||
@@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
use App\Models\Downloads;
|
|
||||||
use App\Jobs\GetFileSizeFromCDN;
|
use App\Jobs\GetFileSizeFromCDN;
|
||||||
|
use App\Models\Downloads;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
class GetFileSize extends Command
|
class GetFileSize extends Command
|
||||||
@@ -28,7 +27,7 @@ class GetFileSize extends Command
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
foreach(Downloads::whereNull('size')->get() as $download) {
|
foreach (Downloads::whereNull('size')->get() as $download) {
|
||||||
GetFileSizeFromCDN::dispatch($download->id);
|
GetFileSizeFromCDN::dispatch($download->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,8 @@ namespace App\Console\Commands;
|
|||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\UserDownload;
|
use App\Models\UserDownload;
|
||||||
|
|
||||||
use Illuminate\Support\Carbon;
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
class ResetUserDownloads extends Command
|
class ResetUserDownloads extends Command
|
||||||
{
|
{
|
||||||
|
|||||||
+18
-17
@@ -5,21 +5,20 @@ namespace App\Helpers;
|
|||||||
use App\Models\Comment;
|
use App\Models\Comment;
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
use App\Models\Hentai;
|
use App\Models\Hentai;
|
||||||
|
use App\Models\PopularDaily;
|
||||||
use App\Models\PopularMonthly;
|
use App\Models\PopularMonthly;
|
||||||
use App\Models\PopularWeekly;
|
use App\Models\PopularWeekly;
|
||||||
use App\Models\PopularDaily;
|
|
||||||
|
|
||||||
use Conner\Tagging\Model\Tag;
|
use Conner\Tagging\Model\Tag;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class CacheHelper
|
class CacheHelper
|
||||||
{
|
{
|
||||||
public static function getRecentlyReleased(bool $guest)
|
public static function getRecentlyReleased(bool $guest)
|
||||||
{
|
{
|
||||||
$guestString = $guest ? 'guest' : 'authed';
|
$guestString = $guest ? 'guest' : 'authed';
|
||||||
return Cache::remember("recently_released_".$guestString, now()->addMinutes(60), function () use ($guest) {
|
|
||||||
|
return Cache::remember('recently_released_'.$guestString, now()->addMinutes(60), function () use ($guest) {
|
||||||
return Episode::with('gallery')
|
return Episode::with('gallery')
|
||||||
->when($guest, fn ($query) => $query->withoutTags(['loli', 'shota']))
|
->when($guest, fn ($query) => $query->withoutTags(['loli', 'shota']))
|
||||||
->orderBy('release_date', 'desc')
|
->orderBy('release_date', 'desc')
|
||||||
@@ -31,7 +30,8 @@ class CacheHelper
|
|||||||
public static function getRecentlyUploaded(bool $guest)
|
public static function getRecentlyUploaded(bool $guest)
|
||||||
{
|
{
|
||||||
$guestString = $guest ? 'guest' : 'authed';
|
$guestString = $guest ? 'guest' : 'authed';
|
||||||
return Cache::remember("recently_uploaded".$guestString, now()->addMinutes(5), function () use ($guest) {
|
|
||||||
|
return Cache::remember('recently_uploaded'.$guestString, now()->addMinutes(5), function () use ($guest) {
|
||||||
return Episode::with('gallery')
|
return Episode::with('gallery')
|
||||||
->when($guest, fn ($query) => $query->withoutTags(['loli', 'shota']))
|
->when($guest, fn ($query) => $query->withoutTags(['loli', 'shota']))
|
||||||
->orderBy('created_at', 'desc')
|
->orderBy('created_at', 'desc')
|
||||||
@@ -42,21 +42,21 @@ class CacheHelper
|
|||||||
|
|
||||||
public static function getTotalViewCount()
|
public static function getTotalViewCount()
|
||||||
{
|
{
|
||||||
return Cache::remember("total_view_count", now()->addMinutes(60), function () {
|
return Cache::remember('total_view_count', now()->addMinutes(60), function () {
|
||||||
return Episode::sum('view_count');
|
return Episode::sum('view_count');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getTotalEpisodeCount()
|
public static function getTotalEpisodeCount()
|
||||||
{
|
{
|
||||||
return Cache::remember("total_episode_count", now()->addMinutes(60), function () {
|
return Cache::remember('total_episode_count', now()->addMinutes(60), function () {
|
||||||
return Episode::count();
|
return Episode::count();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getTotalHentaiCount()
|
public static function getTotalHentaiCount()
|
||||||
{
|
{
|
||||||
return Cache::remember("total_hentai_count", now()->addMinutes(60), function () {
|
return Cache::remember('total_hentai_count', now()->addMinutes(60), function () {
|
||||||
return Hentai::count();
|
return Hentai::count();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -64,10 +64,11 @@ class CacheHelper
|
|||||||
public static function getPopularAllTime(bool $guest)
|
public static function getPopularAllTime(bool $guest)
|
||||||
{
|
{
|
||||||
$guestString = $guest ? 'guest' : 'authed';
|
$guestString = $guest ? 'guest' : 'authed';
|
||||||
return Cache::remember("top_hentai_alltime".$guestString, now()->addMinutes(360), function () use ($guest) {
|
|
||||||
|
return Cache::remember('top_hentai_alltime'.$guestString, now()->addMinutes(360), function () use ($guest) {
|
||||||
return Episode::with('gallery')
|
return Episode::with('gallery')
|
||||||
->when($guest, fn ($query) => $query->withoutTags(['loli', 'shota']))
|
->when($guest, fn ($query) => $query->withoutTags(['loli', 'shota']))
|
||||||
->orderBy('view_count','desc')
|
->orderBy('view_count', 'desc')
|
||||||
->limit(16)
|
->limit(16)
|
||||||
->get();
|
->get();
|
||||||
});
|
});
|
||||||
@@ -75,7 +76,7 @@ class CacheHelper
|
|||||||
|
|
||||||
public static function getPopularMonthly()
|
public static function getPopularMonthly()
|
||||||
{
|
{
|
||||||
return Cache::remember("top_hentai_monthly", now()->addMinutes(360), function () {
|
return Cache::remember('top_hentai_monthly', now()->addMinutes(360), function () {
|
||||||
return PopularMonthly::groupBy('episode_id')
|
return PopularMonthly::groupBy('episode_id')
|
||||||
->select('episode_id', DB::raw('count(*) as total'))
|
->select('episode_id', DB::raw('count(*) as total'))
|
||||||
->with('episode.gallery')
|
->with('episode.gallery')
|
||||||
@@ -87,7 +88,7 @@ class CacheHelper
|
|||||||
|
|
||||||
public static function getPopularWeekly()
|
public static function getPopularWeekly()
|
||||||
{
|
{
|
||||||
return Cache::remember("top_hentai_weekly", now()->addMinutes(360), function () {
|
return Cache::remember('top_hentai_weekly', now()->addMinutes(360), function () {
|
||||||
return PopularWeekly::groupBy('episode_id')
|
return PopularWeekly::groupBy('episode_id')
|
||||||
->select('episode_id', DB::raw('count(*) as total'))
|
->select('episode_id', DB::raw('count(*) as total'))
|
||||||
->with('episode.gallery')
|
->with('episode.gallery')
|
||||||
@@ -100,7 +101,7 @@ class CacheHelper
|
|||||||
|
|
||||||
public static function getPopularDaily()
|
public static function getPopularDaily()
|
||||||
{
|
{
|
||||||
return Cache::remember("top_hentai_daily", now()->addMinutes(30), function () {
|
return Cache::remember('top_hentai_daily', now()->addMinutes(30), function () {
|
||||||
return PopularDaily::groupBy('episode_id')
|
return PopularDaily::groupBy('episode_id')
|
||||||
->select('episode_id', DB::raw('count(*) as total'))
|
->select('episode_id', DB::raw('count(*) as total'))
|
||||||
->with('episode.gallery')
|
->with('episode.gallery')
|
||||||
@@ -112,21 +113,21 @@ class CacheHelper
|
|||||||
|
|
||||||
public static function getMostLikes()
|
public static function getMostLikes()
|
||||||
{
|
{
|
||||||
return Cache::remember("top_likes", now()->addMinutes(30), function () {
|
return Cache::remember('top_likes', now()->addMinutes(30), function () {
|
||||||
return DB::table('markable_likes')->groupBy('markable_id')->select('markable_id', DB::raw('count(*) as total'))->orderBy('total', 'desc')->limit(16)->get();
|
return DB::table('markable_likes')->groupBy('markable_id')->select('markable_id', DB::raw('count(*) as total'))->orderBy('total', 'desc')->limit(16)->get();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getAllTags()
|
public static function getAllTags()
|
||||||
{
|
{
|
||||||
return Cache::remember("all_tags", now()->addMinutes(10080), function () {
|
return Cache::remember('all_tags', now()->addMinutes(10080), function () {
|
||||||
return Tag::where('count', '>', 0)->orderBy('slug', 'ASC')->get();
|
return Tag::where('count', '>', 0)->orderBy('slug', 'ASC')->get();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getLatestComments()
|
public static function getLatestComments()
|
||||||
{
|
{
|
||||||
return Cache::remember("latest_comments", now()->addMinutes(60), function () {
|
return Cache::remember('latest_comments', now()->addMinutes(60), function () {
|
||||||
return Comment::latest()->take(10)->get();
|
return Comment::latest()->take(10)->get();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class GitHelper
|
|||||||
{
|
{
|
||||||
public static function shortCommit()
|
public static function shortCommit()
|
||||||
{
|
{
|
||||||
return Cache::remember("git_commit", now()->addMinutes(60), function () {
|
return Cache::remember('git_commit', now()->addMinutes(60), function () {
|
||||||
try {
|
try {
|
||||||
return trim(exec('git rev-parse --short HEAD'));
|
return trim(exec('git rev-parse --short HEAD'));
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class ContactController extends Controller
|
|||||||
$contacts = Contact::orderBy('created_at', 'DESC')->get();
|
$contacts = Contact::orderBy('created_at', 'DESC')->get();
|
||||||
|
|
||||||
return view('admin.contact.index', [
|
return view('admin.contact.index', [
|
||||||
'contacts' => $contacts
|
'contacts' => $contacts,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,8 @@
|
|||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Episode;
|
|
||||||
|
|
||||||
use App\Jobs\DiscordReleaseNotification;
|
use App\Jobs\DiscordReleaseNotification;
|
||||||
|
use App\Models\Episode;
|
||||||
use App\Services\DownloadService;
|
use App\Services\DownloadService;
|
||||||
use App\Services\EpisodeService;
|
use App\Services\EpisodeService;
|
||||||
use App\Services\GalleryService;
|
use App\Services\GalleryService;
|
||||||
@@ -14,7 +13,9 @@ use Illuminate\Http\Request;
|
|||||||
class EpisodeController extends Controller
|
class EpisodeController extends Controller
|
||||||
{
|
{
|
||||||
protected EpisodeService $episodeService;
|
protected EpisodeService $episodeService;
|
||||||
|
|
||||||
protected GalleryService $galleryService;
|
protected GalleryService $galleryService;
|
||||||
|
|
||||||
protected DownloadService $downloadService;
|
protected DownloadService $downloadService;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
@@ -43,7 +44,7 @@ class EpisodeController extends Controller
|
|||||||
|
|
||||||
// Discord Alert
|
// Discord Alert
|
||||||
if ($request->has('censored')) {
|
if ($request->has('censored')) {
|
||||||
DiscordReleaseNotification::dispatch($referenceEpisode->title." - ".$episodeNumber, 'release-censored');
|
DiscordReleaseNotification::dispatch($referenceEpisode->title.' - '.$episodeNumber, 'release-censored');
|
||||||
} else {
|
} else {
|
||||||
DiscordReleaseNotification::dispatch($episode->slug, 'release');
|
DiscordReleaseNotification::dispatch($episode->slug, 'release');
|
||||||
}
|
}
|
||||||
@@ -51,7 +52,7 @@ class EpisodeController extends Controller
|
|||||||
cache()->flush();
|
cache()->flush();
|
||||||
|
|
||||||
return to_route('hentai.index', [
|
return to_route('hentai.index', [
|
||||||
'title' => $episode->slug
|
'title' => $episode->slug,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ class EpisodeController extends Controller
|
|||||||
cache()->flush();
|
cache()->flush();
|
||||||
|
|
||||||
return to_route('hentai.index', [
|
return to_route('hentai.index', [
|
||||||
'title' => $episode->slug
|
'title' => $episode->slug,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,8 @@
|
|||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Hentai;
|
|
||||||
|
|
||||||
use App\Jobs\DiscordReleaseNotification;
|
use App\Jobs\DiscordReleaseNotification;
|
||||||
|
use App\Models\Hentai;
|
||||||
use App\Services\DownloadService;
|
use App\Services\DownloadService;
|
||||||
use App\Services\EpisodeService;
|
use App\Services\EpisodeService;
|
||||||
use App\Services\GalleryService;
|
use App\Services\GalleryService;
|
||||||
@@ -14,7 +13,9 @@ use Illuminate\Http\Request;
|
|||||||
class ReleaseController extends Controller
|
class ReleaseController extends Controller
|
||||||
{
|
{
|
||||||
protected EpisodeService $episodeService;
|
protected EpisodeService $episodeService;
|
||||||
|
|
||||||
protected GalleryService $galleryService;
|
protected GalleryService $galleryService;
|
||||||
|
|
||||||
protected DownloadService $downloadService;
|
protected DownloadService $downloadService;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
|||||||
@@ -3,15 +3,13 @@
|
|||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
|
||||||
use App\Models\SiteBackground;
|
use App\Models\SiteBackground;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\File;
|
use Illuminate\Support\Facades\File;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Intervention\Image\Laravel\Facades\Image;
|
|
||||||
use Intervention\Image\Encoders\WebpEncoder;
|
use Intervention\Image\Encoders\WebpEncoder;
|
||||||
|
use Intervention\Image\Laravel\Facades\Image;
|
||||||
|
|
||||||
class SiteBackgroundController extends Controller
|
class SiteBackgroundController extends Controller
|
||||||
{
|
{
|
||||||
@@ -36,7 +34,7 @@ class SiteBackgroundController extends Controller
|
|||||||
'date_end' => 'required',
|
'date_end' => 'required',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
foreach($request->file('images') as $file) {
|
foreach ($request->file('images') as $file) {
|
||||||
// Initiating a database transaction in case something goes wrong.
|
// Initiating a database transaction in case something goes wrong.
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
@@ -44,24 +42,25 @@ class SiteBackgroundController extends Controller
|
|||||||
$bg = SiteBackground::create(array_merge(
|
$bg = SiteBackground::create(array_merge(
|
||||||
$request->only(['date_start', 'date_end']),
|
$request->only(['date_start', 'date_end']),
|
||||||
[
|
[
|
||||||
'default' => (bool) $request->input('default', false)
|
'default' => (bool) $request->input('default', false),
|
||||||
]
|
]
|
||||||
));
|
));
|
||||||
|
|
||||||
$resolutions = [1440, 1080, 720, 640];
|
$resolutions = [1440, 1080, 720, 640];
|
||||||
foreach($resolutions as $resolution) {
|
foreach ($resolutions as $resolution) {
|
||||||
// /images/background/1-2560p.webp
|
// /images/background/1-2560p.webp
|
||||||
$targetPath = "/images/background/{$bg->id}-{$resolution}p.webp";
|
$targetPath = "/images/background/{$bg->id}-{$resolution}p.webp";
|
||||||
|
|
||||||
Image::read($file->getRealPath())
|
Image::read($file->getRealPath())
|
||||||
->scaleDown(height: $resolution)
|
->scaleDown(height: $resolution)
|
||||||
->encode(new WebpEncoder())
|
->encode(new WebpEncoder)
|
||||||
->save(public_path($targetPath));
|
->save(public_path($targetPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
Log::error($e->getMessage());
|
Log::error($e->getMessage());
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +84,7 @@ class SiteBackgroundController extends Controller
|
|||||||
SiteBackground::where('id', $request->input('id'))->update(array_merge(
|
SiteBackground::where('id', $request->input('id'))->update(array_merge(
|
||||||
$request->only(['date_start', 'date_end']),
|
$request->only(['date_start', 'date_end']),
|
||||||
[
|
[
|
||||||
'default' => (bool) $request->input('default', false)
|
'default' => (bool) $request->input('default', false),
|
||||||
]
|
]
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -109,13 +108,14 @@ class SiteBackgroundController extends Controller
|
|||||||
|
|
||||||
$resolutions = [1440, 1080, 720, 640];
|
$resolutions = [1440, 1080, 720, 640];
|
||||||
try {
|
try {
|
||||||
foreach($resolutions as $resolution) {
|
foreach ($resolutions as $resolution) {
|
||||||
$targetPath = "/images/background/{$id}-{$resolution}p.webp";
|
$targetPath = "/images/background/{$id}-{$resolution}p.webp";
|
||||||
File::delete(public_path($targetPath));
|
File::delete(public_path($targetPath));
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
Log::error($e->getMessage());
|
Log::error($e->getMessage());
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
use App\Models\EpisodeSubtitle;
|
use App\Models\EpisodeSubtitle;
|
||||||
use App\Models\Subtitle;
|
use App\Models\Subtitle;
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class SubtitleController extends Controller
|
class SubtitleController extends Controller
|
||||||
@@ -37,7 +37,7 @@ class SubtitleController extends Controller
|
|||||||
$episode = Episode::where('id', $request->input('episode_id'))->firstOrFail();
|
$episode = Episode::where('id', $request->input('episode_id'))->firstOrFail();
|
||||||
|
|
||||||
// Clear everything
|
// Clear everything
|
||||||
foreach($episode->subtitles as $sub) {
|
foreach ($episode->subtitles as $sub) {
|
||||||
$sub->delete();
|
$sub->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\Enums\UserRole;
|
use App\Enums\UserRole;
|
||||||
use App\Models\User;
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class UserController extends Controller
|
class UserController extends Controller
|
||||||
@@ -27,7 +27,6 @@ class UserController extends Controller
|
|||||||
'action' => 'required',
|
'action' => 'required',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
$user = User::findOrFail($validated['id']);
|
$user = User::findOrFail($validated['id']);
|
||||||
|
|
||||||
switch ($validated['action']) {
|
switch ($validated['action']) {
|
||||||
@@ -40,7 +39,7 @@ class UserController extends Controller
|
|||||||
alert()->success('Unbanned', 'User has been unbanned.');
|
alert()->success('Unbanned', 'User has been unbanned.');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
alert()->error('Error','Invalid action provided');
|
alert()->error('Error', 'Invalid action provided');
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\Helpers\CacheHelper;
|
use App\Helpers\CacheHelper;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
use App\Models\Studios;
|
use App\Models\Studios;
|
||||||
use App\Models\Subtitle;
|
use App\Models\Subtitle;
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
|
|
||||||
class AdminApiController extends Controller
|
class AdminApiController extends Controller
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,13 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Downloads;
|
use App\Models\Downloads;
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
|
|
||||||
use GrantHolle\Altcha\Rules\ValidAltcha;
|
use GrantHolle\Altcha\Rules\ValidAltcha;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class DownloadApiController extends Controller
|
class DownloadApiController extends Controller
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Hentai;
|
use App\Models\Hentai;
|
||||||
use App\Models\PopularMonthly;
|
use App\Models\PopularMonthly;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
|
|
||||||
class HentaiApiController extends Controller
|
class HentaiApiController extends Controller
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class StreamApiController extends Controller
|
class StreamApiController extends Controller
|
||||||
@@ -22,7 +20,7 @@ class StreamApiController extends Controller
|
|||||||
$episode = Episode::where('id', $request->input('episode_id'))->firstOrFail();
|
$episode = Episode::where('id', $request->input('episode_id'))->firstOrFail();
|
||||||
|
|
||||||
$subtitles = $episode->subtitles
|
$subtitles = $episode->subtitles
|
||||||
->mapWithKeys(fn($sub) => [$sub->subtitle->slug => $sub->subtitle->name])
|
->mapWithKeys(fn ($sub) => [$sub->subtitle->slug => $sub->subtitle->name])
|
||||||
->toArray();
|
->toArray();
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
@@ -33,7 +31,7 @@ class StreamApiController extends Controller
|
|||||||
'stream_url' => $episode->dmca_takedown ? 'stuff/dmca' : $episode->url,
|
'stream_url' => $episode->dmca_takedown ? 'stuff/dmca' : $episode->url,
|
||||||
'stream_domains' => config('hstream.stream_domain'),
|
'stream_domains' => config('hstream.stream_domain'),
|
||||||
'asia_stream_domains' => config('hstream.asia_stream_domain'),
|
'asia_stream_domains' => config('hstream.asia_stream_domain'),
|
||||||
'extra_subtitles' => $subtitles
|
'extra_subtitles' => $subtitles,
|
||||||
], 200);
|
], 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,8 @@ namespace App\Http\Controllers\Api;
|
|||||||
|
|
||||||
use App\Helpers\CacheHelper;
|
use App\Helpers\CacheHelper;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
|
|
||||||
use Conner\Tagging\Model\Tag;
|
use Conner\Tagging\Model\Tag;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class UserApiController extends Controller
|
class UserApiController extends Controller
|
||||||
{
|
{
|
||||||
@@ -33,11 +32,10 @@ class UserApiController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'success',
|
'message' => 'success',
|
||||||
'tags' => $tagWhiteList,
|
'tags' => $tagWhiteList,
|
||||||
'usertags' => $tagBlackList
|
'usertags' => $tagBlackList,
|
||||||
], 200);
|
], 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,9 @@
|
|||||||
namespace App\Http\Controllers\Auth;
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
use App\Enums\UserRole;
|
use App\Enums\UserRole;
|
||||||
use App\Models\User;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
@@ -32,7 +30,7 @@ class DiscordAuthController extends Controller
|
|||||||
|
|
||||||
$user = User::where('discord_id', $discordUser->id)->first();
|
$user = User::where('discord_id', $discordUser->id)->first();
|
||||||
|
|
||||||
if (!$user) {
|
if (! $user) {
|
||||||
// link by email if it already exists
|
// link by email if it already exists
|
||||||
$user = User::where('email', $discordUser->email)->first();
|
$user = User::where('email', $discordUser->email)->first();
|
||||||
|
|
||||||
@@ -77,7 +75,7 @@ class DiscordAuthController extends Controller
|
|||||||
private function checkDiscordRoles(User $user): void
|
private function checkDiscordRoles(User $user): void
|
||||||
{
|
{
|
||||||
// Should not ever happen
|
// Should not ever happen
|
||||||
if (!$user->discord_id) {
|
if (! $user->discord_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +88,7 @@ class DiscordAuthController extends Controller
|
|||||||
// User is not in the guild
|
// User is not in the guild
|
||||||
if ($response->status() === 404) {
|
if ($response->status() === 404) {
|
||||||
$user->removeRole(UserRole::SUPPORTER);
|
$user->removeRole(UserRole::SUPPORTER);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,11 +108,12 @@ class DiscordAuthController extends Controller
|
|||||||
$patreonRoles = config('discord.patreon_roles', []);
|
$patreonRoles = config('discord.patreon_roles', []);
|
||||||
|
|
||||||
// If intersect of array is empty, then the user doesn't have the role
|
// If intersect of array is empty, then the user doesn't have the role
|
||||||
$hasSupporterRole = !empty(array_intersect($discordRoles, $patreonRoles));
|
$hasSupporterRole = ! empty(array_intersect($discordRoles, $patreonRoles));
|
||||||
|
|
||||||
if (!$hasSupporterRole) {
|
if (! $hasSupporterRole) {
|
||||||
// Remove role if not found
|
// Remove role if not found
|
||||||
$user->removeRole(UserRole::SUPPORTER);
|
$user->removeRole(UserRole::SUPPORTER);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,7 @@ class PasswordController extends Controller
|
|||||||
public function update(Request $request): RedirectResponse
|
public function update(Request $request): RedirectResponse
|
||||||
{
|
{
|
||||||
// If user logged in with Discord and has not yet a password, allow to set password
|
// If user logged in with Discord and has not yet a password, allow to set password
|
||||||
if ($request->user()->discord_id && is_null($request->user()->password))
|
if ($request->user()->discord_id && is_null($request->user()->password)) {
|
||||||
{
|
|
||||||
$validated = $request->validateWithBag('updatePassword', [
|
$validated = $request->validateWithBag('updatePassword', [
|
||||||
'password' => ['required', Password::defaults(), 'confirmed'],
|
'password' => ['required', Password::defaults(), 'confirmed'],
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Auth;
|
|||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use GrantHolle\Altcha\Rules\ValidAltcha;
|
||||||
use Illuminate\Auth\Events\Registered;
|
use Illuminate\Auth\Events\Registered;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -11,8 +12,6 @@ use Illuminate\Support\Facades\Auth;
|
|||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Validation\Rules;
|
use Illuminate\Validation\Rules;
|
||||||
|
|
||||||
use GrantHolle\Altcha\Rules\ValidAltcha;
|
|
||||||
|
|
||||||
class RegisteredUserController extends Controller
|
class RegisteredUserController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,9 +3,8 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Contact;
|
use App\Models\Contact;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
|
|
||||||
use GrantHolle\Altcha\Rules\ValidAltcha;
|
use GrantHolle\Altcha\Rules\ValidAltcha;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class ContactController extends Controller
|
class ContactController extends Controller
|
||||||
{
|
{
|
||||||
@@ -30,7 +29,7 @@ class ContactController extends Controller
|
|||||||
'altcha' => ['required', new ValidAltcha],
|
'altcha' => ['required', new ValidAltcha],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$contact = new Contact();
|
$contact = new Contact;
|
||||||
$contact->name = $request->input('name');
|
$contact->name = $request->input('name');
|
||||||
$contact->email = $request->input('email');
|
$contact->email = $request->input('email');
|
||||||
$contact->message = $request->input('message');
|
$contact->message = $request->input('message');
|
||||||
|
|||||||
@@ -2,11 +2,10 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Episode;
|
|
||||||
use App\Helpers\CacheHelper;
|
use App\Helpers\CacheHelper;
|
||||||
|
use App\Models\Episode;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Cookie;
|
|
||||||
|
|
||||||
class HomeController extends Controller
|
class HomeController extends Controller
|
||||||
{
|
{
|
||||||
@@ -19,15 +18,14 @@ class HomeController extends Controller
|
|||||||
|
|
||||||
$guestString = $guest ? 'guest' : 'authed';
|
$guestString = $guest ? 'guest' : 'authed';
|
||||||
|
|
||||||
$mostLikes = \cache()->remember('mostLikes'.$guestString, 300, fn () =>
|
$mostLikes = \cache()->remember('mostLikes'.$guestString, 300, fn () => Episode::with('gallery')
|
||||||
Episode::with('gallery')
|
|
||||||
->when($guest, fn ($query) => $query->withoutTags(['loli', 'shota']))
|
->when($guest, fn ($query) => $query->withoutTags(['loli', 'shota']))
|
||||||
->whereIn('id', function($query) {
|
->whereIn('id', function ($query) {
|
||||||
$mostLikesIds = CacheHelper::getMostLikes()->pluck('markable_id')->toArray();
|
$mostLikesIds = CacheHelper::getMostLikes()->pluck('markable_id')->toArray();
|
||||||
$query->selectRaw('id')
|
$query->selectRaw('id')
|
||||||
->from('episodes')
|
->from('episodes')
|
||||||
->whereIn('id', $mostLikesIds)
|
->whereIn('id', $mostLikesIds)
|
||||||
->orderByRaw("FIELD(id, " . implode(',', $mostLikesIds) . ")");
|
->orderByRaw('FIELD(id, '.implode(',', $mostLikesIds).')');
|
||||||
})
|
})
|
||||||
->get()
|
->get()
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class MatrixController extends Controller
|
|||||||
['name' => '🏠 General', 'description' => 'Our main chat.', 'alias' => 'https://matrix.to/#/#general:hstream.moe'],
|
['name' => '🏠 General', 'description' => 'Our main chat.', 'alias' => 'https://matrix.to/#/#general:hstream.moe'],
|
||||||
['name' => '📡 Releases', 'description' => 'Were we @everyone for new releases.', 'alias' => 'https://matrix.to/#/#releases:hstream.moe'],
|
['name' => '📡 Releases', 'description' => 'Were we @everyone for new releases.', 'alias' => 'https://matrix.to/#/#releases:hstream.moe'],
|
||||||
['name' => '👗 NSFW 2D', 'description' => 'Channel for R18 2D Media.', 'alias' => 'https://matrix.to/#/#nsfw:hstream.moe'],
|
['name' => '👗 NSFW 2D', 'description' => 'Channel for R18 2D Media.', 'alias' => 'https://matrix.to/#/#nsfw:hstream.moe'],
|
||||||
['name' => '👗 NSFW IRL', 'description' => 'Channel for R18 IRL Media.', 'alias' => 'https://matrix.to/#/#nsfw-irl:hstream.moe']
|
['name' => '👗 NSFW IRL', 'description' => 'Channel for R18 IRL Media.', 'alias' => 'https://matrix.to/#/#nsfw-irl:hstream.moe'],
|
||||||
];
|
];
|
||||||
|
|
||||||
return view('matrix.index', [
|
return view('matrix.index', [
|
||||||
@@ -49,7 +49,7 @@ class MatrixController extends Controller
|
|||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return back()
|
return back()
|
||||||
->withErrors([
|
->withErrors([
|
||||||
'username' => $e->getMessage()
|
'username' => $e->getMessage(),
|
||||||
])
|
])
|
||||||
->withInput();
|
->withInput();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
class NotificationController extends Controller
|
class NotificationController extends Controller
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use App\Models\Playlist;
|
|||||||
use App\Models\PlaylistEpisode;
|
use App\Models\PlaylistEpisode;
|
||||||
use App\Services\PlaylistService;
|
use App\Services\PlaylistService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use RealRashid\SweetAlert\Facades\Alert;
|
|
||||||
|
|
||||||
class PlaylistController extends Controller
|
class PlaylistController extends Controller
|
||||||
{
|
{
|
||||||
@@ -31,7 +30,7 @@ class PlaylistController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function show($playlist_id): \Illuminate\View\View
|
public function show($playlist_id): \Illuminate\View\View
|
||||||
{
|
{
|
||||||
if (!is_numeric($playlist_id)) {
|
if (! is_numeric($playlist_id)) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,14 +41,13 @@ class PlaylistController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the user's playlists page.
|
* Display the user's playlists page.
|
||||||
*/
|
*/
|
||||||
public function playlists(Request $request): \Illuminate\View\View
|
public function playlists(Request $request): \Illuminate\View\View
|
||||||
{
|
{
|
||||||
$title = 'Delete Playlist!';
|
$title = 'Delete Playlist!';
|
||||||
$text = "Are you sure you want to delete?";
|
$text = 'Are you sure you want to delete?';
|
||||||
confirmDelete($title, $text);
|
confirmDelete($title, $text);
|
||||||
|
|
||||||
return view('profile.playlists', [
|
return view('profile.playlists', [
|
||||||
@@ -63,7 +61,7 @@ class PlaylistController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function showPlaylist(Request $request, $playlist_id): \Illuminate\View\View
|
public function showPlaylist(Request $request, $playlist_id): \Illuminate\View\View
|
||||||
{
|
{
|
||||||
if (!is_numeric($playlist_id)) {
|
if (! is_numeric($playlist_id)) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +83,7 @@ class PlaylistController extends Controller
|
|||||||
'name' => 'required|max:30',
|
'name' => 'required|max:30',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$playlist = new Playlist();
|
$playlist = new Playlist;
|
||||||
$playlist->user_id = $request->user()->id;
|
$playlist->user_id = $request->user()->id;
|
||||||
$playlist->name = $request->input('name');
|
$playlist->name = $request->input('name');
|
||||||
$playlist->is_private = $request->input('visiblity') === 'private';
|
$playlist->is_private = $request->input('visiblity') === 'private';
|
||||||
@@ -99,7 +97,7 @@ class PlaylistController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function deletePlaylist(Request $request, $playlist_id): \Illuminate\Http\RedirectResponse
|
public function deletePlaylist(Request $request, $playlist_id): \Illuminate\Http\RedirectResponse
|
||||||
{
|
{
|
||||||
if (!is_numeric($playlist_id)) {
|
if (! is_numeric($playlist_id)) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +117,7 @@ class PlaylistController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function deleteEpisodeFromPlaylist(Request $request): \Illuminate\Http\JsonResponse
|
public function deleteEpisodeFromPlaylist(Request $request): \Illuminate\Http\JsonResponse
|
||||||
{
|
{
|
||||||
if (!is_numeric($request->input('playlist')) || !is_numeric($request->input('episode'))) {
|
if (! is_numeric($request->input('playlist')) || ! is_numeric($request->input('episode'))) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'not-numeric',
|
'message' => 'not-numeric',
|
||||||
'user' => $request->user(),
|
'user' => $request->user(),
|
||||||
@@ -151,7 +149,7 @@ class PlaylistController extends Controller
|
|||||||
|
|
||||||
$validated = $request->validate([
|
$validated = $request->validate([
|
||||||
'playlist' => 'required|max:30',
|
'playlist' => 'required|max:30',
|
||||||
'episode_id' => 'required'
|
'episode_id' => 'required',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$playlist = Playlist::where('user_id', $user->id)->where('id', $request->input('playlist'))->firstOrFail();
|
$playlist = Playlist::where('user_id', $user->id)->where('id', $request->input('playlist'))->firstOrFail();
|
||||||
@@ -161,7 +159,7 @@ class PlaylistController extends Controller
|
|||||||
$exists = PlaylistEpisode::where('playlist_id', $playlist->id)->where('episode_id', $episode->id)->exists();
|
$exists = PlaylistEpisode::where('playlist_id', $playlist->id)->where('episode_id', $episode->id)->exists();
|
||||||
if ($exists) {
|
if ($exists) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'already-added'
|
'message' => 'already-added',
|
||||||
], 200);
|
], 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +173,7 @@ class PlaylistController extends Controller
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'success'
|
'message' => 'success',
|
||||||
], 200);
|
], 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +186,7 @@ class PlaylistController extends Controller
|
|||||||
'name' => 'required|max:30',
|
'name' => 'required|max:30',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$playlist = new Playlist();
|
$playlist = new Playlist;
|
||||||
$playlist->user_id = $request->user()->id;
|
$playlist->user_id = $request->user()->id;
|
||||||
$playlist->name = $request->input('name');
|
$playlist->name = $request->input('name');
|
||||||
$playlist->is_private = $request->input('visiblity') === 'private';
|
$playlist->is_private = $request->input('visiblity') === 'private';
|
||||||
@@ -196,7 +194,7 @@ class PlaylistController extends Controller
|
|||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'success',
|
'message' => 'success',
|
||||||
'playlist_id' => $playlist->id
|
'playlist_id' => $playlist->id,
|
||||||
], 200);
|
], 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,22 +2,20 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\ProfileUpdateRequest;
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Http\Requests\ProfileUpdateRequest;
|
use Conner\Tagging\Model\Tag;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Redirect;
|
use Illuminate\Support\Facades\Redirect;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
use Intervention\Image\Laravel\Facades\Image;
|
use Intervention\Image\Laravel\Facades\Image;
|
||||||
|
|
||||||
use Conner\Tagging\Model\Tag;
|
|
||||||
|
|
||||||
class ProfileController extends Controller
|
class ProfileController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -118,9 +116,10 @@ class ProfileController extends Controller
|
|||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
$tags = json_decode($request->input('tags'));
|
$tags = json_decode($request->input('tags'));
|
||||||
|
|
||||||
if (!$tags) {
|
if (! $tags) {
|
||||||
$user->tag_blacklist = null;
|
$user->tag_blacklist = null;
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
return Redirect::route('profile.settings')->with('status', 'blacklist-updated');
|
return Redirect::route('profile.settings')->with('status', 'blacklist-updated');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +143,7 @@ class ProfileController extends Controller
|
|||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
|
|
||||||
// Verify password if user has password
|
// Verify password if user has password
|
||||||
if (!is_null($user->password)) {
|
if (! is_null($user->password)) {
|
||||||
$request->validateWithBag('userDeletion', [
|
$request->validateWithBag('userDeletion', [
|
||||||
'password' => ['required', 'current_password'],
|
'password' => ['required', 'current_password'],
|
||||||
]);
|
]);
|
||||||
@@ -177,8 +176,8 @@ class ProfileController extends Controller
|
|||||||
protected function storeAvatar(\Illuminate\Http\UploadedFile $file, User $user): void
|
protected function storeAvatar(\Illuminate\Http\UploadedFile $file, User $user): void
|
||||||
{
|
{
|
||||||
// Create Folder for Image Upload
|
// Create Folder for Image Upload
|
||||||
if (! Storage::disk('public')->exists("/images/avatars")) {
|
if (! Storage::disk('public')->exists('/images/avatars')) {
|
||||||
Storage::disk('public')->makeDirectory("/images/avatars");
|
Storage::disk('public')->makeDirectory('/images/avatars');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete old avatar if it exists
|
// Delete old avatar if it exists
|
||||||
@@ -196,5 +195,4 @@ class ProfileController extends Controller
|
|||||||
|
|
||||||
$user->avatar = $filename;
|
$user->avatar = $filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,20 +2,18 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Helpers\CacheHelper;
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
use App\Models\Gallery;
|
use App\Models\Gallery;
|
||||||
use App\Models\Hentai;
|
use App\Models\Hentai;
|
||||||
use App\Models\Playlist;
|
use App\Models\Playlist;
|
||||||
use App\Models\PlaylistEpisode;
|
use App\Models\PlaylistEpisode;
|
||||||
use App\Models\Watched;
|
use App\Models\Watched;
|
||||||
use App\Helpers\CacheHelper;
|
use hisorange\BrowserDetect\Facade as Browser;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
use hisorange\BrowserDetect\Facade as Browser;
|
|
||||||
|
|
||||||
class StreamController extends Controller
|
class StreamController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -37,7 +35,6 @@ class StreamController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$episode = Episode::where('slug', $title)->firstOrFail();
|
$episode = Episode::where('slug', $title)->firstOrFail();
|
||||||
$gallery = Gallery::where('episode_id', $episode->id)->get();
|
$gallery = Gallery::where('episode_id', $episode->id)->get();
|
||||||
$moreEpisodes = Episode::with(['gallery', 'studio'])->where('hentai_id', $episode->hentai_id)->whereNot('id', $episode->id)->get();
|
$moreEpisodes = Episode::with(['gallery', 'studio'])->where('hentai_id', $episode->hentai_id)->whereNot('id', $episode->id)->get();
|
||||||
@@ -54,15 +51,15 @@ class StreamController extends Controller
|
|||||||
// Increment Popular Count
|
// Increment Popular Count
|
||||||
$episode->incrementPopularCount();
|
$episode->incrementPopularCount();
|
||||||
|
|
||||||
if (!Auth::guest()) {
|
if (! Auth::guest()) {
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
|
|
||||||
// Add to user watched list
|
// Add to user watched list
|
||||||
$time = Carbon::now()->subHour(1);
|
$time = Carbon::now()->subHour(1);
|
||||||
$alreadyWatched = Watched::where('user_id', $user->id)->where('episode_id', $episode->id)->where('created_at', '>=', $time)->exists();
|
$alreadyWatched = Watched::where('user_id', $user->id)->where('episode_id', $episode->id)->where('created_at', '>=', $time)->exists();
|
||||||
if (!$alreadyWatched) {
|
if (! $alreadyWatched) {
|
||||||
Watched::create(['user_id' => $user->id, 'episode_id' => $episode->id]);
|
Watched::create(['user_id' => $user->id, 'episode_id' => $episode->id]);
|
||||||
cache()->forget('user' . $user->id . 'watched' . $episode->id);
|
cache()->forget('user'.$user->id.'watched'.$episode->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +78,7 @@ class StreamController extends Controller
|
|||||||
$playlistEpisodes = $playlist->episodes()->orderBy('position')->get();
|
$playlistEpisodes = $playlist->episodes()->orderBy('position')->get();
|
||||||
|
|
||||||
// Check if authorized
|
// Check if authorized
|
||||||
if ($playlist->is_private && (Auth::guest() || (!Auth::guest() && Auth::user()->id != $playlist->user_id))) {
|
if ($playlist->is_private && (Auth::guest() || (! Auth::guest() && Auth::user()->id != $playlist->user_id))) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,28 @@
|
|||||||
<?php namespace app\Http\Middleware;
|
<?php
|
||||||
|
|
||||||
|
namespace app\Http\Middleware;
|
||||||
|
|
||||||
use App\Enums\UserRole;
|
use App\Enums\UserRole;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
class IsAdmin {
|
class IsAdmin
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @param \Closure $next
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function handle(Request $request, Closure $next): Response
|
public function handle(Request $request, Closure $next): Response
|
||||||
{
|
{
|
||||||
if(Auth::check() && Auth::user()->hasRole(UserRole::ADMINISTRATOR))
|
if (Auth::check() && Auth::user()->hasRole(UserRole::ADMINISTRATOR)) {
|
||||||
{
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
session()->flash('error_msg','This resource is restricted to Administrators!');
|
session()->flash('error_msg', 'This resource is restricted to Administrators!');
|
||||||
|
|
||||||
return redirect()->route('home.index');
|
return redirect()->route('home.index');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,30 @@
|
|||||||
<?php namespace app\Http\Middleware;
|
<?php
|
||||||
|
|
||||||
|
namespace app\Http\Middleware;
|
||||||
|
|
||||||
use App\Enums\UserRole;
|
use App\Enums\UserRole;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
class IsBanned {
|
class IsBanned
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @param \Closure $next
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function handle(Request $request, Closure $next): Response
|
public function handle(Request $request, Closure $next): Response
|
||||||
{
|
{
|
||||||
if(Auth::check() && Auth::user()->hasRole(UserRole::BANNED))
|
if (Auth::check() && Auth::user()->hasRole(UserRole::BANNED)) {
|
||||||
{
|
|
||||||
Auth::logout();
|
Auth::logout();
|
||||||
$request->session()->invalidate();
|
$request->session()->invalidate();
|
||||||
$request->session()->regenerateToken();
|
$request->session()->regenerateToken();
|
||||||
|
|
||||||
return redirect()->route('home.banned');
|
return redirect()->route('home.banned');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
use App\Enums\UserRole;
|
use App\Enums\UserRole;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
@@ -18,12 +17,12 @@ class IsModerator
|
|||||||
*/
|
*/
|
||||||
public function handle(Request $request, Closure $next): Response
|
public function handle(Request $request, Closure $next): Response
|
||||||
{
|
{
|
||||||
if (Auth::check() && Auth::user()->hasRole(UserRole::MODERATOR))
|
if (Auth::check() && Auth::user()->hasRole(UserRole::MODERATOR)) {
|
||||||
{
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
session()->flash('error_msg','This resource is restricted to Administrators!');
|
session()->flash('error_msg', 'This resource is restricted to Administrators!');
|
||||||
|
|
||||||
return redirect()->route('home.index');
|
return redirect()->route('home.index');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,14 @@ class SetLocale
|
|||||||
// 1. Logged-in user preference
|
// 1. Logged-in user preference
|
||||||
if (Auth::check() && Auth::user()->locale) {
|
if (Auth::check() && Auth::user()->locale) {
|
||||||
App::setLocale(Auth::user()->locale);
|
App::setLocale(Auth::user()->locale);
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Session (guest or user override)
|
// 2. Session (guest or user override)
|
||||||
if (session()->has('locale') && in_array($request->language, config('app.supported_locales'), true)) {
|
if (session()->has('locale') && in_array($request->language, config('app.supported_locales'), true)) {
|
||||||
App::setLocale(session('locale'));
|
App::setLocale(session('locale'));
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Requests\Auth;
|
namespace App\Http\Requests\Auth;
|
||||||
|
|
||||||
|
use GrantHolle\Altcha\Rules\ValidAltcha;
|
||||||
use Illuminate\Auth\Events\Lockout;
|
use Illuminate\Auth\Events\Lockout;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
@@ -9,8 +10,6 @@ use Illuminate\Support\Facades\RateLimiter;
|
|||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
use GrantHolle\Altcha\Rules\ValidAltcha;
|
|
||||||
|
|
||||||
class LoginRequest extends FormRequest
|
class LoginRequest extends FormRequest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ class MatrixRegisterRequest extends FormRequest
|
|||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
$isOldEnough = $this->user()->created_at->lt(now()->subMonth());
|
$isOldEnough = $this->user()->created_at->lt(now()->subMonth());
|
||||||
$noAccount = !$this->user()->matrix_id;
|
$noAccount = ! $this->user()->matrix_id;
|
||||||
|
|
||||||
return $isOldEnough && $noAccount;
|
return $isOldEnough && $noAccount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class ProfileUpdateRequest extends FormRequest
|
|||||||
'nullable',
|
'nullable',
|
||||||
'image',
|
'image',
|
||||||
'mimes:jpg,png,jpeg,webp,gif',
|
'mimes:jpg,png,jpeg,webp,gif',
|
||||||
'max:8192'
|
'max:8192',
|
||||||
],
|
],
|
||||||
'email' => [
|
'email' => [
|
||||||
'required',
|
'required',
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use Illuminate\Contracts\Queue\ShouldQueue;
|
|||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
use Spatie\DiscordAlerts\Facades\DiscordAlert;
|
use Spatie\DiscordAlerts\Facades\DiscordAlert;
|
||||||
|
|
||||||
class DiscordReleaseNotification implements ShouldQueue
|
class DiscordReleaseNotification implements ShouldQueue
|
||||||
@@ -32,26 +31,25 @@ class DiscordReleaseNotification implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
switch($this->messageType)
|
switch ($this->messageType) {
|
||||||
{
|
|
||||||
case 'release':
|
case 'release':
|
||||||
DiscordAlert::message("<@&868457842250764289> (´• ω •`)ノ New **4k** Release! Check it out here: https://hstream.moe/hentai/".$this->slug);
|
DiscordAlert::message('<@&868457842250764289> (´• ω •`)ノ New **4k** Release! Check it out here: https://hstream.moe/hentai/'.$this->slug);
|
||||||
break;
|
break;
|
||||||
case 'release-censored':
|
case 'release-censored':
|
||||||
# Because Discord TOS
|
// Because Discord TOS
|
||||||
DiscordAlert::message("<@&868457842250764289> (´• ω •`)ノ New **4k** Release: ".$this->slug." - *No link here because of* :pLoli:");
|
DiscordAlert::message('<@&868457842250764289> (´• ω •`)ノ New **4k** Release: '.$this->slug.' - *No link here because of* :pLoli:');
|
||||||
break;
|
break;
|
||||||
case 'update':
|
case 'update':
|
||||||
# 1080p 48fps added
|
// 1080p 48fps added
|
||||||
DiscordAlert::to('update')->message("<@&1283518462584426598> (´• ω •`)ノ Added **48fps** to Release! Check it out here: https://hstream.moe/hentai/".$this->slug);
|
DiscordAlert::to('update')->message('<@&1283518462584426598> (´• ω •`)ノ Added **48fps** to Release! Check it out here: https://hstream.moe/hentai/'.$this->slug);
|
||||||
break;
|
break;
|
||||||
case 'updateUHD':
|
case 'updateUHD':
|
||||||
# 4k 48fps added
|
// 4k 48fps added
|
||||||
DiscordAlert::to('update')->message("<@&1326860920902778963> (´• ω •`)ノ Added **48fps 4k** to Release! Check it out here: https://hstream.moe/hentai/".$this->slug);
|
DiscordAlert::to('update')->message('<@&1326860920902778963> (´• ω •`)ノ Added **48fps 4k** to Release! Check it out here: https://hstream.moe/hentai/'.$this->slug);
|
||||||
break;
|
break;
|
||||||
case 'v2':
|
case 'v2':
|
||||||
# v2 re-release
|
// v2 re-release
|
||||||
DiscordAlert::to('rerelease')->message("<@&1425505303075754035> (´• ω •`)ノ **v2 Re-**Release! Check it out here: https://hstream.moe/hentai/".$this->slug);
|
DiscordAlert::to('rerelease')->message('<@&1425505303075754035> (´• ω •`)ノ **v2 Re-**Release! Check it out here: https://hstream.moe/hentai/'.$this->slug);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ use Illuminate\Bus\Queueable;
|
|||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
use Illuminate\Http\Client\RequestException;
|
use Illuminate\Http\Client\RequestException;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\Crypt;
|
use Illuminate\Support\Facades\Crypt;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
|
|
||||||
class GetFileSizeFromCDN implements ShouldQueue
|
class GetFileSizeFromCDN implements ShouldQueue
|
||||||
{
|
{
|
||||||
@@ -35,8 +35,9 @@ class GetFileSizeFromCDN implements ShouldQueue
|
|||||||
{
|
{
|
||||||
// Retrieve the download record, return if not found
|
// Retrieve the download record, return if not found
|
||||||
$download = Downloads::find($this->downloadId);
|
$download = Downloads::find($this->downloadId);
|
||||||
if (!$download) {
|
if (! $download) {
|
||||||
Log::error("Download not found for ID: {$this->downloadId}");
|
Log::error("Download not found for ID: {$this->downloadId}");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ class GetFileSizeFromCDN implements ShouldQueue
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Send HTTP request to the endpoint
|
// Send HTTP request to the endpoint
|
||||||
$response = Http::get($endpoint . '/getSize/' . $file . '/' . $expire);
|
$response = Http::get($endpoint.'/getSize/'.$file.'/'.$expire);
|
||||||
|
|
||||||
// Check if response is successful
|
// Check if response is successful
|
||||||
if ($response->successful()) {
|
if ($response->successful()) {
|
||||||
@@ -67,9 +68,9 @@ class GetFileSizeFromCDN implements ShouldQueue
|
|||||||
Log::error("Failed to retrieve size for download ID: {$this->downloadId}, HTTP status: {$response->status()}");
|
Log::error("Failed to retrieve size for download ID: {$this->downloadId}, HTTP status: {$response->status()}");
|
||||||
}
|
}
|
||||||
} catch (RequestException $e) {
|
} catch (RequestException $e) {
|
||||||
Log::error("HTTP request failed for download ID: {$this->downloadId}, error: " . $e->getMessage());
|
Log::error("HTTP request failed for download ID: {$this->downloadId}, error: ".$e->getMessage());
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error("An error occurred for download ID: {$this->downloadId}, error: " . $e->getMessage());
|
Log::error("An error occurred for download ID: {$this->downloadId}, error: ".$e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ namespace App\Livewire;
|
|||||||
use App\Models\Comment;
|
use App\Models\Comment;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
class AdminCommentSearch extends Component
|
class AdminCommentSearch extends Component
|
||||||
{
|
{
|
||||||
@@ -41,7 +40,7 @@ class AdminCommentSearch extends Component
|
|||||||
->paginate(12);
|
->paginate(12);
|
||||||
|
|
||||||
return view('livewire.admin-comment-search', [
|
return view('livewire.admin-comment-search', [
|
||||||
'comments' => $comments
|
'comments' => $comments,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ namespace App\Livewire;
|
|||||||
use App\Enums\UserRole;
|
use App\Enums\UserRole;
|
||||||
use App\Models\Comment;
|
use App\Models\Comment;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use Livewire\Attributes\Url;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
use Livewire\Attributes\Url;
|
|
||||||
|
|
||||||
class AdminUserSearch extends Component
|
class AdminUserSearch extends Component
|
||||||
{
|
{
|
||||||
@@ -46,7 +45,7 @@ class AdminUserSearch extends Component
|
|||||||
->paginate(20);
|
->paginate(20);
|
||||||
|
|
||||||
return view('livewire.admin-user-search', [
|
return view('livewire.admin-user-search', [
|
||||||
'users' => $users
|
'users' => $users,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
use Livewire\Component;
|
|
||||||
use Livewire\WithPagination;
|
|
||||||
use Livewire\Attributes\Url;
|
|
||||||
|
|
||||||
use App\Models\SiteBackground;
|
use App\Models\SiteBackground;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
use Livewire\Attributes\Url;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Livewire\WithPagination;
|
||||||
|
|
||||||
class BackgroundImages extends Component
|
class BackgroundImages extends Component
|
||||||
{
|
{
|
||||||
@@ -20,16 +19,14 @@ class BackgroundImages extends Component
|
|||||||
{
|
{
|
||||||
$now = Carbon::now();
|
$now = Carbon::now();
|
||||||
|
|
||||||
$images = SiteBackground::when($this->filter === 'active', fn ($query) =>
|
$images = SiteBackground::when($this->filter === 'active', fn ($query) => $query->whereDate('date_start', '<=', $now)->whereDate('date_end', '>=', $now)
|
||||||
$query->whereDate('date_start', '<=', $now)->whereDate('date_end', '>=', $now)
|
|
||||||
)
|
)
|
||||||
->when($this->filter === 'inactive', fn ($query) =>
|
->when($this->filter === 'inactive', fn ($query) => $query->whereDate('date_start', '>', $now)->orWhereDate('date_end', '<', $now)
|
||||||
$query->whereDate('date_start', '>', $now)->orWhereDate('date_end', '<', $now)
|
|
||||||
)
|
)
|
||||||
->paginate(10);
|
->paginate(10);
|
||||||
|
|
||||||
return view('livewire.background-images', [
|
return view('livewire.background-images', [
|
||||||
'images' => $images
|
'images' => $images,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-17
@@ -1,20 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
|
use App\Models\User;
|
||||||
use App\Notifications\CommentNotification;
|
use App\Notifications\CommentNotification;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Livewire\Component;
|
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\RateLimiter;
|
use Illuminate\Support\Facades\RateLimiter;
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Support\Str;
|
||||||
|
use Livewire\Component;
|
||||||
use Maize\Markable\Models\Like;
|
use Maize\Markable\Models\Like;
|
||||||
|
|
||||||
class Comment extends Component
|
class Comment extends Component
|
||||||
@@ -30,21 +26,21 @@ class Comment extends Component
|
|||||||
public $liked = false;
|
public $liked = false;
|
||||||
|
|
||||||
public $replyState = [
|
public $replyState = [
|
||||||
'body' => ''
|
'body' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
public $isEditing = false;
|
public $isEditing = false;
|
||||||
|
|
||||||
public $editState = [
|
public $editState = [
|
||||||
'body' => ''
|
'body' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $listeners = [
|
protected $listeners = [
|
||||||
'refresh' => '$refresh'
|
'refresh' => '$refresh',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'replyState.body' => 'reply'
|
'replyState.body' => 'reply',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function updatedIsEditing($isEditing)
|
public function updatedIsEditing($isEditing)
|
||||||
@@ -54,7 +50,7 @@ class Comment extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->editState = [
|
$this->editState = [
|
||||||
'body' => $this->comment->body
|
'body' => $this->comment->body,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,8 +74,9 @@ class Comment extends Component
|
|||||||
|
|
||||||
public function postReply()
|
public function postReply()
|
||||||
{
|
{
|
||||||
if (!($this->comment->depth() < 2)) {
|
if (! ($this->comment->depth() < 2)) {
|
||||||
$this->addError('replyState.body', "Too many sub comments.");
|
$this->addError('replyState.body', 'Too many sub comments.');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,13 +88,14 @@ class Comment extends Component
|
|||||||
$seconds = RateLimiter::availableIn($rateLimitKey);
|
$seconds = RateLimiter::availableIn($rateLimitKey);
|
||||||
|
|
||||||
$this->addError('replyState.body', "Too many comments. Try again in {$seconds} seconds.");
|
$this->addError('replyState.body', "Too many comments. Try again in {$seconds} seconds.");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RateLimiter::hit($rateLimitKey, $rateLimitMinutes);
|
RateLimiter::hit($rateLimitKey, $rateLimitMinutes);
|
||||||
|
|
||||||
$this->validate([
|
$this->validate([
|
||||||
'replyState.body' => 'required'
|
'replyState.body' => 'required',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$reply = $this->comment->children()->make($this->replyState);
|
$reply = $this->comment->children()->make($this->replyState);
|
||||||
@@ -123,7 +121,7 @@ class Comment extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->replyState = [
|
$this->replyState = [
|
||||||
'body' => ''
|
'body' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->isReplying = false;
|
$this->isReplying = false;
|
||||||
@@ -144,6 +142,7 @@ class Comment extends Component
|
|||||||
if ($this->liked) {
|
if ($this->liked) {
|
||||||
$this->liked = false;
|
$this->liked = false;
|
||||||
$this->likeCount--;
|
$this->likeCount--;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,10 @@
|
|||||||
|
|
||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\RateLimiter;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\RateLimiter;
|
|
||||||
|
|
||||||
class Comments extends Component
|
class Comments extends Component
|
||||||
{
|
{
|
||||||
use WithPagination;
|
use WithPagination;
|
||||||
@@ -14,21 +13,21 @@ class Comments extends Component
|
|||||||
public $model;
|
public $model;
|
||||||
|
|
||||||
public $newCommentState = [
|
public $newCommentState = [
|
||||||
'body' => ''
|
'body' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'newCommentState.body' => 'comment'
|
'newCommentState.body' => 'comment',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $listeners = [
|
protected $listeners = [
|
||||||
'refresh' => '$refresh'
|
'refresh' => '$refresh',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function postComment()
|
public function postComment()
|
||||||
{
|
{
|
||||||
$this->validate([
|
$this->validate([
|
||||||
'newCommentState.body' => 'required'
|
'newCommentState.body' => 'required',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
@@ -39,6 +38,7 @@ class Comments extends Component
|
|||||||
$seconds = RateLimiter::availableIn($rateLimitKey);
|
$seconds = RateLimiter::availableIn($rateLimitKey);
|
||||||
|
|
||||||
$this->addError('newCommentState.body', "Too many comments. Try again in {$seconds} seconds.");
|
$this->addError('newCommentState.body', "Too many comments. Try again in {$seconds} seconds.");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ class Comments extends Component
|
|||||||
$comment->save();
|
$comment->save();
|
||||||
|
|
||||||
$this->newCommentState = [
|
$this->newCommentState = [
|
||||||
'body' => ''
|
'body' => '',
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->resetPage();
|
$this->resetPage();
|
||||||
@@ -65,7 +65,7 @@ class Comments extends Component
|
|||||||
->paginate(50);
|
->paginate(50);
|
||||||
|
|
||||||
return view('livewire.comments', [
|
return view('livewire.comments', [
|
||||||
'comments' => $comments
|
'comments' => $comments,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ class DownloadButton extends Component
|
|||||||
public function clicked($downloadId)
|
public function clicked($downloadId)
|
||||||
{
|
{
|
||||||
$download = Downloads::find($downloadId);
|
$download = Downloads::find($downloadId);
|
||||||
if (!$download) {
|
if (! $download) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,9 @@ namespace App\Livewire;
|
|||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\UserDownload;
|
use App\Models\UserDownload;
|
||||||
|
|
||||||
use Livewire\Component;
|
|
||||||
|
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
class DownloadsFree extends Component
|
class DownloadsFree extends Component
|
||||||
{
|
{
|
||||||
@@ -51,6 +49,7 @@ class DownloadsFree extends Component
|
|||||||
if (Carbon::parse($alreadyDownloaded->created_at)->addHours(6) <= Carbon::now()) {
|
if (Carbon::parse($alreadyDownloaded->created_at)->addHours(6) <= Carbon::now()) {
|
||||||
// Already expired
|
// Already expired
|
||||||
$alreadyDownloaded->delete();
|
$alreadyDownloaded->delete();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,6 +64,7 @@ class DownloadsFree extends Component
|
|||||||
if ($user->downloads_left <= 0) {
|
if ($user->downloads_left <= 0) {
|
||||||
// Daily limit reached
|
// Daily limit reached
|
||||||
$this->granted = 3;
|
$this->granted = 3;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
use App\Models\Downloads;
|
use App\Models\Downloads;
|
||||||
|
use Livewire\Attributes\Url;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
use Livewire\Attributes\Url;
|
|
||||||
|
|
||||||
class DownloadsSearch extends Component
|
class DownloadsSearch extends Component
|
||||||
{
|
{
|
||||||
@@ -25,19 +25,20 @@ class DownloadsSearch extends Component
|
|||||||
|
|
||||||
#[Url(history: true)]
|
#[Url(history: true)]
|
||||||
public $studios = [];
|
public $studios = [];
|
||||||
|
|
||||||
public $studiosCopy = [];
|
public $studiosCopy = [];
|
||||||
|
|
||||||
// To toggle individual option selection
|
// To toggle individual option selection
|
||||||
public function toggleOption($option)
|
public function toggleOption($option)
|
||||||
{
|
{
|
||||||
$this->options[$option] = !$this->options[$option];
|
$this->options[$option] = ! $this->options[$option];
|
||||||
$this->resetPage();
|
$this->resetPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// To toggle dropdown visibility
|
// To toggle dropdown visibility
|
||||||
public function toggleDropdown()
|
public function toggleDropdown()
|
||||||
{
|
{
|
||||||
$this->isOpen = !$this->isOpen;
|
$this->isOpen = ! $this->isOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $queryString = [
|
protected $queryString = [
|
||||||
@@ -87,7 +88,7 @@ class DownloadsSearch extends Component
|
|||||||
public function clicked($downloadId)
|
public function clicked($downloadId)
|
||||||
{
|
{
|
||||||
$download = Downloads::find($downloadId);
|
$download = Downloads::find($downloadId);
|
||||||
if (!$download) {
|
if (! $download) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +99,7 @@ class DownloadsSearch extends Component
|
|||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
if (!auth()->user()->hasRole(\App\Enums\UserRole::SUPPORTER)) {
|
if (! auth()->user()->hasRole(\App\Enums\UserRole::SUPPORTER)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +145,9 @@ class DownloadsSearch extends Component
|
|||||||
|
|
||||||
$downloads = Downloads::when($this->fileSearch != '', fn ($query) => $query->where('url', 'like', '%'.$this->fileSearch.'%'))
|
$downloads = Downloads::when($this->fileSearch != '', fn ($query) => $query->where('url', 'like', '%'.$this->fileSearch.'%'))
|
||||||
->whereIn('type', $this->getSelectedTypes())
|
->whereIn('type', $this->getSelectedTypes())
|
||||||
->when($this->studios !== [], fn ($q) => $q->whereHas('episode', fn ($query) => $query->whereHas('studio', function ($query) { $query->whereIn('slug', $this->studios); })))
|
->when($this->studios !== [], fn ($q) => $q->whereHas('episode', fn ($query) => $query->whereHas('studio', function ($query) {
|
||||||
|
$query->whereIn('slug', $this->studios);
|
||||||
|
})))
|
||||||
->whereNotNull('size')
|
->whereNotNull('size')
|
||||||
->orderBy($orderby, $orderdirection)
|
->orderBy($orderby, $orderdirection)
|
||||||
->paginate(20);
|
->paginate(20);
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ namespace App\Livewire;
|
|||||||
|
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Livewire\Component;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Livewire\Component;
|
||||||
use Maize\Markable\Models\Like;
|
use Maize\Markable\Models\Like;
|
||||||
|
|
||||||
class LikeButton extends Component
|
class LikeButton extends Component
|
||||||
@@ -52,6 +51,7 @@ class LikeButton extends Component
|
|||||||
if ($this->liked) {
|
if ($this->liked) {
|
||||||
$this->liked = false;
|
$this->liked = false;
|
||||||
$this->likeCount--;
|
$this->likeCount--;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Livewire\Attributes\Url;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
use Livewire\Attributes\Url;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
|
|
||||||
class LiveSearch extends Component
|
class LiveSearch extends Component
|
||||||
{
|
{
|
||||||
@@ -20,14 +20,17 @@ class LiveSearch extends Component
|
|||||||
|
|
||||||
#[Url(history: true)]
|
#[Url(history: true)]
|
||||||
public $tags = [];
|
public $tags = [];
|
||||||
|
|
||||||
public $tagsCopy = [];
|
public $tagsCopy = [];
|
||||||
|
|
||||||
#[Url(history: true)]
|
#[Url(history: true)]
|
||||||
public $studios = [];
|
public $studios = [];
|
||||||
|
|
||||||
public $studiosCopy = [];
|
public $studiosCopy = [];
|
||||||
|
|
||||||
#[Url(history: true)]
|
#[Url(history: true)]
|
||||||
public $blacklist = [];
|
public $blacklist = [];
|
||||||
|
|
||||||
public $blacklistCopy = [];
|
public $blacklistCopy = [];
|
||||||
|
|
||||||
#[Url(history: true)]
|
#[Url(history: true)]
|
||||||
@@ -72,7 +75,7 @@ class LiveSearch extends Component
|
|||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
// User blacklist
|
// User blacklist
|
||||||
if (Auth::check() && empty($this->blacklist) && !empty(auth()->user()->tag_blacklist)) {
|
if (Auth::check() && empty($this->blacklist) && ! empty(auth()->user()->tag_blacklist)) {
|
||||||
$this->blacklist = auth()->user()->tag_blacklist;
|
$this->blacklist = auth()->user()->tag_blacklist;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,10 +121,14 @@ class LiveSearch extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
$user_id = Auth::check() ? auth()->user()->id : 0;
|
$user_id = Auth::check() ? auth()->user()->id : 0;
|
||||||
$episodes = Episode::with('gallery')->when($this->search != '', fn ($query) => $query->where(function($query) { $query->where('title', 'like', '%'.$this->search.'%')->orWhere('title_search', 'like', '%'.$this->search.'%')->orWhere('title_jpn', 'like', '%'.$this->search.'%'); }))
|
$episodes = Episode::with('gallery')->when($this->search != '', fn ($query) => $query->where(function ($query) {
|
||||||
|
$query->where('title', 'like', '%'.$this->search.'%')->orWhere('title_search', 'like', '%'.$this->search.'%')->orWhere('title_jpn', 'like', '%'.$this->search.'%');
|
||||||
|
}))
|
||||||
->when($this->tags !== [], fn ($query) => $query->withAllTags($this->tags))
|
->when($this->tags !== [], fn ($query) => $query->withAllTags($this->tags))
|
||||||
->when($this->blacklist !== [], fn ($query) => $query->withoutTags($this->blacklist))
|
->when($this->blacklist !== [], fn ($query) => $query->withoutTags($this->blacklist))
|
||||||
->when($this->studios !== [], fn ($query) => $query->whereHas('studio', function ($query) { $query->whereIn('slug', $this->studios); }))
|
->when($this->studios !== [], fn ($query) => $query->whereHas('studio', function ($query) {
|
||||||
|
$query->whereIn('slug', $this->studios);
|
||||||
|
}))
|
||||||
->when($this->hideWatched !== [] && Auth::check(), fn ($query) => $query->whereDoesntHave('watched', function ($query) use ($user_id) {
|
->when($this->hideWatched !== [] && Auth::check(), fn ($query) => $query->whereDoesntHave('watched', function ($query) use ($user_id) {
|
||||||
$query->where('user_id', $user_id);
|
$query->where('user_id', $user_id);
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
use Livewire\Component;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
class NavLiveSearch extends Component
|
class NavLiveSearch extends Component
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,13 +5,11 @@ namespace App\Livewire;
|
|||||||
use App\Models\Playlist;
|
use App\Models\Playlist;
|
||||||
use App\Models\PlaylistEpisode;
|
use App\Models\PlaylistEpisode;
|
||||||
use App\Services\PlaylistService;
|
use App\Services\PlaylistService;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Livewire\Attributes\Url;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
use Livewire\Attributes\Url;
|
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
|
|
||||||
class PlaylistOverview extends Component
|
class PlaylistOverview extends Component
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,10 +3,9 @@
|
|||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
use App\Models\Playlist;
|
use App\Models\Playlist;
|
||||||
|
use Livewire\Attributes\Url;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
use Livewire\Attributes\Url;
|
|
||||||
|
|
||||||
class Playlists extends Component
|
class Playlists extends Component
|
||||||
{
|
{
|
||||||
@@ -54,12 +53,12 @@ class Playlists extends Component
|
|||||||
$playlists = Playlist::where('is_private', 0)
|
$playlists = Playlist::where('is_private', 0)
|
||||||
->withCount('episodes')
|
->withCount('episodes')
|
||||||
->having('episodes_count', '>', 1)
|
->having('episodes_count', '>', 1)
|
||||||
->when($this->search != '', fn($query) => $query->where('name', 'like', '%' . $this->search . '%'))
|
->when($this->search != '', fn ($query) => $query->where('name', 'like', '%'.$this->search.'%'))
|
||||||
->orderBy($orderby, $orderdirection)
|
->orderBy($orderby, $orderdirection)
|
||||||
->paginate($this->pagination);
|
->paginate($this->pagination);
|
||||||
|
|
||||||
return view('livewire.playlists', [
|
return view('livewire.playlists', [
|
||||||
'playlists' => $playlists
|
'playlists' => $playlists,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
use App\Models\Comment;
|
use App\Models\Comment;
|
||||||
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
|
|
||||||
@@ -36,14 +35,13 @@ class UserComments extends Component
|
|||||||
$orderdirection = 'desc';
|
$orderdirection = 'desc';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$comments = Comment::where('user_id', $this->model->id)
|
$comments = Comment::where('user_id', $this->model->id)
|
||||||
->when($this->commentSearch != '', fn ($query) => $query->where('body', 'like', '%'.$this->commentSearch.'%'))
|
->when($this->commentSearch != '', fn ($query) => $query->where('body', 'like', '%'.$this->commentSearch.'%'))
|
||||||
->orderBy($orderby, $orderdirection)
|
->orderBy($orderby, $orderdirection)
|
||||||
->paginate(10);
|
->paginate(6);
|
||||||
|
|
||||||
return view('livewire.user-comments', [
|
return view('livewire.user-comments', [
|
||||||
'comments' => $comments
|
'comments' => $comments,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Livewire\Attributes\Url;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
use Livewire\Attributes\Url;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
|
|
||||||
class UserLikes extends Component
|
class UserLikes extends Component
|
||||||
{
|
{
|
||||||
@@ -20,14 +20,17 @@ class UserLikes extends Component
|
|||||||
|
|
||||||
#[Url(history: true)]
|
#[Url(history: true)]
|
||||||
public $tags = [];
|
public $tags = [];
|
||||||
|
|
||||||
public $tagsCopy = [];
|
public $tagsCopy = [];
|
||||||
|
|
||||||
#[Url(history: true)]
|
#[Url(history: true)]
|
||||||
public $studios = [];
|
public $studios = [];
|
||||||
|
|
||||||
public $studiosCopy = [];
|
public $studiosCopy = [];
|
||||||
|
|
||||||
#[Url(history: true)]
|
#[Url(history: true)]
|
||||||
public $blacklist = [];
|
public $blacklist = [];
|
||||||
|
|
||||||
public $blacklistCopy = [];
|
public $blacklistCopy = [];
|
||||||
|
|
||||||
#[Url(history: true)]
|
#[Url(history: true)]
|
||||||
@@ -72,7 +75,7 @@ class UserLikes extends Component
|
|||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
// User blacklist
|
// User blacklist
|
||||||
if (Auth::check() && empty($this->blacklist) && !empty(auth()->user()->tag_blacklist)) {
|
if (Auth::check() && empty($this->blacklist) && ! empty(auth()->user()->tag_blacklist)) {
|
||||||
$this->blacklist = auth()->user()->tag_blacklist;
|
$this->blacklist = auth()->user()->tag_blacklist;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,10 +122,14 @@ class UserLikes extends Component
|
|||||||
|
|
||||||
$user_id = Auth::check() ? auth()->user()->id : 0;
|
$user_id = Auth::check() ? auth()->user()->id : 0;
|
||||||
$episodes = Episode::whereHasLike(auth()->user())
|
$episodes = Episode::whereHasLike(auth()->user())
|
||||||
->when($this->search !== '', fn ($query) => $query->where(function($query) { $query->where('title', 'like', '%'.$this->search.'%')->orWhere('title_search', 'like', '%'.$this->search.'%')->orWhere('title_jpn', 'like', '%'.$this->search.'%'); }))
|
->when($this->search !== '', fn ($query) => $query->where(function ($query) {
|
||||||
|
$query->where('title', 'like', '%'.$this->search.'%')->orWhere('title_search', 'like', '%'.$this->search.'%')->orWhere('title_jpn', 'like', '%'.$this->search.'%');
|
||||||
|
}))
|
||||||
->when($this->tags !== [], fn ($query) => $query->withAllTags($this->tags))
|
->when($this->tags !== [], fn ($query) => $query->withAllTags($this->tags))
|
||||||
->when($this->blacklist !== [], fn ($query) => $query->withoutTags($this->blacklist))
|
->when($this->blacklist !== [], fn ($query) => $query->withoutTags($this->blacklist))
|
||||||
->when($this->studios !== [], fn ($query) => $query->whereHas('studio', function ($query) { $query->whereIn('slug', $this->studios); }))
|
->when($this->studios !== [], fn ($query) => $query->whereHas('studio', function ($query) {
|
||||||
|
$query->whereIn('slug', $this->studios);
|
||||||
|
}))
|
||||||
->when($this->hideWatched !== [] && Auth::check(), fn ($query) => $query->whereDoesntHave('watched', function ($query) use ($user_id) {
|
->when($this->hideWatched !== [] && Auth::check(), fn ($query) => $query->whereDoesntHave('watched', function ($query) use ($user_id) {
|
||||||
$query->where('user_id', $user_id);
|
$query->where('user_id', $user_id);
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
use App\Models\Watched as UserWatched;
|
use App\Models\Watched as UserWatched;
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
|
|||||||
@@ -4,19 +4,18 @@ namespace App\Models;
|
|||||||
|
|
||||||
use App\Models\Presenters\CommentPresenter;
|
use App\Models\Presenters\CommentPresenter;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Maize\Markable\Markable;
|
use Maize\Markable\Markable;
|
||||||
use Maize\Markable\Models\Like;
|
use Maize\Markable\Models\Like;
|
||||||
|
|
||||||
class Comment extends Model
|
class Comment extends Model
|
||||||
{
|
{
|
||||||
use HasFactory, SoftDeletes, Markable;
|
use HasFactory, Markable, SoftDeletes;
|
||||||
|
|
||||||
protected static $marks = [
|
protected static $marks = [
|
||||||
Like::class
|
Like::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,7 +24,7 @@ class Comment extends Model
|
|||||||
* @var string[]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'body'
|
'body',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function presenter()
|
public function presenter()
|
||||||
@@ -71,6 +70,6 @@ class Comment extends Model
|
|||||||
*/
|
*/
|
||||||
public function likeCount(): int
|
public function likeCount(): int
|
||||||
{
|
{
|
||||||
return cache()->remember('commentLikes' . $this->id, 300, fn() => $this->likes->count());
|
return cache()->remember('commentLikes'.$this->id, 300, fn () => $this->likes->count());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class Downloads extends Model
|
|||||||
$bytes /= 1024;
|
$bytes /= 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
return round($bytes, 2) . ' ' . $units[$i];
|
return round($bytes, 2).' '.$units[$i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+22
-27
@@ -2,35 +2,28 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Models\Downloads;
|
|
||||||
use App\Models\PopularMonthly;
|
|
||||||
use App\Models\PopularWeekly;
|
|
||||||
use App\Models\PopularDaily;
|
|
||||||
|
|
||||||
use Conner\Tagging\Taggable;
|
use Conner\Tagging\Taggable;
|
||||||
use Laravel\Scout\Searchable;
|
|
||||||
use Maize\Markable\Markable;
|
|
||||||
use Maize\Markable\Models\Like;
|
|
||||||
|
|
||||||
use Spatie\Sitemap\Contracts\Sitemapable;
|
|
||||||
use Spatie\Sitemap\Tags\Url;
|
|
||||||
|
|
||||||
use Illuminate\Support\Carbon;
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Laravel\Scout\Searchable;
|
||||||
|
use Maize\Markable\Markable;
|
||||||
|
use Maize\Markable\Models\Like;
|
||||||
|
use Spatie\Sitemap\Contracts\Sitemapable;
|
||||||
|
use Spatie\Sitemap\Tags\Url;
|
||||||
|
|
||||||
class Episode extends Model implements Sitemapable
|
class Episode extends Model implements Sitemapable
|
||||||
{
|
{
|
||||||
use Markable, Taggable;
|
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
use Markable, Taggable;
|
||||||
use Searchable;
|
use Searchable;
|
||||||
|
|
||||||
protected static $marks = [
|
protected static $marks = [
|
||||||
Like::class
|
Like::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -125,7 +118,7 @@ class Episode extends Model implements Sitemapable
|
|||||||
*/
|
*/
|
||||||
public function viewCount(): int
|
public function viewCount(): int
|
||||||
{
|
{
|
||||||
return cache()->remember('episodeViews' . $this->id, 300, fn() => $this->view_count);
|
return cache()->remember('episodeViews'.$this->id, 300, fn () => $this->view_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,7 +134,7 @@ class Episode extends Model implements Sitemapable
|
|||||||
$index = floor(log($this->viewCount(), 1000));
|
$index = floor(log($this->viewCount(), 1000));
|
||||||
$shortNumber = $this->viewCount() / pow(1000, $index);
|
$shortNumber = $this->viewCount() / pow(1000, $index);
|
||||||
|
|
||||||
return round($shortNumber, 0) . $units[$index - 1];
|
return round($shortNumber, 0).$units[$index - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -149,7 +142,7 @@ class Episode extends Model implements Sitemapable
|
|||||||
*/
|
*/
|
||||||
public function likeCount(): int
|
public function likeCount(): int
|
||||||
{
|
{
|
||||||
return cache()->remember('episodeLikes' . $this->id, 300, fn() => $this->likes->count());
|
return cache()->remember('episodeLikes'.$this->id, 300, fn () => $this->likes->count());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,7 +150,7 @@ class Episode extends Model implements Sitemapable
|
|||||||
*/
|
*/
|
||||||
public function commentCount(): int
|
public function commentCount(): int
|
||||||
{
|
{
|
||||||
return cache()->remember('episodeComments' . $this->id, 300, fn() => $this->comments->count());
|
return cache()->remember('episodeComments'.$this->id, 300, fn () => $this->comments->count());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function comments()
|
public function comments()
|
||||||
@@ -180,6 +173,7 @@ class Episode extends Model implements Sitemapable
|
|||||||
|
|
||||||
$problematicResults .= $pTag;
|
$problematicResults .= $pTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $problematicResults;
|
return $problematicResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,17 +196,17 @@ class Episode extends Model implements Sitemapable
|
|||||||
*/
|
*/
|
||||||
public function hasAutoTrans(): bool
|
public function hasAutoTrans(): bool
|
||||||
{
|
{
|
||||||
return cache()->remember('mt' . $this->id, 900, fn() => $this->subtitles()->exists());
|
return cache()->remember('mt'.$this->id, 900, fn () => $this->subtitles()->exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function is48Fps(): bool
|
public function is48Fps(): bool
|
||||||
{
|
{
|
||||||
return cache()->remember('48fps' . $this->id, 900, fn() => $this->interpolated);
|
return cache()->remember('48fps'.$this->id, 900, fn () => $this->interpolated);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isUHD48Fps(): bool
|
public function isUHD48Fps(): bool
|
||||||
{
|
{
|
||||||
return cache()->remember('48fpsUHD' . $this->id, 900, fn() => $this->interpolated_uhd);
|
return cache()->remember('48fpsUHD'.$this->id, 900, fn () => $this->interpolated_uhd);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getResolution(): string
|
public function getResolution(): string
|
||||||
@@ -226,7 +220,7 @@ class Episode extends Model implements Sitemapable
|
|||||||
|
|
||||||
public function userWatched(int $user_id): bool
|
public function userWatched(int $user_id): bool
|
||||||
{
|
{
|
||||||
return cache()->remember('user' . $user_id . 'watched' . $this->id, 300, fn() => Watched::where('user_id', $user_id)->where('episode_id', $this->id)->exists());
|
return cache()->remember('user'.$user_id.'watched'.$this->id, 300, fn () => Watched::where('user_id', $user_id)->where('episode_id', $this->id)->exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function watched(): HasMany
|
public function watched(): HasMany
|
||||||
@@ -234,15 +228,16 @@ class Episode extends Model implements Sitemapable
|
|||||||
return $this->hasMany(Watched::class);
|
return $this->hasMany(Watched::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDownloadByType(string $type): Downloads | null
|
public function getDownloadByType(string $type): ?Downloads
|
||||||
{
|
{
|
||||||
$cacheKey = "episode_{$this->id}_download_{$type}";
|
$cacheKey = "episode_{$this->id}_download_{$type}";
|
||||||
|
|
||||||
return Cache::remember($cacheKey, now()->addMinutes(10), function () use ($type) {
|
return Cache::remember($cacheKey, now()->addMinutes(10), function () use ($type) {
|
||||||
return $this->downloads()->where('type', $type)->first();
|
return $this->downloads()->where('type', $type)->first();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toSitemapTag(): Url | string | array
|
public function toSitemapTag(): Url|string|array
|
||||||
{
|
{
|
||||||
return Url::create(route('hentai.index', $this->slug))
|
return Url::create(route('hentai.index', $this->slug))
|
||||||
->setLastModificationDate(Carbon::create($this->created_at));
|
->setLastModificationDate(Carbon::create($this->created_at));
|
||||||
|
|||||||
@@ -2,19 +2,18 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Conner\Tagging\Taggable;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Spatie\Sitemap\Contracts\Sitemapable;
|
use Spatie\Sitemap\Contracts\Sitemapable;
|
||||||
use Spatie\Sitemap\Tags\Url;
|
use Spatie\Sitemap\Tags\Url;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
|
||||||
use Illuminate\Support\Carbon;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Conner\Tagging\Taggable;
|
|
||||||
|
|
||||||
class Hentai extends Model implements Sitemapable
|
class Hentai extends Model implements Sitemapable
|
||||||
{
|
{
|
||||||
use Taggable;
|
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
use Taggable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@@ -31,7 +30,7 @@ class Hentai extends Model implements Sitemapable
|
|||||||
return $this->hasMany(Episode::class, 'hentai_id');
|
return $this->hasMany(Episode::class, 'hentai_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function title(): String
|
public function title(): string
|
||||||
{
|
{
|
||||||
return $this->episodes->first()->title;
|
return $this->episodes->first()->title;
|
||||||
}
|
}
|
||||||
@@ -63,7 +62,7 @@ class Hentai extends Model implements Sitemapable
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toSitemapTag(): Url | string | array
|
public function toSitemapTag(): Url|string|array
|
||||||
{
|
{
|
||||||
return Url::create(route('hentai.index', $this->slug))
|
return Url::create(route('hentai.index', $this->slug))
|
||||||
->setLastModificationDate(Carbon::create($this->created_at));
|
->setLastModificationDate(Carbon::create($this->created_at));
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
class Playlist extends Model
|
class Playlist extends Model
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
class PlaylistEpisode extends Model
|
class PlaylistEpisode extends Model
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class PopularDaily extends Model
|
|||||||
*
|
*
|
||||||
* @var string[]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected $fillable = [ 'episode_id' ];
|
protected $fillable = ['episode_id'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Episode.
|
* Get the Episode.
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class PopularMonthly extends Model
|
|||||||
*
|
*
|
||||||
* @var string[]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected $fillable = [ 'episode_id' ];
|
protected $fillable = ['episode_id'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Episode.
|
* Get the Episode.
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class PopularWeekly extends Model
|
|||||||
*
|
*
|
||||||
* @var string[]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected $fillable = [ 'episode_id' ];
|
protected $fillable = ['episode_id'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Episode.
|
* Get the Episode.
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
|
|
||||||
class SiteBackground extends Model
|
class SiteBackground extends Model
|
||||||
{
|
{
|
||||||
@@ -16,13 +15,13 @@ class SiteBackground extends Model
|
|||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'date_start',
|
'date_start',
|
||||||
'date_end',
|
'date_end',
|
||||||
'default'
|
'default',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current IDs of active wallpaper
|
* Returns the current IDs of active wallpaper
|
||||||
*/
|
*/
|
||||||
public function getImages(): ? \Illuminate\Support\Collection
|
public function getImages(): ?\Illuminate\Support\Collection
|
||||||
{
|
{
|
||||||
$now = Carbon::now();
|
$now = Carbon::now();
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
class Studios extends Model
|
class Studios extends Model
|
||||||
{
|
{
|
||||||
|
|||||||
+7
-11
@@ -2,16 +2,15 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
//use Illuminate\Contracts\Auth\MustVerifyEmail;
|
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
|
|
||||||
use App\Enums\UserRole;
|
use App\Enums\UserRole;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
@@ -62,7 +61,6 @@ class User extends Authenticatable
|
|||||||
'discord_avatar' => 'string',
|
'discord_avatar' => 'string',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has Many Playlists.
|
* Has Many Playlists.
|
||||||
*/
|
*/
|
||||||
@@ -100,7 +98,7 @@ class User extends Authenticatable
|
|||||||
*/
|
*/
|
||||||
public function commentCount(): int
|
public function commentCount(): int
|
||||||
{
|
{
|
||||||
return cache()->remember('userComments' . $this->id, 300, fn() => $this->comments->count());
|
return cache()->remember('userComments'.$this->id, 300, fn () => $this->comments->count());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,13 +106,11 @@ class User extends Authenticatable
|
|||||||
*/
|
*/
|
||||||
public function getAvatar(): string
|
public function getAvatar(): string
|
||||||
{
|
{
|
||||||
if ($this->discord_id && $this->discord_avatar && !$this->avatar)
|
if ($this->discord_id && $this->discord_avatar && ! $this->avatar) {
|
||||||
{
|
|
||||||
return "https://external-content.duckduckgo.com/iu/?u={$this->discord_avatar}";
|
return "https://external-content.duckduckgo.com/iu/?u={$this->discord_avatar}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->avatar)
|
if ($this->avatar) {
|
||||||
{
|
|
||||||
return Storage::url($this->avatar);
|
return Storage::url($this->avatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +149,7 @@ class User extends Authenticatable
|
|||||||
*/
|
*/
|
||||||
public function removeRole(UserRole $role): void
|
public function removeRole(UserRole $role): void
|
||||||
{
|
{
|
||||||
if (!$this->hasRole($role)) {
|
if (! $this->hasRole($role)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
class UserDownload extends Model
|
class UserDownload extends Model
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
class Watched extends Model
|
class Watched extends Model
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
namespace App\Notifications;
|
namespace App\Notifications;
|
||||||
|
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
|
||||||
use Illuminate\Notifications\Notification;
|
use Illuminate\Notifications\Notification;
|
||||||
|
|
||||||
class CommentNotification extends Notification
|
class CommentNotification extends Notification
|
||||||
@@ -12,7 +10,9 @@ class CommentNotification extends Notification
|
|||||||
use Queueable;
|
use Queueable;
|
||||||
|
|
||||||
protected $type;
|
protected $type;
|
||||||
|
|
||||||
protected $message;
|
protected $message;
|
||||||
|
|
||||||
protected $url;
|
protected $url;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Policies;
|
namespace App\Policies;
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Comment;
|
use App\Models\Comment;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||||
|
|
||||||
class CommentPolicy
|
class CommentPolicy
|
||||||
|
|||||||
@@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Jobs\GetFileSizeFromCDN;
|
||||||
use App\Models\Downloads;
|
use App\Models\Downloads;
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
|
|
||||||
use App\Jobs\GetFileSizeFromCDN;
|
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class DownloadService
|
class DownloadService
|
||||||
|
|||||||
@@ -5,14 +5,12 @@ namespace App\Services;
|
|||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
use App\Models\Hentai;
|
use App\Models\Hentai;
|
||||||
use App\Models\Studios;
|
use App\Models\Studios;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
use Intervention\Image\Laravel\Facades\Image;
|
|
||||||
use Intervention\Image\Encoders\WebpEncoder;
|
use Intervention\Image\Encoders\WebpEncoder;
|
||||||
|
use Intervention\Image\Laravel\Facades\Image;
|
||||||
|
|
||||||
class EpisodeService
|
class EpisodeService
|
||||||
{
|
{
|
||||||
@@ -24,6 +22,7 @@ class EpisodeService
|
|||||||
|
|
||||||
if (is_numeric($lastPart) && $lastPart < 1000) {
|
if (is_numeric($lastPart) && $lastPart < 1000) {
|
||||||
$slugParts[array_key_last($slugParts)] = 's'.$lastPart;
|
$slugParts[array_key_last($slugParts)] = 's'.$lastPart;
|
||||||
|
|
||||||
return implode('-', $slugParts);
|
return implode('-', $slugParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,11 +35,10 @@ class EpisodeService
|
|||||||
int $episodeNumber,
|
int $episodeNumber,
|
||||||
?Studios $studio = null,
|
?Studios $studio = null,
|
||||||
?Episode $referenceEpisode = null
|
?Episode $referenceEpisode = null
|
||||||
): Episode
|
): Episode {
|
||||||
{
|
$episode = new Episode;
|
||||||
$episode = new Episode();
|
|
||||||
$episode->title = $referenceEpisode->title ?? $request->input('title');
|
$episode->title = $referenceEpisode->title ?? $request->input('title');
|
||||||
$episode->title_search = preg_replace("/[^A-Za-z0-9 ]/", '', $episode->title);
|
$episode->title_search = preg_replace('/[^A-Za-z0-9 ]/', '', $episode->title);
|
||||||
$episode->title_jpn = $referenceEpisode->title_jpn ?? $request->input('title_jpn');
|
$episode->title_jpn = $referenceEpisode->title_jpn ?? $request->input('title_jpn');
|
||||||
$episode->slug = "{$hentai->slug}-{$episodeNumber}";
|
$episode->slug = "{$hentai->slug}-{$episodeNumber}";
|
||||||
$episode->hentai_id = $hentai->id;
|
$episode->hentai_id = $hentai->id;
|
||||||
@@ -96,7 +94,6 @@ class EpisodeService
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function createOrUpdateCover(Request $request, Episode $episode, string $slug, int $episodeNumber): void
|
public function createOrUpdateCover(Request $request, Episode $episode, string $slug, int $episodeNumber): void
|
||||||
{
|
{
|
||||||
if (! $request->hasFile("episodecover{$episodeNumber}")) {
|
if (! $request->hasFile("episodecover{$episodeNumber}")) {
|
||||||
@@ -111,7 +108,7 @@ class EpisodeService
|
|||||||
// Encode and save cover image
|
// Encode and save cover image
|
||||||
Image::read($request->file("episodecover{$episodeNumber}")->getRealPath())
|
Image::read($request->file("episodecover{$episodeNumber}")->getRealPath())
|
||||||
->cover(268, 394)
|
->cover(268, 394)
|
||||||
->encode(new WebpEncoder())
|
->encode(new WebpEncoder)
|
||||||
->save(Storage::disk('public')->path($episode->cover_url));
|
->save(Storage::disk('public')->path($episode->cover_url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,29 +5,25 @@ namespace App\Services;
|
|||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
use App\Models\Gallery;
|
use App\Models\Gallery;
|
||||||
use App\Models\Hentai;
|
use App\Models\Hentai;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\File;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
use Intervention\Image\Laravel\Facades\Image;
|
|
||||||
use Intervention\Image\Encoders\WebpEncoder;
|
use Intervention\Image\Encoders\WebpEncoder;
|
||||||
|
use Intervention\Image\Laravel\Facades\Image;
|
||||||
|
|
||||||
class GalleryService
|
class GalleryService
|
||||||
{
|
{
|
||||||
|
|
||||||
public function createOrUpdateGallery(Request $request, Hentai $hentai, Episode $episode, int $episodeNumber, bool $override = false): void
|
public function createOrUpdateGallery(Request $request, Hentai $hentai, Episode $episode, int $episodeNumber, bool $override = false): void
|
||||||
{
|
{
|
||||||
$galleryInputNumber = $override ? 1 : $episodeNumber;
|
$galleryInputNumber = $override ? 1 : $episodeNumber;
|
||||||
|
|
||||||
if($request->hasFile('episodegallery'.$galleryInputNumber)) {
|
if ($request->hasFile('episodegallery'.$galleryInputNumber)) {
|
||||||
|
|
||||||
$this->deleteOldGallery($episode);
|
$this->deleteOldGallery($episode);
|
||||||
|
|
||||||
$this->createGalleryFolder($hentai);
|
$this->createGalleryFolder($hentai);
|
||||||
|
|
||||||
$counter = 0;
|
$counter = 0;
|
||||||
foreach($request->file('episodegallery'.$galleryInputNumber) as $file) {
|
foreach ($request->file('episodegallery'.$galleryInputNumber) as $file) {
|
||||||
$gallery = $this->createGallery($hentai, $episode, $episodeNumber, $counter);
|
$gallery = $this->createGallery($hentai, $episode, $episodeNumber, $counter);
|
||||||
$this->saveGalleryImage($gallery, $file);
|
$this->saveGalleryImage($gallery, $file);
|
||||||
$counter += 1;
|
$counter += 1;
|
||||||
@@ -45,7 +41,7 @@ class GalleryService
|
|||||||
|
|
||||||
private function createGallery(Hentai $hentai, Episode $episode, int $episodeNumber, int $counter): Gallery
|
private function createGallery(Hentai $hentai, Episode $episode, int $episodeNumber, int $counter): Gallery
|
||||||
{
|
{
|
||||||
$gallery = new Gallery();
|
$gallery = new Gallery;
|
||||||
$gallery->hentai_id = $hentai->id;
|
$gallery->hentai_id = $hentai->id;
|
||||||
$gallery->episode_id = $episode->id;
|
$gallery->episode_id = $episode->id;
|
||||||
$gallery->image_url = "/images/hentai/{$hentai->slug}/gallery-ep-{$episodeNumber}-{$counter}.webp";
|
$gallery->image_url = "/images/hentai/{$hentai->slug}/gallery-ep-{$episodeNumber}-{$counter}.webp";
|
||||||
@@ -59,12 +55,12 @@ class GalleryService
|
|||||||
{
|
{
|
||||||
Image::read($sourceImage->getRealPath())
|
Image::read($sourceImage->getRealPath())
|
||||||
->cover(1920, 1080)
|
->cover(1920, 1080)
|
||||||
->encode(new WebpEncoder())
|
->encode(new WebpEncoder)
|
||||||
->save(Storage::disk('public')->path($gallery->image_url));
|
->save(Storage::disk('public')->path($gallery->image_url));
|
||||||
|
|
||||||
Image::read($sourceImage->getRealPath())
|
Image::read($sourceImage->getRealPath())
|
||||||
->cover(960, 540)
|
->cover(960, 540)
|
||||||
->encode(new WebpEncoder())
|
->encode(new WebpEncoder)
|
||||||
->save(Storage::disk('public')->path($gallery->thumbnail_url));
|
->save(Storage::disk('public')->path($gallery->thumbnail_url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ class MatrixRegistrationService
|
|||||||
// Get nonce from Synapse
|
// Get nonce from Synapse
|
||||||
$nonceResponse = Http::get("$server/_synapse/admin/v1/register");
|
$nonceResponse = Http::get("$server/_synapse/admin/v1/register");
|
||||||
|
|
||||||
if (!$nonceResponse->ok()) {
|
if (! $nonceResponse->ok()) {
|
||||||
throw new \Exception("Could not fetch nonce from Matrix.");
|
throw new \Exception('Could not fetch nonce from Matrix.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$nonce = $nonceResponse->json()['nonce'];
|
$nonce = $nonceResponse->json()['nonce'];
|
||||||
@@ -23,10 +23,10 @@ class MatrixRegistrationService
|
|||||||
// Generate MAC
|
// Generate MAC
|
||||||
$mac = hash_hmac(
|
$mac = hash_hmac(
|
||||||
'sha1',
|
'sha1',
|
||||||
$nonce . "\0" .
|
$nonce."\0".
|
||||||
$username . "\0" .
|
$username."\0".
|
||||||
$password . "\0" .
|
$password."\0".
|
||||||
"notadmin",
|
'notadmin',
|
||||||
$secret
|
$secret
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ return [
|
|||||||
'803325441942356059', // Tier-3
|
'803325441942356059', // Tier-3
|
||||||
'803322725576736858', // Tier-2
|
'803322725576736858', // Tier-2
|
||||||
'802270568912519198', // Tier-1
|
'802270568912519198', // Tier-1
|
||||||
'802234830384267315' // admin
|
'802234830384267315', // admin
|
||||||
],
|
],
|
||||||
|
|
||||||
'discord_bot_token' => env('DISCORD_BOT_TOKEN'),
|
'discord_bot_token' => env('DISCORD_BOT_TOKEN'),
|
||||||
|
|||||||
+2
-2
@@ -30,11 +30,11 @@ return [
|
|||||||
|
|
||||||
// Asia Fallback (HTTP)
|
// Asia Fallback (HTTP)
|
||||||
'asia_download_domain' => [
|
'asia_download_domain' => [
|
||||||
'https://komako-b-ddl.musume-h.xyz'
|
'https://komako-b-ddl.musume-h.xyz',
|
||||||
],
|
],
|
||||||
|
|
||||||
'asia_stream_domain' => [
|
'asia_stream_domain' => [
|
||||||
'https://komako-b-str.musume-h.xyz'
|
'https://komako-b-str.musume-h.xyz',
|
||||||
],
|
],
|
||||||
|
|
||||||
// Free 4k Downloads
|
// Free 4k Downloads
|
||||||
|
|||||||
+1
-1
@@ -38,5 +38,5 @@ return [
|
|||||||
'autoOrientation' => true,
|
'autoOrientation' => true,
|
||||||
'decodeAnimation' => true,
|
'decodeAnimation' => true,
|
||||||
'blendingColor' => 'ffffff',
|
'blendingColor' => 'ffffff',
|
||||||
]
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
+2
-2
@@ -149,12 +149,12 @@ return [
|
|||||||
'title_jpn',
|
'title_jpn',
|
||||||
'slug',
|
'slug',
|
||||||
'description',
|
'description',
|
||||||
'tags'
|
'tags',
|
||||||
],
|
],
|
||||||
'sortableAttributes' => [
|
'sortableAttributes' => [
|
||||||
'created_at',
|
'created_at',
|
||||||
'release_date',
|
'release_date',
|
||||||
'title'
|
'title',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -263,5 +263,4 @@ return [
|
|||||||
'confirm_delete_icon' => env('SWEET_ALERT_CONFIRM_DELETE_ICON', 'warning'),
|
'confirm_delete_icon' => env('SWEET_ALERT_CONFIRM_DELETE_ICON', 'warning'),
|
||||||
'confirm_delete_show_loader_on_confirm' => env('SWEET_ALERT_CONFIRM_DELETE_SHOW_LOADER_ON_CONFIRM', true),
|
'confirm_delete_show_loader_on_confirm' => env('SWEET_ALERT_CONFIRM_DELETE_SHOW_LOADER_ON_CONFIRM', true),
|
||||||
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ return [
|
|||||||
'displayer' => '\Illuminate\Support\Str::title',
|
'displayer' => '\Illuminate\Support\Str::title',
|
||||||
|
|
||||||
// Database connection for Conner\Taggable\Tag model to use
|
// Database connection for Conner\Taggable\Tag model to use
|
||||||
// 'connection' => 'mysql',
|
// 'connection' => 'mysql',
|
||||||
|
|
||||||
// When deleting a model, remove all the tags first
|
// When deleting a model, remove all the tags first
|
||||||
'untag_on_delete' => true,
|
'untag_on_delete' => true,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\Studios;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ use App\Models\Hentai;
|
|||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
{
|
{
|
||||||
@@ -17,16 +17,16 @@ return new class extends Migration
|
|||||||
{
|
{
|
||||||
// Change Tagging from Hentai to Episode
|
// Change Tagging from Hentai to Episode
|
||||||
$hentai = DB::table('hentai')->get();
|
$hentai = DB::table('hentai')->get();
|
||||||
foreach($hentai as $h) {
|
foreach ($hentai as $h) {
|
||||||
|
|
||||||
$episodes = Episode::where('hentai_id', $h->id)->get();
|
$episodes = Episode::where('hentai_id', $h->id)->get();
|
||||||
foreach($episodes as $episode) {
|
foreach ($episodes as $episode) {
|
||||||
$episode->tag($h->tagNames());
|
$episode->tag($h->tagNames());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete Hentai Tags
|
// Delete Hentai Tags
|
||||||
foreach($hentai as $h) {
|
foreach ($hentai as $h) {
|
||||||
$h->untag();
|
$h->untag();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ return new class extends Migration
|
|||||||
});
|
});
|
||||||
|
|
||||||
$episodes = DB::table('episode')->get();
|
$episodes = DB::table('episode')->get();
|
||||||
foreach($episodes as $episode) {
|
foreach ($episodes as $episode) {
|
||||||
$hentai = Hentai::where('id', $episode->hentai_id)->first();
|
$hentai = Hentai::where('id', $episode->hentai_id)->first();
|
||||||
|
|
||||||
$episode->title = $hentai->title;
|
$episode->title = $hentai->title;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ return new class extends Migration
|
|||||||
->where('resolution', '4k')
|
->where('resolution', '4k')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
foreach($episodes as $episode) {
|
foreach ($episodes as $episode) {
|
||||||
$episode->download_url_4k = Str::replace('1080p', '2160p', $episode->download_url);
|
$episode->download_url_4k = Str::replace('1080p', '2160p', $episode->download_url);
|
||||||
$episode->save();
|
$episode->save();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,7 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
Schema::table('gallery', function (Blueprint $table)
|
Schema::table('gallery', function (Blueprint $table) {
|
||||||
{
|
|
||||||
$table->dropIndex(['episode_id', 'hentai_id']);
|
$table->dropIndex(['episode_id', 'hentai_id']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ return new class extends Migration
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Migrate old entries
|
// Migrate old entries
|
||||||
foreach(Episode::all() as $episode) {
|
foreach (Episode::all() as $episode) {
|
||||||
// 1080p
|
// 1080p
|
||||||
if (! empty($episode->download_url)) {
|
if (! empty($episode->download_url)) {
|
||||||
Downloads::create([
|
Downloads::create([
|
||||||
'episode_id' => $episode->id,
|
'episode_id' => $episode->id,
|
||||||
'type' => 'FHD',
|
'type' => 'FHD',
|
||||||
'url' => $episode->download_url
|
'url' => $episode->download_url,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ return new class extends Migration
|
|||||||
Downloads::create([
|
Downloads::create([
|
||||||
'episode_id' => $episode->id,
|
'episode_id' => $episode->id,
|
||||||
'type' => 'FHDi',
|
'type' => 'FHDi',
|
||||||
'url' => $episode->download_url_interpolated
|
'url' => $episode->download_url_interpolated,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ return new class extends Migration
|
|||||||
Downloads::create([
|
Downloads::create([
|
||||||
'episode_id' => $episode->id,
|
'episode_id' => $episode->id,
|
||||||
'type' => 'UHD',
|
'type' => 'UHD',
|
||||||
'url' => $episode->download_url_4k
|
'url' => $episode->download_url_4k,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
use App\Models\Hentai;
|
use App\Models\Hentai;
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ return new class extends Migration
|
|||||||
|
|
||||||
// Update the title_search field with sanitized titles
|
// Update the title_search field with sanitized titles
|
||||||
DB::table('episodes')->update([
|
DB::table('episodes')->update([
|
||||||
'title_search' => DB::raw("REGEXP_REPLACE(title, '[^A-Za-z0-9 ]', '')")
|
'title_search' => DB::raw("REGEXP_REPLACE(title, '[^A-Za-z0-9 ]', '')"),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
use App\Models\Playlist;
|
use App\Models\Playlist;
|
||||||
use App\Models\PlaylistEpisode;
|
use App\Models\PlaylistEpisode;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\Downloads;
|
use App\Models\Downloads;
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
{
|
{
|
||||||
@@ -14,10 +13,10 @@ return new class extends Migration
|
|||||||
*/
|
*/
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
# Delete entries with "#" as URL
|
// Delete entries with "#" as URL
|
||||||
Downloads::where('url', '#')->delete();
|
Downloads::where('url', '#')->delete();
|
||||||
|
|
||||||
# Remove duplicate entries
|
// Remove duplicate entries
|
||||||
$duplicates = DB::table('downloads')
|
$duplicates = DB::table('downloads')
|
||||||
->select('episode_id', 'type', DB::raw('COUNT(*) as count'))
|
->select('episode_id', 'type', DB::raw('COUNT(*) as count'))
|
||||||
->groupBy('episode_id', 'type')
|
->groupBy('episode_id', 'type')
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ return new class extends Migration
|
|||||||
$table->rememberToken()->after('password');
|
$table->rememberToken()->after('password');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
* Fix Discord Profile Pictures
|
* Fix Discord Profile Pictures
|
||||||
@@ -54,8 +53,7 @@ return new class extends Migration
|
|||||||
* The oauth package by socialite now returns a full url of the avatar.
|
* The oauth package by socialite now returns a full url of the avatar.
|
||||||
* Meaning all the old entries have to be fixed.
|
* Meaning all the old entries have to be fixed.
|
||||||
*/
|
*/
|
||||||
foreach (User::whereNotNull('discord_avatar')->get() as $user)
|
foreach (User::whereNotNull('discord_avatar')->get() as $user) {
|
||||||
{
|
|
||||||
$isGif = preg_match('/a_.+/m', $user->discord_avatar) === 1;
|
$isGif = preg_match('/a_.+/m', $user->discord_avatar) === 1;
|
||||||
$extension = $isGif ? 'gif' : 'webp';
|
$extension = $isGif ? 'gif' : 'webp';
|
||||||
$user->discord_avatar = sprintf('https://cdn.discordapp.com/avatars/%s/%s.%s', $user->id, $user->discord_avatar, $extension);
|
$user->discord_avatar = sprintf('https://cdn.discordapp.com/avatars/%s/%s.%s', $user->id, $user->discord_avatar, $extension);
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
use App\Models\Playlist;
|
use App\Models\Playlist;
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
{
|
{
|
||||||
@@ -150,7 +150,7 @@ return new class extends Migration
|
|||||||
$playlists = Playlist::where('user_id', '>', 1_000_000)
|
$playlists = Playlist::where('user_id', '>', 1_000_000)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
foreach($playlists as $playlist) {
|
foreach ($playlists as $playlist) {
|
||||||
DB::table('playlist_episodes')
|
DB::table('playlist_episodes')
|
||||||
->where('playlist_id', '=', $playlist->id)
|
->where('playlist_id', '=', $playlist->id)
|
||||||
->delete();
|
->delete();
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ return new class extends Migration
|
|||||||
// Re-Add foreign key constraint and index
|
// Re-Add foreign key constraint and index
|
||||||
Schema::table('comments', function (Blueprint $table) {
|
Schema::table('comments', function (Blueprint $table) {
|
||||||
$table->foreign('child_id')->references('id')->on('comments')->onDelete('cascade');
|
$table->foreign('child_id')->references('id')->on('comments')->onDelete('cascade');
|
||||||
$table->index(["commenter_id", "commenter_type"]);
|
$table->index(['commenter_id', 'commenter_type']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,17 +14,17 @@ return new class extends Migration
|
|||||||
{
|
{
|
||||||
// Migrate supporters
|
// Migrate supporters
|
||||||
DB::table('users')->where('is_patreon', 1)->update([
|
DB::table('users')->where('is_patreon', 1)->update([
|
||||||
'roles' => DB::raw("JSON_ARRAY('supporter')")
|
'roles' => DB::raw("JSON_ARRAY('supporter')"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Migrate banned
|
// Migrate banned
|
||||||
DB::table('users')->where('is_banned', 1)->update([
|
DB::table('users')->where('is_banned', 1)->update([
|
||||||
'roles' => DB::raw("JSON_ARRAY('banned')")
|
'roles' => DB::raw("JSON_ARRAY('banned')"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Migrate admins
|
// Migrate admins
|
||||||
DB::table('users')->where('is_admin', 1)->update([
|
DB::table('users')->where('is_admin', 1)->update([
|
||||||
'roles' => DB::raw("JSON_ARRAY('admin')")
|
'roles' => DB::raw("JSON_ARRAY('admin')"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Drop columns
|
// Drop columns
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class DatabaseSeeder extends Seeder
|
|||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
$this->call([
|
$this->call([
|
||||||
DeletedUserSeeder::class
|
DeletedUserSeeder::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,9 @@
|
|||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
|
||||||
use Illuminate\Database\Seeder;
|
|
||||||
|
|
||||||
|
|
||||||
class DeletedUserSeeder extends Seeder
|
class DeletedUserSeeder extends Seeder
|
||||||
{
|
{
|
||||||
@@ -18,7 +16,7 @@ class DeletedUserSeeder extends Seeder
|
|||||||
{
|
{
|
||||||
$userexists = User::where('id', '=', 1)->first();
|
$userexists = User::where('id', '=', 1)->first();
|
||||||
|
|
||||||
if (!$userexists) {
|
if (! $userexists) {
|
||||||
DB::table('users')->insert([
|
DB::table('users')->insert([
|
||||||
'id' => 1,
|
'id' => 1,
|
||||||
'username' => 'deleted',
|
'username' => 'deleted',
|
||||||
|
|||||||
@@ -1,130 +1,101 @@
|
|||||||
<div class="py-3 relative">
|
<div>
|
||||||
<div class="mx-auto sm:px-6 lg:px-8 space-y-6 max-w-[100%] lg:max-w-[90%] xl:max-w-[80%] 2xl:max-w-[90%] relative z-10">
|
<div class="mx-auto max-w-5xl px-4 space-y-6">
|
||||||
<!-- Search Filter -->
|
|
||||||
<div class="p-4 sm:p-8 bg-white/30 dark:bg-neutral-950/40 shadow sm:rounded-lg backdrop-blur relative z-100">
|
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 ">
|
|
||||||
|
|
||||||
<!-- Title -->
|
<!-- Filters -->
|
||||||
<div>
|
<div class="p-4 bg-white/40 dark:bg-neutral-950/40 backdrop-blur rounded-xl shadow flex flex-col sm:flex-row gap-3">
|
||||||
<label for="live-search"
|
|
||||||
class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Search</label>
|
|
||||||
<div class="relative right-2 left-0 sm:left-2 transition-all">
|
|
||||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
|
||||||
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true"
|
|
||||||
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
|
|
||||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
|
||||||
stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input wire:model.live.debounce.600ms="commentSearch" type="search" id="live-search"
|
<!-- Search -->
|
||||||
class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900"
|
<div class="relative flex-1">
|
||||||
placeholder="Search comment..." required>
|
<input
|
||||||
|
wire:model.live.debounce.500ms="commentSearch"
|
||||||
<div class="absolute right-0 top-[11px]" wire:loading>
|
type="search"
|
||||||
<svg aria-hidden="true"
|
placeholder="Search comments..."
|
||||||
class="inline w-8 h-8 mr-2 text-gray-200 animate-spin dark:text-gray-600 fill-pink-600"
|
class="w-full pl-10 pr-4 py-3 rounded-lg border-neutral-300 dark:text-neutral-300 bg-white/80 dark:bg-neutral-900/50 dark:border-neutral-700 focus:outline-none focus:ring-2 focus:ring-rose-600 focus:border-rose-700 transition"
|
||||||
viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
>
|
||||||
<path
|
<div class="pointer-events-none absolute inset-y-0 left-0 pl-3 flex items-center">
|
||||||
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
|
<svg class="w-4 h-4 text-gray-400 dark:text-gray-300" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
|
||||||
fill="currentColor" />
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"/>
|
||||||
<path
|
|
||||||
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
|
|
||||||
fill="currentFill" />
|
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Ordering -->
|
<!-- Order -->
|
||||||
<div>
|
<select
|
||||||
<div class="relative right-2 left-0 sm:left-2 transition-all">
|
wire:model.live="order"
|
||||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
class="px-4 py-3 rounded-lg border-neutral-300 dark:text-gray-300 bg-white/80 dark:bg-neutral-900/50 dark:border-neutral-700 min-w-[128px]"
|
||||||
<i class="fa-solid fa-sort text-gray-500 dark:text-gray-400"></i>
|
>
|
||||||
</div>
|
<option value="created_at_desc">Newest</option>
|
||||||
<select wire:model.live="order"
|
<option value="created_at_asc">Oldest</option>
|
||||||
class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900">
|
|
||||||
<option value="created_at_desc">Created DESC</option>
|
|
||||||
<option value="created_at_asc">Created ASC</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="relative pt-5 mx-auto sm:px-6 lg:px-8 space-y-6 text-gray-900 dark:text-white max-w-[100%] lg:max-w-[90%] xl:max-w-[80%] 2xl:max-w-[90%] 2xl:w-[50vw]">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<div class="overflow-x-auto sm:-mx-6 lg:-mx-8">
|
|
||||||
<div class="inline-block min-w-full py-2 sm:px-6 lg:px-8">
|
|
||||||
<div class="overflow-hidden">
|
|
||||||
|
|
||||||
<!-- Desktop -->
|
<!-- Comments -->
|
||||||
<div class="w-full text-left text-sm font-light">
|
<div class="space-y-4">
|
||||||
<!-- Header -->
|
@forelse ($comments as $comment)
|
||||||
<div
|
|
||||||
class="flex bg-white/30 dark:bg-neutral-950/40 backdrop-blur font-medium dark:border-neutral-500 border-b rounded-tl-lg rounded-tr-lg">
|
|
||||||
|
|
||||||
<div class="flex-1 px-6 py-4 text-center">Comment</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Rows -->
|
|
||||||
@foreach ($comments as $comment)
|
|
||||||
<div wire:key="comment-{{ $comment->id }}"
|
|
||||||
class="flex flex-col sm:flex-row items-center border-b bg-white dark:bg-neutral-950 dark:border-zinc-700 hover:bg-zinc-100 dark:hover:bg-neutral-800">
|
|
||||||
|
|
||||||
<!-- Image -->
|
|
||||||
<div class="flex w-fit sm:w-56">
|
|
||||||
@if($comment->commentable_type == \App\Models\Episode::class)
|
|
||||||
@php $episode = \App\Models\Episode::find($comment->commentable_id); @endphp
|
|
||||||
<div class="relative p-1 w-full transition duration-300 ease-in-out md:p-2 md:hover:-translate-y-1 md:hover:scale-110">
|
|
||||||
<a href="{{ route('hentai.index', ['title' => $episode->slug]) }}">
|
|
||||||
<img alt="{{ $episode->title }} - {{ $episode->episode }}" loading="lazy" width="1000"
|
|
||||||
class="block object-cover object-center relative z-20 rounded-lg aspect-video"
|
|
||||||
src="{{ $episode->gallery->first()->thumbnail_url }}" />
|
|
||||||
|
|
||||||
<p class="absolute left-1 md:left-2 bottom-1 md:bottom-2 bg-rose-700/70 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
|
||||||
<i class="fa-regular fa-eye"></i> {{ $episode->viewCountFormatted() }}
|
|
||||||
<i class="fa-regular fa-heart"></i> {{ $episode->likeCount() }}
|
|
||||||
<i class="fa-regular fa-comment"></i> {{ $episode->commentCount() }}
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
@elseif($comment->commentable_type == \App\Models\Hentai::class)
|
|
||||||
@php
|
@php
|
||||||
$hentai = \App\Models\Hentai::find($comment->commentable_id);
|
$model = $comment->commentable;
|
||||||
$episode = $hentai->episodes->first();
|
$episode = $model instanceof \App\Models\Episode
|
||||||
|
? $model
|
||||||
|
: $model->episodes->first();
|
||||||
|
|
||||||
|
$url = route('hentai.index', ['title' => $model->slug]);
|
||||||
@endphp
|
@endphp
|
||||||
<div class="relative p-1 w-full transition duration-300 ease-in-out md:p-2 md:hover:-translate-y-1 md:hover:scale-110">
|
|
||||||
<a href="{{ route('hentai.index', ['title' => $hentai->slug]) }}">
|
|
||||||
<img alt="{{ $episode->title }}" loading="lazy" width="1000"
|
|
||||||
class="block object-cover object-center relative z-20 rounded-lg aspect-video"
|
|
||||||
src="{{ $episode->gallery->first()->thumbnail_url }}" />
|
|
||||||
|
|
||||||
|
<a href="{{ $url }}#comment-{{ $comment->id }}"
|
||||||
|
wire:key="comment-{{ $comment->id }}"
|
||||||
|
class="block group">
|
||||||
|
|
||||||
</a>
|
<div class="bg-white/40 dark:bg-neutral-950/40 backdrop-blur rounded-xl shadow hover:shadow-lg transition overflow-hidden">
|
||||||
</div>
|
|
||||||
@endif
|
<div class="flex flex-col sm:flex-row">
|
||||||
|
|
||||||
|
<!-- Thumbnail -->
|
||||||
|
<div class="sm:w-48 shrink-0">
|
||||||
|
<img
|
||||||
|
src="{{ $episode->gallery->first()->thumbnail_url }}"
|
||||||
|
alt=""
|
||||||
|
class="w-full h-40 sm:h-full object-cover"
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Body -->
|
<!-- Content -->
|
||||||
<div class="flex text-lg flex-1 items-center space-x-2 px-3 py-2 bg-neutral-200 dark:bg-neutral-900 h-[115px] rounded-lg sm:mr-2">
|
<div class="flex-1 p-4 flex flex-col justify-between">
|
||||||
|
|
||||||
|
<!-- Comment -->
|
||||||
|
<div class="text-gray-800 dark:text-gray-200 text-sm line-clamp-3">
|
||||||
{!! $comment->presenter()->markdownBody() !!}
|
{!! $comment->presenter()->markdownBody() !!}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-x-2 sm:mr-2 w-24">
|
<!-- Meta -->
|
||||||
<span class="text-gray-500 dark:text-gray-300 font-medium">
|
<div class="flex items-center justify-between mt-3 text-xs text-gray-700 dark:text-gray-400">
|
||||||
|
|
||||||
|
<span>
|
||||||
{{ $comment->presenter()->relativeCreatedAt() }}
|
{{ $comment->presenter()->relativeCreatedAt() }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<span class="text-rose-600 font-medium group-hover:underline">
|
||||||
|
View comment
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</a>
|
||||||
|
@empty
|
||||||
|
<div class="flex bg-white/40 dark:bg-neutral-950/40 backdrop-blur rounded-xl shadow hover:shadow-lg transition overflow-hidden">
|
||||||
|
<div class="text-gray-800 dark:text-gray-200 text-center w-full p-4">
|
||||||
|
<p class="text-lg">No results</p>
|
||||||
|
<p class="text-sm opacity-70">(╥﹏╥)</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@endforelse
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Pagination -->
|
||||||
|
<div>
|
||||||
{{ $comments->links('pagination::tailwind') }}
|
{{ $comments->links('pagination::tailwind') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="scroll-smooth">
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="scroll-smooth">
|
||||||
@include('partials.head')
|
@include('partials.head')
|
||||||
|
|
||||||
<body class="font-sans antialiased">
|
<body class="font-sans antialiased">
|
||||||
<div class="flex flex-col min-h-screen bg-gray-100 dark:bg-neutral-900">
|
<div class="flex flex-col min-h-screen bg-gray-100 dark:bg-neutral-900">
|
||||||
@include('layouts.navigation')
|
@include('layouts.navigation')
|
||||||
@@ -9,13 +8,11 @@
|
|||||||
<main>
|
<main>
|
||||||
@include('user.partials.background')
|
@include('user.partials.background')
|
||||||
<div
|
<div
|
||||||
class="relative max-w-[120rem] mx-auto sm:px-6 lg:px-8 space-y-6 pt-20 mt-[65px] flex flex-row justify-center xl:justify-normal">
|
class="relative max-w-[120rem] mx-auto sm:px-6 lg:px-8 space-y-6 pt-20 mt-[65px] flex flex-row justify-center md:justify-normal">
|
||||||
<div class="flex flex-col xl:flex-row">
|
<div class="grid md:grid-flow-col gap-4 xl:w-5/6 flex-row">
|
||||||
@include('profile.partials.sidebar')
|
@include('profile.partials.sidebar')
|
||||||
<div class="pb-2 space-y-6 max-w-7xl px-0 md:px-6 lg:px-8 pt-8 xl:pt-0 flex flex-row">
|
<div class="flex flex-col gap-2">
|
||||||
|
|
||||||
<livewire:user-comments :model="$user"/>
|
<livewire:user-comments :model="$user"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -23,5 +20,4 @@
|
|||||||
@include('layouts.footer')
|
@include('layouts.footer')
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -2,66 +2,65 @@
|
|||||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="scroll-smooth">
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="scroll-smooth">
|
||||||
@include('partials.head')
|
@include('partials.head')
|
||||||
<body class="font-sans antialiased">
|
<body class="font-sans antialiased">
|
||||||
<div class="flex flex-col min-h-screen bg-gray-100 dark:bg-neutral-900">
|
<div class="flex flex-col min-h-screen bg-gray-100 dark:bg-neutral-900">
|
||||||
@include('layouts.navigation')
|
@include('layouts.navigation')
|
||||||
<!-- Page Content -->
|
<!-- Page Content -->
|
||||||
<main>
|
<main>
|
||||||
@include('user.partials.background')
|
@include('user.partials.background')
|
||||||
<div class="relative max-w-[120rem] mx-auto sm:px-6 lg:px-8 space-y-6 pt-20 mt-[65px] flex flex-row justify-center md:justify-normal">
|
<div
|
||||||
<div class="grid md:grid-flow-col gap-4 w-5/6 flex-row">
|
class="relative max-w-[120rem] mx-auto sm:px-6 lg:px-8 space-y-6 pt-20 mt-[65px] flex flex-row justify-center md:justify-normal">
|
||||||
|
<div class="grid md:grid-flow-col gap-4 xl:w-5/6 flex-row">
|
||||||
@include('profile.partials.sidebar')
|
@include('profile.partials.sidebar')
|
||||||
<div class="md:col-span-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div class="relative overflow-x-auto rounded-lg w-full">
|
|
||||||
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-white">
|
|
||||||
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-pink-700 dark:text-neutral-200">
|
|
||||||
<tr>
|
|
||||||
<th class="px-6 py-3">Type</th>
|
|
||||||
<th class="px-6 py-3">Message</th>
|
|
||||||
<th class="px-6 py-3">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@forelse($notifications as $notification)
|
@forelse($notifications as $notification)
|
||||||
<tr class="bg-white border-t dark:bg-neutral-950/40 backdrop-blur dark:highlight-white/5 dark:border-pink-700">
|
<div
|
||||||
<td class="px-6 py-4">
|
class="bg-white/40 dark:bg-neutral-950/40 backdrop-blur border border-gray-200 dark:border-neutral-700 rounded-xl shadow-sm p-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-x-4 transition hover:shadow-md">
|
||||||
{{ $notification->data['type'] ?? '' }}
|
|
||||||
</td>
|
<!-- Content -->
|
||||||
<td class="px-6 py-4">
|
<div class="flex flex-col gap-2 w-full h-full mt-2">
|
||||||
|
<div class="flex items-center justify-between flex-none h-2">
|
||||||
|
<span class="text-xs font-semibold uppercase tracking-wide text-sky-600 dark:text-rose-500">
|
||||||
|
{{ $notification->data['type'] ?? 'Notification' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="text-sm sm:text-base text-gray-700 dark:text-gray-300 leading-relaxed h-full">
|
||||||
{{ $notification->data['message'] ?? '' }}
|
{{ $notification->data['message'] ?? '' }}
|
||||||
</td>
|
</p>
|
||||||
<td class="px-6 py-4 flex gap-4">
|
</div>
|
||||||
<a href="{{ $notification->data['url'] }}" class="inline-block rounded bg-sky-600 pl-[4px] pr-[4px] p-[1px] text-xs font-medium uppercase leading-normal text-white transition duration-150 ease-in-out hover:bg-sky-700 focus:bg-sky-600">
|
|
||||||
|
<!-- Actions -->
|
||||||
|
<div class="flex gap-2 sm:gap-2 shrink-0">
|
||||||
|
<a href="{{ $notification->data['url'] }}"
|
||||||
|
class="text-center rounded-lg bg-sky-600 px-3 py-2 text-xs sm:text-sm font-medium text-white hover:bg-sky-700 transition">
|
||||||
Open
|
Open
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<form method="POST" action="{{ route('profile.notifications.delete') }}">
|
<form method="POST" action="{{ route('profile.notifications.delete') }}">
|
||||||
@csrf
|
@csrf
|
||||||
@method('delete')
|
@method('delete')
|
||||||
<input type="hidden" value="{{ $notification->id }}" name="id">
|
<input type="hidden" value="{{ $notification->id }}" name="id">
|
||||||
<button type="submit" class="inline-block rounded bg-rose-600 pl-[4px] pr-[4px] p-[1px] text-xs font-medium uppercase leading-normal text-white transition duration-150 ease-in-out hover:bg-rose-700 focus:bg-rose-600">
|
|
||||||
|
<button type="submit"
|
||||||
|
class="w-full rounded-lg bg-rose-600 px-3 py-2 text-xs sm:text-sm font-medium text-white hover:bg-rose-700 transition">
|
||||||
Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@empty
|
|
||||||
<tr class="bg-white border-t dark:bg-neutral-950/40 backdrop-blur dark:highlight-white/5 dark:border-pink-700">
|
|
||||||
<td class="px-6 py-4">
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4">
|
|
||||||
No entries (╥﹏╥)
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4">
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforelse
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
@empty
|
||||||
|
<div class="text-center py-16 text-gray-500 dark:text-gray-400">
|
||||||
|
<p class="text-lg">No notifications</p>
|
||||||
|
<p class="text-sm opacity-70">(╥﹏╥)</p>
|
||||||
|
</div>
|
||||||
|
@endforelse
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
@include('layouts.footer')
|
@include('layouts.footer')
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+3
-3
@@ -1,13 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Http\Controllers\Admin\AlertController;
|
use App\Http\Controllers\Admin\AlertController;
|
||||||
use App\Http\Controllers\Admin\ContactController;
|
|
||||||
use App\Http\Controllers\Admin\CommentsController;
|
use App\Http\Controllers\Admin\CommentsController;
|
||||||
|
use App\Http\Controllers\Admin\ContactController;
|
||||||
use App\Http\Controllers\Admin\EpisodeController;
|
use App\Http\Controllers\Admin\EpisodeController;
|
||||||
use App\Http\Controllers\Admin\ReleaseController;
|
use App\Http\Controllers\Admin\ReleaseController;
|
||||||
use App\Http\Controllers\Admin\UserController;
|
|
||||||
use App\Http\Controllers\Admin\SubtitleController;
|
|
||||||
use App\Http\Controllers\Admin\SiteBackgroundController;
|
use App\Http\Controllers\Admin\SiteBackgroundController;
|
||||||
|
use App\Http\Controllers\Admin\SubtitleController;
|
||||||
|
use App\Http\Controllers\Admin\UserController;
|
||||||
use App\Http\Controllers\Api\AdminApiController;
|
use App\Http\Controllers\Api\AdminApiController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user