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/ sent statistics GA #158

Merged
merged 4 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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 @@ -7,6 +7,8 @@ sealed interface EnvelopeAddEffect : SideEffect {
data object PopBackStack : EnvelopeAddEffect
data object PopBackStackWithRefresh : EnvelopeAddEffect
data class HandleException(val throwable: Throwable, val retry: () -> Unit) : EnvelopeAddEffect
data class LogClickNextButton(val step: EnvelopeAddStep) : EnvelopeAddEffect
data class LogClickBackButton(val step: EnvelopeAddStep) : EnvelopeAddEffect
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,12 @@ class EnvelopeAddViewModel @Inject constructor(
buttonEnabled = date != null,
)
}

fun logBackButtonClickEvent() {
postSideEffect(EnvelopeAddEffect.LogClickBackButton(currentState.currentStep))
}

fun logNextButtonClickEvent() {
postSideEffect(EnvelopeAddEffect.LogClickNextButton(currentState.currentStep))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.os.bundleOf
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.firebase.analytics.FirebaseAnalytics
import com.susu.core.designsystem.component.appbar.SusuProgressAppBar
import com.susu.core.designsystem.component.appbar.icon.BackIcon
import com.susu.core.designsystem.component.button.FilledButtonColor
Expand All @@ -40,6 +44,7 @@ import com.susu.feature.envelopeadd.content.phone.PhoneContentRoute
import com.susu.feature.envelopeadd.content.present.PresentContentRoute
import com.susu.feature.envelopeadd.content.relationship.RelationshipContentRoute
import com.susu.feature.envelopeadd.content.visited.VisitedContentRoute
import kotlinx.coroutines.launch
import java.time.LocalDateTime

@Composable
Expand All @@ -51,12 +56,31 @@ fun SentEnvelopeAddRoute(
handleException: (Throwable, () -> Unit) -> Unit,
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
val context = LocalContext.current
val scope = rememberCoroutineScope()

viewModel.sideEffect.collectWithLifecycle { sideEffect ->
when (sideEffect) {
is EnvelopeAddEffect.HandleException -> handleException(sideEffect.throwable, sideEffect.retry)
EnvelopeAddEffect.PopBackStack -> popBackStack()
EnvelopeAddEffect.PopBackStackWithRefresh -> popBackStackWithRefresh()
is EnvelopeAddEffect.LogClickBackButton -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "sent_envelope_add_screen_back_at_${sideEffect.step}",
),
)
}

is EnvelopeAddEffect.LogClickNextButton -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "sent_envelope_add_screen_next_at_${sideEffect.step}",
),
)
}
}
}

Expand All @@ -75,8 +99,14 @@ fun SentEnvelopeAddRoute(
SentEnvelopeAddScreen(
uiState = uiState,
categoryName = categoryName,
onClickBack = viewModel::goPrevStep,
onClickNext = viewModel::goNextStep,
onClickBack = {
viewModel.logBackButtonClickEvent()
viewModel.goPrevStep()
},
onClickNext = {
viewModel.logNextButtonClickEvent()
viewModel.goNextStep()
},
updateParentMoney = viewModel::updateMoney,
updateParentName = viewModel::updateName,
updateParentFriendId = viewModel::updateFriendId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@ sealed interface EnvelopeFilterSideEffect : SideEffect {
data object PopBackStack : EnvelopeFilterSideEffect
data class PopBackStackWithFilter(val filter: String) : EnvelopeFilterSideEffect
data class HandleException(val throwable: Throwable, val retry: () -> Unit) : EnvelopeFilterSideEffect

data object LogClickFriendButtonEvent : EnvelopeFilterSideEffect
data object LogClickSliderEvent : EnvelopeFilterSideEffect
data object LogClickApplyButtonEvent : EnvelopeFilterSideEffect
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.os.bundleOf
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.firebase.analytics.FirebaseAnalytics
import com.susu.core.designsystem.component.appbar.SusuDefaultAppBar
import com.susu.core.designsystem.component.appbar.icon.BackIcon
import com.susu.core.designsystem.component.button.FilledButtonColor
Expand All @@ -40,6 +44,7 @@ import com.susu.feature.envelopefilter.component.SearchBar
import com.susu.feature.sent.R
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch

@OptIn(FlowPreview::class)
@Composable
Expand All @@ -50,11 +55,40 @@ fun EnvelopeFilterRoute(
handleException: (Throwable, () -> Unit) -> Unit,
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
val context = LocalContext.current
val scope = rememberCoroutineScope()

viewModel.sideEffect.collectWithLifecycle { sideEffect ->
when (sideEffect) {
is EnvelopeFilterSideEffect.HandleException -> handleException(sideEffect.throwable, sideEffect.retry)
EnvelopeFilterSideEffect.PopBackStack -> popBackStack()
is EnvelopeFilterSideEffect.PopBackStackWithFilter -> popBackStackWithFilter(sideEffect.filter)
EnvelopeFilterSideEffect.LogClickApplyButtonEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "sent_filter_apply_button",
),
)
}

EnvelopeFilterSideEffect.LogClickFriendButtonEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "sent_filter_friend_button",
),
)
}

EnvelopeFilterSideEffect.LogClickSliderEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "sent_filter_slider",
),
)
}
}
}

Expand All @@ -68,15 +102,35 @@ fun EnvelopeFilterRoute(
.collect(viewModel::getFriendList)
}

LaunchedEffect(key1 = uiState.fromAmount, key2 = uiState.toAmount) {
snapshotFlow { uiState.fromAmount }
.debounce(1000L)
.collect {
viewModel.logSliderClickEvent()
}

snapshotFlow { uiState.toAmount }
.debounce(1000L)
.collect {
viewModel.logSliderClickEvent()
}
}
Comment on lines +105 to +117
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slider ๋‚ด๋ถ€์— onValueChangeFinished ์žˆ๋Š”๋ฐ ๊ทธ๊ฑธ๋กœ ga ๊ธฐ๋กํ•˜๋Š”๊ฒŒ ๋” ์ •ํ™•ํ• ๊ฑฐ๊ฐ™์•„์š”

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ฒ˜์Œ์— ๊ทธ ๋ฐฉ์‹์œผ๋กœ ํ–ˆ๋”๋‹ˆ ์Šฌ๋ผ์ด๋”๊ฐ€ ๋ฒ„๋ฒ„๋ฒ„๋ฒ„๋ฒ„๋ฒ„๋ฒ… ํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋”๋ผ๊ณ ์š”,,,,

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์—‡ onValueChange ๋ง๊ตฌ onValueChangeFinished ๋งž๋‚˜์š”?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋„ต............. ์ด๋ ‡๊ฒŒ ๋˜๋”๋ผ๊ณ ์š”

finish.mp4

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๊ธ€์ฟค์š” ... ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค


EnvelopeFilterScreen(
uiState = uiState,
onClickBackIcon = viewModel::popBackStack,
onClickApplyFilterButton = viewModel::popBackStackWithFilter,
onClickApplyFilterButton = {
viewModel.popBackStackWithFilter()
viewModel.logApplyClickEvent()
},
onClickRefreshButton = viewModel::clearFilter,
onTextChangeSearch = viewModel::updateName,
onClickFriendChip = viewModel::toggleFriend,
onClickFriendChip = { friend ->
viewModel.toggleFriend(friend)
viewModel.logFriendClickEvent()
},
onCloseFriendChip = viewModel::unselectFriend,
onMoneyValueChange = viewModel::updateMoneyRange,
onClickRefreshButton = viewModel::clearFilter,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,8 @@ class EnvelopeFilterViewModel @Inject constructor(
toAmount = null,
)
}

fun logApplyClickEvent() = postSideEffect(EnvelopeFilterSideEffect.LogClickApplyButtonEvent)
fun logFriendClickEvent() = postSideEffect(EnvelopeFilterSideEffect.LogClickFriendButtonEvent)
fun logSliderClickEvent() = postSideEffect(EnvelopeFilterSideEffect.LogClickSliderEvent)
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,8 @@ sealed interface SentEffect : SideEffect {
data object ScrollToTop : SentEffect
data class FocusToLastEnvelope(val lastIndex: Int) : SentEffect
data object LogSearchIconClickEvent : SentEffect
data object LogFilterButtonClickEvent : SentEffect
data object LogAlignButtonClickEvent : SentEffect
data class LogAlignItemClickEvent(val align: EnvelopeAlign) : SentEffect
data object LogShowHistoryButtonClickEvent : SentEffect
}
56 changes: 52 additions & 4 deletions feature/sent/src/main/java/com/susu/feature/sent/SentScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,42 @@ fun SentRoute(
),
)
}

SentEffect.LogAlignButtonClickEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "sent_screen_align_button",
),
)
}

SentEffect.LogFilterButtonClickEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "sent_screen_filter_button",
),
)
}

SentEffect.LogShowHistoryButtonClickEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "sent_screen_show_history_button",
),
)
}

is SentEffect.LogAlignItemClickEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "sent_screen_align_item_${sideEffect.align}",
),
)
}
}
}

Expand Down Expand Up @@ -153,7 +189,10 @@ fun SentRoute(
envelopesListState = envelopesListState,
refreshState = refreshState,
padding = padding,
onClickHistoryShowAll = viewModel::navigateSentEnvelope,
onClickHistoryShowAll = { id ->
viewModel.navigateSentEnvelope(id)
viewModel.logShowHistoryButtonClickEvent()
},
onClickAddEnvelope = viewModel::navigateSentAdd,
onClickSearchIcon = {
viewModel.navigateSentEnvelopeSearch()
Expand All @@ -166,11 +205,20 @@ fun SentRoute(
viewModel.getEnvelopesHistoryList(friendId)
}
},
onClickFilterButton = viewModel::navigateEnvelopeFilter,
onClickFilterButton = {
viewModel.navigateEnvelopeFilter()
viewModel.logFilterButtonClickEvent()
},
onClickFriendClose = viewModel::unselectFriend,
onClickMoneyClose = viewModel::removeMoney,
onClickAlignButton = viewModel::showAlignBottomSheet,
onClickAlignBottomSheetItem = viewModel::updateAlignPosition,
onClickAlignButton = {
viewModel.showAlignBottomSheet()
viewModel.logAlignButtonClickEvent()
},
onClickAlignBottomSheetItem = {
viewModel.updateAlignPosition(it)
viewModel.logAlignItemClickEvent(it)
},
onDismissAlignBottomSheet = viewModel::hideAlignBottomSheet,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ class SentViewModel @Inject constructor(
private var filterUri: String? = null

fun logSearchIconClickEvent() = postSideEffect(SentEffect.LogSearchIconClickEvent)
fun logFilterButtonClickEvent() = postSideEffect(SentEffect.LogFilterButtonClickEvent)
fun logAlignButtonClickEvent() = postSideEffect(SentEffect.LogAlignButtonClickEvent)
fun logAlignItemClickEvent(index: Int) = postSideEffect(SentEffect.LogAlignItemClickEvent(EnvelopeAlign.entries[index]))
fun logShowHistoryButtonClickEvent() = postSideEffect(SentEffect.LogShowHistoryButtonClickEvent)

fun getEnvelopesList(refresh: Boolean?, onFinish: () -> Unit = {}) = viewModelScope.launch {
mutex.withLock {
Expand Down
3 changes: 3 additions & 0 deletions feature/statistics/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.os.bundleOf
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.firebase.analytics.FirebaseAnalytics
import com.susu.core.designsystem.component.appbar.SusuDefaultAppBar
import com.susu.core.designsystem.component.appbar.icon.LogoIcon
import com.susu.core.designsystem.component.screen.LoadingScreen
Expand Down Expand Up @@ -58,6 +60,15 @@ fun StatisticsRoute(
viewModel.checkAdditionalInfo()
}

LaunchedEffect(key1 = uiState.currentTab) {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SCREEN_VIEW,
bundleOf(
FirebaseAnalytics.Param.SCREEN_NAME to "statistics_${uiState.currentTab}",
),
)
}

StatisticsScreen(
padding = padding,
uiState = uiState,
Expand Down
Loading
Loading