Skip to content

Commit

Permalink
[MOB-47] Location screen and header updates (#2056)
Browse files Browse the repository at this point in the history
* Location screen and header updates

* use tw sizing

* remove un-necessary prop

* Nit: change name
  • Loading branch information
ameer2468 authored Feb 6, 2024
1 parent 58f9305 commit 2d0c340
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 50 deletions.
24 changes: 20 additions & 4 deletions apps/mobile/src/components/browse/BrowseLocations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack';
import { SettingsStackScreenProps } from '~/navigation/tabs/SettingsStack';

import FolderIcon from '../icons/FolderIcon';
import { Icon } from '../icons/Icon';
import Fade from '../layout/Fade';
import ImportModal from '../modal/ImportModal';
import { LocationModal } from '../modal/location/LocationModal';
Expand All @@ -39,7 +40,7 @@ const BrowseLocationItem: React.FC<BrowseLocationItemProps> = ({
return (
<Pressable onPress={onPress}>
<View
style={tw`h-auto w-[100px] flex-col justify-center gap-3 rounded-md border border-sidebar-line/50 bg-sidebar-box p-2`}
style={tw`h-auto w-[110px] flex-col justify-center gap-3 rounded-md border border-sidebar-line/50 bg-sidebar-box p-2`}
>
<View style={tw`w-full flex-col justify-between gap-1`}>
<View style={tw`flex-row items-center justify-between`}>
Expand All @@ -61,7 +62,7 @@ const BrowseLocationItem: React.FC<BrowseLocationItemProps> = ({
</Pressable>
</View>
<Text
style={tw`w-full max-w-[75px] text-xs font-bold text-white`}
style={tw`w-full max-w-[100px] text-xs font-bold text-white`}
numberOfLines={1}
>
{location.name}
Expand Down Expand Up @@ -98,14 +99,19 @@ const BrowseLocations = () => {
return (
<View style={tw`gap-5`}>
<View style={tw`w-full flex-row items-center justify-between px-7`}>
<Text style={tw`text-xl font-bold text-white`}>Locations</Text>
<Text style={tw`text-lg font-bold text-white`}>Locations</Text>
<View style={tw`flex-row gap-3`}>
<Pressable
disabled={result.data?.nodes.length === 0}
onPress={() => {
navigation.navigate('Locations');
}}
>
<View style={tw`h-8 w-8 items-center justify-center rounded-md bg-accent`}>
<View
style={tw`h-8 w-8 items-center justify-center rounded-md bg-accent ${
result.data?.nodes.length === 0 ? 'opacity-40' : 'opacity-100'
}`}
>
<Eye weight="bold" size={18} style={tw`text-white`} />
</View>
</Pressable>
Expand All @@ -121,6 +127,16 @@ const BrowseLocations = () => {
<Fade color="mobile-screen" width={30} height="100%">
<FlatList
data={locations}
ListEmptyComponent={() => (
<View
style={tw`relative h-auto w-[85.5vw] flex-col items-center justify-center overflow-hidden rounded-md border border-dashed border-sidebar-line p-4`}
>
<Icon name="Folder" size={38} />
<Text style={tw`mt-2 text-center font-medium text-ink-dull`}>
You have no locations
</Text>
</View>
)}
contentContainerStyle={tw`px-7`}
showsHorizontalScrollIndicator={false}
ItemSeparatorComponent={() => <View style={tw`w-2`} />}
Expand Down
23 changes: 20 additions & 3 deletions apps/mobile/src/components/browse/BrowseTags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ModalRef } from '~/components/layout/Modal';
import { tw, twStyle } from '~/lib/tailwind';
import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack';

import { Icon } from '../icons/Icon';
import Fade from '../layout/Fade';
import CreateTagModal from '../modal/tag/CreateTagModal';
import { TagModal } from '../modal/tag/TagModal';
Expand Down Expand Up @@ -63,10 +64,14 @@ const BrowseTags = () => {
return (
<View style={tw`gap-5`}>
<View style={tw`w-full flex-row items-center justify-between px-7`}>
<Text style={tw`text-xl font-bold text-white`}>Tags</Text>
<Text style={tw`text-lg font-bold text-white`}>Tags</Text>
<View style={tw`flex-row gap-3`}>
<Pressable>
<View style={tw`h-8 w-8 items-center justify-center rounded-md bg-accent`}>
<View
style={tw`h-8 w-8 items-center justify-center rounded-md bg-accent ${
tags.data?.nodes.length === 0 ? 'opacity-40' : 'opacity-100'
}`}
>
<Eye weight="bold" size={18} style={tw`text-white`} />
</View>
</Pressable>
Expand All @@ -82,10 +87,22 @@ const BrowseTags = () => {
<Fade color="mobile-screen" width={30} height="100%">
<FlatList
data={tagData}
ListEmptyComponent={() => (
<View
style={tw`relative h-auto w-[85.5vw] flex-col items-center justify-center overflow-hidden rounded-md border border-dashed border-sidebar-line p-4`}
>
<Icon name="Tags" size={38} />
<Text style={tw`mt-2 text-center font-medium text-ink-dull`}>
You have no tags
</Text>
</View>
)}
renderItem={({ item }) => (
<BrowseTagItem
tag={item}
onPress={() => navigation.navigate('Tag', { id: item.id })}
onPress={() =>
navigation.navigate('Tag', { id: item.id, color: item.color! })
}
/>
)}
keyExtractor={(item) => item.id.toString()}
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/src/components/browse/Categories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const CATEGORIES_LIST = [
const Categories = () => {
return (
<View style={tw`relative gap-5`}>
<Text style={tw`px-7 text-xl font-bold text-white`}>Library</Text>
<Text style={tw`text-lg font-bold text-white px-7`}>Library</Text>

Check warning on line 32 in apps/mobile/src/components/browse/Categories.tsx

View workflow job for this annotation

GitHub Actions / ESLint

Invalid Tailwind CSS classnames order
<Fade width={30} height="100%" color="mobile-screen">
<ScrollView showsHorizontalScrollIndicator={false} horizontal>
<View style={tw`flex-row gap-2 px-7`}>
Expand Down
6 changes: 3 additions & 3 deletions apps/mobile/src/components/browse/Jobs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const Jobs = () => {
return (
<View style={tw`gap-5`}>
<View style={tw`w-full flex-row items-center justify-between px-7`}>
<Text style={tw`text-xl font-bold text-white`}>Jobs</Text>
<Text style={tw`text-lg font-bold text-white`}>Jobs</Text>
</View>
<Fade color="mobile-screen" height="100%" width={30}>
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
Expand Down Expand Up @@ -45,7 +45,7 @@ const Job = ({ progress, message, error }: JobProps) => {
: tw.color('accent');
return (
<View
style={tw`h-auto w-[310px] flex-col rounded-md border border-sidebar-line/50 bg-sidebar-box`}
style={tw`h-[170px] w-[310px] flex-col rounded-md border border-sidebar-line/50 bg-sidebar-box`}
>
<View
style={tw`w-full flex-row items-center justify-between rounded-t-md border-b border-sidebar-line/80 bg-mobile-header/50 px-5 py-2`}
Expand All @@ -56,7 +56,7 @@ const Job = ({ progress, message, error }: JobProps) => {
</View>
<DotsThreeOutlineVertical weight="fill" size={20} color={tw.color('ink-faint')} />
</View>
<View style={tw`mx-auto flex-1 flex-row items-center justify-between gap-5 px-5 py-2`}>
<View style={tw`mx-auto flex-1 flex-row items-center justify-between gap-5 px-5 py-3`}>
<AnimatedCircularProgress
size={80}
width={7}
Expand Down
74 changes: 63 additions & 11 deletions apps/mobile/src/components/explorer/Explorer.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { useNavigation } from '@react-navigation/native';
import { FlashList } from '@shopify/flash-list';
import { Rows, SquaresFour } from 'phosphor-react-native';
import { AnimatePresence, MotiView } from 'moti';
import { MonitorPlay, Rows, SlidersHorizontal, SquaresFour } from 'phosphor-react-native';
import { useState } from 'react';
import { Pressable, View } from 'react-native';
import { isPath, type ExplorerItem } from '@sd/client';
import SortByMenu from '~/components/menu/SortByMenu';
import Layout from '~/constants/Layout';
import { tw } from '~/lib/tailwind';
import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack';
import { getExplorerStore } from '~/stores/explorerStore';
import { ExplorerLayoutMode, getExplorerStore, useExplorerStore } from '~/stores/explorerStore';
import { useActionsModalStore } from '~/stores/modalStore';

import FileItem from './FileItem';
Expand All @@ -20,10 +20,10 @@ type ExplorerProps = {

const Explorer = ({ items }: ExplorerProps) => {
const navigation = useNavigation<BrowseStackScreenProps<'Location'>['navigation']>();
const explorerStore = useExplorerStore();
const [layoutMode, setLayoutMode] = useState<ExplorerLayoutMode>(getExplorerStore().layoutMode);

const [layoutMode, setLayoutMode] = useState<'grid' | 'list'>(getExplorerStore().layoutMode);

function changeLayoutMode(kind: 'grid' | 'list') {
function changeLayoutMode(kind: ExplorerLayoutMode) {
// We need to keep layoutMode as a state to make sure flash-list re-renders.
setLayoutMode(kind);
getExplorerStore().layoutMode = kind;
Expand All @@ -44,21 +44,38 @@ const Explorer = ({ items }: ExplorerProps) => {
}

return (
<View style={tw`flex-1`}>
<View style={tw`flex-1 bg-mobile-screen`}>
{/* Header */}
<View style={tw`flex flex-row items-center justify-between p-3`}>
<View style={tw`flex flex-row items-center justify-between`}>
{/* Sort By */}
<SortByMenu />
{/* <SortByMenu /> */}
<AnimatePresence>
{explorerStore.toggleMenu && (
<MotiView
from={{ translateY: -70 }}
animate={{ translateY: 0 }}
transition={{ type: 'timing', duration: 300 }}
exit={{ translateY: -70 }}
>
<ExplorerMenu
changeLayoutMode={(kind: ExplorerLayoutMode) => {
changeLayoutMode(kind);
}}
layoutMode={layoutMode}
/>
</MotiView>
)}
</AnimatePresence>
{/* Layout (Grid/List) */}
{layoutMode === 'grid' ? (
{/* {layoutMode === 'grid' ? (
<Pressable onPress={() => changeLayoutMode('list')}>
<SquaresFour color={tw.color('ink')} size={23} />
</Pressable>
) : (
<Pressable onPress={() => changeLayoutMode('grid')}>
<Rows color={tw.color('ink')} size={23} />
</Pressable>
)}
)} */}
</View>
{/* Items */}
{items && (
Expand Down Expand Up @@ -94,4 +111,39 @@ const Explorer = ({ items }: ExplorerProps) => {
);
};

interface ExplorerMenuProps {
layoutMode: ExplorerLayoutMode;
changeLayoutMode: (kind: ExplorerLayoutMode) => void;
}

const ExplorerMenu = ({ layoutMode, changeLayoutMode }: ExplorerMenuProps) => {
return (
<View
style={tw`w-screen flex-row justify-between border-b border-app-line/50 bg-mobile-header px-7 py-4`}
>
<View style={tw`flex-row gap-3`}>
<Pressable onPress={() => changeLayoutMode('grid')}>
<SquaresFour
color={tw.color(layoutMode === 'grid' ? 'text-accent' : 'text-ink-dull')}
size={23}
/>
</Pressable>
<Pressable onPress={() => changeLayoutMode('list')}>
<Rows
color={tw.color(layoutMode === 'list' ? 'text-accent' : 'text-ink-dull')}
size={23}
/>
</Pressable>
<Pressable onPress={() => changeLayoutMode('media')}>
<MonitorPlay
color={tw.color(layoutMode === 'media' ? 'text-accent' : 'text-ink-dull')}
size={23}
/>
</Pressable>
</View>
<SlidersHorizontal style={tw`text-ink-dull`} />
</View>
);
};

export default Explorer;
93 changes: 79 additions & 14 deletions apps/mobile/src/components/header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,48 @@
import { useNavigation } from '@react-navigation/native';
import { ArrowLeft, MagnifyingGlass } from 'phosphor-react-native';
import { StackHeaderProps } from '@react-navigation/stack';
import { ArrowLeft, DotsThreeOutline, MagnifyingGlass } from 'phosphor-react-native';
import { lazy } from 'react';
import { Pressable, Text, View } from 'react-native';
import { tw } from '~/lib/tailwind';
import { tw, twStyle } from '~/lib/tailwind';
import { getExplorerStore, useExplorerStore } from '~/stores/explorerStore';

import { Icon } from '../icons/Icon';

//Not all pages use these components - so we lazy load for performance
const BrowseLibraryManager = lazy(() => import('../browse/DrawerLibraryManager'));
const Search = lazy(() => import('../inputs/Search'));

interface Props {
type HeaderProps = {
title?: string; //title of the page
showLibrary?: boolean; //show the library manager
searchType?: 'explorer' | 'location'; //Temporary
navBack?: boolean; //navigate back to the previous screen
}
headerKind?: 'default' | 'location' | 'tag'; //kind of header
route?: never;
routeTitle?: never;
};

//you can pass in a routeTitle only if route is passed in
type Props =
| HeaderProps
| ({
route: StackHeaderProps;
routeTitle?: boolean;
} & Omit<HeaderProps, 'route' | 'routeTitle'>);

// Default header with search bar and button to open drawer
export default function Header({ title, showLibrary, searchType, navBack }: Props) {
export default function Header({
title,
showLibrary,
searchType,
navBack,
route,
routeTitle,
headerKind = 'default'
}: Props) {
const navigation = useNavigation();

const explorerStore = useExplorerStore();
const routeParams = route?.route.params as any;
const SearchType = () => {
switch (searchType) {
case 'explorer':
Expand All @@ -29,6 +53,22 @@ export default function Header({ title, showLibrary, searchType, navBack }: Prop
return null;
}
};
const HeaderIconKind = () => {
switch (headerKind) {
case 'location':
return <Icon size={32} name="Folder" />;
case 'tag':
return (
<View
style={twStyle('h-6 w-6 rounded-full', {
backgroundColor: routeParams.color
})}
/>
);
default:
return null;
}
};

return (
<View style={tw`relative h-auto w-full border-b border-app-line/50 bg-mobile-header pt-10`}>
Expand All @@ -44,16 +84,41 @@ export default function Header({ title, showLibrary, searchType, navBack }: Prop
<ArrowLeft size={23} color={tw.color('ink')} />
</Pressable>
)}
<Text style={tw`text-[24px] font-bold text-white`}>{title}</Text>
<View style={tw`flex-row items-center gap-2`}>
<HeaderIconKind />
<Text
numberOfLines={1}
style={tw`max-w-[190px] text-lg font-bold text-white`}
>
{title || (routeTitle && route?.options.title)}
</Text>
</View>
</View>
<View style={tw`flex-row items-center gap-3`}>
<Pressable onPress={() => navigation.navigate('Search')}>
<MagnifyingGlass
size={20}
weight="bold"
color={tw.color('text-zinc-300')}
/>
</Pressable>
{(headerKind === 'location' || headerKind === 'tag') && (
<Pressable
onPress={() => {
getExplorerStore().toggleMenu = !explorerStore.toggleMenu;
}}
>
<DotsThreeOutline
size={24}
color={tw.color(
explorerStore.toggleMenu ? 'text-accent' : 'text-zinc-300'
)}
/>
</Pressable>
)}
</View>
<Pressable onPress={() => navigation.navigate('Search')}>
<MagnifyingGlass
size={20}
weight="bold"
color={tw.color('text-zinc-300')}
/>
</Pressable>
</View>

{showLibrary && <BrowseLibraryManager style="mt-4" />}
{searchType && <SearchType />}
</View>
Expand Down
Loading

0 comments on commit 2d0c340

Please sign in to comment.