Skip to content

Commit

Permalink
Merge pull request #157 from YAPP-Github/feature/#149-ga
Browse files Browse the repository at this point in the history
Feature/#149 GA 추가
  • Loading branch information
jinukeu authored Feb 19, 2024
2 parents 94894b5 + 7882176 commit d2eee66
Show file tree
Hide file tree
Showing 34 changed files with 415 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ internal class FeatureComposeConventionPlugin : Plugin<Project> {
"implementation"(libs.findLibrary("kotlinx.coroutines.android").get())
"implementation"(libs.findLibrary("kotlinx.coroutines.core").get())

"implementation"(platform(libs.findLibrary("firebase.bom").get()))
"implementation"(libs.findLibrary("firebase.analytics").get())

"androidTestImplementation"(libs.findLibrary("junit").get())
"implementation"(libs.findLibrary("timber").get())
}
Expand Down
3 changes: 3 additions & 0 deletions feature/community/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 @@ -24,4 +24,9 @@ sealed interface CommunitySideEffect : SideEffect {
data object NavigateVoteSearch : CommunitySideEffect
data class NavigateVoteDetail(val voteId: Long) : CommunitySideEffect
data class ShowReportDialog(val onConfirmRequest: () -> Unit, val onCheckedAction: () -> Unit) : CommunitySideEffect
data object LogSearchIconClickEvent : CommunitySideEffect
data class LogCategoryClickEvent(val name: String) : CommunitySideEffect
data object LogPopularVoteClickEvent : CommunitySideEffect
data object LogAlignPopularVoteClickEvent : CommunitySideEffect
data object LogShowMyVoteClickEvent : CommunitySideEffect
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ 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.Alignment
import androidx.compose.ui.Modifier
Expand All @@ -40,8 +41,10 @@ import androidx.compose.ui.res.painterResource
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.appbar.icon.SearchIcon
Expand All @@ -67,6 +70,7 @@ import com.susu.feature.community.R
import com.susu.feature.community.community.component.MostPopularVoteCard
import com.susu.feature.community.community.component.VoteCard
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.time.LocalDateTime

@OptIn(ExperimentalMaterial3Api::class)
Expand All @@ -87,7 +91,7 @@ fun CommunityRoute(
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
val context = LocalContext.current

val scope = rememberCoroutineScope()
val refreshState = rememberPullToRefreshState(
positionalThreshold = 100.dp,
)
Expand All @@ -111,6 +115,47 @@ fun CommunityRoute(
)

is CommunitySideEffect.ShowSnackbar -> onShowSnackbar(SnackbarToken(message = sideEffect.message))
CommunitySideEffect.LogSearchIconClickEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "community_screen_search_icon",
),
)
}

CommunitySideEffect.LogAlignPopularVoteClickEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "community_screen_align_popular_vote",
),
)
}
is CommunitySideEffect.LogCategoryClickEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "community_screen_category_${sideEffect.name}",
),
)
}
CommunitySideEffect.LogPopularVoteClickEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "community_screen_popular_vote",
),
)
}
CommunitySideEffect.LogShowMyVoteClickEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "community_screen_show_my_vote",
),
)
}
}
}

Expand Down Expand Up @@ -156,11 +201,27 @@ fun CommunityRoute(
currentTime = currentTime,
voteListState = voteListState,
onClickFloatingButton = viewModel::navigateVoteAdd,
onClickCategory = viewModel::selectCategory,
onClickShowMine = viewModel::toggleShowMyVote,
onClickShowVotePopular = viewModel::toggleShowVotePopular,
onClickCategory = { category ->
viewModel.logCategoryClickEvent(category?.name ?: "")
viewModel.selectCategory(category)
},
onClickShowMine = {
viewModel.logShowMyVoteClickEvent()
viewModel.toggleShowMyVote()
},
onClickShowVotePopular = {
viewModel.logAlignPopularVoteClickEvent()
viewModel.toggleShowVotePopular()
},
onClickVote = viewModel::navigateVoteDetail,
onClickSearchIcon = viewModel::navigateVoteSearch,
onClickPopularVote = {
viewModel.logPopularVoteClickEvent()
viewModel.navigateVoteDetail(it)
},
onClickSearchIcon = {
viewModel.navigateVoteSearch()
viewModel.logSearchIconClickEvent()
},
onClickReport = viewModel::showReportDialog,
)
}
Expand All @@ -176,6 +237,7 @@ fun CommunityScreen(
onClickSearchIcon: () -> Unit = {},
onClickFloatingButton: () -> Unit = {},
onClickVote: (Long) -> Unit = {},
onClickPopularVote: (Long) -> Unit = {},
onClickCategory: (Category?) -> Unit = {},
onClickShowVotePopular: () -> Unit = {},
onClickShowMine: () -> Unit = {},
Expand Down Expand Up @@ -226,7 +288,7 @@ fun CommunityScreen(
items = uiState.popularVoteList,
key = { it.id },
) { vote ->
MostPopularVoteCard(vote, onClick = { onClickVote(vote.id) })
MostPopularVoteCard(vote, onClick = { onClickPopularVote(vote.id) })
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ class CommunityViewModel @Inject constructor(
private var page = 0
private var isLast = false
private var isFirstVisit = true
fun logSearchIconClickEvent() = postSideEffect(CommunitySideEffect.LogSearchIconClickEvent)
fun logPopularVoteClickEvent() = postSideEffect(CommunitySideEffect.LogPopularVoteClickEvent)
fun logShowMyVoteClickEvent() = postSideEffect(CommunitySideEffect.LogShowMyVoteClickEvent)
fun logAlignPopularVoteClickEvent() = postSideEffect(CommunitySideEffect.LogAlignPopularVoteClickEvent)
fun logCategoryClickEvent(name: String) = postSideEffect(CommunitySideEffect.LogCategoryClickEvent(name))

fun addVoteIfNeed(vote: String?) {
val toAddVote = vote?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ sealed interface VoteSearchSideEffect : SideEffect {
data object PopBackStack : VoteSearchSideEffect
data class NavigateVoteDetail(val voteId: Long) : VoteSearchSideEffect
data object FocusClear : VoteSearchSideEffect
data object LogBackClickEvent : VoteSearchSideEffect
data object LogSearchResultClickEvent : VoteSearchSideEffect
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,22 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
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.BackIcon
import com.susu.core.designsystem.component.container.SusuRecentSearchContainer
Expand All @@ -36,6 +40,7 @@ import com.susu.feature.community.R
import kotlinx.collections.immutable.PersistentList
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch

@OptIn(FlowPreview::class)
@Composable
Expand All @@ -47,11 +52,31 @@ fun VoteSearchRoute(
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
val focusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current

val context = LocalContext.current
val scope = rememberCoroutineScope()

viewModel.sideEffect.collectWithLifecycle { sideEffect ->
when (sideEffect) {
VoteSearchSideEffect.PopBackStack -> popBackStack()
is VoteSearchSideEffect.NavigateVoteDetail -> navigateVoteDetail(sideEffect.voteId)
VoteSearchSideEffect.FocusClear -> focusManager.clearFocus()
VoteSearchSideEffect.LogBackClickEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "vote_search_screen_back",
),
)
}
VoteSearchSideEffect.LogSearchResultClickEvent -> scope.launch {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT,
bundleOf(
FirebaseAnalytics.Param.CONTENT_TYPE to "vote_search_screen_search_result",
),
)
}
}
}

Expand All @@ -68,7 +93,10 @@ fun VoteSearchRoute(
VoteSearchScreen(
uiState = uiState,
focusRequester = focusRequester,
onClickBackIcon = viewModel::popBackStack,
onClickBackIcon = {
viewModel.popBackStack()
viewModel.logBackClickEvent()
},
onValueChangeSearchBar = viewModel::updateSearch,
onClickSearchClearIcon = { viewModel.updateSearch("") },
onClickRecentSearchContainer = { search ->
Expand All @@ -79,6 +107,7 @@ fun VoteSearchRoute(
},
onClickRecentSearchContainerCloseIcon = viewModel::deleteVoteRecentSearch,
onClickSearchResultContainer = { vote ->
viewModel.logSearchResultClickEvent()
viewModel.upsertVoteRecentSearch(vote.content)
viewModel.navigateVoteDetail(vote)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,12 @@ class VoteSearchViewModel @Inject constructor(
recentSearchKeywordList = searchList.toPersistentList(),
)
}

fun logBackClickEvent() {
postSideEffect(VoteSearchSideEffect.LogBackClickEvent)
}

fun logSearchResultClickEvent() {
postSideEffect(VoteSearchSideEffect.LogSearchResultClickEvent)
}
}
5 changes: 5 additions & 0 deletions feature/navigator/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<?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" />

<application>
<activity
android:name=".MainActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@ import androidx.compose.animation.slideOut
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.IntOffset
import androidx.core.os.bundleOf
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.currentBackStackEntryAsState
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.google.firebase.analytics.FirebaseAnalytics
import com.susu.core.designsystem.component.dialog.SusuCheckedDialog
import com.susu.core.designsystem.component.dialog.SusuDialog
import com.susu.core.designsystem.component.navigation.SusuNavigationBar
Expand Down Expand Up @@ -45,6 +52,8 @@ internal fun MainScreen(
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
val context = LocalContext.current
val navBackStackEntry by navigator.navController.currentBackStackEntryAsState()
val currentDestination by remember(navBackStackEntry) { derivedStateOf { navBackStackEntry?.destination } }
viewModel.sideEffect.collectWithLifecycle { sideEffect ->
when (sideEffect) {
MainSideEffect.NavigateLogin -> navigator.navigateLogin()
Expand All @@ -63,6 +72,16 @@ internal fun MainScreen(
}
}

LaunchedEffect(key1 = currentDestination) {
FirebaseAnalytics.getInstance(context).logEvent(
FirebaseAnalytics.Event.SCREEN_VIEW,
bundleOf(
FirebaseAnalytics.Param.SCREEN_NAME to currentDestination?.route,
FirebaseAnalytics.Param.SCREEN_CLASS to MainActivity::class.java.simpleName,
),
)
}

val systemUiController = rememberSystemUiController()
systemUiController.setStatusBarColor(color = navigator.statusBarColor, darkIcons = true)

Expand Down
3 changes: 3 additions & 0 deletions feature/received/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 @@ -39,4 +39,6 @@ sealed interface ReceivedEnvelopeAddSideEffect : SideEffect {
data object PopBackStack : ReceivedEnvelopeAddSideEffect
data class PopBackStackWithEnvelope(val envelope: String) : ReceivedEnvelopeAddSideEffect
data class HandleException(val throwable: Throwable, val retry: () -> Unit) : ReceivedEnvelopeAddSideEffect
data class LogClickNextButton(val step: EnvelopeAddStep) : ReceivedEnvelopeAddSideEffect
data class LogClickBackButton(val step: EnvelopeAddStep) : ReceivedEnvelopeAddSideEffect
}
Loading

0 comments on commit d2eee66

Please sign in to comment.