szurubooru/client/js/models/post.js

229 lines
7.7 KiB
JavaScript
Raw Normal View History

'use strict';
const api = require('../api.js');
2016-07-05 21:20:28 +02:00
const tags = require('../tags.js');
const events = require('../events.js');
const CommentList = require('./comment_list.js');
const misc = require('../util/misc.js');
2016-07-03 13:46:49 +02:00
class Post extends events.EventTarget {
constructor() {
super();
this._orig = {};
this._updateFromResponse({});
}
2016-07-03 13:46:49 +02:00
get id() { return this._id; }
get type() { return this._type; }
get mimeType() { return this._mimeType; }
get creationTime() { return this._creationTime; }
get user() { return this._user; }
get safety() { return this._safety; }
get contentUrl() { return this._contentUrl; }
get thumbnailUrl() { return this._thumbnailUrl; }
get canvasWidth() { return this._canvasWidth || 800; }
get canvasHeight() { return this._canvasHeight || 450; }
get fileSize() { return this._fileSize || 0; }
2016-07-27 22:27:33 +02:00
get content() { throw 'Invalid operation'; }
2016-07-03 13:46:49 +02:00
get flags() { return this._flags; }
2016-07-03 13:46:49 +02:00
get tags() { return this._tags; }
get notes() { return this._notes; }
get comments() { return this._comments; }
get relations() { return this._relations; }
get score() { return this._score; }
get favoriteCount() { return this._favoriteCount; }
get ownFavorite() { return this._ownFavorite; }
get ownScore() { return this._ownScore; }
set flags(value) { this._flags = value; }
2016-07-03 13:46:49 +02:00
set tags(value) { this._tags = value; }
set safety(value) { this._safety = value; }
set relations(value) { this._relations = value; }
2016-07-27 22:27:33 +02:00
set content(value) { this._content = value; }
static fromResponse(response) {
const ret = new Post();
ret._updateFromResponse(response);
return ret;
}
static get(id) {
return api.get('/post/' + id)
.then(response => {
return Promise.resolve(Post.fromResponse(response));
}, response => {
return Promise.reject(response.description);
});
}
2016-07-05 21:20:28 +02:00
isTaggedWith(tagName) {
return this._tags.map(s => s.toLowerCase()).includes(tagName);
}
addTag(tagName, addImplications) {
if (this.isTaggedWith(tagName)) {
return;
}
this._tags.push(tagName);
if (addImplications !== false) {
for (let otherTag of tags.getAllImplications(tagName)) {
this.addTag(otherTag, addImplications);
}
}
}
removeTag(tagName) {
this._tags = this._tags.filter(
s => s.toLowerCase() != tagName.toLowerCase());
}
save() {
2016-07-27 22:27:33 +02:00
const files = [];
2016-07-03 13:46:49 +02:00
const detail = {};
// send only changed fields to avoid user privilege violation
if (this._safety !== this._orig._safety) {
detail.safety = this._safety;
}
if (misc.arraysDiffer(this._flags, this._orig._flags)) {
detail.flags = this._flags;
}
if (misc.arraysDiffer(this._tags, this._orig._tags)) {
2016-07-03 13:46:49 +02:00
detail.tags = this._tags;
2016-07-05 21:20:28 +02:00
}
if (misc.arraysDiffer(this._relations, this._orig._relations)) {
2016-07-03 13:46:49 +02:00
detail.relations = this._relations;
}
2016-07-27 22:27:33 +02:00
if (this._content) {
files.content = this._content;
}
2016-07-03 13:46:49 +02:00
let promise = this._id ?
2016-07-27 22:27:33 +02:00
api.put('/post/' + this._id, detail, files) :
api.post('/posts', detail, files);
2016-07-05 21:20:28 +02:00
return promise.then(response => {
this._updateFromResponse(response);
this.dispatchEvent(
new CustomEvent('change', {detail: {post: this}}));
2016-07-27 22:27:33 +02:00
if (this._content) {
this.dispatchEvent(
new CustomEvent('changeContent', {detail: {post: this}}));
}
2016-07-05 21:20:28 +02:00
return Promise.resolve();
}, response => {
return Promise.reject(response.description);
});
}
setScore(score) {
return api.put('/post/' + this._id + '/score', {score: score})
.then(response => {
const prevFavorite = this._ownFavorite;
this._updateFromResponse(response);
if (this._ownFavorite !== prevFavorite) {
this.dispatchEvent(new CustomEvent('changeFavorite', {
detail: {
post: this,
},
}));
}
this.dispatchEvent(new CustomEvent('changeScore', {
detail: {
post: this,
},
}));
return Promise.resolve();
}, response => {
return Promise.reject(response.description);
});
}
addToFavorites() {
return api.post('/post/' + this.id + '/favorite')
.then(response => {
const prevScore = this._ownScore;
this._updateFromResponse(response);
if (this._ownScore !== prevScore) {
this.dispatchEvent(new CustomEvent('changeScore', {
detail: {
post: this,
},
}));
}
this.dispatchEvent(new CustomEvent('changeFavorite', {
detail: {
post: this,
},
}));
return Promise.resolve();
}, response => {
return Promise.reject(response.description);
});
}
removeFromFavorites() {
return api.delete('/post/' + this.id + '/favorite')
.then(response => {
const prevScore = this._ownScore;
this._updateFromResponse(response);
if (this._ownScore !== prevScore) {
this.dispatchEvent(new CustomEvent('changeScore', {
detail: {
post: this,
},
}));
}
this.dispatchEvent(new CustomEvent('changeFavorite', {
detail: {
post: this,
},
}));
return Promise.resolve();
}, response => {
return Promise.reject(response.description);
});
}
2016-07-27 22:27:33 +02:00
mutateContentUrl() {
this._contentUrl =
this._orig._contentUrl +
'?bypass-cache=' +
Math.round(Math.random()*1000);
}
_updateFromResponse(response) {
2016-07-03 13:46:49 +02:00
const map = {
_id: response.id,
_type: response.type,
_mimeType: response.mimeType,
_creationTime: response.creationTime,
_user: response.user,
_safety: response.safety,
_contentUrl: response.contentUrl,
_thumbnailUrl: response.thumbnailUrl,
_canvasWidth: response.canvasWidth,
_canvasHeight: response.canvasHeight,
_fileSize: response.fileSize,
_flags: response.flags || [],
_tags: response.tags || [],
_notes: response.notes || [],
2016-07-03 13:46:49 +02:00
_comments: CommentList.fromResponse(response.comments || []),
_relations: response.relations || [],
2016-07-03 13:46:49 +02:00
_score: response.score,
_favoriteCount: response.favoriteCount,
_ownScore: response.ownScore,
_ownFavorite: response.ownFavorite,
};
Object.assign(this, map);
Object.assign(this._orig, map);
}
};
module.exports = Post;