From 170c1d50aa3e33f8f12fae0ab5a25b7a6620aea9 Mon Sep 17 00:00:00 2001
From: Patrick Willy <46555287+pnwilly@users.noreply.github.com>
Date: Thu, 3 Sep 2026 13:45:51 +0400
Subject: [PATCH 1/8] fix: use native Frappe notification content
---
.../public/js/notification_row_delete_v5.js | 100 ------------------
1 file changed, 100 deletions(-)
diff --git a/reyal_core/public/js/notification_row_delete_v5.js b/reyal_core/public/js/notification_row_delete_v5.js
index adb2413..3f5c41a 100644
--- a/reyal_core/public/js/notification_row_delete_v5.js
+++ b/reyal_core/public/js/notification_row_delete_v5.js
@@ -177,98 +177,6 @@
return $delete;
}
- /**
- * Frappe injects Notification Log.description as raw HTML. That is fine
- * for the Notification Log form, but the Desk bell dropdown must stay
- * compact. Catch email bodies, Quill comment markup, and bare media
- * (comment mentions often store just an
).
- */
- function looks_like_rich_html(html) {
- if (!html) return false;
- return /<(img|video|iframe|figure|svg|picture|audio|source|p|ul|ol|table|div|br|h[1-6]|blockquote|pre|hr|section|article)\b/i.test(
- html
- );
- }
-
- function plain_text_from_html(html) {
- if (typeof strip_html === "function") {
- return strip_html(html).replace(/\s+/g, " ").trim();
- }
- return $("
").html(html).text().replace(/\s+/g, " ").trim();
- }
-
- function plain_preview(html, max_length) {
- const text = plain_text_from_html(html);
- if (!text) return "";
- const limit = max_length || 140;
- return frappe.ellipsis ? frappe.ellipsis(text, limit) : text.slice(0, limit);
- }
-
- /**
- * Collapse rich/media HTML in a rendered notification row (fallback for
- * rows already in the DOM, realtime inserts, etc.).
- */
- function sanitize_notification_item_body($item) {
- const $body = $item.children(".notification-body").first();
- const $message = $body.children(".message").first();
- if (!$message.length) return;
-
- const $description = $message.children(".notification-description").first();
- if ($description.length && looks_like_rich_html($description.html())) {
- const text = plain_preview($description.html(), 140);
- if (text) {
- $description.text(text);
- } else {
- $description.remove();
- }
- }
-
- $message.children("div").not(".notification-description, .notification-timestamp").each(function () {
- const $block = $(this);
- const html = $block.html() || "";
- if (!looks_like_rich_html(html)) return;
- const text = plain_preview(html, 140);
- if (text) {
- // Preserve Frappe's subject HTML when it is only lightweight
- // markup; rewrite only when block/media content leaked in.
- if (/<(img|video|iframe|figure|svg|picture|p|ul|ol|table|div)\b/i.test(html)) {
- $block.text(text);
- }
- }
- });
-
- // Belt-and-suspenders: drop any leftover media under the message.
- $message.find("img, video, iframe, svg, picture, audio").remove();
- $message.children(".notification-description").filter(function () {
- return !($(this).text() || "").trim();
- }).remove();
- }
-
- /**
- * Sanitize the log payload before Frappe builds the row HTML so giant
- * comment images never flash into the dropdown.
- */
- function sanitize_notification_log(notification_log) {
- if (!notification_log) return notification_log;
- const log = Object.assign({}, notification_log);
-
- if (log.description && looks_like_rich_html(log.description)) {
- log.description = plain_preview(log.description, 140);
- }
-
- ["title", "subject"].forEach((field) => {
- if (log[field] && looks_like_rich_html(log[field])) {
- // Keep Frappe's subject-title bold wrappers when present; only
- // strip when media / block markup leaked into the title.
- if (/<(img|video|iframe|figure|svg|picture)\b/i.test(log[field])) {
- log[field] = plain_preview(log[field], 100) || log[field];
- }
- }
- });
-
- return log;
- }
-
function decorate_notification_item($item, notifications) {
const docname = $item.attr("data-name");
if (!docname) return;
@@ -280,7 +188,6 @@
const is_unread = $item.hasClass("unread");
$item.css({ position: "relative", "padding-right": "34px" });
- sanitize_notification_item_body($item);
let $controls = $item.children(".reyal-notification-controls").first();
if (!$controls.length) {
@@ -356,13 +263,6 @@
const view = get_notifications_view(notifications);
if (!view || view[VIEW_PATCH_FLAG]) return;
- const original_item_html = view.get_dropdown_item_html;
- if (original_item_html) {
- view.get_dropdown_item_html = function (notification_log) {
- return original_item_html.call(this, sanitize_notification_log(notification_log));
- };
- }
-
const original_render = view.render_notifications_dropdown;
view.render_notifications_dropdown = function () {
original_render.call(this);
From 6f84fb0c0b28e244d15905f7f38de21a147dd466 Mon Sep 17 00:00:00 2001
From: Patrick Willy <46555287+pnwilly@users.noreply.github.com>
Date: Thu, 3 Sep 2026 13:46:14 +0400
Subject: [PATCH 2/8] fix: remove custom notification content styling
---
.../public/css/notification_row_delete_v5.css | 23 ++-----------------
1 file changed, 2 insertions(+), 21 deletions(-)
diff --git a/reyal_core/public/css/notification_row_delete_v5.css b/reyal_core/public/css/notification_row_delete_v5.css
index 60fa0a7..ec2a295 100644
--- a/reyal_core/public/css/notification_row_delete_v5.css
+++ b/reyal_core/public/css/notification_row_delete_v5.css
@@ -1,7 +1,7 @@
/*
* Compact Desk notifications dropdown.
- * Keep delete/mark-as-read chrome + denser row layout. Rich HTML is sanitized
- * in JS so the avatar|message grid cannot reintroduce the column skew.
+ * Keep delete/mark-as-read chrome + denser row layout while leaving message
+ * rendering to Frappe v15.
*/
.recent-item.notification-item {
@@ -41,15 +41,6 @@
display: none !important;
}
-/* Comment/email media must never expand a dropdown row. */
-.recent-item.notification-item .notification-body .message img,
-.recent-item.notification-item .notification-body .message video,
-.recent-item.notification-item .notification-body .message iframe,
-.recent-item.notification-item .notification-body .message svg,
-.recent-item.notification-item .notification-body .message picture {
- display: none !important;
-}
-
.recent-item.notification-item .notification-body > .user-avatar,
.recent-item.notification-item .notification-body > .avatar {
grid-column: 1;
@@ -105,16 +96,6 @@
max-width: 100%;
}
-.recent-item.notification-item .notification-description {
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-line-clamp: 2;
- line-clamp: 2;
- overflow: hidden;
- overflow-wrap: anywhere;
- word-break: break-word;
-}
-
.recent-item.notification-item .notification-timestamp {
line-height: 1.2;
}
From 1fba48d863f883720b1818010d8db7e5c3c8e7c4 Mon Sep 17 00:00:00 2001
From: Patrick Willy <46555287+pnwilly@users.noreply.github.com>
Date: Thu, 3 Sep 2026 13:46:41 +0400
Subject: [PATCH 3/8] chore: refresh notification assets
---
reyal_core/hooks.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/reyal_core/hooks.py b/reyal_core/hooks.py
index 1937e6a..2164e59 100644
--- a/reyal_core/hooks.py
+++ b/reyal_core/hooks.py
@@ -6,8 +6,8 @@
app_license = "mit"
# Include custom Desk behaviour:
-app_include_js = "/assets/reyal_core/js/notification_row_delete_v5.js?v=20260810_05"
-app_include_css = "/assets/reyal_core/css/notification_row_delete_v5.css?v=20260810_05"
+app_include_js = "/assets/reyal_core/js/notification_row_delete_v5.js?v=20260903_01"
+app_include_css = "/assets/reyal_core/css/notification_row_delete_v5.css?v=20260903_01"
# Install / migrate hooks:
From b7847cc08d01d1be26930a9fc337687f5ec1a87a Mon Sep 17 00:00:00 2001
From: Patrick Willy <46555287+pnwilly@users.noreply.github.com>
Date: Thu, 3 Sep 2026 13:46:52 +0400
Subject: [PATCH 4/8] chore: bump version to 0.0.12
---
reyal_core/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/reyal_core/__init__.py b/reyal_core/__init__.py
index b2f0155..6e2648a 100644
--- a/reyal_core/__init__.py
+++ b/reyal_core/__init__.py
@@ -1 +1 @@
-__version__ = "0.0.11"
+__version__ = "0.0.12"
From 4da6c05413723bba2d0c9bdae32d3b8f28b132ba Mon Sep 17 00:00:00 2001
From: Patrick Willy <46555287+pnwilly@users.noreply.github.com>
Date: Thu, 3 Sep 2026 13:47:03 +0400
Subject: [PATCH 5/8] docs: record native notification rendering
---
CHANGELOG.md | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 48a0ad6..69763e9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog.
+## [0.0.12] - 2026-09-03
+
+### Changed
+
+- Restore Frappe v15's native notification message rendering; retain Reyal's compact layout and per-row delete action
+
## [0.0.11] - 2026-08-29
### Changed
From 9ef36d5e6f5486ff050433c68970035cd6fb81ad Mon Sep 17 00:00:00 2001
From: Patrick Willy <46555287+pnwilly@users.noreply.github.com>
Date: Thu, 3 Sep 2026 14:03:34 +0400
Subject: [PATCH 6/8] fix: restore Frappe v15 notification row spacing
---
reyal_core/public/css/notification_row_delete_v5.css | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/reyal_core/public/css/notification_row_delete_v5.css b/reyal_core/public/css/notification_row_delete_v5.css
index ec2a295..2842bd1 100644
--- a/reyal_core/public/css/notification_row_delete_v5.css
+++ b/reyal_core/public/css/notification_row_delete_v5.css
@@ -1,14 +1,13 @@
/*
- * Compact Desk notifications dropdown.
- * Keep delete/mark-as-read chrome + denser row layout while leaving message
- * rendering to Frappe v15.
+ * Desk notifications with Reyal row actions.
+ * Keep Frappe v15's row spacing while reserving room for the added controls.
*/
.recent-item.notification-item {
position: relative;
- /* Stock Frappe uses 10px padding + 10px margin — reclaim that vertical space. */
- padding: 6px 28px 6px 0 !important;
- margin: 4px 8px !important;
+ /* Match Frappe v15 vertically; retain extra right inset for Reyal controls. */
+ padding: 10px 28px 10px 0 !important;
+ margin: 10px !important;
}
/* Avatar | message only. Description lives inside .message, never as a grid item. */
From 14c3119a09fd8712a4aae4d2e773b79e9926fe9c Mon Sep 17 00:00:00 2001
From: Patrick Willy <46555287+pnwilly@users.noreply.github.com>
Date: Thu, 3 Sep 2026 14:03:57 +0400
Subject: [PATCH 7/8] chore: refresh notification styles
---
reyal_core/hooks.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/reyal_core/hooks.py b/reyal_core/hooks.py
index 2164e59..5bf4bb0 100644
--- a/reyal_core/hooks.py
+++ b/reyal_core/hooks.py
@@ -6,8 +6,8 @@
app_license = "mit"
# Include custom Desk behaviour:
-app_include_js = "/assets/reyal_core/js/notification_row_delete_v5.js?v=20260903_01"
-app_include_css = "/assets/reyal_core/css/notification_row_delete_v5.css?v=20260903_01"
+app_include_js = "/assets/reyal_core/js/notification_row_delete_v5.js?v=20260903_02"
+app_include_css = "/assets/reyal_core/css/notification_row_delete_v5.css?v=20260903_02"
# Install / migrate hooks:
From f9722d202ce408ae03739dc7ac6cc56d3d7ece49 Mon Sep 17 00:00:00 2001
From: Patrick Willy <46555287+pnwilly@users.noreply.github.com>
Date: Thu, 3 Sep 2026 14:04:08 +0400
Subject: [PATCH 8/8] docs: record restored Frappe row spacing
---
CHANGELOG.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 69763e9..37177f5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,7 @@ The format is based on Keep a Changelog.
### Changed
-- Restore Frappe v15's native notification message rendering; retain Reyal's compact layout and per-row delete action
+- Restore Frappe v15's native notification message rendering and vertical row spacing; retain Reyal's per-row controls and avatar grid
## [0.0.11] - 2026-08-29