-
Notifications
You must be signed in to change notification settings - Fork 989
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MBL-1472: Create PPO screen activity, ui, and viewmodel (#2056)
* Create ppo screen scaffold, launch on menu item press * linter * remove unneeded file * Address feedback * linter * Renaming * cleanup * fix test --------- Co-authored-by: Leigh Douglas <[email protected]> Co-authored-by: Yun Cheng <[email protected]>
- Loading branch information
1 parent
6a4f779
commit 9cccf09
Showing
6 changed files
with
297 additions
and
2 deletions.
There are no files selected for viewing
74 changes: 73 additions & 1 deletion
74
...va/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewActivity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,77 @@ | ||
package com.kickstarter.features.pledgedprojectsoverview.ui | ||
|
||
import android.os.Build | ||
import android.os.Bundle | ||
import androidx.activity.OnBackPressedCallback | ||
import androidx.activity.compose.setContent | ||
import androidx.activity.viewModels | ||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.compose.foundation.isSystemInDarkTheme | ||
import androidx.compose.foundation.lazy.rememberLazyListState | ||
import androidx.compose.ui.Modifier | ||
import androidx.lifecycle.compose.collectAsStateWithLifecycle | ||
import androidx.paging.compose.collectAsLazyPagingItems | ||
import com.kickstarter.features.pledgedprojectsoverview.viewmodel.PledgedProjectsOverviewViewModel | ||
import com.kickstarter.libs.utils.TransitionUtils | ||
import com.kickstarter.libs.utils.extensions.getEnvironment | ||
import com.kickstarter.libs.utils.extensions.isDarkModeEnabled | ||
import com.kickstarter.ui.SharedPreferenceKey | ||
import com.kickstarter.ui.activities.AppThemes | ||
import com.kickstarter.ui.compose.designsystem.KickstarterApp | ||
import com.kickstarter.ui.extensions.transition | ||
|
||
class PledgedProjectsOverviewActivity : AppCompatActivity() | ||
class PledgedProjectsOverviewActivity : AppCompatActivity() { | ||
|
||
private lateinit var viewModelFactory: PledgedProjectsOverviewViewModel.Factory | ||
private val viewModel: PledgedProjectsOverviewViewModel by viewModels { viewModelFactory } | ||
private var theme = AppThemes.MATCH_SYSTEM.ordinal | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
|
||
this.getEnvironment()?.let { env -> | ||
setContent { | ||
viewModelFactory = PledgedProjectsOverviewViewModel.Factory(env) | ||
|
||
theme = env.sharedPreferences() | ||
?.getInt(SharedPreferenceKey.APP_THEME, AppThemes.MATCH_SYSTEM.ordinal) | ||
?: AppThemes.MATCH_SYSTEM.ordinal | ||
|
||
val darkModeEnabled = this.isDarkModeEnabled(env = env) | ||
val lazyListState = rememberLazyListState() | ||
|
||
val ppoCardPagingSource = viewModel.ppoCardsState.collectAsLazyPagingItems() | ||
val totalAlerts = viewModel.totalAlertsState.collectAsStateWithLifecycle() | ||
|
||
KickstarterApp( | ||
useDarkTheme = | ||
if (darkModeEnabled) { | ||
when (theme) { | ||
AppThemes.MATCH_SYSTEM.ordinal -> isSystemInDarkTheme() | ||
AppThemes.DARK.ordinal -> true | ||
AppThemes.LIGHT.ordinal -> false | ||
else -> false | ||
} | ||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { | ||
isSystemInDarkTheme() | ||
} else false | ||
) { | ||
PledgedProjectsOverviewScreen( | ||
modifier = Modifier, | ||
onBackPressed = { onBackPressedDispatcher.onBackPressed() }, | ||
lazyColumnListState = lazyListState, | ||
ppoCards = ppoCardPagingSource, | ||
totalAlerts = totalAlerts.value | ||
) | ||
} | ||
|
||
onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) { | ||
override fun handleOnBackPressed() { | ||
finish() | ||
this@PledgedProjectsOverviewActivity.transition(TransitionUtils.slideInFromLeft()) | ||
} | ||
}) | ||
} | ||
} | ||
} | ||
} |
153 changes: 153 additions & 0 deletions
153
...java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewScreen.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
package com.kickstarter.features.pledgedprojectsoverview.ui | ||
|
||
import android.content.res.Configuration | ||
import androidx.compose.foundation.layout.Box | ||
import androidx.compose.foundation.layout.Spacer | ||
import androidx.compose.foundation.layout.fillMaxHeight | ||
import androidx.compose.foundation.layout.fillMaxSize | ||
import androidx.compose.foundation.layout.fillMaxWidth | ||
import androidx.compose.foundation.layout.height | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.lazy.LazyColumn | ||
import androidx.compose.foundation.lazy.LazyListState | ||
import androidx.compose.foundation.lazy.rememberLazyListState | ||
import androidx.compose.material.Scaffold | ||
import androidx.compose.material.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.platform.testTag | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.tooling.preview.Preview | ||
import androidx.paging.PagingData | ||
import androidx.paging.compose.LazyPagingItems | ||
import androidx.paging.compose.collectAsLazyPagingItems | ||
import com.kickstarter.R | ||
import com.kickstarter.ui.compose.designsystem.KSTheme | ||
import com.kickstarter.ui.compose.designsystem.KSTheme.colors | ||
import com.kickstarter.ui.compose.designsystem.KSTheme.dimensions | ||
import com.kickstarter.ui.compose.designsystem.KSTheme.typography | ||
import com.kickstarter.ui.toolbars.compose.TopToolBar | ||
import kotlinx.coroutines.flow.flowOf | ||
|
||
@Composable | ||
@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) | ||
@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) | ||
private fun PledgedProjectsOverviewScreenPreview() { | ||
KSTheme { | ||
Scaffold( | ||
backgroundColor = colors.backgroundSurfacePrimary | ||
) { padding -> | ||
val ppoCardList1 = (0..10).map { | ||
PPOCardDataMock() | ||
} | ||
val ppoCardList = flowOf(PagingData.from(ppoCardList1)).collectAsLazyPagingItems() | ||
PledgedProjectsOverviewScreen( | ||
modifier = Modifier.padding(padding), | ||
lazyColumnListState = rememberLazyListState(), | ||
ppoCards = ppoCardList, | ||
totalAlerts = 10, | ||
onBackPressed = {} | ||
) | ||
} | ||
} | ||
} | ||
|
||
@Composable | ||
fun PledgedProjectsOverviewScreen( | ||
modifier: Modifier, | ||
onBackPressed: () -> Unit, | ||
lazyColumnListState: LazyListState, | ||
ppoCards: LazyPagingItems<PPOCardDataMock>, | ||
totalAlerts: Int = 0 | ||
) { | ||
Box( | ||
modifier = Modifier.fillMaxSize(), | ||
contentAlignment = Alignment.Center | ||
) { | ||
Scaffold( | ||
modifier = modifier, | ||
topBar = { | ||
TopToolBar( | ||
title = stringResource(id = R.string.project_alerts_fpo), | ||
titleColor = colors.textPrimary, | ||
leftOnClickAction = onBackPressed, | ||
leftIconColor = colors.icon, | ||
leftIconModifier = Modifier.testTag(PledgedProjectsOverviewScreenTestTag.BACK_BUTTON.name), | ||
backgroundColor = colors.backgroundSurfacePrimary, | ||
) | ||
}, | ||
backgroundColor = colors.backgroundSurfacePrimary | ||
) { padding -> | ||
LazyColumn( | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.fillMaxHeight() | ||
.padding( | ||
start = dimensions.paddingMedium, | ||
end = dimensions.paddingMedium, | ||
top = dimensions.paddingMedium | ||
) | ||
.padding(paddingValues = padding), | ||
state = lazyColumnListState | ||
) { | ||
item { | ||
Text( | ||
text = stringResource(id = R.string.alerts_fpo, totalAlerts), | ||
style = typography.title3Bold, | ||
color = colors.textPrimary | ||
) | ||
} | ||
|
||
items( | ||
count = ppoCards.itemCount | ||
) { index -> | ||
Spacer(modifier = Modifier.height(dimensions.paddingMedium)) | ||
|
||
ppoCards[index]?.let { | ||
PPOCardView( | ||
viewType = it.viewType, | ||
onCardClick = { }, | ||
projectName = it.projectName, | ||
pledgeAmount = it.pledgeAmount, | ||
imageUrl = it.imageUrl, | ||
imageContentDescription = it.imageContentDescription, | ||
creatorName = it.creatorName, | ||
sendAMessageClickAction = { }, | ||
shippingAddress = it.shippingAddress, | ||
showBadge = it.showBadge, | ||
onActionButtonClicked = { }, | ||
onSecondaryActionButtonClicked = { }, | ||
timeNumberForAction = it.timeNumberForAction | ||
) | ||
} | ||
} | ||
|
||
item { | ||
Spacer(modifier = Modifier.height(dimensions.paddingDoubleLarge)) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
enum class PledgedProjectsOverviewScreenTestTag { | ||
BACK_BUTTON, | ||
} | ||
|
||
// For preview purposes only, will remove once we have the PPO Card payload model from graph | ||
data class PPOCardDataMock( | ||
val viewType: PPOCardViewType = PPOCardViewType.FIX_PAYMENT, | ||
val onCardClick: () -> Unit = { }, | ||
val projectName: String = "This is a project name", | ||
val pledgeAmount: String = "$14.00", | ||
val imageUrl: String = "", | ||
val imageContentDescription: String = "", | ||
val creatorName: String = "Creator Name", | ||
val sendAMessageClickAction: () -> Unit = { }, | ||
val shippingAddress: String = "", | ||
val showBadge: Boolean = true, | ||
val onActionButtonClicked: () -> Unit = {}, | ||
val onSecondaryActionButtonClicked: () -> Unit = {}, | ||
val timeNumberForAction: Int = 25 | ||
) |
26 changes: 26 additions & 0 deletions
26
...ickstarter/features/pledgedprojectsoverview/viewmodel/PledgedProjectsOverviewViewModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.kickstarter.features.pledgedprojectsoverview.viewmodel | ||
|
||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.ViewModelProvider | ||
import androidx.paging.PagingData | ||
import com.kickstarter.features.pledgedprojectsoverview.ui.PPOCardDataMock | ||
import com.kickstarter.libs.Environment | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.flow.StateFlow | ||
import kotlinx.coroutines.flow.asStateFlow | ||
|
||
class PledgedProjectsOverviewViewModel(environment: Environment) : ViewModel() { | ||
|
||
private val ppoCards = MutableStateFlow<PagingData<PPOCardDataMock>>(PagingData.empty()) | ||
private val totalAlerts = MutableStateFlow<Int>(0) | ||
|
||
val ppoCardsState: StateFlow<PagingData<PPOCardDataMock>> = ppoCards.asStateFlow() | ||
val totalAlertsState: StateFlow<Int> = totalAlerts.asStateFlow() | ||
|
||
class Factory(private val environment: Environment) : | ||
ViewModelProvider.Factory { | ||
override fun <T : ViewModel> create(modelClass: Class<T>): T { | ||
return PledgedProjectsOverviewViewModel(environment) as T | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
.../com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewScreenTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.kickstarter.features.pledgedprojectsoverview.ui | ||
|
||
import androidx.compose.foundation.lazy.rememberLazyListState | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.test.onNodeWithTag | ||
import androidx.compose.ui.test.performClick | ||
import androidx.paging.PagingData | ||
import androidx.paging.compose.collectAsLazyPagingItems | ||
import com.kickstarter.KSRobolectricTestCase | ||
import com.kickstarter.ui.compose.designsystem.KSTheme | ||
import kotlinx.coroutines.flow.flowOf | ||
import org.junit.Test | ||
|
||
class PledgedProjectsOverviewScreenTest : KSRobolectricTestCase() { | ||
|
||
private val backButton = | ||
composeTestRule.onNodeWithTag(PledgedProjectsOverviewScreenTestTag.BACK_BUTTON.name) | ||
@Test | ||
fun testBackButtonClick() { | ||
var backClickedCount = 0 | ||
composeTestRule.setContent { | ||
val ppoCardList1 = (0..10).map { | ||
PPOCardDataMock() | ||
} | ||
val ppoCardList = flowOf(PagingData.from(ppoCardList1)).collectAsLazyPagingItems() | ||
|
||
KSTheme { | ||
PledgedProjectsOverviewScreen( | ||
modifier = Modifier, | ||
onBackPressed = { backClickedCount++ }, | ||
lazyColumnListState = rememberLazyListState(), | ||
ppoCards = ppoCardList | ||
) | ||
} | ||
} | ||
|
||
backButton.performClick() | ||
assertEquals(1, backClickedCount) | ||
} | ||
} |