user()->favourites()->with(['authors'])->orderBy('upstream_updated_at', 'desc')->get(); return Inertia::render('Comic/Favourites', [ 'favourites' => $favourites, ]); } public function postFavourite(Request $request): JsonResponse { try { // Get pathname to comic_id $comic = Comic::where('pathword', $request->pathword)->firstOrFail(); } catch (ModelNotFoundException $e) { // Fetch from remote $remoteComic = $this->copyManga->comic($request->pathword); $comic = new Comic; $comic->pathword = $remoteComic['comic']['path_word']; $comic->name = $remoteComic['comic']['name']; $comic->cover = $remoteComic['comic']['cover']; $comic->upstream_updated_at = $remoteComic['comic']['datetime_updated']; $comic->uuid = $remoteComic['comic']['uuid']; $comic->alias = explode(',', $remoteComic['comic']['alias']); $comic->description = $remoteComic['comic']['brief']; $comic->metadata = $remoteComic; $comic->save(); } // Set favourite if ($request->user()->favourites()->where('comic_id', $comic->id)->exists()) { $request->user()->favourites()->detach($comic->id); } else { $request->user()->favourites()->attach($comic->id); } return response()->json($request->user()->favourites()->get(['pathword'])->pluck('pathword')); } public function image(Request $request, string $url): ResponseFactory|Application|IlluminateHttpResponse { // TODO: Ref check and make it require auth $fetcher = new ImageFetcher(base64_decode($url)); return response($fetcher->fetch())->withHeaders([ 'Content-Type' => $fetcher->getMimeType()->value, 'Cache-Control' => 'max-age=604800', ]); } public function index(Request $request): Response { $params = []; if ($request->has('tag')) { $params['theme'] = $request->get('tag'); } $comics = $this->copyManga->comics(30, $request->header('offset', 0), $request->get('top', 'all'), $params); // Prep the array for upsert $comicsUpsertArray = []; $authorsUpsertArray = []; foreach ($comics['list'] as $comic) { $comicsUpsertArray[] = [ 'pathword' => $comic['path_word'], 'uuid' => '', 'name' => $comic['name'], 'alias' => '{}', 'description' => '', 'cover' => $comic['cover'], 'upstream_updated_at' => $comic['datetime_updated'], ]; foreach ($comic['author'] as $author) { $authorsUpsertArray[] = [ 'name' => $author['name'] ]; } } // Do an upsert for comics Comic::upsert($comicsUpsertArray, uniqueBy: 'pathword', update: ['upstream_updated_at']); Author::upsert($authorsUpsertArray, uniqueBy: 'name'); // Had to do a second pass to insert the relationships foreach ($comics['list'] as $comic) { // Get the comic id $comicObj = Comic::where('pathword', $comic['path_word'])->first(); foreach ($comic['author'] as $author) { $authorObj = Author::where('name', $author['name'])->first(); $comicObj->authors()->sync($authorObj); } } return Inertia::render('Comic/Index', [ 'comics' => $comics, 'offset' => $request->header('offset', 0) ]); } public function chapters(Request $request, string $pathword = ''): Response { $comic = $this->copyManga->comic($pathword); $chapters = $this->copyManga->chapters($pathword, 200, 0, [], $request->get('group', 'default')); // Get the comic object and fill other parameters $comicObject = Comic::where('pathword', $pathword)->first(); $comicObject->uuid = $comic['comic']['uuid']; $comicObject->alias = explode(',', $comic['comic']['alias']); $comicObject->description = $comic['comic']['brief']; $comicObject->metadata = $comic; $comicObject->save(); // Get the authors and update the pathword foreach ($comic['comic']['author'] as $author) { $authorObj = Author::where('name', $author['name'])->whereNull('pathword')->first(); if ($authorObj) { // Do nothing if pathword already exist $authorObj->pathword = $author['path_word']; $authorObj->save(); } } // Do the Chapters // Prep the array for upsert $arrayForUpsert = []; foreach ($chapters['list'] as $chapter) { $arrayForUpsert[] = [ 'comic_id' => $comicObject->id, 'chapter_uuid' => $chapter['uuid'], 'name' => $chapter['name'], 'order' => $chapter['index'], 'upstream_created_at' => $chapter['datetime_created'], 'metadata' => json_encode($chapter), ]; } // Do an upsert Chapter::upsert($arrayForUpsert, uniqueBy: 'chapter_uuid'); // Get history $histories = $request->user()->readingHistories()->where('reading_histories.comic_id', $comicObject->id) ->distinct()->select('chapter_uuid')->get()->pluck('chapter_uuid'); return Inertia::render('Comic/Chapters', [ 'comic' => $comic, 'chapters' => $chapters, 'histories' => $histories ]); } public function read(Request $request, string $pathword = '', string $uuid = ''): Response { $comic = $this->copyManga->comic($pathword); $chapter = $this->copyManga->chapter($pathword, $uuid); // Get the authors and update the pathword foreach ($comic['comic']['author'] as $author) { $authorObj = Author::where('name', $author['name'])->whereNull('pathword')->first(); if ($authorObj) { // Do nothing if pathword already exist $authorObj->pathword = $author['path_word']; $authorObj->save(); } } $chapterObj = Chapter::where('chapter_uuid', $chapter['chapter']['uuid'])->first(); $comicObj = Comic::where('pathword', $pathword)->first(); $arrayForUpsert = []; foreach ($chapter['sorted'] as $k => $image) { $metadata = $chapter; unset($metadata['sorted']); unset($metadata['chapter']['contents'], $metadata['chapter']['words']); $arrayForUpsert[] = [ 'comic_id' => $comicObj->id, 'chapter_id' => $chapterObj->id, 'order' => $k, 'url' => $image['url'], 'metadata' => json_encode($metadata), ]; } // Do an upsert Image::upsert($arrayForUpsert, uniqueBy: 'url'); // Update history $request->user()->readingHistories()->attach($chapterObj->id, ['comic_id' => $comicObj->id]); return Inertia::render('Comic/Read', [ 'comic' => $comic, 'chapter' => $chapter, ]); } public function histories(Request $request): Response { // Get history $histories = $request->user()->readingHistories()->with(['comic:id,name,pathword'])->orderByDesc('reading_histories.created_at') ->select(['reading_histories.id as hid', 'reading_histories.created_at', 'chapters.comic_id', 'chapters.name'])->paginate(50)->toArray(); return Inertia::render('Comic/Histories', [ 'histories' => $histories ]); } public function destroyHistories(Request $request): RedirectResponse { $histories = $request->user()->readingHistories()->whereIn('reading_histories.id', $request->get('ids'))->delete(); return redirect()->route('comics.histories'); } public function tags() { // TODO $tags = $this->copyManga->tags(); Cache::forever('tags', $tags); return response()->json($tags); } }