1
0
mirror of https://github.com/flarum/core.git synced 2025-08-06 08:27:42 +02:00

feat: Code Splitting (#3860)

* feat: configure webpack to allow splitting chunks
* feat: `JsDirectoryCompiler` and expose js assets URL
* chore: support es2020 dynamic importing
* feat: control which URL to fetch chunks from
* feat: allow showing async modals & split 'LogInModal'
* feat: split `SignUpModal`
* feat: allow rendering async pages & split `UserSecurityPage`
* fix: module might not be listed in chunk
* feat: lazy load user pages
* feat: track the chunk containing each module
* chore: lightly warn
* chore: split `Composer`
* feat: add common frontend (for split common chunks)
* fix: jsDoc typing imports should be ignored
* feat: split `PostStream` `ForgotPasswordModal` and `EditUserModal`
* fix: multiple inline async imports not picked up
* chore: new `common` frontend assets only needs a jsdir compiler
* feat: add revision hash to chunk import URL
* fix: nothing to split for `admin` frontend yet
* chore: cleanup registry API
* chore: throw an error in debug mode if attempting to import a non-loaded module
* feat: defer `extend` & `override` until after module registration
* fix: plugin not picking up on all module sources
* fix: must override default chunk loader function from webpack plugin
* feat: split tags `TagDiscussionModal` and `TagSelectionModal`
* fix: wrong export name
* feat: import chunked modules from external packages
* feat: extensions compatibility
* feat: Router frontend extender async component
* chore: clean JS output path (removes stale chunks)
* fix: common chunks also need flushing
* chore: flush backend stale chunks
* Apply fixes from StyleCI
* feat: loading alert when async page component is loading
* chore: `yarn format`
* chore: typings
* chore: remove exception
* Apply fixes from StyleCI
* chore(infra): bundlewatch
* chore(infra): bundlewatch split chunks
* feat: split text editor
* chore: tag typings
* chore: bundlewatch
* fix: windows paths
* fix: wrong planned ext import format
This commit is contained in:
Sami Mazouz
2023-08-02 17:57:57 +01:00
committed by GitHub
parent 2ffbc44b4e
commit 229a7affa5
87 changed files with 1217 additions and 304 deletions

View File

@@ -4,8 +4,6 @@ import { override, extend } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import Stream from 'flarum/common/utils/Stream';
import ForumApplication from 'flarum/forum/ForumApplication';
import Composer from 'flarum/forum/components/Composer';
import PostStream from 'flarum/forum/components/PostStream';
import ModalManager from 'flarum/common/components/ModalManager';
import PostMeta from 'flarum/forum/components/PostMeta';
@@ -13,7 +11,7 @@ import DiscussionPage from 'flarum/forum/components/DiscussionPage';
extend(ForumApplication.prototype, 'mount', function () {
if (m.route.param('hideFirstPost')) {
extend(PostStream.prototype, 'view', (vdom) => {
extend('flarum/forum/components/PostStream', 'view', (vdom) => {
if (vdom.children[0].attrs['data-number'] === 1) {
vdom.children.splice(0, 1);
}
@@ -42,7 +40,7 @@ const reposition = function () {
};
extend(ModalManager.prototype, 'show', reposition);
extend(Composer.prototype, 'show', reposition);
extend('flarum/forum/components/Composer', 'show', reposition);
window.iFrameResizer = {
readyCallback: function () {
@@ -50,7 +48,7 @@ window.iFrameResizer = {
},
};
extend(PostStream.prototype, 'goToNumber', function (promise, number) {
extend('flarum/forum/components/PostStream', 'goToNumber', function (promise, number) {
if (number === 'reply' && 'parentIFrame' in window && app.composer.isFullScreen()) {
const itemTop = this.$('.PostStream-item:last').offset().top;
window.parentIFrame.scrollToOffset(0, itemTop);

View File

@@ -13,7 +13,8 @@ use s9e\TextFormatter\Configurator;
return [
(new Extend\Frontend('forum'))
->js(__DIR__.'/js/dist/forum.js')
->css(__DIR__.'/less/forum.less'),
->css(__DIR__.'/less/forum.less')
->jsDirectory(__DIR__.'/js/dist/forum'),
(new Extend\Formatter)
->configure(function (Configurator $config) {

View File

@@ -1,7 +1,4 @@
import emojiMap from 'simple-emoji-map';
import { extend } from 'flarum/common/extend';
import TextEditor from 'flarum/common/components/TextEditor';
import TextEditorButton from 'flarum/common/components/TextEditorButton';
import KeyboardNavigatable from 'flarum/common/utils/KeyboardNavigatable';
@@ -10,11 +7,15 @@ import getEmojiIconCode from './helpers/getEmojiIconCode';
import cdn from './cdn';
export default function addComposerAutocomplete() {
const emojiKeys = Object.keys(emojiMap);
const $container = $('<div class="ComposerBody-emojiDropdownContainer"></div>');
const dropdown = new AutocompleteDropdown();
let emojiMap = null;
extend(TextEditor.prototype, 'oncreate', function () {
extend('flarum/common/components/TextEditor', 'oninit', function () {
this._loaders.push(async () => await import('./emojiMap').then((m) => (emojiMap = m.default)));
});
extend('flarum/common/components/TextEditor', 'onbuild', function () {
const $editor = this.$('.TextEditor-editor').wrap('<div class="ComposerBody-emojiWrapper"></div>');
this.navigator = new KeyboardNavigatable();
@@ -29,7 +30,9 @@ export default function addComposerAutocomplete() {
$editor.after($container);
});
extend(TextEditor.prototype, 'buildEditorParams', function (params) {
extend('flarum/common/components/TextEditor', 'buildEditorParams', function (params) {
const emojiKeys = Object.keys(emojiMap);
let relEmojiStart;
let absEmojiStart;
let typed;
@@ -166,7 +169,7 @@ export default function addComposerAutocomplete() {
});
});
extend(TextEditor.prototype, 'toolbarItems', function (items) {
extend('flarum/common/components/TextEditor', 'toolbarItems', function (items) {
items.add(
'emoji',
<TextEditorButton onclick={() => this.attrs.composer.editor.insertAtCursor(' :')} icon="far fa-smile">

View File

@@ -0,0 +1,3 @@
import emojiMap from 'simple-emoji-map';
export default emojiMap;

View File

@@ -1,6 +1,5 @@
import { extend } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import NotificationGrid from 'flarum/forum/components/NotificationGrid';
import addLikeAction from './addLikeAction';
import addLikesList from './addLikesList';
@@ -16,7 +15,7 @@ app.initializers.add('flarum-likes', () => {
addLikesList();
addLikesTabToUserProfile();
extend(NotificationGrid.prototype, 'notificationTypes', function (items) {
extend('flarum/forum/components/NotificationGrid', 'notificationTypes', function (items) {
items.add('postLiked', {
name: 'postLiked',
icon: 'far fa-thumbs-up',

View File

@@ -1,6 +1,5 @@
import { extend } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import NotificationGrid from 'flarum/forum/components/NotificationGrid';
import DiscussionLockedNotification from './components/DiscussionLockedNotification';
import addLockBadge from './addLockBadge';
@@ -14,7 +13,7 @@ app.initializers.add('flarum-lock', () => {
addLockBadge();
addLockControl();
extend(NotificationGrid.prototype, 'notificationTypes', function (items) {
extend('flarum/forum/components/NotificationGrid', 'notificationTypes', function (items) {
items.add('discussionLocked', {
name: 'discussionLocked',
icon: 'fas fa-lock',

View File

@@ -9,7 +9,6 @@
import app from 'flarum/common/app';
import { extend, override } from 'flarum/common/extend';
import TextEditor from 'flarum/common/components/TextEditor';
import BasicEditorDriver from 'flarum/common/utils/BasicEditorDriver';
import styleSelectedText from 'flarum/common/utils/styleSelectedText';
@@ -89,13 +88,9 @@ export function initialize(app) {
items.add('italic', makeShortcut('italic', 'i', this));
});
if (TextEditor.prototype.markdownToolbarItems) {
override(TextEditor.prototype, 'markdownToolbarItems', markdownToolbarItems);
} else {
TextEditor.prototype.markdownToolbarItems = markdownToolbarItems;
}
override('flarum/common/components/TextEditor', 'markdownToolbarItems', markdownToolbarItems);
extend(TextEditor.prototype, 'toolbarItems', function (items) {
extend('flarum/common/components/TextEditor', 'toolbarItems', function (items) {
items.add(
'markdown',
<MarkdownToolbar for={this.textareaId} setShortcutHandler={(handler) => (shortcutHandler = handler)}>

View File

@@ -0,0 +1,15 @@
{
// 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/*"]
}
}
}

View File

@@ -1,6 +1,5 @@
import app from 'flarum/forum/app';
import { extend } from 'flarum/common/extend';
import TextEditor from 'flarum/common/components/TextEditor';
import TextEditorButton from 'flarum/common/components/TextEditorButton';
import KeyboardNavigatable from 'flarum/common/utils/KeyboardNavigatable';
@@ -11,7 +10,7 @@ export default function addComposerAutocomplete() {
const $container = $('<div class="ComposerBody-mentionsDropdownContainer"></div>');
const dropdown = new AutocompleteDropdown();
extend(TextEditor.prototype, 'oncreate', function () {
extend('flarum/common/components/TextEditor', 'onbuild', function () {
const $editor = this.$('.TextEditor-editor').wrap('<div class="ComposerBody-mentionsWrapper"></div>');
this.navigator = new KeyboardNavigatable();
@@ -26,7 +25,7 @@ export default function addComposerAutocomplete() {
$editor.after($container);
});
extend(TextEditor.prototype, 'buildEditorParams', function (params) {
extend('flarum/common/components/TextEditor', 'buildEditorParams', function (params) {
let relMentionStart;
let absMentionStart;
let matchTyped;
@@ -128,7 +127,7 @@ export default function addComposerAutocomplete() {
params.inputListeners.push(suggestionsInputListener);
});
extend(TextEditor.prototype, 'toolbarItems', function (items) {
extend('flarum/common/components/TextEditor', 'toolbarItems', function (items) {
items.add(
'mention',
<TextEditorButton onclick={() => this.attrs.composer.editor.insertAtCursor(' @')} icon="fas fa-at">

View File

@@ -1,6 +1,5 @@
import { extend } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import NotificationGrid from 'flarum/forum/components/NotificationGrid';
import { getPlainContent } from 'flarum/common/utils/string';
import textContrastClass from 'flarum/common/helpers/textContrastClass';
import Post from 'flarum/forum/components/Post';
@@ -46,7 +45,7 @@ app.initializers.add('flarum-mentions', function () {
app.notificationComponents.groupMentioned = GroupMentionedNotification;
// Add notification preferences.
extend(NotificationGrid.prototype, 'notificationTypes', function (items) {
extend('flarum/forum/components/NotificationGrid', 'notificationTypes', function (items) {
items.add('postMentioned', {
name: 'postMentioned',
icon: 'fas fa-reply',

View File

@@ -6,8 +6,6 @@ import usernameHelper from 'flarum/common/helpers/username';
import avatar from 'flarum/common/helpers/avatar';
import highlight from 'flarum/common/helpers/highlight';
import { truncate } from 'flarum/common/utils/string';
import ReplyComposer from 'flarum/forum/components/ReplyComposer';
import EditPostComposer from 'flarum/forum/components/EditPostComposer';
import getCleanDisplayName from '../utils/getCleanDisplayName';
import type AtMentionFormat from './formats/AtMentionFormat';
@@ -23,7 +21,10 @@ export default class PostMention extends MentionableModel<Post, AtMentionFormat>
* match any username characters that have been typed.
*/
initialResults(): Post[] {
if (!app.composer.bodyMatches(ReplyComposer) && !app.composer.bodyMatches(EditPostComposer)) {
const EditPostComposer = flarum.reg.checkModule('core', 'forum/components/EditPostComposer');
const ReplyComposer = flarum.reg.checkModule('core', 'forum/components/ReplyComposer');
if ((!ReplyComposer || !app.composer.bodyMatches(ReplyComposer)) && (!EditPostComposer || !app.composer.bodyMatches(EditPostComposer))) {
return [];
}

View File

@@ -1,6 +1,5 @@
import app from 'flarum/forum/app';
import DiscussionControls from 'flarum/forum/utils/DiscussionControls';
import EditPostComposer from 'flarum/forum/components/EditPostComposer';
export function insertMention(post, composer, quote) {
return new Promise((resolve) => {
@@ -27,7 +26,9 @@ export function insertMention(post, composer, quote) {
}
export default function reply(post, quote) {
if (app.composer.bodyMatches(EditPostComposer) && app.composer.body.attrs.post.discussion() === post.discussion()) {
const EditPostComposer = flarum.reg.checkModule('core', 'forum/components/EditPostComposer');
if (EditPostComposer && app.composer.bodyMatches(EditPostComposer) && app.composer.body.attrs.post.discussion() === post.discussion()) {
// If we're already editing a post in the discussion of post we're quoting,
// insert the mention directly.
return insertMention(post, app.composer, quote);

View File

@@ -1,9 +1,6 @@
import app from 'flarum/forum/app';
import { extend } from 'flarum/common/extend';
import Button from 'flarum/common/components/Button';
import EditUserModal from 'flarum/common/components/EditUserModal';
import SignUpModal from 'flarum/forum/components/SignUpModal';
import SettingsPage from 'flarum/forum/components/SettingsPage';
import extractText from 'flarum/common/utils/extractText';
import Stream from 'flarum/common/utils/Stream';
import NickNameModal from './components/NicknameModal';
@@ -11,7 +8,7 @@ import NickNameModal from './components/NicknameModal';
export { default as extend } from './extend';
app.initializers.add('flarum/nicknames', () => {
extend(SettingsPage.prototype, 'accountItems', function (items) {
extend('flarum/forum/components/SettingsPage', 'accountItems', function (items) {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;
if (this.user.canEditNickname()) {
@@ -24,11 +21,11 @@ app.initializers.add('flarum/nicknames', () => {
}
});
extend(EditUserModal.prototype, 'oninit', function () {
extend('flarum/common/components/EditUserModal', 'oninit', function () {
this.nickname = Stream(this.attrs.user.displayName());
});
extend(EditUserModal.prototype, 'fields', function (items) {
extend('flarum/common/components/EditUserModal', 'fields', function (items) {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;
if (!this.attrs.user.canEditNickname()) return;
@@ -47,7 +44,7 @@ app.initializers.add('flarum/nicknames', () => {
);
});
extend(EditUserModal.prototype, 'data', function (data) {
extend('flarum/common/components/EditUserModal', 'data', function (data) {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;
if (!this.attrs.user.canEditNickname()) return;
@@ -57,13 +54,13 @@ app.initializers.add('flarum/nicknames', () => {
}
});
extend(SignUpModal.prototype, 'oninit', function () {
extend('flarum/forum/components/SignUpModal', 'oninit', function () {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;
this.nickname = Stream(this.attrs.username || '');
});
extend(SignUpModal.prototype, 'onready', function () {
extend('flarum/forum/components/SignUpModal', 'onready', function () {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;
if (app.forum.attribute('setNicknameOnRegistration') && app.forum.attribute('randomizeUsernameOnRegistration')) {
@@ -71,7 +68,7 @@ app.initializers.add('flarum/nicknames', () => {
}
});
extend(SignUpModal.prototype, 'fields', function (items) {
extend('flarum/forum/components/SignUpModal', 'fields', function (items) {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;
if (app.forum.attribute('setNicknameOnRegistration')) {
@@ -97,7 +94,7 @@ app.initializers.add('flarum/nicknames', () => {
}
});
extend(SignUpModal.prototype, 'submitData', function (data) {
extend('flarum/forum/components/SignUpModal', 'submitData', function (data) {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;
if (app.forum.attribute('setNicknameOnRegistration')) {

View File

@@ -1,10 +1,10 @@
import app from 'flarum/forum/app';
import { extend } from 'flarum/common/extend';
import SettingsPage from 'flarum/forum/components/SettingsPage';
import type SettingsPage from 'flarum/forum/components/SettingsPage';
import Switch from 'flarum/common/components/Switch';
export default function () {
extend(SettingsPage.prototype, 'notificationsItems', function (this: SettingsPage, items) {
extend('flarum/forum/components/SettingsPage', 'notificationsItems', function (this: SettingsPage, items) {
items.add(
'followAfterReply',
<Switch

View File

@@ -1,8 +1,5 @@
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 NotificationGrid from 'flarum/forum/components/NotificationGrid';
import addSubscriptionBadge from './addSubscriptionBadge';
import addSubscriptionControls from './addSubscriptionControls';
@@ -21,7 +18,7 @@ app.initializers.add('subscriptions', function () {
addSubscriptionFilter();
addSubscriptionSettings();
extend(NotificationGrid.prototype, 'notificationTypes', function (items) {
extend('flarum/forum/components/NotificationGrid', 'notificationTypes', function (items) {
items.add('newPost', {
name: 'newPost',
icon: 'fas fa-star',

View File

@@ -10,7 +10,7 @@
"declarationDir": "./dist-typings",
"baseUrl": ".",
"paths": {
"flarum/*": ["../vendor/flarum/core/js/dist-typings/*"]
"flarum/*": ["../../../framework/core/js/dist-typings/*"]
}
}
}

View File

@@ -48,10 +48,14 @@ $eagerLoadTagState = function ($query, ?ServerRequestInterface $request, array $
return [
(new Extend\Frontend('forum'))
->js(__DIR__.'/js/dist/forum.js')
->jsDirectory(__DIR__.'/js/dist/forum')
->css(__DIR__.'/less/forum.less')
->route('/t/{slug}', 'tag', Content\Tag::class)
->route('/tags', 'tags', Content\Tags::class),
(new Extend\Frontend('common'))
->jsDirectory(__DIR__.'/js/dist/common'),
(new Extend\Frontend('admin'))
->js(__DIR__.'/js/dist/admin.js')
->css(__DIR__.'/less/admin.less'),

View File

@@ -2,7 +2,6 @@ import app from 'flarum/admin/app';
import Component from 'flarum/common/Component';
import Button from 'flarum/common/components/Button';
import LoadingIndicator from 'flarum/common/components/LoadingIndicator';
import TagSelectionModal from '../../common/components/TagSelectionModal';
import tagsLabel from '../../common/helpers/tagsLabel';
import type { CommonSettingsItemOptions } from 'flarum/admin/components/AdminPage';
@@ -46,7 +45,7 @@ export default class SelectTagsSettingComponent<
<Button
className="Button Button--text"
onclick={() =>
app.modal.show(TagSelectionModal, {
app.modal.show(() => import('../../common/components/TagSelectionModal'), {
selectedTags: this.tags,
onsubmit: (tags: Tag[]) => {
this.tags = tags;

View File

@@ -6,6 +6,4 @@ import './helpers/tagsLabel';
import './helpers/tagIcon';
import './helpers/tagLabel';
import './components/TagSelectionModal';
import './states/TagListState';

View File

@@ -1,13 +1,11 @@
import { extend, override } from 'flarum/common/extend';
import IndexPage from 'flarum/forum/components/IndexPage';
import DiscussionComposer from 'flarum/forum/components/DiscussionComposer';
import classList from 'flarum/common/utils/classList';
import TagDiscussionModal from './components/TagDiscussionModal';
import tagsLabel from '../common/helpers/tagsLabel';
import getSelectableTags from './utils/getSelectableTags';
export default function () {
export default function addTagComposer() {
extend(IndexPage.prototype, 'newDiscussionAction', function (promise) {
// From `addTagFilter
const tag = this.currentTag();
@@ -21,28 +19,28 @@ export default function () {
}
});
extend(DiscussionComposer.prototype, 'oninit', function () {
extend('flarum/forum/components/DiscussionComposer', 'oninit', function () {
app.tagList.load(['parent']).then(() => m.redraw());
// Add tag-selection abilities to the discussion composer.
this.constructor.prototype.chooseTags = function () {
const selectableTags = getSelectableTags();
if (!selectableTags.length) return;
app.modal.show(() => import('./components/TagDiscussionModal'), {
selectedTags: (this.composer.fields.tags || []).slice(0),
onsubmit: (tags) => {
this.composer.fields.tags = tags;
this.$('textarea').focus();
},
});
};
});
// Add tag-selection abilities to the discussion composer.
DiscussionComposer.prototype.chooseTags = function () {
const selectableTags = getSelectableTags();
if (!selectableTags.length) return;
app.modal.show(TagDiscussionModal, {
selectedTags: (this.composer.fields.tags || []).slice(0),
onsubmit: (tags) => {
this.composer.fields.tags = tags;
this.$('textarea').focus();
},
});
};
// Add a tag-selection menu to the discussion composer's header, after the
// title.
extend(DiscussionComposer.prototype, 'headerItems', function (items) {
extend('flarum/forum/components/DiscussionComposer', 'headerItems', function (items) {
const tags = this.composer.fields.tags || [];
const selectableTags = getSelectableTags();
@@ -59,7 +57,7 @@ export default function () {
);
});
override(DiscussionComposer.prototype, 'onsubmit', function (original) {
override('flarum/forum/components/DiscussionComposer', 'onsubmit', function (original) {
const chosenTags = this.composer.fields.tags || [];
const chosenPrimaryTags = chosenTags.filter((tag) => tag.position() !== null && !tag.isChild());
const chosenSecondaryTags = chosenTags.filter((tag) => tag.position() === null);
@@ -76,7 +74,7 @@ export default function () {
chosenSecondaryTags.length < minSecondaryTags) &&
selectableTags.length
) {
app.modal.show(TagDiscussionModal, {
app.modal.show(() => import('./components/TagDiscussionModal'), {
selectedTags: chosenTags,
onsubmit: (tags) => {
this.composer.fields.tags = tags;
@@ -89,7 +87,7 @@ export default function () {
});
// Add the selected tags as data to submit to the server.
extend(DiscussionComposer.prototype, 'data', function (data) {
extend('flarum/forum/components/DiscussionComposer', 'data', function (data) {
data.relationships = data.relationships || {};
data.relationships.tags = this.composer.fields.tags;
});

View File

@@ -2,15 +2,13 @@ import { extend } from 'flarum/common/extend';
import DiscussionControls from 'flarum/forum/utils/DiscussionControls';
import Button from 'flarum/common/components/Button';
import TagDiscussionModal from './components/TagDiscussionModal';
export default function () {
export default function addTagControl() {
// Add a control allowing the discussion to be moved to another category.
extend(DiscussionControls, 'moderationControls', function (items, discussion) {
if (discussion.canTag()) {
items.add(
'tags',
<Button icon="fas fa-tag" onclick={() => app.modal.show(TagDiscussionModal, { discussion })}>
<Button icon="fas fa-tag" onclick={() => app.modal.show(() => import('./components/TagDiscussionModal'), { discussion })}>
{app.translator.trans('flarum-tags.forum.discussion_controls.edit_tags_button')}
</Button>
);

View File

@@ -13,7 +13,7 @@ import { ComponentAttrs } from 'flarum/common/Component';
const findTag = (slug: string) => app.store.all<Tag>('tags').find((tag) => tag.slug().localeCompare(slug, undefined, { sensitivity: 'base' }) === 0);
export default function () {
export default function addTagFilter() {
IndexPage.prototype.currentTag = function () {
if (this.currentActiveTag) {
return this.currentActiveTag;

View File

@@ -7,7 +7,7 @@ import classList from 'flarum/common/utils/classList';
import tagsLabel from '../common/helpers/tagsLabel';
import sortTags from '../common/utils/sortTags';
export default function () {
export default function addTagLabels() {
// Add tag labels to each discussion in the discussion list.
extend(DiscussionListItem.prototype, 'infoItems', function (items) {
const tags = this.attrs.discussion.tags();

View File

@@ -8,7 +8,7 @@ import TagsPage from './components/TagsPage';
import app from 'flarum/forum/app';
import sortTags from '../common/utils/sortTags';
export default function () {
export default function addTagList() {
// Add a link to the tags page, as well as a list of all the tags,
// to the index page's sidebar.
extend(IndexPage.prototype, 'navItems', function (items) {

View File

@@ -36,7 +36,7 @@ export default class TagDiscussionModal extends TagSelectionModal<TagDiscussionM
},
};
attrs.requireParentTag = true;
attrs.selectableTags = () => getSelectableTags(attrs.discussion);
attrs.selectableTags = () => getSelectableTags(attrs.discussion!);
attrs.selectedTags ??= (attrs.discussion?.tags() as Tag[]) || [];
attrs.canSelect = (tag) => tag.canStartDiscussion();

View File

@@ -3,7 +3,6 @@ import '../common/common';
import './utils/getSelectableTags';
import './components/TagHero';
import './components/TagDiscussionModal';
import './components/TagsPage';
import './components/DiscussionTaggedPost';
import './components/TagLinkButton';

View File

@@ -1,11 +0,0 @@
export default function getSelectableTags(discussion) {
let tags = app.store.all('tags');
if (discussion) {
tags = tags.filter((tag) => tag.canAddToDiscussion() || discussion.tags().indexOf(tag) !== -1);
} else {
tags = tags.filter((tag) => tag.canStartDiscussion());
}
return tags;
}

View File

@@ -0,0 +1,15 @@
import type Tag from '../../common/models/Tag';
import type Discussion from 'flarum/common/models/Discussion';
export default function getSelectableTags(discussion: Discussion) {
let tags = app.store.all<Tag>('tags');
if (discussion) {
const discussionTags = discussion.tags() || [];
tags = tags.filter((tag) => tag.canAddToDiscussion() || discussionTags.includes(tag));
} else {
tags = tags.filter((tag) => tag.canStartDiscussion());
}
return tags;
}