Compare commits

...

80 Commits
v1.8 ... v1.8.2

Author SHA1 Message Date
Peter Papp
28b39a79e6 - frontend build 2021-02-20 16:30:12 +01:00
Peter Papp
2dbd9dd62d Merge remote-tracking branch 'origin/version-v1.8.1'
# Conflicts:
#	resources/js/components/FilesView/FileItemGrid.vue
#	resources/js/components/FilesView/FileItemList.vue
#	resources/js/components/Others/ThumbnailItem.vue
2021-02-20 15:30:44 +01:00
Peter Papp
9dbce7a73a - autofocus disabled on mobile devices
- tabwrapper icon fix
2021-02-20 14:48:59 +01:00
Peter Papp
8ac5c8fd38 - css refactoring to grid for emoji picker
- frontend build
2021-02-20 12:07:55 +01:00
Milos Holba
2a105877f3 add Zip & Download folder to mobile menu, fix thumbnailItem for images without thumbnail, change color of file icon in mobile menu dark mode 2021-02-16 00:07:05 +01:00
Milos Holba
28efba5773 fix open Processing popup for download files 2021-02-15 12:37:06 +01:00
Milos Holba
60f02622da add default class for Folder in FolderIcon 2021-02-15 12:32:46 +01:00
Milos Holba
7eee7deba5 fix create folder on mobile 2021-02-15 10:00:39 +01:00
Peter Papp
ba0b2bd3b9 apple emojis 2021-02-13 12:05:47 +01:00
Peter Papp
86090b5870 folder color picker 2021-02-13 10:30:54 +01:00
Peter Papp
39681bc48a emoji ios styling for list 2021-02-13 09:29:49 +01:00
Milos Holba
96e1bdd99f make folder icon component 2021-02-12 20:43:33 +01:00
Milos Holba
eebeee6948 scss changes in SetFolderIcon, add translation to sk/cn 2021-02-11 20:14:27 +01:00
Milos Holba
7be02edead change base_path to public_path in get_emojis_list function 2021-02-11 16:44:16 +01:00
Milos Holba
d65c27091c change functionality of Emojis List to async load from backend 2021-02-10 19:45:59 +01:00
Milos Holba
6c3630085e test for iOS emojis 2021-02-09 20:42:48 +01:00
Milos Holba
f6dbb5e71e expansion functionality for the reset button in selected emoji input for possibility to set default icon 2021-02-09 19:20:21 +01:00
Peter Papp
a80e4364ae - allow share files to email for demo 2021-02-07 18:20:29 +01:00
Peter Papp
bfb3888555 Merge remote-tracking branch 'origin/version-v1.8.1'
# Conflicts:
#	config/vuefilemanager.php
#	public/chunks/admin-account.js
#	public/chunks/admin.js
#	public/chunks/app-appearance.js
#	public/chunks/app-billings.js
#	public/chunks/app-email.js
#	public/chunks/app-index.js
#	public/chunks/app-others.js
#	public/chunks/app-payments.js
#	public/chunks/app-settings.js
#	public/chunks/app-setup.js
#	public/chunks/billings-detail.js
#	public/chunks/contact-us.js
#	public/chunks/dashboard.js
#	public/chunks/database.js
#	public/chunks/environment-setup.js
#	public/chunks/files.js
#	public/chunks/files~chunks/shared-files~chunks/shared-page.js
#	public/chunks/installation-disclaimer.js
#	public/chunks/invoices.js
#	public/chunks/landing-page.js
#	public/chunks/pages.js
#	public/chunks/plan-create.js
#	public/chunks/plan-delete.js
#	public/chunks/plan-settings.js
#	public/chunks/plan-subscribers.js
#	public/chunks/plan.js
#	public/chunks/plans.js
#	public/chunks/profile.js
#	public/chunks/purchase-code.js
#	public/chunks/settings-create-payment-methods.js
#	public/chunks/settings-invoices.js
#	public/chunks/settings-payment-methods.js
#	public/chunks/settings-storage.js
#	public/chunks/settings-subscription.js
#	public/chunks/settings.js
#	public/chunks/shared-files.js
#	public/chunks/shared-page.js
#	public/chunks/sign-up.js
#	public/chunks/stripe-credentials.js
#	public/chunks/subscription-plans.js
#	public/chunks/subscription-service.js
#	public/chunks/upgrade-billing.js
#	public/chunks/upgrade.js
#	public/chunks/user-create.js
#	public/chunks/user-delete.js
#	public/chunks/user-detail.js
#	public/chunks/user-invoices.js
#	public/chunks/user-password.js
#	public/chunks/user-storage.js
#	public/chunks/user-subscription.js
#	public/chunks/user.js
#	public/chunks/users.js
#	public/js/main.js
#	public/mix-manifest.json
#	resources/js/views/FilePages/Files.vue
2021-02-07 18:05:56 +01:00
Peter Papp
5e408267ee - frontend build 2021-02-07 18:03:40 +01:00
Peter Papp
a4725df5f7 - added createFolder to SharedPage.vue
- queueable email
- frontend build
2021-02-07 17:28:00 +01:00
Peter Papp
dee562c56e - frontend build 2021-02-07 16:40:44 +01:00
Peter Papp
e1016502a1 Merge remote-tracking branch 'origin/version-v1.8.1' into version-v1.8.1
# Conflicts:
#	app/Http/Controllers/FileFunctions/ShareController.php
#	public/mix-manifest.json
2021-02-07 16:36:49 +01:00
Peter Papp
541924448b - Toggle for enable/disable landing page
- New app screenshots for landing page
- frontend build
- some ui fixes
2021-02-07 16:35:48 +01:00
Milos Holba
18b97866f2 MultiEmailInput first email dont need to be separated by comma or space, RenameItem comment ActionButton for more options 2021-02-07 13:26:42 +01:00
Milos Holba
6f2278b908 fix function shared_send_via_email in ShareController 2021-02-07 12:29:08 +01:00
Peter Papp
bdd8d63162 - Toggle for enable/disable landing page
- New app screenshots for laanding page
- frontend build
2021-02-07 12:18:56 +01:00
Peter Papp
8ca7881c5e frontend build 2021-02-07 11:21:51 +01:00
Peter Papp
8d04a94dbc - on-demand notification
- error message on failed after shared link was created
- Shared link email text edit
2021-02-07 11:19:21 +01:00
Milos Holba
44158c74e3 merge remote with local 2021-02-06 16:29:55 +01:00
Milos Holba
847bcec22f add emojis groups navigation, add X icon to select input for reset emoji 2021-02-06 16:12:21 +01:00
Peter Papp
e984ae6beb TabWrapper background change 2021-02-06 16:02:22 +01:00
Peter Papp
e2a52d27f5 Logging out progressbar 2021-02-06 14:18:53 +01:00
Peter Papp
9c92cffde3 Zip and Download title change 2021-02-06 13:57:34 +01:00
Peter Papp
ce20452f38 TabWrapper color change 2021-02-06 13:53:43 +01:00
Peter Papp
6c888c6bd3 Merge remote-tracking branch 'origin/version-v1.8.1' into version-v1.8.1
# Conflicts:
#	public/mix-manifest.json
2021-02-06 13:48:34 +01:00
Peter Papp
2b2d9a0764 - fixed more actions in public shared folder
- 'There is nothing' title changed in new folder
- Play video after click on full preview
- Expanded close cookie disclaimer area
- Show fileinfopanel as default
- Hidden file icons in DesktopToolbar.vue on ipad landscape
- Changed background color in context menu dark mode mobile
2021-02-06 13:48:22 +01:00
Milos Holba
ed2d008f4b stop uploading after failed uploadLimit validation on frontend 2021-02-06 11:15:09 +01:00
Milos Holba
9972f471c4 add Emoji component 2021-02-06 10:37:36 +01:00
Milos Holba
03ef16d90d make component for emojis 2021-02-05 18:13:22 +01:00
Milos Holba
4158d4f31e fix click to rename item in FileItemList/Grid 2021-02-02 18:26:01 +01:00
Milos Holba
e65acd8a4f make new emoji module in vuex, add funcionality for grouping emojis 2021-02-02 16:10:16 +01:00
Milos Holba
ba5e05f77a add tweomji transfer for single emojis 2021-02-01 19:43:30 +01:00
Peter Papp
82cf82e4b5 dashboard widget background changed 2021-02-01 17:02:47 +01:00
Peter Papp
f5e19e47f7 version changing 2021-02-01 16:56:45 +01:00
Peter Papp
43b1aa7f89 frontend build 2021-02-01 16:54:36 +01:00
Peter Papp
0e1ebdd809 Removed confirm dialog when user go back after login in 2021-02-01 16:51:44 +01:00
Peter Papp
6e3adcd459 Fixed streaming video/mp3 on safari browsers with using local disk 2021-02-01 16:37:40 +01:00
Milos Holba
9c147165e1 add to FileItemList/Grid function to unfocuse new foler name input, ThumbnaillItem folderIconHandle revision 2021-01-31 14:39:44 +01:00
Peter Papp
689b064756 - reset emails input after close popup 2021-01-30 15:31:48 +01:00
Peter Papp
6b32ae9795 - Box message fix part 2 2021-01-30 15:08:57 +01:00
Peter Papp
267556b39d - Prevent submit shared form
- Send shared link from FileInfoPanel.vue
2021-01-30 14:01:36 +01:00
Peter Papp
eb2e39cd32 Prevent submit shared form 2021-01-30 13:33:33 +01:00
Peter Papp
58ae75ecc9 MultiEmailInput 2021-01-30 11:52:38 +01:00
Peter Papp
a5dd0e0d30 Tab component reedit 2021-01-30 10:12:33 +01:00
Peter Papp
cec2450940 CopyInput.vue restyling 2021-01-30 09:31:25 +01:00
Milos Holba
fdd8f16384 solved error for get exif data 2021-01-28 11:21:23 +01:00
Milos Holba
2112fe879b add twemoji 2021-01-26 23:17:09 +01:00
Milos Holba
078d920c19 change icon for share , change color in text of Infobox 2021-01-21 20:49:32 +01:00
Milos Holba
98d1926ab3 add send shared link via email in edit sharing option 2021-01-20 18:54:12 +01:00
Milos Holba
2263cc9511 Make table wrapper and table options components 2021-01-19 18:47:53 +01:00
Milos Holba
9a736a2615 Create folder in contextMenu fix empty ul 2021-01-18 20:17:10 +01:00
Milos Holba
4b1e5fcb46 Create Folder - ContextMenu,add X icon for rename popup input, Dekstoptolbar icons,Recent uploads sorting,Windows scroller in nav sidebar,Change color of Delere in context menu 2021-01-18 20:00:26 +01:00
Peter Papp
a0c39bd955 - upgrade service to 1.8.1 from 1.8
- Landing page for Regular Licenses
- Legal pages for Regular Licenses
2021-01-17 16:21:49 +01:00
Peter Papp
973b301a46 Merge remote-tracking branch 'origin/version-v1.8.1' into version-v1.8.1 2021-01-17 13:30:27 +01:00
Peter Papp
e0f192777f - zip folder fix for sisters directories 2021-01-17 13:30:18 +01:00
Milos Holba
ce1bad57cd add change folder icon to rename item popup 2021-01-17 10:24:13 +01:00
Milos Holba
77b126b85a sned shared link via email add validation 2021-01-12 19:13:52 +01:00
Peter Papp
3adf57a6b1 front-end build 2021-01-12 18:34:55 +01:00
Milos Holba
cc72e4e3a2 fixes for mobiles/tablets FileFullPreview,FileInfoPanel after click to non media item,scroll for iPad, ThumbnailItem for media without thumbnail 2021-01-12 17:14:17 +01:00
Milos Holba
3285af3603 add to create share link a send share vie email option 2021-01-11 21:11:09 +01:00
Milos Holba
04990fcf7b add for backend send shared link via email 2021-01-06 17:33:15 +01:00
Milos Holba
ba28ac6184 Change timezone input to select in Settings.vue 2021-01-05 11:40:05 +01:00
Milos Holba
a100671cc0 timezone change int do decimal fix set_time_by_user_timezone function 2021-01-04 12:09:23 +01:00
Milos Holba
ded02fc15b user timezone v1 , add autofocus for CreateFolder,RenameItem popup 2021-01-03 18:00:28 +01:00
Milos Holba
64fd6a2265 first commit Multi restore in trash, focus on the new folder name 2020-12-29 11:39:37 +01:00
Peter Papp
c2a5d4bc74 - removed unwanted file 2020-12-23 18:00:02 +01:00
Peter Papp
fed95cbd64 - updated readme 2020-12-22 10:27:15 +01:00
Peter Papp
e60bbb369a - upgrade controller to v1.8 2020-12-21 20:50:56 +01:00
Peter Papp
7379d17a40 - zip file name fix 2020-12-21 19:00:54 +01:00
152 changed files with 18053 additions and 1704 deletions

View File

@@ -10,7 +10,7 @@
- [Chunk Upload](#chunk-upload)
- [Upgrade Guide](#upgrade-guide)
- [Common Instructions](#common-instructions)
- [Update from 1.7.12 to 1.8](#update-from-1712-to-178)
- [Update from 1.7.12 to 1.8](#update-from-1712-to-18)
- [Update from 1.7.10 to 1.7.11](#update-from-1710-to-1711)
- [Update from 1.7.8 to 1.7.9](#update-from-178-to-179)
- [Update from 1.7.x to 1.7.8](#update-from-17x-to-178)

View File

@@ -102,7 +102,7 @@ class FileManagerFile extends Model
*/
public function getCreatedAtAttribute()
{
return format_date($this->attributes['created_at'], __('vuefilemanager.time'));
return format_date(set_time_by_user_timezone($this->attributes['created_at']), __('vuefilemanager.time'));
}
/**
@@ -114,7 +114,7 @@ class FileManagerFile extends Model
{
if (!$this->attributes['deleted_at']) return null;
return format_date($this->attributes['deleted_at'], __('vuefilemanager.time'));
return format_date(set_time_by_user_timezone($this->attributes['deleted_at']), __('vuefilemanager.time'));
}
/**

View File

@@ -73,6 +73,10 @@ class FileManagerFolder extends Model
'items', 'trashed_items'
];
protected $casts = [
'icon_emoji' => 'object',
];
/**
* Sortable columns
*
@@ -133,7 +137,7 @@ class FileManagerFolder extends Model
*/
public function getCreatedAtAttribute()
{
return format_date($this->attributes['created_at'], __('vuefilemanager.time'));
return format_date(set_time_by_user_timezone($this->attributes['created_at']), __('vuefilemanager.time'));
}
/**
@@ -145,7 +149,7 @@ class FileManagerFolder extends Model
{
if (! $this->attributes['deleted_at']) return null;
return format_date($this->attributes['deleted_at'], __('vuefilemanager.time'));
return format_date(set_time_by_user_timezone($this->attributes['deleted_at']), __('vuefilemanager.time'));
}
/**

View File

@@ -26,6 +26,7 @@ class AppFunctionsController extends Controller
* @var array
*/
private $whitelist = [
'section_features',
'footer_content',
'get_started_description',
'get_started_title',
@@ -44,7 +45,7 @@ class AppFunctionsController extends Controller
'section_get_started',
'section_pricing_content',
'section_feature_boxes',
'section_features',
'allow_homepage',
];
/**
@@ -245,4 +246,16 @@ class AppFunctionsController extends Controller
Artisan::call('config:clear');
Artisan::call('config:cache');
}
/**
* Get Emojis List from the server
*
* @return $emojisList
*/
public function get_emojis_list()
{
$emojisList = json_decode(file_get_contents(public_path('assets/emojis.json'), true));
return collect([$emojisList]);
}
}

View File

@@ -269,15 +269,15 @@ class FileAccessController extends Controller
// Check if file exist
if (!Storage::exists($path)) abort(404);
$header = [
"Content-Type" => Storage::mimeType($path),
"Content-Length" => Storage::size($path),
"Accept-Ranges" => "bytes",
"Content-Range" => "bytes 0-600/" . Storage::size($path),
$headers = [
"Accept-Ranges" => "bytes",
"Content-Type" => Storage::mimeType($path),
"Content-Length" => Storage::size($path),
"Content-Range" => "bytes 0-600/" . Storage::size($path),
"Content-Disposition" => "attachment; filename=" . $file_pretty_name,
];
// Get file
return Storage::download($path, $file_pretty_name, $header);
return response()->download(storage_path('/app/file-manager/') . $file->basename, $file_pretty_name, $headers);
}
/**

View File

@@ -96,7 +96,7 @@ class BrowseController extends Controller
// Get User
$user = User::with(['latest_uploads' => function($query) {
$query->sortable();
$query->sortable(['created_at' => 'desc']);
}])
->where('id', Auth::id())
->first();

View File

@@ -15,6 +15,7 @@ use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use App\Http\Tools\Guardian;
use App\Http\Tools\Editor;
use App\FileManagerFolder;
use App\FileManagerFile;
use Exception;
@@ -114,6 +115,12 @@ class EditItemsController extends Controller
}
}
// If request have a change folder icon values set the folder icon
if ($request->type === 'folder' && $request->filled('folder_icon')) {
Editor::set_folder_icon($request->folder_icon, $unique_id);
}
// Rename Item
return Editor::rename_item($request, $unique_id);
}
@@ -150,6 +157,12 @@ class EditItemsController extends Controller
Guardian::check_item_access($item->folder_id, $shared);
}
// If request have a change folder icon values set the folder icon
if ($request->type === 'folder' && $request->filled('folder_icon')) {
Editor::set_folder_icon($request->folder_icon, $unique_id, $shared);
}
// Rename item
$item = Editor::rename_item($request, $unique_id, $shared);
@@ -315,6 +328,85 @@ class EditItemsController extends Controller
return $new_file;
}
/**
* User download folder via zip
*
* @param $unique_id
* @return string
*/
public function user_zip_folder(Request $request,$unique_id)
{
// Get user id
$user_id = Auth::id();
// Check permission to download for authenticated editor
if ($request->user()->tokenCan('editor')) {
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Check access to requested directory
Guardian::check_item_access($unique_id, $shared);
}
// Get folder
$folder = FileManagerFolder::whereUserId($user_id)
->where('unique_id', $unique_id);
if (! $folder->exists()) {
abort(404, 'Requested folder doesn\'t exists.');
}
$zip = Editor::zip_folder($unique_id);
// Get file
return response([
'url' => route('zip', $zip->id),
'name' => $zip->basename,
], 200);
}
/**
* Guest download folder via zip
*
* @param Request $request
* @param $unique_id
* @param $token
* @return string
*/
public function guest_zip_folder($unique_id, $token)
{
// Get shared record
$shared = get_shared($token);
// Check access to requested folder
Guardian::check_item_access($unique_id, $shared);
// Get folder
$folder = FileManagerFolder::whereUserId($shared->user_id)
->where('unique_id', $unique_id);
if (! $folder->exists()) {
abort(404, 'Requested folder doesn\'t exists.');
}
$zip = Editor::zip_folder($unique_id, $shared);
// Get file
return response([
'url' => route('zip_public', [
'id' => $zip->id,
'token' => $shared->token,
]),
'name' => $zip->basename,
], 200);
}
/**
* User download multiple files via zip
*

View File

@@ -5,6 +5,7 @@ namespace App\Http\Controllers\FileFunctions;
use App\Http\Requests\Share\CreateShareRequest;
use App\Http\Requests\Share\UpdateShareRequest;
use App\Http\Resources\ShareResource;
use App\Notifications\SharedSendViaEmail;
use App\Zip;
use Illuminate\Contracts\Routing\ResponseFactory;
use App\Http\Controllers\Controller;
@@ -12,8 +13,10 @@ use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Str;
use App\Share;
use Validator;
class ShareController extends Controller
{
@@ -58,7 +61,17 @@ class ShareController extends Controller
];
// Return created shared record
return new ShareResource(Share::create($options));
$share = new ShareResource(Share::create($options));
// Send shared link via email
if ($request->has('emails')) {
foreach ($request->emails as $email) {
Notification::route('mail', $email)->notify(new SharedSendViaEmail($token));
}
}
return $share;
}
/**
@@ -96,7 +109,7 @@ class ShareController extends Controller
*/
public function destroy(Request $request)
{
foreach($request->input('tokens') as $token) {
foreach ($request->input('tokens') as $token) {
// Get sharing record
Share::where('token', $token)
@@ -117,4 +130,30 @@ class ShareController extends Controller
// Done
return response('Done!', 204);
}
/**
* Send shared link via email to recipients
*
* @param $token
* @param $request
*/
public function shared_send_via_email(Request $request, $token)
{
// Make validation of array of emails
$validator = Validator::make($request->all(), [
'emails.*' => 'required|email',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad email input');
// Send shared link via email
if($request->has('emails')) {
foreach ($request->emails as $email) {
Notification::route('mail', $email)->notify(new SharedSendViaEmail($token));
}
}
return response('Done!', 204);
}
}

View File

@@ -59,12 +59,12 @@ class TrashController extends Controller
* @param $unique_id
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function restore(Request $request, $unique_id)
public function restore(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'type' => 'required|string',
'to_home' => 'boolean',
$validator = Validator::make($request->input('data'), [
'*.type' => 'required|string',
'*.unique_id' => 'integer',
]);
// Return error
@@ -77,38 +77,41 @@ class TrashController extends Controller
return Demo::response_204();
}
// Get folder
if ($request->type === 'folder') {
foreach($request->input('data') as $restore_item) {
// Get folder
$item = FileManagerFolder::onlyTrashed()
->where('user_id', $user_id)
->where('unique_id', $unique_id)
->first();
if ($restore_item['type'] === 'folder') {
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->parent_id = 0;
$item->save();
// Get folder
$item = FileManagerFolder::onlyTrashed()
->where('user_id', $user_id)
->where('unique_id', $restore_item['unique_id'])
->first();
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->parent_id = 0;
$item->save();
}
} else {
// Get item
$item = FileManagerFile::onlyTrashed()
->where('user_id', $user_id)
->where('unique_id', $restore_item['unique_id'])
->first();
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->folder_id = 0;
$item->save();
}
}
} else {
// Get item
$item = FileManagerFile::onlyTrashed()
->where('user_id', $user_id)
->where('unique_id', $unique_id)
->first();
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->folder_id = 0;
$item->save();
}
// Restore Item
$item->restore();
}
// Restore Item
$item->restore();
// Return response
return response('Done!', 204);
}

View File

@@ -466,19 +466,16 @@ class SetupWizardController extends Controller
]);
// Create legal pages and index content
if ($request->license === 'Extended') {
$pages = collect(config('content.pages'));
$content = $request->license === 'Extended' ? collect(config('content.content_extended')) : collect(config('content.content_regular'));
$pages = collect(config('content.pages'));
$content = collect(config('content.content'));
$content->each(function ($content) {
Setting::updateOrCreate($content);
});
$content->each(function ($content) {
Setting::updateOrCreate($content);
});
$pages->each(function ($page) {
Page::updateOrCreate($page);
});
}
$pages->each(function ($page) {
Page::updateOrCreate($page);
});
// Retrieve access token
$response = Route::dispatch(self::make_login_request($request));

View File

@@ -11,119 +11,6 @@ use Schema;
class UpgradeAppController extends Controller
{
/**
* Upgrade account from 1.6 to 1.7
*
* @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function upgrade(Request $request)
{
$upgraded = Setting::where('name', 'latest_upgrade')->first();
if ($upgraded && $upgraded->value === '1.7') abort(401);
// Create legal pages and index content
if ($request->license === 'Extended') {
$pages = collect(config('content.pages'));
$content = collect(config('content.content'));
$content->each(function ($content) {
Setting::updateOrCreate($content);
});
$pages->each(function ($page) {
Page::updateOrCreate($page);
});
}
// Store Logo
if ($request->hasFile('logo')) {
$logo = store_system_image($request->file('logo'), 'system');
}
// Store Logo horizontal
if ($request->hasFile('logo_horizontal')) {
$logo_horizontal = store_system_image($request->file('logo_horizontal'), 'system');
}
// Store favicon
if ($request->hasFile('favicon')) {
$favicon = store_system_image($request->file('favicon'), 'system');
}
// Get options
$settings = collect([
[
'name' => 'setup_wizard_database',
'value' => 1,
],
[
'name' => 'setup_wizard_success',
'value' => 1,
],
[
'name' => 'license',
'value' => $request->license,
],
[
'name' => 'purchase_code',
'value' => $request->purchase_code,
],
[
'name' => 'app_title',
'value' => $request->title,
],
[
'name' => 'app_description',
'value' => $request->description,
],
[
'name' => 'app_logo',
'value' => $request->hasFile('logo') ? $logo : null,
],
[
'name' => 'app_logo_horizontal',
'value' => $request->hasFile('logo_horizontal') ? $logo_horizontal : null,
],
[
'name' => 'app_favicon',
'value' => $request->hasFile('favicon') ? $favicon : null,
],
[
'name' => 'google_analytics',
'value' => $request->googleAnalytics,
],
[
'name' => 'contact_email',
'value' => $request->contactMail,
],
[
'name' => 'registration',
'value' => $request->userRegistration,
],
[
'name' => 'storage_limitation',
'value' => $request->storageLimitation,
],
[
'name' => 'storage_default',
'value' => $request->defaultStorage ? $request->defaultStorage : 5,
],
[
'name' => 'latest_upgrade',
'value' => '1.7',
],
]);
// Store options
$settings->each(function ($col) {
Setting::updateOrCreate(['name' => $col['name']], $col);
});
return response('Done', 200);
}
/**
* Start maintenance mode
@@ -150,8 +37,52 @@ class UpgradeAppController extends Controller
/**
* Upgrade database
*/
public function upgrade_database()
public function upgrade()
{
/*
* Upgrade user_settings & file_manager_folders table
*
* @since v1.8.1
*/
if (! Schema::hasColumn('user_settings', 'timezone') && ! Schema::hasColumn('file_manager_folders', 'icon_color')) {
$this->upgrade_database();
// Create legal pages and index content for regular license
if (get_setting('license') === 'Regular') {
$pages = collect(config('content.pages'));
$content = collect(config('content.content_regular'));
$content->each(function ($content) {
Setting::updateOrCreate($content);
});
$pages->each(function ($page) {
Page::updateOrCreate($page);
});
}
}
/*
* Upgrade expire_in in shares table
*
* @since v1.8
*/
if (! Schema::hasTable('traffic') && ! Schema::hasTable('zips') && ! Schema::hasTable('jobs')) {
$this->upgrade_database();
}
/*
* Upgrade expire_in in shares table
*
* @since v1.8
*/
if (! Schema::hasTable('traffic') && ! Schema::hasTable('zips') && ! Schema::hasTable('jobs')) {
$this->upgrade_database();
}
/*
* Upgrade expire_in in shares table
*
@@ -159,17 +90,7 @@ class UpgradeAppController extends Controller
*/
if (! Schema::hasColumn('shares', 'expire_in')) {
$command = Artisan::call('migrate', [
'--force' => true
]);
if ($command === 0) {
echo 'Operation was successful.';
}
if ($command === 1) {
echo 'Operation failed.';
}
$this->upgrade_database();
}
/*
@@ -179,17 +100,26 @@ class UpgradeAppController extends Controller
*/
if (! Schema::hasColumn('file_manager_files', 'metadata')) {
$command = Artisan::call('migrate', [
'--force' => true
]);
if ($command === 0) {
echo 'Operation was successful.';
}
if ($command === 1) {
echo 'Operation failed.';
}
$this->upgrade_database();
}
}
/**
* @return int|mixed
*/
private function upgrade_database()
{
$command = Artisan::call('migrate', [
'--force' => true
]);
if ($command === 0) {
echo 'Operation was successful.';
}
if ($command === 1) {
echo 'Operation failed.';
}
return $command;
}
}

View File

@@ -2,6 +2,7 @@
use App\FileManagerFile;
use App\FileManagerFolder;
use App\User;
use App\Setting;
use App\Share;
use ByteUnits\Metric;
@@ -558,7 +559,17 @@ function get_pretty_name($basename, $name, $mimetype)
function get_image_meta_data($file)
{
if (get_file_type_from_mimetype($file->getMimeType()) === 'jpeg') {
return exif_read_data($file);
try {
// Try to get the exif data
return mb_convert_encoding(Image::make($file->getRealPath())->exif(),'UTF8', 'UTF8');
} catch ( \Exception $e) {
return null;
}
}
}
@@ -733,3 +744,61 @@ function remove_accents($string) {
return $string;
}
/**
* Get all files from folder and get their folder location in VueFileManager directories
*
* @param $folders
* @param null $files
* @param array $path
* @return array
*/
function get_files_for_zip($folders, $files, $path = [])
{
// Return file list
if (!isset($folders->folders)) {
return $files->unique()->values()->all();
}
// Push file path
array_push($path, $folders->name);
// Push file to collection
$folders->files->each(function ($file) use ($files, $path) {
$files->push([
'name' => $file->name,
'basename' => $file->basename,
'folder_path' => implode('/', $path),
]);
});
// Get all children folders and folders within
if ($folders->folders->isNotEmpty()) {
$folders->folders->map(function ($folder) use ($files, $path) {
return get_files_for_zip($folder, $files, $path);
});
}
return get_files_for_zip($folders->folders->first(), $files, $path);
}
/**
* Set time by user timezone GMT
*
* @param $time
* @return int
*/
function set_time_by_user_timezone($time)
{
$user = Auth::user();
if($user) {
// Get the value of timezone if user have some
$time_zone = intval($user->settings->timezone * 60 ?? null);
return Carbon::parse($time)->addMinutes($time_zone ?? null);
}
return Carbon::parse($time);
}

View File

@@ -31,6 +31,7 @@ class CreateShareRequest extends FormRequest
'expiration' => 'integer|nullable',
'permission' => 'string',
'password' => 'string',
'emails.*' => 'email'
];
}
}

View File

@@ -76,7 +76,16 @@ class UserResource extends JsonResource
'folders' => $this->folder_tree
],
],
]
],
'timezone' => [
'data' => [
'id' => '1',
'type' => 'timezone',
'attributes' => [
'timezone' =>$this->settings->timezone
],
]
],
]
];
}

View File

@@ -26,6 +26,122 @@ use Symfony\Component\HttpKernel\Exception\HttpException;
class Editor
{
/**
* Store folder icon
*
* @param $folder_icon
* @param $unique_id
* @param $shared
*/
public static function set_folder_icon($folder_icon, $unique_id, $shared = null)
{
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
// Get folder
$folder = FileManagerFolder::where('user_id', $user_id)
->where('unique_id', $unique_id)
->first();
// Set default folder icon
if ($folder_icon === 'default') {
$folder->icon_emoji = null;
$folder->icon_color = null;
}
// If request have emoji set folder icon emoji
if (isset($folder_icon['emoji'])) {
$folder->icon_emoji = $folder_icon['emoji'];
$folder->icon_color = null;
}
// If request have color set folder icon color
if (isset($folder_icon['color'])) {
$folder->icon_emoji = null;
$folder->icon_color = $folder_icon['color'];
}
// Save changes
$folder->save();
}
/**
* Zip requested folder
*
* @param $unique_id
* @param $shared
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public static function zip_folder($unique_id, $shared = null)
{
// Get folder
$requested_folder = FileManagerFolder::with(['folders.files', 'files'])
->where('unique_id', $unique_id)
->where('user_id', Auth::id() ?? $shared->user_id)
->with('folders')
->first();
$files = get_files_for_zip($requested_folder, collect([]));
// Local storage instance
$disk_local = Storage::disk('local');
// Create zip directory
if (!$disk_local->exists('zip')) {
$disk_local->makeDirectory('zip');
}
// Move file to local storage
if (!is_storage_driver('local')) {
// Create temp directory
if (!$disk_local->exists('temp')) {
$disk_local->makeDirectory('temp');
}
foreach ($files as $file) {
try {
$disk_local->put('temp/' . $file['basename'], Storage::get('file-manager/' . $file['basename']));
} catch (FileNotFoundException $e) {
throw new HttpException(404, 'File not found');
}
}
}
// Get zip path
$zip_name = Str::random(16) . '-' . Str::slug($requested_folder->name) . '.zip';
$zip_path = 'zip/' . $zip_name;
// Create zip
$zip = Madzipper::make(storage_path() . '/app/' . $zip_path);
// Get files folder on local storage drive
$files_folder = is_storage_driver('local') ? 'file-manager' : 'temp';
// Add files to zip
foreach ($files as $file) {
$zip->folder($file['folder_path'])->addString($file['name'], File::get(storage_path() . '/app/' . $files_folder . '/' . $file['basename']));
}
// Close zip
$zip->close();
// Delete temporary files
if (!is_storage_driver('local')) {
foreach ($files as $file) {
$disk_local->delete('temp/' . $file['basename']);
}
}
// Store zip record
return Zip::create([
'user_id' => $shared->user_id ?? Auth::id(),
'shared_token' => $shared->token ?? null,
'basename' => $zip_name,
]);
}
/**
* Zip selected files, store it in /zip folder and retrieve zip record
@@ -74,7 +190,7 @@ class Editor
// Add files to zip
$files->each(function ($file) use ($zip, $files_directory) {
$zip->addString($file['name'], File::get(storage_path() . '/app/' . $files_directory . '/' . $file['basename']));
$zip->addString($file['name'] . '.' . $file['mimetype'], File::get(storage_path() . '/app/' . $files_directory . '/' . $file['basename']));
});
// Close zip
@@ -329,7 +445,7 @@ class Editor
$temp_filename = $file->getClientOriginalName();
// File Path
$file_path = config('filesystems.disks.local.root') . '/chunks/' . $temp_filename;\
$file_path = config('filesystems.disks.local.root') . '/chunks/' . $temp_filename;
// Generate file
File::append($file_path, $file->get());
@@ -341,8 +457,8 @@ class Editor
$limit = get_setting('upload_limit');
// File size handling
if( $limit && $file_size > format_bytes($limit)) abort(413);
if ($limit && $file_size > format_bytes($limit)) abort(413);
// If last then process file
if ($request->boolean('is_last')) {

View File

@@ -0,0 +1,64 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Auth;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class SharedSendViaEmail extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* @param $token
*/
public function __construct($token)
{
$this->token = $token;
$this->user = Auth::user();
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject(__('vuefilemanager.shared_link_email_subject' , ['user' => $this->user->name]))
->greeting(__('vuefilemanager.shared_link_email_greeting'))
->line(__('vuefilemanager.shared_link_email_user', ['user' => $this->user->name, 'email' => $this->user->email]))
->action(__('vuefilemanager.shared_link_email_link'), url('/shared', ['token' => $this->token]));
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}

View File

@@ -3,6 +3,8 @@
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Notifications\SharedSendViaEmail;
use Illuminate\Notifications\Notifiable;
/**
* App\Share
@@ -37,6 +39,8 @@ use Illuminate\Database\Eloquent\Model;
*/
class Share extends Model
{
use Notifiable;
protected $guarded = ['id'];
protected $appends = ['link'];
@@ -46,8 +50,8 @@ class Share extends Model
*
* @return string
*/
public function getLinkAttribute() {
public function getLinkAttribute()
{
return url('/shared', ['token' => $this->attributes['token']]);
}
}

View File

@@ -1,27 +1,97 @@
<?php
return [
'pages' => [
'pages' => [
[
'visibility' => 1,
'visibility' => 0,
'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,
'visibility' => 0,
'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,
'visibility' => 0,
'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' => [
'content_regular' => [
[
'name' => 'section_features',
'value' => 0,
],
[
'name' => 'section_feature_boxes',
'value' => 0,
],
[
'name' => 'section_get_started',
'value' => 0,
],
[
'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. Truly 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. Truly 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' => '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. Truly freedom.',
],
[
'name' => 'footer_content',
'value' => '© 2021 Simple & Powerful Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank">Hi5Ve.Digital</a>',
],
[
'name' => 'allow_homepage',
'value' => 1,
],
],
'content_extended' => [
[
'name' => 'section_features',
'value' => '1',
@@ -96,7 +166,7 @@ return [
],
[
'name' => 'footer_content',
'value' => '© 2020 Simple & Powerful Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank">Hi5Ve.Digital</a>',
'value' => '© 2021 Simple & Powerful Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank">Hi5Ve.Digital</a>',
],
],
];

View File

@@ -2,7 +2,7 @@
return [
'version' => '1.8',
'version' => '1.8.2',
// Define size of chunk uploaded by MB. E.g. integer 128 means chunk size will be 128MB.
'chunk_size' => env('CHUNK_SIZE', '128'),

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddTimezoneToUserSettingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('user_settings', function (Blueprint $table) {
$table->decimal('timezone', 10, 1)->after('billing_phone_number')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('user_settings', function (Blueprint $table) {
//
});
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddFolderIconOptionsToFileManagerFoldersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('file_manager_folders', function (Blueprint $table) {
$table->string('icon_color')->after('user_scope')->nullable();
$table->string('icon_emoji')->after('icon_color')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('file_manager_folders', function (Blueprint $table) {
//
});
}
}

50
package-lock.json generated
View File

@@ -10003,6 +10003,53 @@
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"twemoji": {
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-13.0.1.tgz",
"integrity": "sha512-mrTBq+XpCLM4zm76NJOjLHoQNV9mHdBt3Cba/T5lS1rxn8ArwpqE47mqTocupNlkvcLxoeZJjYSUW0DU5ZwqZg==",
"requires": {
"fs-extra": "^8.0.1",
"jsonfile": "^5.0.0",
"twemoji-parser": "13.0.0",
"universalify": "^0.1.2"
},
"dependencies": {
"fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
"dependencies": {
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"requires": {
"graceful-fs": "^4.1.6"
}
}
}
},
"jsonfile": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz",
"integrity": "sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==",
"requires": {
"graceful-fs": "^4.1.6",
"universalify": "^0.1.2"
}
}
}
},
"twemoji-parser": {
"version": "13.0.0",
"resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-13.0.0.tgz",
"integrity": "sha512-zMaGdskpH8yKjT2RSE/HwE340R4Fm+fbie4AaqjDa4H/l07YUmAvxkSfNl6awVWNRRQ0zdzLQ8SAJZuY5MgstQ=="
},
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@@ -10124,8 +10171,7 @@
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
},
"unpipe": {
"version": "1.0.0",

View File

@@ -23,6 +23,7 @@
"@fortawesome/vue-fontawesome": "^0.1.10",
"lodash": "^4.17.20",
"node-sass": "^4.14.1",
"twemoji": "^13.0.1",
"vee-validate": "^3.3.9",
"vue": "^2.6.11",
"vue-feather-icons": "^5.1.0",

14023
public/assets/emojis.json Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 665 KiB

After

Width:  |  Height:  |  Size: 649 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 615 KiB

After

Width:  |  Height:  |  Size: 636 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[43],{"2wZp":function(t,e,i){"use strict";var n=i("Mlra");i.n(n).a},"6Rdq":function(t,e,i){"use strict";var n=i("9Q3x"),r=i("yMep"),o=i("c4kp"),s=i("2QtR"),a=i("L2JU"),c=i("xCqy");function l(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,n)}return i}function p(t,e,i){return e in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}var u={name:"FilesView",components:{DesktopSortingAndPreview:n.a,DesktopToolbar:r.a,FileBrowser:o.a,ContextMenu:s.a},computed:function(t){for(var e=1;e<arguments.length;e++){var i=null!=arguments[e]?arguments[e]:{};e%2?l(Object(i),!0).forEach((function(e){p(t,e,i[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(i)):l(Object(i)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(i,e))}))}return t}({},Object(a.b)(["config"])),methods:{contextMenu:function(t,e){c.a.$emit("contextMenu:show",t,e)}}},d=(i("2wZp"),i("KHd+")),f=Object(d.a)(u,(function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{attrs:{id:"files-view"},on:{"!contextmenu":function(e){return e.preventDefault(),t.contextMenu(e,void 0)}}},[i("ContextMenu"),t._v(" "),i("DesktopSortingAndPreview"),t._v(" "),i("DesktopToolbar"),t._v(" "),i("FileBrowser")],1)}),[],!1,null,null,null);e.a=f.exports},CoTS:function(t,e,i){"use strict";i.r(e);var n=i("6Rdq"),r=i("LtV2"),o=i("hXay"),s=i("CjXH"),a={name:"FilesView",components:{ContentFileView:n.a,ContentSidebar:r.a,ContentGroup:o.a,LinkIcon:s.E,UsersIcon:s.bb},methods:{getShared:function(){this.$store.dispatch("getShared",[{back:!1,init:!1}])},getParticipantUploads:function(){this.$store.dispatch("getParticipantUploads")}},mounted:function(){this.getShared()}},c=i("KHd+"),l=Object(c.a)(a,(function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("section",{attrs:{id:"viewport"}},[i("ContentSidebar",[i("ContentGroup",{attrs:{title:t.$t("sidebar.locations_title")}},[i("div",{staticClass:"menu-list-wrapper vertical"},[i("li",{staticClass:"menu-list-item link",class:{"is-active":t.$isThisLocation(["shared"])},on:{click:function(e){return t.getShared()}}},[i("div",{staticClass:"icon"},[i("link-icon",{attrs:{size:"17"}})],1),t._v(" "),i("div",{staticClass:"label"},[t._v("\n "+t._s(t.$t("sidebar.my_shared"))+"\n ")])]),t._v(" "),i("li",{staticClass:"menu-list-item link",class:{"is-active":t.$isThisLocation(["participant_uploads"])},on:{click:function(e){return t.getParticipantUploads()}}},[i("div",{staticClass:"icon"},[i("users-icon",{attrs:{size:"17"}})],1),t._v(" "),i("div",{staticClass:"label"},[t._v("\n "+t._s(t.$t("sidebar.participant_uploads"))+"\n ")])])])])],1),t._v(" "),i("ContentFileView")],1)}),[],!1,null,"fd8b19c0",null);e.default=l.exports},Mlra:function(t,e,i){var n=i("Q8SN");"string"==typeof n&&(n=[[t.i,n,""]]);var r={hmr:!0,transform:void 0,insertInto:void 0};i("aET+")(n,r);n.locals&&(t.exports=n.locals)},Q8SN:function(t,e,i){(t.exports=i("I1BE")(!1)).push([t.i,"#files-view{font-family:Nunito,sans-serif;font-size:16px;width:100%;height:100%;position:relative;min-width:320px;overflow-x:hidden;padding-left:15px;padding-right:15px;overflow-y:hidden}@media only screen and (max-width:690px){#files-view{padding-left:0;padding-right:0}}",""])}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[43],{"2wZp":function(t,e,n){"use strict";var i=n("Mlra");n.n(i).a},"6Rdq":function(t,e,n){"use strict";var i=n("9Q3x"),r=n("yMep"),o=n("c4kp"),s=n("2QtR"),a=n("L2JU"),c=n("xCqy");function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function p(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var d={name:"FilesView",components:{DesktopSortingAndPreview:i.a,DesktopToolbar:r.a,FileBrowser:o.a,ContextMenu:s.a},computed:function(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?l(Object(n),!0).forEach((function(e){p(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}({},Object(a.b)(["config"])),methods:{contextMenu:function(t,e){c.a.$emit("contextMenu:show",t,e)}}},u=(n("2wZp"),n("KHd+")),f=Object(u.a)(d,(function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{attrs:{id:"files-view"},on:{"!contextmenu":function(e){return e.preventDefault(),t.contextMenu(e,void 0)}}},[n("ContextMenu"),t._v(" "),n("DesktopSortingAndPreview"),t._v(" "),n("DesktopToolbar"),t._v(" "),n("FileBrowser")],1)}),[],!1,null,null,null);e.a=f.exports},CoTS:function(t,e,n){"use strict";n.r(e);var i=n("6Rdq"),r=n("LtV2"),o=n("hXay"),s=n("CjXH"),a={name:"FilesView",components:{ContentFileView:i.a,ContentSidebar:r.a,ContentGroup:o.a,LinkIcon:s.E,UsersIcon:s.db},methods:{getShared:function(){this.$store.dispatch("getShared",[{back:!1,init:!1}])},getParticipantUploads:function(){this.$store.dispatch("getParticipantUploads")}},mounted:function(){this.getShared()}},c=n("KHd+"),l=Object(c.a)(a,(function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("section",{attrs:{id:"viewport"}},[n("ContentSidebar",[n("ContentGroup",{attrs:{title:t.$t("sidebar.locations_title")}},[n("div",{staticClass:"menu-list-wrapper vertical"},[n("li",{staticClass:"menu-list-item link",class:{"is-active":t.$isThisLocation(["shared"])},on:{click:function(e){return t.getShared()}}},[n("div",{staticClass:"icon"},[n("link-icon",{attrs:{size:"17"}})],1),t._v(" "),n("div",{staticClass:"label"},[t._v("\n "+t._s(t.$t("sidebar.my_shared"))+"\n ")])]),t._v(" "),n("li",{staticClass:"menu-list-item link",class:{"is-active":t.$isThisLocation(["participant_uploads"])},on:{click:function(e){return t.getParticipantUploads()}}},[n("div",{staticClass:"icon"},[n("users-icon",{attrs:{size:"17"}})],1),t._v(" "),n("div",{staticClass:"label"},[t._v("\n "+t._s(t.$t("sidebar.participant_uploads"))+"\n ")])])])])],1),t._v(" "),n("ContentFileView")],1)}),[],!1,null,"fd8b19c0",null);e.default=l.exports},Mlra:function(t,e,n){var i=n("Q8SN");"string"==typeof i&&(i=[[t.i,i,""]]);var r={hmr:!0,transform:void 0,insertInto:void 0};n("aET+")(i,r);i.locals&&(t.exports=i.locals)},Q8SN:function(t,e,n){(t.exports=n("I1BE")(!1)).push([t.i,"#files-view {\n font-family: 'Nunito', sans-serif;\n font-size: 16px;\n width: 100%;\n height: 100%;\n position: relative;\n min-width: 320px;\n overflow-x: hidden;\n padding-left: 15px;\n padding-right: 15px;\n overflow-y: hidden;\n}\n@media only screen and (max-width: 690px) {\n#files-view {\n padding-left: 0;\n padding-right: 0;\n}\n}\n",""])}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
public/css/app.css vendored

File diff suppressed because one or more lines are too long

2
public/js/main.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -1,65 +1,65 @@
{
"/chunks/files~chunks/shared-files~chunks/shared-page.js": "/chunks/files~chunks/shared-files~chunks/shared-page.js?id=28609ddbecc1f1fa2c9f",
"/js/main.js": "/js/main.js?id=baa9e433dc272dec4b2a",
"/css/app.css": "/css/app.css?id=8f6d5dcb7110a726e142",
"/chunks/admin.js": "/chunks/admin.js?id=60df31e17e9a453717dc",
"/chunks/admin-account.js": "/chunks/admin-account.js?id=ab97f01586b286e0bba2",
"/chunks/app-appearance.js": "/chunks/app-appearance.js?id=cbcbdb5159db1fdef0fe",
"/chunks/app-billings.js": "/chunks/app-billings.js?id=2a85f4c8ad09b50f4358",
"/chunks/app-email.js": "/chunks/app-email.js?id=49806a5c914ca1a14bff",
"/chunks/app-index.js": "/chunks/app-index.js?id=ff6fb3cb1780d6ea76f2",
"/chunks/app-others.js": "/chunks/app-others.js?id=6eb162d433e0b9b8b7b2",
"/chunks/app-payments.js": "/chunks/app-payments.js?id=ad822a37d1d7c6e99a08",
"/chunks/app-settings.js": "/chunks/app-settings.js?id=e23a68dba034c047ff44",
"/chunks/app-setup.js": "/chunks/app-setup.js?id=c1c6fcc091a248b10060",
"/chunks/billings-detail.js": "/chunks/billings-detail.js?id=0e1d52490ae1b9e56c74",
"/chunks/contact-us.js": "/chunks/contact-us.js?id=a5150dcf81c8e1ab23a4",
"/chunks/create-new-password.js": "/chunks/create-new-password.js?id=58c543c4f92b5ca9a284",
"/chunks/dashboard.js": "/chunks/dashboard.js?id=256a9fc56ca1e81507cf",
"/chunks/database.js": "/chunks/database.js?id=45630822140f0f9d8fb5",
"/chunks/dynamic-page.js": "/chunks/dynamic-page.js?id=08a0c2de8f93e0222600",
"/chunks/environment-setup.js": "/chunks/environment-setup.js?id=be1c6cf5bbedf5c987da",
"/chunks/files.js": "/chunks/files.js?id=e182df6a47e8764f428a",
"/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=7ff98232e7b4cc5d2c2a",
"/chunks/installation-disclaimer.js": "/chunks/installation-disclaimer.js?id=d6ff4604fd61fd8a081d",
"/chunks/invoices.js": "/chunks/invoices.js?id=656daf3bc5b893a94a3c",
"/chunks/landing-page.js": "/chunks/landing-page.js?id=9b500c8f5f2de6ae01b3",
"/chunks/not-found-shared.js": "/chunks/not-found-shared.js?id=53d4f9c58bdac1e568c7",
"/chunks/page-edit.js": "/chunks/page-edit.js?id=682b2836ee0726d72409",
"/chunks/pages.js": "/chunks/pages.js?id=057a23ae05c1272fbc4a",
"/chunks/plan.js": "/chunks/plan.js?id=d679b2c4e3dafe7cb4de",
"/chunks/plan-create.js": "/chunks/plan-create.js?id=921149e0082c663f0ce8",
"/chunks/plan-delete.js": "/chunks/plan-delete.js?id=daff73302efdfacc542a",
"/chunks/plan-settings.js": "/chunks/plan-settings.js?id=3047e82dffef9a9a5f36",
"/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=d46857048beab30edb45",
"/chunks/plans.js": "/chunks/plans.js?id=59e044f4c96b8b23146c",
"/chunks/profile.js": "/chunks/profile.js?id=a71f52eb082c5173b37e",
"/chunks/purchase-code.js": "/chunks/purchase-code.js?id=7ef575dcdf8d8cce1781",
"/chunks/settings.js": "/chunks/settings.js?id=e92a372ac6714092f999",
"/chunks/settings-create-payment-methods.js": "/chunks/settings-create-payment-methods.js?id=8e425a5fcac0dfed8979",
"/chunks/settings-invoices.js": "/chunks/settings-invoices.js?id=124785707d6d7eefc088",
"/chunks/settings-password.js": "/chunks/settings-password.js?id=f7b86ce4daef5d65b9c7",
"/chunks/settings-payment-methods.js": "/chunks/settings-payment-methods.js?id=e470dc96089d86689f74",
"/chunks/settings-storage.js": "/chunks/settings-storage.js?id=d74048cf27bfd83ecacb",
"/chunks/settings-subscription.js": "/chunks/settings-subscription.js?id=754550f7d1abe0678d00",
"/chunks/files~chunks/shared-files~chunks/shared-page.js": "/chunks/files~chunks/shared-files~chunks/shared-page.js?id=3063523dc4a3aee7ac59",
"/js/main.js": "/js/main.js?id=0229401b7e8985e5572a",
"/css/app.css": "/css/app.css?id=dfd52fc997b919cd3686",
"/chunks/admin.js": "/chunks/admin.js?id=7672646537b5813becf0",
"/chunks/admin-account.js": "/chunks/admin-account.js?id=3f5a34aa8341af8d2b4c",
"/chunks/app-appearance.js": "/chunks/app-appearance.js?id=9ec9a42482cb302a05f6",
"/chunks/app-billings.js": "/chunks/app-billings.js?id=92903bd1d316b3db1dfa",
"/chunks/app-email.js": "/chunks/app-email.js?id=9d646578982ba61813b6",
"/chunks/app-index.js": "/chunks/app-index.js?id=4623bd961647897a5b81",
"/chunks/app-others.js": "/chunks/app-others.js?id=b19a701cdfa06e4817ff",
"/chunks/app-payments.js": "/chunks/app-payments.js?id=11c86d822269f1a1577e",
"/chunks/app-settings.js": "/chunks/app-settings.js?id=6784314933372fb1adf0",
"/chunks/app-setup.js": "/chunks/app-setup.js?id=d304bcf7d4157e81f3e2",
"/chunks/billings-detail.js": "/chunks/billings-detail.js?id=b73a5b6f7d2a448cc5ab",
"/chunks/contact-us.js": "/chunks/contact-us.js?id=81906d205ba0107c5105",
"/chunks/create-new-password.js": "/chunks/create-new-password.js?id=004908727045abd0852e",
"/chunks/dashboard.js": "/chunks/dashboard.js?id=cdfd468f0d0f98b9f081",
"/chunks/database.js": "/chunks/database.js?id=b8d8269f77c52f78c784",
"/chunks/dynamic-page.js": "/chunks/dynamic-page.js?id=2e3af103d13536c50757",
"/chunks/environment-setup.js": "/chunks/environment-setup.js?id=106f81cefe76c62d476e",
"/chunks/files.js": "/chunks/files.js?id=b213d4fe15c2a9933f32",
"/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=95ce5e5685dc9315f515",
"/chunks/installation-disclaimer.js": "/chunks/installation-disclaimer.js?id=6db12008aa646ad5fb6f",
"/chunks/invoices.js": "/chunks/invoices.js?id=83389adf0760820af6f5",
"/chunks/landing-page.js": "/chunks/landing-page.js?id=546ed735edf0d80c8a7e",
"/chunks/not-found-shared.js": "/chunks/not-found-shared.js?id=848666d6c49c613f7f99",
"/chunks/page-edit.js": "/chunks/page-edit.js?id=bd41ae13951c2a5025c3",
"/chunks/pages.js": "/chunks/pages.js?id=df7245abef9e3b77a218",
"/chunks/plan.js": "/chunks/plan.js?id=cfd7b4ee7e21639a837d",
"/chunks/plan-create.js": "/chunks/plan-create.js?id=9bb62af36193ee9648d3",
"/chunks/plan-delete.js": "/chunks/plan-delete.js?id=7b7601f044e0ef47720b",
"/chunks/plan-settings.js": "/chunks/plan-settings.js?id=8d3e75ff9adb22a25d57",
"/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=3b4a29497fc878f503db",
"/chunks/plans.js": "/chunks/plans.js?id=feb924949bffcdf3d9fb",
"/chunks/profile.js": "/chunks/profile.js?id=f990697f8d4ff45df434",
"/chunks/purchase-code.js": "/chunks/purchase-code.js?id=5d7406ecd84c676db8fb",
"/chunks/settings.js": "/chunks/settings.js?id=d16d9e2cda6aa3a3f6dc",
"/chunks/settings-create-payment-methods.js": "/chunks/settings-create-payment-methods.js?id=b05e24dd8be60f62ee27",
"/chunks/settings-invoices.js": "/chunks/settings-invoices.js?id=72d317b39264987e6ed0",
"/chunks/settings-password.js": "/chunks/settings-password.js?id=014597c63c94d3ac9f60",
"/chunks/settings-payment-methods.js": "/chunks/settings-payment-methods.js?id=2a0ea9cf661deba6fc13",
"/chunks/settings-storage.js": "/chunks/settings-storage.js?id=b3f25de02dd4ef072df0",
"/chunks/settings-subscription.js": "/chunks/settings-subscription.js?id=aa3d963f578d7bc5ff88",
"/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=47090233afc7b0cdf855",
"/chunks/shared-files.js": "/chunks/shared-files.js?id=adbeabe4eee0cdaefbf4",
"/chunks/shared-page.js": "/chunks/shared-page.js?id=691e43731207990aeef3",
"/chunks/sign-in.js": "/chunks/sign-in.js?id=ec080714b24154cf1081",
"/chunks/sign-up.js": "/chunks/sign-up.js?id=0d8b571bcf5a54f073fd",
"/chunks/stripe-credentials.js": "/chunks/stripe-credentials.js?id=1855b3385d413077987b",
"/chunks/subscription-plans.js": "/chunks/subscription-plans.js?id=8f7dd3b0a9efd8b23cb6",
"/chunks/subscription-service.js": "/chunks/subscription-service.js?id=5d6baf6541a2045e07d4",
"/chunks/upgrade.js": "/chunks/upgrade.js?id=5b8044541a28db10a800",
"/chunks/upgrade-billing.js": "/chunks/upgrade-billing.js?id=a7aac734e0697c974314",
"/chunks/upgrade-plan.js": "/chunks/upgrade-plan.js?id=b5d285ace19d55d6caba",
"/chunks/user.js": "/chunks/user.js?id=a22678762221f8ece00f",
"/chunks/user-create.js": "/chunks/user-create.js?id=d2c5a7a23e892ea0b74f",
"/chunks/user-delete.js": "/chunks/user-delete.js?id=97382205d44cc82a7362",
"/chunks/user-detail.js": "/chunks/user-detail.js?id=368fa9dff628423894ea",
"/chunks/user-invoices.js": "/chunks/user-invoices.js?id=25a90c334e0edcf8497a",
"/chunks/user-password.js": "/chunks/user-password.js?id=66ca2fe7b5f27aea03b4",
"/chunks/user-storage.js": "/chunks/user-storage.js?id=1197c179b53abd596800",
"/chunks/user-subscription.js": "/chunks/user-subscription.js?id=df85e3892af3ff39a586",
"/chunks/users.js": "/chunks/users.js?id=1dd3a0e5ea6717816879"
"/chunks/shared-files.js": "/chunks/shared-files.js?id=ba10fd3f52a7b62d3092",
"/chunks/shared-page.js": "/chunks/shared-page.js?id=4489cb4cfa33fb249bea",
"/chunks/sign-in.js": "/chunks/sign-in.js?id=c52ce81c3dad56d7a7d8",
"/chunks/sign-up.js": "/chunks/sign-up.js?id=2f12850d320b2413cf54",
"/chunks/stripe-credentials.js": "/chunks/stripe-credentials.js?id=6622381f1d96e8319999",
"/chunks/subscription-plans.js": "/chunks/subscription-plans.js?id=f1b093a3bcfebd5bc8a5",
"/chunks/subscription-service.js": "/chunks/subscription-service.js?id=e0e2f821aac16b32da34",
"/chunks/upgrade.js": "/chunks/upgrade.js?id=0c8d40bed72e86359529",
"/chunks/upgrade-billing.js": "/chunks/upgrade-billing.js?id=a8db2246f9326e5c5957",
"/chunks/upgrade-plan.js": "/chunks/upgrade-plan.js?id=f050f10627424b730dc2",
"/chunks/user.js": "/chunks/user.js?id=6f2ab796211a3ac8670f",
"/chunks/user-create.js": "/chunks/user-create.js?id=0d630acda4552c315417",
"/chunks/user-delete.js": "/chunks/user-delete.js?id=db041eae3aef3e45197a",
"/chunks/user-detail.js": "/chunks/user-detail.js?id=8cf2fe554e8d67ac8677",
"/chunks/user-invoices.js": "/chunks/user-invoices.js?id=a0613909cb0c21817804",
"/chunks/user-password.js": "/chunks/user-password.js?id=653bba3eb8d117c3a043",
"/chunks/user-storage.js": "/chunks/user-storage.js?id=630b0ff649e16d3627af",
"/chunks/user-subscription.js": "/chunks/user-subscription.js?id=0b4226ba77f10b83de4a",
"/chunks/users.js": "/chunks/users.js?id=04ca09662595fae56488"
}

View File

@@ -1,6 +0,0 @@
<?php
// Show all information, defaults to INFO_ALL
phpinfo();
?>

View File

@@ -12,6 +12,7 @@
<!--Mobile Navigation-->
<MobileNavigation/>
<!-- Processing popup for zip -->
<ProcessingPopup/>
<!--Confirm Popup-->
@@ -58,7 +59,6 @@
<CookieDisclaimer/>
<!--Background vignette-->
<Vignette/>
</div>
</template>

View File

@@ -23,7 +23,7 @@
<!-- Single options -->
<OptionGroup v-if="multiSelectContextMenu">
<Option @click.native="restoreItem" v-if="item" :title="$t('context_menu.restore')" icon="restore"/>
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash"/>
<Option @click.native="deleteItem" v-if="item" :title="$t('context_menu.delete')" icon="trash"/>
<Option @click.native="emptyTrash" :title="$t('context_menu.empty_trash')" icon="empty-trash"/>
</OptionGroup>
@@ -34,6 +34,7 @@
<!-- Multi options -->
<OptionGroup v-if="!multiSelectContextMenu">
<Option @click.native="restoreItem" v-if="item" :title="$t('context_menu.restore')" icon="restore"/>
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash"/>
<Option @click.native="emptyTrash" :title="$t('context_menu.empty_trash')" icon="empty-trash"/>
</OptionGroup>
@@ -62,6 +63,7 @@
<OptionGroup v-if="item && multiSelectContextMenu">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail"/>
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download"/>
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder"/>
</OptionGroup>
<!-- Multi options -->
@@ -83,13 +85,15 @@
<!-- Base location with MASTER permission-->
<div v-if="$isThisLocation(['base', 'participant_uploads', 'latest']) && $checkPermission('master') && !showFromPreview" id="menu-list" class="menu-options">
<!-- No Files options -->
<OptionGroup v-if="!$isThisLocation(['participant_uploads', 'latest']) && multiSelectContextMenu && !item">
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder"/>
</OptionGroup>
<!-- Single options -->
<OptionGroup v-if="!$isThisLocation(['participant_uploads', 'latest']) && multiSelectContextMenu">
<Option @click.native="addToFavourites" v-if="item && isFolder " :title="isInFavourites
? $t('context_menu.remove_from_favourites')
: $t('context_menu.add_to_favourites')" icon="favourites"/>
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder"/>
<OptionGroup v-if="!$isThisLocation(['participant_uploads', 'latest']) && item && multiSelectContextMenu && isFolder">
<Option @click.native="addToFavourites" :title="isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites')" icon="favourites"/>
</OptionGroup>
@@ -106,6 +110,7 @@
<OptionGroup v-if="item && multiSelectContextMenu ">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail"/>
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download"/>
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder"/>
</OptionGroup>
<!-- Multi options -->
@@ -113,7 +118,6 @@
<Option @click.native="addToFavourites" v-if="item && !hasFile" :title=" isInFavourites
? $t('context_menu.remove_from_favourites')
: $t('context_menu.add_to_favourites')" icon="favourites"/>
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder"/>
</OptionGroup>
<OptionGroup v-if="item && !multiSelectContextMenu">
@@ -129,11 +133,13 @@
<!-- Base & Public location with EDITOR permission-->
<div v-if="$isThisLocation(['base', 'public']) && $checkPermission('editor') && !showFromPreview " id="menu-list" class="menu-options">
<!-- Single options -->
<OptionGroup v-if="multiSelectContextMenu">
<!-- No Files options -->
<OptionGroup v-if="multiSelectContextMenu && !item">
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder"/>
</OptionGroup>
<!-- Single options -->
<OptionGroup v-if="item && multiSelectContextMenu">
<Option @click.native="renameItem" :title=" $t('context_menu.rename')" icon="rename"/>
<Option @click.native="moveItem" :title="$t('context_menu.move')" icon="move-item"/>
@@ -143,12 +149,10 @@
<OptionGroup v-if="item && multiSelectContextMenu">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail"/>
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download"/>
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder"/>
</OptionGroup>
<!-- Multi options -->
<OptionGroup v-if="!multiSelectContextMenu">
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder"/>
</OptionGroup>
<OptionGroup v-if="item && !multiSelectContextMenu">
<Option @click.native="moveItem" :title="$t('context_menu.move')" icon="move-item"/>
@@ -167,6 +171,7 @@
<OptionGroup v-if="item && multiSelectContextMenu">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail"/>
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download"/>
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder"/>
</OptionGroup>
<!-- Multi options -->
@@ -250,11 +255,21 @@ export default {
},
methods: {
downloadFolder(){
this.$store.dispatch('downloadFolder' , this.item)
},
emptyTrash() {
this.$store.dispatch('emptyTrash')
},
restoreItem() {
this.$store.dispatch('restoreItem', this.item)
// If is item not in selected items restore just this single item
if(!this.fileInfoDetail.includes(this.item))
this.$store.dispatch('restoreItem', this.item)
// If is item in selected items restore all items from fileInfoDetail
if(this.fileInfoDetail.includes(this.item))
this.$store.dispatch('restoreItem', null)
},
shareCancel() {
this.$store.dispatch('shareCancel')

View File

@@ -25,22 +25,22 @@
<SearchBar/>
</div>
<!--Files controlls-->
<!--Creating controls-->
<div class="toolbar-button-wrapper" v-if="$checkPermission(['master', 'editor'])">
<ToolbarButtonUpload :class="{ 'is-inactive': canUploadInView || !hasCapacity }" :action="$t('actions.upload')"/>
<ToolbarButton :class="{ 'is-inactive': canCreateFolderInView }" @click.native="createFolder" source="folder-plus" :action="$t('actions.create_folder')"/>
</div>
<div class="toolbar-button-wrapper" v-if="$checkPermission(['master', 'editor'])">
<!--File Controls-->
<div class="toolbar-button-wrapper" v-if="$checkPermission(['master', 'editor']) && ! $isMobile()">
<ToolbarButton source="move" :class="{ 'is-inactive': canMoveInView }" :action="$t('actions.move')" @click.native="moveItem"/>
<ToolbarButton v-if="!$isThisLocation(['public'])" source="share" :class="{ 'is-inactive': canShareInView }" :action="$t('actions.share')" @click.native="shareItem"/>
<ToolbarButton source="trash" :class="{ 'is-inactive': canDeleteInView }" :action="$t('actions.delete')" @click.native="deleteItem"/>
</div>
<!--View options-->
<!--View Controls-->
<div class="toolbar-button-wrapper">
<ToolbarButton source="preview-sorting" class="preview-sorting" :action="$t('actions.sorting_view')" :class="{ active: sortingAndPreview }" @click.stop.native="sortingAndPreview = !sortingAndPreview"/>
<ToolbarButton :action="$t('actions.info_panel')" :class="{ active: fileInfoVisible }" @click.native="$store.dispatch('fileInfoToggle')" source="info"/>
</div>
</div>
@@ -103,7 +103,7 @@ export default {
return !this.$isThisLocation(['base', 'public'])
},
canDeleteInView() {
return !this.$isThisLocation([
let locations = [
'trash',
'trash-root',
'base',
@@ -111,19 +111,22 @@ export default {
'latest',
'shared',
'public'
])
]
return !this.$isThisLocation(locations) || this.fileInfoDetail.length === 0
},
canUploadInView() {
return !this.$isThisLocation(['base', 'public'])
},
canMoveInView() {
return !this.$isThisLocation([
let locations = [
'base',
'participant_uploads',
'latest',
'shared',
'public'
])
]
return !this.$isThisLocation(locations) || this.fileInfoDetail.length === 0
},
canShareInView() {
let locations = [
@@ -134,7 +137,7 @@ export default {
'public'
]
return !this.$isThisLocation(locations) || this.fileInfoDetail.length > 1
return !this.$isThisLocation(locations) || this.fileInfoDetail.length > 1 || this.fileInfoDetail.length === 0
}
},
data() {

View File

@@ -1,72 +1,77 @@
<template>
<MultiSelected :title="title" :subtitle="subtitle" id="multi-select-ui" v-show="dragged" />
<MultiSelected :title="title" :subtitle="subtitle" id="multi-select-ui" v-show="isVisible"/>
</template>
<script>
import MultiSelected from '@/components/FilesView/MultiSelected'
import {mapGetters} from 'vuex'
import {events} from '@/bus'
import { mapGetters } from 'vuex'
import { events } from '@/bus'
export default {
name:"DragUI",
components: {MultiSelected},
computed: {
...mapGetters(['fileInfoDetail']),
title(){
export default {
name: 'DragUI',
components: { MultiSelected },
computed: {
...mapGetters(['fileInfoDetail']),
title() {
let filesLength = this.fileInfoDetail.length,
hasDraggedItem = this.fileInfoDetail.includes(this.draggedItem)
// Title for multiple selected items
if(this.fileInfoDetail.length > 1 && this.fileInfoDetail.includes(this.draggedItem)) {
return this.$t('file_detail.selected_multiple')
}
// Title for multiple selected items
if (filesLength > 1 && hasDraggedItem) {
return this.$t('file_detail.selected_multiple')
}
// Title for single item
if((this.fileInfoDetail.length < 2 || !this.fileInfoDetail.includes(this.draggedItem)) && this.draggedItem ) {
return this.draggedItem.name
}
},
subtitle(){
// Subtitle for multiple selected items
if(this.fileInfoDetail.length > 1 && this.fileInfoDetail.includes(this.draggedItem) ) {
return this.fileInfoDetail.length + ' ' + this.$tc('file_detail.items', this.fileInfoDetail.length)
}
if((this.fileInfoDetail.length < 2 || !this.fileInfoDetail.includes(this.draggedItem)) && this.draggedItem) {
// Subtitle for single folder
if(this.draggedItem.type === 'folder') {
return this.draggedItem.items == 0 ? this.$t('folder.empty') : this.$tc('folder.item_counts', this.draggedItem.items)
}
// Subtitle for single file
if(this.draggedItem !== 'folder' && this.draggedItem.mimetype){
return '.'+this.draggedItem.mimetype
}
}
},
},
data () {
return {
dragged: false,
draggedItem: undefined
// Title for single item
if ((filesLength < 2 || !hasDraggedItem) && this.draggedItem) {
return this.draggedItem.name
}
},
mounted () {
subtitle() {
let filesLength = this.fileInfoDetail.length,
hasDraggedItem = this.fileInfoDetail.includes(this.draggedItem)
// Hnadle Drag & Drop Ghost show
events.$on('dragstart', (data) => {
setTimeout(() => {
this.dragged = true
}, 50);
this.draggedItem = data
})
events.$on('drop', () => {
this.dragged = false
})
// Subtitle for multiple selected items
if (filesLength > 1 && hasDraggedItem) {
return filesLength + ' ' + this.$tc('file_detail.items', filesLength)
}
if ((filesLength < 2 || !hasDraggedItem) && this.draggedItem) {
// Subtitle for single folder
if (this.draggedItem.type === 'folder') {
return this.draggedItem.items == 0 ? this.$t('folder.empty') : this.$tc('folder.item_counts', this.draggedItem.items)
}
// Subtitle for single file
if (this.draggedItem !== 'folder' && this.draggedItem.mimetype) {
return '.' + this.draggedItem.mimetype
}
}
}
},
data() {
return {
isVisible: false,
draggedItem: undefined
}
},
created() {
// Handle Drag & Drop Ghost show
events.$on('dragstart', data => {
this.draggedItem = data
setTimeout(() => {
this.isVisible = true
}, 100)
})
events.$on('drop', () => {
this.isVisible = false
})
}
}
</script>
<style lang="scss" scoped>
@@ -82,38 +87,44 @@ import {events} from '@/bus'
padding: 10px;
border-radius: 8px;
box-shadow: 0 7px 25px 1px rgba(0, 0, 0, 0.12);
background:white;
/deep/.text{
.title {
color: $text;
}
.count {
color: $text-muted;
}
background: white;
/deep/ .text {
.title {
color: $text;
}
/deep/.icon-wrapper {
.icon {
stroke: $theme;
}
.count {
color: $text-muted;
}
}
/deep/ .icon-wrapper {
.icon {
stroke: $theme;
}
}
}
@media (prefers-color-scheme: dark) {
#multi-select-ui {
background: $dark_mode_foreground;
/deep/.text {
/deep/ .text {
.title {
color: $dark_mode_text_primary;
}
.count {
color: $dark_mode_text_secondary;
}
}
/deep/.icon-wrapper {
.icon {
}
/deep/ .icon-wrapper {
.icon {
stroke: $theme;
}
}
}
}
}
}

View File

@@ -34,7 +34,7 @@
@dragstart="dragStart(item)"
@drop.stop.native.prevent="dragFinish(item, $event)"
@contextmenu.native.prevent="contextMenu($event, item)"
:data="item"
:item="item"
v-for="item in data"
:key="item.unique_id"
class="file-item"
@@ -55,7 +55,7 @@
@dragstart="dragStart(item)"
@drop.native.prevent="dragFinish(item, $event)"
@contextmenu.native.prevent="contextMenu($event, item)"
:data="item"
:item="item"
v-for="item in data"
:key="item.unique_id"
class="file-item"
@@ -381,6 +381,20 @@
.mobile-search {
display: block;
}
.file-content {
position: absolute;
top: 0px;
left: 15px;
right: 15px;
bottom: 0;
@include transition;
overflow-y: auto;
overflow-x: hidden;
&.is-offset {
margin-top: 50px;
}
}
}
@media only screen and (max-width: 690px) {

View File

@@ -53,7 +53,7 @@
<div class="sharelink">
<lock-icon v-if="isLocked" @click="shareItemOptions" class="lock-icon" size="17"></lock-icon>
<unlock-icon v-if="! isLocked" @click="shareItemOptions" class="lock-icon" size="17"></unlock-icon>
<CopyInput class="copy-sharelink" size="small" :value="fileInfoDetail[0].shared.link"/>
<CopyInput class="copy-sharelink" size="small" :item="fileInfoDetail[0]"/>
</div>
</ListInfoItem>

View File

@@ -8,48 +8,48 @@
<div class="icon-item">
<!-- MultiSelecting for the mobile version -->
<div :class="{'check-select-folder' : this.data.type === 'folder', 'check-select' : this.data.type !== 'folder'}" v-if="multiSelectMode">
<div :class="{'check-select-folder' : this.item.type === 'folder', 'check-select' : this.item.type !== 'folder'}" v-if="multiSelectMode">
<div class="select-box" :class="{'select-box-active' : isClicked } ">
<CheckIcon v-if="isClicked" class="icon" size="17"/>
</div>
</div>
<!--If is file or image, then link item-->
<span v-if="isFile || (isImage && !data.thumbnail)" class="file-icon-text">
{{ data.mimetype }}
<span v-if="isFile || (isImage && !item.thumbnail)" class="file-icon-text">
{{ item.mimetype }}
</span>
<!--Folder thumbnail-->
<FontAwesomeIcon v-if="isFile || (isImage && !data.thumbnail)" class="file-icon" icon="file"/>
<FontAwesomeIcon v-if="isFile || (isImage && !item.thumbnail)" class="file-icon" icon="file"/>
<!--Image thumbnail-->
<img loading="lazy" v-if="isImage && data.thumbnail" class="image" :src="data.thumbnail" :alt="data.name"/>
<img loading="lazy" v-if="isImage && item.thumbnail" class="image" :src="item.thumbnail" :alt="item.name"/>
<!--Else show only folder icon-->
<FontAwesomeIcon v-if="isFolder" :class="{'is-deleted': isDeleted}" class="folder-icon" icon="folder"/>
<!--Else show only folder icon-->
<FolderIcon v-if="isFolder" :item="item" location="file-item-grid" class="folder"/>
</div>
<!--Name-->
<div class="item-name">
<!--Name-->
<b ref="name" @input="renameItem" @keydown.delete.stop :contenteditable="canEditName" class="name">
<b :ref="this.item.unique_id" @input="renameItem" @keydown.delete.stop @click.stop :contenteditable="canEditName" class="name">
{{ itemName }}
</b>
<div class="item-info">
<!--Shared Icon-->
<div v-if="$checkPermission('master') && data.shared" class="item-shared">
<div v-if="$checkPermission('master') && item.shared" class="item-shared">
<link-icon size="12" class="shared-icon"></link-icon>
</div>
<!--Participant owner Icon-->
<div v-if="$checkPermission('master') && data.user_scope !== 'master'" class="item-shared">
<div v-if="$checkPermission('master') && item.user_scope !== 'master'" class="item-shared">
<user-plus-icon size="12" class="shared-icon"></user-plus-icon>
</div>
<!--Filesize-->
<span v-if="! isFolder" class="item-size">{{ data.filesize }}</span>
<span v-if="! isFolder" class="item-size">{{ item.filesize }}</span>
<!--Folder item counts-->
<span v-if="isFolder" class="item-length">
@@ -58,7 +58,7 @@
</div>
</div>
<span @click.stop="showItemActions" class="show-actions" v-if="$isMobile() && ! ( $checkPermission('visitor') && isFolder || multiSelectMode ) && canShowMobileOptions">
<span @click.stop="showItemActions" class="show-actions" v-if="$isMobile() && ! multiSelectMode && canShowMobileOptions">
<FontAwesomeIcon icon="ellipsis-h" class="icon-action"></FontAwesomeIcon>
</span>
</div>
@@ -67,44 +67,60 @@
<script>
import { LinkIcon, UserPlusIcon, CheckIcon } from 'vue-feather-icons'
import FolderIcon from '@/components/FilesView/FolderIcon'
import { debounce } from 'lodash'
import { mapGetters } from 'vuex'
import { events } from '@/bus'
export default {
name: 'FileItemGrid',
props: ['data'],
props: ['item'],
components: {
UserPlusIcon,
CheckIcon,
LinkIcon
LinkIcon,
FolderIcon,
},
computed: {
...mapGetters([
'FilePreviewType', 'sharedDetail', 'fileInfoDetail'
'FilePreviewType', 'sharedDetail', 'fileInfoDetail', 'data'
]),
...mapGetters({ allData: 'data' }),
folderEmojiOrColor(){
// If folder have set some color
if(this.item.icon_color) {
this.$nextTick(() => {
this.$refs[`folder${this.item.unique_id}`].firstElementChild.style.fill = `${this.item.icon_color}`
})
return false
}
// If folder have set some emoji
if(this.item.icon_emoji)
return this.item.icon_emoji
},
isClicked() {
return this.fileInfoDetail.some(element => element.unique_id == this.data.unique_id)
return this.fileInfoDetail.some(element => element.unique_id == this.item.unique_id)
},
isFolder() {
return this.data.type === 'folder'
return this.item.type === 'folder'
},
isFile() {
return this.data.type !== 'folder' && this.data.type !== 'image'
return this.item.type !== 'folder' && this.item.type !== 'image'
},
isPdf() {
return this.data.mimetype === 'pdf'
return this.item.mimetype === 'pdf'
},
isImage() {
return this.data.type === 'image'
return this.item.type === 'image'
},
isVideo() {
return this.data.type === 'video'
return this.item.type === 'video'
},
isAudio() {
let mimetypes = ['mpeg', 'mp3', 'mp4', 'wan', 'flac']
return mimetypes.includes(this.data.mimetype) && this.data.type === 'audio'
return mimetypes.includes(this.item.mimetype) && this.item.type === 'audio'
},
canEditName() {
return !this.$isMobile()
@@ -119,13 +135,13 @@ export default {
return !this.isDeleted && this.$checkPermission(['master', 'editor'])
},
timeStamp() {
return this.data.deleted_at ? this.$t('item_thumbnail.deleted_at', this.data.deleted_at) : this.data.created_at
return this.item.deleted_at ? this.$t('item_thumbnail.deleted_at', this.item.deleted_at) : this.item.created_at
},
folderItems() {
return this.data.deleted_at ? this.data.trashed_items : this.data.items
return this.item.deleted_at ? this.item.trashed_items : this.item.items
},
isDeleted() {
return this.data.deleted_at ? true : false
return this.item.deleted_at ? true : false
}
},
data() {
@@ -142,12 +158,12 @@ export default {
showItemActions() {
// Load file info detail
this.$store.commit('CLEAR_FILEINFO_DETAIL')
this.$store.commit('GET_FILEINFO_DETAIL', this.data)
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
events.$emit('mobileMenu:show')
},
dragEnter() {
if (this.data.type !== 'folder') return
if (this.item.type !== 'folder') return
this.area = true
},
@@ -158,17 +174,21 @@ export default {
events.$emit('unClick')
if (!this.$isMobile()) {
// After click deselect new folder rename input
document.getSelection().removeAllRanges();
if (e.ctrlKey || e.metaKey && !e.shiftKey) {
// Click + Ctrl
if (this.fileInfoDetail.some(item => item.unique_id === this.data.unique_id)) {
this.$store.commit('REMOVE_ITEM_FILEINFO_DETAIL', this.data)
if (this.fileInfoDetail.some(item => item.unique_id === this.item.unique_id)) {
this.$store.commit('REMOVE_ITEM_FILEINFO_DETAIL', this.item)
} else {
this.$store.commit('GET_FILEINFO_DETAIL', this.data)
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
}
} else if (e.shiftKey) {
// Click + Shift
let lastItem = this.allData.indexOf(this.fileInfoDetail[this.fileInfoDetail.length - 1])
let clickedItem = this.allData.indexOf(this.data)
let lastItem = this.data.indexOf(this.fileInfoDetail[this.fileInfoDetail.length - 1])
let clickedItem = this.data.indexOf(this.item)
// If Click + Shift + Ctrl dont remove already selected items
if (!e.ctrlKey && !e.metaKey) {
@@ -178,18 +198,18 @@ export default {
//Shift selecting from top to bottom
if (lastItem < clickedItem) {
for (let i = lastItem; i <= clickedItem; i++) {
this.$store.commit('GET_FILEINFO_DETAIL', this.allData[i])
this.$store.commit('GET_FILEINFO_DETAIL', this.data[i])
}
//Shift selecting from bottom to top
} else {
for (let i = lastItem; i >= clickedItem; i--) {
this.$store.commit('GET_FILEINFO_DETAIL', this.allData[i])
this.$store.commit('GET_FILEINFO_DETAIL', this.data[i])
}
}
} else {
// Click
this.$store.commit('CLEAR_FILEINFO_DETAIL')
this.$store.commit('GET_FILEINFO_DETAIL', this.data)
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
}
}
@@ -198,25 +218,25 @@ export default {
if (this.$isMobile() && this.isFolder) {
// Go to folder
if (this.$isThisLocation('public')) {
this.$store.dispatch('browseShared', [{ folder: this.data, back: false, init: false }])
this.$store.dispatch('browseShared', [{ folder: this.item, back: false, init: false }])
} else {
this.$store.dispatch('getFolder', [{ folder: this.data, back: false, init: false }])
this.$store.dispatch('getFolder', [{ folder: this.item, back: false, init: false }])
}
}
if (this.$isMobile()) {
if (this.isImage || this.isVideo || this.isAudio) {
this.$store.commit('GET_FILEINFO_DETAIL', this.data)
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
events.$emit('fileFullPreview:show')
}
}
}
if (this.multiSelectMode && this.$isMobile()) {
if (this.fileInfoDetail.some(item => item.unique_id === this.data.unique_id)) {
this.$store.commit('REMOVE_ITEM_FILEINFO_DETAIL', this.data)
if (this.fileInfoDetail.some(item => item.unique_id === this.item.unique_id)) {
this.$store.commit('REMOVE_ITEM_FILEINFO_DETAIL', this.item)
} else {
this.$store.commit('GET_FILEINFO_DETAIL', this.data)
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
}
}
// Get target classname
@@ -234,7 +254,7 @@ export default {
events.$emit('fileFullPreview:show')
} else if (this.isFile || !this.isFolder && !this.isPdf && !this.isVideo && !this.isAudio && !this.isImage) {
this.$downloadFile(this.data.file_url, this.data.name + '.' + this.data.mimetype)
this.$downloadFile(this.item.file_url, this.item.name + '.' + this.item.mimetype)
} else if (this.isFolder) {
@@ -242,9 +262,9 @@ export default {
this.$store.commit('CLEAR_FILEINFO_DETAIL')
if (this.$isThisLocation('public')) {
this.$store.dispatch('browseShared', [{ folder: this.data, back: false, init: false }])
this.$store.dispatch('browseShared', [{ folder: this.item, back: false, init: false }])
} else {
this.$store.dispatch('getFolder', [{ folder: this.data, back: false, init: false }])
this.$store.dispatch('getFolder', [{ folder: this.item, back: false, init: false }])
}
}
},
@@ -254,14 +274,22 @@ export default {
if (e.target.innerText.trim() === '') return
this.$store.dispatch('renameItem', {
unique_id: this.data.unique_id,
type: this.data.type,
unique_id: this.item.unique_id,
type: this.item.type,
name: e.target.innerText
})
}, 300)
},
created() {
this.itemName = this.data.name
this.itemName = this.item.name
events.$on('newFolder:focus', (unique_id) => {
if(this.item.unique_id == unique_id && !this.$isMobile()) {
this.$refs[unique_id].focus()
document.execCommand('selectAll')
}
})
events.$on('mobileSelecting:start', () => {
this.multiSelectMode = true
@@ -274,7 +302,7 @@ export default {
})
// Change item name
events.$on('change:name', (item) => {
if (this.data.unique_id == item.unique_id) this.itemName = item.name
if (this.item.unique_id == item.unique_id) this.itemName = item.name
})
}
}
@@ -314,7 +342,7 @@ export default {
}
.select-box-active {
background-color: $text;
background-color: $theme;
.icon {
stroke: white;
@@ -448,6 +476,7 @@ export default {
display: flex;
align-items: center;
.file-link {
display: block;
}
@@ -490,19 +519,13 @@ export default {
pointer-events: none;
}
.folder-icon {
align-items: flex-end;
@include font-size(80);
margin: 0 auto;
.folder {
width: 80px;
height: 80px;
margin: auto;
path {
fill: $theme;
}
&.is-deleted {
path {
fill: $dark_background;
}
/deep/ .folder-icon {
@include font-size(80)
}
}
}
@@ -536,11 +559,17 @@ export default {
.file-icon-text {
@include font-size(12);
}
.folder-icon {
@include font-size(75);
.folder {
width: 75px;
height: 75px;
margin-top: 0;
margin-bottom: 0;
/deep/ .folder-icon {
@include font-size(75)
}
}
.image {
@@ -564,10 +593,10 @@ export default {
}
.select-box-active {
background-color: #f4f5f6;
background-color: lighten($theme, 5%);
.icon {
stroke: $text;
stroke: white;
}
}
@@ -582,15 +611,6 @@ export default {
stroke: #2F3C54;
}
}
.folder-icon {
&.is-deleted {
path {
fill: lighten($dark_mode_foreground, 5%);
}
}
}
}
.file-item {

View File

@@ -1,9 +1,14 @@
<template>
<div class="file-wrapper" @click.stop="clickedItem" @dblclick="goToItem" spellcheck="false">
<!--List preview-->
<div :draggable="canDrag" @dragstart="$emit('dragstart')" @drop="
drop()
area = false" @dragleave="dragLeave" @dragover.prevent="dragEnter" class="file-item" :class="{'is-clicked' : isClicked , 'no-clicked' : !isClicked && this.$isMobile(), 'is-dragenter': area }">
<div
:draggable="canDrag"
@dragstart="$emit('dragstart')"
@drop="drop()"
@dragleave="dragLeave"
@dragover.prevent="dragEnter"
class="file-item" :class="{'is-clicked' : isClicked , 'no-clicked' : !isClicked && this.$isMobile(), 'is-dragenter': area }"
>
<!-- MultiSelecting for the mobile version -->
<transition name="slide-from-left">
<div class="check-select" v-if="mobileMultiSelect">
@@ -16,39 +21,39 @@
<!--Thumbnail for item-->
<div class="icon-item">
<!--If is file or image, then link item-->
<span v-if="isFile || (isImage && !data.thumbnail)" class="file-icon-text">
{{ data.mimetype | limitCharacters }}
<span v-if="isFile || (isImage && !item.thumbnail)" class="file-icon-text">
{{ item.mimetype | limitCharacters }}
</span>
<!--Folder thumbnail-->
<FontAwesomeIcon v-if="isFile || (isImage && !data.thumbnail)" class="file-icon" icon="file"/>
<FontAwesomeIcon v-if="isFile || (isImage && !item.thumbnail)" class="file-icon" icon="file"/>
<!--Image thumbnail-->
<img loading="lazy" v-if="isImage && data.thumbnail" class="image" :src="data.thumbnail" :alt="data.name"/>
<img loading="lazy" v-if="isImage && item.thumbnail" class="image" :src="item.thumbnail" :alt="item.name"/>
<!--Else show only folder icon-->
<FontAwesomeIcon v-if="isFolder" :class="{ 'is-deleted': isDeleted }" class="folder-icon" icon="folder"/>
<!--Else show only folder icon-->
<FolderIcon v-if="isFolder" :item="item" location="file-item-list" class="folder" />
</div>
<!--Name-->
<div class="item-name">
<b ref="name" @input="renameItem" @keydown.delete.stop :contenteditable="canEditName" class="name">
<b :ref="this.item.unique_id" @input="renameItem" @keydown.delete.stop @click.stop :contenteditable="canEditName" class="name">
{{ itemName }}
</b>
<div class="item-info">
<!--Shared Icon-->
<div v-if="$checkPermission('master') && data.shared" class="item-shared">
<div v-if="$checkPermission('master') && item.shared" class="item-shared">
<link-icon size="12" class="shared-icon"></link-icon>
</div>
<!--Participant owner Icon-->
<div v-if="$checkPermission('master') && data.user_scope !== 'master'" class="item-shared">
<div v-if="$checkPermission('master') && item.user_scope !== 'master'" class="item-shared">
<user-plus-icon size="12" class="shared-icon"></user-plus-icon>
</div>
<!--Filesize and timestamp-->
<span v-if="!isFolder" class="item-size">{{ data.filesize }}, {{ timeStamp }}</span>
<span v-if="!isFolder" class="item-size">{{ item.filesize }}, {{ timeStamp }}</span>
<!--Folder item counts-->
<span v-if="isFolder" class="item-length"> {{ folderItems == 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ timeStamp }} </span>
@@ -57,7 +62,7 @@
<!--Show item actions-->
<transition name="slide-from-right">
<div class="actions" v-if="$isMobile() && !($checkPermission('visitor') && isFolder || mobileMultiSelect)">
<div class="actions" v-if="$isMobile() && ! mobileMultiSelect">
<span @click.stop="showItemActions" class="show-actions">
<FontAwesomeIcon icon="ellipsis-v" class="icon-action"></FontAwesomeIcon>
</span>
@@ -69,42 +74,43 @@
<script>
import { LinkIcon, UserPlusIcon, CheckIcon } from 'vue-feather-icons'
import FolderIcon from '@/components/FilesView/FolderIcon'
import { debounce } from 'lodash'
import { mapGetters } from 'vuex'
import { events } from '@/bus'
export default {
name: 'FileItemList',
props: ['data'],
props: ['item'],
components: {
UserPlusIcon,
LinkIcon,
CheckIcon
FolderIcon,
CheckIcon,
},
computed: {
...mapGetters(['FilePreviewType', 'fileInfoDetail']),
...mapGetters({ allData: 'data' }),
...mapGetters(['FilePreviewType', 'fileInfoDetail', 'data']),
isClicked() {
return this.fileInfoDetail.some(element => element.unique_id == this.data.unique_id)
return this.fileInfoDetail.some(element => element.unique_id == this.item.unique_id)
},
isFolder() {
return this.data.type === 'folder'
return this.item.type === 'folder'
},
isFile() {
return this.data.type !== 'folder' && this.data.type !== 'image'
return this.item.type !== 'folder' && this.item.type !== 'image'
},
isImage() {
return this.data.type === 'image'
return this.item.type === 'image'
},
isPdf() {
return this.data.mimetype === 'pdf'
return this.item.mimetype === 'pdf'
},
isVideo() {
return this.data.type === 'video'
return this.item.type === 'video'
},
isAudio() {
let mimetypes = ['mpeg', 'mp3', 'mp4', 'wan', 'flac']
return mimetypes.includes(this.data.mimetype) && this.data.type === 'audio'
return mimetypes.includes(this.item.mimetype) && this.item.type === 'audio'
},
canEditName() {
return !this.$isMobile() && !this.$isThisLocation(['trash', 'trash-root']) && !this.$checkPermission('visitor') && !(this.sharedDetail && this.sharedDetail.type === 'file')
@@ -113,13 +119,13 @@ export default {
return !this.isDeleted && this.$checkPermission(['master', 'editor'])
},
timeStamp() {
return this.data.deleted_at ? this.$t('item_thumbnail.deleted_at', { time: this.data.deleted_at }) : this.data.created_at
return this.item.deleted_at ? this.$t('item_thumbnail.deleted_at', { time: this.item.deleted_at }) : this.item.created_at
},
folderItems() {
return this.data.deleted_at ? this.data.trashed_items : this.data.items
return this.item.deleted_at ? this.item.trashed_items : this.item.items
},
isDeleted() {
return this.data.deleted_at ? true : false
return this.item.deleted_at ? true : false
}
},
filters: {
@@ -140,17 +146,18 @@ export default {
},
methods: {
drop() {
this.area = false
events.$emit('drop')
},
showItemActions() {
// Load file info detail
this.$store.commit('CLEAR_FILEINFO_DETAIL')
this.$store.commit('GET_FILEINFO_DETAIL', this.data)
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
events.$emit('mobileMenu:show')
},
dragEnter() {
if (this.data.type !== 'folder') return
if (this.item.type !== 'folder') return
this.area = true
},
@@ -162,18 +169,21 @@ export default {
if (!this.$isMobile()) {
// After click deselect new folder rename input
document.getSelection().removeAllRanges();
if ((e.ctrlKey || e.metaKey) && !e.shiftKey) {
// Click + Ctrl
if (this.fileInfoDetail.some(item => item.unique_id === this.data.unique_id)) {
this.$store.commit('REMOVE_ITEM_FILEINFO_DETAIL', this.data)
if (this.fileInfoDetail.some(item => item.unique_id === this.item.unique_id)) {
this.$store.commit('REMOVE_ITEM_FILEINFO_DETAIL', this.item)
} else {
this.$store.commit('GET_FILEINFO_DETAIL', this.data)
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
}
} else if (e.shiftKey) {
// Click + Shift
let lastItem = this.allData.indexOf(this.fileInfoDetail[this.fileInfoDetail.length - 1])
let clickedItem = this.allData.indexOf(this.data)
let lastItem = this.data.indexOf(this.fileInfoDetail[this.fileInfoDetail.length - 1])
let clickedItem = this.data.indexOf(this.item)
// If Click + Shift + Ctrl dont remove already selected items
if (!e.ctrlKey && !e.metaKey) {
@@ -183,18 +193,18 @@ export default {
//Shift selecting from top to bottom
if (lastItem < clickedItem) {
for (let i = lastItem; i <= clickedItem; i++) {
this.$store.commit('GET_FILEINFO_DETAIL', this.allData[i])
this.$store.commit('GET_FILEINFO_DETAIL', this.data[i])
}
//Shift selecting from bottom to top
} else {
for (let i = lastItem; i >= clickedItem; i--) {
this.$store.commit('GET_FILEINFO_DETAIL', this.allData[i])
this.$store.commit('GET_FILEINFO_DETAIL', this.data[i])
}
}
} else {
// Click
this.$store.commit('CLEAR_FILEINFO_DETAIL')
this.$store.commit('GET_FILEINFO_DETAIL', this.data)
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
}
}
@@ -203,25 +213,25 @@ export default {
if (this.$isMobile() && this.isFolder) {
// Go to folder
if (this.$isThisLocation('public')) {
this.$store.dispatch('browseShared', [{ folder: this.data, back: false, init: false }])
this.$store.dispatch('browseShared', [{ folder: this.item, back: false, init: false }])
} else {
this.$store.dispatch('getFolder', [{ folder: this.data, back: false, init: false }])
this.$store.dispatch('getFolder', [{ folder: this.item, back: false, init: false }])
}
}
if (this.$isMobile()) {
if (this.isImage || this.isVideo || this.isAudio) {
this.$store.commit('GET_FILEINFO_DETAIL', this.data)
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
events.$emit('fileFullPreview:show')
}
}
}
if (this.mobileMultiSelect && this.$isMobile()) {
if (this.fileInfoDetail.some(item => item.unique_id === this.data.unique_id)) {
this.$store.commit('REMOVE_ITEM_FILEINFO_DETAIL', this.data)
if (this.fileInfoDetail.some(item => item.unique_id === this.item.unique_id)) {
this.$store.commit('REMOVE_ITEM_FILEINFO_DETAIL', this.item)
} else {
this.$store.commit('GET_FILEINFO_DETAIL', this.data)
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
}
}
@@ -235,7 +245,7 @@ export default {
events.$emit('fileFullPreview:show')
} else if (this.isFile || !this.isFolder && !this.isPdf && !this.isVideo && !this.isAudio && !this.isImage) {
this.$downloadFile(this.data.file_url, this.data.name + '.' + this.data.mimetype)
this.$downloadFile(this.item.file_url, this.item.name + '.' + this.item.mimetype)
} else if (this.isFolder) {
@@ -243,9 +253,9 @@ export default {
this.$store.commit('CLEAR_FILEINFO_DETAIL')
if (this.$isThisLocation('public')) {
this.$store.dispatch('browseShared', [{ folder: this.data, back: false, init: false }])
this.$store.dispatch('browseShared', [{ folder: this.item, back: false, init: false }])
} else {
this.$store.dispatch('getFolder', [{ folder: this.data, back: false, init: false }])
this.$store.dispatch('getFolder', [{ folder: this.item, back: false, init: false }])
}
}
},
@@ -254,14 +264,23 @@ export default {
if (e.target.innerText.trim() === '') return
this.$store.dispatch('renameItem', {
unique_id: this.data.unique_id,
type: this.data.type,
unique_id: this.item.unique_id,
type: this.item.type,
name: e.target.innerText
})
}, 300)
},
created() {
this.itemName = this.data.name
this.itemName = this.item.name
events.$on('newFolder:focus', (unique_id) => {
if(this.item.unique_id == unique_id && !this.$isMobile()) {
this.$refs[unique_id].focus()
document.execCommand('selectAll')
}
})
events.$on('mobileSelecting:start', () => {
this.mobileMultiSelect = true
@@ -275,7 +294,7 @@ export default {
// Change item name
events.$on('change:name', (item) => {
if (this.data.unique_id == item.unique_id) this.itemName = item.name
if (this.item.unique_id == item.unique_id) this.itemName = item.name
})
}
}
@@ -285,6 +304,7 @@ export default {
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.slide-from-left-move {
transition: transform 300s ease;
}
@@ -324,10 +344,10 @@ export default {
}
.select-box-active {
background-color: #f4f5f6;
background-color: $theme;
.icon {
stroke: $text;
stroke: white;
}
}
}
@@ -436,18 +456,13 @@ export default {
flex: 0 0 50px;
line-height: 0;
margin-right: 20px;
.folder {
width: 52px;
height: 52px;
.folder-icon {
@include font-size(52);
path {
fill: $theme;
}
&.is-deleted {
path {
fill: $dark_background;
}
/deep/ .folder-icon {
@include font-size(52)
}
}
@@ -529,10 +544,10 @@ export default {
}
.select-box-active {
background-color: lighten($dark_mode_foreground, 10%);
background-color: $theme;
.icon {
stroke: $theme;
stroke: white;
}
}
}
@@ -545,14 +560,6 @@ export default {
stroke: #2f3c54;
}
}
.folder-icon {
&.is-deleted {
path {
fill: lighten($dark_mode_foreground, 5%);
}
}
}
}
.file-item {

View File

@@ -6,7 +6,7 @@
<p class="title">{{ fileInfoDetail[0].name }}</p>
<span class="file-count"> ({{ showingImageIndex + ' ' + $t('pronouns.of') + ' ' + filteredFiles.length }}) </span>
</div>
<span id="fast-preview-menu" class="fast-menu-icon" @click.stop="menuOpen" v-if="$checkPermission(['master', 'editor'])">
<span id="fast-preview-menu" class="fast-menu-icon" @click.stop="menuOpen" v-if="$checkPermission(['master', 'editor', 'visitor'])">
<more-horizontal-icon class="more-icon" size="14"> </more-horizontal-icon>
</span>
</div>

View File

@@ -0,0 +1,116 @@
<template>
<div :class="[{'is-apple': $isApple()}, location]">
<Emoji
v-if="emoji"
:emoji="emoji"
class="emoji-icon"
/>
<FontAwesomeIcon
v-if="!emoji"
:class="[{ 'is-deleted': isDeleted },{'default-color' : ! color && ! isDeleted}, 'folder-icon' ]"
:style="{fill: color}"
icon="folder"
/>
</div>
</template>
<script>
import Emoji from '@/components/Others/Emoji'
export default {
name: 'FolderIcon',
props: [
'item',
'folderIcon',
'location'
],
components: {
Emoji
},
computed: {
isDeleted() {
return this.item.deleted_at ? true : false
},
emoji() {
// Return emoji if is changed from rename popup
if (this.folderIcon)
return this.folderIcon.emoji ? this.folderIcon.emoji : false
// Return emoji if is already set
return this.item.icon_emoji ? this.item.icon_emoji : false
},
color() {
// Return color if is changed from rename popup
if (this.folderIcon)
return this.folderIcon.color ? this.folderIcon.color : false
// Return color if is already set
return this.item.icon_color ? this.item.icon_color : false
}
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
// Locations
.file-item-list {
&.is-apple .emoji-icon {
font-size: 50px;
line-height: 1.1;
}
}
.file-item-grid {
&.is-apple .emoji-icon {
font-size: 80px;
line-height: 1.1;
}
}
.thumbnail-item {
&.is-apple .emoji-icon {
font-size: 36px;
line-height: 1.1;
}
}
.emoji-picker-preview {
&.is-apple .emoji-icon {
font-size: 22px;
line-height: 1.1;
}
}
.default-color {
path {
fill: $theme !important;
}
}
.folder-icon {
path {
fill: inherit;
}
&.is-deleted {
path {
fill: $dark_background;
}
}
}
@media (prefers-color-scheme: dark) {
.folder-icon {
&.is-deleted {
path {
fill: lighten($dark_mode_foreground, 5%);
}
}
}
}
</style>

Some files were not shown because too many files have changed in this diff Show More