client/posts: implement upload form
This commit is contained in:
parent
b7e9cbd541
commit
5bcf44aa2d
|
@ -0,0 +1,45 @@
|
||||||
|
@import colors
|
||||||
|
|
||||||
|
.post-upload
|
||||||
|
form
|
||||||
|
width: 100%
|
||||||
|
max-width: 40em
|
||||||
|
margin: 0 auto
|
||||||
|
|
||||||
|
&.inactive
|
||||||
|
input[type=submit]
|
||||||
|
display: none
|
||||||
|
|
||||||
|
.dropper-container
|
||||||
|
margin: 0 auto
|
||||||
|
.file-dropper
|
||||||
|
font-size: 150%
|
||||||
|
padding: 2em
|
||||||
|
|
||||||
|
input[type=submit]
|
||||||
|
float: left
|
||||||
|
|
||||||
|
.uploadables-container
|
||||||
|
margin: 2em 0
|
||||||
|
text-align: left
|
||||||
|
line-height: 200%
|
||||||
|
|
||||||
|
.uploadable
|
||||||
|
.file
|
||||||
|
overflow: hidden
|
||||||
|
text-align: left
|
||||||
|
text-overflow: ellipsis
|
||||||
|
|
||||||
|
.safety
|
||||||
|
label
|
||||||
|
margin-right: 1em
|
||||||
|
|
||||||
|
.thumbnail
|
||||||
|
float: left
|
||||||
|
width: 12.5em
|
||||||
|
height: 7em
|
||||||
|
margin: 0 1em 0 0
|
||||||
|
|
||||||
|
.remove
|
||||||
|
float: right
|
||||||
|
color: $inactive-link-color
|
|
@ -0,0 +1,11 @@
|
||||||
|
<div class='post-upload'>
|
||||||
|
<form>
|
||||||
|
<div class='dropper-container'></div>
|
||||||
|
|
||||||
|
<ul class='uploadables-container'></ul>
|
||||||
|
|
||||||
|
<div class='messages'></div>
|
||||||
|
|
||||||
|
<input type='submit' value='Upload all' class='submit'/>
|
||||||
|
</form>
|
||||||
|
</div>
|
|
@ -0,0 +1,40 @@
|
||||||
|
<li class='uploadable'>
|
||||||
|
<a class='remove'>
|
||||||
|
<i class='fa fa-remove'></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class='thumbnail'>
|
||||||
|
<% if (['image'].includes(ctx.uploadable.type)) { %>
|
||||||
|
|
||||||
|
<%= ctx.makeThumbnail(ctx.uploadable.imageUrl) %>
|
||||||
|
|
||||||
|
<% } else { %>
|
||||||
|
|
||||||
|
<%= ctx.makeThumbnail(null) %>
|
||||||
|
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='file'>
|
||||||
|
<strong><%= ctx.uploadable.name %></strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='safety'>
|
||||||
|
<% for (let safety of ['safe', 'sketchy', 'unsafe']) { %>
|
||||||
|
<%= ctx.makeRadio({
|
||||||
|
name: 'safety-' + ctx.uploadable.key,
|
||||||
|
value: safety,
|
||||||
|
text: safety[0].toUpperCase() + safety.substr(1),
|
||||||
|
selectedValue: ctx.uploadable.safety,
|
||||||
|
}) %>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='anonymous'>
|
||||||
|
<%= ctx.makeCheckbox({
|
||||||
|
text: 'Upload anonymously',
|
||||||
|
name: 'anonymous',
|
||||||
|
checked: ctx.uploadable.anonymous,
|
||||||
|
}) %>
|
||||||
|
</div>
|
||||||
|
</li>
|
|
@ -148,10 +148,10 @@ class PostController {
|
||||||
post.relations = e.detail.relations;
|
post.relations = e.detail.relations;
|
||||||
}
|
}
|
||||||
if (e.detail.content !== undefined) {
|
if (e.detail.content !== undefined) {
|
||||||
post.content = e.detail.content;
|
post.newContent = e.detail.content;
|
||||||
}
|
}
|
||||||
if (e.detail.thumbnail !== undefined) {
|
if (e.detail.thumbnail !== undefined) {
|
||||||
post.thumbnail = e.detail.thumbnail;
|
post.newThumbnail = e.detail.thumbnail;
|
||||||
}
|
}
|
||||||
post.save()
|
post.save()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
|
@ -1,13 +1,59 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const router = require('../router.js');
|
||||||
|
const misc = require('../util/misc.js');
|
||||||
const topNavigation = require('../models/top_navigation.js');
|
const topNavigation = require('../models/top_navigation.js');
|
||||||
const EmptyView = require('../views/empty_view.js');
|
const Post = require('../models/post.js');
|
||||||
|
const PostUploadView = require('../views/post_upload_view.js');
|
||||||
|
|
||||||
class PostUploadController {
|
class PostUploadController {
|
||||||
constructor() {
|
constructor() {
|
||||||
topNavigation.activate('upload');
|
topNavigation.activate('upload');
|
||||||
topNavigation.setTitle('Upload');
|
topNavigation.setTitle('Upload');
|
||||||
this._emptyView = new EmptyView();
|
this._view = new PostUploadView();
|
||||||
|
this._view.addEventListener('change', e => this._evtChange(e));
|
||||||
|
this._view.addEventListener('submit', e => this._evtSubmit(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
_evtChange(e) {
|
||||||
|
if (e.detail.uploadables.length) {
|
||||||
|
misc.enableExitConfirmation();
|
||||||
|
} else {
|
||||||
|
misc.disableExitConfirmation();
|
||||||
|
}
|
||||||
|
this._view.clearMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
_evtSubmit(e) {
|
||||||
|
this._view.disableForm();
|
||||||
|
this._view.clearMessages();
|
||||||
|
|
||||||
|
e.detail.uploadables.reduce((promise, uploadable) => {
|
||||||
|
return promise.then(
|
||||||
|
() => {
|
||||||
|
let post = new Post();
|
||||||
|
post.safety = uploadable.safety;
|
||||||
|
if (uploadable.url) {
|
||||||
|
post.newContentUrl = uploadable.url;
|
||||||
|
} else {
|
||||||
|
post.newContent = uploadable.file;
|
||||||
|
}
|
||||||
|
return post.save(uploadable.anonymous)
|
||||||
|
.then(() => {
|
||||||
|
this._view.removeUploadable(uploadable);
|
||||||
|
return Promise.resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, Promise.resolve()).then(
|
||||||
|
() => {
|
||||||
|
misc.disableExitConfirmation();
|
||||||
|
const ctx = router.show('/posts');
|
||||||
|
ctx.controller.showSuccess('Posts uploaded.');
|
||||||
|
}, errorMessage => {
|
||||||
|
this._view.showError(errorMessage);
|
||||||
|
this._view.enableForm();
|
||||||
|
return Promise.reject();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,39 +14,41 @@ class Post extends events.EventTarget {
|
||||||
this._updateFromResponse({});
|
this._updateFromResponse({});
|
||||||
}
|
}
|
||||||
|
|
||||||
get id() { return this._id; }
|
get id() { return this._id; }
|
||||||
get type() { return this._type; }
|
get type() { return this._type; }
|
||||||
get mimeType() { return this._mimeType; }
|
get mimeType() { return this._mimeType; }
|
||||||
get creationTime() { return this._creationTime; }
|
get creationTime() { return this._creationTime; }
|
||||||
get user() { return this._user; }
|
get user() { return this._user; }
|
||||||
get safety() { return this._safety; }
|
get safety() { return this._safety; }
|
||||||
get contentUrl() { return this._contentUrl; }
|
get contentUrl() { return this._contentUrl; }
|
||||||
get thumbnailUrl() { return this._thumbnailUrl; }
|
get thumbnailUrl() { return this._thumbnailUrl; }
|
||||||
get canvasWidth() { return this._canvasWidth || 800; }
|
get canvasWidth() { return this._canvasWidth || 800; }
|
||||||
get canvasHeight() { return this._canvasHeight || 450; }
|
get canvasHeight() { return this._canvasHeight || 450; }
|
||||||
get fileSize() { return this._fileSize || 0; }
|
get fileSize() { return this._fileSize || 0; }
|
||||||
get content() { throw 'Invalid operation'; }
|
get newContent() { throw 'Invalid operation'; }
|
||||||
get thumbnail() { throw 'Invalid operation'; }
|
get newContentUrl() { throw 'Invalid operation'; }
|
||||||
|
get newThumbnail() { throw 'Invalid operation'; }
|
||||||
|
|
||||||
get flags() { return this._flags; }
|
get flags() { return this._flags; }
|
||||||
get tags() { return this._tags; }
|
get tags() { return this._tags; }
|
||||||
get notes() { return this._notes; }
|
get notes() { return this._notes; }
|
||||||
get comments() { return this._comments; }
|
get comments() { return this._comments; }
|
||||||
get relations() { return this._relations; }
|
get relations() { return this._relations; }
|
||||||
|
|
||||||
get score() { return this._score; }
|
get score() { return this._score; }
|
||||||
get commentCount() { return this._commentCount; }
|
get commentCount() { return this._commentCount; }
|
||||||
get favoriteCount() { return this._favoriteCount; }
|
get favoriteCount() { return this._favoriteCount; }
|
||||||
get ownFavorite() { return this._ownFavorite; }
|
get ownFavorite() { return this._ownFavorite; }
|
||||||
get ownScore() { return this._ownScore; }
|
get ownScore() { return this._ownScore; }
|
||||||
get hasCustomThumbnail() { return this._hasCustomThumbnail; }
|
get hasCustomThumbnail() { return this._hasCustomThumbnail; }
|
||||||
|
|
||||||
set flags(value) { this._flags = value; }
|
set flags(value) { this._flags = value; }
|
||||||
set tags(value) { this._tags = value; }
|
set tags(value) { this._tags = value; }
|
||||||
set safety(value) { this._safety = value; }
|
set safety(value) { this._safety = value; }
|
||||||
set relations(value) { this._relations = value; }
|
set relations(value) { this._relations = value; }
|
||||||
set content(value) { this._content = value; }
|
set newContent(value) { this._newContent = value; }
|
||||||
set thumbnail(value) { this._thumbnail = value; }
|
set newContentUrl(value) { this._newContentUrl = value; }
|
||||||
|
set newThumbnail(value) { this._newThumbnail = value; }
|
||||||
|
|
||||||
static fromResponse(response) {
|
static fromResponse(response) {
|
||||||
const ret = new Post();
|
const ret = new Post();
|
||||||
|
@ -84,11 +86,14 @@ class Post extends events.EventTarget {
|
||||||
s => s.toLowerCase() != tagName.toLowerCase());
|
s => s.toLowerCase() != tagName.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
save() {
|
save(anonymous) {
|
||||||
const files = [];
|
const files = [];
|
||||||
const detail = {version: this._version};
|
const detail = {version: this._version};
|
||||||
|
|
||||||
// send only changed fields to avoid user privilege violation
|
// send only changed fields to avoid user privilege violation
|
||||||
|
if (anonymous === true) {
|
||||||
|
detail.anonymous = true;
|
||||||
|
}
|
||||||
if (this._safety !== this._orig._safety) {
|
if (this._safety !== this._orig._safety) {
|
||||||
detail.safety = this._safety;
|
detail.safety = this._safety;
|
||||||
}
|
}
|
||||||
|
@ -108,11 +113,13 @@ class Post extends events.EventTarget {
|
||||||
text: note.text,
|
text: note.text,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
if (this._content) {
|
if (this._newContent) {
|
||||||
files.content = this._content;
|
files.content = this._newContent;
|
||||||
|
} else if (this._newContentUrl) {
|
||||||
|
detail.contentUrl = this._newContentUrl;
|
||||||
}
|
}
|
||||||
if (this._thumbnail !== undefined) {
|
if (this._newThumbnail !== undefined) {
|
||||||
files.thumbnail = this._thumbnail;
|
files.thumbnail = this._newThumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
let promise = this._id ?
|
let promise = this._id ?
|
||||||
|
@ -123,11 +130,11 @@ class Post extends events.EventTarget {
|
||||||
this._updateFromResponse(response);
|
this._updateFromResponse(response);
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new CustomEvent('change', {detail: {post: this}}));
|
new CustomEvent('change', {detail: {post: this}}));
|
||||||
if (this._content) {
|
if (this._newContent || this._newContentUrl) {
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new CustomEvent('changeContent', {detail: {post: this}}));
|
new CustomEvent('changeContent', {detail: {post: this}}));
|
||||||
}
|
}
|
||||||
if (this._thumbnail) {
|
if (this._newThumbnail) {
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new CustomEvent('changeThumbnail', {detail: {post: this}}));
|
new CustomEvent('changeThumbnail', {detail: {post: this}}));
|
||||||
}
|
}
|
||||||
|
@ -254,7 +261,8 @@ class Post extends events.EventTarget {
|
||||||
_flags: [...response.flags || []],
|
_flags: [...response.flags || []],
|
||||||
_tags: [...response.tags || []],
|
_tags: [...response.tags || []],
|
||||||
_notes: NoteList.fromResponse([...response.notes || []]),
|
_notes: NoteList.fromResponse([...response.notes || []]),
|
||||||
_comments: CommentList.fromResponse([...response.comments || []]),
|
_comments: CommentList.fromResponse(
|
||||||
|
[...response.comments || []]),
|
||||||
_relations: [...response.relations || []],
|
_relations: [...response.relations || []],
|
||||||
|
|
||||||
_score: response.score,
|
_score: response.score,
|
||||||
|
|
|
@ -487,6 +487,8 @@ module.exports = misc.arrayToObject([
|
||||||
makeNonVoidElement,
|
makeNonVoidElement,
|
||||||
makeTagLink,
|
makeTagLink,
|
||||||
makePostLink,
|
makePostLink,
|
||||||
|
makeCheckbox,
|
||||||
|
makeRadio,
|
||||||
syncScrollPosition,
|
syncScrollPosition,
|
||||||
slideDown,
|
slideDown,
|
||||||
slideUp,
|
slideUp,
|
||||||
|
|
|
@ -0,0 +1,266 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const events = require('../events.js');
|
||||||
|
const views = require('../util/views.js');
|
||||||
|
const FileDropperControl = require('../controls/file_dropper_control.js');
|
||||||
|
|
||||||
|
const template = views.getTemplate('post-upload');
|
||||||
|
const rowTemplate = views.getTemplate('post-upload-row');
|
||||||
|
|
||||||
|
let globalOrder = 0;
|
||||||
|
|
||||||
|
class Uploadable extends events.EventTarget {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.safety = 'safe';
|
||||||
|
this.anonymous = false;
|
||||||
|
this.order = globalOrder;
|
||||||
|
globalOrder++;
|
||||||
|
}
|
||||||
|
|
||||||
|
get type() {
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
|
get key() {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class File extends Uploadable {
|
||||||
|
constructor(file) {
|
||||||
|
super();
|
||||||
|
this.file = file;
|
||||||
|
|
||||||
|
this._imageUrl = null;
|
||||||
|
let reader = new FileReader();
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
reader.addEventListener('load', e => {
|
||||||
|
this._imageUrl = e.target.result;
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent('finish', {detail: {uploadable: this}}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get type() {
|
||||||
|
return {
|
||||||
|
'application/x-shockwave-flash': 'flash',
|
||||||
|
'image/gif': 'image',
|
||||||
|
'image/jpeg': 'image',
|
||||||
|
'image/png': 'image',
|
||||||
|
'video/mp4': 'video',
|
||||||
|
'video/webm': 'video',
|
||||||
|
}[this.file.type] || 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
|
get imageUrl() {
|
||||||
|
return this._imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
get key() {
|
||||||
|
return this.file.name + this.file.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return this.file.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Url extends Uploadable {
|
||||||
|
constructor(url) {
|
||||||
|
super();
|
||||||
|
this.url = url;
|
||||||
|
this.dispatchEvent(new CustomEvent('finish'));
|
||||||
|
}
|
||||||
|
|
||||||
|
get type() {
|
||||||
|
let extensions = {
|
||||||
|
'swf': 'flash',
|
||||||
|
'jpg': 'image',
|
||||||
|
'png': 'image',
|
||||||
|
'gif': 'image',
|
||||||
|
'mp4': 'video',
|
||||||
|
'webm': 'video',
|
||||||
|
};
|
||||||
|
for (let extension of Object.keys(extensions)) {
|
||||||
|
if (this.url.toLowerCase().indexOf('.' + extension) !== -1) {
|
||||||
|
return extensions[extension];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
|
get imageUrl() {
|
||||||
|
return this.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
get key() {
|
||||||
|
return this.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return this.url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PostUploadView extends events.EventTarget {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this._hostNode = document.getElementById('content-holder');
|
||||||
|
views.replaceContent(this._hostNode, template());
|
||||||
|
views.syncScrollPosition();
|
||||||
|
|
||||||
|
this._uploadables = new Map();
|
||||||
|
this._contentFileDropper = new FileDropperControl(
|
||||||
|
this._contentInputNode,
|
||||||
|
{
|
||||||
|
allowUrls: true,
|
||||||
|
allowMultiple: true,
|
||||||
|
lock: false,
|
||||||
|
});
|
||||||
|
this._contentFileDropper.addEventListener(
|
||||||
|
'fileadd', e => this._evtFilesAdded(e));
|
||||||
|
this._contentFileDropper.addEventListener(
|
||||||
|
'urladd', e => this._evtUrlsAdded(e));
|
||||||
|
|
||||||
|
this._formNode.addEventListener('submit', e => this._evtFormSubmit(e));
|
||||||
|
this._formNode.classList.add('inactive');
|
||||||
|
}
|
||||||
|
|
||||||
|
enableForm() {
|
||||||
|
views.enableForm(this._formNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
disableForm() {
|
||||||
|
views.disableForm(this._formNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
clearMessages() {
|
||||||
|
views.clearMessages(this._hostNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
showSuccess(message) {
|
||||||
|
views.showSuccess(this._hostNode, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
showError(message) {
|
||||||
|
views.showError(this._hostNode, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
addUploadables(uploadables) {
|
||||||
|
this._formNode.classList.remove('inactive');
|
||||||
|
let duplicatesFound = 0;
|
||||||
|
for (let uploadable of uploadables) {
|
||||||
|
if (this._uploadables.has(uploadable.key)) {
|
||||||
|
duplicatesFound++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this._uploadables.set(uploadable.key, uploadable);
|
||||||
|
this._emit('change');
|
||||||
|
this._createRowNode(uploadable);
|
||||||
|
uploadable.addEventListener(
|
||||||
|
'finish', e => this._updateRowNode(e.detail.uploadable));
|
||||||
|
}
|
||||||
|
if (duplicatesFound) {
|
||||||
|
let message = null;
|
||||||
|
if (duplicatesFound < uploadables.length) {
|
||||||
|
message = 'Some of the files were already added ' +
|
||||||
|
'and have been skipped.';
|
||||||
|
} else if (duplicatesFound === 1) {
|
||||||
|
message = 'This file was already added.';
|
||||||
|
} else {
|
||||||
|
message = 'These files were already added.';
|
||||||
|
}
|
||||||
|
alert(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeUploadable(uploadable) {
|
||||||
|
if (!this._uploadables.has(uploadable.key)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uploadable.rowNode.parentNode.removeChild(uploadable.rowNode);
|
||||||
|
this._uploadables.delete(uploadable.key);
|
||||||
|
this._emit('change');
|
||||||
|
if (!this._uploadables.size) {
|
||||||
|
this._formNode.classList.add('inactive');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_evtFilesAdded(e) {
|
||||||
|
this.addUploadables(e.detail.files.map(file => new File(file)));
|
||||||
|
}
|
||||||
|
|
||||||
|
_evtUrlsAdded(e) {
|
||||||
|
this.addUploadables(e.detail.urls.map(url => new Url(url)));
|
||||||
|
}
|
||||||
|
|
||||||
|
_evtFormSubmit(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this._emit('submit');
|
||||||
|
}
|
||||||
|
|
||||||
|
_evtRemoveClick(e, uploadable) {
|
||||||
|
this.removeUploadable(uploadable);
|
||||||
|
}
|
||||||
|
|
||||||
|
_evtSafetyRadioboxChange(e, uploadable) {
|
||||||
|
uploadable.safety = e.target.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
_evtAnonymityCheckboxChange(e, uploadable) {
|
||||||
|
uploadable.anonymous = e.target.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
_emit(eventType) {
|
||||||
|
let sortedUploadables = [...this._uploadables.values()];
|
||||||
|
sortedUploadables.sort((a, b) => a.order - b.order);
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent(
|
||||||
|
eventType, {detail: {uploadables: sortedUploadables}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
_createRowNode(uploadable) {
|
||||||
|
const rowNode = rowTemplate({uploadable: uploadable});
|
||||||
|
this._listNode.appendChild(rowNode);
|
||||||
|
for (let radioboxNode of rowNode.querySelectorAll('.safety input')) {
|
||||||
|
radioboxNode.addEventListener(
|
||||||
|
'change', e => this._evtSafetyRadioboxChange(e, uploadable));
|
||||||
|
}
|
||||||
|
rowNode.querySelector('.anonymous input').addEventListener(
|
||||||
|
'change', e => this._evtAnonymityCheckboxChange(e, uploadable));
|
||||||
|
rowNode.querySelector('a.remove').addEventListener(
|
||||||
|
'click', e => this._evtRemoveClick(e, uploadable));
|
||||||
|
uploadable.rowNode = rowNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateRowNode(uploadable) {
|
||||||
|
const rowNode = rowTemplate({uploadable: uploadable});
|
||||||
|
views.replaceContent(
|
||||||
|
uploadable.rowNode.querySelector('.thumbnail'),
|
||||||
|
rowNode.querySelector('.thumbnail').childNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
get _listNode() {
|
||||||
|
return this._hostNode.querySelector('.uploadables-container');
|
||||||
|
}
|
||||||
|
|
||||||
|
get _formNode() {
|
||||||
|
return this._hostNode.querySelector('form');
|
||||||
|
}
|
||||||
|
|
||||||
|
get _submitButtonNode() {
|
||||||
|
return this._hostNode.querySelector('form [type=submit]');
|
||||||
|
}
|
||||||
|
|
||||||
|
get _contentInputNode() {
|
||||||
|
return this._formNode.querySelector('.dropper-container');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = PostUploadView;
|
Loading…
Reference in New Issue