Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature/#877] 오늘의 솝마디 콕찌르기 기능 구현 #895

Merged
merged 82 commits into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from 69 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
1aa4880
feat: TodayFortuneBox 구현
s9hn Sep 25, 2024
427fcc1
feat: 오늘의 운세(TodayFortuneDashboard) UI 구현
s9hn Sep 25, 2024
1a75a66
feat: FortuneDetailRoute, FortuneDetailScreen 파일 분리
s9hn Sep 25, 2024
e265c4e
refactor: 패키지 네이밍 수정
s9hn Sep 25, 2024
3b483ac
feat: fortune 데이터레이어 구현
s9hn Sep 25, 2024
4241e3f
feat: fortune 도메인레이어 구현, internal 키워드 일괄 적용
s9hn Sep 25, 2024
533a29f
refactor: internal 키워드 삭제
s9hn Sep 25, 2024
f655b50
refactor: 함수 네이밍 수정
s9hn Sep 25, 2024
e26989c
feat: 레이어 의존성 추가
s9hn Sep 25, 2024
5950cec
refactor: 네트워크 path 수정
s9hn Sep 26, 2024
71001df
feat: 네트워크 통신 구현 및 state 적용
s9hn Sep 26, 2024
1e42c44
feat: 오늘의 솝마디 관련 유즈케이스 생성
s9hn Sep 26, 2024
625d11e
refactor: TodayFortuneBox 패딩값 추가
s9hn Sep 26, 2024
430b830
refactor: 타입 및 네이밍 수정
s9hn Sep 26, 2024
83c0641
refactor: internal 추가
s9hn Sep 26, 2024
8d86bcb
test: FortuneDetailScreenTest 구현
s9hn Sep 26, 2024
340c78e
Merge branch 'develop' of https://github.com/sopt-makers/sopt-android…
s9hn Sep 26, 2024
2ea3be9
feat: 콕 찌르기 대시보드 UI 구현
s9hn Sep 26, 2024
37e8027
feat: 콕 찌르기 유저 추천 API 연결
s9hn Sep 26, 2024
0bde946
refactor: UI State 수정 및 적용
s9hn Sep 26, 2024
2f9ffff
refactor: SimpleDataFormatter로 리팩터링
s9hn Sep 26, 2024
69a0acc
refactor: Timber 적용
s9hn Sep 26, 2024
8981910
build: 의존성 수정
s9hn Sep 26, 2024
a7c5b50
refactor: break strategy 적용
s9hn Sep 26, 2024
3c27c00
build: resolve merge conflict
s9hn Sep 27, 2024
c2ac6ed
refactor: 뷰모델 수정
s9hn Sep 27, 2024
4054429
feature #875: delete paddingValue
chattymin Sep 27, 2024
943f65b
feature #875: connect TodayFortuneCard api
chattymin Sep 27, 2024
6d0a46c
feature #875: connect TodayFortuneCard data
chattymin Sep 27, 2024
ec88717
feature #875: delete paddingValue
chattymin Sep 27, 2024
4ae718e
feat: 오늘 부적 받기 버튼 구현
s9hn Sep 27, 2024
a636466
feature #875: change function name
chattymin Sep 28, 2024
e12c749
feature #875: apply typealias
chattymin Sep 28, 2024
b7c1897
feature #875: apply slot for amuletDescription
chattymin Sep 28, 2024
82bc6b8
feat: 콕 찌르기 바텀시트 UI 구현
s9hn Sep 28, 2024
28009d3
refactor: 클릭 리스너 구현
s9hn Sep 28, 2024
af5b437
feature #875: connect navigation
chattymin Sep 28, 2024
712a770
feat: 콕 찌르기 서버통신 구현
s9hn Sep 28, 2024
feeb49b
Merge branch 'feature/#875-fortune-amulet' of https://github.com/sopt…
s9hn Sep 28, 2024
ec46f95
feature #875: connect navigator with DeepLink
chattymin Sep 28, 2024
a5a28a5
feature #875: apply finishActivity
chattymin Sep 28, 2024
1bec46f
feature #875: apply FortuneButton component
chattymin Sep 28, 2024
e464262
feature #875: add contentDescription
chattymin Sep 28, 2024
7328ea8
feature #875: apply design
chattymin Sep 28, 2024
138a332
build: resolve merge-conflict
s9hn Sep 30, 2024
48e6648
refactor: 프로필 사진 사이즈 수정
s9hn Oct 1, 2024
9a2ae03
refactor: 배경색 수정
s9hn Oct 1, 2024
20b6fac
feat: 프로필 클릭 시 플레이그라운드로 이동
s9hn Oct 1, 2024
6b37380
feat: 프로필 기본 이미지 구현
s9hn Oct 1, 2024
3f16042
refactor: 자잘한 개행 및 import
s9hn Oct 1, 2024
1291338
test: 기본 생성 파일 삭제
s9hn Oct 3, 2024
95bce58
refactor: 추천인 이름 글자수 제한 설정
s9hn Oct 4, 2024
f2dc7b7
test: 테스트 코드 수정
s9hn Oct 4, 2024
7e40410
refactor: uimodel의 isEmpty 프로퍼티 제거
s9hn Oct 4, 2024
b0cedac
Merge branch 'develop' of https://github.com/sopt-makers/sopt-android…
s9hn Oct 4, 2024
b5355c0
build: resolve merge-conflict
s9hn Oct 4, 2024
a194ebf
build: resolve merge-conflict
s9hn Oct 4, 2024
55b2a12
refactor: paddingValues 제거
s9hn Oct 4, 2024
aa49859
refactor: 변수명 변경 및 bottomsheet 관리 코루틴 로직 수정
s9hn Oct 4, 2024
cc1e662
refactor: immutableListOf 적용
s9hn Oct 4, 2024
36693b8
build: resolve merge conflict
s9hn Oct 4, 2024
32814ad
build: resolve merge conflict
s9hn Oct 4, 2024
813e735
refactor: 유저 프로필 사진 crop 버그 수정
s9hn Oct 4, 2024
4210c89
refactor: 콕찌르기 버튼 리플 반영
s9hn Oct 4, 2024
2b06df8
refactor: 익명 체크 아이콘 기본값 수정
s9hn Oct 4, 2024
f6c4312
feat: 외부 영역 터치 및 하단 스크롤 시 bottomsheet hide 기능 구현
s9hn Oct 4, 2024
bbd163a
Merge branch 'develop' of https://github.com/sopt-makers/sopt-android…
s9hn Oct 4, 2024
fdf1b30
refactor: 포매팅 정리
s9hn Oct 5, 2024
75c9ae7
Merge branch 'develop' of https://github.com/sopt-makers/sopt-android…
s9hn Oct 5, 2024
4db3eee
build: resolve merge conflict
s9hn Oct 5, 2024
6a91521
feat: snackbar 구현
s9hn Oct 6, 2024
9b3a44a
refactor: Icon으로 수정
s9hn Oct 7, 2024
c08676e
refactor: topAppBar Dim처리 및 snackBar 이동
s9hn Oct 7, 2024
8adbf83
feature #875: change naming
chattymin Oct 8, 2024
3b9c97a
feature #875: add preview
chattymin Oct 8, 2024
69afa3e
refactor: custom breaking word 로직 구현
s9hn Oct 8, 2024
969eeed
refactor: 매직넘버 상수화
s9hn Oct 8, 2024
d79835f
Merge branch 'develop' of https://github.com/sopt-makers/sopt-android…
s9hn Oct 8, 2024
b5b2d8e
build: resolve merge conflict
s9hn Oct 8, 2024
c6dd6ec
Merge branch 'develop' of https://github.com/sopt-makers/sopt-android…
s9hn Oct 12, 2024
d2fdcd6
build: baseline-prof & spotless
s9hn Oct 12, 2024
0750817
Merge branch 'develop' of https://github.com/sopt-makers/sopt-android…
s9hn Oct 13, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import org.sopt.official.common.navigator.DeepLinkType
import org.sopt.official.common.navigator.NavigatorProvider
import org.sopt.official.feature.attendance.AttendanceActivity
import org.sopt.official.feature.auth.AuthActivity
import org.sopt.official.feature.fortune.FortuneActivity
import org.sopt.official.feature.home.HomeActivity
import org.sopt.official.feature.mypage.mypage.MyPageActivity
import org.sopt.official.feature.notification.SchemeActivity
Expand All @@ -43,48 +44,50 @@ import org.sopt.official.stamp.SoptampActivity
import javax.inject.Inject

class NavigatorProviderIntent @Inject constructor(
@ApplicationContext private val context: Context
@ApplicationContext private val context: Context,
) : NavigatorProvider {
override fun getAuthActivityIntent(): Intent = AuthActivity.newInstance(context)
override fun getNotificationActivityIntent() = NotificationActivity.newInstance(context)
override fun getNotificationDetailActivityIntent(notificationId: String) = NotificationDetailActivity.getIntent(
context,
notificationId
)
override fun getAuthActivityIntent(): Intent = AuthActivity.newInstance(context)
override fun getNotificationActivityIntent() = NotificationActivity.newInstance(context)
override fun getNotificationDetailActivityIntent(notificationId: String) = NotificationDetailActivity.getIntent(
context,
notificationId
)

override fun getMyPageActivityIntent(name: String) = MyPageActivity.getIntent(
context,
MyPageActivity.StartArgs(UserActiveState.valueOf(name))
)

override fun getMyPageActivityIntent(name: String) = MyPageActivity.getIntent(
context,
MyPageActivity.StartArgs(UserActiveState.valueOf(name))
)
override fun getAttendanceActivityIntent() = AttendanceActivity.newInstance(context)

override fun getAttendanceActivityIntent() = AttendanceActivity.newInstance(context)
override fun getSoptampActivityIntent() = SoptampActivity.getIntent(context)

override fun getSoptampActivityIntent() = SoptampActivity.getIntent(context)
override fun getPokeNotificationActivityIntent(name: String) = PokeNotificationActivity.getIntent(
context,
PokeNotificationActivity.Argument(name)
)

override fun getPokeNotificationActivityIntent(name: String) = PokeNotificationActivity.getIntent(
context,
PokeNotificationActivity.Argument(name)
)
override fun getFortuneActivityIntent(): Intent = FortuneActivity.getIntent(context)

override fun getSchemeActivityIntent(
notificationId: String,
link: String
) = SchemeActivity.getIntent(
context,
SchemeActivity.Argument(
notificationId,
link
override fun getSchemeActivityIntent(
notificationId: String,
link: String,
) = SchemeActivity.getIntent(
context,
SchemeActivity.Argument(
notificationId,
link
)
)
)

override fun getHomeActivityIntent(
userStatus: UserStatus,
deepLinkType: DeepLinkType?
) = HomeActivity.getIntent(
context,
HomeActivity.StartArgs(
userStatus,
deepLinkType
override fun getHomeActivityIntent(
userStatus: UserStatus,
deepLinkType: DeepLinkType?,
) = HomeActivity.getIntent(
context,
HomeActivity.StartArgs(
userStatus,
deepLinkType
)
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,72 +33,85 @@ import org.sopt.official.common.util.extractQueryParameter
import timber.log.Timber

internal val navigator by lazy {
EntryPointAccessors.fromApplication(appContext, NavigatorEntryPoint::class.java).navigatorProvider()
EntryPointAccessors.fromApplication(appContext, NavigatorEntryPoint::class.java).navigatorProvider()
}

enum class DeepLinkType(
val link: String
val link: String,
) {
HOME("home") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = getHomeIntent(userStatus)
},
NOTIFICATION_LIST("home/notification") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = userStatus.setIntent(navigator.getNotificationActivityIntent())
},
NOTIFICATION_DETAIL("home/notification/detail") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String): Intent {
val notificationId = deepLink.extractQueryParameter("id")
return userStatus.setIntent(navigator.getNotificationDetailActivityIntent(notificationId))
}
},
MY_PAGE("home/mypage") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = userStatus.setIntent(navigator.getMyPageActivityIntent(userStatus.name))
},
ATTENDANCE("home/attendance") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = userStatus.setIntent(navigator.getAttendanceActivityIntent())
},
ATTENDANCE_MODAL("home/attendance/attendance-modal") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = userStatus.setIntent(navigator.getAttendanceActivityIntent())
},
SOPTAMP("home/soptamp") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = userStatus.setIntent(navigator.getSoptampActivityIntent())
},
SOPTAMP_ENTIRE_RANKING("home/soptamp/entire-ranking") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = userStatus.setIntent(navigator.getSoptampActivityIntent())
},
SOPTAMP_CURRENT_GENERATION_RANKING("home/soptamp/current-generation-ranking") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = userStatus.setIntent(navigator.getSoptampActivityIntent())
},
POKE_NOTIFICATION_LIST("home/poke/notification-list") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = userStatus.setIntent(navigator.getPokeNotificationActivityIntent(userStatus.name))
},
UNKNOWN("unknown-deep-link") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = getHomeIntent(userStatus, UNKNOWN)
},
EXPIRED("expired") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = getHomeIntent(userStatus, EXPIRED)
};
HOME("home") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = getHomeIntent(userStatus)
},
NOTIFICATION_LIST("home/notification") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) =
userStatus.setIntent(navigator.getNotificationActivityIntent())
},
NOTIFICATION_DETAIL("home/notification/detail") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String): Intent {
val notificationId = deepLink.extractQueryParameter("id")
return userStatus.setIntent(navigator.getNotificationDetailActivityIntent(notificationId))
}
},
MY_PAGE("home/mypage") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) =
userStatus.setIntent(navigator.getMyPageActivityIntent(userStatus.name))
},
ATTENDANCE("home/attendance") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) =
userStatus.setIntent(navigator.getAttendanceActivityIntent())
},
ATTENDANCE_MODAL("home/attendance/attendance-modal") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) =
userStatus.setIntent(navigator.getAttendanceActivityIntent())
},
SOPTAMP("home/soptamp") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) =
userStatus.setIntent(navigator.getSoptampActivityIntent())
},
SOPTAMP_ENTIRE_RANKING("home/soptamp/entire-ranking") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) =
userStatus.setIntent(navigator.getSoptampActivityIntent())
},
SOPTAMP_CURRENT_GENERATION_RANKING("home/soptamp/current-generation-ranking") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) =
userStatus.setIntent(navigator.getSoptampActivityIntent())
},
POKE_NOTIFICATION_LIST("home/poke/notification-list") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) =
userStatus.setIntent(navigator.getPokeNotificationActivityIntent(userStatus.name))
},
FORTUNE("home/fortune") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) =
userStatus.setIntent(navigator.getFortuneActivityIntent())
},
UNKNOWN("unknown-deep-link") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = getHomeIntent(userStatus, UNKNOWN)
},
EXPIRED("expired") {
override fun getIntent(context: Context, userStatus: UserStatus, deepLink: String) = getHomeIntent(userStatus, EXPIRED)
};

abstract fun getIntent(context: Context, userStatus: UserStatus, deepLink: String): Intent
abstract fun getIntent(context: Context, userStatus: UserStatus, deepLink: String): Intent

companion object {
private fun UserStatus.setIntent(intent: Intent): Intent {
return when (this == UserStatus.UNAUTHENTICATED) {
true -> navigator.getAuthActivityIntent()
false -> intent
}
}
companion object {
private fun UserStatus.setIntent(intent: Intent): Intent {
return when (this == UserStatus.UNAUTHENTICATED) {
true -> navigator.getAuthActivityIntent()
false -> intent
}
}

fun getHomeIntent(userStatus: UserStatus, deepLinkType: DeepLinkType? = null) = userStatus.setIntent(navigator.getHomeActivityIntent(userStatus, deepLinkType))
fun getHomeIntent(userStatus: UserStatus, deepLinkType: DeepLinkType? = null) =
userStatus.setIntent(navigator.getHomeActivityIntent(userStatus, deepLinkType))

fun of(deepLink: String): DeepLinkType {
return try {
val link = deepLink.split("?")[0]
entries.find { it.link == link } ?: UNKNOWN
} catch (exception: Exception) {
Timber.e(exception)
UNKNOWN
}
fun of(deepLink: String): DeepLinkType {
return try {
val link = deepLink.split("?")[0]
entries.find { it.link == link } ?: UNKNOWN
} catch (exception: Exception) {
Timber.e(exception)
UNKNOWN
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,27 @@ import dagger.hilt.components.SingletonComponent
import org.sopt.official.auth.model.UserStatus

interface NavigatorProvider {
fun getAuthActivityIntent(): Intent
fun getNotificationActivityIntent(): Intent
fun getNotificationDetailActivityIntent(notificationId: String): Intent
fun getMyPageActivityIntent(name: String): Intent
fun getAttendanceActivityIntent(): Intent
fun getSoptampActivityIntent(): Intent
fun getPokeNotificationActivityIntent(name: String): Intent
fun getHomeActivityIntent(
userStatus: UserStatus,
deepLinkType: DeepLinkType?
): Intent
fun getAuthActivityIntent(): Intent
fun getNotificationActivityIntent(): Intent
fun getNotificationDetailActivityIntent(notificationId: String): Intent
fun getMyPageActivityIntent(name: String): Intent
fun getAttendanceActivityIntent(): Intent
fun getSoptampActivityIntent(): Intent
fun getPokeNotificationActivityIntent(name: String): Intent
fun getFortuneActivityIntent(): Intent
fun getHomeActivityIntent(
userStatus: UserStatus,
deepLinkType: DeepLinkType?,
): Intent

fun getSchemeActivityIntent(
notificationId: String,
link: String
): Intent
fun getSchemeActivityIntent(
notificationId: String,
link: String,
): Intent
}

@InstallIn(SingletonComponent::class)
@EntryPoint
interface NavigatorEntryPoint {
fun navigatorProvider(): NavigatorProvider
fun navigatorProvider(): NavigatorProvider
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.sopt.official.domain.fortune.usecase

import org.sopt.official.domain.fortune.model.TodayFortuneCard
import org.sopt.official.domain.fortune.repository.FortuneRepository
import javax.inject.Inject

class GetTodayFortuneCardUseCase @Inject constructor(
private val fortuneRepository: FortuneRepository,
) {
suspend operator fun invoke(): TodayFortuneCard = fortuneRepository.fetchTodayFortuneCard()
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
*/
package org.sopt.official.feature.fortune.fortuneDetail

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.ui.semantics.SemanticsProperties
import androidx.compose.ui.semantics.getOrNull
import androidx.compose.ui.test.assertIsDisplayed
Expand Down Expand Up @@ -55,7 +54,6 @@ internal class FortuneDetailScreenTest {
composeRule.setContent {
SoptTheme {
FortuneDetailScreen(
paddingValue = PaddingValues(),
date = date,
onFortuneAmuletClick = { },
onPokeClick = { },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,31 @@ import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.EntryPointAccessors
import org.sopt.official.common.context.appContext
import org.sopt.official.common.navigator.NavigatorEntryPoint
import org.sopt.official.designsystem.SoptTheme

private val navigator by lazy {
EntryPointAccessors.fromApplication(
appContext,
NavigatorEntryPoint::class.java
).navigatorProvider()
}
giovannijunseokim marked this conversation as resolved.
Show resolved Hide resolved

@AndroidEntryPoint
class FortuneActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
SoptTheme {
FoundationScreen()
FoundationScreen(
finishActivity = this::finish,
navigateToHome = {
startActivity(navigator.getAuthActivityIntent())
},
)
}
}
}
Expand Down
Loading