Compare commits
15 Commits
laravel-12
...
2480c5b309
| Author | SHA1 | Date | |
|---|---|---|---|
| 2480c5b309 | |||
| 4fc11d7329 | |||
| f3e5100d5d | |||
| 5b4d3d435e | |||
| 564f816fb9 | |||
| 3709e378c3 | |||
| 4a45dae593 | |||
| 2b0448d517 | |||
| 3bb6af73c3 | |||
| 57cf153560 | |||
| e45fd4b148 | |||
|
d479369770
|
|||
| b8ba17b33f | |||
| 5a8dd12cb8 | |||
| 3a77c4320d |
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
## hstream Website
|
## hstream Website
|
||||||
|
|
||||||
### Install
|
### Install (Ubuntu)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install PHP
|
# Install PHP
|
||||||
sudo add-apt-repository ppa:ondrej/php
|
sudo add-apt-repository ppa:ondrej/php
|
||||||
apt update && apt upgrade
|
apt update && apt upgrade
|
||||||
apt install php8.3 php8.3-xml php8.3-mysql php8.3-gd php8.3-zip php8.3-curl php8.3-mbstring
|
apt install php8.4 php8.4-xml php8.4-mysql php8.4-gd php8.4-zip php8.4-curl php8.4-mbstring
|
||||||
|
|
||||||
# Install NodeJS
|
# Install NodeJS
|
||||||
curl -sL https://deb.nodesource.com/setup_20.x -o /tmp/nodesource_setup.sh
|
curl -sL https://deb.nodesource.com/setup_20.x -o /tmp/nodesource_setup.sh
|
||||||
@@ -22,7 +22,7 @@ mv composer.phar composer
|
|||||||
|
|
||||||
# Install NGINX (skip for local dev)
|
# Install NGINX (skip for local dev)
|
||||||
apt install nginx
|
apt install nginx
|
||||||
apt install php8.3-fpm
|
apt install php8.4-fpm
|
||||||
|
|
||||||
# Install MariaDB
|
# Install MariaDB
|
||||||
apt install mariadb-server
|
apt install mariadb-server
|
||||||
@@ -54,7 +54,7 @@ nano /etc/supervisor/conf.d/laravel-queue.conf :
|
|||||||
|
|
||||||
[program:laravel-queue]
|
[program:laravel-queue]
|
||||||
process_name=%(program_name)s_%(process_num)02d
|
process_name=%(program_name)s_%(process_num)02d
|
||||||
command=php /var/www/hstream/artisan queue:work --queue=default --sleep=3 --tries=3 --max-time=3600
|
command=php84 /var/www/hstream/artisan queue:work --queue=default --sleep=3 --tries=3 --max-time=3600
|
||||||
autostart=true
|
autostart=true
|
||||||
autorestart=true
|
autorestart=true
|
||||||
stopasgroup=true
|
stopasgroup=true
|
||||||
@@ -83,9 +83,9 @@ zip -r hstream_2023_11_30.zip hstream/
|
|||||||
|
|
||||||
### Update
|
### Update
|
||||||
```bash
|
```bash
|
||||||
php artisan down
|
php84 artisan down
|
||||||
git pull
|
git pull
|
||||||
npm run build
|
npm run build
|
||||||
php artisan view:clear && php artisan optimize:clear && php artisan cache:clear && service php8.4-fpm restart
|
php84 artisan view:clear && php84 artisan optimize:clear && php84 artisan cache:clear && service php8.4-fpm restart
|
||||||
php artisan up
|
php84 artisan up
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
+17
-16
@@ -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,7 +64,8 @@ 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')
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
@@ -44,7 +42,7 @@ 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),
|
||||||
]
|
]
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -55,13 +53,14 @@ class SiteBackgroundController extends Controller
|
|||||||
|
|
||||||
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),
|
||||||
]
|
]
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -116,6 +115,7 @@ class SiteBackgroundController extends Controller
|
|||||||
} 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
|
||||||
|
|||||||
@@ -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']) {
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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;
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,6 +113,7 @@ class DiscordAuthController extends Controller
|
|||||||
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()
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\MatrixRegisterRequest;
|
||||||
|
use App\Services\MatrixRegistrationService;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class MatrixController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display the user page.
|
||||||
|
*/
|
||||||
|
public function index(Request $request): \Illuminate\View\View
|
||||||
|
{
|
||||||
|
$rooms = [
|
||||||
|
['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' => '👗 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'],
|
||||||
|
];
|
||||||
|
|
||||||
|
return view('matrix.index', [
|
||||||
|
'user' => $request->user(),
|
||||||
|
'rooms' => $rooms,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create matrix user
|
||||||
|
*/
|
||||||
|
public function store(
|
||||||
|
MatrixRegisterRequest $request,
|
||||||
|
MatrixRegistrationService $matrixService
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
$result = $matrixService->registerUser(
|
||||||
|
$request->username,
|
||||||
|
$request->password
|
||||||
|
);
|
||||||
|
|
||||||
|
$user = $request->user();
|
||||||
|
$user->matrix_id = $result['user_id'];
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
return redirect()
|
||||||
|
->back()
|
||||||
|
->with('success', 'Matrix user created successfully.');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return back()
|
||||||
|
->withErrors([
|
||||||
|
'username' => $e->getMessage(),
|
||||||
|
])
|
||||||
|
->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
|
||||||
{
|
{
|
||||||
@@ -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', [
|
||||||
@@ -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';
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -121,6 +119,7 @@ class ProfileController extends Controller
|
|||||||
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');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class MatrixRegisterRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
$isOldEnough = $this->user()->created_at->lt(now()->subMonth());
|
||||||
|
$noAccount = ! $this->user()->matrix_id;
|
||||||
|
|
||||||
|
return $isOldEnough && $noAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'username' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'min:3',
|
||||||
|
'max:32',
|
||||||
|
'regex:/^[a-z0-9._=-]+$/', // Valid Matrix localpart
|
||||||
|
],
|
||||||
|
'password' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'min:8',
|
||||||
|
'confirmed',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function messages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'username.regex' => 'Username may only contain lowercase letters, numbers and . _ = -',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
@@ -37,6 +37,7 @@ class GetFileSizeFromCDN implements ShouldQueue
|
|||||||
$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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-16
@@ -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,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +75,8 @@ 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,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,15 @@ class DownloadButton extends Component
|
|||||||
|
|
||||||
public $background = 'bg-rose-600';
|
public $background = 'bg-rose-600';
|
||||||
|
|
||||||
|
public $fileExtension = 'HEVC';
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
if (str_contains($this->downloadUrl, 'AV1')) {
|
||||||
|
$this->fileExtension = 'AV1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function clicked($downloadId)
|
public function clicked($downloadId)
|
||||||
{
|
{
|
||||||
$download = Downloads::find($downloadId);
|
$download = Downloads::find($downloadId);
|
||||||
|
|||||||
@@ -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,6 +25,7 @@ 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
|
||||||
@@ -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)]
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
@@ -59,7 +58,7 @@ class Playlists extends Component
|
|||||||
->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)]
|
||||||
@@ -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()
|
||||||
|
|||||||
+13
-18
@@ -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,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -180,6 +173,7 @@ class Episode extends Model implements Sitemapable
|
|||||||
|
|
||||||
$problematicResults .= $pTag;
|
$problematicResults .= $pTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $problematicResults;
|
return $problematicResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,9 +228,10 @@ 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();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,7 +15,7 @@ class SiteBackground extends Model
|
|||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'date_start',
|
'date_start',
|
||||||
'date_end',
|
'date_end',
|
||||||
'default'
|
'default',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-8
@@ -5,13 +5,12 @@ 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.
|
||||||
*/
|
*/
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,17 +5,13 @@ 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;
|
||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
|
|
||||||
|
class MatrixRegistrationService
|
||||||
|
{
|
||||||
|
public function registerUser(string $username, string $password)
|
||||||
|
{
|
||||||
|
$server = config('services.matrix.server');
|
||||||
|
$secret = config('services.matrix.shared_secret');
|
||||||
|
|
||||||
|
// Get nonce from Synapse
|
||||||
|
$nonceResponse = Http::get("$server/_synapse/admin/v1/register");
|
||||||
|
|
||||||
|
if (! $nonceResponse->ok()) {
|
||||||
|
throw new \Exception('Could not fetch nonce from Matrix.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$nonce = $nonceResponse->json()['nonce'];
|
||||||
|
|
||||||
|
// Generate MAC
|
||||||
|
$mac = hash_hmac(
|
||||||
|
'sha1',
|
||||||
|
$nonce."\0".
|
||||||
|
$username."\0".
|
||||||
|
$password."\0".
|
||||||
|
'notadmin',
|
||||||
|
$secret
|
||||||
|
);
|
||||||
|
|
||||||
|
// Send registration request
|
||||||
|
$response = Http::post("$server/_synapse/admin/v1/register", [
|
||||||
|
'nonce' => $nonce,
|
||||||
|
'username' => $username,
|
||||||
|
'password' => $password,
|
||||||
|
'admin' => false,
|
||||||
|
'mac' => $mac,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($response->failed()) {
|
||||||
|
$error = $response->json()['error'] ?? $response->body();
|
||||||
|
throw new \Exception($error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response->json();
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+8
-8
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "2e359f5cfd56c822e336b74becc9c9d9",
|
"content-hash": "3400111a6254560d548639295422875c",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "altcha-org/altcha",
|
"name": "altcha-org/altcha",
|
||||||
@@ -3036,16 +3036,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "livewire/livewire",
|
"name": "livewire/livewire",
|
||||||
"version": "v3.7.3",
|
"version": "v3.7.10",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/livewire/livewire.git",
|
"url": "https://github.com/livewire/livewire.git",
|
||||||
"reference": "a5384df9fbd3eaf02e053bc49aabc8ace293fc1c"
|
"reference": "0dc679eb4c8b4470cb12522b5927ef08ca2358bb"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/livewire/livewire/zipball/a5384df9fbd3eaf02e053bc49aabc8ace293fc1c",
|
"url": "https://api.github.com/repos/livewire/livewire/zipball/0dc679eb4c8b4470cb12522b5927ef08ca2358bb",
|
||||||
"reference": "a5384df9fbd3eaf02e053bc49aabc8ace293fc1c",
|
"reference": "0dc679eb4c8b4470cb12522b5927ef08ca2358bb",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -3100,7 +3100,7 @@
|
|||||||
"description": "A front-end framework for Laravel.",
|
"description": "A front-end framework for Laravel.",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/livewire/livewire/issues",
|
"issues": "https://github.com/livewire/livewire/issues",
|
||||||
"source": "https://github.com/livewire/livewire/tree/v3.7.3"
|
"source": "https://github.com/livewire/livewire/tree/v3.7.10"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -3108,7 +3108,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-12-19T02:00:29+00:00"
|
"time": "2026-02-09T22:49:33+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "maize-tech/laravel-markable",
|
"name": "maize-tech/laravel-markable",
|
||||||
@@ -11584,5 +11584,5 @@
|
|||||||
"php": "^8.2"
|
"php": "^8.2"
|
||||||
},
|
},
|
||||||
"platform-dev": {},
|
"platform-dev": {},
|
||||||
"plugin-api-version": "2.9.0"
|
"plugin-api-version": "2.6.0"
|
||||||
}
|
}
|
||||||
|
|||||||
+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',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|||||||
+7
-1
@@ -47,5 +47,11 @@ return [
|
|||||||
'avatar_default_extension' => env('DISCORD_EXTENSION_DEFAULT', 'webp'), // only pick from jpg, png, webp
|
'avatar_default_extension' => env('DISCORD_EXTENSION_DEFAULT', 'webp'), // only pick from jpg, png, webp
|
||||||
],
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matrix Registration
|
||||||
|
*/
|
||||||
|
'matrix' => [
|
||||||
|
'server' => env('MATRIX_SERVER'),
|
||||||
|
'shared_secret' => env('MATRIX_SHARED_SECRET'),
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ return new class extends Migration
|
|||||||
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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->string('matrix_id')
|
||||||
|
->nullable()
|
||||||
|
->after('discord_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('matrix_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
Generated
+6
-5
@@ -4,6 +4,7 @@
|
|||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
|
"name": "hstream",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
"@fortawesome/fontawesome-free": "^6.5.1",
|
||||||
"@jellyfin/libass-wasm": "^4.1.1",
|
"@jellyfin/libass-wasm": "^4.1.1",
|
||||||
@@ -1263,14 +1264,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.13.2",
|
"version": "1.13.5",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
|
||||||
"integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
|
"integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.6",
|
"follow-redirects": "^1.15.11",
|
||||||
"form-data": "^4.0.4",
|
"form-data": "^4.0.5",
|
||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -49,6 +49,22 @@
|
|||||||
<i class="fa-brands fa-discord"></i> {{ __('nav.our-discord-server') }}
|
<i class="fa-brands fa-discord"></i> {{ __('nav.our-discord-server') }}
|
||||||
</x-dropdown-link>
|
</x-dropdown-link>
|
||||||
|
|
||||||
|
<x-dropdown-link :href="route('join.matrix')">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||||
|
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
class="icon icon-tabler icons-tabler-outline icon-tabler-brand-matrix pr-1">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
<path d="M4 3h-1v18h1" />
|
||||||
|
<path d="M20 21h1v-18h-1" />
|
||||||
|
<path d="M7 9v6" />
|
||||||
|
<path d="M12 15v-3.5a2.5 2.5 0 1 0 -5 0v.5" />
|
||||||
|
<path d="M17 15v-3.5a2.5 2.5 0 1 0 -5 0v.5" />
|
||||||
|
</svg>
|
||||||
|
Join our Matrix
|
||||||
|
</div>
|
||||||
|
</x-dropdown-link>
|
||||||
|
|
||||||
<x-dropdown-link>
|
<x-dropdown-link>
|
||||||
<div class="grid grid-cols-2">
|
<div class="grid grid-cols-2">
|
||||||
<p class="cursor-default">{{ __('nav.theme') }}</p>
|
<p class="cursor-default">{{ __('nav.theme') }}</p>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
@else
|
@else
|
||||||
<p class="text-lg">Episode {{ $episodeNumber }}</p>
|
<p class="text-lg">Episode {{ $episodeNumber }}</p>
|
||||||
@endif
|
@endif
|
||||||
<p class="text-xs">HEVC MKV {{ $fileSize ?? '' }}</p>
|
<p class="text-xs">{{ $fileExtension }} MKV {{ $fileSize ?? '' }}</p>
|
||||||
<p class="text-xs" id="count-{{ $downloadId }}">Downloaded {{ $downloadCount }} times</p>
|
<p class="text-xs" id="count-{{ $downloadId }}">Downloaded {{ $downloadCount }} times</p>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -235,6 +235,11 @@
|
|||||||
'/' .
|
'/' .
|
||||||
$expire;
|
$expire;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$fileExtension = "HEVC";
|
||||||
|
if (str_contains($download->url, 'AV1')) {
|
||||||
|
$fileExtension = "AV1";
|
||||||
|
}
|
||||||
@endphp
|
@endphp
|
||||||
<a href="{{ $downloadURL }}" wire:click="clicked({{ $download->id }})"
|
<a href="{{ $downloadURL }}" wire:click="clicked({{ $download->id }})"
|
||||||
download>
|
download>
|
||||||
@@ -249,7 +254,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col text-center w-full">
|
<div class="flex flex-col text-center w-full">
|
||||||
<p class="text-xs">HEVC MKV</p>
|
<p class="text-xs">{{ $fileExtension }} MKV</p>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
<a href="{{ $dldomains[array_rand($dldomains)] }}/{{ $hdl->getDownloadByType('FHD')->url }}">
|
<a href="{{ $dldomains[array_rand($dldomains)] }}/{{ $hdl->getDownloadByType('FHD')->url }}">
|
||||||
|
@php
|
||||||
|
$fileExtension = "HEVC";
|
||||||
|
if (str_contains($hdl->getDownloadByType('FHD')->url, 'AV1')) {
|
||||||
|
$fileExtension = "AV1";
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
<button class="group rounded-md shadow bg-rose-600 text-white cursor-pointer flex justify-between items-center overflow-hidden transition-all hover:glow m-1 w-[150px]">
|
<button class="group rounded-md shadow bg-rose-600 text-white cursor-pointer flex justify-between items-center overflow-hidden transition-all hover:glow m-1 w-[150px]">
|
||||||
<div class="relative w-12 h-12 bg-white bg-opacity-20 text-white flex justify-center items-center transition-all"><svg id="arrow" class="w-4 h-4 transition-all group-hover:-translate-y-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
<div class="relative w-12 h-12 bg-white bg-opacity-20 text-white flex justify-center items-center transition-all"><svg id="arrow" class="w-4 h-4 transition-all group-hover:-translate-y-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path>
|
||||||
@@ -7,7 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="w-32 text-center">
|
<div class="w-32 text-center">
|
||||||
<p class="px-5 text-sm row-span-2">Episode {{ $hdl->episode }}</p>
|
<p class="px-5 text-sm row-span-2">Episode {{ $hdl->episode }}</p>
|
||||||
<p class="px-5 text-xs">HEVC MKV</p>
|
<p class="px-5 text-xs">{{ $fileExtension }} MKV</p>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -1,130 +1,101 @@
|
|||||||
<div class="py-3 relative">
|
|
||||||
<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">
|
|
||||||
<!-- 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 -->
|
|
||||||
<div>
|
<div>
|
||||||
<label for="live-search"
|
<div class="mx-auto max-w-5xl px-4 space-y-6">
|
||||||
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"
|
<!-- Filters -->
|
||||||
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="p-4 bg-white/40 dark:bg-neutral-950/40 backdrop-blur rounded-xl shadow flex flex-col sm:flex-row gap-3">
|
||||||
placeholder="Search comment..." required>
|
|
||||||
|
|
||||||
<div class="absolute right-0 top-[11px]" wire:loading>
|
<!-- Search -->
|
||||||
<svg aria-hidden="true"
|
<div class="relative flex-1">
|
||||||
class="inline w-8 h-8 mr-2 text-gray-200 animate-spin dark:text-gray-600 fill-pink-600"
|
<input
|
||||||
viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
wire:model.live.debounce.500ms="commentSearch"
|
||||||
<path
|
type="search"
|
||||||
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"
|
placeholder="Search comments..."
|
||||||
fill="currentColor" />
|
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"
|
||||||
<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"
|
<div class="pointer-events-none absolute inset-y-0 left-0 pl-3 flex items-center">
|
||||||
fill="currentFill" />
|
<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">
|
||||||
|
<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>
|
</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>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user