From 780faf46921171bd24f4f2164a2640702aa65e4f Mon Sep 17 00:00:00 2001 From: Davide Iadeluca Date: Thu, 9 Apr 2026 08:53:09 +0200 Subject: [PATCH 1/4] refactor(core): convert `PostEdited` to TS --- .../{PostEdited.js => PostEdited.tsx} | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) rename framework/core/js/src/forum/components/{PostEdited.js => PostEdited.tsx} (64%) diff --git a/framework/core/js/src/forum/components/PostEdited.js b/framework/core/js/src/forum/components/PostEdited.tsx similarity index 64% rename from framework/core/js/src/forum/components/PostEdited.js rename to framework/core/js/src/forum/components/PostEdited.tsx index e4a1902321..9a9c890ca4 100644 --- a/framework/core/js/src/forum/components/PostEdited.js +++ b/framework/core/js/src/forum/components/PostEdited.tsx @@ -1,21 +1,19 @@ -import app from '../../forum/app'; -import Component from '../../common/Component'; +import app from '../app'; +import Component, { ComponentAttrs } from '../../common/Component'; import humanTime from '../../common/utils/humanTime'; import Tooltip from '../../common/components/Tooltip'; +import type Post from '../../common/models/Post'; + +export interface IPostEditedAttrs extends ComponentAttrs { + post: Post; +} + /** * The `PostEdited` component displays information about when and by whom a post * was edited. - * - * ### Attrs - * - * - `post` */ -export default class PostEdited extends Component { - oninit(vnode) { - super.oninit(vnode); - } - +export default class PostEdited extends Component { view() { const post = this.attrs.post; const editedUser = post.editedUser(); @@ -27,8 +25,4 @@ export default class PostEdited extends Component { ); } - - oncreate(vnode) { - super.oncreate(vnode); - } } From 0e59de89d2ac4dadd4d683dbe4b4efe9fc8f7b5e Mon Sep 17 00:00:00 2001 From: Davide Iadeluca Date: Thu, 9 Apr 2026 08:59:12 +0200 Subject: [PATCH 2/4] refactor(core): convert `UserCard` to TS --- .../components/{UserCard.js => UserCard.tsx} | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) rename framework/core/js/src/forum/components/{UserCard.js => UserCard.tsx} (85%) diff --git a/framework/core/js/src/forum/components/UserCard.js b/framework/core/js/src/forum/components/UserCard.tsx similarity index 85% rename from framework/core/js/src/forum/components/UserCard.js rename to framework/core/js/src/forum/components/UserCard.tsx index f43951e4c4..572b3d92e5 100644 --- a/framework/core/js/src/forum/components/UserCard.js +++ b/framework/core/js/src/forum/components/UserCard.tsx @@ -1,5 +1,5 @@ -import app from '../../forum/app'; -import Component from '../../common/Component'; +import app from '../app'; +import Component, { ComponentAttrs } from '../../common/Component'; import humanTime from '../../common/utils/humanTime'; import ItemList from '../../common/utils/ItemList'; import UserControls from '../utils/UserControls'; @@ -12,19 +12,22 @@ import classList from '../../common/utils/classList'; import Icon from '../../common/components/Icon'; import Avatar from '../../common/components/Avatar'; +import type Mithril from 'mithril'; +import type User from '../../common/models/User'; + +export interface IUserCardAttrs extends ComponentAttrs { + userd: User; + className?: string; + editable?: boolean; + controlsButtonClassName?: string; +} + /** * The `UserCard` component displays a user's profile card. This is used both on * the `UserPage` (in the hero) and in discussions, shown when hovering over a * post author. - * - * ### Attrs - * - * - `user` - * - `className` - * - `editable` - * - `controlsButtonClassName` */ -export default class UserCard extends Component { +export default class UserCard extends Component { view() { const user = this.attrs.user; const color = user.color(); @@ -42,7 +45,7 @@ export default class UserCard extends Component { } profileItems() { - const items = new ItemList(); + const items = new ItemList(); items.add('avatar', this.avatar(), 100); items.add('content', this.content(), 10); @@ -69,7 +72,7 @@ export default class UserCard extends Component { } contentItems() { - const items = new ItemList(); + const items = new ItemList(); const user = this.attrs.user; const badges = user.badges().toArray(); @@ -87,11 +90,10 @@ export default class UserCard extends Component { /** * Build an item list of tidbits of info to show on this user's profile. - * - * @return {ItemList} */ infoItems() { - const items = new ItemList(); + const items = new ItemList(); + const user = this.attrs.user; const lastSeenAt = user.lastSeenAt(); @@ -115,7 +117,7 @@ export default class UserCard extends Component { } controlsItems() { - const items = new ItemList(); + const items = new ItemList(); const user = this.attrs.user; const controls = UserControls.controls(user, this).toArray(); From 457891ccb2a7c7682136af748df8b0683819dd4e Mon Sep 17 00:00:00 2001 From: Davide Iadeluca Date: Thu, 9 Apr 2026 09:08:24 +0200 Subject: [PATCH 3/4] refactor(core): convert `TerminalPost` to TS --- .../js/src/forum/components/TerminalPost.js | 33 ----------------- .../js/src/forum/components/TerminalPost.tsx | 36 +++++++++++++++++++ 2 files changed, 36 insertions(+), 33 deletions(-) delete mode 100644 framework/core/js/src/forum/components/TerminalPost.js create mode 100644 framework/core/js/src/forum/components/TerminalPost.tsx diff --git a/framework/core/js/src/forum/components/TerminalPost.js b/framework/core/js/src/forum/components/TerminalPost.js deleted file mode 100644 index 06f7c5181c..0000000000 --- a/framework/core/js/src/forum/components/TerminalPost.js +++ /dev/null @@ -1,33 +0,0 @@ -import app from '../../forum/app'; -import Component from '../../common/Component'; -import humanTime from '../../common/helpers/humanTime'; - -import Icon from '../../common/components/Icon'; - -/** - * Displays information about a the first or last post in a discussion. - * - * ### Attrs - * - * - `discussion` - * - `lastPost` - */ -export default class TerminalPost extends Component { - view() { - const discussion = this.attrs.discussion; - const lastPost = this.attrs.lastPost && discussion.replyCount(); - - const user = discussion[lastPost ? 'lastPostedUser' : 'user'](); - const time = discussion[lastPost ? 'lastPostedAt' : 'createdAt'](); - - return ( - - {!!lastPost && }{' '} - {app.translator.trans('core.forum.discussion_list.' + (lastPost ? 'replied' : 'started') + '_text', { - user, - ago: humanTime(time), - })} - - ); - } -} diff --git a/framework/core/js/src/forum/components/TerminalPost.tsx b/framework/core/js/src/forum/components/TerminalPost.tsx new file mode 100644 index 0000000000..7e35f6cee4 --- /dev/null +++ b/framework/core/js/src/forum/components/TerminalPost.tsx @@ -0,0 +1,36 @@ +import app from '../app'; +import Component, { ComponentAttrs } from '../../common/Component'; +import humanTime from '../../common/helpers/humanTime'; + +import Icon from '../../common/components/Icon'; + +import type Discussion from '../../common/models/Discussion'; + +export interface ITerminalPostAttrs extends ComponentAttrs { + discussion: Discussion; + lastPost?: boolean; +} + +/** + * Displays information about a the first or last post in a discussion. + */ +export default class TerminalPost extends Component { + view() { + const discussion = this.attrs.discussion; + const lastPost = this.attrs.lastPost && discussion.replyCount(); + + const user = discussion[lastPost ? 'lastPostedUser' : 'user'](); + const time = discussion[lastPost ? 'lastPostedAt' : 'createdAt'](); + + return ( + + {!!lastPost && }{' '} + {time && + app.translator.trans('core.forum.discussion_list.' + (lastPost ? 'replied' : 'started') + '_text', { + user, + ago: humanTime(time), + })} + + ); + } +} From 03ecef38e8a4d2ca8d31559cf11caaecd7bc1ed4 Mon Sep 17 00:00:00 2001 From: Davide Iadeluca Date: Thu, 9 Apr 2026 09:11:01 +0200 Subject: [PATCH 4/4] refactor(core): convert `HeaderSecondary` to TS --- .../{HeaderSecondary.js => HeaderSecondary.tsx} | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) rename framework/core/js/src/forum/components/{HeaderSecondary.js => HeaderSecondary.tsx} (87%) diff --git a/framework/core/js/src/forum/components/HeaderSecondary.js b/framework/core/js/src/forum/components/HeaderSecondary.tsx similarity index 87% rename from framework/core/js/src/forum/components/HeaderSecondary.js rename to framework/core/js/src/forum/components/HeaderSecondary.tsx index 7386daf07c..6406676e6f 100644 --- a/framework/core/js/src/forum/components/HeaderSecondary.js +++ b/framework/core/js/src/forum/components/HeaderSecondary.tsx @@ -1,5 +1,5 @@ -import app from '../../forum/app'; -import Component from '../../common/Component'; +import app from '../app'; +import Component, { ComponentAttrs } from '../../common/Component'; import Button from '../../common/components/Button'; import SessionDropdown from './SessionDropdown'; import SelectDropdown from '../../common/components/SelectDropdown'; @@ -8,23 +8,22 @@ import ItemList from '../../common/utils/ItemList'; import listItems from '../../common/helpers/listItems'; import GlobalSearch from './GlobalSearch'; +import type Mithril from 'mithril'; + +export interface IHeaderSecondaryAttrs extends ComponentAttrs {} + /** * The `HeaderSecondary` component displays secondary header controls, such as * the search box and the user menu. On the default skin, these are shown on the * right side of the header. */ -export default class HeaderSecondary extends Component { +export default class HeaderSecondary extends Component { view() { return
    {listItems(this.items().toArray())}
; } - /** - * Build an item list for the controls. - * - * @return {ItemList} - */ items() { - const items = new ItemList(); + const items = new ItemList(); items.add('search', , 30);