From 5e6b4f284da8125d13eee95d8d968e78e4094887 Mon Sep 17 00:00:00 2001
From: SimoneMariaRomeo <180769497+SimoneMariaRomeo@users.noreply.github.com>
Date: Tue, 12 May 2026 04:42:56 +0700
Subject: [PATCH 1/3] test(mail): cover unread-only empty notice
#689
---
src/app/message-list-empty-notice.spec.ts | 24 +++++++++++++++++++++++
src/app/message-list-empty-notice.ts | 13 ++++++++++++
2 files changed, 37 insertions(+)
create mode 100644 src/app/message-list-empty-notice.spec.ts
create mode 100644 src/app/message-list-empty-notice.ts
diff --git a/src/app/message-list-empty-notice.spec.ts b/src/app/message-list-empty-notice.spec.ts
new file mode 100644
index 000000000..b628a37cf
--- /dev/null
+++ b/src/app/message-list-empty-notice.spec.ts
@@ -0,0 +1,24 @@
+import { getEmptyMessageListNotice } from './message-list-empty-notice';
+
+describe('getEmptyMessageListNotice', () => {
+ it('shows a clear notice when Unread only hides all messages in a folder', () => {
+ const notice = getEmptyMessageListNotice({
+ hasVisibleRows: false,
+ ignoredUnreadFolders: ['Sent'],
+ selectedFolder: 'Inbox',
+ unreadOnly: true,
+ });
+
+ expect(notice).toBe('No unread messages in Inbox.');
+ });
+
+ it('does not show an empty-state notice while rows are visible', () => {
+ const notice = getEmptyMessageListNotice({
+ hasVisibleRows: true,
+ selectedFolder: 'Inbox',
+ unreadOnly: true,
+ });
+
+ expect(notice).toBeNull();
+ });
+});
diff --git a/src/app/message-list-empty-notice.ts b/src/app/message-list-empty-notice.ts
new file mode 100644
index 000000000..e0e305072
--- /dev/null
+++ b/src/app/message-list-empty-notice.ts
@@ -0,0 +1,13 @@
+export interface EmptyMessageListNoticeContext {
+ hasVisibleRows: boolean;
+ ignoredUnreadFolders?: string[];
+ searchText?: string;
+ selectedFolder?: string;
+ showingSearchResults?: boolean;
+ showingWebSocketSearchResults?: boolean;
+ unreadOnly?: boolean;
+}
+
+export function getEmptyMessageListNotice(context: EmptyMessageListNoticeContext): string {
+ return null;
+}
From d795d8e41474c90a61469517a125f00e399d8f12 Mon Sep 17 00:00:00 2001
From: SimoneMariaRomeo <180769497+SimoneMariaRomeo@users.noreply.github.com>
Date: Tue, 12 May 2026 04:44:00 +0700
Subject: [PATCH 2/3] fix(mail): show empty unread-only message
#689
---
src/app/app.component.html | 4 ++++
src/app/app.component.scss | 16 ++++++++++++++++
src/app/app.component.ts | 17 ++++++++++++++++-
src/app/message-list-empty-notice.ts | 18 +++++++++++++++++-
4 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/src/app/app.component.html b/src/app/app.component.html
index ec21e8698..c4e54aeb2 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -413,6 +413,10 @@
No Message Selected
+
+
+ {{ messageListEmptyNotice }}
+
0) {
+ if (this.canvastable.rows) {
const options = new Map();
options.set('unreadOnly', this.unreadMessagesOnlyCheckbox);
options.set('searchText', this.searchText);
this.canvastable.rows.filterBy(options);
+ this.updateMessageListEmptyNotice();
this.canvastable.hasChanges = true;
}
}
+ private updateMessageListEmptyNotice() {
+ this.messageListEmptyNotice = getEmptyMessageListNotice({
+ hasVisibleRows: this.canvastable.rows.rowCount() > 0,
+ ignoredUnreadFolders: this.messagelistservice.ignoreUnreadInFolders,
+ searchText: this.searchText,
+ selectedFolder: this.selectedFolder,
+ showingSearchResults: this.showingSearchResults,
+ showingWebSocketSearchResults: this.showingWebSocketSearchResults,
+ unreadOnly: this.unreadMessagesOnlyCheckbox,
+ });
+ }
+
public clearSelection() {
if (this.canvastable.rows) {
this.canvastable.rows.clearSelection();
diff --git a/src/app/message-list-empty-notice.ts b/src/app/message-list-empty-notice.ts
index e0e305072..91cf3a9c6 100644
--- a/src/app/message-list-empty-notice.ts
+++ b/src/app/message-list-empty-notice.ts
@@ -9,5 +9,21 @@ export interface EmptyMessageListNoticeContext {
}
export function getEmptyMessageListNotice(context: EmptyMessageListNoticeContext): string {
- return null;
+ if (context.hasVisibleRows) {
+ return null;
+ }
+
+ const selectedFolder = context.selectedFolder || 'this folder';
+ const ignoresUnreadOnly = (context.ignoredUnreadFolders || []).includes(selectedFolder);
+ if (context.unreadOnly && !ignoresUnreadOnly) {
+ return `No unread messages in ${selectedFolder}.`;
+ }
+
+ const searchIsActive = (context.searchText || '').length >= 3
+ || context.showingWebSocketSearchResults;
+ if (searchIsActive) {
+ return 'No messages match this search.';
+ }
+
+ return `No messages in ${selectedFolder}.`;
}
From 380bf9383d57c3f4a09e0dc9c31dd30f20d1337e Mon Sep 17 00:00:00 2001
From: SimoneMariaRomeo <180769497+SimoneMariaRomeo@users.noreply.github.com>
Date: Tue, 12 May 2026 04:54:52 +0700
Subject: [PATCH 3/3] style(mail): add Runbox license headers
#689
---
src/app/message-list-empty-notice.spec.ts | 19 +++++++++++++++++++
src/app/message-list-empty-notice.ts | 19 +++++++++++++++++++
2 files changed, 38 insertions(+)
diff --git a/src/app/message-list-empty-notice.spec.ts b/src/app/message-list-empty-notice.spec.ts
index b628a37cf..44c1de5ff 100644
--- a/src/app/message-list-empty-notice.spec.ts
+++ b/src/app/message-list-empty-notice.spec.ts
@@ -1,3 +1,22 @@
+// --------- BEGIN RUNBOX LICENSE ---------
+// Copyright (C) 2016-2026 Runbox Solutions AS (runbox.com).
+//
+// This file is part of Runbox 7.
+//
+// Runbox 7 is free software: You can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the
+// Free Software Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// Runbox 7 is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Runbox 7. If not, see .
+// ---------- END RUNBOX LICENSE ----------
+
import { getEmptyMessageListNotice } from './message-list-empty-notice';
describe('getEmptyMessageListNotice', () => {
diff --git a/src/app/message-list-empty-notice.ts b/src/app/message-list-empty-notice.ts
index 91cf3a9c6..08c4fb0ec 100644
--- a/src/app/message-list-empty-notice.ts
+++ b/src/app/message-list-empty-notice.ts
@@ -1,3 +1,22 @@
+// --------- BEGIN RUNBOX LICENSE ---------
+// Copyright (C) 2016-2026 Runbox Solutions AS (runbox.com).
+//
+// This file is part of Runbox 7.
+//
+// Runbox 7 is free software: You can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the
+// Free Software Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// Runbox 7 is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Runbox 7. If not, see .
+// ---------- END RUNBOX LICENSE ----------
+
export interface EmptyMessageListNoticeContext {
hasVisibleRows: boolean;
ignoredUnreadFolders?: string[];