Skip to content

Commit

Permalink
[MOB-95] Tags support & more (#2494)
Browse files Browse the repository at this point in the history
* tags support wip

* Mob: tags in explorer, ui adjustments, add filter based on search click and more

* Fix tags scroll on filters

* Set heights so UI updates correctly

* Update Tags.tsx

* remove console logs

* remove console logs

* Update Locations.tsx

* type

* Update locations.rs

* make tags abit smaller

* list view visual improvements

* Remove plus
  • Loading branch information
ameer2468 committed May 17, 2024
1 parent c091cca commit 9d47af8
Show file tree
Hide file tree
Showing 31 changed files with 486 additions and 145 deletions.
25 changes: 24 additions & 1 deletion apps/mobile/src/components/explorer/FileItem.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ExplorerItem, Tag, getItemFilePath, getItemObject } from '@sd/client';
import { Text, View } from 'react-native';
import { ExplorerItem, getItemFilePath } from '@sd/client';
import Layout from '~/constants/Layout';
import { tw, twStyle } from '~/lib/tailwind';
import { getExplorerStore } from '~/stores/explorerStore';

import { useMemo } from 'react';
import FileThumb from './FileThumb';

type FileItemProps = {
Expand All @@ -14,6 +15,13 @@ const FileItem = ({ data }: FileItemProps) => {
const gridItemSize = Layout.window.width / getExplorerStore().gridNumColumns;

const filePath = getItemFilePath(data);
const object = getItemObject(data);

const maxTags = 3;
const tags = useMemo(() => {
if (!object) return [];
return 'tags' in object ? object.tags.slice(0, maxTags) : [];
}, [object]);

return (
<View
Expand All @@ -29,6 +37,21 @@ const FileItem = ({ data }: FileItemProps) => {
{filePath?.extension && `.${filePath.extension}`}
</Text>
</View>
<View style={twStyle(`mx-auto flex-row justify-center pt-1.5`, {
left: tags.length * 2 //for every tag we add 2px to the left
})}>
{tags.map(({tag}: {tag: Tag}, idx: number) => {
return (
<View
key={tag.id}
style={twStyle(`relative h-3.5 w-3.5 rounded-full border-2 border-black`, {
backgroundColor: tag.color!,
right: idx * 6,
})}
/>
)
})}
</View>
</View>
);
};
Expand Down
34 changes: 30 additions & 4 deletions apps/mobile/src/components/explorer/FileRow.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ExplorerItem, getItemFilePath } from '@sd/client';
import React from 'react';
import { ExplorerItem, Tag, getItemFilePath, getItemObject } from '@sd/client';
import React, { useMemo } from 'react';
import { Text, View } from 'react-native';
import { tw, twStyle } from '~/lib/tailwind';
import { getExplorerStore } from '~/stores/explorerStore';
Expand All @@ -12,21 +12,47 @@ type FileRowProps = {

const FileRow = ({ data }: FileRowProps) => {
const filePath = getItemFilePath(data);
const object = getItemObject(data);

const maxTags = 3;
const tags = useMemo(() => {
if (!object) return [];
return 'tags' in object ? object.tags.slice(0, maxTags) : [];
}, [object]);

return (
<>
<View
style={twStyle('flex flex-row items-center px-3', {
height: getExplorerStore().listItemSize
})}
>
<FileThumb data={data} size={0.6} />
<View style={tw`ml-3 max-w-[80%]`}>
<Text numberOfLines={1} style={tw`text-center text-xs font-medium text-ink-dull`}>
<View style={tw`mx-2 flex-1 flex-row items-center justify-between border-b border-white/10 pb-3`}>
<View style={tw`max-w-[80%]`}>
<Text numberOfLines={1} style={tw`text-center text-sm font-medium text-ink`}>
{filePath?.name}
{filePath?.extension && `.${filePath.extension}`}
</Text>
</View>
<View style={twStyle(`mr-1 flex-row`, {
left: tags.length * 6 //for every tag we add 2px to the left,
})}>
{tags.map(({tag}: {tag: Tag}, idx: number) => {
return (
<View
key={tag.id}
style={twStyle(`relative h-3.5 w-3.5 rounded-full border-2 border-black`, {
backgroundColor: tag.color!,
right: idx * 6,
})}
/>
)
})}
</View>
</View>
</View>
</>
);
};

Expand Down
94 changes: 73 additions & 21 deletions apps/mobile/src/components/explorer/sections/InfoTagPills.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,100 @@ import {
isPath,
useLibraryQuery
} from '@sd/client';
import React from 'react';
import { Alert, Pressable, View, ViewStyle } from 'react-native';
import React, { useRef, useState } from 'react';
import { FlatList, NativeScrollEvent, Pressable, View, ViewStyle } from 'react-native';
import Fade from '~/components/layout/Fade';
import { ModalRef } from '~/components/layout/Modal';
import AddTagModal from '~/components/modal/AddTagModal';
import { InfoPill, PlaceholderPill } from '~/components/primitive/InfoPill';
import { tw, twStyle } from '~/lib/tailwind';

type Props = {
data: ExplorerItem;
style?: ViewStyle;
contentContainerStyle?: ViewStyle;
columnCount?: number;
};

const InfoTagPills = ({ data, style }: Props) => {
const InfoTagPills = ({ data, style, contentContainerStyle, columnCount = 3 }: Props) => {

const objectData = getItemObject(data);
const filePath = getItemFilePath(data);
const [startedScrolling, setStartedScrolling] = useState(false);
const [reachedBottom, setReachedBottom] = useState(true); // needs to be set to true for initial rendering fade to be correct

const tagsQuery = useLibraryQuery(['tags.getForObject', objectData?.id ?? -1], {
enabled: objectData != null
enabled: objectData != null,
});
const items = tagsQuery.data;

const ref = useRef<ModalRef>(null);
const tags = tagsQuery.data;
const isDir = data && isPath(data) ? data.item.is_dir : false;

// Fade the tag pills 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 (
<View style={twStyle('mt-1 flex flex-row flex-wrap', style)}>
{/* Kind */}
<InfoPill containerStyle={tw`mr-1`} text={isDir ? 'Folder' : getExplorerItemData(data).kind} />
<>
<View style={twStyle('mb-3 mt-2 flex-col flex-wrap items-start gap-1', style)}>
<View style={tw`flex-row gap-1`}>
<Pressable style={tw`relative z-10`} onPress={() => ref.current?.present()}>
<PlaceholderPill
text={'Tags'}
/>
</Pressable>
{/* Kind */}
<InfoPill text={isDir ? 'Folder' : getExplorerItemData(data).kind} />
{/* Extension */}
{filePath?.extension && (
<InfoPill text={filePath.extension} containerStyle={tw`mr-1`} />
<InfoPill text={filePath.extension} />
)}
{/* TODO: What happens if I have too many? */}
{items?.map((tag) => (
<InfoPill
key={tag.id}
text={tag.name ?? 'Unnamed Tag'}
containerStyle={twStyle('mr-1', { backgroundColor: tag.color + 'CC' })}
textStyle={tw`text-white`}
/>
))}
<Pressable onPress={() => Alert.alert('TODO')}>
<PlaceholderPill text={'Add Tag'} />
</Pressable>
</View>
<View onLayout={(e) => {
if (e.nativeEvent.layout.height >= 80) {
setReachedBottom(false);
} else {
setReachedBottom(true);
}
}} style={twStyle(`relative flex-row flex-wrap gap-1 overflow-hidden`)}>
<Fade
fadeSides="top-bottom"
orientation="vertical"
color="bg-app-modal"
width={20}
topFadeStyle={twStyle(startedScrolling ? 'mt-0' : 'h-0')}
bottomFadeStyle={twStyle(reachedBottom ? 'h-0' : 'h-6')}
height="100%"
>
<FlatList
onScroll={(e) => fadeScroll(e.nativeEvent)}
style={tw`max-h-20 w-full grow-0`}
data={tags}
scrollEventThrottle={1}
showsVerticalScrollIndicator={false}
numColumns={columnCount}
contentContainerStyle={twStyle(`gap-1`, contentContainerStyle)}
columnWrapperStyle={tags && twStyle(tags.length > 0 && `flex-wrap gap-1`)}
key={tags?.length}
keyExtractor={(item) => item.id.toString() + Math.floor(Math.random() * 10)}
renderItem={({ item }) => (
<InfoPill
text={item.name ?? 'Unnamed Tag'}
containerStyle={twStyle({ backgroundColor: item.color + 'CC' })}
textStyle={tw`text-white`}
/>
)}/>
</Fade>
</View>
</View>
<AddTagModal ref={ref}/>
</>
);
};

Expand Down
32 changes: 28 additions & 4 deletions apps/mobile/src/components/header/DynamicHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { tw, twStyle } from '~/lib/tailwind';
import { getExplorerStore, useExplorerStore } from '~/stores/explorerStore';

import { FilterItem, TagItem, useSearchStore } from '~/stores/searchStore';
import { Icon } from '../icons/Icon';

type Props = {
headerRoute?: NativeStackHeaderProps; //supporting title from the options object of navigation
optionsRoute?: RouteProp<any, any>; //supporting params passed
kind: 'tag' | 'location'; //the kind of icon to display
kind: 'tags' | 'locations'; //the kind of icon to display
explorerMenu?: boolean; //whether to show the explorer menu
};

Expand All @@ -26,6 +27,28 @@ export default function DynamicHeader({
const headerHeight = useSafeAreaInsets().top;
const isAndroid = Platform.OS === 'android';
const explorerStore = useExplorerStore();
const searchStore = useSearchStore();
const params = headerRoute?.route.params as {
id: number;
color: string;
name: string;
}

//pressing the search icon will add a filter
//based on the screen

const searchHandler = (key: Props['kind']) => {
if (!params) return;
const keys: {
tags: TagItem;
locations: FilterItem;
} = {
tags: {id: params.id, color: params.color},
locations: {id: params.id, name: params.name},
}
searchStore.searchFrom(key, keys[key])
}


return (
<View
Expand Down Expand Up @@ -53,6 +76,7 @@ export default function DynamicHeader({
<Pressable
hitSlop={12}
onPress={() => {
searchHandler(kind)
navigation.navigate('SearchStack', {
screen: 'Search'
});
Expand Down Expand Up @@ -94,12 +118,12 @@ interface HeaderIconKindProps {

const HeaderIconKind = ({ routeParams, kind }: HeaderIconKindProps) => {
switch (kind) {
case 'location':
case 'locations':
return <Icon size={24} name="Folder" />;
case 'tag':
case 'tags':
return (
<View
style={twStyle('h-[24px] w-[24px] rounded-full', {
style={twStyle('h-5 w-5 rounded-full', {
backgroundColor: routeParams.color
})}
/>
Expand Down
4 changes: 2 additions & 2 deletions apps/mobile/src/components/locations/ListLocation.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useNavigation } from '@react-navigation/native';
import { Location, arraysEqual, humanizeSize, useOnlineLocations } from '@sd/client';
import { DotsThreeVertical } from 'phosphor-react-native';
import { useRef } from 'react';
import { Pressable, Text, View } from 'react-native';
import { Swipeable } from 'react-native-gesture-handler';
import { arraysEqual, humanizeSize, Location, useOnlineLocations } from '@sd/client';
import { tw, twStyle } from '~/lib/tailwind';
import { SettingsStackScreenProps } from '~/navigation/tabs/SettingsStack';

Expand All @@ -25,7 +25,7 @@ const ListLocation = ({ location }: ListLocationProps) => {
return (
<Swipeable
ref={swipeRef}
containerStyle={tw`rounded-md border border-app-cardborder bg-app-card`}
containerStyle={tw`h-16 rounded-md border border-app-cardborder bg-app-card`}
enableTrackpadTwoFingerGesture
renderRightActions={(progress, _, swipeable) => (
<>
Expand Down

0 comments on commit 9d47af8

Please sign in to comment.