Remove search bar and "improve" search in "posts"

merge-requests/3337/head
danidfra 2025-02-28 20:12:47 -03:00
rodzic 7d778e40d2
commit 0962a018c1
4 zmienionych plików z 56 dodań i 61 usunięć

Wyświetl plik

@ -4,8 +4,7 @@ import { useState } from 'react';
import HStack from 'soapbox/components/ui/hstack.tsx';
import SvgIcon from 'soapbox/components/ui/svg-icon.tsx';
import Text from 'soapbox/components/ui/text.tsx';
import Search from 'soapbox/features/compose/components/search.tsx';
import { useIsMobile } from 'soapbox/hooks/useIsMobile.ts';
interface TabItem {
name: string;
@ -24,11 +23,8 @@ interface TabsProps {
*/
const ExplorerTabs: React.FC<TabsProps> = ({ items, activeItem }) => {
const [activeTab, setActiveTab] = useState(activeItem || items[0].name);
const [lastSelected, setLastSelected] = useState('');
const isMobile = useIsMobile();
const handleTabClick = (name: string) => {
setLastSelected(activeTab);
setActiveTab(name);
const activeItem = items.find(item => item.name === name);
if (activeItem && typeof activeItem.action === 'function') {
@ -39,47 +35,38 @@ const ExplorerTabs: React.FC<TabsProps> = ({ items, activeItem }) => {
return (
<HStack className='inset-x-0 bottom-4 z-[999] w-full p-2' alignItems='center' justifyContent='center'>
{/* Header */}
<HStack space={1} className='w-full rounded-full bg-gray-200/60 p-1.5 dark:bg-gray-800' justifyContent='around'>
<HStack space={1} className='w-full rounded-full bg-gray-200/60 p-1 dark:bg-gray-800' justifyContent='around'>
{items.map(({ name, label, icon }) => {
const isSelected = activeTab === name;
const shouldKeepBg = lastSelected === name && activeTab === 'search';
return (
<HStack key={name} alignItems='center' justifyContent='center'>
{name === 'search' && isSelected ? (
<Search autoSubmit />
) : (
<HStack
space={1}
alignItems='center'
justifyContent='center'
onClick={() => handleTabClick(name)}
/* eslint-disable-next-line tailwindcss/no-custom-classname */
className={clsx(
'group cursor-pointer rounded-full px-5 py-3 text-sm font-medium transition-all duration-300',
isSelected || shouldKeepBg
? 'border-gray-500 bg-gray-500 text-white shadow-md dark:border-gray-700 dark:bg-gray-700'
: 'dark:hover:bg-gray-800/200 text-gray-500 hover:bg-gray-400/60 hover:!text-white',
{ '!p-2': shouldKeepBg },
)}
<HStack
space={1}
alignItems='center'
justifyContent='center'
onClick={() => handleTabClick(name)}
/* eslint-disable-next-line tailwindcss/no-custom-classname */
className={clsx(
'group cursor-pointer rounded-full px-5 py-3 text-sm font-medium transition-all duration-300',
isSelected
? 'border-gray-500 bg-gray-500 text-white shadow-md dark:border-gray-700 dark:bg-gray-700'
: 'dark:hover:bg-gray-800/200 text-gray-500 hover:bg-gray-400/60 hover:!text-white',
)}
>
<SvgIcon
src={icon}
className='size-5 '
/>
<Text
className={clsx('transition-all duration-300', {
'!text-gray-500 group-hover:!text-white': !isSelected,
'!text-white': isSelected,
})}
>
<SvgIcon
src={icon}
className='size-5 '
/>
{(activeTab !== 'search' || isSelected) &&
(isMobile ? isSelected : !isMobile) && (
<Text
className={clsx('transition-all duration-300', {
'!text-gray-500 group-hover:!text-white': !isSelected,
'!text-white': isSelected || shouldKeepBg,
})}
>
{label}
</Text>
)}
</HStack>
)}
{label}
</Text>
</HStack>
</HStack>
);
})}

Wyświetl plik

@ -1,5 +1,4 @@
import globeIcon from '@tabler/icons/outline/globe.svg';
import searchIcon from '@tabler/icons/outline/search.svg';
import trendIcon from '@tabler/icons/outline/trending-up.svg';
import userIcon from '@tabler/icons/outline/user.svg';
import xIcon from '@tabler/icons/outline/x.svg';
@ -34,26 +33,29 @@ import PublicTimeline from 'soapbox/features/public-timeline/index.tsx';
import { useAppDispatch } from 'soapbox/hooks/useAppDispatch.ts';
import { useAppSelector } from 'soapbox/hooks/useAppSelector.ts';
import { useSuggestions } from 'soapbox/queries/suggestions.ts';
import { initialState as filterInitialState } from 'soapbox/reducers/search-filter.ts';
import { SearchFilter } from 'soapbox/reducers/search.ts';
import type { OrderedSet as ImmutableOrderedSet } from 'immutable';
import type { VirtuosoHandle } from 'react-virtuoso';
const messages = defineMessages({
accounts: { id: 'search_results.posts', defaultMessage: 'Accounts' },
statuses: { id: 'search_results.accounts', defaultMessage: 'Posts' },
accounts: { id: 'search_results.accounts', defaultMessage: 'Accounts' },
statuses: { id: 'search_results.posts', defaultMessage: 'Posts' },
trends: { id: 'search_results.trends', defaultMessage: 'Trends' },
search: { id: 'common.search', defaultMessage: 'Search' },
});
const SearchResults = () => {
const node = useRef<VirtuosoHandle>(null);
const filters = useAppSelector((state) => state.search_filter);
const intl = useIntl();
const dispatch = useAppDispatch();
const { data: suggestions } = useSuggestions();
const [globalTimeline, setGlobalTimeline] = useState(true);
const [withFilter, setWithFilter] = useState(false);
const [tab, setTab] = useState('global');
const value = useAppSelector((state) => state.search.submittedValue);
const results = useAppSelector((state) => state.search.results);
@ -74,9 +76,9 @@ const SearchResults = () => {
};
const handleUnsetAccount = () => dispatch(setSearchAccount(null));
const handleAction = (filter: SearchFilter) =>{
setGlobalTimeline(false);
const handleAction = (filter: SearchFilter, tab: string) =>{
selectFilter(filter);
setTab(tab);
};
const selectFilter = (newActiveFilter: SearchFilter) => dispatch(setFilter(newActiveFilter));
@ -86,31 +88,26 @@ const SearchResults = () => {
items.push(
{
label: intl.formatMessage(messages.statuses),
action: () => setGlobalTimeline(true),
name: 'statuses',
action: () => handleAction('statuses', 'global'),
name: 'global',
icon: globeIcon,
},
{
label: intl.formatMessage(messages.trends),
action: () => handleAction('statuses'),
name: 'trends',
action: () => handleAction('statuses', 'statuses'),
name: 'statuses',
icon: trendIcon,
},
// TODO : limit search accounts to only be able use include
{
label: intl.formatMessage(messages.accounts),
action: () => handleAction('accounts'),
action: () => handleAction('accounts', 'accounts'),
name: 'accounts',
icon: userIcon,
},
{
label: intl.formatMessage(messages.search),
action: () => null,
name: 'search',
icon: searchIcon,
},
);
return <ExplorerTabs items={items} activeItem={selectedFilter} />;
return <ExplorerTabs items={items} activeItem={tab} />;
};
const getCurrentIndex = (id: string): number => {
@ -146,6 +143,16 @@ const SearchResults = () => {
dispatch(fetchTrendingStatuses());
}, []);
useEffect(() => {
setWithFilter(filters.length !== filterInitialState.length ||
!filters.every((filter, index) =>
filter.name === filterInitialState[index].name &&
filter.status === filterInitialState[index].status &&
filter.value === filterInitialState[index].value,
),
);
}, [filters]);
let searchResults;
let hasMore = false;
let loaded;
@ -257,7 +264,7 @@ const SearchResults = () => {
</div>
)}
{globalTimeline ? <PublicTimeline /> : (noResultsMessage || (
{tab === 'global' && !withFilter ? <PublicTimeline /> : (noResultsMessage || (
<ScrollableList
id='search-results'
ref={node}

Wyświetl plik

@ -1447,9 +1447,9 @@
"scheduled_status.cancel": "Cancel",
"search.action": "Search for “{query}”",
"search.placeholder": "Search",
"search_results.accounts": "Posts",
"search_results.accounts": "Accounts",
"search_results.filter_message": "You are searching for posts from @{acct}.",
"search_results.posts": "Accounts",
"search_results.posts": "Posts",
"search_results.trends": "Trends",
"security.codes.fail": "Failed to fetch backup codes",
"security.confirm.fail": "Incorrect code or password. Try again.",

Wyświetl plik

@ -144,5 +144,6 @@ const search_filter = createSlice({
});
export type { IFilters };
export { initialState };
export const { changeStatus, changeMedia, changeLanguage, selectProtocol, createFilter, removeFilter, resetFilters } = search_filter.actions;
export default search_filter.reducer;