diff --git a/app/src/main/java/com/kickstarter/features/pledgedprojectsoverview/data/PPOCardFactory.kt b/app/src/main/java/com/kickstarter/features/pledgedprojectsoverview/data/PPOCardFactory.kt index 3911b68767..b2050eb2a6 100644 --- a/app/src/main/java/com/kickstarter/features/pledgedprojectsoverview/data/PPOCardFactory.kt +++ b/app/src/main/java/com/kickstarter/features/pledgedprojectsoverview/data/PPOCardFactory.kt @@ -58,5 +58,24 @@ class PPOCardFactory private constructor() { viewType = PPOCardViewType.CONFIRM_ADDRESS ) } + + fun fixPaymentCard(): PPOCard { + return ppoCard( + backingID = "1234", + amount = "$12.00", + address = "Firsty Lasty\n123 First Street, Apt #5678\nLos Angeles, CA 90025-1234\nUnited States", + currencySymbol = "$", + currencyCode = CurrencyCode.USD, + projectName = "Super Duper Project", + projectId = "12345", + projectSlug = "project/slug", + imageUrl = "image/url", + creatorName = "Creator Name", + backingDetailsUrl = "backing/details/url", + timeNumberForAction = 7, + showBadge = false, + viewType = PPOCardViewType.FIX_PAYMENT + ) + } } } diff --git a/app/src/main/java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewActivity.kt b/app/src/main/java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewActivity.kt index d9ff4ea2c3..e227e538ea 100644 --- a/app/src/main/java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewActivity.kt +++ b/app/src/main/java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewActivity.kt @@ -1,10 +1,13 @@ package com.kickstarter.features.pledgedprojectsoverview.ui +import android.app.Activity import android.content.Intent import android.os.Build import android.os.Bundle import androidx.activity.OnBackPressedCallback import androidx.activity.compose.setContent +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.compose.foundation.isSystemInDarkTheme @@ -17,11 +20,15 @@ import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.paging.compose.collectAsLazyPagingItems +import com.kickstarter.features.pledgedprojectsoverview.data.PledgedProjectsOverviewQueryData import com.kickstarter.features.pledgedprojectsoverview.viewmodel.PledgedProjectsOverviewViewModel import com.kickstarter.libs.MessagePreviousScreenType +import com.kickstarter.libs.RefTag import com.kickstarter.libs.utils.TransitionUtils import com.kickstarter.libs.utils.extensions.getEnvironment +import com.kickstarter.libs.utils.extensions.getProjectIntent import com.kickstarter.libs.utils.extensions.isDarkModeEnabled +import com.kickstarter.libs.utils.extensions.isTrue import com.kickstarter.ui.IntentKey import com.kickstarter.ui.SharedPreferenceKey import com.kickstarter.ui.activities.AppThemes @@ -36,6 +43,20 @@ class PledgedProjectsOverviewActivity : AppCompatActivity() { private lateinit var viewModelFactory: PledgedProjectsOverviewViewModel.Factory private val viewModel: PledgedProjectsOverviewViewModel by viewModels { viewModelFactory } private var theme = AppThemes.MATCH_SYSTEM.ordinal + private var startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + if (result.resultCode == Activity.RESULT_OK) { + val data = result.data?.getBooleanExtra(IntentKey.FIX_PAYMENT_SUCCESS, false) + data?.let { + if (it.isTrue()) { + viewModel.getPledgedProjects( + PledgedProjectsOverviewQueryData( + 25, null, null, null + ) + ) + } + } + } + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -87,7 +108,8 @@ class PledgedProjectsOverviewActivity : AppCompatActivity() { onSeeAllBackedProjectsClick = { startProfileActivity() }, pullRefreshCallback = { // TODO call viewmodel.getPledgedProjects() here - } + }, + onFixPaymentClick = { projectSlug -> openManagePledge(projectSlug, resultLauncher = startForResult) } ) } @@ -128,4 +150,16 @@ class PledgedProjectsOverviewActivity : AppCompatActivity() { TransitionUtils.transition(it, TransitionUtils.slideInFromRight()) } } + + private fun openManagePledge(projectSlug: String, resultLauncher: ActivityResultLauncher) { + resultLauncher.launch( + Intent().getProjectIntent(this) + .putExtra(IntentKey.PROJECT_PARAM, projectSlug) + .putExtra(IntentKey.EXPAND_PLEDGE_SHEET, true) + .putExtra(IntentKey.REF_TAG, RefTag.activity()) + ) + this.let { + TransitionUtils.transition(it, TransitionUtils.slideInFromRight()) + } + } } diff --git a/app/src/main/java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewScreen.kt b/app/src/main/java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewScreen.kt index 4d04e483e0..eff3a1d8e1 100644 --- a/app/src/main/java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewScreen.kt +++ b/app/src/main/java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewScreen.kt @@ -63,7 +63,7 @@ private fun PledgedProjectsOverviewScreenPreview() { backgroundColor = colors.backgroundSurfacePrimary ) { padding -> val ppoCardList1 = (0..10).map { - PPOCardFactory.confirmAddressCard() + PPOCardFactory.fixPaymentCard() } val ppoCardPagingList = flowOf(PagingData.from(ppoCardList1)).collectAsLazyPagingItems() PledgedProjectsOverviewScreen( @@ -76,7 +76,8 @@ private fun PledgedProjectsOverviewScreenPreview() { onProjectPledgeSummaryClick = {}, onSendMessageClick = {}, onSeeAllBackedProjectsClick = {}, - errorSnackBarHostState = SnackbarHostState() + errorSnackBarHostState = SnackbarHostState(), + onFixPaymentClick = {} ) } } @@ -105,7 +106,8 @@ private fun PledgedProjectsOverviewScreenErrorPreview() { onSendMessageClick = {}, onSeeAllBackedProjectsClick = {}, isErrored = true, - errorSnackBarHostState = SnackbarHostState() + errorSnackBarHostState = SnackbarHostState(), + onFixPaymentClick = {} ) } } @@ -129,8 +131,9 @@ private fun PledgedProjectsOverviewScreenEmptyPreview() { onAddressConfirmed = {}, onProjectPledgeSummaryClick = {}, onSendMessageClick = {}, + errorSnackBarHostState = SnackbarHostState(), + onFixPaymentClick = {}, onSeeAllBackedProjectsClick = {}, - errorSnackBarHostState = SnackbarHostState() ) } } @@ -151,7 +154,8 @@ fun PledgedProjectsOverviewScreen( onSeeAllBackedProjectsClick: () -> Unit, isLoading: Boolean = false, isErrored: Boolean = false, - pullRefreshCallback: () -> Unit = {} + pullRefreshCallback: () -> Unit = {}, + onFixPaymentClick: (projectSlug: String) -> Unit, ) { val openConfirmAddressAlertDialog = remember { mutableStateOf(false) } var confirmedAddress by remember { mutableStateOf("") } // TODO: This is either the original shipping address or the user-edited address @@ -227,7 +231,14 @@ fun PledgedProjectsOverviewScreen( sendAMessageClickAction = { onSendMessageClick(it.projectSlug() ?: "") }, shippingAddress = it.address() ?: "", // TODO replace with formatted address from PPO response showBadge = it.showBadge(), - onActionButtonClicked = { }, + onActionButtonClicked = { + when (it.viewType()) { + PPOCardViewType.FIX_PAYMENT -> { + onFixPaymentClick(it.projectSlug() ?: "") + } + else -> {} + } + }, onSecondaryActionButtonClicked = { when (it.viewType()) { PPOCardViewType.CONFIRM_ADDRESS -> { diff --git a/app/src/main/java/com/kickstarter/ui/IntentKey.kt b/app/src/main/java/com/kickstarter/ui/IntentKey.kt index 563ff6bc00..c62fa692fd 100644 --- a/app/src/main/java/com/kickstarter/ui/IntentKey.kt +++ b/app/src/main/java/com/kickstarter/ui/IntentKey.kt @@ -55,4 +55,5 @@ object IntentKey { const val FLAGGINGKIND = "com.kickstarter.kickstarter.intent_report_project" const val PREVIOUS_SCREEN = "com.kickstarter.kickstarter.previous_screen" const val OAUTH_REDIRECT_URL = "com.kickstarter.kickstarter.oauth_redirect_url" + const val FIX_PAYMENT_SUCCESS = "com.kickstarter.kickstarter.fix_payment_success" } diff --git a/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt b/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt index e665a6a39c..319b725e91 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/ProjectPageActivity.kt @@ -1120,6 +1120,9 @@ class ProjectPageActivity : private fun showUpdatePledgeSuccess() { clearFragmentBackStack() backingFragment()?.pledgeSuccessfullyUpdated() + val intent = Intent() + .putExtra(IntentKey.FIX_PAYMENT_SUCCESS, true) + setResult(Activity.RESULT_OK, intent) } private fun startShareIntent(projectNameAndShareUrl: Pair) { diff --git a/app/src/test/java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewScreenTest.kt b/app/src/test/java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewScreenTest.kt index a389e938d5..1d3d67fe13 100644 --- a/app/src/test/java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewScreenTest.kt +++ b/app/src/test/java/com/kickstarter/features/pledgedprojectsoverview/ui/PledgedProjectsOverviewScreenTest.kt @@ -37,7 +37,8 @@ PledgedProjectsOverviewScreenTest : KSRobolectricTestCase() { onSendMessageClick = {}, onAddressConfirmed = {}, onProjectPledgeSummaryClick = {}, - onSeeAllBackedProjectsClick = {} + onSeeAllBackedProjectsClick = {}, + onFixPaymentClick = {} ) } } diff --git a/app/src/test/java/com/kickstarter/features/pledgedprojectsoverview/viewmodel/PledgedProjectsOverviewViewModelTest.kt b/app/src/test/java/com/kickstarter/features/pledgedprojectsoverview/viewmodel/PledgedProjectsOverviewViewModelTest.kt index 6562668649..ff47eaedc6 100644 --- a/app/src/test/java/com/kickstarter/features/pledgedprojectsoverview/viewmodel/PledgedProjectsOverviewViewModelTest.kt +++ b/app/src/test/java/com/kickstarter/features/pledgedprojectsoverview/viewmodel/PledgedProjectsOverviewViewModelTest.kt @@ -9,6 +9,7 @@ import com.kickstarter.mock.factories.ProjectFactory import com.kickstarter.mock.services.MockApolloClientV2 import com.kickstarter.models.Project import io.reactivex.Observable +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.toList import kotlinx.coroutines.launch import kotlinx.coroutines.test.UnconfinedTestDispatcher @@ -16,6 +17,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test +@OptIn(ExperimentalCoroutinesApi::class) class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() { private lateinit var viewModel: PledgedProjectsOverviewViewModel @@ -27,7 +29,7 @@ class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() { } @Test - fun `emits_project_when_message_creator_called`() = + fun `emits project when message creator called`() = runTest { val projectState = mutableListOf() @@ -53,7 +55,7 @@ class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() { } @Test - fun `emits_error_when_message_creator_called`() = + fun `emits error when message creator called`() = runTest { var snackbarAction = 0 viewModel = PledgedProjectsOverviewViewModel.Factory( @@ -76,7 +78,7 @@ class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() { } @Test - fun `emits_snackbar_when_confirms_address`() = + fun `emits snackbar when confirms address`() = runTest { var snackbarAction = 0 viewModel.provideSnackbarMessage { snackbarAction = it } @@ -90,7 +92,7 @@ class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() { } @Test - fun `emits_error_state_when_errored`() = + fun `emits error state when errored`() = runTest { val mockApolloClientV2 = object : MockApolloClientV2() { @@ -121,7 +123,7 @@ class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() { } @Test - fun `emits_empty_state_when_no_pledges`() = + fun `emits empty state when no pledges`() = runTest { val mockApolloClientV2 = object : MockApolloClientV2() { @@ -152,7 +154,7 @@ class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() { } @Test - fun `emits_loading_then_success_state_when_successful`() = + fun `emits loading then success state when successful`() = runTest { val mockApolloClientV2 = object : MockApolloClientV2() {