Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clipboard][Android] Fixes clipboard listener is called twice #19723

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/expo-clipboard/CHANGELOG.md
Expand Up @@ -8,6 +8,9 @@

### 🐛 Bug fixes

- Fixed clipboard listener is called twice on Android.
- Fixed clipboard listener can crash the application during initialization on Android.

### 💡 Others

## 4.0.0 — 2022-10-25
Expand Down
Expand Up @@ -147,19 +147,34 @@ class ClipboardModule : Module() {

private inner class ClipboardEventEmitter {
private var isListening = true
private var timestamp = -1L
fun resumeListening() {
isListening = true
}

fun resumeListening() { isListening = true }
fun pauseListening() { isListening = false }
fun pauseListening() {
isListening = false
}

fun attachListener() = maybeClipboardManager?.addPrimaryClipChangedListener(listener).ifNull {
Log.e(TAG, "'CLIPBOARD_SERVICE' unavailable. Events won't be received")
}

fun detachListener() = maybeClipboardManager?.removePrimaryClipChangedListener(listener)

private val listener = ClipboardManager.OnPrimaryClipChangedListener {
if (!appContext.hasActiveReactInstance) {
return@OnPrimaryClipChangedListener
}

maybeClipboardManager.takeIf { isListening }
?.primaryClipDescription
?.let { clip ->
if (timestamp == clip.timestamp) {
return@OnPrimaryClipChangedListener
}
timestamp = clip.timestamp

this@ClipboardModule.sendEvent(
CLIPBOARD_CHANGED_EVENT_NAME,
bundleOf(
Expand Down
2 changes: 2 additions & 0 deletions packages/expo-modules-core/CHANGELOG.md
Expand Up @@ -6,6 +6,8 @@

### 🎉 New features

- Added `AppContext.hasActiveReactInstance` on Android.

### 🐛 Bug fixes

### 💡 Others
Expand Down
Expand Up @@ -164,13 +164,15 @@ class AppContext(
* A directory for storing user documents and other permanent files.
*/
val persistentFilesDirectory: File
get() = appDirectories?.persistentFilesDirectory ?: throw ModuleNotFoundException("expo.modules.interfaces.filesystem.AppDirectories")
get() = appDirectories?.persistentFilesDirectory
?: throw ModuleNotFoundException("expo.modules.interfaces.filesystem.AppDirectories")

/**
* A directory for storing temporary files that can be removed at any time by the device's operating system.
*/
val cacheDirectory: File
get() = appDirectories?.cacheDirectory ?: throw ModuleNotFoundException("expo.modules.interfaces.filesystem.AppDirectories")
get() = appDirectories?.cacheDirectory
?: throw ModuleNotFoundException("expo.modules.interfaces.filesystem.AppDirectories")

/**
* Provides access to the permissions manager from the legacy module registry
Expand Down Expand Up @@ -226,6 +228,12 @@ class AppContext(
val reactContext: Context?
get() = reactContextHolder.get()

/**
* @return true if there is an non-null, alive react native instance
*/
val hasActiveReactInstance: Boolean
get() = reactContextHolder.get()?.hasActiveReactInstance() ?: false

/**
* Provides access to the event emitter
*/
Expand Down