diff --git a/logs/v2.3.7.txt b/logs/v2.3.7.txt deleted file mode 100644 index ac35c40..0000000 --- a/logs/v2.3.7.txt +++ /dev/null @@ -1,30 +0,0 @@ -## New - -- you can now use “shift + click” to limit bulk selection to specific files. -- added new shortcuts -- you can now copy files/folders instead of moving as well. -- add new option for path breadcrumb for mobile to make it easier to navigate -- add audio for success & alert ops -- don't reset the selection if (deleting/moving/copying) an item has returned an error. - -## Fix - -- some fixes & cleanups here and there -- fixed issue with local-storage overriding the original keys -- fixed update folder info after moving -- fixed not selecting an item after getting the files from server “rare” -- fixed refreshing the manager when using “key modifier + r” -- fixed the hardcoded translation & now all handled through laravel. -- fixed pre-mature selection of first item after delete/move form submit -- fixed showing an empty notification -- fixed axios showing vague error message - -## Update - -- cleanup & optimization “js, controller” -- slightly better scroll to item -- change view files structure -- make file-box smaller on mobile -- update read me -- update wiki -- update resources diff --git a/logs/v2.3.8.txt b/logs/v2.3.8.txt new file mode 100644 index 0000000..0d6d7cb --- /dev/null +++ b/logs/v2.3.8.txt @@ -0,0 +1,10 @@ +- fix “select + click” for search +- add support for zip progress +- new styling for path breadcrumb on mobile +- add animation for breadcrumbs +- fix local-storage toolbar changing on its own +- some cleanup to the controller + +- update assets +- update db file +- update language file \ No newline at end of file diff --git a/src/Controllers/MediaController.php b/src/Controllers/MediaController.php index bbc86d4..0227311 100755 --- a/src/Controllers/MediaController.php +++ b/src/Controllers/MediaController.php @@ -11,33 +11,39 @@ class MediaController extends Controller { use OpsTrait; + // main protected $fileSystem; protected $storageDisk; protected $ignoreFiles; protected $fileChars; protected $folderChars; protected $sanitizedText; - protected $unallowed_mimes; + protected $unallowedMimes; protected $LMF; - protected $locked_files_list; - protected $disks; + // extra + protected $storageDiskInfo; + protected $lockedList; + protected $cacheStore; + protected $db; public function __construct() { $config = config('mediaManager'); - $this->fileSystem = array_get($config, 'storage_disk'); - $this->storageDisk = app('filesystem')->disk($this->fileSystem); - $this->ignoreFiles = array_get($config, 'ignore_files'); - $this->fileChars = array_get($config, 'allowed_fileNames_chars'); - $this->folderChars = array_get($config, 'allowed_folderNames_chars'); - $this->sanitizedText = array_get($config, 'sanitized_text'); - $this->unallowed_mimes = array_get($config, 'unallowed_mimes'); - $this->LMF = array_get($config, 'last_modified_format'); - - $this->locked_files_list = array_get($config, 'locked_files_list'); - $this->disks = config("filesystems.disks.{$this->fileSystem}"); + $this->fileSystem = array_get($config, 'storage_disk'); + $this->storageDisk = app('filesystem')->disk($this->fileSystem); + $this->ignoreFiles = array_get($config, 'ignore_files'); + $this->fileChars = array_get($config, 'allowed_fileNames_chars'); + $this->folderChars = array_get($config, 'allowed_folderNames_chars'); + $this->sanitizedText = array_get($config, 'sanitized_text'); + $this->unallowedMimes = array_get($config, 'unallowed_mimes'); + $this->LMF = array_get($config, 'last_modified_format'); + + $this->db = app('db')->connection('mediamanager'); + $this->lockedList = $this->db->table('locked')->pluck('path'); + $this->storageDiskInfo = config("filesystems.disks.{$this->fileSystem}"); + $this->cacheStore = app('cache')->store('mediamanager'); } /** @@ -68,7 +74,7 @@ public function get_files(Request $request) } return response()->json([ - 'locked' => app('db')->connection('mediamanager')->table('locked')->pluck('path'), + 'locked' => $this->lockedList, 'files' => [ 'path' => $folder, 'items' => $this->getData($folder), @@ -121,7 +127,7 @@ public function upload(Request $request) try { // check for mime type - if (str_contains($file_type, $this->unallowed_mimes)) { + if (str_contains($file_type, $this->unallowedMimes)) { throw new Exception(trans('MediaManager::messages.not_allowed_file_ext', ['attr'=>$file_type])); } @@ -291,7 +297,7 @@ public function move_file(Request $request) 'size' => $file_size, ]; } else { - $exc = array_get($this->disks, 'root') + $exc = array_get($this->storageDiskInfo, 'root') ? trans('MediaManager::messages.error_moving') : trans('MediaManager::messages.error_moving_cloud'); @@ -334,7 +340,7 @@ public function move_file(Request $request) } else { $exc = trans('MediaManager::messages.error_moving'); - if ('folder' == $one['type'] && !array_get($this->disks, 'root')) { + if ('folder' == $one['type'] && !array_get($this->storageDiskInfo, 'root')) { $exc = trans('MediaManager::messages.error_moving_cloud'); } @@ -410,7 +416,7 @@ public function lock_file(Request $request) { $path = $request->path; $state = $request->state; - $db = app('db')->connection('mediamanager')->table('locked'); + $db = $this->db->table('locked'); 'locked' == $state ? $db->insert(['path'=>$path]) @@ -420,60 +426,136 @@ public function lock_file(Request $request) } /** - * zip folders. - * - * @param Request $request [description] - * - * @return [type] [description] + * zip ops. */ public function folder_download(Request $request) { - $name = $request->name; - $dir = "{$request->folders}/$name"; + return $this->download( + $request->name, + $this->storageDisk->allFiles("{$request->folders}/$request->name"), + 'folder' + ); + } + + public function files_download(Request $request) + { + return $this->download( + $request->name . '-files', + json_decode($request->list, true), + 'files' + ); + } + + protected function download($name, $list, $type) + { + // track changes + $counter = 100 / count($list); + $store = $this->cacheStore; + $cache_name = $name; + $store->forever("$cache_name.progress", 0); - return response()->stream(function () use ($name, $dir) { + return response()->stream(function () use ($name, $list, $type, $counter, $store, $cache_name) { $zip = new ZipStream("$name.zip", [ 'content_type' => 'application/octet-stream', ]); - foreach ($this->storageDisk->allFiles($dir) as $file) { - if ($streamRead = $this->storageDisk->readStream($file)) { - $zip->addFileFromStream(pathinfo($file, PATHINFO_BASENAME), $streamRead); + foreach ($list as $file) { + if ('folder' == $type) { + $file_name = pathinfo($file, PATHINFO_BASENAME); + $streamRead = $this->storageDisk->readStream($file); + } else { + $file_name = $file['name']; + $streamRead = @fopen($file['path'], 'r'); + } + + if ($streamRead) { + $store->increment("$cache_name.progress", round($counter, 2)); + $zip->addFileFromStream($file_name, $streamRead); } else { - die('Could not open stream for reading'); + $store->forever("$cache_name.abort", $file_name); + die(); } } + $store->forever("$cache_name.done", true); $zip->finish(); }); } /** - * zip files. - * - * @param Request $request [description] - * - * @return [type] [description] + * zip progress update. */ - public function files_download(Request $request) + public function zip_progress(Request $request) { - $name = $request->name; - $list = json_decode($request->list, true); + // stop execution + $start = time(); + $maxExecution = ini_get('max_execution_time'); + $sleep = array_get($this->storageDiskInfo, 'root') ? 0.5 : 1.5; + $close = false; + + // params + $id = $request->header('last-event-id'); + $name = $request->name; + + // get changes + $store = $this->cacheStore; + $cache_name = $name; + + return response()->stream(function () use ($start, $maxExecution, $close, $sleep, $store, $cache_name) { + while (!$close) { + // progress + $this->es_msg($store->get("$cache_name.progress"), 'progress'); + + // avoid server crash + if (time() >= $start + $maxExecution) { + $close = true; + $this->es_msg(null, 'exit'); + $this->clearZipCache($store, $cache_name); + } - return response()->stream(function () use ($name, $list) { - $zip = new ZipStream("$name.zip", [ - 'content_type' => 'application/octet-stream', - ]); + // abort + if ($store->has("$cache_name.abort")) { + $close = true; + $this->es_msg('Could not open "' . $store->get("$cache_name.abort") . '" stream for reading.', 'abort'); + $this->clearZipCache($store, $cache_name); + } - foreach ($list as $file) { - if ($streamRead = fopen($file['path'], 'r')) { - $zip->addFileFromStream($file['name'], $streamRead); - } else { - die('Could not open stream for reading'); + // done + if ($store->has("$cache_name.done")) { + $close = true; + $this->es_msg(100, 'progress'); + $this->es_msg('All Done', 'done'); + $this->clearZipCache($store, $cache_name); + } + + ob_flush(); + flush(); + + // don't wait unnecessary + if (!$close) { + sleep($sleep); } } + }, 200, [ + 'Content-Type' => 'text/event-stream', // needed for SSE to work + 'Cache-Control' => 'no-cache', // make sure we dont cache this response + 'X-Accel-Buffering' => 'no', // needed for while loop to work + 'Access-Control-Allow-Origin' => config('app.url'), // for cors + 'Access-Control-Expose-Headers' => '*', // for cors + 'Access-Control-Allow-Credentials' => true, // for cors + ]); + } - $zip->finish(); - }); + protected function es_msg($data = null, $event = null) + { + echo $event ? "event: $event\n" : ':'; + echo $data ? 'data: ' . json_encode(['response' => $data]) . "\n\n" : ':'; + } + + protected function clearZipCache($store, $item) + { + $store->forget("$item.progress"); + $store->forget("$item.done"); + $store->forget("$item.abort"); } } diff --git a/src/Controllers/OpsTrait.php b/src/Controllers/OpsTrait.php index 7998fef..d65c18c 100644 --- a/src/Controllers/OpsTrait.php +++ b/src/Controllers/OpsTrait.php @@ -120,10 +120,10 @@ protected function folderFiles($folder) */ protected function getFilePath($name) { - $disks = $this->disks; - $url = $this->storageDisk->url($name); - $dir = str_replace(array_get($disks, 'url'), '', $url); - $root = array_get($disks, 'root'); + $info = $this->storageDiskInfo; + $url = $this->storageDisk->url($name); + $dir = str_replace(array_get($info, 'url'), '', $url); + $root = array_get($info, 'root'); // for other disks without root ex."cloud" if (!$root) { diff --git a/src/MediaManagerServiceProvider.php b/src/MediaManagerServiceProvider.php index ed2a6c6..ce372fa 100644 --- a/src/MediaManagerServiceProvider.php +++ b/src/MediaManagerServiceProvider.php @@ -43,6 +43,13 @@ protected function packagePublish() 'prefix' => '', ]]); + // caching for zip-stream + config(['cache.stores.mediamanager' => [ + 'driver' => 'database', + 'table' => 'cache', + 'connection' => 'mediamanager', + ]]); + // public $this->publishes([ __DIR__ . '/dist' => public_path('assets/vendor/MediaManager'), diff --git a/src/MediaRoutes.php b/src/MediaRoutes.php index d08f254..5bcb28d 100644 --- a/src/MediaRoutes.php +++ b/src/MediaRoutes.php @@ -22,6 +22,7 @@ public static function routes() Route::post('rename_file', ['uses' => '\ctf0\MediaManager\Controllers\MediaController@rename_file', 'as' => 'rename_file']); Route::post('lock_file', ['uses' => '\ctf0\MediaManager\Controllers\MediaController@lock_file', 'as' => 'lock_file']); + Route::get('zip_progress/{name?}', ['uses' => '\ctf0\MediaManager\Controllers\MediaController@zip_progress', 'as' => 'zip_progress']); Route::post('folder_download', ['uses' => '\ctf0\MediaManager\Controllers\MediaController@folder_download', 'as' => 'folder_download']); Route::post('files_download', ['uses' => '\ctf0\MediaManager\Controllers\MediaController@files_download', 'as' => 'files_download']); }); diff --git a/src/database/MediaManager.sqlite b/src/database/MediaManager.sqlite index fbb18c6..ebdb212 100644 Binary files a/src/database/MediaManager.sqlite and b/src/database/MediaManager.sqlite differ diff --git a/src/resources/assets/js/components/media.vue b/src/resources/assets/js/components/media.vue index 08295c0..5288983 100644 --- a/src/resources/assets/js/components/media.vue +++ b/src/resources/assets/js/components/media.vue @@ -33,6 +33,7 @@ export default { 'filesRoute', 'dirsRoute', 'lockFileRoute', + 'zipProgressRoute', 'restrictPath', 'uploadPanelImgList', 'hideExt', @@ -118,10 +119,10 @@ export default { let ls = this.$ls.get('mediamanager') if (ls) { - this.randomNames = ls.randomNames == 'undefined' ? false : ls.randomNames - this.folders = ls.folders == 'undefined' ? [] : ls.folders - this.toolBar = ls.toolBar == 'undefined' ? true : ls.toolBar - this.selectedFile = ls.selectedFileName == 'undefined' ? null : ls.selectedFileName + this.randomNames = ls.randomNames === undefined ? false : ls.randomNames + this.folders = ls.folders === undefined ? [] : ls.folders + this.toolBar = ls.toolBar === undefined ? true : ls.toolBar + this.selectedFile = ls.selectedFileName === undefined ? null : ls.selectedFileName } }, diff --git a/src/resources/assets/js/components/mixins/download.js b/src/resources/assets/js/components/mixins/download.js new file mode 100644 index 0000000..6106403 --- /dev/null +++ b/src/resources/assets/js/components/mixins/download.js @@ -0,0 +1,87 @@ +export default { + methods: { + saveFile(item) { + if (this.isBulkSelecting()) { + this.bulkList.forEach((e) => { + if (e.type == 'folder') { + return this.showNotif(this.trans('sep_download'), 'warning') + } + downloadFile(e.path) + }) + + this.$refs['success-audio'].play() + return this.showNotif('All Done') + } + + downloadFile(item.path) + return this.showNotif(`"${item.name}" ${this.trans('downloaded')}`) + }, + hasFolder() { + return this.bulkList.some((e) => { + return e.type == 'folder' + }) + }, + + ZipDownload(type) { + this.showProgress = true + + // de-select download btn + this.$refs['zip'].forEach((e) => { + e.blur() + }) + + let folders = this.folders + let name = type == 'folder' + ? this.selectedFile.name + : folders.length ? `${folders[folders.length - 1]}-files` : 'media_manager-files' + + let es = new EventSource( + `${this.zipProgressRoute}/${name}`, + {withCredentials: true} + ) + + // events + es.addEventListener('progress', (e) => { + this.progressCounter = `${this.getESData(e)}%` + }, false) + + es.addEventListener('abort', (e) => { + this.showNotif(this.getESData(e), 'danger') + this.hideProgress(es) + }, false) + + es.addEventListener('done', (e) => { + this.showNotif(this.getESData(e)) + setTimeout(() => { + this.hideProgress(es) + }, 1000) + }, false) + + es.addEventListener('exit', () => { + console.warn('Error: script took too long, listener terminated') + this.hideProgress(es) + }, false) + + // error + es.addEventListener('error', (e) => { + if (e.readyState == EventSource.CLOSED) { + this.hideProgress(es) + console.error(`Error: connection terminated, ${EventSource}`) + } + }, false) + }, + getESData(e, item = 'response') { + let data = JSON.parse(e.data) + + return item ? data[item] : data + }, + hideProgress(es) { + es.close() + this.progressCounter = 0 + this.showProgress = false + this.toggleInfo = true + this.toggleLoading() + this.loadingFiles('hide') + } + } +} diff --git a/src/resources/assets/js/components/mixins/form.js b/src/resources/assets/js/components/mixins/form.js index 9ca59e8..65991b2 100644 --- a/src/resources/assets/js/components/mixins/form.js +++ b/src/resources/assets/js/components/mixins/form.js @@ -1,4 +1,7 @@ +import Download from './download' + export default { + mixins: [Download], methods: { /* Main */ getFiles(folders = '/', prev_folder = null, prev_file = null) { @@ -58,27 +61,25 @@ export default { this.selectFirst() } - // check for prev opened folder - if (prev_folder) { - this.$nextTick(() => { + this.$nextTick(() => { + // check for prev opened folder + if (prev_folder) { this.files.items.some((e, i) => { if (e.name == prev_folder) { return this.setSelected(e, i) } }) - }) - } + } - // check for prev selected file - if (prev_file) { - this.$nextTick(() => { + // check for prev selected file + if (prev_file) { this.files.items.some((e, i) => { if (e.name == prev_file) { return this.setSelected(e, i) } }) - }) - } + } + }) // we have files if (this.allItemsCount) { @@ -86,19 +87,17 @@ export default { this.loadingFiles('hide') this.toggleInfo = true - // scroll to prev selected item - setTimeout(() => { + this.$nextTick(() => { + // scroll to prev selected item if (this.currentFileIndex) { this.scrollToFile(this.$refs[`file_${this.currentFileIndex}`]) } - }, 800) - // scroll to breadcrumb item - setTimeout(() => { + // scroll to breadcrumb item let name = folders.split('/').pop() - let count = document.getElementById(`${name ? name : 'home'}-bc`).offsetLeft - this.$refs.bc.scrollBy({top: 0, left: count, behavior: 'smooth'}) - }, 100) + let count = document.getElementById(`${name ? name : 'library'}-bc`).offsetLeft + this.$refs.bc.$el.scrollBy({top: 0, left: count, behavior: 'smooth'}) + }) return this.updateDirsList() } @@ -389,7 +388,7 @@ export default { if (this.filteredItemsCount) { this.filterdList.some((e) => { - if (e.name == destination) { + if (e.type == 'folder' && e.name == destination) { e.items += parseInt(count) e.size += parseInt(weight) } @@ -397,7 +396,7 @@ export default { } this.files.items.some((e) => { - if (e.name == destination) { + if (e.type == 'folder' && e.name == destination) { e.items += parseInt(count) e.size += parseInt(weight) } diff --git a/src/resources/assets/js/components/mixins/selected.js b/src/resources/assets/js/components/mixins/selected.js index 68e71fe..eb15310 100644 --- a/src/resources/assets/js/components/mixins/selected.js +++ b/src/resources/assets/js/components/mixins/selected.js @@ -15,17 +15,41 @@ export default { if (e && e.shiftKey) { this.bulkSelect = true - // normal + // forward let begin = this.currentFileIndex - let end = index + 1 + let end = index + let dir = 'forward' - // reverse + // backward if (begin > index) { begin = index - end = this.currentFileIndex + 1 + end = this.currentFileIndex + dir = 'backward' } - return this.bulkList = this.allFiles.slice(begin, end) + // search + if (this.searchFor) { + this.bulkList = [] + let indexList = this.getRange(begin, end) + + indexList.map((i) => { + this.$refs[`file_${i}`][0].click() + }) + + // to have the same expected pattern as normal shift + click + if (dir == 'forward') { + this.selectedFile = this.bulkList[0] + this.currentFileIndex = indexList[0] + } else { + this.selectedFile = this.bulkList[this.bulkItemsCount - 1] + this.currentFileIndex = indexList[indexList.length - 1] + } + + return + } + + // default + return this.bulkList = this.allFiles.slice(begin, end + 1) } // normal selection @@ -37,6 +61,9 @@ export default { this.pushtoBulkList(file) } }, + getRange(start, end) { + return Array(end - start + 1).fill().map((_, idx) => start + idx) + }, selectedFileIs(val) { if (this.selectedFile !== null) { return this.fileTypeIs(this.selectedFile, val) diff --git a/src/resources/assets/js/components/mixins/utils.js b/src/resources/assets/js/components/mixins/utils.js index 66bb14f..11db75a 100644 --- a/src/resources/assets/js/components/mixins/utils.js +++ b/src/resources/assets/js/components/mixins/utils.js @@ -179,20 +179,6 @@ export default { this.linkCopied = true this.$copyText(path) }, - // download - saveFile(item) { - if (this.isBulkSelecting()) { - this.bulkList.forEach((e) => { - downloadFile(e.path) - }) - - manager.$refs['success-audio'].play() - return this.showNotif('All Done') - } - - downloadFile(item.path) - return this.showNotif(`"${item.name}" ${this.trans('downloaded')}`) - }, // ls updateLs(obj) { diff --git a/src/resources/assets/js/manager.js b/src/resources/assets/js/manager.js index 1c1a1de..f705b8c 100644 --- a/src/resources/assets/js/manager.js +++ b/src/resources/assets/js/manager.js @@ -54,7 +54,7 @@ import 'vue-awesome/icons/shopping-basket' import 'vue-awesome/icons/folder' import 'vue-awesome/icons/refresh' import 'vue-awesome/icons/share' -import 'vue-awesome/icons/i-cursor' +import 'vue-awesome/icons/terminal' import 'vue-awesome/icons/trash' import 'vue-awesome/icons/minus' import 'vue-awesome/icons/plus' diff --git a/src/resources/assets/sass/extra/vars.scss b/src/resources/assets/sass/extra/vars.scss index 6a01529..86d0683 100644 --- a/src/resources/assets/sass/extra/vars.scss +++ b/src/resources/assets/sass/extra/vars.scss @@ -19,4 +19,4 @@ $red: hsl(348, 100%, 61%); $blue: hsl(217, 71%, 53%); $shadow_1: 0 10px 45px 0 rgba($black, 0.2); $shadow_2: 0 6px 25px 0 rgba($black, 0.3); -$shadow_3: 0 6px 20px rgba($black, 0.08); +$shadow_3: 0 6px 10px rgba($black, 0.08); diff --git a/src/resources/assets/sass/media.scss b/src/resources/assets/sass/media.scss index eb39e0e..e5156e2 100644 --- a/src/resources/assets/sass/media.scss +++ b/src/resources/assets/sass/media.scss @@ -124,41 +124,81 @@ overflow: scroll; align-items: center; width: 100%; - padding: 1rem 0; + padding: 1rem 0 2rem; list-style: none; + transition: all 0.25s ease-in-out; li { + position: relative; flex: 1; margin-right: 1rem; + padding: 2px; text-align: center; + border: 1px dashed darken($active_theme, 2%); + border-radius: 5px; - a { - display: block; + // --- + &::after { + position: absolute; + top: 50%; + right: -1rem; + width: 1rem; + content: ''; + border-top: 1px dashed darken($active_theme, 2%); + } + + &:last-of-type { + margin-right: 0; + margin-left: 1px; + padding-right: 2rem; + + &::after { + display: none; + } + + // get around vue not animating items + // because of changeing border style + &::before { + position: absolute; + top: -1px; + right: -1px; + bottom: -1px; + left: 15%; + content: ''; + border: 1px solid $white; + border-left: none; + border-radius: 0 5px 5px 0; + } + } + + // ---• + &:nth-last-of-type(2)::before { + font-size: 1.8rem; + position: absolute; + z-index: 1; + top: 0.65rem; + right: -1.57rem; + content: '•'; + color: darken($active_theme, 2%); } a, - &:only-of-type { + p { + display: block; padding: 1rem; - transition: all 0.3s ease-in-out; white-space: nowrap; - color: $blue; - border: 1px solid lighten($active_theme, 2%); border-radius: 5px; background: $white; - - &:hover { - border-color: transparent; - box-shadow: $shadow_3; - } } - &:only-of-type { - display: none; - } + a { + transition: all 0.25s ease-in-out; + color: $blue; + box-shadow: $shadow_3; - &:last-of-type { - margin-right: 0; - padding-right: 3rem; + &:hover { + box-shadow: none; + } } } } @@ -427,6 +467,7 @@ overflow: hidden; text-align: center; color: darken($active_theme, 50%); + border-bottom: 1px dashed darken($active_theme, 5%); .__sidebar-none-selected { display: flex; @@ -475,10 +516,6 @@ &:not(.__sidebar-count) { flex: 1; - &:not(:empty) { - border-top: 1px solid darken($active_theme, 5%); - } - h4 { font-size: 1rem; margin-bottom: 0.1em; @@ -549,8 +586,7 @@ /* modal */ .__modal-preview { - align-items: center; - padding: 0.7rem; + padding: 0.7rem 0.7rem 0; * { color: $black; @@ -735,18 +771,23 @@ padding: 0; cursor: pointer; vertical-align: bottom; + color: darken($active_theme, 70%); border: none; border-radius: 0; background: transparent; - * { - color: darken($active_theme, 70%); - } - &:focus { border: none; box-shadow: none !important; } + + &:disabled { + cursor: not-allowed; + + * { + color: darken($active_theme, 20%); + } + } } a[target='_blank'] { @@ -811,25 +852,31 @@ a[target='_blank'] { } .modal { + overflow: scroll; align-items: flex-start; - &.is-active { - padding-top: 4%; + .modal-background { + position: fixed; } -} -.modal-card { - margin: 0; - padding: 1rem; -} + .modal-card { + margin: 0; + padding: 1rem; + } -.modal-content { - box-shadow: $shadow_1; -} + .modal-content { + box-shadow: $shadow_1; + } -.modal-card-foot { - justify-content: flex-end; - background-color: $white; + .modal-card-foot { + justify-content: flex-end; + background-color: $white; + } + + &.is-active { + margin-bottom: 2%; + padding-top: 4%; + } } .image { diff --git a/src/resources/lang/en/messages.php b/src/resources/lang/en/messages.php index d489609..cdbfc4f 100644 --- a/src/resources/lang/en/messages.php +++ b/src/resources/lang/en/messages.php @@ -3,7 +3,7 @@ return array ( 'add_folder' => 'Add Folder', 'add_new_folder' => 'Add New Folder', - 'ajax_error' => 'Oh NO! Something Went Wrong', + 'ajax_error' => 'Oh NO! Something Went Wrong.', 'are_you_sure_delete' => 'Are you sure you want to delete ?', 'audio_support' => 'Your browser does not support the audio element.', 'bulk_select' => 'Bulk Select', @@ -11,6 +11,7 @@ 'clear' => 'Clear :attr', 'close' => 'Close', 'copied' => 'Copied', + 'copy' => 'Copy', 'copy_file_folder' => 'Copy File/Folder', 'copy_files' => 'Copy Files Instead ?', 'copy_success' => 'Successfully Copied', @@ -18,7 +19,7 @@ 'create_new_folder' => 'Create New Folder', 'create_success' => 'Successfully Created', 'delete' => 'Delete', - 'delete_confirm' => 'Yes, Delete it!', + 'delete_confirm' => 'Yes, Delete it !', 'delete_folder' => 'Deleting a folder will remove all files and folders contained inside.', 'delete_success' => 'Successfully Deleted', 'destination_folder' => 'Destination Folder', @@ -26,10 +27,11 @@ 'download_folder' => 'Download Folder', 'downloaded' => 'Downloaded', 'error_already_exists' => 'A File/Folder already exists with that name.', - 'error_creating_dir' => 'Something seems to have gone wrong with creating the directory, please check your permissions,', - 'error_deleting_file' => 'Something seems to have gone wrong deleting this file / folder, please check your permissions,', + 'error_creating_dir' => 'Something gone wrong while creating the directory, please check your permissions,', + 'error_deleting_file' => 'Something  gone wrong while deleting this file / folder, please check your permissions,', 'error_doesnt_exist' => 'Folder ":attr" Doesnt Exist', - 'error_moving' => 'There seems to be a problem moving that file / folder, make sure you have the correct permissions.', + 'error_moving' => 'There seems to be a problem moving this file / folder, make sure you have the correct permissions.', + 'error_moving_cloud' => 'Cloud Folders can\'t be "Renamed, Moved or Copied".', 'filter_by' => 'Filter By :attr', 'find' => 'Find', 'found' => 'Found', @@ -59,6 +61,7 @@ 'select_all' => 'Select All', 'select_non' => 'Select Non', 'selected' => 'Selected', + 'sep_download' => 'Folders Should Be Downloaded Separately.', 'single_char_folder' => 'Folders With First Level Path As Single Character Should Be Avoided', 'size' => 'Size', 'sort_by' => 'Sort By', @@ -71,9 +74,6 @@ 'upload' => 'Upload', 'upload_success' => 'Successfully Uploaded', 'upload_text' => 'Drag & Drop Files
Or
Click To Upload', - 'url' => 'URL', 'use_random_names' => 'Use Random Names ?', 'video_support' => 'Your browser does not support the video tag.', - 'copy' => 'Copy', - 'error_moving_cloud' => 'Cloud Folders can\'t be "Renamed / Moved or Copied".', ); \ No newline at end of file diff --git a/src/resources/views/_manager.blade.php b/src/resources/views/_manager.blade.php index a0cdfe1..d80c892 100644 --- a/src/resources/views/_manager.blade.php +++ b/src/resources/views/_manager.blade.php @@ -17,17 +17,19 @@ 'no_val' => trans('MediaManager::messages.no_val'), 'single_char_folder' => trans('MediaManager::messages.single_char_folder'), 'downloaded' => trans('MediaManager::messages.downloaded'), + 'sep_download' => trans('MediaManager::messages.sep_download'), 'upload_success' => trans('MediaManager::messages.upload_success'), 'create_success' => trans('MediaManager::messages.create_success'), 'rename_success' => trans('MediaManager::messages.rename_success'), 'move_success' => trans('MediaManager::messages.move_success'), 'delete_success' => trans('MediaManager::messages.delete_success'), - 'copy_success' => trans('MediaManager::messages.copy_success') + 'copy_success' => trans('MediaManager::messages.copy_success'), ]) }}" :upload-panel-img-list="{{ $patterns }}" files-route="{{ route('media.files') }}" dirs-route="{{ route('media.directories') }}" lock-file-route="{{ route('media.lock_file') }}" + zip-progress-route="{{ route('media.zip_progress') }}" :restrict-path="{{ isset($path) ? $path : 'null' }}">
@@ -90,7 +92,7 @@ :disabled="mv_dl() || !checkForFolders || isLoading" v-tippy title="m" @click="moveItem()"> - + {{ trans('MediaManager::messages.move') }}
@@ -101,7 +103,7 @@ :disabled="!selectedFile || IsInLockedList(selectedFile) || isLoading" v-if="!isBulkSelecting()" @click="renameItem()"> - + {{ trans('MediaManager::messages.rename') }} @@ -286,11 +288,6 @@ class="button" - {{-- mobile breadCrumb --}} - @if ($alt_breadcrumb) - @include('MediaManager::extras._breadcrumb') - @endif - {{-- ====================================================================== --}} {{-- dropzone --}} @@ -318,6 +315,13 @@ class="button" {{-- ====================================================================== --}} + {{-- mobile breadCrumb --}} + @if ($alt_breadcrumb) + @include('MediaManager::extras._breadcrumb') + @endif + + {{-- ====================================================================== --}} +
{{-- loadings --}} @@ -514,11 +518,11 @@ class="link image"

{{ trans('MediaManager::messages.download_folder') }}:
-
+ {{ csrf_field() }} -
@@ -543,11 +547,11 @@ class="link image" {{-- zip --}}