复制图片功能

This commit is contained in:
Wisp X
2021-12-30 15:09:55 +08:00
parent d609d5527c
commit 4897e6e6c8
5 changed files with 148 additions and 55 deletions

View File

@@ -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'));

View File

@@ -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);
});
}

View File

@@ -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);
});
}

View File

@@ -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; // 等待上传

View File

@@ -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>