mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-06-30 12:33:31 +00:00
[MOB-99] Job remove & more (#2514)
* Clear job and improve job manager design * pullToRefresh, search adjustment, and more * ts * use rspc instead of query client * Update JobManagerModal.tsx
This commit is contained in:
parent
d64b21357b
commit
530e3c8ac8
|
@ -25,6 +25,7 @@ const SortByMenu = () => {
|
|||
return (
|
||||
<View style={tw`flex-row items-center gap-1.5`}>
|
||||
<Menu
|
||||
containerStyle={tw`max-w-44`}
|
||||
trigger={<Trigger activeOption={sortOptions[searchStore.sort.by]} />}
|
||||
|
||||
>
|
||||
|
@ -40,6 +41,7 @@ const SortByMenu = () => {
|
|||
))}
|
||||
</Menu>
|
||||
<Menu
|
||||
containerStyle={tw`max-w-40`}
|
||||
trigger={<Trigger
|
||||
triggerIcon={searchStore.sort.direction === 'Asc' ? ArrowUpIcon : ArrowDownIcon}
|
||||
activeOption={searchStore.sort.direction}
|
||||
|
|
|
@ -48,7 +48,7 @@ export default function Header({ route, navBack, title, search = false }: Props)
|
|||
}}
|
||||
>
|
||||
<MagnifyingGlass
|
||||
size={24}
|
||||
size={20}
|
||||
weight="bold"
|
||||
color={tw.color('text-zinc-300')}
|
||||
/>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { TextItems } from '@sd/client';
|
||||
import { Image } from 'expo-image';
|
||||
import { Icon } from 'phosphor-react-native';
|
||||
import { Fragment } from 'react';
|
||||
import { Text, View, ViewStyle } from 'react-native';
|
||||
import { TextItems } from '@sd/client';
|
||||
import { styled, tw, twStyle } from '~/lib/tailwind';
|
||||
|
||||
type JobContainerProps = {
|
||||
|
@ -25,7 +25,7 @@ export default function JobContainer(props: JobContainerProps) {
|
|||
<View
|
||||
style={twStyle(
|
||||
'flex flex-row justify-center',
|
||||
'border-b border-app-line/50 px-8 py-4',
|
||||
'border-b border-app-line/30 px-8 py-4',
|
||||
isChild && 'my-1.5 border-b-0 p-2 pl-12',
|
||||
restProps.containerStyle
|
||||
)}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import { Folder } from '@sd/assets/icons';
|
||||
import dayjs from 'dayjs';
|
||||
import { DotsThreeVertical, Pause, Play, Stop } from 'phosphor-react-native';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { Animated, Pressable, View } from 'react-native';
|
||||
import { Swipeable } from 'react-native-gesture-handler';
|
||||
import {
|
||||
getJobNiceActionName,
|
||||
getTotalTasks,
|
||||
|
@ -11,13 +6,20 @@ import {
|
|||
JobProgressEvent,
|
||||
JobReport,
|
||||
useLibraryMutation,
|
||||
useRspcLibraryContext,
|
||||
useTotalElapsedTimeText
|
||||
} from '@sd/client';
|
||||
import { tw } from '~/lib/tailwind';
|
||||
import dayjs from 'dayjs';
|
||||
import { DotsThreeVertical, Eye, Pause, Play, Stop, Trash } from 'phosphor-react-native';
|
||||
import { SetStateAction, useMemo, useState } from 'react';
|
||||
import { Animated, Pressable, View } from 'react-native';
|
||||
import { Swipeable } from 'react-native-gesture-handler';
|
||||
import { tw, twStyle } from '~/lib/tailwind';
|
||||
|
||||
import { AnimatedHeight } from '../animation/layout';
|
||||
import { ProgressBar } from '../animation/ProgressBar';
|
||||
import { Button } from '../primitive/Button';
|
||||
import { Menu, MenuItem } from '../primitive/Menu';
|
||||
import { toast } from '../primitive/Toast';
|
||||
import Job from './Job';
|
||||
import JobContainer from './JobContainer';
|
||||
|
@ -58,11 +60,11 @@ export default function ({ group, progress }: JobGroupProps) {
|
|||
return (
|
||||
<Animated.View
|
||||
style={[
|
||||
tw`flex flex-row items-center pr-4`,
|
||||
tw`mt-5 flex flex-row items-start pr-4`,
|
||||
{ transform: [{ translateX: translate }] }
|
||||
]}
|
||||
>
|
||||
<Options activeJob={runningJob} group={group} />
|
||||
<Options showChildJobs={showChildJobs} setShowChildJobs={setShowChildJobs} activeJob={runningJob} group={group} />
|
||||
</Animated.View>
|
||||
);
|
||||
};
|
||||
|
@ -158,8 +160,23 @@ const toastErrorSuccess = (
|
|||
};
|
||||
};
|
||||
|
||||
function Options({ activeJob, group }: { activeJob?: JobReport; group: JobGroup }) {
|
||||
// const queryClient = useQueryClient();
|
||||
interface OptionsProps {
|
||||
activeJob?: JobReport;
|
||||
group: JobGroup;
|
||||
showChildJobs: boolean;
|
||||
setShowChildJobs: React.Dispatch<SetStateAction<boolean>>
|
||||
}
|
||||
|
||||
function Options({ activeJob, group, setShowChildJobs, showChildJobs }: OptionsProps) {
|
||||
|
||||
const rspc = useRspcLibraryContext();
|
||||
|
||||
const clearJob = useLibraryMutation(
|
||||
['jobs.clear'], {
|
||||
onSuccess: () => {
|
||||
rspc.queryClient.invalidateQueries(['jobs.reports']);
|
||||
}
|
||||
})
|
||||
|
||||
const resumeJob = useLibraryMutation(
|
||||
['jobs.resume'],
|
||||
|
@ -179,32 +196,45 @@ function Options({ activeJob, group }: { activeJob?: JobReport; group: JobGroup
|
|||
[group.jobs]
|
||||
);
|
||||
|
||||
// const clearJob = useLibraryMutation(
|
||||
// ['jobs.clear'],
|
||||
// toastErrorSuccess('failed_to_remove_job', undefined, () => {
|
||||
// queryClient.invalidateQueries(['jobs.reports']);
|
||||
// })
|
||||
// );
|
||||
const clearJobHandler = () => {
|
||||
group.jobs.forEach((job) => {
|
||||
clearJob.mutate(job.id);
|
||||
//only one toast for all jobs
|
||||
if (job.id === group.id)
|
||||
toast.success('Job has been removed');
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Resume */}
|
||||
{(group.status === 'Queued' || group.status === 'Paused' || isJobPaused) && (
|
||||
<Button variant="outline" size="sm" onPress={() => resumeJob.mutate(group.id)}>
|
||||
<Play size={18} color="white" />
|
||||
<Button style={tw`h-7 w-7`} variant="outline" size="sm" onPress={() => resumeJob.mutate(group.id)}>
|
||||
<Play size={16} color="white" />
|
||||
</Button>
|
||||
)}
|
||||
{/* TODO: This should remove the job from panel */}
|
||||
{!activeJob !== undefined ? (
|
||||
<Button variant="outline" size="sm">
|
||||
<Menu
|
||||
containerStyle={tw`max-w-25`}
|
||||
trigger={
|
||||
<View style={tw`flex h-7 w-7 flex-row items-center justify-center rounded-md border border-app-inputborder`}>
|
||||
<DotsThreeVertical size={16} color="white" />
|
||||
</Button>
|
||||
</View>
|
||||
}
|
||||
>
|
||||
<MenuItem
|
||||
style={twStyle(showChildJobs ? 'rounded bg-app-screen/50' : 'bg-transparent')}
|
||||
onSelect={() => setShowChildJobs(!showChildJobs)}
|
||||
text="Expand" icon={Eye}/>
|
||||
<MenuItem onSelect={clearJobHandler} text='Remove' icon={Trash}/>
|
||||
</Menu>
|
||||
) : (
|
||||
<View style={tw`flex flex-row gap-2`}>
|
||||
<Button variant="outline" size="sm" onPress={() => pauseJob.mutate(group.id)}>
|
||||
<Button style={tw`h-7 w-7`} variant="outline" size="sm" onPress={() => pauseJob.mutate(group.id)}>
|
||||
<Pause size={16} color="white" />
|
||||
</Button>
|
||||
<Button variant="outline" size="sm" onPress={() => cancelJob.mutate(group.id)}>
|
||||
<Button style={tw`h-7 w-7`} variant="outline" size="sm" onPress={() => cancelJob.mutate(group.id)}>
|
||||
<Stop size={16} color="white" />
|
||||
</Button>
|
||||
</View>
|
||||
|
|
|
@ -7,14 +7,14 @@ import { Icon, IconName } from '../icons/Icon';
|
|||
|
||||
interface Props {
|
||||
description: string; //description of empty state
|
||||
icon: IconName; //Spacedrive icon
|
||||
icon?: IconName; //Spacedrive icon
|
||||
style?: ClassInput; //Tailwind classes
|
||||
iconSize?: number; //Size of the icon
|
||||
textSize?: ClassInput; //Size of the text
|
||||
textStyle?: ClassInput; //Size of the text
|
||||
includeHeaderHeight?: boolean; //Height of the header
|
||||
}
|
||||
|
||||
const Empty = ({ description, icon, style, includeHeaderHeight = false, textSize = 'text-sm', iconSize = 38 }: Props) => {
|
||||
const Empty = ({ description, icon, style, includeHeaderHeight = false, textStyle, iconSize = 38 }: Props) => {
|
||||
const headerHeight = useSafeAreaInsets().top;
|
||||
return (
|
||||
<View
|
||||
|
@ -25,8 +25,8 @@ const Empty = ({ description, icon, style, includeHeaderHeight = false, textSize
|
|||
style
|
||||
)}
|
||||
>
|
||||
<Icon name={icon} size={iconSize} />
|
||||
<Text style={twStyle(`mt-2 text-center font-medium text-ink-dull`, textSize)}>
|
||||
{icon && <Icon name={icon} size={iconSize} />}
|
||||
<Text style={twStyle(`mt-2 text-center text-sm font-medium text-ink-dull`, textStyle)}>
|
||||
{description}
|
||||
</Text>
|
||||
</View>
|
||||
|
|
|
@ -20,7 +20,7 @@ const GridLocation: React.FC<GridLocationProps> = ({ location, modalRef }: GridL
|
|||
<View style={tw`w-full flex-col justify-between gap-1`}>
|
||||
<View style={tw`flex-row items-center justify-between`}>
|
||||
<View style={tw`relative`}>
|
||||
<FolderIcon size={42} />
|
||||
<FolderIcon size={36} />
|
||||
<View
|
||||
style={twStyle(
|
||||
'z-5 absolute bottom-[6px] right-[2px] h-2 w-2 rounded-full',
|
||||
|
|
|
@ -27,6 +27,8 @@ const ImportModal = forwardRef<ModalRef, unknown>((_, ref) => {
|
|||
//custom message handling
|
||||
if (error.message.startsWith("location already exists")) {
|
||||
return toast.error('This location has already been added');
|
||||
} else if (error.message.startsWith("nested location currently")) {
|
||||
return toast.error('Nested locations are currently not supported');
|
||||
}
|
||||
switch (error.message) {
|
||||
case 'NEED_RELINK':
|
||||
|
|
|
@ -1,40 +1,51 @@
|
|||
import { forwardRef } from 'react';
|
||||
import { FlatList, Text, View } from 'react-native';
|
||||
import { BottomSheetFlatList } from '@gorhom/bottom-sheet';
|
||||
import { useJobProgress, useLibraryQuery } from '@sd/client';
|
||||
import { forwardRef, useEffect } from 'react';
|
||||
import JobGroup from '~/components/job/JobGroup';
|
||||
import Empty from '~/components/layout/Empty';
|
||||
import { Modal, ModalRef } from '~/components/layout/Modal';
|
||||
import useForwardedRef from '~/hooks/useForwardedRef';
|
||||
import { tw } from '~/lib/tailwind';
|
||||
|
||||
// TODO:
|
||||
// - When there is no job, make modal height smaller
|
||||
// - Add clear all jobs button
|
||||
//TODO: Handle data fetching better when modal is opened
|
||||
|
||||
export const JobManagerModal = forwardRef<ModalRef, unknown>((_, ref) => {
|
||||
// const queryClient = useQueryClient();
|
||||
|
||||
// const rspc = useRspcLibraryContext();
|
||||
const jobGroups = useLibraryQuery(['jobs.reports']);
|
||||
const progress = useJobProgress(jobGroups.data);
|
||||
const modalRef = useForwardedRef(ref);
|
||||
|
||||
//TODO: Add clear all jobs button
|
||||
// const clearAllJobs = useLibraryMutation(['jobs.clearAll'], {
|
||||
// onError: () => {
|
||||
// // TODO: Show error toast
|
||||
// toast.error('Failed to clear all jobs.');
|
||||
// },
|
||||
// onSuccess: () => {
|
||||
// queryClient.invalidateQueries(['jobs.reports ']);
|
||||
// }
|
||||
// });
|
||||
|
||||
useEffect(() => {
|
||||
if (jobGroups.data?.length === 0) {
|
||||
modalRef.current?.snapToPosition('20');
|
||||
}
|
||||
}, [jobGroups, modalRef]);
|
||||
|
||||
return (
|
||||
<Modal ref={ref} snapPoints={['60']} title="Recent Jobs" showCloseButton>
|
||||
<FlatList
|
||||
<Modal
|
||||
ref={modalRef}
|
||||
snapPoints={['60']}
|
||||
title="Recent Jobs"
|
||||
showCloseButton
|
||||
>
|
||||
<BottomSheetFlatList
|
||||
data={jobGroups.data}
|
||||
style={tw`flex-1`}
|
||||
keyExtractor={(i) => i.id}
|
||||
contentContainerStyle={tw`mt-4`}
|
||||
renderItem={({ item }) => <JobGroup group={item} progress={progress} />}
|
||||
ListEmptyComponent={
|
||||
<View style={tw`flex h-60 items-center justify-center`}>
|
||||
<Text style={tw`text-center text-base text-ink-dull`}>No jobs.</Text>
|
||||
</View>
|
||||
<Empty style="border-0" description='No jobs.'/>
|
||||
}
|
||||
/>
|
||||
</Modal>
|
||||
|
|
|
@ -11,8 +11,8 @@ const button = cva(['items-center justify-center rounded-md border shadow-sm'],
|
|||
gray: ['border-app-box bg-app shadow-none'],
|
||||
darkgray: ['border-app-box bg-app shadow-none'],
|
||||
accent: ['border-accent-deep bg-accent shadow-md shadow-app-shade/10'],
|
||||
outline: ['border-app-lightborder bg-black shadow-none'],
|
||||
transparent: ['border-0 bg-black shadow-none'],
|
||||
outline: ['border border-app-inputborder bg-transparent shadow-none'],
|
||||
transparent: ['border-0 bg-transparent shadow-none'],
|
||||
dashed: ['border border-dashed border-app-line bg-transparent shadow-none']
|
||||
},
|
||||
size: {
|
||||
|
|
|
@ -14,13 +14,14 @@ type MenuProps = {
|
|||
trigger: React.ReactNode;
|
||||
children: React.ReactNode[] | React.ReactNode;
|
||||
triggerStyle?: ClassInput;
|
||||
containerStyle?: ClassInput;
|
||||
};
|
||||
|
||||
// TODO: Still looks a bit off...
|
||||
export const Menu = (props: MenuProps) => (
|
||||
<PMenu style={twStyle(props.triggerStyle)}>
|
||||
<MenuTrigger>{props.trigger}</MenuTrigger>
|
||||
<MenuOptions optionsContainerStyle={tw`rounded-md border border-app-cardborder bg-app-menu p-1`}>
|
||||
<MenuOptions optionsContainerStyle={twStyle(`rounded-md border border-app-cardborder bg-app-menu p-1`, props.containerStyle)}>
|
||||
{props.children}
|
||||
</MenuOptions>
|
||||
</PMenu>
|
||||
|
@ -28,24 +29,25 @@ export const Menu = (props: MenuProps) => (
|
|||
|
||||
type MenuItemProps = {
|
||||
icon?: Icon;
|
||||
textStyle?: ClassInput;
|
||||
iconStyle?: ClassInput;
|
||||
style?: ClassInput;
|
||||
} & MenuOptionProps;
|
||||
|
||||
export const MenuItem = ({ icon, ...props }: MenuItemProps) => {
|
||||
export const MenuItem = ({ icon, textStyle, iconStyle, style, ...props }: MenuItemProps) => {
|
||||
const Icon = icon;
|
||||
|
||||
return (
|
||||
<View style={tw`flex flex-1 flex-row items-center`}>
|
||||
<View style={twStyle(`flex-1 flex-row items-center px-2 py-1`, style)}>
|
||||
{Icon && (
|
||||
<View style={tw`ml-1`}>
|
||||
<Icon size={16} style={tw`text-ink`} />
|
||||
</View>
|
||||
<Icon size={14} style={twStyle(`text-ink-dull`, iconStyle)} />
|
||||
)}
|
||||
<MenuOption
|
||||
{...props}
|
||||
customStyles={{
|
||||
optionText: tw`w-full py-1 text-sm font-medium text-ink`
|
||||
optionText: twStyle(`text-sm font-medium text-ink-dull`, textStyle)
|
||||
}}
|
||||
style={tw`flex flex-row items-center`}
|
||||
style={tw`flex flex-row`}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
|
|
@ -5,13 +5,13 @@ import Toast, { ToastConfig } from 'react-native-toast-message';
|
|||
import { tw } from '~/lib/tailwind';
|
||||
|
||||
const baseStyles = 'max-w-[340px] flex-row gap-1 items-center justify-center overflow-hidden rounded-md border p-3 shadow-lg bg-app-input border-app-inputborder';
|
||||
const containerStyle = 'flex-row items-start gap-2'
|
||||
const containerStyle = 'flex-row items-start gap-1.5'
|
||||
|
||||
const toastConfig: ToastConfig = {
|
||||
success: ({ text1, ...rest }) => (
|
||||
<View style={tw.style(baseStyles)}>
|
||||
<View style={tw.style(containerStyle)}>
|
||||
<CheckCircle size={24} weight="fill" color={tw.color("text-green-500")} />
|
||||
<CheckCircle size={20} weight="fill" color={tw.color("text-green-500")} />
|
||||
<Text style={tw`self-center text-left text-sm font-medium text-ink`} numberOfLines={3}>
|
||||
{text1}
|
||||
</Text>
|
||||
|
@ -21,7 +21,7 @@ const toastConfig: ToastConfig = {
|
|||
error: ({ text1, ...rest }) => (
|
||||
<View style={tw.style(baseStyles)}>
|
||||
<View style={tw.style(containerStyle)}>
|
||||
<WarningCircle size={24} weight="fill" color={tw.color("text-red-500")} />
|
||||
<WarningCircle size={20} weight="fill" color={tw.color("text-red-500")} />
|
||||
<Text style={tw`self-center text-left text-sm font-medium text-ink`} numberOfLines={3}>
|
||||
{text1}
|
||||
</Text>
|
||||
|
@ -31,7 +31,7 @@ const toastConfig: ToastConfig = {
|
|||
info: ({ text1, ...rest }) => (
|
||||
<View style={tw.style(baseStyles)}>
|
||||
<View style={tw.style(containerStyle)}>
|
||||
<Info size={24} weight="fill" color={tw.color("text-accent")} />
|
||||
<Info size={20} weight="fill" color={tw.color("text-accent")} />
|
||||
<Text style={tw`self-center text-left text-sm font-medium text-ink`} numberOfLines={3}>
|
||||
{text1}
|
||||
</Text>
|
||||
|
|
|
@ -79,7 +79,7 @@ module.exports = {
|
|||
// shadow
|
||||
shade: `hsla(${DARK_HUE}, 15%, 0%, ${ALPHA})`,
|
||||
// menu
|
||||
menu: `hsla(${DARK_HUE}, 25%, 5%, ${ALPHA})`
|
||||
menu: `hsla(${DARK_HUE}, 10%, 5%, ${ALPHA})`
|
||||
},
|
||||
sidebar: {
|
||||
box: `hsla(${DARK_HUE}, 15%, 16%, ${ALPHA})`,
|
||||
|
|
|
@ -17,7 +17,6 @@ export function useFiltersSearch(search: string) {
|
|||
|
||||
const locations = useLibraryQuery(['locations.list'], {
|
||||
keepPreviousData: true,
|
||||
enabled: (name || ext) ? true : false,
|
||||
});
|
||||
|
||||
const filterFactory = (key: SearchFilters, value: Filters[keyof Filters]) => {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import BrowseCategories from '~/components/browse/BrowseCategories';
|
||||
import BrowseLocations from '~/components/browse/BrowseLocations';
|
||||
import BrowseTags from '~/components/browse/BrowseTags';
|
||||
import ScreenContainer from '~/components/layout/ScreenContainer';
|
||||
|
@ -6,7 +5,7 @@ import ScreenContainer from '~/components/layout/ScreenContainer';
|
|||
export default function BrowseScreen() {
|
||||
return (
|
||||
<ScreenContainer>
|
||||
<BrowseCategories />
|
||||
{/* <BrowseCategories /> */}
|
||||
<BrowseLocations />
|
||||
<BrowseTags />
|
||||
</ScreenContainer>
|
||||
|
|
|
@ -77,7 +77,6 @@ export default function LocationScreen({ navigation, route }: BrowseStackScreenP
|
|||
includeHeaderHeight
|
||||
icon={'FolderNoSpace'}
|
||||
style={tw`flex-1 items-center justify-center border-0`}
|
||||
textSize="text-md"
|
||||
iconSize={100}
|
||||
description={'No files found'}
|
||||
/>}
|
||||
|
|
|
@ -60,7 +60,6 @@ export default function LocationsScreen({ viewStyle }: Props) {
|
|||
<Empty
|
||||
icon="Folder"
|
||||
style={'border-0'}
|
||||
textSize="text-md"
|
||||
iconSize={84}
|
||||
description="You have not added any locations"
|
||||
/>
|
||||
|
|
|
@ -38,7 +38,6 @@ export default function TagScreen({ navigation, route }: BrowseStackScreenProps<
|
|||
includeHeaderHeight
|
||||
icon={'Tags'}
|
||||
style={tw`flex-1 items-center justify-center border-0`}
|
||||
textSize="text-md"
|
||||
iconSize={100}
|
||||
description={'No items assigned to this tag'}
|
||||
/>} {...objects} />;
|
||||
|
|
|
@ -65,7 +65,6 @@ export default function TagsScreen({ viewStyle = 'list' }: Props) {
|
|||
<Empty
|
||||
icon="Tags"
|
||||
style={'border-0'}
|
||||
textSize="text-md"
|
||||
iconSize={84}
|
||||
description="You have not created any tags"
|
||||
/>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useIsFocused } from '@react-navigation/native';
|
||||
import { usePathsExplorerQuery } from '@sd/client';
|
||||
import { useLibraryQuery, usePathsExplorerQuery } from '@sd/client';
|
||||
import { ArrowLeft, DotsThree, FunnelSimple } from 'phosphor-react-native';
|
||||
import { Suspense, useDeferredValue, useState } from 'react';
|
||||
import { ActivityIndicator, Platform, Pressable, TextInput, View } from 'react-native';
|
||||
|
@ -23,6 +23,8 @@ const SearchScreen = ({ navigation }: SearchStackScreenProps<'Search'>) => {
|
|||
const deferredSearch = useDeferredValue(search);
|
||||
const order = useSortBy();
|
||||
|
||||
const locations = useLibraryQuery(['locations.list']).data ?? [];
|
||||
|
||||
const objects = usePathsExplorerQuery({
|
||||
order,
|
||||
arg: {
|
||||
|
@ -43,6 +45,13 @@ const SearchScreen = ({ navigation }: SearchStackScreenProps<'Search'>) => {
|
|||
const noObjects = objects.items?.length === 0 || !objects.items;
|
||||
const noSearch = deferredSearch.length === 0 && appliedFiltersLength === 0;
|
||||
|
||||
const searchIcon =
|
||||
locations.length > 0 && noObjects && noSearch ? 'FolderNoSpace' :
|
||||
noSearch && noObjects ? 'Search' : 'FolderNoSpace';
|
||||
|
||||
const searchDescription = locations.length === 0 ? 'You have not added any locations to search' : noObjects
|
||||
|| noSearch ? 'No files found' : 'No results found for this search';
|
||||
|
||||
return (
|
||||
<View
|
||||
style={twStyle('relative z-50 flex-1 bg-app-header', {
|
||||
|
@ -117,12 +126,12 @@ const SearchScreen = ({ navigation }: SearchStackScreenProps<'Search'>) => {
|
|||
emptyComponent={
|
||||
<Empty
|
||||
includeHeaderHeight
|
||||
icon={noSearch ? 'Search' : 'FolderNoSpace'}
|
||||
icon={searchIcon}
|
||||
description={searchDescription}
|
||||
style={tw`flex-1 items-center justify-center border-0`}
|
||||
textSize="text-md"
|
||||
textStyle={tw`max-w-[220px]`}
|
||||
iconSize={100}
|
||||
description={noSearch ? 'Add filters or type to search for files' : 'No files found'}
|
||||
/>
|
||||
/>
|
||||
}
|
||||
tabHeight={false} />
|
||||
</Suspense>
|
||||
|
|
Loading…
Reference in a new issue