From 58f85bfc22ddd382f1d8ceda6b2dc796fbb088e9 Mon Sep 17 00:00:00 2001 From: User Date: Sat, 28 Dec 2024 15:34:35 -0500 Subject: [PATCH] History Links LocalStorage for reading mode Debugging with Sentry --- .gitignore | 3 + .../Auth/RegisteredUserController.php | 2 +- app/Http/Controllers/ComicController.php | 7 +- app/Http/Requests/ProfileUpdateRequest.php | 2 +- bootstrap/app.php | 3 +- bun.lockb | Bin 152800 -> 169274 bytes composer.json | 2 + composer.lock | 587 ++++++++++++++++-- config/sentry.php | 129 ++++ package.json | 2 + resources/js/Layouts/AppLayout.jsx | 20 +- resources/js/Pages/Comic/Histories.jsx | 35 +- resources/js/Pages/Comic/Index.jsx | 3 +- resources/js/Pages/Comic/Read.jsx | 32 +- resources/js/app.jsx | 16 + vite.config.js | 21 +- 16 files changed, 758 insertions(+), 106 deletions(-) create mode 100644 config/sentry.php diff --git a/.gitignore b/.gitignore index bec2973..ce96d2c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,6 @@ yarn-error.log /.nova /.vscode /.zed + +# Sentry Config File +.env.sentry-build-plugin diff --git a/app/Http/Controllers/Auth/RegisteredUserController.php b/app/Http/Controllers/Auth/RegisteredUserController.php index 9ec74be..a446ab9 100644 --- a/app/Http/Controllers/Auth/RegisteredUserController.php +++ b/app/Http/Controllers/Auth/RegisteredUserController.php @@ -34,7 +34,7 @@ class RegisteredUserController extends Controller { $request->validate([ 'name' => 'required|string|max:255', - 'email' => 'required|string|lowercase|email|max:255|contains:yumj.in|unique:'.User::class, + 'email' => 'required|string|lowercase|email|max:255|ends_with:@yumj.in|unique:'.User::class, 'password' => ['required', 'confirmed', Rules\Password::defaults()], ]); diff --git a/app/Http/Controllers/ComicController.php b/app/Http/Controllers/ComicController.php index 2a008b3..bcd6971 100644 --- a/app/Http/Controllers/ComicController.php +++ b/app/Http/Controllers/ComicController.php @@ -241,7 +241,12 @@ class ComicController extends Controller public function destroyHistories(Request $request): RedirectResponse { - $histories = $request->user()->readingHistories()->whereIn('reading_histories.id', $request->get('ids'))->delete(); + if (!is_array($request->get('ids')) && $request->get('ids') === 'all') { + $histories = $request->user()->readingHistories()->delete(); + } else { + $histories = $request->user()->readingHistories()->whereIn('reading_histories.id', $request->get('ids'))->delete(); + } + return redirect()->route('comics.histories'); } diff --git a/app/Http/Requests/ProfileUpdateRequest.php b/app/Http/Requests/ProfileUpdateRequest.php index e41248e..e5a56a8 100644 --- a/app/Http/Requests/ProfileUpdateRequest.php +++ b/app/Http/Requests/ProfileUpdateRequest.php @@ -20,7 +20,7 @@ class ProfileUpdateRequest extends FormRequest 'name' => ['required', 'string', 'max:255'], 'email' => [ 'required', - 'contains:@yumj.in', + 'ends_with:@yumj.in', 'string', 'lowercase', 'email', diff --git a/bootstrap/app.php b/bootstrap/app.php index f5a0a6b..682ced6 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -5,6 +5,7 @@ use Illuminate\Foundation\Application; use Illuminate\Foundation\Configuration\Exceptions; use Illuminate\Foundation\Configuration\Middleware; use Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets; +use Sentry\Laravel\Integration; return Application::configure(basePath: dirname(__DIR__)) ->withRouting( @@ -22,5 +23,5 @@ return Application::configure(basePath: dirname(__DIR__)) // }) ->withExceptions(function (Exceptions $exceptions) { - // + Integration::handles($exceptions); })->create(); diff --git a/bun.lockb b/bun.lockb index 56f01cb441c288a331a5fbaf86ba5d4cbd749b87..574592b1bf5fb146af81b281f2f06f8e4610683b 100755 GIT binary patch delta 37929 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 bPH<;0Ed)CXnXx2a;Wue|E3j%I95nlXpLD%F delta 27542 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.2", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0", + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "https://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.8.2" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2024-09-09T07:06:30+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.3", @@ -2721,6 +2858,67 @@ ], "time": "2024-07-20T21:41:07+00:00" }, + { + "name": "predis/predis", + "version": "v2.3.0", + "source": { + "type": "git", + "url": "https://github.com/predis/predis.git", + "reference": "bac46bfdb78cd6e9c7926c697012aae740cb9ec9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/predis/predis/zipball/bac46bfdb78cd6e9c7926c697012aae740cb9ec9", + "reference": "bac46bfdb78cd6e9c7926c697012aae740cb9ec9", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.3", + "phpstan/phpstan": "^1.9", + "phpunit/phpunit": "^8.0 || ^9.4" + }, + "suggest": { + "ext-relay": "Faster connection with in-memory caching (>=0.6.2)" + }, + "type": "library", + "autoload": { + "psr-4": { + "Predis\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Till Krüss", + "homepage": "https://till.im", + "role": "Maintainer" + } + ], + "description": "A flexible and feature-complete Redis client for PHP.", + "homepage": "http://github.com/predis/predis", + "keywords": [ + "nosql", + "predis", + "redis" + ], + "support": { + "issues": "https://github.com/predis/predis/issues", + "source": "https://github.com/predis/predis/tree/v2.3.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/tillkruss", + "type": "github" + } + ], + "time": "2024-11-21T20:00:02+00:00" + }, { "name": "psr/clock", "version": "1.0.0", @@ -3437,6 +3635,184 @@ ], "time": "2024-04-27T21:32:50+00:00" }, + { + "name": "sentry/sentry", + "version": "4.10.0", + "source": { + "type": "git", + "url": "https://github.com/getsentry/sentry-php.git", + "reference": "2af937d47d8aadb8dab0b1d7b9557e495dd12856" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/2af937d47d8aadb8dab0b1d7b9557e495dd12856", + "reference": "2af937d47d8aadb8dab0b1d7b9557e495dd12856", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "guzzlehttp/psr7": "^1.8.4|^2.1.1", + "jean85/pretty-package-versions": "^1.5|^2.0.4", + "php": "^7.2|^8.0", + "psr/log": "^1.0|^2.0|^3.0", + "symfony/options-resolver": "^4.4.30|^5.0.11|^6.0|^7.0" + }, + "conflict": { + "raven/raven": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.4", + "guzzlehttp/promises": "^2.0.3", + "guzzlehttp/psr7": "^1.8.4|^2.1.1", + "monolog/monolog": "^1.6|^2.0|^3.0", + "phpbench/phpbench": "^1.0", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^8.5|^9.6", + "symfony/phpunit-bridge": "^5.2|^6.0|^7.0", + "vimeo/psalm": "^4.17" + }, + "suggest": { + "monolog/monolog": "Allow sending log messages to Sentry by using the included Monolog handler." + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Sentry\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sentry", + "email": "accounts@sentry.io" + } + ], + "description": "PHP SDK for Sentry (http://sentry.io)", + "homepage": "http://sentry.io", + "keywords": [ + "crash-reporting", + "crash-reports", + "error-handler", + "error-monitoring", + "log", + "logging", + "profiling", + "sentry", + "tracing" + ], + "support": { + "issues": "https://github.com/getsentry/sentry-php/issues", + "source": "https://github.com/getsentry/sentry-php/tree/4.10.0" + }, + "funding": [ + { + "url": "https://sentry.io/", + "type": "custom" + }, + { + "url": "https://sentry.io/pricing/", + "type": "custom" + } + ], + "time": "2024-11-06T07:44:19+00:00" + }, + { + "name": "sentry/sentry-laravel", + "version": "4.10.2", + "source": { + "type": "git", + "url": "https://github.com/getsentry/sentry-laravel.git", + "reference": "0e2e5bc4311da51349487afcf67b8fca937f6d94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/0e2e5bc4311da51349487afcf67b8fca937f6d94", + "reference": "0e2e5bc4311da51349487afcf67b8fca937f6d94", + "shasum": "" + }, + "require": { + "illuminate/support": "^6.0 | ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0", + "nyholm/psr7": "^1.0", + "php": "^7.2 | ^8.0", + "sentry/sentry": "^4.10", + "symfony/psr-http-message-bridge": "^1.0 | ^2.0 | ^6.0 | ^7.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.11", + "guzzlehttp/guzzle": "^7.2", + "laravel/folio": "^1.1", + "laravel/framework": "^6.0 | ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0", + "livewire/livewire": "^2.0 | ^3.0", + "mockery/mockery": "^1.3", + "orchestra/testbench": "^4.7 | ^5.1 | ^6.0 | ^7.0 | ^8.0 | ^9.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8.4 | ^9.3 | ^10.4" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Sentry": "Sentry\\Laravel\\Facade" + }, + "providers": [ + "Sentry\\Laravel\\ServiceProvider", + "Sentry\\Laravel\\Tracing\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-0": { + "Sentry\\Laravel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sentry", + "email": "accounts@sentry.io" + } + ], + "description": "Laravel SDK for Sentry (https://sentry.io)", + "homepage": "https://sentry.io", + "keywords": [ + "crash-reporting", + "crash-reports", + "error-handler", + "error-monitoring", + "laravel", + "log", + "logging", + "profiling", + "sentry", + "tracing" + ], + "support": { + "issues": "https://github.com/getsentry/sentry-laravel/issues", + "source": "https://github.com/getsentry/sentry-laravel/tree/4.10.2" + }, + "funding": [ + { + "url": "https://sentry.io/", + "type": "custom" + }, + { + "url": "https://sentry.io/pricing/", + "type": "custom" + } + ], + "time": "2024-12-17T11:38:58+00:00" + }, { "name": "symfony/clock", "version": "v7.2.0", @@ -4387,6 +4763,73 @@ ], "time": "2024-12-07T08:50:44+00:00" }, + { + "name": "symfony/options-resolver", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-20T11:17:29+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.31.0", @@ -5084,6 +5527,89 @@ ], "time": "2024-11-06T14:24:19+00:00" }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "03f2f72319e7acaf2a9f6fcbe30ef17eec51594f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/03f2f72319e7acaf2a9f6fcbe30ef17eec51594f", + "reference": "03f2f72319e7acaf2a9f6fcbe30ef17eec51594f", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/http-message": "^1.0|^2.0", + "symfony/http-foundation": "^6.4|^7.0" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-kernel": "<6.4" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "php-http/discovery": "^1.15", + "psr/log": "^1.1.4|^2|^3", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "https://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-26T08:57:56+00:00" + }, { "name": "symfony/routing", "version": "v7.2.0", @@ -6392,65 +6918,6 @@ }, "time": "2020-07-09T08:09:16+00:00" }, - { - "name": "jean85/pretty-package-versions", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/3c4e5f62ba8d7de1734312e4fff32f67a8daaf10", - "reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.1.0", - "php": "^7.4|^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.2", - "jean85/composer-provided-replaced-stub-package": "^1.0", - "phpstan/phpstan": "^1.4", - "phpunit/phpunit": "^7.5|^8.5|^9.6", - "vimeo/psalm": "^4.3 || ^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Jean85\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alessandro Lai", - "email": "alessandro.lai85@gmail.com" - } - ], - "description": "A library to get pretty versions strings of installed dependencies", - "keywords": [ - "composer", - "package", - "release", - "versions" - ], - "support": { - "issues": "https://github.com/Jean85/pretty-package-versions/issues", - "source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.0" - }, - "time": "2024-11-18T16:19:46+00:00" - }, { "name": "laravel/breeze", "version": "v2.3.0", diff --git a/config/sentry.php b/config/sentry.php new file mode 100644 index 0000000..b159b0a --- /dev/null +++ b/config/sentry.php @@ -0,0 +1,129 @@ + env('SENTRY_LARAVEL_DSN', env('SENTRY_DSN')), + + // @see https://spotlightjs.com/ + // 'spotlight' => env('SENTRY_SPOTLIGHT', false), + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#logger + // 'logger' => Sentry\Logger\DebugFileLogger::class, // By default this will log to `storage_path('logs/sentry.log')` + + // The release version of your application + // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) + 'release' => env('SENTRY_RELEASE'), + + // When left empty or `null` the Laravel environment will be used (usually discovered from `APP_ENV` in your `.env`) + 'environment' => env('SENTRY_ENVIRONMENT'), + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#sample-rate + 'sample_rate' => env('SENTRY_SAMPLE_RATE') === null ? 1.0 : (float) env('SENTRY_SAMPLE_RATE'), + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#traces-sample-rate + 'traces_sample_rate' => env('SENTRY_TRACES_SAMPLE_RATE') === null ? null : (float) env('SENTRY_TRACES_SAMPLE_RATE'), + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#profiles-sample-rate + 'profiles_sample_rate' => env('SENTRY_PROFILES_SAMPLE_RATE') === null ? null : (float) env('SENTRY_PROFILES_SAMPLE_RATE'), + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#send-default-pii + 'send_default_pii' => env('SENTRY_SEND_DEFAULT_PII', false), + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#ignore-exceptions + // 'ignore_exceptions' => [], + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#ignore-transactions + 'ignore_transactions' => [ + // Ignore Laravel's default health URL + '/up', + ], + + // Breadcrumb specific configuration + 'breadcrumbs' => [ + // Capture Laravel logs as breadcrumbs + 'logs' => env('SENTRY_BREADCRUMBS_LOGS_ENABLED', true), + + // Capture Laravel cache events (hits, writes etc.) as breadcrumbs + 'cache' => env('SENTRY_BREADCRUMBS_CACHE_ENABLED', true), + + // Capture Livewire components like routes as breadcrumbs + 'livewire' => env('SENTRY_BREADCRUMBS_LIVEWIRE_ENABLED', true), + + // Capture SQL queries as breadcrumbs + 'sql_queries' => env('SENTRY_BREADCRUMBS_SQL_QUERIES_ENABLED', true), + + // Capture SQL query bindings (parameters) in SQL query breadcrumbs + 'sql_bindings' => env('SENTRY_BREADCRUMBS_SQL_BINDINGS_ENABLED', false), + + // Capture queue job information as breadcrumbs + 'queue_info' => env('SENTRY_BREADCRUMBS_QUEUE_INFO_ENABLED', true), + + // Capture command information as breadcrumbs + 'command_info' => env('SENTRY_BREADCRUMBS_COMMAND_JOBS_ENABLED', true), + + // Capture HTTP client request information as breadcrumbs + 'http_client_requests' => env('SENTRY_BREADCRUMBS_HTTP_CLIENT_REQUESTS_ENABLED', true), + + // Capture send notifications as breadcrumbs + 'notifications' => env('SENTRY_BREADCRUMBS_NOTIFICATIONS_ENABLED', true), + ], + + // Performance monitoring specific configuration + 'tracing' => [ + // Trace queue jobs as their own transactions (this enables tracing for queue jobs) + 'queue_job_transactions' => env('SENTRY_TRACE_QUEUE_ENABLED', true), + + // Capture queue jobs as spans when executed on the sync driver + 'queue_jobs' => env('SENTRY_TRACE_QUEUE_JOBS_ENABLED', true), + + // Capture SQL queries as spans + 'sql_queries' => env('SENTRY_TRACE_SQL_QUERIES_ENABLED', true), + + // Capture SQL query bindings (parameters) in SQL query spans + 'sql_bindings' => env('SENTRY_TRACE_SQL_BINDINGS_ENABLED', false), + + // Capture where the SQL query originated from on the SQL query spans + 'sql_origin' => env('SENTRY_TRACE_SQL_ORIGIN_ENABLED', true), + + // Define a threshold in milliseconds for SQL queries to resolve their origin + 'sql_origin_threshold_ms' => env('SENTRY_TRACE_SQL_ORIGIN_THRESHOLD_MS', 100), + + // Capture views rendered as spans + 'views' => env('SENTRY_TRACE_VIEWS_ENABLED', true), + + // Capture Livewire components as spans + 'livewire' => env('SENTRY_TRACE_LIVEWIRE_ENABLED', true), + + // Capture HTTP client requests as spans + 'http_client_requests' => env('SENTRY_TRACE_HTTP_CLIENT_REQUESTS_ENABLED', true), + + // Capture Laravel cache events (hits, writes etc.) as spans + 'cache' => env('SENTRY_TRACE_CACHE_ENABLED', true), + + // Capture Redis operations as spans (this enables Redis events in Laravel) + 'redis_commands' => env('SENTRY_TRACE_REDIS_COMMANDS', false), + + // Capture where the Redis command originated from on the Redis command spans + 'redis_origin' => env('SENTRY_TRACE_REDIS_ORIGIN_ENABLED', true), + + // Capture send notifications as spans + 'notifications' => env('SENTRY_TRACE_NOTIFICATIONS_ENABLED', true), + + // Enable tracing for requests without a matching route (404's) + 'missing_routes' => env('SENTRY_TRACE_MISSING_ROUTES_ENABLED', false), + + // Configures if the performance trace should continue after the response has been sent to the user until the application terminates + // This is required to capture any spans that are created after the response has been sent like queue jobs dispatched using `dispatch(...)->afterResponse()` for example + 'continue_after_response' => env('SENTRY_TRACE_CONTINUE_AFTER_RESPONSE', true), + + // Enable the tracing integrations supplied by Sentry (recommended) + 'default_integrations' => env('SENTRY_TRACE_DEFAULT_INTEGRATIONS_ENABLED', true), + ], + +]; diff --git a/package.json b/package.json index eeb6c64..39754b8 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,8 @@ "@radix-ui/react-tabs": "^1.1.2", "@radix-ui/react-toast": "^1.2.4", "@radix-ui/react-tooltip": "^1.1.6", + "@sentry/react": "^8.47.0", + "@sentry/vite-plugin": "^2.22.7", "@tanstack/react-table": "^8.20.6", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/resources/js/Layouts/AppLayout.jsx b/resources/js/Layouts/AppLayout.jsx index 949efab..2edf37d 100644 --- a/resources/js/Layouts/AppLayout.jsx +++ b/resources/js/Layouts/AppLayout.jsx @@ -1,14 +1,16 @@ -import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar'; +import { useEffect, useState } from 'react'; +import { Link } from '@inertiajs/react'; +import { Moon, Sun } from 'lucide-react'; + +import { Separator } from '@radix-ui/react-separator'; +import { Tooltip, TooltipProvider, TooltipTrigger } from '@radix-ui/react-tooltip'; + import { AppSidebar } from '@/components/ui/app-sidebar.jsx'; -import { Separator } from "@radix-ui/react-separator"; -import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList } from "@/components/ui/breadcrumb"; -import { Toaster } from '@/components/ui/toaster'; +import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList } from '@/components/ui/breadcrumb'; import { Button } from '@/components/ui/button'; -import { Moon, Settings, Sun } from 'lucide-react'; -import { Link, usePage } from '@inertiajs/react'; -import { useEffect, useState } from "react"; -import { Tooltip, TooltipProvider, TooltipTrigger } from "@radix-ui/react-tooltip"; -import { TooltipContent } from "@/components/ui/tooltip.jsx"; +import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar'; +import { TooltipContent } from '@/components/ui/tooltip.jsx'; +import { Toaster } from '@/components/ui/toaster'; export default function AppLayout({ auth, header, children, toolbar }) { diff --git a/resources/js/Pages/Comic/Histories.jsx b/resources/js/Pages/Comic/Histories.jsx index 6b7f13b..67dd464 100644 --- a/resources/js/Pages/Comic/Histories.jsx +++ b/resources/js/Pages/Comic/Histories.jsx @@ -1,5 +1,5 @@ -import { useState } from "react"; -import { Head, router } from '@inertiajs/react'; +import { useState } from 'react'; +import { Head, Link, router } from '@inertiajs/react'; import AppLayout from '@/Layouts/AppLayout.jsx'; import { BreadcrumbItem, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb"; @@ -24,16 +24,9 @@ export default function Histories({ auth, histories }) { } } - const deleteButtonOnClickHandler = (e) => { - if (ids.length === 0) { - toast({ - title: "Error", - description: `No items selected.`, - }); - return; - } + const deleteButtonOnClickHandler = () => { router.visit(route('comics.destroyHistories'), { - data: { ids: ids }, + data: (ids.length > 0) ? { ids: ids } : { ids: 'all' }, method: "PATCH", only: ['histories'], onSuccess: data => { @@ -58,15 +51,17 @@ export default function Histories({ auth, histories }) { Histories
-
- +
+
Select - Comic Chapter + Comic Read at @@ -80,8 +75,16 @@ export default function Histories({ auth, histories }) { onChange={ (e) => checkboxOnChangeHandler(e) } /> - { h.name } - { h.comic.name } + + + { h.name } + + + + + { h.comic.name } + + { h.created_at } )) } diff --git a/resources/js/Pages/Comic/Index.jsx b/resources/js/Pages/Comic/Index.jsx index a85871b..e09a0b6 100644 --- a/resources/js/Pages/Comic/Index.jsx +++ b/resources/js/Pages/Comic/Index.jsx @@ -58,8 +58,9 @@ export default function Index({ comics, offset, auth }) { Home -
+
+ ;
diff --git a/resources/js/Pages/Comic/Read.jsx b/resources/js/Pages/Comic/Read.jsx index 45cbc2b..dc4b315 100644 --- a/resources/js/Pages/Comic/Read.jsx +++ b/resources/js/Pages/Comic/Read.jsx @@ -1,18 +1,22 @@ import { Head, Link, router } from '@inertiajs/react'; import AppLayout from '@/Layouts/AppLayout.jsx'; import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; -import { BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb.jsx"; -import { Button } from "@/components/ui/button"; import { ChevronFirst, ChevronLast, Rows3, Settings } from "lucide-react"; +import { Tooltip, TooltipProvider, TooltipTrigger } from '@radix-ui/react-tooltip'; + +import { throttle } from 'lodash'; + +import { BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator } from '@/components/ui/breadcrumb'; +import { Button } from '@/components/ui/button'; import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; -import PrimaryButton from "@/components/PrimaryButton.jsx"; -import { Switch } from "@/components/ui/switch"; -import { Tooltip, TooltipProvider, TooltipTrigger } from "@radix-ui/react-tooltip"; -import { TooltipContent } from "@/components/ui/tooltip.jsx"; -import { throttle } from "lodash"; +import PrimaryButton from '@/components/PrimaryButton'; +import { Switch } from '@/components/ui/switch'; +import { TooltipContent } from "@/components/ui/tooltip"; export default function Read({ auth, comic, chapter }) { + const validReadingModes = ['rtl', 'utd']; + const [readingMode, setReadingMode] = useState('rtl'); // rtl, utd const [isTwoPagesPerScreen, setIsTwoPagePerScreen] = useState(false); const [currentImage, setCurrentImage] = useState(1); @@ -24,6 +28,14 @@ export default function Read({ auth, comic, chapter }) { const [loading, setLoading] = useState(true); + const getLocalStorageReadingMode = () => { + if (window.localStorage.getItem('readingMode') !== null && validReadingModes.includes(window.localStorage.getItem('readingMode'))) { + return window.localStorage.getItem('readingMode'); + } + + return "rtl"; + } + function useWindowSize() { const [size, setSize] = useState([0, 0]); useLayoutEffect(() => { @@ -41,8 +53,10 @@ export default function Read({ auth, comic, chapter }) { const toggleReadingMode = (e) => { if (e) { + window.localStorage.setItem('readingMode', 'utd'); setReadingMode('utd'); } else { + window.localStorage.setItem('readingMode', 'rtl'); setReadingMode('rtl'); } } @@ -154,7 +168,7 @@ export default function Read({ auth, comic, chapter }) {

Turn on for UTD mode

- toggleReadingMode(e) } /> @@ -227,6 +241,8 @@ export default function Read({ auth, comic, chapter }) { }, [windowSize]); useEffect(() => { + setReadingMode(getLocalStorageReadingMode()); + if (!ref.current) return; const handleScroll = () => { diff --git a/resources/js/app.jsx b/resources/js/app.jsx index 9f00218..e2f8fa9 100644 --- a/resources/js/app.jsx +++ b/resources/js/app.jsx @@ -4,9 +4,25 @@ import './bootstrap'; import { createInertiaApp } from '@inertiajs/react'; import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'; import { createRoot } from 'react-dom/client'; +import * as Sentry from "@sentry/react"; const appName = import.meta.env.VITE_APP_NAME || 'Laravel'; +Sentry.init({ + dsn: "https://2adec7430e89618582219032ea835a8d@o1017868.ingest.us.sentry.io/4508547646029824", + integrations: [ + Sentry.browserTracingIntegration(), + Sentry.replayIntegration(), + ], + // Tracing + tracesSampleRate: 0.1, // Capture 10% of the transactions + // Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled + tracePropagationTargets: ["localhost", /^https:\/\/c\.yumj\.in/], + // Session Replay + replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production. + replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur. +}); + createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name) => diff --git a/vite.config.js b/vite.config.js index 19f2908..d7b2ea6 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,13 +1,18 @@ +import { sentryVitePlugin } from "@sentry/vite-plugin"; import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; import react from '@vitejs/plugin-react'; export default defineConfig({ - plugins: [ - laravel({ - input: 'resources/js/app.jsx', - refresh: true, - }), - react(), - ], -}); + plugins: [laravel({ + input: 'resources/js/app.jsx', + refresh: true, + }), react(), sentryVitePlugin({ + org: "pokebeacon", + project: "cv4-react" + })], + + build: { + sourcemap: true + } +}); \ No newline at end of file