Selecting an avatar or workspace logo now opens a crop dialog (drag + zoom) before uploading, so the image is framed the way it renders. The crop is performed client-side and the resized 512x512 result is what gets uploaded. This reworks the idea from #131 without its cropper dependency: vue-advanced-cropper was last released ~2 years ago and we did not want an unmaintained package for something this load-bearing. What we need is narrow (fixed 1:1, a circle/square mask, fixed-size output), so a small canvas-based cropper covers it: - imageCrop.ts: pure transform math (cover-fit, clamp, zoom, viewport->source). - ImageCropperDialog.vue: CSS-transform preview, pointer drag, wheel/button zoom, a ResizeObserver to measure the modal (no requestAnimationFrame timing hacks), and a canvas toBlob only on save. - PhotoUpload.vue: opens the cropper on file select; the mask shape follows the display shape (round avatar / square logo) instead of always being round. - crop_* strings added to all 15 locales. Also installs Pest browser testing (pest-plugin-browser + Playwright) and adds a browser test for the crop flow. TestCase only calls withoutVite() for non-browser tests, since browser tests need the real Vite assets to boot the SPA. The Pest browser server does not parse multipart uploads, so the test asserts the crop dispatches the correct upload request; endpoint persistence stays covered by ProfileUpdateTest.
162 lines
5.3 KiB
JSON
162 lines
5.3 KiB
JSON
{
|
|
"$schema": "https://getcomposer.org/schema.json",
|
|
"name": "trypost-it/trypost",
|
|
"type": "project",
|
|
"description": "Open-source social media scheduling for creators and teams",
|
|
"keywords": [
|
|
"open-source",
|
|
"self-hosted",
|
|
"laravel",
|
|
"social-media",
|
|
"social-media-scheduler",
|
|
"social-media-management",
|
|
"content-scheduling",
|
|
"twitter",
|
|
"linkedin",
|
|
"instagram",
|
|
"facebook",
|
|
"tiktok",
|
|
"youtube",
|
|
"threads",
|
|
"pinterest"
|
|
],
|
|
"license": "AGPL-3.0-only",
|
|
"homepage": "https://trypost.it",
|
|
"support": {
|
|
"issues": "https://github.com/trypost-it/trypost/issues",
|
|
"source": "https://github.com/trypost-it/trypost"
|
|
},
|
|
"authors": [
|
|
{
|
|
"name": "Paulo Castellano",
|
|
"homepage": "https://github.com/paulocastellano"
|
|
}
|
|
],
|
|
"require": {
|
|
"php": "^8.2",
|
|
"google/apiclient": "^2.19",
|
|
"inertiajs/inertia-laravel": "^3.0",
|
|
"intervention/image": "^4.0",
|
|
"laravel/ai": "^0.5.1",
|
|
"laravel/boost": "^2.0",
|
|
"laravel/cashier": "^16.2",
|
|
"laravel/framework": "^13.0",
|
|
"laravel/horizon": "^5.45",
|
|
"laravel/mcp": "^0.6.4",
|
|
"laravel/nightwatch": "^1.22",
|
|
"laravel/passport": "^13.7",
|
|
"laravel/reverb": "^1.0",
|
|
"laravel/socialite": "^5.24",
|
|
"laravel/tinker": "^3.0",
|
|
"laravel/wayfinder": "^0.1.9",
|
|
"league/color-extractor": "^0.4.0",
|
|
"league/flysystem-aws-s3-v3": "^3.0",
|
|
"league/html-to-markdown": "^5.1",
|
|
"posthog/posthog-php": "^4.1",
|
|
"predis/predis": "^3.3",
|
|
"sendkit/sendkit-laravel": "^1.1",
|
|
"simplepie/simplepie": "^1.9",
|
|
"socialiteproviders/facebook": "^4.1",
|
|
"socialiteproviders/instagram": "^5.1",
|
|
"socialiteproviders/linkedin": "^5.0",
|
|
"socialiteproviders/pinterest": "^4.3",
|
|
"socialiteproviders/tiktok": "^5.2",
|
|
"socialiteproviders/twitter": "^4.1",
|
|
"symfony/css-selector": "^8.0",
|
|
"symfony/dom-crawler": "^8.0"
|
|
},
|
|
"require-dev": {
|
|
"fakerphp/faker": "^1.23",
|
|
"laravel/pail": "^1.2.2",
|
|
"laravel/pint": "^1.24",
|
|
"laravel/sail": "*",
|
|
"laravel/telescope": "^5.19",
|
|
"mockery/mockery": "^1.6",
|
|
"nunomaduro/collision": "^8.6",
|
|
"pestphp/pest": "^4.4",
|
|
"pestphp/pest-plugin-browser": "^4.3",
|
|
"pestphp/pest-plugin-laravel": "^4.1"
|
|
},
|
|
"autoload": {
|
|
"files": [
|
|
"app/Helpers/Upload.php"
|
|
],
|
|
"psr-4": {
|
|
"App\\": "app/",
|
|
"Database\\Factories\\": "database/factories/",
|
|
"Database\\Seeders\\": "database/seeders/"
|
|
}
|
|
},
|
|
"autoload-dev": {
|
|
"psr-4": {
|
|
"Tests\\": "tests/"
|
|
}
|
|
},
|
|
"scripts": {
|
|
"setup": [
|
|
"composer install",
|
|
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\"",
|
|
"@php artisan key:generate",
|
|
"@php artisan migrate --force",
|
|
"npm install",
|
|
"npm run build"
|
|
],
|
|
"dev": [
|
|
"Composer\\Config::disableProcessTimeout",
|
|
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite --kill-others"
|
|
],
|
|
"dev:ssr": [
|
|
"npm run build:ssr",
|
|
"Composer\\Config::disableProcessTimeout",
|
|
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"php artisan inertia:start-ssr\" --names=server,queue,logs,ssr --kill-others"
|
|
],
|
|
"lint": [
|
|
"pint --parallel"
|
|
],
|
|
"test:lint": [
|
|
"pint --parallel --test"
|
|
],
|
|
"test": [
|
|
"@php artisan config:clear --ansi",
|
|
"@test:lint",
|
|
"@php artisan test"
|
|
],
|
|
"post-autoload-dump": [
|
|
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
|
"@php artisan package:discover --ansi"
|
|
],
|
|
"post-update-cmd": [
|
|
"@php artisan vendor:publish --tag=laravel-assets --ansi --force",
|
|
"@php artisan boost:update --ansi"
|
|
],
|
|
"post-root-package-install": [
|
|
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
|
],
|
|
"post-create-project-cmd": [
|
|
"@php artisan key:generate --ansi",
|
|
"@php -r \"file_exists('database/database.sqlite') || touch('database/database.sqlite');\"",
|
|
"@php artisan migrate --graceful --ansi"
|
|
],
|
|
"pre-package-uninstall": [
|
|
"Illuminate\\Foundation\\ComposerScripts::prePackageUninstall"
|
|
]
|
|
},
|
|
"extra": {
|
|
"laravel": {
|
|
"dont-discover": [
|
|
"laravel/telescope"
|
|
]
|
|
}
|
|
},
|
|
"config": {
|
|
"optimize-autoloader": true,
|
|
"preferred-install": "dist",
|
|
"sort-packages": true,
|
|
"allow-plugins": {
|
|
"pestphp/pest-plugin": true,
|
|
"php-http/discovery": true
|
|
}
|
|
},
|
|
"minimum-stability": "stable",
|
|
"prefer-stable": true
|
|
}
|