implement message filter by reactions
This commit is contained in:
Vendored
+3
@@ -763,6 +763,9 @@ body[showing-chat] #chat-page-wrapper {
|
||||
grid-template-columns: repeat(3, minmax(80px, 1fr));
|
||||
}
|
||||
}
|
||||
.grid.message-reaction-filter {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
/* src/View/ChatPages/taskPage.css */
|
||||
#chat-page > div > #main > #task-page > .pane-wrapper > .pane > .main-content {
|
||||
|
||||
Vendored
+94
-2
@@ -2021,6 +2021,7 @@
|
||||
this.status = new State(
|
||||
void 0
|
||||
);
|
||||
this.isHidden = new State(false);
|
||||
this.allReactions = new MapState();
|
||||
this.userReaction = new State(
|
||||
void 0
|
||||
@@ -2105,6 +2106,41 @@
|
||||
this.chatMessage = chatMessage;
|
||||
this.sentByUser = sentByUser;
|
||||
this.loadData();
|
||||
this.messagePageViewModel.reactionFilter.subscribe((content) => {
|
||||
console.log(content, content == void 0);
|
||||
if (content == void 0) {
|
||||
this.isHidden.value = false;
|
||||
return;
|
||||
}
|
||||
let count = 0;
|
||||
switch (content) {
|
||||
case "\u{1F44D}" /* ThumbsUp */: {
|
||||
count = this.reactionsThumbsUpCount.value;
|
||||
break;
|
||||
}
|
||||
case "\u2705" /* Check */: {
|
||||
count = this.reactionsCheckCount.value;
|
||||
break;
|
||||
}
|
||||
case "\u{1F6D1}" /* Stop */: {
|
||||
count = this.reactionsStopCount.value;
|
||||
break;
|
||||
}
|
||||
case "\u2757\uFE0F" /* Attention */: {
|
||||
count = this.reactionsAttentionCount.value;
|
||||
break;
|
||||
}
|
||||
case "\u203C\uFE0F" /* DoubleAttention */: {
|
||||
count = this.reactionsDoubleAttentionCount.value;
|
||||
break;
|
||||
}
|
||||
case "\u2753" /* Question */: {
|
||||
count = this.reactionsQuestionCount.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.isHidden.value = count == 0;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2171,6 +2207,7 @@
|
||||
this.chatMessageViewModels = new MapState();
|
||||
this.filteredMessageViewModels = new ListState();
|
||||
this.isFilterModalOpen = new State(false);
|
||||
this.reactionFilter = new State(void 0);
|
||||
this.composingMessage = new State("");
|
||||
// methods
|
||||
this.sendMessage = () => {
|
||||
@@ -2224,6 +2261,12 @@
|
||||
this.closeFilterModal = () => {
|
||||
this.isFilterModalOpen.value = false;
|
||||
};
|
||||
this.revokeReactionFilter = () => {
|
||||
this.reactionFilter.value = void 0;
|
||||
};
|
||||
this.setReactionFilter = (content) => {
|
||||
this.reactionFilter.value = content;
|
||||
};
|
||||
// load
|
||||
this.loadData = () => {
|
||||
this.chatMessageViewModels.clear();
|
||||
@@ -3583,7 +3626,8 @@
|
||||
"div",
|
||||
{
|
||||
class: "message-bubble",
|
||||
"toggle:sentbyuser": chatMessageViewModel.sentByUser
|
||||
"toggle:sentbyuser": chatMessageViewModel.sentByUser,
|
||||
"toggle:hidden": chatMessageViewModel.isHidden
|
||||
},
|
||||
/* @__PURE__ */ createElement("div", { class: "main tile" }, /* @__PURE__ */ createElement("div", { class: "text-container" }, /* @__PURE__ */ createElement("span", { class: "sender-name ellipsis" }, chatMessageViewModel.sender), /* @__PURE__ */ createElement(
|
||||
"span",
|
||||
@@ -3610,8 +3654,32 @@
|
||||
);
|
||||
}
|
||||
|
||||
// src/View/Components/messageReactionFilterButton.tsx
|
||||
function MessageReactionFilterButton(messagePageViewModel, content) {
|
||||
const select = () => {
|
||||
messagePageViewModel.setReactionFilter(content);
|
||||
};
|
||||
const isSelected = createProxyState(
|
||||
[messagePageViewModel.reactionFilter],
|
||||
() => messagePageViewModel.reactionFilter.value == content
|
||||
);
|
||||
return /* @__PURE__ */ createElement(
|
||||
"button",
|
||||
{
|
||||
class: "flex justify-center",
|
||||
"on:click": select,
|
||||
"toggle:selected": isSelected
|
||||
},
|
||||
content
|
||||
);
|
||||
}
|
||||
|
||||
// src/View/Modals/messageFilterModal.tsx
|
||||
function MessageFilterModal(coreViewModel2, messagePageViewModel, converter) {
|
||||
const noFilter = createProxyState(
|
||||
[messagePageViewModel.reactionFilter],
|
||||
() => messagePageViewModel.reactionFilter.value == void 0
|
||||
);
|
||||
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": messagePageViewModel.isFilterModalOpen }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.chatPage.message.messageFilterHeadline), /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement(
|
||||
"input",
|
||||
{
|
||||
@@ -3628,7 +3696,25 @@
|
||||
"toggle:disabled": messagePageViewModel.searchViewModel.cannotApplySearch
|
||||
},
|
||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "search")
|
||||
)), /* @__PURE__ */ createElement("hr", null)), /* @__PURE__ */ createElement("button", { "on:click": messagePageViewModel.closeFilterModal }, coreViewModel2.translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
|
||||
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("h3", null, coreViewModel2.translations.chatPage.message.messageFilterReactionsHadline), /* @__PURE__ */ createElement("div", { class: "flex-column gap" }, /* @__PURE__ */ createElement("button", { "toggle:selected": noFilter, "on:click": messagePageViewModel.revokeReactionFilter }, coreViewModel2.translations.chatPage.message.messageFilterAllReactionsButton), /* @__PURE__ */ createElement("div", { class: "grid gap message-reaction-filter" }, MessageReactionFilterButton(
|
||||
messagePageViewModel,
|
||||
"\u{1F44D}" /* ThumbsUp */
|
||||
), MessageReactionFilterButton(
|
||||
messagePageViewModel,
|
||||
"\u2705" /* Check */
|
||||
), MessageReactionFilterButton(
|
||||
messagePageViewModel,
|
||||
"\u{1F6D1}" /* Stop */
|
||||
), MessageReactionFilterButton(
|
||||
messagePageViewModel,
|
||||
"\u2757\uFE0F" /* Attention */
|
||||
), MessageReactionFilterButton(
|
||||
messagePageViewModel,
|
||||
"\u203C\uFE0F" /* DoubleAttention */
|
||||
), MessageReactionFilterButton(
|
||||
messagePageViewModel,
|
||||
"\u2753" /* Question */
|
||||
)))), /* @__PURE__ */ createElement("button", { "on:click": messagePageViewModel.closeFilterModal }, coreViewModel2.translations.general.closeButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
|
||||
}
|
||||
|
||||
// src/View/ChatPages/messagePage.tsx
|
||||
@@ -5164,6 +5250,8 @@
|
||||
message: {
|
||||
messagesHeadline: "Messages",
|
||||
messageFilterHeadline: "Filter messages",
|
||||
messageFilterReactionsHadline: "Reactions",
|
||||
messageFilterAllReactionsButton: "Show all",
|
||||
///
|
||||
composerInputPlaceholder: "Type a message...",
|
||||
sendMessageButtonAudioLabel: "send message",
|
||||
@@ -5372,6 +5460,8 @@
|
||||
message: {
|
||||
messagesHeadline: "Nachrichten",
|
||||
messageFilterHeadline: "Nachrichten filtern",
|
||||
messageFilterReactionsHadline: "Reaktionen",
|
||||
messageFilterAllReactionsButton: "Alle anzeigen",
|
||||
composerInputPlaceholder: "Schreib eine Nachricht...",
|
||||
sendMessageButtonAudioLabel: "nachricht senden",
|
||||
filterMessagesButtonAudioLabel: "nachrichten filtern",
|
||||
@@ -5568,6 +5658,8 @@
|
||||
message: {
|
||||
messagesHeadline: "Mensajes",
|
||||
messageFilterHeadline: "Filtrar mensajes",
|
||||
messageFilterReactionsHadline: "Reacciones",
|
||||
messageFilterAllReactionsButton: "Mostrar todas",
|
||||
composerInputPlaceholder: "Escribe un mensaje...",
|
||||
sendMessageButtonAudioLabel: "enviar mensaje",
|
||||
filterMessagesButtonAudioLabel: "filtrar mensajes",
|
||||
|
||||
@@ -216,3 +216,7 @@
|
||||
grid-template-columns: repeat(3, minmax(80px, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
.grid.message-reaction-filter {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ export function ChatMessage(
|
||||
<div
|
||||
class="message-bubble"
|
||||
toggle:sentbyuser={chatMessageViewModel.sentByUser}
|
||||
toggle:hidden={chatMessageViewModel.isHidden}
|
||||
>
|
||||
<div class="main tile">
|
||||
<div class="text-container">
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import * as React from "bloatless-react";
|
||||
import {
|
||||
ChatMessageReaction,
|
||||
ReactionSymbols,
|
||||
} from "../../Model/Chat/chatModel";
|
||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
|
||||
|
||||
export function MessageReactionFilterButton(
|
||||
messagePageViewModel: MessagePageViewModel,
|
||||
content: ReactionSymbols,
|
||||
) {
|
||||
const select = () => {
|
||||
messagePageViewModel.setReactionFilter(content);
|
||||
};
|
||||
|
||||
const isSelected = React.createProxyState(
|
||||
[messagePageViewModel.reactionFilter],
|
||||
() => messagePageViewModel.reactionFilter.value == content,
|
||||
);
|
||||
|
||||
return (
|
||||
<button
|
||||
class="flex justify-center"
|
||||
on:click={select}
|
||||
toggle:selected={isSelected}
|
||||
>
|
||||
{content}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -5,24 +5,40 @@ import { StringToOption } from "../Components/option";
|
||||
import { v4 } from "uuid";
|
||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
|
||||
import { MessageReactionFilterButton } from "../Components/messageReactionFilterButton";
|
||||
import { ReactionSymbols } from "../../Model/Chat/chatModel";
|
||||
|
||||
export function MessageFilterModal<T>(
|
||||
coreViewModel: CoreViewModel,
|
||||
messagePageViewModel: MessagePageViewModel,
|
||||
converter: React.StateItemConverter<T>,
|
||||
) {
|
||||
const noFilter = React.createProxyState(
|
||||
[messagePageViewModel.reactionFilter],
|
||||
() => messagePageViewModel.reactionFilter.value == undefined,
|
||||
);
|
||||
|
||||
return (
|
||||
<div class="modal" toggle:open={messagePageViewModel.isFilterModalOpen}>
|
||||
<div>
|
||||
<main>
|
||||
<h2>{coreViewModel.translations.chatPage.message.messageFilterHeadline}</h2>
|
||||
<h2>
|
||||
{
|
||||
coreViewModel.translations.chatPage.message
|
||||
.messageFilterHeadline
|
||||
}
|
||||
</h2>
|
||||
<div class="flex-row width-input">
|
||||
<input
|
||||
placeholder={
|
||||
coreViewModel.translations.general.searchLabel
|
||||
}
|
||||
bind:value={messagePageViewModel.searchViewModel.searchInput}
|
||||
on:enter={messagePageViewModel.searchViewModel.applySearch}
|
||||
bind:value={
|
||||
messagePageViewModel.searchViewModel.searchInput
|
||||
}
|
||||
on:enter={
|
||||
messagePageViewModel.searchViewModel.applySearch
|
||||
}
|
||||
></input>
|
||||
<button
|
||||
class="primary"
|
||||
@@ -30,14 +46,61 @@ export function MessageFilterModal<T>(
|
||||
coreViewModel.translations.general
|
||||
.searchButtonAudioLabel
|
||||
}
|
||||
on:click={messagePageViewModel.searchViewModel.applySearch}
|
||||
toggle:disabled={messagePageViewModel.searchViewModel.cannotApplySearch}
|
||||
on:click={
|
||||
messagePageViewModel.searchViewModel.applySearch
|
||||
}
|
||||
toggle:disabled={
|
||||
messagePageViewModel.searchViewModel
|
||||
.cannotApplySearch
|
||||
}
|
||||
>
|
||||
<span class="icon">search</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<hr></hr>
|
||||
|
||||
<h3>
|
||||
{
|
||||
coreViewModel.translations.chatPage.message
|
||||
.messageFilterReactionsHadline
|
||||
}
|
||||
</h3>
|
||||
|
||||
<div class="flex-column gap">
|
||||
<button toggle:selected={noFilter} on:click={messagePageViewModel.revokeReactionFilter}>
|
||||
{
|
||||
coreViewModel.translations.chatPage.message
|
||||
.messageFilterAllReactionsButton
|
||||
}
|
||||
</button>
|
||||
<div class="grid gap message-reaction-filter">
|
||||
{MessageReactionFilterButton(
|
||||
messagePageViewModel,
|
||||
ReactionSymbols.ThumbsUp,
|
||||
)}
|
||||
{MessageReactionFilterButton(
|
||||
messagePageViewModel,
|
||||
ReactionSymbols.Check,
|
||||
)}
|
||||
{MessageReactionFilterButton(
|
||||
messagePageViewModel,
|
||||
ReactionSymbols.Stop,
|
||||
)}
|
||||
{MessageReactionFilterButton(
|
||||
messagePageViewModel,
|
||||
ReactionSymbols.Attention,
|
||||
)}
|
||||
{MessageReactionFilterButton(
|
||||
messagePageViewModel,
|
||||
ReactionSymbols.DoubleAttention,
|
||||
)}
|
||||
{MessageReactionFilterButton(
|
||||
messagePageViewModel,
|
||||
ReactionSymbols.Question,
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<button on:click={messagePageViewModel.closeFilterModal}>
|
||||
{coreViewModel.translations.general.closeButton}
|
||||
|
||||
@@ -184,7 +184,10 @@ const englishTranslations = {
|
||||
|
||||
message: {
|
||||
messagesHeadline: "Messages",
|
||||
|
||||
messageFilterHeadline: "Filter messages",
|
||||
messageFilterReactionsHadline: "Reactions",
|
||||
messageFilterAllReactionsButton: "Show all",
|
||||
|
||||
///
|
||||
|
||||
@@ -482,7 +485,10 @@ export const allTranslations: {
|
||||
|
||||
message: {
|
||||
messagesHeadline: "Nachrichten",
|
||||
|
||||
messageFilterHeadline: "Nachrichten filtern",
|
||||
messageFilterReactionsHadline: "Reaktionen",
|
||||
messageFilterAllReactionsButton: "Alle anzeigen",
|
||||
|
||||
composerInputPlaceholder: "Schreib eine Nachricht...",
|
||||
sendMessageButtonAudioLabel: "nachricht senden",
|
||||
@@ -754,7 +760,10 @@ export const allTranslations: {
|
||||
|
||||
message: {
|
||||
messagesHeadline: "Mensajes",
|
||||
|
||||
messageFilterHeadline: "Filtrar mensajes",
|
||||
messageFilterReactionsHadline: "Reacciones",
|
||||
messageFilterAllReactionsButton: "Mostrar todas",
|
||||
|
||||
composerInputPlaceholder: "Escribe un mensaje...",
|
||||
sendMessageButtonAudioLabel: "enviar mensaje",
|
||||
|
||||
@@ -22,6 +22,8 @@ export default class ChatMessageViewModel {
|
||||
);
|
||||
sentByUser: boolean;
|
||||
|
||||
isHidden = new React.State<boolean>(false);
|
||||
|
||||
allReactions = new React.MapState<ChatMessageReaction>();
|
||||
userReaction = new React.State<ReactionSymbols | string | undefined>(
|
||||
undefined,
|
||||
@@ -129,5 +131,43 @@ export default class ChatMessageViewModel {
|
||||
this.chatMessage = chatMessage;
|
||||
this.sentByUser = sentByUser;
|
||||
this.loadData();
|
||||
|
||||
this.messagePageViewModel.reactionFilter.subscribe((content) => {
|
||||
console.log(content, content==undefined)
|
||||
if (content == undefined) {
|
||||
this.isHidden.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
switch (content) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
this.isHidden.value = count == 0;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ export default class MessagePageViewModel {
|
||||
new React.ListState();
|
||||
searchViewModel: SearchViewModel<ChatMessageViewModel>;
|
||||
isFilterModalOpen = new React.State<boolean>(false);
|
||||
reactionFilter = new React.State<ReactionSymbols | undefined>(undefined);
|
||||
|
||||
composingMessage: React.State<string> = new React.State("");
|
||||
|
||||
// guards
|
||||
@@ -94,6 +96,14 @@ export default class MessagePageViewModel {
|
||||
this.isFilterModalOpen.value = false;
|
||||
};
|
||||
|
||||
revokeReactionFilter = (): void => {
|
||||
this.reactionFilter.value = undefined;
|
||||
}
|
||||
|
||||
setReactionFilter = (content: ReactionSymbols): void => {
|
||||
this.reactionFilter.value = content;
|
||||
};
|
||||
|
||||
// load
|
||||
loadData = (): void => {
|
||||
this.chatMessageViewModels.clear();
|
||||
|
||||
Reference in New Issue
Block a user