remodel ChatViewModel
This commit is contained in:
@@ -3,15 +3,17 @@ import "./messagePage.css";
|
||||
import * as React from "bloatless-react";
|
||||
|
||||
import { ChatMessageViewModelToView } from "../Components/chatMessage";
|
||||
import ChatViewModel from "../../ViewModel/Chat/chatViewModel";
|
||||
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
|
||||
import { translations } from "../translations";
|
||||
|
||||
export function MessagePage(chatViewModel: ChatViewModel) {
|
||||
export function MessagePage(messagePageViewModel: MessagePageViewModel) {
|
||||
messagePageViewModel.loadMessages();
|
||||
|
||||
const messageContainer = (
|
||||
<div
|
||||
id="message-container"
|
||||
children:append={[
|
||||
chatViewModel.chatMessageViewModels,
|
||||
messagePageViewModel.chatMessageViewModels,
|
||||
ChatMessageViewModelToView,
|
||||
]}
|
||||
></div>
|
||||
@@ -28,14 +30,16 @@ export function MessagePage(chatViewModel: ChatViewModel) {
|
||||
|
||||
scrollDown();
|
||||
}
|
||||
chatViewModel.chatMessageViewModels.subscribeSilent(scrollDownIfApplicable);
|
||||
messagePageViewModel.chatMessageViewModels.subscribeSilent(
|
||||
scrollDownIfApplicable
|
||||
);
|
||||
setTimeout(() => scrollDown(), 100);
|
||||
|
||||
return (
|
||||
<div id="message-page">
|
||||
<div class="pane">
|
||||
<div class="toolbar">
|
||||
<span subscribe:innerText={chatViewModel.primaryChannel}></span>
|
||||
<span>{translations.chatPage.message.messagesHeadline}</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
{messageContainer}
|
||||
@@ -43,8 +47,8 @@ export function MessagePage(chatViewModel: ChatViewModel) {
|
||||
<div class="content-width-constraint">
|
||||
<div class="input-width-constraint">
|
||||
<input
|
||||
bind:value={chatViewModel.composingMessage}
|
||||
on:enter={chatViewModel.sendMessage}
|
||||
bind:value={messagePageViewModel.composingMessage}
|
||||
on:enter={messagePageViewModel.sendMessage}
|
||||
placeholder={
|
||||
translations.chatPage.message.composerInputPlaceholder
|
||||
}
|
||||
@@ -54,8 +58,8 @@ export function MessagePage(chatViewModel: ChatViewModel) {
|
||||
aria-label={
|
||||
translations.chatPage.message.sendMessageButtonAudioLabel
|
||||
}
|
||||
on:click={chatViewModel.sendMessage}
|
||||
toggle:disabled={chatViewModel.cannotSendMessage}
|
||||
on:click={messagePageViewModel.sendMessage}
|
||||
toggle:disabled={messagePageViewModel.cannotSendMessage}
|
||||
>
|
||||
<span class="icon">send</span>
|
||||
</button>
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import * as React from "bloatless-react";
|
||||
|
||||
import ChatViewModel from "../../ViewModel/chatViewModel";
|
||||
import { Color } from "../../colors";
|
||||
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
||||
import { DeletableListItem } from "../Components/deletableListItem";
|
||||
import SettingsPageViewModel from "../../ViewModel/Pages/settingsPageViewModel";
|
||||
import { translations } from "../translations";
|
||||
|
||||
export function SettingsPage(chatViewModel: ChatViewModel) {
|
||||
export function SettingsPage(settingsPageViewModel: SettingsPageViewModel) {
|
||||
settingsPageViewModel.loadData();
|
||||
|
||||
const secondaryChannelConverter: React.StateItemConverter<string> = (
|
||||
secondaryChannel: string
|
||||
) => {
|
||||
return DeletableListItem(secondaryChannel, <span></span>, () => {
|
||||
chatViewModel.removeSecondaryChannel(secondaryChannel);
|
||||
settingsPageViewModel.removeSecondaryChannel(secondaryChannel);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -27,8 +29,8 @@ export function SettingsPage(chatViewModel: ChatViewModel) {
|
||||
<div>
|
||||
<span>{translations.chatPage.settings.primaryChannelLabel}</span>
|
||||
<input
|
||||
bind:value={chatViewModel.primaryChannelInput}
|
||||
on:enter={chatViewModel.setPrimaryChannel}
|
||||
bind:value={settingsPageViewModel.primaryChannelInput}
|
||||
on:enter={settingsPageViewModel.setPrimaryChannel}
|
||||
></input>
|
||||
</div>
|
||||
</label>
|
||||
@@ -38,8 +40,8 @@ export function SettingsPage(chatViewModel: ChatViewModel) {
|
||||
aria-label={
|
||||
translations.chatPage.settings.setPrimaryChannelButtonAudioLabel
|
||||
}
|
||||
on:click={chatViewModel.setPrimaryChannel}
|
||||
toggle:disabled={chatViewModel.cannotSetPrimaryChannel}
|
||||
on:click={settingsPageViewModel.setPrimaryChannel}
|
||||
toggle:disabled={settingsPageViewModel.cannotSetPrimaryChannel}
|
||||
>
|
||||
{translations.general.setButton}
|
||||
<span class="icon">check</span>
|
||||
@@ -56,8 +58,8 @@ export function SettingsPage(chatViewModel: ChatViewModel) {
|
||||
placeholder={
|
||||
translations.chatPage.settings.newSecondaryChannelPlaceholder
|
||||
}
|
||||
bind:value={chatViewModel.newSecondaryChannelInput}
|
||||
on:enter={chatViewModel.addSecondaryChannel}
|
||||
bind:value={settingsPageViewModel.newSecondaryChannelInput}
|
||||
on:enter={settingsPageViewModel.addSecondaryChannel}
|
||||
></input>
|
||||
<button
|
||||
class="primary"
|
||||
@@ -65,8 +67,8 @@ export function SettingsPage(chatViewModel: ChatViewModel) {
|
||||
translations.chatPage.settings
|
||||
.addSecondaryChannelButtonAudioLabel
|
||||
}
|
||||
on:click={chatViewModel.addSecondaryChannel}
|
||||
toggle:disabled={chatViewModel.cannotAddSecondaryChannel}
|
||||
on:click={settingsPageViewModel.addSecondaryChannel}
|
||||
toggle:disabled={settingsPageViewModel.cannotAddSecondaryChannel}
|
||||
>
|
||||
<span class="icon">add</span>
|
||||
</button>
|
||||
@@ -75,7 +77,7 @@ export function SettingsPage(chatViewModel: ChatViewModel) {
|
||||
<div
|
||||
class="flex-column gap width-input"
|
||||
children:append={[
|
||||
chatViewModel.secondaryChannels,
|
||||
settingsPageViewModel.secondaryChannels,
|
||||
secondaryChannelConverter,
|
||||
]}
|
||||
></div>
|
||||
@@ -87,9 +89,9 @@ export function SettingsPage(chatViewModel: ChatViewModel) {
|
||||
<div>
|
||||
<span>{translations.chatPage.settings.encryptionKeyLabel}</span>
|
||||
<input
|
||||
bind:value={chatViewModel.encryptionKeyInput}
|
||||
on:enter={chatViewModel.setEncryptionKey}
|
||||
set:type={chatViewModel.encryptionKeyInputType}
|
||||
bind:value={settingsPageViewModel.encryptionKeyInput}
|
||||
on:enter={settingsPageViewModel.setEncryptionKey}
|
||||
set:type={settingsPageViewModel.encryptionKeyInputType}
|
||||
></input>
|
||||
</div>
|
||||
</label>
|
||||
@@ -99,8 +101,8 @@ export function SettingsPage(chatViewModel: ChatViewModel) {
|
||||
aria-label={
|
||||
translations.chatPage.settings.setEncryptionKeyButtonAudioLabel
|
||||
}
|
||||
on:click={chatViewModel.setEncryptionKey}
|
||||
toggle:disabled={chatViewModel.cannotSetEncryptionKey}
|
||||
on:click={settingsPageViewModel.setEncryptionKey}
|
||||
toggle:disabled={settingsPageViewModel.cannotSetEncryptionKey}
|
||||
>
|
||||
{translations.general.setButton}
|
||||
<span class="icon">check</span>
|
||||
@@ -110,7 +112,7 @@ export function SettingsPage(chatViewModel: ChatViewModel) {
|
||||
<label class="inline">
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={chatViewModel.shouldShowEncryptionKey}
|
||||
bind:checked={settingsPageViewModel.shouldShowEncryptionKey}
|
||||
></input>
|
||||
{translations.chatPage.settings.showEncryptionKey}
|
||||
</label>
|
||||
@@ -120,12 +122,12 @@ export function SettingsPage(chatViewModel: ChatViewModel) {
|
||||
<div class="flex-row gap width-input">
|
||||
{...Object.values(Color).map((color) => {
|
||||
const isSelected = React.createProxyState(
|
||||
[chatViewModel.color],
|
||||
() => chatViewModel.color.value == color
|
||||
[settingsPageViewModel.color],
|
||||
() => settingsPageViewModel.color.value == color
|
||||
);
|
||||
|
||||
function setColor() {
|
||||
chatViewModel.setColor(color);
|
||||
settingsPageViewModel.setColor(color);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -146,7 +148,7 @@ export function SettingsPage(chatViewModel: ChatViewModel) {
|
||||
{DangerousActionButton(
|
||||
translations.chatPage.settings.deleteChatButton,
|
||||
"chat_error",
|
||||
chatViewModel.remove
|
||||
settingsPageViewModel.remove
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import * as React from "bloatless-react";
|
||||
|
||||
import TaskViewModel from "../../ViewModel/Files/taskViewModel";
|
||||
import TaskPageViewModel from "../../ViewModel/Pages/taskPageViewModel";
|
||||
import { translations } from "../translations";
|
||||
|
||||
export function TaskPage(taskViewModel: TaskViewModel) {
|
||||
export function TaskPage(taskPageViewModel: TaskPageViewModel) {
|
||||
return (
|
||||
<div id="task-page">
|
||||
<div class="pane side">
|
||||
<div class="content">
|
||||
<div class="flex-row width-input">
|
||||
<input
|
||||
bind:value={taskViewModel.newBoardNameInput}
|
||||
on:enter={taskViewModel.createBoard}
|
||||
bind:value={taskPageViewModel.newBoardNameInput}
|
||||
on:enter={taskPageViewModel.createBoard}
|
||||
placeholder={translations.chatPage.task.newBoardNamePlaceholder}
|
||||
></input>
|
||||
<button
|
||||
@@ -19,8 +19,8 @@ export function TaskPage(taskViewModel: TaskViewModel) {
|
||||
aria-label={
|
||||
translations.chatPage.task.createBoardButtonAudioLabel
|
||||
}
|
||||
on:click={taskViewModel.createBoard}
|
||||
toggle:disabled={taskViewModel.cannotCreateBoard}
|
||||
on:click={taskPageViewModel.createBoard}
|
||||
toggle:disabled={taskPageViewModel.cannotCreateBoard}
|
||||
>
|
||||
<span class="icon">add</span>
|
||||
</button>
|
||||
|
||||
@@ -6,12 +6,18 @@ import ChatViewModel from "../../ViewModel/Chat/chatViewModel";
|
||||
|
||||
export function ChatEntry(chatViewModel: ChatViewModel) {
|
||||
const view = (
|
||||
<button set:color={chatViewModel.color} class="chat-entry tile" on:click={chatViewModel.open}>
|
||||
<button
|
||||
set:color={chatViewModel.settingsPageViewModel.color}
|
||||
class="chat-entry tile"
|
||||
on:click={chatViewModel.open}
|
||||
>
|
||||
<span
|
||||
class="shadow"
|
||||
subscribe:innerText={chatViewModel.primaryChannel}
|
||||
subscribe:innerText={chatViewModel.settingsPageViewModel.primaryChannel}
|
||||
></span>
|
||||
<h2 subscribe:innerText={chatViewModel.primaryChannel}></h2>
|
||||
<h2
|
||||
subscribe:innerText={chatViewModel.settingsPageViewModel.primaryChannel}
|
||||
></h2>
|
||||
</button>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from "bloatless-react";
|
||||
|
||||
import ChatMessageViewModel from "../../Model/chatMessageViewModel";
|
||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||
import { translations } from "../translations";
|
||||
|
||||
export function ChatMessageInfoModal(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from "bloatless-react";
|
||||
|
||||
import ChatViewModel, { ChatPageType } from "../../ViewModel/chatViewModel";
|
||||
import ChatViewModel, { ChatPageType } from "../../ViewModel/Chat/chatViewModel";
|
||||
|
||||
export function ChatViewToggleButton(
|
||||
label: string,
|
||||
|
||||
+12
-7
@@ -15,19 +15,24 @@ export function ChatPage(chatViewModel: ChatViewModel) {
|
||||
|
||||
chatViewModel.selectedPage.subscribe((selectedPage) => {
|
||||
switch (selectedPage) {
|
||||
case ChatPageType.Settings:
|
||||
return (mainContent.value = SettingsPage(chatViewModel));
|
||||
case ChatPageType.Tasks:
|
||||
return (mainContent.value = TaskPage(chatViewModel));
|
||||
default:
|
||||
return (mainContent.value = MessagePage(chatViewModel));
|
||||
case ChatPageType.Settings: {
|
||||
mainContent.value = SettingsPage(chatViewModel.settingsPageViewModel);
|
||||
break;
|
||||
}
|
||||
case ChatPageType.Tasks: {
|
||||
mainContent.value = TaskPage(chatViewModel.taskPageViewModel);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
mainContent.value = MessagePage(chatViewModel.messagePageViewModel);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<article
|
||||
id="chat-page"
|
||||
set:color={chatViewModel.color}
|
||||
set:color={chatViewModel.settingsPageViewModel.color}
|
||||
class="subtle-background"
|
||||
>
|
||||
<div>
|
||||
|
||||
@@ -2,7 +2,7 @@ import "./chatPage.css";
|
||||
|
||||
import * as React from "bloatless-react";
|
||||
|
||||
import ChatListViewModel from "../ViewModel/chatListViewModel";
|
||||
import ChatListViewModel from "../ViewModel/Chat/chatListViewModel";
|
||||
import { ChatPage } from "./chatPage";
|
||||
|
||||
export function ChatPageWrapper(chatListViewModel: ChatListViewModel) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as React from "bloatless-react";
|
||||
|
||||
import { Option, StringToOption } from "./Components/option";
|
||||
|
||||
import ChatListViewModel from "../ViewModel/chatListViewModel";
|
||||
import ChatListViewModel from "../ViewModel/Chat/chatListViewModel";
|
||||
import { ChatViewModelToChatEntry } from "./Components/chatEntry";
|
||||
import ConnectionViewModel from "../ViewModel/Global/connectionViewModel";
|
||||
import SettingsViewModel from "../ViewModel/Global/settingsViewModel";
|
||||
|
||||
@@ -104,6 +104,8 @@ const englishTranslations = {
|
||||
},
|
||||
|
||||
message: {
|
||||
messagesHeadline: "Messages",
|
||||
|
||||
composerInputPlaceholder: "Type a message...",
|
||||
sendMessageButtonAudioLabel: "send message",
|
||||
|
||||
|
||||
Reference in New Issue
Block a user