Skip to content

Commit

Permalink
[Feature/#908] 오늘의 솝마디 앰플리튜드 & NDS & 에러뷰 적용 (#910)
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: 뷰모델 수정

* feature #875: delete paddingValue

* feature #875: connect TodayFortuneCard api

* feature #875: connect TodayFortuneCard data

* feature #875: delete paddingValue

* feat: 오늘 부적 받기 버튼 구현

* feature #875: change function name

* feature #875: apply typealias

* feature #875: apply slot for amuletDescription

* feat: 콕 찌르기 바텀시트 UI 구현

* refactor: 클릭 리스너 구현

* feature #875: connect navigation

* feat: 콕 찌르기 서버통신 구현

* feature #875: connect navigator with DeepLink

* feature #875: apply finishActivity

* feature #875: apply FortuneButton component

* feature #875: add contentDescription

* feature #875: apply design

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

* refactor: 배경색 수정

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

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

* refactor: 자잘한 개행 및 import

* test: 기본 생성 파일 삭제

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

* test: 테스트 코드 수정

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

* refactor: paddingValues 제거

* refactor: 변수명 변경 및 bottomsheet 관리 코루틴 로직 수정

* refactor: immutableListOf 적용

* refactor: 유저 프로필 사진 crop 버그 수정

* refactor: 콕찌르기 버튼 리플 반영

* refactor: 익명 체크 아이콘 기본값 수정

* feat: 외부 영역 터치 및 하단 스크롤 시 bottomsheet hide 기능 구현

* refactor: 포매팅 정리

* feat: snackbar 구현

* refactor: Icon으로 수정

* refactor: topAppBar Dim처리 및 snackBar 이동

* feature #875: change naming

* feature #875: add preview

* refactor: custom breaking word 로직 구현

* refactor: 매직넘버 상수화

* build: baseline-prof & spotless

* refactor: 가독성 개선

* feat: AmplitudeTracker 구현

* feat: AmplitudeTracker 적용

* refactor: NDS 적용 및 import 추가

* refactor: 람다 네이밍 수정

* feat: FortuneDetailErrorDialog 구현

* feat: FortuneDetailErrorDialog 및 CircularProgressIndicator 구현, 분기처리

* refactor: amplitudeTracker 선언 로직 수정

* refactor: 앰플리튜드 수정사항 반영

* refactor: 뷰모델 함수 네이밍 수정

* build: spotless & baseline

---------

Co-authored-by: Dongmin <[email protected]>
  • Loading branch information
s9hn and chattymin authored Oct 16, 2024
1 parent 9785e2f commit 520dd11
Show file tree
Hide file tree
Showing 28 changed files with 691 additions and 2,277 deletions.
1,207 changes: 150 additions & 1,057 deletions app/src/release/generated/baselineProfiles/baseline-prof.txt

Large diffs are not rendered by default.

1,207 changes: 150 additions & 1,057 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 2023 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 All @@ -22,7 +22,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package org.sopt.official.data.soptamp.remote.mapper

import org.sopt.official.data.soptamp.remote.model.MissionData
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 All @@ -22,7 +22,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package org.sopt.official.data.soptamp.remote.model.response

import kotlinx.serialization.Serializable
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 All @@ -22,7 +22,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package org.sopt.official.data.soptamp.remote.model.response

import kotlinx.serialization.SerialName
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* MIT License
* Copyright 2023 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 @@ -58,6 +58,7 @@ internal class FortuneDetailScreenTest {
onFortuneAmuletClick = { },
onPokeClick = { },
onProfileClick = { },
onErrorDialogCheckClick = { },
uiState = Success(
todaySentence = TodaySentence(
userName = name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,15 @@ import android.content.Intent
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.staticCompositionLocalOf
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.EntryPointAccessors
import org.sopt.official.analytics.AmplitudeTracker
import org.sopt.official.common.context.appContext
import org.sopt.official.common.navigator.NavigatorEntryPoint
import org.sopt.official.designsystem.SoptTheme
import javax.inject.Inject

private val navigator by lazy {
EntryPointAccessors.fromApplication(
Expand All @@ -42,21 +46,30 @@ private val navigator by lazy {
).navigatorProvider()
}

internal val LocalAmplitudeTracker = staticCompositionLocalOf<AmplitudeTracker> {
error("No AmplitudeTracker provided")
}

@AndroidEntryPoint
class FortuneActivity : AppCompatActivity() {

@Inject
lateinit var amplitudeTracker: AmplitudeTracker

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
SoptTheme {
FoundationScreen(
onClickLeadingIcon = {
startActivity(navigator.getNotificationActivityIntent())
},
navigateToHome = {
startActivity(navigator.getAuthActivityIntent())
},
)
CompositionLocalProvider(LocalAmplitudeTracker provides amplitudeTracker) {
FoundationScreen(
onClickLeadingIcon = {
startActivity(navigator.getNotificationActivityIntent())
},
navigateToHome = {
startActivity(navigator.getAuthActivityIntent())
},
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,34 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.sopt.official.designsystem.Gray200
import org.sopt.official.analytics.EventType
import org.sopt.official.designsystem.SoptTheme
import org.sopt.official.designsystem.SoptTheme.colors
import org.sopt.official.feature.fortune.LocalAmplitudeTracker

@Composable
fun FortuneTopBar(
onClickNavigationIcon: () -> Unit,
modifier: Modifier = Modifier,
isEnabled: Boolean = true,
) {
val amplitudeTracker = LocalAmplitudeTracker.current

Box(modifier = modifier.fillMaxWidth()) {
Icon(
imageVector = Icons.Filled.Close,
tint = if (!isEnabled) Gray200 else SoptTheme.colors.onBackground,
tint = colors.onBackground,
contentDescription = null,
modifier = Modifier.padding(start = 8.dp, top = 2.dp, bottom = 2.dp).padding(8.dp)
.clickable { if (isEnabled) onClickNavigationIcon() },
.clickable {
if (isEnabled) {
onClickNavigationIcon()
amplitudeTracker.track(
type = EventType.CLICK,
name = "click_leave_soptmadi_title",
)
}
},
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,18 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.sopt.official.analytics.EventType
import org.sopt.official.designsystem.SoptTheme
import org.sopt.official.feature.fortune.LocalAmplitudeTracker
import org.sopt.official.feature.fortune.component.CircleShapeBorderButton
import org.sopt.official.feature.fortune.component.UrlImage

@Composable
internal fun FortuneAmuletRoute(
navigateToHome: () -> Unit,
onHomeClick: () -> Unit,
viewModel: FortuneAmuletViewModel = hiltViewModel(),
) {
val amplitudeTracker = LocalAmplitudeTracker.current
val state by viewModel.state.collectAsStateWithLifecycle()

when {
Expand Down Expand Up @@ -82,8 +85,19 @@ internal fun FortuneAmuletRoute(
)
},
imageUrl = state.imageUrl,
navigateToHome = navigateToHome
)
onHomeClick = {
amplitudeTracker.track(
type = EventType.CLICK,
name = "click_done_home",
)
onHomeClick()
}
).also {
amplitudeTracker.track(
type = EventType.VIEW,
name = "view_soptmadi_charmcard",
)
}
}
}
}
Expand All @@ -93,7 +107,7 @@ private fun FortuneAmuletScreen(
description: String,
amuletDescription: @Composable ColumnScope.() -> Unit,
imageUrl: String,
navigateToHome: () -> Unit,
onHomeClick: () -> Unit,
) {
Column(
modifier = Modifier
Expand Down Expand Up @@ -134,7 +148,7 @@ private fun FortuneAmuletScreen(
modifier = Modifier.padding(horizontal = 20.dp, vertical = 12.dp)
)
},
onClick = navigateToHome
onClick = onHomeClick
)

Spacer(modifier = Modifier.height(50.dp))
Expand All @@ -161,7 +175,7 @@ fun PreviewFortuneAmuletScreen() {
)
},
imageUrl = "https://sopt-makers.s3.ap-northeast-2.amazonaws.com/mainpage/makers-app-img/test_fortune_card.png",
navigateToHome = {}
onHomeClick = {}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fun NavGraphBuilder.fortuneAmuletNavGraph(
) {
composable<FortuneAmulet> {
FortuneAmuletRoute(
navigateToHome = navigateToHome
onHomeClick = navigateToHome
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ModalBottomSheetLayout
import androidx.compose.material.ModalBottomSheetValue
import androidx.compose.material.ModalBottomSheetValue.Hidden
import androidx.compose.material.rememberModalBottomSheetState
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarDuration.Short
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
Expand All @@ -45,8 +45,14 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.launch
import org.sopt.official.designsystem.Gray800
import org.sopt.official.analytics.EventType.CLICK
import org.sopt.official.analytics.EventType.VIEW
import org.sopt.official.designsystem.SoptTheme.colors
import org.sopt.official.feature.fortune.LocalAmplitudeTracker
import org.sopt.official.feature.fortune.feature.fortuneDetail.component.PokeMessageBottomSheetScreen
import org.sopt.official.feature.fortune.feature.fortuneDetail.model.FortuneDetailUiState.Success

internal const val DEFAULT_ID = -1

@Composable
internal fun FortuneDetailRoute(
Expand All @@ -59,12 +65,22 @@ internal fun FortuneDetailRoute(
val context = LocalContext.current
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
var isAnonymous by remember { mutableStateOf(true) }
var selectedIndex by remember { mutableIntStateOf(-1) }
val bottomSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
var selectedIndex by remember { mutableIntStateOf(DEFAULT_ID) }
val bottomSheetState = rememberModalBottomSheetState(initialValue = Hidden)
val scope = rememberCoroutineScope()
val amplitudeTracker = LocalAmplitudeTracker.current

LaunchedEffect(key1 = uiState) {
if (uiState is Success) {
amplitudeTracker.track(
type = VIEW,
name = "view_soptmadi_todays",
)
}
}

LaunchedEffect(bottomSheetState.currentValue) {
if (bottomSheetState.currentValue == ModalBottomSheetValue.Hidden) isBottomSheetVisible(false)
LaunchedEffect(key1 = bottomSheetState.currentValue) {
if (bottomSheetState.currentValue == Hidden) isBottomSheetVisible(false)
}

ModalBottomSheetLayout(
Expand All @@ -73,11 +89,19 @@ internal fun FortuneDetailRoute(
topStart = 20.dp,
topEnd = 20.dp,
),
sheetBackgroundColor = Gray800,
sheetBackgroundColor = colors.onSurface800,
sheetContent = {
PokeMessageBottomSheetScreen(
selectedIndex = selectedIndex,
onItemClick = { newSelectedIndex, message ->
amplitudeTracker.track(
type = CLICK,
name = "send_choice",
properties = mapOf(
"index" to newSelectedIndex + 1,
"message" to message,
),
)
scope.launch {
selectedIndex = newSelectedIndex
bottomSheetState.hide()
Expand All @@ -88,10 +112,15 @@ internal fun FortuneDetailRoute(
},
onIconClick = {
isAnonymous = !isAnonymous
amplitudeTracker.track(
type = CLICK,
name = "click_anonymity",
properties = mapOf("isAnonymous" to isAnonymous),
)
if (isAnonymous.not()) scope.launch {
snackBarHostState.showSnackbar(
message = "",
duration = SnackbarDuration.Short,
duration = Short,
)
}
},
Expand All @@ -101,19 +130,30 @@ internal fun FortuneDetailRoute(
) {
FortuneDetailScreen(
date = date,
onFortuneAmuletClick = onFortuneAmuletClick,
onFortuneAmuletClick = {
amplitudeTracker.track(
type = CLICK,
name = "click_get_charmcard",
)
onFortuneAmuletClick()
},
onProfileClick = { userId ->
context.startActivity(
Intent(Intent.ACTION_VIEW, Uri.parse("https://playground.sopt.org/members/${userId}"))
)
},
onPokeClick = {
amplitudeTracker.track(
type = CLICK,
name = "click_randomepeople",
)
scope.launch {
bottomSheetState.show()
}.invokeOnCompletion {
isBottomSheetVisible(true)
}
},
onErrorDialogCheckClick = viewModel::updateUi,
uiState = uiState,
)
}
Expand Down
Loading

0 comments on commit 520dd11

Please sign in to comment.