flare: add patched flare-signal with five local feature patches
- 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.
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user