remodel ChatViewModel

This commit is contained in:
marlon-erler
2024-07-22 21:07:44 +02:00
parent 7c4558a5b2
commit ba27c61a29
17 changed files with 541 additions and 361 deletions
@@ -0,0 +1,78 @@
import * as React from "bloatless-react";
import { ChatMessage } from "../../Model/Chat/chatModel";
import ChatMessageViewModel from "../Chat/chatMessageViewModel";
import ChatViewModel from "../Chat/chatViewModel";
export default class MessagePageViewModel {
chatViewModel: ChatViewModel;
// state
chatMessageViewModels: React.MapState<ChatMessageViewModel> =
new React.MapState();
composingMessage: React.State<string> = new React.State("");
// guards
cannotSendMessage: React.State<boolean>;
// methods
addChatMessage = (chatMessage: ChatMessage): void => {
const chatMessageModel = new ChatMessageViewModel(
this,
chatMessage,
chatMessage.sender == this.chatViewModel.settingsViewModel.username.value
);
const existingChatMessageViewModel: ChatMessageViewModel | undefined =
this.chatMessageViewModels.value.get(chatMessage.id);
if (existingChatMessageViewModel != undefined) {
existingChatMessageViewModel.body.value = chatMessage.body;
existingChatMessageViewModel.status.value = chatMessage.status;
} else {
this.chatMessageViewModels.set(chatMessage.id, chatMessageModel);
}
};
// messaging
sendMessage = (): void => {
if (this.cannotSendMessage.value == true) return;
this.sendMessageFromBody(this.composingMessage.value);
this.composingMessage.value = "";
};
sendMessageFromBody = (body: string): void => {
this.chatViewModel.chatModel.sendMessage(body);
};
decryptMessage = async (
messageViewModel: ChatMessageViewModel
): Promise<void> => {
const chatMessage: ChatMessage = messageViewModel.chatMessage;
await this.chatViewModel.chatModel.decryptMessage(chatMessage);
this.chatViewModel.chatModel.addMessage(chatMessage);
messageViewModel.loadData();
};
// load
loadData = (): void => {
this.cannotSendMessage = React.createProxyState(
[this.chatViewModel.settingsViewModel.username, this.composingMessage],
() =>
this.chatViewModel.settingsViewModel.username.value == "" ||
this.composingMessage.value == ""
);
};
loadMessages = (): void => {
for (const chatMessage of this.chatViewModel.chatModel.messages) {
this.addChatMessage(chatMessage);
}
};
// init
constructor(chatViewModel: ChatViewModel) {
this.chatViewModel = chatViewModel;
this.loadData();
}
}
@@ -0,0 +1,124 @@
import * as React from "bloatless-react";
import ChatViewModel from "../Chat/chatViewModel";
import { Color } from "../../colors";
export default class SettingsPageViewModel {
chatViewModel: ChatViewModel;
// state
primaryChannel: React.State<string> = new React.State("");
primaryChannelInput: React.State<string> = new React.State("");
secondaryChannels: React.ListState<string> = new React.ListState();
newSecondaryChannelInput: React.State<string> = new React.State("");
encryptionKeyInput: React.State<string> = new React.State("");
shouldShowEncryptionKey: React.State<boolean> = new React.State(false);
encryptionKeyInputType: React.State<"text" | "password"> =
React.createProxyState([this.shouldShowEncryptionKey], () =>
this.shouldShowEncryptionKey.value == true ? "text" : "password"
);
color: React.State<Color> = new React.State<Color>(Color.Standard);
// guards
cannotSetPrimaryChannel: React.State<boolean> = React.createProxyState(
[this.primaryChannel, this.primaryChannelInput],
() =>
this.primaryChannelInput.value == "" ||
this.primaryChannelInput.value == this.primaryChannel.value
);
cannotAddSecondaryChannel: React.State<boolean> = React.createProxyState(
[this.newSecondaryChannelInput],
() => this.newSecondaryChannelInput.value == ""
);
cannotSetEncryptionKey: React.State<boolean>;
// methods
setPrimaryChannel = (): void => {
this.chatViewModel.chatModel.setPrimaryChannel(
this.primaryChannelInput.value
);
this.primaryChannel.value =
this.chatViewModel.chatModel.info.primaryChannel;
this.chatViewModel.chatListViewModel.updateIndices();
};
addSecondaryChannel = (): void => {
this.secondaryChannels.add(this.newSecondaryChannelInput.value);
this.newSecondaryChannelInput.value = "";
this.storeSecondaryChannels();
this.loadSecondaryChannels();
};
removeSecondaryChannel = (secondaryChannel: string): void => {
this.secondaryChannels.remove(secondaryChannel);
this.storeSecondaryChannels();
};
storeSecondaryChannels = (): void => {
this.chatViewModel.chatModel.setSecondaryChannels([
...this.secondaryChannels.value.values(),
]);
};
setEncryptionKey = (): void => {
this.chatViewModel.chatModel.setEncryptionKey(
this.encryptionKeyInput.value
);
// disable button
this.encryptionKeyInput.callSubscriptions();
};
setColor = (newColor: Color): void => {
this.color.value = newColor;
this.chatViewModel.chatModel.setColor(newColor);
};
remove = (): void => {
this.chatViewModel.close();
this.chatViewModel.chatModel.delete();
this.chatViewModel.chatListViewModel.loadChats();
};
// load
loadViewRelevantData = (): void => {
this.primaryChannel.value =
this.chatViewModel.chatModel.info.primaryChannel;
this.color.value = this.chatViewModel.chatModel.color;
this.cannotSetEncryptionKey = React.createProxyState(
[this.encryptionKeyInput],
() =>
this.encryptionKeyInput.value ==
this.chatViewModel.chatModel.info.encryptionKey
);
};
loadData = (): void => {
this.primaryChannelInput.value =
this.chatViewModel.chatModel.info.primaryChannel;
this.loadSecondaryChannels();
this.encryptionKeyInput.value =
this.chatViewModel.chatModel.info.encryptionKey;
};
loadSecondaryChannels = (): void => {
this.secondaryChannels.clear();
for (const secondaryChannel of this.chatViewModel.chatModel
.secondaryChannels) {
this.secondaryChannels.add(secondaryChannel);
}
};
// init
constructor(chatViewModel: ChatViewModel) {
this.chatViewModel = chatViewModel;
this.loadViewRelevantData();
}
}
+35
View File
@@ -0,0 +1,35 @@
import * as React from "bloatless-react";
import TaskModel, {
BoardInfoFileContent,
} from "../../Model/Files/taskModel";
import StorageModel from "../../Model/Global/storageModel";
export default class TaskPageViewModel {
taskModel: TaskModel;
// state
newBoardNameInput: React.State<string> = new React.State("");
boards: React.ListState<BoardInfoFileContent> = new React.ListState();
// guards
cannotCreateBoard: React.State<boolean> = React.createProxyState(
[this.newBoardNameInput],
() => this.newBoardNameInput.value == ""
);
// methods
createBoard = (): void => {
if (this.cannotCreateBoard.value == true) return;
this.taskModel.createBoard(this.newBoardNameInput.value);
this.newBoardNameInput.value = "";
};
// init
constructor(taskModel: TaskModel, storageModel: StorageModel) {
this.taskModel = taskModel;
}
}