mirror of
https://github.com/flarum/core.git
synced 2025-08-04 23:47:32 +02:00
WIP: move some things around
This commit is contained in:
@@ -1,9 +1,15 @@
|
|||||||
import * as m from 'mithril';
|
|
||||||
import Application from './lib/Application';
|
import Application from './lib/Application';
|
||||||
import routes from './routes';
|
import routes from './routes';
|
||||||
import Nav from './components/Nav';
|
import Search from './components/Search';
|
||||||
|
|
||||||
export default class ForumApplication extends Application {
|
export default class ForumApplication extends Application {
|
||||||
|
/**
|
||||||
|
* The page's search component instance.
|
||||||
|
*
|
||||||
|
* @type {SearchBox}
|
||||||
|
*/
|
||||||
|
search = new Search();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of notification types to their components.
|
* A map of notification types to their components.
|
||||||
*
|
*
|
||||||
@@ -18,23 +24,10 @@ export default class ForumApplication extends Application {
|
|||||||
*/
|
*/
|
||||||
postComponents = {};
|
postComponents = {};
|
||||||
|
|
||||||
/**
|
//app.postComponents.comment = CommentPost;
|
||||||
* The page's search component instance.
|
//app.postComponents.discussionRenamed = DiscussionRenamedPost;
|
||||||
*
|
|
||||||
* @type {SearchBox}
|
|
||||||
*/
|
|
||||||
search = new Search();
|
|
||||||
|
|
||||||
/**
|
// app.notificationComponents.discussionRenamed = DiscussionRenamedNotification;
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
mount() {
|
|
||||||
m.route.prefix('#');
|
|
||||||
|
|
||||||
super.mount();
|
|
||||||
|
|
||||||
m.mount(document.getElementById('nav'), <Nav/>);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
@@ -43,50 +36,51 @@ export default class ForumApplication extends Application {
|
|||||||
routes(router);
|
routes(router);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// TODO: work out where to put these helper functions
|
||||||
* Check whether or not the user is currently composing a reply to a
|
// /**
|
||||||
* discussion.
|
// * Check whether or not the user is currently composing a reply to a
|
||||||
*
|
// * discussion.
|
||||||
* @param {Discussion} discussion
|
// *
|
||||||
* @return {Boolean}
|
// * @param {Discussion} discussion
|
||||||
*/
|
// * @return {Boolean}
|
||||||
composingReplyTo(discussion) {
|
// */
|
||||||
return this.composer.component instanceof ReplyComposer &&
|
// composingReplyTo(discussion) {
|
||||||
this.composer.component.props.discussion === discussion &&
|
// return this.composer.component instanceof ReplyComposer &&
|
||||||
this.composer.position !== Composer.PositionEnum.HIDDEN;
|
// this.composer.component.props.discussion === discussion &&
|
||||||
}
|
// this.composer.position !== Composer.PositionEnum.HIDDEN;
|
||||||
|
// }
|
||||||
/**
|
//
|
||||||
* Check whether or not the user is currently viewing a discussion.
|
// /**
|
||||||
*
|
// * Check whether or not the user is currently viewing a discussion.
|
||||||
* @param {Discussion} discussion
|
// *
|
||||||
* @return {Boolean}
|
// * @param {Discussion} discussion
|
||||||
*/
|
// * @return {Boolean}
|
||||||
viewingDiscussion(discussion) {
|
// */
|
||||||
return this.current instanceof DiscussionPage &&
|
// viewingDiscussion(discussion) {
|
||||||
this.current.discussion === discussion;
|
// return this.current instanceof DiscussionPage &&
|
||||||
}
|
// this.current.discussion === discussion;
|
||||||
|
// }
|
||||||
/**
|
//
|
||||||
* Callback for when an external authenticator (social login) action has
|
// /**
|
||||||
* completed.
|
// * 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
|
// * If the payload indicates that the user has been logged in, then the page
|
||||||
* with the provided details.
|
// * 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 `authenticated` prop indicates that the user has logged
|
// * @param {Object} payload A dictionary of props to pass into the sign up
|
||||||
* in, and thus the page is reloaded.
|
// * modal. A truthy `authenticated` prop indicates that the user has logged
|
||||||
* @public
|
// * in, and thus the page is reloaded.
|
||||||
*/
|
// * @public
|
||||||
authenticationComplete(payload) {
|
// */
|
||||||
if (payload.authenticated) {
|
// authenticationComplete(payload) {
|
||||||
window.location.reload();
|
// if (payload.authenticated) {
|
||||||
} else {
|
// window.location.reload();
|
||||||
const modal = new SignUpModal(payload);
|
// } else {
|
||||||
this.modal.show(modal);
|
// const modal = new SignUpModal(payload);
|
||||||
modal.$('[name=password]').focus();
|
// this.modal.show(modal);
|
||||||
}
|
// modal.$('[name=password]').focus();
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
import CommentPost from 'flarum/components/CommentPost';
|
|
||||||
import DiscussionRenamedPost from 'flarum/components/DiscussionRenamedPost';
|
|
||||||
import DiscussionRenamedNotification from 'flarum/components/DiscussionRenamedNotification';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `components` initializer registers components to display the default post
|
|
||||||
* types, activity types, and notifications type with the application.
|
|
||||||
*
|
|
||||||
* @param {ForumApp} app
|
|
||||||
*/
|
|
||||||
export default function components(app) {
|
|
||||||
app.postComponents.comment = CommentPost;
|
|
||||||
app.postComponents.discussionRenamed = DiscussionRenamedPost;
|
|
||||||
|
|
||||||
app.notificationComponents.discussionRenamed = DiscussionRenamedNotification;
|
|
||||||
}
|
|
@@ -1,64 +0,0 @@
|
|||||||
import IndexPage from 'flarum/components/IndexPage';
|
|
||||||
import DiscussionPage from 'flarum/components/DiscussionPage';
|
|
||||||
import PostsUserPage from 'flarum/components/PostsUserPage';
|
|
||||||
import DiscussionsUserPage from 'flarum/components/DiscussionsUserPage';
|
|
||||||
import SettingsPage from 'flarum/components/SettingsPage';
|
|
||||||
import NotificationsPage from 'flarum/components/NotificationsPage';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `routes` initializer defines the forum app's routes.
|
|
||||||
*
|
|
||||||
* @param {App} app
|
|
||||||
*/
|
|
||||||
export default function(app) {
|
|
||||||
app.routes = {
|
|
||||||
'index': {path: '/all', component: IndexPage.component()},
|
|
||||||
'index.filter': {path: '/:filter', component: IndexPage.component()},
|
|
||||||
|
|
||||||
'discussion': {path: '/d/:id', component: DiscussionPage.component()},
|
|
||||||
'discussion.near': {path: '/d/:id/:near', component: DiscussionPage.component()},
|
|
||||||
|
|
||||||
'user': {path: '/u/:username', component: PostsUserPage.component()},
|
|
||||||
'user.posts': {path: '/u/:username', component: PostsUserPage.component()},
|
|
||||||
'user.discussions': {path: '/u/:username/discussions', component: DiscussionsUserPage.component()},
|
|
||||||
|
|
||||||
'settings': {path: '/settings', component: SettingsPage.component()},
|
|
||||||
'notifications': {path: '/notifications', component: NotificationsPage.component()}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a URL to a discussion.
|
|
||||||
*
|
|
||||||
* @param {Discussion} discussion
|
|
||||||
* @param {Integer} [near]
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
app.route.discussion = (discussion, near) => {
|
|
||||||
return app.route(near && near !== 1 ? 'discussion.near' : 'discussion', {
|
|
||||||
id: discussion.id() + '-' + discussion.slug(),
|
|
||||||
near: near && near !== 1 ? near : undefined
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a URL to a post.
|
|
||||||
*
|
|
||||||
* @param {Post} post
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
app.route.post = post => {
|
|
||||||
return app.route.discussion(post.discussion(), post.number());
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a URL to a user.
|
|
||||||
*
|
|
||||||
* @param {User} user
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
app.route.user = user => {
|
|
||||||
return app.route('user', {
|
|
||||||
username: user.username()
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
@@ -1,15 +1,58 @@
|
|||||||
import DashboardPage from './components/DashboardPage';
|
import IndexPage from './components/IndexPage';
|
||||||
import BasicsPage from './components/BasicsPage';
|
import DiscussionPage from './components/DiscussionPage';
|
||||||
import PermissionsPage from './components/PermissionsPage';
|
import PostsUserPage from './components/PostsUserPage';
|
||||||
import AppearancePage from './components/AppearancePage';
|
import DiscussionsUserPage from './components/DiscussionsUserPage';
|
||||||
import ExtensionsPage from './components/ExtensionsPage';
|
import SettingsPage from './components/SettingsPage';
|
||||||
import MailPage from './components/MailPage';
|
import NotificationsPage from './components/NotificationsPage';
|
||||||
|
|
||||||
export default function(router) {
|
export default function(router) {
|
||||||
router.add('dashboard', '/', DashboardPage);
|
router.add('index', '/all', IndexPage);
|
||||||
router.add('basics', '/basics', BasicsPage);
|
router.add('index.filter', '/:filter', IndexPage);
|
||||||
router.add('permissions', '/permissions', PermissionsPage);
|
|
||||||
router.add('appearance', '/appearance', AppearancePage);
|
router.add('discussion', '/d/:id', DiscussionPage);
|
||||||
router.add('extensions', '/extensions', ExtensionsPage);
|
router.add('discussion.near', '/d/:id/:near', DiscussionPage);
|
||||||
router.add('mail', '/mail', MailPage);
|
|
||||||
|
router.add('user', '/u/:username', PostsUserPage);
|
||||||
|
router.add('user.posts', '/u/:username', PostsUserPage);
|
||||||
|
router.add('user.discussions', '/u/:username/discussions', DiscussionsUserPage);
|
||||||
|
|
||||||
|
router.add('settings', '/settings', SettingsPage);
|
||||||
|
router.add('notifications', '/notifications', NotificationsPage);
|
||||||
|
|
||||||
|
// TODO: work out where to put these shortcut functions
|
||||||
|
// /**
|
||||||
|
// * Generate a URL to a discussion.
|
||||||
|
// *
|
||||||
|
// * @param {Discussion} discussion
|
||||||
|
// * @param {Integer} [near]
|
||||||
|
// * @return {String}
|
||||||
|
// */
|
||||||
|
// app.route.discussion = (discussion, near) => {
|
||||||
|
// return app.route(near && near !== 1 ? 'discussion.near' : 'discussion', {
|
||||||
|
// id: discussion.id() + '-' + discussion.slug(),
|
||||||
|
// near: near && near !== 1 ? near : undefined
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Generate a URL to a post.
|
||||||
|
// *
|
||||||
|
// * @param {Post} post
|
||||||
|
// * @return {String}
|
||||||
|
// */
|
||||||
|
// app.route.post = post => {
|
||||||
|
// return app.route.discussion(post.discussion(), post.number());
|
||||||
|
// };
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Generate a URL to a user.
|
||||||
|
// *
|
||||||
|
// * @param {User} user
|
||||||
|
// * @return {String}
|
||||||
|
// */
|
||||||
|
// app.route.user = user => {
|
||||||
|
// return app.route('user', {
|
||||||
|
// username: user.username()
|
||||||
|
// });
|
||||||
|
// };
|
||||||
}
|
}
|
||||||
|
@@ -1,115 +0,0 @@
|
|||||||
/**
|
|
||||||
* The `History` class keeps track and manages a stack of routes that the user
|
|
||||||
* has navigated to in their session.
|
|
||||||
*
|
|
||||||
* An item can be pushed to the top of the stack using the `push` method. An
|
|
||||||
* item in the stack has a name and a URL. The name need not be unique; if it is
|
|
||||||
* the same as the item before it, that will be overwritten with the new URL. In
|
|
||||||
* this way, if a user visits a discussion, and then visits another discussion,
|
|
||||||
* popping the history stack will still take them back to the discussion list
|
|
||||||
* rather than the previous discussion.
|
|
||||||
*/
|
|
||||||
export default class History {
|
|
||||||
constructor(defaultRoute) {
|
|
||||||
/**
|
|
||||||
* The stack of routes that have been navigated to.
|
|
||||||
*
|
|
||||||
* @type {Array}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.stack = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the item on the top of the stack.
|
|
||||||
*
|
|
||||||
* @return {Object}
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
getCurrent() {
|
|
||||||
return this.stack[this.stack.length - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the previous item on the stack.
|
|
||||||
*
|
|
||||||
* @return {Object}
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
getPrevious() {
|
|
||||||
return this.stack[this.stack.length - 2];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Push an item to the top of the stack.
|
|
||||||
*
|
|
||||||
* @param {String} name The name of the route.
|
|
||||||
* @param {String} title The title of the route.
|
|
||||||
* @param {String} [url] The URL of the route. The current URL will be used if
|
|
||||||
* not provided.
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
push(name, title, url = m.route()) {
|
|
||||||
// If we're pushing an item with the same name as second-to-top item in the
|
|
||||||
// stack, we will assume that the user has clicked the 'back' button in
|
|
||||||
// their browser. In this case, we don't want to push a new item, so we will
|
|
||||||
// pop off the top item, and then the second-to-top item will be overwritten
|
|
||||||
// below.
|
|
||||||
const secondTop = this.stack[this.stack.length - 2];
|
|
||||||
if (secondTop && secondTop.name === name) {
|
|
||||||
this.stack.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're pushing an item with the same name as the top item in the stack,
|
|
||||||
// then we'll overwrite it with the new URL.
|
|
||||||
const top = this.getCurrent();
|
|
||||||
if (top && top.name === name) {
|
|
||||||
Object.assign(top, {url, title});
|
|
||||||
} else {
|
|
||||||
this.stack.push({name, url, title});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether or not the history stack is able to be popped.
|
|
||||||
*
|
|
||||||
* @return {Boolean}
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
canGoBack() {
|
|
||||||
return this.stack.length > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Go back to the previous route in the history stack.
|
|
||||||
*
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
back() {
|
|
||||||
this.stack.pop();
|
|
||||||
|
|
||||||
m.route(this.getCurrent().url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the URL of the previous page.
|
|
||||||
*
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
backUrl() {
|
|
||||||
const secondTop = this.stack[this.stack.length - 2];
|
|
||||||
|
|
||||||
return secondTop.url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Go to the first route in the history stack.
|
|
||||||
*
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
home() {
|
|
||||||
this.stack.splice(0);
|
|
||||||
|
|
||||||
m.route('/');
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,3 +1,4 @@
|
|||||||
|
import * as m from 'mithril';
|
||||||
import ItemList from 'flarum/utils/ItemList';
|
import ItemList from 'flarum/utils/ItemList';
|
||||||
import Alert from 'flarum/components/Alert';
|
import Alert from 'flarum/components/Alert';
|
||||||
import Button from 'flarum/components/Button';
|
import Button from 'flarum/components/Button';
|
||||||
@@ -19,6 +20,7 @@ export default class Application {
|
|||||||
constructor() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
* [data description]
|
* [data description]
|
||||||
|
*
|
||||||
* @type {[type]}
|
* @type {[type]}
|
||||||
*/
|
*/
|
||||||
this.data = null;
|
this.data = null;
|
||||||
@@ -33,6 +35,7 @@ export default class Application {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* [router description]
|
* [router description]
|
||||||
|
*
|
||||||
* @type {Router}
|
* @type {Router}
|
||||||
*/
|
*/
|
||||||
this.router = new Router();
|
this.router = new Router();
|
||||||
@@ -72,12 +75,14 @@ export default class Application {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* [title description]
|
* [title description]
|
||||||
|
*
|
||||||
* @type {DocumentTitle}
|
* @type {DocumentTitle}
|
||||||
*/
|
*/
|
||||||
this.title = new DocumentTitle();
|
this.title = new DocumentTitle();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [ajax description]
|
* [ajax description]
|
||||||
|
*
|
||||||
* @type {Ajax}
|
* @type {Ajax}
|
||||||
*/
|
*/
|
||||||
this.ajax = new Ajax();
|
this.ajax = new Ajax();
|
||||||
@@ -91,6 +96,7 @@ export default class Application {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* [loadModules description]
|
* [loadModules description]
|
||||||
|
*
|
||||||
* @param {[type]} modules [description]
|
* @param {[type]} modules [description]
|
||||||
* @return {[type]}
|
* @return {[type]}
|
||||||
*/
|
*/
|
||||||
@@ -98,11 +104,11 @@ export default class Application {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*
|
/**
|
||||||
* Boot the application by running all of the registered initializers.
|
* Boot the application by running all of the registered initializers.
|
||||||
*
|
*
|
||||||
* @public
|
* @public
|
||||||
|
*/
|
||||||
boot(data) {
|
boot(data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
|
||||||
|
3
js/lib/DocumentTitle.tsx
Normal file
3
js/lib/DocumentTitle.tsx
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export default class DocumentTitle {
|
||||||
|
|
||||||
|
}
|
@@ -1,26 +0,0 @@
|
|||||||
import Store from 'flarum/Store';
|
|
||||||
import Forum from 'flarum/models/Forum';
|
|
||||||
import User from 'flarum/models/User';
|
|
||||||
import Discussion from 'flarum/models/Discussion';
|
|
||||||
import Post from 'flarum/models/Post';
|
|
||||||
import Group from 'flarum/models/Group';
|
|
||||||
import Activity from 'flarum/models/Activity';
|
|
||||||
import Notification from 'flarum/models/Notification';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `store` initializer creates the application's data store and registers
|
|
||||||
* the default resource types to their models.
|
|
||||||
*
|
|
||||||
* @param {App} app
|
|
||||||
*/
|
|
||||||
export default function store(app) {
|
|
||||||
app.store = new Store({
|
|
||||||
forums: Forum,
|
|
||||||
users: User,
|
|
||||||
discussions: Discussion,
|
|
||||||
posts: Post,
|
|
||||||
groups: Group,
|
|
||||||
activity: Activity,
|
|
||||||
notifications: Notification
|
|
||||||
});
|
|
||||||
}
|
|
@@ -1,20 +0,0 @@
|
|||||||
/**
|
|
||||||
* The `mixin` utility assigns the properties of a set of 'mixin' objects to
|
|
||||||
* the prototype of a parent object.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* class MyClass extends mixin(ExistingClass, evented, etc) {}
|
|
||||||
*
|
|
||||||
* @param {Class} Parent The class to extend the new class from.
|
|
||||||
* @param {...Object} mixins The objects to mix in.
|
|
||||||
* @return {Class} A new class that extends Parent and contains the mixins.
|
|
||||||
*/
|
|
||||||
export default function mixin(Parent, ...mixins) {
|
|
||||||
class Mixed extends Parent {}
|
|
||||||
|
|
||||||
mixins.forEach(object => {
|
|
||||||
Object.assign(Mixed.prototype, object);
|
|
||||||
});
|
|
||||||
|
|
||||||
return Mixed;
|
|
||||||
}
|
|
Reference in New Issue
Block a user