Skip to content

Commit

Permalink
feat!: make app progressive
Browse files Browse the repository at this point in the history
  • Loading branch information
phanan committed Jul 4, 2022
1 parent a895952 commit fbbe434
Show file tree
Hide file tree
Showing 208 changed files with 5,039 additions and 7,830 deletions.
14 changes: 11 additions & 3 deletions app/Console/Commands/PruneLibraryCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@

namespace App\Console\Commands;

use App\Events\LibraryChanged;
use App\Services\LibraryManager;
use Illuminate\Console\Command;

class PruneLibraryCommand extends Command
{
protected $signature = 'koel:prune';
protected $description = 'Remove empty artists and albums';

public function handle(): void
public function __construct(private LibraryManager $libraryManager)
{
event(new LibraryChanged());
parent::__construct();
}

public function handle(): int
{
$this->libraryManager->prune();

$this->info('Empty artists and albums removed.');

return Command::SUCCESS;
}
}
7 changes: 0 additions & 7 deletions app/Events/MediaCacheObsolete.php

This file was deleted.

4 changes: 2 additions & 2 deletions app/Http/Controllers/API/Interaction/BatchLikeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ class BatchLikeController extends Controller
{
public function store(BatchInteractionRequest $request)
{
$interactions = $this->interactionService->batchLike((array) $request->songs, $this->currentUser);
$interactions = $this->interactionService->batchLike((array) $request->songs, $this->user);

return response()->json($interactions);
}

public function destroy(BatchInteractionRequest $request)
{
$this->interactionService->batchUnlike((array) $request->songs, $this->currentUser);
$this->interactionService->batchUnlike((array) $request->songs, $this->user);

return response()->noContent();
}
Expand Down
4 changes: 2 additions & 2 deletions app/Http/Controllers/API/Interaction/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ class Controller extends BaseController
protected InteractionService $interactionService;

/** @var User */
protected ?Authenticatable $currentUser = null;
protected ?Authenticatable $user = null;

public function __construct(InteractionService $interactionService, ?Authenticatable $currentUser)
{
$this->interactionService = $interactionService;
$this->currentUser = $currentUser;
$this->user = $currentUser;
}
}
2 changes: 1 addition & 1 deletion app/Http/Controllers/API/Interaction/LikeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ class LikeController extends Controller
{
public function store(SongLikeRequest $request)
{
return response()->json($this->interactionService->toggleLike($request->song, $this->currentUser));
return response()->json($this->interactionService->toggleLike($request->song, $this->user));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class PlayCountController extends Controller
{
public function store(StorePlayCountRequest $request)
{
$interaction = $this->interactionService->increasePlayCount($request->song, $this->currentUser);
$interaction = $this->interactionService->increasePlayCount($request->song, $this->user);
event(new SongStartedPlaying($interaction->song, $interaction->user));

return response()->json($interaction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,24 @@

namespace App\Http\Controllers\API\Interaction;

use App\Models\User;
use App\Repositories\InteractionRepository;
use App\Services\InteractionService;
use Illuminate\Contracts\Auth\Authenticatable;

class RecentlyPlayedController extends Controller
{
private InteractionRepository $interactionRepository;

/** @param User $user */
public function __construct(
InteractionService $interactionService,
InteractionRepository $interactionRepository,
?Authenticatable $currentUser
protected InteractionService $interactionService,
protected InteractionRepository $interactionRepository,
protected ?Authenticatable $user
) {
parent::__construct($interactionService, $currentUser);

$this->interactionRepository = $interactionRepository;
parent::__construct($interactionService, $user);
}

public function index(?int $count = null)
{
return response()->json($this->interactionRepository->getRecentlyPlayed($this->currentUser, $count));
return response()->json($this->interactionRepository->getRecentlyPlayed($this->user, $count));
}
}
38 changes: 18 additions & 20 deletions app/Http/Controllers/API/ProfileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,36 @@
namespace App\Http\Controllers\API;

use App\Http\Requests\API\ProfileUpdateRequest;
use App\Http\Resources\UserResource;
use App\Models\User;
use App\Services\TokenManager;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Hashing\Hasher as Hash;
use Illuminate\Contracts\Hashing\Hasher;
use Illuminate\Validation\ValidationException;

class ProfileController extends Controller
{
private Hash $hash;
private TokenManager $tokenManager;

/** @var User */
private ?Authenticatable $currentUser;

public function __construct(Hash $hash, TokenManager $tokenManager, ?Authenticatable $currentUser)
{
$this->hash = $hash;
$this->tokenManager = $tokenManager;
$this->currentUser = $currentUser;
/** @param User $user */
public function __construct(
private Hasher $hash,
private TokenManager $tokenManager,
private ?Authenticatable $user
) {
}

public function show()
{
return response()->json($this->currentUser);
return UserResource::make($this->user);
}

public function update(ProfileUpdateRequest $request)
{
if (config('koel.misc.demo')) {
return response()->json();
return response()->noContent();
}

throw_unless(
$this->hash->check($request->current_password, $this->currentUser->password),
$this->hash->check($request->current_password, $this->user->password),
ValidationException::withMessages(['current_password' => 'Invalid current password'])
);

Expand All @@ -46,12 +42,14 @@ public function update(ProfileUpdateRequest $request)
$data['password'] = $this->hash->make($request->new_password);
}

$this->currentUser->update($data);
$this->user->update($data);

$responseData = $request->new_password
? ['token' => $this->tokenManager->refreshToken($this->currentUser)->plainTextToken]
: [];
$response = UserResource::make($this->user)->response();

if ($request->new_password) {
$response->header('Authorization', $this->tokenManager->refreshToken($this->user)->plainTextToken);
}

return response()->json($responseData);
return $response;
}
}
41 changes: 29 additions & 12 deletions app/Http/Controllers/API/SongController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,46 @@
namespace App\Http\Controllers\API;

use App\Http\Requests\API\SongUpdateRequest;
use App\Models\Song;
use App\Http\Resources\AlbumResource;
use App\Http\Resources\ArtistResource;
use App\Http\Resources\SongResource;
use App\Models\User;
use App\Repositories\AlbumRepository;
use App\Repositories\ArtistRepository;
use App\Services\LibraryManager;
use App\Services\SongService;
use App\Values\SongUpdateData;
use Illuminate\Contracts\Auth\Authenticatable;

class SongController extends Controller
{
private ArtistRepository $artistRepository;
private AlbumRepository $albumRepository;

public function __construct(ArtistRepository $artistRepository, AlbumRepository $albumRepository)
{
$this->artistRepository = $artistRepository;
$this->albumRepository = $albumRepository;
/** @param User $user */
public function __construct(
private SongService $songService,
private AlbumRepository $albumRepository,
private ArtistRepository $artistRepository,
private LibraryManager $libraryManager,
private ?Authenticatable $user
) {
}

public function update(SongUpdateRequest $request)
{
$updatedSongs = Song::updateInfo($request->songs, $request->data);
$updatedSongs = $this->songService->updateSongs($request->songs, SongUpdateData::fromRequest($request));
$albums = $this->albumRepository->getByIds($updatedSongs->pluck('album_id')->toArray(), $this->user);

$artists = $this->artistRepository->getByIds(
array_merge(
$updatedSongs->pluck('artist_id')->all(),
$updatedSongs->pluck('album_artist_id')->all()
)
);

return response()->json([
'artists' => $this->artistRepository->getByIds($updatedSongs->pluck('artist_id')->all()),
'albums' => $this->albumRepository->getByIds($updatedSongs->pluck('album_id')->all()),
'songs' => $updatedSongs,
'songs' => SongResource::collection($updatedSongs),
'albums' => AlbumResource::collection($albums),
'artists' => ArtistResource::collection($artists),
'removed' => $this->libraryManager->prune(),
]);
}
}
36 changes: 21 additions & 15 deletions app/Http/Controllers/API/UploadController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,41 @@

namespace App\Http\Controllers\API;

use App\Events\MediaCacheObsolete;
use App\Exceptions\MediaPathNotSetException;
use App\Exceptions\SongUploadFailedException;
use App\Http\Requests\API\UploadRequest;
use App\Http\Resources\AlbumResource;
use App\Http\Resources\SongResource;
use App\Models\User;
use App\Repositories\AlbumRepository;
use App\Repositories\SongRepository;
use App\Services\UploadService;
use Illuminate\Http\JsonResponse;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\Response;

class UploadController extends Controller
{
private UploadService $uploadService;
/** @param User $user */
public function __invoke(
UploadService $uploadService,
AlbumRepository $albumRepository,
SongRepository $songRepository,
UploadRequest $request,
Authenticatable $user
) {
$this->authorize('admin', User::class);

public function __construct(UploadService $uploadService)
{
$this->uploadService = $uploadService;
}

public function store(UploadRequest $request): JsonResponse
{
try {
$song = $this->uploadService->handleUploadedFile($request->file);
$song = $songRepository->getOne($uploadService->handleUploadedFile($request->file)->id);

return response()->json([
'song' => SongResource::make($song),
'album' => AlbumResource::make($albumRepository->getOne($song->album_id)),
]);
} catch (MediaPathNotSetException $e) {
abort(Response::HTTP_FORBIDDEN, $e->getMessage());
} catch (SongUploadFailedException $e) {
abort(Response::HTTP_BAD_REQUEST, $e->getMessage());
}

event(new MediaCacheObsolete());

return response()->json($song->load('album', 'artist'));
}
}
49 changes: 28 additions & 21 deletions app/Http/Controllers/API/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,53 @@

use App\Http\Requests\API\UserStoreRequest;
use App\Http\Requests\API\UserUpdateRequest;
use App\Http\Resources\UserResource;
use App\Models\User;
use Illuminate\Contracts\Hashing\Hasher as Hash;
use App\Repositories\UserRepository;
use App\Services\UserService;

class UserController extends Controller
{
private Hash $hash;
public function __construct(private UserRepository $userRepository, private UserService $userService)
{
}

public function __construct(Hash $hash)
public function index()
{
$this->hash = $hash;
$this->authorize('admin', User::class);

return UserResource::collection($this->userRepository->getAll());
}

public function store(UserStoreRequest $request)
{
return response()->json(User::create([
'name' => $request->name,
'email' => $request->email,
'password' => $this->hash->make($request->password),
'is_admin' => $request->is_admin,
]));
$this->authorize('admin', User::class);

return UserResource::make($this->userService->createUser(
$request->name,
$request->email,
$request->password,
$request->get('is_admin') ?: false
));
}

public function update(UserUpdateRequest $request, User $user)
{
$data = $request->only('name', 'email', 'is_admin');

if ($request->password) {
$data['password'] = $this->hash->make($request->password);
}

$user->update($data);

return response()->json($user);
$this->authorize('admin', User::class);

return UserResource::make($this->userService->updateUser(
$user,
$request->name,
$request->email,
$request->password,
$request->get('is_admin') ?: false
));
}

public function destroy(User $user)
{
$this->authorize('destroy', $user);

$user->delete();
$this->userService->deleteUser($user);

return response()->noContent();
}
Expand Down
Loading

0 comments on commit fbbe434

Please sign in to comment.