- patches/flare/000{1..5}-*.patch: typing indicators, formatted
messages, edited messages, multi-select with delete-for-me, and
in-channel message search. Mirror the matching commits in
~/projects/forks/flare and apply cleanly on top of upstream 0.20.4
(which is what nixpkgs ships).
- home/profiles/gui.nix: include a flare-signal override that appends
the patches via overrideAttrs. None of them touch Cargo.lock so the
cargoDeps hash stays valid; signal-desktop stays alongside it.
176 lines
6.4 KiB
Diff
176 lines
6.4 KiB
Diff
From 46765e848362129bb2d0fc34b2047e6cb2555258 Mon Sep 17 00:00:00 2001
|
|
From: Simon Gardling <titaniumtown@proton.me>
|
|
Date: Thu, 30 Apr 2026 04:25:07 -0400
|
|
Subject: [PATCH 6/6] feat(messages): Show 'This message was deleted.'
|
|
placeholder
|
|
|
|
Upstream hides the whole MessageItem when is-deleted is true via a
|
|
top-level visible bind on the template root. Replace that with a
|
|
Signal-Desktop-style behaviour: the row stays in the timeline, but the
|
|
bubble's regular content (header, quote, attachments, label, popover
|
|
trigger) and any reactions are hidden, and a single italic-dim
|
|
placeholder label takes their place.
|
|
|
|
The two pieces of imperative state set in code (media_overlay and the
|
|
floating timestamp_img indicator over media-only messages) are reset
|
|
in a small setup_deleted helper that subscribes to is-deleted, since
|
|
they are not reachable through bindings.
|
|
---
|
|
data/resources/style.css | 6 ++++++
|
|
data/resources/ui/message_item.blp | 29 +++++++++++++++++++++----
|
|
src/gui/message_item.rs | 34 ++++++++++++++++++++++++++++++
|
|
3 files changed, 65 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/data/resources/style.css b/data/resources/style.css
|
|
index 1c0cdfd..3b0de9a 100644
|
|
--- a/data/resources/style.css
|
|
+++ b/data/resources/style.css
|
|
@@ -9,6 +9,12 @@
|
|
background-color: @bubble_bg_color;
|
|
}
|
|
|
|
+/* Deletion placeholder shown in place of remotely-deleted messages. */
|
|
+.deleted-message {
|
|
+ font-style: italic;
|
|
+ opacity: 0.6;
|
|
+}
|
|
+
|
|
.message-input-bar {
|
|
border-top: 1px solid @borders;
|
|
}
|
|
diff --git a/data/resources/ui/message_item.blp b/data/resources/ui/message_item.blp
|
|
index ba3fd23..49002a5 100644
|
|
--- a/data/resources/ui/message_item.blp
|
|
+++ b/data/resources/ui/message_item.blp
|
|
@@ -71,8 +71,6 @@ template $FlMessageItem: $ContextMenuBin {
|
|
"message-item",
|
|
]
|
|
|
|
- visible: bind $not(template.message as <$FlTextMessage>.is-deleted) as <bool>;
|
|
-
|
|
Grid {
|
|
column-spacing: 12;
|
|
row-spacing: 12;
|
|
@@ -149,11 +147,32 @@ template $FlMessageItem: $ContextMenuBin {
|
|
"message-bubble",
|
|
]
|
|
|
|
+ // Deletion placeholder "This message was deleted." — visible only when
|
|
+ // the message has been remotely deleted; hides the rest of the bubble's
|
|
+ // content and any reactions/attachments via the .deleted CSS class on
|
|
+ // the message-item.
|
|
+ Label deleted_label {
|
|
+ styles [
|
|
+ "deleted-message",
|
|
+ ]
|
|
+
|
|
+ label: _("This message was deleted.");
|
|
+ visible: bind template.message as <$FlTextMessage>.is-deleted;
|
|
+ halign: start;
|
|
+ xalign: 0;
|
|
+
|
|
+ layout {
|
|
+ row: 0;
|
|
+ column: 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
Label header {
|
|
styles [
|
|
"heading",
|
|
]
|
|
|
|
+ visible: bind $not(template.message as <$FlTextMessage>.is-deleted) as <bool>;
|
|
label: bind template.message as <$FlTextMessage>.sender as <$FlContact>.title;
|
|
hexpand: true;
|
|
halign: start;
|
|
@@ -177,7 +196,7 @@ template $FlMessageItem: $ContextMenuBin {
|
|
"quote",
|
|
]
|
|
|
|
- visible: bind $is_some(template.message as <$FlTextMessage>.quote) as <bool>;
|
|
+ visible: bind $and($is_some(template.message as <$FlTextMessage>.quote) as <bool>, $not(template.message as <$FlTextMessage>.is-deleted) as <bool>) as <bool>;
|
|
|
|
Label {
|
|
styles [
|
|
@@ -219,6 +238,7 @@ template $FlMessageItem: $ContextMenuBin {
|
|
}
|
|
|
|
Box box_attachments {
|
|
+ visible: bind $not(template.message as <$FlTextMessage>.is-deleted) as <bool>;
|
|
layout {
|
|
row: 2;
|
|
column: 0;
|
|
@@ -276,6 +296,7 @@ template $FlMessageItem: $ContextMenuBin {
|
|
}
|
|
|
|
$FlMessageLabel label_message {
|
|
+ visible: bind $not(template.message as <$FlTextMessage>.is-deleted) as <bool>;
|
|
label: bind $markup_urls(template.message as <$FlTextMessage>.body) as <string>;
|
|
attributes: bind template.message as <$FlTextMessage>.message-attributes;
|
|
|
|
@@ -306,7 +327,7 @@ template $FlMessageItem: $ContextMenuBin {
|
|
]
|
|
|
|
label: bind $fix_emoji(template.message as <$FlTextMessage>.reactions) as <string>;
|
|
- visible: bind template.has-reaction;
|
|
+ visible: bind $and(template.has-reaction, $not(template.message as <$FlTextMessage>.is-deleted) as <bool>) as <bool>;
|
|
wrap-mode: word;
|
|
justify: left;
|
|
vexpand: false;
|
|
diff --git a/src/gui/message_item.rs b/src/gui/message_item.rs
|
|
index d88306f..33479da 100644
|
|
--- a/src/gui/message_item.rs
|
|
+++ b/src/gui/message_item.rs
|
|
@@ -35,6 +35,7 @@ impl MessageItem {
|
|
s.setup_requires_attention();
|
|
s.setup_pending_and_error();
|
|
s.setup_selection();
|
|
+ s.setup_deleted();
|
|
s
|
|
}
|
|
|
|
@@ -325,6 +326,39 @@ impl MessageItem {
|
|
message.notify("requires-attention");
|
|
}
|
|
|
|
+ /// Reflect the message's `is-deleted` state in the UI.
|
|
+ ///
|
|
+ /// Upstream simply hid the row entirely; we instead keep the row but
|
|
+ /// show a `"This message was deleted."` placeholder (handled in the
|
|
+ /// blueprint) and clean up the bits that the deletion pseudo-message
|
|
+ /// can't reach via the bind layer: the media overlay (whose visibility
|
|
+ /// is set imperatively in `set_message`) and the standalone
|
|
+ /// `timestamp_img` indicator that floats over media-only messages.
|
|
+ pub fn setup_deleted(&self) {
|
|
+ let message = self.message();
|
|
+ let apply = clone!(
|
|
+ #[weak(rename_to = s)]
|
|
+ self,
|
|
+ move || {
|
|
+ if s.message().is_deleted() {
|
|
+ s.add_css_class("deleted");
|
|
+ s.imp().media_overlay.set_visible(false);
|
|
+ s.imp().timestamp_img.set_visible(false);
|
|
+ } else {
|
|
+ // Symmetric reset for any future code path that flips
|
|
+ // is-deleted back off (e.g. an unsend/restore flow).
|
|
+ // Today nothing does, but the asymmetry is fragile.
|
|
+ s.remove_css_class("deleted");
|
|
+ }
|
|
+ }
|
|
+ );
|
|
+ self.track_notify_local(&message, "is-deleted", {
|
|
+ let apply = apply.clone();
|
|
+ move |_, _| apply()
|
|
+ });
|
|
+ apply();
|
|
+ }
|
|
+
|
|
pub fn setup_pending_and_error(&self) {
|
|
let message = self.message();
|
|
message.connect_notify_local(
|
|
--
|
|
2.53.0
|
|
|