Files
lsky-pro/resources/views/images.blade.php
T
2021-12-25 01:38:58 +08:00

259 lines
13 KiB
PHP

@section('title', '我的图片')
@push('styles')
<link rel="stylesheet" href="{{ asset('css/justified-gallery/justifiedGallery.min.css') }}">
<link rel="stylesheet" href="{{ asset('css/viewer-js/viewer.min.css') }}">
@endpush
<x-app-layout>
<div class="relative flex justify-between items-center px-2 py-2 z-[3] top-0 left-0 right-0 bg-white border-solid border-b">
<div class="space-x-2 flex justify-between items-center">
<a class="text-sm py-2 px-3 hover:bg-gray-100 rounded text-gray-800" href="javascript:getAlbums()"><i class="fas fa-bars text-blue-500"></i> 相册</a>
<div class="block md:hidden">
<x-dropdown direction="right">
<x-slot name="trigger">
<a class="text-sm py-2 px-3 hover:bg-gray-100 rounded text-gray-800" href="javascript:void(0)"><i class="fas fa-ellipsis-h text-blue-500"></i></a>
</x-slot>
<x-slot name="content">
<x-dropdown-link href="{{ route('/') }}">移动到相册</x-dropdown-link>
<x-dropdown-link href="{{ route('/') }}">标记为不健康</x-dropdown-link>
<x-dropdown-link href="{{ route('/') }}" class="text-red-500">公开</x-dropdown-link>
<x-dropdown-link href="{{ route('/') }}" class="text-red-500">删除</x-dropdown-link>
</x-slot>
</x-dropdown>
</div>
</div>
<div class="flex space-x-2 items-center">
<input type="text" id="search" class="px-2.5 py-1.5 border-0 outline-none rounded bg-gray-100 text-sm transition-all duration-300 hidden md:block md:w-36 md:hover:w-52 md:focus:w-52" placeholder="输入关键字搜索...">
<x-dropdown direction="left">
<x-slot name="trigger">
<a id="order" class="text-sm py-2 px-3 hover:bg-gray-100 rounded text-gray-800" href="javascript:void(0)">
<span>最新</span>
<i class="fas fa-sort-alpha-up text-blue-500"></i>
</a>
</x-slot>
<x-slot name="content">
<x-dropdown-link href="javascript:void(0)" @click="setOrderBy('newest1'); open = false">最新
</x-dropdown-link>
<x-dropdown-link href="javascript:void(0)" @click="setOrderBy('earliest'); open = false">最早
</x-dropdown-link>
<x-dropdown-link href="javascript:void(0)" @click="setOrderBy('utmost'); open = false">最大
</x-dropdown-link>
<x-dropdown-link href="javascript:void(0)" @click="setOrderBy('least'); open = false">最小
</x-dropdown-link>
</x-slot>
</x-dropdown>
</div>
</div>
<div class="relative inset-0 h-full">
<!-- content -->
<div id="photos-scroll" class="absolute inset-0 overflow-y-scroll select-none">
<div id="photos-grid"></div>
</div>
<!-- right drawer -->
<div id="drawer-mask" class="absolute hidden inset-0 bg-gray-500 bg-opacity-50 z-[2]" onclick="drawer.close()"></div>
<div id="drawer" class="absolute bg-white w-52 md:w-72 top-0 -right-[1000px] bottom-0 z-[2] flex flex-col transition-all duration-300">
<div class="flex justify-between items-center text-md px-3 py-1 border-b">
<span class="text-gray-600 truncate" id="drawer-title"></span>
<a href="javascript:drawer.close()" class="p-2"><i class="fas fa-times text-blue-500"></i></a>
</div>
<div id="drawer-content" class="overflow-y-auto"></div>
</div>
</div>
<script type="text/html" id="photos-item">
<a href="javascript:void(0)" class="photos-item relative cursor-default rounded outline outline-2 outline-offset-2 outline-transparent">
<div class="photo-select absolute z-[1] top-1 right-1 rounded-full overflow-hidden text-white text-lg bg-white border border-gray-500 cursor-pointer hidden group-hover:block">
<i class="fas fa-check-circle block"></i>
</div>
<div class="photo-mask absolute left-0 right-0 bottom-0 h-20 z-[1] bg-gradient-to-t from-black">
<div class="absolute left-2 bottom-2 text-white z-[2] w-[90%]">
<p class="text-sm truncate" title="__name__">__name__</p>
<p class="text-xs" title="__human_date__">__date__</p>
</div>
</div>
<img alt="__name__" src="__url__" width="__width__" height="__height__">
</a>
</script>
<script type="text/html" id="albums-item">
<a href="javascript:void(0)" data-id="__id__" class="flex justify-between items-center px-2 py-1 rounded w-full bg-gray-100 text-gray-800 hover:bg-blue-300 hover:text-white">
<span class="text-sm truncate w-[80%]">__name__</span>
<span class="text-xs">__image_num__</span>
</a>
</script>
@push('scripts')
<script src="{{ asset('js/justified-gallery/jquery.justifiedGallery.min.js') }}"></script>
<script src="{{ asset('js/viewer-js/viewer.min.js') }}"></script>
<script src="{{ asset('js/dragselect/ds.min.js') }}"></script>
<script>
let gridConfigs = {
rowHeight: 180,
margins: 16,
captions: false,
border: 10,
waitThumbnailsLoad: false,
};
let selectedAlbum = 0; // 选择的相册
const $photos = $("#photos-grid");
const $drawer = $("#drawer");
const $drawerMask = $('#drawer-mask');
const viewer = new Viewer(document.getElementById('photos-grid'), {});
const drawer = {
open(title, $content, callback) {
$drawerMask.fadeIn();
$drawer.css('right', 0);
$drawer.find('#drawer-title').html(title);
$drawer.find('#drawer-content').html($content);
callback && callback();
},
close(callback) {
$drawerMask.fadeOut();
$drawer.css('right', '-1000px');
callback && callback();
},
toggle(title, $content, callback) {
if ($drawerMask.is(':hidden')) {
this.open(title, $content, callback);
} else {
this.close(callback);
}
}
}
$photos.justifiedGallery(gridConfigs);
const infinite = utils.infiniteScroll('#photos-scroll', {
url: '{{ route('user.images') }}',
success: function (response) {
if (!response.status) {
return toastr.error(response.message);
}
let images = response.data.images.data;
if (images.length <= 0 || response.data.images.current_page === response.data.images.last_page) {
this.finished = true;
}
let html = '';
for (const i in images) {
html += $('#photos-item').html()
.replace(/__name__/g, images[i].filename)
.replace(/__human_date__/g, images[i].human_date)
.replace(/__date__/g, images[i].date)
.replace(/__url__/g, images[i].url)
.replace(/__width__/g, images[i].width)
.replace(/__height__/g, images[i].height)
}
$photos.append(html);
ds.setSelectables($photos.find('.photos-item'));
},
complete: function () {
if ($photos.html() !== '') {
// 由于 justifiedGallery 创建后占高度(无论是否有内容或内容被清空),导致加载过程中在没有数据的情况下高度被拉开
// 所以需要在重置前销毁,重置数据后重新构建 justifiedGallery
if ($photos.hasClass('reset')) {
$photos.justifiedGallery(gridConfigs).removeClass('reset');
}
$photos.justifiedGallery('norewind')
viewer.update();
} else {
// 没有任何数据时销毁 justifiedGallery
$photos.justifiedGallery('destroy')
}
}
});
const resetImages = (params) => {
$photos.addClass('reset').html('').justifiedGallery('destroy');
infinite.refresh(params);
}
const getAlbums = () => {
drawer.toggle('我的相册', '<div id="albums-container" class="flex flex-col justify-center items-center w-full p-3 space-y-2"></div>', function () {
let $albums = $('#albums-container');
utils.infiniteScroll('#drawer-content', {
url: '{{ route('user.albums') }}',
success: function (response) {
if (!response.status) {
return toastr.error(response.message);
}
let albums = response.data.albums.data;
if (albums.length <= 0 || response.data.albums.current_page === response.data.albums.last_page) {
this.finished = true;
}
let html = '';
for (const i in albums) {
let item = $('#albums-item').html()
.replace(/__id__/g, albums[i].id)
.replace(/__name__/g, albums[i].name)
.replace(/__image_num__/g, albums[i].image_num)
if (albums[i].id === selectedAlbum) {
// 选中的相册高亮
item = item
.replace(/bg-gray-100/g, 'bg-blue-400')
.replace(/text-gray-800/g, 'text-white')
}
html += item;
}
$albums.append(html);
}
});
$albums.off('click', 'a').on('click', 'a', function () {
selectedAlbum = $(this).data('id');
resetImages({page: 1, album_id: selectedAlbum});
drawer.close();
});
});
}
const setOrderBy = function (sort) {
resetImages({page: 1, order: sort})
$('#order span').text({newest: '最新', earliest: '最早', utmost: '最大', least: '最小'}[sort]);
};
$('#search').keydown(function (e) {
if (e.keyCode === 13) {
resetImages({page: 1, keyword: $(this).val()});
}
});
</script>
<script>
const ds = new DragSelect({
area: document.getElementById('photos-grid'),
keyboardDrag: false,
// multiSelectMode: true,
// multiSelectToggling: false,
});
// 预期使用组件内部 api 实现单击选择图标进行选择/反选,但是 click 事件总在组件的 mousedown 事件后触发。
// 并且组件没有提供跳过某个元素选择的 api,只能通过组件选框,然后自定义 class 来判断选中项目。
// see https://github.com/ThibaultJanBeyer/DragSelect/issues/113#issuecomment-1000904432
// TODO 可能有更优的解决方案?
ds.subscribe('dragstart', ({ event }) => {
if ($(event.target).hasClass('justified-gallery')) {
$photos.find('a.photos-item').removeClass('selected');
}
});
ds.subscribe('dragmove', ({ items, event}) => {
$(items).addClass('selected');
});
$photos.on('click', '.photo-select', function (e) {
$(this).closest('a.photos-item').toggleClass('selected');
});
</script>
@endpush
</x-app-layout>