From 1bef410e0e46a83a812a827f3707a482e0663849 Mon Sep 17 00:00:00 2001 From: Jakz Date: Wed, 1 May 2024 11:57:12 +0800 Subject: [PATCH 01/20] Move createGallery to shared --- .../GalleryNavbar/GalleryRightContent.tsx | 10 ++++++++-- .../shared/src/hooks}/useCreateGallery.ts | 18 ++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) rename {apps/web/src/components/MultiGallery => packages/shared/src/hooks}/useCreateGallery.ts (74%) diff --git a/apps/web/src/contexts/globalLayout/GlobalNavbar/GalleryNavbar/GalleryRightContent.tsx b/apps/web/src/contexts/globalLayout/GlobalNavbar/GalleryNavbar/GalleryRightContent.tsx index a44cc42011..4a23d6ed8d 100644 --- a/apps/web/src/contexts/globalLayout/GlobalNavbar/GalleryNavbar/GalleryRightContent.tsx +++ b/apps/web/src/contexts/globalLayout/GlobalNavbar/GalleryNavbar/GalleryRightContent.tsx @@ -13,7 +13,6 @@ import { DropdownSection } from '~/components/core/Dropdown/DropdownSection'; import IconContainer from '~/components/core/IconContainer'; import { HStack, VStack } from '~/components/core/Spacer/Stack'; import FollowButton from '~/components/Follow/FollowButton'; -import useCreateGallery from '~/components/MultiGallery/useCreateGallery'; import Settings from '~/components/Settings/Settings'; import { AuthButton } from '~/contexts/globalLayout/GlobalNavbar/AuthButton'; import { EditLink } from '~/contexts/globalLayout/GlobalNavbar/CollectionNavbar/EditLink'; @@ -27,6 +26,7 @@ import EditUserInfoModal from '~/scenes/UserGalleryPage/EditUserInfoModal'; import LinkButton from '~/scenes/UserGalleryPage/LinkButton'; import { contexts } from '~/shared/analytics/constants'; import { useTrack } from '~/shared/contexts/AnalyticsContext'; +import useCreateGallery from '~/shared/hooks/useCreateGallery'; import QRCodeButton from './QRCodeButton'; @@ -90,7 +90,13 @@ export function GalleryRightContent({ queryRef, galleryRef, username }: GalleryR const latestPosition = query?.userByUsername?.galleries?.length.toString() ?? '0'; try { - await createGallery(latestPosition); + await createGallery(latestPosition, (galleryId) => { + const route = { + pathname: '/gallery/[galleryId]/edit', + query: { galleryId }, + }; + router.push(route); + }); } catch (error) { if (error instanceof Error) { pushToast({ diff --git a/apps/web/src/components/MultiGallery/useCreateGallery.ts b/packages/shared/src/hooks/useCreateGallery.ts similarity index 74% rename from apps/web/src/components/MultiGallery/useCreateGallery.ts rename to packages/shared/src/hooks/useCreateGallery.ts index f77007aee0..8cd351e4f4 100644 --- a/apps/web/src/components/MultiGallery/useCreateGallery.ts +++ b/packages/shared/src/hooks/useCreateGallery.ts @@ -1,14 +1,11 @@ -import { useRouter } from 'next/router'; import { useCallback } from 'react'; import { graphql } from 'relay-runtime'; +import { ValidationError } from '~/errors/ValidationError'; import { useCreateGalleryMutation } from '~/generated/useCreateGalleryMutation.graphql'; -import { ValidationError } from '~/shared/errors/ValidationError'; -import { usePromisifiedMutation } from '~/shared/relay/usePromisifiedMutation'; +import { usePromisifiedMutation } from '~/relay/usePromisifiedMutation'; export default function useCreateGallery() { - const router = useRouter(); - const [createGallery] = usePromisifiedMutation(graphql` mutation useCreateGalleryMutation($input: CreateGalleryInput!) @raw_response_type { createGallery(input: $input) { @@ -27,7 +24,7 @@ export default function useCreateGallery() { `); return useCallback( - async (position: string) => { + async (position: string, onSuccess: (galleryId: string) => void) => { try { const response = await createGallery({ variables: { @@ -44,17 +41,14 @@ export default function useCreateGallery() { } const galleryId = response?.createGallery?.gallery?.dbid; - const route = { - pathname: '/gallery/[galleryId]/edit', - query: { galleryId }, - }; + if (galleryId) { - router.push(route); + onSuccess(galleryId); } } catch (error) { throw new Error('Failed to create gallery'); } }, - [createGallery, router] + [createGallery] ); } From 719fbf40ad9da96808ebee356064afe9659efa70 Mon Sep 17 00:00:00 2001 From: Jakz Date: Wed, 1 May 2024 12:15:04 +0800 Subject: [PATCH 02/20] fix import --- packages/shared/src/hooks/useCreateGallery.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/shared/src/hooks/useCreateGallery.ts b/packages/shared/src/hooks/useCreateGallery.ts index 8cd351e4f4..f2f2d102b9 100644 --- a/packages/shared/src/hooks/useCreateGallery.ts +++ b/packages/shared/src/hooks/useCreateGallery.ts @@ -1,9 +1,10 @@ import { useCallback } from 'react'; import { graphql } from 'relay-runtime'; -import { ValidationError } from '~/errors/ValidationError'; import { useCreateGalleryMutation } from '~/generated/useCreateGalleryMutation.graphql'; -import { usePromisifiedMutation } from '~/relay/usePromisifiedMutation'; + +import { ValidationError } from '../errors/ValidationError'; +import { usePromisifiedMutation } from '../relay/usePromisifiedMutation'; export default function useCreateGallery() { const [createGallery] = usePromisifiedMutation(graphql` From b2759c83586446b37aeca9262eb212b215c0e650 Mon Sep 17 00:00:00 2001 From: Jakz Date: Wed, 1 May 2024 12:15:15 +0800 Subject: [PATCH 03/20] Able to create new gallery --- .../Tabs/ProfileViewGalleriesTab.tsx | 69 ++++++++++++++++--- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/apps/mobile/src/components/ProfileView/Tabs/ProfileViewGalleriesTab.tsx b/apps/mobile/src/components/ProfileView/Tabs/ProfileViewGalleriesTab.tsx index 262d44e7d1..88e96a13fa 100644 --- a/apps/mobile/src/components/ProfileView/Tabs/ProfileViewGalleriesTab.tsx +++ b/apps/mobile/src/components/ProfileView/Tabs/ProfileViewGalleriesTab.tsx @@ -1,3 +1,4 @@ +import { useNavigation } from '@react-navigation/native'; import { ListRenderItem } from '@shopify/flash-list'; import { useCallback, useMemo } from 'react'; import { View } from 'react-native'; @@ -5,18 +6,26 @@ import { Tabs } from 'react-native-collapsible-tab-view'; import { useFragment } from 'react-relay'; import { graphql } from 'relay-runtime'; +import { Button } from '~/components/Button'; import { GalleryPreviewCard } from '~/components/ProfileView/GalleryPreviewCard'; import { useListContentStyle } from '~/components/ProfileView/Tabs/useListContentStyle'; +import { useToastActions } from '~/contexts/ToastContext'; import { GalleryPreviewCardFragment$key } from '~/generated/GalleryPreviewCardFragment.graphql'; import { ProfileViewGalleriesTabFragment$key } from '~/generated/ProfileViewGalleriesTabFragment.graphql'; +import { RootStackNavigatorProp } from '~/navigation/types'; +import useCreateGallery from '~/shared/hooks/useCreateGallery'; import { removeNullValues } from '~/shared/relay/removeNullValues'; -type ListItem = { - kind: 'gallery'; - isFeatured: boolean; - gallery: GalleryPreviewCardFragment$key; - galleryId: string; -}; +type ListItem = + | { + kind: 'gallery'; + isFeatured: boolean; + gallery: GalleryPreviewCardFragment$key; + galleryId: string; + } + | { + kind: 'add-gallery'; + }; type ProfileViewGalleriesTabProps = { queryRef: ProfileViewGalleriesTabFragment$key; @@ -45,22 +54,60 @@ export function ProfileViewGalleriesTab({ queryRef }: ProfileViewGalleriesTabPro queryRef ); + const { pushToast } = useToastActions(); const user = query.userByUsername; + const createGallery = useCreateGallery(); + const navigation = useNavigation(); + + const handleCreateGallery = useCallback(async () => { + const latestPosition = query?.userByUsername?.galleries?.length.toString() ?? '0'; + + try { + await createGallery(latestPosition, (galleryId) => { + navigation.navigate('GalleryEditor', { galleryId, stagedTokens: [] }); + }); + } catch (error) { + if (error instanceof Error) { + pushToast({ + message: 'Unfortunately there was an error to create your gallery', + }); + } + } + }, [createGallery, navigation, pushToast, query?.userByUsername?.galleries?.length]); const items = useMemo(() => { - return removeNullValues(user?.galleries).map((gallery): ListItem => { - return { - kind: 'gallery', + const items: ListItem[] = []; + removeNullValues(user?.galleries).forEach((gallery) => { + items.push({ + kind: 'gallery', gallery, galleryId: gallery.dbid, isFeatured: user?.featuredGallery?.dbid === gallery.dbid, - }; + }); }); + + items.push({ kind: 'add-gallery' }); + + return items; }, [user?.featuredGallery?.dbid, user?.galleries]); const renderItem = useCallback>( ({ item }) => { + if (item.kind === 'add-gallery') { + return ( + +