Skip to content

Commit

Permalink
[Feature/#873] 오늘의 솝마디 콕찌르기 추천 기능 구현 (#881)
Browse files Browse the repository at this point in the history
* feat: TodayFortuneBox 구현

* feat: 오늘의 운세(TodayFortuneDashboard) UI 구현

* feat: FortuneDetailRoute, FortuneDetailScreen 파일 분리

* refactor: 패키지 네이밍 수정

* feat: fortune 데이터레이어 구현

- di 모듈 추가
- network api 구현

* feat: fortune 도메인레이어 구현, internal 키워드 일괄 적용

- mapper 구현
- 레포지토리 인터페이스 생성 및 적용
- 힐트모듈 수정

* refactor: internal 키워드 삭제

* refactor: 함수 네이밍 수정

* feat: 레이어 의존성 추가

* refactor: 네트워크 path 수정

* feat: 네트워크 통신 구현 및 state 적용

* feat: 오늘의 솝마디 관련 유즈케이스 생성

* refactor: TodayFortuneBox 패딩값 추가

* refactor: 타입 및 네이밍 수정

* refactor: internal 추가

* test: FortuneDetailScreenTest 구현

* feat: 콕 찌르기 대시보드 UI 구현

* feat: 콕 찌르기 유저 추천 API 연결

* refactor: UI State 수정 및 적용

* refactor: SimpleDataFormatter로 리팩터링

* refactor: Timber 적용

* build: 의존성 수정

* refactor: break strategy 적용

* refactor: 뷰모델 수정

* refactor: 프로필 사진 사이즈 수정

* refactor: 배경색 수정

* feat: 프로필 클릭 시 플레이그라운드로 이동

* feat: 프로필 기본 이미지 구현

* refactor: 자잘한 개행 및 import

* test: 기본 생성 파일 삭제

* refactor: 추천인 이름 글자수 제한 설정

* test: 테스트 코드 수정

* refactor: uimodel의 isEmpty 프로퍼티 제거

* refactor: vectorResource 적용

* build: spotless & baseline 적용
  • Loading branch information
s9hn authored Oct 4, 2024
1 parent a9e2d60 commit 38f22cd
Show file tree
Hide file tree
Showing 22 changed files with 2,443 additions and 2,129 deletions.
2,028 changes: 1,010 additions & 1,018 deletions app/src/release/generated/baselineProfiles/baseline-prof.txt

Large diffs are not rendered by default.

2,028 changes: 1,010 additions & 1,018 deletions app/src/release/generated/baselineProfiles/startup-prof.txt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* MIT License
* Copyright 2024 SOPT - Shout Our Passion Together
* Copyright 2023-2024 SOPT - Shout Our Passion Together
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* MIT License
* Copyright 2024 SOPT - Shout Our Passion Together
* Copyright 2023-2024 SOPT - Shout Our Passion Together
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
*/
package org.sopt.official.data.poke.implementation

import javax.inject.Inject
import org.sopt.official.data.poke.dto.request.GetFriendListDetailRequest
import org.sopt.official.data.poke.dto.request.GetPokeMessageListRequest
import org.sopt.official.data.poke.dto.request.GetPokeNotificationListRequest
Expand All @@ -44,6 +43,7 @@ import org.sopt.official.domain.poke.entity.PokeUserResponse
import org.sopt.official.domain.poke.repository.PokeRepository
import org.sopt.official.domain.poke.type.PokeFriendType
import org.sopt.official.domain.poke.type.PokeMessageType
import javax.inject.Inject

class PokeRepositoryImpl @Inject constructor(
private val localDataSource: PokeLocalDataSource,
Expand All @@ -62,7 +62,7 @@ class PokeRepositoryImpl @Inject constructor(
return remoteDataSource.checkNewInPoke()
}

override suspend fun getOnboardingPokeUserList(randomType: String, size: Int): GetOnboardingPokeUserListResponse {
override suspend fun getOnboardingPokeUserList(randomType: String?, size: Int): GetOnboardingPokeUserListResponse {
return remoteDataSource.getOnboardingPokeUserList(randomType, size)
}

Expand Down Expand Up @@ -110,7 +110,7 @@ class PokeRepositoryImpl @Inject constructor(
)
}

override suspend fun pokeUser(userId: Int, isAnonymous: Boolean, message: String,): PokeUserResponse {
override suspend fun pokeUser(userId: Int, isAnonymous: Boolean, message: String): PokeUserResponse {
return remoteDataSource.pokeUser(
pokeUserRequest =
PokeUserRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ interface PokeService {

@GET("poke/random")
suspend fun getOnboardingPokeUserList(
@Query("randomType") randomType: String,
@Query("size") size: Int
@Query("randomType") randomType: String?,
@Query("size") size: Int,
): Response<PokeRandomUserListResult>

@GET("poke/to/me")
Expand All @@ -60,16 +60,16 @@ interface PokeService {
suspend fun getPokeFriendOfFriendList(): Response<List<PokeFriendOfFriendListResult>>

@GET("poke/to/me/list")
suspend fun getPokeNotificationList(@Query("page") page: Int,): Response<PokeNotificationResult>
suspend fun getPokeNotificationList(@Query("page") page: Int): Response<PokeNotificationResult>

@GET("poke/friend/list")
suspend fun getFriendListSummary(): Response<GetFriendListSummaryResult>

@GET("poke/friend/list")
suspend fun getFriendListDetail(@Query("type") type: String, @Query("page") page: Int,): Response<GetFriendListDetailResult>
suspend fun getFriendListDetail(@Query("type") type: String, @Query("page") page: Int): Response<GetFriendListDetailResult>

@GET("poke/message")
suspend fun getPokeMessageList(@Query("messageType") messageType: String,): Response<GetPokeMessageListResult>
suspend fun getPokeMessageList(@Query("messageType") messageType: String): Response<GetPokeMessageListResult>

@PUT("poke/{userId}")
suspend fun pokeUser(@Path("userId") userId: Int, @Body pokeMessageRequest: PokeMessageRequest): Response<PokeUserResult>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
*/
package org.sopt.official.data.poke.source.remote

import javax.inject.Inject
import org.sopt.official.data.poke.dto.request.GetFriendListDetailRequest
import org.sopt.official.data.poke.dto.request.GetPokeMessageListRequest
import org.sopt.official.data.poke.dto.request.GetPokeNotificationListRequest
Expand All @@ -41,6 +40,7 @@ import org.sopt.official.domain.poke.entity.GetPokeMeResponse
import org.sopt.official.domain.poke.entity.GetPokeMessageListResponse
import org.sopt.official.domain.poke.entity.GetPokeNotificationListResponse
import org.sopt.official.domain.poke.entity.PokeUserResponse
import javax.inject.Inject

class PokeRemoteDataSource @Inject constructor(
private val service: PokeService,
Expand All @@ -54,7 +54,7 @@ class PokeRemoteDataSource @Inject constructor(
}
}

suspend fun getOnboardingPokeUserList(randomType: String, size: Int): GetOnboardingPokeUserListResponse {
suspend fun getOnboardingPokeUserList(randomType: String?, size: Int): GetOnboardingPokeUserListResponse {
val response = service.getOnboardingPokeUserList(randomType, size)
return GetOnboardingPokeUserListResponse().apply {
statusCode = response.code().toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,17 @@ interface PokeRepository {
suspend fun checkNewInPokeOnboarding(): Boolean
suspend fun updateNewInPokeOnboarding()
suspend fun checkNewInPoke(): CheckNewInPokeResponse
suspend fun getOnboardingPokeUserList(randomType: String, size: Int): GetOnboardingPokeUserListResponse
suspend fun getOnboardingPokeUserList(randomType: String? = null, size: Int): GetOnboardingPokeUserListResponse
suspend fun getPokeMe(): GetPokeMeResponse
suspend fun getPokeFriend(): GetPokeFriendResponse
suspend fun getPokeFriendOfFriendList(): GetPokeFriendOfFriendListResponse
suspend fun getPokeNotificationList(page: Int): GetPokeNotificationListResponse

suspend fun getFriendListSummary(): GetFriendListSummaryResponse

suspend fun getFriendListDetail(type: PokeFriendType, page: Int,): GetFriendListDetailResponse
suspend fun getFriendListDetail(type: PokeFriendType, page: Int): GetFriendListDetailResponse

suspend fun getPokeMessageList(messageType: PokeMessageType,): GetPokeMessageListResponse
suspend fun getPokeMessageList(messageType: PokeMessageType): GetPokeMessageListResponse

suspend fun pokeUser(userId: Int, isAnonymous: Boolean, message: String,): PokeUserResponse
suspend fun pokeUser(userId: Int, isAnonymous: Boolean, message: String): PokeUserResponse
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
*/
package org.sopt.official.domain.poke.usecase

import javax.inject.Inject
import org.sopt.official.domain.poke.entity.ApiResult
import org.sopt.official.domain.poke.entity.PokeRandomUserList
import org.sopt.official.domain.poke.entity.apiResult
import org.sopt.official.domain.poke.repository.PokeRepository
import javax.inject.Inject

class GetOnboardingPokeUserListUseCase @Inject constructor(
private val repository: PokeRepository,
Expand Down
1 change: 1 addition & 0 deletions feature/fortune/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ android {
dependencies {
// domain
implementation(projects.domain.fortune)
implementation(projects.domain.poke)

// core
implementation(projects.core.common)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ import org.junit.Rule
import org.junit.Test
import org.sopt.official.designsystem.SoptTheme
import org.sopt.official.feature.fortune.feature.fortuneDetail.FortuneDetailScreen
import org.sopt.official.feature.fortune.feature.fortuneDetail.model.FortuneDetailUiState
import org.sopt.official.feature.fortune.feature.fortuneDetail.model.FortuneDetailUiState.Success
import org.sopt.official.feature.fortune.feature.fortuneDetail.model.FortuneDetailUiState.Success.TodaySentence
import org.sopt.official.feature.fortune.feature.fortuneDetail.model.FortuneDetailUiState.Success.UserInfo

internal class FortuneDetailScreenTest {

Expand All @@ -50,17 +52,27 @@ internal class FortuneDetailScreenTest {
val content = "안녕하세요안녕하세요안녕하세요안녕하세요안녕하세요"

// when:

composeRule.setContent {
SoptTheme {
FortuneDetailScreen(
paddingValue = PaddingValues(),
date = date,
onFortuneAmuletClick = { },
uiState = FortuneDetailUiState.TodaySentence(
userName = name,
content = content,
)
onPokeClick = { },
onProfileClick = { },
uiState = Success(
todaySentence = TodaySentence(
userName = name,
content = content,
),
userInfo = UserInfo(
userId = 0L,
profile = "",
userName = "동민",
generation = 111,
part = "기획 파트",
)
),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@
*/
package org.sopt.official.feature.fortune.feature.fortuneDetail

import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle

Expand All @@ -37,12 +40,19 @@ internal fun FortuneDetailRoute(
onFortuneAmuletClick: () -> Unit,
viewModel: FortuneDetailViewModel = hiltViewModel(),
) {
val context = LocalContext.current
val uiState by viewModel.uiState.collectAsStateWithLifecycle()

FortuneDetailScreen(
paddingValue = paddingValue,
date = date,
onFortuneAmuletClick = onFortuneAmuletClick,
onPokeClick = {},
onProfileClick = { userId ->
context.startActivity(
Intent(Intent.ACTION_VIEW, Uri.parse("https://playground.sopt.org/members/${userId}"))
)
},
uiState = uiState,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,31 +36,46 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.sopt.official.designsystem.SoptTheme
import org.sopt.official.feature.fortune.feature.fortuneDetail.component.PokeRecommendationDashboard
import org.sopt.official.feature.fortune.feature.fortuneDetail.component.TodayFortuneDashboard
import org.sopt.official.feature.fortune.feature.fortuneDetail.model.FortuneDetailUiState
import org.sopt.official.feature.fortune.feature.fortuneDetail.model.FortuneDetailUiState.Error
import org.sopt.official.feature.fortune.feature.fortuneDetail.model.FortuneDetailUiState.Loading
import org.sopt.official.feature.fortune.feature.fortuneDetail.model.FortuneDetailUiState.TodaySentence
import org.sopt.official.feature.fortune.feature.fortuneDetail.model.FortuneDetailUiState.Success
import org.sopt.official.feature.fortune.feature.fortuneDetail.model.FortuneDetailUiState.Success.TodaySentence
import org.sopt.official.feature.fortune.feature.fortuneDetail.model.FortuneDetailUiState.Success.UserInfo
import timber.log.Timber

@Composable
internal fun FortuneDetailScreen(
paddingValue: PaddingValues,
date: String,
onFortuneAmuletClick: () -> Unit,
onPokeClick: (userId: Long) -> Unit,
onProfileClick: (userId: Long) -> Unit,
modifier: Modifier = Modifier,
uiState: FortuneDetailUiState = Loading,
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier.fillMaxSize().padding(paddingValues = paddingValue),
modifier = modifier
.fillMaxSize()
.padding(paddingValues = paddingValue),
) {
Spacer(modifier = Modifier.height(height = 16.dp))
when (uiState) {
is TodaySentence -> {
is Success -> {
TodayFortuneDashboard(
date = date,
todaySentence = uiState.message,
todaySentence = uiState.todaySentence.message,
)
Spacer(modifier = Modifier.height(height = 20.dp))
PokeRecommendationDashboard(
profile = uiState.userInfo.profile,
name = uiState.userInfo.userName,
userDescription = uiState.userInfo.userDescription,
onPokeClick = { onPokeClick(uiState.userInfo.userId) },
onProfileClick = { onProfileClick(uiState.userInfo.userId) }
)
}

Expand All @@ -80,10 +95,21 @@ private fun FortuneDetailScreenPreview() {
paddingValue = PaddingValues(vertical = 16.dp),
date = "2024-09-09",
onFortuneAmuletClick = {},
uiState = TodaySentence(
userName = "누누",
content = "오늘 하루종일 기분 좋을 것 같은 날이네요.",
uiState = Success(
todaySentence = TodaySentence(
userName = "이현우",
content = "사과해요나한테사과해요나한테사과해요나한테"
),
userInfo = UserInfo(
userId = 0L,
profile = "",
userName = "동민",
generation = 111,
part = "기획 파트"
)
),
onPokeClick = { },
onProfileClick = { },
)
}
}
Loading

0 comments on commit 38f22cd

Please sign in to comment.