From e2dd7e7753b8bbbe5bd37f415f97bcddb8130f70 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 13 May 2024 15:59:33 +0200 Subject: [PATCH 1/4] Woo POS FF --- .../android/ui/woopos/WooPosFeatureFlagEnabled.kt | 8 ++++++++ .../kotlin/com/woocommerce/android/util/FeatureFlag.kt | 2 ++ 2 files changed, 10 insertions(+) create mode 100644 WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/WooPosFeatureFlagEnabled.kt diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/WooPosFeatureFlagEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/WooPosFeatureFlagEnabled.kt new file mode 100644 index 00000000000..4ce93483481 --- /dev/null +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/WooPosFeatureFlagEnabled.kt @@ -0,0 +1,8 @@ +package com.woocommerce.android.ui.woopos + +import com.woocommerce.android.util.FeatureFlag +import javax.inject.Inject + +class WooPosFeatureFlagEnabled @Inject constructor() { + fun isEnabled() = FeatureFlag.WOO_POS.isEnabled() +} diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/util/FeatureFlag.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/util/FeatureFlag.kt index 261cffa4e29..8a6db970eff 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/util/FeatureFlag.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/util/FeatureFlag.kt @@ -6,6 +6,7 @@ import android.content.Context * "Feature flags" are used to hide in-progress features from release versions */ enum class FeatureFlag { + WOO_POS, DB_DOWNGRADE, MORE_MENU_INBOX, WC_SHIPPING_BANNER, @@ -28,6 +29,7 @@ enum class FeatureFlag { OTHER_PAYMENT_METHODS, MORE_MENU_INBOX, + WOO_POS, WC_SHIPPING_BANNER, BETTER_CUSTOMER_SEARCH_M2, ORDER_CREATION_AUTO_TAX_RATE, From bc8f3b63b3f5906a64742e4b0bde252e10a4163f Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 13 May 2024 16:46:55 +0200 Subject: [PATCH 2/4] POS button to MORE menu --- .../android/ui/moremenu/MoreMenuViewModel.kt | 10 ++++++++++ ...{WooPosFeatureFlagEnabled.kt => IsWooPosEnabled.kt} | 4 ++-- WooCommerce/src/main/res/values/strings.xml | 3 +++ 3 files changed, 15 insertions(+), 2 deletions(-) rename WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/{WooPosFeatureFlagEnabled.kt => IsWooPosEnabled.kt} (52%) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt index 3736c1aa4fa..1a2fe616cf8 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt @@ -28,6 +28,7 @@ import com.woocommerce.android.ui.payments.taptopay.TapToPayAvailabilityStatus import com.woocommerce.android.ui.payments.taptopay.isAvailable import com.woocommerce.android.ui.plans.domain.SitePlan import com.woocommerce.android.ui.plans.repository.SitePlanRepository +import com.woocommerce.android.ui.woopos.IsWooPosEnabled import com.woocommerce.android.viewmodel.MultiLiveEvent import com.woocommerce.android.viewmodel.ResourceProvider import com.woocommerce.android.viewmodel.ScopedViewModel @@ -57,6 +58,7 @@ class MoreMenuViewModel @Inject constructor( private val moreMenuNewFeatureHandler: MoreMenuNewFeatureHandler, private val tapToPayAvailabilityStatus: TapToPayAvailabilityStatus, private val isBlazeEnabled: IsBlazeEnabled, + private val isWooPosAvailable: IsWooPosEnabled, ) : ScopedViewModel(savedState) { val moreMenuViewState = combine( @@ -133,6 +135,14 @@ class MoreMenuViewModel @Inject constructor( icon = R.drawable.ic_more_menu_inbox, isEnabled = moreMenuRepository.isInboxEnabled(), onClick = ::onInboxButtonClick + ), + MenuUiButton( + title = R.string.more_menu_button_woo_pos, + description = R.string.more_menu_button_woo_pos_description, + icon = R.drawable.ic_more_menu_payments, + isEnabled = isWooPosAvailable(), + onClick = { + } ) ) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/WooPosFeatureFlagEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt similarity index 52% rename from WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/WooPosFeatureFlagEnabled.kt rename to WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt index 4ce93483481..9e7ef857473 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/WooPosFeatureFlagEnabled.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt @@ -3,6 +3,6 @@ package com.woocommerce.android.ui.woopos import com.woocommerce.android.util.FeatureFlag import javax.inject.Inject -class WooPosFeatureFlagEnabled @Inject constructor() { - fun isEnabled() = FeatureFlag.WOO_POS.isEnabled() +class IsWooPosEnabled @Inject constructor() { + operator fun invoke() = FeatureFlag.WOO_POS.isEnabled() } diff --git a/WooCommerce/src/main/res/values/strings.xml b/WooCommerce/src/main/res/values/strings.xml index 1aa7cfaea3d..2a0023651b1 100644 --- a/WooCommerce/src/main/res/values/strings.xml +++ b/WooCommerce/src/main/res/values/strings.xml @@ -3660,6 +3660,9 @@ Settings Update your preferences + Woo Pos + Temporary entry point to POS mode + From 213de23a08fa5b0720472b68a40a5a8998b784a2 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 13 May 2024 16:52:03 +0200 Subject: [PATCH 3/4] Added tests --- .../android/ui/moremenu/MoreMenuViewModel.kt | 4 +-- .../ui/moremenu/MoreMenuViewModelTests.kt | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt index 1a2fe616cf8..b1d8dbd5646 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt @@ -58,7 +58,7 @@ class MoreMenuViewModel @Inject constructor( private val moreMenuNewFeatureHandler: MoreMenuNewFeatureHandler, private val tapToPayAvailabilityStatus: TapToPayAvailabilityStatus, private val isBlazeEnabled: IsBlazeEnabled, - private val isWooPosAvailable: IsWooPosEnabled, + private val isWooPosEnabled: IsWooPosEnabled, ) : ScopedViewModel(savedState) { val moreMenuViewState = combine( @@ -140,7 +140,7 @@ class MoreMenuViewModel @Inject constructor( title = R.string.more_menu_button_woo_pos, description = R.string.more_menu_button_woo_pos_description, icon = R.drawable.ic_more_menu_payments, - isEnabled = isWooPosAvailable(), + isEnabled = isWooPosEnabled(), onClick = { } ) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModelTests.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModelTests.kt index 7e0dbb0e4b6..e92b4c183bc 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModelTests.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModelTests.kt @@ -9,6 +9,7 @@ import com.woocommerce.android.ui.moremenu.domain.MoreMenuRepository import com.woocommerce.android.ui.payments.taptopay.TapToPayAvailabilityStatus import com.woocommerce.android.ui.plans.domain.SitePlan import com.woocommerce.android.ui.plans.repository.SitePlanRepository +import com.woocommerce.android.ui.woopos.IsWooPosEnabled import com.woocommerce.android.util.captureValues import com.woocommerce.android.util.runAndCaptureValues import com.woocommerce.android.viewmodel.BaseUnitTest @@ -72,6 +73,9 @@ class MoreMenuViewModelTests : BaseUnitTest() { private val isBlazeEnabled: IsBlazeEnabled = mock { onBlocking { invoke() } doReturn true } + private val isWooPosEnabled: IsWooPosEnabled = mock { + on { invoke() } doReturn true + } private val blazeCampaignsStore: BlazeCampaignsStore = mock() @@ -92,6 +96,7 @@ class MoreMenuViewModelTests : BaseUnitTest() { blazeCampaignsStore = blazeCampaignsStore, tapToPayAvailabilityStatus = tapToPayAvailabilityStatus, isBlazeEnabled = isBlazeEnabled, + isWooPosEnabled = isWooPosEnabled, ) } @@ -402,4 +407,35 @@ class MoreMenuViewModelTests : BaseUnitTest() { assertThat(event).isEqualTo(MoreMenuViewModel.MoreMenuEvent.OpenBlazeCampaignListEvent) } + + @Test + fun `given isWooPosEnabled returns false, when building state, then WooPOS button is not displayed`() = + testBlocking { + // GIVEN + setup { + whenever(isWooPosEnabled.invoke()).thenReturn(false) + } + + // WHEN + val states = viewModel.moreMenuViewState.captureValues() + + // THEN + assertThat(states.last().generalMenuItems.first { it.title == R.string.more_menu_button_woo_pos }.isEnabled) + .isFalse() + } + + @Test + fun `given isWooPosEnabled returns true, when building state, then WooPOS button is displayed`() = testBlocking { + // GIVEN + setup { + whenever(isWooPosEnabled.invoke()).thenReturn(true) + } + + // WHEN + val states = viewModel.moreMenuViewState.captureValues() + + // THEN + assertThat(states.last().generalMenuItems.first { it.title == R.string.more_menu_button_woo_pos }.isEnabled) + .isTrue() + } } From c6199cc12a6af64b36a62d4abd0f3f2ce22e4f1a Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 13 May 2024 17:02:51 +0200 Subject: [PATCH 4/4] Dummy WooPosActivity with opening it from the fragment --- WooCommerce/src/main/AndroidManifest.xml | 54 +++++++++++-------- .../android/ui/moremenu/MoreMenuFragment.kt | 9 ++++ .../android/ui/moremenu/MoreMenuViewModel.kt | 2 + .../android/ui/woopos/root/WooPosActivity.kt | 29 ++++++++++ 4 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/root/WooPosActivity.kt diff --git a/WooCommerce/src/main/AndroidManifest.xml b/WooCommerce/src/main/AndroidManifest.xml index 8969e4cfb5a..6e75c9bba77 100644 --- a/WooCommerce/src/main/AndroidManifest.xml +++ b/WooCommerce/src/main/AndroidManifest.xml @@ -14,8 +14,10 @@ - - + + @@ -47,16 +49,17 @@ + android:windowSoftInputMode="adjustResize"> - @@ -65,19 +68,20 @@ - + - + - - - - + + + + - + + @@ -94,15 +98,15 @@ - - + + + android:exported="true" + android:theme="@style/LoginTheme"> @@ -155,7 +159,8 @@ + tools:replace="android:screenOrientation" /> + + android:exported="false" + android:permission="android.permission.BIND_JOB_SERVICE" /> - + - - + diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuFragment.kt index 9cdf4192c7a..d26af1b66ea 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuFragment.kt @@ -1,5 +1,6 @@ package com.woocommerce.android.ui.moremenu +import android.content.Intent import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -20,6 +21,7 @@ import com.woocommerce.android.ui.main.AppBarStatus import com.woocommerce.android.ui.main.MainActivity import com.woocommerce.android.ui.moremenu.MoreMenuViewModel.MoreMenuEvent.NavigateToSettingsEvent import com.woocommerce.android.ui.moremenu.MoreMenuViewModel.MoreMenuEvent.NavigateToSubscriptionsEvent +import com.woocommerce.android.ui.moremenu.MoreMenuViewModel.MoreMenuEvent.NavigateToWooPosEvent import com.woocommerce.android.ui.moremenu.MoreMenuViewModel.MoreMenuEvent.OpenBlazeCampaignCreationEvent import com.woocommerce.android.ui.moremenu.MoreMenuViewModel.MoreMenuEvent.OpenBlazeCampaignListEvent import com.woocommerce.android.ui.moremenu.MoreMenuViewModel.MoreMenuEvent.StartSitePickerEvent @@ -30,6 +32,7 @@ import com.woocommerce.android.ui.moremenu.MoreMenuViewModel.MoreMenuEvent.ViewP import com.woocommerce.android.ui.moremenu.MoreMenuViewModel.MoreMenuEvent.ViewReviewsEvent import com.woocommerce.android.ui.moremenu.MoreMenuViewModel.MoreMenuEvent.ViewStoreEvent import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderFlowParam +import com.woocommerce.android.ui.woopos.root.WooPosActivity import com.woocommerce.android.util.ChromeCustomTabUtils import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @@ -99,9 +102,15 @@ class MoreMenuFragment : TopLevelFragment() { is ViewPayments -> navigateToPayments() is OpenBlazeCampaignCreationEvent -> openBlazeCreationFlow() is OpenBlazeCampaignListEvent -> openBlazeCampaignList() + is NavigateToWooPosEvent -> openWooPos() } } } + + private fun openWooPos() { + startActivity(Intent(requireContext(), WooPosActivity::class.java)) + } + private fun openBlazeCampaignList() { findNavController().navigateSafely( MoreMenuFragmentDirections.actionMoreMenuToBlazeCampaignListFragment() diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt index b1d8dbd5646..81b54b2e4ce 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt @@ -142,6 +142,7 @@ class MoreMenuViewModel @Inject constructor( icon = R.drawable.ic_more_menu_payments, isEnabled = isWooPosEnabled(), onClick = { + triggerEvent(MoreMenuEvent.NavigateToWooPosEvent) } ) ) @@ -326,5 +327,6 @@ class MoreMenuViewModel @Inject constructor( object ViewReviewsEvent : MoreMenuEvent() object ViewInboxEvent : MoreMenuEvent() object ViewCouponsEvent : MoreMenuEvent() + object NavigateToWooPosEvent : MoreMenuEvent() } } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/root/WooPosActivity.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/root/WooPosActivity.kt new file mode 100644 index 00000000000..274c599943b --- /dev/null +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/root/WooPosActivity.kt @@ -0,0 +1,29 @@ +package com.woocommerce.android.ui.woopos.root + +import android.os.Bundle +import androidx.activity.compose.setContent +import androidx.appcompat.app.AppCompatActivity +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier + +class WooPosActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + Box( + Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + Text( + text = "Woo POS!", + style = MaterialTheme.typography.h3, + color = MaterialTheme.colors.primary, + ) + } + } + } +}