Skip to content

Commit 06f2224

Browse files
authored
Merge pull request #482 from projects200/feat/feed
[Feat] 피드 개발
2 parents e758c89 + 19d95cb commit 06f2224

File tree

88 files changed

+4430
-41
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+4430
-41
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ dependencies {
8686
implementation(projects.feature.exercise)
8787
implementation(projects.feature.timer)
8888
implementation(projects.feature.matching)
89+
implementation(projects.feature.feed)
8990
implementation(projects.feature.chatting)
9091

9192
implementation(libs.androidx.appcompat)

app/src/main/java/com/project200/undabang/main/MainActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ class MainActivity : AppCompatActivity(), BottomNavigationController {
146146
com.project200.undabang.feature.exercise.R.id.exerciseShareEditFragment,
147147
com.project200.undabang.feature.matching.R.id.matchingGuideFragment,
148148
com.project200.undabang.feature.chatting.R.id.chattingRoomFragment,
149+
com.project200.undabang.feature.feed.R.id.feedFormFragment,
150+
com.project200.undabang.feature.feed.R.id.feedDetailFragment,
149151
// ... 필요한 다른 프래그먼트 ID들 추가 ... //
150152
)
151153

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="28dp"
3+
android:height="28dp"
4+
android:viewportWidth="28"
5+
android:viewportHeight="28">
6+
<path
7+
android:pathData="M3.5,7.875C3.5,6.715 3.961,5.602 4.781,4.781C5.602,3.961 6.715,3.5 7.875,3.5H20.125C21.285,3.5 22.398,3.961 23.219,4.781C24.039,5.602 24.5,6.715 24.5,7.875V20.125C24.5,21.285 24.039,22.398 23.219,23.219C22.398,24.039 21.285,24.5 20.125,24.5H7.875C6.715,24.5 5.602,24.039 4.781,23.219C3.961,22.398 3.5,21.285 3.5,20.125V7.875ZM7.875,5.25C7.179,5.25 6.511,5.527 6.019,6.019C5.527,6.511 5.25,7.179 5.25,7.875V12.25H15.75V5.25H7.875ZM5.25,14V20.125C5.25,20.821 5.527,21.489 6.019,21.981C6.511,22.473 7.179,22.75 7.875,22.75H15.75V14H5.25ZM17.5,15.75H22.75V12.25H17.5V15.75ZM22.75,17.5H17.5V22.75H20.125C20.821,22.75 21.489,22.473 21.981,21.981C22.473,21.489 22.75,20.821 22.75,20.125V17.5ZM22.75,7.875C22.75,7.179 22.473,6.511 21.981,6.019C21.489,5.527 20.821,5.25 20.125,5.25H17.5V10.5H22.75V7.875Z"
8+
android:fillColor="#9E9E9E"/>
9+
</vector>

app/src/main/res/menu/bottom_nav_menu.xml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@
88
android:id="@id/matching_nav_graph"
99
android:icon="@drawable/ic_nav_matching"
1010
android:title="@string/matching" />
11+
<item
12+
android:id="@id/feed_nav_graph"
13+
android:icon="@drawable/ic_nav_feed"
14+
android:title="@string/feed" />
1115
<item
1216
android:id="@id/chatting_nav_graph"
1317
android:icon="@drawable/ic_chatting"
1418
android:title="@string/chatting"/>
15-
<item
16-
android:id="@id/timer_nav_graph"
17-
android:icon="@drawable/ic_nav_timer"
18-
android:title="@string/timer" />
19+
<!-- <item-->
20+
<!-- android:id="@id/timer_nav_graph"-->
21+
<!-- android:icon="@drawable/ic_nav_timer"-->
22+
<!-- android:title="@string/timer" />-->
1923
<item
2024
android:id="@id/profile_nav_graph"
2125
android:icon="@drawable/ic_nav_mypage"

app/src/main/res/navigation/bottom_nav_graph.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
<include app:graph="@navigation/exercise_nav_graph" />
88
<include app:graph="@navigation/matching_nav_graph"/>
9+
<include app:graph="@navigation/feed_nav_graph"/>
910
<include app:graph="@navigation/chatting_nav_graph"/>
1011
<include app:graph="@navigation/timer_nav_graph" />
1112
<include app:graph="@navigation/profile_nav_graph" />

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
<string name="exercise_record">기록</string>
1212
<string name="matching">매칭</string>
13+
<string name="feed">피드</string>
1314
<string name="chatting">채팅</string>
1415
<string name="timer">타이머</string>
1516
<string name="profile">MY</string>

data/src/main/java/com/project200/data/api/ApiService.kt

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
package com.project200.data.api
22

33
import com.project200.data.dto.BaseResponse
4+
import com.project200.data.dto.CommentDTO
5+
import com.project200.data.dto.CreateCommentRequestDTO
6+
import com.project200.data.dto.CreateCommentResponseDTO
7+
import com.project200.data.dto.CreateFeedRequestDTO
48
import com.project200.data.dto.CustomTimerIdDTO
59
import com.project200.data.dto.DeletePreferredExerciseDTO
610
import com.project200.data.dto.EditExercisePlaceDTO
711
import com.project200.data.dto.ExerciseIdDto
812
import com.project200.data.dto.ExpectedScoreInfoDTO
13+
import com.project200.data.dto.FeedCreateResultDTO
14+
import com.project200.data.dto.FeedDTO
15+
import com.project200.data.dto.FeedPictureUploadDTO
916
import com.project200.data.dto.GetBlockedMemberDTO
1017
import com.project200.data.dto.GetChattingMessagesDTO
1118
import com.project200.data.dto.GetChattingRoomsDTO
@@ -15,6 +22,7 @@ import com.project200.data.dto.GetExerciseCountByRangeDTO
1522
import com.project200.data.dto.GetExercisePlaceDTO
1623
import com.project200.data.dto.GetExerciseRecordData
1724
import com.project200.data.dto.GetExerciseRecordListDto
25+
import com.project200.data.dto.GetFeedsDTO
1826
import com.project200.data.dto.GetIsNicknameDuplicated
1927
import com.project200.data.dto.GetIsRegisteredData
2028
import com.project200.data.dto.GetMatchingMembersDto
@@ -27,6 +35,7 @@ import com.project200.data.dto.GetProfileDTO
2735
import com.project200.data.dto.GetProfileImageResponseDto
2836
import com.project200.data.dto.GetScoreDTO
2937
import com.project200.data.dto.GetSimpleTimersDTO
38+
import com.project200.data.dto.LikeRequestDTO
3039
import com.project200.data.dto.NotificationStateDTO
3140
import com.project200.data.dto.PatchCustomTimerTitleRequest
3241
import com.project200.data.dto.PatchExerciseRequestDto
@@ -46,6 +55,7 @@ import com.project200.data.dto.PostSignUpRequest
4655
import com.project200.data.dto.PutProfileRequest
4756
import com.project200.data.dto.SimpleTimerIdDTO
4857
import com.project200.data.dto.SimpleTimerRequest
58+
import com.project200.data.dto.UpdateFeedRequestDTO
4959
import com.project200.data.utils.AccessTokenApi
5060
import com.project200.data.utils.AccessTokenWithFcmApi
5161
import com.project200.data.utils.IdTokenApi
@@ -474,4 +484,94 @@ interface ApiService {
474484
@Header("X-Fcm-Token") fcmToken: String,
475485
@Body notiRequest: List<NotificationStateDTO>,
476486
): BaseResponse<Unit?>
487+
488+
/** 피드 */
489+
@GET("api/v1/feeds")
490+
@AccessTokenApi
491+
suspend fun getFeeds(
492+
@Query("prevFeedId") prevFeedId: Long?,
493+
@Query("size") size: Int?,
494+
): BaseResponse<GetFeedsDTO?>
495+
496+
@GET("api/v1/feeds/{feedId}")
497+
@AccessTokenApi
498+
suspend fun getFeedDetail(
499+
@Path("feedId") feedId: Long,
500+
): BaseResponse<FeedDTO>
501+
502+
@POST("api/v1/feeds")
503+
@AccessTokenApi
504+
suspend fun postFeed(
505+
@Body createFeedRequest: CreateFeedRequestDTO,
506+
): BaseResponse<FeedCreateResultDTO>
507+
508+
@DELETE("api/v1/feeds/{feedId}")
509+
@AccessTokenApi
510+
suspend fun deleteFeed(
511+
@Path("feedId") feedId: Long,
512+
): BaseResponse<Unit?>
513+
514+
@PATCH("api/v1/feeds/{feedId}")
515+
@AccessTokenApi
516+
suspend fun updateFeed(
517+
@Path("feedId") feedId: Long,
518+
@Body updateFeedRequest: UpdateFeedRequestDTO,
519+
): BaseResponse<Unit?>
520+
521+
// 피드 좋아요
522+
@POST("api/v1/feeds/{feedId}/like")
523+
@AccessTokenApi
524+
suspend fun likeFeed(
525+
@Path("feedId") feedId: Long,
526+
@Body request: LikeRequestDTO,
527+
): BaseResponse<Unit?>
528+
529+
/** 댓글 */
530+
// 댓글 목록 조회
531+
@GET("api/v1/feeds/{feedId}/comments")
532+
@AccessTokenApi
533+
suspend fun getComments(
534+
@Path("feedId") feedId: Long,
535+
): BaseResponse<List<CommentDTO>>
536+
537+
// 댓글 작성
538+
@POST("api/v1/feeds/{feedId}/comments")
539+
@AccessTokenApi
540+
suspend fun createComment(
541+
@Path("feedId") feedId: Long,
542+
@Body request: CreateCommentRequestDTO,
543+
): BaseResponse<CreateCommentResponseDTO>
544+
545+
// 댓글 좋아요
546+
@POST("api/v1/comments/{commentId}/like")
547+
@AccessTokenApi
548+
suspend fun likeComment(
549+
@Path("commentId") commentId: Long,
550+
@Body request: LikeRequestDTO,
551+
): BaseResponse<Unit?>
552+
553+
// 댓글 삭제
554+
@DELETE("api/v1/comments/{commentId}")
555+
@AccessTokenApi
556+
suspend fun deleteComment(
557+
@Path("commentId") commentId: Long,
558+
): BaseResponse<Unit?>
559+
560+
/** 피드 이미지 */
561+
// 피드 이미지 업로드
562+
@Multipart
563+
@POST("api/v1/feeds/{feedId}/pictures")
564+
@AccessTokenApi
565+
suspend fun postFeedImages(
566+
@Path("feedId") feedId: Long,
567+
@Part pictures: List<MultipartBody.Part>,
568+
): BaseResponse<List<FeedPictureUploadDTO>>
569+
570+
// 피드 이미지 삭제
571+
@DELETE("api/v1/feeds/{feedId}/pictures/{pictureId}")
572+
@AccessTokenApi
573+
suspend fun deleteFeedImage(
574+
@Path("feedId") feedId: Long,
575+
@Path("pictureId") pictureId: Long,
576+
): BaseResponse<Unit?>
477577
}

data/src/main/java/com/project200/data/di/RepositoryModule.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import com.project200.data.impl.ChatSocketRepositoryImpl
77
import com.project200.data.impl.ChattingRepositoryImpl
88
import com.project200.data.impl.ExerciseRecordRepositoryImpl
99
import com.project200.data.impl.FcmRepositoryImpl
10+
import com.project200.data.impl.FeedRepositoryImpl
1011
import com.project200.data.impl.MatchingRepositoryImpl
1112
import com.project200.data.impl.MemberRepositoryImpl
1213
import com.project200.data.impl.NotificationRepositoryImpl
@@ -20,6 +21,7 @@ import com.project200.domain.repository.ChatSocketRepository
2021
import com.project200.domain.repository.ChattingRepository
2122
import com.project200.domain.repository.ExerciseRecordRepository
2223
import com.project200.domain.repository.FcmRepository
24+
import com.project200.domain.repository.FeedRepository
2325
import com.project200.domain.repository.MatchingRepository
2426
import com.project200.domain.repository.MemberRepository
2527
import com.project200.domain.repository.NotificationRepository
@@ -86,4 +88,8 @@ abstract class RepositoryModule {
8688
@Binds
8789
@Singleton
8890
abstract fun bindNotificationRepository(notificationRepositoryImpl: NotificationRepositoryImpl): NotificationRepository
91+
92+
@Binds
93+
@Singleton
94+
abstract fun bindFeedRepository(feedRepositoryImpl: FeedRepositoryImpl): FeedRepository
8995
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.project200.data.dto
2+
3+
import com.squareup.moshi.JsonClass
4+
import java.time.LocalDateTime
5+
6+
@JsonClass(generateAdapter = true)
7+
data class GetCommentsDTO(
8+
val comments: List<CommentDTO>,
9+
)
10+
11+
@JsonClass(generateAdapter = true)
12+
data class CommentDTO(
13+
val commentId: Long,
14+
val memberId: String,
15+
val memberNickname: String,
16+
val memberProfileImageUrl: String?,
17+
val memberThumbnailUrl: String?,
18+
val content: String,
19+
val likesCount: Int,
20+
val taggedMember: TaggedMemberDTO,
21+
val commentIsLiked: Boolean = false,
22+
val createdAt: LocalDateTime,
23+
val children: List<ReplyDTO>,
24+
)
25+
26+
@JsonClass(generateAdapter = true)
27+
data class TaggedMemberDTO(
28+
val memberId: String?,
29+
val memberNickname: String?,
30+
)
31+
32+
@JsonClass(generateAdapter = true)
33+
data class ReplyDTO(
34+
val commentId: Long,
35+
val memberId: String,
36+
val memberNickname: String,
37+
val memberProfileImageUrl: String?,
38+
val memberThumbnailUrl: String?,
39+
val content: String,
40+
val likesCount: Int,
41+
val commentIsLiked: Boolean = false,
42+
val createdAt: LocalDateTime,
43+
val taggedMember: TaggedMemberDTO? = null,
44+
)
45+
46+
@JsonClass(generateAdapter = true)
47+
data class CreateCommentRequestDTO(
48+
val content: String,
49+
val parentCommentId: Long?,
50+
val taggedMemberId: String? = null,
51+
)
52+
53+
@JsonClass(generateAdapter = true)
54+
data class CreateCommentResponseDTO(
55+
val commentId: Long,
56+
)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.project200.data.dto
2+
3+
import com.squareup.moshi.JsonClass
4+
import java.time.LocalDateTime
5+
6+
@JsonClass(generateAdapter = true)
7+
data class GetFeedsDTO(
8+
val hasNext: Boolean,
9+
val feeds: List<FeedDTO>,
10+
)
11+
12+
@JsonClass(generateAdapter = true)
13+
data class FeedDTO(
14+
val feedId: Long,
15+
val feedContent: String,
16+
val feedLikesCount: Int,
17+
val feedCommentsCount: Int,
18+
val feedTypeId: Long?,
19+
val feedTypeName: String?,
20+
val feedTypeDesc: String?,
21+
val feedCreatedAt: LocalDateTime,
22+
val feedIsLiked: Boolean,
23+
val feedHasCommented: Boolean,
24+
val memberId: String,
25+
val nickname: String,
26+
val profileUrl: String?,
27+
val thumbnailUrl: String?,
28+
val feedPictures: List<FeedPictureDTO>,
29+
)
30+
31+
@JsonClass(generateAdapter = true)
32+
data class FeedPictureDTO(
33+
val feedPictureId: Long,
34+
val feedPictureUrl: String,
35+
)
36+
37+
@JsonClass(generateAdapter = true)
38+
data class CreateFeedRequestDTO(
39+
val feedContent: String,
40+
val feedTypeId: Long?,
41+
)
42+
43+
@JsonClass(generateAdapter = true)
44+
data class FeedCreateResultDTO(
45+
val feedId: Long,
46+
)
47+
48+
@JsonClass(generateAdapter = true)
49+
data class UpdateFeedRequestDTO(
50+
val feedContent: String,
51+
val feedTypeId: Long?,
52+
)
53+
54+
@JsonClass(generateAdapter = true)
55+
data class FeedPictureUploadDTO(
56+
val pictureId: Long,
57+
val pictureUrl: String,
58+
)
59+
60+
@JsonClass(generateAdapter = true)
61+
data class LikeRequestDTO(
62+
val liked: Boolean,
63+
)

0 commit comments

Comments
 (0)