mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-06-30 12:33:31 +00:00
[MOB-97] Fade select tags and empty location state (#2496)
* fade select tags and empty location state * smaller tags * smaller tags in filters and add tags modal
This commit is contained in:
parent
ce3d4ff7a6
commit
96a45ee76c
|
@ -1,11 +1,12 @@
|
|||
import { Tag, getItemObject, useLibraryMutation, useLibraryQuery, useRspcContext } from "@sd/client";
|
||||
import { CaretLeft, Plus } from "phosphor-react-native";
|
||||
import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { FlatList, Pressable, Text, View } from "react-native";
|
||||
import { FlatList, NativeScrollEvent, Pressable, Text, View } from "react-native";
|
||||
import useForwardedRef from "~/hooks/useForwardedRef";
|
||||
import { tw, twStyle } from "~/lib/tailwind";
|
||||
import { useActionsModalStore } from "~/stores/modalStore";
|
||||
import Card from "../layout/Card";
|
||||
import Fade from "../layout/Fade";
|
||||
import { Modal, ModalRef } from "../layout/Modal";
|
||||
import { Button } from "../primitive/Button";
|
||||
import CreateTagModal from "./tag/CreateTagModal";
|
||||
|
@ -20,6 +21,8 @@ const AddTagModal = forwardRef<ModalRef, unknown>((_, ref) => {
|
|||
|
||||
const modalRef = useForwardedRef(ref);
|
||||
const newTagRef = useRef<ModalRef>(null);
|
||||
const [startedScrolling, setStartedScrolling] = useState(false);
|
||||
const [reachedBottom, setReachedBottom] = useState(true); // needs to be set to true for initial rendering fade to be correct
|
||||
|
||||
const rspc = useRspcContext();
|
||||
const tagsQuery = useLibraryQuery(['tags.list']);
|
||||
|
@ -98,6 +101,15 @@ const AddTagModal = forwardRef<ModalRef, unknown>((_, ref) => {
|
|||
);
|
||||
}
|
||||
|
||||
// Fade the tags when scrolling
|
||||
const fadeScroll = ({ layoutMeasurement, contentOffset, contentSize }: NativeScrollEvent) => {
|
||||
const isScrolling = contentOffset.y > 0;
|
||||
setStartedScrolling(isScrolling);
|
||||
|
||||
const hasReachedBottom = layoutMeasurement.height + contentOffset.y >= contentSize.height;
|
||||
setReachedBottom(hasReachedBottom);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
|
@ -115,18 +127,37 @@ const AddTagModal = forwardRef<ModalRef, unknown>((_, ref) => {
|
|||
>
|
||||
<CaretLeft color={tw.color('ink')} size={16} weight="bold" />
|
||||
</Pressable>
|
||||
<View onLayout={(e) => {
|
||||
if (e.nativeEvent.layout.height >= 80) {
|
||||
setReachedBottom(false);
|
||||
} else {
|
||||
setReachedBottom(true);
|
||||
}
|
||||
}} style={twStyle(`relative mt-4 h-[70%]`)}>
|
||||
<Fade
|
||||
fadeSides="top-bottom"
|
||||
orientation="vertical"
|
||||
color="bg-app-modal"
|
||||
width={20}
|
||||
topFadeStyle={twStyle(startedScrolling ? 'mt-0 h-6' : 'h-0')}
|
||||
bottomFadeStyle={twStyle(reachedBottom ? 'h-0' : 'h-6')}
|
||||
height="100%"
|
||||
>
|
||||
<FlatList
|
||||
data={tagsData}
|
||||
numColumns={3}
|
||||
onScroll={(e) => fadeScroll(e.nativeEvent)}
|
||||
extraData={selectedTags}
|
||||
key={tagsData ? 'tags' : '_'}
|
||||
keyExtractor={(item) => item.id.toString()}
|
||||
contentContainerStyle={tw`mx-auto mt-4 p-4 pb-10`}
|
||||
contentContainerStyle={tw`mx-auto p-4 pb-6`}
|
||||
ItemSeparatorComponent={() => <View style={tw`h-2`} />}
|
||||
renderItem={({ item }) => (
|
||||
<TagItem isSelected={() => isSelected(item.id)} select={() => selectTag(item.id)} tag={item} />
|
||||
)}
|
||||
/>
|
||||
</Fade>
|
||||
</View>
|
||||
<View style={tw`flex-row gap-2 px-5`}>
|
||||
<Button
|
||||
onPress={() => newTagRef.current?.present()}
|
||||
|
@ -164,7 +195,7 @@ const TagItem = ({tag, select, isSelected}: Props) => {
|
|||
})}
|
||||
>
|
||||
<View
|
||||
style={twStyle(`h-4 w-4 rounded-full`, {
|
||||
style={twStyle(`h-3.5 w-3.5 rounded-full`, {
|
||||
backgroundColor: tag.color!
|
||||
})}
|
||||
/>
|
||||
|
|
|
@ -179,16 +179,16 @@ const ExtensionView = ({ extensions }: { extensions: string[] }) => (
|
|||
);
|
||||
|
||||
const TagView = ({ tags }: { tags: TagItem[] }) => (
|
||||
<>
|
||||
<View style={tw`mx-auto flex-row items-center justify-center`}>
|
||||
{tags.map((tag) => (
|
||||
<View
|
||||
key={tag.id}
|
||||
style={twStyle(`h-5 w-5 rounded-full`, {
|
||||
backgroundColor: tag.color
|
||||
style={twStyle(`h-4.5 w-4.5 relative rounded-full border-2 border-app-card`, {
|
||||
backgroundColor: tag.color,
|
||||
})}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
</View>
|
||||
);
|
||||
|
||||
const LocationView = ({ locations }: { locations: FilterItemType[] }) => (
|
||||
|
|
|
@ -76,7 +76,7 @@ const TagFilter = memo(({ tag }: Props) => {
|
|||
})}
|
||||
>
|
||||
<View
|
||||
style={twStyle(`h-5 w-5 rounded-full`, {
|
||||
style={twStyle(`h-3.5 w-3.5 rounded-full`, {
|
||||
backgroundColor: tag.color!
|
||||
})}
|
||||
/>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { useLibraryQuery, usePathsExplorerQuery } from '@sd/client';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import Explorer from '~/components/explorer/Explorer';
|
||||
import Empty from '~/components/layout/Empty';
|
||||
import { useSortBy } from '~/hooks/useSortBy';
|
||||
import { tw } from '~/lib/tailwind';
|
||||
import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack';
|
||||
import { getExplorerStore } from '~/stores/explorerStore';
|
||||
|
||||
|
@ -62,5 +64,15 @@ export default function LocationScreen({ navigation, route }: BrowseStackScreenP
|
|||
getExplorerStore().path = path ?? '';
|
||||
}, [id, path]);
|
||||
|
||||
return <Explorer {...paths} />;
|
||||
return <Explorer
|
||||
isEmpty={paths.count === 0}
|
||||
emptyComponent={<Empty
|
||||
includeHeaderHeight
|
||||
icon={'FolderNoSpace'}
|
||||
style={tw`flex-1 items-center justify-center border-0`}
|
||||
textSize="text-md"
|
||||
iconSize={100}
|
||||
description={'No files found'}
|
||||
/>}
|
||||
{...paths} />
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue