diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorFragment.kt index 9e6f40d27e9..d871b51c30a 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorFragment.kt @@ -6,12 +6,15 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController +import com.woocommerce.android.R +import com.woocommerce.android.extensions.copyToClipboard import com.woocommerce.android.extensions.navigateBackWithResult import com.woocommerce.android.ui.base.BaseFragment import com.woocommerce.android.ui.compose.composeView import com.woocommerce.android.ui.main.AppBarStatus import com.woocommerce.android.viewmodel.MultiLiveEvent import dagger.hilt.android.AndroidEntryPoint +import org.wordpress.android.util.ToastUtils @AndroidEntryPoint class CustomFieldsEditorFragment : BaseFragment() { @@ -32,9 +35,15 @@ class CustomFieldsEditorFragment : BaseFragment() { private fun handleEvents() { viewModel.event.observe(viewLifecycleOwner) { event -> when (event) { + is CustomFieldsEditorViewModel.CopyContentToClipboard -> copyToClipboard(event) is MultiLiveEvent.Event.ExitWithResult<*> -> navigateBackWithResult(event.key!!, event.data) MultiLiveEvent.Event.Exit -> findNavController().navigateUp() } } } + + private fun copyToClipboard(event: CustomFieldsEditorViewModel.CopyContentToClipboard) { + requireContext().copyToClipboard(getString(event.labelResource), event.content) + ToastUtils.showToast(requireContext(), R.string.copied_to_clipboard) + } } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorScreen.kt index 4c199f8dfc7..1670091a063 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorScreen.kt @@ -36,6 +36,8 @@ fun CustomFieldsEditorScreen(viewModel: CustomFieldsEditorViewModel) { onValueChanged = viewModel::onValueChanged, onDoneClicked = viewModel::onDoneClicked, onDeleteClicked = viewModel::onDeleteClicked, + onCopyKeyClicked = viewModel::onCopyKeyClicked, + onCopyValueClicked = viewModel::onCopyValueClicked, onBackButtonClick = viewModel::onBackClick, ) } @@ -48,6 +50,8 @@ private fun CustomFieldsEditorScreen( onValueChanged: (String) -> Unit, onDoneClicked: () -> Unit, onDeleteClicked: () -> Unit, + onCopyKeyClicked: () -> Unit, + onCopyValueClicked: () -> Unit, onBackButtonClick: () -> Unit, ) { BackHandler { onBackButtonClick() } @@ -64,24 +68,28 @@ private fun CustomFieldsEditorScreen( text = stringResource(R.string.done) ) } - if (!state.isCreatingNewItem) { - WCOverflowMenu( - items = listOf(R.string.delete), - mapper = { stringResource(it) }, - itemColor = { - when (it) { - R.string.delete -> MaterialTheme.colors.error - else -> LocalContentColor.current - } - }, - onSelected = { resourceId -> - when (resourceId) { - R.string.delete -> onDeleteClicked() - else -> error("Unhandled menu item") - } + WCOverflowMenu( + items = listOfNotNull( + R.string.custom_fields_editor_copy_key, + R.string.custom_fields_editor_copy_value, + if (!state.isCreatingNewItem) R.string.delete else null, + ), + mapper = { stringResource(it) }, + itemColor = { + when (it) { + R.string.delete -> MaterialTheme.colors.error + else -> LocalContentColor.current } - ) - } + }, + onSelected = { resourceId -> + when (resourceId) { + R.string.delete -> onDeleteClicked() + R.string.custom_fields_editor_copy_key -> onCopyKeyClicked() + R.string.custom_fields_editor_copy_value -> onCopyValueClicked() + else -> error("Unhandled menu item") + } + } + ) } ) }, @@ -140,6 +148,8 @@ private fun CustomFieldsEditorScreenPreview() { onValueChanged = {}, onDoneClicked = {}, onDeleteClicked = {}, + onCopyKeyClicked = {}, + onCopyValueClicked = {}, onBackButtonClick = {} ) } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorViewModel.kt index ee4a4651cba..7194bf2078a 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorViewModel.kt @@ -1,5 +1,6 @@ package com.woocommerce.android.ui.customfields.editor +import androidx.annotation.StringRes import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.asLiveData import androidx.lifecycle.viewModelScope @@ -109,6 +110,14 @@ class CustomFieldsEditorViewModel @Inject constructor( ) } + fun onCopyKeyClicked() { + triggerEvent(CopyContentToClipboard(R.string.custom_fields_editor_key_label, customFieldDraft.value.key)) + } + + fun onCopyValueClicked() { + triggerEvent(CopyContentToClipboard(R.string.custom_fields_editor_value_label, customFieldDraft.value.value)) + } + fun onBackClick() { if (state.value?.hasChanges == true) { showDiscardChangesDialog.value = true @@ -144,4 +153,9 @@ class CustomFieldsEditorViewModel @Inject constructor( val onDiscard: () -> Unit, val onCancel: () -> Unit ) + + data class CopyContentToClipboard( + @StringRes val labelResource: Int, + val content: String + ) : MultiLiveEvent.Event() } diff --git a/WooCommerce/src/main/res/values/strings.xml b/WooCommerce/src/main/res/values/strings.xml index 258ccfa49dd..ad4eb969e84 100644 --- a/WooCommerce/src/main/res/values/strings.xml +++ b/WooCommerce/src/main/res/values/strings.xml @@ -4296,4 +4296,6 @@ Value This key is already used for another custom field.\nThe app currently does not support creating duplicate keys. Please use wp-admin to duplicate a key if needed. Invalid key: please remove the \"_\" character from the beginning. + Copy Key + Copy Value diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorViewModelTest.kt index 5274c0dfdcd..ed838f2a466 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/customfields/editor/CustomFieldsEditorViewModelTest.kt @@ -246,4 +246,36 @@ class CustomFieldsEditorViewModelTest : BaseUnitTest() { .isEqualTo(UiString.UiStringRes(R.string.custom_fields_editor_key_error_underscore)) assertThat(state.showDoneButton).isFalse() } + + @Test + fun `when tapping copy key, then copy key to clipboard`() = testBlocking { + setup(editing = true) + + val event = viewModel.event.runAndCaptureValues { + viewModel.onCopyKeyClicked() + }.last() + + assertThat(event).isEqualTo( + CustomFieldsEditorViewModel.CopyContentToClipboard( + R.string.custom_fields_editor_key_label, + CUSTOM_FIELD.key + ) + ) + } + + @Test + fun `when tapping copy value, then copy value to clipboard`() = testBlocking { + setup(editing = true) + + val event = viewModel.event.runAndCaptureValues { + viewModel.onCopyValueClicked() + }.last() + + assertThat(event).isEqualTo( + CustomFieldsEditorViewModel.CopyContentToClipboard( + R.string.custom_fields_editor_value_label, + CUSTOM_FIELD.valueAsString + ) + ) + } }