@rentlydev/rently-tuya 0.1.0

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.
Files changed (288) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +281 -0
  3. package/android/build.gradle +182 -0
  4. package/android/gradle.properties +7 -0
  5. package/android/libs/airbrake-android-1.4.0.jar +0 -0
  6. package/android/src/main/AndroidManifest.xml +1 -0
  7. package/android/src/main/AndroidManifestNew.xml +25 -0
  8. package/android/src/main/java/com/rentlytuya/RentlyTuyaModule.kt +503 -0
  9. package/android/src/main/java/com/rentlytuya/RentlyTuyaPackage.kt +18 -0
  10. package/android/src/main/java/com/rentlytuya/TuyaActivity.kt +45 -0
  11. package/android/src/main/java/com/rentlytuya/alerts/FormatSDCardAlert.kt +83 -0
  12. package/android/src/main/java/com/rentlytuya/alerts/PermissionAlert.kt +91 -0
  13. package/android/src/main/java/com/rentlytuya/alerts/RemoveDoorbellAlert.kt +83 -0
  14. package/android/src/main/java/com/rentlytuya/alerts/RemoveDoorbellFailureAlert.kt +71 -0
  15. package/android/src/main/java/com/rentlytuya/alerts/ResetWifiAlert.kt +83 -0
  16. package/android/src/main/java/com/rentlytuya/alerts/SuccessAlert.kt +74 -0
  17. package/android/src/main/java/com/rentlytuya/components/Alert.kt +47 -0
  18. package/android/src/main/java/com/rentlytuya/components/AnchorButton.kt +125 -0
  19. package/android/src/main/java/com/rentlytuya/components/Button.kt +147 -0
  20. package/android/src/main/java/com/rentlytuya/components/CustomDatePicker.kt +275 -0
  21. package/android/src/main/java/com/rentlytuya/components/Divider.kt +53 -0
  22. package/android/src/main/java/com/rentlytuya/components/EncryptedImageView.kt +59 -0
  23. package/android/src/main/java/com/rentlytuya/components/Label.kt +155 -0
  24. package/android/src/main/java/com/rentlytuya/components/LoadingIndicator.kt +75 -0
  25. package/android/src/main/java/com/rentlytuya/components/Slider.kt +66 -0
  26. package/android/src/main/java/com/rentlytuya/components/Switch.kt +51 -0
  27. package/android/src/main/java/com/rentlytuya/components/VideoView.kt +45 -0
  28. package/android/src/main/java/com/rentlytuya/dashboard/AdvancedSettings.kt +259 -0
  29. package/android/src/main/java/com/rentlytuya/dashboard/Dashboard.kt +551 -0
  30. package/android/src/main/java/com/rentlytuya/dashboard/DoorbellSettings.kt +874 -0
  31. package/android/src/main/java/com/rentlytuya/dashboard/Messages.kt +463 -0
  32. package/android/src/main/java/com/rentlytuya/dashboard/NavController.kt +358 -0
  33. package/android/src/main/java/com/rentlytuya/dashboard/OfflineScreen.kt +160 -0
  34. package/android/src/main/java/com/rentlytuya/dashboard/Playback.kt +685 -0
  35. package/android/src/main/java/com/rentlytuya/tuya/Messages.kt +234 -0
  36. package/android/src/main/java/com/rentlytuya/tuya/Playback.kt +385 -0
  37. package/android/src/main/java/com/rentlytuya/tuya/ScreenCapture.kt +244 -0
  38. package/android/src/main/java/com/rentlytuya/tuya/Settings.kt +809 -0
  39. package/android/src/main/java/com/rentlytuya/tuya/Tuya.kt +497 -0
  40. package/android/src/main/java/com/rentlytuya/ui/theme/LocalColor.kt +80 -0
  41. package/android/src/main/java/com/rentlytuya/ui/theme/LocalFont.kt +35 -0
  42. package/android/src/main/java/com/rentlytuya/ui/theme/Theme.kt +34 -0
  43. package/android/src/main/java/com/rentlytuya/ui/theme/Type.kt +34 -0
  44. package/android/src/main/java/com/rentlytuya/util/Airbrake.kt +40 -0
  45. package/android/src/main/java/com/rentlytuya/util/DpConstants.kt +53 -0
  46. package/android/src/main/java/com/rentlytuya/util/FrescoManager.kt +86 -0
  47. package/android/src/main/java/com/rentlytuya/util/HeapAnalytics.kt +16 -0
  48. package/android/src/main/java/com/rentlytuya/util/KeylessModule.kt +81 -0
  49. package/android/src/main/java/com/rentlytuya/util/PermissionHandler.kt +75 -0
  50. package/android/src/main/java/com/rentlytuya/util/ReactParamsCheck.kt +152 -0
  51. package/android/src/main/java/com/rentlytuya/util/Util.kt +128 -0
  52. package/android/src/main/res/drawable/ic_close.xml +12 -0
  53. package/android/src/main/res/drawable/ic_launcher_background.xml +170 -0
  54. package/android/src/main/res/drawable/ic_launcher_foreground.xml +30 -0
  55. package/android/src/main/res/drawable/img_place_holder.png +0 -0
  56. package/android/src/main/res/drawable-hdpi/ic_action_arrow_backward.png +0 -0
  57. package/android/src/main/res/drawable-hdpi/ic_arrow_backward_white.png +0 -0
  58. package/android/src/main/res/drawable-hdpi/ic_arrow_blue_right.png +0 -0
  59. package/android/src/main/res/drawable-hdpi/ic_calendar.png +0 -0
  60. package/android/src/main/res/drawable-hdpi/ic_camera.png +0 -0
  61. package/android/src/main/res/drawable-hdpi/ic_message.png +0 -0
  62. package/android/src/main/res/drawable-hdpi/ic_pause.png +0 -0
  63. package/android/src/main/res/drawable-hdpi/ic_play.png +0 -0
  64. package/android/src/main/res/drawable-hdpi/ic_play_back.png +0 -0
  65. package/android/src/main/res/drawable-hdpi/ic_record.png +0 -0
  66. package/android/src/main/res/drawable-hdpi/ic_retry.png +0 -0
  67. package/android/src/main/res/drawable-hdpi/ic_setting.png +0 -0
  68. package/android/src/main/res/drawable-hdpi/ic_sound_off.png +0 -0
  69. package/android/src/main/res/drawable-hdpi/ic_sound_on.png +0 -0
  70. package/android/src/main/res/drawable-mdpi/ic_action_arrow_backward.png +0 -0
  71. package/android/src/main/res/drawable-mdpi/ic_arrow_backward_white.png +0 -0
  72. package/android/src/main/res/drawable-mdpi/ic_arrow_blue_right.png +0 -0
  73. package/android/src/main/res/drawable-mdpi/ic_battery_average.png +0 -0
  74. package/android/src/main/res/drawable-mdpi/ic_battery_charging.png +0 -0
  75. package/android/src/main/res/drawable-mdpi/ic_battery_full.png +0 -0
  76. package/android/src/main/res/drawable-mdpi/ic_battery_good.png +0 -0
  77. package/android/src/main/res/drawable-mdpi/ic_battery_low.png +0 -0
  78. package/android/src/main/res/drawable-mdpi/ic_calendar.png +0 -0
  79. package/android/src/main/res/drawable-mdpi/ic_camera.png +0 -0
  80. package/android/src/main/res/drawable-mdpi/ic_message.png +0 -0
  81. package/android/src/main/res/drawable-mdpi/ic_pause.png +0 -0
  82. package/android/src/main/res/drawable-mdpi/ic_play.png +0 -0
  83. package/android/src/main/res/drawable-mdpi/ic_play_back.png +0 -0
  84. package/android/src/main/res/drawable-mdpi/ic_record.png +0 -0
  85. package/android/src/main/res/drawable-mdpi/ic_retry.png +0 -0
  86. package/android/src/main/res/drawable-mdpi/ic_setting.png +0 -0
  87. package/android/src/main/res/drawable-mdpi/ic_sound_off.png +0 -0
  88. package/android/src/main/res/drawable-mdpi/ic_sound_on.png +0 -0
  89. package/android/src/main/res/drawable-xhdpi/ic_action_arrow_backward.png +0 -0
  90. package/android/src/main/res/drawable-xhdpi/ic_arrow_backward_white.png +0 -0
  91. package/android/src/main/res/drawable-xhdpi/ic_arrow_blue_right.png +0 -0
  92. package/android/src/main/res/drawable-xhdpi/ic_battery_average.png +0 -0
  93. package/android/src/main/res/drawable-xhdpi/ic_battery_charging.png +0 -0
  94. package/android/src/main/res/drawable-xhdpi/ic_battery_full.png +0 -0
  95. package/android/src/main/res/drawable-xhdpi/ic_battery_good.png +0 -0
  96. package/android/src/main/res/drawable-xhdpi/ic_battery_low.png +0 -0
  97. package/android/src/main/res/drawable-xhdpi/ic_calendar.png +0 -0
  98. package/android/src/main/res/drawable-xhdpi/ic_camera.png +0 -0
  99. package/android/src/main/res/drawable-xhdpi/ic_message.png +0 -0
  100. package/android/src/main/res/drawable-xhdpi/ic_pause.png +0 -0
  101. package/android/src/main/res/drawable-xhdpi/ic_play.png +0 -0
  102. package/android/src/main/res/drawable-xhdpi/ic_play_back.png +0 -0
  103. package/android/src/main/res/drawable-xhdpi/ic_record.png +0 -0
  104. package/android/src/main/res/drawable-xhdpi/ic_retry.png +0 -0
  105. package/android/src/main/res/drawable-xhdpi/ic_setting.png +0 -0
  106. package/android/src/main/res/drawable-xhdpi/ic_sound_off.png +0 -0
  107. package/android/src/main/res/drawable-xhdpi/ic_sound_on.png +0 -0
  108. package/android/src/main/res/drawable-xxhdpi/ic_action_arrow_backward.png +0 -0
  109. package/android/src/main/res/drawable-xxhdpi/ic_arrow_backward_white.png +0 -0
  110. package/android/src/main/res/drawable-xxhdpi/ic_arrow_blue_right.png +0 -0
  111. package/android/src/main/res/drawable-xxhdpi/ic_battery_average.png +0 -0
  112. package/android/src/main/res/drawable-xxhdpi/ic_battery_charging.png +0 -0
  113. package/android/src/main/res/drawable-xxhdpi/ic_battery_full.png +0 -0
  114. package/android/src/main/res/drawable-xxhdpi/ic_battery_good.png +0 -0
  115. package/android/src/main/res/drawable-xxhdpi/ic_battery_low.png +0 -0
  116. package/android/src/main/res/drawable-xxhdpi/ic_calendar.png +0 -0
  117. package/android/src/main/res/drawable-xxhdpi/ic_camera.png +0 -0
  118. package/android/src/main/res/drawable-xxhdpi/ic_message.png +0 -0
  119. package/android/src/main/res/drawable-xxhdpi/ic_pause.png +0 -0
  120. package/android/src/main/res/drawable-xxhdpi/ic_play.png +0 -0
  121. package/android/src/main/res/drawable-xxhdpi/ic_play_back.png +0 -0
  122. package/android/src/main/res/drawable-xxhdpi/ic_record.png +0 -0
  123. package/android/src/main/res/drawable-xxhdpi/ic_retry.png +0 -0
  124. package/android/src/main/res/drawable-xxhdpi/ic_setting.png +0 -0
  125. package/android/src/main/res/drawable-xxhdpi/ic_sound_off.png +0 -0
  126. package/android/src/main/res/drawable-xxhdpi/ic_sound_on.png +0 -0
  127. package/android/src/main/res/drawable-xxxhdpi/ic_action_arrow_backward.png +0 -0
  128. package/android/src/main/res/drawable-xxxhdpi/ic_arrow_backward_white.png +0 -0
  129. package/android/src/main/res/drawable-xxxhdpi/ic_arrow_blue_right.png +0 -0
  130. package/android/src/main/res/drawable-xxxhdpi/ic_calendar.png +0 -0
  131. package/android/src/main/res/drawable-xxxhdpi/ic_camera.png +0 -0
  132. package/android/src/main/res/drawable-xxxhdpi/ic_message.png +0 -0
  133. package/android/src/main/res/drawable-xxxhdpi/ic_pause.png +0 -0
  134. package/android/src/main/res/drawable-xxxhdpi/ic_play.png +0 -0
  135. package/android/src/main/res/drawable-xxxhdpi/ic_play_back.png +0 -0
  136. package/android/src/main/res/drawable-xxxhdpi/ic_record.png +0 -0
  137. package/android/src/main/res/drawable-xxxhdpi/ic_retry.png +0 -0
  138. package/android/src/main/res/drawable-xxxhdpi/ic_setting.png +0 -0
  139. package/android/src/main/res/drawable-xxxhdpi/ic_sound_off.png +0 -0
  140. package/android/src/main/res/drawable-xxxhdpi/ic_sound_on.png +0 -0
  141. package/android/src/main/res/font/quicksand_bold.ttf +0 -0
  142. package/android/src/main/res/font/quicksand_light.ttf +0 -0
  143. package/android/src/main/res/font/quicksand_medium.ttf +0 -0
  144. package/android/src/main/res/font/quicksand_regular.ttf +0 -0
  145. package/android/src/main/res/font/quicksand_semi_bold.ttf +0 -0
  146. package/android/src/main/res/values/strings.xml +121 -0
  147. package/android/thingMapping.gradle +200 -0
  148. package/android/thingMapping.json +2014 -0
  149. package/ios/components/Alert.swift +54 -0
  150. package/ios/components/AnchorButton.swift +100 -0
  151. package/ios/components/Button.swift +118 -0
  152. package/ios/components/CustomDatePicker.swift +275 -0
  153. package/ios/components/Divider.swift +28 -0
  154. package/ios/components/Image.swift +72 -0
  155. package/ios/components/Label.swift +105 -0
  156. package/ios/components/Switch.swift +61 -0
  157. package/ios/dashboard/AdvanceSettings.swift +127 -0
  158. package/ios/dashboard/Dashboard.swift +354 -0
  159. package/ios/dashboard/Messages.swift +361 -0
  160. package/ios/dashboard/NavigationController.swift +173 -0
  161. package/ios/dashboard/OfflineScreen.swift +109 -0
  162. package/ios/dashboard/Playback.swift +543 -0
  163. package/ios/dashboard/PreviewManager.swift +117 -0
  164. package/ios/dashboard/Settings.swift +672 -0
  165. package/ios/icons/Charging.png +0 -0
  166. package/ios/icons/Charging@2x.png +0 -0
  167. package/ios/icons/Charging@3x.png +0 -0
  168. package/ios/icons/back_arraow.png +0 -0
  169. package/ios/icons/back_arraow@2x.png +0 -0
  170. package/ios/icons/back_arraow@3x.png +0 -0
  171. package/ios/icons/battery_average.png +0 -0
  172. package/ios/icons/battery_average@2x.png +0 -0
  173. package/ios/icons/battery_average@3x.png +0 -0
  174. package/ios/icons/battery_full.png +0 -0
  175. package/ios/icons/battery_full@2x.png +0 -0
  176. package/ios/icons/battery_full@3x.png +0 -0
  177. package/ios/icons/battery_good.png +0 -0
  178. package/ios/icons/battery_good@2x.png +0 -0
  179. package/ios/icons/battery_good@3x.png +0 -0
  180. package/ios/icons/battery_low.png +0 -0
  181. package/ios/icons/battery_low@2x.png +0 -0
  182. package/ios/icons/battery_low@3x.png +0 -0
  183. package/ios/icons/calendar.png +0 -0
  184. package/ios/icons/calendar@2x.png +0 -0
  185. package/ios/icons/calendar@3x.png +0 -0
  186. package/ios/icons/cloud.png +0 -0
  187. package/ios/icons/cloud@2x.png +0 -0
  188. package/ios/icons/cloud@3x.png +0 -0
  189. package/ios/icons/down_update.png +0 -0
  190. package/ios/icons/down_update@2x.png +0 -0
  191. package/ios/icons/down_update@3x.png +0 -0
  192. package/ios/icons/exit_fullscreen.png +0 -0
  193. package/ios/icons/exit_fullscreen@2x.png +0 -0
  194. package/ios/icons/exit_fullscreen@3x.png +0 -0
  195. package/ios/icons/expand.png +0 -0
  196. package/ios/icons/fullscreen.png +0 -0
  197. package/ios/icons/fullscreen@2x.png +0 -0
  198. package/ios/icons/fullscreen@3x.png +0 -0
  199. package/ios/icons/image_placeholder.png +0 -0
  200. package/ios/icons/information.png +0 -0
  201. package/ios/icons/information@2x.png +0 -0
  202. package/ios/icons/information@3x.png +0 -0
  203. package/ios/icons/keyless_Setting.png +0 -0
  204. package/ios/icons/keyless_Setting@2x.png +0 -0
  205. package/ios/icons/keyless_Setting@3x.png +0 -0
  206. package/ios/icons/keyless_back@1x.png +0 -0
  207. package/ios/icons/keyless_back@2x.png +0 -0
  208. package/ios/icons/keyless_back@3x.png +0 -0
  209. package/ios/icons/keyless_filter.png +0 -0
  210. package/ios/icons/keyless_filter@2x.png +0 -0
  211. package/ios/icons/keyless_filter@3x.png +0 -0
  212. package/ios/icons/keyless_message.png +0 -0
  213. package/ios/icons/keyless_message@2x.png +0 -0
  214. package/ios/icons/keyless_message@3x.png +0 -0
  215. package/ios/icons/keyless_pause.png +0 -0
  216. package/ios/icons/keyless_pause@2x.png +0 -0
  217. package/ios/icons/keyless_pause@3x.png +0 -0
  218. package/ios/icons/keyless_photo.png +0 -0
  219. package/ios/icons/keyless_photo@2x.png +0 -0
  220. package/ios/icons/keyless_photo@3x.png +0 -0
  221. package/ios/icons/keyless_play.png +0 -0
  222. package/ios/icons/keyless_play@2x.png +0 -0
  223. package/ios/icons/keyless_play@3x.png +0 -0
  224. package/ios/icons/keyless_play_list.png +0 -0
  225. package/ios/icons/keyless_play_list@2x.png +0 -0
  226. package/ios/icons/keyless_play_list@3x.png +0 -0
  227. package/ios/icons/keyless_play_playback.png +0 -0
  228. package/ios/icons/keyless_play_playback@2x.png +0 -0
  229. package/ios/icons/keyless_play_playback@3x.png +0 -0
  230. package/ios/icons/keyless_record.png +0 -0
  231. package/ios/icons/keyless_record@2x.png +0 -0
  232. package/ios/icons/keyless_record@3x.png +0 -0
  233. package/ios/icons/keyless_record_on.png +0 -0
  234. package/ios/icons/keyless_record_on@2x.png +0 -0
  235. package/ios/icons/keyless_record_on@3x.png +0 -0
  236. package/ios/icons/keyless_sound_off.png +0 -0
  237. package/ios/icons/keyless_sound_off@2x.png +0 -0
  238. package/ios/icons/keyless_sound_off@3x.png +0 -0
  239. package/ios/icons/keyless_sound_on.png +0 -0
  240. package/ios/icons/keyless_sound_on@2x.png +0 -0
  241. package/ios/icons/keyless_sound_on@3x.png +0 -0
  242. package/ios/icons/keyless_speak_off.png +0 -0
  243. package/ios/icons/keyless_speak_off@2x.png +0 -0
  244. package/ios/icons/keyless_speak_on.png +0 -0
  245. package/ios/icons/keyless_speak_on@2x.png +0 -0
  246. package/ios/icons/keyless_speak_on@3x.png +0 -0
  247. package/ios/icons/refresh.png +0 -0
  248. package/ios/icons/refresh@2x.png +0 -0
  249. package/ios/icons/refresh@3x.png +0 -0
  250. package/ios/icons/ty_camera_control_hd_normal@2x.png +0 -0
  251. package/ios/icons/ty_camera_control_hd_normal@3x.png +0 -0
  252. package/ios/icons/ty_camera_control_sd_normal@2x.png +0 -0
  253. package/ios/icons/ty_camera_control_sd_normal@3x.png +0 -0
  254. package/ios/icons/upgrade_success.png +0 -0
  255. package/ios/icons/upgrade_success@2x.png +0 -0
  256. package/ios/icons/upgrade_success@3x.png +0 -0
  257. package/ios/listener/KeylessListener.m +8 -0
  258. package/ios/listener/KeylessListener.swift +56 -0
  259. package/ios/listener/RentlyTuya-Bridging-Header.h +5 -0
  260. package/ios/listener/RentlyTuya.mm +56 -0
  261. package/ios/listener/RentlyTuya.swift +544 -0
  262. package/ios/theme/LocalColor.swift +33 -0
  263. package/ios/theme/LocalFont.swift +32 -0
  264. package/ios/theme/Theme.swift +71 -0
  265. package/ios/tuya/CameraManager.swift +296 -0
  266. package/ios/tuya/SettingsManager.swift +475 -0
  267. package/ios/tuya/Tuya.swift +570 -0
  268. package/ios/tuya/TuyaMessages.swift +98 -0
  269. package/ios/utils/Airbrake.swift +31 -0
  270. package/ios/utils/AppUtility.swift +76 -0
  271. package/ios/utils/HeapAnalytics.swift +8 -0
  272. package/ios/utils/OrientationManager.swift +60 -0
  273. package/ios/utils/PromiseHandler.swift +36 -0
  274. package/lib/commonjs/index.js +90 -0
  275. package/lib/commonjs/index.js.map +1 -0
  276. package/lib/commonjs/package.json +1 -0
  277. package/lib/module/index.js +83 -0
  278. package/lib/module/index.js.map +1 -0
  279. package/lib/module/package.json +1 -0
  280. package/lib/typescript/commonjs/package.json +1 -0
  281. package/lib/typescript/commonjs/src/index.d.ts +75 -0
  282. package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
  283. package/lib/typescript/module/package.json +1 -0
  284. package/lib/typescript/module/src/index.d.ts +75 -0
  285. package/lib/typescript/module/src/index.d.ts.map +1 -0
  286. package/package.json +188 -0
  287. package/rently-tuya.podspec +52 -0
  288. package/src/index.tsx +158 -0
@@ -0,0 +1,40 @@
1
+ package com.rentlytuya.util
2
+
3
+ import android.content.Context
4
+ import android.util.Log
5
+ import com.loopj.android.airbrake.AirbrakeNotifier
6
+ import com.rentlytuya.tuya.Tuya.TAG
7
+
8
+ object Airbrake {
9
+
10
+ private var isInitialized = false
11
+
12
+ fun initialize(
13
+ airbrakeKey: String,
14
+ airbrakeID: String,
15
+ context: Context
16
+ ) {
17
+ if (isInitialized) return
18
+ runCatching {
19
+ AirbrakeNotifier.register(context, airbrakeKey)
20
+ isInitialized = true
21
+ Log.i(TAG, "Successfully Initialized Airbrake")
22
+ }.onFailure {
23
+ Log.i(TAG, "Error in Airbrake Initialization")
24
+ it.printStackTrace()
25
+ }
26
+ }
27
+
28
+ fun logMessage(title: String, message: String, additionalInfo: Map<String, String>? = null) {
29
+ Log.i(TAG, "$title, $message, $additionalInfo")
30
+ if (!isInitialized) return
31
+ runCatching {
32
+ val logData = additionalInfo.orEmpty()
33
+ val throwable = Throwable("$title: $message")
34
+ AirbrakeNotifier.notify(throwable, logData)
35
+ }.onFailure {
36
+ Log.i(TAG, "Error in Airbrake log message")
37
+ it.printStackTrace()
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,53 @@
1
+ package com.rentlytuya.util
2
+
3
+ object DPConstants {
4
+
5
+ const val PTZ_CONTROL: String = "119"
6
+ const val PTZ_STOP: String = "116"
7
+
8
+ const val BASIC_FLIP: String = "103"
9
+ const val WATERMARK: String = "104"
10
+ const val ANTI_DISMANTLING_ALARM: String = "231"
11
+
12
+ // 0-Auto, 1-Off, 2-On
13
+ const val BASIC_NIGHT_VISION: String = "108"
14
+
15
+ // 0-None, 1-Mechanical, 2-Digital, 3-No bells
16
+ const val CHIME_TYPE: String = "165"
17
+
18
+ // Motion Detection for 8s and AOSU Doorbell
19
+ const val MOTION_SWITCH: String = "134"
20
+ const val MOTION_SENSITIVITY: String = "106"
21
+
22
+ // Motion Sensitivity for AOSU
23
+ const val MOTION_SENSITIVITY_AOSU: String = "152"
24
+
25
+ // Motion Detection for 15s
26
+ const val PIR_SWITCH: String = "240"
27
+ const val PIR_SENSITIVITY: String = "241"
28
+
29
+ // 1-Normal, 2-Abnormal, 3-Insufficient Capacity, 4-Formatting.., 5-No Storage
30
+ const val SD_STATUS: String = "110"
31
+ const val SD_STORAGE: String = "109"
32
+ const val SD_FORMAT: String = "111"
33
+ const val SD_FORMAT_STATUS: String = "117"
34
+ const val SD_RECORD_SWITCH: String = "150"
35
+ const val SD_RECORD_MODE: String = "151"
36
+
37
+ const val WIRELESS_ELECTRICITY: String = "145"
38
+
39
+ // 0-Battery Powered, 1-Wire Mode
40
+ const val WIRELESS_POWER_MODE: String = "146"
41
+
42
+ // DP Data type
43
+ const val SCHEMA_TYPE_RAW: String = "raw"
44
+ const val SCHEMA_TYPE_BOOL: String = "bool"
45
+ const val SCHEMA_TYPE_ENUM: String = "enum"
46
+ const val SCHEMA_TYPE_VALUE: String = "value"
47
+ const val SCHEMA_TYPE_STRING: String = "string"
48
+
49
+ const val PTZ_UP: String = "0"
50
+ const val PTZ_LEFT: String = "2"
51
+ const val PTZ_DOWN: String = "4"
52
+ const val PTZ_RIGHT: String = "6"
53
+ }
@@ -0,0 +1,86 @@
1
+ package com.rentlytuya.util
2
+
3
+ import android.content.Context
4
+ import android.os.StatFs
5
+ import com.facebook.drawee.backends.pipeline.Fresco
6
+ import com.facebook.imagepipeline.core.ExecutorSupplier
7
+ import com.facebook.imagepipeline.core.ImagePipelineConfig
8
+ import com.facebook.imagepipeline.listener.RequestListener
9
+ import com.thingclips.imagepipeline.okhttp3.OkHttpImagePipelineConfigFactory
10
+ import com.thingclips.smart.android.common.task.ThingExecutor
11
+ import okhttp3.Cache
12
+ import okhttp3.OkHttpClient
13
+ import java.io.File
14
+ import java.util.concurrent.Executor
15
+ import java.util.concurrent.ScheduledExecutorService
16
+ import java.util.concurrent.TimeUnit
17
+
18
+ object FrescoManager {
19
+
20
+ @JvmStatic
21
+ fun initFresco(context: Context) {
22
+ val defaultConfig = getDefaultConfig(context)
23
+ initFresco(context, defaultConfig)
24
+ }
25
+
26
+ @JvmStatic
27
+ fun initFresco(context: Context, config: ImagePipelineConfig) {
28
+ Fresco.initialize(context, config)
29
+ }
30
+
31
+ private fun getDefaultConfig(context: Context): ImagePipelineConfig {
32
+ val requestListeners: Set<RequestListener> = emptySet()
33
+ val cacheDir = File(context.cacheDir, "okhttp3")
34
+ val size = calculateDiskCacheSize(cacheDir)
35
+
36
+ val okHttpClient = OkHttpClient.Builder()
37
+ .cache(Cache(cacheDir, size))
38
+ .connectTimeout(0, TimeUnit.MILLISECONDS)
39
+ .readTimeout(0, TimeUnit.MILLISECONDS)
40
+ .writeTimeout(0, TimeUnit.MILLISECONDS)
41
+ .build()
42
+
43
+ val builder = OkHttpImagePipelineConfigFactory.newBuilder(
44
+ context.applicationContext, okHttpClient
45
+ ).setRequestListeners(requestListeners)
46
+
47
+ builder.setExecutorSupplier(object : ExecutorSupplier {
48
+ override fun forLocalStorageRead(): Executor =
49
+ ThingExecutor.getInstance().thingExecutorService
50
+
51
+ override fun forLocalStorageWrite(): Executor =
52
+ ThingExecutor.getInstance().thingExecutorService
53
+
54
+ override fun forDecode(): Executor = ThingExecutor.getInstance().thingExecutorService
55
+
56
+ override fun forBackgroundTasks(): Executor = ThingExecutor.getInstance().thingExecutorService
57
+
58
+ override fun forLightweightBackgroundTasks(): Executor =
59
+ ThingExecutor.getInstance().thingExecutorService
60
+
61
+ override fun forThumbnailProducer(): Executor =
62
+ ThingExecutor.getInstance().thingExecutorService
63
+
64
+ override fun scheduledExecutorServiceForBackgroundTasks(): ScheduledExecutorService? = null
65
+ })
66
+
67
+ return builder.build()
68
+ }
69
+
70
+ private const val MIN_DISK_CACHE_SIZE = 5 * 1024 * 1024L // 5MB
71
+ private const val MAX_DISK_CACHE_SIZE = 10 * 1024 * 1024L // 50MB
72
+
73
+ private fun calculateDiskCacheSize(dir: File): Long {
74
+ var size = MIN_DISK_CACHE_SIZE
75
+
76
+ try {
77
+ val statFs = StatFs(dir.absolutePath)
78
+ val available = statFs.blockCountLong * statFs.blockSizeLong
79
+ size = available / 50 // Target 2% of the total space.
80
+ } catch (ignored: IllegalArgumentException) {
81
+ }
82
+
83
+ // Bound inside min/max size for disk cache.
84
+ return size.coerceIn(MIN_DISK_CACHE_SIZE, MAX_DISK_CACHE_SIZE)
85
+ }
86
+ }
@@ -0,0 +1,16 @@
1
+ package com.rentlytuya.util
2
+
3
+ import android.util.Log
4
+ import com.heapanalytics.android.Heap
5
+ import com.rentlytuya.tuya.Tuya.TAG
6
+
7
+ object Heap {
8
+
9
+ fun trackEvent(eventName: String, properties: Map<String, String>? = null) {
10
+ try {
11
+ Heap.track(eventName, properties)
12
+ } catch (e: Exception) {
13
+ Log.e(TAG, "Error in Heap trackEvent: $eventName", e)
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,81 @@
1
+ package com.rentlytuya.util
2
+
3
+ import android.util.Log
4
+ import com.facebook.react.ReactApplication
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
7
+ import com.facebook.react.bridge.ReactMethod
8
+ import com.facebook.react.bridge.WritableNativeArray
9
+ import com.facebook.react.module.annotations.ReactModule
10
+ import com.facebook.react.modules.core.DeviceEventManagerModule
11
+ import com.rentlytuya.tuya.Tuya.TAG
12
+
13
+ @ReactModule(name = "KeylessListener")
14
+ class KeylessModule(private val reactContext: ReactApplicationContext) :
15
+ ReactContextBaseJavaModule(reactContext) {
16
+
17
+ private var eventEmitter: DeviceEventManagerModule.RCTDeviceEventEmitter? = null
18
+ private var onSuccessListener: ((String) -> Unit)? = null
19
+ private var onFailureListener: ((String) -> Unit)? = null
20
+
21
+ override fun getName(): String = "KeylessListener"
22
+
23
+ override fun initialize() {
24
+ super.initialize()
25
+ eventEmitter =
26
+ reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
27
+ }
28
+
29
+ fun sendDataToJS(
30
+ eventName: String,
31
+ deviceId: String,
32
+ onSuccess: (String) -> Unit,
33
+ onFailure: (String) -> Unit
34
+ ) {
35
+ try {
36
+ val params = WritableNativeArray()
37
+ params.pushString(deviceId) // For Update Default Settings value, id is passed
38
+
39
+ onSuccessListener = onSuccess
40
+ onFailureListener = onFailure
41
+ invokeJSMethod(methodName = eventName, params = params)
42
+ } catch (e: Exception) {
43
+ Log.e(TAG, "Error sending event to JS: ${e.message}", e)
44
+ }
45
+ }
46
+
47
+ private fun invokeJSMethod(methodName: String, params: WritableNativeArray) {
48
+ try {
49
+ val reactInstanceManager = (reactContext.applicationContext as ReactApplication)
50
+ .reactNativeHost.reactInstanceManager
51
+
52
+ val currentReactContext = reactInstanceManager.currentReactContext
53
+ if (currentReactContext == null || !currentReactContext.hasActiveCatalystInstance()) {
54
+ Log.e(TAG, "ReactContext is not active or null. Attempting to recreate")
55
+ reactInstanceManager.recreateReactContextInBackground()
56
+ Thread.sleep(2000)
57
+ }
58
+
59
+ if (currentReactContext != null) {
60
+ val catalystInstance = currentReactContext.catalystInstance
61
+ catalystInstance?.callFunction("RNOperation", methodName, params)
62
+ ?: Log.e(TAG, "Catalyst instance is null")
63
+ }
64
+
65
+ } catch (e: Exception) {
66
+ Log.e(TAG, "Error invoking JS method: ${e.message}", e)
67
+ }
68
+ }
69
+
70
+ @ReactMethod
71
+ fun successCallback(message: String) {
72
+ onSuccessListener?.invoke(message)
73
+ onSuccessListener = null
74
+ }
75
+
76
+ @ReactMethod
77
+ fun failureCallback(message: String) {
78
+ onFailureListener?.invoke(message)
79
+ onFailureListener = null
80
+ }
81
+ }
@@ -0,0 +1,75 @@
1
+ package com.rentlytuya.util
2
+
3
+ import android.app.Activity
4
+ import android.content.Context
5
+ import android.content.Intent
6
+ import android.content.pm.PackageManager
7
+ import android.net.Uri
8
+ import android.provider.Settings
9
+ import androidx.core.app.ActivityCompat
10
+ import androidx.core.content.ContextCompat
11
+
12
+ object PermissionHandler {
13
+
14
+ fun isPermissionGranted(context: Context, permission: String): Boolean {
15
+ return ContextCompat.checkSelfPermission(
16
+ context,
17
+ permission
18
+ ) == PackageManager.PERMISSION_GRANTED
19
+ }
20
+
21
+ fun arePermissionsGranted(context: Context, permissions: Array<String>): Boolean {
22
+ return permissions.all { permission ->
23
+ ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
24
+ }
25
+ }
26
+
27
+ fun checkAndRequestPermissions(
28
+ activity: Activity,
29
+ permissions: Array<String>,
30
+ requestCode: Int
31
+ ): Boolean {
32
+ try {
33
+ val notGrantedPermissions = permissions.filter { permission ->
34
+ ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
35
+ }
36
+
37
+ return if (notGrantedPermissions.isNotEmpty()) {
38
+ val shouldShowRationale = notGrantedPermissions.any { permission ->
39
+ ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)
40
+ }
41
+
42
+ if (!shouldShowRationale) {
43
+ ActivityCompat.requestPermissions(
44
+ activity,
45
+ notGrantedPermissions.toTypedArray(),
46
+ requestCode
47
+ )
48
+ } else {
49
+ openAppSettings(activity)
50
+ }
51
+ false
52
+ } else {
53
+ true
54
+ }
55
+ } catch (e: Exception) {
56
+ e.printStackTrace()
57
+ return false
58
+ }
59
+ }
60
+
61
+ fun requestPermission(activity: Activity, permission: String, requestCode: Int) {
62
+ try {
63
+ ActivityCompat.requestPermissions(activity, arrayOf(permission), requestCode)
64
+ } catch (e: Exception) {
65
+ e.printStackTrace()
66
+ }
67
+ }
68
+
69
+ private fun openAppSettings(activity: Activity) {
70
+ val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
71
+ data = Uri.fromParts("package", activity.packageName, null)
72
+ }
73
+ activity.startActivity(intent)
74
+ }
75
+ }
@@ -0,0 +1,152 @@
1
+ package com.rentlytuya.util
2
+
3
+ import android.text.TextUtils
4
+ import com.alibaba.fastjson.JSON
5
+ import com.alibaba.fastjson.JSONArray
6
+ import com.alibaba.fastjson.JSONObject
7
+ import com.facebook.react.bridge.Arguments
8
+ import com.facebook.react.bridge.ReadableArray
9
+ import com.facebook.react.bridge.ReadableMap
10
+ import com.facebook.react.bridge.ReadableType
11
+ import com.facebook.react.bridge.WritableArray
12
+ import com.facebook.react.bridge.WritableMap
13
+ import java.math.BigDecimal
14
+
15
+ fun ReadableMap.checkParams(vararg keys: String): Boolean {
16
+ for (key in keys) {
17
+ if (!hasKey(key)) {
18
+ return false
19
+ }
20
+ }
21
+ return true
22
+ }
23
+
24
+ object ReactUtils {
25
+
26
+ private fun parseToMap(readableMap: ReadableMap): HashMap<String, Any?> {
27
+ val iterator = readableMap.keySetIterator()
28
+ val deconstructedMap = HashMap<String, Any?>()
29
+ while (iterator.hasNextKey()) {
30
+ val key = iterator.nextKey()
31
+ val type = readableMap.getType(key)
32
+ when (type) {
33
+ ReadableType.Null -> deconstructedMap[key] = null
34
+ ReadableType.Boolean -> deconstructedMap[key] = readableMap.getBoolean(key)
35
+ ReadableType.Number -> {
36
+ val value = readableMap.getDouble(key)
37
+ deconstructedMap[key] = if (value > Integer.MAX_VALUE && value % 1 == 0.0) {
38
+ value.toLong()
39
+ } else {
40
+ value
41
+ }
42
+ }
43
+
44
+ ReadableType.String -> deconstructedMap[key] = readableMap.getString(key)
45
+ ReadableType.Map -> deconstructedMap[key] = parseToMap(readableMap.getMap(key)!!)
46
+ ReadableType.Array -> deconstructedMap[key] = parseToList(readableMap.getArray(key)!!)
47
+ }
48
+ }
49
+ return deconstructedMap
50
+ }
51
+
52
+ fun parseToLongMap(readableMap: ReadableMap): HashMap<String, Any?> {
53
+ val iterator = readableMap.keySetIterator()
54
+ val deconstructedMap = HashMap<String, Any?>()
55
+ while (iterator.hasNextKey()) {
56
+ val key = iterator.nextKey()
57
+ val type = readableMap.getType(key)
58
+ when (type) {
59
+ ReadableType.Null -> deconstructedMap[key] = null
60
+ ReadableType.Boolean -> deconstructedMap[key] = readableMap.getBoolean(key)
61
+ ReadableType.Number -> {
62
+ val value = readableMap.getDouble(key)
63
+ deconstructedMap[key] = try {
64
+ if (value > Integer.MAX_VALUE && value % 1 == 0.0) {
65
+ value.toLong()
66
+ } else {
67
+ value.toLong()
68
+ }
69
+ } catch (e: Exception) {
70
+ value
71
+ }
72
+ }
73
+
74
+ ReadableType.String -> deconstructedMap[key] = readableMap.getString(key)
75
+ ReadableType.Map -> deconstructedMap[key] = parseToMap(readableMap.getMap(key)!!)
76
+ ReadableType.Array -> deconstructedMap[key] = parseToList(readableMap.getArray(key)!!)
77
+ }
78
+ }
79
+ return deconstructedMap
80
+ }
81
+
82
+ private fun parseToList(readableArray: ReadableArray): ArrayList<Any?> {
83
+ val deconstructedList = ArrayList<Any?>(readableArray.size())
84
+ for (i in 0 until readableArray.size()) {
85
+ val indexType = readableArray.getType(i)
86
+ when (indexType) {
87
+ ReadableType.Null -> deconstructedList.add(i, null)
88
+ ReadableType.Boolean -> deconstructedList.add(i, readableArray.getBoolean(i))
89
+ ReadableType.Number -> {
90
+ val value = readableArray.getDouble(i)
91
+ deconstructedList.add(
92
+ i,
93
+ if (value > Integer.MAX_VALUE && value % 1 == 0.0) value.toLong() else value
94
+ )
95
+ }
96
+
97
+ ReadableType.String -> deconstructedList.add(i, readableArray.getString(i))
98
+ ReadableType.Map -> deconstructedList.add(i, parseToMap(readableArray.getMap(i)))
99
+ ReadableType.Array -> deconstructedList.add(i, parseToList(readableArray.getArray(i)))
100
+ }
101
+ }
102
+ return deconstructedList
103
+ }
104
+
105
+ private fun parseToWritableMap(s: String): WritableMap {
106
+ return if (TextUtils.isEmpty(s)) Arguments.createMap() else parseToWritableMap(
107
+ JSON.parseObject(
108
+ s
109
+ )
110
+ )
111
+ }
112
+
113
+ fun parseToWritableMap(data: Any?): WritableMap {
114
+ return if (data == null) Arguments.createMap() else parseToWritableMap(JSON.toJSONString(data))
115
+ }
116
+
117
+ private fun parseToWritableMap(json: JSONObject): WritableMap {
118
+ val map = Arguments.createMap()
119
+ for ((key, obv) in json.entries) {
120
+ when (obv) {
121
+ is JSONObject -> map.putMap(key, parseToWritableMap(obv))
122
+ is JSONArray -> map.putArray(key, parseToWritableArray(obv))
123
+ is Int -> map.putInt(key, obv)
124
+ is String -> map.putString(key, obv)
125
+ is Boolean -> map.putBoolean(key, obv)
126
+ is Double -> map.putDouble(key, obv)
127
+ is BigDecimal -> map.putDouble(key, obv.toDouble())
128
+ is Long -> map.putString(key, obv.toString())
129
+ else -> map.putNull(key)
130
+ }
131
+ }
132
+ return map
133
+ }
134
+
135
+ private fun parseToWritableArray(jsonArray: JSONArray): WritableArray {
136
+ val list = Arguments.createArray()
137
+ for (obv in jsonArray.toTypedArray()) {
138
+ when (obv) {
139
+ is JSONObject -> list.pushMap(parseToWritableMap(obv))
140
+ is JSONArray -> list.pushArray(parseToWritableArray(obv))
141
+ is Int -> list.pushInt(obv)
142
+ is String -> list.pushString(obv)
143
+ is Boolean -> list.pushBoolean(obv)
144
+ is Double -> list.pushDouble(obv)
145
+ is BigDecimal -> list.pushDouble(obv.toDouble())
146
+ is Long -> list.pushString(obv.toString())
147
+ else -> list.pushNull()
148
+ }
149
+ }
150
+ return list
151
+ }
152
+ }
@@ -0,0 +1,128 @@
1
+ package com.rentlytuya.util
2
+
3
+ import android.content.res.Configuration
4
+ import android.os.Build
5
+ import androidx.annotation.RequiresApi
6
+ import androidx.compose.runtime.Composable
7
+ import androidx.compose.ui.res.stringResource
8
+ import java.text.SimpleDateFormat
9
+ import java.time.Instant
10
+ import java.time.LocalDateTime
11
+ import java.time.ZoneId
12
+ import java.time.ZoneOffset
13
+ import java.time.format.DateTimeFormatter
14
+ import java.util.Calendar
15
+ import java.util.Date
16
+ import java.util.Locale
17
+ import java.util.concurrent.TimeUnit
18
+ import kotlin.contracts.ExperimentalContracts
19
+ import kotlin.contracts.contract
20
+
21
+ object Util {
22
+ @Composable
23
+ fun strings(id: Int): String =
24
+ stringResource(id = id)
25
+
26
+ fun isLandscape(config: Configuration): Boolean =
27
+ config.orientation == Configuration.ORIENTATION_LANDSCAPE
28
+ }
29
+
30
+ object DateUtil {
31
+
32
+ fun getCurrentTimeInSeconds(): Long {
33
+ return System.currentTimeMillis() / 1000
34
+ }
35
+
36
+ fun getDateMinusYearsInSeconds(years: Int): Long {
37
+ val calendar = Calendar.getInstance()
38
+ calendar.add(Calendar.YEAR, -years)
39
+
40
+ return calendar.timeInMillis / 1000
41
+ }
42
+
43
+ fun getDateComponents(dateLong: Long): Triple<Int, Int, Int> {
44
+ val calendar = Calendar.getInstance().apply {
45
+ timeInMillis = dateLong
46
+ }
47
+
48
+ val year = calendar.get(Calendar.YEAR)
49
+ val month = calendar.get(Calendar.MONTH) + 1
50
+ val day = calendar.get(Calendar.DAY_OF_MONTH)
51
+
52
+ return Triple(year, month, day)
53
+ }
54
+
55
+ fun convertTimestampToTime(timestamp: Int, format: String = "hh:mm a"): String {
56
+ val date = Date(timestamp * 1000L)
57
+ val formatter = SimpleDateFormat(format, Locale.getDefault())
58
+ return formatter.format(date)
59
+ }
60
+
61
+ fun formatSecondsToHHMMSS(seconds: Int): String {
62
+ val hours = seconds / 3600
63
+ val minutes = (seconds % 3600) / 60
64
+ val secs = seconds % 60
65
+
66
+ return String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, secs)
67
+ }
68
+
69
+ fun calculateDuration(startTime: Int, endTime: Int): String {
70
+ val diffInSeconds = endTime - startTime
71
+
72
+ val hours = TimeUnit.SECONDS.toHours(diffInSeconds.toLong())
73
+ val minutes = TimeUnit.SECONDS.toMinutes(diffInSeconds.toLong()) % 60
74
+ val seconds = diffInSeconds % 60
75
+
76
+ return String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds)
77
+ }
78
+
79
+ fun calculateSecondsBetweenTimestamps(startTime: Int, endTime: Int): Long {
80
+ return (endTime - startTime).toLong()
81
+ }
82
+
83
+ fun incrementTimestampBySeconds(timestamp: Int, secondsToAdd: Int): Int {
84
+ return timestamp + secondsToAdd
85
+ }
86
+
87
+ @RequiresApi(Build.VERSION_CODES.O)
88
+ fun getStartOfDay(epochMillis: Long): Long {
89
+ return Instant.ofEpochMilli(epochMillis)
90
+ .atZone(ZoneId.systemDefault())
91
+ .toLocalDate()
92
+ .atStartOfDay(ZoneId.systemDefault())
93
+ .toInstant()
94
+ .toEpochMilli()
95
+ }
96
+
97
+ @RequiresApi(Build.VERSION_CODES.O)
98
+ fun convertToEpoch(isoDateString: String): Long {
99
+ return try {
100
+ val instant = Instant.from(DateTimeFormatter.ISO_INSTANT.parse(isoDateString))
101
+ instant.epochSecond
102
+ } catch (e: Exception) {
103
+ e.printStackTrace()
104
+ val oneYearBack = LocalDateTime.now().minusYears(1).toEpochSecond(ZoneOffset.UTC)
105
+ oneYearBack
106
+ }
107
+ }
108
+
109
+ @OptIn(ExperimentalContracts::class)
110
+ inline fun <reified T> T?.isNull(): Boolean {
111
+ contract {
112
+ returns(true) implies (this@isNull == null)
113
+ }
114
+ return this == null
115
+ }
116
+
117
+ @OptIn(ExperimentalContracts::class)
118
+ inline fun <reified T> T?.isNotNull(): Boolean {
119
+ contract {
120
+ returns(true) implies (this@isNotNull != null)
121
+ }
122
+ return this != null
123
+ }
124
+
125
+ fun Boolean?.isTrue(): Boolean {
126
+ return this == true
127
+ }
128
+ }
@@ -0,0 +1,12 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:width="24dp"
3
+ android:height="24dp"
4
+ android:tint="#FFFFFF"
5
+ android:viewportWidth="24"
6
+ android:viewportHeight="24">
7
+
8
+ <path
9
+ android:fillColor="@android:color/white"
10
+ android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" />
11
+
12
+ </vector>