Skip to content

Commit

Permalink
Merge pull request #12579 from woocommerce/issue/12578-copy-field
Browse files Browse the repository at this point in the history
[Custom Fields] Support for copying key and value
JorgeMucientes authored Sep 16, 2024
2 parents 2a89ace + 4be88f0 commit d1eb9ed
Showing 5 changed files with 84 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
@@ -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 = {}
)
}
Original file line number Diff line number Diff line change
@@ -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()
}
2 changes: 2 additions & 0 deletions WooCommerce/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -4301,4 +4301,6 @@
<string name="custom_fields_editor_value_label">Value</string>
<string name="custom_fields_editor_key_error_duplicate">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.</string>
<string name="custom_fields_editor_key_error_underscore">Invalid key: please remove the \"_\" character from the beginning.</string>
<string name="custom_fields_editor_copy_key">Copy Key</string>
<string name="custom_fields_editor_copy_value">Copy Value</string>
</resources>
Original file line number Diff line number Diff line change
@@ -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
)
)
}
}

0 comments on commit d1eb9ed

Please sign in to comment.