diff --git a/app/Http/Controllers/FileFunctions/EditItemsController.php b/app/Http/Controllers/FileFunctions/EditItemsController.php index 2519e851..4eb3456c 100644 --- a/app/Http/Controllers/FileFunctions/EditItemsController.php +++ b/app/Http/Controllers/FileFunctions/EditItemsController.php @@ -15,6 +15,7 @@ use Illuminate\Support\Facades\Auth; use App\Http\Controllers\Controller; use App\Http\Tools\Guardian; use App\Http\Tools\Editor; +use App\FileManagerFolder; use App\FileManagerFile; use Exception; @@ -315,6 +316,85 @@ class EditItemsController extends Controller return $new_file; } + +/** + * User download folder via zip + * + * @param $unique_id + * @return string + */ + public function user_zip_folder(Request $request,$unique_id) + { + // Get user id + $user_id = Auth::id(); + + // Check permission to download for authenticated editor + if ($request->user()->tokenCan('editor')) { + + // check if shared_token cookie exist + if (!$request->hasCookie('shared_token')) abort('401'); + + // Get shared token + $shared = get_shared($request->cookie('shared_token')); + + // Check access to requested directory + Guardian::check_item_access($unique_id, $shared); + } + + // Get folder + $folder = FileManagerFolder::whereUserId($user_id) + ->where('unique_id', $unique_id); + + if (! $folder->exists()) { + abort(404, 'Requested folder doesn\'t exists.'); + } + + $zip = Editor::zip_folder($unique_id); + + // Get file + return response([ + 'url' => route('zip', $zip->id), + 'name' => $zip->basename, + ], 200); + } + + /** + * Guest download folder via zip + * + * @param Request $request + * @param $unique_id + * @param $token + * @return string + */ + public function guest_zip_folder($unique_id, $token) + { + // Get shared record + $shared = get_shared($token); + + // Check access to requested folder + Guardian::check_item_access($unique_id, $shared); + + // Get folder + $folder = FileManagerFolder::whereUserId($shared->user_id) + ->where('unique_id', $unique_id); + + + if (! $folder->exists()) { + abort(404, 'Requested folder doesn\'t exists.'); + } + + $zip = Editor::zip_folder($unique_id, $shared); + + // Get file + return response([ + 'url' => route('zip_public', [ + 'id' => $zip->id, + 'token' => $shared->token, + ]), + 'name' => $zip->basename, + ], 200); + } + /** * User download multiple files via zip * @@ -349,6 +429,8 @@ class EditItemsController extends Controller $zip = Editor::zip_files($files); + dd($zip); + // Get file return response([ 'url' => route('zip', $zip->id), diff --git a/app/Http/Controllers/FileFunctions/TrashController.php b/app/Http/Controllers/FileFunctions/TrashController.php index 2cd7c807..b5854e2e 100644 --- a/app/Http/Controllers/FileFunctions/TrashController.php +++ b/app/Http/Controllers/FileFunctions/TrashController.php @@ -59,12 +59,12 @@ class TrashController extends Controller * @param $unique_id * @return ResponseFactory|\Illuminate\Http\Response */ - public function restore(Request $request, $unique_id) + public function restore(Request $request) { // Validate request - $validator = Validator::make($request->all(), [ - 'type' => 'required|string', - 'to_home' => 'boolean', + $validator = Validator::make($request->input('data'), [ + '*.type' => 'required|string', + '*.unique_id' => 'integer', ]); // Return error @@ -77,38 +77,41 @@ class TrashController extends Controller return Demo::response_204(); } - // Get folder - if ($request->type === 'folder') { - + foreach($request->input('data') as $restore_item) { + // Get folder - $item = FileManagerFolder::onlyTrashed() - ->where('user_id', $user_id) - ->where('unique_id', $unique_id) - ->first(); + if ($restore_item['type'] === 'folder') { - // Restore item to home directory - if ($request->has('to_home') && $request->to_home) { - $item->parent_id = 0; - $item->save(); + // Get folder + $item = FileManagerFolder::onlyTrashed() + ->where('user_id', $user_id) + ->where('unique_id', $restore_item['unique_id']) + ->first(); + + // Restore item to home directory + if ($request->has('to_home') && $request->to_home) { + $item->parent_id = 0; + $item->save(); + } + } else { + + // Get item + $item = FileManagerFile::onlyTrashed() + ->where('user_id', $user_id) + ->where('unique_id', $restore_item['unique_id']) + ->first(); + + // Restore item to home directory + if ($request->has('to_home') && $request->to_home) { + $item->folder_id = 0; + $item->save(); + } } - } else { - // Get item - $item = FileManagerFile::onlyTrashed() - ->where('user_id', $user_id) - ->where('unique_id', $unique_id) - ->first(); - - // Restore item to home directory - if ($request->has('to_home') && $request->to_home) { - $item->folder_id = 0; - $item->save(); - } + // Restore Item + $item->restore(); } - // Restore Item - $item->restore(); - // Return response return response('Done!', 204); } diff --git a/app/Http/Helpers/helpers.php b/app/Http/Helpers/helpers.php index e5a56daa..abe6d458 100644 --- a/app/Http/Helpers/helpers.php +++ b/app/Http/Helpers/helpers.php @@ -559,6 +559,10 @@ function get_image_meta_data($file) { if (get_file_type_from_mimetype($file->getMimeType()) === 'jpeg') { return exif_read_data($file); + + return mb_convert_encoding( + exif_read_data($file), 'UTF8', 'UTF8' + ); } } @@ -733,3 +737,32 @@ function remove_accents($string) { return $string; } +/** + * Get all files from folder and get their folder location in VueFileManager directories + * + * @param $folders + * @param array $files + * @param array $path + * @return array + */ +function get_files_for_zip($folders, $files = [], $path = []) +{ + // Return file list + if (!isset($folders->folders)) { + return $files; + } + + // Push path + array_push($path, $folders->name); + + // Write file list + foreach ($folders->files as $file) { + array_push($files, [ + 'name' => $file->name, + 'basename' => $file->basename, + 'folder_path' => implode('/', $path), + ]); + } + + return get_files_for_zip($folders->folders->first(), $files, $path); +} diff --git a/app/Http/Tools/Editor.php b/app/Http/Tools/Editor.php index 2440ef9c..fd7dbdf8 100644 --- a/app/Http/Tools/Editor.php +++ b/app/Http/Tools/Editor.php @@ -26,6 +26,83 @@ use Symfony\Component\HttpKernel\Exception\HttpException; class Editor { + /** + * Zip requested folder + * + * @param $unique_id + * @return mixed + * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + */ + public static function zip_folder($unique_id, $shared = null) + { + // Get folder + $requested_folder = FileManagerFolder::with(['folders.files', 'files']) + ->where('unique_id', $unique_id) + ->where('user_id', Auth::id() ?? $shared->user_id) + ->with('folders') + ->first(); + + + $files = get_files_for_zip($requested_folder); + + // Local storage instance + $disk_local = Storage::disk('local'); + + // Create zip directory + if (!$disk_local->exists('zip')) { + $disk_local->makeDirectory('zip'); + } + + // Move file to local storage + if (!is_storage_driver('local')) { + + // Create temp directory + if (!$disk_local->exists('temp')) { + $disk_local->makeDirectory('temp'); + } + + foreach ($files as $file) { + try { + $disk_local->put('temp/' . $file['basename'], Storage::get('file-manager/' . $file['basename'])); + } catch (FileNotFoundException $e) { + throw new HttpException(404, 'File not found'); + } + } + } + + // Get zip path + $zip_name = Str::random(16) . '-' . Str::slug($requested_folder->name) . '.zip'; + $zip_path = 'zip/' . $zip_name; + + // Create zip + $zip = Madzipper::make(storage_path() . '/app/' . $zip_path); + + // Get files folder on local storage drive + $files_folder = is_storage_driver('local') ? 'file-manager' : 'temp'; + + // Add files to zip + foreach ($files as $file) { + $zip->folder($file['folder_path'])->addString($file['name'], File::get(storage_path() . '/app/' . $files_folder . '/' . $file['basename'])); + } + + // Close zip + $zip->close(); + + // Delete temporary files + if (!is_storage_driver('local')) { + + foreach ($files as $file) { + $disk_local->delete('temp/' . $file['basename']); + } + } + + // Store zip record + return Zip::create([ + 'user_id' => $shared->user_id ?? Auth::id(), + 'shared_token' => $shared->token ?? null, + 'basename' => $zip_name, + ]); + } /** * Zip selected files, store it in /zip folder and retrieve zip record diff --git a/config/app.php b/config/app.php index 00d4ec4c..bc30b52b 100644 --- a/config/app.php +++ b/config/app.php @@ -67,7 +67,7 @@ return [ | */ - 'timezone' => 'UTC', + 'timezone' => 'America/Toronto', /* |-------------------------------------------------------------------------- diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 01f6edbc..4ff9d93b 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,65 +1,78 @@ { - "/chunks/files~chunks/shared-files~chunks/shared-page.js": "/chunks/files~chunks/shared-files~chunks/shared-page.js?id=28609ddbecc1f1fa2c9f", - "/js/main.js": "/js/main.js?id=baa9e433dc272dec4b2a", - "/css/app.css": "/css/app.css?id=8f6d5dcb7110a726e142", - "/chunks/admin.js": "/chunks/admin.js?id=60df31e17e9a453717dc", - "/chunks/admin-account.js": "/chunks/admin-account.js?id=ab97f01586b286e0bba2", - "/chunks/app-appearance.js": "/chunks/app-appearance.js?id=cbcbdb5159db1fdef0fe", - "/chunks/app-billings.js": "/chunks/app-billings.js?id=2a85f4c8ad09b50f4358", - "/chunks/app-email.js": "/chunks/app-email.js?id=49806a5c914ca1a14bff", - "/chunks/app-index.js": "/chunks/app-index.js?id=ff6fb3cb1780d6ea76f2", - "/chunks/app-others.js": "/chunks/app-others.js?id=6eb162d433e0b9b8b7b2", - "/chunks/app-payments.js": "/chunks/app-payments.js?id=ad822a37d1d7c6e99a08", - "/chunks/app-settings.js": "/chunks/app-settings.js?id=e23a68dba034c047ff44", - "/chunks/app-setup.js": "/chunks/app-setup.js?id=c1c6fcc091a248b10060", - "/chunks/billings-detail.js": "/chunks/billings-detail.js?id=0e1d52490ae1b9e56c74", - "/chunks/contact-us.js": "/chunks/contact-us.js?id=a5150dcf81c8e1ab23a4", - "/chunks/create-new-password.js": "/chunks/create-new-password.js?id=58c543c4f92b5ca9a284", - "/chunks/dashboard.js": "/chunks/dashboard.js?id=256a9fc56ca1e81507cf", - "/chunks/database.js": "/chunks/database.js?id=45630822140f0f9d8fb5", - "/chunks/dynamic-page.js": "/chunks/dynamic-page.js?id=08a0c2de8f93e0222600", - "/chunks/environment-setup.js": "/chunks/environment-setup.js?id=be1c6cf5bbedf5c987da", - "/chunks/files.js": "/chunks/files.js?id=e182df6a47e8764f428a", - "/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=7ff98232e7b4cc5d2c2a", - "/chunks/installation-disclaimer.js": "/chunks/installation-disclaimer.js?id=d6ff4604fd61fd8a081d", - "/chunks/invoices.js": "/chunks/invoices.js?id=656daf3bc5b893a94a3c", - "/chunks/landing-page.js": "/chunks/landing-page.js?id=9b500c8f5f2de6ae01b3", - "/chunks/not-found-shared.js": "/chunks/not-found-shared.js?id=53d4f9c58bdac1e568c7", - "/chunks/page-edit.js": "/chunks/page-edit.js?id=682b2836ee0726d72409", - "/chunks/pages.js": "/chunks/pages.js?id=057a23ae05c1272fbc4a", - "/chunks/plan.js": "/chunks/plan.js?id=d679b2c4e3dafe7cb4de", - "/chunks/plan-create.js": "/chunks/plan-create.js?id=921149e0082c663f0ce8", - "/chunks/plan-delete.js": "/chunks/plan-delete.js?id=daff73302efdfacc542a", - "/chunks/plan-settings.js": "/chunks/plan-settings.js?id=3047e82dffef9a9a5f36", - "/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=d46857048beab30edb45", - "/chunks/plans.js": "/chunks/plans.js?id=59e044f4c96b8b23146c", - "/chunks/profile.js": "/chunks/profile.js?id=a71f52eb082c5173b37e", - "/chunks/purchase-code.js": "/chunks/purchase-code.js?id=7ef575dcdf8d8cce1781", - "/chunks/settings.js": "/chunks/settings.js?id=e92a372ac6714092f999", - "/chunks/settings-create-payment-methods.js": "/chunks/settings-create-payment-methods.js?id=8e425a5fcac0dfed8979", - "/chunks/settings-invoices.js": "/chunks/settings-invoices.js?id=124785707d6d7eefc088", - "/chunks/settings-password.js": "/chunks/settings-password.js?id=f7b86ce4daef5d65b9c7", - "/chunks/settings-payment-methods.js": "/chunks/settings-payment-methods.js?id=e470dc96089d86689f74", - "/chunks/settings-storage.js": "/chunks/settings-storage.js?id=d74048cf27bfd83ecacb", - "/chunks/settings-subscription.js": "/chunks/settings-subscription.js?id=754550f7d1abe0678d00", - "/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=47090233afc7b0cdf855", - "/chunks/shared-files.js": "/chunks/shared-files.js?id=adbeabe4eee0cdaefbf4", - "/chunks/shared-page.js": "/chunks/shared-page.js?id=691e43731207990aeef3", - "/chunks/sign-in.js": "/chunks/sign-in.js?id=ec080714b24154cf1081", - "/chunks/sign-up.js": "/chunks/sign-up.js?id=0d8b571bcf5a54f073fd", - "/chunks/stripe-credentials.js": "/chunks/stripe-credentials.js?id=1855b3385d413077987b", - "/chunks/subscription-plans.js": "/chunks/subscription-plans.js?id=8f7dd3b0a9efd8b23cb6", - "/chunks/subscription-service.js": "/chunks/subscription-service.js?id=5d6baf6541a2045e07d4", - "/chunks/upgrade.js": "/chunks/upgrade.js?id=5b8044541a28db10a800", - "/chunks/upgrade-billing.js": "/chunks/upgrade-billing.js?id=a7aac734e0697c974314", - "/chunks/upgrade-plan.js": "/chunks/upgrade-plan.js?id=b5d285ace19d55d6caba", - "/chunks/user.js": "/chunks/user.js?id=a22678762221f8ece00f", - "/chunks/user-create.js": "/chunks/user-create.js?id=d2c5a7a23e892ea0b74f", - "/chunks/user-delete.js": "/chunks/user-delete.js?id=97382205d44cc82a7362", - "/chunks/user-detail.js": "/chunks/user-detail.js?id=368fa9dff628423894ea", - "/chunks/user-invoices.js": "/chunks/user-invoices.js?id=25a90c334e0edcf8497a", - "/chunks/user-password.js": "/chunks/user-password.js?id=66ca2fe7b5f27aea03b4", - "/chunks/user-storage.js": "/chunks/user-storage.js?id=1197c179b53abd596800", - "/chunks/user-subscription.js": "/chunks/user-subscription.js?id=df85e3892af3ff39a586", - "/chunks/users.js": "/chunks/users.js?id=1dd3a0e5ea6717816879" + "/js/main.js": "/js/main.js", + "/css/app.css": "/css/app.css", + "/chunks/admin.js": "/chunks/admin.js?id=d9ef79cabf24df304657", + "/chunks/admin-account.js": "/chunks/admin-account.js?id=63c04ed6eb66b99be097", + "/chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chu~2d9ff916.js": "/chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chu~2d9ff916.js?id=07b0ad73181498d46930", + "/chunks/admin-account~chunks/app-setup~chunks/billings-detail~chunks/create-new-password~chunks/datab~01aef58e.js": "/chunks/admin-account~chunks/app-setup~chunks/billings-detail~chunks/create-new-password~chunks/datab~01aef58e.js?id=6cb8c3f7a9aed769ec61", + "/chunks/admin~chunks/files~chunks/settings~chunks/shared-files~chunks/shared-page.js": "/chunks/admin~chunks/files~chunks/settings~chunks/shared-files~chunks/shared-page.js?id=7480293537e480966ae0", + "/chunks/app-appearance.js": "/chunks/app-appearance.js?id=b99a5c881b7f15a7e8c5", + "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~605f4c49.js": "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~605f4c49.js?id=9e50edacd8630aa6fc22", + "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~8cc7d96f.js": "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~8cc7d96f.js?id=b6dbd27dc777d0878f4b", + "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~b9e5655a.js": "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~b9e5655a.js?id=d066e2c40f4c0ca68bf1", + "/chunks/app-billings.js": "/chunks/app-billings.js?id=aac5bd51067578358164", + "/chunks/app-email.js": "/chunks/app-email.js?id=9d1631b19f6492b8cae4", + "/chunks/app-index.js": "/chunks/app-index.js?id=ec7605e0fcf922be3dbc", + "/chunks/app-others.js": "/chunks/app-others.js?id=44efcfb317747ff3b508", + "/chunks/app-payments.js": "/chunks/app-payments.js?id=187ecc16f9f7fbc4ccac", + "/chunks/app-settings.js": "/chunks/app-settings.js?id=033223b2f39c72c71a73", + "/chunks/app-settings~chunks/dashboard~chunks/invoices~chunks/page-edit~chunks/pages~chunks/plan~chunk~8a0e1d25.js": "/chunks/app-settings~chunks/dashboard~chunks/invoices~chunks/page-edit~chunks/pages~chunks/plan~chunk~8a0e1d25.js?id=52e8a931f975c4e03a3c", + "/chunks/app-setup.js": "/chunks/app-setup.js?id=8038cc956f309a321a7c", + "/chunks/billings-detail.js": "/chunks/billings-detail.js?id=bbfc290b50cebb202228", + "/chunks/contact-us.js": "/chunks/contact-us.js?id=4dc0385ff5abe06d164e", + "/chunks/contact-us~chunks/dynamic-page~chunks/landing-page.js": "/chunks/contact-us~chunks/dynamic-page~chunks/landing-page.js?id=a4b8a7017c82de28296b", + "/chunks/create-new-password.js": "/chunks/create-new-password.js?id=108dcc4b5af4c973be56", + "/chunks/dashboard.js": "/chunks/dashboard.js?id=0feeb46fa2549c8d4be4", + "/chunks/dashboard~chunks/invoices~chunks/pages~chunks/plan-subscribers~chunks/plans~chunks/settings-i~0e2a0654.js": "/chunks/dashboard~chunks/invoices~chunks/pages~chunks/plan-subscribers~chunks/plans~chunks/settings-i~0e2a0654.js?id=cc1b4cbd4aa7f70151f7", + "/chunks/database.js": "/chunks/database.js?id=ce57f3e69798319aab7b", + "/chunks/dynamic-page.js": "/chunks/dynamic-page.js?id=f7ff36abf37571173944", + "/chunks/environment-setup.js": "/chunks/environment-setup.js?id=48efd0b887fbc804ac90", + "/chunks/files.js": "/chunks/files.js?id=6a283c2c9f8a02500bc6", + "/chunks/files~chunks/settings-subscription~chunks/shared-files~chunks/shared-page~chunks/user-subscription.js": "/chunks/files~chunks/settings-subscription~chunks/shared-files~chunks/shared-page~chunks/user-subscription.js?id=b646ec02fb9d6a497e74", + "/chunks/files~chunks/shared-files~chunks/shared-page.js": "/chunks/files~chunks/shared-files~chunks/shared-page.js?id=e2d1c1c0098efd3314c0", + "/chunks/files~chunks/shared-page.js": "/chunks/files~chunks/shared-page.js?id=47ade53389e84dd64310", + "/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=d5e39543eeb619cb5513", + "/chunks/installation-disclaimer.js": "/chunks/installation-disclaimer.js?id=f037ea11689d01ea489e", + "/chunks/invoices.js": "/chunks/invoices.js?id=0dddc007dba47ac5785e", + "/chunks/landing-page.js": "/chunks/landing-page.js?id=963140915655ff33f611", + "/chunks/not-found-shared.js": "/chunks/not-found-shared.js?id=8c8ee101f3445e086040", + "/chunks/page-edit.js": "/chunks/page-edit.js?id=0952cc3fb3aa4797a679", + "/chunks/pages.js": "/chunks/pages.js?id=313adabcad5dafb0f932", + "/chunks/plan.js": "/chunks/plan.js?id=41d7a74e57ac07ce3619", + "/chunks/plan-create.js": "/chunks/plan-create.js?id=8d1c89c91afa65224225", + "/chunks/plan-delete.js": "/chunks/plan-delete.js?id=4da54a76628aef67ea3e", + "/chunks/plan-settings.js": "/chunks/plan-settings.js?id=e608674e1719be65fe6f", + "/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=8655313c7b71b1019c8f", + "/chunks/plans.js": "/chunks/plans.js?id=d6d92de642403caa999b", + "/chunks/profile.js": "/chunks/profile.js?id=1e629aa55540ed106ce7", + "/chunks/profile~chunks/settings-password.js": "/chunks/profile~chunks/settings-password.js?id=f9e2ea1515204b5c63b6", + "/chunks/purchase-code.js": "/chunks/purchase-code.js?id=91a470e84a34587f3944", + "/chunks/settings.js": "/chunks/settings.js?id=87d29c7fd4e0e6f1a3bd", + "/chunks/settings-create-payment-methods.js": "/chunks/settings-create-payment-methods.js?id=8bc4707d554ffca037a1", + "/chunks/settings-invoices.js": "/chunks/settings-invoices.js?id=f5c1b720a5b12060b83b", + "/chunks/settings-password.js": "/chunks/settings-password.js?id=0229d51aca95ffc75902", + "/chunks/settings-payment-methods.js": "/chunks/settings-payment-methods.js?id=6645f6fa891ede787f43", + "/chunks/settings-storage.js": "/chunks/settings-storage.js?id=0ec77e47b2622ee5e253", + "/chunks/settings-subscription.js": "/chunks/settings-subscription.js?id=00c6bca64820c4fd3a89", + "/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=b671f4f3198119b48449", + "/chunks/shared-files.js": "/chunks/shared-files.js?id=b13068f12911fbf79f74", + "/chunks/shared-page.js": "/chunks/shared-page.js?id=09252cb95089d52ee56a", + "/chunks/sign-in.js": "/chunks/sign-in.js?id=0212907c9bf1cdbd99ed", + "/chunks/sign-up.js": "/chunks/sign-up.js?id=91001c0d2c2522eb0d03", + "/chunks/stripe-credentials.js": "/chunks/stripe-credentials.js?id=0e90002c41282e286785", + "/chunks/subscription-plans.js": "/chunks/subscription-plans.js?id=6ceb34852ec8a0280aef", + "/chunks/subscription-service.js": "/chunks/subscription-service.js?id=7176521fbf0047110ae1", + "/chunks/upgrade.js": "/chunks/upgrade.js?id=84fa2517046334070313", + "/chunks/upgrade-billing.js": "/chunks/upgrade-billing.js?id=816be29562b9052cabb1", + "/chunks/upgrade-billing~chunks/upgrade-plan.js": "/chunks/upgrade-billing~chunks/upgrade-plan.js?id=a589c99d29f03bc71487", + "/chunks/upgrade-plan.js": "/chunks/upgrade-plan.js?id=8bf12e8b93c7eaee4171", + "/chunks/user.js": "/chunks/user.js?id=bdb8a51693952859f5e1", + "/chunks/user-create.js": "/chunks/user-create.js?id=d0056a5db2089bc05508", + "/chunks/user-delete.js": "/chunks/user-delete.js?id=91d17d44835dd32ec36f", + "/chunks/user-detail.js": "/chunks/user-detail.js?id=b5b474dd8fea7b99c766", + "/chunks/user-invoices.js": "/chunks/user-invoices.js?id=68ea653f6d345e469307", + "/chunks/user-password.js": "/chunks/user-password.js?id=ac51d17a4aa7ae50bc88", + "/chunks/user-storage.js": "/chunks/user-storage.js?id=5cfec8a8f8a8aef24ef2", + "/chunks/user-subscription.js": "/chunks/user-subscription.js?id=34603496ceacb8bd2da3", + "/chunks/users.js": "/chunks/users.js?id=6e68cb068f69fba3199c" } diff --git a/resources/js/App.vue b/resources/js/App.vue index 2d992fc0..2aa81815 100644 --- a/resources/js/App.vue +++ b/resources/js/App.vue @@ -12,6 +12,7 @@ + diff --git a/resources/js/components/FilesView/ContextMenu.vue b/resources/js/components/FilesView/ContextMenu.vue index 3c3b72fd..2b7c998e 100644 --- a/resources/js/components/FilesView/ContextMenu.vue +++ b/resources/js/components/FilesView/ContextMenu.vue @@ -30,10 +30,12 @@ + @@ -62,6 +64,7 @@ @@ -106,6 +109,7 @@ @@ -143,6 +147,7 @@ @@ -167,6 +172,7 @@ @@ -250,11 +256,21 @@ export default { }, methods: { + downloadFolder(){ + this.$store.dispatch('downloadFolder' , this.item) + }, emptyTrash() { this.$store.dispatch('emptyTrash') }, restoreItem() { - this.$store.dispatch('restoreItem', this.item) + + // If is item not in selected items restore just this single item + if(!this.fileInfoDetail.includes(this.item)) + this.$store.dispatch('restoreItem', this.item) + + // If is item in selected items restore all items from fileInfoDetail + if(this.fileInfoDetail.includes(this.item)) + this.$store.dispatch('restoreItem', null) }, shareCancel() { this.$store.dispatch('shareCancel') diff --git a/resources/js/components/FilesView/FileItemGrid.vue b/resources/js/components/FilesView/FileItemGrid.vue index 94a9b5db..c0d093b5 100644 --- a/resources/js/components/FilesView/FileItemGrid.vue +++ b/resources/js/components/FilesView/FileItemGrid.vue @@ -32,7 +32,7 @@
- + {{ itemName }} @@ -263,6 +263,14 @@ export default { created() { this.itemName = this.data.name + events.$on('newFolder:focus', (unique_id) => { + + if(this.data.unique_id == unique_id) { + this.$refs[unique_id].focus() + document.execCommand('selectAll') + } + }) + events.$on('mobileSelecting:start', () => { this.multiSelectMode = true this.$store.commit('CLEAR_FILEINFO_DETAIL') diff --git a/resources/js/components/FilesView/FileItemList.vue b/resources/js/components/FilesView/FileItemList.vue index 36cca2bf..3ff54a41 100644 --- a/resources/js/components/FilesView/FileItemList.vue +++ b/resources/js/components/FilesView/FileItemList.vue @@ -28,11 +28,13 @@ + +
- + {{ itemName }} @@ -263,6 +265,14 @@ export default { created() { this.itemName = this.data.name + events.$on('newFolder:focus', (unique_id) => { + + if(this.data.unique_id == unique_id) { + this.$refs[unique_id].focus() + document.execCommand('selectAll') + } + }) + events.$on('mobileSelecting:start', () => { this.mobileMultiSelect = true this.$store.commit('CLEAR_FILEINFO_DETAIL') diff --git a/resources/js/components/FilesView/Option.vue b/resources/js/components/FilesView/Option.vue index 3fcb0f4c..baa0b7ec 100644 --- a/resources/js/components/FilesView/Option.vue +++ b/resources/js/components/FilesView/Option.vue @@ -12,6 +12,7 @@ +
{{ title }} @@ -24,6 +25,7 @@ import { CornerDownRightIcon, DownloadCloudIcon, FolderPlusIcon, + PaperclipIcon, LifeBuoyIcon, Trash2Icon, Edit2Icon, @@ -41,6 +43,7 @@ import { CornerDownRightIcon, DownloadCloudIcon, FolderPlusIcon, + PaperclipIcon, LifeBuoyIcon, Trash2Icon, SmileIcon, diff --git a/resources/js/components/FilesView/SortingAndPreviewMenu.vue b/resources/js/components/FilesView/SortingAndPreviewMenu.vue index c77e3051..dc250f4d 100644 --- a/resources/js/components/FilesView/SortingAndPreviewMenu.vue +++ b/resources/js/components/FilesView/SortingAndPreviewMenu.vue @@ -84,8 +84,6 @@ export default { this.filter.field = field - console.log(this.filter); - // Set sorting direction if (this.filter.sort === 'DESC') this.filter.sort = 'ASC' diff --git a/resources/js/i18n/lang/cn.json b/resources/js/i18n/lang/cn.json index 0930f97d..2bc77749 100644 --- a/resources/js/i18n/lang/cn.json +++ b/resources/js/i18n/lang/cn.json @@ -283,7 +283,8 @@ "share_edit": "编辑分享设定", "upload": "上传", "select": "Select", - "no_options": "No Options Available" + "no_options": "No Options Available", + "zip_folder": "Zip Folder" }, "mobile_selecting": { "select_all": "Select All", diff --git a/resources/js/i18n/lang/en.json b/resources/js/i18n/lang/en.json index 83c8e385..34b90d75 100644 --- a/resources/js/i18n/lang/en.json +++ b/resources/js/i18n/lang/en.json @@ -285,7 +285,8 @@ "share_edit": "Edit Sharing", "upload": "Upload", "select": "Select", - "no_options": "No Options Available" + "no_options": "No Options Available", + "zip_folder": "Zip Folder" }, "mobile_selecting": { "select_all": "Select All", diff --git a/resources/js/i18n/lang/sk.json b/resources/js/i18n/lang/sk.json index 08db223a..a0412e21 100644 --- a/resources/js/i18n/lang/sk.json +++ b/resources/js/i18n/lang/sk.json @@ -285,7 +285,8 @@ "share_edit": "Upraviť zdieľanie", "upload": "Nahrať", "select": "Výber", - "no_options": "Nie sú k dispozícii žiadne možnosti" + "no_options": "Nie sú k dispozícii žiadne možnosti", + "zip_folder": "Zazipovať priečinok" }, "mobile_selecting": { "select_all": "Vybrať všetko", diff --git a/resources/js/store/modules/fileFunctions.js b/resources/js/store/modules/fileFunctions.js index 90ffce84..168b33c1 100644 --- a/resources/js/store/modules/fileFunctions.js +++ b/resources/js/store/modules/fileFunctions.js @@ -10,6 +10,27 @@ const defaultState = { } const actions = { + downloadFolder: ({commit, getters}, folder) => { + + commit('ZIPPING_FILE_STATUS', true) + + // Get route + let route = getters.sharedDetail && !getters.sharedDetail.protected + ? '/api/zip-folder/' + folder.unique_id + '/public/' + router.currentRoute.params.token + : '/api/zip-folder/' + folder.unique_id + + axios.get(route) + .then(response => { + Vue.prototype.$downloadFile(response.data.url, response.data.name) + }) + .catch(() => { + Vue.prototype.$isSomethingWrong() + }) + .finally(() => { + commit('ZIPPING_FILE_STATUS', false) + }) + + }, downloadFiles: ({ commit, getters }) => { let files = [] @@ -96,6 +117,11 @@ const actions = { events.$emit('scrollTop') + //Set focus on new folder name + setTimeout(() => { + events.$emit('newFolder:focus', response.data.unique_id) + }, 10); + if (getters.currentFolder.location !== 'public') dispatch('getAppData') if (getters.currentFolder.location === 'public') @@ -220,24 +246,36 @@ const actions = { }, restoreItem: ({ commit, getters }, item) => { + let itemToRestore = [] + let items = [item] let restoreToHome = false + // If coming no selected item dont get items to restore from fileInfoDetail + if (!item) + items = getters.fileInfoDetail + // Check if file can be restored to home directory if (getters.currentFolder.location === 'trash') restoreToHome = true - // Remove file - commit('REMOVE_ITEM', item.unique_id) + items.forEach(data => itemToRestore.push({ + 'type': data.type, + 'unique_id': data.unique_id, + })) // Remove file preview commit('CLEAR_FILEINFO_DETAIL') axios - .post(getters.api + '/restore-item/' + item.unique_id, { - type: item.type, + .post(getters.api + '/restore-items' ,{ to_home: restoreToHome, - _method: 'patch' + data: itemToRestore, }) + .then( + + // Remove file + items.forEach( data => commit('REMOVE_ITEM', data.unique_id) ) + ) .catch(() => Vue.prototype.$isSomethingWrong()) }, deleteItem: ({ commit, getters, dispatch }, noSelectedItem) => { diff --git a/resources/js/views/Shared/SharedPage.vue b/resources/js/views/Shared/SharedPage.vue index a2336ac1..1dbae1f6 100644 --- a/resources/js/views/Shared/SharedPage.vue +++ b/resources/js/views/Shared/SharedPage.vue @@ -9,6 +9,9 @@ + + + @@ -116,6 +119,7 @@ import MobileSortingAndPreview from '@/components/FilesView/MobileSortingAndPreview' import MobileMultiSelectMenu from '@/components/FilesView/MobileMultiSelectMenu' import DesktopSortingAndPreview from '@/components/FilesView/DesktopSortingAndPreview' + import ProcessingPopup from '@/components/FilesView/ProcessingPopup' import TreeMenuNavigator from '@/components/Others/TreeMenuNavigator' import FileFullPreview from '@/components/FilesView/FileFullPreview' import DesktopToolbar from '@/components/FilesView/DesktopToolbar' @@ -152,6 +156,7 @@ ValidationObserver, TreeMenuNavigator, FileFullPreview, + ProcessingPopup, DesktopToolbar, ContentSidebar, DragUI, diff --git a/routes/api.php b/routes/api.php index b42b1cbd..3ab3f385 100644 --- a/routes/api.php +++ b/routes/api.php @@ -48,6 +48,7 @@ Route::group(['middleware' => ['api']], function () { Route::post('/create-folder/public/{token}', 'FileFunctions\EditItemsController@guest_create_folder'); Route::post('/remove-item/public/{token}', 'FileFunctions\EditItemsController@guest_delete_item'); Route::post('/zip/public/{token}', 'FileFunctions\EditItemsController@guest_zip_multiple_files'); + Route::get('/zip-folder/{unique_id}/public/{token}', 'FileFunctions\EditItemsController@guest_zip_folder'); Route::post('/upload/public/{token}', 'FileFunctions\EditItemsController@guest_upload'); Route::post('/move/public/{token}', 'FileFunctions\EditItemsController@guest_move'); @@ -108,7 +109,7 @@ Route::group(['middleware' => ['auth:api', 'auth.master', 'scope:master']], func Route::get('/trash', 'FileBrowser\BrowseController@trash'); // Trash - Route::patch('/restore-item/{unique_id}', 'FileFunctions\TrashController@restore'); + Route::post('/restore-items', 'FileFunctions\TrashController@restore'); Route::delete('/empty-trash', 'FileFunctions\TrashController@clear'); // Favourites @@ -188,6 +189,7 @@ Route::group(['middleware' => ['auth:api', 'auth.shared', 'auth.master', 'scope: Route::post('/create-folder', 'FileFunctions\EditItemsController@user_create_folder'); Route::post('/remove-item', 'FileFunctions\EditItemsController@user_delete_item'); Route::post('/zip', 'FileFunctions\EditItemsController@user_zip_multiple_files'); + Route::get('/zip-folder/{unique_id}', 'FileFunctions\EditItemsController@user_zip_folder'); Route::post('/upload', 'FileFunctions\EditItemsController@user_upload'); Route::post('/move', 'FileFunctions\EditItemsController@user_move'); });