framework/js/old/forum/ForumApplication.js
2020-04-18 09:02:49 -04:00

165 lines
5.0 KiB
JavaScript

import History from './utils/History';
import Pane from './utils/Pane';
import Search from './components/Search';
import ReplyComposer from './components/ReplyComposer';
import DiscussionPage from './components/DiscussionPage';
import SignUpModal from './components/SignUpModal';
import HeaderPrimary from './components/HeaderPrimary';
import HeaderSecondary from './components/HeaderSecondary';
import Composer from './components/Composer';
import DiscussionRenamedNotification from './components/DiscussionRenamedNotification';
import CommentPost from './components/CommentPost';
import DiscussionRenamedPost from './components/DiscussionRenamedPost';
import routes from './routes';
import alertEmailConfirmation from './utils/alertEmailConfirmation';
import Application from '../common/Application';
import Navigation from '../common/components/Navigation';
export default class ForumApplication extends Application {
/**
* A map of notification types to their components.
*
* @type {Object}
*/
notificationComponents = {
discussionRenamed: DiscussionRenamedNotification,
};
/**
* A map of post types to their components.
*
* @type {Object}
*/
postComponents = {
comment: CommentPost,
discussionRenamed: DiscussionRenamedPost,
};
/**
* The page's search component instance.
*
* @type {Search}
*/
search = new Search();
/**
* An object which controls the state of the page's side pane.
*
* @type {Pane}
*/
pane = null;
/**
* An object which controls the state of the page's drawer.
*
* @type {Drawer}
*/
drawer = null;
/**
* The app's history stack, which keeps track of which routes the user visits
* so that they can easily navigate back to the previous route.
*
* @type {History}
*/
history = new History();
constructor() {
super();
routes(this);
}
/**
* @inheritdoc
*/
mount() {
// Get the configured default route and update that route's path to be '/'.
// Push the homepage as the first route, so that the user will always be
// able to click on the 'back' button to go home, regardless of which page
// they started on.
const defaultRoute = this.forum.attribute('defaultRoute');
let defaultAction = 'index';
for (const i in this.routes) {
if (this.routes[i].path === defaultRoute) defaultAction = i;
}
this.routes[defaultAction].path = '/';
this.history.push(defaultAction, this.translator.trans('core.forum.header.back_to_index_tooltip'), '/');
m.mount(document.getElementById('app-navigation'), Navigation.component({ className: 'App-backControl', drawer: true }));
m.mount(document.getElementById('header-navigation'), Navigation.component());
m.mount(document.getElementById('header-primary'), HeaderPrimary.component());
m.mount(document.getElementById('header-secondary'), HeaderSecondary.component());
this.pane = new Pane(document.getElementById('app'));
this.composer = m.mount(document.getElementById('composer'), Composer.component());
m.route.mode = 'pathname';
super.mount(this.forum.attribute('basePath'));
alertEmailConfirmation(this);
// Route the home link back home when clicked. We do not want it to register
// if the user is opening it in a new tab, however.
$('#home-link').click((e) => {
if (e.ctrlKey || e.metaKey || e.which === 2) return;
e.preventDefault();
app.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());
m.redraw();
}
});
}
/**
* Check whether or not the user is currently composing a reply to a
* discussion.
*
* @param {Discussion} discussion
* @return {Boolean}
*/
composingReplyTo(discussion) {
return (
this.composer.component instanceof ReplyComposer &&
this.composer.component.props.discussion === discussion &&
this.composer.position !== Composer.PositionEnum.HIDDEN
);
}
/**
* Check whether or not the user is currently viewing a discussion.
*
* @param {Discussion} discussion
* @return {Boolean}
*/
viewingDiscussion(discussion) {
return this.current instanceof DiscussionPage && this.current.discussion === discussion;
}
/**
* Callback for when an external authenticator (social login) action has
* completed.
*
* If the payload indicates that the user has been logged in, then the page
* will be reloaded. Otherwise, a SignUpModal will be opened, prefilled
* with the provided details.
*
* @param {Object} payload A dictionary of props to pass into the sign up
* modal. A truthy `loggedIn` prop indicates that the user has logged
* in, and thus the page is reloaded.
* @public
*/
authenticationComplete(payload) {
if (payload.loggedIn) {
window.location.reload();
} else {
const modal = new SignUpModal(payload);
this.modal.show(modal);
}
}
}