画廊页面

This commit is contained in:
Wisp X 2022-02-11 13:48:22 +08:00
parent 6d8031b0a2
commit 588f05dfde
14 changed files with 601 additions and 361 deletions

View File

@ -41,11 +41,17 @@ class UserController extends Controller
return view('user.gallery');
}
public function works(): Response
{
return $this->success();
}
public function update(UserSettingRequest $request): Response
{
/** @var User $user */
$user = Auth::user();
$user->name = $request->validated('name');
$user->url = $request->validated('url');
$user->configs = $user->configs->merge(collect($request->validated('configs'))->transform(function ($value) {
return (int)$value;
}));

View File

@ -13,6 +13,7 @@ class UserSettingRequest extends FormRequest
{
return [
'name' => 'required|between:2,20',
'url' => 'url',
'password' => 'nullable|between:6,32',
'configs' => 'array',
'configs.default_album' => 'required|numeric',
@ -27,6 +28,7 @@ class UserSettingRequest extends FormRequest
return [
'name.required' => '昵称不能为空',
'name.between' => '昵称必须在 2-20 个字符之间',
'url.url' => '个人主页地址格式不正确',
'password.between' => '昵称必须在 6-32 个字符之间',
'configs.array' => '配置值不正确',
'configs.default_album.required' => '默认相册选择错误',

View File

@ -4,8 +4,10 @@ namespace App\Models;
use App\Enums\ImagePermission;
use App\Enums\UserConfigKey;
use App\Utils;
use Carbon\Carbon;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
@ -23,6 +25,7 @@ use Laravel\Sanctum\HasApiTokens;
* @property string $remember_token
* @property boolean $is_adminer
* @property float $capacity
* @property string $url
* @property Collection $configs
* @property int $image_num
* @property int $album_num
@ -31,6 +34,7 @@ use Laravel\Sanctum\HasApiTokens;
* @property Carbon $email_verified_at
* @property Carbon $updated_at
* @property Carbon $created_at
* @property-read string $avatar
* @property-read Group $group
* @property-read \Illuminate\Database\Eloquent\Collection $albums
* @property-read \Illuminate\Database\Eloquent\Collection $images
@ -48,6 +52,7 @@ class User extends Authenticatable implements MustVerifyEmail
'name',
'email',
'password',
'url',
'configs',
'registered_ip',
];
@ -91,6 +96,11 @@ class User extends Authenticatable implements MustVerifyEmail
});
}
public function avatar(): Attribute
{
return new Attribute(fn () => Utils::getAvatar($this->email));
}
public function group(): BelongsTo
{
return $this->belongsTo(Group::class, 'group_id', 'id');

View File

@ -9,6 +9,29 @@ use Illuminate\Support\Facades\Cache;
class Utils
{
/**
* 获取头像地址
*
* @param $email
* @param int $s
* @param string $d
* @param string $r
* @return string
*/
public static function getAvatar($email, int $s = 96, string $d = 'mp', string $r = 'g'): string
{
preg_match_all('/((\d)*)@qq.com/', $email, $vai);
if (empty($vai['1']['0'])) {
$url = 'https://gravatar.cat.net/avatar/';
$url .= md5(strtolower(trim($email)));
$url .= "?s=$s&d=$d&r=$r";
return $url;
} else {
$url = 'https://q2.qlogo.cn/headimg_dl?dst_uin='.$vai['1']['0'].'&spec=100';
}
return $url;
}
/**
* 获取系统配置,获取全部配置时将返回
*
@ -87,8 +110,8 @@ class Utils
/**
* 格式化配置,设置默认配置以及将字符串数字转换为数字
*
* @param array $defaults 默认配置
* @param array $configs 新配置
* @param array $defaults 默认配置
* @param array $configs 新配置
* @return array
*/
public static function parseConfigs(array $defaults, array $configs): array

View File

@ -26,6 +26,7 @@ return new class extends Migration
$table->rememberToken();
$table->boolean('is_adminer')->default(false)->comment('是否为管理员');
$table->decimal('capacity', 20)->default(0)->comment('总容量(kb)');
$table->string('url')->default('')->comment('个人主页');
$table->json('configs')->comment('配置');
$table->unsignedBigInteger('image_num')->default(0)->comment('图片数量');
$table->unsignedBigInteger('album_num')->default(0)->comment('相册数量');

123
package-lock.json generated
View File

@ -18,6 +18,7 @@
"deepmerge": "^4.2.2",
"dragselect": "^2.3.0",
"echarts": "^5.2.2",
"imagesloaded": "^4.1.4",
"jquery": "^3.6.0",
"jquery.photoswipe": "^1.1.1",
"justifiedGallery": "^3.8.1",
@ -25,6 +26,7 @@
"less": "^4.1.2",
"less-loader": "^10.2.0",
"lodash": "^4.17.19",
"masonry-layout": "^4.2.2",
"postcss": "^8.2.1",
"postcss-import": "^14.0.1",
"resolve-url-loader": "^4.0.0",
@ -4424,6 +4426,13 @@
"minimalistic-assert": "^1.0.0"
}
},
"node_modules/desandro-matches-selector": {
"version": "2.0.2",
"resolved": "https://repo.huaweicloud.com/repository/npm/desandro-matches-selector/-/desandro-matches-selector-2.0.2.tgz",
"integrity": "sha1-cXvu1NwT59jzdi9wem1YpndCGOE=",
"dev": true,
"license": "MIT"
},
"node_modules/destroy": {
"version": "1.0.4",
"resolved": "https://repo.huaweicloud.com/repository/npm/destroy/-/destroy-1.0.4.tgz",
@ -4904,6 +4913,13 @@
"node": ">= 0.6"
}
},
"node_modules/ev-emitter": {
"version": "1.1.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/ev-emitter/-/ev-emitter-1.1.1.tgz",
"integrity": "sha512-ipiDYhdQSCZ4hSbX4rMW+XzNKMD1prg/sTvoVmSLkuQ1MVlwjJQQA+sW8tMYR3BLUr9KjodFV4pvzunvRhd33Q==",
"dev": true,
"license": "MIT"
},
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://repo.huaweicloud.com/repository/npm/eventemitter3/-/eventemitter3-4.0.7.tgz",
@ -5250,6 +5266,16 @@
"node": ">=8"
}
},
"node_modules/fizzy-ui-utils": {
"version": "2.0.7",
"resolved": "https://repo.huaweicloud.com/repository/npm/fizzy-ui-utils/-/fizzy-ui-utils-2.0.7.tgz",
"integrity": "sha512-CZXDVXQ1If3/r8s0T+v+qVeMshhfcuq0rqIFgJnrtd+Bu8GmDmqMjntjUePypVtjHXKJ6V4sw9zeyox34n9aCg==",
"dev": true,
"license": "MIT",
"dependencies": {
"desandro-matches-selector": "^2.0.0"
}
},
"node_modules/follow-redirects": {
"version": "1.14.8",
"resolved": "https://repo.huaweicloud.com/repository/npm/follow-redirects/-/follow-redirects-1.14.8.tgz",
@ -5391,6 +5417,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-size": {
"version": "2.0.3",
"resolved": "https://repo.huaweicloud.com/repository/npm/get-size/-/get-size-2.0.3.tgz",
"integrity": "sha512-lXNzT/h/dTjTxRbm9BXb+SGxxzkm97h/PCIKtlN/CBCxxmkkIVV21udumMS93MuVTDX583gqc94v3RjuHmI+2Q==",
"dev": true,
"license": "MIT"
},
"node_modules/get-stream": {
"version": "6.0.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/get-stream/-/get-stream-6.0.1.tgz",
@ -5997,6 +6030,16 @@
"node": ">=8"
}
},
"node_modules/imagesloaded": {
"version": "4.1.4",
"resolved": "https://repo.huaweicloud.com/repository/npm/imagesloaded/-/imagesloaded-4.1.4.tgz",
"integrity": "sha512-ltiBVcYpc/TYTF5nolkMNsnREHW+ICvfQ3Yla2Sgr71YFwQ86bDwV9hgpFhFtrGPuwEx5+LqOHIrdXBdoWwwsA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ev-emitter": "^1.0.0"
}
},
"node_modules/img-loader": {
"version": "4.0.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/img-loader/-/img-loader-4.0.0.tgz",
@ -6843,6 +6886,17 @@
"semver": "bin/semver.js"
}
},
"node_modules/masonry-layout": {
"version": "4.2.2",
"resolved": "https://repo.huaweicloud.com/repository/npm/masonry-layout/-/masonry-layout-4.2.2.tgz",
"integrity": "sha512-iGtAlrpHNyxaR19CvKC3npnEcAwszXoyJiI8ARV2ePi7fmYhIud25MHK8Zx4P0LCC4d3TNO9+rFa1KoK1OEOaA==",
"dev": true,
"license": "MIT",
"dependencies": {
"get-size": "^2.0.2",
"outlayer": "^2.1.0"
}
},
"node_modules/md5": {
"version": "2.3.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/md5/-/md5-2.3.0.tgz",
@ -7494,6 +7548,18 @@
"dev": true,
"license": "MIT"
},
"node_modules/outlayer": {
"version": "2.1.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/outlayer/-/outlayer-2.1.1.tgz",
"integrity": "sha1-KYY7beEOpdrf/8rfoNcokHOH6aI=",
"dev": true,
"license": "MIT",
"dependencies": {
"ev-emitter": "^1.0.0",
"fizzy-ui-utils": "^2.0.0",
"get-size": "^2.0.2"
}
},
"node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/p-limit/-/p-limit-2.3.0.tgz",
@ -13994,6 +14060,12 @@
"minimalistic-assert": "^1.0.0"
}
},
"desandro-matches-selector": {
"version": "2.0.2",
"resolved": "https://repo.huaweicloud.com/repository/npm/desandro-matches-selector/-/desandro-matches-selector-2.0.2.tgz",
"integrity": "sha1-cXvu1NwT59jzdi9wem1YpndCGOE=",
"dev": true
},
"destroy": {
"version": "1.0.4",
"resolved": "https://repo.huaweicloud.com/repository/npm/destroy/-/destroy-1.0.4.tgz",
@ -14348,6 +14420,12 @@
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
"dev": true
},
"ev-emitter": {
"version": "1.1.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/ev-emitter/-/ev-emitter-1.1.1.tgz",
"integrity": "sha512-ipiDYhdQSCZ4hSbX4rMW+XzNKMD1prg/sTvoVmSLkuQ1MVlwjJQQA+sW8tMYR3BLUr9KjodFV4pvzunvRhd33Q==",
"dev": true
},
"eventemitter3": {
"version": "4.0.7",
"resolved": "https://repo.huaweicloud.com/repository/npm/eventemitter3/-/eventemitter3-4.0.7.tgz",
@ -14605,6 +14683,15 @@
"path-exists": "^4.0.0"
}
},
"fizzy-ui-utils": {
"version": "2.0.7",
"resolved": "https://repo.huaweicloud.com/repository/npm/fizzy-ui-utils/-/fizzy-ui-utils-2.0.7.tgz",
"integrity": "sha512-CZXDVXQ1If3/r8s0T+v+qVeMshhfcuq0rqIFgJnrtd+Bu8GmDmqMjntjUePypVtjHXKJ6V4sw9zeyox34n9aCg==",
"dev": true,
"requires": {
"desandro-matches-selector": "^2.0.0"
}
},
"follow-redirects": {
"version": "1.14.8",
"resolved": "https://repo.huaweicloud.com/repository/npm/follow-redirects/-/follow-redirects-1.14.8.tgz",
@ -14688,6 +14775,12 @@
"has-symbols": "^1.0.1"
}
},
"get-size": {
"version": "2.0.3",
"resolved": "https://repo.huaweicloud.com/repository/npm/get-size/-/get-size-2.0.3.tgz",
"integrity": "sha512-lXNzT/h/dTjTxRbm9BXb+SGxxzkm97h/PCIKtlN/CBCxxmkkIVV21udumMS93MuVTDX583gqc94v3RjuHmI+2Q==",
"dev": true
},
"get-stream": {
"version": "6.0.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/get-stream/-/get-stream-6.0.1.tgz",
@ -15099,6 +15192,15 @@
"replace-ext": "^1.0.0"
}
},
"imagesloaded": {
"version": "4.1.4",
"resolved": "https://repo.huaweicloud.com/repository/npm/imagesloaded/-/imagesloaded-4.1.4.tgz",
"integrity": "sha512-ltiBVcYpc/TYTF5nolkMNsnREHW+ICvfQ3Yla2Sgr71YFwQ86bDwV9hgpFhFtrGPuwEx5+LqOHIrdXBdoWwwsA==",
"dev": true,
"requires": {
"ev-emitter": "^1.0.0"
}
},
"img-loader": {
"version": "4.0.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/img-loader/-/img-loader-4.0.0.tgz",
@ -15675,6 +15777,16 @@
}
}
},
"masonry-layout": {
"version": "4.2.2",
"resolved": "https://repo.huaweicloud.com/repository/npm/masonry-layout/-/masonry-layout-4.2.2.tgz",
"integrity": "sha512-iGtAlrpHNyxaR19CvKC3npnEcAwszXoyJiI8ARV2ePi7fmYhIud25MHK8Zx4P0LCC4d3TNO9+rFa1KoK1OEOaA==",
"dev": true,
"requires": {
"get-size": "^2.0.2",
"outlayer": "^2.1.0"
}
},
"md5": {
"version": "2.3.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/md5/-/md5-2.3.0.tgz",
@ -16137,6 +16249,17 @@
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
"dev": true
},
"outlayer": {
"version": "2.1.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/outlayer/-/outlayer-2.1.1.tgz",
"integrity": "sha1-KYY7beEOpdrf/8rfoNcokHOH6aI=",
"dev": true,
"requires": {
"ev-emitter": "^1.0.0",
"fizzy-ui-utils": "^2.0.0",
"get-size": "^2.0.2"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/p-limit/-/p-limit-2.3.0.tgz",

View File

@ -10,13 +10,11 @@
"production": "mix --production"
},
"devDependencies": {
"axios": "^0.25",
"laravel-mix": "^6.0.6",
"lodash": "^4.17.19",
"@fortawesome/fontawesome-free": "^5.15.4",
"@tailwindcss/forms": "^0.4.0",
"alpinejs": "^3.4.2",
"autoprefixer": "^10.1.0",
"axios": "^0.25",
"blueimp-canvas-to-blob": "^3.29.0",
"blueimp-file-upload": "^10.32.0",
"blueimp-load-image": "^5.16.0",
@ -28,14 +26,18 @@
"jquery": "^3.6.0",
"jquery.photoswipe": "^1.1.1",
"justifiedGallery": "^3.8.1",
"laravel-mix": "^6.0.6",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"lodash": "^4.17.19",
"masonry-layout": "^4.2.2",
"postcss": "^8.2.1",
"postcss-import": "^14.0.1",
"resolve-url-loader": "^4.0.0",
"sweetalert2": "^11.3.3",
"tailwindcss": "^3.0.0",
"toastr": "^2.1.4",
"viewerjs": "^1.10.2"
"viewerjs": "^1.10.2",
"imagesloaded": "^4.1.4"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -33925,6 +33925,19 @@ __webpack_require__.r(__webpack_exports__);
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "./resources/css/gallery.less":
/*!************************************!*\
!*** ./resources/css/gallery.less ***!
\************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "./resources/css/context-js.less":
@ -38161,6 +38174,7 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*
/******/ "/js/app": 0,
/******/ "css/app": 0,
/******/ "css/context-js/context-js": 0,
/******/ "css/gallery": 0,
/******/ "css/common": 0,
/******/ "css/fontawesome": 0
/******/ };
@ -38212,11 +38226,12 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
/******/ __webpack_require__.O(undefined, ["css/app","css/context-js/context-js","css/common","css/fontawesome"], () => (__webpack_require__("./resources/js/app.js")))
/******/ __webpack_require__.O(undefined, ["css/app","css/context-js/context-js","css/common","css/fontawesome"], () => (__webpack_require__("./resources/css/fontawesome.less")))
/******/ __webpack_require__.O(undefined, ["css/app","css/context-js/context-js","css/common","css/fontawesome"], () => (__webpack_require__("./resources/css/common.less")))
/******/ __webpack_require__.O(undefined, ["css/app","css/context-js/context-js","css/common","css/fontawesome"], () => (__webpack_require__("./resources/css/context-js.less")))
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["css/app","css/context-js/context-js","css/common","css/fontawesome"], () => (__webpack_require__("./resources/css/app.css")))
/******/ __webpack_require__.O(undefined, ["css/app","css/context-js/context-js","css/gallery","css/common","css/fontawesome"], () => (__webpack_require__("./resources/js/app.js")))
/******/ __webpack_require__.O(undefined, ["css/app","css/context-js/context-js","css/gallery","css/common","css/fontawesome"], () => (__webpack_require__("./resources/css/fontawesome.less")))
/******/ __webpack_require__.O(undefined, ["css/app","css/context-js/context-js","css/gallery","css/common","css/fontawesome"], () => (__webpack_require__("./resources/css/common.less")))
/******/ __webpack_require__.O(undefined, ["css/app","css/context-js/context-js","css/gallery","css/common","css/fontawesome"], () => (__webpack_require__("./resources/css/gallery.less")))
/******/ __webpack_require__.O(undefined, ["css/app","css/context-js/context-js","css/gallery","css/common","css/fontawesome"], () => (__webpack_require__("./resources/css/context-js.less")))
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["css/app","css/context-js/context-js","css/gallery","css/common","css/fontawesome"], () => (__webpack_require__("./resources/css/app.css")))
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
/******/
/******/ })()

View File

@ -2,6 +2,7 @@
"/js/app.js": "/js/app.js",
"/css/app.css": "/css/app.css",
"/css/context-js/context-js.css": "/css/context-js/context-js.css",
"/css/gallery.css": "/css/gallery.css",
"/css/common.css": "/css/common.css",
"/css/fontawesome.css": "/css/fontawesome.css",
"/js/blueimp-file-upload/jquery.ui.widget.js": "/js/blueimp-file-upload/jquery.ui.widget.js",
@ -16,5 +17,7 @@
"/js/clipboard/index.browser.js": "/js/clipboard/index.browser.js",
"/js/dragselect/ds.min.js": "/js/dragselect/ds.min.js",
"/js/context-js/context-js.js": "/js/context-js/context-js.js",
"/js/echarts/echarts.min.js": "/js/echarts/echarts.min.js"
"/js/echarts/echarts.min.js": "/js/echarts/echarts.min.js",
"/js/masonry/masonry.pkgd.min.js": "/js/masonry/masonry.pkgd.min.js",
"/js/imagesloaded/imagesloaded.pkgd.min.js": "/js/imagesloaded/imagesloaded.pkgd.min.js"
}

View File

@ -0,0 +1,9 @@
.images-grid {
.grid-item {
transition: all .3s;
&:hover {
margin-top: -5px;
box-shadow: 15.8px 21.3px 83.8px rgba(0, 0, 0, 0.07), 102px 137px 196px rgba(0, 0, 0, 0.035);
}
}
}

View File

@ -1,24 +1,47 @@
@section('title', '画廊')
@push('styles')
<link rel="stylesheet" href="{{ asset('css/gallery.css') }}">
@endpush
<x-app-layout>
<div class="max-w-2xl p-4 lg:max-w-7xl">
<div class="grid grid-cols-1 gap-y-10 gap-x-6 sm:grid-cols-2 md:grid-cols-4 xl:grid-cols-6 lg:grid-cols-8 xl:gap-x-8">
@foreach(\App\Models\Image::all() as $image)
<div class="flex flex-col bg-white rounded-md h-56 overflow-hidden">
<div class="flex justify-center items-center grow p-2 bg-auto bg-no-repeat bg-center bg-cover">
<img class="block object-cover" src="{{ $image->thumb_url }}">
<div class="p-4">
<div class="mb-4">
<p class="mb-2 text-xl font-semibold text-gray-700">2022 1 </p>
<div class="images-grid">
@foreach(\App\Models\Image::all() as $image)
<div class="grid-item relative mb-4 bg-white rounded-md w-40 overflow-hidden">
<div class="relative overflow-hidden w-full h-32">
<img class="grow object-cover object-center w-full h-full" src="{{ $image->thumb_url }}"/>
</div>
<a href="{{ $image->user->url ?: 'javascript:void(0)' }}" class="flex justify-between items-center px-2 py-3 bg-white overflow-hidden">
<img src="{{ $image->user->avatar }}" class="w-6 h-6 rounded-full">
<p class="ml-2 truncate">{{ $image->user->name }}</p>
</a>
</div>
<div class="flex">
11
</div>
</div>
@endforeach
@endforeach
</div>
</div>
</div>
@push('scripts')
<script src="{{ asset('js/masonry/masonry.pkgd.min.js') }}"></script>
<script src="{{ asset('js/imagesloaded/imagesloaded.pkgd.min.js') }}"></script>
<script>
var $grid = $('.images-grid').masonry({
itemSelector: '.grid-item',
gutter: 14,
originLeft: true,
originTop: true,
duration: '0.8s',
resize: true,
initLayout: true,
percentPosition: true,
horizontalOrder: true,
});
$grid.imagesLoaded().progress(function() {
$grid.masonry('layout');
});
</script>
@endpush
</x-app-layout>

View File

@ -44,6 +44,11 @@
</x-select>
</div>
<div class="col-span-6">
<label for="url" class="block text-sm font-medium text-gray-700">个人主页</label>
<x-input type="url" name="url" id="url" autocomplete="url" value="{{ Auth::user()->url }}" placeholder="个人主页地址http(s)://"/>
</div>
<div class="col-span-6">
<label for="password" class="block text-sm font-medium text-gray-700">密码</label>
<x-input type="password" name="password" id="password" placeholder="不修改请留空" autocomplete="password" />

View File

@ -18,6 +18,7 @@ mix.js('resources/js/app.js', 'public/js').postCss('resources/css/app.css', 'pub
]);
mix.less('resources/css/fontawesome.less', 'public/css');
mix.less('resources/css/common.less', 'public/css');
mix.less('resources/css/gallery.less', 'public/css');
mix.copy('node_modules/blueimp-file-upload/js/vendor/jquery.ui.widget.js', 'public/js/blueimp-file-upload');
mix.copy('node_modules/blueimp-file-upload/js/jquery.iframe-transport.js', 'public/js/blueimp-file-upload');
@ -45,3 +46,8 @@ mix.copy('resources/js/context-js.js', 'public/js/context-js')
// apache echarts
mix.copy('node_modules/echarts/dist/echarts.min.js', 'public/js/echarts')
// masonry layout
mix.copy('node_modules/masonry-layout/dist/masonry.pkgd.min.js', 'public/js/masonry')
// imagesloaded
mix.copy('node_modules/imagesloaded/imagesloaded.pkgd.min.js', 'public/js/imagesloaded')