mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-05-23 13:24:42 +00:00
Version 1.3
- i18n localization support - Added SK, EN language files - Video/Audio preview in file preview panel (Thanks to Joshua Fouyon to participating on this feature) - Drop uploading (You can now drag files from desktop and drop it to VueFileManager) - Fixed bug when rename item in safari browser - Fixed bug when you drag folder from trash to favourites in sidebar panel - small functions and design improvements
This commit is contained in:
@@ -428,7 +428,7 @@ class FileManagerController extends Controller
|
|||||||
|
|
||||||
// File
|
// File
|
||||||
$filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName());
|
$filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName());
|
||||||
$filetype = 'file';
|
$filetype = get_file_type($file);
|
||||||
$thumbnail = null;
|
$thumbnail = null;
|
||||||
$filesize = $file->getSize();
|
$filesize = $file->getSize();
|
||||||
$directory = 'file-manager';
|
$directory = 'file-manager';
|
||||||
@@ -442,9 +442,8 @@ class FileManagerController extends Controller
|
|||||||
Storage::disk('local')->putFileAs($directory, $file, $filename, 'public');
|
Storage::disk('local')->putFileAs($directory, $file, $filename, 'public');
|
||||||
|
|
||||||
// Create image thumbnail
|
// Create image thumbnail
|
||||||
if (substr($file->getMimeType(), 0, 5) == 'image') {
|
if ( $filetype == 'image' ) {
|
||||||
|
|
||||||
$filetype = 'image';
|
|
||||||
$thumbnail = 'thumbnail-' . $filename;
|
$thumbnail = 'thumbnail-' . $filename;
|
||||||
|
|
||||||
// Create intervention image
|
// Create intervention image
|
||||||
@@ -562,6 +561,8 @@ class FileManagerController extends Controller
|
|||||||
$response->header("Content-Type", $type);
|
$response->header("Content-Type", $type);
|
||||||
$response->header("Content-Disposition", 'attachment; filename=' . $filename);
|
$response->header("Content-Disposition", 'attachment; filename=' . $filename);
|
||||||
$response->header("Content-Length", $size);
|
$response->header("Content-Length", $size);
|
||||||
|
$response->header("Accept-Ranges", "bytes");
|
||||||
|
$response->header("Content-Range", "bytes 0-" . $size . "/" . $size);
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-1
@@ -100,7 +100,8 @@ function get_storage_fill_percentage($used, $capacity)
|
|||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function user_storage_percentage() {
|
function user_storage_percentage()
|
||||||
|
{
|
||||||
|
|
||||||
$user = \Illuminate\Support\Facades\Auth::user();
|
$user = \Illuminate\Support\Facades\Auth::user();
|
||||||
|
|
||||||
@@ -172,3 +173,29 @@ function format_date($date, $format = '%d. %B. %Y, %H:%M')
|
|||||||
|
|
||||||
return $start->formatLocalized($format);
|
return $start->formatLocalized($format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get file type from mimetype
|
||||||
|
*
|
||||||
|
* @param $file
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function get_file_type($file)
|
||||||
|
{
|
||||||
|
// Get mimetype from file
|
||||||
|
$mimetype = explode('/', $file->getMimeType());
|
||||||
|
|
||||||
|
switch ($mimetype[0]) {
|
||||||
|
case 'image':
|
||||||
|
return 'image';
|
||||||
|
break;
|
||||||
|
case 'video':
|
||||||
|
return 'video';
|
||||||
|
break;
|
||||||
|
case 'audio':
|
||||||
|
return 'audio';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 'file';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2",
|
"php": "^7.2",
|
||||||
"askedio/laravel-soft-cascade": "^6.0",
|
"askedio/laravel-soft-cascade": "^6.0",
|
||||||
|
"doctrine/dbal": "^2.10",
|
||||||
"fideloper/proxy": "^4.0",
|
"fideloper/proxy": "^4.0",
|
||||||
"fruitcake/laravel-cors": "^1.0",
|
"fruitcake/laravel-cors": "^1.0",
|
||||||
"gabrielelana/byte-units": "^0.5.0",
|
"gabrielelana/byte-units": "^0.5.0",
|
||||||
|
|||||||
Generated
+460
-200
File diff suppressed because it is too large
Load Diff
+32
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class ChangeTypeAttributeInFileManagerFilesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('file_manager_files', function (Blueprint $table) {
|
||||||
|
DB::statement('ALTER TABLE file_manager_files MODIFY type TEXT;');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('file_manager_files', function (Blueprint $table) {
|
||||||
|
//
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-8
@@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
# Host: 127.0.0.1 (MySQL 5.7.25)
|
# Host: 127.0.0.1 (MySQL 5.7.25)
|
||||||
# Database: file-manager
|
# Database: file-manager
|
||||||
# Generation Time: 2020-03-14 17:32:56 +0000
|
# Generation Time: 2020-04-03 07:57:39 +0000
|
||||||
# ************************************************************
|
# ************************************************************
|
||||||
|
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ CREATE TABLE `file_manager_files` (
|
|||||||
`basename` text COLLATE utf8mb4_unicode_ci,
|
`basename` text COLLATE utf8mb4_unicode_ci,
|
||||||
`mimetype` text COLLATE utf8mb4_unicode_ci,
|
`mimetype` text COLLATE utf8mb4_unicode_ci,
|
||||||
`filesize` text COLLATE utf8mb4_unicode_ci,
|
`filesize` text COLLATE utf8mb4_unicode_ci,
|
||||||
`type` enum('image','file') COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
`type` text COLLATE utf8mb4_unicode_ci,
|
||||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||||
`created_at` timestamp NULL DEFAULT NULL,
|
`created_at` timestamp NULL DEFAULT NULL,
|
||||||
`updated_at` timestamp NULL DEFAULT NULL,
|
`updated_at` timestamp NULL DEFAULT NULL,
|
||||||
@@ -100,7 +100,7 @@ DROP TABLE IF EXISTS `migrations`;
|
|||||||
|
|
||||||
CREATE TABLE `migrations` (
|
CREATE TABLE `migrations` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`migration` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
|
`migration` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
`batch` int(11) NOT NULL,
|
`batch` int(11) NOT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
@@ -122,7 +122,8 @@ VALUES
|
|||||||
(10,'2019_08_19_000000_create_failed_jobs_table',1),
|
(10,'2019_08_19_000000_create_failed_jobs_table',1),
|
||||||
(11,'2020_03_03_065147_add_user_id_to_file_manager_files_table',2),
|
(11,'2020_03_03_065147_add_user_id_to_file_manager_files_table',2),
|
||||||
(12,'2020_03_03_065155_add_user_id_to_file_manager_folders_table',2),
|
(12,'2020_03_03_065155_add_user_id_to_file_manager_folders_table',2),
|
||||||
(13,'2020_03_03_070319_create_favourites_folders_table',3);
|
(13,'2020_03_03_070319_create_favourites_folders_table',3),
|
||||||
|
(14,'2020_04_02_055021_change_type_attribute_in_file_manager_files_table',4);
|
||||||
|
|
||||||
/*!40000 ALTER TABLE `migrations` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `migrations` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
@@ -137,7 +138,7 @@ CREATE TABLE `oauth_access_tokens` (
|
|||||||
`id` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
|
`id` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
`user_id` bigint(20) unsigned DEFAULT NULL,
|
`user_id` bigint(20) unsigned DEFAULT NULL,
|
||||||
`client_id` bigint(20) unsigned NOT NULL,
|
`client_id` bigint(20) unsigned NOT NULL,
|
||||||
`name` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||||
`scopes` text COLLATE utf8mb4_unicode_ci,
|
`scopes` text COLLATE utf8mb4_unicode_ci,
|
||||||
`revoked` tinyint(1) NOT NULL,
|
`revoked` tinyint(1) NOT NULL,
|
||||||
`created_at` timestamp NULL DEFAULT NULL,
|
`created_at` timestamp NULL DEFAULT NULL,
|
||||||
@@ -175,7 +176,7 @@ DROP TABLE IF EXISTS `oauth_clients`;
|
|||||||
CREATE TABLE `oauth_clients` (
|
CREATE TABLE `oauth_clients` (
|
||||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`user_id` bigint(20) unsigned DEFAULT NULL,
|
`user_id` bigint(20) unsigned DEFAULT NULL,
|
||||||
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
|
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
`secret` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
`secret` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||||
`redirect` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
`redirect` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
`personal_access_client` tinyint(1) NOT NULL,
|
`personal_access_client` tinyint(1) NOT NULL,
|
||||||
@@ -234,8 +235,8 @@ CREATE TABLE `oauth_refresh_tokens` (
|
|||||||
DROP TABLE IF EXISTS `password_resets`;
|
DROP TABLE IF EXISTS `password_resets`;
|
||||||
|
|
||||||
CREATE TABLE `password_resets` (
|
CREATE TABLE `password_resets` (
|
||||||
`email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
|
`email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
`token` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
|
`token` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
`created_at` timestamp NULL DEFAULT NULL,
|
`created_at` timestamp NULL DEFAULT NULL,
|
||||||
KEY `password_resets_email_index` (`email`)
|
KEY `password_resets_email_index` (`email`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
Generated
+660
-410
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -12,14 +12,14 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"axios": "^0.19",
|
"axios": "^0.19",
|
||||||
"cross-env": "^5.1",
|
"cross-env": "^5.1",
|
||||||
"laravel-mix": "^5.0.1",
|
"laravel-mix": "^5.0.4",
|
||||||
"resolve-url-loader": "^2.3.1",
|
"resolve-url-loader": "^2.3.1",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
"vue-template-compiler": "^2.6.11"
|
"vue-template-compiler": "^2.6.11"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "^1.2.26",
|
"@fortawesome/fontawesome-svg-core": "^1.2.28",
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.12.0",
|
"@fortawesome/free-solid-svg-icons": "^5.13.0",
|
||||||
"@fortawesome/vue-fontawesome": "^0.1.9",
|
"@fortawesome/vue-fontawesome": "^0.1.9",
|
||||||
"css-element-queries": "^1.2.3",
|
"css-element-queries": "^1.2.3",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
|
|||||||
@@ -5,6 +5,13 @@
|
|||||||
|
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
|
|
||||||
|
AddType video/ogg .ogv
|
||||||
|
AddType video/mp4 .mp4
|
||||||
|
AddType video/webm .webm
|
||||||
|
<ifModule mod_headers.c>
|
||||||
|
Header set Connection keep-alive
|
||||||
|
</ifModule>
|
||||||
|
|
||||||
# Handle Authorization Header
|
# Handle Authorization Header
|
||||||
RewriteCond %{HTTP:Authorization} .
|
RewriteCond %{HTTP:Authorization} .
|
||||||
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||||
|
|||||||
Binary file not shown.
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
@import url(https://fonts.googleapis.com/css2?family=Nunito:wght@200;300;400;600;700&display=swap);
|
@import url(https://fonts.googleapis.com/css2?family=Nunito:wght@200;300;400;600;700;900&display=swap);
|
||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -1,40 +1,4 @@
|
|||||||
{
|
{
|
||||||
"/js/main.js": "/js/main.js",
|
"/js/main.js": "/js/main.js",
|
||||||
"/css/app.css": "/css/app.css",
|
"/css/app.css": "/css/app.css"
|
||||||
"/js/main.b199e742764976d477eb.hot-update.js": "/js/main.b199e742764976d477eb.hot-update.js",
|
|
||||||
"/js/main.74bd4021acf8f5e6f2c0.hot-update.js": "/js/main.74bd4021acf8f5e6f2c0.hot-update.js",
|
|
||||||
"/js/main.7751cc56f809bdcca52f.hot-update.js": "/js/main.7751cc56f809bdcca52f.hot-update.js",
|
|
||||||
"/js/main.6550285a609d98fd0a2c.hot-update.js": "/js/main.6550285a609d98fd0a2c.hot-update.js",
|
|
||||||
"/js/main.593b8d94aebec435eaa6.hot-update.js": "/js/main.593b8d94aebec435eaa6.hot-update.js",
|
|
||||||
"/js/main.9646136421cb914b9bc8.hot-update.js": "/js/main.9646136421cb914b9bc8.hot-update.js",
|
|
||||||
"/js/main.34d97ba06940b269e518.hot-update.js": "/js/main.34d97ba06940b269e518.hot-update.js",
|
|
||||||
"/js/main.93f2bdf89f84cfacf4f3.hot-update.js": "/js/main.93f2bdf89f84cfacf4f3.hot-update.js",
|
|
||||||
"/js/main.817de8c8f5fd813c607b.hot-update.js": "/js/main.817de8c8f5fd813c607b.hot-update.js",
|
|
||||||
"/js/main.963bfdadae1fb90e0238.hot-update.js": "/js/main.963bfdadae1fb90e0238.hot-update.js",
|
|
||||||
"/js/main.1512db5a6a7632fb9e8e.hot-update.js": "/js/main.1512db5a6a7632fb9e8e.hot-update.js",
|
|
||||||
"/js/main.3a19340ddc14dcc839a1.hot-update.js": "/js/main.3a19340ddc14dcc839a1.hot-update.js",
|
|
||||||
"/js/main.397553844e2b0ca23cc7.hot-update.js": "/js/main.397553844e2b0ca23cc7.hot-update.js",
|
|
||||||
"/js/main.c87eeede975b87bf2b16.hot-update.js": "/js/main.c87eeede975b87bf2b16.hot-update.js",
|
|
||||||
"/js/main.f580b09761154926899f.hot-update.js": "/js/main.f580b09761154926899f.hot-update.js",
|
|
||||||
"/js/main.91d490a5132517514bfb.hot-update.js": "/js/main.91d490a5132517514bfb.hot-update.js",
|
|
||||||
"/js/main.bdad4fbdd1e409eb4b21.hot-update.js": "/js/main.bdad4fbdd1e409eb4b21.hot-update.js",
|
|
||||||
"/js/main.48d106f956e2b5fecbb0.hot-update.js": "/js/main.48d106f956e2b5fecbb0.hot-update.js",
|
|
||||||
"/js/main.3f7d1e2b874ad885f9ba.hot-update.js": "/js/main.3f7d1e2b874ad885f9ba.hot-update.js",
|
|
||||||
"/js/main.be94f32edd036852aa82.hot-update.js": "/js/main.be94f32edd036852aa82.hot-update.js",
|
|
||||||
"/js/main.0b838845dace73e0df6d.hot-update.js": "/js/main.0b838845dace73e0df6d.hot-update.js",
|
|
||||||
"/js/main.aac07313ac3ce9a2e597.hot-update.js": "/js/main.aac07313ac3ce9a2e597.hot-update.js",
|
|
||||||
"/js/main.37168073afe720eff29e.hot-update.js": "/js/main.37168073afe720eff29e.hot-update.js",
|
|
||||||
"/js/main.1eafca2af4cbb4242c1f.hot-update.js": "/js/main.1eafca2af4cbb4242c1f.hot-update.js",
|
|
||||||
"/js/main.8f3db6ec42d42fa7152e.hot-update.js": "/js/main.8f3db6ec42d42fa7152e.hot-update.js",
|
|
||||||
"/js/main.3d0c0e744120bafa0076.hot-update.js": "/js/main.3d0c0e744120bafa0076.hot-update.js",
|
|
||||||
"/js/main.5bf20eacf51dd037796e.hot-update.js": "/js/main.5bf20eacf51dd037796e.hot-update.js",
|
|
||||||
"/js/main.bf91b39fc6ebda933d92.hot-update.js": "/js/main.bf91b39fc6ebda933d92.hot-update.js",
|
|
||||||
"/js/main.87b79f2adeaf95ca1eae.hot-update.js": "/js/main.87b79f2adeaf95ca1eae.hot-update.js",
|
|
||||||
"/js/main.caeb9ea0fe68c0e20cbc.hot-update.js": "/js/main.caeb9ea0fe68c0e20cbc.hot-update.js",
|
|
||||||
"/js/main.61e2b39b769cf182b833.hot-update.js": "/js/main.61e2b39b769cf182b833.hot-update.js",
|
|
||||||
"/js/main.ac3b225c09da944dd637.hot-update.js": "/js/main.ac3b225c09da944dd637.hot-update.js",
|
|
||||||
"/js/main.e90426301ffd1febd2e8.hot-update.js": "/js/main.e90426301ffd1febd2e8.hot-update.js",
|
|
||||||
"/js/main.ee9680aa2ebf66f438e2.hot-update.js": "/js/main.ee9680aa2ebf66f438e2.hot-update.js",
|
|
||||||
"/js/main.0af6eb46c23ed68de4db.hot-update.js": "/js/main.0af6eb46c23ed68de4db.hot-update.js",
|
|
||||||
"/js/main.7d6e0c7874e39ca5797d.hot-update.js": "/js/main.7d6e0c7874e39ca5797d.hot-update.js"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,6 @@
|
|||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import "@assets/app.scss";
|
||||||
|
|
||||||
|
|
||||||
#files-view {
|
#files-view {
|
||||||
font-family: 'Nunito', sans-serif;
|
font-family: 'Nunito', sans-serif;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
@@ -161,27 +160,21 @@
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
height: 90px;
|
height: 90px;
|
||||||
|
|
||||||
&.file {
|
.file-icon {
|
||||||
.file-icon {
|
@include font-size(75);
|
||||||
@include font-size(75);
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-icon-text {
|
|
||||||
@include font-size(12);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.folder {
|
.file-icon-text {
|
||||||
@include font-size(14);
|
@include font-size(12);
|
||||||
|
|
||||||
|
|
||||||
.folder-icon {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.image img {
|
.folder-icon {
|
||||||
|
@include font-size(75);
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image {
|
||||||
width: 90px;
|
width: 90px;
|
||||||
height: 90px;
|
height: 90px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<ul class="menu-options" id="menu-options-list" ref="list" @click="closeAndResetContextMenu">
|
<ul class="menu-options" id="menu-options-list" ref="list" @click="closeAndResetContextMenu">
|
||||||
|
|
||||||
<!--View-->
|
<!--View-->
|
||||||
<li class="menu-option" @click="addToFavourites" v-if="! $isTrashLocation() && item && item.type === 'folder'">{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}</li>
|
<li class="menu-option" @click="addToFavourites" v-if="! $isTrashLocation() && item && isFolder">{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}</li>
|
||||||
<li class="menu-option" @click="createFolder" v-if="! $isTrashLocation()">{{ $t('context_menu.create_folder') }}</li>
|
<li class="menu-option" @click="createFolder" v-if="! $isTrashLocation()">{{ $t('context_menu.create_folder') }}</li>
|
||||||
|
|
||||||
<!--Edits-->
|
<!--Edits-->
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
<!--Others-->
|
<!--Others-->
|
||||||
<li class="menu-option" @click="ItemDetail" v-if="item">{{ $t('context_menu.detail') }}</li>
|
<li class="menu-option" @click="ItemDetail" v-if="item">{{ $t('context_menu.detail') }}</li>
|
||||||
<li class="menu-option" @click="downloadItem" v-if="isFile || isImage">{{ $t('context_menu.download') }}</li>
|
<li class="menu-option" @click="downloadItem" v-if="! isFolder && item">{{ $t('context_menu.download') }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -34,11 +34,14 @@
|
|||||||
name: 'ContextMenu',
|
name: 'ContextMenu',
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['app']),
|
...mapGetters(['app']),
|
||||||
|
isFolder() {
|
||||||
|
return this.item && this.item.type === 'folder'
|
||||||
|
},
|
||||||
isFile() {
|
isFile() {
|
||||||
return this.item && this.item.type === 'file' ? true : false
|
return (this.item && this.item.type !== 'folder') && (this.item && this.item.type !== 'image')
|
||||||
},
|
},
|
||||||
isImage() {
|
isImage() {
|
||||||
return this.item && this.item.type === 'image' ? true : false
|
return this.item && this.item.type === 'image'
|
||||||
},
|
},
|
||||||
isInFavourites() {
|
isInFavourites() {
|
||||||
return this.app.favourites.find(el => el.unique_id == this.item.unique_id)
|
return this.app.favourites.find(el => el.unique_id == this.item.unique_id)
|
||||||
|
|||||||
@@ -1,31 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="fileInfoDetail">
|
<div v-if="fileInfoDetail">
|
||||||
<div class="file-headline" spellcheck="false">
|
<div class="file-headline" spellcheck="false">
|
||||||
<!--Image thumbnail-->
|
|
||||||
<div v-if="fileInfoDetail.type == 'image'" class="image-preview">
|
<FilePreview />
|
||||||
<img
|
|
||||||
@dblclick="$openImageOnNewTab(fileInfoDetail.file_url)"
|
|
||||||
:src="fileInfoDetail.thumbnail"
|
|
||||||
:alt="fileInfoDetail.name"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--File info-->
|
<!--File info-->
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<div class="icon-preview" @dblclick="getItemAction">
|
<div class="icon-preview" @dblclick="getItemAction">
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon v-if="fileInfoDetail.type == 'folder'" icon="folder"></FontAwesomeIcon>
|
||||||
v-if="fileInfoDetail.type == 'folder'"
|
<FontAwesomeIcon v-if="fileInfoDetail.type == 'file'" icon="file"></FontAwesomeIcon>
|
||||||
icon="folder"
|
<FontAwesomeIcon v-if="fileInfoDetail.type == 'image'" icon="file-image"></FontAwesomeIcon>
|
||||||
></FontAwesomeIcon>
|
<FontAwesomeIcon v-if="fileInfoDetail.type == 'video'" icon="file-video"></FontAwesomeIcon>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon v-if="fileInfoDetail.type == 'audio'" icon="file-audio"></FontAwesomeIcon>
|
||||||
v-if="fileInfoDetail.type == 'file'"
|
|
||||||
icon="file"
|
|
||||||
></FontAwesomeIcon>
|
|
||||||
<FontAwesomeIcon
|
|
||||||
v-if="fileInfoDetail.type == 'image'"
|
|
||||||
icon="file-image"
|
|
||||||
></FontAwesomeIcon>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="file-info">
|
<div class="file-info">
|
||||||
@@ -64,12 +51,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import FilePreview from '@/components/VueFileManagerComponents/FilesView/FilePreview'
|
||||||
import {mapGetters} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
import {debounce} from 'lodash'
|
import {debounce} from 'lodash'
|
||||||
import {events} from "@/bus"
|
import {events} from "@/bus"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FilesInfoPanel',
|
name: 'FileInfoPanel',
|
||||||
|
components: {
|
||||||
|
FilePreview
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['fileInfoDetail'])
|
...mapGetters(['fileInfoDetail'])
|
||||||
},
|
},
|
||||||
@@ -122,20 +113,6 @@
|
|||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|
||||||
.image-preview {
|
|
||||||
width: 100%;
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 7px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
border-radius: 4px;
|
|
||||||
overflow: hidden;
|
|
||||||
width: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex {
|
.flex {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: top;
|
align-items: top;
|
||||||
@@ -251,6 +228,13 @@
|
|||||||
span {
|
span {
|
||||||
color: $dark_mode_text_primary
|
color: $dark_mode_text_primary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.action-button {
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
:class="{ 'is-clicked': isClicked, 'is-dragenter': area }"
|
:class="{ 'is-clicked': isClicked, 'is-dragenter': area }"
|
||||||
>
|
>
|
||||||
<!--Thumbnail for item-->
|
<!--Thumbnail for item-->
|
||||||
<div class="icon-item" :class="data.type">
|
<div class="icon-item">
|
||||||
<!--If is file or image, then link item-->
|
<!--If is file or image, then link item-->
|
||||||
<span v-if="isFile" class="file-icon-text">{{
|
<span v-if="isFile" class="file-icon-text">{{
|
||||||
data.mimetype
|
data.mimetype
|
||||||
@@ -29,15 +29,10 @@
|
|||||||
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file"/>
|
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file"/>
|
||||||
|
|
||||||
<!--Image thumbnail-->
|
<!--Image thumbnail-->
|
||||||
<img v-if="isImage" :src="data.thumbnail" :alt="data.name"/>
|
<img v-if="isImage" class="image" :src="data.thumbnail" :alt="data.name"/>
|
||||||
|
|
||||||
<!--Else show only folder icon-->
|
<!--Else show only folder icon-->
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon v-if="isFolder" :class="{'is-deleted': isDeleted}" class="folder-icon" icon="folder"/>
|
||||||
v-if="isFolder"
|
|
||||||
:class="{'is-deleted': isDeleted}"
|
|
||||||
class="folder-icon"
|
|
||||||
icon="folder"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Name-->
|
<!--Name-->
|
||||||
@@ -52,7 +47,7 @@
|
|||||||
>
|
>
|
||||||
|
|
||||||
<!--Other attributes-->
|
<!--Other attributes-->
|
||||||
<span v-if="isFile || isImage" class="item-size">{{
|
<span v-if="! isFolder" class="item-size">{{
|
||||||
data.filesize
|
data.filesize
|
||||||
}}</span>
|
}}</span>
|
||||||
|
|
||||||
@@ -82,7 +77,7 @@
|
|||||||
return this.data.type === 'folder'
|
return this.data.type === 'folder'
|
||||||
},
|
},
|
||||||
isFile() {
|
isFile() {
|
||||||
return this.data.type === 'file'
|
return this.data.type !== 'folder' && this.data.type !== 'image'
|
||||||
},
|
},
|
||||||
isImage() {
|
isImage() {
|
||||||
return this.data.type === 'image'
|
return this.data.type === 'image'
|
||||||
@@ -207,7 +202,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.file-wrapper {
|
.file-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -232,6 +226,11 @@
|
|||||||
.name {
|
.name {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
|
&[contenteditable] {
|
||||||
|
-webkit-user-select: text;
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
|
||||||
&[contenteditable='true']:hover {
|
&[contenteditable='true']:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
@@ -282,6 +281,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.icon-item {
|
.icon-item {
|
||||||
|
text-align: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 110px;
|
height: 110px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
@@ -303,41 +303,33 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.file {
|
.file-icon-text {
|
||||||
|
margin: 5px auto 0;
|
||||||
.file-icon-text {
|
position: absolute;
|
||||||
margin: 5px auto 0;
|
text-align: center;
|
||||||
position: absolute;
|
left: 0;
|
||||||
text-align: center;
|
right: 0;
|
||||||
left: 0;
|
color: $theme;
|
||||||
right: 0;
|
font-weight: 600;
|
||||||
color: $theme;
|
user-select: none;
|
||||||
font-weight: 600;
|
max-width: 65px;
|
||||||
user-select: none;
|
max-height: 20px;
|
||||||
max-width: 65px;
|
overflow: hidden;
|
||||||
max-height: 20px;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.image {
|
.image {
|
||||||
img {
|
max-width: 95%;
|
||||||
max-width: 95%;
|
object-fit: cover;
|
||||||
object-fit: cover;
|
user-select: none;
|
||||||
user-select: none;
|
height: 110px;
|
||||||
height: 110px;
|
border-radius: 5px;
|
||||||
border-radius: 5px;
|
margin: 0 auto;
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.folder {
|
|
||||||
align-items: flex-end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.folder-icon {
|
.folder-icon {
|
||||||
|
align-items: flex-end;
|
||||||
@include font-size(80);
|
@include font-size(80);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
:class="{ 'is-clicked': isClicked, 'is-dragenter': area }"
|
:class="{ 'is-clicked': isClicked, 'is-dragenter': area }"
|
||||||
>
|
>
|
||||||
<!--Thumbnail for item-->
|
<!--Thumbnail for item-->
|
||||||
<div class="icon-item" :class="data.type">
|
<div class="icon-item">
|
||||||
<!--If is file or image, then link item-->
|
<!--If is file or image, then link item-->
|
||||||
<span v-if="isFile" class="file-icon-text">{{
|
<span v-if="isFile" class="file-icon-text">{{
|
||||||
data.mimetype | limitCharacters
|
data.mimetype | limitCharacters
|
||||||
@@ -28,15 +28,10 @@
|
|||||||
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file"/>
|
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file"/>
|
||||||
|
|
||||||
<!--Image thumbnail-->
|
<!--Image thumbnail-->
|
||||||
<img v-if="isImage" :src="data.thumbnail" :alt="data.name"/>
|
<img v-if="isImage" class="image" :src="data.thumbnail" :alt="data.name"/>
|
||||||
|
|
||||||
<!--Else show only folder icon-->
|
<!--Else show only folder icon-->
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon v-if="isFolder" :class="{'is-deleted': isDeleted}" class="folder-icon" icon="folder"/>
|
||||||
v-if="isFolder"
|
|
||||||
:class="{'is-deleted': isDeleted}"
|
|
||||||
class="folder-icon"
|
|
||||||
icon="folder"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Name-->
|
<!--Name-->
|
||||||
@@ -50,7 +45,7 @@
|
|||||||
>{{ itemName }}</span>
|
>{{ itemName }}</span>
|
||||||
|
|
||||||
<!--Other attributes-->
|
<!--Other attributes-->
|
||||||
<span v-if="isFile || isImage" class="item-size">{{ data.filesize }}, {{ timeStamp }}</span>
|
<span v-if="! isFolder" class="item-size">{{ data.filesize }}, {{ timeStamp }}</span>
|
||||||
|
|
||||||
<span v-if="isFolder" class="item-length">
|
<span v-if="isFolder" class="item-length">
|
||||||
{{ folderItems == 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ timeStamp }}
|
{{ folderItems == 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ timeStamp }}
|
||||||
@@ -81,7 +76,7 @@
|
|||||||
return this.data.type === 'folder'
|
return this.data.type === 'folder'
|
||||||
},
|
},
|
||||||
isFile() {
|
isFile() {
|
||||||
return this.data.type === 'file'
|
return this.data.type !== 'folder' && this.data.type !== 'image'
|
||||||
},
|
},
|
||||||
isImage() {
|
isImage() {
|
||||||
return this.data.type === 'image'
|
return this.data.type === 'image'
|
||||||
@@ -248,7 +243,11 @@
|
|||||||
|
|
||||||
.name {
|
.name {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
//display: inline-block;
|
|
||||||
|
&[contenteditable] {
|
||||||
|
-webkit-user-select: text;
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
|
||||||
&[contenteditable='true']:hover {
|
&[contenteditable='true']:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
@@ -276,6 +275,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.icon-item {
|
.icon-item {
|
||||||
|
text-align: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 0 0 50px;
|
flex: 0 0 50px;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
@@ -305,38 +305,32 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.file {
|
.file-icon-text {
|
||||||
|
line-height: 1;
|
||||||
|
top: 40%;
|
||||||
|
@include font-size(11);
|
||||||
|
margin: 0 auto;
|
||||||
|
position: absolute;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
left: 0;
|
||||||
.file-icon-text {
|
right: 0;
|
||||||
line-height: 1;
|
color: $theme;
|
||||||
top: 40%;
|
font-weight: 600;
|
||||||
@include font-size(11);
|
user-select: none;
|
||||||
margin: 0 auto;
|
max-width: 50px;
|
||||||
position: absolute;
|
max-height: 20px;
|
||||||
text-align: center;
|
overflow: hidden;
|
||||||
left: 0;
|
text-overflow: ellipsis;
|
||||||
right: 0;
|
white-space: nowrap;
|
||||||
color: $theme;
|
|
||||||
font-weight: 600;
|
|
||||||
user-select: none;
|
|
||||||
max-width: 50px;
|
|
||||||
max-height: 20px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.image {
|
.image {
|
||||||
img {
|
object-fit: cover;
|
||||||
object-fit: cover;
|
user-select: none;
|
||||||
user-select: none;
|
max-width: 100%;
|
||||||
max-width: 100%;
|
border-radius: 5px;
|
||||||
border-radius: 5px;
|
width: 50px;
|
||||||
width: 50px;
|
height: 50px;
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="canBePreview" class="preview">
|
||||||
|
<img v-if="fileInfoDetail.type == 'image'" :src="fileInfoDetail.thumbnail" :alt="fileInfoDetail.name" />
|
||||||
|
<audio v-else-if="fileInfoDetail.type == 'audio'" :src="fileInfoDetail.file_url" controlsList="nodownload" controls></audio>
|
||||||
|
<video v-else-if="fileInfoDetail.type == 'video'" controlsList="nodownload" disablePictureInPicture playsinline controls>
|
||||||
|
<source :src="fileInfoDetail.file_url" type="video/mp4">
|
||||||
|
</video>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import { includes } from 'lodash'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FilePreview',
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['fileInfoDetail']),
|
||||||
|
canBePreview() {
|
||||||
|
return this.fileInfoDetail && ! includes([
|
||||||
|
'folder', 'file'
|
||||||
|
], this.fileInfoDetail.type)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import "@assets/app.scss";
|
||||||
|
|
||||||
|
.preview {
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 7px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio {
|
||||||
|
width: 100%;
|
||||||
|
&::-webkit-media-controls-panel {
|
||||||
|
background-color: $light_background;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-media-controls-play-button {
|
||||||
|
color: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
video {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="file-content" :class="{ 'is-offset': uploadingFilesCount }">
|
<div class="file-content" :class="{ 'is-offset': uploadingFilesCount, 'is-dragging': isDragging }"
|
||||||
|
@dragover.prevent
|
||||||
|
@drop.stop.prevent="dropUpload($event)"
|
||||||
|
@dragover="dragEnter"
|
||||||
|
@dragleave="dragLeave"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="files-container"
|
class="files-container"
|
||||||
ref="fileContainer"
|
ref="fileContainer"
|
||||||
@@ -18,7 +23,10 @@
|
|||||||
<MobileActions v-if="$isMinimalScale()" />
|
<MobileActions v-if="$isMinimalScale()" />
|
||||||
|
|
||||||
<!--Item previews list-->
|
<!--Item previews list-->
|
||||||
<div v-if="isList" class="file-list-wrapper">
|
<div
|
||||||
|
v-if="isList"
|
||||||
|
class="file-list-wrapper"
|
||||||
|
>
|
||||||
<transition-group
|
<transition-group
|
||||||
name="file"
|
name="file"
|
||||||
tag="section"
|
tag="section"
|
||||||
@@ -27,7 +35,7 @@
|
|||||||
>
|
>
|
||||||
<FileItemList
|
<FileItemList
|
||||||
@dragstart="dragStart(item)"
|
@dragstart="dragStart(item)"
|
||||||
@drop="dragFinish(item)"
|
@drop.stop.native.prevent="dragFinish(item, $event)"
|
||||||
@contextmenu.native.prevent="contextMenu($event, item)"
|
@contextmenu.native.prevent="contextMenu($event, item)"
|
||||||
:data="item"
|
:data="item"
|
||||||
v-for="item in data"
|
v-for="item in data"
|
||||||
@@ -47,7 +55,7 @@
|
|||||||
>
|
>
|
||||||
<FileItemGrid
|
<FileItemGrid
|
||||||
@dragstart="dragStart(item)"
|
@dragstart="dragStart(item)"
|
||||||
@drop="dragFinish(item)"
|
@drop.native.prevent="dragFinish(item, $event)"
|
||||||
@contextmenu.native.prevent="contextMenu($event, item)"
|
@contextmenu.native.prevent="contextMenu($event, item)"
|
||||||
:data="item"
|
:data="item"
|
||||||
v-for="item in data"
|
v-for="item in data"
|
||||||
@@ -133,10 +141,23 @@
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
draggingId: undefined
|
draggingId: undefined,
|
||||||
|
isDragging: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
dropUpload(event) {
|
||||||
|
// Upload external file
|
||||||
|
this.$uploadExternalFiles(event, this.currentFolder.unique_id)
|
||||||
|
|
||||||
|
this.isDragging = false
|
||||||
|
},
|
||||||
|
dragEnter() {
|
||||||
|
this.isDragging = true
|
||||||
|
},
|
||||||
|
dragLeave() {
|
||||||
|
this.isDragging = false
|
||||||
|
},
|
||||||
dragStart(data) {
|
dragStart(data) {
|
||||||
|
|
||||||
events.$emit('dragstart', data)
|
events.$emit('dragstart', data)
|
||||||
@@ -144,15 +165,26 @@
|
|||||||
// Store dragged folder
|
// Store dragged folder
|
||||||
this.draggingId = data
|
this.draggingId = data
|
||||||
},
|
},
|
||||||
dragFinish(data) {
|
dragFinish(data, event) {
|
||||||
// Prevent to drop on file or image
|
|
||||||
if (data.type !== 'folder' || this.draggingId === data) return
|
|
||||||
|
|
||||||
// Move folder to new parent
|
if (event.dataTransfer.items.length == 0) {
|
||||||
this.moveTo(this.draggingId, data)
|
|
||||||
},
|
// Prevent to drop on file or image
|
||||||
moveTo(from_item, to_item) {
|
if (data.type !== 'folder' || this.draggingId === data) return
|
||||||
this.$store.dispatch('moveItem', [from_item, to_item])
|
|
||||||
|
// Move folder to new parent
|
||||||
|
this.$store.dispatch('moveItem', [this.draggingId, data])
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Get unique_id of current folder
|
||||||
|
const unique_id = data.type !== 'folder' ? this.currentFolder.unique_id : data.unique_id
|
||||||
|
|
||||||
|
// Upload external file
|
||||||
|
this.$uploadExternalFiles(event, unique_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isDragging = false
|
||||||
},
|
},
|
||||||
contextMenu(event, item) {
|
contextMenu(event, item) {
|
||||||
events.$emit('contextMenu:show', event, item)
|
events.$emit('contextMenu:show', event, item)
|
||||||
@@ -225,6 +257,10 @@
|
|||||||
.file-content {
|
.file-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
|
|
||||||
|
&.is-dragging {
|
||||||
|
@include transform(scale(0.99));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.files-container {
|
.files-container {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<ul class="menu-options">
|
<ul class="menu-options">
|
||||||
<li class="menu-option"
|
<li class="menu-option"
|
||||||
@click="addToFavourites"
|
@click="addToFavourites"
|
||||||
v-if="! $isTrashLocation() && fileInfoDetail && fileInfoDetail.type === 'folder'"
|
v-if="! $isTrashLocation() && fileInfoDetail && isFolder"
|
||||||
>
|
>
|
||||||
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
|
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
|
||||||
</li>
|
</li>
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
<li
|
<li
|
||||||
class="menu-option"
|
class="menu-option"
|
||||||
@click="downloadItem"
|
@click="downloadItem"
|
||||||
v-if="isFile || isImage"
|
v-if="! isFolder"
|
||||||
>
|
>
|
||||||
{{ $t('context_menu.download') }}
|
{{ $t('context_menu.download') }}
|
||||||
</li>
|
</li>
|
||||||
@@ -76,19 +76,13 @@
|
|||||||
return this.app.favourites.find(el => el.unique_id == this.fileInfoDetail.unique_id)
|
return this.app.favourites.find(el => el.unique_id == this.fileInfoDetail.unique_id)
|
||||||
},
|
},
|
||||||
isFile() {
|
isFile() {
|
||||||
return this.fileInfoDetail && this.fileInfoDetail.type === 'file'
|
return (this.fileInfoDetail && this.fileInfoDetail.type !== 'folder') && (this.fileInfoDetail && this.fileInfoDetail.type !== 'image')
|
||||||
? true
|
|
||||||
: false
|
|
||||||
},
|
},
|
||||||
isImage() {
|
isImage() {
|
||||||
return this.fileInfoDetail && this.fileInfoDetail.type === 'image'
|
return this.fileInfoDetail && this.fileInfoDetail.type === 'image'
|
||||||
? true
|
|
||||||
: false
|
|
||||||
},
|
},
|
||||||
isFolder() {
|
isFolder() {
|
||||||
return this.fileInfoDetail && this.fileInfoDetail.type === 'folder'
|
return this.fileInfoDetail && this.fileInfoDetail.type === 'folder'
|
||||||
? true
|
|
||||||
: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="file-item">
|
<div class="file-item">
|
||||||
|
|
||||||
<!--Thumbnail for item-->
|
<!--Thumbnail for item-->
|
||||||
<div class="icon-item" :class="file.type">
|
<div class="icon-item">
|
||||||
|
|
||||||
<!--If is file or image, then link item-->
|
<!--If is file or image, then link item-->
|
||||||
<span v-if="isFile" class="file-icon-text">{{ file.mimetype }}</span>
|
<span v-if="isFile" class="file-icon-text">{{ file.mimetype }}</span>
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file"/>
|
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file"/>
|
||||||
|
|
||||||
<!--Image thumbnail-->
|
<!--Image thumbnail-->
|
||||||
<img v-if="isImage" :src="file.thumbnail" :alt="file.name"/>
|
<img v-if="isImage" class="image" :src="file.thumbnail" :alt="file.name"/>
|
||||||
|
|
||||||
<!--Else show only folder icon-->
|
<!--Else show only folder icon-->
|
||||||
<FontAwesomeIcon v-if="isFolder" class="folder-icon" icon="folder"/>
|
<FontAwesomeIcon v-if="isFolder" class="folder-icon" icon="folder"/>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
return this.file.type === 'folder'
|
return this.file.type === 'folder'
|
||||||
},
|
},
|
||||||
isFile() {
|
isFile() {
|
||||||
return this.file.type === 'file'
|
return this.file.type !== 'folder' && this.file.type !== 'image'
|
||||||
},
|
},
|
||||||
isImage() {
|
isImage() {
|
||||||
return this.file.type === 'image'
|
return this.file.type === 'image'
|
||||||
@@ -87,6 +87,8 @@
|
|||||||
.icon-item {
|
.icon-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-width: 40px;
|
min-width: 40px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 0;
|
||||||
|
|
||||||
.file-icon {
|
.file-icon {
|
||||||
@include font-size(35);
|
@include font-size(35);
|
||||||
@@ -106,39 +108,32 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.file {
|
.file-icon-text {
|
||||||
|
line-height: 1;
|
||||||
|
top: 40%;
|
||||||
|
@include font-size(9);
|
||||||
|
margin: 0 auto;
|
||||||
|
position: absolute;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
left: 0;
|
||||||
.file-icon-text {
|
right: 0;
|
||||||
top: 40%;
|
color: $theme;
|
||||||
@include font-size(9);
|
font-weight: 600;
|
||||||
margin: 0 auto;
|
user-select: none;
|
||||||
position: absolute;
|
max-width: 20px;
|
||||||
text-align: center;
|
max-height: 20px;
|
||||||
left: 0;
|
overflow: hidden;
|
||||||
right: 0;
|
text-overflow: ellipsis;
|
||||||
color: $theme;
|
white-space: nowrap;
|
||||||
font-weight: 600;
|
|
||||||
user-select: none;
|
|
||||||
max-width: 20px;
|
|
||||||
max-height: 20px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.image {
|
.image {
|
||||||
line-height: 0;
|
object-fit: cover;
|
||||||
|
user-select: none;
|
||||||
img {
|
max-width: 100%;
|
||||||
object-fit: cover;
|
border-radius: 5px;
|
||||||
user-select: none;
|
width: 36px;
|
||||||
max-width: 100%;
|
height: 36px;
|
||||||
border-radius: 5px;
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-35
@@ -2,7 +2,7 @@
|
|||||||
<div class="file-item">
|
<div class="file-item">
|
||||||
|
|
||||||
<!--Thumbnail for item-->
|
<!--Thumbnail for item-->
|
||||||
<div class="icon-item" :class="file.type">
|
<div class="icon-item">
|
||||||
|
|
||||||
<!--If is file or image, then link item-->
|
<!--If is file or image, then link item-->
|
||||||
<span v-if="isFile" class="file-icon-text">{{ file.mimetype }}</span>
|
<span v-if="isFile" class="file-icon-text">{{ file.mimetype }}</span>
|
||||||
@@ -11,10 +11,10 @@
|
|||||||
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file" />
|
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file" />
|
||||||
|
|
||||||
<!--Image thumbnail-->
|
<!--Image thumbnail-->
|
||||||
<img v-if="isImage" :src="file.thumbnail" :alt="file.name" />
|
<img v-if="isImage" class="image" :src="file.thumbnail" :alt="file.name" />
|
||||||
|
|
||||||
<!--Else show only folder icon-->
|
<!--Else show only folder icon-->
|
||||||
<FontAwesomeIcon v-if="isFolder" class="folder-icon" icon="folder" />
|
<FontAwesomeIcon v-if="isFolder" class="folder-icon" icon="folder" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Name-->
|
<!--Name-->
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<span class="name" >{{ file.name }}</span>
|
<span class="name" >{{ file.name }}</span>
|
||||||
|
|
||||||
<!--Other attributes-->
|
<!--Other attributes-->
|
||||||
<span v-if="isFile || isImage" class="item-size">{{ file.filesize }}, {{ file.created_at }}</span>
|
<span v-if="! isFolder" class="item-size">{{ file.filesize }}, {{ file.created_at }}</span>
|
||||||
|
|
||||||
<span v-if="isFolder" class="item-length">{{ file.items == 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ file.created_at }}</span>
|
<span v-if="isFolder" class="item-length">{{ file.items == 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ file.created_at }}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -41,7 +41,7 @@ export default {
|
|||||||
return this.file.type === 'folder'
|
return this.file.type === 'folder'
|
||||||
},
|
},
|
||||||
isFile() {
|
isFile() {
|
||||||
return this.file.type === 'file'
|
return this.file.type !== 'folder' && this.file.type !== 'image'
|
||||||
},
|
},
|
||||||
isImage() {
|
isImage() {
|
||||||
return this.file.type === 'image'
|
return this.file.type === 'image'
|
||||||
@@ -101,6 +101,8 @@ export default {
|
|||||||
.icon-item {
|
.icon-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-width: 40px;
|
min-width: 40px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 0;
|
||||||
|
|
||||||
.file-icon {
|
.file-icon {
|
||||||
@include font-size(35);
|
@include font-size(35);
|
||||||
@@ -112,39 +114,32 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.file {
|
.file-icon-text {
|
||||||
|
top: 40%;
|
||||||
|
@include font-size(9);
|
||||||
|
line-height: 1;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: absolute;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
left: 0;
|
||||||
.file-icon-text {
|
right: 0;
|
||||||
top: 40%;
|
color: $theme;
|
||||||
@include font-size(9);
|
font-weight: 600;
|
||||||
margin: 0 auto;
|
user-select: none;
|
||||||
position: absolute;
|
max-width: 20px;
|
||||||
text-align: center;
|
max-height: 20px;
|
||||||
left: 0;
|
overflow: hidden;
|
||||||
right: 0;
|
text-overflow: ellipsis;
|
||||||
color: $theme;
|
white-space: nowrap;
|
||||||
font-weight: 600;
|
|
||||||
user-select: none;
|
|
||||||
max-width: 20px;
|
|
||||||
max-height: 20px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.image {
|
.image {
|
||||||
line-height: 0;
|
object-fit: cover;
|
||||||
|
user-select: none;
|
||||||
img {
|
max-width: 100%;
|
||||||
object-fit: cover;
|
border-radius: 5px;
|
||||||
user-select: none;
|
width: 36px;
|
||||||
max-width: 100%;
|
height: 36px;
|
||||||
border-radius: 5px;
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+73
@@ -130,6 +130,79 @@ const Helpers = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vue.prototype.$uploadExternalFiles = async function(event, parent_id) {
|
||||||
|
|
||||||
|
// Prevent submit empty files
|
||||||
|
if (event.dataTransfer.items.length == 0) return
|
||||||
|
|
||||||
|
// Get files
|
||||||
|
const files = [...event.dataTransfer.items].map(item => item.getAsFile());
|
||||||
|
|
||||||
|
if (this.$store.getters.app.storage.percentage >= 100) {
|
||||||
|
events.$emit('alert:open', {
|
||||||
|
emoji: '😬😬😬',
|
||||||
|
title: this.$t('popup_exceed_limit.title'),
|
||||||
|
message: this.$t('popup_exceed_limit.message')
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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++
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
|
||||||
|
if (error.response.status == 423) {
|
||||||
|
|
||||||
|
events.$emit('alert:open', {
|
||||||
|
emoji: '😬😬😬',
|
||||||
|
title: this.$t('popup_exceed_limit.title'),
|
||||||
|
message: this.$t('popup_exceed_limit.message')
|
||||||
|
})
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Show error message
|
||||||
|
events.$emit('alert:open', {
|
||||||
|
title: this.$t('popup_error.title'),
|
||||||
|
message: this.$t('popup_error.message'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Vue.prototype.$downloadFile = function(url, filename) {
|
Vue.prototype.$downloadFile = function(url, filename) {
|
||||||
var anchor = document.createElement('a')
|
var anchor = document.createElement('a')
|
||||||
|
|
||||||
|
|||||||
Vendored
+4
@@ -8,6 +8,8 @@ import Helpers from './helpers'
|
|||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
||||||
import {
|
import {
|
||||||
|
faFileAudio,
|
||||||
|
faFileVideo,
|
||||||
faSyncAlt,
|
faSyncAlt,
|
||||||
faShare,
|
faShare,
|
||||||
faHome,
|
faHome,
|
||||||
@@ -34,6 +36,8 @@ import {
|
|||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
|
faFileAudio,
|
||||||
|
faFileVideo,
|
||||||
faHdd,
|
faHdd,
|
||||||
faSyncAlt,
|
faSyncAlt,
|
||||||
faShare,
|
faShare,
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
return [
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Pagination Language Lines
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| The following language lines are used by the paginator library to build
|
|
||||||
| the simple pagination links. You are free to change them to anything
|
|
||||||
| you want to customize your views to better match your application.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'previous' => '« Previous',
|
|
||||||
'next' => 'Next »',
|
|
||||||
|
|
||||||
];
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
return [
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Pagination Language Lines
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| The following language lines are used by the paginator library to build
|
|
||||||
| the simple pagination links. You are free to change them to anything
|
|
||||||
| you want to customize your views to better match your application.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'previous' => '« Predchádzajúca',
|
|
||||||
'next' => 'Nasledujúca »',
|
|
||||||
|
|
||||||
];
|
|
||||||
Vendored
-6
@@ -23,10 +23,4 @@ mix.js('resources/js/main.js', 'public/js')
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.options({
|
|
||||||
hmrOptions: {
|
|
||||||
host: '192.168.1.131',
|
|
||||||
port: '8080'
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.disableNotifications();
|
.disableNotifications();
|
||||||
|
|||||||
Reference in New Issue
Block a user