Create "save/reset" filter options

merge-requests/3337/head
danidfra 2025-02-28 15:20:53 -03:00
rodzic 89bc1902ed
commit 7d778e40d2
4 zmienionych plików z 59 dodań i 6 usunięć

Wyświetl plik

@ -12,6 +12,7 @@ import {
CreateFilter, CreateFilter,
LanguageFilter, LanguageFilter,
MediaFilter, MediaFilter,
PersistentFilter,
PlatformFilters, PlatformFilters,
ToggleRepliesFilter, ToggleRepliesFilter,
generateFilter, generateFilter,
@ -49,6 +50,8 @@ const ExplorerFilter = () => {
() => { () => {
const value = formatFilters(filters); const value = formatFilters(filters);
sessionStorage.setItem('reduxFilterState', JSON.stringify(filters));
dispatch(changeSearch(value)); dispatch(changeSearch(value));
dispatch(submitSearch(undefined, value)); dispatch(submitSearch(undefined, value));
}, [filters, dispatch], }, [filters, dispatch],
@ -83,7 +86,6 @@ const ExplorerFilter = () => {
{/* Media toggle */} {/* Media toggle */}
<MediaFilter /> <MediaFilter />
{/* Language */} {/* Language */}
<LanguageFilter /> <LanguageFilter />
@ -95,6 +97,10 @@ const ExplorerFilter = () => {
{/* Create your filter */} {/* Create your filter */}
<CreateFilter /> <CreateFilter />
<Divider />
{/* Reset your filters */}
<PersistentFilter />
</Stack> </Stack>
</Stack> </Stack>

Wyświetl plik

@ -17,7 +17,7 @@ import { IGenerateFilter } from 'soapbox/features/explorer/components/explorerFi
import { SelectDropdown } from 'soapbox/features/forms/index.tsx'; import { SelectDropdown } from 'soapbox/features/forms/index.tsx';
import { useAppDispatch } from 'soapbox/hooks/useAppDispatch.ts'; import { useAppDispatch } from 'soapbox/hooks/useAppDispatch.ts';
import { useAppSelector } from 'soapbox/hooks/useAppSelector.ts'; import { useAppSelector } from 'soapbox/hooks/useAppSelector.ts';
import { changeStatus, changeLanguage, changeMedia, createFilter, removeFilter, selectProtocol } from 'soapbox/reducers/search-filter.ts'; import { changeStatus, changeLanguage, changeMedia, createFilter, removeFilter, selectProtocol, resetFilters } from 'soapbox/reducers/search-filter.ts';
import { AppDispatch, RootState } from 'soapbox/store.ts'; import { AppDispatch, RootState } from 'soapbox/store.ts';
import toast from 'soapbox/toast.tsx'; import toast from 'soapbox/toast.tsx';
@ -27,6 +27,7 @@ const messages = defineMessages({
language: { id: 'column.explorer.filters.language', defaultMessage: 'Language:' }, language: { id: 'column.explorer.filters.language', defaultMessage: 'Language:' },
platforms: { id: 'column.explorer.filters.platforms', defaultMessage: 'Platforms:' }, platforms: { id: 'column.explorer.filters.platforms', defaultMessage: 'Platforms:' },
createYourFilter: { id: 'column.explorer.filters.create_your_filter', defaultMessage: 'Create your filter' }, createYourFilter: { id: 'column.explorer.filters.create_your_filter', defaultMessage: 'Create your filter' },
filterPersistence: { id: 'column.explorer.filters.filter_persistence', defaultMessage: 'Filter persistence:' },
filterByWords: { id: 'column.explorer.filters.filter_by_words', defaultMessage: 'Filter by this/these words' }, filterByWords: { id: 'column.explorer.filters.filter_by_words', defaultMessage: 'Filter by this/these words' },
include: { id: 'column.explorer.filters.include', defaultMessage: 'Include' }, include: { id: 'column.explorer.filters.include', defaultMessage: 'Include' },
exclude: { id: 'column.explorer.filters.exclude', defaultMessage: 'Exclude' }, exclude: { id: 'column.explorer.filters.exclude', defaultMessage: 'Exclude' },
@ -163,6 +164,38 @@ const PlatformFilters = () => {
}; };
const PersistentFilter = () => {
const intl = useIntl();
const dispatch = useAppDispatch();
const filters = useAppSelector((state) => state.search_filter);
const handleSalveFilter = () => {
localStorage.setItem('reduxFilterState', JSON.stringify(filters));
};
const handleReset = () => {
dispatch(resetFilters());
localStorage.removeItem('reduxFilterState');
};
return (
<HStack alignItems='center' space={2}>
<Text size='md' weight='bold'>
{intl.formatMessage(messages.filterPersistence)}
</Text>
<HStack alignItems='center' space={2} grow className='p-1'>
<Button text='Reset Filters' className='w-full' theme='tertiary' onClick={handleReset} />
<Button text='Save Filters' className='w-full' theme='primary' onClick={handleSalveFilter} />
</HStack>
</HStack>
);
};
const CreateFilter = () => { const CreateFilter = () => {
const intl = useIntl(); const intl = useIntl();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@ -193,7 +226,7 @@ const CreateFilter = () => {
<HStack space={6}> <HStack space={6}>
<div className='relative w-full items-center'> <div className='relative w-full items-center p-0.5'>
<Input theme='search' value={inputValue} className='h-9' onChange={(e) => setInputValue(e.target.value)} /> <Input theme='search' value={inputValue} className='h-9' onChange={(e) => setInputValue(e.target.value)} />
<div <div
role='button' role='button'
@ -246,7 +279,7 @@ const CreateFilter = () => {
<HStack className='w-full p-0.5' space={2}> <HStack className='w-full p-0.5' space={2}>
<Button <Button
className='w-1/2' theme='secondary' onClick={() => { className='w-1/2' theme='muted' onClick={() => {
setInclude(false); setInclude(false);
setInputValue(''); setInputValue('');
} }
@ -255,7 +288,7 @@ const CreateFilter = () => {
{intl.formatMessage(messages.cancel)} {intl.formatMessage(messages.cancel)}
</Button> </Button>
<Button className='w-1/2' theme='primary' onClick={handleAddFilter}> <Button className='w-1/2' theme='secondary' onClick={handleAddFilter}>
{intl.formatMessage(messages.addFilter)} {intl.formatMessage(messages.addFilter)}
</Button> </Button>
</HStack> </HStack>
@ -427,4 +460,4 @@ const generateFilter = (dispatch: AppDispatch, { name, status }: IGenerateFilter
); );
}; };
export { CreateFilter, PlatformFilters, MediaFilter, LanguageFilter, ToggleRepliesFilter, generateFilter }; export { CreateFilter, PersistentFilter, PlatformFilters, MediaFilter, LanguageFilter, ToggleRepliesFilter, generateFilter };

Wyświetl plik

@ -378,6 +378,7 @@
"column.explorer.filters.exclude": "Exclude", "column.explorer.filters.exclude": "Exclude",
"column.explorer.filters.fediverse": "Fediverse", "column.explorer.filters.fediverse": "Fediverse",
"column.explorer.filters.filter_by_words": "Filter by this/these words", "column.explorer.filters.filter_by_words": "Filter by this/these words",
"column.explorer.filters.filter_persistence": "Filter persistence:",
"column.explorer.filters.include": "Include", "column.explorer.filters.include": "Include",
"column.explorer.filters.language": "Language:", "column.explorer.filters.language": "Language:",
"column.explorer.filters.language.default": "Global", "column.explorer.filters.language.default": "Global",

Wyświetl plik

@ -7,8 +7,21 @@ import appReducer from './reducers/index.ts';
import type { AnyAction } from 'redux'; import type { AnyAction } from 'redux';
const loadState = () => {
try {
const savedState = localStorage.getItem('reduxFilterState');
return savedState ? JSON.parse(savedState) : undefined;
} catch (error) {
console.error('Failed to load state:', error);
return undefined;
}
};
const preloadedState = { ...loadState() ? { search_filter: loadState() } : {} };
export const store = configureStore({ export const store = configureStore({
reducer: appReducer, reducer: appReducer,
preloadedState,
middleware: () => new Tuple( middleware: () => new Tuple(
thunk, thunk,
errorsMiddleware(), errorsMiddleware(),