@zezosoft/zezo-ott-react-native-ui-kit 1.1.1 → 1.1.2

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 (349) hide show
  1. package/lib/module/Styles/globalStyles.js +0 -5
  2. package/lib/module/Styles/globalStyles.js.map +1 -1
  3. package/lib/module/components/Auth/AuthProvider/AuthProvider.js +64 -40
  4. package/lib/module/components/Auth/AuthProvider/AuthProvider.js.map +1 -1
  5. package/lib/module/components/Auth/ForgotPassword/ForgotPassword.js +5 -2
  6. package/lib/module/components/Auth/ForgotPassword/ForgotPassword.js.map +1 -1
  7. package/lib/module/components/Auth/Login/LoginWithEmail.js +17 -11
  8. package/lib/module/components/Auth/Login/LoginWithEmail.js.map +1 -1
  9. package/lib/module/components/Auth/Login/LoginWithPhone.js +12 -6
  10. package/lib/module/components/Auth/Login/LoginWithPhone.js.map +1 -1
  11. package/lib/module/components/Auth/OTP/OTP.js +7 -4
  12. package/lib/module/components/Auth/OTP/OTP.js.map +1 -1
  13. package/lib/module/components/Auth/QrLogin/QrLogin.js +133 -86
  14. package/lib/module/components/Auth/QrLogin/QrLogin.js.map +1 -1
  15. package/lib/module/components/Auth/QrLogin/components/QrViewArea.js +174 -109
  16. package/lib/module/components/Auth/QrLogin/components/QrViewArea.js.map +1 -1
  17. package/lib/module/components/Auth/SignUp/SignUp.js +19 -13
  18. package/lib/module/components/Auth/SignUp/SignUp.js.map +1 -1
  19. package/lib/module/components/Auth/SplashScreen/SplashScreen.js +54 -36
  20. package/lib/module/components/Auth/SplashScreen/SplashScreen.js.map +1 -1
  21. package/lib/module/components/Auth/SplashScreen/components/SplashImage/SplashImage.js +29 -11
  22. package/lib/module/components/Auth/SplashScreen/components/SplashImage/SplashImage.js.map +1 -1
  23. package/lib/module/components/Auth/SplashScreen/components/SplashLottie/SplashLottie.js +13 -7
  24. package/lib/module/components/Auth/SplashScreen/components/SplashLottie/SplashLottie.js.map +1 -1
  25. package/lib/module/components/Auth/SplashScreen/components/SplashVideo/SplashVideo.js +33 -21
  26. package/lib/module/components/Auth/SplashScreen/components/SplashVideo/SplashVideo.js.map +1 -1
  27. package/lib/module/components/BackgroundLayout/BackgroundLayout.js +26 -20
  28. package/lib/module/components/BackgroundLayout/BackgroundLayout.js.map +1 -1
  29. package/lib/module/components/BlogView/BlogView.js +36 -20
  30. package/lib/module/components/BlogView/BlogView.js.map +1 -1
  31. package/lib/module/components/Button/BackBtn.js +24 -20
  32. package/lib/module/components/Button/BackBtn.js.map +1 -1
  33. package/lib/module/components/Button/PrimaryBtn.js +19 -13
  34. package/lib/module/components/Button/PrimaryBtn.js.map +1 -1
  35. package/lib/module/components/Button/SecondaryBtn.js +19 -13
  36. package/lib/module/components/Button/SecondaryBtn.js.map +1 -1
  37. package/lib/module/components/Button/TextButton.js +19 -13
  38. package/lib/module/components/Button/TextButton.js.map +1 -1
  39. package/lib/module/components/Content/Card/Category/Category.js +70 -37
  40. package/lib/module/components/Content/Card/Category/Category.js.map +1 -1
  41. package/lib/module/components/Content/Card/Sliders/Styles/One.js +40 -32
  42. package/lib/module/components/Content/Card/Sliders/Styles/One.js.map +1 -1
  43. package/lib/module/components/Content/Card/Sliders/Styles/Two.js +109 -48
  44. package/lib/module/components/Content/Card/Sliders/Styles/Two.js.map +1 -1
  45. package/lib/module/components/Content/Card/Styles/RotateInOut.js +4 -11
  46. package/lib/module/components/Content/Card/Styles/RotateInOut.js.map +1 -1
  47. package/lib/module/components/Content/Card/components/CardPoster.js +105 -43
  48. package/lib/module/components/Content/Card/components/CardPoster.js.map +1 -1
  49. package/lib/module/components/Content/Card/components/RentOrBuyIcon.js +18 -17
  50. package/lib/module/components/Content/Card/components/RentOrBuyIcon.js.map +1 -1
  51. package/lib/module/components/Content/Card/components/ThumbnailCard.js +78 -28
  52. package/lib/module/components/Content/Card/components/ThumbnailCard.js.map +1 -1
  53. package/lib/module/components/Content/Content.js +44 -25
  54. package/lib/module/components/Content/Content.js.map +1 -1
  55. package/lib/module/components/Content/Sections.js +37 -29
  56. package/lib/module/components/Content/Sections.js.map +1 -1
  57. package/lib/module/components/ContentView/ContentView.js +70 -41
  58. package/lib/module/components/ContentView/ContentView.js.map +1 -1
  59. package/lib/module/components/ContentView/MoreContentList.js +74 -40
  60. package/lib/module/components/ContentView/MoreContentList.js.map +1 -1
  61. package/lib/module/components/ContentView/components/AboutSection.js +40 -19
  62. package/lib/module/components/ContentView/components/AboutSection.js.map +1 -1
  63. package/lib/module/components/ContentView/components/CastCard.js +6 -7
  64. package/lib/module/components/ContentView/components/CastCard.js.map +1 -1
  65. package/lib/module/components/ContentView/components/EpisodeCard.js +2 -2
  66. package/lib/module/components/ContentView/components/EpisodeCard.js.map +1 -1
  67. package/lib/module/components/ContentView/components/GenreTags.js +25 -13
  68. package/lib/module/components/ContentView/components/GenreTags.js.map +1 -1
  69. package/lib/module/components/ContentView/components/HeroBanner.js +39 -11
  70. package/lib/module/components/ContentView/components/HeroBanner.js.map +1 -1
  71. package/lib/module/components/ContentView/components/MiniInfo.js +84 -77
  72. package/lib/module/components/ContentView/components/MiniInfo.js.map +1 -1
  73. package/lib/module/components/ContentView/components/PlayButton.js +11 -7
  74. package/lib/module/components/ContentView/components/PlayButton.js.map +1 -1
  75. package/lib/module/components/ContentView/components/Title.js +12 -12
  76. package/lib/module/components/ContentView/components/Title.js.map +1 -1
  77. package/lib/module/components/ContentView/components/TrailerButton.js +12 -7
  78. package/lib/module/components/ContentView/components/TrailerButton.js.map +1 -1
  79. package/lib/module/components/Fallbacks/NoContentFallback.js +27 -22
  80. package/lib/module/components/Fallbacks/NoContentFallback.js.map +1 -1
  81. package/lib/module/components/Fallbacks/NotFoundFallback.js +6 -4
  82. package/lib/module/components/Fallbacks/NotFoundFallback.js.map +1 -1
  83. package/lib/module/components/Headers/AppHeader.js +22 -13
  84. package/lib/module/components/Headers/AppHeader.js.map +1 -1
  85. package/lib/module/components/Headers/Three.js +6 -5
  86. package/lib/module/components/Headers/Three.js.map +1 -1
  87. package/lib/module/components/Headers/Two.js +19 -14
  88. package/lib/module/components/Headers/Two.js.map +1 -1
  89. package/lib/module/components/Input/InputOne.js +46 -31
  90. package/lib/module/components/Input/InputOne.js.map +1 -1
  91. package/lib/module/components/Loader/Loader.js +2 -2
  92. package/lib/module/components/Loader/Loader.js.map +1 -1
  93. package/lib/module/components/Logo/Logo.js +17 -14
  94. package/lib/module/components/Logo/Logo.js.map +1 -1
  95. package/lib/module/components/Search/One.js +2 -1
  96. package/lib/module/components/Search/One.js.map +1 -1
  97. package/lib/module/components/Search/components/SearchCard.js +15 -19
  98. package/lib/module/components/Search/components/SearchCard.js.map +1 -1
  99. package/lib/module/components/Settings/AppSettings.js +97 -62
  100. package/lib/module/components/Settings/AppSettings.js.map +1 -1
  101. package/lib/module/components/Subscription/SubOne.js +313 -254
  102. package/lib/module/components/Subscription/SubOne.js.map +1 -1
  103. package/lib/module/components/Text/Text.js +15 -12
  104. package/lib/module/components/Text/Text.js.map +1 -1
  105. package/lib/module/components/User/DeviceSessions/DeviceSessions.js +25 -23
  106. package/lib/module/components/User/DeviceSessions/DeviceSessions.js.map +1 -1
  107. package/lib/module/components/User/ProfileUpdate/ProfileUpdate.js +23 -18
  108. package/lib/module/components/User/ProfileUpdate/ProfileUpdate.js.map +1 -1
  109. package/lib/module/components/User/PurchaseHistory/PurchaseHistory.js +38 -24
  110. package/lib/module/components/User/PurchaseHistory/PurchaseHistory.js.map +1 -1
  111. package/lib/module/components/User/WatchHistory/WatchHistory.js +21 -14
  112. package/lib/module/components/User/WatchHistory/WatchHistory.js.map +1 -1
  113. package/lib/module/components/User/WatchLater/WatchLater.js +30 -21
  114. package/lib/module/components/User/WatchLater/WatchLater.js.map +1 -1
  115. package/lib/module/components/User/components/UserAvatar.js +38 -19
  116. package/lib/module/components/User/components/UserAvatar.js.map +1 -1
  117. package/lib/module/components/User/components/UserSection.js +37 -17
  118. package/lib/module/components/User/components/UserSection.js.map +1 -1
  119. package/lib/module/components/View/View.js +7 -4
  120. package/lib/module/components/View/View.js.map +1 -1
  121. package/lib/module/components/index.js +0 -1
  122. package/lib/module/components/index.js.map +1 -1
  123. package/lib/module/hooks/index.js +17 -0
  124. package/lib/module/hooks/index.js.map +1 -0
  125. package/lib/module/hooks/useDebounce.js +25 -6
  126. package/lib/module/hooks/useDebounce.js.map +1 -1
  127. package/lib/module/hooks/useKeyboard.js +7 -4
  128. package/lib/module/hooks/useKeyboard.js.map +1 -1
  129. package/lib/module/hooks/useNavigationMode.js +10 -4
  130. package/lib/module/hooks/useNavigationMode.js.map +1 -1
  131. package/lib/module/hooks/usePaginatedSection.js +1 -1
  132. package/lib/module/hooks/usePaginatedSection.js.map +1 -1
  133. package/lib/module/hooks/usePrevious.js +30 -0
  134. package/lib/module/hooks/usePrevious.js.map +1 -0
  135. package/lib/module/hooks/useSafeCallback.js +33 -0
  136. package/lib/module/hooks/useSafeCallback.js.map +1 -0
  137. package/lib/module/hooks/useSkeletonItems.js +33 -0
  138. package/lib/module/hooks/useSkeletonItems.js.map +1 -0
  139. package/lib/module/hooks/useSplashCache.js +2 -1
  140. package/lib/module/hooks/useSplashCache.js.map +1 -1
  141. package/lib/module/hooks/useThemeColors.js +33 -0
  142. package/lib/module/hooks/useThemeColors.js.map +1 -0
  143. package/lib/module/theme/ThemeProvider.js +17 -11
  144. package/lib/module/theme/ThemeProvider.js.map +1 -1
  145. package/lib/module/theme/hook/useInternalTheme.js +18 -11
  146. package/lib/module/theme/hook/useInternalTheme.js.map +1 -1
  147. package/lib/module/theme/hook/useThemeStatusBar.js +10 -4
  148. package/lib/module/theme/hook/useThemeStatusBar.js.map +1 -1
  149. package/lib/typescript/src/Styles/globalStyles.d.ts +0 -5
  150. package/lib/typescript/src/Styles/globalStyles.d.ts.map +1 -1
  151. package/lib/typescript/src/components/Auth/AuthProvider/AuthProvider.d.ts.map +1 -1
  152. package/lib/typescript/src/components/Auth/ForgotPassword/ForgotPassword.d.ts.map +1 -1
  153. package/lib/typescript/src/components/Auth/Login/LoginWithEmail.d.ts.map +1 -1
  154. package/lib/typescript/src/components/Auth/Login/LoginWithPhone.d.ts.map +1 -1
  155. package/lib/typescript/src/components/Auth/OTP/OTP.d.ts.map +1 -1
  156. package/lib/typescript/src/components/Auth/QrLogin/QrLogin.d.ts +0 -15
  157. package/lib/typescript/src/components/Auth/QrLogin/QrLogin.d.ts.map +1 -1
  158. package/lib/typescript/src/components/Auth/QrLogin/components/QrViewArea.d.ts +0 -1
  159. package/lib/typescript/src/components/Auth/QrLogin/components/QrViewArea.d.ts.map +1 -1
  160. package/lib/typescript/src/components/Auth/SignUp/SignUp.d.ts.map +1 -1
  161. package/lib/typescript/src/components/Auth/SplashScreen/SplashScreen.d.ts.map +1 -1
  162. package/lib/typescript/src/components/Auth/SplashScreen/components/SplashImage/SplashImage.d.ts.map +1 -1
  163. package/lib/typescript/src/components/Auth/SplashScreen/components/SplashLottie/SplashLottie.d.ts.map +1 -1
  164. package/lib/typescript/src/components/Auth/SplashScreen/components/SplashVideo/SplashVideo.d.ts.map +1 -1
  165. package/lib/typescript/src/components/Auth/index.d.ts.map +1 -1
  166. package/lib/typescript/src/components/BackgroundLayout/BackgroundLayout.d.ts +1 -1
  167. package/lib/typescript/src/components/BackgroundLayout/BackgroundLayout.d.ts.map +1 -1
  168. package/lib/typescript/src/components/BlogView/BlogView.d.ts +2 -1
  169. package/lib/typescript/src/components/BlogView/BlogView.d.ts.map +1 -1
  170. package/lib/typescript/src/components/Button/BackBtn.d.ts +2 -2
  171. package/lib/typescript/src/components/Button/BackBtn.d.ts.map +1 -1
  172. package/lib/typescript/src/components/Button/PrimaryBtn.d.ts +2 -1
  173. package/lib/typescript/src/components/Button/PrimaryBtn.d.ts.map +1 -1
  174. package/lib/typescript/src/components/Button/SecondaryBtn.d.ts +2 -1
  175. package/lib/typescript/src/components/Button/SecondaryBtn.d.ts.map +1 -1
  176. package/lib/typescript/src/components/Button/TextButton.d.ts +2 -2
  177. package/lib/typescript/src/components/Button/TextButton.d.ts.map +1 -1
  178. package/lib/typescript/src/components/Button/index.d.ts +2 -2
  179. package/lib/typescript/src/components/Content/Card/Category/Category.d.ts.map +1 -1
  180. package/lib/typescript/src/components/Content/Card/Sliders/Styles/One.d.ts.map +1 -1
  181. package/lib/typescript/src/components/Content/Card/Sliders/Styles/Two.d.ts.map +1 -1
  182. package/lib/typescript/src/components/Content/Card/Styles/RotateInOut.d.ts.map +1 -1
  183. package/lib/typescript/src/components/Content/Card/components/CardPoster.d.ts.map +1 -1
  184. package/lib/typescript/src/components/Content/Card/components/RentOrBuyIcon.d.ts +2 -2
  185. package/lib/typescript/src/components/Content/Card/components/RentOrBuyIcon.d.ts.map +1 -1
  186. package/lib/typescript/src/components/Content/Card/components/ThumbnailCard.d.ts +2 -0
  187. package/lib/typescript/src/components/Content/Card/components/ThumbnailCard.d.ts.map +1 -1
  188. package/lib/typescript/src/components/Content/Content.d.ts +2 -0
  189. package/lib/typescript/src/components/Content/Content.d.ts.map +1 -1
  190. package/lib/typescript/src/components/Content/Sections.d.ts +2 -2
  191. package/lib/typescript/src/components/Content/Sections.d.ts.map +1 -1
  192. package/lib/typescript/src/components/ContentView/ContentView.d.ts +6 -1
  193. package/lib/typescript/src/components/ContentView/ContentView.d.ts.map +1 -1
  194. package/lib/typescript/src/components/ContentView/MoreContentList.d.ts.map +1 -1
  195. package/lib/typescript/src/components/ContentView/components/AboutSection.d.ts +2 -1
  196. package/lib/typescript/src/components/ContentView/components/AboutSection.d.ts.map +1 -1
  197. package/lib/typescript/src/components/ContentView/components/CastCard.d.ts +6 -1
  198. package/lib/typescript/src/components/ContentView/components/CastCard.d.ts.map +1 -1
  199. package/lib/typescript/src/components/ContentView/components/EpisodeCard.d.ts +2 -1
  200. package/lib/typescript/src/components/ContentView/components/EpisodeCard.d.ts.map +1 -1
  201. package/lib/typescript/src/components/ContentView/components/GenreTags.d.ts +1 -1
  202. package/lib/typescript/src/components/ContentView/components/GenreTags.d.ts.map +1 -1
  203. package/lib/typescript/src/components/ContentView/components/HeroBanner.d.ts +2 -1
  204. package/lib/typescript/src/components/ContentView/components/HeroBanner.d.ts.map +1 -1
  205. package/lib/typescript/src/components/ContentView/components/MiniInfo.d.ts +1 -1
  206. package/lib/typescript/src/components/ContentView/components/MiniInfo.d.ts.map +1 -1
  207. package/lib/typescript/src/components/ContentView/components/PlayButton.d.ts +2 -1
  208. package/lib/typescript/src/components/ContentView/components/PlayButton.d.ts.map +1 -1
  209. package/lib/typescript/src/components/ContentView/components/Title.d.ts +1 -1
  210. package/lib/typescript/src/components/ContentView/components/Title.d.ts.map +1 -1
  211. package/lib/typescript/src/components/ContentView/components/TrailerButton.d.ts +2 -1
  212. package/lib/typescript/src/components/ContentView/components/TrailerButton.d.ts.map +1 -1
  213. package/lib/typescript/src/components/Fallbacks/NoContentFallback.d.ts +2 -1
  214. package/lib/typescript/src/components/Fallbacks/NoContentFallback.d.ts.map +1 -1
  215. package/lib/typescript/src/components/Fallbacks/NotFoundFallback.d.ts +1 -1
  216. package/lib/typescript/src/components/Fallbacks/NotFoundFallback.d.ts.map +1 -1
  217. package/lib/typescript/src/components/Headers/AppHeader.d.ts +2 -2
  218. package/lib/typescript/src/components/Headers/AppHeader.d.ts.map +1 -1
  219. package/lib/typescript/src/components/Headers/Three.d.ts +2 -2
  220. package/lib/typescript/src/components/Headers/Three.d.ts.map +1 -1
  221. package/lib/typescript/src/components/Headers/Two.d.ts +2 -2
  222. package/lib/typescript/src/components/Headers/Two.d.ts.map +1 -1
  223. package/lib/typescript/src/components/Headers/index.d.ts +2 -2
  224. package/lib/typescript/src/components/Input/Input.d.ts +1 -1
  225. package/lib/typescript/src/components/Input/InputOne.d.ts +2 -2
  226. package/lib/typescript/src/components/Input/InputOne.d.ts.map +1 -1
  227. package/lib/typescript/src/components/Loader/Loader.d.ts.map +1 -1
  228. package/lib/typescript/src/components/Logo/Logo.d.ts +2 -1
  229. package/lib/typescript/src/components/Logo/Logo.d.ts.map +1 -1
  230. package/lib/typescript/src/components/Search/One.d.ts.map +1 -1
  231. package/lib/typescript/src/components/Search/components/SearchCard.d.ts +2 -5
  232. package/lib/typescript/src/components/Search/components/SearchCard.d.ts.map +1 -1
  233. package/lib/typescript/src/components/Search/index.d.ts +1 -1
  234. package/lib/typescript/src/components/Settings/AppSettings.d.ts +2 -2
  235. package/lib/typescript/src/components/Settings/AppSettings.d.ts.map +1 -1
  236. package/lib/typescript/src/components/Subscription/SubOne.d.ts.map +1 -1
  237. package/lib/typescript/src/components/Subscription/index.d.ts.map +1 -1
  238. package/lib/typescript/src/components/Text/Text.d.ts +2 -2
  239. package/lib/typescript/src/components/Text/Text.d.ts.map +1 -1
  240. package/lib/typescript/src/components/User/DeviceSessions/DeviceSessions.d.ts +1 -1
  241. package/lib/typescript/src/components/User/DeviceSessions/DeviceSessions.d.ts.map +1 -1
  242. package/lib/typescript/src/components/User/ProfileUpdate/ProfileUpdate.d.ts +1 -1
  243. package/lib/typescript/src/components/User/ProfileUpdate/ProfileUpdate.d.ts.map +1 -1
  244. package/lib/typescript/src/components/User/PurchaseHistory/PurchaseHistory.d.ts +1 -1
  245. package/lib/typescript/src/components/User/PurchaseHistory/PurchaseHistory.d.ts.map +1 -1
  246. package/lib/typescript/src/components/User/WatchHistory/WatchHistory.d.ts +1 -1
  247. package/lib/typescript/src/components/User/WatchHistory/WatchHistory.d.ts.map +1 -1
  248. package/lib/typescript/src/components/User/WatchLater/WatchLater.d.ts +1 -1
  249. package/lib/typescript/src/components/User/WatchLater/WatchLater.d.ts.map +1 -1
  250. package/lib/typescript/src/components/User/components/UserAvatar.d.ts +1 -1
  251. package/lib/typescript/src/components/User/components/UserAvatar.d.ts.map +1 -1
  252. package/lib/typescript/src/components/User/components/UserSection.d.ts +1 -1
  253. package/lib/typescript/src/components/User/components/UserSection.d.ts.map +1 -1
  254. package/lib/typescript/src/components/View/View.d.ts +2 -0
  255. package/lib/typescript/src/components/View/View.d.ts.map +1 -1
  256. package/lib/typescript/src/components/index.d.ts +0 -1
  257. package/lib/typescript/src/components/index.d.ts.map +1 -1
  258. package/lib/typescript/src/hooks/index.d.ts +14 -0
  259. package/lib/typescript/src/hooks/index.d.ts.map +1 -0
  260. package/lib/typescript/src/hooks/useDebounce.d.ts.map +1 -1
  261. package/lib/typescript/src/hooks/useKeyboard.d.ts.map +1 -1
  262. package/lib/typescript/src/hooks/useNavigationMode.d.ts.map +1 -1
  263. package/lib/typescript/src/hooks/usePrevious.d.ts +12 -0
  264. package/lib/typescript/src/hooks/usePrevious.d.ts.map +1 -0
  265. package/lib/typescript/src/hooks/useSafeCallback.d.ts +15 -0
  266. package/lib/typescript/src/hooks/useSafeCallback.d.ts.map +1 -0
  267. package/lib/typescript/src/hooks/useSkeletonItems.d.ts +11 -0
  268. package/lib/typescript/src/hooks/useSkeletonItems.d.ts.map +1 -0
  269. package/lib/typescript/src/hooks/useSplashCache.d.ts.map +1 -1
  270. package/lib/typescript/src/hooks/useThemeColors.d.ts +27 -0
  271. package/lib/typescript/src/hooks/useThemeColors.d.ts.map +1 -0
  272. package/lib/typescript/src/theme/ThemeProvider.d.ts.map +1 -1
  273. package/lib/typescript/src/theme/hook/useInternalTheme.d.ts.map +1 -1
  274. package/lib/typescript/src/theme/hook/useThemeStatusBar.d.ts.map +1 -1
  275. package/package.json +2 -2
  276. package/src/Styles/globalStyles.ts +0 -5
  277. package/src/components/Auth/AuthProvider/AuthProvider.tsx +288 -212
  278. package/src/components/Auth/ForgotPassword/ForgotPassword.tsx +11 -4
  279. package/src/components/Auth/Login/LoginWithEmail.tsx +266 -238
  280. package/src/components/Auth/Login/LoginWithPhone.tsx +18 -6
  281. package/src/components/Auth/OTP/OTP.tsx +21 -5
  282. package/src/components/Auth/QrLogin/QrLogin.tsx +225 -185
  283. package/src/components/Auth/QrLogin/components/QrViewArea.tsx +282 -166
  284. package/src/components/Auth/SignUp/SignUp.tsx +312 -293
  285. package/src/components/Auth/SplashScreen/SplashScreen.tsx +186 -131
  286. package/src/components/Auth/SplashScreen/components/SplashImage/SplashImage.tsx +32 -15
  287. package/src/components/Auth/SplashScreen/components/SplashLottie/SplashLottie.tsx +11 -5
  288. package/src/components/Auth/SplashScreen/components/SplashVideo/SplashVideo.tsx +34 -18
  289. package/src/components/BackgroundLayout/BackgroundLayout.tsx +43 -37
  290. package/src/components/BlogView/BlogView.tsx +66 -30
  291. package/src/components/Button/BackBtn.tsx +64 -34
  292. package/src/components/Button/PrimaryBtn.tsx +42 -25
  293. package/src/components/Button/SecondaryBtn.tsx +41 -25
  294. package/src/components/Button/TextButton.tsx +54 -32
  295. package/src/components/Content/Card/Category/Category.tsx +94 -56
  296. package/src/components/Content/Card/Sliders/Styles/One.tsx +63 -47
  297. package/src/components/Content/Card/Sliders/Styles/Two.tsx +131 -51
  298. package/src/components/Content/Card/Styles/RotateInOut.tsx +7 -9
  299. package/src/components/Content/Card/components/CardPoster.tsx +136 -55
  300. package/src/components/Content/Card/components/RentOrBuyIcon.tsx +58 -38
  301. package/src/components/Content/Card/components/ThumbnailCard.tsx +122 -47
  302. package/src/components/Content/Content.tsx +164 -97
  303. package/src/components/Content/Sections.tsx +99 -43
  304. package/src/components/ContentView/ContentView.tsx +194 -128
  305. package/src/components/ContentView/MoreContentList.tsx +215 -151
  306. package/src/components/ContentView/components/AboutSection.tsx +132 -93
  307. package/src/components/ContentView/components/CastCard.tsx +148 -138
  308. package/src/components/ContentView/components/EpisodeCard.tsx +160 -155
  309. package/src/components/ContentView/components/GenreTags.tsx +68 -53
  310. package/src/components/ContentView/components/HeroBanner.tsx +326 -284
  311. package/src/components/ContentView/components/MiniInfo.tsx +181 -159
  312. package/src/components/ContentView/components/PlayButton.tsx +27 -16
  313. package/src/components/ContentView/components/Title.tsx +89 -72
  314. package/src/components/ContentView/components/TrailerButton.tsx +35 -22
  315. package/src/components/Fallbacks/NoContentFallback.tsx +107 -103
  316. package/src/components/Fallbacks/NotFoundFallback.tsx +12 -4
  317. package/src/components/Headers/AppHeader.tsx +42 -26
  318. package/src/components/Headers/Three.tsx +12 -8
  319. package/src/components/Headers/Two.tsx +31 -10
  320. package/src/components/Input/InputOne.tsx +136 -108
  321. package/src/components/Loader/Loader.tsx +2 -2
  322. package/src/components/Logo/Logo.tsx +43 -27
  323. package/src/components/Search/One.tsx +2 -4
  324. package/src/components/Search/components/SearchCard.tsx +19 -13
  325. package/src/components/Settings/AppSettings.tsx +217 -128
  326. package/src/components/Subscription/SubOne.tsx +394 -317
  327. package/src/components/Text/Text.tsx +33 -22
  328. package/src/components/User/DeviceSessions/DeviceSessions.tsx +129 -102
  329. package/src/components/User/ProfileUpdate/ProfileUpdate.tsx +36 -17
  330. package/src/components/User/PurchaseHistory/PurchaseHistory.tsx +194 -140
  331. package/src/components/User/WatchHistory/WatchHistory.tsx +63 -36
  332. package/src/components/User/WatchLater/WatchLater.tsx +119 -81
  333. package/src/components/User/components/UserAvatar.tsx +49 -15
  334. package/src/components/User/components/UserSection.tsx +71 -37
  335. package/src/components/View/View.tsx +10 -2
  336. package/src/components/index.ts +0 -1
  337. package/src/hooks/index.ts +14 -0
  338. package/src/hooks/useDebounce.ts +25 -6
  339. package/src/hooks/useKeyboard.ts +12 -5
  340. package/src/hooks/useNavigationMode.ts +16 -5
  341. package/src/hooks/usePaginatedSection.ts +1 -1
  342. package/src/hooks/usePrevious.ts +28 -0
  343. package/src/hooks/useSafeCallback.ts +43 -0
  344. package/src/hooks/useSkeletonItems.ts +30 -0
  345. package/src/hooks/useSplashCache.ts +2 -1
  346. package/src/hooks/useThemeColors.ts +51 -0
  347. package/src/theme/ThemeProvider.tsx +25 -9
  348. package/src/theme/hook/useInternalTheme.ts +19 -13
  349. package/src/theme/hook/useThemeStatusBar.ts +14 -5
@@ -24,6 +24,7 @@ import CardPoster from '../components/CardPoster';
24
24
  import NavigateToMore from '../components/NavigateToMore';
25
25
 
26
26
  import { usePaginatedSection } from '../../../../hooks/usePaginatedSection';
27
+ import { useSkeletonItems } from '../../../../hooks/useSkeletonItems';
27
28
  import type {
28
29
  IGetSectionData,
29
30
  ISectionContent,
@@ -149,13 +150,11 @@ const RotateCarousel: React.FC<Props> = ({
149
150
  );
150
151
 
151
152
  // Memoized skeleton items
152
- const skeletonItems = useMemo(() => {
153
- const count = isLoading ? skeletonCount : isPaginating ? 1 : 0;
154
- return Array.from({ length: count }, (_, i) => ({
155
- _id: `skeleton-${i}`,
156
- isSkeleton: true,
157
- }));
158
- }, [isLoading, isPaginating, skeletonCount]);
153
+ const skeletonCountMemo = useMemo(
154
+ () => (isLoading ? skeletonCount : isPaginating ? 1 : 0),
155
+ [isLoading, isPaginating, skeletonCount]
156
+ );
157
+ const skeletonItems = useSkeletonItems(skeletonCountMemo);
159
158
 
160
159
  // Optimized finalData to avoid unnecessary spread
161
160
  const finalData = useMemo(
@@ -167,7 +166,6 @@ const RotateCarousel: React.FC<Props> = ({
167
166
  : data,
168
167
  [isLoading, data, skeletonItems]
169
168
  );
170
-
171
169
  // Debounced loadMoreData to prevent excessive calls
172
170
  const debouncedLoadMore = useMemo(
173
171
  () =>
@@ -297,7 +295,7 @@ const RotateCarousel: React.FC<Props> = ({
297
295
  data={finalData as any}
298
296
  vertical={false}
299
297
  renderItem={renderItem}
300
- firstItem={1}
298
+ firstItem={2}
301
299
  inactiveSlideOpacity={0.6}
302
300
  inactiveSlideScale={0.9}
303
301
  sliderWidth={width}
@@ -3,7 +3,7 @@
3
3
  * @lastModified Sat 25 Oct 2025 at 04:01 PM
4
4
  */
5
5
 
6
- import React, { useState, useEffect, useMemo } from 'react';
6
+ import React, { useState, useEffect, useMemo, useCallback } from 'react';
7
7
  import { View, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
8
8
  import FastImage, {
9
9
  type ResizeMode,
@@ -17,6 +17,9 @@ import type { ITheme } from '../../../../theme/themes';
17
17
  import RentOrBuyIcon from './RentOrBuyIcon';
18
18
  import type { IContentData } from '@zezosoft/zezo-ott-api-client';
19
19
 
20
+ // Module-level cache to track successfully loaded images
21
+ const loadedImageCache = new Set<string>();
22
+
20
23
  export type CardPosterProps = {
21
24
  content_offering_type?: IContentData['content_offering_type'];
22
25
  posterUri: string;
@@ -50,19 +53,51 @@ const CardPoster: React.FC<CardPosterProps> = ({
50
53
  );
51
54
  }, [posterUri]);
52
55
 
56
+ // Reset image loading state when isLoading prop changes
53
57
  useEffect(() => {
54
- if (hasValidPoster) {
58
+ if (isLoading) {
55
59
  setImageLoading(true);
56
60
  setImageError(false);
57
- FastImage.preload([{ uri: posterUri }]);
61
+ }
62
+ }, [isLoading]);
63
+
64
+ useEffect(() => {
65
+ if (hasValidPoster) {
66
+ // Check if this image was already loaded successfully before
67
+ const isAlreadyLoaded = loadedImageCache.has(posterUri);
68
+
69
+ if (isAlreadyLoaded) {
70
+ // Image was loaded before, skip loading state
71
+ setImageLoading(false);
72
+ setImageError(false);
73
+ } else {
74
+ // Image not loaded before, show loading
75
+ setImageLoading(true);
76
+ setImageError(false);
77
+ FastImage.preload([{ uri: posterUri }]);
78
+ }
58
79
  } else {
59
80
  setImageLoading(false);
60
81
  setImageError(true);
61
82
  }
62
83
  }, [posterUri, hasValidPoster]);
63
84
 
64
- const showSkeleton =
65
- isLoading || (imageLoading && !imageError && hasValidPoster);
85
+ const showSkeleton = useMemo(
86
+ () => isLoading || (imageLoading && !imageError && hasValidPoster),
87
+ [isLoading, imageLoading, imageError, hasValidPoster]
88
+ );
89
+
90
+ // Memoize theme colors
91
+ const themeColors = useMemo(
92
+ () => ({
93
+ background: theme.colors.background,
94
+ skeletonBaseColor: theme.colors.skeletonBaseColor,
95
+ skeletonHighlightColor: theme.colors.skeletonHighlightColor,
96
+ error: theme.colors.error,
97
+ errorContainer: theme.colors.errorContainer,
98
+ }),
99
+ [theme.colors]
100
+ );
66
101
 
67
102
  const fallbackImageStyle: ImageStyle = useMemo(
68
103
  () => ({
@@ -76,14 +111,90 @@ const CardPoster: React.FC<CardPosterProps> = ({
76
111
  [borderRadius]
77
112
  );
78
113
 
114
+ // Memoize FastImage source
115
+ const imageSource = useMemo(
116
+ () => ({
117
+ uri: posterUri,
118
+ cache: FastImage.cacheControl.immutable,
119
+ priority: FastImage.priority.normal,
120
+ }),
121
+ [posterUri]
122
+ );
123
+
124
+ // Memoize callback handlers
125
+ const handleLoadStart = useCallback(() => {
126
+ // Only set loading if image is not already in cache
127
+ if (!loadedImageCache.has(posterUri)) {
128
+ setImageLoading(true);
129
+ setImageError(false);
130
+ }
131
+ }, [posterUri]);
132
+
133
+ const handleLoad = useCallback(() => {
134
+ setImageLoading(false);
135
+ setImageError(false);
136
+ // Add to cache when successfully loaded
137
+ loadedImageCache.add(posterUri);
138
+ }, [posterUri]);
139
+
140
+ const handleError = useCallback(() => {
141
+ setImageLoading(false);
142
+ setImageError(true);
143
+ }, []);
144
+
145
+ // Memoize wrapper style
146
+ const wrapperStyle = useMemo(
147
+ () => [
148
+ styles.posterWrapper,
149
+ { borderRadius, backgroundColor: themeColors.background },
150
+ posterWrapperStyle,
151
+ ],
152
+ [borderRadius, themeColors.background, posterWrapperStyle]
153
+ );
154
+
155
+ // Memoize skeleton wrapper style
156
+ const skeletonWrapperStyle = useMemo(
157
+ () => [styles.skeletonWrapper, { borderRadius }],
158
+ [borderRadius]
159
+ );
160
+
161
+ // Memoize skeleton item style
162
+ const skeletonItemStyle = useMemo(
163
+ () => [styles.skeleton, { borderRadius }],
164
+ [borderRadius]
165
+ );
166
+
167
+ // Memoize image style array
168
+ const imageStyleArray = useMemo(
169
+ () => [
170
+ fallbackImageStyle,
171
+ showSkeleton ? styles.hidden : styles.visible,
172
+ imageStyle,
173
+ ],
174
+ [fallbackImageStyle, showSkeleton, imageStyle]
175
+ );
176
+
177
+ // Memoize fallback wrapper style
178
+ const fallbackWrapperStyle = useMemo(
179
+ () => [
180
+ styles.fallbackWrapper,
181
+ {
182
+ borderRadius,
183
+ backgroundColor: themeColors.background,
184
+ borderColor: themeColors.error,
185
+ },
186
+ ],
187
+ [borderRadius, themeColors.background, themeColors.error]
188
+ );
189
+
190
+ // Memoize fallback inner style
191
+ const fallbackInnerStyle = useMemo(
192
+ () => [styles.fallback, { backgroundColor: themeColors.errorContainer }],
193
+ [themeColors.errorContainer]
194
+ );
195
+
79
196
  return (
80
- <View
81
- style={[
82
- styles.posterWrapper,
83
- { borderRadius, backgroundColor: theme.colors.background },
84
- posterWrapperStyle,
85
- ]}
86
- >
197
+ <View style={wrapperStyle}>
87
198
  {!showSkeleton && content_offering_type && (
88
199
  <RentOrBuyIcon
89
200
  theme={theme}
@@ -92,60 +203,30 @@ const CardPoster: React.FC<CardPosterProps> = ({
92
203
  />
93
204
  )}
94
205
  {showSkeleton && (
95
- <View style={[styles.skeletonWrapper, { borderRadius }]}>
206
+ <View style={skeletonWrapperStyle}>
96
207
  <SkeletonPlaceholder
97
- backgroundColor={theme.colors.skeletonBaseColor}
98
- highlightColor={theme.colors.skeletonHighlightColor}
208
+ backgroundColor={themeColors.skeletonBaseColor}
209
+ highlightColor={themeColors.skeletonHighlightColor}
99
210
  >
100
- <SkeletonPlaceholder.Item
101
- style={[styles.skeleton, { borderRadius }]}
102
- />
211
+ <SkeletonPlaceholder.Item style={skeletonItemStyle} />
103
212
  </SkeletonPlaceholder>
104
213
  </View>
105
214
  )}
106
215
  {hasValidPoster && (
107
216
  <FastImage
108
- source={{
109
- uri: posterUri,
110
- cache: FastImage.cacheControl.immutable,
111
- priority: FastImage.priority.normal,
112
- }}
113
- style={[
114
- fallbackImageStyle,
115
- showSkeleton ? styles.hidden : styles.visible,
116
- imageStyle,
117
- ]}
217
+ source={imageSource}
218
+ style={imageStyleArray}
118
219
  resizeMode={resizeMode}
119
- onLoadStart={() => {
120
- setImageLoading(true);
121
- setImageError(false);
122
- }}
123
- onLoad={() => setImageLoading(false)}
124
- onError={() => {
125
- setImageLoading(false);
126
- setImageError(true);
127
- }}
220
+ onLoadStart={handleLoadStart}
221
+ onLoad={handleLoad}
222
+ onError={handleError}
128
223
  />
129
224
  )}
130
225
  {!showSkeleton && (!hasValidPoster || imageError) && (
131
- <View
132
- style={[
133
- styles.fallbackWrapper,
134
- {
135
- borderRadius,
136
- backgroundColor: theme.colors.background,
137
- borderColor: theme.colors.error,
138
- },
139
- ]}
140
- >
141
- <View
142
- style={[
143
- styles.fallback,
144
- { backgroundColor: theme.colors.errorContainer },
145
- ]}
146
- >
147
- <ImageOff size={scale(18)} color={theme.colors.error} />
148
- <Text style={styles.fallbackText} color={theme.colors.error}>
226
+ <View style={fallbackWrapperStyle}>
227
+ <View style={fallbackInnerStyle}>
228
+ <ImageOff size={scale(18)} color={themeColors.error} />
229
+ <Text style={styles.fallbackText} color={themeColors.error}>
149
230
  Image Failed
150
231
  </Text>
151
232
  </View>
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useMemo } from 'react';
2
2
  import { View, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
3
3
  import Svg, { Path } from 'react-native-svg';
4
4
  import { scale } from 'react-native-size-matters';
@@ -13,30 +13,34 @@ interface RentOrBuyIconProps {
13
13
  size?: number;
14
14
  }
15
15
 
16
- const PremiumIcon: React.FC<{ fillColor: string }> = ({ fillColor }) => (
17
- <Svg viewBox="0 0 1024 1024" width="100%" height="100%">
18
- <Path
19
- transform="translate(507,81)"
20
- d="M0 0l19 1 15 3 15 6 11 6 13 10 11 11 9 13 8 15 5 17 2 14v15l-3 17-5 15-7 14-9 12-9 10-15 11-16 8-10 4h-3l13 49 12 36 9 24 14 30 9 17 13 21 10 13 11 13 7 8 11 9 10 8 12 7 16 7 21 5h28l16-4 15-5 22-12 12-9 10-8 10-9 9-9 2-3h2l2-4 8-9 13-18 7-10 9-15 11-19 13-27 5-13-5-2-13-12-7-8-7-11-6-15-2-11v-22l5-19 8-15 11-13 10-9 14-8 15-5 14-2h10l14 2 15 5 12 7 11 9 9 10 8 13 5 12 3 7v37l-2 2-4 11-7 13-9 11-7 7-16 10-16 6-10 2-4 16-10 53-11 57-22 115-14 73-11 56-7 37-3 4h-719l-3-9-14-72-23-120-17-88-23-120-1-2-14-3-12-5-10-6-11-9-11-13-9-17-4-12v-35h2l2-9 8-16 4-6 9-10 10-9 15-8 17-5 19-1 15 2 15 5 15 9 13 12 10 14 5 11 4 13 1 6v18l-3 16-7 16-6 9-11 13-13 9 4 10 17 35 10 17 12 19 13 17 8 10 14 15 11 11 14 11 13 9 21 11 19 6 10 2h27l25-6 17-9 9-5 13-11 8-7 5-5 9-10 13-17 13-22 9-16 13-28 8-21 12-35 11-41 3-13-19-8-12-7-10-8-13-13-10-15-7-16-4-15-1-8v-18l3-18 6-16 8-15 9-11 7-8 13-10 12-7 16-6 15-3z"
21
- fill={fillColor}
22
- />
23
- <Path
24
- transform="translate(785,818)"
25
- d="M0 0l64 1 15 4 13 8 9 8 9 13 5 13 2 15-2 16-5 12-6 10-9 10-11 7-12 5-10 2h-672l-15-4-12-7-10-9-9-13-5-13-2-11v-9l3-15 8-16 11-12 10-7 11-5 10-2z"
26
- fill={fillColor}
27
- />
28
- </Svg>
16
+ const PremiumIcon: React.FC<{ fillColor: string }> = React.memo(
17
+ ({ fillColor }) => (
18
+ <Svg viewBox="0 0 1024 1024" width="100%" height="100%">
19
+ <Path
20
+ transform="translate(507,81)"
21
+ d="M0 0l19 1 15 3 15 6 11 6 13 10 11 11 9 13 8 15 5 17 2 14v15l-3 17-5 15-7 14-9 12-9 10-15 11-16 8-10 4h-3l13 49 12 36 9 24 14 30 9 17 13 21 10 13 11 13 7 8 11 9 10 8 12 7 16 7 21 5h28l16-4 15-5 22-12 12-9 10-8 10-9 9-9 2-3h2l2-4 8-9 13-18 7-10 9-15 11-19 13-27 5-13-5-2-13-12-7-8-7-11-6-15-2-11v-22l5-19 8-15 11-13 10-9 14-8 15-5 14-2h10l14 2 15 5 12 7 11 9 9 10 8 13 5 12 3 7v37l-2 2-4 11-7 13-9 11-7 7-16 10-16 6-10 2-4 16-10 53-11 57-22 115-14 73-11 56-7 37-3 4h-719l-3-9-14-72-23-120-17-88-23-120-1-2-14-3-12-5-10-6-11-9-11-13-9-17-4-12v-35h2l2-9 8-16 4-6 9-10 10-9 15-8 17-5 19-1 15 2 15 5 15 9 13 12 10 14 5 11 4 13 1 6v18l-3 16-7 16-6 9-11 13-13 9 4 10 17 35 10 17 12 19 13 17 8 10 14 15 11 11 14 11 13 9 21 11 19 6 10 2h27l25-6 17-9 9-5 13-11 8-7 5-5 9-10 13-17 13-22 9-16 13-28 8-21 12-35 11-41 3-13-19-8-12-7-10-8-13-13-10-15-7-16-4-15-1-8v-18l3-18 6-16 8-15 9-11 7-8 13-10 12-7 16-6 15-3z"
22
+ fill={fillColor}
23
+ />
24
+ <Path
25
+ transform="translate(785,818)"
26
+ d="M0 0l64 1 15 4 13 8 9 8 9 13 5 13 2 15-2 16-5 12-6 10-9 10-11 7-12 5-10 2h-672l-15-4-12-7-10-9-9-13-5-13-2-11v-9l3-15 8-16 11-12 10-7 11-5 10-2z"
27
+ fill={fillColor}
28
+ />
29
+ </Svg>
30
+ )
29
31
  );
30
32
 
31
- const BuyOrRentIcon: React.FC<{ fillColor: string }> = ({ fillColor }) => (
32
- <Svg fill="none" viewBox="5 5 18 18" width="100%" height="100%">
33
- <Path
34
- fill={fillColor}
35
- fillRule="evenodd"
36
- clipRule="evenodd"
37
- d="M9.834 9.835H11.2c0-.108-.002-.215-.003-.319-.014-1.424-.024-2.412 2.734-2.412 2.504 0 2.732.453 2.732 2.73l1.365.001c0-3.871-.91-4.099-4.097-4.099h-.21c-3.225-.002-3.709-.002-3.887 4.1zm-.153-.001H7.712a1.976 1.976 0 00-1.976 1.976v6.064a4.252 4.252 0 004.252 4.252h7.886a4.252 4.252 0 004.252-4.252V11.81a1.976 1.976 0 00-1.976-1.976H18.18a.153.153 0 00-.153.153v3.716a.683.683 0 01-1.365 0V9.987a.153.153 0 00-.153-.153h-5.158a.153.153 0 00-.152.153v3.716a.683.683 0 01-1.366 0V9.987a.153.153 0 00-.153-.153z"
38
- />
39
- </Svg>
33
+ const BuyOrRentIcon: React.FC<{ fillColor: string }> = React.memo(
34
+ ({ fillColor }) => (
35
+ <Svg fill="none" viewBox="5 5 18 18" width="100%" height="100%">
36
+ <Path
37
+ fill={fillColor}
38
+ fillRule="evenodd"
39
+ clipRule="evenodd"
40
+ d="M9.834 9.835H11.2c0-.108-.002-.215-.003-.319-.014-1.424-.024-2.412 2.734-2.412 2.504 0 2.732.453 2.732 2.73l1.365.001c0-3.871-.91-4.099-4.097-4.099h-.21c-3.225-.002-3.709-.002-3.887 4.1zm-.153-.001H7.712a1.976 1.976 0 00-1.976 1.976v6.064a4.252 4.252 0 004.252 4.252h7.886a4.252 4.252 0 004.252-4.252V11.81a1.976 1.976 0 00-1.976-1.976H18.18a.153.153 0 00-.153.153v3.716a.683.683 0 01-1.365 0V9.987a.153.153 0 00-.153-.153h-5.158a.153.153 0 00-.152.153v3.716a.683.683 0 01-1.366 0V9.987a.153.153 0 00-.153-.153z"
41
+ />
42
+ </Svg>
43
+ )
40
44
  );
41
45
 
42
46
  const RentOrBuyIcon: React.FC<RentOrBuyIconProps> = ({
@@ -46,14 +50,22 @@ const RentOrBuyIcon: React.FC<RentOrBuyIconProps> = ({
46
50
  position = 'topLeft',
47
51
  size = 22,
48
52
  }) => {
49
- if (!content_offering_type) return null;
53
+ const typeUpper = useMemo(
54
+ () => content_offering_type?.toUpperCase(),
55
+ [content_offering_type]
56
+ );
50
57
 
51
- const typeUpper = content_offering_type.toUpperCase();
52
- if (!['PREMIUM', 'BUY_OR_RENT'].includes(typeUpper)) return null;
58
+ const isValidType = useMemo(
59
+ () => typeUpper && ['PREMIUM', 'BUY_OR_RENT'].includes(typeUpper),
60
+ [typeUpper]
61
+ );
53
62
 
54
- const fillColor = theme?.colors.premiumIcon || '#CA091E';
63
+ const fillColor = useMemo(
64
+ () => theme?.colors.premiumIcon || '#CA091E',
65
+ [theme?.colors.premiumIcon]
66
+ );
55
67
 
56
- const positionStyle: ViewStyle = (() => {
68
+ const positionStyle = useMemo<ViewStyle>(() => {
57
69
  switch (position) {
58
70
  case 'topLeft':
59
71
  return { top: 6, left: 6 };
@@ -66,18 +78,26 @@ const RentOrBuyIcon: React.FC<RentOrBuyIconProps> = ({
66
78
  default:
67
79
  return { top: 6, left: 6 };
68
80
  }
69
- })();
81
+ }, [position]);
82
+
83
+ const IconComponent = useMemo(
84
+ () => (typeUpper === 'PREMIUM' ? PremiumIcon : BuyOrRentIcon),
85
+ [typeUpper]
86
+ );
87
+
88
+ const containerStyle = useMemo(
89
+ () => [
90
+ styles.container,
91
+ { width: size, height: size },
92
+ style || positionStyle,
93
+ ],
94
+ [size, style, positionStyle]
95
+ );
70
96
 
71
- const IconComponent = typeUpper === 'PREMIUM' ? PremiumIcon : BuyOrRentIcon;
97
+ if (!content_offering_type || !isValidType) return null;
72
98
 
73
99
  return (
74
- <View
75
- style={[
76
- styles.container,
77
- { width: size, height: size },
78
- style || positionStyle,
79
- ]}
80
- >
100
+ <View style={containerStyle}>
81
101
  <View style={styles.iconWrapper}>
82
102
  <IconComponent fillColor={fillColor} />
83
103
  </View>
@@ -85,7 +105,7 @@ const RentOrBuyIcon: React.FC<RentOrBuyIconProps> = ({
85
105
  );
86
106
  };
87
107
 
88
- export default RentOrBuyIcon;
108
+ export default React.memo(RentOrBuyIcon);
89
109
 
90
110
  const styles = StyleSheet.create({
91
111
  container: {
@@ -3,7 +3,7 @@
3
3
  * @lastModified Wed 25 Jun 2025 at 05:40 PM
4
4
  */
5
5
 
6
- import React, { useState } from 'react';
6
+ import React, { useState, useEffect, useMemo, useCallback } from 'react';
7
7
  import { View, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
8
8
  import type {
9
9
  ImageStyle as FastImageStyle,
@@ -17,6 +17,9 @@ import { ImageOff } from 'lucide-react-native';
17
17
  import type { ITheme } from '../../../../theme/themes';
18
18
  import { RFValue } from 'react-native-responsive-fontsize';
19
19
 
20
+ // Module-level cache to track successfully loaded images
21
+ const loadedImageCache = new Set<string>();
22
+
20
23
  export type ThumbnailCardProps = {
21
24
  thumbnailUri?: string;
22
25
  theme: ITheme;
@@ -39,32 +42,121 @@ export const ThumbnailCard: React.FC<ThumbnailCardProps> = ({
39
42
  const [imageLoading, setImageLoading] = useState(true);
40
43
  const [imageError, setImageError] = useState(false);
41
44
 
42
- const hasValidThumbnail = !!thumbnailUri && thumbnailUri.startsWith('http');
43
- const showSkeleton = isLoading || (imageLoading && !imageError);
45
+ const hasValidThumbnail = useMemo(
46
+ () => !!thumbnailUri && thumbnailUri.startsWith('http'),
47
+ [thumbnailUri]
48
+ );
44
49
 
45
- const fallbackImageStyle: FastImageStyle = {
46
- width: '100%',
47
- aspectRatio: 16 / 9,
48
- borderRadius,
49
- position: 'absolute',
50
- top: 0,
51
- left: 0,
52
- };
50
+ // Reset image loading state when isLoading prop changes
51
+ useEffect(() => {
52
+ if (isLoading) {
53
+ setImageLoading(true);
54
+ setImageError(false);
55
+ }
56
+ }, [isLoading]);
57
+
58
+ // Reset when thumbnailUri changes
59
+ useEffect(() => {
60
+ if (hasValidThumbnail) {
61
+ // Check if this image was already loaded successfully before
62
+ const isAlreadyLoaded = loadedImageCache.has(thumbnailUri);
63
+
64
+ if (isAlreadyLoaded) {
65
+ // Image was loaded before, skip loading state
66
+ setImageLoading(false);
67
+ setImageError(false);
68
+ } else {
69
+ // Image not loaded before, show loading
70
+ setImageLoading(true);
71
+ setImageError(false);
72
+ FastImage.preload([{ uri: thumbnailUri }]);
73
+ }
74
+ } else {
75
+ setImageLoading(false);
76
+ setImageError(true);
77
+ }
78
+ }, [thumbnailUri, hasValidThumbnail]);
79
+
80
+ const showSkeleton = useMemo(
81
+ () => isLoading || (imageLoading && !imageError && hasValidThumbnail),
82
+ [isLoading, imageLoading, imageError, hasValidThumbnail]
83
+ );
84
+
85
+ const fallbackImageStyle = useMemo<FastImageStyle>(
86
+ () => ({
87
+ width: '100%',
88
+ aspectRatio: 16 / 9,
89
+ borderRadius,
90
+ position: 'absolute',
91
+ top: 0,
92
+ left: 0,
93
+ }),
94
+ [borderRadius]
95
+ );
96
+
97
+ const wrapperStyleMemo = useMemo(
98
+ () => [
99
+ styles.thumbnailWrapper,
100
+ {
101
+ borderRadius,
102
+ backgroundColor: theme.colors.background,
103
+ shadowColor: theme.colors.shadow,
104
+ },
105
+ wrapperStyle,
106
+ ],
107
+ [borderRadius, theme.colors.background, theme.colors.shadow, wrapperStyle]
108
+ );
109
+
110
+ const skeletonWrapperStyle = useMemo(
111
+ () => [styles.skeletonWrapper, { borderRadius }],
112
+ [borderRadius]
113
+ );
114
+
115
+ const imageStyleMemo = useMemo(
116
+ () => [
117
+ fallbackImageStyle,
118
+ showSkeleton ? styles.hidden : styles.visible,
119
+ imageStyle,
120
+ ],
121
+ [fallbackImageStyle, showSkeleton, imageStyle]
122
+ );
123
+
124
+ const fallbackStyle = useMemo(
125
+ () => [
126
+ styles.fallback,
127
+ {
128
+ borderRadius,
129
+ backgroundColor: theme.colors.errorContainer,
130
+ borderColor: theme.colors.error,
131
+ },
132
+ ],
133
+ [borderRadius, theme.colors.errorContainer, theme.colors.error]
134
+ );
135
+
136
+ const handleLoadStart = useCallback(() => {
137
+ // Only set loading if image is not already in cache
138
+ if (!loadedImageCache.has(thumbnailUri)) {
139
+ setImageLoading(true);
140
+ setImageError(false);
141
+ }
142
+ }, [thumbnailUri]);
143
+
144
+ const handleLoadEnd = useCallback(() => {
145
+ setImageLoading(false);
146
+ setImageError(false);
147
+ // Add to cache when successfully loaded
148
+ loadedImageCache.add(thumbnailUri);
149
+ }, [thumbnailUri]);
150
+
151
+ const handleError = useCallback(() => {
152
+ setImageLoading(false);
153
+ setImageError(true);
154
+ }, []);
53
155
 
54
156
  return (
55
- <View
56
- style={[
57
- styles.thumbnailWrapper,
58
- {
59
- borderRadius,
60
- backgroundColor: theme.colors.background,
61
- shadowColor: theme.colors.shadow,
62
- },
63
- wrapperStyle,
64
- ]}
65
- >
157
+ <View style={wrapperStyleMemo}>
66
158
  {showSkeleton && (
67
- <View style={[styles.skeletonWrapper, { borderRadius }]}>
159
+ <View style={skeletonWrapperStyle}>
68
160
  <SkeletonPlaceholder
69
161
  backgroundColor={theme.colors.skeletonBaseColor}
70
162
  highlightColor={theme.colors.skeletonHighlightColor}
@@ -79,35 +171,16 @@ export const ThumbnailCard: React.FC<ThumbnailCardProps> = ({
79
171
  {hasValidThumbnail && (
80
172
  <FastImage
81
173
  source={{ uri: thumbnailUri }}
82
- style={[
83
- fallbackImageStyle,
84
- showSkeleton ? styles.hidden : styles.visible,
85
- imageStyle,
86
- ]}
174
+ style={imageStyleMemo}
87
175
  resizeMode={resizeMode}
88
- onLoadStart={() => {
89
- setImageLoading(true);
90
- setImageError(false);
91
- }}
92
- onLoadEnd={() => setImageLoading(false)}
93
- onError={() => {
94
- setImageLoading(false);
95
- setImageError(true);
96
- }}
176
+ onLoadStart={handleLoadStart}
177
+ onLoadEnd={handleLoadEnd}
178
+ onError={handleError}
97
179
  />
98
180
  )}
99
181
 
100
182
  {!showSkeleton && (!hasValidThumbnail || imageError) && (
101
- <View
102
- style={[
103
- styles.fallback,
104
- {
105
- borderRadius,
106
- backgroundColor: theme.colors.errorContainer,
107
- borderColor: theme.colors.error,
108
- },
109
- ]}
110
- >
183
+ <View style={fallbackStyle}>
111
184
  <ImageOff size={scale(18)} color={theme.colors.error} />
112
185
  <Text style={styles.fallbackText} color={theme.colors.error}>
113
186
  Image Failed
@@ -118,6 +191,8 @@ export const ThumbnailCard: React.FC<ThumbnailCardProps> = ({
118
191
  );
119
192
  };
120
193
 
194
+ export default React.memo(ThumbnailCard);
195
+
121
196
  const styles = StyleSheet.create({
122
197
  thumbnailWrapper: {
123
198
  width: '100%',