mirror of
https://github.com/bulwarkmail/native.git
synced 2026-10-31 08:06:36 +00:00
feat: add a setting to clear the search when switching folders
This commit is contained in:
@@ -32,6 +32,7 @@ export function ReadingSettings() {
|
||||
const deleteAction = useSettingsStore((s) => s.deleteAction);
|
||||
const permanentlyDeleteJunk = useSettingsStore((s) => s.permanentlyDeleteJunk);
|
||||
const showPreview = useSettingsStore((s) => s.showPreview);
|
||||
const clearSearchOnFolderChange = useSettingsStore((s) => s.clearSearchOnFolderChange);
|
||||
const disableThreading = useSettingsStore((s) => s.disableThreading);
|
||||
const includeGroupInUnified = useSettingsStore((s) => s.includeGroupInUnified);
|
||||
const autoSelectReplyIdentity = useSettingsStore((s) => s.autoSelectReplyIdentity);
|
||||
@@ -184,6 +185,10 @@ export function ReadingSettings() {
|
||||
<ToggleSwitch checked={permanentlyDeleteJunk} onChange={(v) => update('permanentlyDeleteJunk', v)} />
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem label={t('settings.email_behavior.clear_search_on_folder_change.label', "Clear search when switching folders")} description={t('settings.email_behavior.clear_search_on_folder_change.description', "Clicking a folder (Inbox, Sent, …) clears the active search and browses that folder. When off, the search stays applied and re-runs in the folder you switch to.")}>
|
||||
<ToggleSwitch checked={clearSearchOnFolderChange} onChange={(v) => update('clearSearchOnFolderChange', v)} />
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem label={t('settings.email_behavior.show_preview.label', "Show Preview Text")} description={t('settings.email_behavior.show_preview.description', "Display email preview in the list")}>
|
||||
<ToggleSwitch checked={showPreview} onChange={(v) => update('showPreview', v)} />
|
||||
</SettingItem>
|
||||
|
||||
@@ -236,6 +236,36 @@ describe('email-store', () => {
|
||||
expect(useEmailStore.getState().emailStates).toEqual({ 'mb-empty': 'em-state-0' });
|
||||
expect(mockGetEmails).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('drops the search and browses the folder with "clear search when switching folders"', async () => {
|
||||
useSettingsStore.getState().updateSetting('clearSearchOnFolderChange', true);
|
||||
try {
|
||||
useEmailStore.setState({
|
||||
currentMailboxId: 'mb-1',
|
||||
mailboxes: [
|
||||
{ id: 'mb-1', name: 'Inbox', isShared: false } as any,
|
||||
{ id: 'mb-2', name: 'Receipts', isShared: false } as any,
|
||||
],
|
||||
searchQuery: 'invoice',
|
||||
filters: { isUnread: true },
|
||||
emails: [{ id: 'hit' } as any],
|
||||
});
|
||||
mockQueryEmails.mockResolvedValue({ ids: [], total: 0, queryState: 'q' });
|
||||
|
||||
await useEmailStore.getState().selectMailbox('mb-2');
|
||||
|
||||
const state = useEmailStore.getState();
|
||||
expect(state.searchQuery).toBe('');
|
||||
expect(state.filters).toEqual({});
|
||||
// The search hits neither stay on screen nor become Inbox's snapshot.
|
||||
expect(state.emails).toEqual([]);
|
||||
expect(state.mailboxSnapshots['mb-1']).toBeUndefined();
|
||||
expect(mockQueryEmails.mock.calls[0][0]).toBe('mb-2');
|
||||
expect(mockQueryEmails.mock.calls[0][1].filter).toBeUndefined();
|
||||
} finally {
|
||||
useSettingsStore.getState().updateSetting('clearSearchOnFolderChange', false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadMoreEmails', () => {
|
||||
|
||||
@@ -752,6 +752,11 @@ export const useEmailStore = create<EmailState>()(
|
||||
};
|
||||
}
|
||||
|
||||
// "Clear search when switching folders": drop the query and filters and
|
||||
// browse the folder, instead of re-running the search there.
|
||||
const clearSearch = !baseView && useSettingsStore.getState().clearSearchOnFolderChange;
|
||||
const browse = baseView || clearSearch;
|
||||
|
||||
const incoming = mailboxSnapshots[mailboxId];
|
||||
// Swap to the new mailbox's cached view immediately. If there's no
|
||||
// snapshot, fall through to the offline cache as a second-best seed;
|
||||
@@ -759,11 +764,11 @@ export const useEmailStore = create<EmailState>()(
|
||||
// a blank list — better than the previous flash to "Loading…".
|
||||
// With a search/filter active the search is kept and re-run in the new
|
||||
// folder (#553), so the current results stay on screen until it lands.
|
||||
let seededEmails: Email[] = baseView ? incoming?.emails ?? [] : state.emails;
|
||||
let seededTotal = baseView ? incoming?.total ?? 0 : state.totalEmails;
|
||||
const seededQueryState = baseView ? incoming?.queryState : undefined;
|
||||
let seededEmails: Email[] = browse ? incoming?.emails ?? [] : state.emails;
|
||||
let seededTotal = browse ? incoming?.total ?? 0 : state.totalEmails;
|
||||
const seededQueryState = browse ? incoming?.queryState : undefined;
|
||||
|
||||
if (baseView && seededEmails.length === 0) {
|
||||
if (browse && seededEmails.length === 0) {
|
||||
const cacheStore = useOfflineCacheStore.getState();
|
||||
if (!cacheStore.hydrated) await cacheStore.hydrate();
|
||||
if (cacheStore.totalCount() > 0) {
|
||||
@@ -786,6 +791,7 @@ export const useEmailStore = create<EmailState>()(
|
||||
}
|
||||
|
||||
set({
|
||||
...(clearSearch ? { searchQuery: '', filters: {} } : {}),
|
||||
currentMailboxId: mailboxId,
|
||||
emails: seededEmails,
|
||||
totalEmails: seededTotal,
|
||||
|
||||
@@ -197,6 +197,9 @@ interface PersistedSettings {
|
||||
showAvatarsInJunk: boolean;
|
||||
// Show the "/ total" part of the folder counts in the drawer (#498).
|
||||
showFolderTotalCount: boolean;
|
||||
// Opening a folder drops an active search and filters and browses it,
|
||||
// instead of re-running the search there (#553, the default).
|
||||
clearSearchOnFolderChange: boolean;
|
||||
// Unified views span every logged-in account instead of just the active
|
||||
// one (own + its shared/group folders). Off by default like the webmail.
|
||||
unifiedCrossAccount: boolean;
|
||||
@@ -366,6 +369,7 @@ const DEFAULT_PERSISTED: PersistedSettings = {
|
||||
messageListOrderScope: 'inbox',
|
||||
showAvatarsInJunk: false,
|
||||
showFolderTotalCount: true,
|
||||
clearSearchOnFolderChange: false,
|
||||
unifiedCrossAccount: false,
|
||||
mailAttachmentAction: 'preview',
|
||||
attachmentPosition: 'beside-sender',
|
||||
|
||||
Reference in New Issue
Block a user