mirror of
https://github.com/flarum/framework.git
synced 2025-05-21 22:36:01 +08:00
Massive refactor
- Use contextual namespaces within Flarum\Core - Clean up and docblock everything - Refactor Activity/Notification blueprint stuff - Refactor Formatter stuff - Refactor Search stuff - Upgrade to JSON-API 1.0 - Removed “addedPosts” and “removedPosts” relationships from discussion API. This was used for adding/removing event posts after renaming a discussion etc. Instead we should make an additional request to get all new posts Todo: - Fix Extenders and extensions - Get rid of repository interfaces - Fix other bugs I’ve inevitably introduced
This commit is contained in:
@ -46,9 +46,11 @@ export default class ActivityPage extends UserPage {
|
||||
|
||||
loadResults(offset) {
|
||||
return app.store.find('activity', {
|
||||
users: this.user().id(),
|
||||
page: {offset, limit: this.loadLimit},
|
||||
type: this.props.filter
|
||||
filter: {
|
||||
user: this.user().id(),
|
||||
type: this.props.filter
|
||||
},
|
||||
page: {offset, limit: this.loadLimit}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -208,6 +208,7 @@ class Composer extends Component {
|
||||
if (flexible.length) {
|
||||
flexible.height(height -
|
||||
(flexible.offset().top - this.$().offset().top) -
|
||||
parseInt(flexible.css('padding-bottom')) -
|
||||
this.$('.text-editor-controls').outerHeight(true));
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ export default class DiscussionPage extends mixin(Component, evented) {
|
||||
|
||||
params() {
|
||||
return {
|
||||
near: this.currentNear,
|
||||
page: {near: this.currentNear},
|
||||
include: ['posts', 'posts.user', 'posts.user.groups']
|
||||
};
|
||||
}
|
||||
@ -91,7 +91,7 @@ export default class DiscussionPage extends mixin(Component, evented) {
|
||||
var includedPosts = [];
|
||||
if (discussion.payload && discussion.payload.included) {
|
||||
discussion.payload.included.forEach(record => {
|
||||
if (record.type === 'posts' && record.links && record.links.discussion) {
|
||||
if (record.type === 'posts' && record.relationships && record.relationships.discussion) {
|
||||
includedPosts.push(app.store.getById('posts', record.id));
|
||||
}
|
||||
});
|
||||
|
@ -9,7 +9,7 @@ export default class DiscussionsSearchResults {
|
||||
|
||||
search(string) {
|
||||
this.results[string] = [];
|
||||
return app.store.find('discussions', {q: string, page: {limit: 3}, include: 'relevantPosts,relevantPosts.discussion'}).then(results => {
|
||||
return app.store.find('discussions', {filter: {q: string}, page: {limit: 3}, include: 'relevantPosts,relevantPosts.discussion'}).then(results => {
|
||||
this.results[string] = results;
|
||||
});
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ export default class NotificationList extends Component {
|
||||
this.loading(true);
|
||||
m.redraw();
|
||||
app.store.find('notifications').then(notifications => {
|
||||
app.session.user().pushData({unreadNotificationsCount: 0});
|
||||
app.session.user().pushAttributes({unreadNotificationsCount: 0});
|
||||
this.loading(false);
|
||||
app.cache.notifications = notifications.sort((a, b) => b.time() - a.time());
|
||||
m.redraw();
|
||||
|
@ -76,11 +76,11 @@ class PostStream extends mixin(Component, evented) {
|
||||
sync() {
|
||||
var addedPosts = this.discussion.addedPosts();
|
||||
if (addedPosts) addedPosts.forEach(this.pushPost.bind(this));
|
||||
this.discussion.pushData({links: {addedPosts: null}});
|
||||
this.discussion.pushAttributes({links: {addedPosts: null}});
|
||||
|
||||
var removedPosts = this.discussion.removedPosts();
|
||||
if (removedPosts) removedPosts.forEach(this.removePost.bind(this));
|
||||
this.discussion.pushData({removedPosts: null});
|
||||
this.discussion.pushAttributes({removedPosts: null});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,8 +352,8 @@ class PostStream extends mixin(Component, evented) {
|
||||
this.clear();
|
||||
|
||||
return app.store.find('posts', {
|
||||
discussions: this.discussion.id(),
|
||||
near: number
|
||||
filter: {discussion: this.discussion.id()},
|
||||
page: {near: number}
|
||||
}).then(this.setup.bind(this));
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ export default class ReplyComposer extends ComposerBody {
|
||||
data() {
|
||||
return {
|
||||
content: this.content(),
|
||||
links: {discussion: this.props.discussion}
|
||||
relationships: {discussion: this.props.discussion}
|
||||
};
|
||||
}
|
||||
|
||||
@ -47,8 +47,8 @@ export default class ReplyComposer extends ComposerBody {
|
||||
app.store.createRecord('posts').save(data).then((post) => {
|
||||
app.composer.hide();
|
||||
|
||||
discussion.pushData({
|
||||
links: {
|
||||
discussion.pushAttributes({
|
||||
relationships: {
|
||||
lastUser: post.user(),
|
||||
lastPost: post
|
||||
},
|
||||
@ -58,7 +58,7 @@ export default class ReplyComposer extends ComposerBody {
|
||||
readTime: post.time(),
|
||||
readNumber: post.number()
|
||||
});
|
||||
discussion.data().links.posts.linkage.push({type: 'posts', id: post.id()});
|
||||
discussion.data().relationships.posts.data.push({type: 'posts', id: post.id()});
|
||||
|
||||
// If we're currently viewing the discussion which this reply was made
|
||||
// in, then we can add the post to the end of the post stream.
|
||||
|
@ -113,7 +113,7 @@ export default class SettingsPage extends UserPage {
|
||||
label: 'Allow others to see when I am online',
|
||||
state: this.user().preferences().discloseOnline,
|
||||
onchange: (value, component) => {
|
||||
this.user().pushData({lastSeenTime: null});
|
||||
this.user().pushAttributes({lastSeenTime: null});
|
||||
this.save('discloseOnline')(value, component);
|
||||
}
|
||||
})
|
||||
|
@ -3,7 +3,7 @@ import avatar from 'flarum/helpers/avatar';
|
||||
|
||||
export default class UsersSearchResults {
|
||||
search(string) {
|
||||
return app.store.find('users', {q: string, page: {limit: 5}});
|
||||
return app.store.find('users', {filter: {q: string}, page: {limit: 5}});
|
||||
}
|
||||
|
||||
view(string) {
|
||||
|
@ -13,17 +13,17 @@ export default function(app) {
|
||||
|
||||
function hideAction() {
|
||||
this.save({ isHidden: true });
|
||||
this.pushData({ hideTime: new Date(), hideUser: app.session.user() });
|
||||
this.pushAttributes({ hideTime: new Date(), hideUser: app.session.user() });
|
||||
}
|
||||
|
||||
function restoreAction() {
|
||||
this.save({ isHidden: false });
|
||||
this.pushData({ hideTime: null, hideUser: null });
|
||||
this.pushAttributes({ hideTime: null, hideUser: null });
|
||||
}
|
||||
|
||||
function deleteAction() {
|
||||
this.delete();
|
||||
this.discussion().pushData({removedPosts: [this.id()]});
|
||||
// this.discussion().pushAttributes({removedPosts: [this.id()]});
|
||||
if (app.current instanceof DiscussionPage) {
|
||||
app.current.stream.removePost(this.id());
|
||||
}
|
||||
|
@ -6,18 +6,27 @@ export default class Model {
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
id() {
|
||||
return this.data().id;
|
||||
}
|
||||
|
||||
pushData(newData) {
|
||||
var data = this.data();
|
||||
|
||||
for (var i in newData) {
|
||||
if (i === 'links') {
|
||||
if (i === 'relationships') {
|
||||
data[i] = data[i] || {};
|
||||
for (var j in newData[i]) {
|
||||
if (newData[i][j] instanceof Model) {
|
||||
newData[i][j] = {linkage: {type: newData[i][j].data().type, id: newData[i][j].data().id}};
|
||||
newData[i][j] = {data: {type: newData[i][j].data().type, id: newData[i][j].data().id}};
|
||||
}
|
||||
data[i][j] = newData[i][j];
|
||||
}
|
||||
} else if (i === 'attributes') {
|
||||
data[i] = data[i] || {};
|
||||
for (var j in newData[i]) {
|
||||
data[i][j] = newData[i][j];
|
||||
}
|
||||
} else {
|
||||
data[i] = newData[i];
|
||||
}
|
||||
@ -26,19 +35,40 @@ export default class Model {
|
||||
this.freshness = new Date();
|
||||
}
|
||||
|
||||
save(data) {
|
||||
if (data.links) {
|
||||
for (var i in data.links) {
|
||||
var model = data.links[i];
|
||||
var linkage = model => {
|
||||
pushAttributes(attributes) {
|
||||
var data = {attributes};
|
||||
|
||||
if (attributes.relationships) {
|
||||
data.relationships = attributes.relationships;
|
||||
delete attributes.relationships;
|
||||
}
|
||||
|
||||
this.pushData(data);
|
||||
}
|
||||
|
||||
save(attributes) {
|
||||
var data = {
|
||||
type: this.data().type,
|
||||
id: this.data().id,
|
||||
attributes
|
||||
};
|
||||
|
||||
if (attributes.relationships) {
|
||||
data.relationships = {};
|
||||
|
||||
for (var i in attributes.relationships) {
|
||||
var model = attributes.relationships[i];
|
||||
var relationshipData = model => {
|
||||
return {type: model.data().type, id: model.data().id};
|
||||
};
|
||||
if (model instanceof Array) {
|
||||
data.links[i] = {linkage: model.map(linkage)};
|
||||
data.relationships[i] = {data: model.map(relationshipData)};
|
||||
} else {
|
||||
data.links[i] = {linkage: linkage(model)};
|
||||
data.relationships[i] = {data: relationshipData(model)};
|
||||
}
|
||||
}
|
||||
|
||||
delete attributes.relationships;
|
||||
}
|
||||
|
||||
// clone the relevant parts of the model's old data so that we can revert
|
||||
@ -46,7 +76,7 @@ export default class Model {
|
||||
var oldData = {};
|
||||
var currentData = this.data();
|
||||
for (var i in data) {
|
||||
if (i === 'links') {
|
||||
if (i === 'relationships') {
|
||||
oldData[i] = oldData[i] || {};
|
||||
for (var j in currentData[i]) {
|
||||
oldData[i][j] = currentData[i][j];
|
||||
@ -59,7 +89,7 @@ export default class Model {
|
||||
this.pushData(data);
|
||||
|
||||
return app.request({
|
||||
method: this.exists ? 'PUT' : 'POST',
|
||||
method: this.exists ? 'PATCH' : 'POST',
|
||||
url: app.config['api_url']+'/'+this.data().type+(this.exists ? '/'+this.data().id : ''),
|
||||
data: {data},
|
||||
background: true,
|
||||
@ -84,36 +114,36 @@ export default class Model {
|
||||
}).then(() => this.exists = false);
|
||||
}
|
||||
|
||||
static prop(name, transform) {
|
||||
static attribute(name, transform) {
|
||||
return function() {
|
||||
var data = this.data()[name];
|
||||
var data = this.data().attributes[name];
|
||||
return transform ? transform(data) : data;
|
||||
}
|
||||
}
|
||||
|
||||
static one(name) {
|
||||
static hasOne(name) {
|
||||
return function() {
|
||||
var data = this.data();
|
||||
if (data.links) {
|
||||
var link = data.links[name];
|
||||
return link && app.store.getById(link.linkage.type, link.linkage.id);
|
||||
if (data.relationships) {
|
||||
var relationship = data.relationships[name];
|
||||
return relationship && app.store.getById(relationship.data.type, relationship.data.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static many(name) {
|
||||
static hasMany(name) {
|
||||
return function() {
|
||||
var data = this.data();
|
||||
if (data.links) {
|
||||
var link = this.data().links[name];
|
||||
return link && link.linkage.map(function(link) {
|
||||
return app.store.getById(link.type, link.id)
|
||||
if (data.relationships) {
|
||||
var relationship = this.data().relationships[name];
|
||||
return relationship && relationship.data.map(function(link) {
|
||||
return app.store.getById(link.type, link.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static date(data) {
|
||||
static transformDate(data) {
|
||||
return data ? new Date(data) : null;
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,11 @@ import Model from 'flarum/model';
|
||||
|
||||
class Activity extends Model {}
|
||||
|
||||
Activity.prototype.id = Model.prop('id');
|
||||
Activity.prototype.contentType = Model.prop('contentType');
|
||||
Activity.prototype.content = Model.prop('content');
|
||||
Activity.prototype.time = Model.prop('time', Model.date);
|
||||
Activity.prototype.contentType = Model.attribute('contentType');
|
||||
Activity.prototype.content = Model.attribute('content');
|
||||
Activity.prototype.time = Model.attribute('time', Model.transformDate);
|
||||
|
||||
Activity.prototype.user = Model.one('user');
|
||||
Activity.prototype.subject = Model.one('subject');
|
||||
Activity.prototype.user = Model.hasOne('user');
|
||||
Activity.prototype.subject = Model.hasOne('subject');
|
||||
|
||||
export default Activity;
|
||||
|
@ -6,25 +6,25 @@ class Discussion extends Model {
|
||||
pushData(newData) {
|
||||
super.pushData(newData);
|
||||
|
||||
var links = this.data().links;
|
||||
var posts = links && links.posts;
|
||||
if (posts) {
|
||||
if (newData.removedPosts) {
|
||||
posts.linkage.forEach((linkage, i) => {
|
||||
if (newData.removedPosts.indexOf(linkage.id) !== -1) {
|
||||
posts.linkage.splice(i, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
// var links = this.data().links;
|
||||
// var posts = links && links.posts;
|
||||
// if (posts) {
|
||||
// if (newData.removedPosts) {
|
||||
// posts.linkage.forEach((linkage, i) => {
|
||||
// if (newData.removedPosts.indexOf(linkage.id) !== -1) {
|
||||
// posts.linkage.splice(i, 1);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
if (newData.links && newData.links.addedPosts) {
|
||||
newData.links.addedPosts.linkage.forEach(linkage => {
|
||||
if (posts.linkage[posts.linkage.length - 1].id != linkage.id) {
|
||||
posts.linkage.push(linkage);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// if (newData.links && newData.links.addedPosts) {
|
||||
// newData.links.addedPosts.linkage.forEach(linkage => {
|
||||
// if (posts.linkage[posts.linkage.length - 1].id != linkage.id) {
|
||||
// posts.linkage.push(linkage);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
unreadCount() {
|
||||
@ -40,34 +40,33 @@ class Discussion extends Model {
|
||||
}
|
||||
}
|
||||
|
||||
Discussion.prototype.id = Model.prop('id');
|
||||
Discussion.prototype.title = Model.prop('title');
|
||||
Discussion.prototype.title = Model.attribute('title');
|
||||
Discussion.prototype.slug = computed('title', title => title.toLowerCase().replace(/[^a-z0-9]/gi, '-').replace(/-+/g, '-').replace(/-$|^-/g, '') || '-');
|
||||
|
||||
Discussion.prototype.startTime = Model.prop('startTime', Model.date);
|
||||
Discussion.prototype.startUser = Model.one('startUser');
|
||||
Discussion.prototype.startPost = Model.one('startPost');
|
||||
Discussion.prototype.startTime = Model.attribute('startTime', Model.transformDate);
|
||||
Discussion.prototype.startUser = Model.hasOne('startUser');
|
||||
Discussion.prototype.startPost = Model.hasOne('startPost');
|
||||
|
||||
Discussion.prototype.lastTime = Model.prop('lastTime', Model.date);
|
||||
Discussion.prototype.lastUser = Model.one('lastUser');
|
||||
Discussion.prototype.lastPost = Model.one('lastPost');
|
||||
Discussion.prototype.lastPostNumber = Model.prop('lastPostNumber');
|
||||
Discussion.prototype.lastTime = Model.attribute('lastTime', Model.transformDate);
|
||||
Discussion.prototype.lastUser = Model.hasOne('lastUser');
|
||||
Discussion.prototype.lastPost = Model.hasOne('lastPost');
|
||||
Discussion.prototype.lastPostNumber = Model.attribute('lastPostNumber');
|
||||
|
||||
Discussion.prototype.canReply = Model.prop('canReply');
|
||||
Discussion.prototype.canRename = Model.prop('canRename');
|
||||
Discussion.prototype.canDelete = Model.prop('canDelete');
|
||||
Discussion.prototype.canReply = Model.attribute('canReply');
|
||||
Discussion.prototype.canRename = Model.attribute('canRename');
|
||||
Discussion.prototype.canDelete = Model.attribute('canDelete');
|
||||
|
||||
Discussion.prototype.commentsCount = Model.prop('commentsCount');
|
||||
Discussion.prototype.commentsCount = Model.attribute('commentsCount');
|
||||
Discussion.prototype.repliesCount = computed('commentsCount', commentsCount => Math.max(0, commentsCount - 1));
|
||||
|
||||
Discussion.prototype.posts = Model.many('posts');
|
||||
Discussion.prototype.postIds = function() { return this.data().links.posts.linkage.map((link) => link.id); };
|
||||
Discussion.prototype.relevantPosts = Model.many('relevantPosts');
|
||||
Discussion.prototype.addedPosts = Model.many('addedPosts');
|
||||
Discussion.prototype.removedPosts = Model.prop('removedPosts');
|
||||
Discussion.prototype.posts = Model.hasMany('posts');
|
||||
Discussion.prototype.postIds = function() { return this.data().relationships.posts.data.map((link) => link.id); };
|
||||
Discussion.prototype.relevantPosts = Model.hasMany('relevantPosts');
|
||||
Discussion.prototype.addedPosts = Model.hasMany('addedPosts');
|
||||
Discussion.prototype.removedPosts = Model.attribute('removedPosts');
|
||||
|
||||
Discussion.prototype.readTime = Model.prop('readTime', Model.date);
|
||||
Discussion.prototype.readNumber = Model.prop('readNumber');
|
||||
Discussion.prototype.readTime = Model.attribute('readTime', Model.transformDate);
|
||||
Discussion.prototype.readNumber = Model.attribute('readNumber');
|
||||
|
||||
Discussion.prototype.isUnread = computed('unreadCount', unreadCount => !!unreadCount);
|
||||
|
||||
|
@ -2,10 +2,9 @@ import Model from 'flarum/model';
|
||||
|
||||
class Group extends Model {}
|
||||
|
||||
Group.prototype.id = Model.prop('id');
|
||||
Group.prototype.nameSingular = Model.prop('nameSingular');
|
||||
Group.prototype.namePlural = Model.prop('namePlural');
|
||||
Group.prototype.color = Model.prop('color');
|
||||
Group.prototype.icon = Model.prop('icon');
|
||||
Group.prototype.nameSingular = Model.attribute('nameSingular');
|
||||
Group.prototype.namePlural = Model.attribute('namePlural');
|
||||
Group.prototype.color = Model.attribute('color');
|
||||
Group.prototype.icon = Model.attribute('icon');
|
||||
|
||||
export default Group;
|
||||
|
@ -3,17 +3,16 @@ import computed from 'flarum/utils/computed';
|
||||
|
||||
class Notification extends Model {}
|
||||
|
||||
Notification.prototype.id = Model.prop('id');
|
||||
Notification.prototype.contentType = Model.prop('contentType');
|
||||
Notification.prototype.subjectId = Model.prop('subjectId');
|
||||
Notification.prototype.content = Model.prop('content');
|
||||
Notification.prototype.time = Model.prop('time', Model.date);
|
||||
Notification.prototype.isRead = Model.prop('isRead');
|
||||
Notification.prototype.unreadCount = Model.prop('unreadCount');
|
||||
Notification.prototype.contentType = Model.attribute('contentType');
|
||||
Notification.prototype.subjectId = Model.attribute('subjectId');
|
||||
Notification.prototype.content = Model.attribute('content');
|
||||
Notification.prototype.time = Model.attribute('time', Model.date);
|
||||
Notification.prototype.isRead = Model.attribute('isRead');
|
||||
Notification.prototype.unreadCount = Model.attribute('unreadCount');
|
||||
Notification.prototype.additionalUnreadCount = computed('unreadCount', unreadCount => Math.max(0, unreadCount - 1));
|
||||
|
||||
Notification.prototype.user = Model.one('user');
|
||||
Notification.prototype.sender = Model.one('sender');
|
||||
Notification.prototype.subject = Model.one('subject');
|
||||
Notification.prototype.user = Model.hasOne('user');
|
||||
Notification.prototype.sender = Model.hasOne('sender');
|
||||
Notification.prototype.subject = Model.hasOne('subject');
|
||||
|
||||
export default Notification;
|
||||
|
@ -3,26 +3,25 @@ import computed from 'flarum/utils/computed';
|
||||
|
||||
class Post extends Model {}
|
||||
|
||||
Post.prototype.id = Model.prop('id');
|
||||
Post.prototype.number = Model.prop('number');
|
||||
Post.prototype.discussion = Model.one('discussion');
|
||||
Post.prototype.number = Model.attribute('number');
|
||||
Post.prototype.discussion = Model.hasOne('discussion');
|
||||
|
||||
Post.prototype.time = Model.prop('time', Model.date);
|
||||
Post.prototype.user = Model.one('user');
|
||||
Post.prototype.contentType = Model.prop('contentType');
|
||||
Post.prototype.content = Model.prop('content');
|
||||
Post.prototype.contentHtml = Model.prop('contentHtml');
|
||||
Post.prototype.time = Model.attribute('time', Model.transformDate);
|
||||
Post.prototype.user = Model.hasOne('user');
|
||||
Post.prototype.contentType = Model.attribute('contentType');
|
||||
Post.prototype.content = Model.attribute('content');
|
||||
Post.prototype.contentHtml = Model.attribute('contentHtml');
|
||||
Post.prototype.contentPlain = computed('contentHtml', contentHtml => $('<div/>').html(contentHtml.replace(/(<\/p>|<br>)/g, '$1 ')).text());
|
||||
|
||||
Post.prototype.editTime = Model.prop('editTime', Model.date);
|
||||
Post.prototype.editUser = Model.one('editUser');
|
||||
Post.prototype.editTime = Model.attribute('editTime', Model.transformDate);
|
||||
Post.prototype.editUser = Model.hasOne('editUser');
|
||||
Post.prototype.isEdited = computed('editTime', editTime => !!editTime);
|
||||
|
||||
Post.prototype.hideTime = Model.prop('hideTime', Model.date);
|
||||
Post.prototype.hideUser = Model.one('hideUser');
|
||||
Post.prototype.hideTime = Model.attribute('hideTime', Model.transformDate);
|
||||
Post.prototype.hideUser = Model.hasOne('hideUser');
|
||||
Post.prototype.isHidden = computed('hideTime', hideTime => !!hideTime);
|
||||
|
||||
Post.prototype.canEdit = Model.prop('canEdit');
|
||||
Post.prototype.canDelete = Model.prop('canDelete');
|
||||
Post.prototype.canEdit = Model.attribute('canEdit');
|
||||
Post.prototype.canDelete = Model.attribute('canDelete');
|
||||
|
||||
export default Post;
|
||||
|
@ -6,29 +6,28 @@ import Badge from 'flarum/components/badge';
|
||||
|
||||
class User extends Model {}
|
||||
|
||||
User.prototype.id = Model.prop('id');
|
||||
User.prototype.username = Model.prop('username');
|
||||
User.prototype.email = Model.prop('email');
|
||||
User.prototype.isConfirmed = Model.prop('isConfirmed');
|
||||
User.prototype.password = Model.prop('password');
|
||||
User.prototype.avatarUrl = Model.prop('avatarUrl');
|
||||
User.prototype.bio = Model.prop('bio');
|
||||
User.prototype.bioHtml = Model.prop('bioHtml');
|
||||
User.prototype.preferences = Model.prop('preferences');
|
||||
User.prototype.username = Model.attribute('username');
|
||||
User.prototype.email = Model.attribute('email');
|
||||
User.prototype.isConfirmed = Model.attribute('isConfirmed');
|
||||
User.prototype.password = Model.attribute('password');
|
||||
User.prototype.avatarUrl = Model.attribute('avatarUrl');
|
||||
User.prototype.bio = Model.attribute('bio');
|
||||
User.prototype.bioHtml = Model.attribute('bioHtml');
|
||||
User.prototype.preferences = Model.attribute('preferences');
|
||||
|
||||
User.prototype.groups = Model.many('groups');
|
||||
User.prototype.groups = Model.hasMany('groups');
|
||||
|
||||
User.prototype.joinTime = Model.prop('joinTime', Model.date);
|
||||
User.prototype.lastSeenTime = Model.prop('lastSeenTime', Model.date);
|
||||
User.prototype.joinTime = Model.attribute('joinTime', Model.transformDate);
|
||||
User.prototype.lastSeenTime = Model.attribute('lastSeenTime', Model.transformDate);
|
||||
User.prototype.online = function() { return this.lastSeenTime() > moment().subtract(5, 'minutes').toDate(); };
|
||||
User.prototype.readTime = Model.prop('readTime', Model.date);
|
||||
User.prototype.unreadNotificationsCount = Model.prop('unreadNotificationsCount');
|
||||
User.prototype.readTime = Model.attribute('readTime', Model.transformDate);
|
||||
User.prototype.unreadNotificationsCount = Model.attribute('unreadNotificationsCount');
|
||||
|
||||
User.prototype.discussionsCount = Model.prop('discussionsCount');
|
||||
User.prototype.commentsCount = Model.prop('commentsCount');
|
||||
User.prototype.discussionsCount = Model.attribute('discussionsCount');
|
||||
User.prototype.commentsCount = Model.attribute('commentsCount');
|
||||
;
|
||||
User.prototype.canEdit = Model.prop('canEdit');
|
||||
User.prototype.canDelete = Model.prop('canDelete');
|
||||
User.prototype.canEdit = Model.attribute('canEdit');
|
||||
User.prototype.canDelete = Model.attribute('canDelete');
|
||||
|
||||
User.prototype.color = computed('username', 'avatarUrl', 'avatarColor', function(username, avatarUrl, avatarColor) {
|
||||
if (avatarColor) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
export default function truncate(string, length, start) {
|
||||
start = start || 0;
|
||||
string = string || '';
|
||||
|
||||
return (start > 0 ? '...' : '')+string.substring(start, start + length)+(string.length > start + length ? '...' : '');
|
||||
}
|
||||
|
Reference in New Issue
Block a user