mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-04 00:06:53 +00:00
feat: filter search results by message size
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { splitSearchText, textConditions, textFilter } from '../search-utils';
|
||||
import { sizeFilterBytes, sizePresetOf, splitSearchText, textConditions, textFilter } from '../search-utils';
|
||||
import { textFilterMatches, type StalwartTextVersion } from './stalwart-text-model';
|
||||
|
||||
type Filter = Record<string, unknown>;
|
||||
@@ -125,3 +125,29 @@ describe('text search results (P1-7)', () => {
|
||||
expect(hits('0.16', textFilter('project budg*'))).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
// The size filter (webmail 720e14622): KB bounds as typed, sent in bytes.
|
||||
describe('sizeFilterBytes', () => {
|
||||
it('turns a KB value into bytes', () => {
|
||||
expect(sizeFilterBytes('1024')).toBe(1024 * 1024);
|
||||
expect(sizeFilterBytes('1.5')).toBe(1536);
|
||||
});
|
||||
|
||||
it('reads an empty, zero, negative or non-numeric value as unset', () => {
|
||||
for (const value of [undefined, '', '0', '-5', 'abc', 'Infinity']) {
|
||||
expect(sizeFilterBytes(value)).toBeNull();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('sizePresetOf', () => {
|
||||
it('names the panel choice for the bounds', () => {
|
||||
expect(sizePresetOf(undefined, undefined)).toBe('any');
|
||||
expect(sizePresetOf('', '')).toBe('any');
|
||||
expect(sizePresetOf('1024', undefined)).toBe('mb1');
|
||||
expect(sizePresetOf('25600', '')).toBe('mb25');
|
||||
expect(sizePresetOf('2048', undefined)).toBe('custom');
|
||||
expect(sizePresetOf('1024', '4096')).toBe('custom');
|
||||
expect(sizePresetOf(undefined, '100')).toBe('custom');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,33 @@
|
||||
// Free-text search conditions for Email/query, ported from the webmail's
|
||||
// lib/jmap/search-utils.ts (5967a1c4) so both clients send the same filters.
|
||||
|
||||
/**
|
||||
* A KB size field (the filter panel's custom size) as a positive byte count
|
||||
* for Email/query's minSize / maxSize (RFC 8621 §4.4.1), or null when unset
|
||||
* or not a positive number (webmail lib/jmap/search-utils.ts, 720e14622).
|
||||
*/
|
||||
export function sizeFilterBytes(value: string | undefined): number | null {
|
||||
const kb = Number(value);
|
||||
if (!value || !Number.isFinite(kb) || kb <= 0) return null;
|
||||
return Math.round(kb * 1024);
|
||||
}
|
||||
|
||||
/** The size presets of the filter panel, in MB: "Larger than 1 MB" and so on. */
|
||||
export const SIZE_PRESETS_MB = [1, 5, 10, 25] as const;
|
||||
|
||||
/**
|
||||
* Which size choice the filter panel shows for the KB bounds: none set, a
|
||||
* "Larger than N MB" preset, or a custom range.
|
||||
*/
|
||||
export function sizePresetOf(minSizeKb: string | undefined, maxSizeKb: string | undefined): string {
|
||||
if (!minSizeKb && !maxSizeKb) return 'any';
|
||||
if (!maxSizeKb) {
|
||||
const mb = SIZE_PRESETS_MB.find((m) => String(m * 1024) === minSizeKb);
|
||||
if (mb) return `mb${mb}`;
|
||||
}
|
||||
return 'custom';
|
||||
}
|
||||
|
||||
/** Filter properties whose value the server reads as free text. */
|
||||
export type SearchTextProperty = 'text' | 'from' | 'to' | 'subject' | 'body';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user