forum: add RenameDiscussionModal, DiscussionRenamedPost and EventPost components

This commit is contained in:
David Sevilla Martin 2020-03-28 09:09:46 -04:00
parent 37cec1487e
commit dbc3aac14e
No known key found for this signature in database
GPG Key ID: F764F1417E16B15F
5 changed files with 184 additions and 5 deletions

View File

@ -6,6 +6,7 @@ import HeaderSecondary from './components/HeaderSecondary';
import Page from './components/Page';
import DiscussionList from './components/DiscussionList';
import CommentPost from './components/CommentPost';
import DiscussionRenamedPost from './components/DiscussionRenamedPost';
import Notification from '../common/models/Notification';
@ -29,7 +30,7 @@ export default class Forum extends Application {
postComponents = {
comment: CommentPost,
// discussionRenamed: DiscussionRenamedPost
discussionRenamed: DiscussionRenamedPost,
};
previous?: Page;
@ -74,11 +75,11 @@ export default class Forum extends Application {
$('#home-link').click((e: MouseEvent) => {
if (e.ctrlKey || e.metaKey || e.which === 2) return;
e.preventDefault();
app.history.home();
this.history.home();
// Reload the current user so that their unread notification count is refreshed.
if (app.session.user) {
app.store.find('users', app.session.user.id());
if (this.session.user) {
this.store.find('users', this.session.user.id());
m.redraw();
}
});

View File

@ -0,0 +1,29 @@
import EventPost from './EventPost';
/**
* The `DiscussionRenamedPost` component displays a discussion event post
* indicating that the discussion has been renamed.
*/
export default class DiscussionRenamedPost extends EventPost {
icon() {
return 'fas fa-pencil-alt';
}
description(data) {
const renamed = app.translator.trans('core.forum.post_stream.discussion_renamed_text', data);
const oldName = app.translator.transText('core.forum.post_stream.discussion_renamed_old_tooltip', data);
return <span title={oldName}>{renamed}</span>;
}
descriptionData() {
const post = this.props.post;
const oldTitle = post.content()[0];
const newTitle = post.content()[1];
return {
old: oldTitle,
new: <strong className="DiscussionRenamedPost-new">{newTitle}</strong>,
};
}
}

View File

@ -0,0 +1,68 @@
import Post from './Post';
import { ucfirst } from '../../common/utils/string';
import usernameHelper from '../../common/helpers/username';
import icon from '../../common/helpers/icon';
interface DescriptionData {
[key: string]: any;
}
/**
* The `EventPost` component displays a post which indicating a discussion
* event, like a discussion being renamed or stickied. Subclasses must implement
* the `icon` and `description` methods.
*/
export default abstract class EventPost extends Post {
attrs() {
const attrs = super.attrs();
attrs.className = classNames(attrs.className, 'EventPost', ucfirst(this.props.post.contentType()) + 'Post');
return attrs;
}
content() {
const user = this.props.post.user();
const username = usernameHelper(user);
const data: DescriptionData = Object.assign(this.descriptionData(), {
user,
username: user ? (
<m.route.Link className="EventPost-user" href={app.route.user(user)}>
{username}
</m.route.Link>
) : (
username
),
});
return super
.content()
.concat([icon(this.icon(), { className: 'EventPost-icon' }), <div class="EventPost-info">{this.description(data)}</div>]);
}
/**
* Get the name of the event icon.
*/
abstract icon(): string;
/**
* Get the translation data for the description of the event.
*/
abstract descriptionData(): DescriptionData;
/**
* Get the description text for the event.
*
* @return The description to render in the DOM
*/
description(data: DescriptionData): any {
return app.translator.transChoice(this.descriptionKey(), data.count, data);
}
/**
* Get the translation key for the description of the event.
*/
descriptionKey(): string {
return '';
}
}

View File

@ -0,0 +1,81 @@
import app from '../app';
import Modal from '../../common/components/Modal';
import Button from '../../common/components/Button';
import Discussion from '../../common/models/Discussion';
/**
* The 'RenameDiscussionModal' displays a modal dialog with an input to rename a discussion
*/
export default class RenameDiscussionModal extends Modal {
discussion!: Discussion;
currentTitle!: string;
newTitle!: Mithril.Stream<string>;
oninit(vnode) {
super.oninit(vnode);
this.discussion = this.props.discussion;
this.currentTitle = this.props.currentTitle;
this.newTitle = m.prop(this.currentTitle);
}
className() {
return 'RenameDiscussionModal Modal--small';
}
title() {
return app.translator.transText('core.forum.rename_discussion.title');
}
content() {
return (
<div className="Modal-body">
<div className="Form Form--centered">
<div className="Form-group">
<input className="FormControl" bidi={this.newTitle} type="text" />
</div>
<div className="Form-group">
{Button.component({
className: 'Button Button--primary Button--block',
type: 'submit',
loading: this.loading,
children: app.translator.trans('core.forum.rename_discussion.submit_button'),
})}
</div>
</div>
</div>
);
}
onsubmit(e) {
e.preventDefault();
this.loading = true;
const title = this.newTitle;
const currentTitle = this.currentTitle;
// If the title is different to what it was before, then save it. After the
// save has completed, update the post stream as there will be a new post
// indicating that the discussion was renamed.
if (title && title !== currentTitle) {
return this.discussion
.save({ title })
.then(() => {
// if (app.viewingDiscussion(this.discussion)) {
app.current.stream.update();
// }
m.redraw();
this.hide();
})
.catch(() => {
this.loading = false;
m.redraw();
});
} else {
this.hide();
}
}
}

View File

@ -3,7 +3,7 @@ import DiscussionPage from '../components/DiscussionPage';
import LogInModal from '../components/LogInModal';
import Button from '../../common/components/Button';
import Separator from '../../common/components/Separator';
// import RenameDiscussionModal from '../components/RenameDiscussionModal';
import RenameDiscussionModal from '../components/RenameDiscussionModal';
import ItemList from '../../common/utils/ItemList';
import extractText from '../../common/utils/extractText';
import Discussion from '../../common/models/Discussion';