expo-native-sheet-emojis 1.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +5 -3
- package/android/src/main/java/expo/community/modules/emojisheet/EmojiData.kt +19 -0
- package/android/src/main/java/expo/community/modules/emojisheet/EmojiSheetModule.kt +18 -1
- package/ios/EmojiSheetModule.podspec +1 -1
- package/ios/EmojiSheetUIView.swift +20 -0
- package/package.json +1 -1
package/android/build.gradle
CHANGED
|
@@ -20,11 +20,11 @@ buildscript {
|
|
|
20
20
|
android {
|
|
21
21
|
namespace "expo.community.modules.emojisheet"
|
|
22
22
|
|
|
23
|
-
compileSdkVersion safeExtGet("compileSdkVersion",
|
|
23
|
+
compileSdkVersion safeExtGet("compileSdkVersion", 35)
|
|
24
24
|
|
|
25
25
|
defaultConfig {
|
|
26
|
-
minSdkVersion safeExtGet("minSdkVersion",
|
|
27
|
-
targetSdkVersion safeExtGet("targetSdkVersion",
|
|
26
|
+
minSdkVersion safeExtGet("minSdkVersion", 24)
|
|
27
|
+
targetSdkVersion safeExtGet("targetSdkVersion", 35)
|
|
28
28
|
versionCode 1
|
|
29
29
|
versionName "1.0.0"
|
|
30
30
|
}
|
|
@@ -45,5 +45,7 @@ android {
|
|
|
45
45
|
implementation "androidx.recyclerview:recyclerview:1.3.2"
|
|
46
46
|
implementation "androidx.appcompat:appcompat:1.6.1"
|
|
47
47
|
implementation "com.google.android.material:material:1.11.0"
|
|
48
|
+
implementation "androidx.emoji2:emoji2:1.6.0"
|
|
49
|
+
implementation "androidx.emoji2:emoji2-views-helper:1.6.0"
|
|
48
50
|
}
|
|
49
51
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package expo.community.modules.emojisheet
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
+
import android.os.Build
|
|
4
5
|
import org.json.JSONArray
|
|
5
6
|
|
|
6
7
|
data class EmojiItem(
|
|
@@ -37,6 +38,7 @@ object EmojiData {
|
|
|
37
38
|
val json = context.assets.open("emojis.json").bufferedReader().use { it.readText() }
|
|
38
39
|
val array = JSONArray(json)
|
|
39
40
|
val categories = mutableListOf<EmojiCategory>()
|
|
41
|
+
val maxVersion = maxSupportedEmojiVersion()
|
|
40
42
|
for (i in 0 until array.length()) {
|
|
41
43
|
val obj = array.getJSONObject(i)
|
|
42
44
|
val title = obj.getString("title")
|
|
@@ -44,6 +46,8 @@ object EmojiData {
|
|
|
44
46
|
val items = mutableListOf<EmojiItem>()
|
|
45
47
|
for (j in 0 until dataArray.length()) {
|
|
46
48
|
val item = dataArray.getJSONObject(j)
|
|
49
|
+
val emojiVersion = item.getString("v").toDoubleOrNull() ?: 0.0
|
|
50
|
+
if (emojiVersion > maxVersion) continue
|
|
47
51
|
val keywordsArray = item.getJSONArray("keywords")
|
|
48
52
|
val keywords = mutableListOf<String>()
|
|
49
53
|
for (k in 0 until keywordsArray.length()) {
|
|
@@ -65,6 +69,21 @@ object EmojiData {
|
|
|
65
69
|
return categories
|
|
66
70
|
}
|
|
67
71
|
|
|
72
|
+
// API level → max Unicode emoji version (conservative estimates)
|
|
73
|
+
private fun maxSupportedEmojiVersion(): Double {
|
|
74
|
+
return when {
|
|
75
|
+
Build.VERSION.SDK_INT >= 35 -> 16.0
|
|
76
|
+
Build.VERSION.SDK_INT >= 34 -> 15.0
|
|
77
|
+
Build.VERSION.SDK_INT >= 33 -> 15.0
|
|
78
|
+
Build.VERSION.SDK_INT >= 32 -> 14.0
|
|
79
|
+
Build.VERSION.SDK_INT >= 31 -> 14.0
|
|
80
|
+
Build.VERSION.SDK_INT >= 30 -> 13.1
|
|
81
|
+
Build.VERSION.SDK_INT >= 29 -> 12.1
|
|
82
|
+
Build.VERSION.SDK_INT >= 28 -> 11.0
|
|
83
|
+
else -> 11.0
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
68
87
|
fun displayName(categoryTitle: String, customNames: Map<String, String>? = null): String {
|
|
69
88
|
customNames?.get(categoryTitle)?.let { return it }
|
|
70
89
|
return categoryDisplayNames[categoryTitle] ?: categoryTitle.replace("_", " ")
|
|
@@ -8,6 +8,9 @@ import android.view.View
|
|
|
8
8
|
import android.view.ViewGroup
|
|
9
9
|
import android.view.animation.AccelerateDecelerateInterpolator
|
|
10
10
|
import android.view.WindowManager
|
|
11
|
+
import androidx.core.view.ViewCompat
|
|
12
|
+
import androidx.core.view.WindowCompat
|
|
13
|
+
import androidx.core.view.WindowInsetsCompat
|
|
11
14
|
import android.widget.FrameLayout
|
|
12
15
|
import android.widget.LinearLayout
|
|
13
16
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
@@ -240,6 +243,18 @@ class EmojiSheetModule : Module() {
|
|
|
240
243
|
|
|
241
244
|
bottomSheet.setContentView(container)
|
|
242
245
|
|
|
246
|
+
ViewCompat.setOnApplyWindowInsetsListener(container) { view, insets ->
|
|
247
|
+
val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime())
|
|
248
|
+
val systemBarInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
|
249
|
+
view.setPadding(
|
|
250
|
+
systemBarInsets.left,
|
|
251
|
+
0,
|
|
252
|
+
systemBarInsets.right,
|
|
253
|
+
maxOf(imeInsets.bottom, systemBarInsets.bottom)
|
|
254
|
+
)
|
|
255
|
+
WindowInsetsCompat.CONSUMED
|
|
256
|
+
}
|
|
257
|
+
|
|
243
258
|
// Strip ALL backgrounds from BottomSheet internals
|
|
244
259
|
bottomSheet.setOnShowListener { dlg ->
|
|
245
260
|
val d = dlg as BottomSheetDialog
|
|
@@ -252,7 +267,9 @@ class EmojiSheetModule : Module() {
|
|
|
252
267
|
pickerView.loadDataAsync()
|
|
253
268
|
}
|
|
254
269
|
|
|
255
|
-
bottomSheet.window?.
|
|
270
|
+
bottomSheet.window?.let { window ->
|
|
271
|
+
WindowCompat.setDecorFitsSystemWindows(window, false)
|
|
272
|
+
}
|
|
256
273
|
bottomSheet.window?.setDimAmount(backdropOpacity)
|
|
257
274
|
|
|
258
275
|
bottomSheet.behavior.apply {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Pod::Spec.new do |s|
|
|
2
2
|
s.name = 'EmojiSheetModule'
|
|
3
|
-
s.version = '1.1
|
|
3
|
+
s.version = '1.2.1'
|
|
4
4
|
s.summary = 'Native emoji picker bottom sheet for React Native'
|
|
5
5
|
s.description = 'A fully native iOS/Android emoji picker presented in a bottom sheet with search, skin tones, and theming support.'
|
|
6
6
|
s.author = ''
|
|
@@ -393,6 +393,23 @@ class EmojiSheetUIView: UIView,
|
|
|
393
393
|
}
|
|
394
394
|
}
|
|
395
395
|
|
|
396
|
+
// iOS version → max Unicode emoji version. Source: https://emojipedia.org/apple
|
|
397
|
+
// Cases MUST remain ordered most-specific first (Swift evaluates top-to-bottom).
|
|
398
|
+
private static func maxSupportedEmojiVersion() -> Double {
|
|
399
|
+
let osVersion = ProcessInfo.processInfo.operatingSystemVersion
|
|
400
|
+
switch (osVersion.majorVersion, osVersion.minorVersion) {
|
|
401
|
+
case (18, 4...): return 16.0
|
|
402
|
+
case (18, _): return 15.1
|
|
403
|
+
case (17, 4...): return 15.1
|
|
404
|
+
case (17, _): return 15.0
|
|
405
|
+
case (16, 4...): return 15.0
|
|
406
|
+
case (16, _): return 14.0
|
|
407
|
+
case (15, 4...): return 14.0
|
|
408
|
+
case (15, _): return 13.1
|
|
409
|
+
default: return 13.1
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
396
413
|
private static func parseEmojiJSON() -> [EmojiSection] {
|
|
397
414
|
let bundle = Bundle(for: EmojiSheetUIView.self)
|
|
398
415
|
guard let url = bundle.url(forResource: "emojis", withExtension: "json"),
|
|
@@ -402,6 +419,7 @@ class EmojiSheetUIView: UIView,
|
|
|
402
419
|
return []
|
|
403
420
|
}
|
|
404
421
|
|
|
422
|
+
let maxVersion = Self.maxSupportedEmojiVersion()
|
|
405
423
|
return json.compactMap { sectionDict -> EmojiSection? in
|
|
406
424
|
guard let title = sectionDict["title"] as? String,
|
|
407
425
|
let items = sectionDict["data"] as? [[String: Any]]
|
|
@@ -418,6 +436,8 @@ class EmojiSheetUIView: UIView,
|
|
|
418
436
|
else {
|
|
419
437
|
return nil
|
|
420
438
|
}
|
|
439
|
+
let emojiVersion = Double(v) ?? 0
|
|
440
|
+
guard emojiVersion <= maxVersion else { return nil }
|
|
421
441
|
return EmojiItem(emoji: emoji, name: name, version: v, toneEnabled: toneEnabled, keywords: keywords, id: id)
|
|
422
442
|
}
|
|
423
443
|
return EmojiSection(title: title, data: emojis)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-native-sheet-emojis",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "A fully native emoji picker bottom sheet for React Native. Built with Swift and Kotlin for maximum performance. Features search with multilingual keywords, skin tones, frequently used tracking, theming, and configurable layout.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|