chunk upload and multipart upload beta.1

This commit is contained in:
carodej
2020-07-29 12:29:30 +02:00
parent bf8db1be52
commit 18761eb5b3
18 changed files with 307 additions and 243 deletions

View File

@@ -16,6 +16,7 @@ But, it can't be done without you, development is more and more complicated and
- [Server Requirements](#server-requirements)
- [Installation](#installation)
- [PHP Configuration](#php-configuration)
- [Chunk Upload](#chunk-upload)
- [Nginx Configuration](#nginx-configuration)
- [Apache Configuration](#apache-configuration)
- [Recover Failed Installation](#installation-failed)
@@ -82,11 +83,16 @@ That was the hardest part of installation proces. Please follow instructions in
There are several PHP settings good to know to setup before you try upload any file. Please set these values in your php.ini, we provide minimal setup for you. When you set `-1` then you set infinity limits.
```
memory_limit = 512M
upload_max_filesize = 1024M
post_max_size = 1024M
memory_limit = 128M
upload_max_filesize = 128
post_max_size = 128M
max_file_uploads = 50
max_execution_time = 1800
```
## Chunk Upload
VueFileManager in default supporting chunk upload. Default chunk upload size is `128MB`. If you wish change this default value, go to `/config/vuefilemanager.php` and change `chunk_size` attribute.
if you use external storage, and upload large files, to prevent failing upload process make sure you have enough space in your application space.
## Nginx Configuration
If you running VueFileManager undex Nginx, don't forget set this value in your `nginx.conf` file:

View File

@@ -148,6 +148,7 @@ class BrowseController extends Controller
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected'])
->where('user_id', $user_id)
->where('parent_id', $unique_id)
->orderBy('created_at', 'DESC')
->get();
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected'])

View File

@@ -589,8 +589,8 @@ class SetupWizardController extends Controller
// Create legal pages and index content
if ($request->license === 'Extended') {
$pages = collect(config('vuefilemanager.pages'));
$content = collect(config('vuefilemanager.content'));
$pages = collect(config('content.pages'));
$content = collect(config('content.content'));
$content->each(function ($content) {
Setting::updateOrCreate($content);

View File

@@ -25,8 +25,8 @@ class UpgradeAppController extends Controller
// Create legal pages and index content
if ($request->license === 'Extended') {
$pages = collect(config('vuefilemanager.pages'));
$content = collect(config('vuefilemanager.content'));
$pages = collect(config('content.pages'));
$content = collect(config('content.content'));
$content->each(function ($content) {
Setting::updateOrCreate($content);

View File

@@ -463,10 +463,10 @@ function format_date($date, $format = '%d. %B. %Y, %H:%M')
* @param $file
* @return string
*/
function get_file_type($file_path)
function get_file_type($file_mimetype)
{
// Get mimetype from file
$mimetype = explode('/', Storage::disk('local')->mimeType($file_path));
$mimetype = explode('/', $file_mimetype);
switch ($mimetype[0]) {
case 'image':
@@ -483,7 +483,13 @@ function get_file_type($file_path)
}
}
// Get mimetype from file
/**
* Get file type from mimetype
*
* @param $mimetype
* @return mixed
*/
function get_file_type_from_mimetype($mimetype)
{
return explode('/', $mimetype)[1];

View File

@@ -102,7 +102,7 @@ class Demo
$filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName());
$thumbnail = null;
$filesize = $file->getSize();
$filetype = get_file_type($file);
$filetype = get_file_type($file->getMimeType());
return [
'id' => random_int(1000, 9999),

View File

@@ -239,68 +239,58 @@ class Editor
public static function upload($request, $shared = null)
{
// Get parent_id from request
$folder_id = $request->parent_id === 0 ? 0 : $request->parent_id;
$file = $request->file('file');
// Check or create directories
self::check_directories(['chunks', 'file-manager']);
// File name
$user_file_name = basename('chunks/' . substr($file->getClientOriginalName(),17), '.part');
$disk_file_name = basename('chunks/' . $file->getClientOriginalName(), '.part');
$temp_filename = $file->getClientOriginalName();
// Generate file
File::append(storage_path() . '/app/chunks/' . $file->getClientOriginalName(), $file->get());
File::append(storage_path() . '/app/chunks/' . $temp_filename, $file->get());
// If last then process file
if ($request->has('is_last') && $request->boolean('is_last')) {
if ($request->boolean('is_last')) {
// Get original file name
$original_file_name = basename('chunks/' . $file->getClientOriginalName(), '.part');
// Rename chunk part to original file name in chunk directory
Storage::disk('local')->move('chunks/' . $file->getClientOriginalName(), 'chunks/' . $original_file_name);
$disk_local = Storage::disk('local');
// Get user data
$user_scope = is_null($shared) ? $request->user()->token()->scopes[0] : 'editor';
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
$user_storage_used = user_storage_percentage($user_id, Storage::disk('local')->size('chunks/' . $original_file_name));
// Get storage limitation setup
$storage_limitation = get_setting('storage_limitation');
// File Info
$file_size = $disk_local->size('chunks/' . $temp_filename);
$file_mimetype = $disk_local->mimeType('chunks/' . $temp_filename);
// Check if user can upload
if ($storage_limitation && $user_storage_used >= 100) {
// Delete file
Storage::disk('local')->delete('chunks/' . $original_file_name);
// Abort uploading
abort(423, 'You exceed your storage limit!');
}
// File name
$prefixed_file_name = Str::random() . '-' . str_replace(' ', '', $original_file_name);
// Check if user has enough space to upload file
self::check_user_storage_capacity($user_id, $file_size, $temp_filename);
// Create thumbnail
$thumbnail = self::get_image_thumbnail('chunks/' . $original_file_name, $prefixed_file_name, $file);
$thumbnail = self::get_image_thumbnail('chunks/' . $temp_filename, $user_file_name);
// Store to disk
Storage::disk('local')->move('chunks/' . $original_file_name, 'file-manager/' . $prefixed_file_name);
// Move finished file from chunk to file-manager directory
$disk_local->move('chunks/' . $temp_filename, 'file-manager/' . $disk_file_name);
// Store file
$options = [
'name' => pathinfo($file->getClientOriginalName())['filename'],
'mimetype' => get_file_type_from_mimetype(Storage::disk('local')->mimeType('file-manager/' . $prefixed_file_name)),
'mimetype' => get_file_type_from_mimetype($file_mimetype),
'type' => get_file_type($file_mimetype),
'folder_id' => $request->parent_id,
'name' => $user_file_name,
'unique_id' => get_unique_id(),
'basename' => $disk_file_name,
'user_scope' => $user_scope,
'folder_id' => $folder_id,
'thumbnail' => $thumbnail,
'basename' => $prefixed_file_name,
'filesize' => Storage::disk('local')->size('file-manager/' . $prefixed_file_name),
'type' => get_file_type('file-manager/' . $prefixed_file_name),
'filesize' => $file_size,
'user_id' => $user_id,
];
// Move files to external storage
if (! is_storage_driver(['local'])) {
self::move_to_external_storage($prefixed_file_name, $thumbnail);
self::move_to_external_storage($disk_file_name, $thumbnail);
}
// Return new file
@@ -316,13 +306,15 @@ class Editor
*/
private static function move_to_external_storage(string $filename, ?string $thumbnail): void
{
$disk_local = Storage::disk('local');
foreach ([$filename, $thumbnail] as $file) {
// Check if file exist
if (!$file) continue;
// Get file size
$filesize = Storage::disk('local')->size('file-manager/' . $filename);
$filesize = $disk_local->size('file-manager/' . $filename);
// If file is bigger than 5.2MB then run multipart upload
if ($filesize > 5242880) {
@@ -342,16 +334,18 @@ class Editor
'key' => 'file-manager/' . $file
]);
// Upload content
try {
// Upload content
$uploader->upload();
} catch (MultipartUploadException $e) {
// Write error log
Log::error($e->getMessage());
// Delete file after error
Storage::disk('local')->delete('file-manager/' . $file);
$disk_local->delete('file-manager/' . $file);
throw new HttpException(409, $e->getMessage());
}
@@ -363,7 +357,7 @@ class Editor
}
// Delete file after upload
Storage::disk('local')->delete('file-manager/' . $file);
$disk_local->delete('file-manager/' . $file);
}
}
@@ -391,34 +385,63 @@ class Editor
/**
* Create thumbnail for images
*
* @param string $chunk_file_path
* @param string $file_path
* @param string $filename
* @param $file
* @return string|null
*/
private static function get_image_thumbnail(string $chunk_file_path, string $filename, $file)
private static function get_image_thumbnail(string $file_path, string $filename)
{
if (in_array(Storage::disk('local')->mimeType($chunk_file_path), ['image/gif', 'image/jpeg', 'image/jpg', 'image/png', 'image/webp'])) {
$local_disk = Storage::disk('local');
// Create thumbnail from image
if (in_array($local_disk->mimeType($file_path), ['image/gif', 'image/jpeg', 'image/jpg', 'image/png', 'image/webp'])) {
// Get thumbnail name
$thumbnail = 'thumbnail-' . $filename;
// Create intervention image
$image = Image::make(storage_path() . '/app/' . $chunk_file_path)->orientate();
$image = Image::make(storage_path() . '/app/' . $file_path)->orientate();
// Resize image
$image->resize(564, null, function ($constraint) {
$image->resize(512, null, function ($constraint) {
$constraint->aspectRatio();
})->stream();
// Store thumbnail to disk
Storage::disk('local')->put('file-manager/' . $thumbnail, $image);
$local_disk->put('file-manager/' . $thumbnail, $image);
}
} elseif (Storage::disk('local')->mimeType($chunk_file_path) === 'image/svg+xml') {
// Return thumbnail as svg file
if ($local_disk->mimeType($file_path) === 'image/svg+xml') {
$thumbnail = $filename;
}
return $thumbnail ?? null;
}
/**
* Check if user has enough space to upload file
*
* @param $user_id
* @param int $file_size
* @param $temp_filename
*/
private static function check_user_storage_capacity($user_id, int $file_size, $temp_filename): void
{
// Get user storage percentage and get storage_limitation setting
$user_storage_used = user_storage_percentage($user_id, $file_size);
$storage_limitation = get_setting('storage_limitation');
// Check if user can upload
if ($storage_limitation && $user_storage_used >= 100) {
// Delete file
Storage::disk('local')->delete('chunks/' . $temp_filename);
// Abort uploading
abort(423, 'You exceed your storage limit!');
}
}
}

102
config/content.php Normal file
View File

@@ -0,0 +1,102 @@
<?php
return [
'pages' => [
[
'visibility' => 1,
'title' => 'Terms of Service',
'slug' => 'terms-of-service',
'content' => 'Laoreet cum hendrerit iaculis arcu phasellus congue et elementum, pharetra risus imperdiet aptent posuere rutrum parturient blandit, dapibus tellus ridiculus potenti aliquam sociis turpis. Nullam commodo eget laoreet risus cursus vel placerat, in dapibus sociis gravida faucibus sodales, fringilla potenti elit semper iaculis ullamcorper. Dignissim vulputate pretium montes pellentesque mollis, consectetur adipiscing curabitur semper sem rhoncus, litora viverra curae proin.',
],
[
'visibility' => 1,
'title' => 'Privacy Policy',
'slug' => 'privacy-policy',
'content' => 'Sit orci justo augue maecenas laoreet consectetur natoque magnis in viverra sagittis, himenaeos urna facilisis mus proin primis diam accumsan tristique inceptos. Primis quisque posuere sit praesent lobortis feugiat semper convallis facilisis, vivamus gravida ligula nostra curae eu donec duis parturient senectus, arcu dolor viverra penatibus natoque cum nisi commodo. Litora sociis mauris justo nullam suspendisse mattis maecenas nascetur congue phasellus cras ultricies posuere donec, dapibus egestas diam lacus ornare montes senectus tincidunt eu taciti sed consequat.',
],
[
'visibility' => 1,
'title' => 'Cookie Policy',
'slug' => 'cookie-policy',
'content' => 'Metus penatibus ligula dolor natoque non habitasse laoreet facilisis, libero vivamus eget semper vulputate interdum integer, phasellus lorem enim blandit consectetur nullam sollicitudin. Hendrerit interdum luctus ut in molestie himenaeos eros cum laoreet parturient est, eu lectus hac et netus viverra dictumst congue elit sem senectus litora, fames scelerisque adipiscing inceptos fringilla montes sociosqu suscipit auctor potenti. Elementum lacus vulputate viverra ac morbi ligula ipsum facilisi, sit eu imperdiet lacinia congue dis vitae.',
],
],
'content' => [
[
'name' => 'section_features',
'value' => '1',
],
[
'name' => 'section_feature_boxes',
'value' => '1',
],
[
'name' => 'section_pricing_content',
'value' => '1',
],
[
'name' => 'section_get_started',
'value' => '1',
],
[
'name' => 'header_title',
'value' => 'Simple <span style="color: #41B883">&</span> Powerful Personal Cloud Storage',
],
[
'name' => 'header_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
],
[
'name' => 'features_title',
'value' => 'The Fastest Growing <span style="color: #41B883">File Manager</span> on the CodeCanyon Market',
],
[
'name' => 'features_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
],
[
'name' => 'feature_title_1',
'value' => 'Truly Freedom',
],
[
'name' => 'feature_description_1',
'value' => 'You have full control over VueFileManager, no third authorities will control your service or usage, only you.',
],
[
'name' => 'feature_title_2',
'value' => 'The Sky is the Limit',
],
[
'name' => 'feature_description_2',
'value' => 'VueFileManager is cloud storage software. You have to install and running application on your own server hosting.',
],
[
'name' => 'feature_title_3',
'value' => 'No Monthly Fees',
],
[
'name' => 'feature_description_3',
'value' => 'When you running VueFileManager on your own server hosting, anybody can\'t control your content or resell your user data. Your data is safe.',
],
[
'name' => 'pricing_title',
'value' => 'Pick the <span style="color: #41B883;">Best Plan</span> For Your Needs',
],
[
'name' => 'pricing_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
],
[
'name' => 'get_started_title',
'value' => 'Ready to Get <span style="color: #41B883">Started</span><br> With Us?',
],
[
'name' => 'get_started_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
],
[
'name' => 'footer_content',
'value' => '© 2020 Simple & Powerfull Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank">Hi5Ve.Digital</a>',
],
],
];

View File

@@ -6,104 +6,4 @@ return [
// Define size of chunk uploaded by MB. E.g. integer 128 means chunk size will be 128MB.
'chunk_size' => '128',
'pages' => [
[
'visibility' => 1,
'title' => 'Terms of Service',
'slug' => 'terms-of-service',
'content' => 'Laoreet cum hendrerit iaculis arcu phasellus congue et elementum, pharetra risus imperdiet aptent posuere rutrum parturient blandit, dapibus tellus ridiculus potenti aliquam sociis turpis. Nullam commodo eget laoreet risus cursus vel placerat, in dapibus sociis gravida faucibus sodales, fringilla potenti elit semper iaculis ullamcorper. Dignissim vulputate pretium montes pellentesque mollis, consectetur adipiscing curabitur semper sem rhoncus, litora viverra curae proin.',
],
[
'visibility' => 1,
'title' => 'Privacy Policy',
'slug' => 'privacy-policy',
'content' => 'Sit orci justo augue maecenas laoreet consectetur natoque magnis in viverra sagittis, himenaeos urna facilisis mus proin primis diam accumsan tristique inceptos. Primis quisque posuere sit praesent lobortis feugiat semper convallis facilisis, vivamus gravida ligula nostra curae eu donec duis parturient senectus, arcu dolor viverra penatibus natoque cum nisi commodo. Litora sociis mauris justo nullam suspendisse mattis maecenas nascetur congue phasellus cras ultricies posuere donec, dapibus egestas diam lacus ornare montes senectus tincidunt eu taciti sed consequat.',
],
[
'visibility' => 1,
'title' => 'Cookie Policy',
'slug' => 'cookie-policy',
'content' => 'Metus penatibus ligula dolor natoque non habitasse laoreet facilisis, libero vivamus eget semper vulputate interdum integer, phasellus lorem enim blandit consectetur nullam sollicitudin. Hendrerit interdum luctus ut in molestie himenaeos eros cum laoreet parturient est, eu lectus hac et netus viverra dictumst congue elit sem senectus litora, fames scelerisque adipiscing inceptos fringilla montes sociosqu suscipit auctor potenti. Elementum lacus vulputate viverra ac morbi ligula ipsum facilisi, sit eu imperdiet lacinia congue dis vitae.',
],
],
'content' => [
[
'name' => 'section_features',
'value' => '1',
],
[
'name' => 'section_feature_boxes',
'value' => '1',
],
[
'name' => 'section_pricing_content',
'value' => '1',
],
[
'name' => 'section_get_started',
'value' => '1',
],
[
'name' => 'header_title',
'value' => 'Simple <span style="color: #41B883">&</span> Powerfull Personal Cloud Storage',
],
[
'name' => 'header_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
],
[
'name' => 'features_title',
'value' => 'The Fastest Growing <span style="color: #41B883">File Manager</span> on the CodeCanyon Market',
],
[
'name' => 'features_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
],
[
'name' => 'feature_title_1',
'value' => 'Truly Freedom',
],
[
'name' => 'feature_description_1',
'value' => 'You have full control over VueFileManager, no third authorities will control your service or usage, only you.',
],
[
'name' => 'feature_title_2',
'value' => 'The Sky is the Limit',
],
[
'name' => 'feature_description_2',
'value' => 'VueFileManager is cloud storage software. You have to install and running application on your own server hosting.',
],
[
'name' => 'feature_title_3',
'value' => 'No Monthly Fees',
],
[
'name' => 'feature_description_3',
'value' => 'When you running VueFileManager on your own server hosting, anybody can\'t control your content or resell your user data. Your data is safe.',
],
[
'name' => 'pricing_title',
'value' => 'Pick the <span style="color: #41B883;">Best Plan</span> For Your Needs',
],
[
'name' => 'pricing_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
],
[
'name' => 'get_started_title',
'value' => 'Ready to Get <span style="color: #41B883">Started</span><br> With Us?',
],
[
'name' => 'get_started_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
],
[
'name' => 'footer_content',
'value' => '© 2020 Simple & Powerfull Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank">Hi5Ve.Digital</a>',
],
],
];

2
public/js/main.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -238,6 +238,7 @@
flex: 0 0 100%;
@include transition(150ms);
position: relative;
scroll-behavior: smooth;
&.is-fileinfo-visible {
flex: 0 1 100%;

View File

@@ -2,24 +2,39 @@
<transition name="info-panel">
<div v-if="uploadingFilesCount" class="upload-progress">
<div class="progress-title">
<span>{{ $t('uploading.progress', {current:uploadingFilesCount.current, total: uploadingFilesCount.total, progress: uploadingFileProgress}) }}</span>
<span v-if="isProcessingFile">
<refresh-cw-icon size="12" class="sync-alt"></refresh-cw-icon>
{{ $t('uploading.processing_file') }}
</span>
<span v-if="!isProcessingFile && uploadingFilesCount.total === 1">
{{ $t('uploading.progress_single_upload', {progress: uploadingFileProgress}) }}
</span>
<span v-if="!isProcessingFile && uploadingFilesCount.total > 1">
{{ $t('uploading.progress', {current:uploadingFilesCount.current, total: uploadingFilesCount.total, progress: uploadingFileProgress}) }}
</span>
</div>
<ProgressBar :progress="uploadingFileProgress"/>
<ProgressBar :progress="uploadingFileProgress" />
</div>
</transition>
</template>
<script>
import ProgressBar from '@/components/FilesView/ProgressBar'
import { RefreshCwIcon } from 'vue-feather-icons'
import {mapGetters} from 'vuex'
export default {
name: 'UploadProgress',
components: {
RefreshCwIcon,
ProgressBar,
},
computed: {
...mapGetters(['uploadingFileProgress', 'uploadingFilesCount'])
...mapGetters([
'uploadingFileProgress',
'uploadingFilesCount',
'isProcessingFile',
])
}
}
</script>
@@ -28,6 +43,24 @@
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.sync-alt {
animation: spin 1s linear infinite;
margin-right: 5px;
polyline, path {
stroke: $theme;
}
}
@keyframes spin {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
.info-panel-enter-active,
.info-panel-leave-active {
transition: all 0.3s ease;

View File

@@ -73,28 +73,31 @@ const Helpers = {
this.$store.dispatch('createFolder', folderName)
}
Vue.prototype.$uploadFiles = async function (files) {
// Prevent submit empty files
if (files && files.length == 0) return
Vue.prototype.$handleUploading = async function (files, parent_id) {
let fileCount = files ? files.length : 0
let fileCountSucceed = 1
let fileBuffer = []
// Append the file list to fileBuffer array
Array.prototype.push.apply(fileBuffer, files);
let fileSucceed = 0
// Update files count in progressbar
store.commit('UPDATE_FILE_COUNT_PROGRESS', {
current: fileCountSucceed,
total: fileCount
current: fileSucceed,
total: files.length
})
// Reset upload progress to 0
store.commit('UPLOADING_FILE_PROGRESS', 0)
// Get parent id
const rootFolder = this.$store.getters.currentFolder
? this.$store.getters.currentFolder.unique_id
: 0
let parentFolder = this.$store.getters.currentFolder ? this.$store.getters.currentFolder.unique_id : 0
let rootFolder = parent_id ? parent_id : parentFolder
for (var i = files.length - 1; i >= 0; i--) {
let file = files[i],
// Upload files
do {
let file = fileBuffer.shift(),
chunks = []
// Calculate ceils
@@ -108,21 +111,23 @@ const Helpers = {
));
}
// Set form Data
let formData = new FormData()
let uploadedSize = 0
// Set Data
let formData = new FormData(),
uploadedSize = 0,
isNotGeneralError = true
do {
let isLast = chunks.length === 1
let chunk = chunks.shift()
let attempts = 0
let isLast = chunks.length === 1,
chunk = chunks.shift(),
attempts = 0,
filename = Array(16).fill(0).map(x => Math.random().toString(36).charAt(2)).join('') + '-' + file.name + '.part'
// Set form data
formData.set('is_last', isLast);
formData.set('file', chunk, `${file.name}.part`);
formData.set('file', chunk, filename);
formData.set('parent_id', rootFolder)
formData.set('is_last', isLast);
// Upload data
// Upload chunks
do {
await store.dispatch('uploadFiles', {
form: formData,
@@ -130,35 +135,39 @@ const Helpers = {
totalUploadedSize: uploadedSize
}).then(() => {
uploadedSize = uploadedSize + chunk.size
}).catch(() => {
}).catch((error) => {
// Count attempts
attempts++
if (attempts === 3) {
events.$emit('alert:open', {
title: this.$t('popup_error.title'),
message: this.$t('popup_error.message'),
})
}
})
} while (attempts !== 0 && attempts !== 3)
// Break uploading proccess
if (error.response.status === 500)
isNotGeneralError = false
} while (chunks.length !== 0)
// Show Error
if (attempts === 3)
this.$isSomethingWrong()
})
} while (isNotGeneralError && attempts !== 0 && attempts !== 3)
} while (isNotGeneralError && chunks.length !== 0)
fileSucceed++
// Progress file log
store.commit('UPDATE_FILE_COUNT_PROGRESS', {
current: fileCountSucceed,
total: fileCount
current: fileSucceed,
total: files.length
})
// Uploading finished
if (fileCount === fileCountSucceed) {
store.commit('UPDATE_FILE_COUNT_PROGRESS', undefined)
} else {
// Add uploaded file
fileCountSucceed++
}
}
} while (fileBuffer.length !== 0)
store.commit('UPDATE_FILE_COUNT_PROGRESS', undefined)
}
Vue.prototype.$uploadFiles = async function (files) {
this.$handleUploading(files, undefined)
}
Vue.prototype.$uploadExternalFiles = async function (event, parent_id) {
@@ -167,44 +176,9 @@ const Helpers = {
if (event.dataTransfer.items.length == 0) return
// Get files
const files = [...event.dataTransfer.items].map(item => item.getAsFile());
let files = [...event.dataTransfer.items].map(item => item.getAsFile());
let fileCountSucceed = 1
store.commit('UPDATE_FILE_COUNT_PROGRESS', {
current: fileCountSucceed,
total: files.length
})
for (var i = files.length - 1; i >= 0; i--) {
let formData = new FormData()
// Append data
formData.append('file', files[i])
// Append form data
formData.append('parent_id', parent_id)
// Upload data
await store.dispatch('uploadFiles', formData).then(() => {
// Progress file log
store.commit('UPDATE_FILE_COUNT_PROGRESS', {
current: fileCountSucceed,
total: files.length
})
// Progress file log
store.commit('INCREASE_FOLDER_ITEM', parent_id)
// Uploading finished
if (files.length === fileCountSucceed) {
store.commit('UPDATE_FILE_COUNT_PROGRESS', undefined)
} else {
// Add uploaded file
fileCountSucceed++
}
})
}
this.$handleUploading(files, parent_id)
}
Vue.prototype.$downloadFile = function (url, filename) {

View File

@@ -680,7 +680,9 @@
"href": "Please confirm your payment."
},
"uploading": {
"progress": "上传文件 {current}/{total}"
"processing_file": "Processing File...",
"progress_single_upload": "上传文件 {progress}%",
"progress": "上传文件 {progress}% - {current}/{total}"
},
"user_add_card": {
"default_description": "",

View File

@@ -680,6 +680,8 @@
"href": "Please confirm your payment."
},
"uploading": {
"processing_file": "Processing File...",
"progress_single_upload": "Uploading File {progress}%",
"progress": "Uploading File {progress}% - {current}/{total}"
},
"user_add_card": {

View File

@@ -680,7 +680,9 @@
"href": "Prosím potvrďte Vašu platbu."
},
"uploading": {
"progress": "Nahrávam súbory {current}/{total}"
"processing_file": "Spracuvávam súbor...",
"progress_single_upload": "Nahrávam súbor {progress}%",
"progress": "Nahrávam súbory {progress}% - {current}/{total}"
},
"user_add_card": {
"default_description": "Vaša karta bude uložená a použitá pre platbu ako prvá.",

View File

@@ -8,6 +8,7 @@ const defaultState = {
fileInfoDetail: undefined,
currentFolder: undefined,
uploadingFileProgress: 0,
isProcessingFile: false,
navigation: undefined,
isSearching: false,
browseHistory: [],
@@ -285,11 +286,15 @@ const mutations = {
STORE_CURRENT_FOLDER(state, folder) {
state.currentFolder = folder
},
PROCESSING_FILE(state, status) {
state.isProcessingFile = status
}
}
const getters = {
uploadingFileProgress: state => state.uploadingFileProgress,
uploadingFilesCount: state => state.uploadingFilesCount,
isProcessingFile: state => state.isProcessingFile,
fileInfoDetail: state => state.fileInfoDetail,
currentFolder: state => state.currentFolder,
browseHistory: state => state.browseHistory,

View File

@@ -42,6 +42,8 @@ const actions = {
.then(response => {
commit('ADD_NEW_FOLDER', response.data)
events.$emit('scrollTop')
if ( getters.currentFolder.location !== 'public' ) {
dispatch('getAppData')
}
@@ -87,14 +89,17 @@ const actions = {
},
onUploadProgress: event => {
let loaded = totalUploadedSize + event.loaded
var percentCompleted = Math.floor(((totalUploadedSize + event.loaded) / fileSize) * 100)
var percentCompleted = Math.floor((loaded * 100) / fileSize)
commit('UPLOADING_FILE_PROGRESS', percentCompleted >= 100 ? 100 : percentCompleted)
commit('UPLOADING_FILE_PROGRESS', percentCompleted)
if (percentCompleted >= 100) {
commit('PROCESSING_FILE', true)
}
}
})
.then(response => {
commit('PROCESSING_FILE', false)
// Check if user is in uploading folder, if yes, than show new file
if (response.data.folder_id == getters.currentFolder.unique_id)
@@ -103,6 +108,8 @@ const actions = {
resolve(response)
})
.catch(error => {
commit('PROCESSING_FILE', false)
reject(error)
switch (error.response.status) {