2016-06-13 23:28:55 +02:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const api = require('../api.js');
|
2016-07-05 21:20:28 +02:00
|
|
|
const tags = require('../tags.js');
|
2016-06-13 23:28:55 +02:00
|
|
|
const events = require('../events.js');
|
2016-07-22 13:27:52 +02:00
|
|
|
const NoteList = require('./note_list.js');
|
2016-06-17 20:25:44 +02:00
|
|
|
const CommentList = require('./comment_list.js');
|
2016-07-26 20:49:48 +02:00
|
|
|
const misc = require('../util/misc.js');
|
2016-07-03 13:46:49 +02:00
|
|
|
|
2016-06-13 23:28:55 +02:00
|
|
|
class Post extends events.EventTarget {
|
|
|
|
constructor() {
|
|
|
|
super();
|
2016-07-26 21:01:52 +02:00
|
|
|
this._orig = {};
|
|
|
|
this._updateFromResponse({});
|
2016-06-13 23:28:55 +02:00
|
|
|
}
|
|
|
|
|
2016-08-20 22:40:25 +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; }
|
|
|
|
get newContent() { throw 'Invalid operation'; }
|
|
|
|
get newContentUrl() { throw 'Invalid operation'; }
|
|
|
|
get newThumbnail() { throw 'Invalid operation'; }
|
2016-07-03 13:46:49 +02:00
|
|
|
|
2016-08-20 22:40:25 +02:00
|
|
|
get flags() { return this._flags; }
|
|
|
|
get tags() { return this._tags; }
|
|
|
|
get notes() { return this._notes; }
|
|
|
|
get comments() { return this._comments; }
|
|
|
|
get relations() { return this._relations; }
|
2016-07-03 13:46:49 +02:00
|
|
|
|
2016-08-20 22:40:25 +02:00
|
|
|
get score() { return this._score; }
|
|
|
|
get commentCount() { return this._commentCount; }
|
|
|
|
get favoriteCount() { return this._favoriteCount; }
|
|
|
|
get ownFavorite() { return this._ownFavorite; }
|
|
|
|
get ownScore() { return this._ownScore; }
|
2016-07-31 23:54:29 +02:00
|
|
|
get hasCustomThumbnail() { return this._hasCustomThumbnail; }
|
2016-07-03 13:46:49 +02:00
|
|
|
|
2016-08-20 22:40:25 +02:00
|
|
|
set flags(value) { this._flags = value; }
|
|
|
|
set tags(value) { this._tags = value; }
|
|
|
|
set safety(value) { this._safety = value; }
|
|
|
|
set relations(value) { this._relations = value; }
|
|
|
|
set newContent(value) { this._newContent = value; }
|
|
|
|
set newContentUrl(value) { this._newContentUrl = value; }
|
|
|
|
set newThumbnail(value) { this._newThumbnail = value; }
|
2016-06-19 19:16:40 +02:00
|
|
|
|
2016-06-17 20:25:44 +02:00
|
|
|
static fromResponse(response) {
|
2016-06-19 19:16:40 +02:00
|
|
|
const ret = new Post();
|
|
|
|
ret._updateFromResponse(response);
|
|
|
|
return ret;
|
2016-06-17 20:25:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static get(id) {
|
|
|
|
return api.get('/post/' + id)
|
|
|
|
.then(response => {
|
2016-06-19 19:16:40 +02:00
|
|
|
return Promise.resolve(Post.fromResponse(response));
|
2016-06-17 20:25:44 +02:00
|
|
|
}, response => {
|
2016-06-19 19:16:40 +02:00
|
|
|
return Promise.reject(response.description);
|
2016-06-17 20:25:44 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
|
2016-08-20 22:40:25 +02:00
|
|
|
save(anonymous) {
|
2016-07-27 22:27:33 +02:00
|
|
|
const files = [];
|
2016-08-06 22:44:04 +02:00
|
|
|
const detail = {version: this._version};
|
2016-07-03 13:46:49 +02:00
|
|
|
|
|
|
|
// send only changed fields to avoid user privilege violation
|
2016-08-20 22:40:25 +02:00
|
|
|
if (anonymous === true) {
|
|
|
|
detail.anonymous = true;
|
|
|
|
}
|
2016-07-03 13:46:49 +02:00
|
|
|
if (this._safety !== this._orig._safety) {
|
|
|
|
detail.safety = this._safety;
|
|
|
|
}
|
2016-07-26 20:49:48 +02:00
|
|
|
if (misc.arraysDiffer(this._flags, this._orig._flags)) {
|
2016-07-26 20:37:55 +02:00
|
|
|
detail.flags = this._flags;
|
|
|
|
}
|
2016-07-26 20:49:48 +02:00
|
|
|
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
|
|
|
}
|
2016-07-26 20:49:48 +02:00
|
|
|
if (misc.arraysDiffer(this._relations, this._orig._relations)) {
|
2016-07-03 13:46:49 +02:00
|
|
|
detail.relations = this._relations;
|
|
|
|
}
|
2016-07-22 13:27:52 +02:00
|
|
|
if (misc.arraysDiffer(this._notes, this._orig._notes)) {
|
|
|
|
detail.notes = [...this._notes].map(note => ({
|
|
|
|
polygon: [...note.polygon].map(
|
|
|
|
point => [point.x, point.y]),
|
|
|
|
text: note.text,
|
|
|
|
}));
|
|
|
|
}
|
2016-08-20 22:40:25 +02:00
|
|
|
if (this._newContent) {
|
|
|
|
files.content = this._newContent;
|
|
|
|
} else if (this._newContentUrl) {
|
|
|
|
detail.contentUrl = this._newContentUrl;
|
2016-07-27 22:27:33 +02:00
|
|
|
}
|
2016-08-20 22:40:25 +02:00
|
|
|
if (this._newThumbnail !== undefined) {
|
|
|
|
files.thumbnail = this._newThumbnail;
|
2016-07-28 19:28:48 +02:00
|
|
|
}
|
|
|
|
|
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-08-20 22:40:25 +02:00
|
|
|
if (this._newContent || this._newContentUrl) {
|
2016-07-27 22:27:33 +02:00
|
|
|
this.dispatchEvent(
|
|
|
|
new CustomEvent('changeContent', {detail: {post: this}}));
|
|
|
|
}
|
2016-08-20 22:40:25 +02:00
|
|
|
if (this._newThumbnail) {
|
2016-07-28 19:28:48 +02:00
|
|
|
this.dispatchEvent(
|
|
|
|
new CustomEvent('changeThumbnail', {detail: {post: this}}));
|
|
|
|
}
|
2016-07-05 21:20:28 +02:00
|
|
|
return Promise.resolve();
|
|
|
|
}, response => {
|
|
|
|
return Promise.reject(response.description);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-08-02 10:37:56 +02:00
|
|
|
feature() {
|
|
|
|
return api.post('/featured-post', {id: this._id})
|
|
|
|
.then(response => {
|
|
|
|
return Promise.resolve();
|
|
|
|
}, response => {
|
|
|
|
return Promise.reject(response.description);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-08-02 11:05:40 +02:00
|
|
|
delete() {
|
2016-08-20 13:08:02 +02:00
|
|
|
return api.delete('/post/' + this._id, {version: this._version})
|
2016-08-02 11:05:40 +02:00
|
|
|
.then(response => {
|
|
|
|
this.dispatchEvent(new CustomEvent('delete', {
|
|
|
|
detail: {
|
|
|
|
post: this,
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
return Promise.resolve();
|
|
|
|
}, response => {
|
|
|
|
return Promise.reject(response.description);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-06-17 20:25:44 +02:00
|
|
|
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', {
|
2016-06-19 19:16:40 +02:00
|
|
|
detail: {
|
2016-06-17 20:25:44 +02:00
|
|
|
post: this,
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
this.dispatchEvent(new CustomEvent('changeScore', {
|
2016-06-19 19:16:40 +02:00
|
|
|
detail: {
|
2016-06-17 20:25:44 +02:00
|
|
|
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', {
|
2016-06-19 19:16:40 +02:00
|
|
|
detail: {
|
2016-06-17 20:25:44 +02:00
|
|
|
post: this,
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
this.dispatchEvent(new CustomEvent('changeFavorite', {
|
2016-06-19 19:16:40 +02:00
|
|
|
detail: {
|
2016-06-17 20:25:44 +02:00
|
|
|
post: this,
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
return Promise.resolve();
|
|
|
|
}, response => {
|
|
|
|
return Promise.reject(response.description);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
removeFromFavorites() {
|
2016-08-20 13:08:02 +02:00
|
|
|
return api.delete('/post/' + this.id + '/favorite')
|
2016-06-17 20:25:44 +02:00
|
|
|
.then(response => {
|
|
|
|
const prevScore = this._ownScore;
|
|
|
|
this._updateFromResponse(response);
|
|
|
|
if (this._ownScore !== prevScore) {
|
|
|
|
this.dispatchEvent(new CustomEvent('changeScore', {
|
2016-06-19 19:16:40 +02:00
|
|
|
detail: {
|
2016-06-17 20:25:44 +02:00
|
|
|
post: this,
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
this.dispatchEvent(new CustomEvent('changeFavorite', {
|
2016-06-19 19:16:40 +02:00
|
|
|
detail: {
|
2016-06-17 20:25:44 +02:00
|
|
|
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=' +
|
2016-07-30 10:00:42 +02:00
|
|
|
Math.round(Math.random() * 1000);
|
2016-07-27 22:27:33 +02:00
|
|
|
}
|
|
|
|
|
2016-06-17 20:25:44 +02:00
|
|
|
_updateFromResponse(response) {
|
2016-07-22 13:27:52 +02:00
|
|
|
const map = () => ({
|
2016-08-06 22:44:04 +02:00
|
|
|
_version: response.version,
|
2016-07-03 13:46:49 +02:00
|
|
|
_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,
|
|
|
|
|
2016-08-08 17:51:09 +02:00
|
|
|
_flags: [...response.flags || []],
|
|
|
|
_tags: [...response.tags || []],
|
|
|
|
_notes: NoteList.fromResponse([...response.notes || []]),
|
2016-08-20 22:40:25 +02:00
|
|
|
_comments: CommentList.fromResponse(
|
|
|
|
[...response.comments || []]),
|
2016-08-08 17:51:09 +02:00
|
|
|
_relations: [...response.relations || []],
|
2016-07-03 13:46:49 +02:00
|
|
|
|
|
|
|
_score: response.score,
|
2016-08-21 20:11:14 +02:00
|
|
|
_commentCount: response.commentCount,
|
2016-07-03 13:46:49 +02:00
|
|
|
_favoriteCount: response.favoriteCount,
|
|
|
|
_ownScore: response.ownScore,
|
|
|
|
_ownFavorite: response.ownFavorite,
|
2016-07-31 23:54:29 +02:00
|
|
|
_hasCustomThumbnail: response.hasCustomThumbnail,
|
2016-07-22 13:27:52 +02:00
|
|
|
});
|
2016-07-03 13:46:49 +02:00
|
|
|
|
2016-07-22 13:27:52 +02:00
|
|
|
Object.assign(this, map());
|
|
|
|
Object.assign(this._orig, map());
|
2016-06-13 23:28:55 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = Post;
|