I have also extended the MessageStream with the purpose of sending some parameters along to the messageItem (nextMessage, previousMessage). First of all I wonder if there is a better way to do this and if there isn't I have a problem. This is my ExtendedMessageStream:
export default class ExtendedMessageStream extends MessageStream {
content() {
const items: Mithril.Children[] = [];
const messages = this.attrs.state.getAllItems().sort((a, b) => a.createdAt().getTime() - b.createdAt().getTime());
const ReplyPlaceholder = this.replyPlaceholderComponent();
const LoadingPost = this.loadingPostComponent();
if (messages[0].id() !== (this.attrs.dialog.data.relationships?.firstMessage.data as ModelIdentifier).id) {
items.push(
<div className="MessageStream-item" key="loadPrevious">
<Button
onclick={() => this.whileMaintainingScroll(() => this.attrs.state.loadNext())}
type="button"
className="Button Button--block MessageStream-loadPrev"
>
{app.translator.trans('flarum-messages.forum.messages_page.stream.load_previous_button')}
</Button>
</div>
);
if (LoadingPost) {
items.push(
<div className="MessageStream-item" key="loading-prev">
<LoadingPost />
</div>
);
}
}
messages.forEach((message, index) => {
const nextMessage = messages[index + 1];
const sameUserAsNext = nextMessage && nextMessage.user().id() === message.user().id();
const previousMessage = messages[index - 1];
const sameUserAsPrevious = previousMessage && previousMessage.user().id() === message.user().id();
items.push(this.messageItem(message, index, sameUserAsNext, sameUserAsPrevious));
});
if (ReplyPlaceholder) {
items.push(
<div className="MessageStream-item" key="reply" /*data-index={this.attrs.state.count()}*/>
<ReplyPlaceholder
discussion={this.attrs.dialog}
onclick={() => {
import('flarum/forum/components/ComposerBody').then(() => {
app.composer
.load(() => import('ext:flarum/messages/forum/components/MessageComposer'), {
user: app.session.user,
replyingTo: this.attrs.dialog,
onsubmit: () => {
this.attrs.state.refresh().then(() => setTimeout(() => this.scrollToBottom(), 50));
},
})
.then(() => app.composer.show());
});
}}
composingReply={() => app.composer.composingMessageTo(this.attrs.dialog)}
/>
</div>
);
}
return items;
}
}
The problem is that when I now click on the ReplyPlaceholder, it will show the following error:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'bind')
at h.view (ComposerBody.tsx:55:31)
at view.c (render.js:37:16)
at render.js:156:45
at render.js:161:3
at h (render.js:73:8)
at d (render.js:57:5)
at render.js:135:5
at h (render.js:70:14)
at d (render.js:57:5)
at render.js:135:5
And every time I click it afterward it shows
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'onremove')
at S (render.js:657:59)
at S (render.js:666:25)
at S (render.js:666:25)
at S (render.js:660:32)
at S (render.js:660:32)
at C (render.js:611:4)
at k (render.js:585:23)
at p (render.js:274:51)
at render.js:935:4
at r.mount (mount-redraw.js:39:4)
I then added the following in place of the .then
.then(composer => {
if (composer && composer.show) {
composer.show();
} else {
console.error('Composer could not be loaded or shown');
}
})
And this logged the error.
Lastly, I tried importing the MessageComposer normally as the stream component is already lazy imported:
import MessageComposer from 'ext:flarum/messages/forum/components/MessageComposer';
if (ReplyPlaceholder) {
items.push(
<div className="MessageStream-item" key="reply">
<ReplyPlaceholder
discussion={this.attrs.dialog}
onclick={() => {
app.composer
.load(MessageComposer, {
user: app.session.user,
replyingTo: this.attrs.dialog,
onsubmit: () => {
this.attrs.state.refresh().then(() => setTimeout(() => this.scrollToBottom(), 50));
},
})
.then(() => app.composer.show());
}}
composingReply={() => app.composer.composingMessageTo(this.attrs.dialog)}
/>
</div>
);
}
But this gave an error stating it couldn't find the module:
Error: No module found for flarum-messages:forum/components/MessageComposer
at Object.get (ExportRegistry.ts:42:13)
at ext:flarum/messages/forum/components/MessageComposer (MessageComposer')":1:1)
at __webpack_require__ (bootstrap:19:1)
at ./src/forum/components/messages/ExtendedMessageStream.tsx (ExtendedMessage.tsx:38:1)
at __webpack_require__ (bootstrap:19:1)
at ./src/forum/components/messages/ExtendedDialogSection.tsx (ExtendedComment.tsx:32:1)
at __webpack_require__ (bootstrap:19:1)
at ./src/forum/components/messages/ExtendedMessagesPage.tsx (ExtendedMessageStream.tsx:91:1)
at __webpack_require__ (bootstrap:19:1)
at async index.ts:47:1
a @ router.js:84
Promise.then
t @ router.js:119
N @ router.js:88
M @ router.js:192
mount @ Application.tsx:226
mount @ ForumApplication.tsx:88
boot @ Application.tsx:188
(anonymous) @ messages:106
I really wonder if the MessageComposer can work this way or if there is a better way to get the next and previous message into the messageItem.