Compare commits
20 Commits
74cece07e1
...
main
Author | SHA1 | Date | |
---|---|---|---|
dca4924e9a | |||
9ad7c7afc2 | |||
6c8d34b030 | |||
35a0d61437 | |||
725a441d9e | |||
96a9019eba | |||
e2497867f0 | |||
a6c47cf2e6 | |||
fffa320c08 | |||
2880547f3e | |||
b5dbf24e91 | |||
43cf5db6c9 | |||
9e0042b09f | |||
e717b2bd07 | |||
bbbc4ac329 | |||
55739a21b5 | |||
bc193c7141 | |||
c0a22e875c | |||
4697073e9f | |||
9be33db14f |
@@ -8,7 +8,7 @@
|
||||
# Install PHP
|
||||
sudo add-apt-repository ppa:ondrej/php
|
||||
apt update && apt upgrade
|
||||
apt install php8.4 php8.4-xml php8.4-mysql php8.4-gd php8.4-zip php8.4-curl php8.4-mbstring
|
||||
apt install php8.3 php8.3-xml php8.3-mysql php8.3-gd php8.3-zip php8.3-curl php8.3-mbstring
|
||||
|
||||
# Install NodeJS
|
||||
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)
|
||||
apt install nginx
|
||||
apt install php8.4-fpm
|
||||
apt install php8.3-fpm
|
||||
|
||||
# Install MariaDB
|
||||
apt install mariadb-server
|
||||
|
@@ -60,13 +60,6 @@ class CacheHelper
|
||||
});
|
||||
}
|
||||
|
||||
public static function getTotalMonthlyViews()
|
||||
{
|
||||
return Cache::remember("total_monthly_view_count", now()->addMinutes(60), function () {
|
||||
return PopularMonthly::count();
|
||||
});
|
||||
}
|
||||
|
||||
public static function getPopularAllTime(bool $guest)
|
||||
{
|
||||
$guestString = $guest ? 'guest' : 'authed';
|
||||
|
19
app/Helpers/GitHelper.php
Normal file
19
app/Helpers/GitHelper.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class GitHelper
|
||||
{
|
||||
public static function shortCommit()
|
||||
{
|
||||
return Cache::remember("git_commit", now()->addMinutes(60), function () {
|
||||
try {
|
||||
return trim(exec('git rev-parse --short HEAD'));
|
||||
} catch (\Exception $e) {
|
||||
return 'unknown';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@@ -42,7 +42,11 @@ class EpisodeController extends Controller
|
||||
$this->galleryService->createOrUpdateGallery($request, $referenceEpisode->hentai, $episode, $episodeNumber, true);
|
||||
|
||||
// Discord Alert
|
||||
DiscordReleaseNotification::dispatch($episode->slug, 'release');
|
||||
if ($request->has('censored')) {
|
||||
DiscordReleaseNotification::dispatch($referenceEpisode->title." - ".$episodeNumber, 'release-censored');
|
||||
} else {
|
||||
DiscordReleaseNotification::dispatch($episode->slug, 'release');
|
||||
}
|
||||
|
||||
cache()->flush();
|
||||
|
||||
@@ -76,6 +80,10 @@ class EpisodeController extends Controller
|
||||
DiscordReleaseNotification::dispatch($episode->slug, 'updateUHD');
|
||||
}
|
||||
|
||||
if ($request->has('v2')) {
|
||||
DiscordReleaseNotification::dispatch($episode->slug, 'v2');
|
||||
}
|
||||
|
||||
cache()->flush();
|
||||
|
||||
return to_route('hentai.index', [
|
||||
|
@@ -72,9 +72,13 @@ class ReleaseController extends Controller
|
||||
$releasedEpisodes[] = $episode->slug;
|
||||
}
|
||||
|
||||
foreach ($releasedEpisodes as $slug) {
|
||||
// Dispatch Discord Alert
|
||||
DiscordReleaseNotification::dispatch($slug, 'release');
|
||||
if ($request->has('censored')) {
|
||||
DiscordReleaseNotification::dispatch($request->input('title'), 'release-censored');
|
||||
} else {
|
||||
foreach ($releasedEpisodes as $slug) {
|
||||
// Dispatch Discord Alert
|
||||
DiscordReleaseNotification::dispatch($slug, 'release');
|
||||
}
|
||||
}
|
||||
|
||||
cache()->flush();
|
||||
|
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Torrents;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TorrentController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display Add Torrent Page.
|
||||
*/
|
||||
public function index(int $hentai_id): \Illuminate\View\View
|
||||
{
|
||||
return view('admin.add-torrent', [
|
||||
'hentai_id' => $hentai_id
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Torrent.
|
||||
*/
|
||||
public function store(Request $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'hentai_id' => 'required|exists:hentais,id',
|
||||
'torrent_url' => 'required|string|max:256',
|
||||
'torrent_episodes' => 'required|string|max:8',
|
||||
]);
|
||||
|
||||
Torrents::create([
|
||||
'hentai_id' => $request->hentai_id,
|
||||
'torrent_url' => $request->torrent_url,
|
||||
'episodes' => $request->torrent_episodes,
|
||||
]);
|
||||
|
||||
return to_route('download.search');
|
||||
}
|
||||
}
|
56
app/Http/Controllers/Api/HentaiApiController.php
Normal file
56
app/Http/Controllers/Api/HentaiApiController.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\Hentai;
|
||||
use App\Models\PopularMonthly;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class HentaiApiController extends Controller
|
||||
{
|
||||
/**
|
||||
* Get a list of all hentai with it's episodes
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// Cache for 10 minutes
|
||||
$data = Cache::remember('api_hentai_list', now()->addMinutes(10), function () {
|
||||
return Hentai::with('episodes')
|
||||
->orderBy('created_at', 'desc')
|
||||
->get()
|
||||
->map(function ($hentai) {
|
||||
return [
|
||||
'title' => $hentai->episodes[0]->title,
|
||||
'title_jpn' => $hentai->episodes[0]->title_jpn,
|
||||
'slug' => $hentai->slug,
|
||||
'episodes' => $hentai->episodes->map(function ($ep) {
|
||||
return [
|
||||
'episode' => $ep->episode,
|
||||
'slug' => $ep->slug,
|
||||
];
|
||||
}),
|
||||
];
|
||||
});
|
||||
});
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get monthly views by day for stats
|
||||
*/
|
||||
public function getMonthlyViews()
|
||||
{
|
||||
// Cache for 60 minutes
|
||||
$data = Cache::remember('api_monthly_views', now()->addMinutes(60), function () {
|
||||
return PopularMonthly::selectRaw('DATE(created_at) as date, COUNT(*) as count')
|
||||
->groupBy('date')
|
||||
->orderBy('date', 'asc')
|
||||
->get();
|
||||
});
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DownloadsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display Downloads Page.
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\View\View
|
||||
{
|
||||
$user = $request->user();
|
||||
if (!$user->is_patreon) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
return view('search.download-patreon');
|
||||
}
|
||||
}
|
@@ -87,7 +87,6 @@ class HomeController extends Controller
|
||||
'viewCount' => CacheHelper::getTotalViewCount(),
|
||||
'episodeCount' => CacheHelper::getTotalEpisodeCount(),
|
||||
'hentaiCount' => CacheHelper::getTotalHentaiCount(),
|
||||
'monthlyCount' => CacheHelper::getTotalMonthlyViews()
|
||||
]);
|
||||
}
|
||||
|
||||
|
@@ -32,19 +32,29 @@ class DiscordReleaseNotification implements ShouldQueue
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
// Wait 2s to avoid Discord API Rate limit
|
||||
sleep(2);
|
||||
|
||||
if ($this->messageType == 'release') {
|
||||
DiscordAlert::message("<@&868457842250764289> (´• ω •`)ノ New **4k** Release! Check it out here: https://hstream.moe/hentai/".$this->slug);
|
||||
}
|
||||
|
||||
if ($this->messageType == 'update') {
|
||||
DiscordAlert::to('update')->message("<@&1283518462584426598> (´• ω •`)ノ Added **48fps** to Release! Check it out here: https://hstream.moe/hentai/".$this->slug);
|
||||
}
|
||||
|
||||
if ($this->messageType == 'updateUHD') {
|
||||
DiscordAlert::to('update')->message("<@&1326860920902778963> (´• ω •`)ノ Added **48fps 4k** to Release! Check it out here: https://hstream.moe/hentai/".$this->slug);
|
||||
switch($this->messageType)
|
||||
{
|
||||
case 'release':
|
||||
DiscordAlert::message("<@&868457842250764289> (´• ω •`)ノ New **4k** Release! Check it out here: https://hstream.moe/hentai/".$this->slug);
|
||||
break;
|
||||
case 'release-censored':
|
||||
# Because Discord TOS
|
||||
DiscordAlert::message("<@&868457842250764289> (´• ω •`)ノ New **4k** Release: ".$this->slug." - *No link here because of* :pLoli:");
|
||||
break;
|
||||
case 'update':
|
||||
# 1080p 48fps added
|
||||
DiscordAlert::to('update')->message("<@&1283518462584426598> (´• ω •`)ノ Added **48fps** to Release! Check it out here: https://hstream.moe/hentai/".$this->slug);
|
||||
break;
|
||||
case 'updateUHD':
|
||||
# 4k 48fps added
|
||||
DiscordAlert::to('update')->message("<@&1326860920902778963> (´• ω •`)ノ Added **48fps 4k** to Release! Check it out here: https://hstream.moe/hentai/".$this->slug);
|
||||
break;
|
||||
case 'v2':
|
||||
# v2 re-release
|
||||
DiscordAlert::to('rerelease')->message("<@&1425505303075754035> (´• ω •`)ノ **v2 Re-**Release! Check it out here: https://hstream.moe/hentai/".$this->slug);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\Hentai;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
class Downloads extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
public $search;
|
||||
|
||||
public $order = 'az';
|
||||
|
||||
public $withTorrents;
|
||||
|
||||
protected $queryString = [
|
||||
'search' => ['except' => '', 'as' => 's'],
|
||||
'withTorrents' => ['withTorrents' => '', 'as' => 'withTorrents'],
|
||||
'order' => ['except' => '', 'as' => 'order'],
|
||||
];
|
||||
|
||||
public function updatingSearch()
|
||||
{
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$orderby = 'slug';
|
||||
$orderdirection = 'desc';
|
||||
|
||||
switch ($this->order) {
|
||||
case 'az':
|
||||
$orderby = 'slug';
|
||||
$orderdirection = 'asc';
|
||||
break;
|
||||
case 'za':
|
||||
$orderby = 'slug';
|
||||
$orderdirection = 'desc';
|
||||
break;
|
||||
default:
|
||||
$orderby = 'created_at';
|
||||
$orderdirection = 'desc';
|
||||
}
|
||||
|
||||
$hentai = Hentai::with('episodes')
|
||||
->when($this->search != '', fn ($query) => $query->whereHas('episodes', fn ($q) => $q->where('title', 'like', '%'.$this->search.'%')->orWhere('title_jpn', 'like', '%'.$this->search.'%')))
|
||||
->when($this->withTorrents != '', fn ($query) => $query->whereHas('torrents'))
|
||||
->orderBy($orderby, $orderdirection)
|
||||
->paginate(10);
|
||||
|
||||
return view('livewire.downloads', [
|
||||
'hentai' => $hentai,
|
||||
'query' => $this->search,
|
||||
]);
|
||||
}
|
||||
}
|
@@ -6,7 +6,7 @@ use App\Models\Downloads;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
class DownloadsPatreon extends Component
|
||||
class DownloadsSearch extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
@@ -24,6 +24,18 @@ class DownloadsPatreon extends Component
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
public function clicked($downloadId)
|
||||
{
|
||||
$download = Downloads::find($downloadId);
|
||||
if (!$download) {
|
||||
return;
|
||||
}
|
||||
|
||||
$download->count++;
|
||||
$download->save();
|
||||
cache()->forget("episode_{$download->episode->id}_download_{$download->type}");
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$orderby = 'created_at';
|
||||
@@ -60,12 +72,12 @@ class DownloadsPatreon extends Component
|
||||
}
|
||||
|
||||
$downloads = Downloads::when($this->fileSearch != '', fn ($query) => $query->where('url', 'like', '%'.$this->fileSearch.'%'))
|
||||
->where('size', '>', 0)
|
||||
->where(fn ($q) => $q->where('type', '=', 'UHD')->orWhere('type', '=', 'UHDi'))
|
||||
->when(!auth()->user()->is_patreon, fn ($query) => $query->whereIn('type', ['FHD', 'FHDi']))
|
||||
->whereNotNull('size')
|
||||
->orderBy($orderby, $orderdirection)
|
||||
->paginate(20);
|
||||
|
||||
return view('livewire.downloads-patreon', [
|
||||
return view('livewire.downloads-search', [
|
||||
'downloads' => $downloads,
|
||||
'query' => $this->fileSearch,
|
||||
]);
|
@@ -32,11 +32,6 @@ class Hentai extends Model implements Sitemapable
|
||||
return $this->hasMany(Episode::class, 'hentai_id');
|
||||
}
|
||||
|
||||
public function torrents()
|
||||
{
|
||||
return $this->hasMany(Torrents::class, 'hentai_id');
|
||||
}
|
||||
|
||||
public function title(): String
|
||||
{
|
||||
return $this->episodes->first()->title;
|
||||
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Torrents extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'hentai_id',
|
||||
'torrent_url',
|
||||
'episodes',
|
||||
];
|
||||
}
|
@@ -19,7 +19,7 @@
|
||||
"laravel/tinker": "^2.10",
|
||||
"laravelista/comments": "dev-l11-compatibility",
|
||||
"livewire/livewire": "^3.6.4",
|
||||
"maize-tech/laravel-markable": "2.2.0",
|
||||
"maize-tech/laravel-markable": "^2.3.0",
|
||||
"mews/captcha": "3.4.4",
|
||||
"predis/predis": "^2.2",
|
||||
"realrashid/sweet-alert": "^7.2",
|
||||
@@ -29,7 +29,7 @@
|
||||
"vluzrmos/language-detector": "^2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-debugbar": "3.14.7",
|
||||
"barryvdh/laravel-debugbar": "^3.14.7",
|
||||
"fakerphp/faker": "^1.24.0",
|
||||
"laravel/pint": "^1.18",
|
||||
"laravel/sail": "^1.38",
|
||||
|
2567
composer.lock
generated
2567
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@ return [
|
||||
'webhook_urls' => [
|
||||
'default' => env('DISCORD_ALERT_WEBHOOK'),
|
||||
'update' => env('DISCORD_ALERT_UPDATE_WEBHOOK'),
|
||||
'rerelease' => env('DISCORD_ALERT_RERELEASE_WEBHOOK'),
|
||||
],
|
||||
|
||||
/*
|
||||
|
@@ -6,7 +6,8 @@ return [
|
||||
'https://imoto-ddl.ane-h.xyz',
|
||||
'https://chibi-ddl.imoto-h.xyz',
|
||||
'https://koneko-ddl.musume-h.xyz',
|
||||
'https://shinobu-ddl.rorikon-h.xyz'
|
||||
'https://shinobu-ddl.rorikon-h.xyz',
|
||||
'https://oppai-ddl.shoujo-h.org',
|
||||
],
|
||||
|
||||
// 4k Download Domain
|
||||
@@ -14,7 +15,8 @@ return [
|
||||
'https://imoto-ddlp.ane-h.xyz',
|
||||
'https://chibi-ddlp.imoto-h.xyz',
|
||||
'https://koneko-ddlp.musume-h.xyz',
|
||||
'https://shinobu-ddlp.rorikon-h.xyz'
|
||||
'https://shinobu-ddlp.rorikon-h.xyz',
|
||||
'https://oppai-ddlp.shoujo-h.org',
|
||||
],
|
||||
|
||||
// Stream Domain
|
||||
@@ -22,7 +24,8 @@ return [
|
||||
'https://imoto-str.ane-h.xyz',
|
||||
'https://chibi-str.imoto-h.xyz',
|
||||
'https://koneko-str.musume-h.xyz',
|
||||
'https://shinobu-str.rorikon-h.xyz'
|
||||
'https://shinobu-str.rorikon-h.xyz',
|
||||
'https://oppai-str.shoujo-h.org',
|
||||
],
|
||||
|
||||
// Asia Fallback (HTTP)
|
||||
|
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Downloads;
|
||||
|
||||
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
|
||||
{
|
||||
# Delete entries with "#" as URL
|
||||
Downloads::where('url', '#')->forceDelete();
|
||||
|
||||
# Remove duplicate entries
|
||||
$duplicates = DB::table('downloads')
|
||||
->select('episode_id', 'type', DB::raw('COUNT(*) as count'))
|
||||
->groupBy('episode_id', 'type')
|
||||
->having('count', '>', 1)
|
||||
->get();
|
||||
|
||||
foreach ($duplicates as $duplicate) {
|
||||
// Find all rows for this episode_id and type
|
||||
$rows = DB::table('downloads')
|
||||
->where('episode_id', $duplicate->episode_id)
|
||||
->where('type', $duplicate->type)
|
||||
->orderBy('count', 'desc') // Order by count to delete the ones with the lower count
|
||||
->get();
|
||||
|
||||
// Delete the rows with lower counts, keeping the one with the highest count
|
||||
$rows->skip(1)->each(function ($row) {
|
||||
DB::table('downloads')->where('id', $row->id)->delete();
|
||||
});
|
||||
}
|
||||
|
||||
Schema::table('downloads', function (Blueprint $table) {
|
||||
$table->unique(['episode_id', 'type']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('downloads', function (Blueprint $table) {
|
||||
$table->dropUnique(['episode_id', 'type']);
|
||||
});
|
||||
}
|
||||
};
|
@@ -0,0 +1,24 @@
|
||||
<?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::dropIfExists('torrents');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Not reversible
|
||||
}
|
||||
};
|
1824
package-lock.json
generated
1824
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,17 +9,18 @@
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"autoprefixer": "^10.4.18",
|
||||
"axios": "^1.6.8",
|
||||
"laravel-vite-plugin": "^1.0.2",
|
||||
"laravel-vite-plugin": "^2.0.0",
|
||||
"postcss": "^8.4.35",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"vite": "^5.1.6",
|
||||
"vite-plugin-static-copy": "^1.0.1"
|
||||
"vite": "^7.1.6",
|
||||
"vite-plugin-static-copy": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
||||
"@jellyfin/libass-wasm": "^4.1.1",
|
||||
"@yaireo/tagify": "^4.21.2",
|
||||
"dashjs": "^4.7.4",
|
||||
"chart.js": "^4.5.0",
|
||||
"dashjs": "^5.0.0",
|
||||
"hammerjs": "^2.0.8",
|
||||
"plyr": "^3.7.8",
|
||||
"tw-elements": "^1.1.0",
|
||||
|
@@ -1,5 +1,5 @@
|
||||
// Plyr Player
|
||||
import Plyr from 'plyr/dist/plyr.polyfilled.min.js';
|
||||
import Plyr from 'plyr';
|
||||
import 'plyr/dist/plyr.css';
|
||||
|
||||
// Vidstack Player
|
||||
@@ -8,7 +8,7 @@ import 'vidstack/player/styles/default/layouts/video.css';
|
||||
import { VidstackPlayer, VidstackPlayerLayout } from 'vidstack/global/player';
|
||||
|
||||
// Dash Support
|
||||
import dashjs from 'dashjs';
|
||||
import * as dashjs from 'dashjs';
|
||||
|
||||
// Subtitle Support
|
||||
import SubtitlesOctopus from '@jellyfin/libass-wasm';
|
||||
|
73
resources/js/stats.js
Normal file
73
resources/js/stats.js
Normal file
@@ -0,0 +1,73 @@
|
||||
import Chart from 'chart.js/auto';
|
||||
|
||||
// Theming
|
||||
if (localStorage.theme !== 'light') {
|
||||
Chart.defaults.color = "#ADBABD";
|
||||
Chart.defaults.borderColor = "rgba(255,255,255,0.1)";
|
||||
Chart.defaults.backgroundColor = "rgba(255,255,0,0.1)";
|
||||
Chart.defaults.elements.line.borderColor = "rgba(255,255,0,0.4)";
|
||||
}
|
||||
|
||||
// Get Tags from API
|
||||
window.axios.get('/v1/monthly-views').then(function (response) {
|
||||
if (response.status != 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = {
|
||||
labels: response.data.map((entry) => { return entry.date }),
|
||||
datasets: [{
|
||||
label: 'Views',
|
||||
fill: false,
|
||||
backgroundColor: 'rgba(190, 18, 60, 0.3)',
|
||||
borderColor: 'rgba(190, 18, 60, 1.0)',
|
||||
cubicInterpolationMode: 'monotone',
|
||||
data: response.data.map((entry) => { return entry.count }),
|
||||
}]
|
||||
}
|
||||
|
||||
const config = {
|
||||
type: 'line',
|
||||
data: data,
|
||||
options: {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Views the last 30 days',
|
||||
font: {
|
||||
size: 18
|
||||
}
|
||||
},
|
||||
},
|
||||
interaction: {
|
||||
intersect: false,
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
display: true,
|
||||
title: {
|
||||
display: true
|
||||
}
|
||||
},
|
||||
y: {
|
||||
display: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Views'
|
||||
},
|
||||
suggestedMin: 0,
|
||||
suggestedMax: 40000
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const monthlyViewChart = new Chart(
|
||||
document.getElementById('monthlyChart'),
|
||||
config
|
||||
);
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
|
@@ -1,32 +0,0 @@
|
||||
<x-app-layout>
|
||||
<div class="p-5">
|
||||
<div class="w-[50%] mx-auto sm:px-6 lg:px-8 text-gray-800 dark:text-gray-200 bg-white dark:bg-neutral-950 rounded-lg">
|
||||
<div class="relative p-4">
|
||||
<form method="POST" action="{{ route('admin.add.torrent') }}">
|
||||
@csrf
|
||||
|
||||
<div class="p-4">
|
||||
<label class="mb-2 leading-tight text-gray-800 dark:text-gray-200 w-full" for="name">Hentai ID:</label>
|
||||
<input id="hentai_id" name="hentai_id" class="block w-full p-4 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" value="{{ $hentai_id }}" required>
|
||||
</div>
|
||||
|
||||
<div class="p-4">
|
||||
<label class="mb-2 leading-tight text-gray-800 dark:text-gray-200 w-full" for="name">Torrent URL:</label>
|
||||
<input id="torrent_url" name="torrent_url" class="block w-full p-4 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" required>
|
||||
</div>
|
||||
|
||||
<div class="p-4">
|
||||
<label class="mb-2 leading-tight text-gray-800 dark:text-gray-200 w-full" for="name">Episodes (e.g. "01-02" or "01"):</label>
|
||||
<input id="torrent_episodes" name="torrent_episodes" class="block w-full p-4 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" required>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-shrink-0 flex-wrap items-center justify-end rounded-b-md p-4">
|
||||
<button type="submit" class="ml-1 inline-block rounded bg-rose-600 px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white transition duration-150 ease-in-out hover:bg-rose-700 focus:bg-rose-600" data-te-ripple-init data-te-ripple-color="light">
|
||||
Create
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-app-layout>
|
@@ -97,6 +97,13 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap flex-shrink-0 justify-end items-center p-4 rounded-b-md">
|
||||
<div class="inline-block mr-2">
|
||||
<input class="w-4 h-4 text-rose-600 bg-gray-100 border-gray-300 rounded focus:ring-rose-500 dark:focus:ring-rose-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||
type="checkbox" value="true" id="v2" name="v2" />
|
||||
<label class="inline-block hover:cursor-pointer dark:text-white" for="v2">
|
||||
v2 Re-Release Notification
|
||||
</label>
|
||||
</div>
|
||||
<button type="button" class="inline-block px-6 pt-2.5 pb-2 text-xs font-medium leading-normal uppercase rounded transition duration-150 ease-in-out bg-primary-100 text-primary-700 hover:bg-primary-accent-100 focus:bg-primary-accent-100 focus:outline-none focus:ring-0 active:bg-primary-accent-200" data-te-modal-dismiss data-te-ripple-init data-te-ripple-color="light">
|
||||
Cancel
|
||||
</button>
|
||||
|
@@ -56,6 +56,13 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-shrink-0 flex-wrap items-center justify-end rounded-b-md p-4">
|
||||
<div class="inline-block mr-2">
|
||||
<input class="w-4 h-4 text-rose-600 bg-gray-100 border-gray-300 rounded focus:ring-rose-500 dark:focus:ring-rose-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||
type="checkbox" value="true" id="censored" name="censored" />
|
||||
<label class="inline-block hover:cursor-pointer dark:text-white" for="censored">
|
||||
Censored Notification
|
||||
</label>
|
||||
</div>
|
||||
<button type="button" class="inline-block rounded bg-primary-100 px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-primary-700 transition duration-150 ease-in-out hover:bg-primary-accent-100 focus:bg-primary-accent-100 focus:outline-none focus:ring-0 active:bg-primary-accent-200" data-te-modal-dismiss data-te-ripple-init data-te-ripple-color="light">
|
||||
Cancel
|
||||
</button>
|
||||
|
@@ -62,13 +62,12 @@
|
||||
|
||||
<div class="p-4 pt-0">
|
||||
<label class="leading-tight text-gray-800 dark:text-gray-200 w-full" for="description1">Description 1:</label>
|
||||
<textarea rows="4" cols="50" id="description1" name="description1" class="mt-1 block w-full border-gray-300 dark:border-gray-700 dark:bg-neutral-900 dark:text-gray-300 focus:border-rose-500 dark:focus:border-rose-600 focus:ring-rose-500 dark:focus:ring-rose-600 rounded-md shadow-sm" required>
|
||||
</textarea>
|
||||
<textarea rows="4" cols="50" id="description1" name="description1" class="mt-1 block w-full border-gray-300 dark:border-gray-700 dark:bg-neutral-900 dark:text-gray-300 focus:border-rose-500 dark:focus:border-rose-600 focus:ring-rose-500 dark:focus:ring-rose-600 rounded-md shadow-sm" required></textarea>
|
||||
</div>
|
||||
|
||||
<div class="p-4 pt-0">
|
||||
<label class="leading-tight text-gray-800 dark:text-gray-200 w-full" for="episodedlurl1">Download 1080p 1:</label>
|
||||
<x-text-input id="episodedlurl1" class="block w-full" type="text" name="episodedlurl1" required />
|
||||
<x-text-input id="episodedlurl1" class="block w-full" type="text" name="episodedlurl1" />
|
||||
</div>
|
||||
|
||||
<div class="p-4 pt-0">
|
||||
@@ -78,7 +77,7 @@
|
||||
|
||||
<div class="p-4 pt-0">
|
||||
<label class="leading-tight text-gray-800 dark:text-gray-200 w-full" for="episodedlurl4k1">Download 4k 1:</label>
|
||||
<x-text-input id="episodedlurl4k1" class="block w-full" type="text" name="episodedlurl4k1" required />
|
||||
<x-text-input id="episodedlurl4k1" class="block w-full" type="text" name="episodedlurl4k1" />
|
||||
</div>
|
||||
|
||||
<div class="p-4 pt-0">
|
||||
@@ -90,6 +89,13 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-shrink-0 flex-wrap items-center justify-end rounded-b-md p-4">
|
||||
<div class="inline-block mr-2">
|
||||
<input class="w-4 h-4 text-rose-600 bg-gray-100 border-gray-300 rounded focus:ring-rose-500 dark:focus:ring-rose-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||
type="checkbox" value="true" id="censored" name="censored" />
|
||||
<label class="inline-block hover:cursor-pointer dark:text-white" for="censored">
|
||||
Censored Notification
|
||||
</label>
|
||||
</div>
|
||||
<button type="button" class="inline-block rounded bg-primary-100 px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-primary-700 transition duration-150 ease-in-out hover:bg-primary-accent-100 focus:bg-primary-accent-100 focus:outline-none focus:ring-0 active:bg-primary-accent-200" data-te-modal-dismiss data-te-ripple-init data-te-ripple-color="light">
|
||||
Cancel
|
||||
</button>
|
||||
|
@@ -1,7 +1,11 @@
|
||||
<x-app-layout>
|
||||
<div class="container my-24 mx-auto md:px-6 z-10 relative">
|
||||
<p class="leading-normal font-bold text-lg text-rose-600 text-center">
|
||||
<p class="leading-normal font-bold text-2xl text-rose-600 text-center">
|
||||
(╥﹏╥)
|
||||
</p>
|
||||
<br>
|
||||
<p class="leading-normal font-bold text-lg text-rose-600 text-center">
|
||||
Please login to view this hentai!
|
||||
</p>
|
||||
</div>
|
||||
</x-app-layout>
|
@@ -1,6 +1,6 @@
|
||||
@props(['episode'])
|
||||
|
||||
<div class="relative p-1 mb-8 w-full transition duration-300 ease-in-out md:p-2 hover:-translate-y-1 hover:scale-110">
|
||||
<div class="relative p-1 mb-8 w-full transition duration-300 ease-in-out md:p-2 md:hover:-translate-y-1 md:hover:scale-110">
|
||||
<a class="hover:text-blue-600" 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"
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
@guest
|
||||
<p
|
||||
class="absolute right-2 top-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">
|
||||
class="absolute right-1 md:right-2 top-1 md:top-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">
|
||||
{{ $episode->getResolution() }}</p>
|
||||
<p
|
||||
class="absolute left-4 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">
|
||||
class="absolute left-1 md:left-4 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() }}
|
||||
@@ -29,20 +29,20 @@
|
||||
@auth
|
||||
@if ($episode->userWatched(auth()->user()->id))
|
||||
<p
|
||||
class="absolute right-2 top-2 bg-green-600/80 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
class="absolute right-1 md:right-2 top-1 md:top-2 bg-green-600/80 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
{{ $episode->getResolution() }}</p>
|
||||
<p
|
||||
class="absolute left-2 bottom-2 bg-green-600/80 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
class="absolute left-1 md:left-2 bottom-1 md:bottom-2 bg-green-600/80 !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>
|
||||
@else
|
||||
<p
|
||||
class="absolute right-2 top-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">
|
||||
class="absolute right-1 md:right-2 top-1 md:top-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">
|
||||
{{ $episode->getResolution() }}</p>
|
||||
<p
|
||||
class="absolute left-2 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">
|
||||
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() }}
|
||||
@@ -50,7 +50,7 @@
|
||||
@endif
|
||||
@endauth
|
||||
|
||||
<div class="absolute w-[95%] grid grid-cols-1 text-center">
|
||||
<div class="absolute w-[95%] grid grid-cols-1 text-center">
|
||||
<p class="text-sm text-center text-black dark:text-white">{{ $episode->title }} -
|
||||
{{ $episode->episode }}</p>
|
||||
</div>
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<div class="flex justify-center pb-10">
|
||||
<img src="/images/cropped-HS-1-270x270.webp" class="max-w-[150px]" alt="hstream.moe Logo" />
|
||||
</div>
|
||||
<div class="grid md:grid-cols-5 lg:gap-x-12">
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-4 lg:gap-x-12">
|
||||
<div class="mb-12 md:mb-0">
|
||||
<div class="mb-6 inline-block rounded-md bg-white dark:bg-neutral-950 p-4 text-sky-500">
|
||||
<i class="fa-solid fa-eye text-3xl"> {{ number_format($viewCount) }}</i>
|
||||
@@ -14,15 +14,7 @@
|
||||
</h5>
|
||||
</div>
|
||||
<div class="mb-12 md:mb-0">
|
||||
<div class="mb-6 inline-block rounded-md bg-white dark:bg-neutral-950 p-4 text-sky-500">
|
||||
<i class="fa-solid fa-calendar-days text-3xl"> {{ number_format($monthlyCount) }}</i>
|
||||
</div>
|
||||
<h5 class="text-lg font-medium dark:text-neutral-300">
|
||||
views the last 30 days
|
||||
</h5>
|
||||
</div>
|
||||
<div class="mb-12 md:mb-0">
|
||||
<div class="mb-6 inline-block rounded-md bg-white dark:bg-neutral-950 p-4 text-rose-600">
|
||||
<div class="b-6 inline-block rounded-md bg-white dark:bg-neutral-950 p-4 text-sky-500">
|
||||
<i class="fa-solid fa-video text-3xl"> {{ $episodeCount }}</i>
|
||||
</div>
|
||||
<h5 class="text-lg font-medium dark:text-neutral-300">
|
||||
@@ -46,7 +38,10 @@
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center dark:bg-neutral-950 bg-gray-50 rounded-xl md:m-11 hidden md:block">
|
||||
<canvas id="monthlyChart"></canvas>
|
||||
</div>
|
||||
</section>
|
||||
<p class="text-center text-black/40 dark:text-white/40">Cached for 60 Minutes</p>
|
||||
</div>
|
||||
@vite(['resources/js/stats.js'])
|
||||
</x-app-layout>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<footer class="mt-auto bg-white z-10 rounded-lg shadow dark:bg-neutral-950 m-4">
|
||||
<footer class="bg-white z-10 rounded-lg shadow dark:bg-neutral-950 m-4 mb-0 mt-auto">
|
||||
<div class="w-full xl:max-w-[95%] 2xl:max-w-[84%] mx-auto p-4">
|
||||
<div class="sm:flex sm:items-center sm:justify-between">
|
||||
<a href="https://hstream.moe/" class="flex items-center mb-4 sm:mb-0">
|
||||
@@ -65,3 +65,9 @@
|
||||
</div>
|
||||
</footer>
|
||||
@include('modals.language-selector')
|
||||
|
||||
<div class="m-2 w-full mx-auto">
|
||||
<div class="text-sm text-gray-500 text-center">
|
||||
<p>Render time: {{ number_format(microtime(true) - (defined('LARAVEL_START') ? LARAVEL_START : request()->server('REQUEST_TIME_FLOAT')), 3) }} seconds | Memory usage: {{ number_format(memory_get_peak_usage(true) / 1048576, 2) }} MB | Git: <a href="https://gitea.hstream.moe/w33b/hstream/commits/branch/main" target="_blank">{{ \App\Helpers\GitHelper::shortCommit() }}</a></p>
|
||||
</div>
|
||||
</div>
|
@@ -67,53 +67,61 @@
|
||||
<!-- Header -->
|
||||
<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">Title</div>
|
||||
<div class="w-28 px-6 py-4">Size</div>
|
||||
<div class="w-32 px-6 py-4">Date</div>
|
||||
<div class="flex-1 px-6 py-4 hidden sm:block">Title</div>
|
||||
<div class="w-28 px-6 py-4 hidden sm:block">Size</div>
|
||||
<div class="w-32 px-6 py-4 hidden sm:block">Date</div>
|
||||
<div class="w-32 px-6 py-4">Download</div>
|
||||
</div>
|
||||
|
||||
@php
|
||||
$dldomains = config('hstream.download_domain');
|
||||
$dlpdomains = config('hstream.download_domain_4k');
|
||||
@endphp
|
||||
|
||||
<!-- Rows -->
|
||||
@foreach ($downloads as $download)
|
||||
@php
|
||||
$title = explode('/', $download->url)[2];
|
||||
$bytes = $download->size;
|
||||
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
$power = $bytes > 0 ? floor(log($bytes, 1024)) : 0;
|
||||
$fileSize = round($bytes / pow(1024, $power), 2) . ' ' . $units[$power];
|
||||
@endphp
|
||||
|
||||
<div
|
||||
class="flex items-center border-b bg-white/70 dark:bg-neutral-950/80 dark:border-zinc-700 hover:bg-white/80 dark:hover:bg-neutral-950/90">
|
||||
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">
|
||||
<!-- Title -->
|
||||
<div class="flex flex-1 items-center space-x-2 px-3 py-2">
|
||||
<span class="cursor-default">
|
||||
{{ $title }}
|
||||
</span>
|
||||
{{ $title }}
|
||||
</div>
|
||||
|
||||
<!-- Size -->
|
||||
<div class="w-28 whitespace-nowrap">
|
||||
{{ $fileSize }}
|
||||
<div class="w-28 whitespace-nowrap flex">
|
||||
<span class="block sm:hidden">
|
||||
Size:
|
||||
</span>
|
||||
{{ $download->getFileSize() }}
|
||||
</div>
|
||||
|
||||
<!-- Date -->
|
||||
<div class="w-32 whitespace-nowrap">
|
||||
<div class="w-32 whitespace-nowrap flex">
|
||||
<span class="block sm:hidden">
|
||||
Date:
|
||||
</span>
|
||||
{{ $download->created_at->format('Y-m-d') }}
|
||||
</div>
|
||||
|
||||
<!-- Download -->
|
||||
<div class="w-32 whitespace-nowrap">
|
||||
@php
|
||||
$dlpdomains = config('hstream.download_domain_4k');
|
||||
$now = \Illuminate\Support\Carbon::now();
|
||||
$expire = \Illuminate\Support\Facades\Crypt::encryptString($now->addHours(6));
|
||||
$file = \Illuminate\Support\Facades\Crypt::encryptString('hentai/'.$download->url);
|
||||
$downloadURL = $dlpdomains[array_rand($dlpdomains)].'/download/'.$file.'/'.$expire;
|
||||
if (in_array($download->type, ['FHD', 'FHDi'])) {
|
||||
$downloadURL = $dldomains[array_rand($dldomains)].'/'.$download->url;
|
||||
} else {
|
||||
$now = \Illuminate\Support\Carbon::now();
|
||||
$expire = \Illuminate\Support\Facades\Crypt::encryptString($now->addHours(6));
|
||||
$file = \Illuminate\Support\Facades\Crypt::encryptString('hentai/'.$download->url);
|
||||
$downloadURL = $dlpdomains[array_rand($dlpdomains)].'/download/'.$file.'/'.$expire;
|
||||
}
|
||||
@endphp
|
||||
<a href="{{ $downloadURL }}" download>
|
||||
<a href="{{ $downloadURL }}" wire:click="clicked({{ $download->id }})" download>
|
||||
<button id="dl-{{ $download->id }}"
|
||||
class="group rounded-md bg-transparent border-[1px] border-white/20 shadow dark:text-white text-blac cursor-pointer flex justify-between items-center overflow-hidden transition-all w-[110px] h-[35px]">
|
||||
class="group rounded-md bg-transparent border-[1px] border-white/20 shadow dark:text-white text-blac cursor-pointer flex justify-between items-center overflow-hidden transition-all w-[110px] h-[32px] mt-1 mb-1">
|
||||
<div
|
||||
class="relative w-12 h-[40px] bg-transparent dark:text-white text-black flex justify-center items-center transition-all">
|
||||
<svg class="w-4 h-4 transition-all group-hover:-translate-y-1"
|
@@ -1,146 +0,0 @@
|
||||
<div class="py-3">
|
||||
<div class="mx-auto sm:px-6 lg:px-8 space-y-6 max-w-[100%] xl:max-w-[80%] 2xl:max-w-[50%]">
|
||||
<!-- Search Filter -->
|
||||
<div class="p-4 sm:p-8 bg-white dark:bg-neutral-800 shadow sm:rounded-lg">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
|
||||
<!-- Title -->
|
||||
<div>
|
||||
<label for="live-search"
|
||||
class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Search</label>
|
||||
<div class="relative right-2 left-0 sm:left-2 transition-all">
|
||||
<div class="absolute inset-y-0 left-2 flex items-center pl-3 pointer-events-none">
|
||||
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||
stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<input wire:model.live.debounce.600ms="search" type="search" id="live-search"
|
||||
class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900"
|
||||
placeholder="{{ __('search.search-hentai') }}" required>
|
||||
|
||||
<div class="absolute right-0 top-[11px]" wire:loading>
|
||||
<svg aria-hidden="true"
|
||||
class="inline w-8 h-8 mr-2 text-gray-200 animate-spin dark:text-gray-600 fill-pink-600"
|
||||
viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
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"
|
||||
fill="currentColor" />
|
||||
<path
|
||||
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
|
||||
fill="currentFill" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Ordering -->
|
||||
<div>
|
||||
<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">
|
||||
<i class="fa-solid fa-sort text-gray-500 dark:text-gray-400"></i>
|
||||
</div>
|
||||
<select wire:model.live="order"
|
||||
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="az">A-Z</option>
|
||||
<option value="za">Z-A</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="float-right text-gray-900 dark:text-white">
|
||||
<input type="checkbox" wire:model.live="withTorrents">
|
||||
Show only with Torrent
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@php $dldomains = config('hstream.download_domain'); @endphp
|
||||
|
||||
<div class="relative pt-5 mx-auto sm:px-6 lg:px-8 space-y-6 text-gray-900 dark:text-white xl:max-w-[95%] 2xl:max-w-[60%]" wire:keydown.right.window="nextPage" wire:keydown.left.window="previousPage">
|
||||
<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 -->
|
||||
<table class="min-w-full text-left text-sm font-light collapse md:visible">
|
||||
<thead class="border-b font-medium dark:border-neutral-500 bg-white dark:bg-neutral-800 shadow sm:rounded-lg">
|
||||
<tr>
|
||||
<th scope="col" class="px-6 py-4">Title</th>
|
||||
<th scope="col" class="px-6 py-4">Download</th>
|
||||
<th scope="col" class="px-6 py-4">Torrent</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($hentai as $h)
|
||||
@php $episode = $h->episodes->first(); @endphp
|
||||
<tr class="border-b dark:border-neutral-500">
|
||||
<td class="whitespace-nowrap px-6 py-4">
|
||||
{{ $episode->title }}
|
||||
@if ($episode->title != $episode->title_jpn)
|
||||
<br>
|
||||
{{ $episode->title_jpn }}
|
||||
@endif
|
||||
@auth
|
||||
@if(Auth::user()->is_admin)
|
||||
<br>
|
||||
<a href="{{ route('admin.add.torrentpage', ['hentai_id' => $h->id]) }}" target="_blank">Add Torrent</a>
|
||||
@endif
|
||||
@endauth
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-6 py-4">
|
||||
@foreach($h->episodes as $episode)
|
||||
@include('livewire.partials.download-button', ['hdl' => $episode])
|
||||
@endforeach
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-6 py-4">
|
||||
@include('livewire.partials.torrent-button', ['hentai' => $h])
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Mobile -->
|
||||
<table class="min-w-full text-left text-sm font-light visible md:collapse">
|
||||
<thead class="font-medium">
|
||||
<tr>
|
||||
<th scope="col" class="px-6 py-4"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($hentai as $h)
|
||||
@php $episode = $h->episodes->first(); @endphp
|
||||
<tr class="border-b dark:border-neutral-500">
|
||||
<td class="px-2 py-4 grid grid-flow-row">
|
||||
{{ $episode->title }}
|
||||
@if ($episode->title != $episode->title_jpn)
|
||||
<br>
|
||||
{{ $episode->title_jpn }}
|
||||
@endif
|
||||
<br>
|
||||
<div class="flex flex-row flex-wrap">
|
||||
@foreach($h->episodes as $episode)
|
||||
@include('livewire.partials.download-button', ['hdl' => $episode])
|
||||
@endforeach
|
||||
@include('livewire.partials.torrent-button', ['hentai' => $h])
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ $hentai->links('pagination::tailwind') }}
|
||||
|
||||
</div>
|
||||
</div>
|
@@ -1,10 +1,10 @@
|
||||
<div wire:key="episode-{{ $episode->id }}">
|
||||
@if ($searchIsJpn)
|
||||
<div class="relative p-1 mb-14 w-full transition duration-300 ease-in-out md:p-2 hover:-translate-y-1 hover:scale-110"
|
||||
<div class="relative p-1 mb-14 w-full transition duration-300 ease-in-out md:p-2 md:hover:-translate-y-1 md:hover:scale-110"
|
||||
data-thumbs="{{ optional($episode->gallery)->pluck('thumbnail_url') }}">
|
||||
@else
|
||||
<div class="relative p-1 mb-8 w-full transition duration-300 ease-in-out md:p-2 hover:-translate-y-1 hover:scale-110"
|
||||
data-thumbs="{{ optional($episode->gallery)->pluck('thumbnail_url') }}">
|
||||
<div class="relative p-1 mb-8 w-full transition duration-300 ease-in-out md:p-2 md:hover:-translate-y-1 md:hover:scale-110"
|
||||
data-thumbs="{{ optional($episode->gallery)->pluck('thumbnail_url') }}">
|
||||
@endif
|
||||
<a class="hover:text-blue-600" href="{{ route('hentai.index', ['title' => $episode->slug]) }}">
|
||||
<div class="absolute w-[95%] top-[38%] text-center z-10">
|
||||
@@ -27,7 +27,7 @@
|
||||
src="{{ optional($episode->gallery->first())->thumbnail_url }}">
|
||||
@if ($episode->hasAutoTrans())
|
||||
<p
|
||||
class="absolute right-2 bottom-2 bg-blue-600/80 !text-white rounded-tl-lg rounded-br-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
class="absolute right-1 md:right-2 bottom-1 md:bottom-2 bg-blue-600/80 !text-white rounded-tl-lg rounded-br-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
<i class="fa-regular fa-closed-captioning"></i> Multi-Subs
|
||||
</p>
|
||||
@endif
|
||||
@@ -44,27 +44,27 @@
|
||||
@php $problematic = cache()->rememberForever('episodeProblematic'.$episode->id, fn () => $episode->getProblematicTags()); @endphp
|
||||
@if (!empty($problematic))
|
||||
<p
|
||||
class="absolute left-2 top-2 bg-red-700/70 !text-white rounded-br-lg rounded-tl-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
class="absolute left-1 md:left-2 top-1 md:top-2 bg-red-700/70 !text-white rounded-br-lg rounded-tl-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
<i class="fa-solid fa-triangle-exclamation"></i> {{ $problematic }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
@if (auth()->check() && $episode->userWatched(auth()->user()->id))
|
||||
<p
|
||||
class="absolute right-2 top-2 bg-green-600/80 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
class="absolute right-1 md:right-2 top-1 md:top-2 bg-green-600/80 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
{{ $episode->getResolution() }}</p>
|
||||
<p
|
||||
class="absolute left-2 bottom-2 bg-green-600/80 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
class="absolute left-1 md:left-2 bottom-1 md:bottom-2 bg-green-600/80 !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>
|
||||
@else
|
||||
<p
|
||||
class="absolute right-2 top-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">
|
||||
class="absolute right-1 md:right-2 top-1 md:top-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">
|
||||
{{ $episode->getResolution() }}</p>
|
||||
<p
|
||||
class="absolute left-2 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">
|
||||
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>
|
||||
|
@@ -1,25 +0,0 @@
|
||||
@forelse ($hentai->torrents as $torrent)
|
||||
<a href="{{ $torrent->torrent_url }}" target="_blank">
|
||||
<button class="group rounded-md shadow bg-primary-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">
|
||||
<i id="arrow" class="fa-solid fa-magnet transition-all group-hover:-translate-y-1"></i>
|
||||
<div id="progress" class="absolute w-full h-0 bg-white bg-opacity-20 top-0 duration-200"></div>
|
||||
</div>
|
||||
<div class="w-32 text-center">
|
||||
<p class="text-sm">Episode {{ $torrent->episodes }}</p>
|
||||
</div>
|
||||
</button>
|
||||
</a>
|
||||
@empty
|
||||
<a>
|
||||
<button class="group rounded-md shadow bg-gray-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">
|
||||
<i id="arrow" class="fa-solid fa-magnet transition-all group-hover:-translate-y-1"></i>
|
||||
<div id="progress" class="absolute w-full h-0 bg-white bg-opacity-20 top-0 duration-200"></div>
|
||||
</div>
|
||||
<div class="w-32 text-center">
|
||||
<p class="text-sm">Torrent not available</p>
|
||||
</div>
|
||||
</button>
|
||||
</a>
|
||||
@endforelse
|
@@ -1,4 +1,6 @@
|
||||
@auth
|
||||
@php $download = $episode->getDownloadByType('FHD'); @endphp
|
||||
@isset($download)
|
||||
<p class="font-bold text-gray-800 dark:text-gray-200">
|
||||
<i class="fa-solid fa-lock-open pr-[4px] text-green-400"></i> 1080p
|
||||
</p>
|
||||
@@ -13,13 +15,21 @@
|
||||
@foreach ($dlList as $hdl)
|
||||
@include('modals.partials.download-button')
|
||||
@endforeach
|
||||
|
||||
@include('livewire.partials.torrent-button', ['hentai' => $episode->hentai])
|
||||
</div>
|
||||
|
||||
@include('modals.partials.download-backup')
|
||||
@else
|
||||
<p class="text-gray-800 dark:text-gray-200 font-bold">
|
||||
<i class="fa-solid fa-lock pr-[4px] text-red-600"></i> 1080p
|
||||
</p>
|
||||
<p class="text-gray-800 dark:text-gray-200">
|
||||
Unavailable.
|
||||
</p>
|
||||
@endisset
|
||||
|
||||
@if ($episode->interpolated)
|
||||
@php $download = $episode->getDownloadByType('FHDi'); @endphp
|
||||
@isset($download)
|
||||
<p class="font-bold text-gray-800 dark:text-gray-200">
|
||||
<i class="fa-solid fa-lock-open pr-[4px] text-green-400"></i> 1080p 48fps
|
||||
</p>
|
||||
@@ -29,10 +39,19 @@
|
||||
@include('modals.partials.download-button-interpolated')
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<p class="text-gray-800 dark:text-gray-200 font-bold">
|
||||
<i class="fa-solid fa-lock pr-[4px] text-red-600"></i> 1080p 48fps
|
||||
</p>
|
||||
<p class="text-gray-800 dark:text-gray-200">
|
||||
Unavailable.
|
||||
</p>
|
||||
@endisset
|
||||
@endif
|
||||
|
||||
|
||||
<br>
|
||||
@php $download = $episode->getDownloadByType('UHD'); @endphp
|
||||
@isset($download)
|
||||
@if (!Auth::user()->is_patreon)
|
||||
@if (config('hstream.free_downloads'))
|
||||
<p class="font-bold text-gray-800 dark:text-gray-200">
|
||||
@@ -61,6 +80,14 @@
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
@else
|
||||
<p class="text-gray-800 dark:text-gray-200 font-bold">
|
||||
<i class="fa-solid fa-lock pr-[4px] text-red-600"></i> 4k
|
||||
</p>
|
||||
<p class="text-gray-800 dark:text-gray-200">
|
||||
Unavailable.
|
||||
</p>
|
||||
@endisset
|
||||
|
||||
<br>
|
||||
@if ($episode->interpolated_uhd)
|
||||
|
@@ -8,6 +8,9 @@
|
||||
@foreach ($dlList as $hdl)
|
||||
@php
|
||||
$download = $hdl->getDownloadByType('FHD');
|
||||
@endphp
|
||||
@isset($download)
|
||||
@php
|
||||
$downloadURL = $dlDomainsBackup[array_rand($dlDomainsBackup)].'/'.$download->url;
|
||||
$background = 'bg-green-600';
|
||||
@endphp
|
||||
@@ -20,6 +23,11 @@
|
||||
:fill-numbers="$fillNumbers"
|
||||
:file-size="$download->getFileSize()"
|
||||
:background="$background">
|
||||
@else
|
||||
<a class="inline-flex items-center ml-4 px-4 p-4 mt-4 cursor-not-allowed bg-gray-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 active:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-rose-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150" id="downloadEpisode" alt="Kekw">
|
||||
<i class="fa-solid fa-download mr-2"></i> Episode {{ $hdl->episode }} (Unavailable)
|
||||
</a>
|
||||
@endisset
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,5 +1,9 @@
|
||||
@php
|
||||
$download = $hdl->getDownloadByType('FHD');
|
||||
@endphp
|
||||
|
||||
@isset($download)
|
||||
@php
|
||||
$downloadURL = $dldomains[array_rand($dldomains)].'/'.$download->url;
|
||||
@endphp
|
||||
|
||||
@@ -10,3 +14,8 @@
|
||||
:episode-number="$hdl->episode"
|
||||
:fill-numbers="$fillNumbers"
|
||||
:file-size="$download->getFileSize()">
|
||||
@else
|
||||
<a class="inline-flex items-center ml-4 px-4 p-4 mt-4 cursor-not-allowed bg-gray-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 active:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-rose-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150" id="downloadEpisode" alt="Kekw">
|
||||
<i class="fa-solid fa-download mr-2"></i> Episode {{ $hdl->episode }} (Unavailable)
|
||||
</a>
|
||||
@endisset
|
@@ -1,5 +1,16 @@
|
||||
@guest
|
||||
|
||||
@php $download = $episode->getDownloadByType('FHD'); @endphp
|
||||
@isset($download)
|
||||
@include('modals.partials.download-captcha')
|
||||
@else
|
||||
<p class="text-gray-800 dark:text-gray-200 font-bold">
|
||||
<i class="fa-solid fa-lock pr-[4px] text-red-600"></i> FHD
|
||||
</p>
|
||||
<p class="text-gray-800 dark:text-gray-200">
|
||||
Unavailable.
|
||||
</p>
|
||||
@endisset
|
||||
|
||||
@if ($episode->interpolated)
|
||||
<br>
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<br>
|
||||
@php $download = $episode->getDownloadByType('FHD'); @endphp
|
||||
@isset($download)
|
||||
<p class="font-bold text-gray-800 dark:text-gray-200">
|
||||
<i class="fa-solid fa-lock-open pr-[4px] text-green-400"></i> Subtitles
|
||||
</p>
|
||||
@@ -32,3 +34,11 @@
|
||||
@endforeach
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<p class="text-gray-800 dark:text-gray-200 font-bold">
|
||||
<i class="fa-solid fa-lock pr-[4px] text-red-600"></i> Subtitles
|
||||
</p>
|
||||
<p class="text-gray-800 dark:text-gray-200">
|
||||
Unavailable.
|
||||
</p>
|
||||
@endisset
|
@@ -12,7 +12,7 @@
|
||||
@endif
|
||||
|
||||
<div
|
||||
class="relative p-1 mb-8 w-full transition duration-300 ease-in-out md:p-2 hover:-translate-y-1 hover:scale-110">
|
||||
class="relative p-1 mb-8 w-full transition duration-300 ease-in-out md:p-2 md:hover:-translate-y-1 md:hover:scale-110">
|
||||
<a class="hover:text-blue-600" href="{{ route('hentai.index', ['title' => $episode->slug]) }}">
|
||||
<img alt="{{ $episode->title }} - {{ $episode->episode }}" loading="lazy" width="400"
|
||||
class="block relative rounded-lg object-cover object-center aspect-[11/16] z-20 "
|
||||
@@ -20,10 +20,10 @@
|
||||
|
||||
@guest
|
||||
<p
|
||||
class="absolute right-2 top-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">
|
||||
class="absolute right-1 md:right-2 top-1 md:top-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">
|
||||
{{ $episode->getResolution() }}</p>
|
||||
<p
|
||||
class="absolute left-2 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">
|
||||
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() }}
|
||||
@@ -33,7 +33,7 @@
|
||||
@php $problematic = cache()->rememberForever('episodeProblematic'.$episode->id, fn () => $episode->getProblematicTags()); @endphp
|
||||
@if (!empty($problematic))
|
||||
<p
|
||||
class="absolute left-2 top-2 bg-red-700/70 !text-white rounded-br-lg rounded-tl-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
class="absolute left-1 md:left-2 top-1 md:top-2 bg-red-700/70 !text-white rounded-br-lg rounded-tl-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
<i class="fa-solid fa-triangle-exclamation"></i> {{ $problematic }}
|
||||
</p>
|
||||
@endif
|
||||
@@ -41,20 +41,20 @@
|
||||
@auth
|
||||
@if ($episode->userWatched(auth()->user()->id))
|
||||
<p
|
||||
class="absolute right-2 top-2 bg-green-600/80 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
class="absolute right-1 md:right-2 top-1 md:top-2 bg-green-600/80 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
{{ $episode->getResolution() }}</p>
|
||||
<p
|
||||
class="absolute left-2 bottom-2 bg-green-600/80 !text-white rounded-bl-lg rounded-tr-lg p-1 pr-2 pl-2 font-semibold text-sm z-30">
|
||||
class="absolute left-1 md:left-2 bottom-1 md:bottom-2 bg-green-600/80 !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>
|
||||
@else
|
||||
<p
|
||||
class="absolute right-2 top-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">
|
||||
class="absolute right-1 md:right-2 top-1 md:top-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">
|
||||
{{ $episode->getResolution() }}</p>
|
||||
<p
|
||||
class="absolute left-2 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">
|
||||
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() }}
|
||||
|
@@ -1,4 +0,0 @@
|
||||
<x-app-layout>
|
||||
@include('user.partials.background')
|
||||
@livewire('downloads-patreon')
|
||||
</x-app-layout>
|
@@ -1,3 +1,4 @@
|
||||
<x-app-layout>
|
||||
@livewire('downloads')
|
||||
@include('user.partials.background')
|
||||
@livewire('downloads-search')
|
||||
</x-app-layout>
|
||||
|
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\ContactController;
|
||||
use App\Http\Controllers\DownloadsController;
|
||||
use App\Http\Controllers\HomeController;
|
||||
use App\Http\Controllers\PlaylistController;
|
||||
use App\Http\Controllers\ProfileController;
|
||||
@@ -9,6 +8,7 @@ use App\Http\Controllers\StreamController;
|
||||
use App\Http\Controllers\UserController;
|
||||
use App\Http\Controllers\Api\AdminApiController;
|
||||
use App\Http\Controllers\Api\DownloadApiController;
|
||||
use App\Http\Controllers\Api\HentaiApiController;
|
||||
use App\Http\Controllers\Api\StreamApiController;
|
||||
use App\Http\Controllers\Api\UserApiController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
@@ -23,6 +23,10 @@ Route::get('/', [HomeController::class, 'index'])->name('home.index');
|
||||
Route::get('/stats', [HomeController::class, 'stats'])->name('home.stats');
|
||||
Route::get('/banned', [HomeController::class, 'banned'])->name('home.banned');
|
||||
|
||||
// API Endpoint
|
||||
Route::get('/v1/hentai-list', [HentaiApiController::class, 'index'])->name('api.hentai.index');
|
||||
Route::get('/v1/monthly-views', [HentaiApiController::class, 'getMonthlyViews'])->name('api.hentai.monthly');
|
||||
|
||||
// Stream Page
|
||||
Route::get('/hentai/{title}', [StreamController::class, 'index'])->name('hentai.index');
|
||||
Route::post('/player/api', [StreamApiController::class, 'getStream'])->name('hentai.player');
|
||||
@@ -78,9 +82,6 @@ Route::middleware('auth')->group(function () {
|
||||
|
||||
// Download Page
|
||||
Route::get('/download-search', [HomeController::class, 'downloadSearch'])->name('download.search');
|
||||
|
||||
// Download Page for Patreon Subscribers
|
||||
Route::get('/files', [DownloadsController::class, 'index'])->name('files.index');
|
||||
});
|
||||
|
||||
Route::get('/user/{username}', [UserController::class, 'index'])->name('user.index');
|
||||
@@ -126,10 +127,6 @@ Route::group(['middleware' => ['auth', 'auth.admin']], function () {
|
||||
Route::get('/admin/tags/{episode_id}', [AdminApiController::class, 'getEpisodeTags'])->name('admin.tags.episode');
|
||||
Route::get('/admin/studio/{episode_id}', [AdminApiController::class, 'getEpisodeStudio'])->name('admin.studio.episode');
|
||||
|
||||
// Torrents
|
||||
Route::get('/admin/add-torrent/{hentai_id}', [App\Http\Controllers\Admin\TorrentController::class, 'index'])->name('admin.add.torrentpage');
|
||||
Route::post('/admin/add-torrent', [App\Http\Controllers\Admin\TorrentController::class, 'store'])->name('admin.add.torrent');
|
||||
|
||||
// Subtitles
|
||||
Route::get('/admin/subtitles/{episode_id}', [AdminApiController::class, 'getSubtitles'])->name('admin.subtitles');
|
||||
Route::post('/admin/add-new-subtitle', [App\Http\Controllers\Admin\SubtitleController::class, 'store'])->name('admin.add.new.subtitle');
|
||||
|
@@ -20,7 +20,8 @@ export default defineConfig({
|
||||
'resources/js/user-blacklist.js',
|
||||
'resources/js/admin-edit.js',
|
||||
'resources/js/admin-subtitles.js',
|
||||
'resources/js/preview.js'
|
||||
'resources/js/preview.js',
|
||||
'resources/js/stats.js'
|
||||
],
|
||||
refresh: true,
|
||||
}),
|
||||
|
Reference in New Issue
Block a user