mirror of
https://github.com/flarum/framework.git
synced 2024-12-03 15:43:59 +08:00
Refactor post components and controls
This commit is contained in:
parent
1f53547ee5
commit
3baa817326
|
@ -1,6 +1,7 @@
|
|||
import App from 'flarum/utils/app';
|
||||
import store from 'flarum/initializers/store';
|
||||
import discussionControls from 'flarum/initializers/discussion-controls';
|
||||
import postControls from 'flarum/initializers/post-controls';
|
||||
import preload from 'flarum/initializers/preload';
|
||||
import session from 'flarum/initializers/session';
|
||||
import routes from 'flarum/initializers/routes';
|
||||
|
@ -12,6 +13,7 @@ var app = new App();
|
|||
|
||||
app.initializers.add('store', store);
|
||||
app.initializers.add('discussion-controls', discussionControls);
|
||||
app.initializers.add('post-controls', postControls);
|
||||
app.initializers.add('session', session);
|
||||
app.initializers.add('routes', routes);
|
||||
app.initializers.add('components', components);
|
||||
|
|
|
@ -4,8 +4,8 @@ export default class Notification extends Component {
|
|||
view() {
|
||||
var notification = this.props.notification;
|
||||
|
||||
return m('div.notification', {
|
||||
classNames: !notification.isRead ? 'unread' : '',
|
||||
return m('div.notification.notification-'+notification.contentType(), {
|
||||
classNames: !notification.isRead() ? 'unread' : '',
|
||||
onclick: this.read.bind(this)
|
||||
}, this.content());
|
||||
}
|
||||
|
|
24
framework/core/js/forum/src/components/post-activity.js
Normal file
24
framework/core/js/forum/src/components/post-activity.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import Post from 'flarum/components/post';
|
||||
import username from 'flarum/helpers/username';
|
||||
import icon from 'flarum/helpers/icon';
|
||||
import humanTime from 'flarum/utils/human-time';
|
||||
|
||||
export default class PostActivity extends Post {
|
||||
view(content, attrs) {
|
||||
attrs.className = 'post-activity '+(attrs.className || '');
|
||||
|
||||
var iconName = attrs.icon;
|
||||
delete attrs.icon;
|
||||
|
||||
var post = this.props.post;
|
||||
|
||||
return super.view([
|
||||
icon(iconName+' post-icon'),
|
||||
m('div.post-activity-info', [
|
||||
m('a.post-user', {href: app.route('user', { username: post.user().username() }), config: m.route}, username(post.user())), ' ',
|
||||
content
|
||||
]),
|
||||
m('div.post-activity-time', humanTime(post.time()))
|
||||
], attrs);
|
||||
}
|
||||
}
|
|
@ -1,14 +1,10 @@
|
|||
import Component from 'flarum/component';
|
||||
import Post from 'flarum/components/post';
|
||||
import classList from 'flarum/utils/class-list';
|
||||
import ComposerEdit from 'flarum/components/composer-edit';
|
||||
import PostHeaderUser from 'flarum/components/post-header-user';
|
||||
import PostHeaderMeta from 'flarum/components/post-header-meta';
|
||||
import PostHeaderEdited from 'flarum/components/post-header-edited';
|
||||
import PostHeaderToggle from 'flarum/components/post-header-toggle';
|
||||
import ItemList from 'flarum/utils/item-list';
|
||||
import ActionButton from 'flarum/components/action-button';
|
||||
import DropdownButton from 'flarum/components/dropdown-button';
|
||||
import SubtreeRetainer from 'flarum/utils/subtree-retainer';
|
||||
import listItems from 'flarum/helpers/list-items';
|
||||
|
||||
/**
|
||||
|
@ -16,43 +12,30 @@ import listItems from 'flarum/helpers/list-items';
|
|||
(controls, header, and footer) surrounding the post's HTML content. Allows
|
||||
the post to be edited with the composer, hidden, or restored.
|
||||
*/
|
||||
export default class PostComment extends Component {
|
||||
export default class PostComment extends Post {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.postHeaderUser = new PostHeaderUser({post: this.props.post});
|
||||
|
||||
this.subtree = new SubtreeRetainer(
|
||||
() => this.props.post.freshness,
|
||||
() => this.props.post.user() && this.props.post.user().freshness,
|
||||
this.postHeaderUser.showCard
|
||||
);
|
||||
this.subtree.add(this.postHeaderUser.showCard);
|
||||
}
|
||||
|
||||
view() {
|
||||
var post = this.props.post;
|
||||
|
||||
var classes = {
|
||||
'is-hidden': post.isHidden(),
|
||||
'is-edited': post.isEdited(),
|
||||
'reveal-content': this.revealContent
|
||||
};
|
||||
|
||||
var controls = this.controlItems().toArray();
|
||||
|
||||
// @todo Having to wrap children in a div isn't nice
|
||||
return m('article.post.post-comment', {className: classList(classes)}, this.subtree.retain() || m('div', [
|
||||
controls.length ? DropdownButton.component({
|
||||
items: controls,
|
||||
className: 'contextual-controls',
|
||||
buttonClass: 'btn btn-default btn-icon btn-sm btn-naked',
|
||||
menuClass: 'pull-right'
|
||||
}) : '',
|
||||
return super.view([
|
||||
m('header.post-header', m('ul', listItems(this.headerItems().toArray()))),
|
||||
m('div.post-body', m.trust(post.contentHtml())),
|
||||
m('aside.post-footer', m('ul', listItems(this.footerItems().toArray()))),
|
||||
m('aside.post-actions', m('ul', listItems(this.actionItems().toArray())))
|
||||
]));
|
||||
], {
|
||||
className: classList({
|
||||
'post-comment': true,
|
||||
'is-hidden': post.isHidden(),
|
||||
'is-edited': post.isEdited(),
|
||||
'reveal-content': this.revealContent
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
toggleContent() {
|
||||
|
@ -78,25 +61,6 @@ export default class PostComment extends Component {
|
|||
return items;
|
||||
}
|
||||
|
||||
controlItems() {
|
||||
var items = new ItemList();
|
||||
var post = this.props.post;
|
||||
|
||||
if (post.isHidden()) {
|
||||
if (post.canEdit()) {
|
||||
items.add('restore', ActionButton.component({ icon: 'reply', label: 'Restore', onclick: this.restore.bind(this) }));
|
||||
}
|
||||
if (post.canDelete()) {
|
||||
items.add('delete', ActionButton.component({ icon: 'times', label: 'Delete Forever', onclick: this.delete.bind(this) }));
|
||||
}
|
||||
} else if (post.canEdit()) {
|
||||
items.add('edit', ActionButton.component({ icon: 'pencil', label: 'Edit', onclick: this.edit.bind(this) }));
|
||||
items.add('hide', ActionButton.component({ icon: 'times', label: 'Delete', onclick: this.hide.bind(this) }));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
footerItems() {
|
||||
return new ItemList();
|
||||
}
|
||||
|
@ -104,30 +68,4 @@ export default class PostComment extends Component {
|
|||
actionItems() {
|
||||
return new ItemList();
|
||||
}
|
||||
|
||||
edit() {
|
||||
if (!this.composer || app.composer.component !== this.composer) {
|
||||
this.composer = new ComposerEdit({ post: this.props.post });
|
||||
app.composer.load(this.composer);
|
||||
}
|
||||
app.composer.show();
|
||||
}
|
||||
|
||||
hide() {
|
||||
var post = this.props.post;
|
||||
post.save({ isHidden: true });
|
||||
post.pushData({ hideTime: new Date(), hideUser: app.session.user() });
|
||||
}
|
||||
|
||||
restore() {
|
||||
var post = this.props.post;
|
||||
post.save({ isHidden: false });
|
||||
post.pushData({ hideTime: null, hideUser: null });
|
||||
}
|
||||
|
||||
delete() {
|
||||
var post = this.props.post;
|
||||
post.delete();
|
||||
this.props.ondelete && this.props.ondelete(post);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,59 +1,14 @@
|
|||
import Component from 'flarum/component';
|
||||
import icon from 'flarum/helpers/icon';
|
||||
import username from 'flarum/helpers/username';
|
||||
import humanTime from 'flarum/utils/human-time';
|
||||
import SubtreeRetainer from 'flarum/utils/subtree-retainer';
|
||||
import ItemList from 'flarum/utils/item-list';
|
||||
import ActionButton from 'flarum/components/action-button';
|
||||
import DropdownButton from 'flarum/components/dropdown-button';
|
||||
|
||||
export default class PostDiscussionRenamed extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.subtree = new SubtreeRetainer(
|
||||
() => this.props.post.freshness,
|
||||
() => this.props.post.user().freshness
|
||||
);
|
||||
}
|
||||
|
||||
view(ctrl) {
|
||||
var controls = this.controlItems().toArray();
|
||||
import PostActivity from 'flarum/components/post-activity';
|
||||
|
||||
export default class PostDiscussionRenamed extends PostActivity {
|
||||
view() {
|
||||
var post = this.props.post;
|
||||
var oldTitle = post.content()[0];
|
||||
var newTitle = post.content()[1];
|
||||
|
||||
return m('article.post.post-activity.post-discussion-renamed', this.subtree.retain() || m('div', [
|
||||
controls.length ? DropdownButton.component({
|
||||
items: controls,
|
||||
className: 'contextual-controls',
|
||||
buttonClass: 'btn btn-default btn-icon btn-sm btn-naked',
|
||||
menuClass: 'pull-right'
|
||||
}) : '',
|
||||
icon('pencil post-icon'),
|
||||
m('div.post-activity-info', [
|
||||
m('a.post-user', {href: app.route('user', { username: post.user().username() }), config: m.route}, username(post.user())),
|
||||
' changed the title from ', m('strong.old-title', oldTitle), ' to ', m('strong.new-title', newTitle), '.'
|
||||
]),
|
||||
m('div.post-activity-time', humanTime(post.time()))
|
||||
]));
|
||||
}
|
||||
|
||||
controlItems() {
|
||||
var items = new ItemList();
|
||||
var post = this.props.post;
|
||||
|
||||
if (post.canDelete()) {
|
||||
items.add('delete', ActionButton.component({ icon: 'times', label: 'Delete', onclick: this.delete.bind(this) }));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
delete() {
|
||||
var post = this.props.post;
|
||||
post.delete();
|
||||
this.props.ondelete && this.props.ondelete(post);
|
||||
return super.view(['changed the title from ', m('strong.old-title', oldTitle), ' to ', m('strong.new-title', newTitle), '.'], {
|
||||
className: 'post-discussion-renamed',
|
||||
icon: 'pencil'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
31
framework/core/js/forum/src/components/post.js
Normal file
31
framework/core/js/forum/src/components/post.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
import Component from 'flarum/component';
|
||||
import SubtreeRetainer from 'flarum/utils/subtree-retainer';
|
||||
import DropdownButton from 'flarum/components/dropdown-button';
|
||||
|
||||
export default class Post extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.subtree = new SubtreeRetainer(
|
||||
() => this.props.post.freshness,
|
||||
() => {
|
||||
var user = this.props.post.user();
|
||||
return user && user.freshness;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
view(content, attrs) {
|
||||
var controls = this.props.post.controls(this).toArray();
|
||||
|
||||
return m('article.post', attrs, this.subtree.retain() || m('div', [
|
||||
controls.length ? DropdownButton.component({
|
||||
items: controls,
|
||||
className: 'contextual-controls',
|
||||
buttonClass: 'btn btn-default btn-icon btn-sm btn-naked',
|
||||
menuClass: 'pull-right'
|
||||
}) : '',
|
||||
content
|
||||
]));
|
||||
}
|
||||
}
|
48
framework/core/js/forum/src/initializers/post-controls.js
Normal file
48
framework/core/js/forum/src/initializers/post-controls.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
import Post from 'flarum/models/post';
|
||||
import ComposerEdit from 'flarum/components/composer-edit';
|
||||
import ActionButton from 'flarum/components/action-button';
|
||||
import Separator from 'flarum/components/separator';
|
||||
import ItemList from 'flarum/utils/item-list';
|
||||
|
||||
export default function(app) {
|
||||
function editAction() {
|
||||
app.composer.load(new ComposerEdit({ post: this }));
|
||||
app.composer.show();
|
||||
}
|
||||
|
||||
function hideAction() {
|
||||
this.save({ isHidden: true });
|
||||
this.pushData({ hideTime: new Date(), hideUser: app.session.user() });
|
||||
}
|
||||
|
||||
function restoreAction() {
|
||||
this.save({ isHidden: false });
|
||||
this.pushData({ hideTime: null, hideUser: null });
|
||||
}
|
||||
|
||||
function deleteAction() {
|
||||
this.delete();
|
||||
if (app.current instanceof DiscussionPage) {
|
||||
app.current.stream().removePost(this.id());
|
||||
}
|
||||
}
|
||||
|
||||
Post.prototype.controls = function(context) {
|
||||
var items = new ItemList();
|
||||
|
||||
if (this.contentType() === 'comment' && this.canEdit()) {
|
||||
if (this.isHidden()) {
|
||||
items.add('restore', ActionButton.component({ icon: 'reply', label: 'Restore', onclick: restoreAction.bind(this) }));
|
||||
} else {
|
||||
items.add('edit', ActionButton.component({ icon: 'pencil', label: 'Edit', onclick: editAction.bind(this) }));
|
||||
items.add('hide', ActionButton.component({ icon: 'times', label: 'Delete', onclick: hideAction.bind(this) }));
|
||||
}
|
||||
}
|
||||
|
||||
if ((this.contentType() !== 'comment' || this.isHidden()) && this.canDelete()) {
|
||||
items.add('delete', ActionButton.component({ icon: 'times', label: 'Delete', onclick: deleteAction.bind(this) }));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user