Skip to content

Commit

Permalink
Add publish gallery screen with preview card
Browse files Browse the repository at this point in the history
  • Loading branch information
jakzaizzat committed May 2, 2024
1 parent 482c970 commit ed76aff
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { useMemo } from 'react';
import { View } from 'react-native';
import { graphql, useFragment } from 'react-relay';
import { removeNullValues } from 'shared/relay/removeNullValues';
import { parseCollectionLayout } from 'shared/utils/collectionLayout';

import { GalleryEditorTokenPreview } from '~/components/GalleryEditor/GalleryEditorTokenPreview';
import { WhiteSpace } from '~/components/GalleryEditor/SortableTokenGrid/SortableTokenGrid';
import { Typography } from '~/components/Typography';
import { PublishGalleryPreviewFragment$key } from '~/generated/PublishGalleryPreviewFragment.graphql';

type Props = {
galleryRef: PublishGalleryPreviewFragment$key;
};

const CONTAINER_WIDTH = 300;

export function PublishGalleryPreview({ galleryRef }: Props) {
const gallery = useFragment(
graphql`
fragment PublishGalleryPreviewFragment on Gallery {
id
name
collections {
name
collectorsNote
layout {
__typename
sections
sectionLayout {
columns
whitespace
}
...collectionLayoutParseFragment
}
tokens {
id
token {
...GalleryEditorTokenPreviewFragment
}
}
}
}
`,
galleryRef
);

// get first section in the gallery
const firstSection = gallery.collections?.[0];

const nonNullTokens = useMemo(() => {
return removeNullValues(firstSection?.tokens);
}, [firstSection?.tokens]);

const rows = useMemo(() => {
const layout = firstSection?.layout || {
__typename: 'CollectionLayout',
sections: [],
sectionLayout: [],
};

return parseCollectionLayout(
nonNullTokens,
{
...layout,
sections: removeNullValues(layout.sections ?? []),
sectionLayout: removeNullValues(layout.sectionLayout ?? []),
},
true
);
}, [nonNullTokens, firstSection?.layout]);

if (!gallery) {
return null;
}

return (
<View
className="bg-offWhite dark:bg-black-800 border border-porcelain flex w-full flex-col space-y-3 rounded-xl px-4 pt-4"
style={{
shadowColor: 'rgb(0, 0, 0)',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.05,
shadowRadius: 2,
}}
>
<View className="flex flex-row items-center justify-center">
<View className="flex flex-1 flex-col">
<Typography className="text-xs" font={{ family: 'ABCDiatype', weight: 'Bold' }}>
{firstSection?.name || 'Untitled'}
</Typography>
<Typography
numberOfLines={1}
className="text-xs"
font={{ family: 'ABCDiatype', weight: 'Regular' }}
>
{firstSection?.collectorsNote}
</Typography>
</View>
</View>
<View>
<View className="flex-row flex-wrap gap-2 max-h-64 overflow-hidden">
{rows.map((row) => {
// 64 is the padding on the left and right of the container
const widthPerToken = (CONTAINER_WIDTH - 64) / row.columns;

return (
<View key={row.id} className="flex-row flex-wrap gap-2">
{row.items.map((item) => {
if ('whitespace' in item) {
return <WhiteSpace key={item.id} size={widthPerToken} />;
} else {
return (
<View
key={item.id}
className="aspect-square"
style={{
width: widthPerToken,
}}
>
{item.token && <GalleryEditorTokenPreview tokenRef={item.token} />}
</View>
);
}
})}
</View>
);
})}
</View>
</View>
</View>
);
}
16 changes: 14 additions & 2 deletions apps/mobile/src/components/GalleryEditor/GalleryEditorNavbar.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { useNavigation } from '@react-navigation/native';
import clsx from 'clsx';
import { useCallback } from 'react';
import { View } from 'react-native';

import { useBottomSheetModalActions } from '~/contexts/BottomSheetModalContext';
import { useGalleryEditorActions } from '~/contexts/GalleryEditor/GalleryEditorContext';
import { StagedSectionList } from '~/contexts/GalleryEditor/types';
import { RootStackNavigatorProp } from '~/navigation/types';

import { BackButton } from '../BackButton';
import { Button } from '../Button';
import { BaseM } from '../Text';

export function GalleryEditorNavbar() {
const { activeRowId, sections, sectionIdBeingEdited, saveGallery } = useGalleryEditorActions();
const { activeRowId, galleryId, sections, sectionIdBeingEdited, saveGallery } =
useGalleryEditorActions();
const navigation = useNavigation<RootStackNavigatorProp>();

const { showBottomSheetModal } = useBottomSheetModalActions();

Expand All @@ -27,6 +31,14 @@ export function GalleryEditorNavbar() {
});
}, [activeRowId, sections, sectionIdBeingEdited, showBottomSheetModal]);

const handlePublishGallery = useCallback(async () => {
await saveGallery();

navigation.navigate('PublishGallery', {
galleryId,
});
}, [galleryId, navigation, saveGallery]);

return (
<View className="p-4 flex-row items-center justify-between">
<BackButton />
Expand All @@ -43,7 +55,7 @@ export function GalleryEditorNavbar() {
variant="secondary"
/>
<Button
onPress={saveGallery}
onPress={handlePublishGallery}
text="Publish"
eventElementId={null}
eventName={null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,6 @@ type WhiteSpaceProps = {
style?: ViewProps['style'];
};

function WhiteSpace({ size, style }: WhiteSpaceProps) {
export function WhiteSpace({ size, style }: WhiteSpaceProps) {
return <View style={[{ width: size, height: size }, style]} />;
}
2 changes: 2 additions & 0 deletions apps/mobile/src/navigation/RootStackNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { DesignSystemButtonsScreen } from '~/screens/DesignSystemButtonsScreen';
import { GalleryEditorNftSelector } from '~/screens/GalleryScreen/GalleryEditorNftSelector';
import { GalleryEditorNftSelectorContractScreen } from '~/screens/GalleryScreen/GalleryEditorNftSelectorContractScreen';
import { GalleryEditorScreen } from '~/screens/GalleryScreen/GalleryEditorScreen';
import { PublishGalleryScreen } from '~/screens/GalleryScreen/PublishGallery/PublishGalleryScreen';
import { TwitterSuggestionListScreen } from '~/screens/HomeScreen/TwitterSuggestionListScreen';
import { UserSuggestionListScreen } from '~/screens/HomeScreen/UserSuggestionListScreen';
import { PostComposerScreen } from '~/screens/PostScreen/PostComposerScreen';
Expand Down Expand Up @@ -106,6 +107,7 @@ export function RootStackNavigator({ navigationContainerRef }: Props) {

<Stack.Screen name="GalleryEditor" component={GalleryEditorScreen} />
<Stack.Screen name="NftSelectorGalleryEditor" component={GalleryEditorNftSelector} />
<Stack.Screen name="PublishGallery" component={PublishGalleryScreen} />
<Stack.Screen
name="NftSelectorContractGalleryEditor"
component={GalleryEditorNftSelectorContractScreen}
Expand Down
3 changes: 3 additions & 0 deletions apps/mobile/src/navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ export type RootStackNavigatorParamList = {
contractAddress: string;
ownerFilter?: 'Collected' | 'Created';
};
PublishGallery: {
galleryId: string;
};
};

export type ScreenWithNftSelector = 'ProfilePicture' | 'Post' | 'Community' | 'Onboarding';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { RouteProp, useRoute } from '@react-navigation/native';
import { TextInput, View } from 'react-native';
import { graphql, useLazyLoadQuery } from 'react-relay';

import { BackButton } from '~/components/BackButton';
import { Button } from '~/components/Button';
import { PublishGalleryPreview } from '~/components/Gallery/PublishGallery/PublishGalleryPreview';
import { useSafeAreaPadding } from '~/components/SafeAreaViewWithPadding';
import { BaseM } from '~/components/Text';
import { Typography } from '~/components/Typography';
import { PublishGalleryScreenQuery } from '~/generated/PublishGalleryScreenQuery.graphql';
import { RootStackNavigatorParamList } from '~/navigation/types';

export function PublishGalleryScreen() {
const route = useRoute<RouteProp<RootStackNavigatorParamList, 'PublishGallery'>>();

const query = useLazyLoadQuery<PublishGalleryScreenQuery>(
graphql`
query PublishGalleryScreenQuery($galleryId: DBID!) {
viewer {
__typename
}
galleryById(id: $galleryId) {
__typename
...PublishGalleryPreviewFragment
}
}
`,
{
galleryId: route.params.galleryId,
}
);

const { top } = useSafeAreaPadding();
const gallery = query.galleryById;

if (!gallery) {
throw new Error('Gallery not found');
}

return (
<View
className="flex flex-col flex-1 bg-white dark:bg-black-900 space-y-4"
style={{
paddingTop: top,
}}
>
<View className="p-4 flex-row items-center justify-between">
<BackButton />

<View className="flex-row gap-2">
<Button
onPress={() => {}}
text="Publish"
eventElementId={null}
eventName={null}
eventContext={null}
size="xs"
fontWeight="Bold"
/>
</View>
</View>

<View className="space-y-6">
<View className="flex-col items-center">
<TextInput
className="text-[32px] leading-[36px] text-metal dark:text-white"
// onChangeText={setGalleryName}
placeholder="My Gallery"
style={{
fontFamily: 'GTAlpinaLight',
}}
autoCorrect={false}
spellCheck={false}
>
<Typography
font={{
family: 'GTAlpina',
weight: 'Light',
}}
className="text-[32px] leading-[36px] text-black-900 dark:text-white"
>
{/* {galleryName} */}
</Typography>
</TextInput>
</View>
<View className="w-[300] mx-auto">
<PublishGalleryPreview galleryRef={gallery} />
</View>
<View className="items-center">
<TextInput
// onChangeText={setGalleryDescription}
placeholder="Add a description (optional)"
className="text-metal"
multiline
>
<BaseM classNameOverride="text-metal leading-1">Add a description (optional)</BaseM>
</TextInput>
</View>
</View>
</View>
);
}

0 comments on commit ed76aff

Please sign in to comment.