From a1f4bf216c17659a5c360301c1b9714a21723ca8 Mon Sep 17 00:00:00 2001 From: Chi Hoon Choi <102471757+watchiswatch@users.noreply.github.com> Date: Sun, 14 Jan 2024 16:43:15 +0900 Subject: [PATCH] =?UTF-8?q?[Refactor][BottomSheet]=20upload=20screen=20?= =?UTF-8?q?=EB=B0=94=ED=85=80=EC=8B=9C=ED=8A=B8=20=EB=86=92=EC=9D=B4?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20&=20=EC=9E=90=EC=9E=98=ED=95=9C=20?= =?UTF-8?q?=EB=94=94=EC=9E=90=EC=9D=B8=20=EA=B5=90=EC=A0=95=20(#270)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 잘못된 margin 수정 * fix: 수정 시 뒤로가기 모달 수정 * fix: 폴더 선택 바텀 시트를 키보드 높이에 동적으로 적용되어 위치하도록 작업 했으나, 키보드가 최소 한 번은 나타나야 그 높이를 알 수 있어서, 처음 열때는 정적 높이를 지정할 수 없는 상태로 우선 push * chore: 콘솔 제거 * upload screen 초입 시 autoFocus가 있으면 keyboard를 띄우고 시작할 수 있음을 깨달음 * android에서 contitinal button 의 글자가 희미한 현상 해결을 위해 색상을 투명도가 아닌 hex로 조정. 이것이 해결책이 될지는 불확실 * fix: 예외처리 추가 * fix: folder 삭제 모달 디자인 수정 --- .../bottomsheet/SheetPostOptions.tsx | 10 +- src/components/buttons/ConditionalButton.tsx | 6 +- .../challenge/ChallengeParticipationView.tsx | 4 +- .../comments/CommentVerticalDots.tsx | 2 +- .../comments/SheetOthersComment.tsx | 3 +- src/components/modal/TwoButtonModal.tsx | 10 +- .../texts/StaticSizeScrollTextArea.tsx | 2 + src/screens/Feed/FeedVerticalDots.tsx | 2 +- .../folderSettings/FolderEditScreen.tsx | 2 +- .../folderSettings/FolderEditSection.tsx | 12 +- src/screens/upload/FolderSheetContent.tsx | 120 +++++++++--------- src/screens/upload/LinkSheetContent.tsx | 2 +- src/screens/upload/UploadScreen.tsx | 65 +++++++--- 13 files changed, 137 insertions(+), 103 deletions(-) diff --git a/src/components/bottomsheet/SheetPostOptions.tsx b/src/components/bottomsheet/SheetPostOptions.tsx index a08fbae9..5a7979b3 100644 --- a/src/components/bottomsheet/SheetPostOptions.tsx +++ b/src/components/bottomsheet/SheetPostOptions.tsx @@ -5,12 +5,13 @@ import { BottomSheetModalMethods } from '@gorhom/bottom-sheet/lib/typescript/typ import { Feather } from '@expo/vector-icons'; import ConditionalButton from '../buttons/ConditionalButton'; import TwoButtonModal from '../modal/TwoButtonModal'; -import { reportInsight, reportType } from '../../utils/api/report/insight/insightReport'; +import { reportInsight } from '../../utils/api/report/insight/insightReport'; import { Toast } from 'react-native-toast-message/lib/src/Toast'; import DetailReportSheetContent from '../../screens/detailedPost/DetailReportSheetContent'; import { blockApi } from '../../utils/api/block/block'; import { useNavigation } from '@react-navigation/native'; import { InsightAPI } from '../../utils/api/InsightAPI'; +import { reportType } from '../../utils/api/report/comment/commentReport'; interface BSPostOptionsProps { modalRef: React.RefObject; @@ -39,7 +40,6 @@ const SheetPostOptions = ({ const [isModalVisible, setIsModalVisible] = useState(false); const [selectedReport, setSelectedReport] = useState(null); const [reportText, setReportText] = useState(''); - const [isSnackBarVisible, setIsSnackBarVisible] = useState(false); const screenWidth = Dimensions.get('window').width; const navigation = useNavigation(); @@ -147,7 +147,7 @@ const SheetPostOptions = ({ 기타 신고 사유 - + - {text} + {text} @@ -83,6 +82,5 @@ const styles = StyleSheet.create({ text: { fontWeight: '600', fontSize: 18, - color: 'white', }, }); diff --git a/src/components/challenge/ChallengeParticipationView.tsx b/src/components/challenge/ChallengeParticipationView.tsx index d5daf3a8..42e1cc78 100644 --- a/src/components/challenge/ChallengeParticipationView.tsx +++ b/src/components/challenge/ChallengeParticipationView.tsx @@ -27,7 +27,7 @@ const ChallengeParticipationView = ({ () => getFormattedDateArray(startDate as string, dayProgresses as []), [current, insightPerWeek, startDate, endDate, dayProgresses], ); - const firstDay = formattedWeekWithCheck[0].day; + const firstDay = formattedWeekWithCheck[0]?.day ?? ''; return ( @@ -45,7 +45,7 @@ const ChallengeParticipationView = ({ return ( {today === challenge.day && } - + {challenge.day} ); diff --git a/src/components/comments/CommentVerticalDots.tsx b/src/components/comments/CommentVerticalDots.tsx index 93cd2ad3..ba4287a4 100644 --- a/src/components/comments/CommentVerticalDots.tsx +++ b/src/components/comments/CommentVerticalDots.tsx @@ -21,7 +21,7 @@ const CommentVerticalDots = ({ userId, userName, commentId }: FeedVerticalDotsPr const handleLayout = (event) => { const height = event.nativeEvent.layout.height; - setContentHeight(height + 50); + setContentHeight(height + 76); }; const renderBackdrop = useCallback( diff --git a/src/components/comments/SheetOthersComment.tsx b/src/components/comments/SheetOthersComment.tsx index cca2050c..ec7746e5 100644 --- a/src/components/comments/SheetOthersComment.tsx +++ b/src/components/comments/SheetOthersComment.tsx @@ -26,7 +26,6 @@ const SheetOthersComment = ({ modalRef, userId, userName, commentId }: BSPostOpt const [isModalVisible, setIsModalVisible] = useState(false); const [selectedReport, setSelectedReport] = useState(null); const [reportText, setReportText] = useState(''); - const [isSnackBarVisible, setIsSnackBarVisible] = useState(false); const screenWidth = Dimensions.get('window').width; const handlePress = () => { @@ -146,7 +145,7 @@ const SheetOthersComment = ({ modalRef, userId, userName, commentId }: BSPostOpt ))} - 기타 사유 신고 + 기타 신고 사유 diff --git a/src/components/modal/TwoButtonModal.tsx b/src/components/modal/TwoButtonModal.tsx index e507bb38..1069ec36 100644 --- a/src/components/modal/TwoButtonModal.tsx +++ b/src/components/modal/TwoButtonModal.tsx @@ -43,8 +43,8 @@ const TwoButtonModal = ({ { const theme = useTheme(); @@ -44,6 +45,7 @@ const StaticSizeScrollTextArea = ({ numberOfLines={16} scrollEnabled={true} textAlignVertical="top" + autoFocus={autoFocus} /> diff --git a/src/screens/Feed/FeedVerticalDots.tsx b/src/screens/Feed/FeedVerticalDots.tsx index 979baf48..d3f38288 100644 --- a/src/screens/Feed/FeedVerticalDots.tsx +++ b/src/screens/Feed/FeedVerticalDots.tsx @@ -39,7 +39,7 @@ const FeedVerticalDots = ({ const handleLayout = (event) => { const height = event.nativeEvent.layout.height; - setContentHeight(height + 50); + setContentHeight(height + 72); }; const renderBackdrop = useCallback( diff --git a/src/screens/settings/folderSettings/FolderEditScreen.tsx b/src/screens/settings/folderSettings/FolderEditScreen.tsx index d8a53088..3b31d975 100644 --- a/src/screens/settings/folderSettings/FolderEditScreen.tsx +++ b/src/screens/settings/folderSettings/FolderEditScreen.tsx @@ -79,7 +79,7 @@ const FolderEditScreen = ({ navigation }) => { diff --git a/src/screens/settings/folderSettings/FolderEditSection.tsx b/src/screens/settings/folderSettings/FolderEditSection.tsx index b578129b..bf790465 100644 --- a/src/screens/settings/folderSettings/FolderEditSection.tsx +++ b/src/screens/settings/folderSettings/FolderEditSection.tsx @@ -1,5 +1,5 @@ import { Pressable, StyleSheet, Text, View } from 'react-native'; -import React, { useCallback, useLayoutEffect, useRef, useState } from 'react'; +import React, { useCallback, useRef, useState } from 'react'; import { SvgXml } from 'react-native-svg'; import { roundedMinus } from '../../../../assets/images/user/settings/folder/rounded_minus'; import { ScrollView } from 'react-native-gesture-handler'; @@ -8,19 +8,20 @@ import BottomSheetHeader from '../../../components/header/BottomSheetHeader'; import HeaderRightButton from '../../../components/header/HeaderRightButton'; import BlandTextInput from '../../../components/texts/BlandTextInput'; import { BottomSheetBackdrop, BottomSheetModal } from '@gorhom/bottom-sheet'; -import { UploadApis } from '../../../utils/api/UploadAPIs'; import { Toast } from 'react-native-toast-message/lib/src/Toast'; import { MypageQueryKeys } from '../../../utils/api/mypageAPI'; -import { Updater, useQueryClient } from '@tanstack/react-query'; +import { useQueryClient } from '@tanstack/react-query'; import { drawerApi } from '../../../utils/api/drawer/drawerApi'; import { getUserId } from '../../../utils/hooks/asyncStorage/Login'; import { useGetUserId } from '../../../utils/hooks/useGetUserId'; +import { useTheme } from 'react-native-paper'; interface FolderEditSectionProps { userFolderList: FolderData[]; } const FolderEditSection = ({ userFolderList }: FolderEditSectionProps) => { + const theme = useTheme(); const [isModalVisible, setIsModalVisible] = useState(false); const [pressedFolderId, setPressedFolderId] = useState(null); const [folderName, setFolderName] = useState(''); @@ -130,7 +131,7 @@ const FolderEditSection = ({ userFolderList }: FolderEditSectionProps) => { @@ -161,11 +162,12 @@ const FolderEditSection = ({ userFolderList }: FolderEditSectionProps) => { dismissable={true} visible={isModalVisible} onDismiss={() => setIsModalVisible(false)} - mainTitle="폴더 삭제" + mainTitle="폴더를 삭제할까요?" leftButtonText="취소" rightButtonText="삭제하기" leftButtonPress={() => setIsModalVisible(false)} rightButtonPress={handleDeleteFolder} + rightButtonColor={theme.colors.graphic.red} /> ); diff --git a/src/screens/upload/FolderSheetContent.tsx b/src/screens/upload/FolderSheetContent.tsx index 180960f8..7e039973 100644 --- a/src/screens/upload/FolderSheetContent.tsx +++ b/src/screens/upload/FolderSheetContent.tsx @@ -1,30 +1,34 @@ -import { Pressable, StyleSheet, Text, View } from 'react-native'; +import { LayoutChangeEvent, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native'; import React, { useState } from 'react'; import BottomSheetHeader from '../../components/header/BottomSheetHeader'; import HeaderRightButton from '../../components/header/HeaderRightButton'; import Folder from '../../components/Folder/Folder'; import BlandTextInput from '../../components/texts/BlandTextInput'; -import { BottomSheetScrollView, useBottomSheet } from '@gorhom/bottom-sheet'; +import { useBottomSheet } from '@gorhom/bottom-sheet'; import { backButtonModalClose } from '../../utils/helper/bottomSheetUtils/bottomSheetUtils'; import { IFolder } from '../../types/upload'; import { useTheme } from 'react-native-paper'; interface FolderSheetContentProps { + scrollViewHeight?: number; onHeaderLeftPress: () => void; handleSheetComplete: () => void; setFolder: React.Dispatch>; selectedFolder: string; setSelectedFolder: React.Dispatch>; folders: IFolder[]; + onLayout?: (event: LayoutChangeEvent) => void; } const FolderSheetContent = ({ + scrollViewHeight, onHeaderLeftPress, handleSheetComplete, setFolder, setSelectedFolder, folders, selectedFolder, + onLayout, }: FolderSheetContentProps) => { const theme = useTheme(); const [createFolder, setCreateFolder] = useState(false); @@ -35,67 +39,67 @@ const FolderSheetContent = ({ setCreateFolder(true); }; - return ( - - {createFolder ? ( - <> - ( - - )} - /> + return createFolder ? ( + + + ( + + )} + /> - - - - - ) : ( - <> + + + + + + ) : ( + + + {folders.map((folder) => { + return ( - {folders.map((folder, index) => { - return ( - - ); - })} - - - 새 폴더 만들기 - - - - )} - + ); + })} + + + 새 폴더 만들기 + + + ); }; @@ -104,8 +108,6 @@ export default FolderSheetContent; const styles = StyleSheet.create({ contentContainer: { width: '100%', - // BottomSheetScrollView height makes it not scrollable - // height: '80%', flexDirection: 'column', justifyContent: 'flex-start', }, diff --git a/src/screens/upload/LinkSheetContent.tsx b/src/screens/upload/LinkSheetContent.tsx index eadabdcf..342bb506 100644 --- a/src/screens/upload/LinkSheetContent.tsx +++ b/src/screens/upload/LinkSheetContent.tsx @@ -57,7 +57,7 @@ export default LinkSheetContent; const styles = StyleSheet.create({ contentContainer: { width: '100%', - height: '80%', + height: 250, flexDirection: 'column', justifyContent: 'flex-start', }, diff --git a/src/screens/upload/UploadScreen.tsx b/src/screens/upload/UploadScreen.tsx index 44c89e77..70db2a11 100644 --- a/src/screens/upload/UploadScreen.tsx +++ b/src/screens/upload/UploadScreen.tsx @@ -1,6 +1,6 @@ import { BottomSheetBackdrop, BottomSheetModal } from '@gorhom/bottom-sheet'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { SafeAreaView, ScrollView, StyleSheet, View } from 'react-native'; +import { Keyboard, SafeAreaView, ScrollView, StyleSheet, View } from 'react-native'; import DividerBar from '../../components/bars/DividerBar'; import InsightLinkTriggerButton from '../../components/buttons/InsightLinkTriggerButton'; import UploadLinkCard from '../../components/cards/LinkCardForUpload'; @@ -29,7 +29,6 @@ import TwoButtonModal from '../../components/modal/TwoButtonModal'; import isTextNotOnlySpace from '../../utils/helper/strings/isTextNotOnlySpace'; import { useFocusEffect } from '@react-navigation/native'; import * as Clipboard from 'expo-clipboard'; -import isDarkMode from '../../utils/helper/display/isDarkMode'; const UploadScreen = ({ navigation, route }) => { const { isEdit, link, insightId } = route?.params ?? {}; @@ -43,6 +42,9 @@ const UploadScreen = ({ navigation, route }) => { const folderSheetRef = useRef(null); const [isLoading, setIsLoading] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false); + const [linkSheetContentHeight, setLinkSheetContentHeight] = useState(400); + const [folderSheetContentHeight, setFolderSheetContentHeight] = useState(400); + const [keyboardHeight, setKeyboardHeight] = useState(0); const queryClient = useQueryClient(); const theme = useTheme(); @@ -63,7 +65,9 @@ const UploadScreen = ({ navigation, route }) => { ChallengeAPI.getChallengeProgress, ); - const snapPoints = useMemo(() => ['50%', '80%'], []); + const linkSheetSnapPoints = [linkSheetContentHeight]; + + const folderSheetSnapPoints = [folderSheetContentHeight]; const insightTextLimit = 400; @@ -99,6 +103,14 @@ const UploadScreen = ({ navigation, route }) => { useEffect(() => { UploadApis.getFolderList().then(setFolders); + + const keyboardShowListener = Keyboard.addListener('keyboardDidShow', (e) => { + setKeyboardHeight(e.endCoordinates.height); + }); + + return () => { + keyboardShowListener.remove(); + }; }, []); const handleSubmit = async () => { @@ -158,6 +170,18 @@ const UploadScreen = ({ navigation, route }) => { ); }; + const handleLinkSheetLayout = (event) => { + const height = event.nativeEvent.layout.height; + const additinalHeight = keyboardHeight || 350; + setLinkSheetContentHeight(height + additinalHeight); + }; + + const handleFolderSheetLayout = (event) => { + const height = event.nativeEvent.layout.height; + const additinalHeight = keyboardHeight || 350; + setFolderSheetContentHeight(height + additinalHeight); + }; + const handleEditPress = () => { setIsValidSite(false); handleSheetPresent(linkSheetRef); @@ -190,7 +214,6 @@ const UploadScreen = ({ navigation, route }) => { useCallback(() => { const getClipboard = async () => { const clipboard = await Clipboard.getStringAsync(); - console.log(`darkmode: ${isDarkMode()}`); if (clipboard.startsWith('http')) { try { await fetch(clipboard, { @@ -238,7 +261,7 @@ const UploadScreen = ({ navigation, route }) => { placeholder="인사이트를 입력해주세요." limit={insightTextLimit} height={280} - autoFocus={false} + autoFocus={true} /> @@ -253,39 +276,45 @@ const UploadScreen = ({ navigation, route }) => { - handleSheetClose(linkSheetRef)} - /> + + handleSheetClose(linkSheetRef)} + /> + handleSheetClose(folderSheetRef)} + onHeaderLeftPress={() => { + handleSheetClose(folderSheetRef); + }} folders={folders} setFolder={setFolders} selectedFolder={selectedFolder} setSelectedFolder={setSelectedFolder} + onLayout={handleFolderSheetLayout} /> setIsModalVisible(false)} - leftButtonText="뒤로가기" + leftButtonText={isEdit ? '취소하기' : '뒤로가기'} rightButtonText="계속 작성하기" leftButtonPress={() => { setIsModalVisible(false);