Files
CT/src/View/ChatPages/messagePage.tsx
T

128 lines
5.1 KiB
TypeScript
Raw Normal View History

2024-07-20 21:10:06 +02:00
import "./messagePage.css";
2024-07-20 17:19:10 +02:00
import * as React from "bloatless-react";
2024-07-22 21:07:44 +02:00
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
import { ChatMessage } from "../Components/chatMessage";
import { MessageFilterModal } from "../Modals/messageFilterModal";
2024-07-20 17:19:10 +02:00
export function MessagePage(
coreViewModel: CoreViewModel,
messagePageViewModel: MessagePageViewModel,
) {
2026-04-01 08:29:39 +00:00
messagePageViewModel.loadData();
const ChatMessageViewModelToView: React.StateItemConverter<
ChatMessageViewModel
> = (chatMessageViewModel: ChatMessageViewModel) => {
return ChatMessage(coreViewModel, chatMessageViewModel);
};
2024-07-22 21:07:44 +02:00
2026-04-01 08:29:39 +00:00
const messageContainer = (
<div
id="message-container"
children:append={[
2026-04-11 19:26:13 +00:00
messagePageViewModel.filteredMessageViewModels,
2026-04-01 08:29:39 +00:00
ChatMessageViewModelToView,
]}
></div>
);
2024-07-21 01:12:35 +02:00
2026-04-08 14:07:07 +00:00
function scrollDown(hard: boolean = false) {
if (hard) {
messageContainer.setAttribute("scroll-hard", "");
}
2026-04-01 08:29:39 +00:00
messageContainer.scrollTop = messageContainer.scrollHeight;
2026-04-08 14:07:07 +00:00
messageContainer.removeAttribute("scroll-hard");
2026-04-01 08:29:39 +00:00
}
function scrollDownIfApplicable() {
const scrollFromBottom =
messageContainer.scrollHeight -
(messageContainer.scrollTop + messageContainer.offsetHeight);
if (scrollFromBottom > 400) return;
2024-07-21 01:12:35 +02:00
2026-04-01 08:29:39 +00:00
scrollDown();
}
2026-04-11 19:26:13 +00:00
messagePageViewModel.filteredMessageViewModels.subscribeSilent(
2026-04-01 08:29:39 +00:00
scrollDownIfApplicable,
);
2026-04-08 14:07:07 +00:00
setTimeout(() => scrollDown(true), 100);
2024-07-21 01:12:35 +02:00
2026-04-01 08:29:39 +00:00
return (
<div id="message-page">
<div class="pane-wrapper">
<div class="pane">
<div class="toolbar">
<span class="title">
{
coreViewModel.translations.chatPage.message
.messagesHeadline
}
2026-04-01 08:29:39 +00:00
</span>
2026-04-11 19:26:13 +00:00
<span>
<button
class="ghost"
2026-04-12 19:20:37 +00:00
on:click={messagePageViewModel.showFilterModal}
2026-04-11 19:26:13 +00:00
aria-label={
coreViewModel.translations.chatPage.message
.filterMessagesButtonAudioLabel
}
toggle:selected={
messagePageViewModel.isFilterActive
}
2026-04-11 19:26:13 +00:00
>
<span class="icon">filter_alt</span>
2026-04-11 19:26:13 +00:00
</button>
</span>
2026-04-01 08:29:39 +00:00
</div>
<div class="content">
{messageContainer}
<div id="composer">
<div class="content-width-constraint">
<div class="input-width-constraint">
<input
bind:value={
messagePageViewModel.composingMessage
}
on:enter={
messagePageViewModel.sendMessage
}
placeholder={
coreViewModel.translations.chatPage
.message
2026-04-01 08:29:39 +00:00
.composerInputPlaceholder
}
></input>
<button
class="primary"
aria-label={
coreViewModel.translations.chatPage
.message
2026-04-01 08:29:39 +00:00
.sendMessageButtonAudioLabel
}
on:click={
messagePageViewModel.sendMessage
}
toggle:disabled={
messagePageViewModel.cannotSendMessage
}
>
<span class="icon">send</span>
</button>
</div>
</div>
</div>
</div>
</div>
2024-07-21 01:53:25 +02:00
</div>
2026-04-11 19:26:13 +00:00
{MessageFilterModal(
2026-04-11 19:26:13 +00:00
coreViewModel,
messagePageViewModel,
2026-04-11 19:26:13 +00:00
ChatMessageViewModelToView,
)}
</div>
2026-04-01 08:29:39 +00:00
);
2024-07-20 17:19:10 +02:00
}