@zezosoft/zezo-ott-react-native-ui-kit 1.0.3 → 1.0.5

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 (265) hide show
  1. package/README.md +1 -1
  2. package/lib/module/assets/animations/Failed.json +2103 -0
  3. package/lib/module/assets/animations/Pending.json +522 -0
  4. package/lib/module/assets/animations/Successful.json +2289 -0
  5. package/lib/module/assets/animations/heart.json +788 -0
  6. package/lib/module/components/Alert/AlertDialog.js +208 -0
  7. package/lib/module/components/Alert/AlertDialog.js.map +1 -0
  8. package/lib/module/components/Alert/index.js +1 -0
  9. package/lib/module/components/Alert/index.js.map +1 -1
  10. package/lib/module/components/Auth/AuthProvider/AuthProvider.js +270 -0
  11. package/lib/module/components/Auth/AuthProvider/AuthProvider.js.map +1 -0
  12. package/lib/module/components/Auth/QrLogin/QrLogin.js +267 -0
  13. package/lib/module/components/Auth/QrLogin/QrLogin.js.map +1 -0
  14. package/lib/module/components/Auth/QrLogin/components/QrViewArea.js +178 -0
  15. package/lib/module/components/Auth/QrLogin/components/QrViewArea.js.map +1 -0
  16. package/lib/module/components/Auth/SplashScreen/SplashScreen.js +63 -65
  17. package/lib/module/components/Auth/SplashScreen/SplashScreen.js.map +1 -1
  18. package/lib/module/components/Auth/SplashScreen/components/SplashVideo/SplashVideo.js +82 -41
  19. package/lib/module/components/Auth/SplashScreen/components/SplashVideo/SplashVideo.js.map +1 -1
  20. package/lib/module/components/Auth/index.js +5 -1
  21. package/lib/module/components/Auth/index.js.map +1 -1
  22. package/lib/module/components/BackgroundLayout/BackgroundLayout.js +3 -3
  23. package/lib/module/components/BackgroundLayout/BackgroundLayout.js.map +1 -1
  24. package/lib/module/components/Button/SecondaryBtn.js +91 -0
  25. package/lib/module/components/Button/SecondaryBtn.js.map +1 -0
  26. package/lib/module/components/Button/index.js +2 -0
  27. package/lib/module/components/Button/index.js.map +1 -1
  28. package/lib/module/components/Content/Card/NowWatching/NowWatching.js +6 -3
  29. package/lib/module/components/Content/Card/NowWatching/NowWatching.js.map +1 -1
  30. package/lib/module/components/Content/Card/Sliders/Styles/One.js +4 -1
  31. package/lib/module/components/Content/Card/Sliders/Styles/One.js.map +1 -1
  32. package/lib/module/components/Content/Card/Sliders/Styles/Two.js +4 -1
  33. package/lib/module/components/Content/Card/Sliders/Styles/Two.js.map +1 -1
  34. package/lib/module/components/Content/Card/Styles/Five.js +1 -0
  35. package/lib/module/components/Content/Card/Styles/Five.js.map +1 -1
  36. package/lib/module/components/Content/Card/Styles/Four.js +1 -0
  37. package/lib/module/components/Content/Card/Styles/Four.js.map +1 -1
  38. package/lib/module/components/Content/Card/Styles/One.js +7 -3
  39. package/lib/module/components/Content/Card/Styles/One.js.map +1 -1
  40. package/lib/module/components/Content/Card/Styles/RotateInOut.js +1 -0
  41. package/lib/module/components/Content/Card/Styles/RotateInOut.js.map +1 -1
  42. package/lib/module/components/Content/Card/Styles/Six.js +4 -1
  43. package/lib/module/components/Content/Card/Styles/Six.js.map +1 -1
  44. package/lib/module/components/Content/Card/Styles/Three.js +1 -0
  45. package/lib/module/components/Content/Card/Styles/Three.js.map +1 -1
  46. package/lib/module/components/Content/Card/Styles/TopTen.js +1 -0
  47. package/lib/module/components/Content/Card/Styles/TopTen.js.map +1 -1
  48. package/lib/module/components/Content/Card/Styles/Two.js +1 -0
  49. package/lib/module/components/Content/Card/Styles/Two.js.map +1 -1
  50. package/lib/module/components/Content/Card/components/CardPoster.js +12 -28
  51. package/lib/module/components/Content/Card/components/CardPoster.js.map +1 -1
  52. package/lib/module/components/Content/Card/components/RentOrBuyIcon.js +116 -0
  53. package/lib/module/components/Content/Card/components/RentOrBuyIcon.js.map +1 -0
  54. package/lib/module/components/Content/Card/components/ThumbnailCard.js +1 -2
  55. package/lib/module/components/Content/Card/components/ThumbnailCard.js.map +1 -1
  56. package/lib/module/components/ContentView/ContentView.js +1 -0
  57. package/lib/module/components/ContentView/ContentView.js.map +1 -1
  58. package/lib/module/components/ContentView/MoreContentList.js +1 -0
  59. package/lib/module/components/ContentView/MoreContentList.js.map +1 -1
  60. package/lib/module/components/ContentView/components/EpisodeCard.js +6 -10
  61. package/lib/module/components/ContentView/components/EpisodeCard.js.map +1 -1
  62. package/lib/module/components/ContentView/components/HeroBanner.js +17 -5
  63. package/lib/module/components/ContentView/components/HeroBanner.js.map +1 -1
  64. package/lib/module/components/Headers/AppHeader.js +1 -1
  65. package/lib/module/components/Headers/AppHeader.js.map +1 -1
  66. package/lib/module/components/Headers/One.js +1 -1
  67. package/lib/module/components/Headers/One.js.map +1 -1
  68. package/lib/module/components/Headers/Two.js +1 -1
  69. package/lib/module/components/Headers/Two.js.map +1 -1
  70. package/lib/module/components/Logo/Logo.js +5 -5
  71. package/lib/module/components/Logo/Logo.js.map +1 -1
  72. package/lib/module/components/Reels/ReelsSeries/Model/Episodes.js +110 -0
  73. package/lib/module/components/Reels/ReelsSeries/Model/Episodes.js.map +1 -0
  74. package/lib/module/components/Reels/ReelsSeries/Model/Synopsis.js +212 -0
  75. package/lib/module/components/Reels/ReelsSeries/Model/Synopsis.js.map +1 -0
  76. package/lib/module/components/Reels/ReelsSeries/ReelSeriesDetailsModal.js +182 -0
  77. package/lib/module/components/Reels/ReelsSeries/ReelSeriesDetailsModal.js.map +1 -0
  78. package/lib/module/components/Reels/ReelsSeries/ReelSeriesOverlay.js +203 -0
  79. package/lib/module/components/Reels/ReelsSeries/ReelSeriesOverlay.js.map +1 -0
  80. package/lib/module/components/Reels/ReelsSeries/ReelsSeries.js +121 -0
  81. package/lib/module/components/Reels/ReelsSeries/ReelsSeries.js.map +1 -0
  82. package/lib/module/components/Reels/ReelsSeries/ReelsSeriesItem.js +290 -0
  83. package/lib/module/components/Reels/ReelsSeries/ReelsSeriesItem.js.map +1 -0
  84. package/lib/module/components/Reels/ReelsSeries/types.js +2 -0
  85. package/lib/module/components/Reels/ReelsSeries/types.js.map +1 -0
  86. package/lib/module/components/Reels/index.js +11 -0
  87. package/lib/module/components/Reels/index.js.map +1 -0
  88. package/lib/module/components/Subscription/SubOne.js +2 -2
  89. package/lib/module/components/Subscription/SubOne.js.map +1 -1
  90. package/lib/module/components/User/DeviceSessions/DeviceSessions.js +8 -0
  91. package/lib/module/components/User/DeviceSessions/DeviceSessions.js.map +1 -1
  92. package/lib/module/components/User/ProfileUpdate/ProfileUpdate.js +255 -0
  93. package/lib/module/components/User/ProfileUpdate/ProfileUpdate.js.map +1 -0
  94. package/lib/module/components/User/WatchHistory/WatchHistory.js +1 -0
  95. package/lib/module/components/User/WatchHistory/WatchHistory.js.map +1 -1
  96. package/lib/module/components/User/WatchLater/WatchLater.js +1 -0
  97. package/lib/module/components/User/WatchLater/WatchLater.js.map +1 -1
  98. package/lib/module/components/User/components/UserAvatar.js +35 -8
  99. package/lib/module/components/User/components/UserAvatar.js.map +1 -1
  100. package/lib/module/components/User/components/UserSection.js +8 -13
  101. package/lib/module/components/User/components/UserSection.js.map +1 -1
  102. package/lib/module/components/User/index.js +2 -1
  103. package/lib/module/components/User/index.js.map +1 -1
  104. package/lib/module/components/index.js +1 -0
  105. package/lib/module/components/index.js.map +1 -1
  106. package/lib/module/hooks/useSplashCache.js +117 -0
  107. package/lib/module/hooks/useSplashCache.js.map +1 -0
  108. package/lib/module/store/RecentSearchesStore.js +0 -1
  109. package/lib/module/store/RecentSearchesStore.js.map +1 -1
  110. package/lib/module/theme/ThemeProvider.js +13 -10
  111. package/lib/module/theme/ThemeProvider.js.map +1 -1
  112. package/lib/module/theme/themes.js +2 -0
  113. package/lib/module/theme/themes.js.map +1 -1
  114. package/lib/module/utils/Formater.js +17 -0
  115. package/lib/module/utils/Formater.js.map +1 -0
  116. package/lib/typescript/src/components/Alert/AlertDialog.d.ts +18 -0
  117. package/lib/typescript/src/components/Alert/AlertDialog.d.ts.map +1 -0
  118. package/lib/typescript/src/components/Alert/index.d.ts +1 -0
  119. package/lib/typescript/src/components/Alert/index.d.ts.map +1 -1
  120. package/lib/typescript/src/components/Auth/AuthProvider/AuthProvider.d.ts +35 -0
  121. package/lib/typescript/src/components/Auth/AuthProvider/AuthProvider.d.ts.map +1 -0
  122. package/lib/typescript/src/components/Auth/QrLogin/QrLogin.d.ts +32 -0
  123. package/lib/typescript/src/components/Auth/QrLogin/QrLogin.d.ts.map +1 -0
  124. package/lib/typescript/src/components/Auth/QrLogin/components/QrViewArea.d.ts +15 -0
  125. package/lib/typescript/src/components/Auth/QrLogin/components/QrViewArea.d.ts.map +1 -0
  126. package/lib/typescript/src/components/Auth/SplashScreen/SplashScreen.d.ts +4 -3
  127. package/lib/typescript/src/components/Auth/SplashScreen/SplashScreen.d.ts.map +1 -1
  128. package/lib/typescript/src/components/Auth/SplashScreen/components/SplashVideo/SplashVideo.d.ts +1 -1
  129. package/lib/typescript/src/components/Auth/SplashScreen/components/SplashVideo/SplashVideo.d.ts.map +1 -1
  130. package/lib/typescript/src/components/Auth/index.d.ts +3 -0
  131. package/lib/typescript/src/components/Auth/index.d.ts.map +1 -1
  132. package/lib/typescript/src/components/BackgroundLayout/BackgroundLayout.d.ts.map +1 -1
  133. package/lib/typescript/src/components/Button/SecondaryBtn.d.ts +21 -0
  134. package/lib/typescript/src/components/Button/SecondaryBtn.d.ts.map +1 -0
  135. package/lib/typescript/src/components/Button/index.d.ts +11 -0
  136. package/lib/typescript/src/components/Button/index.d.ts.map +1 -1
  137. package/lib/typescript/src/components/Content/Card/NowWatching/NowWatching.d.ts.map +1 -1
  138. package/lib/typescript/src/components/Content/Card/Sliders/Styles/One.d.ts.map +1 -1
  139. package/lib/typescript/src/components/Content/Card/Sliders/Styles/Two.d.ts.map +1 -1
  140. package/lib/typescript/src/components/Content/Card/Styles/Five.d.ts.map +1 -1
  141. package/lib/typescript/src/components/Content/Card/Styles/Four.d.ts.map +1 -1
  142. package/lib/typescript/src/components/Content/Card/Styles/One.d.ts.map +1 -1
  143. package/lib/typescript/src/components/Content/Card/Styles/RotateInOut.d.ts.map +1 -1
  144. package/lib/typescript/src/components/Content/Card/Styles/Six.d.ts.map +1 -1
  145. package/lib/typescript/src/components/Content/Card/Styles/Three.d.ts.map +1 -1
  146. package/lib/typescript/src/components/Content/Card/Styles/TopTen.d.ts.map +1 -1
  147. package/lib/typescript/src/components/Content/Card/Styles/Two.d.ts.map +1 -1
  148. package/lib/typescript/src/components/Content/Card/components/CardPoster.d.ts +4 -2
  149. package/lib/typescript/src/components/Content/Card/components/CardPoster.d.ts.map +1 -1
  150. package/lib/typescript/src/components/Content/Card/components/RentOrBuyIcon.d.ts +14 -0
  151. package/lib/typescript/src/components/Content/Card/components/RentOrBuyIcon.d.ts.map +1 -0
  152. package/lib/typescript/src/components/ContentView/ContentView.d.ts.map +1 -1
  153. package/lib/typescript/src/components/ContentView/MoreContentList.d.ts.map +1 -1
  154. package/lib/typescript/src/components/ContentView/components/EpisodeCard.d.ts.map +1 -1
  155. package/lib/typescript/src/components/ContentView/components/HeroBanner.d.ts +1 -1
  156. package/lib/typescript/src/components/ContentView/components/HeroBanner.d.ts.map +1 -1
  157. package/lib/typescript/src/components/Logo/Logo.d.ts.map +1 -1
  158. package/lib/typescript/src/components/Reels/ReelsSeries/Model/Episodes.d.ts +12 -0
  159. package/lib/typescript/src/components/Reels/ReelsSeries/Model/Episodes.d.ts.map +1 -0
  160. package/lib/typescript/src/components/Reels/ReelsSeries/Model/Synopsis.d.ts +9 -0
  161. package/lib/typescript/src/components/Reels/ReelsSeries/Model/Synopsis.d.ts.map +1 -0
  162. package/lib/typescript/src/components/Reels/ReelsSeries/ReelSeriesDetailsModal.d.ts +13 -0
  163. package/lib/typescript/src/components/Reels/ReelsSeries/ReelSeriesDetailsModal.d.ts.map +1 -0
  164. package/lib/typescript/src/components/Reels/ReelsSeries/ReelSeriesOverlay.d.ts +18 -0
  165. package/lib/typescript/src/components/Reels/ReelsSeries/ReelSeriesOverlay.d.ts.map +1 -0
  166. package/lib/typescript/src/components/Reels/ReelsSeries/ReelsSeries.d.ts +15 -0
  167. package/lib/typescript/src/components/Reels/ReelsSeries/ReelsSeries.d.ts.map +1 -0
  168. package/lib/typescript/src/components/Reels/ReelsSeries/ReelsSeriesItem.d.ts +18 -0
  169. package/lib/typescript/src/components/Reels/ReelsSeries/ReelsSeriesItem.d.ts.map +1 -0
  170. package/lib/typescript/src/components/Reels/ReelsSeries/types.d.ts +24 -0
  171. package/lib/typescript/src/components/Reels/ReelsSeries/types.d.ts.map +1 -0
  172. package/lib/typescript/src/components/Reels/index.d.ts +8 -0
  173. package/lib/typescript/src/components/Reels/index.d.ts.map +1 -0
  174. package/lib/typescript/src/components/Subscription/SubOne.d.ts.map +1 -1
  175. package/lib/typescript/src/components/User/DeviceSessions/DeviceSessions.d.ts +1 -0
  176. package/lib/typescript/src/components/User/DeviceSessions/DeviceSessions.d.ts.map +1 -1
  177. package/lib/typescript/src/components/User/ProfileUpdate/ProfileUpdate.d.ts +27 -0
  178. package/lib/typescript/src/components/User/ProfileUpdate/ProfileUpdate.d.ts.map +1 -0
  179. package/lib/typescript/src/components/User/WatchHistory/WatchHistory.d.ts.map +1 -1
  180. package/lib/typescript/src/components/User/WatchLater/WatchLater.d.ts.map +1 -1
  181. package/lib/typescript/src/components/User/components/UserAvatar.d.ts +4 -0
  182. package/lib/typescript/src/components/User/components/UserAvatar.d.ts.map +1 -1
  183. package/lib/typescript/src/components/User/components/UserSection.d.ts.map +1 -1
  184. package/lib/typescript/src/components/User/index.d.ts +2 -1
  185. package/lib/typescript/src/components/User/index.d.ts.map +1 -1
  186. package/lib/typescript/src/components/index.d.ts +1 -0
  187. package/lib/typescript/src/components/index.d.ts.map +1 -1
  188. package/lib/typescript/src/hooks/useSplashCache.d.ts +22 -0
  189. package/lib/typescript/src/hooks/useSplashCache.d.ts.map +1 -0
  190. package/lib/typescript/src/store/RecentSearchesStore.d.ts.map +1 -1
  191. package/lib/typescript/src/theme/ThemeProvider.d.ts.map +1 -1
  192. package/lib/typescript/src/theme/themes.d.ts +1 -0
  193. package/lib/typescript/src/theme/themes.d.ts.map +1 -1
  194. package/lib/typescript/src/types/content/content-view.types.d.ts +1 -0
  195. package/lib/typescript/src/types/content/content-view.types.d.ts.map +1 -1
  196. package/lib/typescript/src/utils/Formater.d.ts +2 -0
  197. package/lib/typescript/src/utils/Formater.d.ts.map +1 -0
  198. package/package.json +13 -5
  199. package/src/assets/animations/Failed.json +2103 -0
  200. package/src/assets/animations/Pending.json +522 -0
  201. package/src/assets/animations/Successful.json +2289 -0
  202. package/src/assets/animations/heart.json +788 -0
  203. package/src/components/Alert/AlertDialog.tsx +247 -0
  204. package/src/components/Alert/index.ts +1 -0
  205. package/src/components/Auth/AuthProvider/AuthProvider.tsx +344 -0
  206. package/src/components/Auth/QrLogin/QrLogin.tsx +306 -0
  207. package/src/components/Auth/QrLogin/components/QrViewArea.tsx +213 -0
  208. package/src/components/Auth/SplashScreen/SplashScreen.tsx +89 -80
  209. package/src/components/Auth/SplashScreen/components/SplashVideo/SplashVideo.tsx +90 -40
  210. package/src/components/Auth/index.ts +4 -0
  211. package/src/components/BackgroundLayout/BackgroundLayout.tsx +3 -3
  212. package/src/components/Button/SecondaryBtn.tsx +116 -0
  213. package/src/components/Button/index.ts +2 -0
  214. package/src/components/Content/Card/NowWatching/NowWatching.tsx +4 -0
  215. package/src/components/Content/Card/Sliders/Styles/One.tsx +2 -0
  216. package/src/components/Content/Card/Sliders/Styles/Two.tsx +2 -0
  217. package/src/components/Content/Card/Styles/Five.tsx +1 -0
  218. package/src/components/Content/Card/Styles/Four.tsx +1 -0
  219. package/src/components/Content/Card/Styles/One.tsx +7 -1
  220. package/src/components/Content/Card/Styles/RotateInOut.tsx +1 -0
  221. package/src/components/Content/Card/Styles/Six.tsx +2 -0
  222. package/src/components/Content/Card/Styles/Three.tsx +1 -0
  223. package/src/components/Content/Card/Styles/TopTen.tsx +1 -0
  224. package/src/components/Content/Card/Styles/Two.tsx +1 -0
  225. package/src/components/Content/Card/components/CardPoster.tsx +23 -51
  226. package/src/components/Content/Card/components/RentOrBuyIcon.tsx +109 -0
  227. package/src/components/Content/Card/components/ThumbnailCard.tsx +1 -2
  228. package/src/components/ContentView/ContentView.tsx +1 -0
  229. package/src/components/ContentView/MoreContentList.tsx +1 -0
  230. package/src/components/ContentView/components/EpisodeCard.tsx +4 -9
  231. package/src/components/ContentView/components/HeroBanner.tsx +16 -0
  232. package/src/components/Headers/AppHeader.tsx +1 -1
  233. package/src/components/Headers/One.tsx +1 -1
  234. package/src/components/Headers/Two.tsx +1 -1
  235. package/src/components/Logo/Logo.tsx +5 -7
  236. package/src/components/Reels/ReelsSeries/Model/Episodes.tsx +133 -0
  237. package/src/components/Reels/ReelsSeries/Model/Synopsis.tsx +242 -0
  238. package/src/components/Reels/ReelsSeries/ReelSeriesDetailsModal.tsx +209 -0
  239. package/src/components/Reels/ReelsSeries/ReelSeriesOverlay.tsx +185 -0
  240. package/src/components/Reels/ReelsSeries/ReelsSeries.tsx +163 -0
  241. package/src/components/Reels/ReelsSeries/ReelsSeriesItem.tsx +333 -0
  242. package/src/components/Reels/ReelsSeries/types.ts +27 -0
  243. package/src/components/Reels/index.ts +8 -0
  244. package/src/components/Subscription/SubOne.tsx +4 -2
  245. package/src/components/User/DeviceSessions/DeviceSessions.tsx +11 -0
  246. package/src/components/User/ProfileUpdate/ProfileUpdate.tsx +263 -0
  247. package/src/components/User/WatchHistory/WatchHistory.tsx +1 -0
  248. package/src/components/User/WatchLater/WatchLater.tsx +1 -0
  249. package/src/components/User/components/UserAvatar.tsx +36 -3
  250. package/src/components/User/components/UserSection.tsx +10 -13
  251. package/src/components/User/index.ts +3 -1
  252. package/src/components/index.ts +1 -0
  253. package/src/hooks/useSplashCache.ts +166 -0
  254. package/src/store/RecentSearchesStore.ts +0 -1
  255. package/src/theme/ThemeProvider.tsx +12 -9
  256. package/src/theme/themes.ts +3 -0
  257. package/src/types/content/content-view.types.ts +1 -0
  258. package/src/utils/Formater.ts +14 -0
  259. package/lib/module/hooks/useInitSplashCacheSync.js +0 -116
  260. package/lib/module/hooks/useInitSplashCacheSync.js.map +0 -1
  261. package/lib/typescript/src/hooks/useInitSplashCacheSync.d.ts +0 -22
  262. package/lib/typescript/src/hooks/useInitSplashCacheSync.d.ts.map +0 -1
  263. package/src/hooks/useInitSplashCacheSync.ts +0 -174
  264. /package/lib/module/assets/{img → svg}/h.svg +0 -0
  265. /package/src/assets/{img → svg}/h.svg +0 -0
@@ -0,0 +1,306 @@
1
+ /**
2
+ * @author Ashok Desai
3
+ * @lastModified oct 02 Oct 2025 at 10:30 AM
4
+ */
5
+ import React, { useState, useRef } from 'react';
6
+ import {
7
+ View,
8
+ StyleSheet,
9
+ Dimensions,
10
+ TouchableOpacity,
11
+ ActivityIndicator,
12
+ StatusBar,
13
+ } from 'react-native';
14
+ import { scale } from 'react-native-size-matters';
15
+ import { RFValue } from 'react-native-responsive-fontsize';
16
+ import { Text } from '../../Text';
17
+ import AppHeader from '../../Headers/AppHeader';
18
+ import { useTheme } from '../../../theme/hook/useTheme';
19
+ import type { AppTheme } from '../../../theme/themes';
20
+ import { Camera as CameraIcon, QrCode } from 'lucide-react-native';
21
+ import {
22
+ Camera,
23
+ useCameraDevice,
24
+ useCameraPermission,
25
+ useCodeScanner,
26
+ type Code as BaseCode,
27
+ } from 'react-native-vision-camera';
28
+ import QrViewArea from './components/QrViewArea';
29
+
30
+ const { width: SCREEN_W, height: SCREEN_H } = Dimensions.get('window');
31
+ const HEADER_HEIGHT = 25;
32
+
33
+ export interface Code extends BaseCode {
34
+ bounds?: {
35
+ origin: { x: number; y: number };
36
+ size: { width: number; height: number };
37
+ };
38
+ }
39
+
40
+ export type QrLoginProps = {
41
+ title?: string;
42
+ description?: string;
43
+ scanButtonText?: string;
44
+ onBackPress?: () => void;
45
+ onScanSuccess?: (value: string) => void;
46
+ theme?: AppTheme;
47
+ cameraType?: 'back' | 'front';
48
+ layout?: 'one' | 'two';
49
+ };
50
+
51
+ const DEFAULTS = {
52
+ title: 'QR Login',
53
+ description: 'Please move your camera over the QR Code',
54
+ scanButtonText: 'Scan QR Code',
55
+ cameraType: 'back' as const,
56
+ };
57
+
58
+ export const QrLogin: React.FC<QrLoginProps> = ({
59
+ title = DEFAULTS.title,
60
+ description = DEFAULTS.description,
61
+ scanButtonText = DEFAULTS.scanButtonText,
62
+ onBackPress,
63
+ onScanSuccess,
64
+ theme,
65
+ cameraType = DEFAULTS.cameraType,
66
+ layout = 'one',
67
+ }) => {
68
+ const { theme: appliedTheme } = useTheme(theme);
69
+ const { colors } = appliedTheme;
70
+
71
+ const [scanActive, setScanActive] = useState(false);
72
+ const [requesting, setRequesting] = useState(false);
73
+
74
+ const device = useCameraDevice(cameraType);
75
+ const { hasPermission, requestPermission } = useCameraPermission();
76
+
77
+ const scanTimer = useRef<NodeJS.Timeout | null>(null);
78
+ const lastValueRef = useRef<string | null>(null);
79
+ const isScanning = useRef(false);
80
+
81
+ // ---- Check if QR inside scan box ----
82
+ const isCodeInsideBox = (code: Code): boolean => {
83
+ if (!code.bounds) return true;
84
+ const { origin, size } = code.bounds;
85
+ if (!origin || !size) return true;
86
+
87
+ const defaultBoxW = Math.min(SCREEN_W * 0.7, 320);
88
+ const boxW = defaultBoxW * 0.9;
89
+ const boxH = boxW;
90
+ const availableHeight = SCREEN_H - HEADER_HEIGHT;
91
+ const boxTop = Math.floor(
92
+ HEADER_HEIGHT + (availableHeight - boxH) / 2 - scale(40)
93
+ );
94
+ const sideOverlayWidth = Math.floor((SCREEN_W - boxW) / 2);
95
+
96
+ return (
97
+ origin.x >= sideOverlayWidth &&
98
+ origin.y >= boxTop &&
99
+ origin.x + size.width <= sideOverlayWidth + boxW &&
100
+ origin.y + size.height <= boxTop + boxH
101
+ );
102
+ };
103
+
104
+ // ---- Code Scanner ----
105
+ const codeScanner = useCodeScanner({
106
+ codeTypes: ['qr'],
107
+ onCodeScanned: (codes) => {
108
+ if (isScanning.current) return;
109
+ for (const c of codes) {
110
+ const code = c as Code;
111
+ const value = code?.value;
112
+ if (!value || !isCodeInsideBox(code)) continue;
113
+
114
+ if (lastValueRef.current === value) return;
115
+ lastValueRef.current = value;
116
+
117
+ if (scanTimer.current) clearTimeout(scanTimer.current);
118
+
119
+ scanTimer.current = setTimeout(() => {
120
+ isScanning.current = true;
121
+ setScanActive(false);
122
+ onScanSuccess?.(value);
123
+
124
+ setTimeout(() => {
125
+ isScanning.current = false;
126
+ lastValueRef.current = null;
127
+ }, 1000);
128
+ }, 1000);
129
+
130
+ break;
131
+ }
132
+ },
133
+ });
134
+
135
+ const startScan = async () => {
136
+ if (!hasPermission) {
137
+ setRequesting(true);
138
+ const granted = await requestPermission();
139
+ setRequesting(false);
140
+ if (!granted) return;
141
+ }
142
+ setScanActive(true);
143
+ };
144
+
145
+ return (
146
+ <View style={[styles.container, { backgroundColor: colors.background }]}>
147
+ <StatusBar
148
+ translucent
149
+ backgroundColor="transparent"
150
+ barStyle={appliedTheme.dark ? 'light-content' : 'dark-content'}
151
+ />
152
+
153
+ <View style={[styles.headerWrapper, { height: HEADER_HEIGHT }]}>
154
+ <AppHeader
155
+ title={title}
156
+ onBackPress={onBackPress}
157
+ theme={appliedTheme}
158
+ titleAlign="left"
159
+ />
160
+ </View>
161
+
162
+ <View style={styles.cameraWrapper}>
163
+ {scanActive ? (
164
+ device ? (
165
+ <>
166
+ <Camera
167
+ style={StyleSheet.absoluteFill}
168
+ device={device}
169
+ isActive={true}
170
+ codeScanner={codeScanner}
171
+ />
172
+ <QrViewArea
173
+ theme={appliedTheme}
174
+ layout={layout}
175
+ headerHeight={HEADER_HEIGHT}
176
+ />
177
+ </>
178
+ ) : (
179
+ <View
180
+ style={[styles.center, { backgroundColor: colors.background }]}
181
+ >
182
+ <Text
183
+ style={{ color: colors.textPrimary, fontSize: RFValue(16) }}
184
+ >
185
+ No camera available
186
+ </Text>
187
+ </View>
188
+ )
189
+ ) : (
190
+ <View style={styles.content}>
191
+ <View style={styles.card}>
192
+ <CameraIcon
193
+ size={scale(50)}
194
+ color={colors.button}
195
+ strokeWidth={1.6}
196
+ style={{ marginBottom: scale(12) }}
197
+ />
198
+
199
+ <Text style={[styles.descText, { color: colors.textPrimary }]}>
200
+ {description}
201
+ </Text>
202
+
203
+ <View
204
+ style={[
205
+ styles.qrBox,
206
+ {
207
+ borderColor: colors.primary,
208
+ backgroundColor: colors.skeletonBaseColor,
209
+ },
210
+ ]}
211
+ >
212
+ <QrCode
213
+ size={scale(180)}
214
+ color={colors.button}
215
+ strokeWidth={1.6}
216
+ />
217
+ </View>
218
+
219
+ <TouchableOpacity
220
+ style={[styles.scanBtn, { borderColor: colors.button }]}
221
+ onPress={startScan}
222
+ activeOpacity={0.85}
223
+ >
224
+ <CameraIcon
225
+ size={scale(22)}
226
+ color={colors.button}
227
+ strokeWidth={2}
228
+ style={{ marginRight: 10 }}
229
+ />
230
+ <Text style={[styles.scanText, { color: colors.button }]}>
231
+ {scanButtonText}
232
+ </Text>
233
+ </TouchableOpacity>
234
+
235
+ {requesting && (
236
+ <ActivityIndicator
237
+ style={{ marginTop: scale(12) }}
238
+ color={colors.primary}
239
+ />
240
+ )}
241
+ </View>
242
+ </View>
243
+ )}
244
+ </View>
245
+ </View>
246
+ );
247
+ };
248
+
249
+ const styles = StyleSheet.create({
250
+ container: { flex: 1 },
251
+ headerWrapper: {
252
+ position: 'absolute',
253
+ top: 0,
254
+ left: 0,
255
+ right: 0,
256
+ zIndex: 20,
257
+ elevation: 20,
258
+ },
259
+ cameraWrapper: {
260
+ flex: 1,
261
+ top: HEADER_HEIGHT,
262
+ },
263
+ center: {
264
+ flex: 1,
265
+ alignItems: 'center',
266
+ justifyContent: 'center',
267
+ },
268
+ content: {
269
+ flex: 1,
270
+ justifyContent: 'center',
271
+ alignItems: 'center',
272
+ padding: scale(14),
273
+ marginBottom: scale(50),
274
+ },
275
+ card: {
276
+ width: SCREEN_W - scale(40),
277
+ minHeight: SCREEN_H / 2.5,
278
+ alignItems: 'center',
279
+ padding: scale(20),
280
+ },
281
+ descText: {
282
+ fontSize: RFValue(15),
283
+ textAlign: 'center',
284
+ marginVertical: scale(12),
285
+ },
286
+ qrBox: {
287
+ marginVertical: scale(20),
288
+ padding: scale(20),
289
+ borderWidth: 2,
290
+ borderRadius: scale(12),
291
+ justifyContent: 'center',
292
+ alignItems: 'center',
293
+ },
294
+ scanBtn: {
295
+ flexDirection: 'row',
296
+ alignItems: 'center',
297
+ borderWidth: scale(2),
298
+ borderRadius: scale(12),
299
+ paddingVertical: scale(10),
300
+ paddingHorizontal: scale(25),
301
+ marginTop: scale(20),
302
+ },
303
+ scanText: { fontWeight: '600', fontSize: RFValue(14) },
304
+ });
305
+
306
+ export default QrLogin;
@@ -0,0 +1,213 @@
1
+ /**
2
+ * @author Ashok Desai
3
+ * @lastModified oct 02 Oct 2025 at 10:30 AM
4
+ */
5
+ import React, { useEffect, useRef } from 'react';
6
+ import {
7
+ View,
8
+ StyleSheet,
9
+ Animated,
10
+ Easing,
11
+ Dimensions,
12
+ Platform,
13
+ } from 'react-native';
14
+ import { scale } from 'react-native-size-matters';
15
+ import Svg, { Rect } from 'react-native-svg';
16
+ import type { AppTheme } from '../../../../theme/themes';
17
+ import { useTheme } from '../../../../theme/hook/useTheme';
18
+
19
+ const { width: SCREEN_W, height: SCREEN_H } = Dimensions.get('window');
20
+
21
+ type QrViewAreaProps = {
22
+ scanBoxWidth?: number;
23
+ layout?: 'one' | 'two';
24
+ headerHeight?: number;
25
+ theme?: AppTheme;
26
+ };
27
+
28
+ const QrViewArea: React.FC<QrViewAreaProps> = ({
29
+ scanBoxWidth,
30
+ layout = 'one',
31
+ headerHeight = 60,
32
+ theme,
33
+ }) => {
34
+ const { theme: appliedTheme } = useTheme(theme);
35
+ const { colors } = appliedTheme;
36
+
37
+ const anim = useRef(new Animated.Value(0)).current;
38
+
39
+ const defaultBoxW = scanBoxWidth || Math.min(SCREEN_W * 0.7, 320);
40
+ const boxW = defaultBoxW * 0.9;
41
+ const boxH = boxW;
42
+
43
+ const availableHeight = SCREEN_H - headerHeight;
44
+ const boxTop = Math.floor(
45
+ headerHeight + (availableHeight - boxH) / 2 - scale(40)
46
+ );
47
+
48
+ const topOverlayHeight = Math.floor(boxTop - headerHeight);
49
+ const bottomOverlayHeight = Math.floor(SCREEN_H - (boxTop + boxH));
50
+ const sideOverlayWidth = Math.floor((SCREEN_W - boxW) / 2);
51
+
52
+ const margin = scale(12);
53
+ const lineTravel = boxH - margin * 2 - scale(3);
54
+
55
+ const translateY = anim.interpolate({
56
+ inputRange: [0, 1],
57
+ outputRange: [0, lineTravel],
58
+ });
59
+
60
+ useEffect(() => {
61
+ const animation = Animated.loop(
62
+ Animated.sequence([
63
+ Animated.timing(anim, {
64
+ toValue: 1,
65
+ duration: 2000,
66
+ easing: Easing.linear,
67
+ useNativeDriver: true,
68
+ }),
69
+ Animated.timing(anim, {
70
+ toValue: 0,
71
+ duration: 2000,
72
+ easing: Easing.linear,
73
+ useNativeDriver: true,
74
+ }),
75
+ ])
76
+ );
77
+ animation.start();
78
+ return () => animation.stop();
79
+ }, [anim]);
80
+
81
+ return (
82
+ <>
83
+ <View
84
+ style={[
85
+ styles.overlayTB,
86
+ {
87
+ top: headerHeight,
88
+ height: topOverlayHeight,
89
+ backgroundColor: colors.overlay,
90
+ },
91
+ ]}
92
+ />
93
+ <View
94
+ style={[
95
+ styles.overlayTB,
96
+ {
97
+ top: boxTop + boxH,
98
+ height: bottomOverlayHeight,
99
+ backgroundColor: colors.overlay,
100
+ },
101
+ ]}
102
+ />
103
+ <View
104
+ style={[
105
+ styles.overlayLR,
106
+ {
107
+ top: boxTop,
108
+ height: boxH,
109
+ width: sideOverlayWidth,
110
+ backgroundColor: colors.overlay,
111
+ },
112
+ ]}
113
+ />
114
+ <View
115
+ style={[
116
+ styles.overlayLR,
117
+ {
118
+ top: boxTop,
119
+ right: 0,
120
+ height: boxH,
121
+ width: sideOverlayWidth,
122
+ backgroundColor: colors.overlay,
123
+ },
124
+ ]}
125
+ />
126
+
127
+ <View
128
+ style={[
129
+ styles.scanBox,
130
+ { top: boxTop, width: boxW, height: boxH, left: sideOverlayWidth },
131
+ ]}
132
+ >
133
+ {layout === 'two' ? (
134
+ <Svg width={boxW} height={boxH}>
135
+ <Rect
136
+ width={boxW}
137
+ height={boxH}
138
+ ry={scale(8)}
139
+ stroke={colors.button}
140
+ strokeWidth={scale(5)}
141
+ strokeDasharray={[scale(12), scale(6)]}
142
+ fill="none"
143
+ />
144
+ </Svg>
145
+ ) : (
146
+ ['tl', 'tr', 'bl', 'br'].map((c) => (
147
+ <View
148
+ key={c}
149
+ style={[
150
+ styles.corner,
151
+ styles[`corner_${c}` as keyof typeof styles],
152
+ {
153
+ borderColor: colors.button,
154
+ width: scale(18),
155
+ height: scale(18),
156
+ borderTopWidth: c.startsWith('t') ? scale(3) : 0,
157
+ borderBottomWidth: c.startsWith('b') ? scale(3) : 0,
158
+ borderLeftWidth: c.endsWith('l') ? scale(3) : 0,
159
+ borderRightWidth: c.endsWith('r') ? scale(3) : 0,
160
+ },
161
+ ]}
162
+ />
163
+ ))
164
+ )}
165
+
166
+ <Animated.View
167
+ style={{
168
+ position: 'absolute',
169
+ top: margin,
170
+ left: margin,
171
+ right: margin,
172
+ height: scale(3),
173
+ borderRadius: scale(1.5),
174
+ backgroundColor: colors.button,
175
+ transform: [{ translateY }],
176
+ shadowColor: colors.shadow,
177
+ shadowOffset: { width: 0, height: 4 },
178
+ shadowOpacity: 0.3,
179
+ shadowRadius: 5,
180
+ elevation: Platform.OS === 'android' ? 4 : 0,
181
+ }}
182
+ />
183
+ </View>
184
+ </>
185
+ );
186
+ };
187
+
188
+ const styles = StyleSheet.create({
189
+ overlayTB: {
190
+ position: 'absolute',
191
+ left: 0,
192
+ right: 0,
193
+ },
194
+ overlayLR: {
195
+ position: 'absolute',
196
+ },
197
+ scanBox: {
198
+ position: 'absolute',
199
+ justifyContent: 'center',
200
+ alignItems: 'center',
201
+ overflow: 'hidden',
202
+ zIndex: 10,
203
+ },
204
+ corner: {
205
+ position: 'absolute',
206
+ },
207
+ corner_tl: { top: 0, left: 0 },
208
+ corner_tr: { top: 0, right: 0 },
209
+ corner_bl: { bottom: 0, left: 0 },
210
+ corner_br: { bottom: 0, right: 0 },
211
+ });
212
+
213
+ export default QrViewArea;