format
This commit is contained in:
@@ -105,11 +105,11 @@ export default class ChatListViewModel {
|
||||
|
||||
// utility
|
||||
getDisplayName = (fullChannel: string): string => {
|
||||
for (const vm of this.chatViewModels.value) {
|
||||
const fullReference = vm.chatModel.id;
|
||||
if (fullReference == fullChannel) return vm.chatModel.info.name;
|
||||
}
|
||||
for (const vm of this.chatViewModels.value) {
|
||||
const fullReference = vm.chatModel.id;
|
||||
if (fullReference == fullChannel) return vm.chatModel.info.name;
|
||||
}
|
||||
|
||||
return fullChannel;
|
||||
}
|
||||
return fullChannel;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,7 +17,10 @@ export default class ChatMessageViewModel {
|
||||
body: React.State<string> = new React.State("");
|
||||
inlineReply: ChatMessageViewModel | undefined = undefined;
|
||||
replies: React.MapState<ChatMessageViewModel> = new React.MapState();
|
||||
replyCount: React.State<number> = React.createProxyState([this.replies], ()=>this.replies.value.size);
|
||||
replyCount: React.State<number> = React.createProxyState(
|
||||
[this.replies],
|
||||
() => this.replies.value.size,
|
||||
);
|
||||
status: React.State<ChatMessageStatuses | any> = new React.State<any>(
|
||||
undefined,
|
||||
);
|
||||
@@ -100,106 +103,119 @@ export default class ChatMessageViewModel {
|
||||
};
|
||||
|
||||
toggleHiding = (): void => {
|
||||
let hideForReactions: boolean = false;
|
||||
let hideForReplyView: boolean = false;
|
||||
let hideForReactions: boolean = false;
|
||||
let hideForReplyView: boolean = false;
|
||||
|
||||
// reactions
|
||||
const reactionFilter = this.messagePageViewModel.reactionFilter.value;
|
||||
if (reactionFilter == undefined) {
|
||||
hideForReactions = false;
|
||||
} else {
|
||||
let count: number = 0;
|
||||
switch (reactionFilter) {
|
||||
case ReactionSymbols.ThumbsUp: {
|
||||
count = this.reactionsThumbsUpCount.value;
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.Check: {
|
||||
count = this.reactionsCheckCount.value;
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.Stop: {
|
||||
count = this.reactionsStopCount.value;
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.Attention: {
|
||||
count = this.reactionsAttentionCount.value;
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.DoubleAttention: {
|
||||
count = this.reactionsDoubleAttentionCount.value;
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.Question: {
|
||||
count = this.reactionsQuestionCount.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
hideForReactions = count == 0;
|
||||
}
|
||||
// reactions
|
||||
const reactionFilter = this.messagePageViewModel.reactionFilter.value;
|
||||
if (reactionFilter == undefined) {
|
||||
hideForReactions = false;
|
||||
} else {
|
||||
let count: number = 0;
|
||||
switch (reactionFilter) {
|
||||
case ReactionSymbols.ThumbsUp: {
|
||||
count = this.reactionsThumbsUpCount.value;
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.Check: {
|
||||
count = this.reactionsCheckCount.value;
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.Stop: {
|
||||
count = this.reactionsStopCount.value;
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.Attention: {
|
||||
count = this.reactionsAttentionCount.value;
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.DoubleAttention: {
|
||||
count = this.reactionsDoubleAttentionCount.value;
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.Question: {
|
||||
count = this.reactionsQuestionCount.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
hideForReactions = count == 0;
|
||||
}
|
||||
|
||||
// reply
|
||||
const selectedMessage = this.messagePageViewModel.replyViewSelectedMessage.value;
|
||||
if (selectedMessage == undefined) hideForReplyView = false;
|
||||
else if (selectedMessage.chatMessage.id == this.chatMessage.id) hideForReplyView = false;
|
||||
else if (this.inlineReply != undefined && selectedMessage.chatMessage.id == this.inlineReply.chatMessage.id) hideForReplyView = false;
|
||||
else hideForReplyView = true;
|
||||
// reply
|
||||
const selectedMessage =
|
||||
this.messagePageViewModel.replyViewSelectedMessage.value;
|
||||
if (selectedMessage == undefined) hideForReplyView = false;
|
||||
else if (selectedMessage.chatMessage.id == this.chatMessage.id)
|
||||
hideForReplyView = false;
|
||||
else if (
|
||||
this.inlineReply != undefined &&
|
||||
selectedMessage.chatMessage.id == this.inlineReply.chatMessage.id
|
||||
)
|
||||
hideForReplyView = false;
|
||||
else hideForReplyView = true;
|
||||
|
||||
this.isHidden.value = hideForReactions || hideForReplyView;
|
||||
}
|
||||
this.isHidden.value = hideForReactions || hideForReplyView;
|
||||
};
|
||||
|
||||
// reactions
|
||||
handleReaction = (reaction: ChatMessageReaction): void => {
|
||||
if (reaction.isDeleting) {
|
||||
this.allReactions.remove(reaction.sender);
|
||||
} else {
|
||||
this.allReactions.set(reaction.sender, reaction);
|
||||
}
|
||||
if (reaction.isDeleting) {
|
||||
this.allReactions.remove(reaction.sender);
|
||||
} else {
|
||||
this.allReactions.set(reaction.sender, reaction);
|
||||
}
|
||||
|
||||
if (reaction.sender != this.coreViewModel.settingsModel.username)
|
||||
return;
|
||||
this.userReaction.value = reaction.isDeleting
|
||||
? undefined
|
||||
: reaction.content;
|
||||
if (reaction.sender != this.coreViewModel.settingsModel.username)
|
||||
return;
|
||||
this.userReaction.value = reaction.isDeleting
|
||||
? undefined
|
||||
: reaction.content;
|
||||
};
|
||||
|
||||
sendReaction = (content: ReactionSymbols, isDeleting: boolean): void => {
|
||||
this.messagePageViewModel.sendReaction(
|
||||
this.chatMessage.id,
|
||||
content,
|
||||
isDeleting,
|
||||
);
|
||||
this.messagePageViewModel.sendReaction(
|
||||
this.chatMessage.id,
|
||||
content,
|
||||
isDeleting,
|
||||
);
|
||||
};
|
||||
|
||||
// load
|
||||
loadData = (): void => {
|
||||
this.channel = this.chatMessage.channel;
|
||||
this.sender = this.chatMessage.sender;
|
||||
this.dateSent = new Date(this.chatMessage.dateSent).toLocaleString();
|
||||
this.body.value = this.chatMessage.body;
|
||||
this.status.value = this.chatMessage.status;
|
||||
this.channel = this.chatMessage.channel;
|
||||
this.sender = this.chatMessage.sender;
|
||||
this.dateSent = new Date(this.chatMessage.dateSent).toLocaleString();
|
||||
this.body.value = this.chatMessage.body;
|
||||
this.status.value = this.chatMessage.status;
|
||||
|
||||
if (this.chatMessage.inlineReplyId) {
|
||||
this.inlineReply =
|
||||
this.messagePageViewModel.chatMessageViewModels.value.get(
|
||||
this.chatMessage.inlineReplyId,
|
||||
);
|
||||
this.inlineReply?.replies.set(this.chatMessage.id, this);
|
||||
}
|
||||
if (this.chatMessage.inlineReplyId) {
|
||||
this.inlineReply =
|
||||
this.messagePageViewModel.chatMessageViewModels.value.get(
|
||||
this.chatMessage.inlineReplyId,
|
||||
);
|
||||
this.inlineReply?.replies.set(this.chatMessage.id, this);
|
||||
}
|
||||
};
|
||||
|
||||
// init
|
||||
constructor(
|
||||
public readonly coreViewModel: CoreViewModel,
|
||||
public readonly messagePageViewModel: MessagePageViewModel,
|
||||
chatMessage: ChatMessage,
|
||||
sentByUser: boolean,
|
||||
public readonly coreViewModel: CoreViewModel,
|
||||
public readonly messagePageViewModel: MessagePageViewModel,
|
||||
chatMessage: ChatMessage,
|
||||
sentByUser: boolean,
|
||||
) {
|
||||
this.chatMessage = chatMessage;
|
||||
this.sentByUser = sentByUser;
|
||||
this.loadData();
|
||||
this.chatMessage = chatMessage;
|
||||
this.sentByUser = sentByUser;
|
||||
this.loadData();
|
||||
|
||||
React.bulkSubscribe([this.messagePageViewModel.reactionFilter, this.messagePageViewModel.replyViewSelectedMessage, this.allReactions], this.toggleHiding);
|
||||
this.toggleHiding();
|
||||
React.bulkSubscribe(
|
||||
[
|
||||
this.messagePageViewModel.reactionFilter,
|
||||
this.messagePageViewModel.replyViewSelectedMessage,
|
||||
this.allReactions,
|
||||
],
|
||||
this.toggleHiding,
|
||||
);
|
||||
this.toggleHiding();
|
||||
}
|
||||
}
|
||||
|
||||
+123
-120
@@ -31,7 +31,7 @@ export default class ChatViewModel extends ContextHost<ChatPageTypes> {
|
||||
// state
|
||||
displayedColor: React.State<Colors> = new React.State<any>(Colors.Standard);
|
||||
selectedPage: React.State<ChatPageTypes> = new React.State<any>(
|
||||
ChatPageTypes.Messages,
|
||||
ChatPageTypes.Messages,
|
||||
);
|
||||
pageContexts = new React.MapState<Context>();
|
||||
|
||||
@@ -42,186 +42,189 @@ export default class ChatViewModel extends ContextHost<ChatPageTypes> {
|
||||
|
||||
// context
|
||||
get isOpen(): boolean {
|
||||
return this.chatListViewModel.selectedChat.value == this;
|
||||
return this.chatListViewModel.selectedChat.value == this;
|
||||
}
|
||||
|
||||
get contextSelection(): ChatPageTypes {
|
||||
return this.selectedPage.value;
|
||||
return this.selectedPage.value;
|
||||
}
|
||||
|
||||
// view
|
||||
open = (): void => {
|
||||
this.coreViewModel.context = this;
|
||||
this.chatListViewModel.openChat(this);
|
||||
//this.selectedPage.callSubscriptions();
|
||||
this.coreViewModel.context = this;
|
||||
this.chatListViewModel.openChat(this);
|
||||
//this.selectedPage.callSubscriptions();
|
||||
};
|
||||
|
||||
openPage = (page: ChatPageTypes): void => {
|
||||
this.closeCurrentContext();
|
||||
this.selectedPage.value = page;
|
||||
this.closeCurrentContext();
|
||||
this.selectedPage.value = page;
|
||||
};
|
||||
|
||||
setColor = (color: Colors): void => {
|
||||
this.setDisplayedColor(color);
|
||||
this.chatModel.setColor(color);
|
||||
this.setDisplayedColor(color);
|
||||
this.chatModel.setColor(color);
|
||||
};
|
||||
|
||||
setDisplayedColor = (color: Colors): void => {
|
||||
this.displayedColor.value = color;
|
||||
this.displayedColor.value = color;
|
||||
};
|
||||
|
||||
resetColor = (): void => {
|
||||
this.displayedColor.value = this.settingsPageViewModel.color.value;
|
||||
this.displayedColor.value = this.settingsPageViewModel.color.value;
|
||||
};
|
||||
|
||||
updateIndex = (): void => {
|
||||
const index: number =
|
||||
this.chatListViewModel.chatIndexManager.getIndex(this);
|
||||
this.index.value = index;
|
||||
const index: number =
|
||||
this.chatListViewModel.chatIndexManager.getIndex(this);
|
||||
this.index.value = index;
|
||||
};
|
||||
|
||||
// load
|
||||
loadPageSelection = (): void => {
|
||||
const path: string[] = StorageModel.getPath(
|
||||
StorageModelSubPaths.Chat,
|
||||
filePaths.chat.lastUsedPage(this.chatModel.id),
|
||||
);
|
||||
const lastUsedPage: string | null =
|
||||
this.coreViewModel.storageModel.read(path);
|
||||
if (lastUsedPage != null) {
|
||||
this.openPage(lastUsedPage as ChatPageTypes);
|
||||
}
|
||||
const path: string[] = StorageModel.getPath(
|
||||
StorageModelSubPaths.Chat,
|
||||
filePaths.chat.lastUsedPage(this.chatModel.id),
|
||||
);
|
||||
const lastUsedPage: string | null =
|
||||
this.coreViewModel.storageModel.read(path);
|
||||
if (lastUsedPage != null) {
|
||||
this.openPage(lastUsedPage as ChatPageTypes);
|
||||
}
|
||||
|
||||
this.selectedPage.subscribeSilent((newPage) => {
|
||||
this.coreViewModel.storageModel.write(path, newPage);
|
||||
this.resetColor();
|
||||
});
|
||||
this.selectedPage.subscribeSilent((newPage) => {
|
||||
this.coreViewModel.storageModel.write(path, newPage);
|
||||
this.resetColor();
|
||||
});
|
||||
};
|
||||
|
||||
loadInfo = (): void => {
|
||||
this.updateReadStatus();
|
||||
this.taskBoardSuggestions.set(CALENDAR_EVENT_BOARD_ID, [
|
||||
CALENDAR_EVENT_BOARD_ID,
|
||||
this.coreViewModel.translations.chatPage.calendar.eventsBoard,
|
||||
]);
|
||||
this.updateReadStatus();
|
||||
this.taskBoardSuggestions.set(CALENDAR_EVENT_BOARD_ID, [
|
||||
CALENDAR_EVENT_BOARD_ID,
|
||||
this.coreViewModel.translations.chatPage.calendar.eventsBoard,
|
||||
]);
|
||||
};
|
||||
|
||||
updateReadStatus = (): void => {
|
||||
if (
|
||||
this.chatListViewModel.selectedChat.value == this &&
|
||||
this.selectedPage.value == ChatPageTypes.Messages
|
||||
) {
|
||||
this.chatModel.setReadStatus(false);
|
||||
}
|
||||
this.hasUnreadMessages.value = this.chatModel.info.hasUnreadMessages;
|
||||
if (
|
||||
this.chatListViewModel.selectedChat.value == this &&
|
||||
this.selectedPage.value == ChatPageTypes.Messages
|
||||
) {
|
||||
this.chatModel.setReadStatus(false);
|
||||
}
|
||||
this.hasUnreadMessages.value = this.chatModel.info.hasUnreadMessages;
|
||||
};
|
||||
|
||||
setReadStatus = (hasUnreadMessages: boolean): void => {
|
||||
this.chatModel.setReadStatus(hasUnreadMessages);
|
||||
this.hasUnreadMessages.value = hasUnreadMessages;
|
||||
this.chatModel.setReadStatus(hasUnreadMessages);
|
||||
this.hasUnreadMessages.value = hasUnreadMessages;
|
||||
};
|
||||
|
||||
subscribeReadStatus = (): void => {
|
||||
React.createProxyState(
|
||||
[this.selectedPage, this.chatListViewModel.selectedChat],
|
||||
() => {
|
||||
if (this.chatListViewModel.selectedChat.value != this) return;
|
||||
if (this.selectedPage.value != ChatPageTypes.Messages) return;
|
||||
this.setReadStatus(false);
|
||||
},
|
||||
);
|
||||
React.createProxyState(
|
||||
[this.selectedPage, this.chatListViewModel.selectedChat],
|
||||
() => {
|
||||
if (this.chatListViewModel.selectedChat.value != this) return;
|
||||
if (this.selectedPage.value != ChatPageTypes.Messages) return;
|
||||
this.setReadStatus(false);
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
// exit
|
||||
close = (): void => {
|
||||
this.coreViewModel.closeContext(this.contextId);
|
||||
this.coreViewModel.closeContext(this.contextId);
|
||||
};
|
||||
|
||||
handleContextClose = (): void => {
|
||||
this.chatListViewModel.closeChat();
|
||||
this.chatListViewModel.closeChat();
|
||||
};
|
||||
|
||||
// init
|
||||
constructor(
|
||||
readonly coreViewModel: CoreViewModel,
|
||||
public readonly chatModel: ChatModel,
|
||||
public readonly settingsViewModel: SettingsViewModel,
|
||||
public readonly notificationViewModel: NotificationViewModel,
|
||||
public readonly connectionViewModel: ConnectionViewModel,
|
||||
public readonly chatListViewModel: ChatListViewModel,
|
||||
readonly coreViewModel: CoreViewModel,
|
||||
public readonly chatModel: ChatModel,
|
||||
public readonly settingsViewModel: SettingsViewModel,
|
||||
public readonly notificationViewModel: NotificationViewModel,
|
||||
public readonly connectionViewModel: ConnectionViewModel,
|
||||
public readonly chatListViewModel: ChatListViewModel,
|
||||
) {
|
||||
super("chat", coreViewModel);
|
||||
super("chat", coreViewModel);
|
||||
|
||||
// page viewModels
|
||||
this.calendarViewModel = new CalendarPageViewModel(
|
||||
coreViewModel,
|
||||
this,
|
||||
this.chatModel.fileModel.boardsAndTasksModel.calendarModel,
|
||||
this.chatModel.fileModel.boardsAndTasksModel,
|
||||
);
|
||||
this.taskPageViewModel = new TaskPageViewModel(
|
||||
this.coreViewModel,
|
||||
this,
|
||||
this.chatModel.fileModel.boardsAndTasksModel,
|
||||
);
|
||||
this.messagePageViewModel = new MessagePageViewModel(
|
||||
this.coreViewModel,
|
||||
this,
|
||||
);
|
||||
this.settingsPageViewModel = new SettingsPageViewModel(
|
||||
this.coreViewModel,
|
||||
this,
|
||||
);
|
||||
// page viewModels
|
||||
this.calendarViewModel = new CalendarPageViewModel(
|
||||
coreViewModel,
|
||||
this,
|
||||
this.chatModel.fileModel.boardsAndTasksModel.calendarModel,
|
||||
this.chatModel.fileModel.boardsAndTasksModel,
|
||||
);
|
||||
this.taskPageViewModel = new TaskPageViewModel(
|
||||
this.coreViewModel,
|
||||
this,
|
||||
this.chatModel.fileModel.boardsAndTasksModel,
|
||||
);
|
||||
this.messagePageViewModel = new MessagePageViewModel(
|
||||
this.coreViewModel,
|
||||
this,
|
||||
);
|
||||
this.settingsPageViewModel = new SettingsPageViewModel(
|
||||
this.coreViewModel,
|
||||
this,
|
||||
);
|
||||
|
||||
// handlers
|
||||
chatModel.chatMessageHandlerManager.setHandler(
|
||||
this.chatModel.id,
|
||||
(chatMessage: ChatMessage) => {
|
||||
this.messagePageViewModel.showChatMessage(chatMessage);
|
||||
this.updateReadStatus();
|
||||
// handlers
|
||||
chatModel.chatMessageHandlerManager.setHandler(
|
||||
this.chatModel.id,
|
||||
(chatMessage: ChatMessage) => {
|
||||
this.messagePageViewModel.showChatMessage(chatMessage);
|
||||
this.updateReadStatus();
|
||||
|
||||
this.notificationViewModel.showNotification(chatMessage);
|
||||
},
|
||||
);
|
||||
chatModel.reactionHandlerManager.setHandler(
|
||||
this.chatModel.id,
|
||||
(reaction: ChatMessageReaction) => {
|
||||
this.messagePageViewModel.handleReaction(reaction);
|
||||
},
|
||||
);
|
||||
chatModel.changeHandlerManager.setHandler(this.chatModel.id, this.settingsPageViewModel.updateData);
|
||||
this.notificationViewModel.showNotification(chatMessage);
|
||||
},
|
||||
);
|
||||
chatModel.reactionHandlerManager.setHandler(
|
||||
this.chatModel.id,
|
||||
(reaction: ChatMessageReaction) => {
|
||||
this.messagePageViewModel.handleReaction(reaction);
|
||||
},
|
||||
);
|
||||
chatModel.changeHandlerManager.setHandler(
|
||||
this.chatModel.id,
|
||||
this.settingsPageViewModel.updateData,
|
||||
);
|
||||
|
||||
// load
|
||||
this.loadPageSelection();
|
||||
this.resetColor();
|
||||
this.loadInfo();
|
||||
this.subscribeReadStatus();
|
||||
// load
|
||||
this.loadPageSelection();
|
||||
this.resetColor();
|
||||
this.loadInfo();
|
||||
this.subscribeReadStatus();
|
||||
|
||||
// keystrokes
|
||||
this.registerKeyStroke(CommonKeys.Home, this.close);
|
||||
this.registerKeyStroke("u", () =>
|
||||
this.openPage(ChatPageTypes.Messages),
|
||||
);
|
||||
this.registerKeyStroke("i", () => this.openPage(ChatPageTypes.Tasks));
|
||||
this.registerKeyStroke("o", () =>
|
||||
this.openPage(ChatPageTypes.Calendar),
|
||||
);
|
||||
this.registerKeyStroke(CommonKeys.Settings, () =>
|
||||
this.openPage(ChatPageTypes.Settings),
|
||||
);
|
||||
// keystrokes
|
||||
this.registerKeyStroke(CommonKeys.Home, this.close);
|
||||
this.registerKeyStroke("u", () =>
|
||||
this.openPage(ChatPageTypes.Messages),
|
||||
);
|
||||
this.registerKeyStroke("i", () => this.openPage(ChatPageTypes.Tasks));
|
||||
this.registerKeyStroke("o", () =>
|
||||
this.openPage(ChatPageTypes.Calendar),
|
||||
);
|
||||
this.registerKeyStroke(CommonKeys.Settings, () =>
|
||||
this.openPage(ChatPageTypes.Settings),
|
||||
);
|
||||
|
||||
// context
|
||||
this.chatListViewModel.selectedChat.subscribeSilent(
|
||||
this.updateContexts,
|
||||
);
|
||||
this.selectedPage.subscribeSilent(this.updateContexts);
|
||||
// context
|
||||
this.chatListViewModel.selectedChat.subscribeSilent(
|
||||
this.updateContexts,
|
||||
);
|
||||
this.selectedPage.subscribeSilent(this.updateContexts);
|
||||
}
|
||||
}
|
||||
|
||||
// types
|
||||
export enum ChatPageTypes {
|
||||
Settings = "settings",
|
||||
Messages = "messages",
|
||||
Tasks = "tasks",
|
||||
Calendar = "calendar",
|
||||
Messages = "messages",
|
||||
Tasks = "tasks",
|
||||
Calendar = "calendar",
|
||||
}
|
||||
|
||||
@@ -9,13 +9,19 @@ import ConnectionModel from "../../Model/Global/connectionModel";
|
||||
import ChatListModel from "../../Model/Chat/chatListModel";
|
||||
|
||||
export default class CoreViewModel {
|
||||
swRegistration: ServiceWorkerRegistration|undefined = undefined;
|
||||
swRegistration: ServiceWorkerRegistration | undefined = undefined;
|
||||
|
||||
version: React.State<string> = new React.State("");
|
||||
latestVersion: React.State<string> = new React.State("");
|
||||
noUpdateAvailable: React.State<boolean> = React.createProxyState([this.latestVersion], () => {
|
||||
return (this.latestVersion.value == "" || this.latestVersion.value == this.version.value)
|
||||
})
|
||||
version: React.State<string> = new React.State("");
|
||||
latestVersion: React.State<string> = new React.State("");
|
||||
noUpdateAvailable: React.State<boolean> = React.createProxyState(
|
||||
[this.latestVersion],
|
||||
() => {
|
||||
return (
|
||||
this.latestVersion.value == "" ||
|
||||
this.latestVersion.value == this.version.value
|
||||
);
|
||||
},
|
||||
);
|
||||
updateText: React.State<string> = new React.State("");
|
||||
|
||||
translations: Translations;
|
||||
@@ -82,11 +88,11 @@ export default class CoreViewModel {
|
||||
};
|
||||
|
||||
handleChron = (): void => {
|
||||
const newDate = new Date();
|
||||
if (this.unwrappedTodayDate.toDateString() != newDate.toDateString())
|
||||
this.todayDate.value = new Date();
|
||||
if (formatTime(newDate) != this.time.value)
|
||||
this.time.value = formatTime(newDate);
|
||||
const newDate = new Date();
|
||||
if (this.unwrappedTodayDate.toDateString() != newDate.toDateString())
|
||||
this.todayDate.value = new Date();
|
||||
if (formatTime(newDate) != this.time.value)
|
||||
this.time.value = formatTime(newDate);
|
||||
};
|
||||
|
||||
// DRAG & DROP
|
||||
@@ -94,75 +100,79 @@ export default class CoreViewModel {
|
||||
|
||||
// OFFLINE MODE & UPDATE
|
||||
configureServiceWorker = async (): Promise<void> => {
|
||||
if ("serviceWorker" in navigator) {
|
||||
try {
|
||||
this.swRegistration = await navigator.serviceWorker.register(
|
||||
"sw.js",
|
||||
{
|
||||
scope: "/",
|
||||
},
|
||||
);
|
||||
if (this.swRegistration.active) {
|
||||
console.log("Service worker active");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Could not install service worker: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ("serviceWorker" in navigator) {
|
||||
try {
|
||||
this.swRegistration = await navigator.serviceWorker.register(
|
||||
"sw.js",
|
||||
{
|
||||
scope: "/",
|
||||
},
|
||||
);
|
||||
if (this.swRegistration.active) {
|
||||
console.log("Service worker active");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Could not install service worker: ${error}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
checkUpdates = (): void => {
|
||||
fetch("/version").then(async response => {
|
||||
this.version.value = await response.text();
|
||||
});
|
||||
fetch("/latestVersion").then(async response => {
|
||||
this.latestVersion.value = (await response.text()).replace("\n", "");
|
||||
})
|
||||
}
|
||||
fetch("/version").then(async (response) => {
|
||||
this.version.value = await response.text();
|
||||
});
|
||||
fetch("/latestVersion").then(async (response) => {
|
||||
this.latestVersion.value = (await response.text()).replace(
|
||||
"\n",
|
||||
"",
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
update = async (): Promise<void> => {
|
||||
if (!this.swRegistration) return;
|
||||
await this.swRegistration.update();
|
||||
setTimeout(()=>{
|
||||
window.location.reload();
|
||||
}, 500);
|
||||
}
|
||||
if (!this.swRegistration) return;
|
||||
await this.swRegistration.update();
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 500);
|
||||
};
|
||||
|
||||
// init
|
||||
constructor(
|
||||
public readonly storageModel: StorageModel,
|
||||
public readonly settingsModel: SettingsModel,
|
||||
public readonly connectionModel: ConnectionModel,
|
||||
public readonly chatListModel: ChatListModel,
|
||||
public readonly fileTransferModel: FileTransferModel,
|
||||
public readonly storageModel: StorageModel,
|
||||
public readonly settingsModel: SettingsModel,
|
||||
public readonly connectionModel: ConnectionModel,
|
||||
public readonly chatListModel: ChatListModel,
|
||||
public readonly fileTransferModel: FileTransferModel,
|
||||
) {
|
||||
this.translations =
|
||||
allTranslations[settingsModel.language] || allTranslations.en;
|
||||
this.translations =
|
||||
allTranslations[settingsModel.language] || allTranslations.en;
|
||||
|
||||
this.latestVersion.subscribe(latestVersion => {
|
||||
this.updateText.value = this.translations.homePage.updateButton(latestVersion);
|
||||
});
|
||||
this.latestVersion.subscribe((latestVersion) => {
|
||||
this.updateText.value =
|
||||
this.translations.homePage.updateButton(latestVersion);
|
||||
});
|
||||
|
||||
document.body.addEventListener("keydown", this.handleKeyDown);
|
||||
document.body.addEventListener("keydown", this.handleKeyDown);
|
||||
|
||||
window.onpopstate = () => {
|
||||
if (!this.context) return;
|
||||
this.closeContext(this.context.contextId, true);
|
||||
};
|
||||
window.onpopstate = () => {
|
||||
if (!this.context) return;
|
||||
this.closeContext(this.context.contextId, true);
|
||||
};
|
||||
|
||||
this.configureServiceWorker();
|
||||
this.checkUpdates();
|
||||
this.configureServiceWorker();
|
||||
this.checkUpdates();
|
||||
|
||||
this.startChron();
|
||||
this.chronHandlerManager.setHandler(
|
||||
"core-view-model",
|
||||
this.handleChron,
|
||||
);
|
||||
this.startChron();
|
||||
this.chronHandlerManager.setHandler(
|
||||
"core-view-model",
|
||||
this.handleChron,
|
||||
);
|
||||
}
|
||||
|
||||
// util
|
||||
static checkIsKeystroke(e: KeyboardEvent): boolean {
|
||||
return (e.metaKey || e.altKey) && e.ctrlKey;
|
||||
return (e.metaKey || e.altKey) && e.ctrlKey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,19 +181,19 @@ export class Context {
|
||||
keystrokes = new Map<string, () => void>();
|
||||
|
||||
handleKeystroke = (e: KeyboardEvent): boolean => {
|
||||
const fn: (() => void) | undefined = this.keystrokes.get(
|
||||
e.key.toLowerCase(),
|
||||
);
|
||||
if (!fn) return false;
|
||||
fn();
|
||||
return true;
|
||||
const fn: (() => void) | undefined = this.keystrokes.get(
|
||||
e.key.toLowerCase(),
|
||||
);
|
||||
if (!fn) return false;
|
||||
fn();
|
||||
return true;
|
||||
};
|
||||
|
||||
close = (): void => {};
|
||||
handleContextClose = (fromHistoryEvent: boolean): void => {};
|
||||
|
||||
registerKeyStroke = (key: string, fn: () => void): void => {
|
||||
this.keystrokes.set(key, fn);
|
||||
this.keystrokes.set(key, fn);
|
||||
};
|
||||
|
||||
constructor(public contextDebugDescription: string) {}
|
||||
@@ -194,45 +204,45 @@ export class ContextHost<T> extends Context {
|
||||
currentContext = new React.State<Context | undefined>(undefined);
|
||||
|
||||
get isOpen(): boolean {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
get contextSelection(): T | undefined {
|
||||
return undefined;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
registerContext = (key: T, context: Context): void => {
|
||||
this.contexts.set(key, context);
|
||||
this.contexts.set(key, context);
|
||||
};
|
||||
|
||||
closeCurrentContext = (): void => {
|
||||
if (this.currentContext.value) {
|
||||
this.coreViewModel.closeContext(
|
||||
this.currentContext.value.contextId,
|
||||
);
|
||||
}
|
||||
this.currentContext.value = undefined;
|
||||
if (this.currentContext.value) {
|
||||
this.coreViewModel.closeContext(
|
||||
this.currentContext.value.contextId,
|
||||
);
|
||||
}
|
||||
this.currentContext.value = undefined;
|
||||
};
|
||||
|
||||
updateContexts = (): void => {
|
||||
if (this.isOpen == false) return;
|
||||
if (this.isOpen == false) return;
|
||||
|
||||
const selection = this.contextSelection;
|
||||
if (!selection) return;
|
||||
const selectedContext: Context | undefined =
|
||||
this.contexts.get(selection);
|
||||
if (!selectedContext) return;
|
||||
if (selectedContext != this.currentContext.value) {
|
||||
this.closeCurrentContext();
|
||||
}
|
||||
const selection = this.contextSelection;
|
||||
if (!selection) return;
|
||||
const selectedContext: Context | undefined =
|
||||
this.contexts.get(selection);
|
||||
if (!selectedContext) return;
|
||||
if (selectedContext != this.currentContext.value) {
|
||||
this.closeCurrentContext();
|
||||
}
|
||||
|
||||
this.coreViewModel.context = selectedContext;
|
||||
this.currentContext.value = selectedContext;
|
||||
this.coreViewModel.context = selectedContext;
|
||||
this.currentContext.value = selectedContext;
|
||||
};
|
||||
|
||||
constructor(
|
||||
contextDebugDescription: string,
|
||||
public coreViewModel: CoreViewModel,
|
||||
contextDebugDescription: string,
|
||||
public coreViewModel: CoreViewModel,
|
||||
) {
|
||||
super(contextDebugDescription);
|
||||
super(contextDebugDescription);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import CoreViewModel, { Context } from "./coreViewModel";
|
||||
import * as React from "../../react";
|
||||
import { CommonKeys } from "../../View/keystrokes";
|
||||
import { formatISO } from "../../Model/Utility/utility";
|
||||
import StorageModel, {
|
||||
StorageModelSubPaths,
|
||||
filePaths,
|
||||
} from "../../Model/Global/storageModel";
|
||||
import { TransferData } from "../../Model/Global/fileTransferModel";
|
||||
import ChatModel from "../../Model/Chat/chatModel";
|
||||
import {formatISO} from "../../Model/Utility/utility";
|
||||
|
||||
export default class FileTransferViewModel extends Context {
|
||||
// state
|
||||
@@ -143,7 +143,7 @@ export default class FileTransferViewModel extends Context {
|
||||
|
||||
downloadFile = async (): Promise<void> => {
|
||||
if (this.cannotExport.value == true) return;
|
||||
const date = formatISO(new Date());
|
||||
const date = formatISO(new Date());
|
||||
|
||||
const backup: Blob =
|
||||
await this.coreViewModel.fileTransferModel.generateBackup(
|
||||
|
||||
@@ -16,11 +16,9 @@ export default class NotificationViewModel {
|
||||
if (this.seenMessageIds.has(message.id)) return;
|
||||
if (this.chatListViewModel.selectedChat.value == undefined) return;
|
||||
|
||||
const notification: Notification =
|
||||
this.createNotification(message);
|
||||
const notification: Notification = this.createNotification(message);
|
||||
const currentChat =
|
||||
this.chatListViewModel.selectedChat.value.chatModel
|
||||
.id;
|
||||
this.chatListViewModel.selectedChat.value.chatModel.id;
|
||||
const currentPage =
|
||||
this.chatListViewModel.selectedChat.value.selectedPage.value;
|
||||
if (
|
||||
@@ -39,10 +37,7 @@ export default class NotificationViewModel {
|
||||
|
||||
const chat = [
|
||||
...this.chatListViewModel.chatViewModels.value.values(),
|
||||
].find(
|
||||
(chat) =>
|
||||
chat.chatModel.id == notification.fullChannel,
|
||||
);
|
||||
].find((chat) => chat.chatModel.id == notification.fullChannel);
|
||||
if (!chat) return;
|
||||
chat.open();
|
||||
chat.openPage(ChatPageTypes.Messages);
|
||||
@@ -86,12 +81,12 @@ export default class NotificationViewModel {
|
||||
|
||||
// util
|
||||
createNotification(message: ChatMessage): Notification {
|
||||
const fullChannel = ChatModel.splitChannel(message.channel)[0];
|
||||
const chat = this.chatListViewModel.getDisplayName(fullChannel);
|
||||
const fullChannel = ChatModel.splitChannel(message.channel)[0];
|
||||
const chat = this.chatListViewModel.getDisplayName(fullChannel);
|
||||
return {
|
||||
messageId: message.id,
|
||||
chat,
|
||||
fullChannel,
|
||||
fullChannel,
|
||||
sender: message.sender,
|
||||
body: message.body,
|
||||
};
|
||||
|
||||
@@ -53,129 +53,129 @@ export default class SettingsViewModel extends Context {
|
||||
|
||||
// view
|
||||
applyTheme = (): void => {
|
||||
let theme: string = this.theme.value;
|
||||
|
||||
if (theme == ThemeSettings.System)
|
||||
theme = SettingsViewModel.getSystemTheme();
|
||||
let theme: string = this.theme.value;
|
||||
|
||||
switch (theme) {
|
||||
case ThemeSettings.Dynamic:
|
||||
const scene = this.selectDynamicScene();
|
||||
this.setScene(scene);
|
||||
break;
|
||||
case ThemeSettings.Dark:
|
||||
this.setScene(DynamicSceneNight);
|
||||
break;
|
||||
case ThemeSettings.Black:
|
||||
this.setScene(DynamicSceneBlack);
|
||||
break;
|
||||
default:
|
||||
this.setScene(DynamicSceneDay);
|
||||
}
|
||||
if (theme == ThemeSettings.System)
|
||||
theme = SettingsViewModel.getSystemTheme();
|
||||
|
||||
switch (theme) {
|
||||
case ThemeSettings.Dynamic:
|
||||
const scene = this.selectDynamicScene();
|
||||
this.setScene(scene);
|
||||
break;
|
||||
case ThemeSettings.Dark:
|
||||
this.setScene(DynamicSceneNight);
|
||||
break;
|
||||
case ThemeSettings.Black:
|
||||
this.setScene(DynamicSceneBlack);
|
||||
break;
|
||||
default:
|
||||
this.setScene(DynamicSceneDay);
|
||||
}
|
||||
};
|
||||
|
||||
selectDynamicScene = (): DynamicScene => {
|
||||
let hour = new Date().getHours();
|
||||
let hour = new Date().getHours();
|
||||
|
||||
if (hour >= 21 || hour <= 6) {
|
||||
return DynamicSceneNight;
|
||||
} else if (hour > 6 && hour < 10) {
|
||||
return DynamicSceneSunrise;
|
||||
} else if (hour < 14) {
|
||||
return DynamicSceneDay;
|
||||
} else if (hour < 17) {
|
||||
return DynamicSceneAfternoon;
|
||||
} else {
|
||||
return DynamicSceneSunset;
|
||||
}
|
||||
if (hour >= 21 || hour <= 6) {
|
||||
return DynamicSceneNight;
|
||||
} else if (hour > 6 && hour < 10) {
|
||||
return DynamicSceneSunrise;
|
||||
} else if (hour < 14) {
|
||||
return DynamicSceneDay;
|
||||
} else if (hour < 17) {
|
||||
return DynamicSceneAfternoon;
|
||||
} else {
|
||||
return DynamicSceneSunset;
|
||||
}
|
||||
};
|
||||
|
||||
setScene = (scene: DynamicScene): void => {
|
||||
document.body.style.setProperty(
|
||||
"--backdrop-grass-filter",
|
||||
`brightness(${scene.brightness})`,
|
||||
);
|
||||
document.body.style.setProperty(
|
||||
"--backdrop-grass-filter",
|
||||
`brightness(${scene.brightness})`,
|
||||
);
|
||||
|
||||
function setSkyColor(
|
||||
tone: 1 | 2,
|
||||
hue: number,
|
||||
saturation: number,
|
||||
luma: number,
|
||||
) {
|
||||
document.body.style.setProperty(
|
||||
`--sky-${tone}`,
|
||||
`hsl(${hue}, ${saturation}%, ${luma}%)`,
|
||||
);
|
||||
}
|
||||
setSkyColor(1, scene.hue1, scene.saturation, scene.luma);
|
||||
setSkyColor(2, scene.hue2, scene.saturation - 10, scene.luma - 10);
|
||||
function setSkyColor(
|
||||
tone: 1 | 2,
|
||||
hue: number,
|
||||
saturation: number,
|
||||
luma: number,
|
||||
) {
|
||||
document.body.style.setProperty(
|
||||
`--sky-${tone}`,
|
||||
`hsl(${hue}, ${saturation}%, ${luma}%)`,
|
||||
);
|
||||
}
|
||||
setSkyColor(1, scene.hue1, scene.saturation, scene.luma);
|
||||
setSkyColor(2, scene.hue2, scene.saturation - 10, scene.luma - 10);
|
||||
|
||||
document.body.setAttribute("theme", scene.baseTheme);
|
||||
document.body.setAttribute("theme", scene.baseTheme);
|
||||
};
|
||||
|
||||
// exit
|
||||
close = (): void => {
|
||||
this.coreViewModel.closeContext(this.contextId);
|
||||
this.coreViewModel.closeContext(this.contextId);
|
||||
};
|
||||
|
||||
handleContextClose = (): void => {
|
||||
this.isShowingSettingsModal.value = false;
|
||||
if (this.requiresReload.value == true) {
|
||||
window.location.reload();
|
||||
}
|
||||
this.isShowingSettingsModal.value = false;
|
||||
if (this.requiresReload.value == true) {
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
// init
|
||||
constructor(public readonly coreViewModel: CoreViewModel) {
|
||||
super("settings");
|
||||
super("settings");
|
||||
|
||||
this.username.value = coreViewModel.settingsModel.username;
|
||||
this.usernameInput.value = coreViewModel.settingsModel.username;
|
||||
this.firstDayOfWeek.value = coreViewModel.settingsModel.firstDayOfWeek;
|
||||
this.language.value = coreViewModel.settingsModel.language;
|
||||
this.theme.value = coreViewModel.settingsModel.theme;
|
||||
this.username.value = coreViewModel.settingsModel.username;
|
||||
this.usernameInput.value = coreViewModel.settingsModel.username;
|
||||
this.firstDayOfWeek.value = coreViewModel.settingsModel.firstDayOfWeek;
|
||||
this.language.value = coreViewModel.settingsModel.language;
|
||||
this.theme.value = coreViewModel.settingsModel.theme;
|
||||
|
||||
// subscriptions
|
||||
this.firstDayOfWeek.subscribe(this.setFirstDayofWeek);
|
||||
this.language.subscribeSilent((newValue) => {
|
||||
this.coreViewModel.settingsModel.setLanguage(newValue);
|
||||
this.requiresReload.value = true;
|
||||
});
|
||||
this.theme.subscribeSilent((newValue) => {
|
||||
this.coreViewModel.settingsModel.setTheme(newValue);
|
||||
});
|
||||
// subscriptions
|
||||
this.firstDayOfWeek.subscribe(this.setFirstDayofWeek);
|
||||
this.language.subscribeSilent((newValue) => {
|
||||
this.coreViewModel.settingsModel.setLanguage(newValue);
|
||||
this.requiresReload.value = true;
|
||||
});
|
||||
this.theme.subscribeSilent((newValue) => {
|
||||
this.coreViewModel.settingsModel.setTheme(newValue);
|
||||
});
|
||||
|
||||
// set theme
|
||||
this.theme.subscribe(() => {
|
||||
this.applyTheme();
|
||||
});
|
||||
SettingsViewModel.generateThemeMedia().addEventListener("change", () =>
|
||||
this.applyTheme(),
|
||||
);
|
||||
const seconds = new Date().getSeconds();
|
||||
const secondsUntilNewMinute = 60 - seconds;
|
||||
setTimeout(() => {
|
||||
setInterval(this.applyTheme, 1000 * 60);
|
||||
}, secondsUntilNewMinute);
|
||||
// set theme
|
||||
this.theme.subscribe(() => {
|
||||
this.applyTheme();
|
||||
});
|
||||
SettingsViewModel.generateThemeMedia().addEventListener("change", () =>
|
||||
this.applyTheme(),
|
||||
);
|
||||
const seconds = new Date().getSeconds();
|
||||
const secondsUntilNewMinute = 60 - seconds;
|
||||
setTimeout(() => {
|
||||
setInterval(this.applyTheme, 1000 * 60);
|
||||
}, secondsUntilNewMinute);
|
||||
|
||||
// keystrokes
|
||||
this.registerKeyStroke(CommonKeys.CloseOrCancel, this.close);
|
||||
// keystrokes
|
||||
this.registerKeyStroke(CommonKeys.CloseOrCancel, this.close);
|
||||
}
|
||||
|
||||
static generateThemeMedia(): MediaQueryList {
|
||||
return window.matchMedia("(prefers-color-scheme: dark)");
|
||||
return window.matchMedia("(prefers-color-scheme: dark)");
|
||||
}
|
||||
|
||||
static getSystemTheme(): string {
|
||||
const media = SettingsViewModel.generateThemeMedia();
|
||||
return media.matches == true ? ThemeSettings.Dark : ThemeSettings.Light;
|
||||
const media = SettingsViewModel.generateThemeMedia();
|
||||
return media.matches == true ? ThemeSettings.Dark : ThemeSettings.Light;
|
||||
}
|
||||
}
|
||||
|
||||
export enum SettingsModalPages {
|
||||
Appearance,
|
||||
Regional,
|
||||
Info,
|
||||
Regional,
|
||||
Info,
|
||||
}
|
||||
|
||||
export interface DynamicScene {
|
||||
|
||||
@@ -50,15 +50,17 @@ export default class StorageViewModel extends Context {
|
||||
};
|
||||
|
||||
calculateUsage = (): void => {
|
||||
this.occupiedSpaceMB.value = this.coreViewModel.storageModel.calculateUsage();
|
||||
this.maximumSpaceMB.value = this.coreViewModel.storageModel.determineCapacity();
|
||||
}
|
||||
this.occupiedSpaceMB.value =
|
||||
this.coreViewModel.storageModel.calculateUsage();
|
||||
this.maximumSpaceMB.value =
|
||||
this.coreViewModel.storageModel.determineCapacity();
|
||||
};
|
||||
|
||||
// view
|
||||
showStorageModal = (): void => {
|
||||
this.coreViewModel.context = this;
|
||||
this.isShowingStorageModal.value = true;
|
||||
this.calculateUsage();
|
||||
this.calculateUsage();
|
||||
};
|
||||
|
||||
// exit
|
||||
|
||||
@@ -7,11 +7,11 @@ import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
||||
import * as React from "../../react";
|
||||
import { Colors } from "../../colors";
|
||||
import { CommonKeys } from "../../View/keystrokes";
|
||||
import { PinchToZoomData } from "../../Model/Utility/utility";
|
||||
import BoardsAndTasksModel, {
|
||||
BoardInfoFileContent,
|
||||
TaskFileContent,
|
||||
} from "../../Model/Files/boardsAndTasksModel";
|
||||
import {PinchToZoomData} from "../../Model/Utility/utility";
|
||||
|
||||
export default class BoardViewModel extends TaskContainingPageViewModel {
|
||||
// state
|
||||
@@ -34,7 +34,11 @@ export default class BoardViewModel extends TaskContainingPageViewModel {
|
||||
new React.ListState();
|
||||
isFilterActive: React.State<boolean>;
|
||||
|
||||
pinchToZoomData: React.State<PinchToZoomData> = new React.State({zoom: 1, x: 0, y: 0});
|
||||
pinchToZoomData: React.State<PinchToZoomData> = new React.State({
|
||||
zoom: 1,
|
||||
x: 0,
|
||||
y: 0,
|
||||
});
|
||||
|
||||
// paths
|
||||
getBasePath = (): string[] => {
|
||||
|
||||
@@ -4,11 +4,19 @@ import CoreViewModel from "../Global/coreViewModel";
|
||||
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
||||
import * as React from "../../react";
|
||||
import { CommonKeys } from "../../View/keystrokes";
|
||||
import {
|
||||
formatISO,
|
||||
formatISOFromParts,
|
||||
formatMonthStringFromParts,
|
||||
formatTime,
|
||||
isoToDateString,
|
||||
isoToMonthString,
|
||||
padZero,
|
||||
} from "../../Model/Utility/utility";
|
||||
import CalendarModel, { MonthGrid } from "../../Model/Files/calendarModel";
|
||||
import BoardsAndTasksModel, {
|
||||
TaskFileContent,
|
||||
} from "../../Model/Files/boardsAndTasksModel";
|
||||
import {formatISO, formatISOFromParts, formatMonthStringFromParts, formatTime, isoToDateString, isoToMonthString, padZero} from "../../Model/Utility/utility";
|
||||
|
||||
export const CALENDAR_EVENT_BOARD_ID = "events";
|
||||
|
||||
@@ -22,7 +30,11 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel {
|
||||
}
|
||||
|
||||
get selectedDateString(): string {
|
||||
return formatISOFromParts(this.selectedYear.value, this.selectedMonth.value, this.selectedDate.value);
|
||||
return formatISOFromParts(
|
||||
this.selectedYear.value,
|
||||
this.selectedMonth.value,
|
||||
this.selectedDate.value,
|
||||
);
|
||||
}
|
||||
|
||||
// paths
|
||||
@@ -39,8 +51,8 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel {
|
||||
monthGrid: React.State<
|
||||
MonthGrid<React.MapState<TaskViewModel>> | undefined
|
||||
> = new React.State<any>(undefined);
|
||||
|
||||
nextTask = new React.State<TaskViewModel|undefined>(undefined);
|
||||
|
||||
nextTask = new React.State<TaskViewModel | undefined>(undefined);
|
||||
|
||||
// methods
|
||||
createEvent = (): void => {
|
||||
@@ -65,9 +77,7 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel {
|
||||
};
|
||||
|
||||
getEventsForDate = (): React.MapState<TaskViewModel> | undefined => {
|
||||
const paddedDate: string = padZero(
|
||||
this.selectedDate.toString(), 2
|
||||
);
|
||||
const paddedDate: string = padZero(this.selectedDate.toString(), 2);
|
||||
|
||||
if (this.monthGrid.value == undefined) {
|
||||
return undefined;
|
||||
@@ -82,9 +92,7 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel {
|
||||
): React.MapState<TaskViewModel> | null => {
|
||||
if (this.monthGrid.value == null) return null;
|
||||
|
||||
const date: string = isoToDateString(
|
||||
taskFileContent.date ?? "",
|
||||
);
|
||||
const date: string = isoToDateString(taskFileContent.date ?? "");
|
||||
return this.monthGrid.value.days[date];
|
||||
};
|
||||
|
||||
@@ -152,11 +160,7 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel {
|
||||
};
|
||||
|
||||
handleDrop = (year: string, month: string, date: string): void => {
|
||||
const ISOString: string = formatISOFromParts(
|
||||
year,
|
||||
month,
|
||||
date,
|
||||
);
|
||||
const ISOString: string = formatISOFromParts(year, month, date);
|
||||
|
||||
const draggedObject: any = this.coreViewModel.draggedObject.value;
|
||||
if (draggedObject instanceof TaskViewModel == false) return;
|
||||
@@ -165,37 +169,34 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel {
|
||||
};
|
||||
|
||||
handleChron = (): void => {
|
||||
this.updateMonthGrid();
|
||||
this.updateNextTask();
|
||||
}
|
||||
this.updateMonthGrid();
|
||||
this.updateNextTask();
|
||||
};
|
||||
|
||||
updateMonthGrid = (): void => {
|
||||
const today = formatISO(this.coreViewModel.todayDate.value)
|
||||
if (
|
||||
this.currentTodayDate == today
|
||||
)
|
||||
return;
|
||||
const today = formatISO(this.coreViewModel.todayDate.value);
|
||||
if (this.currentTodayDate == today) return;
|
||||
this.loadMonthTasks();
|
||||
this.currentTodayDate = today;
|
||||
this.selectedDate.callSubscriptions();
|
||||
this.selectedDate.callSubscriptions();
|
||||
};
|
||||
|
||||
updateNextTask = (): void => {
|
||||
if (this.selectedDateString != this.currentTodayDate) {
|
||||
this.nextTask.value = undefined;
|
||||
return;
|
||||
}
|
||||
if (this.selectedDateString != this.currentTodayDate) {
|
||||
this.nextTask.value = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
const tasks = this.getEventsForDate();
|
||||
if (tasks == undefined) return;
|
||||
const taskArray =[...tasks.value.values()];
|
||||
const sorted = taskArray.sort((a, b) => a.index.value - b.index.value);
|
||||
for (const task of sorted) {
|
||||
if (task.time.value <= this.coreViewModel.time.value) continue;
|
||||
this.nextTask.value = task;
|
||||
break;
|
||||
};
|
||||
}
|
||||
const tasks = this.getEventsForDate();
|
||||
if (tasks == undefined) return;
|
||||
const taskArray = [...tasks.value.values()];
|
||||
const sorted = taskArray.sort((a, b) => a.index.value - b.index.value);
|
||||
for (const task of sorted) {
|
||||
if (task.time.value <= this.coreViewModel.time.value) continue;
|
||||
this.nextTask.value = task;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// load
|
||||
loadMonthTasks = (): void => {
|
||||
@@ -217,8 +218,7 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel {
|
||||
}
|
||||
};
|
||||
|
||||
loadData = (): void => {
|
||||
};
|
||||
loadData = (): void => {};
|
||||
|
||||
// init
|
||||
constructor(
|
||||
@@ -237,9 +237,9 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel {
|
||||
React.bulkSubscribe([this.selectedYear, this.selectedMonth], () => {
|
||||
this.loadMonthTasks();
|
||||
});
|
||||
this.selectedDate.subscribeSilent(()=>{
|
||||
this.updateNextTask();
|
||||
})
|
||||
this.selectedDate.subscribeSilent(() => {
|
||||
this.updateNextTask();
|
||||
});
|
||||
|
||||
// handlers
|
||||
boardsAndTasksModel.taskHandlerManager.setHandler(
|
||||
|
||||
@@ -16,9 +16,17 @@ export default class MessagePageViewModel extends Context {
|
||||
new React.MapState();
|
||||
filteredMessageViewModels: React.ListState<ChatMessageViewModel> =
|
||||
new React.ListState();
|
||||
replyViewSelectedMessage = new React.State<ChatMessageViewModel|undefined>(undefined);
|
||||
isReplyViewActive: React.State<boolean> = React.createProxyState([this.replyViewSelectedMessage], ()=>this.replyViewSelectedMessage.value != undefined);
|
||||
isReplyViewInactive = React.createProxyState([this.isReplyViewActive], ()=>!this.isReplyViewActive.value);
|
||||
replyViewSelectedMessage = new React.State<
|
||||
ChatMessageViewModel | undefined
|
||||
>(undefined);
|
||||
isReplyViewActive: React.State<boolean> = React.createProxyState(
|
||||
[this.replyViewSelectedMessage],
|
||||
() => this.replyViewSelectedMessage.value != undefined,
|
||||
);
|
||||
isReplyViewInactive = React.createProxyState(
|
||||
[this.isReplyViewActive],
|
||||
() => !this.isReplyViewActive.value,
|
||||
);
|
||||
searchViewModel: SearchViewModel<ChatMessageViewModel>;
|
||||
isFilterModalOpen = new React.State<boolean>(false);
|
||||
reactionFilter = new React.State<ReactionSymbols | undefined>(undefined);
|
||||
@@ -39,193 +47,194 @@ export default class MessagePageViewModel extends Context {
|
||||
if (this.cannotSendMessage.value == true) return;
|
||||
|
||||
const idPromise = this.sendMessageFromBody(this.composingMessage.value);
|
||||
this.composingMessage.value = "";
|
||||
this.composingMessage.value = "";
|
||||
|
||||
const id = await idPromise;
|
||||
if (id && this.reactionFilter.value != undefined) {
|
||||
this.sendReaction(id, this.reactionFilter.value, false);
|
||||
}
|
||||
const id = await idPromise;
|
||||
if (id && this.reactionFilter.value != undefined) {
|
||||
this.sendReaction(id, this.reactionFilter.value, false);
|
||||
}
|
||||
};
|
||||
|
||||
sendMessageFromBody = (body: string): Promise<string|false>=> {
|
||||
let replyId: string | undefined = undefined;
|
||||
if (this.replyingMessage.value) {
|
||||
replyId = this.replyingMessage.value.chatMessage.id;
|
||||
}
|
||||
const id = this.chatViewModel.chatModel.sendMessage(body, replyId);
|
||||
sendMessageFromBody = (body: string): Promise<string | false> => {
|
||||
let replyId: string | undefined = undefined;
|
||||
if (this.replyingMessage.value) {
|
||||
replyId = this.replyingMessage.value.chatMessage.id;
|
||||
}
|
||||
const id = this.chatViewModel.chatModel.sendMessage(body, replyId);
|
||||
|
||||
if (this.replyViewSelectedMessage.value == undefined)
|
||||
this.replyingMessage.value = undefined;
|
||||
if (this.replyViewSelectedMessage.value == undefined)
|
||||
this.replyingMessage.value = undefined;
|
||||
|
||||
return id;
|
||||
return id;
|
||||
};
|
||||
|
||||
decryptMessage = async (
|
||||
messageViewModel: ChatMessageViewModel,
|
||||
messageViewModel: ChatMessageViewModel,
|
||||
): Promise<void> => {
|
||||
const chatMessage: ChatMessage = messageViewModel.chatMessage;
|
||||
await this.chatViewModel.chatModel.decryptMessage(chatMessage);
|
||||
this.chatViewModel.chatModel.addMessage(chatMessage);
|
||||
messageViewModel.loadData();
|
||||
const chatMessage: ChatMessage = messageViewModel.chatMessage;
|
||||
await this.chatViewModel.chatModel.decryptMessage(chatMessage);
|
||||
this.chatViewModel.chatModel.addMessage(chatMessage);
|
||||
messageViewModel.loadData();
|
||||
};
|
||||
|
||||
sendReaction = (
|
||||
messageId: string,
|
||||
content: ReactionSymbols,
|
||||
isDeleting: boolean,
|
||||
messageId: string,
|
||||
content: ReactionSymbols,
|
||||
isDeleting: boolean,
|
||||
): void => {
|
||||
this.chatViewModel.chatModel.sendReaction(
|
||||
messageId,
|
||||
content,
|
||||
isDeleting,
|
||||
);
|
||||
this.chatViewModel.chatModel.sendReaction(
|
||||
messageId,
|
||||
content,
|
||||
isDeleting,
|
||||
);
|
||||
};
|
||||
|
||||
setReply = (
|
||||
chatMessageViewModel: ChatMessageViewModel | undefined,
|
||||
setFocus: boolean = true,
|
||||
chatMessageViewModel: ChatMessageViewModel | undefined,
|
||||
setFocus: boolean = true,
|
||||
): void => {
|
||||
this.replyingMessage.value = chatMessageViewModel;
|
||||
if (setFocus == false || chatMessageViewModel == undefined) return;
|
||||
this.setFocus();
|
||||
this.replyingMessage.value = chatMessageViewModel;
|
||||
if (setFocus == false || chatMessageViewModel == undefined) return;
|
||||
this.setFocus();
|
||||
};
|
||||
|
||||
resetReply = (setFocus: boolean = true): void => {
|
||||
this.replyingMessage.value = undefined;
|
||||
if (setFocus == false) return;
|
||||
this.setFocus();
|
||||
this.replyingMessage.value = undefined;
|
||||
if (setFocus == false) return;
|
||||
this.setFocus();
|
||||
};
|
||||
|
||||
// view
|
||||
showChatMessage = (chatMessage: ChatMessage): void => {
|
||||
const chatMessageViewModel = new ChatMessageViewModel(
|
||||
this.coreViewModel,
|
||||
this,
|
||||
chatMessage,
|
||||
chatMessage.sender ==
|
||||
this.chatViewModel.settingsViewModel.username.value,
|
||||
);
|
||||
const chatMessageViewModel = new ChatMessageViewModel(
|
||||
this.coreViewModel,
|
||||
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,
|
||||
chatMessageViewModel,
|
||||
);
|
||||
}
|
||||
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,
|
||||
chatMessageViewModel,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
handleReaction = (reaction: ChatMessageReaction): void => {
|
||||
const messageViewModel: ChatMessageViewModel | undefined =
|
||||
this.chatMessageViewModels.value.get(reaction.messageId);
|
||||
if (messageViewModel == undefined) return;
|
||||
messageViewModel.handleReaction(reaction);
|
||||
const messageViewModel: ChatMessageViewModel | undefined =
|
||||
this.chatMessageViewModels.value.get(reaction.messageId);
|
||||
if (messageViewModel == undefined) return;
|
||||
messageViewModel.handleReaction(reaction);
|
||||
};
|
||||
|
||||
showFilterModal = (): void => {
|
||||
this.isFilterModalOpen.value = true;
|
||||
this.isFilterModalOpen.value = true;
|
||||
};
|
||||
|
||||
hideFilterModal = (): void => {
|
||||
this.isFilterModalOpen.value = false;
|
||||
this.isFilterModalOpen.value = false;
|
||||
};
|
||||
|
||||
revokeReactionFilter = (persist: boolean = true): void => {
|
||||
this.reactionFilter.value = undefined;
|
||||
if (persist) this.chatViewModel.chatModel.storeFilter("");
|
||||
this.reactionFilter.value = undefined;
|
||||
if (persist) this.chatViewModel.chatModel.storeFilter("");
|
||||
};
|
||||
|
||||
setReactionFilter = (content: ReactionSymbols): void => {
|
||||
this.reactionFilter.value = content;
|
||||
this.chatViewModel.chatModel.storeFilter(content);
|
||||
this.reactionFilter.value = content;
|
||||
this.chatViewModel.chatModel.storeFilter(content);
|
||||
};
|
||||
|
||||
resetFilter = (): void => {
|
||||
this.revokeReactionFilter();
|
||||
this.searchViewModel.search("");
|
||||
this.revokeReactionFilter();
|
||||
this.searchViewModel.search("");
|
||||
};
|
||||
|
||||
setReplyView = (message: ChatMessageViewModel): void => {
|
||||
this.replyViewSelectedMessage.value = message;
|
||||
this.revokeReactionFilter(false);
|
||||
this.setReply(message, false);
|
||||
}
|
||||
this.replyViewSelectedMessage.value = message;
|
||||
this.revokeReactionFilter(false);
|
||||
this.setReply(message, false);
|
||||
};
|
||||
|
||||
resetReplyView = (): void => {
|
||||
this.replyViewSelectedMessage.value = undefined;
|
||||
this.resetReply(false);
|
||||
this.restoreFilter();
|
||||
}
|
||||
this.replyViewSelectedMessage.value = undefined;
|
||||
this.resetReply(false);
|
||||
this.restoreFilter();
|
||||
};
|
||||
|
||||
setFocus = (): void => {
|
||||
this.focusSetter.callSubscriptions();
|
||||
this.focusSetter.callSubscriptions();
|
||||
};
|
||||
|
||||
// load
|
||||
loadData = (): void => {
|
||||
this.chatMessageViewModels.clear();
|
||||
for (const chatMessage of this.chatViewModel.chatModel.messages) {
|
||||
this.showChatMessage(chatMessage);
|
||||
}
|
||||
for (const reaction of this.chatViewModel.chatModel.reactions) {
|
||||
this.handleReaction(reaction);
|
||||
}
|
||||
this.chatMessageViewModels.clear();
|
||||
for (const chatMessage of this.chatViewModel.chatModel.messages) {
|
||||
this.showChatMessage(chatMessage);
|
||||
}
|
||||
for (const reaction of this.chatViewModel.chatModel.reactions) {
|
||||
this.handleReaction(reaction);
|
||||
}
|
||||
};
|
||||
|
||||
restoreFilter = (): void => {
|
||||
const previousFilter = this.chatViewModel.chatModel.getFilter() as any;
|
||||
if (Object.values(ReactionSymbols).includes(previousFilter)) this.setReactionFilter(previousFilter);
|
||||
}
|
||||
const previousFilter = this.chatViewModel.chatModel.getFilter() as any;
|
||||
if (Object.values(ReactionSymbols).includes(previousFilter))
|
||||
this.setReactionFilter(previousFilter);
|
||||
};
|
||||
|
||||
// init
|
||||
constructor(
|
||||
public readonly coreViewModel: CoreViewModel,
|
||||
public readonly chatViewModel: ChatViewModel,
|
||||
public readonly coreViewModel: CoreViewModel,
|
||||
public readonly chatViewModel: ChatViewModel,
|
||||
) {
|
||||
super("message-page");
|
||||
this.restoreFilter();
|
||||
super("message-page");
|
||||
this.restoreFilter();
|
||||
|
||||
// states
|
||||
this.cannotSendMessage = React.createProxyState(
|
||||
[
|
||||
this.chatViewModel.settingsViewModel.username,
|
||||
this.composingMessage,
|
||||
],
|
||||
() =>
|
||||
this.chatViewModel.settingsViewModel.username.value == "" ||
|
||||
this.composingMessage.value == "",
|
||||
);
|
||||
// states
|
||||
this.cannotSendMessage = React.createProxyState(
|
||||
[
|
||||
this.chatViewModel.settingsViewModel.username,
|
||||
this.composingMessage,
|
||||
],
|
||||
() =>
|
||||
this.chatViewModel.settingsViewModel.username.value == "" ||
|
||||
this.composingMessage.value == "",
|
||||
);
|
||||
|
||||
this.searchViewModel = new SearchViewModel(
|
||||
this.chatMessageViewModels,
|
||||
this.filteredMessageViewModels,
|
||||
(chatMessageViewModel) => [chatMessageViewModel.body.value],
|
||||
new React.ListState(),
|
||||
);
|
||||
this.searchViewModel = new SearchViewModel(
|
||||
this.chatMessageViewModels,
|
||||
this.filteredMessageViewModels,
|
||||
(chatMessageViewModel) => [chatMessageViewModel.body.value],
|
||||
new React.ListState(),
|
||||
);
|
||||
|
||||
this.isFilterActive = React.createProxyState(
|
||||
[this.searchViewModel.appliedQuery, this.reactionFilter],
|
||||
() =>
|
||||
this.searchViewModel.appliedQuery.value != "" ||
|
||||
this.reactionFilter.value != undefined,
|
||||
);
|
||||
this.isFilterActive = React.createProxyState(
|
||||
[this.searchViewModel.appliedQuery, this.reactionFilter],
|
||||
() =>
|
||||
this.searchViewModel.appliedQuery.value != "" ||
|
||||
this.reactionFilter.value != undefined,
|
||||
);
|
||||
|
||||
// keystrokes
|
||||
this.registerKeyStroke(CommonKeys.Filter, this.showFilterModal);
|
||||
this.registerKeyStroke(CommonKeys.CloseOrCancel, () => {
|
||||
if (this.isFilterModalOpen.value == true) {
|
||||
this.hideFilterModal();
|
||||
} else {
|
||||
this.replyingMessage.value = undefined;
|
||||
}
|
||||
});
|
||||
this.registerKeyStroke(CommonKeys.Reset, this.resetFilter);
|
||||
this.registerKeyStroke(CommonKeys.Create, this.setFocus);
|
||||
// keystrokes
|
||||
this.registerKeyStroke(CommonKeys.Filter, this.showFilterModal);
|
||||
this.registerKeyStroke(CommonKeys.CloseOrCancel, () => {
|
||||
if (this.isFilterModalOpen.value == true) {
|
||||
this.hideFilterModal();
|
||||
} else {
|
||||
this.replyingMessage.value = undefined;
|
||||
}
|
||||
});
|
||||
this.registerKeyStroke(CommonKeys.Reset, this.resetFilter);
|
||||
this.registerKeyStroke(CommonKeys.Create, this.setFocus);
|
||||
|
||||
this.chatViewModel.registerContext(ChatPageTypes.Messages, this);
|
||||
this.chatViewModel.registerContext(ChatPageTypes.Messages, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,7 @@ export default class SettingsPageViewModel extends Context {
|
||||
);
|
||||
cannotSetColor: React.State<boolean> = React.createProxyState(
|
||||
[this.color, this.appliedColor],
|
||||
() =>
|
||||
this.color.value == this.appliedColor.value,
|
||||
() => this.color.value == this.appliedColor.value,
|
||||
);
|
||||
cannotAddSecondaryChannel: React.State<boolean> = React.createProxyState(
|
||||
[this.newSecondaryChannelInput],
|
||||
@@ -41,11 +40,8 @@ export default class SettingsPageViewModel extends Context {
|
||||
|
||||
// methods
|
||||
setName = (): void => {
|
||||
this.chatViewModel.chatModel.setName(
|
||||
this.nameInput.value,
|
||||
);
|
||||
this.name.value =
|
||||
this.chatViewModel.chatModel.info.name;
|
||||
this.chatViewModel.chatModel.setName(this.nameInput.value);
|
||||
this.name.value = this.chatViewModel.chatModel.info.name;
|
||||
|
||||
this.chatViewModel.chatListViewModel.updateIndices();
|
||||
};
|
||||
@@ -79,7 +75,7 @@ export default class SettingsPageViewModel extends Context {
|
||||
|
||||
applyColor = (): void => {
|
||||
this.chatViewModel.setColor(this.color.value);
|
||||
this.appliedColor.value = this.color.value;
|
||||
this.appliedColor.value = this.color.value;
|
||||
};
|
||||
|
||||
remove = (): void => {
|
||||
@@ -90,18 +86,17 @@ export default class SettingsPageViewModel extends Context {
|
||||
|
||||
// load
|
||||
preloadData = (): void => {
|
||||
this.name.value =
|
||||
this.chatViewModel.chatModel.info.name;
|
||||
|
||||
this.name.value = this.chatViewModel.chatModel.info.name;
|
||||
|
||||
this.color.value = this.chatViewModel.chatModel.color;
|
||||
this.appliedColor.value = this.color.value;
|
||||
this.appliedColor.value = this.color.value;
|
||||
};
|
||||
|
||||
updateData = (): void => {
|
||||
this.preloadData();
|
||||
this.nameInput.value = this.name.value;
|
||||
this.chatViewModel.resetColor();
|
||||
}
|
||||
this.preloadData();
|
||||
this.nameInput.value = this.name.value;
|
||||
this.chatViewModel.resetColor();
|
||||
};
|
||||
|
||||
loadData = (): void => {
|
||||
this.nameInput.value = this.name.value;
|
||||
|
||||
@@ -178,8 +178,13 @@ export default class TaskPageViewModel extends ContextHost<string> {
|
||||
|
||||
this.chatViewModel = chatViewModel;
|
||||
|
||||
// filter
|
||||
implementFilter(this.boardViewModels, this.boardMatches, this.boardQuery, (board) => board.name.value);
|
||||
// filter
|
||||
implementFilter(
|
||||
this.boardViewModels,
|
||||
this.boardMatches,
|
||||
this.boardQuery,
|
||||
(board) => board.name.value,
|
||||
);
|
||||
|
||||
// context
|
||||
this.chatViewModel.registerContext(ChatPageTypes.Tasks, this);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import TaskContainingPageViewModel from "./taskContainingPageViewModel";
|
||||
import CalendarPageViewModel from "./calendarPageViewModel";
|
||||
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
||||
import ChatViewModel from "../Chat/chatViewModel";
|
||||
import * as React from "../../react";
|
||||
@@ -8,7 +9,6 @@ import { localeCompare, padZero } from "../../Model/Utility/utility";
|
||||
import BoardsAndTasksModel, {
|
||||
TaskFileContent,
|
||||
} from "../../Model/Files/boardsAndTasksModel";
|
||||
import CalendarPageViewModel from "./calendarPageViewModel";
|
||||
|
||||
export default class TaskViewModel extends Context {
|
||||
// util
|
||||
@@ -200,11 +200,11 @@ export default class TaskViewModel extends Context {
|
||||
this.loadTaskData();
|
||||
this.loadVersionIds();
|
||||
|
||||
if (this.containingViewModel instanceof CalendarPageViewModel) {
|
||||
this.containingViewModel.nextTask.subscribe((nextTask)=>{
|
||||
this.isNotNext.value = nextTask != this;
|
||||
})
|
||||
}
|
||||
if (this.containingViewModel instanceof CalendarPageViewModel) {
|
||||
this.containingViewModel.nextTask.subscribe((nextTask) => {
|
||||
this.isNotNext.value = nextTask != this;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
loadTaskData = (): void => {
|
||||
|
||||
Reference in New Issue
Block a user