diff --git a/CLAUDE.md b/CLAUDE.md index f583ed4d..dc73db65 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -28,6 +28,7 @@ ## Foundational Context - vue (VUE) - v3 - @laravel/vite-plugin-wayfinder (WAYFINDER) - v0 - eslint (ESLINT) - v9 +- laravel-echo (ECHO) - v2 - prettier (PRETTIER) - v3 ## Conventions diff --git a/GEMINI.md b/GEMINI.md index f583ed4d..dc73db65 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -28,6 +28,7 @@ ## Foundational Context - vue (VUE) - v3 - @laravel/vite-plugin-wayfinder (WAYFINDER) - v0 - eslint (ESLINT) - v9 +- laravel-echo (ECHO) - v2 - prettier (PRETTIER) - v3 ## Conventions diff --git a/app/Broadcasting/PostChannel.php b/app/Broadcasting/PostChannel.php new file mode 100644 index 00000000..de8639b6 --- /dev/null +++ b/app/Broadcasting/PostChannel.php @@ -0,0 +1,30 @@ + $user->id, + 'user_email' => $user->email, + 'post_id' => $post->id, + 'workspace_id' => $post->workspace_id, + ]); + + $result = $post->workspace->hasMember($user); + + Log::info('PostChannel::join result', [ + 'result' => $result, + 'workspace_owner_id' => $post->workspace->user_id, + 'is_owner' => $post->workspace->user_id === $user->id, + ]); + + return $result; + } +} diff --git a/app/Enums/SocialPlatform.php b/app/Enums/SocialPlatform.php index 5d7be70d..1f439853 100644 --- a/app/Enums/SocialPlatform.php +++ b/app/Enums/SocialPlatform.php @@ -91,4 +91,19 @@ public function supportsTextOnly(): bool self::Threads => true, }; } + + public function isEnabled(): bool + { + return config("trypost.platforms.{$this->value}.enabled", true); + } + + /** + * Get all enabled platforms. + * + * @return array + */ + public static function enabled(): array + { + return array_filter(self::cases(), fn (self $platform) => $platform->isEnabled()); + } } diff --git a/app/Events/PostPlatformStatusUpdated.php b/app/Events/PostPlatformStatusUpdated.php new file mode 100644 index 00000000..5cf9c9e2 --- /dev/null +++ b/app/Events/PostPlatformStatusUpdated.php @@ -0,0 +1,44 @@ +postPlatform->post_id), + ]; + } + + public function broadcastWith(): array + { + $post = $this->postPlatform->post->fresh(); + + return [ + 'post_platform' => [ + 'id' => $this->postPlatform->id, + 'status' => $this->postPlatform->status, + 'platform_url' => $this->postPlatform->platform_url, + 'error_message' => $this->postPlatform->error_message, + 'published_at' => $this->postPlatform->published_at?->toISOString(), + ], + 'post' => [ + 'id' => $post->id, + 'status' => $post->status->value, + 'published_at' => $post->published_at?->toISOString(), + ], + ]; + } +} diff --git a/app/Http/Controllers/Auth/FacebookController.php b/app/Http/Controllers/Auth/FacebookController.php index 6c9c3c51..264cc05f 100644 --- a/app/Http/Controllers/Auth/FacebookController.php +++ b/app/Http/Controllers/Auth/FacebookController.php @@ -22,11 +22,11 @@ class FacebookController extends SocialController 'pages_show_list', 'pages_read_engagement', 'pages_manage_posts', - 'pages_read_user_content', ]; public function connect(Request $request, Workspace $workspace): Response { + $this->ensurePlatformEnabled(); $this->authorize('manageAccounts', $workspace); if ($workspace->hasConnectedPlatform($this->platform->value)) { diff --git a/app/Http/Controllers/Auth/InstagramController.php b/app/Http/Controllers/Auth/InstagramController.php index 2c284df8..de93dd90 100644 --- a/app/Http/Controllers/Auth/InstagramController.php +++ b/app/Http/Controllers/Auth/InstagramController.php @@ -14,7 +14,7 @@ class InstagramController extends SocialController { - protected string $driver = 'facebook'; + protected string $driver = 'instagram'; protected SocialPlatform $platform = SocialPlatform::Instagram; @@ -27,6 +27,7 @@ class InstagramController extends SocialController public function connect(Request $request, Workspace $workspace): Response { + $this->ensurePlatformEnabled(); $this->authorize('manageAccounts', $workspace); if ($workspace->hasConnectedPlatform($this->platform->value)) { diff --git a/app/Http/Controllers/Auth/LinkedInController.php b/app/Http/Controllers/Auth/LinkedInController.php index f8ddc2e3..c28dfde7 100644 --- a/app/Http/Controllers/Auth/LinkedInController.php +++ b/app/Http/Controllers/Auth/LinkedInController.php @@ -27,6 +27,7 @@ class LinkedInController extends SocialController public function connect(Request $request, Workspace $workspace): Response { + $this->ensurePlatformEnabled(); $this->authorize('manageAccounts', $workspace); if ($workspace->hasConnectedPlatform($this->platform->value)) { diff --git a/app/Http/Controllers/Auth/LinkedInPageController.php b/app/Http/Controllers/Auth/LinkedInPageController.php index 69f054d1..b083e348 100644 --- a/app/Http/Controllers/Auth/LinkedInPageController.php +++ b/app/Http/Controllers/Auth/LinkedInPageController.php @@ -31,6 +31,7 @@ class LinkedInPageController extends SocialController public function connect(Request $request, Workspace $workspace): SymfonyResponse { + $this->ensurePlatformEnabled(); $this->authorize('manageAccounts', $workspace); if ($workspace->hasConnectedPlatform($this->platform->value)) { diff --git a/app/Http/Controllers/Auth/SocialController.php b/app/Http/Controllers/Auth/SocialController.php index cfc002cd..94bf738d 100644 --- a/app/Http/Controllers/Auth/SocialController.php +++ b/app/Http/Controllers/Auth/SocialController.php @@ -16,13 +16,22 @@ class SocialController extends Controller { + protected SocialPlatform $platform; + + protected function ensurePlatformEnabled(): void + { + if (isset($this->platform) && ! $this->platform->isEnabled()) { + abort(403, 'This platform is currently unavailable.'); + } + } + public function index(Workspace $workspace): Response { $this->authorize('view', $workspace); $connectedAccounts = $workspace->socialAccounts; - $platforms = collect(SocialPlatform::cases())->map(function ($platform) use ($connectedAccounts) { + $platforms = collect(SocialPlatform::enabled())->map(function ($platform) use ($connectedAccounts) { $connected = $connectedAccounts->firstWhere('platform', $platform); return [ @@ -32,7 +41,7 @@ public function index(Workspace $workspace): Response 'connected' => $connected !== null, 'account' => $connected, ]; - }); + })->values(); return Inertia::render('accounts/Index', [ 'workspace' => $workspace, diff --git a/app/Http/Controllers/Auth/ThreadsController.php b/app/Http/Controllers/Auth/ThreadsController.php index dad7b57d..84663cf6 100644 --- a/app/Http/Controllers/Auth/ThreadsController.php +++ b/app/Http/Controllers/Auth/ThreadsController.php @@ -24,6 +24,7 @@ class ThreadsController extends SocialController public function connect(Request $request, Workspace $workspace): Response { + $this->ensurePlatformEnabled(); $this->authorize('manageAccounts', $workspace); if ($workspace->hasConnectedPlatform($this->platform->value)) { diff --git a/app/Http/Controllers/Auth/TikTokController.php b/app/Http/Controllers/Auth/TikTokController.php index df3c8e56..4dcbbadf 100644 --- a/app/Http/Controllers/Auth/TikTokController.php +++ b/app/Http/Controllers/Auth/TikTokController.php @@ -24,6 +24,7 @@ class TikTokController extends SocialController public function connect(Request $request, Workspace $workspace): Response { + $this->ensurePlatformEnabled(); $this->authorize('manageAccounts', $workspace); if ($workspace->hasConnectedPlatform($this->platform->value)) { diff --git a/app/Http/Controllers/Auth/XController.php b/app/Http/Controllers/Auth/XController.php index 260301d8..3bfdde15 100644 --- a/app/Http/Controllers/Auth/XController.php +++ b/app/Http/Controllers/Auth/XController.php @@ -24,6 +24,7 @@ class XController extends SocialController public function connect(Request $request, Workspace $workspace): Response { + $this->ensurePlatformEnabled(); $this->authorize('manageAccounts', $workspace); if ($workspace->hasConnectedPlatform($this->platform->value)) { diff --git a/app/Http/Controllers/Auth/YouTubeController.php b/app/Http/Controllers/Auth/YouTubeController.php index 2ff7e7bd..b243085b 100644 --- a/app/Http/Controllers/Auth/YouTubeController.php +++ b/app/Http/Controllers/Auth/YouTubeController.php @@ -24,6 +24,7 @@ class YouTubeController extends SocialController public function connect(Request $request, Workspace $workspace): Response { + $this->ensurePlatformEnabled(); $this->authorize('manageAccounts', $workspace); if ($workspace->hasConnectedPlatform($this->platform->value)) { diff --git a/app/Jobs/PublishToSocialPlatform.php b/app/Jobs/PublishToSocialPlatform.php index b369d66f..50e91a80 100644 --- a/app/Jobs/PublishToSocialPlatform.php +++ b/app/Jobs/PublishToSocialPlatform.php @@ -3,6 +3,7 @@ namespace App\Jobs; use App\Enums\SocialPlatform; +use App\Events\PostPlatformStatusUpdated; use App\Models\PostPlatform; use App\Services\Social\FacebookPublisher; use App\Services\Social\InstagramPublisher; @@ -29,6 +30,7 @@ public function __construct(public PostPlatform $postPlatform) {} public function handle(): void { $this->postPlatform->markAsPublishing(); + $this->broadcastStatus(); try { $publisher = $this->getPublisher(); @@ -47,6 +49,14 @@ public function handle(): void // Always check and update post status after each platform finishes $this->updatePostStatus(); + + // Broadcast final status + $this->broadcastStatus(); + } + + private function broadcastStatus(): void + { + PostPlatformStatusUpdated::dispatch($this->postPlatform->fresh()); } private function getPublisher(): LinkedInPublisher|LinkedInPagePublisher|XPublisher|TikTokPublisher|YouTubePublisher|FacebookPublisher|InstagramPublisher|ThreadsPublisher diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index c022048b..d111e7d1 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use App\Socialite\InstagramExtendSocialite; use App\Socialite\LinkedInPageExtendSocialite; use Carbon\CarbonImmutable; use Illuminate\Support\Facades\Date; @@ -34,6 +35,7 @@ public function boot(): void protected function configureSocialite(): void { + Event::listen(SocialiteWasCalled::class, InstagramExtendSocialite::class); Event::listen(SocialiteWasCalled::class, LinkedInExtendSocialite::class); Event::listen(SocialiteWasCalled::class, LinkedInPageExtendSocialite::class); Event::listen(SocialiteWasCalled::class, TikTokExtendSocialite::class); diff --git a/app/Services/Social/ThreadsPublisher.php b/app/Services/Social/ThreadsPublisher.php index 9edd7242..41fc48b2 100644 --- a/app/Services/Social/ThreadsPublisher.php +++ b/app/Services/Social/ThreadsPublisher.php @@ -73,7 +73,7 @@ private function publishTextPost(string $userId, string $accessToken, string $co private function publishImagePost(string $userId, string $accessToken, string $content, $media): array { - Log::info('Threads publishing image post', ['user_id' => $userId]); + Log::info('Threads publishing image post', ['user_id' => $userId, 'image_url' => $media->url]); // Step 1: Create container $containerResponse = Http::post("{$this->baseUrl}/{$userId}/threads", [ @@ -93,7 +93,12 @@ private function publishImagePost(string $userId, string $accessToken, string $c $containerId = $containerResponse->json()['id']; - // Step 2: Publish + Log::info('Threads image container created', ['container_id' => $containerId]); + + // Step 2: Wait for image processing + $this->waitForMediaProcessing($containerId, $accessToken); + + // Step 3: Publish return $this->publishContainer($userId, $accessToken, $containerId); } @@ -164,10 +169,8 @@ private function publishCarousel(string $userId, string $accessToken, string $co $childId = $containerResponse->json()['id']; - // Wait for video processing if needed - if ($isVideo) { - $this->waitForMediaProcessing($childId, $accessToken); - } + // Wait for media processing (both images and videos) + $this->waitForMediaProcessing($childId, $accessToken); $childContainers[] = $childId; } @@ -234,32 +237,45 @@ private function waitForMediaProcessing(string $containerId, string $accessToken { for ($i = 0; $i < $maxAttempts; $i++) { $statusResponse = Http::get("{$this->baseUrl}/{$containerId}", [ - 'fields' => 'status', + 'fields' => 'status,error_message', 'access_token' => $accessToken, ]); if ($statusResponse->failed()) { + Log::warning('Threads status check failed', [ + 'container_id' => $containerId, + 'attempt' => $i, + 'body' => $statusResponse->body(), + ]); sleep(3); continue; } - $status = $statusResponse->json()['status'] ?? 'UNKNOWN'; + $data = $statusResponse->json(); + $status = $data['status'] ?? 'UNKNOWN'; - Log::info('Threads media processing status', ['status' => $status, 'attempt' => $i]); + Log::info('Threads media processing status', [ + 'container_id' => $containerId, + 'status' => $status, + 'attempt' => $i, + 'response' => $data, + ]); if ($status === 'FINISHED') { return; } if ($status === 'ERROR') { - throw new \Exception('Threads media processing failed'); + $errorMessage = $data['error_message'] ?? 'Unknown error'; + throw new \Exception('Threads media processing failed: '.$errorMessage); } sleep(3); } - Log::warning('Threads media processing timeout, proceeding anyway'); + Log::warning('Threads media processing timeout', ['container_id' => $containerId]); + throw new \Exception('Threads media processing timeout after '.$maxAttempts.' attempts'); } private function refreshToken(SocialAccount $account): void diff --git a/app/Socialite/InstagramExtendSocialite.php b/app/Socialite/InstagramExtendSocialite.php new file mode 100644 index 00000000..004b59b1 --- /dev/null +++ b/app/Socialite/InstagramExtendSocialite.php @@ -0,0 +1,13 @@ +extendSocialite('instagram', \Laravel\Socialite\Two\FacebookProvider::class); + } +} diff --git a/composer.json b/composer.json index ae6266d7..45722e17 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,8 @@ "mockery/mockery": "^1.6", "nunomaduro/collision": "^8.6", "pestphp/pest": "^4.3", - "pestphp/pest-plugin-laravel": "^4.0" + "pestphp/pest-plugin-laravel": "^4.0", + "spatie/laravel-horizon-watcher": "^1.1" }, "autoload": { "files": [ diff --git a/composer.lock b/composer.lock index 9db1311d..14001629 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": "c6c2e7e35c2c6d5737296f159edc9a95", + "content-hash": "6993d4c308ced358f1dca8da903c9c22", "packages": [ { "name": "aws/aws-crt-php", @@ -12063,6 +12063,195 @@ ], "time": "2025-02-07T05:00:38+00:00" }, + { + "name": "spatie/file-system-watcher", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/file-system-watcher.git", + "reference": "2fe96de88af6660b3ab7658a8f1d41b10ad0aff6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/file-system-watcher/zipball/2fe96de88af6660b3ab7658a8f1d41b10ad0aff6", + "reference": "2fe96de88af6660b3ab7658a8f1d41b10ad0aff6", + "shasum": "" + }, + "require": { + "php": "^8.3", + "symfony/process": "^7.0|^8.0" + }, + "require-dev": { + "pestphp/pest": "^4.0", + "spatie/ray": "^1.22", + "spatie/temporary-directory": "^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Watcher\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Watch changes in the file system using PHP", + "homepage": "https://github.com/spatie/file-system-watcher", + "keywords": [ + "file-system-watcher", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/file-system-watcher/issues", + "source": "https://github.com/spatie/file-system-watcher/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-11-26T10:41:42+00:00" + }, + { + "name": "spatie/laravel-horizon-watcher", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-horizon-watcher.git", + "reference": "141b94e8eea18f465c4419e8eea54936308a8788" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-horizon-watcher/zipball/141b94e8eea18f465c4419e8eea54936308a8788", + "reference": "141b94e8eea18f465c4419e8eea54936308a8788", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^9.0|^10.0|^11.0|^12.0", + "php": "^8.1", + "spatie/file-system-watcher": "^1.1.1", + "spatie/laravel-package-tools": "^1.13.6" + }, + "require-dev": { + "laravel/pint": "^1.2", + "nunomaduro/collision": "^6.3.1|^8.0", + "orchestra/testbench": "^7.11|^8.0|^9.0|^10.0", + "pestphp/pest": "^1.22.1|^2.34|^3.7", + "pestphp/pest-plugin-laravel": "^1.3|^2.3|^3.1", + "phpunit/phpunit": "^9.5.26|^10.5|^11.5.3", + "spatie/laravel-ray": "^1.31" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "HorizonWatcher": "Spatie\\HorizonWatcher\\Facades\\HorizonWatcher" + }, + "providers": [ + "Spatie\\HorizonWatcher\\HorizonWatcherServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\HorizonWatcher\\": "src", + "Spatie\\HorizonWatcher\\Database\\Factories\\": "database/factories" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Automatically restart Horizon when local PHP files change", + "homepage": "https://github.com/spatie/laravel-horizon-watcher", + "keywords": [ + "laravel", + "laravel-horizon-watcher", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-horizon-watcher/issues", + "source": "https://github.com/spatie/laravel-horizon-watcher/tree/1.1.4" + }, + "time": "2025-07-17T15:43:23+00:00" + }, + { + "name": "spatie/laravel-package-tools", + "version": "1.92.7", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-package-tools.git", + "reference": "f09a799850b1ed765103a4f0b4355006360c49a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/f09a799850b1ed765103a4f0b4355006360c49a5", + "reference": "f09a799850b1ed765103a4f0b4355006360c49a5", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^9.28|^10.0|^11.0|^12.0", + "php": "^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "orchestra/testbench": "^7.7|^8.0|^9.0|^10.0", + "pestphp/pest": "^1.23|^2.1|^3.1", + "phpunit/php-code-coverage": "^9.0|^10.0|^11.0", + "phpunit/phpunit": "^9.5.24|^10.5|^11.5", + "spatie/pest-plugin-test-time": "^1.1|^2.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\LaravelPackageTools\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Tools for creating Laravel packages", + "homepage": "https://github.com/spatie/laravel-package-tools", + "keywords": [ + "laravel-package-tools", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-package-tools/issues", + "source": "https://github.com/spatie/laravel-package-tools/tree/1.92.7" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-07-17T15:46:43+00:00" + }, { "name": "staabm/side-effects-detector", "version": "1.0.5", diff --git a/config/services.php b/config/services.php index 3bae0c89..fe4534e7 100644 --- a/config/services.php +++ b/config/services.php @@ -67,13 +67,20 @@ 'redirect' => env('GOOGLE_CLIENT_REDIRECT'), ], - // Facebook (used for Facebook Pages and Instagram) + // Facebook Pages 'facebook' => [ 'client_id' => env('FACEBOOK_CLIENT_ID'), 'client_secret' => env('FACEBOOK_CLIENT_SECRET'), 'redirect' => env('FACEBOOK_CLIENT_REDIRECT'), ], + // Instagram + 'instagram' => [ + 'client_id' => env('INSTAGRAM_CLIENT_ID'), + 'client_secret' => env('INSTAGRAM_CLIENT_SECRET'), + 'redirect' => env('INSTAGRAM_CLIENT_REDIRECT'), + ], + // Threads 'threads' => [ 'client_id' => env('THREADS_CLIENT_ID'), diff --git a/config/trypost.php b/config/trypost.php new file mode 100644 index 00000000..801db826 --- /dev/null +++ b/config/trypost.php @@ -0,0 +1,43 @@ + [ + 'linkedin' => [ + 'enabled' => env('TRYPOST_LINKEDIN_ENABLED', true), + ], + 'linkedin-page' => [ + 'enabled' => env('TRYPOST_LINKEDIN_PAGE_ENABLED', true), + ], + 'x' => [ + 'enabled' => env('TRYPOST_X_ENABLED', true), + ], + 'tiktok' => [ + 'enabled' => env('TRYPOST_TIKTOK_ENABLED', true), + ], + 'youtube' => [ + 'enabled' => env('TRYPOST_YOUTUBE_ENABLED', true), + ], + 'facebook' => [ + 'enabled' => env('TRYPOST_FACEBOOK_ENABLED', true), + ], + 'instagram' => [ + 'enabled' => env('TRYPOST_INSTAGRAM_ENABLED', true), + ], + 'threads' => [ + 'enabled' => env('TRYPOST_THREADS_ENABLED', true), + ], + ], + +]; diff --git a/package-lock.json b/package-lock.json index e57b4101..5840a3bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "@types/node": "^22.13.5", "@vitejs/plugin-vue": "^6.0.0", "@vue/eslint-config-typescript": "^14.3.0", + "chokidar": "^5.0.0", "concurrently": "^9.0.1", "eslint": "^9.17.0", "eslint-config-prettier": "^10.0.1", @@ -2889,6 +2890,22 @@ "node": ">=8" } }, + "node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/class-variance-authority": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", @@ -6005,6 +6022,20 @@ ], "license": "MIT" }, + "node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", diff --git a/package.json b/package.json index 7e888cc5..7c79f906 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@types/node": "^22.13.5", "@vitejs/plugin-vue": "^6.0.0", "@vue/eslint-config-typescript": "^14.3.0", + "chokidar": "^5.0.0", "concurrently": "^9.0.1", "eslint": "^9.17.0", "eslint-config-prettier": "^10.0.1", diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png index c2efef6d..dd0665ff 100644 Binary files a/public/apple-touch-icon.png and b/public/apple-touch-icon.png differ diff --git a/public/favicon.ico b/public/favicon.ico index 236fadb9..876e54b7 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/favicon.png b/public/favicon.png deleted file mode 100644 index dd0665ff..00000000 Binary files a/public/favicon.png and /dev/null differ diff --git a/public/favicon.svg b/public/favicon.svg index e4e710e0..189a0e92 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1,3 +1,13 @@ - - + + + + + + + + + + + + diff --git a/resources/js/app.ts b/resources/js/app.ts index 20097f5b..fa4ef5cf 100644 --- a/resources/js/app.ts +++ b/resources/js/app.ts @@ -1,5 +1,4 @@ import '../css/app.css'; -import './echo'; import { createInertiaApp } from '@inertiajs/vue3'; import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'; diff --git a/resources/js/echo.ts b/resources/js/echo.ts deleted file mode 100644 index 425da419..00000000 --- a/resources/js/echo.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Echo from 'laravel-echo'; -import Pusher from 'pusher-js'; - -window.Pusher = Pusher; - -window.Echo = new Echo({ - broadcaster: 'reverb', - key: import.meta.env.VITE_REVERB_APP_KEY, - wsHost: import.meta.env.VITE_REVERB_HOST, - wsPort: import.meta.env.VITE_REVERB_PORT ?? 80, - wssPort: import.meta.env.VITE_REVERB_PORT ?? 443, - forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https', - enabledTransports: ['ws', 'wss'], -}); diff --git a/resources/js/pages/posts/Show.vue b/resources/js/pages/posts/Show.vue index 12deef41..ef0b296e 100644 --- a/resources/js/pages/posts/Show.vue +++ b/resources/js/pages/posts/Show.vue @@ -1,6 +1,8 @@