From e4f97249ae43425d5ff399e3e714136cfbea5609 Mon Sep 17 00:00:00 2001 From: Allan Kong Date: Fri, 18 Apr 2025 20:08:27 -0600 Subject: [PATCH 01/10] Updated Inertia --- composer.json | 2 +- composer.lock | 38 +++++++++++---------------- package-lock.json | 67 ++++++++++++++++------------------------------- package.json | 2 +- 4 files changed, 39 insertions(+), 70 deletions(-) diff --git a/composer.json b/composer.json index b54b19cd..5ebfb7ee 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "license": "MIT", "require": { "php": "^8.2", - "inertiajs/inertia-laravel": "^1.0", + "inertiajs/inertia-laravel": "^2.0", "joelbutcher/socialstream": "^6.2", "laravel/framework": "^11.31", "laravel/jetstream": "^5.3", diff --git a/composer.lock b/composer.lock index bffa78f9..db760c84 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7e374310093dc0692e1d229ea1a6e12e", + "content-hash": "7725813741904ac1263575e1bcce49b0", "packages": [ { "name": "bacon/bacon-qr-code", @@ -1223,28 +1223,29 @@ }, { "name": "inertiajs/inertia-laravel", - "version": "v1.3.2", + "version": "v2.0.2", "source": { "type": "git", "url": "https://github.com/inertiajs/inertia-laravel.git", - "reference": "7e6a030ffab315099782a4844a2175455f511c68" + "reference": "248e815cf8d41307cbfb735efaa514c118e2f3b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/inertiajs/inertia-laravel/zipball/7e6a030ffab315099782a4844a2175455f511c68", - "reference": "7e6a030ffab315099782a4844a2175455f511c68", + "url": "https://api.github.com/repos/inertiajs/inertia-laravel/zipball/248e815cf8d41307cbfb735efaa514c118e2f3b4", + "reference": "248e815cf8d41307cbfb735efaa514c118e2f3b4", "shasum": "" }, "require": { "ext-json": "*", - "laravel/framework": "^8.74|^9.0|^10.0|^11.0", - "php": "^7.3|~8.0.0|~8.1.0|~8.2.0|~8.3.0|~8.4.0", - "symfony/console": "^5.3|^6.0|^7.0" + "laravel/framework": "^10.0|^11.0|^12.0", + "php": "^8.1.0", + "symfony/console": "^6.2|^7.0" }, "require-dev": { + "laravel/pint": "^1.16", "mockery/mockery": "^1.3.3", - "orchestra/testbench": "^6.45|^7.44|^8.25|^9.3", - "phpunit/phpunit": "^8.0|^9.5.8|^10.4", + "orchestra/testbench": "^8.0|^9.2|^10.0", + "phpunit/phpunit": "^10.4|^11.5", "roave/security-advisories": "dev-master" }, "suggest": { @@ -1256,9 +1257,6 @@ "providers": [ "Inertia\\ServiceProvider" ] - }, - "branch-alias": { - "dev-master": "1.x-dev" } }, "autoload": { @@ -1287,15 +1285,9 @@ ], "support": { "issues": "https://github.com/inertiajs/inertia-laravel/issues", - "source": "https://github.com/inertiajs/inertia-laravel/tree/v1.3.2" + "source": "https://github.com/inertiajs/inertia-laravel/tree/v2.0.2" }, - "funding": [ - { - "url": "https://github.com/reinink", - "type": "github" - } - ], - "time": "2024-12-05T14:52:50+00:00" + "time": "2025-04-10T15:08:36+00:00" }, { "name": "joelbutcher/socialstream", @@ -10074,12 +10066,12 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, "platform": { "php": "^8.2" }, - "platform-dev": {}, + "platform-dev": [], "plugin-api-version": "2.6.0" } diff --git a/package-lock.json b/package-lock.json index 2aef6c0d..878c7fe8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ }, "devDependencies": { "@iconify/vue": "^4.3.0", - "@inertiajs/vue3": "^1.0.14", + "@inertiajs/vue3": "^2.0.8", "@tailwindcss/forms": "^0.5.7", "@tailwindcss/typography": "^0.5.10", "@vitejs/plugin-vue": "^5.0.0", @@ -536,28 +536,26 @@ } }, "node_modules/@inertiajs/core": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@inertiajs/core/-/core-1.3.0.tgz", - "integrity": "sha512-TJ8R1eUYY473m9DaKlCPRdHTdznFWTDuy5VvEzXg3t/hohbDQedLj46yn/uAqziJPEUZJrSftZzPI2NMzL9tQA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@inertiajs/core/-/core-2.0.8.tgz", + "integrity": "sha512-YE+b5FktbSSaWJt4CjCHy7z3t+IV97G/8kD33mkj2Fqqf+Jfsypd/jsOuxrQGSMDpIyAGR6EDoaiuss6+JuIPA==", "dev": true, "license": "MIT", "dependencies": { - "axios": "^1.6.0", - "deepmerge": "^4.0.0", - "nprogress": "^0.2.0", + "axios": "^1.8.2", + "es-toolkit": "^1.34.1", "qs": "^6.9.0" } }, "node_modules/@inertiajs/vue3": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@inertiajs/vue3/-/vue3-1.3.0.tgz", - "integrity": "sha512-GizqdCM3u4JWunit3uUbW4fEmTLKQTi1W7VvPRdrNy8XDt4Qy2cCmfFjq+aH5tHBSS3fI/ngYuhN7XvwqNaKvw==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@inertiajs/vue3/-/vue3-2.0.8.tgz", + "integrity": "sha512-XzerZJxxiTE40U6X9MggjQivUpHjHNaDnrts8TVnYIO6iRMSzrgqVMW/9DXIZGAuwE1z832Kj58/sWAefx+/BQ==", "dev": true, "license": "MIT", "dependencies": { - "@inertiajs/core": "1.3.0", - "lodash.clonedeep": "^4.5.0", - "lodash.isequal": "^4.5.0" + "@inertiajs/core": "2.0.8", + "es-toolkit": "^1.33.0" }, "peerDependencies": { "vue": "^3.0.0" @@ -1729,16 +1727,6 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1869,6 +1857,17 @@ "node": ">= 0.4" } }, + "node_modules/es-toolkit": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.35.0.tgz", + "integrity": "sha512-kVHyrRoC0eLc1hWJ6npG8nNFtOG+nWfcMI+XE0RaFO0gxd6Ions8r0O/U64QyZgY7IeidUnS5oZlRZYUgMGCAg==", + "dev": true, + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, "node_modules/esbuild": { "version": "0.25.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", @@ -2379,21 +2378,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", @@ -2574,13 +2558,6 @@ "node": ">=0.10.0" } }, - "node_modules/nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", - "dev": true, - "license": "MIT" - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", diff --git a/package.json b/package.json index c3a539df..102e8918 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ }, "devDependencies": { "@iconify/vue": "^4.3.0", - "@inertiajs/vue3": "^1.0.14", + "@inertiajs/vue3": "^2.0.8", "@tailwindcss/forms": "^0.5.7", "@tailwindcss/typography": "^0.5.10", "@vitejs/plugin-vue": "^5.0.0", From a735ac6f3b13457b7ab1457e5b6f82067bd2ef16 Mon Sep 17 00:00:00 2001 From: Allan Kong Date: Fri, 18 Apr 2025 20:08:46 -0600 Subject: [PATCH 02/10] Deferred loading, and modulated the comments system --- app/Http/Controllers/CommentController.php | 42 +------------- .../ComputerScienceResourceController.php | 8 +-- app/Services/CommentService.php | 50 ++++++++++++++--- .../seeders/ComputerScienceResourceSeeder.php | 2 +- database/seeders/UserSeeder.php | 16 +++--- resources/js/Pages/Resources/Show.vue | 55 ++++++++++++------- 6 files changed, 91 insertions(+), 82 deletions(-) diff --git a/app/Http/Controllers/CommentController.php b/app/Http/Controllers/CommentController.php index 5f68fb24..47fcea01 100644 --- a/app/Http/Controllers/CommentController.php +++ b/app/Http/Controllers/CommentController.php @@ -7,7 +7,6 @@ use App\Http\Resources\CommentResource; use App\Models\Comment; use App\Services\ModelResolverService; -use Illuminate\Database\Eloquent\Collection; use App\Http\Resources\UserResource; use App\Services\CommentService; use Auth; @@ -157,44 +156,7 @@ public function show(string $commentableType, int $commentableId, int $index) $commentableType = $this->modelResolver->getModelClass($commentableType); $paginatedResults = $this->commentService->getPaginatedComments($commentableType, $commentableId, $index); - $nestedComments = new Collection($paginatedResults['comments']); - - // Lazy eager load the user for the root comment and for each reply. - $nestedComments->load(['user', 'replies.user']); - - // Flatten the comments and replies into the desired format. - $flattenedComments = collect(); - - foreach ($nestedComments as $comment) { - // Transform the root comment. - $flattenedComments->push( - new CommentResource($comment) - ); - - // Transform any loaded replies. - if ($comment->relationLoaded('replies')) { - foreach ($comment->replies as $reply) { - $flattenedComments->push( - new CommentResource($reply) - ); - } - } - } - - // Extract unique users into a separate collection. - $users = collect(); - - foreach ($flattenedComments as $comment) { - if ($comment->relationLoaded('user') && $comment->user) { - $users->put($comment->user->id, new UserResource($comment->user)); - } - } - - Log::debug("Returned comments: " . json_encode($flattenedComments)); - return [ - 'comments' => $flattenedComments, - 'users' => $users->values(), - 'has_more_comments' => $paginatedResults['has_more_comments'], - ]; + + return $paginatedResults; } } diff --git a/app/Http/Controllers/ComputerScienceResourceController.php b/app/Http/Controllers/ComputerScienceResourceController.php index b63ea7d1..955c91b3 100644 --- a/app/Http/Controllers/ComputerScienceResourceController.php +++ b/app/Http/Controllers/ComputerScienceResourceController.php @@ -4,11 +4,7 @@ use App\Http\Requests\ComputerScienceResource\StoreResourceRequest; use App\Models\ComputerScienceResource; -use App\Models\ResourceReview; -use Illuminate\Database\Console\DumpCommand; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; -use Illuminate\Http\Request; use Inertia\Inertia; use Auth; @@ -77,11 +73,9 @@ public function store(StoreResourceRequest $request) */ public function show(ComputerScienceResource $computerScienceResource) { - $reviews = $computerScienceResource->reviews()->orderByDesc('created_at')->get(); - return Inertia::render('Resources/Show', [ 'resource' => fn() => $computerScienceResource->load('user'), - 'reviews' => fn () => $reviews, + 'reviews' => Inertia::defer(fn () => $computerScienceResource->reviews()->orderByDesc('created_at')->get()), ]); } diff --git a/app/Services/CommentService.php b/app/Services/CommentService.php index 754648f9..aaaa33e7 100644 --- a/app/Services/CommentService.php +++ b/app/Services/CommentService.php @@ -2,8 +2,10 @@ namespace App\Services; +use App\Http\Resources\CommentResource; +use App\Http\Resources\UserResource; use App\Models\Comment; -use Illuminate\Support\Collection; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Facades\Log; class CommentService @@ -30,8 +32,8 @@ public function getPaginatedComments(string $commentableType, int $commentableId // Get the root comments: $rootComments = Comment::where([ 'commentable_type' => $commentableType, - 'commentable_id' => $commentableId, - 'depth' => 1, + 'commentable_id' => $commentableId, + 'depth' => 1, ]) ->orderBy('created_at') ->get(); @@ -40,7 +42,7 @@ public function getPaginatedComments(string $commentableType, int $commentableId // Initialize variables $currentCommentsSum = 0; - $commentsToReturn = []; + $resultingPaginatedComments = []; $currentIndex = 0; $hasMoreComments = false; @@ -53,7 +55,7 @@ public function getPaginatedComments(string $commentableType, int $commentableId // Force include oversized comment if it's the first in page Log::warning("Had to force include for oversized comment tree. Should consider increasing the max commentx in config or lowering the replies size limit."); if ($currentIndex === $index) { - $commentsToReturn[] = $comment; + $resultingPaginatedComments[] = $comment; $currentCommentsSum += $childrenCount; } $currentIndex++; @@ -71,13 +73,47 @@ public function getPaginatedComments(string $commentableType, int $commentableId } // Only add comments for the desired index else if ($currentIndex === $index) { - $commentsToReturn[] = $comment; + $resultingPaginatedComments[] = $comment; } $currentCommentsSum += $childrenCount; } + $nestedComments = new Collection($resultingPaginatedComments); + // Lazy eager load the user for the root comment and for each reply. + $nestedComments->load(['user', 'replies.user']); + + // Flatten the comments and replies into the desired format. + $flattenedComments = collect(); + + foreach ($nestedComments as $comment) { + // Transform the root comment. + $flattenedComments->push( + new CommentResource($comment) + ); + + // Transform any loaded replies. + if ($comment->relationLoaded('replies')) { + foreach ($comment->replies as $reply) { + $flattenedComments->push( + new CommentResource($reply) + ); + } + } + } + + // Extract unique users into a separate collection. + $users = collect(); + + foreach ($flattenedComments as $comment) { + if ($comment->relationLoaded('user') && $comment->user) { + $users->put($comment->user->id, new UserResource($comment->user)); + } + } + + Log::debug("Returned comments: " . json_encode($flattenedComments)); return [ - 'comments' => new Collection($commentsToReturn), + 'comments' => $flattenedComments, + 'users' => $users->values(), 'has_more_comments' => $hasMoreComments, ]; } diff --git a/database/seeders/ComputerScienceResourceSeeder.php b/database/seeders/ComputerScienceResourceSeeder.php index 340c9edd..2e315472 100644 --- a/database/seeders/ComputerScienceResourceSeeder.php +++ b/database/seeders/ComputerScienceResourceSeeder.php @@ -14,6 +14,6 @@ class ComputerScienceResourceSeeder extends Seeder */ public function run(): void { - ComputerScienceResource::factory(1)->create(); + ComputerScienceResource::factory(5)->create(); } } diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php index 8d5b38d2..a22feda1 100644 --- a/database/seeders/UserSeeder.php +++ b/database/seeders/UserSeeder.php @@ -19,12 +19,14 @@ public function run(): void Log::info('Running UserSeeder'); User::factory(10)->create(); - User::factory()->create( - [ - 'name'=>'Allan Kong', - 'email'=>'allankong176@gmail.com', - 'password'=>Hash::make('password'), - ] - ); + if (!User::where('name','Allan Kong')->exists()) { + User::factory()->create( + [ + 'name' => 'Allan Kong', + 'email' => 'allankong176@gmail.com', + 'password' => Hash::make('password'), + ] + ); + } } } diff --git a/resources/js/Pages/Resources/Show.vue b/resources/js/Pages/Resources/Show.vue index 36bfd6ed..2ef40e76 100644 --- a/resources/js/Pages/Resources/Show.vue +++ b/resources/js/Pages/Resources/Show.vue @@ -1,9 +1,13 @@