smelukov on master
typo fix Merge pull request #58 from ago… (compare)
Что нравится:
Что вызывает вопросы:
const Field = require('app.ui.common.field').Field;
const Preloader = require('app.ui.common.preloader');
const DomEvent = require('basis.dom.event');
const FileUploader = require('basis.net.upload').FileUploader;
const Config = require('app.config');
const STATE = require('basis.data.state');
const arrayFrom = basis.array.from;
const ImageUploader = Field.subclass({
template: resource('./templates/imageUploader.tmpl'),
init: function() {
Field.prototype.init.call(this);
this.fileUploader = new FileUploader({
handler: {
start: () => this.setState(STATE.PROCESSING),
success: (self, request, response) => {
this.setState(STATE.READY);
this.setValue(response.data);
}
}
});
},
uploadUrl: '',
data: {
hovered: false,
uploading: false
},
binding: {
objectId: node => node.basisObjectId,
hovered: 'data:',
preloader: 'satellite:'
},
satellite: {
preloader: {
instance: Preloader,
events: 'stateChanged',
existsIf: (owner) => owner.state == STATE.PROCESSING
}
},
templateSync: function(){
Field.prototype.templateSync.call(this);
let dropZone = this.tmpl.dropZone;
let fileInput = this.tmpl.fileInput;
arrayFrom(['dragenter', 'dragover', 'dragleave', 'drop']).forEach((eventName) => {
DomEvent.addHandler(dropZone, eventName, this.preventDefaults, this)
});
arrayFrom(['dragenter', 'dragover']).forEach((eventName) => {
DomEvent.addHandler(dropZone, eventName, this.highlight, this)
});
arrayFrom(['dragleave', 'drop']).forEach((eventName) => {
DomEvent.addHandler(dropZone, eventName, this.unhighlight, this)
});
DomEvent.addHandler(dropZone, 'drop', this.dropHandler, this);
DomEvent.addHandler(fileInput, 'change', this.fileSelectionHandler, this);
},
highlight: function () {
this.update({ hovered: true })
},
unhighlight: function () {
this.update({ hovered: false })
},
preventDefaults: function(e) {
e.preventDefault();
e.stopPropagation();
},
dropHandler: function (e) {
let dataTransfer = e.dataTransfer;
let file = dataTransfer.files[0];
this.processFile(file);
},
fileSelectionHandler: function () {
let fileInput = this.tmpl.fileInput;
let file = fileInput.files[0];
this.processFile(file);
},
processFile: function (file) {
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
this.setValue(reader.result);
if(this.uploadUrl !== '')
this.fileUploader.uploadFiles(Config.API_HOST + this.uploadUrl, [file], 'file');
// else
// this.setValue(reader.result);
};
reader.onerror = (error) => {
console.log('Error: ', error);
};
},
action: {
removeIcon: function (e) {
e.preventDefault();
let fileInput = this.tmpl.fileInput;
fileInput.value = '';
this.setValue('');
}
}
});
module.exports = ImageUploader;
<b:style src="./imageUploader.css" />
<b:style src="/app/ui/common/icon/templates/icon.css" ns="icon"/>
<b:l10n src="/app/l10n/imageUploader.l10n"/>
<b:define name="hovered" type="bool"/>
<b:isolate/>
<b:include src="app.ui.common.field.Field">
<b:replace ref="fieldPlace">
<div class="imageUploader">
<form>
<input{fileInput} type="file" name="file" id="imageUploader_{objectId}" class="imageUploader__fileInput" accept="image/*"/>
<label class="imageUploader__label" for="imageUploader_{objectId}">
<div{dropZone} class="imageUploader__dropZone _{hovered}">
<img src="{value}" class="imageUploader__image" b:show="{value}"/>
<b:svg use="#icon-picons-photo" class="icon:svg imageUploader__icon" b:hide="{value}"/>
<!--{preloader}-->
</div>
<div class="imageUploader__hint" b:hide="{value}">{l10n:clickToUpload}</div>
<div class="imageUploader__hint" b:show="{value}" event-click="removeIcon">{l10n:clickToRemove}</div>
</label>
</form>
</div>
</b:replace>
</b:include>
@import "variables";
.imageUploader {
width: 108px;
cursor: pointer;
&__dropZone {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 108px;
height: 108px;
font-size: 45px;
background: $grey-ultra-light;
border: 2px dashed $grey-light;
border-radius: 10px;
overflow: hidden;
}
&__dropZone._hovered {
border: 2px solid $green-primary;
opacity: 0.5;
}
&__image {
max-width:100%;
max-height:100%;
pointer-events: none;
}
&__fileInput {
position: absolute;
top: 0;
left: -10000px;
opacity: 0;
}
&__icon {
stroke-width: 0.1;
color: $grey-light;
}
&__dropZone._hovered &__icon {
color: $green-primary;
}
&__label {
display: block;
cursor: pointer;
}
&__hint {
display: block;
padding-top: 5px;
line-height: 15px;
color: $blue-primary;
font-size: 12px;
text-align: center;
}
&__hint:hover {
text-decoration: underline;
}
}
@smelukov Прошу прощения за задержку в ответе, жизненные обстоятельства.
Попробую иначе сформулировать.
В базисе при конечной сборке (в продакшен) все js-файлы сборщиком пакуются в единый образ и после сборки динамически файлы подгрузить нельзя, о чём явно написано в документации:
Содержимое ресурсов считается частью программы (приложения), как если бы его содержимое был указано непосредственно в коде. По этой причине ресурсы загружаются синхронно, не могут быть внешними (по отношению к приложению) или быть динамическими (результатом выполнения серверного скрипта). После выполнения сборки содержимое ресурсов встраивается в основной код приложения и не загружаются отдельно. Особый случай – виртуальные ресурсы, которые не привязаны к конкретному файлу.
Но у меня есть потребность подгрузить ряд скриптов динамически уже после сборки. Эти скрипты могут расширять шаблоны и существующую логику.
Например в карточной игре worldoftanks general есть подобный функционал https://habr.com/company/wargaming/blog/271357/ и я хочу нечто похожее с базисом.
В документации к базису упоминаются некие виртуальные ресурсы, но как их использовать я не понял.
У меня была мысль подгружать скрипты минуя сам базис и там проникая через глобальную видимость уже патчить, но это как-то показалось некрасиво, поэтому решил спросить тут.
@sm0g Может есть кто живой. Сделал в своём проекте https://www.memoriz.app поддержку Markdown, для примера залил документацию по basis с githuba (раздел Программирование - Javascript ...), ...
Здорово :+1: