diff --git a/lib/src/main/java/com/basistheory/elements/event/CopyEvent.kt b/lib/src/main/java/com/basistheory/elements/event/CopyEvent.kt new file mode 100644 index 0000000..09d181b --- /dev/null +++ b/lib/src/main/java/com/basistheory/elements/event/CopyEvent.kt @@ -0,0 +1,4 @@ +package com.basistheory.elements.event + +class CopyEvent + diff --git a/lib/src/main/java/com/basistheory/elements/event/ElementEventListeners.kt b/lib/src/main/java/com/basistheory/elements/event/ElementEventListeners.kt index f2c23ed..ccb50e2 100644 --- a/lib/src/main/java/com/basistheory/elements/event/ElementEventListeners.kt +++ b/lib/src/main/java/com/basistheory/elements/event/ElementEventListeners.kt @@ -4,4 +4,5 @@ class ElementEventListeners { val change: MutableList<(ChangeEvent) -> Unit> = mutableListOf() val focus: MutableList<(FocusEvent) -> Unit> = mutableListOf() val blur: MutableList<(BlurEvent) -> Unit> = mutableListOf() + val copy: MutableList<(CopyEvent) -> Unit> = mutableListOf() } diff --git a/lib/src/main/java/com/basistheory/elements/view/TextElement.kt b/lib/src/main/java/com/basistheory/elements/view/TextElement.kt index 2b8a4ce..2a23d72 100644 --- a/lib/src/main/java/com/basistheory/elements/view/TextElement.kt +++ b/lib/src/main/java/com/basistheory/elements/view/TextElement.kt @@ -18,8 +18,6 @@ import android.util.AttributeSet import android.util.TypedValue import android.view.Gravity import android.view.MotionEvent -import android.view.View.OnFocusChangeListener -import android.view.View.OnTouchListener import android.view.ViewGroup import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputConnection @@ -33,6 +31,7 @@ import com.basistheory.elements.R import com.basistheory.elements.constants.ElementValueType import com.basistheory.elements.event.BlurEvent import com.basistheory.elements.event.ChangeEvent +import com.basistheory.elements.event.CopyEvent import com.basistheory.elements.event.ElementEventListeners import com.basistheory.elements.event.FocusEvent import com.basistheory.elements.model.ElementValueReference @@ -311,6 +310,10 @@ open class TextElement @JvmOverloads constructor( _eventListeners.blur.add(listener) } + fun addCopyEventListener(listener: (CopyEvent) -> Unit) { + _eventListeners.copy.add(listener) + } + override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? { return _editText.onCreateInputConnection(outAttrs) } @@ -468,6 +471,9 @@ open class TextElement @JvmOverloads constructor( val clip: ClipData = ClipData.newPlainText("Value", getText()) clipboard.setPrimaryClip(clip) + // dispatch copy event + _eventListeners.copy.iterator().forEach { it(CopyEvent()) } + // update icon _editText.setCompoundDrawablesWithIntrinsicBounds(null, null, checkIcon, null) @@ -482,4 +488,9 @@ open class TextElement @JvmOverloads constructor( private fun removeCopy() { _editText.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null) } + + fun performCopy() { + if (!_enableCopy) return + copyTextToClipboard() + } } diff --git a/lib/src/test/java/com/basistheory/elements/view/CardExpirationDateElementTests.kt b/lib/src/test/java/com/basistheory/elements/view/CardExpirationDateElementTests.kt index ae43796..190cbc1 100644 --- a/lib/src/test/java/com/basistheory/elements/view/CardExpirationDateElementTests.kt +++ b/lib/src/test/java/com/basistheory/elements/view/CardExpirationDateElementTests.kt @@ -10,6 +10,8 @@ import org.robolectric.Robolectric import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config import strikt.api.expectThat +import strikt.assertions.hasSize +import strikt.assertions.isEmpty import strikt.assertions.isEqualTo import strikt.assertions.isFalse import strikt.assertions.isTrue @@ -191,4 +193,30 @@ class CardExpirationDateElementTests { cardExpirationDateElement.setText("aa") expectThat(cardExpirationDateElement.getTransformedText()).isEqualTo("") } + + @Test + fun `CopyEvent listener receives events when copy is triggered`() { + cardExpirationDateElement.enableCopy = true + cardExpirationDateElement.setText("12/99") + + val copyEvents = mutableListOf() + + cardExpirationDateElement.addCopyEventListener { copyEvents.add(it) } + cardExpirationDateElement.performCopy() + + expectThat(copyEvents).hasSize(1) + } + + @Test + fun `CopyEvent is not raised when enableCopy is false`() { + cardExpirationDateElement.enableCopy = false + cardExpirationDateElement.setText("12/99") + + val copyEvents = mutableListOf() + + cardExpirationDateElement.addCopyEventListener { copyEvents.add(it) } + cardExpirationDateElement.performCopy() + + expectThat(copyEvents).isEmpty() + } } diff --git a/lib/src/test/java/com/basistheory/elements/view/CardNumberElementTests.kt b/lib/src/test/java/com/basistheory/elements/view/CardNumberElementTests.kt index 2948008..f612940 100644 --- a/lib/src/test/java/com/basistheory/elements/view/CardNumberElementTests.kt +++ b/lib/src/test/java/com/basistheory/elements/view/CardNumberElementTests.kt @@ -340,4 +340,30 @@ class CardNumberElementTests { expectThat(cardNumberElement.binDetails).isNull() } + + @Test + fun `CopyEvent listener receives events when copy is triggered`() { + cardNumberElement.enableCopy = true + cardNumberElement.setText("4242 4242 4242 4242") + + val copyEvents = mutableListOf() + + cardNumberElement.addCopyEventListener { copyEvents.add(it) } + cardNumberElement.performCopy() + + expectThat(copyEvents).hasSize(1) + } + + @Test + fun `CopyEvent is not raised when enableCopy is false`() { + cardNumberElement.enableCopy = false + cardNumberElement.setText("4242 4242 4242 4242") + + val copyEvents = mutableListOf() + + cardNumberElement.addCopyEventListener { copyEvents.add(it) } + cardNumberElement.performCopy() + + expectThat(copyEvents).isEmpty() + } } \ No newline at end of file diff --git a/lib/src/test/java/com/basistheory/elements/view/CardVerificationCodeElementTests.kt b/lib/src/test/java/com/basistheory/elements/view/CardVerificationCodeElementTests.kt index 6790cfc..b1525f9 100644 --- a/lib/src/test/java/com/basistheory/elements/view/CardVerificationCodeElementTests.kt +++ b/lib/src/test/java/com/basistheory/elements/view/CardVerificationCodeElementTests.kt @@ -166,4 +166,31 @@ class CardVerificationCodeElementTests { expectThat(cvcElement.getText()).isEqualTo("123") // value does not change expectThat(changeEvents).single() // no new change events were published } + + @Test + fun `CopyEvent listener receives events when copy is triggered`() { + cvcElement.enableCopy = true + cvcElement.setText("123") + + val copyEvents = mutableListOf() + + cvcElement.addCopyEventListener { copyEvents.add(it) } + cvcElement.performCopy() + + expectThat(copyEvents).hasSize(1) + } + + + @Test + fun `CopyEvent is not raised when enableCopy is false`() { + cvcElement.enableCopy = false + cvcElement.setText("123") + + val copyEvents = mutableListOf() + + cvcElement.addCopyEventListener { copyEvents.add(it) } + cvcElement.performCopy() + + expectThat(copyEvents).isEmpty() + } } \ No newline at end of file diff --git a/lib/src/test/java/com/basistheory/elements/view/TextElementTests.kt b/lib/src/test/java/com/basistheory/elements/view/TextElementTests.kt index 18d7e40..313ff26 100644 --- a/lib/src/test/java/com/basistheory/elements/view/TextElementTests.kt +++ b/lib/src/test/java/com/basistheory/elements/view/TextElementTests.kt @@ -2,6 +2,7 @@ package com.basistheory.elements.view import android.app.Activity import com.basistheory.elements.event.ChangeEvent +import com.basistheory.elements.event.CopyEvent import com.basistheory.elements.model.ElementValueReference import com.basistheory.elements.view.mask.ElementMask import com.basistheory.elements.view.transform.RegexReplaceElementTransform @@ -198,4 +199,30 @@ class TextElementTests { expectThat(textElement.getText()).isEqualTo("4242424242424242") } + + @Test + fun `CopyEvent listener receives events when copy is triggered`() { + textElement.enableCopy = true + textElement.setText("test value") + + val copyEvents = mutableListOf() + + textElement.addCopyEventListener { copyEvents.add(it) } + textElement.performCopy() + + expectThat(copyEvents).hasSize(1) + } + + @Test + fun `CopyEvent is not raised when enableCopy is false`() { + textElement.enableCopy = false + textElement.setText("test value") + + val copyEvents = mutableListOf() + + textElement.addCopyEventListener { copyEvents.add(it) } + textElement.performCopy() + + expectThat(copyEvents).isEmpty() + } }