mirror of
https://github.com/flarum/framework.git
synced 2024-11-22 14:41:39 +08:00
revert Application implementation from experimental breaking change to use existing implementation in master
This commit is contained in:
parent
4484f3e35f
commit
ef47e09300
32237
js/dist/forum.js
vendored
32237
js/dist/forum.js
vendored
File diff suppressed because it is too large
Load Diff
2
js/dist/forum.js.map
vendored
2
js/dist/forum.js.map
vendored
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,5 @@
|
|||
import Mithril from 'mithril';
|
||||
|
||||
import Bus from './Bus';
|
||||
import Translator from './Translator';
|
||||
import Session from './Session';
|
||||
import Store from './Store';
|
||||
|
@ -10,6 +9,8 @@ import extract from './utils/extract';
|
|||
import mapRoutes from './utils/mapRoutes';
|
||||
import Drawer from './utils/Drawer';
|
||||
import RequestError from './utils/RequestError';
|
||||
import ItemList from './utils/ItemList';
|
||||
import ScrollListener from './utils/ScrollListener';
|
||||
|
||||
import Forum from './models/Forum';
|
||||
import Discussion from './models/Discussion';
|
||||
|
@ -23,6 +24,8 @@ import Button from './components/Button';
|
|||
import ModalManager from './components/ModalManager';
|
||||
import RequestErrorModal from './components/RequestErrorModal';
|
||||
|
||||
import { flattenDeep } from 'lodash-es';
|
||||
|
||||
export type ApplicationData = {
|
||||
apiDocument: any;
|
||||
locale: string;
|
||||
|
@ -35,22 +38,39 @@ export default abstract class Application {
|
|||
/**
|
||||
* The forum model for this application.
|
||||
*/
|
||||
forum: Forum;
|
||||
public forum!: Forum;
|
||||
|
||||
data: ApplicationData;
|
||||
/**
|
||||
* A map of routes, keyed by a unique route name. Each route is an object
|
||||
* containing the following properties:
|
||||
*
|
||||
* - `path` The path that the route is accessed at.
|
||||
* - `component` The Mithril component to render when this route is active.
|
||||
*
|
||||
* @example
|
||||
* app.routes.discussion = {path: '/d/:id', component: DiscussionPage.component()};
|
||||
*/
|
||||
public routes: { [key: string]: { path: string; component: any; [key: string]: any } } = {};
|
||||
|
||||
translator = new Translator();
|
||||
bus = new Bus();
|
||||
/**
|
||||
* An ordered list of initializers to bootstrap the application.
|
||||
*/
|
||||
public initializers = new ItemList();
|
||||
|
||||
/**
|
||||
* The app's session.
|
||||
*/
|
||||
session: Session;
|
||||
public session!: Session;
|
||||
|
||||
/**
|
||||
* The app's translator.
|
||||
*/
|
||||
public translator = new Translator();
|
||||
|
||||
/**
|
||||
* The app's data store.
|
||||
*/
|
||||
store = new Store({
|
||||
public store = new Store({
|
||||
forums: Forum,
|
||||
users: User,
|
||||
discussions: Discussion,
|
||||
|
@ -59,37 +79,38 @@ export default abstract class Application {
|
|||
notifications: Notification,
|
||||
});
|
||||
|
||||
drawer = new Drawer();
|
||||
|
||||
modal: ModalManager;
|
||||
|
||||
/**
|
||||
* A local cache that can be used to store data at the application level, so
|
||||
* that is persists between different routes.
|
||||
*/
|
||||
cache: { [key: string]: any } = {};
|
||||
public cache: { [key: string]: any } = {};
|
||||
|
||||
routes = {};
|
||||
|
||||
title = '';
|
||||
titleCount = 0;
|
||||
/**
|
||||
* Whether or not the app has been booted.
|
||||
*/
|
||||
public booted: boolean = false;
|
||||
|
||||
/**
|
||||
* An Alert that was shown as a result of an AJAX request error. If present,
|
||||
* it will be dismissed on the next successful request.
|
||||
*/
|
||||
private requestError: Alert = null;
|
||||
private requestError: Alert | null = null;
|
||||
|
||||
mount(basePath = '') {
|
||||
m.mount(document.getElementById('modal'), new ModalManager());
|
||||
data!: ApplicationData;
|
||||
|
||||
// this.alerts = m.mount(document.getElementById('alerts'), <AlertManager />);
|
||||
title = '';
|
||||
titleCount = 0;
|
||||
|
||||
m.route(document.getElementById('content'), basePath + '/', mapRoutes(this.routes, basePath));
|
||||
drawer = new Drawer();
|
||||
modal!: ModalManager;
|
||||
|
||||
load(payload) {
|
||||
this.data = payload;
|
||||
this.translator.locale = payload.locale;
|
||||
}
|
||||
|
||||
boot(payload: any) {
|
||||
this.data = payload;
|
||||
boot() {
|
||||
this.initializers.toArray().forEach(initializer => initializer(this));
|
||||
|
||||
this.store.pushPayload({ data: this.data.resources });
|
||||
|
||||
|
@ -97,26 +118,42 @@ export default abstract class Application {
|
|||
|
||||
this.session = new Session(this.store.getById('users', this.data.session.userId), this.data.session.csrfToken);
|
||||
|
||||
this.locale();
|
||||
this.plugins();
|
||||
this.setupRoutes();
|
||||
this.mount();
|
||||
|
||||
this.bus.dispatch('app.booting');
|
||||
this.booted = true;
|
||||
}
|
||||
|
||||
locale() {
|
||||
this.translator.locale = this.data.locale;
|
||||
bootExtensions(extensions) {
|
||||
Object.keys(extensions).forEach(name => {
|
||||
const extension = extensions[name];
|
||||
|
||||
this.bus.dispatch('app.locale');
|
||||
const extenders = flattenDeep(extension.extend);
|
||||
|
||||
for (const extender of extenders) {
|
||||
extender.extend(this, { name, exports: extension });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
plugins() {
|
||||
this.bus.dispatch('app.plugins');
|
||||
}
|
||||
mount(basePath = '') {
|
||||
m.mount(document.getElementById('modal'), new ModalManager());
|
||||
|
||||
setupRoutes() {
|
||||
this.bus.dispatch('app.routes');
|
||||
// this.alerts = m.mount(document.getElementById('alerts'), <AlertManager />);
|
||||
|
||||
m.route(document.getElementById('content'), basePath + '/', mapRoutes(this.routes, basePath));
|
||||
|
||||
// Add a class to the body which indicates that the page has been scrolled
|
||||
// down.
|
||||
new ScrollListener(top => {
|
||||
const $app = $('#app');
|
||||
const offset = $app.offset().top;
|
||||
|
||||
$app.toggleClass('affix', top >= offset).toggleClass('scrolled', top > offset);
|
||||
}).start();
|
||||
|
||||
$(() => {
|
||||
$('body').addClass('ontouchstart' in window ? 'touch' : 'no-touch');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,44 +3,24 @@ import History from './utils/History';
|
|||
|
||||
import HeaderPrimary from './components/HeaderPrimary';
|
||||
import HeaderSecondary from './components/HeaderSecondary';
|
||||
|
||||
import Page from './components/Page';
|
||||
import IndexPage from './components/IndexPage';
|
||||
import DiscussionList from './components/DiscussionList';
|
||||
import DiscussionPage from './components/DiscussionPage';
|
||||
import PostsUserPage from './components/PostsUserPage';
|
||||
import DiscussionsUserPage from './components/DiscussionsUserPage';
|
||||
import SettingsPage from './components/SettingsPage';
|
||||
|
||||
import CommentPost from './components/CommentPost';
|
||||
|
||||
import User from '../common/models/User';
|
||||
import Post from '../common/models/Post';
|
||||
import Discussion from '../common/models/Discussion';
|
||||
import Notification from '../common/models/Notification';
|
||||
|
||||
import routes from './routes';
|
||||
|
||||
export default class Forum extends Application {
|
||||
routes = {
|
||||
index: { path: '/all', component: IndexPage },
|
||||
|
||||
discussion: { path: '/d/:id', component: DiscussionPage },
|
||||
'discussion.near': { path: '/d/:id/:near', component: DiscussionPage },
|
||||
|
||||
user: { path: '/u/:username', component: PostsUserPage },
|
||||
'user.posts': { path: '/u/:username', component: PostsUserPage },
|
||||
'user.discussions': { path: '/u/:username/discussions', component: DiscussionsUserPage },
|
||||
|
||||
settings: { path: '/settings', component: SettingsPage },
|
||||
|
||||
'index.filter': { path: '/:filter', component: IndexPage },
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
history: History = new History();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
cache: {
|
||||
notifications?: Notification[][];
|
||||
discussionList?: DiscussionList;
|
||||
|
@ -55,6 +35,12 @@ export default class Forum extends Application {
|
|||
previous: Page;
|
||||
current: Page;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
routes(this);
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -97,36 +83,4 @@ export default class Forum extends Application {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
setupRoutes() {
|
||||
super.setupRoutes();
|
||||
|
||||
this.route.discussion = (discussion: Discussion, near?: number): string => {
|
||||
const slug = discussion?.slug();
|
||||
const hasNear = near && near !== 1;
|
||||
const params = {
|
||||
id: discussion.id() + (slug.trim() ? '-' + slug : ''),
|
||||
};
|
||||
|
||||
if (hasNear) params['near'] = near;
|
||||
|
||||
return this.route(near && near !== 1 ? 'discussion.near' : 'discussion', params);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a URL to a post.
|
||||
*/
|
||||
this.route.post = (post: Post): string => {
|
||||
return this.route.discussion(post.discussion(), post.number());
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a URL to a user.
|
||||
*/
|
||||
this.route.user = (user: User): string => {
|
||||
return this.route('user', {
|
||||
username: user.username(),
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,17 +5,6 @@ const app = new Forum();
|
|||
// @ts-ignore
|
||||
window.app = app;
|
||||
|
||||
app.bus.subscribe('app.plugins', () => {
|
||||
// @ts-ignore
|
||||
const extensions = flarum.extensions;
|
||||
|
||||
Object.keys(extensions).forEach(name => {
|
||||
const extension = extensions[name];
|
||||
|
||||
// if (typeof extension === 'function') extension();
|
||||
});
|
||||
});
|
||||
|
||||
export { app };
|
||||
|
||||
// Export compat API
|
||||
|
|
57
js/src/forum/routes.ts
Normal file
57
js/src/forum/routes.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
import IndexPage from './components/IndexPage';
|
||||
import DiscussionPage from './components/DiscussionPage';
|
||||
import PostsUserPage from './components/PostsUserPage';
|
||||
import DiscussionsUserPage from './components/DiscussionsUserPage';
|
||||
import SettingsPage from './components/SettingsPage';
|
||||
|
||||
import Discussion from '../common/models/Discussion';
|
||||
import Post from '../common/models/Post';
|
||||
import User from '../common/models/User';
|
||||
|
||||
export default app => {
|
||||
app.routes = {
|
||||
index: { path: '/all', component: IndexPage },
|
||||
|
||||
discussion: { path: '/d/:id', component: DiscussionPage },
|
||||
'discussion.near': { path: '/d/:id/:near', component: DiscussionPage },
|
||||
|
||||
user: { path: '/u/:username', component: PostsUserPage },
|
||||
'user.posts': { path: '/u/:username', component: PostsUserPage },
|
||||
'user.discussions': { path: '/u/:username/discussions', component: DiscussionsUserPage },
|
||||
|
||||
settings: { path: '/settings', component: SettingsPage },
|
||||
|
||||
'index.filter': { path: '/:filter', component: IndexPage },
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a URL to a discussion.
|
||||
*/
|
||||
app.route.discussion = (discussion: Discussion, near?: number): string => {
|
||||
const slug = discussion?.slug();
|
||||
const hasNear = near && near !== 1;
|
||||
const params = {
|
||||
id: discussion.id() + (slug.trim() ? '-' + slug : ''),
|
||||
};
|
||||
|
||||
if (hasNear) params['near'] = near;
|
||||
|
||||
return app.route(hasNear ? 'discussion.near' : 'discussion', params);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a URL to a post.
|
||||
*/
|
||||
app.route.post = (post: Post): string => {
|
||||
return app.route.discussion(post.discussion(), post.number());
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a URL to a user.
|
||||
*/
|
||||
app.route.user = (user: User): string => {
|
||||
return app.route('user', {
|
||||
username: user.username(),
|
||||
});
|
||||
};
|
||||
};
|
|
@ -25,9 +25,9 @@
|
|||
document.getElementById('flarum-loading').style.display = 'none';
|
||||
|
||||
try {
|
||||
app.boot(@json($payload));
|
||||
// flarum.core.app.bootExtensions(flarum.extensions);
|
||||
// flarum.core.app.boot();
|
||||
flarum.core.app.load(@json($payload));
|
||||
flarum.core.app.bootExtensions(flarum.extensions);
|
||||
flarum.core.app.boot();
|
||||
} catch (e) {
|
||||
var error = document.getElementById('flarum-loading-error');
|
||||
error.innerHTML += document.getElementById('flarum-content').textContent;
|
||||
|
|
Loading…
Reference in New Issue
Block a user