Harden filter import: item-level validation and user feedback
importFromAyuGram now skips individual malformed entries (missing id/text) instead of crashing, and validates the top-level structure properly. Import shows a toast on success, empty result, or parse failure.
This commit is contained in:
parent
1913174e1c
commit
ffb1ba8108
@ -33,7 +33,7 @@ const SettingsAyuLike = ({
|
|||||||
messageFilters,
|
messageFilters,
|
||||||
onReset,
|
onReset,
|
||||||
}: OwnProps & StateProps) => {
|
}: OwnProps & StateProps) => {
|
||||||
const { setSharedSettingOption } = getActions();
|
const { setSharedSettingOption, showNotification } = getActions();
|
||||||
const fileInputRef = useRef<HTMLInputElement>();
|
const fileInputRef = useRef<HTMLInputElement>();
|
||||||
const [isClearConfirmOpen, openClearConfirm, closeClearConfirm] = useFlag(false);
|
const [isClearConfirmOpen, openClearConfirm, closeClearConfirm] = useFlag(false);
|
||||||
|
|
||||||
@ -59,11 +59,16 @@ const SettingsAyuLike = ({
|
|||||||
reader.onload = () => {
|
reader.onload = () => {
|
||||||
try {
|
try {
|
||||||
const imported = importFromAyuGram(JSON.parse(reader.result as string));
|
const imported = importFromAyuGram(JSON.parse(reader.result as string));
|
||||||
setSharedSettingOption({
|
if (imported.length === 0) {
|
||||||
ayuLike: { hideSponsoredMessages, messageFilters: imported },
|
showNotification({ message: 'No valid filter rules found in file' });
|
||||||
});
|
} else {
|
||||||
|
setSharedSettingOption({
|
||||||
|
ayuLike: { hideSponsoredMessages, messageFilters: imported },
|
||||||
|
});
|
||||||
|
showNotification({ message: `Imported ${imported.length} filter rules` });
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Silently ignore malformed files — user will see no change
|
showNotification({ message: 'Invalid file: not a valid AyuGram filter export' });
|
||||||
}
|
}
|
||||||
// Reset so the same file can be re-imported
|
// Reset so the same file can be re-imported
|
||||||
e.target.value = '';
|
e.target.value = '';
|
||||||
|
|||||||
@ -47,16 +47,23 @@ interface AyuGramExport {
|
|||||||
|
|
||||||
export function importFromAyuGram(json: unknown): MessageFilterRule[] {
|
export function importFromAyuGram(json: unknown): MessageFilterRule[] {
|
||||||
const data = json as AyuGramExport;
|
const data = json as AyuGramExport;
|
||||||
if (!Array.isArray(data?.filters)) throw new Error('Invalid AyuGram export format');
|
if (!data || typeof data !== 'object' || !Array.isArray(data.filters)) {
|
||||||
|
throw new Error('Invalid AyuGram export format');
|
||||||
|
}
|
||||||
|
|
||||||
return data.filters.map((f) => ({
|
return data.filters.flatMap((f) => {
|
||||||
id: f.id,
|
if (!f || typeof f !== 'object') return [];
|
||||||
enabled: Boolean(f.enabled),
|
if (typeof f.id !== 'string' || !f.id) return [];
|
||||||
reversed: Boolean(f.reversed),
|
if (typeof f.text !== 'string' || !f.text) return [];
|
||||||
caseInsensitive: Boolean(f.caseInsensitive),
|
return [{
|
||||||
regex: f.text,
|
id: f.id,
|
||||||
chatIds: f.dialogId ? [String(f.dialogId)] : undefined,
|
enabled: Boolean(f.enabled),
|
||||||
}));
|
reversed: Boolean(f.reversed),
|
||||||
|
caseInsensitive: Boolean(f.caseInsensitive),
|
||||||
|
regex: f.text,
|
||||||
|
chatIds: f.dialogId ? [String(f.dialogId)] : undefined,
|
||||||
|
}];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function exportToAyuGram(rules: MessageFilterRule[]): string {
|
export function exportToAyuGram(rules: MessageFilterRule[]): string {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user