1
0
mirror of https://github.com/flarum/core.git synced 2025-10-28 05:56:12 +01:00

Allow extensions to use route resolvers (#2275)

- mapRoutes: don't wrap components in resolvers if they are already resolvers
- Extract defaultResolver into its own class
- Allow either route resolver instances, or components with an optional resolverClass which should accept the component and route name in its constructor.
- Introduce a resolver for DiscussionPage, so that routing from one post to another on the same discussion triggers a scroll instead of rerendering
This commit is contained in:
Alexander Skvortsov
2020-10-15 18:01:17 -04:00
committed by GitHub
parent c1d91be2f4
commit 988b6c9023
6 changed files with 100 additions and 9 deletions

View File

@@ -0,0 +1,47 @@
import DefaultResolver from '../../common/resolvers/DefaultResolver';
/**
* This isn't exported as it is a temporary measure.
* A more robust system will be implemented alongside UTF-8 support in beta 15.
*/
function getDiscussionIdFromSlug(slug: string | undefined) {
if (!slug) return;
return slug.split('-')[0];
}
/**
* A custom route resolver for DiscussionPage that generates the same key to all posts
* on the same discussion. It triggers a scroll when going from one post to another
* in the same discussion.
*/
export default class DiscussionPageResolver extends DefaultResolver {
static scrollToPostNumber: number | null = null;
makeKey() {
const params = { ...m.route.param() };
if ('near' in params) {
delete params.near;
}
params.id = getDiscussionIdFromSlug(params.id);
return this.routeName.replace('.near', '') + JSON.stringify(params);
}
onmatch(args, requestedPath, route) {
if (route.includes('/d/:id') && getDiscussionIdFromSlug(args.id) === getDiscussionIdFromSlug(m.route.param('id'))) {
DiscussionPageResolver.scrollToPostNumber = parseInt(args.near);
}
return super.onmatch(args, requestedPath, route);
}
render(vnode) {
if (DiscussionPageResolver.scrollToPostNumber !== null) {
const number = DiscussionPageResolver.scrollToPostNumber;
// Scroll after a timeout to avoid clashes with the render.
setTimeout(() => app.current.get('stream').goToNumber(number));
DiscussionPageResolver.scrollToPostNumber = null;
}
return super.render(vnode);
}
}