From 2a977f3ac5ed0323e15990f06fdd231447e4fb0a Mon Sep 17 00:00:00 2001 From: d0422 Date: Thu, 26 Sep 2024 00:39:07 +0900 Subject: [PATCH 01/12] =?UTF-8?q?feat:=20badge=20query=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apis/queries/mypage/useMyBadgeQuery.ts | 65 +++++++++++++++++++ .../react-native/src/constants/QUERY_KEYS.ts | 1 + 2 files changed, 66 insertions(+) create mode 100644 packages/react-native/src/apis/queries/mypage/useMyBadgeQuery.ts diff --git a/packages/react-native/src/apis/queries/mypage/useMyBadgeQuery.ts b/packages/react-native/src/apis/queries/mypage/useMyBadgeQuery.ts new file mode 100644 index 00000000..40941697 --- /dev/null +++ b/packages/react-native/src/apis/queries/mypage/useMyBadgeQuery.ts @@ -0,0 +1,65 @@ +import { useSuspenseQuery } from '@tanstack/react-query'; +import useAuthAxios from '@/apis/useAuthAxios'; +import { badgePath } from '@/components/common/Badge'; +import { Region } from '@/constants/CITY'; +import QUERY_KEYS from '@/constants/QUERY_KEYS'; +import { ServerResponse } from '@/types/response'; + +interface BadgeResponse { + region: Region; + count: number; +} + +const badgeMapper = (badge: BadgeResponse): keyof typeof badgePath => { + switch (badge.region) { + case Region.SEOUL: + return '서울'; + case Region.GYEONGGI: + return '경기'; + case Region.INCHEON: + return '인천'; + case Region.GANGWON: + return '강원'; + case Region.SEJONG: + return '세종'; + case Region.DAEJEON: + return '대전'; + case Region.GWANGJU: + return '광주'; + case Region.DAEGU: + return '대구'; + case Region.ULSAN: + return '울산'; + case Region.BUSAN: + return '부산'; + case Region.CHUNGBUK || Region.CHUNGNAM: + return '충청'; + case Region.GYEONGBUK || Region.GYEONGNAM: + return '경상'; + case Region.JEONBUK || Region.JEONNAM: + return '전라'; + case Region.JEJU: + default: + return '제주'; + } +}; + +export default function useMyBadgeQuery() { + const authAxios = useAuthAxios(); + const getBadges = async () => { + const result = + await authAxios.get>('/api/user/badge'); + + const badges = result.data.result.map((badge) => ({ + count: badge.count, + badgeRegion: badgeMapper(badge), + })); + + return badges; + }; + + return useSuspenseQuery({ + queryKey: [QUERY_KEYS.MY_BADGES], + queryFn: getBadges, + }); +} diff --git a/packages/react-native/src/constants/QUERY_KEYS.ts b/packages/react-native/src/constants/QUERY_KEYS.ts index 0113fac3..5e2a94e0 100644 --- a/packages/react-native/src/constants/QUERY_KEYS.ts +++ b/packages/react-native/src/constants/QUERY_KEYS.ts @@ -14,6 +14,7 @@ const QUERY_KEYS = { SPOT_DETAIL: 'spotDetail', SEARCH: 'search', MY_SPOTS: 'mySpots', + MY_BADGES: 'myBadges', }; export default QUERY_KEYS; From 8479a0c50c99763ca5fb2786209c8e3687f29288 Mon Sep 17 00:00:00 2001 From: d0422 Date: Thu, 26 Sep 2024 00:39:31 +0900 Subject: [PATCH 02/12] =?UTF-8?q?feat:=20MyBadge=20api=20UI=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react-native/src/pages/MyPage/MyBadge.tsx | 26 ++++++++++--------- .../src/routes/MyPageTabNavigator.tsx | 5 ---- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/packages/react-native/src/pages/MyPage/MyBadge.tsx b/packages/react-native/src/pages/MyPage/MyBadge.tsx index 48fceeb5..50c1de0c 100644 --- a/packages/react-native/src/pages/MyPage/MyBadge.tsx +++ b/packages/react-native/src/pages/MyPage/MyBadge.tsx @@ -3,40 +3,42 @@ import { FlatList, View } from 'react-native'; import Badge, { badgePath } from '@/components/common/Badge'; import Spacing from '@/components/common/Spacing'; import BadgeListBottomSheet from '@/components/mypage/BadgeListBottomSheet'; +import useMyBadgeQuery from '@/apis/queries/mypage/useMyBadgeQuery'; +import withSuspense from '@/components/HOC/withSuspense'; -export default function MyBadge() { +export default withSuspense(function MyBadge() { + const { data: badges } = useMyBadgeQuery(); const [containerWidth, setContainerWidth] = useState(0); - const [selectedBadge, setSelectedBadge] = useState(); + // const [selectedBadge, setSelectedBadge] = useState(); - const locationList = Object.keys(badgePath) as (keyof typeof badgePath)[]; const numColumns = 3; const paddingHorizontal = 8; return ( <> setContainerWidth(e.nativeEvent.layout.width)} style={{ flex: 1, backgroundColor: 'black', paddingHorizontal }} renderItem={({ item, index }) => ( setSelectedBadge(item)} - count={index % 4} + label={item.badgeRegion} + // onPress={() => setSelectedBadge(item.badgeRegion)} + count={item.count} /> )} - keyExtractor={(item) => item} + keyExtractor={(item) => item.badgeRegion} numColumns={numColumns} /> - setSelectedBadge(undefined)} - /> + /> */} ); -} +}); diff --git a/packages/react-native/src/routes/MyPageTabNavigator.tsx b/packages/react-native/src/routes/MyPageTabNavigator.tsx index 3d9195b0..34b9d338 100644 --- a/packages/react-native/src/routes/MyPageTabNavigator.tsx +++ b/packages/react-native/src/routes/MyPageTabNavigator.tsx @@ -41,11 +41,6 @@ export default function MyPageTabNavigator() { component={MyBadge} options={{ tabBarLabel: 'Bagde Collection' }} /> - {/* */} ); } From 8b9b60e815c8af4ba3f4f4340cc48736ddd21a8c Mon Sep 17 00:00:00 2001 From: d0422 Date: Thu, 26 Sep 2024 00:41:14 +0900 Subject: [PATCH 03/12] =?UTF-8?q?feat:=20custom=20fallback=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react-native/src/pages/MyPage/MyBadge.tsx | 80 +++++++++------- .../react-native/src/pages/MyPage/MySpot.tsx | 96 +++++++++++-------- 2 files changed, 102 insertions(+), 74 deletions(-) diff --git a/packages/react-native/src/pages/MyPage/MyBadge.tsx b/packages/react-native/src/pages/MyPage/MyBadge.tsx index 50c1de0c..74b8f688 100644 --- a/packages/react-native/src/pages/MyPage/MyBadge.tsx +++ b/packages/react-native/src/pages/MyPage/MyBadge.tsx @@ -1,44 +1,58 @@ import { useState } from 'react'; import { FlatList, View } from 'react-native'; -import Badge, { badgePath } from '@/components/common/Badge'; +import { Font } from 'design-system'; +import Badge from '@/components/common/Badge'; import Spacing from '@/components/common/Spacing'; -import BadgeListBottomSheet from '@/components/mypage/BadgeListBottomSheet'; import useMyBadgeQuery from '@/apis/queries/mypage/useMyBadgeQuery'; import withSuspense from '@/components/HOC/withSuspense'; -export default withSuspense(function MyBadge() { - const { data: badges } = useMyBadgeQuery(); - const [containerWidth, setContainerWidth] = useState(0); - // const [selectedBadge, setSelectedBadge] = useState(); +export default withSuspense( + function MyBadge() { + const { data: badges } = useMyBadgeQuery(); + const [containerWidth, setContainerWidth] = useState(0); + // const [selectedBadge, setSelectedBadge] = useState(); - const numColumns = 3; - const paddingHorizontal = 8; + const numColumns = 3; + const paddingHorizontal = 8; - return ( - <> - setContainerWidth(e.nativeEvent.layout.width)} - style={{ flex: 1, backgroundColor: 'black', paddingHorizontal }} - renderItem={({ item, index }) => ( - - setSelectedBadge(item.badgeRegion)} - count={item.count} - /> - - - )} - keyExtractor={(item) => item.badgeRegion} - numColumns={numColumns} - /> - {/* + setContainerWidth(e.nativeEvent.layout.width)} + style={{ flex: 1, backgroundColor: 'black', paddingHorizontal }} + renderItem={({ item, index }) => ( + + setSelectedBadge(item.badgeRegion)} + count={item.count} + /> + + + )} + keyExtractor={(item) => item.badgeRegion} + numColumns={numColumns} + /> + {/* setSelectedBadge(undefined)} /> */} - - ); -}); + + ); + }, + { + fallback: ( + + + 잠시만 + + + 기다려주세요 + + + ), + }, +); diff --git a/packages/react-native/src/pages/MyPage/MySpot.tsx b/packages/react-native/src/pages/MyPage/MySpot.tsx index c199e50f..5b1a53fb 100644 --- a/packages/react-native/src/pages/MyPage/MySpot.tsx +++ b/packages/react-native/src/pages/MyPage/MySpot.tsx @@ -9,48 +9,62 @@ import { StackNavigation } from '@/types/navigation'; const { width } = Dimensions.get('window'); -export default withSuspense(function MySpot() { - const { data: mySpots } = useMySpotsQuery(); - const navigation = useNavigation>(); - const numColumns = 2; - const paddingHorizontal = 8; - const gap = 16; +export default withSuspense( + function MySpot() { + const { data: mySpots } = useMySpotsQuery(); + const navigation = useNavigation>(); + const numColumns = 2; + const paddingHorizontal = 8; + const gap = 16; + + if (mySpots.length === 0) { + return ( + + + 좋아요한 SPOT이 없어요 + + + ); + } - if (mySpots.length === 0) { return ( - - - 좋아요한 SPOT이 없어요 + ( + + navigation.navigate('MyPage/Detail', { + contentId: item.contentId, + id: item.id, + workId: item.workId, + }) + } + /> + )} + keyExtractor={(item) => item.name + item.id + item.contentId} + numColumns={numColumns} + /> + ); + }, + { + fallback: ( + + + 잠시만 + + + 기다려주세요 - ); - } - - return ( - ( - - navigation.navigate('MyPage/Detail', { - contentId: item.contentId, - id: item.id, - workId: item.workId, - }) - } - /> - )} - keyExtractor={(item) => item.name + item.id + item.contentId} - numColumns={numColumns} - /> - ); -}); + ), + }, +); From 14245f28d1a1a2035a48026d706b13d4fef3ed56 Mon Sep 17 00:00:00 2001 From: d0422 Date: Thu, 26 Sep 2024 00:54:13 +0900 Subject: [PATCH 04/12] =?UTF-8?q?feat:=20storage=20delete=20data=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react-native/src/utils/storage.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/react-native/src/utils/storage.ts b/packages/react-native/src/utils/storage.ts index 337b086d..e2c5b152 100644 --- a/packages/react-native/src/utils/storage.ts +++ b/packages/react-native/src/utils/storage.ts @@ -21,7 +21,12 @@ const saveData = async ({ key, value }: SaveDataParams) => { await AsyncStorage.setItem(key, stringifiedObject); }; +const deleteData = async (key: K) => { + AsyncStorage.setItem(key, ''); +}; + export const AppStorage = { getData, saveData, + deleteData, }; From e4080c4091e063bd73dd022a07a1bf843ec01c3f Mon Sep 17 00:00:00 2001 From: d0422 Date: Thu, 26 Sep 2024 00:55:51 +0900 Subject: [PATCH 05/12] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react-native/src/pages/MyPage/EditProfile.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/react-native/src/pages/MyPage/EditProfile.tsx b/packages/react-native/src/pages/MyPage/EditProfile.tsx index b9cacbdd..e8822ba4 100644 --- a/packages/react-native/src/pages/MyPage/EditProfile.tsx +++ b/packages/react-native/src/pages/MyPage/EditProfile.tsx @@ -9,6 +9,7 @@ import { StackNavigation, StackRouteProps } from '@/types/navigation'; import useNicknameMutation from '@/apis/mutations/useNicknameMutation'; import MutationLoadingModal from '@/components/common/MutationLoadingModal'; import useProfileImageMutation from '@/apis/mutations/useProfileImageMutation'; +import { AppStorage } from '@/utils/storage'; interface EditProfileProps { navigation: StackNavigation<'MyPage/EditProfile'>; @@ -76,9 +77,11 @@ export default function EditProfile({ navigation }: EditProfileProps) { 닉네임으로 프로필 사진 설정하기 - {/* FIXME: 로그아웃 기능 추가 */} Alert.alert('로그아웃')} + onPress={async () => { + await AppStorage.deleteData('token'); + navigation.navigate('Login'); + }} className="opacity-50" > From 71cff9b62456a90852cbe21051bf0b85bf9b4cae Mon Sep 17 00:00:00 2001 From: d0422 Date: Thu, 26 Sep 2024 00:58:40 +0900 Subject: [PATCH 06/12] =?UTF-8?q?feat:=20=EC=98=A4=EB=A5=98=EC=8B=9C=20?= =?UTF-8?q?=EC=9E=84=EC=8B=9C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react-native/src/App.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/react-native/src/App.tsx b/packages/react-native/src/App.tsx index bb7fb94e..b1ce33cf 100644 --- a/packages/react-native/src/App.tsx +++ b/packages/react-native/src/App.tsx @@ -2,6 +2,7 @@ import { BottomSheetModalProvider } from '@gorhom/bottom-sheet'; import { NavigationContainer } from '@react-navigation/native'; import StackNavigator from '@routes/StackNavigator'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { Alert } from 'react-native'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; const queryClient = new QueryClient({ @@ -10,6 +11,11 @@ const queryClient = new QueryClient({ retry: false, throwOnError: true, }, + mutations: { + onError: () => { + Alert.alert('오류가 발생했어요', '잠시뒤에 시도해보세요.'); + }, + }, }, }); export default function App() { From a1487c11cd77c6a859b439c3b4c3cfda23de33ac Mon Sep 17 00:00:00 2001 From: d0422 Date: Thu, 26 Sep 2024 02:46:56 +0900 Subject: [PATCH 07/12] =?UTF-8?q?fix:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=B2=88=EC=A9=8D=EC=9D=B4=EB=8A=94=20=EC=9D=B4=EC=8A=88=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react-native/src/pages/Maps/Maps.tsx | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/react-native/src/pages/Maps/Maps.tsx b/packages/react-native/src/pages/Maps/Maps.tsx index 3b101373..d2b2a1c2 100644 --- a/packages/react-native/src/pages/Maps/Maps.tsx +++ b/packages/react-native/src/pages/Maps/Maps.tsx @@ -1,5 +1,12 @@ import { useRef, useState } from 'react'; -import { Dimensions, View, TouchableOpacity, Alert } from 'react-native'; +import { + Dimensions, + View, + TouchableOpacity, + Alert, + ScrollView, + Image as RNImage, +} from 'react-native'; import { Font } from 'design-system'; import { geoPath, geoMercator } from 'd3-geo'; import { Svg, G, Path, Image, Defs, Pattern } from 'react-native-svg'; @@ -13,7 +20,9 @@ import Header from '@/components/common/Header'; import MapSaveButtonIcon from '@/assets/MapSaveButtonIcon'; import MapDownloadIcon from '@/assets/MapDownloadIcon'; import useRecordRepresentativeMutation from '@/apis/mutations/useRecordRepresentativeMutation'; -import useRecordRepresentativeQuery from '@/apis/queries/records/useRecordRepresentativeQuery'; +import useRecordRepresentativeQuery, { + RegionRepresentImage, +} from '@/apis/queries/records/useRecordRepresentativeQuery'; import useToggle from '@/hooks/useToggle'; import BottomSheet from '@/components/common/BottomSheet'; import MutationLoadingModal from '@/components/common/MutationLoadingModal'; @@ -93,6 +102,20 @@ export default withSuspense(function Maps({ navigation }: MapsMainProps) { return ( + + {regionImage && + Object.values(regionImage).map( + (value, index) => + value && ( + + ), + )} +
From a9f47b0d8d9033b2717a36f1a35d8ef422a7544e Mon Sep 17 00:00:00 2001 From: d0422 Date: Thu, 26 Sep 2024 03:12:45 +0900 Subject: [PATCH 08/12] =?UTF-8?q?chore:=20image-crop-picker=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react-native/package.json | 1 + yarn.lock | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/packages/react-native/package.json b/packages/react-native/package.json index dbcb62a3..37c70263 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -39,6 +39,7 @@ "react-native-dotenv": "^3.4.11", "react-native-element-dropdown": "^2.12.1", "react-native-gesture-handler": "^2.17.1", + "react-native-image-crop-picker": "^0.41.2", "react-native-image-picker": "^7.1.2", "react-native-linear-gradient": "^2.8.3", "react-native-mail": "^6.1.1", diff --git a/yarn.lock b/yarn.lock index 03f20a90..f296b182 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14740,6 +14740,15 @@ __metadata: languageName: node linkType: hard +"react-native-image-crop-picker@npm:^0.41.2": + version: 0.41.2 + resolution: "react-native-image-crop-picker@npm:0.41.2" + peerDependencies: + react-native: ">=0.40.0" + checksum: c1333b3b761e948bd0bc856773f68dcc859c7ce39dda3e14d2c32c17d55927735bfc5cbbb7ac5e8bac21feda87c93399f2a596aca7d5b0611cc1e8203d97ad2e + languageName: node + linkType: hard + "react-native-image-picker@npm:^7.1.2": version: 7.1.2 resolution: "react-native-image-picker@npm:7.1.2" @@ -15001,6 +15010,7 @@ __metadata: react-native-dotenv: ^3.4.11 react-native-element-dropdown: ^2.12.1 react-native-gesture-handler: ^2.17.1 + react-native-image-crop-picker: ^0.41.2 react-native-image-picker: ^7.1.2 react-native-linear-gradient: ^2.8.3 react-native-mail: ^6.1.1 From 33913770a7e20cf1e2bbb9cf27fc1ef1c5ce5003 Mon Sep 17 00:00:00 2001 From: d0422 Date: Thu, 26 Sep 2024 03:13:05 +0900 Subject: [PATCH 09/12] =?UTF-8?q?feat:=20getCropPhoto=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react-native/src/hooks/useGallery.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/react-native/src/hooks/useGallery.ts b/packages/react-native/src/hooks/useGallery.ts index 57ed7c3d..ebb65e9b 100644 --- a/packages/react-native/src/hooks/useGallery.ts +++ b/packages/react-native/src/hooks/useGallery.ts @@ -1,5 +1,6 @@ import { CameraRoll } from '@react-native-camera-roll/camera-roll'; import { Alert, Linking, Platform } from 'react-native'; +import ImageCropPicker from 'react-native-image-crop-picker'; import { Asset, launchImageLibrary } from 'react-native-image-picker'; import { check, @@ -126,5 +127,18 @@ export default function useGallery() { return response.assets[0].uri as GetPhotoReturnType; }; - return { savePhoto, getPhoto }; + const getCropPhoto = async () => { + const hasPermission = await hasGalleryPermission('read'); + if (!hasPermission) return Promise.reject(); + + const result = await ImageCropPicker.openPicker({ + width: 300, + height: 300, + cropping: true, + mediaType: 'photo', + }); + return result; + }; + + return { savePhoto, getPhoto, getCropPhoto }; } From 99cf6588f5dd629ea2d2ee32768ee23aebf73c8d Mon Sep 17 00:00:00 2001 From: d0422 Date: Thu, 26 Sep 2024 03:15:36 +0900 Subject: [PATCH 10/12] =?UTF-8?q?feat:=20customForm=20image=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=ED=95=9C=20=ED=83=80=EC=9E=85=EC=9D=84=20=EB=AA=A8?= =?UTF-8?q?=EB=91=90=20=ED=8F=BC=EC=97=90=20=EC=B6=94=EA=B0=80=20=ED=95=A0?= =?UTF-8?q?=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react-native/src/utils/CustomForm.ts | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/react-native/src/utils/CustomForm.ts b/packages/react-native/src/utils/CustomForm.ts index 6b82f32c..dfb142bc 100644 --- a/packages/react-native/src/utils/CustomForm.ts +++ b/packages/react-native/src/utils/CustomForm.ts @@ -1,5 +1,6 @@ import { Platform } from 'react-native'; import { Asset } from 'react-native-image-picker'; +import { Image } from 'react-native-image-crop-picker'; import { getDateString, normalizeDate } from './date'; class CustomForm { @@ -13,12 +14,28 @@ class CustomForm { this.#form.append(key, value); } - appendImage(key: string, image: Asset) { + appendImage(key: string, image: Asset | Image) { + if ((image as Image).mime) { + const cropedImage = image as Image; + this.#form.append(key, { + name: `${getDateString(normalizeDate())}`, + type: cropedImage.mime, + uri: + Platform.OS === 'ios' + ? cropedImage.path?.replace('file://', '') + : cropedImage.path, + }); + return; + } + + const normalImage = image as Asset; this.#form.append(key, { - name: `${getDateString(normalizeDate())}_${image.fileName}`, - type: image.type, + name: `${getDateString(normalizeDate())}_${normalImage.fileName}`, + type: normalImage.type, uri: - Platform.OS === 'ios' ? image.uri?.replace('file://', '') : image.uri, + Platform.OS === 'ios' + ? normalImage.uri?.replace('file://', '') + : normalImage.uri, }); } From 7716ab9a3daddb81d6d5fc8a1c97b9ac2de4e245 Mon Sep 17 00:00:00 2001 From: d0422 Date: Thu, 26 Sep 2024 03:16:09 +0900 Subject: [PATCH 11/12] =?UTF-8?q?feat:=20crop=EB=90=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=EB=A5=BC=20=EB=8C=80=ED=91=9C=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=EB=A1=9C=20=EC=84=A4=EC=A0=95=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../useRecordRepresentativeMutation.ts | 4 ++-- packages/react-native/src/hooks/useGallery.ts | 19 +++++++++++-------- packages/react-native/src/pages/Maps/Maps.tsx | 4 ++-- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/react-native/src/apis/mutations/useRecordRepresentativeMutation.ts b/packages/react-native/src/apis/mutations/useRecordRepresentativeMutation.ts index 81cafd7e..eee8689e 100644 --- a/packages/react-native/src/apis/mutations/useRecordRepresentativeMutation.ts +++ b/packages/react-native/src/apis/mutations/useRecordRepresentativeMutation.ts @@ -1,6 +1,6 @@ import { Alert } from 'react-native'; import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { Asset } from 'react-native-image-picker'; +import { Image } from 'react-native-image-crop-picker'; import { REGION_MAPPER } from '@/constants/CITY'; import { KoreaLocationName } from '@/types/map'; import { AppStorage } from '@/utils/storage'; @@ -10,7 +10,7 @@ import QUERY_KEYS from '@/constants/QUERY_KEYS'; interface MutationRequestParams { region: KoreaLocationName; - image: Asset; + image: Image; } export default function useRecordRepresentativeMutation() { diff --git a/packages/react-native/src/hooks/useGallery.ts b/packages/react-native/src/hooks/useGallery.ts index ebb65e9b..07ee2887 100644 --- a/packages/react-native/src/hooks/useGallery.ts +++ b/packages/react-native/src/hooks/useGallery.ts @@ -130,14 +130,17 @@ export default function useGallery() { const getCropPhoto = async () => { const hasPermission = await hasGalleryPermission('read'); if (!hasPermission) return Promise.reject(); - - const result = await ImageCropPicker.openPicker({ - width: 300, - height: 300, - cropping: true, - mediaType: 'photo', - }); - return result; + try { + const result = await ImageCropPicker.openPicker({ + width: 300, + height: 300, + cropping: true, + mediaType: 'photo', + }); + return result; + } catch (err) { + return null; + } }; return { savePhoto, getPhoto, getCropPhoto }; diff --git a/packages/react-native/src/pages/Maps/Maps.tsx b/packages/react-native/src/pages/Maps/Maps.tsx index d2b2a1c2..00f54dfa 100644 --- a/packages/react-native/src/pages/Maps/Maps.tsx +++ b/packages/react-native/src/pages/Maps/Maps.tsx @@ -59,7 +59,7 @@ const REGION_PATTERN_SIZE: Record< export default withSuspense(function Maps({ navigation }: MapsMainProps) { const [region, setRegion] = useState(); - const { getPhoto, savePhoto } = useGallery(); + const { savePhoto, getCropPhoto } = useGallery(); const [isButtonClicked, setButtonClicked] = useState(false); const [showBottomSheet, toggleBottomSheet] = useToggle(); const ref = useRef(null); @@ -77,7 +77,7 @@ export default withSuspense(function Maps({ navigation }: MapsMainProps) { const handleAddRegionImage = async (regionName: KoreaLocationName) => { toggleBottomSheet(); - const photo = await getPhoto({ fullObject: true }); + const photo = await getCropPhoto(); if (!photo) { Alert.alert('이미지가 선택되지 않았습니다!'); From c89f7e3edb498df784ac41fdb26de31bbc7b8308 Mon Sep 17 00:00:00 2001 From: d0422 Date: Thu, 26 Sep 2024 03:23:43 +0900 Subject: [PATCH 12/12] =?UTF-8?q?fix:=20=EC=A7=80=EB=8F=84=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EA=B3=A0=EC=A0=95=20=EB=A0=8C=EB=8D=94?= =?UTF-8?q?=EB=A7=81=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react-native/src/pages/Maps/Maps.tsx | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/react-native/src/pages/Maps/Maps.tsx b/packages/react-native/src/pages/Maps/Maps.tsx index 00f54dfa..217e6278 100644 --- a/packages/react-native/src/pages/Maps/Maps.tsx +++ b/packages/react-native/src/pages/Maps/Maps.tsx @@ -20,9 +20,7 @@ import Header from '@/components/common/Header'; import MapSaveButtonIcon from '@/assets/MapSaveButtonIcon'; import MapDownloadIcon from '@/assets/MapDownloadIcon'; import useRecordRepresentativeMutation from '@/apis/mutations/useRecordRepresentativeMutation'; -import useRecordRepresentativeQuery, { - RegionRepresentImage, -} from '@/apis/queries/records/useRecordRepresentativeQuery'; +import useRecordRepresentativeQuery from '@/apis/queries/records/useRecordRepresentativeQuery'; import useToggle from '@/hooks/useToggle'; import BottomSheet from '@/components/common/BottomSheet'; import MutationLoadingModal from '@/components/common/MutationLoadingModal'; @@ -38,23 +36,23 @@ const REGION_PATTERN_SIZE: Record< KoreaLocationName, { size: number; x: number; y: number } > = { - 강원도: { size: 0.47, x: -20, y: 30 }, + 강원도: { size: 0.5, x: -60, y: 0 }, 경기도: { size: 0.4, x: -80, y: 60 }, - 경상남도: { size: 0.3, x: 80, y: 120 }, - 경상북도: { size: 0.4, x: 40, y: -140 }, + 경상남도: { size: 0.3, x: 80, y: 100 }, + 경상북도: { size: 0.45, x: 20, y: -180 }, 광주광역시: { size: 0.08, x: 4, y: 4 }, 대구광역시: { size: 0.2, x: -10, y: 8 }, 대전광역시: { size: 0.1, x: -6, y: -8 }, 부산광역시: { size: 0.15, x: -10, y: 60 }, - 서울특별시: { size: 0.1, x: 0, y: 20 }, + 서울특별시: { size: 0.15, x: -10, y: 30 }, 세종특별자치시: { size: 0.1, x: 15, y: 50 }, 울산광역시: { size: 0.2, x: -20, y: 40 }, 인천광역시: { size: 0.2, x: -20, y: -15 }, - 전라남도: { size: 0.35, x: -80, y: 20 }, - 전라북도: { size: 0.25, x: 0, y: 130 }, + 전라남도: { size: 0.35, x: -80, y: 85 }, + 전라북도: { size: 0.25, x: 0, y: 120 }, 제주특별자치도: { size: 0.3, x: 40, y: 80 }, - 충청남도: { size: 0.3, x: -50, y: -20 }, - 충청북도: { size: 0.27, x: -50, y: 0 }, + 충청남도: { size: 0.3, x: -50, y: -30 }, + 충청북도: { size: 0.4, x: -40, y: 160 }, }; export default withSuspense(function Maps({ navigation }: MapsMainProps) {