playlistService = $playlistService; } public function mount($playlist_id) { $this->playlist = Playlist::withCount('episodes')->with('user')->findOrFail($playlist_id); $this->sanitizePerPage(); $this->repairNullPositions(); } public function updatingSearch(): void { $this->resetPage(); } public function updatingPerPage(): void { $this->resetPage(); } public function getEpisodesProperty(): LengthAwarePaginator { $this->sanitizePerPage(); return PlaylistEpisode::query() ->where('playlist_id', $this->playlist->id) ->when($this->search !== '', fn ($query) => $query->whereHas('episode', fn ($episode) => $episode ->where('title', 'like', '%'.$this->search.'%') ->orWhere('title_jpn', 'like', '%'.$this->search.'%'))) ->orderBy('position') ->with(['episode.gallery' => fn ($gallery) => $gallery->orderBy('id')->limit(1)]) ->paginate($this->perPage); } public function getFirstEpisodeProperty(): ?Episode { return PlaylistEpisode::where('playlist_id', $this->playlist->id) ->orderBy('position') ->first()?->episode; } public function moveUp($episodeId) { if (! $this->isOwner()) { return; } $episode = PlaylistEpisode::find($episodeId); if (! $episode) { return; } $above = PlaylistEpisode::where('playlist_id', $episode->playlist_id) ->where('position', '<', $episode->position) ->orderBy('position', 'desc') ->first(); if ($above) { $this->playlistService->swapPositions($episode, $above); } } public function moveDown($episodeId) { if (! $this->isOwner()) { return; } $episode = PlaylistEpisode::find($episodeId); if (! $episode) { return; } $below = PlaylistEpisode::where('playlist_id', $episode->playlist_id) ->where('position', '>', $episode->position) ->orderBy('position') ->first(); if ($below) { $this->playlistService->swapPositions($episode, $below); } } public function remove($episodeId) { if (! $this->isOwner()) { return; } PlaylistEpisode::find($episodeId)?->delete(); $this->playlistService->reorderPositions($this->playlist); $this->playlist->loadCount('episodes'); $lastPage = max(1, (int) ceil(PlaylistEpisode::where('playlist_id', $this->playlist->id)->count() / $this->perPage)); if ($this->getPage() > $lastPage) { $this->setPage($lastPage); } } public function editName() { if (! $this->isOwner()) { return; } $this->editingPlaylistName = $this->playlist->name; $this->editingName = true; } public function cancelEditName() { $this->editingName = false; $this->editingPlaylistName = ''; } public function updateName() { if (! $this->isOwner()) { return; } $this->validate([ 'editingPlaylistName' => 'required|max:30', ]); $this->playlist->update([ 'name' => $this->editingPlaylistName, ]); $this->editingName = false; $this->editingPlaylistName = ''; } public function toggleVisibility() { if (! $this->isOwner()) { return; } $this->playlist->update([ 'is_private' => ! $this->playlist->is_private, ]); $this->playlist->loadCount('episodes'); } public function render() { return view('livewire.playlist-overview', [ 'episodes' => $this->episodes, 'firstEpisode' => $this->firstEpisode, 'isOwner' => $this->isOwner(), ]); } private function isOwner(): bool { return Auth::check() && Auth::user()->id === $this->playlist->user_id; } private function sanitizePerPage(): void { if (! in_array($this->perPage, [25, 50, 100], true)) { $this->perPage = 25; } } private function repairNullPositions(): void { if (! PlaylistEpisode::where('playlist_id', $this->playlist->id)->whereNull('position')->exists()) { return; } PlaylistEpisode::where('playlist_id', $this->playlist->id) ->orderBy('position')->orderBy('id') ->get() ->each(fn ($playlistEpisode, $index) => $playlistEpisode->update(['position' => $index + 1])); } }