Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
de377c3
feat: 친구 요청, 삭제 api 추가
wonill Feb 20, 2025
fd9c61a
feat: 친구 요청, 삭제 훅 추가
wonill Feb 20, 2025
bd04147
design: 바텀탭 네비게이터 특정 스크린에서 보이지 않게 설정
wonill Feb 21, 2025
f6227b2
chore: 네비게이션 상수화 및 소셜 네비게이션 구조 세팅
wonill Feb 21, 2025
198f741
feat: 채팅창 FlatList로 교체
wonill Feb 22, 2025
6a16f63
design : flatlist 레이아웃 채팅창 스타일에 맞게 수정
wonill Feb 22, 2025
85399af
feat: 채팅창 KeyboardAvoidingView 적용
wonill Feb 22, 2025
709d190
fix: 안드로이드 이미지 업로드 오류 해결
wonill Feb 22, 2025
7e1c224
스토리북 버튼 숨김
wonill Feb 22, 2025
daf2f13
chore: 사용하지 않는 스토리북 관련 코드 주석처리
wonill Feb 22, 2025
f956f06
feat: 메세지 전송 버튼 추가
wonill Feb 22, 2025
547363b
feat: 채팅방 유저정보 데이터 바인딩
wonill Feb 23, 2025
851c3a0
feat: 채팅방 옵션 컴포넌트 추가
wonill Feb 23, 2025
b985cf6
feat: 유저 차단 api 함수 추가
wonill Feb 23, 2025
6af1cab
feat: 유저 차단 해제 api 함수 추가
wonill Feb 23, 2025
c2d7d33
feat: 차단 목록 조회 api 함수 추가
wonill Feb 23, 2025
1d1b2cc
feat: 채팅방 메시지 조회 api 함수 추가
wonill Feb 23, 2025
cdb3853
fix: 채팅방 목록 조회 api 함수 타입 수정
wonill Feb 23, 2025
06cd14e
feat: 채팅 메시지 조회 쿼리 훅 작성
wonill Feb 23, 2025
43dcd47
feat: 차단 관련 쿼리 훅 작성
wonill Feb 23, 2025
3bb6bd6
feat: 유저 차단, 차단 해제 기능 구현
wonill Feb 23, 2025
b0d4849
feat: 차단 목록 조회 및 해제 기능 구현
wonill Feb 23, 2025
05cff8f
fix: text 태그가 아닌 곳에 문자열이 삽입되어 생긴 오류 해결
wonill Feb 23, 2025
0549059
fix: 채팅방 리스트 조회 탭 타입오류 해결
wonill Feb 24, 2025
27929a5
design: CoumpoundOption 모달 애니메이션 추가
wonill Feb 24, 2025
8f711a8
feat: 차단 목록 없을 시 보여줄 컴포넌트 추가
wonill Feb 24, 2025
d329a48
feat: 소셜 친구 탭에 FriendOption 추가
wonill Feb 24, 2025
693dac1
feat: 친구 목록 옵션 모달 추가
wonill Feb 24, 2025
a269b8b
fix: useUserById 쿼리 훅 타입 오류 수정
wonill Feb 24, 2025
007884b
fix: 프로필 컴포넌트 오류 수정
wonill Feb 24, 2025
48039b2
design: 친구 옵션 프로필 디자인
wonill Feb 24, 2025
6e12293
feat: 친구 삭제 기능 추가
wonill Feb 24, 2025
e9eb305
fix: 차단 기능 오류 수정
wonill Feb 24, 2025
a2f28f8
feat: 채팅 훅 작성
wonill Feb 25, 2025
f7161a2
feat: 채팅 전송 기능 추가
wonill Feb 26, 2025
06cdddc
채팅 더미데이터 추가
wonill Feb 26, 2025
6f89d0e
채팅 더미데이터 삭제
wonill Feb 26, 2025
a378a50
fix : DogProfile margin 수정
kimjuyoung78 Feb 16, 2025
31277c8
feat : 패밀리장 표기(Crown)추가
kimjuyoung78 Feb 16, 2025
c44fa5f
add : crown.svg 추가
kimjuyoung78 Feb 16, 2025
63a1144
feat : React Query 구현 (패밀리 퇴출, 패밀리장 위임)
kimjuyoung78 Feb 17, 2025
7b20419
feat : 패밀리 퇴출하기 단일 선택 기능 추가. ClickFamily컴포넌트 로직 수정
kimjuyoung78 Feb 20, 2025
e5eed88
feat : 패밀리장 위임하기 단일 선택 기능 추가, 주석 삭제
kimjuyoung78 Feb 20, 2025
5300638
feat : 패밀리장 위임, 퇴출 회원 자신 제외
kimjuyoung78 Feb 20, 2025
f174eb3
feat : 패밀리 퇴출하기 기능 구현
kimjuyoung78 Feb 20, 2025
4df2f39
주석삭제
kimjuyoung78 Feb 20, 2025
7196b06
feat : 패밀리장 위임 기능 구현
kimjuyoung78 Feb 20, 2025
43f53f1
feat : 패밀리 나가기 Query 코드 작성
kimjuyoung78 Feb 20, 2025
79ba9c0
feat : 패밀리 들어가기 컴포넌트 추가, 각 경우별 함수 추가
kimjuyoung78 Feb 20, 2025
e375293
feat : familyCount와 userInfo.isRepresentative 조건에 따라 버튼을 동적으로 렌더링 (3가…
kimjuyoung78 Feb 20, 2025
0b9d3eb
feat : Alert 사용, 사용자 확인 절차 추가 및 패밀리장 위임과 나가기 API 호출 안전하게 순차 실행
kimjuyoung78 Feb 22, 2025
5c425e6
feat : 패밀리 구성원(패밀리장 X) 패밀리 나갈 경우 alert 및 deleteFamilyMySelf 함수 실행 추가
kimjuyoung78 Feb 22, 2025
44be7ad
npm install 재설치
kimjuyoung78 Feb 22, 2025
840a86a
feat: 소셜 친구 탭에 FriendOption 추가
wonill Feb 24, 2025
3625116
fix: develop 병합 및 충돌 수정
wonill Feb 27, 2025
eea6b11
feat: 유저 차단 api 함수 추가
wonill Feb 23, 2025
6940f86
feat: 친구 목록 옵션 모달 추가
wonill Feb 24, 2025
dc78e88
fix: useUserById 쿼리 훅 타입 오류 수정
wonill Feb 24, 2025
4a8a6a1
feat: 친구 삭제 기능 추가
wonill Feb 24, 2025
31ab0a6
fix: 차단 기능 오류 수정
wonill Feb 24, 2025
8f817b1
feat: 채팅 훅 작성
wonill Feb 25, 2025
9d1f728
feat: 채팅 전송 기능 추가
wonill Feb 26, 2025
71aec72
feat : 패밀리장 표기(Crown)추가
kimjuyoung78 Feb 16, 2025
4954b14
feat : 패밀리 퇴출하기 단일 선택 기능 추가. ClickFamily컴포넌트 로직 수정
kimjuyoung78 Feb 20, 2025
06b280b
feat : 패밀리 들어가기 컴포넌트 추가, 각 경우별 함수 추가
kimjuyoung78 Feb 20, 2025
73a9cda
feat : familyCount와 userInfo.isRepresentative 조건에 따라 버튼을 동적으로 렌더링 (3가…
kimjuyoung78 Feb 20, 2025
cd5ea84
feat: 소셜 친구 탭에 FriendOption 추가
wonill Feb 24, 2025
210ec60
fix: develop 병합 및 충돌 수정
wonill Feb 27, 2025
7b61785
Merge branch 'develop' into 66-feature/social
wonill Feb 27, 2025
a5500ad
fix: linter 오류 수정
wonill Feb 27, 2025
4e379ee
fix: useEffect 사용규칙 위반 수정
wonill Feb 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 21 additions & 23 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import styled from '@emotion/native';
import { DefaultTheme, NavigationContainer } from '@react-navigation/native';
import { useState } from 'react';
import { AppProviders } from '~providers/AppProviders';
import { lightTheme } from '~styles/theme';
import StoryBookUI from '../.storybook';
import { RootNavigator } from '~navigation/RootNavigator';
import { useWebSocket } from '~hooks/useWebSocket';
import { WebSocketProvider } from '~providers/WebSocketProvider';
Expand Down Expand Up @@ -35,40 +32,41 @@ const MainApp = () => {

export const App = () => {
// const { isMswEnabled } = useInitializeMsw();
const [storybookEnabled, setStorybookEnabled] = useState(false);
// const [storybookEnabled, setStorybookEnabled] = useState(false);

// if (__DEV__ && !isMswEnabled) {
// return <Text>Loading MSW...</Text>;
// }

const toggleStorybook = () => setStorybookEnabled(prev => !prev);
// const toggleStorybook = () => setStorybookEnabled(prev => !prev);

return (
<>
{__DEV__ && (
{/* {__DEV__ && (
<StoryBookFloatingButton onPress={toggleStorybook} activeOpacity={0.8}>
<StoryBookButtonText>S</StoryBookButtonText>
</StoryBookFloatingButton>
)}
{__DEV__ && storybookEnabled ? <StoryBookUI /> : <MainApp />}
{__DEV__ && storybookEnabled ? <StoryBookUI /> : <MainApp />} */}
<MainApp />
</>
);
};

const StoryBookFloatingButton = styled.TouchableOpacity`
position: absolute;
right: 30px;
bottom: 30px;
z-index: 1000;
width: 60px;
height: 60px;
border-radius: 30px;
background-color: purple;
align-items: center;
justify-content: center;
`;
// const StoryBookFloatingButton = styled.TouchableOpacity`
// position: absolute;
// right: 30px;
// bottom: 30px;
// z-index: 1000;
// width: 60px;
// height: 60px;
// border-radius: 30px;
// background-color: purple;
// align-items: center;
// justify-content: center;
// `;

const StoryBookButtonText = styled.Text`
color: white;
font-size: 24px;
`;
// const StoryBookButtonText = styled.Text`
// color: white;
// font-size: 24px;
// `;
10 changes: 1 addition & 9 deletions src/apis/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,7 @@ export const api = ky.create({
async request => {
const accessToken = await getAccessToken();
if (accessToken) {
request.headers.set(
'Authorization',
// accessToken,
// `Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBY2Nlc3NUb2tlbiIsInByb3ZpZGVyIjoiS0FLQU8iLCJleHAiOjE3Mzk3NjQwMDIsImVtYWlsIjoibWtoNjc5M0BuYXZlci5jb20ifQ.EF03NpevMSZ2DcM5Q-trEEmRa0KEb5HpJ1HlD-Vj8xy3N2JoFvdQFoWDJRM3IGVwx58L9T2oV7GBTr6wJOevnA`,
// 패밀리장, 가족많음
// `Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBY2Nlc3NUb2tlbiIsInByb3ZpZGVyIjoiR09PR0xFIiwiZXhwIjoxNzQwMjQ4MjA3LCJlbWFpbCI6ImJibGJibGFuNjlAZ21haWwuY29tIn0.CpauBw9_yXlYQjr-BZP7xqm1u63pj1g1aM3kX9HwCm37BMhpOQGz1Mq8R42CihtC8henTRy0OHaxa7q9-1Svzw`,
//나 혼자 패밀리장
`Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBY2Nlc3NUb2tlbiIsInByb3ZpZGVyIjoiS0FLQU8iLCJleHAiOjE3NDEyNzUwNjcsImVtYWlsIjoibndpNjk1OUBnbWFpbC5jb20ifQ.pOk3HSBSFGPKGIL4KS7tbwCrzPfCloQZrA4xWzZVpngYTnodSZuenuoUYRC1DkWY-EdmvK-cv_am2EnPryhsxg`,
);
request.headers.set('Authorization', `Bearer ${accessToken}`);
}
},
],
Expand Down
23 changes: 23 additions & 0 deletions src/apis/block/blockUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { HTTPError } from 'ky';
import { api } from '~apis/api';
import { APIResponse } from '~types/api';

export interface ResponseBlockUser {
blockId: number;
blockerMemberId: number;
blockedMemberId: number;
blockedMemberName: string;
}

export const blockUser = async (blockedId: number): Promise<APIResponse<ResponseBlockUser>> => {
try {
const response = await api.post(`block/${blockedId}`).json<APIResponse<ResponseBlockUser>>();
return response;
} catch (error) {
if (error instanceof HTTPError) {
const errorData = await error.response.json();
console.error(errorData);
}
throw error;
}
};
52 changes: 52 additions & 0 deletions src/apis/block/fetchBlockedUsers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { HTTPError } from 'ky';
import { api } from '~apis/api';
import { APIResponse } from '~types/api';
import { FamilyRole } from '~types/family-role';
import { Gender } from '~types/gender';

export interface BlockedUser {
blockId: number;
blockedMemberName: string;
memberGender: Gender;
familyRole: FamilyRole;
}

interface Sort {
unsorted: boolean;
sorted: boolean;
empty: boolean;
}

interface Pageable {
pageNumber: number;
pageSize: number;
paged: boolean;
unpaged: boolean;
offset: number;
sort: Sort;
}

export interface ResponseBlockList {
pageable: Pageable;
numberOfElements: number;
size: number;
content: BlockedUser[];
number: number;
sort: Sort;
first: boolean;
last: boolean;
empty: boolean;
}

export const fetchBlockedUsers = async (page = 0): Promise<APIResponse<ResponseBlockList>> => {
try {
const response = await api.get(`block/list?page=${page}`).json<APIResponse<ResponseBlockList>>();
return response;
} catch (error) {
if (error instanceof HTTPError) {
const errorData = error.response.json();
console.error(errorData);
}
throw error;
}
};
16 changes: 16 additions & 0 deletions src/apis/block/unblockUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { HTTPError } from 'ky';
import { api } from '~apis/api';
import { APIResponse } from '~types/api';

export const unblockUser = async (blockId: number): Promise<APIResponse<string>> => {
try {
const response = await api.delete(`block/${blockId}`).json<APIResponse<string>>();
return response;
} catch (error) {
if (error instanceof HTTPError) {
const errorData = await error.response.json();
console.error(errorData);
}
throw error;
}
};
47 changes: 47 additions & 0 deletions src/apis/block/useBlock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useMutation, useSuspenseQuery } from '@tanstack/react-query';
import { blockUser } from '~apis/block/blockUser';
import { UseMutationCustomOptions } from '~types/api';
import { unblockUser } from './unblockUser';
import { BlockedUser, fetchBlockedUsers } from '~apis/block/fetchBlockedUsers';

const useBlockedUserList = () => {
return useSuspenseQuery({
queryKey: ['allBlockedUsers'],
queryFn: async () => {
let allData: BlockedUser[] = [];
let currentPage = 0;
let isLastPage = false;

while (!isLastPage) {
const response = await fetchBlockedUsers(currentPage);
allData = [...allData, ...response.data.content];
isLastPage = response.data.last;
currentPage += 1;
}

return allData;
},
});
};

const useBlockUser = (mutationOptions?: UseMutationCustomOptions) => {
return useMutation({
mutationFn: (blockedId: number) => blockUser(blockedId),
...mutationOptions,
});
};

const useUnblockUser = (mutationOptions?: UseMutationCustomOptions) => {
return useMutation({
mutationFn: (blockId: number) => unblockUser(blockId),
...mutationOptions,
});
};

export const useBlock = () => {
const blockedUsers = useBlockedUserList().data;
const blockUserMutation = useBlockUser();
const unblockUserMutation = useUnblockUser();

return { blockedUsers, blockUserMutation, unblockUserMutation };
};
73 changes: 73 additions & 0 deletions src/apis/chat/fetchChatMessages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { HTTPError } from 'ky';
import { api } from '~apis/api';
import { APIResponse } from '~types/api';
import { BooleanString } from '~types/boolean-string';
import { FamilyRole } from '~types/family-role';
import { Gender } from '~types/gender';

interface Sort {
unsorted: boolean;
sorted: boolean;
empty: boolean;
}

interface Pageble {
pageNumber: number;
pageSize: number;
paged: boolean;
unpaged: boolean;
offset: number;
sort: Sort;
}

interface MemberInfo {
memberId: number;
memberName: string;
email: string;
memberGender: Gender;
familyRole: FamilyRole;
memberProfileImg: number;
}

interface ChatContent {
chatId: number;
createdAt: string;
updatedAt: string;
chatRoomId: number;
memberInfo: MemberInfo;
chatType: string;
isRead: BooleanString;
text: string;
}

export interface ResponseFetchChatMessages {
pageable: Pageble;
numberOfElements: number;
size: number;
content: ChatContent[];
number: number;
sort: Sort;
first: boolean;
last: boolean;
empty: boolean;
}

export const fetchChatMessages = async (
chatRoomId: number,
lastMessageCreatedAt: string,
): Promise<APIResponse<ResponseFetchChatMessages>> => {
try {
const response = await api
.get(`chat/message/${chatRoomId}`, {
json: { chatRoomId, lastMessageCreatedAt },
})
.json<APIResponse<ResponseFetchChatMessages>>();
return response;
} catch (error) {
if (error instanceof HTTPError) {
const errorData = await error.response.json();
console.error(errorData);
}
throw error;
}
};
28 changes: 14 additions & 14 deletions src/apis/chat/fetchChatRooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@ import { AvatarNumber } from '~types/avatar-number';
import { FamilyRole } from '~types/family-role';
import { Gender } from '~types/gender';

export type FetchChatRoomsResponseType = {
interface Member {
memberId: number;
memberName: string;
email: string;
memberGender: Gender;
familyRole: FamilyRole;
memberProfileImg: AvatarNumber;
}
export interface ResponseFetchChatRoom {
chatRoomId: number;
name: string;
lastMessage: string;
unreadMessageCount: number;
members: [
{
memberId: number;
memberName: string;
email: string;
memberGender: Gender;
familyRole: FamilyRole;
memberProfileImg: AvatarNumber;
},
];
}[];
export const fetchChatRooms = async (): Promise<APIResponse<FetchChatRoomsResponseType>> => {
members: Member[];
}

export const fetchChatRooms = async (): Promise<APIResponse<ResponseFetchChatRoom[]>> => {
try {
const response = await api.get('chat/rooms').json<APIResponse<FetchChatRoomsResponseType>>();
const response = await api.get('chat/rooms').json<APIResponse<ResponseFetchChatRoom[]>>();
return response;
} catch (error) {
console.error('Error:', error);
Expand Down
18 changes: 18 additions & 0 deletions src/apis/chat/useChatMessages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useQuery } from '@tanstack/react-query';
import { fetchChatMessages } from '~apis/chat/fetchChatMessages';
import { UseQueryCustomOptions } from '~types/api';

export const useChatMessages = (
chatRoomId: number,
lastMessageCreatedAt: string,
queryOptions?: UseQueryCustomOptions,
) => {
return useQuery({
queryKey: ['chatMessages', chatRoomId, lastMessageCreatedAt],
queryFn: ({ queryKey }) => {
const [, chatRoomId, lastMessageCreatedAt] = queryKey;

Check warning on line 13 in src/apis/chat/useChatMessages.ts

View workflow job for this annotation

GitHub Actions / build-and-lint

'chatRoomId' is already declared in the upper scope on line 6 column 3

Check warning on line 13 in src/apis/chat/useChatMessages.ts

View workflow job for this annotation

GitHub Actions / build-and-lint

'lastMessageCreatedAt' is already declared in the upper scope on line 7 column 3
return fetchChatMessages(chatRoomId as number, lastMessageCreatedAt as string);
},
...queryOptions,
});
};
1 change: 0 additions & 1 deletion src/apis/dog/createDog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export const createDog = async (dogProfile: DogProfileType): Promise<APIResponse
);

formData.append('profileImgFile', dogProfile.profileImgFile);

const response = await api
.post('dogs/create', {
body: formData,
Expand Down
8 changes: 5 additions & 3 deletions src/apis/dog/fetchAccumulatedWalkInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { api } from '~apis/api.ts';
import { APIResponse } from '~types/api';

export type FetchAccumulatedWalkInfoRequestType = {
dogId: number;
memberId: number;
};

export type FetchAccumulatedWalkInfoResponseType = {
Expand All @@ -12,10 +12,12 @@ export type FetchAccumulatedWalkInfoResponseType = {
};

export const fetchAccumulatedWalkInfo = async ({
dogId,
memberId,
}: FetchAccumulatedWalkInfoRequestType): Promise<APIResponse<FetchAccumulatedWalkInfoResponseType>> => {
try {
const response = await api.get(`dogs/${dogId}/walks`).json<APIResponse<FetchAccumulatedWalkInfoResponseType>>();
const response = await api
.get(`member/walk-info/${memberId}`)
.json<APIResponse<FetchAccumulatedWalkInfoResponseType>>();
return response;
} catch (error) {
console.error('Error:', error);
Expand Down
Loading
Loading