From f35d1a119e7871e41e2c134b613a59a90c87b91f Mon Sep 17 00:00:00 2001 From: w33b Date: Sun, 19 Jul 2026 13:22:28 +0200 Subject: [PATCH] Add ability to edit the playlist name and visibility #5 --- app/Http/Controllers/PlaylistController.php | 28 +++++++ app/Livewire/PlaylistOverview.php | 51 +++++++++++++ app/Models/Playlist.php | 20 +++++ resources/js/modals-playlist.js | 57 +++++++++++---- .../livewire/playlist-overview.blade.php | 50 ++++++++++++- .../views/modals/add-to-playlist.blade.php | 73 ++++++------------- .../views/modals/create-playlist.blade.php | 25 ++++--- .../profile/partials/user-playlists.blade.php | 70 +++++++++++++++--- routes/user.php | 1 + 9 files changed, 290 insertions(+), 85 deletions(-) diff --git a/app/Http/Controllers/PlaylistController.php b/app/Http/Controllers/PlaylistController.php index 8a03190..5cea863 100644 --- a/app/Http/Controllers/PlaylistController.php +++ b/app/Http/Controllers/PlaylistController.php @@ -95,6 +95,34 @@ class PlaylistController extends Controller return to_route('profile.playlists'); } + /** + * Update user playlist. + */ + public function updatePlaylist(Request $request, $playlist_id): RedirectResponse + { + if (! is_numeric($playlist_id)) { + abort(404); + } + + $validated = $request->validate([ + 'name' => 'required|max:30', + 'is_private' => 'required|boolean', + ]); + + $user = $request->user(); + + $playlist = Playlist::where('user_id', $user->id) + ->where('id', $playlist_id) + ->firstOrFail(); + + $playlist->update([ + 'name' => $request->input('name'), + 'is_private' => $request->input('is_private'), + ]); + + return back()->with('status', 'playlist-updated'); + } + /** * Delete user playlist. */ diff --git a/app/Livewire/PlaylistOverview.php b/app/Livewire/PlaylistOverview.php index a07e867..9247149 100644 --- a/app/Livewire/PlaylistOverview.php +++ b/app/Livewire/PlaylistOverview.php @@ -26,6 +26,10 @@ class PlaylistOverview extends Component public Collection $playlistEpisodes; + public bool $editingName = false; + + public string $editingPlaylistName = ''; + public function boot(PlaylistService $playlistService) { $this->playlistService = $playlistService; @@ -112,6 +116,53 @@ class PlaylistOverview extends Component $this->refreshEpisodes(); } + public function editName() + { + if (! Auth::check() || Auth::user()->id !== $this->playlist->user->id) { + return; + } + + $this->editingPlaylistName = $this->playlist->name; + $this->editingName = true; + } + + public function cancelEditName() + { + $this->editingName = false; + $this->editingPlaylistName = ''; + } + + public function updateName() + { + if (! Auth::check() || Auth::user()->id !== $this->playlist->user->id) { + return; + } + + $this->validate([ + 'editingPlaylistName' => 'required|max:30', + ]); + + $this->playlist->update([ + 'name' => $this->editingPlaylistName, + ]); + + $this->editingName = false; + $this->editingPlaylistName = ''; + } + + public function toggleVisibility() + { + if (! Auth::check() || Auth::user()->id !== $this->playlist->user->id) { + return; + } + + $this->playlist->update([ + 'is_private' => ! $this->playlist->is_private, + ]); + + $this->playlist->refresh(); + } + public function render() { return view('livewire.playlist-overview', [ diff --git a/app/Models/Playlist.php b/app/Models/Playlist.php index e353e3d..28d17cf 100644 --- a/app/Models/Playlist.php +++ b/app/Models/Playlist.php @@ -7,6 +7,26 @@ use Illuminate\Database\Eloquent\Relations\HasMany; class Playlist extends Model { + /** + * The attributes that are mass assignable. + * + * @var array + */ + protected $fillable = [ + 'user_id', + 'name', + 'is_private', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'is_private' => 'boolean', + ]; + /** * Belongs To A User. */ diff --git a/resources/js/modals-playlist.js b/resources/js/modals-playlist.js index 0730103..ec1c0a4 100644 --- a/resources/js/modals-playlist.js +++ b/resources/js/modals-playlist.js @@ -1,14 +1,10 @@ if (document.getElementById("playlist-add")) { - function createPlaylist() { - console.log('Adding to Playlist: ' + document.querySelector("#playlist").value) - + function addToPlaylist() { window.axios.post('/hentai/add-to-playlist', { playlist: document.getElementById('playlist').value, episode_id: document.getElementById('e_id').value }).then(function (response) { if (response.status == 200) { - document.getElementById("playlist-cancel").click(); - if (response.data.message == 'already-added') { Swal.fire({ title: "Already added!", @@ -18,6 +14,8 @@ if (document.getElementById("playlist-add")) { } if (response.data.message == 'success') { + document.getElementById("playlist-cancel").click(); + Swal.fire({ title: "Success!", text: "Added episode to the playlist!", @@ -27,33 +25,66 @@ if (document.getElementById("playlist-add")) { } }).catch(function (error) { console.log(error); + Swal.fire({ + title: "Error!", + text: "Could not add episode to playlist.", + icon: "error" + }); }); } - document.querySelector("#playlist-add").addEventListener("click", createPlaylist); + document.querySelector("#playlist-add").addEventListener("click", addToPlaylist); } if (document.getElementById("playlist-create-and-add")) { function createAndAddPlaylist() { + const nameField = document.getElementById('playlist-name'); + const visibilityField = document.getElementById('playlist-visibility'); + + if (!nameField.value.trim()) { + Swal.fire({ + title: "Name required!", + text: "Please enter a playlist name.", + icon: "warning" + }); + return; + } + window.axios.post('/hentai/create-playlist', { - name: document.getElementById('name').value, - visiblity: document.getElementById('visiblity').value + name: nameField.value, + visiblity: visibilityField.value }).then(function (response) { window.axios.post('/hentai/add-to-playlist', { playlist: response.data.playlist_id, episode_id: document.getElementById('e_id').value - }).then(function (response) { - if (response.status == 200) { - document.getElementById("playlist-cancel").click(); + }).then(function (addResponse) { + if (addResponse.status == 200) { + const cancelBtn = document.getElementById("playlist-cancel"); + if (cancelBtn) cancelBtn.click(); + + Swal.fire({ + title: "Success!", + text: "Playlist created and episode added!", + icon: "success" + }); } }).catch(function (error) { console.log(error); + Swal.fire({ + title: "Error!", + text: "Could not add episode to the new playlist.", + icon: "error" + }); }); - }).catch(function (error) { console.log(error); + Swal.fire({ + title: "Error!", + text: "Could not create playlist.", + icon: "error" + }); }); } document.querySelector("#playlist-create-and-add").addEventListener("click", createAndAddPlaylist); -} +} \ No newline at end of file diff --git a/resources/views/livewire/playlist-overview.blade.php b/resources/views/livewire/playlist-overview.blade.php index 4586aa6..683d5e7 100644 --- a/resources/views/livewire/playlist-overview.blade.php +++ b/resources/views/livewire/playlist-overview.blade.php @@ -9,9 +9,55 @@ src="{{ $playlist->user->getAvatar() }}">
-

{{ $playlist->name }}

+ @if ($editingName) +
+ + + +
+ @error('editingPlaylistName') +

{{ $message }}

+ @enderror + @else +

+ {{ $playlist->name }} + @auth + @if (Auth::id() === $playlist->user->id) + + @endif + @endauth +

+ @endif

Episodes: {{ count($playlistEpisodes) }}

-

Creator: {{ $playlist->user->name }}

+

+ Creator: {{ $playlist->user->name }} + @auth + @if (Auth::id() === $playlist->user->id) + + + + @else + + + {{ $playlist->is_private ? 'Private' : 'Public' }} + + @endif + @endauth +

diff --git a/resources/views/modals/add-to-playlist.blade.php b/resources/views/modals/add-to-playlist.blade.php index 7a0bcc8..b141dfa 100644 --- a/resources/views/modals/add-to-playlist.blade.php +++ b/resources/views/modals/add-to-playlist.blade.php @@ -13,96 +13,71 @@
- @php $playlists = Auth::user()->playlists; @endphp @if (count($playlists) > 0) +
- +
- + +
+

Or Create a New Playlist

+ @else +

+ No Playlists found. Create one below! +

+ @endif + +
- - + +
- -
- + - - @else - - - - No Playlists found. Please create a Playlist first! - - -
- - - -
- -
- - - -
- - - - @endif -
diff --git a/resources/views/modals/create-playlist.blade.php b/resources/views/modals/create-playlist.blade.php index f0aa249..9578f01 100644 --- a/resources/views/modals/create-playlist.blade.php +++ b/resources/views/modals/create-playlist.blade.php @@ -8,7 +8,7 @@ class="fixed inset-0 z-[1055] hidden overflow-y-auto bg-black/60 backdrop-blur-sm" >
-
+
@@ -17,25 +17,30 @@ @csrf
- - + +
-
- +
+
- -
- -
@@ -43,4 +48,4 @@
-
+ \ No newline at end of file diff --git a/resources/views/profile/partials/user-playlists.blade.php b/resources/views/profile/partials/user-playlists.blade.php index 7262766..32c77b3 100644 --- a/resources/views/profile/partials/user-playlists.blade.php +++ b/resources/views/profile/partials/user-playlists.blade.php @@ -20,17 +20,65 @@ ... @endif -
-
- {{ $playlist->name }} -
-

- {{ $count }} Episodes - {{ $playlist->is_private == 1 ? 'Private' : 'Public' }} - @if($count > 0) - {{ __('playlist.play') }} - @endif -

- Delete +
+ + + + +
@endforeach diff --git a/routes/user.php b/routes/user.php index e0bff80..e6372bf 100644 --- a/routes/user.php +++ b/routes/user.php @@ -42,6 +42,7 @@ Route::middleware('auth')->group(function () { Route::get('/user/playlists', [PlaylistController::class, 'playlists'])->name('profile.playlists'); Route::get('/user/playlist/{playlist_id}', [PlaylistController::class, 'showPlaylist'])->name('profile.playlist.show'); Route::post('/create-playlist', [PlaylistController::class, 'createPlaylist'])->name('profile.playlists.create'); + Route::patch('/user/playlist/{playlist_id}', [PlaylistController::class, 'updatePlaylist'])->name('profile.playlist.update'); Route::delete('/user/playlist/{playlist_id}', [PlaylistController::class, 'deletePlaylist'])->name('profile.playlist.delete'); Route::post('/user/playlist-episode', [PlaylistController::class, 'deleteEpisodeFromPlaylist'])->name('playlist.delete.episode');