Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce frontend extenders #3645

Merged
merged 10 commits into from
Jan 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions extensions/flags/js/src/forum/extend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Extend from 'flarum/common/extenders';
import FlagsPage from './components/FlagsPage';

export default [new Extend.Routes().add('flags', '/flags', FlagsPage)];
4 changes: 2 additions & 2 deletions extensions/flags/js/src/forum/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import addFlagControl from './addFlagControl';
import addFlagsDropdown from './addFlagsDropdown';
import addFlagsToPosts from './addFlagsToPosts';

export { default as extend } from './extend';

app.initializers.add('flarum-flags', () => {
Post.prototype.flags = Model.hasMany<Flag>('flags');
Post.prototype.canFlag = Model.attribute<boolean>('canFlag');

app.store.models.flags = Flag;

app.routes.flags = { path: '/flags', component: FlagsPage };

app.flags = new FlagListState(app);

addFlagControl();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@ import { extend } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import UserPage from 'flarum/forum/components/UserPage';
import LinkButton from 'flarum/common/components/LinkButton';
import LikesUserPage from './components/LikesUserPage';
import ItemList from 'flarum/common/utils/ItemList';
import type Mithril from 'mithril';

export default function addLikesTabToUserProfile() {
app.routes['user.likes'] = { path: '/u/:username/likes', component: LikesUserPage };
extend(UserPage.prototype, 'navItems', function (items: ItemList<Mithril.Children>) {
const user = this.user;
items.add(
'likes',
<LinkButton href={app.route('user.likes', { username: user.slug() })} icon="far fa-thumbs-up">
<LinkButton href={app.route('user.likes', { username: user?.slug() })} icon="far fa-thumbs-up">
{app.translator.trans('flarum-likes.forum.user.likes_link')}
</LinkButton>,
88
Expand Down
4 changes: 4 additions & 0 deletions extensions/likes/js/src/forum/extend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Extend from 'flarum/common/extenders';
import LikesUserPage from './components/LikesUserPage';

export default [new Extend.Routes().add('user.likes', '/u/:username/likes', LikesUserPage)];
2 changes: 2 additions & 0 deletions extensions/likes/js/src/forum/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import addLikesList from './addLikesList';
import PostLikedNotification from './components/PostLikedNotification';
import addLikesTabToUserProfile from './addLikesTabToUserProfile';

export { default as extend } from './extend';

app.initializers.add('flarum-likes', () => {
app.notificationComponents.postLiked = PostLikedNotification;

Expand Down
20 changes: 20 additions & 0 deletions extensions/likes/js/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// Use Flarum's tsconfig as a starting point
"extends": "flarum-tsconfig",
// This will match all .ts, .tsx, .d.ts, .js, .jsx files in your `src` folder
// and also tells your Typescript server to read core's global typings for
// access to `dayjs` and `$` in the global namespace.
"include": ["src/**/*", "../../../framework/core/js/dist-typings/@types/**/*", "@types/**/*"],
"compilerOptions": {
// This will output typings to `dist-typings`
"declarationDir": "./dist-typings",
"paths": {
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
// TODO: remove after export registry system implemented
// Without this, the old-style `@flarum/core` import is resolved to
// source code in flarum/core instead of the dist typings.
// This causes an inaccurate "duplicate export" error.
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"],
}
}
}
4 changes: 4 additions & 0 deletions extensions/lock/js/src/forum/extend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Extend from 'flarum/common/extenders';
import DiscussionLockedPost from './components/DiscussionLockedPost';

export default [new Extend.PostTypes().add('discussionLocked', DiscussionLockedPost)];
4 changes: 2 additions & 2 deletions extensions/lock/js/src/forum/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import Model from 'flarum/common/Model';
import Discussion from 'flarum/common/models/Discussion';
import NotificationGrid from 'flarum/forum/components/NotificationGrid';

import DiscussionLockedPost from './components/DiscussionLockedPost';
import DiscussionLockedNotification from './components/DiscussionLockedNotification';
import addLockBadge from './addLockBadge';
import addLockControl from './addLockControl';

export { default as extend } from './extend';

app.initializers.add('flarum-lock', () => {
app.postComponents.discussionLocked = DiscussionLockedPost;
app.notificationComponents.discussionLocked = DiscussionLockedNotification;

Discussion.prototype.isLocked = Model.attribute('isLocked');
Expand Down
20 changes: 20 additions & 0 deletions extensions/lock/js/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// Use Flarum's tsconfig as a starting point
"extends": "flarum-tsconfig",
// This will match all .ts, .tsx, .d.ts, .js, .jsx files in your `src` folder
// and also tells your Typescript server to read core's global typings for
// access to `dayjs` and `$` in the global namespace.
"include": ["src/**/*", "../../../framework/core/js/dist-typings/@types/**/*", "@types/**/*"],
"compilerOptions": {
// This will output typings to `dist-typings`
"declarationDir": "./dist-typings",
"paths": {
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
// TODO: remove after export registry system implemented
// Without this, the old-style `@flarum/core` import is resolved to
// source code in flarum/core instead of the dist typings.
// This causes an inaccurate "duplicate export" error.
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"],
}
}
}
4 changes: 4 additions & 0 deletions extensions/mentions/js/src/forum/extend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Extend from 'flarum/common/extenders';
import MentionsUserPage from './components/MentionsUserPage';

export default [new Extend.Routes().add('user.mentions', '/u/:username/mentions', MentionsUserPage)];
4 changes: 2 additions & 2 deletions extensions/mentions/js/src/forum/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import UserMentionedNotification from './components/UserMentionedNotification';
import GroupMentionedNotification from './components/GroupMentionedNotification';
import UserPage from 'flarum/forum/components/UserPage';
import LinkButton from 'flarum/common/components/LinkButton';
import MentionsUserPage from './components/MentionsUserPage';
import User from 'flarum/common/models/User';
import Model from 'flarum/common/Model';

export { default as extend } from './extend';

app.initializers.add('flarum-mentions', function () {
User.prototype.canMentionGroups = Model.attribute('canMentionGroups');

Expand Down Expand Up @@ -65,7 +66,6 @@ app.initializers.add('flarum-mentions', function () {
});

// Add mentions tab in user profile
app.routes['user.mentions'] = { path: '/u/:username/mentions', component: MentionsUserPage };
extend(UserPage.prototype, 'navItems', function (items) {
const user = this.user;
items.add(
Expand Down
20 changes: 20 additions & 0 deletions extensions/mentions/js/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// Use Flarum's tsconfig as a starting point
"extends": "flarum-tsconfig",
// This will match all .ts, .tsx, .d.ts, .js, .jsx files in your `src` folder
// and also tells your Typescript server to read core's global typings for
// access to `dayjs` and `$` in the global namespace.
"include": ["src/**/*", "../../../framework/core/js/dist-typings/@types/**/*", "@types/**/*"],
"compilerOptions": {
// This will output typings to `dist-typings`
"declarationDir": "./dist-typings",
"paths": {
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
// TODO: remove after export registry system implemented
// Without this, the old-style `@flarum/core` import is resolved to
// source code in flarum/core instead of the dist typings.
// This causes an inaccurate "duplicate export" error.
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"],
}
}
}
4 changes: 4 additions & 0 deletions extensions/sticky/js/src/forum/extend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Extend from 'flarum/common/extenders';
import DiscussionStickiedPost from './components/DiscussionStickiedPost';

export default [new Extend.PostTypes().add('discussionStickied', DiscussionStickiedPost)];
5 changes: 2 additions & 3 deletions extensions/sticky/js/src/forum/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ import app from 'flarum/forum/app';
import Model from 'flarum/common/Model';
import Discussion from 'flarum/common/models/Discussion';

import DiscussionStickiedPost from './components/DiscussionStickiedPost';
import addStickyBadge from './addStickyBadge';
import addStickyControl from './addStickyControl';
import addStickyExcerpt from './addStickyExcerpt';
import addStickyClass from './addStickyClass';

app.initializers.add('flarum-sticky', () => {
app.postComponents.discussionStickied = DiscussionStickiedPost;
export { default as extend } from './extend';

app.initializers.add('flarum-sticky', () => {
Discussion.prototype.isSticky = Model.attribute('isSticky');
Discussion.prototype.canSticky = Model.attribute('canSticky');

Expand Down
20 changes: 20 additions & 0 deletions extensions/sticky/js/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// Use Flarum's tsconfig as a starting point
"extends": "flarum-tsconfig",
// This will match all .ts, .tsx, .d.ts, .js, .jsx files in your `src` folder
// and also tells your Typescript server to read core's global typings for
// access to `dayjs` and `$` in the global namespace.
"include": ["src/**/*", "../../../framework/core/js/dist-typings/@types/**/*", "@types/**/*"],
"compilerOptions": {
// This will output typings to `dist-typings`
"declarationDir": "./dist-typings",
"paths": {
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
// TODO: remove after export registry system implemented
// Without this, the old-style `@flarum/core` import is resolved to
// source code in flarum/core instead of the dist typings.
// This causes an inaccurate "duplicate export" error.
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"],
}
}
}
4 changes: 4 additions & 0 deletions extensions/subscriptions/js/src/forum/extend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Extend from 'flarum/common/extenders';
import IndexPage from 'flarum/forum/components/IndexPage';

export default [new Extend.Routes().add('following', '/following', IndexPage)];
4 changes: 2 additions & 2 deletions extensions/subscriptions/js/src/forum/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { extend } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import Model from 'flarum/common/Model';
import Discussion from 'flarum/common/models/Discussion';
import IndexPage from 'flarum/forum/components/IndexPage';
import NotificationGrid from 'flarum/forum/components/NotificationGrid';

import addSubscriptionBadge from './addSubscriptionBadge';
Expand All @@ -12,8 +11,9 @@ import addSubscriptionSettings from './addSubscriptionSettings';

import NewPostNotification from './components/NewPostNotification';

export { default as extend } from './extend';

app.initializers.add('subscriptions', function () {
app.routes.following = { path: '/following', component: IndexPage };
app.notificationComponents.newPost = NewPostNotification;

Discussion.prototype.subscription = Model.attribute('subscription');
Expand Down
14 changes: 14 additions & 0 deletions extensions/tags/js/src/forum/extend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import app from 'flarum/forum/app';
import Extend from 'flarum/common/extenders';
import IndexPage from 'flarum/forum/components/IndexPage';
import DiscussionTaggedPost from './components/DiscussionTaggedPost';
import TagsPage from './components/TagsPage';

export default [
new Extend.Routes()
.add('tags', '/tags', TagsPage)
.add('tag', '/t/:tags', IndexPage)
.helper('tag', (tag) => app.route('tag', { tags: tag.slug() })),

new Extend.PostTypes().add('discussionTagged', DiscussionTaggedPost),
];
12 changes: 2 additions & 10 deletions extensions/tags/js/src/forum/index.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
import app from 'flarum/forum/app';
import Model from 'flarum/common/Model';
import Discussion from 'flarum/common/models/Discussion';
import IndexPage from 'flarum/forum/components/IndexPage';

import TagListState from '../common/states/TagListState';
import Tag from '../common/models/Tag';
import TagsPage from './components/TagsPage';
import DiscussionTaggedPost from './components/DiscussionTaggedPost';

import addTagList from './addTagList';
import addTagFilter from './addTagFilter';
import addTagLabels from './addTagLabels';
import addTagControl from './addTagControl';
import addTagComposer from './addTagComposer';

app.initializers.add('flarum-tags', function () {
app.routes.tags = { path: '/tags', component: TagsPage };
app.routes.tag = { path: '/t/:tags', component: IndexPage };

app.route.tag = (tag: Tag) => app.route('tag', { tags: tag.slug() });

app.postComponents.discussionTagged = DiscussionTaggedPost;
export { default as extend } from './extend';

app.initializers.add('flarum-tags', function () {
app.store.models.tags = Tag;

app.tagList = new TagListState();
Expand Down
5 changes: 2 additions & 3 deletions framework/core/js/src/common/Application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import type { ComponentAttrs } from './Component';
import Model, { SavedModelData } from './Model';
import fireApplicationError from './helpers/fireApplicationError';
import IHistory from './IHistory';
import IExtender from './extenders/IExtender';

export type FlarumScreens = 'phone' | 'tablet' | 'desktop' | 'desktop-hd';

Expand Down Expand Up @@ -300,8 +301,7 @@ export default class Application {
caughtInitializationErrors.forEach((handler) => handler());
}

// TODO: This entire system needs a do-over for v2
public bootExtensions(extensions: Record<string, { extend?: unknown[] }>) {
public bootExtensions(extensions: Record<string, { extend?: IExtender[] }>) {
Object.keys(extensions).forEach((name) => {
const extension = extensions[name];

Expand All @@ -311,7 +311,6 @@ export default class Application {
const extenders = extension.extend.flat(Infinity);

for (const extender of extenders) {
// @ts-expect-error This is beyond saving atm.
extender.extend(this, { name, exports: extension });
}
});
Expand Down
5 changes: 3 additions & 2 deletions framework/core/js/src/common/compat.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @ts-expect-error We need to explicitly use the prefix to distinguish between the extend folder.
import * as extend from './extend.ts';
import * as extend from './extend';
import extenders from './extenders';
import Session from './Session';
import Store from './Store';
import BasicEditorDriver from './utils/BasicEditorDriver';
Expand Down Expand Up @@ -90,6 +90,7 @@ import ModalManagerState from './states/ModalManagerState';
import PageState from './states/PageState';

export default {
extenders,
extend: extend,
Session: Session,
Store: Store,
Expand Down
41 changes: 0 additions & 41 deletions framework/core/js/src/common/extend/Model.js

This file was deleted.

13 changes: 0 additions & 13 deletions framework/core/js/src/common/extend/PostTypes.js

This file was deleted.

13 changes: 0 additions & 13 deletions framework/core/js/src/common/extend/Routes.js

This file was deleted.

3 changes: 0 additions & 3 deletions framework/core/js/src/common/extend/index.js

This file was deleted.

Loading