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[];