@onekeyfe/react-native-native-list 3.0.105
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/README.md +342 -0
- package/android/CMakeLists.txt +20 -0
- package/android/build.gradle +105 -0
- package/android/gradle.properties +4 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/cpp/cpp-adapter.cpp +6 -0
- package/android/src/main/java/com/onekey/nativelist/HybridNativeList.kt +125 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListAdapter.kt +165 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListModels.kt +147 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListPackage.kt +25 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListRowView.kt +2939 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListView.kt +1794 -0
- package/common/fonts/Roobert-Bold.ttf +0 -0
- package/common/fonts/Roobert-Medium.ttf +0 -0
- package/common/fonts/Roobert-Regular.ttf +0 -0
- package/common/fonts/Roobert-SemiBold.ttf +0 -0
- package/docs/DESIGN.md +129 -0
- package/ios/HybridNativeList.swift +131 -0
- package/ios/NativeListCell.swift +2858 -0
- package/ios/NativeListDesignAssets.swift +110 -0
- package/ios/NativeListModels.swift +215 -0
- package/ios/RNCNativeListView.swift +1737 -0
- package/ios/Resources/NativeListIcons.xcassets/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_arrow_bottom.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_arrow_bottom.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_arrow_top.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_arrow_top.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chart_trending_up.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chart_trending_up.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_checkbox_checked.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_checkbox_checked.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_checkbox_indeterminate.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_checkbox_indeterminate.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_bottom.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_bottom.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_grabber_ver.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_grabber_ver.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_right_small.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_right_small.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_top.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_chevron_top.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_dot_hor.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_dot_hor.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_drag.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_drag.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_error_solid.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_error_solid.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_image_square_waves.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_image_square_waves.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_info_circle.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_info_circle.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_minus_circle.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_minus_circle.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_minus_circle_solid.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_minus_circle_solid.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_pencil.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_pencil.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_plus_circle.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_plus_circle.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_plus_small.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_plus_small.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_questionmark_solid.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_questionmark_solid.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_shield_exclamation.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_shield_exclamation.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_speaker_promote.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_speaker_promote.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_star.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_star.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_star_solid.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_star_solid.imageset/icon.svg +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_swap_hor.imageset/Contents.json +1 -0
- package/ios/Resources/NativeListIcons.xcassets/onekey_swap_hor.imageset/icon.svg +1 -0
- package/lib/module/NativeList.js +183 -0
- package/lib/module/NativeList.nitro.js +4 -0
- package/lib/module/NativeList.types.js +4 -0
- package/lib/module/NativeList.web.js +167 -0
- package/lib/module/index.js +6 -0
- package/lib/module/models.js +2 -0
- package/lib/module/package.json +1 -0
- package/lib/module/scrolling.js +121 -0
- package/lib/module/selection.js +85 -0
- package/lib/module/validation.js +562 -0
- package/lib/module/web/NativeListWebEngine.js +2238 -0
- package/lib/nitrogen/generated/.gitattributes +1 -0
- package/lib/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
- package/lib/nitrogen/generated/android/c++/JHybridNativeListSpec.cpp +201 -0
- package/lib/nitrogen/generated/android/c++/JHybridNativeListSpec.hpp +84 -0
- package/lib/nitrogen/generated/android/c++/JNativeListScrollAlignment.hpp +64 -0
- package/lib/nitrogen/generated/android/c++/views/JHybridNativeListStateUpdater.cpp +104 -0
- package/lib/nitrogen/generated/android/c++/views/JHybridNativeListStateUpdater.hpp +54 -0
- package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/Func_void_std__string.kt +78 -0
- package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/HybridNativeListSpec.kt +177 -0
- package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/NativeListScrollAlignment.kt +25 -0
- package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/nativelistOnLoad.kt +35 -0
- package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/views/HybridNativeListManager.kt +96 -0
- package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/views/HybridNativeListStateUpdater.kt +23 -0
- package/lib/nitrogen/generated/android/nativelist+autolinking.cmake +83 -0
- package/lib/nitrogen/generated/android/nativelist+autolinking.gradle +27 -0
- package/lib/nitrogen/generated/android/nativelistOnLoad.cpp +58 -0
- package/lib/nitrogen/generated/android/nativelistOnLoad.hpp +34 -0
- package/lib/nitrogen/generated/ios/NativeListModule+autolinking.rb +62 -0
- package/lib/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Bridge.cpp +41 -0
- package/lib/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Bridge.hpp +91 -0
- package/lib/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Umbrella.hpp +49 -0
- package/lib/nitrogen/generated/ios/NativeListModuleAutolinking.mm +33 -0
- package/lib/nitrogen/generated/ios/NativeListModuleAutolinking.swift +26 -0
- package/lib/nitrogen/generated/ios/c++/HybridNativeListSpecSwift.cpp +11 -0
- package/lib/nitrogen/generated/ios/c++/HybridNativeListSpecSwift.hpp +180 -0
- package/lib/nitrogen/generated/ios/c++/views/HybridNativeListComponent.mm +180 -0
- package/lib/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
- package/lib/nitrogen/generated/ios/swift/HybridNativeListSpec.swift +69 -0
- package/lib/nitrogen/generated/ios/swift/HybridNativeListSpec_cxx.swift +447 -0
- package/lib/nitrogen/generated/ios/swift/NativeListScrollAlignment.swift +48 -0
- package/lib/nitrogen/generated/shared/c++/HybridNativeListSpec.cpp +43 -0
- package/lib/nitrogen/generated/shared/c++/HybridNativeListSpec.hpp +87 -0
- package/lib/nitrogen/generated/shared/c++/NativeListScrollAlignment.hpp +84 -0
- package/lib/nitrogen/generated/shared/c++/views/HybridNativeListComponent.cpp +46 -0
- package/lib/nitrogen/generated/shared/c++/views/HybridNativeListComponent.hpp +103 -0
- package/lib/nitrogen/generated/shared/json/NativeListConfig.json +16 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeList.d.ts +18 -0
- package/lib/typescript/src/NativeList.nitro.d.ts +29 -0
- package/lib/typescript/src/NativeList.types.d.ts +87 -0
- package/lib/typescript/src/NativeList.web.d.ts +19 -0
- package/lib/typescript/src/index.d.ts +7 -0
- package/lib/typescript/src/models.d.ts +456 -0
- package/lib/typescript/src/scrolling.d.ts +32 -0
- package/lib/typescript/src/selection.d.ts +27 -0
- package/lib/typescript/src/validation.d.ts +7 -0
- package/lib/typescript/src/web/NativeListWebEngine.d.ts +203 -0
- package/nitro.json +23 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
- package/nitrogen/generated/android/c++/JHybridNativeListSpec.cpp +201 -0
- package/nitrogen/generated/android/c++/JHybridNativeListSpec.hpp +84 -0
- package/nitrogen/generated/android/c++/JNativeListScrollAlignment.hpp +64 -0
- package/nitrogen/generated/android/c++/views/JHybridNativeListStateUpdater.cpp +104 -0
- package/nitrogen/generated/android/c++/views/JHybridNativeListStateUpdater.hpp +54 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/Func_void_std__string.kt +78 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/HybridNativeListSpec.kt +177 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/NativeListScrollAlignment.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/nativelistOnLoad.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/views/HybridNativeListManager.kt +96 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/views/HybridNativeListStateUpdater.kt +23 -0
- package/nitrogen/generated/android/nativelist+autolinking.cmake +83 -0
- package/nitrogen/generated/android/nativelist+autolinking.gradle +27 -0
- package/nitrogen/generated/android/nativelistOnLoad.cpp +58 -0
- package/nitrogen/generated/android/nativelistOnLoad.hpp +34 -0
- package/nitrogen/generated/ios/NativeListModule+autolinking.rb +62 -0
- package/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Bridge.cpp +41 -0
- package/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Bridge.hpp +91 -0
- package/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Umbrella.hpp +49 -0
- package/nitrogen/generated/ios/NativeListModuleAutolinking.mm +33 -0
- package/nitrogen/generated/ios/NativeListModuleAutolinking.swift +26 -0
- package/nitrogen/generated/ios/c++/HybridNativeListSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridNativeListSpecSwift.hpp +180 -0
- package/nitrogen/generated/ios/c++/views/HybridNativeListComponent.mm +180 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridNativeListSpec.swift +69 -0
- package/nitrogen/generated/ios/swift/HybridNativeListSpec_cxx.swift +447 -0
- package/nitrogen/generated/ios/swift/NativeListScrollAlignment.swift +48 -0
- package/nitrogen/generated/shared/c++/HybridNativeListSpec.cpp +43 -0
- package/nitrogen/generated/shared/c++/HybridNativeListSpec.hpp +87 -0
- package/nitrogen/generated/shared/c++/NativeListScrollAlignment.hpp +84 -0
- package/nitrogen/generated/shared/c++/views/HybridNativeListComponent.cpp +46 -0
- package/nitrogen/generated/shared/c++/views/HybridNativeListComponent.hpp +103 -0
- package/nitrogen/generated/shared/json/NativeListConfig.json +16 -0
- package/package.json +126 -0
- package/react-native-native-list.podspec +38 -0
- package/react-native.config.js +19 -0
- package/src/NativeList.nitro.ts +48 -0
- package/src/NativeList.tsx +298 -0
- package/src/NativeList.types.ts +125 -0
- package/src/NativeList.web.tsx +258 -0
- package/src/index.ts +35 -0
- package/src/models.ts +604 -0
- package/src/scrolling.ts +189 -0
- package/src/selection.ts +159 -0
- package/src/validation.ts +877 -0
- package/src/web/NativeListWebEngine.ts +3767 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
package com.margelo.nitro.nativelist
|
|
2
|
+
|
|
3
|
+
import android.view.ViewGroup
|
|
4
|
+
import androidx.recyclerview.widget.AsyncDifferConfig
|
|
5
|
+
import androidx.recyclerview.widget.AsyncListDiffer
|
|
6
|
+
import androidx.recyclerview.widget.DiffUtil
|
|
7
|
+
import androidx.recyclerview.widget.ListUpdateCallback
|
|
8
|
+
import androidx.recyclerview.widget.RecyclerView
|
|
9
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
10
|
+
import org.json.JSONObject
|
|
11
|
+
import java.util.Collections
|
|
12
|
+
import java.util.WeakHashMap
|
|
13
|
+
|
|
14
|
+
internal class NativeListAdapter(
|
|
15
|
+
private val context: ThemedReactContext,
|
|
16
|
+
) : RecyclerView.Adapter<NativeListViewHolder>() {
|
|
17
|
+
private var suppressDifferUpdates = false
|
|
18
|
+
private var reorderItems: MutableList<NativeListItem>? = null
|
|
19
|
+
private val differ = AsyncListDiffer(
|
|
20
|
+
object : ListUpdateCallback {
|
|
21
|
+
override fun onInserted(position: Int, count: Int) {
|
|
22
|
+
if (!suppressDifferUpdates) notifyItemRangeInserted(position, count)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
override fun onRemoved(position: Int, count: Int) {
|
|
26
|
+
if (!suppressDifferUpdates) notifyItemRangeRemoved(position, count)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun onMoved(fromPosition: Int, toPosition: Int) {
|
|
30
|
+
if (!suppressDifferUpdates) notifyItemMoved(fromPosition, toPosition)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override fun onChanged(position: Int, count: Int, payload: Any?) {
|
|
34
|
+
if (!suppressDifferUpdates) notifyItemRangeChanged(position, count, payload)
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
AsyncDifferConfig.Builder(DIFF).build(),
|
|
38
|
+
)
|
|
39
|
+
val currentList: List<NativeListItem>
|
|
40
|
+
get() = differ.currentList
|
|
41
|
+
private val createdRows = Collections.newSetFromMap(
|
|
42
|
+
WeakHashMap<NativeListRowView, Boolean>(),
|
|
43
|
+
)
|
|
44
|
+
var theme: JSONObject? = null
|
|
45
|
+
var layout: String = "linear"
|
|
46
|
+
var orientation: String = "vertical"
|
|
47
|
+
var selectedKeys: Set<String> = emptySet()
|
|
48
|
+
var checkboxState: (NativeListItem, NativeSelectionTarget?, String) -> String = { _, _, fallback -> fallback }
|
|
49
|
+
var onRowPress: ((NativeListItem, NativeListActionOrigin) -> Unit)? = null
|
|
50
|
+
var onAction: ((NativeListItem, String, NativeSelectionTarget?, NativeListActionOrigin?) -> Unit)? = null
|
|
51
|
+
var onBindingInvalidated: ((NativeListRowView, Long) -> Unit)? = null
|
|
52
|
+
|
|
53
|
+
override fun getItemCount(): Int = reorderItems?.size ?: differ.currentList.size
|
|
54
|
+
|
|
55
|
+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NativeListViewHolder {
|
|
56
|
+
val view = NativeListRowView(context)
|
|
57
|
+
view.layoutParams = ViewGroup.LayoutParams(
|
|
58
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
59
|
+
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
60
|
+
)
|
|
61
|
+
view.onRowPress = { item, origin -> onRowPress?.invoke(item, origin) }
|
|
62
|
+
view.onAction = { item, actionKey, target, origin ->
|
|
63
|
+
onAction?.invoke(item, actionKey, target, origin)
|
|
64
|
+
}
|
|
65
|
+
view.onBindingInvalidated = { row, epoch -> onBindingInvalidated?.invoke(row, epoch) }
|
|
66
|
+
createdRows.add(view)
|
|
67
|
+
return NativeListViewHolder(view)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
override fun onBindViewHolder(holder: NativeListViewHolder, position: Int) {
|
|
71
|
+
val item = itemAt(position) ?: return
|
|
72
|
+
holder.rowView.bind(
|
|
73
|
+
item,
|
|
74
|
+
theme,
|
|
75
|
+
layout,
|
|
76
|
+
orientation,
|
|
77
|
+
position,
|
|
78
|
+
selectedKeys.contains(item.key),
|
|
79
|
+
checkboxState,
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
override fun onBindViewHolder(
|
|
84
|
+
holder: NativeListViewHolder,
|
|
85
|
+
position: Int,
|
|
86
|
+
payloads: MutableList<Any>,
|
|
87
|
+
) {
|
|
88
|
+
if (payloads.contains(SELECTION_PAYLOAD)) {
|
|
89
|
+
val item = itemAt(position) ?: return
|
|
90
|
+
holder.rowView.bindSelection(
|
|
91
|
+
item,
|
|
92
|
+
theme,
|
|
93
|
+
layout,
|
|
94
|
+
position,
|
|
95
|
+
selectedKeys.contains(item.key),
|
|
96
|
+
checkboxState,
|
|
97
|
+
)
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
onBindViewHolder(holder, position)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
override fun onViewRecycled(holder: NativeListViewHolder) {
|
|
104
|
+
holder.rowView.recycle()
|
|
105
|
+
super.onViewRecycled(holder)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
fun itemAt(position: Int): NativeListItem? =
|
|
109
|
+
reorderItems?.getOrNull(position) ?: differ.currentList.getOrNull(position)
|
|
110
|
+
|
|
111
|
+
fun positionOfKey(key: String): Int =
|
|
112
|
+
(reorderItems ?: differ.currentList).indexOfFirst { it.key == key }
|
|
113
|
+
|
|
114
|
+
fun submitList(items: List<NativeListItem>, commitCallback: (() -> Unit)? = null) {
|
|
115
|
+
if (reorderItems != null) {
|
|
116
|
+
reorderItems = null
|
|
117
|
+
notifyDataSetChanged()
|
|
118
|
+
}
|
|
119
|
+
differ.submitList(items.toList()) { commitCallback?.invoke() }
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
fun moveReordered(from: Int, to: Int): List<NativeListItem>? {
|
|
123
|
+
val items = reorderItems ?: differ.currentList.toMutableList().also { reorderItems = it }
|
|
124
|
+
if (from !in items.indices || to !in items.indices) return null
|
|
125
|
+
val moved = items.removeAt(from)
|
|
126
|
+
items.add(to, moved)
|
|
127
|
+
notifyItemMoved(from, to)
|
|
128
|
+
return items
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
fun commitReordered(items: List<NativeListItem>, commitCallback: () -> Unit) {
|
|
132
|
+
val committed = items.toList()
|
|
133
|
+
suppressDifferUpdates = true
|
|
134
|
+
differ.submitList(committed) {
|
|
135
|
+
reorderItems = null
|
|
136
|
+
suppressDifferUpdates = false
|
|
137
|
+
commitCallback()
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
fun cancelReorder() {
|
|
142
|
+
if (reorderItems == null) return
|
|
143
|
+
reorderItems = null
|
|
144
|
+
notifyDataSetChanged()
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
fun dispose() {
|
|
148
|
+
reorderItems = null
|
|
149
|
+
suppressDifferUpdates = false
|
|
150
|
+
createdRows.forEach(NativeListRowView::dispose)
|
|
151
|
+
createdRows.clear()
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
companion object {
|
|
155
|
+
private val DIFF = object : DiffUtil.ItemCallback<NativeListItem>() {
|
|
156
|
+
override fun areItemsTheSame(oldItem: NativeListItem, newItem: NativeListItem): Boolean =
|
|
157
|
+
oldItem.key == newItem.key && oldItem.type == newItem.type
|
|
158
|
+
|
|
159
|
+
override fun areContentsTheSame(oldItem: NativeListItem, newItem: NativeListItem): Boolean =
|
|
160
|
+
oldItem.revision == newItem.revision && oldItem.content == newItem.content
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
internal const val SELECTION_PAYLOAD = "selection"
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
package com.margelo.nitro.nativelist
|
|
2
|
+
|
|
3
|
+
import org.json.JSONArray
|
|
4
|
+
import org.json.JSONObject
|
|
5
|
+
|
|
6
|
+
internal data class NativeListItem(
|
|
7
|
+
val key: String,
|
|
8
|
+
val type: String,
|
|
9
|
+
val sectionKey: String?,
|
|
10
|
+
val revision: Int,
|
|
11
|
+
val json: JSONObject,
|
|
12
|
+
) {
|
|
13
|
+
val content: String = json.toString()
|
|
14
|
+
|
|
15
|
+
val isSelectable: Boolean
|
|
16
|
+
get() = !json.optBoolean("disabled", false) && type in SELECTABLE_TYPES
|
|
17
|
+
|
|
18
|
+
val isReorderable: Boolean
|
|
19
|
+
get() {
|
|
20
|
+
if (json.optBoolean("disabled", false)) return false
|
|
21
|
+
if (type == "rail" && json.optBoolean("draggable", false)) return true
|
|
22
|
+
if (type == "identity" && json.optBoolean("draggable", false)) return true
|
|
23
|
+
if (type == "walletGroup" && json.optBoolean("draggable", false)) return true
|
|
24
|
+
val trailing = json.optJSONArray("trailing") ?: return false
|
|
25
|
+
return (0 until trailing.length()).any { index ->
|
|
26
|
+
trailing.optJSONObject(index)?.optString("kind") == "drag"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
companion object {
|
|
31
|
+
private val SELECTABLE_TYPES = setOf(
|
|
32
|
+
"identity",
|
|
33
|
+
"rail",
|
|
34
|
+
"activity",
|
|
35
|
+
"message",
|
|
36
|
+
"dataRow",
|
|
37
|
+
"mediaTile",
|
|
38
|
+
"metricCard",
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
fun parse(json: JSONObject): NativeListItem {
|
|
42
|
+
val key = json.getString("key")
|
|
43
|
+
val type = json.getString("type")
|
|
44
|
+
return NativeListItem(
|
|
45
|
+
key = key,
|
|
46
|
+
type = type,
|
|
47
|
+
sectionKey = json.optString("sectionKey").takeIf { it.isNotEmpty() },
|
|
48
|
+
revision = json.optInt("revision", 0),
|
|
49
|
+
json = json,
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
internal data class NativeListConfig(
|
|
56
|
+
val generation: Int,
|
|
57
|
+
val layout: String,
|
|
58
|
+
val orientation: String,
|
|
59
|
+
val gridColumns: Int,
|
|
60
|
+
val stickyHeaders: Boolean,
|
|
61
|
+
val contentPadding: Int,
|
|
62
|
+
val contentPaddingHorizontal: Int?,
|
|
63
|
+
val contentPaddingTop: Int?,
|
|
64
|
+
val contentPaddingBottom: Int?,
|
|
65
|
+
val itemSpacing: Int,
|
|
66
|
+
val selectionMode: String,
|
|
67
|
+
val rowPressToggles: Boolean,
|
|
68
|
+
val selectedKeys: LinkedHashSet<String>,
|
|
69
|
+
val reorderable: Boolean,
|
|
70
|
+
val pullToRefresh: Boolean,
|
|
71
|
+
val refreshing: Boolean,
|
|
72
|
+
val loadMore: Boolean,
|
|
73
|
+
val endReachedThreshold: Double,
|
|
74
|
+
val sectionIndexEnabled: Boolean,
|
|
75
|
+
val sectionIndexHapticsEnabled: Boolean,
|
|
76
|
+
val theme: JSONObject?,
|
|
77
|
+
val fixedFooter: NativeListItem?,
|
|
78
|
+
val items: List<NativeListItem>,
|
|
79
|
+
) {
|
|
80
|
+
companion object {
|
|
81
|
+
fun parse(snapshotJson: String): NativeListConfig {
|
|
82
|
+
val root = JSONObject(snapshotJson)
|
|
83
|
+
require(root.getInt("schemaVersion") == 1) { "Unsupported schemaVersion" }
|
|
84
|
+
val layout = root.getJSONObject("layout")
|
|
85
|
+
val selection = root.optJSONObject("selection")
|
|
86
|
+
val capabilities = root.optJSONObject("capabilities")
|
|
87
|
+
val sectionIndex = capabilities?.optJSONObject("sectionIndex")
|
|
88
|
+
val rowArray = root.getJSONArray("rows")
|
|
89
|
+
val items = ArrayList<NativeListItem>(rowArray.length())
|
|
90
|
+
val keys = HashSet<String>(rowArray.length())
|
|
91
|
+
for (index in 0 until rowArray.length()) {
|
|
92
|
+
val item = NativeListItem.parse(rowArray.getJSONObject(index))
|
|
93
|
+
require(keys.add(item.key)) { "Duplicate row key: ${item.key}" }
|
|
94
|
+
items.add(item)
|
|
95
|
+
}
|
|
96
|
+
if (items.isEmpty()) {
|
|
97
|
+
root.optJSONObject("emptyState")?.let { items.add(NativeListItem.parse(it)) }
|
|
98
|
+
}
|
|
99
|
+
val selectedKeys = LinkedHashSet<String>()
|
|
100
|
+
selection?.optJSONArray("selectedKeys")?.forEachString { selectedKeys.add(it) }
|
|
101
|
+
require(selectedKeys.all(keys::contains)) { "Selection contains an unknown row key" }
|
|
102
|
+
val fixedFooter = root.optJSONObject("fixedFooter")?.let(NativeListItem::parse)
|
|
103
|
+
return NativeListConfig(
|
|
104
|
+
generation = root.getInt("generation"),
|
|
105
|
+
layout = layout.getString("kind"),
|
|
106
|
+
orientation = layout.optString("orientation", "vertical"),
|
|
107
|
+
gridColumns = layout.optInt("gridColumns", 1).coerceIn(1, 4),
|
|
108
|
+
stickyHeaders = layout.optBoolean("stickyHeaders", false),
|
|
109
|
+
contentPadding = layout.optInt("contentPadding", 0).coerceAtLeast(0),
|
|
110
|
+
contentPaddingHorizontal = layout.optionalNonNegativeInt("contentPaddingHorizontal"),
|
|
111
|
+
contentPaddingTop = layout.optionalNonNegativeInt("contentPaddingTop"),
|
|
112
|
+
contentPaddingBottom = layout.optionalNonNegativeInt("contentPaddingBottom"),
|
|
113
|
+
itemSpacing = layout.optInt("itemSpacing", 0).coerceAtLeast(0),
|
|
114
|
+
selectionMode = selection?.optString("mode", "none") ?: "none",
|
|
115
|
+
rowPressToggles = selection?.optBoolean("rowPressToggles", false) ?: false,
|
|
116
|
+
selectedKeys = selectedKeys,
|
|
117
|
+
reorderable = capabilities?.optBoolean("reorderable", false) ?: false,
|
|
118
|
+
pullToRefresh = capabilities?.optBoolean("pullToRefresh", false) ?: false,
|
|
119
|
+
refreshing = capabilities?.optBoolean("refreshing", false) ?: false,
|
|
120
|
+
loadMore = capabilities?.optBoolean("loadMore", false) ?: false,
|
|
121
|
+
endReachedThreshold = capabilities?.optDouble("endReachedThreshold", 0.2) ?: 0.2,
|
|
122
|
+
sectionIndexEnabled = sectionIndex?.optBoolean("enabled", false) ?: false,
|
|
123
|
+
sectionIndexHapticsEnabled = sectionIndex?.optBoolean("hapticsEnabled", true) ?: true,
|
|
124
|
+
theme = root.optJSONObject("theme"),
|
|
125
|
+
fixedFooter = fixedFooter,
|
|
126
|
+
items = items,
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private fun JSONObject.optionalNonNegativeInt(key: String): Int? =
|
|
133
|
+
if (has(key) && !isNull(key)) optInt(key).coerceAtLeast(0) else null
|
|
134
|
+
|
|
135
|
+
internal inline fun JSONArray.forEachString(block: (String) -> Unit) {
|
|
136
|
+
for (index in 0 until length()) block(getString(index))
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
internal fun mergeRow(original: JSONObject, changes: JSONObject): JSONObject {
|
|
140
|
+
val result = JSONObject(original.toString())
|
|
141
|
+
val keys = changes.keys()
|
|
142
|
+
while (keys.hasNext()) {
|
|
143
|
+
val key = keys.next()
|
|
144
|
+
if (key != "key" && key != "type") result.put(key, changes.get(key))
|
|
145
|
+
}
|
|
146
|
+
return result
|
|
147
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package com.margelo.nitro.nativelist
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.BaseReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
7
|
+
import com.facebook.react.uimanager.ViewManager
|
|
8
|
+
import com.margelo.nitro.nativelist.views.HybridNativeListManager
|
|
9
|
+
|
|
10
|
+
class NativeListPackage : BaseReactPackage() {
|
|
11
|
+
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? = null
|
|
12
|
+
|
|
13
|
+
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider =
|
|
14
|
+
ReactModuleInfoProvider { HashMap() }
|
|
15
|
+
|
|
16
|
+
override fun createViewManagers(
|
|
17
|
+
reactContext: ReactApplicationContext,
|
|
18
|
+
): List<ViewManager<*, *>> = listOf(HybridNativeListManager())
|
|
19
|
+
|
|
20
|
+
companion object {
|
|
21
|
+
init {
|
|
22
|
+
System.loadLibrary("nativelist")
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|