2020-05-05 16:07:06 +02:00
|
|
|
|
<template>
|
2020-05-06 15:22:51 +02:00
|
|
|
|
<div class="ui-media" :class="'display-' + configuration.display">
|
2020-05-06 14:08:14 +02:00
|
|
|
|
<div v-if="items.length > 0" class="ui-media-previews">
|
2020-05-05 16:07:06 +02:00
|
|
|
|
<div v-for="item in items" class="ui-media-preview">
|
|
|
|
|
|
<div class="ui-media-preview-image">
|
|
|
|
|
|
<img v-if="item.source" :src="getPreview(item)" :alt="item.name" />
|
2020-05-06 14:08:14 +02:00
|
|
|
|
<button v-if="!disabled" type="button" class="ui-media-preview-image-delete" @click="remove(item)" v-localize:title="'@ui.remove'"><i class="fth-x"></i></button>
|
2020-05-06 15:22:51 +02:00
|
|
|
|
<button v-if="!disabled" type="button" class="ui-media-preview-image-edit" @click="edit(item)" v-localize:title="'@ui.edit'"><i class="fth-edit-2"></i></button>
|
2020-05-06 14:08:14 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="ui-media-preview-text">
|
|
|
|
|
|
<b :title="item.name">{{getFilename(item.name)}}</b>
|
2020-05-06 15:22:51 +02:00
|
|
|
|
<span class="is-filesize">{{getFileinfo(item)}}</span>
|
2020-05-05 16:07:06 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="ui-media-add" v-if="canAdd">
|
|
|
|
|
|
<ui-select-button v-if="!configuration.disallowSelect" icon="fth-folder" label="@mediapicker.select_text" description="@mediapicker.select_description" :disabled="disabled" />
|
|
|
|
|
|
<div v-if="!configuration.disallowUpload" class="ui-media-add-upload">
|
|
|
|
|
|
<input type="file" :accept="acceptedFileExtensions" :multiple="multiple" @change="onUpload" />
|
|
|
|
|
|
<ui-select-button icon="fth-upload" label="@mediapicker.upload_text" :description="uploadDescription" :disabled="true" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
import { each as _each, extend as _extend, debounce as _debounce, isArray as _isArray } from 'underscore';
|
2020-11-20 10:32:17 +01:00
|
|
|
|
import Strings from 'zero/helpers/strings.js';
|
|
|
|
|
|
import Overlay from 'zero/helpers/overlay.js';
|
2020-11-01 22:20:29 +01:00
|
|
|
|
import MediaOverlay from 'zero/pages/media/media-item.vue';
|
2020-05-05 16:07:06 +02:00
|
|
|
|
|
|
|
|
|
|
const TYPES = {
|
|
|
|
|
|
ALL: 'all',
|
|
|
|
|
|
IMAGE: 'image',
|
|
|
|
|
|
VIDEO: 'video',
|
|
|
|
|
|
DOCUMENT: 'document',
|
|
|
|
|
|
OTHER: 'other'
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const DISPLAY = {
|
|
|
|
|
|
DEFAULT: 'default',
|
|
|
|
|
|
BIG: 'big',
|
|
|
|
|
|
GRID: 'grid'
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2020-05-06 14:08:14 +02:00
|
|
|
|
const MAX_FILENAME_LENGTH = 32;
|
|
|
|
|
|
|
2020-05-05 16:07:06 +02:00
|
|
|
|
const defaultConfig = {
|
|
|
|
|
|
// maximum media items
|
|
|
|
|
|
limit: 1,
|
|
|
|
|
|
// media type
|
|
|
|
|
|
type: TYPES.ALL,
|
|
|
|
|
|
// how the previews are displayed
|
|
|
|
|
|
display: DISPLAY.DEFAULT,
|
|
|
|
|
|
// whether the select button is disallowed
|
|
|
|
|
|
disallowSelect: false,
|
|
|
|
|
|
// whether file upload is disallowed
|
|
|
|
|
|
disallowUpload: false,
|
|
|
|
|
|
// allowed file extensions
|
|
|
|
|
|
fileExtensions: [],
|
|
|
|
|
|
// maximum file size in MiB
|
|
|
|
|
|
maxFileSize: 10
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
2020-05-14 16:05:33 +02:00
|
|
|
|
name: 'uiMediaOld',
|
2020-05-05 16:07:06 +02:00
|
|
|
|
|
|
|
|
|
|
props: {
|
|
|
|
|
|
disabled: {
|
|
|
|
|
|
type: Boolean,
|
|
|
|
|
|
default: false
|
|
|
|
|
|
},
|
|
|
|
|
|
config: {
|
|
|
|
|
|
type: Object,
|
|
|
|
|
|
default: () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
return defaultConfig;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
value: {
|
|
|
|
|
|
type: [Array, Object]
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
data: () => ({
|
|
|
|
|
|
configuration: {},
|
|
|
|
|
|
items: []
|
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
|
|
|
|
watch: {
|
|
|
|
|
|
config: {
|
|
|
|
|
|
deep: true,
|
|
|
|
|
|
handler: function ()
|
|
|
|
|
|
{
|
|
|
|
|
|
this.initialize();
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
value: {
|
|
|
|
|
|
deep: true,
|
|
|
|
|
|
handler: function ()
|
|
|
|
|
|
{
|
|
|
|
|
|
this.initialize();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
computed: {
|
|
|
|
|
|
multiple()
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.configuration.limit > 1;
|
|
|
|
|
|
},
|
|
|
|
|
|
canAdd()
|
|
|
|
|
|
{
|
2020-05-06 15:27:47 +02:00
|
|
|
|
return !this.disabled && this.configuration.limit - this.items.length > 0;
|
2020-05-05 16:07:06 +02:00
|
|
|
|
},
|
|
|
|
|
|
uploadDescription()
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.configuration.fileExtensions.length > 0 ? this.displayedFileExtensions : '@mediapicker.upload_description';
|
|
|
|
|
|
},
|
|
|
|
|
|
acceptedFileExtensions()
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.configuration.fileExtensions.join(',');
|
|
|
|
|
|
},
|
|
|
|
|
|
displayedFileExtensions()
|
|
|
|
|
|
{
|
|
|
|
|
|
return this.configuration.fileExtensions.join(', ').replace(/\./g, '');
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
created()
|
|
|
|
|
|
{
|
|
|
|
|
|
this.initialize();
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
|
|
|
|
|
|
initialize()
|
|
|
|
|
|
{
|
|
|
|
|
|
this.configuration = _extend(defaultConfig, this.config);
|
|
|
|
|
|
|
|
|
|
|
|
if (_isArray(this.value))
|
|
|
|
|
|
{
|
|
|
|
|
|
this.items = this.value;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (!!this.value && typeof this.value === 'object' && this.value.source)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.items = [this.value];
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
onUpload(event)
|
|
|
|
|
|
{
|
|
|
|
|
|
let remaining = this.configuration.limit - this.items.length;
|
|
|
|
|
|
const files = event.target.files;
|
|
|
|
|
|
|
|
|
|
|
|
if (files && files.length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (var i = 0; i < files.length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (i >= remaining)
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.addFile(files[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.update();
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addFromLibrary(item)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.items.push(item);
|
|
|
|
|
|
this.update();
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addFile(file)
|
|
|
|
|
|
{
|
|
|
|
|
|
var source = URL.createObjectURL(file);
|
|
|
|
|
|
var media = {
|
|
|
|
|
|
id: 'upload:' + Strings.guid(),
|
|
|
|
|
|
name: file.name,
|
|
|
|
|
|
source: source,
|
|
|
|
|
|
size: file.size,
|
|
|
|
|
|
mimeType: file.type
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
this.items.push(media);
|
|
|
|
|
|
|
|
|
|
|
|
var reader = new FileReader();
|
|
|
|
|
|
reader.onload = function (e)
|
|
|
|
|
|
{
|
|
|
|
|
|
media.source = e.target.result;
|
|
|
|
|
|
};
|
|
|
|
|
|
reader.readAsDataURL(file);
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-06 14:08:14 +02:00
|
|
|
|
remove(item)
|
|
|
|
|
|
{
|
|
|
|
|
|
const index = this.items.indexOf(item);
|
|
|
|
|
|
this.items.splice(item, 1);
|
|
|
|
|
|
this.update();
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-05 16:07:06 +02:00
|
|
|
|
update()
|
|
|
|
|
|
{
|
|
|
|
|
|
this.$emit('input', this.multiple ? this.items : this.items[0]);
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-06 15:22:51 +02:00
|
|
|
|
edit(item)
|
|
|
|
|
|
{
|
|
|
|
|
|
let model = JSON.parse(JSON.stringify(item));
|
|
|
|
|
|
|
|
|
|
|
|
let options = {
|
|
|
|
|
|
title: '@iconpicker.title',
|
|
|
|
|
|
closeLabel: '@ui.close',
|
|
|
|
|
|
component: MediaOverlay,
|
|
|
|
|
|
model: model,
|
2020-05-06 15:27:47 +02:00
|
|
|
|
theme: 'dark',
|
|
|
|
|
|
disabled: this.disabled
|
2020-05-06 15:22:51 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return Overlay.open(options).then(value =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (value.deletionRequested)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.remove(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
item.alternativeText = value.alternativeText;
|
|
|
|
|
|
item.caption = value.caption;
|
|
|
|
|
|
item.focalPoint = value.focalPoint;
|
|
|
|
|
|
}
|
|
|
|
|
|
}, () => { });
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-05 16:07:06 +02:00
|
|
|
|
getPreview(item)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!item.id || item.id.indexOf('upload:') > -1 || item.source.indexOf("http") === 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return item.source;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (item.id.indexOf("native:") > -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
return item.source + "?width=100&height=100";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-06 14:08:14 +02:00
|
|
|
|
if (!item.hasThumbnail)
|
2020-05-05 16:07:06 +02:00
|
|
|
|
{
|
|
|
|
|
|
return item.source;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var extension = '.' + item.source.split('.').pop();
|
|
|
|
|
|
return item.source.replace(extension, ".thumb" + extension);
|
2020-05-06 14:08:14 +02:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getFilename(name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (name.length < MAX_FILENAME_LENGTH)
|
|
|
|
|
|
{
|
|
|
|
|
|
return name;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const parts = name.split('.');
|
|
|
|
|
|
const extension = parts.pop();
|
|
|
|
|
|
|
|
|
|
|
|
return parts.join('.').substring(0, MAX_FILENAME_LENGTH - 6) + '...' + extension;
|
2020-05-06 15:22:51 +02:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getFileinfo(item)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (item.dimension)
|
|
|
|
|
|
{
|
|
|
|
|
|
return `${Strings.filesize(item.size)} – ${item.dimension.width} × ${item.dimension.height}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return Strings.filesize(item.size);
|
2020-05-05 16:07:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
|
|
|
|
.ui-media
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ui-media-add
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ui-media-add-upload
|
|
|
|
|
|
{
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
|
|
|
|
.ui-select-button + &
|
|
|
|
|
|
{
|
|
|
|
|
|
margin-left: var(--padding);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
input[type="file"]
|
|
|
|
|
|
{
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
right: 0;
|
|
|
|
|
|
bottom: 0;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
opacity: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-06 15:22:51 +02:00
|
|
|
|
.ui-media-previews
|
|
|
|
|
|
{
|
|
|
|
|
|
.display-grid &
|
|
|
|
|
|
{
|
|
|
|
|
|
display: flex;
|
2020-08-31 11:48:05 +02:00
|
|
|
|
gap: 10px;
|
2020-05-06 15:22:51 +02:00
|
|
|
|
|
|
|
|
|
|
.ui-media-preview + .ui-media-preview
|
|
|
|
|
|
{
|
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-06 14:08:14 +02:00
|
|
|
|
.ui-media-previews + .ui-media-add,
|
|
|
|
|
|
.ui-media-preview + .ui-media-preview
|
|
|
|
|
|
{
|
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-06 15:22:51 +02:00
|
|
|
|
.ui-media:not(.display-grid) .ui-media-previews + .ui-media-add
|
2020-05-06 14:08:14 +02:00
|
|
|
|
{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
|
|
|
|
.ui-select-button + .ui-media-add-upload
|
|
|
|
|
|
{
|
|
|
|
|
|
margin-left: 0;
|
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-05 16:07:06 +02:00
|
|
|
|
.ui-media-preview
|
|
|
|
|
|
{
|
2020-05-06 14:08:14 +02:00
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
2020-05-05 16:07:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ui-media-preview-image
|
|
|
|
|
|
{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
align-items: center;
|
2020-05-06 14:08:14 +02:00
|
|
|
|
width: 50px;
|
|
|
|
|
|
height: 50px;
|
2020-05-05 16:07:06 +02:00
|
|
|
|
/*background: var(--color-bg);*/
|
|
|
|
|
|
border: 1px solid var(--color-line-light);
|
2020-05-06 14:08:14 +02:00
|
|
|
|
padding: 3px;
|
2020-05-05 16:07:06 +02:00
|
|
|
|
border-radius: var(--radius);
|
2020-09-07 14:55:05 +02:00
|
|
|
|
color: var(--color-text);
|
2020-05-05 16:07:06 +02:00
|
|
|
|
position: relative;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
|
|
|
|
img
|
|
|
|
|
|
{
|
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
|
max-height: 100%;
|
|
|
|
|
|
margin: auto;
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
color: transprent;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
font-size: 0;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
z-index: 2;
|
|
|
|
|
|
}
|
2020-05-06 14:08:14 +02:00
|
|
|
|
|
2020-05-06 15:22:51 +02:00
|
|
|
|
&:hover .ui-media-preview-image-delete,
|
|
|
|
|
|
&:hover .ui-media-preview-image-edit
|
2020-05-06 14:08:14 +02:00
|
|
|
|
{
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
transition-delay: 0.1s;
|
|
|
|
|
|
}
|
2020-05-06 15:22:51 +02:00
|
|
|
|
|
|
|
|
|
|
.display-big &, .display-grid &
|
|
|
|
|
|
{
|
|
|
|
|
|
width: 100px;
|
|
|
|
|
|
height: 100px;
|
|
|
|
|
|
}
|
2020-05-06 14:08:14 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ui-media-preview-text
|
|
|
|
|
|
{
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
margin-left: 16px;
|
|
|
|
|
|
font-size: var(--font-size);
|
|
|
|
|
|
|
|
|
|
|
|
.is-filesize
|
|
|
|
|
|
{
|
2020-09-07 14:55:05 +02:00
|
|
|
|
color: var(--color-text-dim);
|
2020-05-06 14:08:14 +02:00
|
|
|
|
margin-top: 3px;
|
|
|
|
|
|
font-size: var(--font-size-xs);
|
|
|
|
|
|
}
|
2020-05-06 15:22:51 +02:00
|
|
|
|
|
|
|
|
|
|
.display-grid &
|
|
|
|
|
|
{
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
}
|
2020-05-06 14:08:14 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-06 15:22:51 +02:00
|
|
|
|
.ui-media-preview-image-delete,
|
|
|
|
|
|
.ui-media-preview-image-edit
|
2020-05-06 14:08:14 +02:00
|
|
|
|
{
|
|
|
|
|
|
opacity: 0;
|
|
|
|
|
|
transition: opacity 0.15s ease;
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
right: 3px;
|
|
|
|
|
|
bottom: 3px;
|
|
|
|
|
|
width: 24px;
|
|
|
|
|
|
height: 24px;
|
|
|
|
|
|
line-height: 26px;
|
|
|
|
|
|
border-radius: 20px;
|
|
|
|
|
|
background: var(--color-negative);
|
2020-09-07 14:55:05 +02:00
|
|
|
|
color: var(--color-primary-text);
|
2020-05-06 14:08:14 +02:00
|
|
|
|
z-index: 2;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
font-size: 13px;
|
2020-05-06 15:22:51 +02:00
|
|
|
|
|
|
|
|
|
|
.ui-media.display-default &
|
|
|
|
|
|
{
|
|
|
|
|
|
width: 20px;
|
|
|
|
|
|
height: 20px;
|
|
|
|
|
|
line-height: 22px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ui-media-preview-image-edit
|
|
|
|
|
|
{
|
|
|
|
|
|
right: 30px;
|
|
|
|
|
|
background: var(--color-bg);
|
2020-09-07 14:55:05 +02:00
|
|
|
|
color: var(--color-text);
|
2020-05-06 15:22:51 +02:00
|
|
|
|
|
|
|
|
|
|
.ui-media.display-default &
|
|
|
|
|
|
{
|
|
|
|
|
|
right: 24px;
|
|
|
|
|
|
}
|
2020-05-05 16:07:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
</style>
|