edf9f77060
Search previously defaulted to 'all kinds' — every kind in the picker (50+), which means a user typing 'bitcoin' into the search bar got a firehose of music tracks, podcasts, bird detections, geocaches, and every other supported NIP. The Posts tab is meant to surface Agora content; the long-tail kinds belong behind an explicit opt-in. Introduce 'agora' as a new sentinel value for the Kind filter that expands to AGORA_PRESET_KIND_VALUES (Campaigns, Pledges, Communities, Posts, Articles, Events, Polls, Photos, Videos). Make it the default in DEFAULT_FILTERS, teach parseKindFilter to resolve it, and render both 'Agora content' and 'All kinds' as top-level selectable rows in the KindPicker (with the existing Agora-curated quick-list still appearing as individual selectable items below). The active-filter chip summary suppresses a chip when the default 'agora' is in effect, surfaces 'All kinds' as a chip when the user explicitly broadens the search, and continues to show individual kind labels for everything else.
55 lines
1.8 KiB
TypeScript
55 lines
1.8 KiB
TypeScript
import { clsx, type ClassValue } from "clsx"
|
|
import { twMerge } from "tailwind-merge"
|
|
import { AGORA_PRESET_KIND_VALUES } from "./feedFilterUtils"
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs))
|
|
}
|
|
|
|
/**
|
|
* Parse a kindFilter string into an array of kind numbers.
|
|
* Supports:
|
|
* - 'all' → undefined (no override)
|
|
* - 'agora' → the AGORA_PRESET_KIND_VALUES set (Campaigns, Pledges,
|
|
* Communities, Posts, Articles, Events, Polls, Photos, Videos)
|
|
* - 'custom' → parse customKindText as comma/space-separated numbers
|
|
* - Single kind number (e.g. '1') → [1]
|
|
* - Comma-separated kind numbers (e.g. '1,30023,20') → [1, 30023, 20]
|
|
*/
|
|
export function parseKindFilter(kindFilter: string, customKindText?: string): number[] | undefined {
|
|
if (kindFilter === 'all' || kindFilter === '') return undefined;
|
|
if (kindFilter === 'agora') return AGORA_PRESET_KIND_VALUES.map(Number);
|
|
if (kindFilter === 'custom') {
|
|
if (!customKindText) return undefined;
|
|
const parsed = customKindText.trim().split(/[\s,]+/).map(Number).filter((n) => Number.isInteger(n) && n > 0);
|
|
return parsed.length > 0 ? parsed : undefined;
|
|
}
|
|
// Comma-separated or single value
|
|
const parsed = kindFilter.split(',').map(Number).filter((n) => Number.isInteger(n) && n > 0);
|
|
return parsed.length > 0 ? parsed : undefined;
|
|
}
|
|
|
|
/**
|
|
* Format a number in compact English notation.
|
|
* Examples:
|
|
* 1,200 → "1.2K"
|
|
* 15,400 → "15.4K"
|
|
* 1,200,000 → "1.2M"
|
|
* 999 → "999"
|
|
*
|
|
* Uses Intl.NumberFormat for locale-consistent formatting.
|
|
*/
|
|
export function formatCompactNumber(num: number): string {
|
|
if (num < 1000) {
|
|
return num.toString();
|
|
}
|
|
|
|
const formatter = new Intl.NumberFormat('en', {
|
|
notation: 'compact',
|
|
compactDisplay: 'short',
|
|
maximumFractionDigits: 1,
|
|
});
|
|
|
|
return formatter.format(num);
|
|
}
|