Skip to content

Commit 2124aa9

Browse files
committed
Fix blacklist mode logic for event filtering
- Fix backend API communication for blacklist mode - In blacklist mode: selected items are blocked, backend receives inverse (allowed items) - In whitelist mode: selected items are allowed, backend receives them directly - Fix mode switching to preserve blocked items when loading from backend - Add helper functions to calculate inverse kinds for blacklist mode - Ensure core kinds are never blockable in blacklist mode - Add AddKindForm component for dynamic kind addition
1 parent 79d5cd7 commit 2124aa9

6 files changed

Lines changed: 117 additions & 22 deletions

File tree

src/components/relay-settings/layouts/DesktopLayout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export const DesktopLayout: React.FC<DesktopLayoutProps> = ({
9797
onKindsActiveChange,
9898
onKindsChange,
9999
onDynamicKindsChange,
100+
onAddKind,
100101
onRemoveKind,
101102
// Media props
102103
photos,
@@ -171,6 +172,7 @@ export const DesktopLayout: React.FC<DesktopLayoutProps> = ({
171172
onKindsActiveChange={onKindsActiveChange}
172173
onKindsChange={onKindsChange}
173174
onDynamicKindsChange={onDynamicKindsChange}
175+
onAddKind={onAddKind}
174176
onRemoveKind={onRemoveKind}
175177
/>
176178

src/components/relay-settings/layouts/MobileLayout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export const MobileLayout: React.FC<MobileLayoutProps> = ({
9494
onKindsActiveChange,
9595
onKindsChange,
9696
onDynamicKindsChange,
97+
onAddKind,
9798
onRemoveKind,
9899
// Media props
99100
photos,
@@ -162,6 +163,7 @@ export const MobileLayout: React.FC<MobileLayoutProps> = ({
162163
onKindsActiveChange={onKindsActiveChange}
163164
onKindsChange={onKindsChange}
164165
onDynamicKindsChange={onDynamicKindsChange}
166+
onAddKind={onAddKind}
165167
onRemoveKind={onRemoveKind}
166168
/>
167169

src/components/relay-settings/sections/KindsSection/KindsSection.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { BaseSwitch } from '@app/components/common/BaseSwitch/BaseSwitch';
55
import * as S from '@app/pages/uiComponentsPages/UIComponentsPage.styles';
66
import { CollapsibleSection } from '../../shared/CollapsibleSection/CollapsibleSection';
77
import { KindsList } from './components/KindsList';
8+
import { AddKindForm } from './components/AddKindForm';
89
import { DynamicKindsList } from './components/DynamicKindsList';
910

1011
export interface KindsSectionProps {
@@ -16,6 +17,7 @@ export interface KindsSectionProps {
1617
onKindsActiveChange: (active: boolean) => void;
1718
onKindsChange: (values: string[]) => void;
1819
onDynamicKindsChange: (values: string[]) => void;
20+
onAddKind: (kind: string) => void;
1921
onRemoveKind: (kind: string) => void;
2022
}
2123

@@ -28,6 +30,7 @@ export const KindsSection: React.FC<KindsSectionProps> = ({
2830
onKindsActiveChange,
2931
onKindsChange,
3032
onDynamicKindsChange,
33+
onAddKind,
3134
onRemoveKind,
3235
}) => {
3336
const header = mode !== 'whitelist' ? 'Blacklisted Kind Numbers' : 'Kind Numbers';
@@ -54,6 +57,11 @@ export const KindsSection: React.FC<KindsSectionProps> = ({
5457
onKindsChange={onKindsChange}
5558
/>
5659

60+
<AddKindForm
61+
mode={mode}
62+
onAddKind={onAddKind}
63+
/>
64+
5765
<DynamicKindsList
5866
mode={mode}
5967
dynamicKinds={dynamicKinds}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// src/components/relay-settings/sections/KindsSection/components/AddKindForm.tsx
2+
3+
import React, { useState } from 'react';
4+
import { Input } from 'antd';
5+
import { BaseButton } from '@app/components/common/BaseButton/BaseButton';
6+
7+
interface AddKindFormProps {
8+
onAddKind: (kind: string) => void;
9+
mode: string;
10+
}
11+
12+
export const AddKindForm: React.FC<AddKindFormProps> = ({ onAddKind, mode }) => {
13+
const [newKind, setNewKind] = useState('');
14+
15+
const handleAddKind = () => {
16+
if (newKind) {
17+
onAddKind(newKind);
18+
setNewKind('');
19+
}
20+
};
21+
22+
if (mode === 'whitelist') {
23+
return null;
24+
}
25+
26+
return (
27+
<div style={{ padding: '1.5rem 0rem 0rem 0rem', display: 'flex', flexDirection: 'column', gap: '.5rem' }}>
28+
<h3>{'Add to Blacklist'}</h3>
29+
<div style={{ display: 'flex' }} className="custom-checkbox-group grid-checkbox-group large-label">
30+
<Input
31+
value={newKind}
32+
onChange={(e) => setNewKind(e.target.value)}
33+
placeholder="Enter new kind"
34+
/>
35+
<BaseButton onClick={handleAddKind}>
36+
Add Kind
37+
</BaseButton>
38+
</div>
39+
</div>
40+
);
41+
};
42+
43+
export default AddKindForm;

src/constants/coreKinds.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,22 @@ export const ensureCoreKinds = (kindList: string[]): string[] => {
2222
// Helper function to check if a kind is protected
2323
export const isCoreKind = (kind: string): boolean => {
2424
return CORE_KINDS.includes(kind);
25+
};
26+
27+
// Helper function to get all possible kinds from noteOptions
28+
export const getAllPossibleKinds = (): string[] => {
29+
// Import noteOptions dynamically to avoid circular dependency
30+
const { noteOptions } = require('../constants/relaySettings');
31+
return noteOptions.map((option: any) => option.kindString);
32+
};
33+
34+
// Helper function to calculate inverse for blacklist mode
35+
export const calculateInverseKinds = (selectedKinds: string[]): string[] => {
36+
const allPossibleKinds = getAllPossibleKinds();
37+
// In blacklist mode: selected = blocked, so remove selected from all possible kinds
38+
// Core kinds can never be blocked, so they're always in the whitelist
39+
const allowedKinds = allPossibleKinds.filter(kind =>
40+
!selectedKinds.includes(kind) || isCoreKind(kind)
41+
);
42+
return allowedKinds;
2543
};

src/hooks/useRelaySettings.ts

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import config from '@app/config/config';
33
import { readToken } from '@app/services/localStorage.service';
44
import { useHandleLogout } from './authUtils';
55
import { Settings } from '@app/constants/relaySettings';
6-
import { CORE_KINDS, ensureCoreKinds } from '@app/constants/coreKinds';
6+
import { CORE_KINDS, ensureCoreKinds, calculateInverseKinds, getAllPossibleKinds, isCoreKind } from '@app/constants/coreKinds';
77

88
// Legacy interface - no longer used with new API
99
// interface BackendRelaySettings { ... }
@@ -54,25 +54,32 @@ const useRelaySettings = () => {
5454
return;
5555
}
5656

57-
lastMode.current = relaySettings.mode;
58-
59-
if (relaySettings.mode === 'blacklist') {
60-
// Store current settings before clearing
61-
setPreviousSmartSettings({
62-
kinds: relaySettings.kinds,
63-
photos: relaySettings.photos,
64-
videos: relaySettings.videos,
65-
audio: relaySettings.audio,
66-
});
57+
// Only clear arrays when user manually switches TO blacklist mode
58+
// Don't clear if we're in blacklist mode and already have blocked items (loaded from backend)
59+
if (relaySettings.mode === 'blacklist' && lastMode.current === 'whitelist') {
60+
// Only clear if we don't have any blocked items (user switching, not loading from backend)
61+
const hasBlockedItems = relaySettings.kinds.length > 0 || relaySettings.photos.length > 0 ||
62+
relaySettings.videos.length > 0 || relaySettings.audio.length > 0;
63+
64+
if (!hasBlockedItems) {
65+
// Store current settings before clearing
66+
setPreviousSmartSettings({
67+
kinds: relaySettings.kinds,
68+
photos: relaySettings.photos,
69+
videos: relaySettings.videos,
70+
audio: relaySettings.audio,
71+
});
6772

68-
setRelaySettings(prev => ({
69-
...prev,
70-
kinds: [],
71-
photos: [],
72-
videos: [],
73-
audio: [],
74-
}));
75-
} else if (relaySettings.mode === 'whitelist' && previousSmartSettings) {
73+
// Clear selections in blacklist mode - user starts fresh and selects what to block
74+
setRelaySettings(prev => ({
75+
...prev,
76+
kinds: [],
77+
photos: [],
78+
videos: [],
79+
audio: [],
80+
}));
81+
}
82+
} else if (relaySettings.mode === 'whitelist' && lastMode.current === 'blacklist' && previousSmartSettings) {
7683
// Restore previous whitelist mode settings
7784
setRelaySettings(prev => ({
7885
...prev,
@@ -82,6 +89,9 @@ const useRelaySettings = () => {
8289
audio: previousSmartSettings.audio,
8390
}));
8491
}
92+
93+
// Update lastMode after processing
94+
lastMode.current = relaySettings.mode;
8595
}, [relaySettings.mode, previousSmartSettings]);
8696
/* eslint-enable react-hooks/exhaustive-deps */
8797

@@ -97,9 +107,19 @@ const useRelaySettings = () => {
97107
if (backendData.event_filtering) {
98108
settings.mode = backendData.event_filtering.mode || 'whitelist';
99109
settings.moderationMode = backendData.event_filtering.moderation_mode || 'strict';
100-
// Always ensure core kinds are included from backend data
110+
// Handle kinds based on mode
101111
const backendKinds = backendData.event_filtering.kind_whitelist || [];
102-
settings.kinds = ensureCoreKinds(backendKinds);
112+
113+
if (settings.mode === 'blacklist') {
114+
// In blacklist mode: backend sends allowed kinds, we need to calculate blocked kinds
115+
const allPossibleKinds = getAllPossibleKinds();
116+
const blockedKinds = allPossibleKinds.filter(kind => !backendKinds.includes(kind));
117+
// Only show non-core kinds as blocked (core kinds can't be blocked)
118+
settings.kinds = blockedKinds.filter(kind => !isCoreKind(kind));
119+
} else {
120+
// In whitelist mode: backend sends allowed kinds directly
121+
settings.kinds = ensureCoreKinds(backendKinds);
122+
}
103123

104124
// Extract mime types and file sizes from actual backend format
105125
const mediaDefinitions = backendData.event_filtering.media_definitions || {};
@@ -166,7 +186,9 @@ const useRelaySettings = () => {
166186
event_filtering: {
167187
mode: settings.mode,
168188
moderation_mode: settings.moderationMode,
169-
kind_whitelist: ensureCoreKinds(settings.kinds), // Always include core kinds
189+
kind_whitelist: settings.mode === 'blacklist'
190+
? calculateInverseKinds(settings.kinds) // For blacklist: send inverse (all kinds except blocked ones)
191+
: ensureCoreKinds(settings.kinds), // For whitelist: send selected kinds directly
170192
media_definitions: mediaDefinitions,
171193
dynamic_kinds: {
172194
enabled: false,

0 commit comments

Comments
 (0)