refactor(episode): migrate episode upload to Livewire with real-time CDN verification
Replace the server-rendered episode upload form with a Livewire component, introducing an interactive admin experience that validates the new episode's stream path against all configured mirrors before saving. The controller-based `store` method and its route are removed, and episode creation now flows through the `AdminEpisodeForm` component with frontend upload handling and dynamic quality checks. Key changes: - Add `AdminEpisodeForm` Livewire component with file uploads, tag handling, and debounced stream/base-url validation. - Extend `CdnPathValidator::validateStream` to accept an episode number so the manifest path can point to the specific episode being added. - Remove the `store` method from `EpisodeController` and its POST route. - Delete the legacy `createEpisode` method from `EpisodeService`. - Replace the Blade upload modal with the Livewire view, including progress indicators and validation badges. - Add feature tests for the Livewire component and update unit tests for the CDN validator's episode-specific manifest check.
This commit is contained in:
@@ -32,39 +32,6 @@ class EpisodeService
|
||||
return $slug;
|
||||
}
|
||||
|
||||
public function createEpisode(
|
||||
Request $request,
|
||||
Hentai $hentai,
|
||||
int $episodeNumber,
|
||||
?Studios $studio = null,
|
||||
?Episode $referenceEpisode = null
|
||||
): Episode {
|
||||
$episode = new Episode;
|
||||
$episode->title = $referenceEpisode->title ?? $request->input('title');
|
||||
$episode->title_search = preg_replace('/[^A-Za-z0-9 ]/', '', $episode->title);
|
||||
$episode->title_jpn = $referenceEpisode->title_jpn ?? $request->input('title_jpn');
|
||||
$episode->slug = "{$hentai->slug}-{$episodeNumber}";
|
||||
$episode->hentai_id = $hentai->id;
|
||||
$episode->studios_id = $referenceEpisode->studio->id ?? $studio->id;
|
||||
$episode->episode = $episodeNumber;
|
||||
$episode->description = $referenceEpisode ? $request->input('description') : $request->input("description{$episodeNumber}");
|
||||
$episode->url = $referenceEpisode ? $request->input('baseurl') : rtrim($request->input('baseurl'), '/').'/E'.str_pad($episodeNumber, 2, '0', STR_PAD_LEFT);
|
||||
$episode->view_count = 0;
|
||||
$episode->interpolated = true;
|
||||
$episode->is_dvd_aspect = false;
|
||||
$episode->release_date = $referenceEpisode->release_date ?? Carbon::parse($request->input('releasedate'))->format('Y-m-d');
|
||||
$episode->cover_url = "/images/hentai/{$hentai->slug}/cover-ep-{$episodeNumber}.webp";
|
||||
$episode->save();
|
||||
|
||||
// Tagging
|
||||
$tags = $referenceEpisode ? $referenceEpisode->tags : json_decode($request->input('tags'));
|
||||
foreach ($tags as $t) {
|
||||
$episode->tag($referenceEpisode ? $t->name : $t->value);
|
||||
}
|
||||
|
||||
return $episode;
|
||||
}
|
||||
|
||||
private function applyTags(Request $request, Episode $episode): void
|
||||
{
|
||||
$tags = json_decode($request->input('tags'));
|
||||
|
||||
Reference in New Issue
Block a user