add message filter
This commit is contained in:
Vendored
+7
@@ -709,6 +709,13 @@ body[showing-chat] #chat-page-wrapper {
|
|||||||
.message-bubble .tile.main .body {
|
.message-bubble .tile.main .body {
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
.modal .message-bubble .tile.main .body {
|
||||||
|
word-break: keep-all;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
.message-bubble[sentbyuser] {
|
.message-bubble[sentbyuser] {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+144
-107
@@ -2022,7 +2022,9 @@
|
|||||||
void 0
|
void 0
|
||||||
);
|
);
|
||||||
this.allReactions = new MapState();
|
this.allReactions = new MapState();
|
||||||
this.userReaction = new State(void 0);
|
this.userReaction = new State(
|
||||||
|
void 0
|
||||||
|
);
|
||||||
this.reactionsThumbsUp = MapState;
|
this.reactionsThumbsUp = MapState;
|
||||||
this.reactionsCheck = MapState;
|
this.reactionsCheck = MapState;
|
||||||
this.reactionsStop = MapState;
|
this.reactionsStop = MapState;
|
||||||
@@ -2081,7 +2083,8 @@
|
|||||||
} else {
|
} else {
|
||||||
this.allReactions.set(reaction.sender, reaction);
|
this.allReactions.set(reaction.sender, reaction);
|
||||||
}
|
}
|
||||||
if (reaction.sender != this.coreViewModel.settingsModel.username) return;
|
if (reaction.sender != this.coreViewModel.settingsModel.username)
|
||||||
|
return;
|
||||||
this.userReaction.value = reaction.isDeleting ? void 0 : reaction.content;
|
this.userReaction.value = reaction.isDeleting ? void 0 : reaction.content;
|
||||||
};
|
};
|
||||||
this.sendReaction = (content, isDeleting) => {
|
this.sendReaction = (content, isDeleting) => {
|
||||||
@@ -2105,6 +2108,59 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// src/ViewModel/Utility/searchViewModel.ts
|
||||||
|
var SearchViewModel = class {
|
||||||
|
// init
|
||||||
|
constructor(allObjects, matchingObjects, getStringsOfObject, suggestions) {
|
||||||
|
// state
|
||||||
|
this.appliedQuery = new State("");
|
||||||
|
this.searchInput = new State("");
|
||||||
|
// guards
|
||||||
|
this.cannotApplySearch = createProxyState(
|
||||||
|
[this.searchInput, this.appliedQuery],
|
||||||
|
() => this.searchInput.value == this.appliedQuery.value
|
||||||
|
);
|
||||||
|
// methods
|
||||||
|
this.search = (searchTerm) => {
|
||||||
|
this.searchInput.value = searchTerm;
|
||||||
|
this.applySearch();
|
||||||
|
};
|
||||||
|
this.applySearch = () => {
|
||||||
|
this.appliedQuery.value = this.searchInput.value;
|
||||||
|
this.matchingObjects.clear();
|
||||||
|
for (const object of this.allObjects.value.values()) {
|
||||||
|
const doesMatch = this.checkDoesMatchSearch(object);
|
||||||
|
if (doesMatch == false) continue;
|
||||||
|
this.matchingObjects.add(object);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// utility
|
||||||
|
this.checkDoesMatchSearch = (object) => {
|
||||||
|
return checkDoesObjectMatchSearch(
|
||||||
|
this.appliedQuery.value,
|
||||||
|
this.getStringsOfObject,
|
||||||
|
object
|
||||||
|
);
|
||||||
|
};
|
||||||
|
this.allObjects = allObjects;
|
||||||
|
this.matchingObjects = matchingObjects;
|
||||||
|
this.getStringsOfObject = getStringsOfObject;
|
||||||
|
this.suggestions = suggestions;
|
||||||
|
this.allObjects.handleAddition((newObject) => {
|
||||||
|
const doesMatch = this.checkDoesMatchSearch(newObject);
|
||||||
|
if (doesMatch == false) {
|
||||||
|
this.matchingObjects.remove(newObject);
|
||||||
|
} else {
|
||||||
|
if (this.matchingObjects.value.has(newObject)) return;
|
||||||
|
this.matchingObjects.add(newObject);
|
||||||
|
this.allObjects.handleRemoval(newObject, () => {
|
||||||
|
this.matchingObjects.remove(newObject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// src/ViewModel/Pages/messagePageViewModel.ts
|
// src/ViewModel/Pages/messagePageViewModel.ts
|
||||||
var MessagePageViewModel = class {
|
var MessagePageViewModel = class {
|
||||||
// init
|
// init
|
||||||
@@ -2113,6 +2169,8 @@
|
|||||||
this.chatViewModel = chatViewModel;
|
this.chatViewModel = chatViewModel;
|
||||||
// state
|
// state
|
||||||
this.chatMessageViewModels = new MapState();
|
this.chatMessageViewModels = new MapState();
|
||||||
|
this.filteredMessageViewModels = new ListState();
|
||||||
|
this.isFilterModalOpen = new State(false);
|
||||||
this.composingMessage = new State("");
|
this.composingMessage = new State("");
|
||||||
// methods
|
// methods
|
||||||
this.sendMessage = () => {
|
this.sendMessage = () => {
|
||||||
@@ -2160,6 +2218,9 @@
|
|||||||
if (messageViewModel == void 0) return;
|
if (messageViewModel == void 0) return;
|
||||||
messageViewModel.handleReaction(reaction);
|
messageViewModel.handleReaction(reaction);
|
||||||
};
|
};
|
||||||
|
this.openFilterModal = () => {
|
||||||
|
this.isFilterModalOpen.value = true;
|
||||||
|
};
|
||||||
// load
|
// load
|
||||||
this.loadData = () => {
|
this.loadData = () => {
|
||||||
this.chatMessageViewModels.clear();
|
this.chatMessageViewModels.clear();
|
||||||
@@ -2177,6 +2238,12 @@
|
|||||||
],
|
],
|
||||||
() => this.chatViewModel.settingsViewModel.username.value == "" || this.composingMessage.value == ""
|
() => this.chatViewModel.settingsViewModel.username.value == "" || this.composingMessage.value == ""
|
||||||
);
|
);
|
||||||
|
this.searchViewModel = new SearchViewModel(
|
||||||
|
this.chatMessageViewModels,
|
||||||
|
this.filteredMessageViewModels,
|
||||||
|
(chatMessageViewModel) => [chatMessageViewModel.body.value],
|
||||||
|
new ListState()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2271,59 +2338,6 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/ViewModel/Utility/searchViewModel.ts
|
|
||||||
var SearchViewModel = class {
|
|
||||||
// init
|
|
||||||
constructor(allObjects, matchingObjects, getStringsOfObject, suggestions) {
|
|
||||||
// state
|
|
||||||
this.appliedQuery = new State("");
|
|
||||||
this.searchInput = new State("");
|
|
||||||
// guards
|
|
||||||
this.cannotApplySearch = createProxyState(
|
|
||||||
[this.searchInput, this.appliedQuery],
|
|
||||||
() => this.searchInput.value == this.appliedQuery.value
|
|
||||||
);
|
|
||||||
// methods
|
|
||||||
this.search = (searchTerm) => {
|
|
||||||
this.searchInput.value = searchTerm;
|
|
||||||
this.applySearch();
|
|
||||||
};
|
|
||||||
this.applySearch = () => {
|
|
||||||
this.appliedQuery.value = this.searchInput.value;
|
|
||||||
this.matchingObjects.clear();
|
|
||||||
for (const object of this.allObjects.value.values()) {
|
|
||||||
const doesMatch = this.checkDoesMatchSearch(object);
|
|
||||||
if (doesMatch == false) continue;
|
|
||||||
this.matchingObjects.add(object);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// utility
|
|
||||||
this.checkDoesMatchSearch = (object) => {
|
|
||||||
return checkDoesObjectMatchSearch(
|
|
||||||
this.appliedQuery.value,
|
|
||||||
this.getStringsOfObject,
|
|
||||||
object
|
|
||||||
);
|
|
||||||
};
|
|
||||||
this.allObjects = allObjects;
|
|
||||||
this.matchingObjects = matchingObjects;
|
|
||||||
this.getStringsOfObject = getStringsOfObject;
|
|
||||||
this.suggestions = suggestions;
|
|
||||||
this.allObjects.handleAddition((newObject) => {
|
|
||||||
const doesMatch = this.checkDoesMatchSearch(newObject);
|
|
||||||
if (doesMatch == false) {
|
|
||||||
this.matchingObjects.remove(newObject);
|
|
||||||
} else {
|
|
||||||
if (this.matchingObjects.value.has(newObject)) return;
|
|
||||||
this.matchingObjects.add(newObject);
|
|
||||||
this.allObjects.handleRemoval(newObject, () => {
|
|
||||||
this.matchingObjects.remove(newObject);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/ViewModel/Pages/boardViewModel.ts
|
// src/ViewModel/Pages/boardViewModel.ts
|
||||||
var BoardViewModel = class extends TaskContainingPageViewModel {
|
var BoardViewModel = class extends TaskContainingPageViewModel {
|
||||||
// init
|
// init
|
||||||
@@ -3407,7 +3421,10 @@
|
|||||||
function MessageReactionButton(coreViewModel2, chatMessageViewModel, content) {
|
function MessageReactionButton(coreViewModel2, chatMessageViewModel, content) {
|
||||||
let audioLabel;
|
let audioLabel;
|
||||||
let count;
|
let count;
|
||||||
let isActive = createProxyState([chatMessageViewModel.userReaction], () => chatMessageViewModel.userReaction.value == content);
|
let isActive = createProxyState(
|
||||||
|
[chatMessageViewModel.userReaction],
|
||||||
|
() => chatMessageViewModel.userReaction.value == content
|
||||||
|
);
|
||||||
function sendReaction() {
|
function sendReaction() {
|
||||||
chatMessageViewModel.sendReaction(content, isActive.value);
|
chatMessageViewModel.sendReaction(content, isActive.value);
|
||||||
}
|
}
|
||||||
@@ -3590,6 +3607,52 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// src/View/Modals/searchModal.tsx
|
||||||
|
function SearchModal(coreViewModel2, searchViewModel, headline, converter, isOpen) {
|
||||||
|
function close() {
|
||||||
|
isOpen.value = false;
|
||||||
|
}
|
||||||
|
const suggestionId = v4_default();
|
||||||
|
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isOpen }, /* @__PURE__ */ createElement("div", { style: "max-width: 64rem" }, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, headline), /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement(
|
||||||
|
"input",
|
||||||
|
{
|
||||||
|
placeholder: coreViewModel2.translations.general.searchLabel,
|
||||||
|
"bind:value": searchViewModel.searchInput,
|
||||||
|
"on:enter": searchViewModel.applySearch,
|
||||||
|
list: suggestionId
|
||||||
|
}
|
||||||
|
), /* @__PURE__ */ createElement(
|
||||||
|
"datalist",
|
||||||
|
{
|
||||||
|
hidden: true,
|
||||||
|
id: suggestionId,
|
||||||
|
"children:append": [
|
||||||
|
searchViewModel.suggestions,
|
||||||
|
StringToOption
|
||||||
|
]
|
||||||
|
}
|
||||||
|
), /* @__PURE__ */ createElement(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
class: "primary",
|
||||||
|
"aria-label": coreViewModel2.translations.general.searchButtonAudioLabel,
|
||||||
|
"on:click": searchViewModel.applySearch,
|
||||||
|
"toggle:disabled": searchViewModel.cannotApplySearch
|
||||||
|
},
|
||||||
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "search")
|
||||||
|
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
class: "grid gap",
|
||||||
|
style: "grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr))",
|
||||||
|
"children:append": [
|
||||||
|
searchViewModel.matchingObjects,
|
||||||
|
converter
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)), /* @__PURE__ */ createElement("button", { "on:click": close }, coreViewModel2.translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
|
||||||
|
}
|
||||||
|
|
||||||
// src/View/ChatPages/messagePage.tsx
|
// src/View/ChatPages/messagePage.tsx
|
||||||
function MessagePage(coreViewModel2, messagePageViewModel) {
|
function MessagePage(coreViewModel2, messagePageViewModel) {
|
||||||
messagePageViewModel.loadData();
|
messagePageViewModel.loadData();
|
||||||
@@ -3601,7 +3664,7 @@
|
|||||||
{
|
{
|
||||||
id: "message-container",
|
id: "message-container",
|
||||||
"children:append": [
|
"children:append": [
|
||||||
messagePageViewModel.chatMessageViewModels,
|
messagePageViewModel.filteredMessageViewModels,
|
||||||
ChatMessageViewModelToView
|
ChatMessageViewModelToView
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -3618,11 +3681,19 @@
|
|||||||
if (scrollFromBottom > 400) return;
|
if (scrollFromBottom > 400) return;
|
||||||
scrollDown();
|
scrollDown();
|
||||||
}
|
}
|
||||||
messagePageViewModel.chatMessageViewModels.subscribeSilent(
|
messagePageViewModel.filteredMessageViewModels.subscribeSilent(
|
||||||
scrollDownIfApplicable
|
scrollDownIfApplicable
|
||||||
);
|
);
|
||||||
setTimeout(() => scrollDown(true), 100);
|
setTimeout(() => scrollDown(true), 100);
|
||||||
return /* @__PURE__ */ createElement("div", { id: "message-page" }, /* @__PURE__ */ createElement("div", { class: "pane-wrapper" }, /* @__PURE__ */ createElement("div", { class: "pane" }, /* @__PURE__ */ createElement("div", { class: "toolbar" }, /* @__PURE__ */ createElement("span", { class: "title" }, coreViewModel2.translations.chatPage.message.messagesHeadline)), /* @__PURE__ */ createElement("div", { class: "content" }, messageContainer, /* @__PURE__ */ createElement("div", { id: "composer" }, /* @__PURE__ */ createElement("div", { class: "content-width-constraint" }, /* @__PURE__ */ createElement("div", { class: "input-width-constraint" }, /* @__PURE__ */ createElement(
|
return /* @__PURE__ */ createElement("div", { id: "message-page" }, /* @__PURE__ */ createElement("div", { class: "pane-wrapper" }, /* @__PURE__ */ createElement("div", { class: "pane" }, /* @__PURE__ */ createElement("div", { class: "toolbar" }, /* @__PURE__ */ createElement("span", { class: "title" }, coreViewModel2.translations.chatPage.message.messagesHeadline), /* @__PURE__ */ createElement("span", null, /* @__PURE__ */ createElement(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
class: "ghost",
|
||||||
|
"on:click": messagePageViewModel.openFilterModal,
|
||||||
|
"aria-label": coreViewModel2.translations.chatPage.message.filterMessagesButtonAudioLabel
|
||||||
|
},
|
||||||
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "filter_alt")
|
||||||
|
))), /* @__PURE__ */ createElement("div", { class: "content" }, messageContainer, /* @__PURE__ */ createElement("div", { id: "composer" }, /* @__PURE__ */ createElement("div", { class: "content-width-constraint" }, /* @__PURE__ */ createElement("div", { class: "input-width-constraint" }, /* @__PURE__ */ createElement(
|
||||||
"input",
|
"input",
|
||||||
{
|
{
|
||||||
"bind:value": messagePageViewModel.composingMessage,
|
"bind:value": messagePageViewModel.composingMessage,
|
||||||
@@ -3638,7 +3709,13 @@
|
|||||||
"toggle:disabled": messagePageViewModel.cannotSendMessage
|
"toggle:disabled": messagePageViewModel.cannotSendMessage
|
||||||
},
|
},
|
||||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "send")
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "send")
|
||||||
))))))));
|
))))))), SearchModal(
|
||||||
|
coreViewModel2,
|
||||||
|
messagePageViewModel.searchViewModel,
|
||||||
|
coreViewModel2.translations.chatPage.message.messageFilterHeadline,
|
||||||
|
ChatMessageViewModelToView,
|
||||||
|
messagePageViewModel.isFilterModalOpen
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/View/Components/colorPicker.tsx
|
// src/View/Components/colorPicker.tsx
|
||||||
@@ -4158,52 +4235,6 @@
|
|||||||
return RibbonButton(label, icon, isSelected, select);
|
return RibbonButton(label, icon, isSelected, select);
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/View/Modals/searchModal.tsx
|
|
||||||
function SearchModal(coreViewModel2, searchViewModel, headline, converter, isOpen) {
|
|
||||||
function close() {
|
|
||||||
isOpen.value = false;
|
|
||||||
}
|
|
||||||
const suggestionId = v4_default();
|
|
||||||
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isOpen }, /* @__PURE__ */ createElement("div", { style: "max-width: 64rem" }, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, headline), /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement(
|
|
||||||
"input",
|
|
||||||
{
|
|
||||||
placeholder: coreViewModel2.translations.general.searchLabel,
|
|
||||||
"bind:value": searchViewModel.searchInput,
|
|
||||||
"on:enter": searchViewModel.applySearch,
|
|
||||||
list: suggestionId
|
|
||||||
}
|
|
||||||
), /* @__PURE__ */ createElement(
|
|
||||||
"datalist",
|
|
||||||
{
|
|
||||||
hidden: true,
|
|
||||||
id: suggestionId,
|
|
||||||
"children:append": [
|
|
||||||
searchViewModel.suggestions,
|
|
||||||
StringToOption
|
|
||||||
]
|
|
||||||
}
|
|
||||||
), /* @__PURE__ */ createElement(
|
|
||||||
"button",
|
|
||||||
{
|
|
||||||
class: "primary",
|
|
||||||
"aria-label": coreViewModel2.translations.general.searchButtonAudioLabel,
|
|
||||||
"on:click": searchViewModel.applySearch,
|
|
||||||
"toggle:disabled": searchViewModel.cannotApplySearch
|
|
||||||
},
|
|
||||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "search")
|
|
||||||
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement(
|
|
||||||
"div",
|
|
||||||
{
|
|
||||||
class: "grid gap",
|
|
||||||
style: "grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr))",
|
|
||||||
"children:append": [
|
|
||||||
searchViewModel.matchingObjects,
|
|
||||||
converter
|
|
||||||
]
|
|
||||||
}
|
|
||||||
)), /* @__PURE__ */ createElement("button", { "on:click": close }, coreViewModel2.translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
|
|
||||||
}
|
|
||||||
|
|
||||||
// src/View/ChatPages/boardPage.tsx
|
// src/View/ChatPages/boardPage.tsx
|
||||||
function BoardPage(coreViewModel2, boardViewModel) {
|
function BoardPage(coreViewModel2, boardViewModel) {
|
||||||
boardViewModel.loadData();
|
boardViewModel.loadData();
|
||||||
@@ -5110,9 +5141,11 @@
|
|||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
messagesHeadline: "Messages",
|
messagesHeadline: "Messages",
|
||||||
|
messageFilterHeadline: "Filter messages",
|
||||||
///
|
///
|
||||||
composerInputPlaceholder: "Type a message...",
|
composerInputPlaceholder: "Type a message...",
|
||||||
sendMessageButtonAudioLabel: "send message",
|
sendMessageButtonAudioLabel: "send message",
|
||||||
|
filterMessagesButtonAudioLabel: "filter messages",
|
||||||
///
|
///
|
||||||
showMessageInfoButtonAudioLabel: "show message info",
|
showMessageInfoButtonAudioLabel: "show message info",
|
||||||
messageInfoHeadline: "Message Info",
|
messageInfoHeadline: "Message Info",
|
||||||
@@ -5316,8 +5349,10 @@
|
|||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
messagesHeadline: "Nachrichten",
|
messagesHeadline: "Nachrichten",
|
||||||
|
messageFilterHeadline: "Nachrichten filtern",
|
||||||
composerInputPlaceholder: "Schreib eine Nachricht...",
|
composerInputPlaceholder: "Schreib eine Nachricht...",
|
||||||
sendMessageButtonAudioLabel: "nachricht senden",
|
sendMessageButtonAudioLabel: "nachricht senden",
|
||||||
|
filterMessagesButtonAudioLabel: "nachrichten filtern",
|
||||||
showMessageInfoButtonAudioLabel: "nachrichteninfo anzeigen",
|
showMessageInfoButtonAudioLabel: "nachrichteninfo anzeigen",
|
||||||
messageInfoHeadline: "Nachrichteninfo",
|
messageInfoHeadline: "Nachrichteninfo",
|
||||||
sentBy: "Gesendet von",
|
sentBy: "Gesendet von",
|
||||||
@@ -5510,8 +5545,10 @@
|
|||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
messagesHeadline: "Mensajes",
|
messagesHeadline: "Mensajes",
|
||||||
|
messageFilterHeadline: "Filtrar mensajes",
|
||||||
composerInputPlaceholder: "Escribe un mensaje...",
|
composerInputPlaceholder: "Escribe un mensaje...",
|
||||||
sendMessageButtonAudioLabel: "enviar mensaje",
|
sendMessageButtonAudioLabel: "enviar mensaje",
|
||||||
|
filterMessagesButtonAudioLabel: "filtrar mensajes",
|
||||||
showMessageInfoButtonAudioLabel: "mostrar informaci\xF3n del mensaje",
|
showMessageInfoButtonAudioLabel: "mostrar informaci\xF3n del mensaje",
|
||||||
messageInfoHeadline: "Informaci\xF3n del Mensaje",
|
messageInfoHeadline: "Informaci\xF3n del Mensaje",
|
||||||
sentBy: "Enviado por",
|
sentBy: "Enviado por",
|
||||||
@@ -5592,7 +5629,7 @@
|
|||||||
this.connectionModel = connectionModel2;
|
this.connectionModel = connectionModel2;
|
||||||
this.chatListModel = chatListModel2;
|
this.chatListModel = chatListModel2;
|
||||||
this.fileTransferModel = fileTransferModel2;
|
this.fileTransferModel = fileTransferModel2;
|
||||||
this.BUILD = "Build 26.04.10.B";
|
this.BUILD = "Build 26.04.11.A";
|
||||||
// DRAG & DROP
|
// DRAG & DROP
|
||||||
this.draggedObject = new State(void 0);
|
this.draggedObject = new State(void 0);
|
||||||
// SUGGESTIONS
|
// SUGGESTIONS
|
||||||
|
|||||||
@@ -149,6 +149,14 @@
|
|||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal .message-bubble .tile.main .body {
|
||||||
|
word-break: keep-all;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.message-bubble[sentbyuser] {
|
.message-bubble[sentbyuser] {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
|
|||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||||
import { ChatMessage } from "../Components/chatMessage";
|
import { ChatMessage } from "../Components/chatMessage";
|
||||||
|
import { SearchModal } from "../Modals/searchModal";
|
||||||
|
|
||||||
export function MessagePage(
|
export function MessagePage(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
@@ -22,7 +23,7 @@ export function MessagePage(
|
|||||||
<div
|
<div
|
||||||
id="message-container"
|
id="message-container"
|
||||||
children:append={[
|
children:append={[
|
||||||
messagePageViewModel.chatMessageViewModels,
|
messagePageViewModel.filteredMessageViewModels,
|
||||||
ChatMessageViewModelToView,
|
ChatMessageViewModelToView,
|
||||||
]}
|
]}
|
||||||
></div>
|
></div>
|
||||||
@@ -43,7 +44,7 @@ export function MessagePage(
|
|||||||
|
|
||||||
scrollDown();
|
scrollDown();
|
||||||
}
|
}
|
||||||
messagePageViewModel.chatMessageViewModels.subscribeSilent(
|
messagePageViewModel.filteredMessageViewModels.subscribeSilent(
|
||||||
scrollDownIfApplicable,
|
scrollDownIfApplicable,
|
||||||
);
|
);
|
||||||
setTimeout(() => scrollDown(true), 100);
|
setTimeout(() => scrollDown(true), 100);
|
||||||
@@ -59,6 +60,18 @@ export function MessagePage(
|
|||||||
.messagesHeadline
|
.messagesHeadline
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
|
<span>
|
||||||
|
<button
|
||||||
|
class="ghost"
|
||||||
|
on:click={messagePageViewModel.openFilterModal}
|
||||||
|
aria-label={
|
||||||
|
coreViewModel.translations.chatPage.message
|
||||||
|
.filterMessagesButtonAudioLabel
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span class="icon">filter_alt</span>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{messageContainer}
|
{messageContainer}
|
||||||
@@ -100,6 +113,15 @@ export function MessagePage(
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{SearchModal(
|
||||||
|
coreViewModel,
|
||||||
|
messagePageViewModel.searchViewModel,
|
||||||
|
coreViewModel.translations.chatPage.message
|
||||||
|
.messageFilterHeadline,
|
||||||
|
ChatMessageViewModelToView,
|
||||||
|
messagePageViewModel.isFilterModalOpen,
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ export function MessageReactionButton(
|
|||||||
) {
|
) {
|
||||||
let audioLabel: string;
|
let audioLabel: string;
|
||||||
let count: React.State<number>;
|
let count: React.State<number>;
|
||||||
let isActive = React.createProxyState([chatMessageViewModel.userReaction], (() => chatMessageViewModel.userReaction.value == content))
|
let isActive = React.createProxyState(
|
||||||
|
[chatMessageViewModel.userReaction],
|
||||||
|
() => chatMessageViewModel.userReaction.value == content,
|
||||||
|
);
|
||||||
|
|
||||||
function sendReaction() {
|
function sendReaction() {
|
||||||
chatMessageViewModel.sendReaction(content, isActive.value);
|
chatMessageViewModel.sendReaction(content, isActive.value);
|
||||||
|
|||||||
@@ -184,11 +184,13 @@ const englishTranslations = {
|
|||||||
|
|
||||||
message: {
|
message: {
|
||||||
messagesHeadline: "Messages",
|
messagesHeadline: "Messages",
|
||||||
|
messageFilterHeadline: "Filter messages",
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
composerInputPlaceholder: "Type a message...",
|
composerInputPlaceholder: "Type a message...",
|
||||||
sendMessageButtonAudioLabel: "send message",
|
sendMessageButtonAudioLabel: "send message",
|
||||||
|
filterMessagesButtonAudioLabel: "filter messages",
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
@@ -480,9 +482,11 @@ export const allTranslations: {
|
|||||||
|
|
||||||
message: {
|
message: {
|
||||||
messagesHeadline: "Nachrichten",
|
messagesHeadline: "Nachrichten",
|
||||||
|
messageFilterHeadline: "Nachrichten filtern",
|
||||||
|
|
||||||
composerInputPlaceholder: "Schreib eine Nachricht...",
|
composerInputPlaceholder: "Schreib eine Nachricht...",
|
||||||
sendMessageButtonAudioLabel: "nachricht senden",
|
sendMessageButtonAudioLabel: "nachricht senden",
|
||||||
|
filterMessagesButtonAudioLabel: "nachrichten filtern",
|
||||||
|
|
||||||
showMessageInfoButtonAudioLabel: "nachrichteninfo anzeigen",
|
showMessageInfoButtonAudioLabel: "nachrichteninfo anzeigen",
|
||||||
messageInfoHeadline: "Nachrichteninfo",
|
messageInfoHeadline: "Nachrichteninfo",
|
||||||
@@ -750,9 +754,11 @@ export const allTranslations: {
|
|||||||
|
|
||||||
message: {
|
message: {
|
||||||
messagesHeadline: "Mensajes",
|
messagesHeadline: "Mensajes",
|
||||||
|
messageFilterHeadline: "Filtrar mensajes",
|
||||||
|
|
||||||
composerInputPlaceholder: "Escribe un mensaje...",
|
composerInputPlaceholder: "Escribe un mensaje...",
|
||||||
sendMessageButtonAudioLabel: "enviar mensaje",
|
sendMessageButtonAudioLabel: "enviar mensaje",
|
||||||
|
filterMessagesButtonAudioLabel: "filtrar mensajes",
|
||||||
|
|
||||||
showMessageInfoButtonAudioLabel:
|
showMessageInfoButtonAudioLabel:
|
||||||
"mostrar información del mensaje",
|
"mostrar información del mensaje",
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ export default class ChatMessageViewModel {
|
|||||||
sentByUser: boolean;
|
sentByUser: boolean;
|
||||||
|
|
||||||
allReactions = new React.MapState<ChatMessageReaction>();
|
allReactions = new React.MapState<ChatMessageReaction>();
|
||||||
userReaction = new React.State<ReactionSymbols | string | undefined>(undefined);
|
userReaction = new React.State<ReactionSymbols | string | undefined>(
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
reactionsThumbsUp = React.MapState<ChatMessageReaction>;
|
reactionsThumbsUp = React.MapState<ChatMessageReaction>;
|
||||||
reactionsCheck = React.MapState<ChatMessageReaction>;
|
reactionsCheck = React.MapState<ChatMessageReaction>;
|
||||||
reactionsStop = React.MapState<ChatMessageReaction>;
|
reactionsStop = React.MapState<ChatMessageReaction>;
|
||||||
@@ -93,8 +95,11 @@ export default class ChatMessageViewModel {
|
|||||||
this.allReactions.set(reaction.sender, reaction);
|
this.allReactions.set(reaction.sender, reaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reaction.sender != this.coreViewModel.settingsModel.username) return;
|
if (reaction.sender != this.coreViewModel.settingsModel.username)
|
||||||
this.userReaction.value = reaction.isDeleting ? undefined : reaction.content;
|
return;
|
||||||
|
this.userReaction.value = reaction.isDeleting
|
||||||
|
? undefined
|
||||||
|
: reaction.content;
|
||||||
};
|
};
|
||||||
|
|
||||||
sendReaction = (content: ReactionSymbols, isDeleting: boolean): void => {
|
sendReaction = (content: ReactionSymbols, isDeleting: boolean): void => {
|
||||||
|
|||||||
@@ -8,11 +8,16 @@ import {
|
|||||||
import ChatMessageViewModel from "../Chat/chatMessageViewModel";
|
import ChatMessageViewModel from "../Chat/chatMessageViewModel";
|
||||||
import ChatViewModel from "../Chat/chatViewModel";
|
import ChatViewModel from "../Chat/chatViewModel";
|
||||||
import CoreViewModel from "../Global/coreViewModel";
|
import CoreViewModel from "../Global/coreViewModel";
|
||||||
|
import SearchViewModel from "../Utility/searchViewModel";
|
||||||
|
|
||||||
export default class MessagePageViewModel {
|
export default class MessagePageViewModel {
|
||||||
// state
|
// state
|
||||||
chatMessageViewModels: React.MapState<ChatMessageViewModel> =
|
chatMessageViewModels: React.MapState<ChatMessageViewModel> =
|
||||||
new React.MapState();
|
new React.MapState();
|
||||||
|
filteredMessageViewModels: React.ListState<ChatMessageViewModel> =
|
||||||
|
new React.ListState();
|
||||||
|
searchViewModel: SearchViewModel<ChatMessageViewModel>;
|
||||||
|
isFilterModalOpen = new React.State<boolean>(false);
|
||||||
composingMessage: React.State<string> = new React.State("");
|
composingMessage: React.State<string> = new React.State("");
|
||||||
|
|
||||||
// guards
|
// guards
|
||||||
@@ -81,6 +86,10 @@ export default class MessagePageViewModel {
|
|||||||
messageViewModel.handleReaction(reaction);
|
messageViewModel.handleReaction(reaction);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
openFilterModal = (): void => {
|
||||||
|
this.isFilterModalOpen.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
// load
|
// load
|
||||||
loadData = (): void => {
|
loadData = (): void => {
|
||||||
this.chatMessageViewModels.clear();
|
this.chatMessageViewModels.clear();
|
||||||
@@ -106,5 +115,12 @@ export default class MessagePageViewModel {
|
|||||||
this.chatViewModel.settingsViewModel.username.value == "" ||
|
this.chatViewModel.settingsViewModel.username.value == "" ||
|
||||||
this.composingMessage.value == "",
|
this.composingMessage.value == "",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.searchViewModel = new SearchViewModel(
|
||||||
|
this.chatMessageViewModels,
|
||||||
|
this.filteredMessageViewModels,
|
||||||
|
(chatMessageViewModel) => [chatMessageViewModel.body.value],
|
||||||
|
new React.ListState(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user