✨ 复制图片功能
This commit is contained in:
@@ -41,12 +41,12 @@ class ImageController extends Controller
|
||||
$builder->whereRaw("concat(IFNULL(origin_name,''),IFNULL(alias_name,'')) like ?", ["%{$keyword}%"]);
|
||||
})->when((int) $request->query('album_id'), function (Builder $builder, $albumId) {
|
||||
$builder->where('album_id', $albumId);
|
||||
})->paginate(40);
|
||||
})->paginate(1);
|
||||
$images->getCollection()->each(function (Image $image) {
|
||||
$image->human_date = $image->created_at->diffForHumans();
|
||||
$image->date = $image->created_at->format('Y-m-d H:i:s');
|
||||
$image->append(['url', 'filename'])->setVisible([
|
||||
'id', 'filename', 'url', 'human_date', 'date', 'human_date', 'width', 'height'
|
||||
$image->append(['url', 'filename', 'links'])->setVisible([
|
||||
'id', 'filename', 'url', 'human_date', 'date', 'human_date', 'width', 'height', 'links'
|
||||
]);
|
||||
});
|
||||
return $this->success('success', compact('images'));
|
||||
|
||||
56
public/js/context-js/context-js.js
vendored
56
public/js/context-js/context-js.js
vendored
@@ -23,58 +23,69 @@ window.context = window.context || (function () {
|
||||
options = $.extend({}, options, opts);
|
||||
|
||||
$(document).on('click', 'html', function () {
|
||||
$('.dropdown-context').fadeOut(options.fadeSpeed, function(){
|
||||
$('.dropdown-context').css({display:''}).find('.drop-left').removeClass('drop-left');
|
||||
$('.dropdown-context').fadeOut(options.fadeSpeed, function () {
|
||||
$('.dropdown-context').css({display: ''}).find('.drop-left').removeClass('drop-left');
|
||||
});
|
||||
});
|
||||
if(options.preventDoubleContext){
|
||||
if (options.preventDoubleContext) {
|
||||
$(document).on('contextmenu', '.dropdown-context', function (e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
$(document).on('mouseenter', '.dropdown-submenu', function(){
|
||||
$(document).on('mouseenter', '.dropdown-submenu', function () {
|
||||
let $sub = $(this).find('.dropdown-context-sub:first'),
|
||||
subWidth = $sub.width(),
|
||||
subLeft = $sub.offset().left,
|
||||
collision = (subWidth+subLeft) > window.innerWidth;
|
||||
if(collision){
|
||||
collision = (subWidth + subLeft) > window.innerWidth;
|
||||
if (collision) {
|
||||
$sub.addClass('drop-left');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function updateOptions(opts){
|
||||
function updateOptions(opts) {
|
||||
options = $.extend({}, options, opts);
|
||||
}
|
||||
|
||||
function buildMenu(data, id, subMenu) {
|
||||
let subClass = (subMenu) ? ' dropdown-context-sub' : '',
|
||||
compressed = options.compress ? ' compressed-context' : '',
|
||||
$menu = $('<ul class="dropdown-menu dropdown-context' + subClass + compressed+'" id="dropdown-' + id + '"></ul>');
|
||||
$menu = $('<ul class="dropdown-menu dropdown-context' + subClass + compressed + '" id="dropdown-' + id + '"></ul>');
|
||||
let i = 0, linkTarget = '';
|
||||
for(i; i<data.length; i++) {
|
||||
for (i; i < data.length; i++) {
|
||||
if (typeof data[i].divider !== 'undefined') {
|
||||
$menu.append('<li class="divider"></li>');
|
||||
} else if (typeof data[i].header !== 'undefined') {
|
||||
$menu.append('<li class="nav-header">' + data[i].header + '</li>');
|
||||
} else {
|
||||
if (typeof data[i].href == 'undefined') {
|
||||
data[i].href = '#';
|
||||
data[i].href = 'javascript:void(0)';
|
||||
}
|
||||
if (typeof data[i].target !== 'undefined') {
|
||||
linkTarget = ' target="'+data[i].target+'"';
|
||||
linkTarget = ' target="' + data[i].target + '"';
|
||||
}
|
||||
let $sub;
|
||||
if (typeof data[i].subMenu !== 'undefined') {
|
||||
$sub = ('<li class="dropdown-submenu"><a tabindex="-1" href="' + data[i].href + '">' + data[i].text + '</a></li>');
|
||||
$sub = $('<li class="dropdown-submenu"><a tabindex="-1" href="' + data[i].href + '">' + data[i].text + '</a></li>');
|
||||
} else {
|
||||
$sub = $('<li><a tabindex="-1" href="' + data[i].href + '"'+linkTarget+'>' + data[i].text + '</a></li>');
|
||||
$sub = $('<li><a tabindex="-1" href="' + data[i].href + '"' + linkTarget + '>' + data[i].text + '</a></li>');
|
||||
}
|
||||
let $a = $sub.find('a');
|
||||
if (typeof data[i].classes !== 'undefined') {
|
||||
for (const classKey in data[i].classes) {
|
||||
$a.addClass(data[i].classes[classKey]);
|
||||
}
|
||||
}
|
||||
if (typeof data[i].attributes !== 'undefined') {
|
||||
for (const attributesKey in data[i].attributes) {
|
||||
$a.attr(attributesKey, data[i].attributes[attributesKey]);
|
||||
}
|
||||
}
|
||||
if (typeof data[i].action !== 'undefined') {
|
||||
let actionID = 'event-' + new Date().getTime() * Math.floor(Math.random()*100000),
|
||||
let actionID = 'event-' + new Date().getTime() * Math.floor(Math.random() * 100000),
|
||||
eventAction = data[i].action;
|
||||
$sub.find('a').attr('id', actionID);
|
||||
$a.attr('id', actionID);
|
||||
$('#' + actionID).addClass('context-event');
|
||||
$(document).on('click', '#' + actionID, function () {
|
||||
eventAction.call(this, selection);
|
||||
@@ -93,7 +104,18 @@ window.context = window.context || (function () {
|
||||
return $menu;
|
||||
}
|
||||
|
||||
function addContext(selector, data) {
|
||||
/**
|
||||
* 添加菜单
|
||||
* @param selector 被右击元素
|
||||
* @param data 数据 {
|
||||
* text: String, // 文本
|
||||
* classes: Array, // class
|
||||
* attributes: Object, // 属性
|
||||
* action: Function, // 点击后的回调
|
||||
* }
|
||||
* @param open 右击元素后的回调
|
||||
*/
|
||||
function addContext(selector, data, open) {
|
||||
|
||||
let d = new Date(),
|
||||
id = d.getTime(),
|
||||
@@ -129,6 +151,8 @@ window.context = window.context || (function () {
|
||||
}).fadeIn(options.fadeSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
open && open.call($dd.get(0), this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
56
resources/js/context-js.js
vendored
56
resources/js/context-js.js
vendored
@@ -23,58 +23,69 @@ window.context = window.context || (function () {
|
||||
options = $.extend({}, options, opts);
|
||||
|
||||
$(document).on('click', 'html', function () {
|
||||
$('.dropdown-context').fadeOut(options.fadeSpeed, function(){
|
||||
$('.dropdown-context').css({display:''}).find('.drop-left').removeClass('drop-left');
|
||||
$('.dropdown-context').fadeOut(options.fadeSpeed, function () {
|
||||
$('.dropdown-context').css({display: ''}).find('.drop-left').removeClass('drop-left');
|
||||
});
|
||||
});
|
||||
if(options.preventDoubleContext){
|
||||
if (options.preventDoubleContext) {
|
||||
$(document).on('contextmenu', '.dropdown-context', function (e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
$(document).on('mouseenter', '.dropdown-submenu', function(){
|
||||
$(document).on('mouseenter', '.dropdown-submenu', function () {
|
||||
let $sub = $(this).find('.dropdown-context-sub:first'),
|
||||
subWidth = $sub.width(),
|
||||
subLeft = $sub.offset().left,
|
||||
collision = (subWidth+subLeft) > window.innerWidth;
|
||||
if(collision){
|
||||
collision = (subWidth + subLeft) > window.innerWidth;
|
||||
if (collision) {
|
||||
$sub.addClass('drop-left');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function updateOptions(opts){
|
||||
function updateOptions(opts) {
|
||||
options = $.extend({}, options, opts);
|
||||
}
|
||||
|
||||
function buildMenu(data, id, subMenu) {
|
||||
let subClass = (subMenu) ? ' dropdown-context-sub' : '',
|
||||
compressed = options.compress ? ' compressed-context' : '',
|
||||
$menu = $('<ul class="dropdown-menu dropdown-context' + subClass + compressed+'" id="dropdown-' + id + '"></ul>');
|
||||
$menu = $('<ul class="dropdown-menu dropdown-context' + subClass + compressed + '" id="dropdown-' + id + '"></ul>');
|
||||
let i = 0, linkTarget = '';
|
||||
for(i; i<data.length; i++) {
|
||||
for (i; i < data.length; i++) {
|
||||
if (typeof data[i].divider !== 'undefined') {
|
||||
$menu.append('<li class="divider"></li>');
|
||||
} else if (typeof data[i].header !== 'undefined') {
|
||||
$menu.append('<li class="nav-header">' + data[i].header + '</li>');
|
||||
} else {
|
||||
if (typeof data[i].href == 'undefined') {
|
||||
data[i].href = '#';
|
||||
data[i].href = 'javascript:void(0)';
|
||||
}
|
||||
if (typeof data[i].target !== 'undefined') {
|
||||
linkTarget = ' target="'+data[i].target+'"';
|
||||
linkTarget = ' target="' + data[i].target + '"';
|
||||
}
|
||||
let $sub;
|
||||
if (typeof data[i].subMenu !== 'undefined') {
|
||||
$sub = ('<li class="dropdown-submenu"><a tabindex="-1" href="' + data[i].href + '">' + data[i].text + '</a></li>');
|
||||
$sub = $('<li class="dropdown-submenu"><a tabindex="-1" href="' + data[i].href + '">' + data[i].text + '</a></li>');
|
||||
} else {
|
||||
$sub = $('<li><a tabindex="-1" href="' + data[i].href + '"'+linkTarget+'>' + data[i].text + '</a></li>');
|
||||
$sub = $('<li><a tabindex="-1" href="' + data[i].href + '"' + linkTarget + '>' + data[i].text + '</a></li>');
|
||||
}
|
||||
let $a = $sub.find('a');
|
||||
if (typeof data[i].classes !== 'undefined') {
|
||||
for (const classKey in data[i].classes) {
|
||||
$a.addClass(data[i].classes[classKey]);
|
||||
}
|
||||
}
|
||||
if (typeof data[i].attributes !== 'undefined') {
|
||||
for (const attributesKey in data[i].attributes) {
|
||||
$a.attr(attributesKey, data[i].attributes[attributesKey]);
|
||||
}
|
||||
}
|
||||
if (typeof data[i].action !== 'undefined') {
|
||||
let actionID = 'event-' + new Date().getTime() * Math.floor(Math.random()*100000),
|
||||
let actionID = 'event-' + new Date().getTime() * Math.floor(Math.random() * 100000),
|
||||
eventAction = data[i].action;
|
||||
$sub.find('a').attr('id', actionID);
|
||||
$a.attr('id', actionID);
|
||||
$('#' + actionID).addClass('context-event');
|
||||
$(document).on('click', '#' + actionID, function () {
|
||||
eventAction.call(this, selection);
|
||||
@@ -93,7 +104,18 @@ window.context = window.context || (function () {
|
||||
return $menu;
|
||||
}
|
||||
|
||||
function addContext(selector, data) {
|
||||
/**
|
||||
* 添加菜单
|
||||
* @param selector 被右击元素
|
||||
* @param data 数据 {
|
||||
* text: String, // 文本
|
||||
* classes: Array, // class
|
||||
* attributes: Object, // 属性
|
||||
* action: Function, // 点击后的回调
|
||||
* }
|
||||
* @param open 右击元素后的回调
|
||||
*/
|
||||
function addContext(selector, data, open) {
|
||||
|
||||
let d = new Date(),
|
||||
id = d.getTime(),
|
||||
@@ -129,6 +151,8 @@ window.context = window.context || (function () {
|
||||
}).fadeIn(options.fadeSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
open && open.call($dd.get(0), this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
@push('scripts')
|
||||
<script src="{{ asset('js/blueimp-file-upload/jquery.ui.widget.js') }}"></script>
|
||||
<script src="{{ asset('js/blueimp-file-upload/jquery.iframe-transport.js') }}"></script>
|
||||
<script src="{{ asset('js/blueimp-file-upload/jquery.fileupload.js') }}"></script>
|
||||
<script src="{{ asset('js/blueimp-load-image/load-image.all.min.js') }}"></script>
|
||||
<script src="{{ asset('js/clipboard/clipboard.min.js') }}"></script>
|
||||
@endpush
|
||||
|
||||
<div class="pb-6 h-full">
|
||||
<input type="file" id="picker" name="file" class="hidden" accept="image/*" multiple>
|
||||
|
||||
@@ -66,7 +58,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
@push('scripts')
|
||||
<script src="{{ asset('js/blueimp-file-upload/jquery.ui.widget.js') }}"></script>
|
||||
<script src="{{ asset('js/blueimp-file-upload/jquery.iframe-transport.js') }}"></script>
|
||||
<script src="{{ asset('js/blueimp-file-upload/jquery.fileupload.js') }}"></script>
|
||||
<script src="{{ asset('js/blueimp-load-image/load-image.all.min.js') }}"></script>
|
||||
<script src="{{ asset('js/clipboard/clipboard.min.js') }}"></script>
|
||||
@endpush
|
||||
@push('scripts')
|
||||
<script>
|
||||
(new ClipboardJS('#copy-all', {
|
||||
@@ -88,7 +86,9 @@
|
||||
$(e.trigger).attr('disabled', false).text(text);
|
||||
}, 1000);
|
||||
}
|
||||
}).on('error', function(e) {});
|
||||
}).on('error', function(e) {
|
||||
toastr.warning('复制失败')
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
const UPLOAD_WAITING = 0; // 等待上传
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="photos-item-tpl">
|
||||
<a href="javascript:void(0)" class="photos-item relative cursor-default rounded outline outline-2 outline-offset-2 outline-transparent">
|
||||
<a href="javascript:void(0)" data-json='__json__' class="photos-item relative cursor-default rounded outline outline-2 outline-offset-2 outline-transparent">
|
||||
<div class="photo-selector absolute z-[2] top-0 right-0 overflow-hidden cursor-pointer sm:hidden group-hover:block">
|
||||
<div class="p-1 text-xl sm:text-2xl">
|
||||
<i class="fas fa-check-circle block rounded-full bg-white text-white border border-gray-500"></i>
|
||||
@@ -122,6 +122,7 @@
|
||||
<script src="{{ asset('js/dragselect/ds.min.js') }}"></script>
|
||||
<script src="{{ asset('js/context-js/context-js.js') }}"></script>
|
||||
<script src="{{ asset('js/clipboard/index.browser.js') }}"></script>
|
||||
<script src="{{ asset('js/clipboard/clipboard.min.js') }}"></script>
|
||||
<script>
|
||||
let gridConfigs = {
|
||||
rowHeight: 180,
|
||||
@@ -133,9 +134,10 @@
|
||||
|
||||
let selectedAlbum = 0; // 选择的相册
|
||||
|
||||
const PHOTOS_GRID = '#photos-grid';
|
||||
const PHOTOS_ITEM = '.photos-item';
|
||||
|
||||
const $photos = $("#photos-grid");
|
||||
const $photos = $(PHOTOS_GRID);
|
||||
const $drawer = $("#drawer");
|
||||
const $drawerMask = $('#drawer-mask');
|
||||
const viewer = new Viewer(document.getElementById('photos-grid'), {});
|
||||
@@ -184,6 +186,7 @@
|
||||
.replace(/__url__/g, images[i].url)
|
||||
.replace(/__width__/g, images[i].width)
|
||||
.replace(/__height__/g, images[i].height)
|
||||
.replace(/__json__/g, JSON.stringify(images[i]))
|
||||
}
|
||||
|
||||
$photos.append(html);
|
||||
@@ -365,6 +368,17 @@
|
||||
preventDoubleContext: true,
|
||||
compress: false
|
||||
});
|
||||
|
||||
new ClipboardJS('.dropdown-menu li a.copy', {
|
||||
text: function(trigger) {
|
||||
return $(trigger).data('copy-value');
|
||||
}
|
||||
}).on('success', _ => {
|
||||
toastr.success('复制成功');
|
||||
}).on('error', _ => {
|
||||
toastr.warning('复制失败')
|
||||
});
|
||||
|
||||
const methods = {
|
||||
copy: {
|
||||
text: '复制',
|
||||
@@ -377,7 +391,7 @@
|
||||
});
|
||||
},
|
||||
},
|
||||
refresh: {text: '刷新', action: e => imagesInfinite.refresh()},
|
||||
refresh: {text: '刷新', action: _ => imagesInfinite.refresh()},
|
||||
open: {
|
||||
text: '新窗口打开',
|
||||
action: e => {
|
||||
@@ -387,11 +401,36 @@
|
||||
links: {
|
||||
text: '复制链接',
|
||||
subMenu: [
|
||||
{text: 'Url', action: e => {}},
|
||||
{text: 'Html', action: e => {}},
|
||||
{text: 'BBCode', action: e => {}},
|
||||
{text: 'Markdown', action: e => {}},
|
||||
{text: 'Markdown with link', action: e => {}},
|
||||
{
|
||||
text: 'Url',
|
||||
classes: ['copy'],
|
||||
attributes: {"data-link-type": "url"},
|
||||
action: e => {},
|
||||
},
|
||||
{
|
||||
text: 'Html',
|
||||
classes: ['copy'],
|
||||
attributes: {"data-link-type": "html"},
|
||||
action: e => {},
|
||||
},
|
||||
{
|
||||
text: 'BBCode',
|
||||
classes: ['copy'],
|
||||
attributes: {"data-link-type": "bbcode"},
|
||||
action: e => {},
|
||||
},
|
||||
{
|
||||
text: 'Markdown',
|
||||
classes: ['copy'],
|
||||
attributes: {"data-link-type": "markdown"},
|
||||
action: e => {},
|
||||
},
|
||||
{
|
||||
text: 'Markdown with link',
|
||||
classes: ['copy'],
|
||||
attributes: {"data-link-type": "markdown_with_link"},
|
||||
action: e => {},
|
||||
},
|
||||
],
|
||||
},
|
||||
detail: {text: '详细信息', action: e => {}},
|
||||
@@ -399,7 +438,7 @@
|
||||
delete: {text: '删除', action: e => {}},
|
||||
};
|
||||
// 点击容器
|
||||
context.attach('#photos-grid', [
|
||||
context.attach(PHOTOS_GRID, [
|
||||
methods.refresh,
|
||||
]);
|
||||
// 点击图片
|
||||
@@ -412,7 +451,13 @@
|
||||
methods.rename,
|
||||
{divider: true},
|
||||
methods.delete,
|
||||
]);
|
||||
], function (e) {
|
||||
let data = $(e).closest(PHOTOS_ITEM).data('json');
|
||||
// 追加链接
|
||||
$(this).find('.copy').each(function () {
|
||||
$(this).data('copy-value', data.links[$(this).data('link-type')])
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
</x-app-layout>
|
||||
|
||||
Reference in New Issue
Block a user