implement showing only replies

This commit is contained in:
marlon-erler
2026-09-23 14:44:34 +02:00
parent 787615aab4
commit 4901c0c5c0
7 changed files with 1003 additions and 39 deletions
+936 -29
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -234,7 +234,7 @@
text-align: right; text-align: right;
} }
.message-bubble > .inline-reply { .message-bubble > :is(.inline-reply, .reply-link, .message-reaction-row) {
cursor: pointer; cursor: pointer;
display: flex; display: flex;
@@ -248,20 +248,20 @@
overflow: hidden; overflow: hidden;
padding: 0px var(--control-padding); padding: 0px var(--control-padding);
gap: var(--text-gap); }
.message-bubble > .inline-reply {
border-left: var(--outline-width) solid var(--primary); border-left: var(--outline-width) solid var(--primary);
gap: var(--text-gap);
}
.message-bubble > .reply-link {
gap: 5px;
} }
.message-bubble > .message-reaction-row { .message-bubble > .message-reaction-row {
max-width: var(--max-input-width);
width: 100%;
padding: var(--gap-between-tiles); padding: var(--gap-between-tiles);
background: var(--surface-alt);
display: none !important; display: none !important;
overflow: hidden;
} }
.message-bubble > .message-reaction-row:has(button:not([count="0"])) { .message-bubble > .message-reaction-row:has(button:not([count="0"])) {
+2
View File
@@ -5,6 +5,7 @@ import * as React from "../../react";
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 { ChatMessageStatuses } from "../../Model/Chat/chatModel"; import { ChatMessageStatuses } from "../../Model/Chat/chatModel";
import {ReplyLink} from "./replyLink";
export function ChatMessage( export function ChatMessage(
coreViewModel: CoreViewModel, coreViewModel: CoreViewModel,
@@ -75,6 +76,7 @@ export function ChatMessage(
</div> </div>
</div> </div>
{MessageReactionButtonRow(coreViewModel, chatMessageViewModel)} {MessageReactionButtonRow(coreViewModel, chatMessageViewModel)}
{ReplyLink(coreViewModel, chatMessageViewModel)}
{ChatMessageInfoModal(coreViewModel, chatMessageViewModel)} {ChatMessageInfoModal(coreViewModel, chatMessageViewModel)}
</div> </div>
); );
+22
View File
@@ -0,0 +1,22 @@
import * as React from "../../react";
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
export function ReplyLink(coreViewModel: CoreViewModel, chatMessageViewModel: ChatMessageViewModel) {
const isHidden = React.createProxyState([chatMessageViewModel.replyCount], ()=>chatMessageViewModel.replyCount.value == 0);
function select() {
chatMessageViewModel.messagePageViewModel.replyViewSelectedMessage.value = chatMessageViewModel;
}
return (
<div
class="reply-link"
toggle:hidden={isHidden}
on:click={select}
>
<span>{coreViewModel.translations.chatPage.message.replyPrefixLabel}</span>
<b class="ellipsis" subscribe:innerText={chatMessageViewModel.replyCount}></b>
</div>
);
}
+8
View File
@@ -248,6 +248,10 @@ const englishTranslations = {
attentionReaction: "Reaction: exclamation mark", attentionReaction: "Reaction: exclamation mark",
doubleAttentionReaction: "Reaction: double exclamation mark", doubleAttentionReaction: "Reaction: double exclamation mark",
questionReaction: "Reaction: question mark", questionReaction: "Reaction: question mark",
//
replyPrefixLabel: "Replies: ",
}, },
task: { task: {
@@ -569,6 +573,8 @@ export const allTranslations: {
attentionReaction: "Reaktion: Ausrufezeichen", attentionReaction: "Reaktion: Ausrufezeichen",
doubleAttentionReaction: "Reaktion: doppeltes Ausrufezeichen", doubleAttentionReaction: "Reaktion: doppeltes Ausrufezeichen",
questionReaction: "Reaktion: Fragezeichen", questionReaction: "Reaktion: Fragezeichen",
replyPrefixLabel: "Antworten: ",
}, },
task: { task: {
@@ -871,6 +877,8 @@ export const allTranslations: {
attentionReaction: "Reaccion: signo de atención", attentionReaction: "Reaccion: signo de atención",
doubleAttentionReaction: "Reaccion: signo de atención doble", doubleAttentionReaction: "Reaccion: signo de atención doble",
questionReaction: "Reaccion: signo de interrogación", questionReaction: "Reaccion: signo de interrogación",
replyPrefixLabel: "Respuestas: ",
}, },
task: { task: {
+21 -2
View File
@@ -16,6 +16,8 @@ export default class ChatMessageViewModel {
dateSent: string = ""; dateSent: string = "";
body: React.State<string> = new React.State(""); body: React.State<string> = new React.State("");
inlineReply: ChatMessageViewModel | undefined = undefined; inlineReply: ChatMessageViewModel | undefined = undefined;
replies: React.MapState<ChatMessageViewModel> = new React.MapState();
replyCount: React.State<number> = React.createProxyState([this.replies], ()=>this.replies.value.size);
status: React.State<ChatMessageStatuses | any> = new React.State<any>( status: React.State<ChatMessageStatuses | any> = new React.State<any>(
undefined, undefined,
); );
@@ -133,6 +135,7 @@ export default class ChatMessageViewModel {
this.messagePageViewModel.chatMessageViewModels.value.get( this.messagePageViewModel.chatMessageViewModels.value.get(
this.chatMessage.inlineReplyId, this.chatMessage.inlineReplyId,
); );
this.inlineReply.replies.set(this.chatMessage.id, this);
} }
}; };
@@ -147,9 +150,16 @@ export default class ChatMessageViewModel {
this.sentByUser = sentByUser; this.sentByUser = sentByUser;
this.loadData(); this.loadData();
let hideForReactions: boolean = false;
let hideForReplyView: boolean = false;
const updateHiding = () => {
this.isHidden.value = hideForReactions || hideForReplyView;
}
this.messagePageViewModel.reactionFilter.subscribe((content) => { this.messagePageViewModel.reactionFilter.subscribe((content) => {
if (content == undefined) { if (content == undefined) {
this.isHidden.value = false; hideForReactions = false;
return; return;
} }
@@ -181,7 +191,16 @@ export default class ChatMessageViewModel {
} }
} }
this.isHidden.value = count == 0; hideForReactions = count == 0;
updateHiding();
}); });
this.messagePageViewModel.replyViewSelectedMessage.subscribe(selectedMessage => {
if (selectedMessage == undefined) hideForReplyView = false;
else if (selectedMessage == this) hideForReplyView = false;
else if (selectedMessage == this.inlineReply) hideForReplyView = false;
else hideForReplyView = true;
updateHiding();
})
} }
} }
@@ -16,6 +16,7 @@ export default class MessagePageViewModel extends Context {
new React.MapState(); new React.MapState();
filteredMessageViewModels: React.ListState<ChatMessageViewModel> = filteredMessageViewModels: React.ListState<ChatMessageViewModel> =
new React.ListState(); new React.ListState();
replyViewSelectedMessage: React.State<ChatMessageViewModel|undefined> = new React.State(undefined);
searchViewModel: SearchViewModel<ChatMessageViewModel>; searchViewModel: SearchViewModel<ChatMessageViewModel>;
isFilterModalOpen = new React.State<boolean>(false); isFilterModalOpen = new React.State<boolean>(false);
reactionFilter = new React.State<ReactionSymbols | undefined>(undefined); reactionFilter = new React.State<ReactionSymbols | undefined>(undefined);
@@ -25,6 +26,7 @@ export default class MessagePageViewModel extends Context {
undefined, undefined,
); );
composingMessage = new React.State<string>(""); composingMessage = new React.State<string>("");
focusSetter = new React.State(null); focusSetter = new React.State(null);
// guards // guards
@@ -131,6 +133,10 @@ export default class MessagePageViewModel extends Context {
this.searchViewModel.search(""); this.searchViewModel.search("");
}; };
resetReplyView = (): void => {
this.replyViewSelectedMessage.value = undefined;
}
setFocus = (): void => { setFocus = (): void => {
this.focusSetter.callSubscriptions(); this.focusSetter.callSubscriptions();
}; };