@oxyhq/services 5.4.2 → 5.4.3

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 (359) hide show
  1. package/lib/commonjs/assets/OxyLogo.svg +1 -0
  2. package/lib/commonjs/assets/assets/OxyLogo.svg +1 -0
  3. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Black.ttf +0 -0
  4. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Bold.ttf +0 -0
  5. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-ExtraBold.ttf +0 -0
  6. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Light.ttf +0 -0
  7. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Medium.ttf +0 -0
  8. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Regular.ttf +0 -0
  9. package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-SemiBold.ttf +0 -0
  10. package/lib/commonjs/assets/assets/icons/OxyServices.tsx +67 -0
  11. package/lib/commonjs/assets/assets/icons/logo_OxyServices.svg +1 -0
  12. package/lib/commonjs/assets/fonts/Phudu/Phudu-Black.ttf +0 -0
  13. package/lib/commonjs/assets/fonts/Phudu/Phudu-Bold.ttf +0 -0
  14. package/lib/commonjs/assets/fonts/Phudu/Phudu-ExtraBold.ttf +0 -0
  15. package/lib/commonjs/assets/fonts/Phudu/Phudu-Light.ttf +0 -0
  16. package/lib/commonjs/assets/fonts/Phudu/Phudu-Medium.ttf +0 -0
  17. package/lib/commonjs/assets/fonts/Phudu/Phudu-Regular.ttf +0 -0
  18. package/lib/commonjs/assets/fonts/Phudu/Phudu-SemiBold.ttf +0 -0
  19. package/lib/commonjs/assets/icons/OxyServices.js +53 -0
  20. package/lib/commonjs/assets/icons/OxyServices.js.map +1 -0
  21. package/lib/commonjs/assets/icons/logo_OxyServices.svg +1 -0
  22. package/lib/commonjs/constants/version.js +28 -0
  23. package/lib/commonjs/constants/version.js.map +1 -0
  24. package/lib/commonjs/core/index.js +1660 -0
  25. package/lib/commonjs/core/index.js.map +1 -0
  26. package/lib/commonjs/index.js +160 -0
  27. package/lib/commonjs/index.js.map +1 -0
  28. package/lib/commonjs/lib/sonner.js +21 -0
  29. package/lib/commonjs/lib/sonner.js.map +1 -0
  30. package/lib/commonjs/models/interfaces.js +2 -0
  31. package/lib/commonjs/models/interfaces.js.map +1 -0
  32. package/lib/commonjs/models/secureSession.js +2 -0
  33. package/lib/commonjs/models/secureSession.js.map +1 -0
  34. package/lib/commonjs/node/index.js +54 -0
  35. package/lib/commonjs/node/index.js.map +1 -0
  36. package/lib/commonjs/ui/components/Avatar.js +98 -0
  37. package/lib/commonjs/ui/components/Avatar.js.map +1 -0
  38. package/lib/commonjs/ui/components/FollowButton.js +246 -0
  39. package/lib/commonjs/ui/components/FollowButton.js.map +1 -0
  40. package/lib/commonjs/ui/components/FontLoader.js +181 -0
  41. package/lib/commonjs/ui/components/FontLoader.js.map +1 -0
  42. package/lib/commonjs/ui/components/GroupedItem.js +109 -0
  43. package/lib/commonjs/ui/components/GroupedItem.js.map +1 -0
  44. package/lib/commonjs/ui/components/GroupedSection.js +33 -0
  45. package/lib/commonjs/ui/components/GroupedSection.js.map +1 -0
  46. package/lib/commonjs/ui/components/OxyLogo.js +56 -0
  47. package/lib/commonjs/ui/components/OxyLogo.js.map +1 -0
  48. package/lib/commonjs/ui/components/OxyProvider.js +517 -0
  49. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -0
  50. package/lib/commonjs/ui/components/OxySignInButton.js +178 -0
  51. package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -0
  52. package/lib/commonjs/ui/components/ProfileCard.js +124 -0
  53. package/lib/commonjs/ui/components/ProfileCard.js.map +1 -0
  54. package/lib/commonjs/ui/components/QuickActions.js +87 -0
  55. package/lib/commonjs/ui/components/QuickActions.js.map +1 -0
  56. package/lib/commonjs/ui/components/Section.js +36 -0
  57. package/lib/commonjs/ui/components/Section.js.map +1 -0
  58. package/lib/commonjs/ui/components/SectionTitle.js +35 -0
  59. package/lib/commonjs/ui/components/SectionTitle.js.map +1 -0
  60. package/lib/commonjs/ui/components/bottomSheet/index.js +37 -0
  61. package/lib/commonjs/ui/components/bottomSheet/index.js.map +1 -0
  62. package/lib/commonjs/ui/components/icon/OxyIcon.js +27 -0
  63. package/lib/commonjs/ui/components/icon/OxyIcon.js.map +1 -0
  64. package/lib/commonjs/ui/components/icon/index.js +14 -0
  65. package/lib/commonjs/ui/components/icon/index.js.map +1 -0
  66. package/lib/commonjs/ui/components/index.js +97 -0
  67. package/lib/commonjs/ui/components/index.js.map +1 -0
  68. package/lib/commonjs/ui/context/OxyContext.js +584 -0
  69. package/lib/commonjs/ui/context/OxyContext.js.map +1 -0
  70. package/lib/commonjs/ui/index.js +128 -0
  71. package/lib/commonjs/ui/index.js.map +1 -0
  72. package/lib/commonjs/ui/navigation/OxyRouter.js +264 -0
  73. package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -0
  74. package/lib/commonjs/ui/navigation/types.js +6 -0
  75. package/lib/commonjs/ui/navigation/types.js.map +1 -0
  76. package/lib/commonjs/ui/screens/AccountCenterScreen.js +313 -0
  77. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -0
  78. package/lib/commonjs/ui/screens/AccountManagementDemo.js +299 -0
  79. package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -0
  80. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +855 -0
  81. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -0
  82. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +843 -0
  83. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -0
  84. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +788 -0
  85. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -0
  86. package/lib/commonjs/ui/screens/AppInfoScreen.js +664 -0
  87. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -0
  88. package/lib/commonjs/ui/screens/BillingManagementScreen.js +636 -0
  89. package/lib/commonjs/ui/screens/BillingManagementScreen.js.map +1 -0
  90. package/lib/commonjs/ui/screens/FileManagementScreen.js +2515 -0
  91. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -0
  92. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +1620 -0
  93. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -0
  94. package/lib/commonjs/ui/screens/ProfileScreen.js +450 -0
  95. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -0
  96. package/lib/commonjs/ui/screens/SessionManagementScreen.js +449 -0
  97. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -0
  98. package/lib/commonjs/ui/screens/SignInScreen.js +1004 -0
  99. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -0
  100. package/lib/commonjs/ui/screens/SignUpScreen.js +937 -0
  101. package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -0
  102. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +88 -0
  103. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -0
  104. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +364 -0
  105. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -0
  106. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +227 -0
  107. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -0
  108. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +148 -0
  109. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -0
  110. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +127 -0
  111. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -0
  112. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +105 -0
  113. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -0
  114. package/lib/commonjs/ui/styles/FONTS.md +126 -0
  115. package/lib/commonjs/ui/styles/fonts.js +84 -0
  116. package/lib/commonjs/ui/styles/fonts.js.map +1 -0
  117. package/lib/commonjs/ui/styles/index.js +28 -0
  118. package/lib/commonjs/ui/styles/index.js.map +1 -0
  119. package/lib/commonjs/ui/styles/theme.js +121 -0
  120. package/lib/commonjs/ui/styles/theme.js.map +1 -0
  121. package/lib/commonjs/utils/deviceManager.js +173 -0
  122. package/lib/commonjs/utils/deviceManager.js.map +1 -0
  123. package/lib/commonjs/utils/index.js +13 -0
  124. package/lib/commonjs/utils/index.js.map +1 -0
  125. package/lib/commonjs/utils/polyfills.js +42 -0
  126. package/lib/commonjs/utils/polyfills.js.map +1 -0
  127. package/lib/module/assets/OxyLogo.svg +1 -0
  128. package/lib/module/assets/assets/OxyLogo.svg +1 -0
  129. package/lib/module/assets/assets/fonts/Phudu/Phudu-Black.ttf +0 -0
  130. package/lib/module/assets/assets/fonts/Phudu/Phudu-Bold.ttf +0 -0
  131. package/lib/module/assets/assets/fonts/Phudu/Phudu-ExtraBold.ttf +0 -0
  132. package/lib/module/assets/assets/fonts/Phudu/Phudu-Light.ttf +0 -0
  133. package/lib/module/assets/assets/fonts/Phudu/Phudu-Medium.ttf +0 -0
  134. package/lib/module/assets/assets/fonts/Phudu/Phudu-Regular.ttf +0 -0
  135. package/lib/module/assets/assets/fonts/Phudu/Phudu-SemiBold.ttf +0 -0
  136. package/lib/module/assets/assets/icons/OxyServices.tsx +67 -0
  137. package/lib/module/assets/assets/icons/logo_OxyServices.svg +1 -0
  138. package/lib/module/assets/fonts/Phudu/Phudu-Black.ttf +0 -0
  139. package/lib/module/assets/fonts/Phudu/Phudu-Bold.ttf +0 -0
  140. package/lib/module/assets/fonts/Phudu/Phudu-ExtraBold.ttf +0 -0
  141. package/lib/module/assets/fonts/Phudu/Phudu-Light.ttf +0 -0
  142. package/lib/module/assets/fonts/Phudu/Phudu-Medium.ttf +0 -0
  143. package/lib/module/assets/fonts/Phudu/Phudu-Regular.ttf +0 -0
  144. package/lib/module/assets/fonts/Phudu/Phudu-SemiBold.ttf +0 -0
  145. package/lib/module/assets/icons/OxyServices.js +46 -0
  146. package/lib/module/assets/icons/OxyServices.js.map +1 -0
  147. package/lib/module/assets/icons/logo_OxyServices.svg +1 -0
  148. package/lib/module/constants/version.js +21 -0
  149. package/lib/module/constants/version.js.map +1 -0
  150. package/lib/module/core/index.js +1634 -0
  151. package/lib/module/core/index.js.map +1 -0
  152. package/lib/module/index.js +48 -0
  153. package/lib/module/index.js.map +1 -0
  154. package/lib/module/lib/sonner.js +16 -0
  155. package/lib/module/lib/sonner.js.map +1 -0
  156. package/lib/module/models/interfaces.js +2 -0
  157. package/lib/module/models/interfaces.js.map +1 -0
  158. package/lib/module/models/secureSession.js +2 -0
  159. package/lib/module/models/secureSession.js.map +1 -0
  160. package/lib/module/node/index.js +23 -0
  161. package/lib/module/node/index.js.map +1 -0
  162. package/lib/module/ui/components/Avatar.js +93 -0
  163. package/lib/module/ui/components/Avatar.js.map +1 -0
  164. package/lib/module/ui/components/FollowButton.js +241 -0
  165. package/lib/module/ui/components/FollowButton.js.map +1 -0
  166. package/lib/module/ui/components/FontLoader.js +176 -0
  167. package/lib/module/ui/components/FontLoader.js.map +1 -0
  168. package/lib/module/ui/components/GroupedItem.js +104 -0
  169. package/lib/module/ui/components/GroupedItem.js.map +1 -0
  170. package/lib/module/ui/components/GroupedSection.js +28 -0
  171. package/lib/module/ui/components/GroupedSection.js.map +1 -0
  172. package/lib/module/ui/components/OxyLogo.js +49 -0
  173. package/lib/module/ui/components/OxyLogo.js.map +1 -0
  174. package/lib/module/ui/components/OxyProvider.js +511 -0
  175. package/lib/module/ui/components/OxyProvider.js.map +1 -0
  176. package/lib/module/ui/components/OxySignInButton.js +172 -0
  177. package/lib/module/ui/components/OxySignInButton.js.map +1 -0
  178. package/lib/module/ui/components/ProfileCard.js +119 -0
  179. package/lib/module/ui/components/ProfileCard.js.map +1 -0
  180. package/lib/module/ui/components/QuickActions.js +82 -0
  181. package/lib/module/ui/components/QuickActions.js.map +1 -0
  182. package/lib/module/ui/components/Section.js +31 -0
  183. package/lib/module/ui/components/Section.js.map +1 -0
  184. package/lib/module/ui/components/SectionTitle.js +30 -0
  185. package/lib/module/ui/components/SectionTitle.js.map +1 -0
  186. package/lib/module/ui/components/bottomSheet/index.js +5 -0
  187. package/lib/module/ui/components/bottomSheet/index.js.map +1 -0
  188. package/lib/module/ui/components/icon/OxyIcon.js +22 -0
  189. package/lib/module/ui/components/icon/OxyIcon.js.map +1 -0
  190. package/lib/module/ui/components/icon/index.js +4 -0
  191. package/lib/module/ui/components/icon/index.js.map +1 -0
  192. package/lib/module/ui/components/index.js +18 -0
  193. package/lib/module/ui/components/index.js.map +1 -0
  194. package/lib/module/ui/context/OxyContext.js +579 -0
  195. package/lib/module/ui/context/OxyContext.js.map +1 -0
  196. package/lib/module/ui/index.js +24 -0
  197. package/lib/module/ui/index.js.map +1 -0
  198. package/lib/module/ui/navigation/OxyRouter.js +257 -0
  199. package/lib/module/ui/navigation/OxyRouter.js.map +1 -0
  200. package/lib/module/ui/navigation/types.js +4 -0
  201. package/lib/module/ui/navigation/types.js.map +1 -0
  202. package/lib/module/ui/screens/AccountCenterScreen.js +308 -0
  203. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -0
  204. package/lib/module/ui/screens/AccountManagementDemo.js +296 -0
  205. package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -0
  206. package/lib/module/ui/screens/AccountOverviewScreen.js +849 -0
  207. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -0
  208. package/lib/module/ui/screens/AccountSettingsScreen.js +837 -0
  209. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -0
  210. package/lib/module/ui/screens/AccountSwitcherScreen.js +782 -0
  211. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -0
  212. package/lib/module/ui/screens/AppInfoScreen.js +658 -0
  213. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -0
  214. package/lib/module/ui/screens/BillingManagementScreen.js +631 -0
  215. package/lib/module/ui/screens/BillingManagementScreen.js.map +1 -0
  216. package/lib/module/ui/screens/FileManagementScreen.js +2510 -0
  217. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -0
  218. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +1615 -0
  219. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -0
  220. package/lib/module/ui/screens/ProfileScreen.js +444 -0
  221. package/lib/module/ui/screens/ProfileScreen.js.map +1 -0
  222. package/lib/module/ui/screens/SessionManagementScreen.js +444 -0
  223. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -0
  224. package/lib/module/ui/screens/SignInScreen.js +998 -0
  225. package/lib/module/ui/screens/SignInScreen.js.map +1 -0
  226. package/lib/module/ui/screens/SignUpScreen.js +932 -0
  227. package/lib/module/ui/screens/SignUpScreen.js.map +1 -0
  228. package/lib/module/ui/screens/karma/KarmaAboutScreen.js +83 -0
  229. package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -0
  230. package/lib/module/ui/screens/karma/KarmaCenterScreen.js +358 -0
  231. package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -0
  232. package/lib/module/ui/screens/karma/KarmaFAQScreen.js +222 -0
  233. package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -0
  234. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +142 -0
  235. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -0
  236. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +122 -0
  237. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -0
  238. package/lib/module/ui/screens/karma/KarmaRulesScreen.js +100 -0
  239. package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -0
  240. package/lib/module/ui/styles/FONTS.md +126 -0
  241. package/lib/module/ui/styles/fonts.js +81 -0
  242. package/lib/module/ui/styles/fonts.js.map +1 -0
  243. package/lib/module/ui/styles/index.js +5 -0
  244. package/lib/module/ui/styles/index.js.map +1 -0
  245. package/lib/module/ui/styles/theme.js +114 -0
  246. package/lib/module/ui/styles/theme.js.map +1 -0
  247. package/lib/module/utils/deviceManager.js +167 -0
  248. package/lib/module/utils/deviceManager.js.map +1 -0
  249. package/lib/module/utils/index.js +4 -0
  250. package/lib/module/utils/index.js.map +1 -0
  251. package/lib/module/utils/polyfills.js +36 -0
  252. package/lib/module/utils/polyfills.js.map +1 -0
  253. package/lib/typescript/assets/icons/OxyServices.d.ts +29 -0
  254. package/lib/typescript/assets/icons/OxyServices.d.ts.map +1 -0
  255. package/lib/typescript/constants/version.d.ts +14 -0
  256. package/lib/typescript/constants/version.d.ts.map +1 -0
  257. package/lib/typescript/core/index.d.ts +603 -0
  258. package/lib/typescript/core/index.d.ts.map +1 -0
  259. package/lib/typescript/index.d.ts +20 -0
  260. package/lib/typescript/index.d.ts.map +1 -0
  261. package/lib/typescript/lib/sonner.d.ts +6 -0
  262. package/lib/typescript/lib/sonner.d.ts.map +1 -0
  263. package/lib/typescript/models/interfaces.d.ts +179 -0
  264. package/lib/typescript/models/interfaces.d.ts.map +1 -0
  265. package/lib/typescript/models/secureSession.d.ts +27 -0
  266. package/lib/typescript/models/secureSession.d.ts.map +1 -0
  267. package/lib/typescript/node/index.d.ts +11 -0
  268. package/lib/typescript/node/index.d.ts.map +1 -0
  269. package/lib/typescript/ui/components/Avatar.d.ts +62 -0
  270. package/lib/typescript/ui/components/Avatar.d.ts.map +1 -0
  271. package/lib/typescript/ui/components/FollowButton.d.ts +92 -0
  272. package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -0
  273. package/lib/typescript/ui/components/FontLoader.d.ts +15 -0
  274. package/lib/typescript/ui/components/FontLoader.d.ts.map +1 -0
  275. package/lib/typescript/ui/components/GroupedItem.d.ts +17 -0
  276. package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -0
  277. package/lib/typescript/ui/components/GroupedSection.d.ts +19 -0
  278. package/lib/typescript/ui/components/GroupedSection.d.ts.map +1 -0
  279. package/lib/typescript/ui/components/OxyLogo.d.ts +29 -0
  280. package/lib/typescript/ui/components/OxyLogo.d.ts.map +1 -0
  281. package/lib/typescript/ui/components/OxyProvider.d.ts +12 -0
  282. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -0
  283. package/lib/typescript/ui/components/OxySignInButton.d.ts +70 -0
  284. package/lib/typescript/ui/components/OxySignInButton.d.ts.map +1 -0
  285. package/lib/typescript/ui/components/ProfileCard.d.ts +20 -0
  286. package/lib/typescript/ui/components/ProfileCard.d.ts.map +1 -0
  287. package/lib/typescript/ui/components/QuickActions.d.ts +15 -0
  288. package/lib/typescript/ui/components/QuickActions.d.ts.map +1 -0
  289. package/lib/typescript/ui/components/Section.d.ts +11 -0
  290. package/lib/typescript/ui/components/Section.d.ts.map +1 -0
  291. package/lib/typescript/ui/components/SectionTitle.d.ts +9 -0
  292. package/lib/typescript/ui/components/SectionTitle.d.ts.map +1 -0
  293. package/lib/typescript/ui/components/bottomSheet/index.d.ts +4 -0
  294. package/lib/typescript/ui/components/bottomSheet/index.d.ts.map +1 -0
  295. package/lib/typescript/ui/components/icon/OxyIcon.d.ts +10 -0
  296. package/lib/typescript/ui/components/icon/OxyIcon.d.ts.map +1 -0
  297. package/lib/typescript/ui/components/icon/index.d.ts +3 -0
  298. package/lib/typescript/ui/components/icon/index.d.ts.map +1 -0
  299. package/lib/typescript/ui/components/index.d.ts +13 -0
  300. package/lib/typescript/ui/components/index.d.ts.map +1 -0
  301. package/lib/typescript/ui/context/OxyContext.d.ts +42 -0
  302. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -0
  303. package/lib/typescript/ui/index.d.ts +15 -0
  304. package/lib/typescript/ui/index.d.ts.map +1 -0
  305. package/lib/typescript/ui/navigation/OxyRouter.d.ts +5 -0
  306. package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -0
  307. package/lib/typescript/ui/navigation/types.d.ts +116 -0
  308. package/lib/typescript/ui/navigation/types.d.ts.map +1 -0
  309. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts +5 -0
  310. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -0
  311. package/lib/typescript/ui/screens/AccountManagementDemo.d.ts +8 -0
  312. package/lib/typescript/ui/screens/AccountManagementDemo.d.ts.map +1 -0
  313. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts +5 -0
  314. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -0
  315. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts +5 -0
  316. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -0
  317. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts +5 -0
  318. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -0
  319. package/lib/typescript/ui/screens/AppInfoScreen.d.ts +5 -0
  320. package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -0
  321. package/lib/typescript/ui/screens/BillingManagementScreen.d.ts +5 -0
  322. package/lib/typescript/ui/screens/BillingManagementScreen.d.ts.map +1 -0
  323. package/lib/typescript/ui/screens/FileManagementScreen.d.ts +8 -0
  324. package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -0
  325. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts +5 -0
  326. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -0
  327. package/lib/typescript/ui/screens/ProfileScreen.d.ts +9 -0
  328. package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -0
  329. package/lib/typescript/ui/screens/SessionManagementScreen.d.ts +5 -0
  330. package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -0
  331. package/lib/typescript/ui/screens/SignInScreen.d.ts +5 -0
  332. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -0
  333. package/lib/typescript/ui/screens/SignUpScreen.d.ts +5 -0
  334. package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -0
  335. package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts +5 -0
  336. package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts.map +1 -0
  337. package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts +5 -0
  338. package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts.map +1 -0
  339. package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts +5 -0
  340. package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts.map +1 -0
  341. package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts +5 -0
  342. package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts.map +1 -0
  343. package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts +5 -0
  344. package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts.map +1 -0
  345. package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts +5 -0
  346. package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts.map +1 -0
  347. package/lib/typescript/ui/styles/fonts.d.ts +21 -0
  348. package/lib/typescript/ui/styles/fonts.d.ts.map +1 -0
  349. package/lib/typescript/ui/styles/index.d.ts +3 -0
  350. package/lib/typescript/ui/styles/index.d.ts.map +1 -0
  351. package/lib/typescript/ui/styles/theme.d.ts +68 -0
  352. package/lib/typescript/ui/styles/theme.d.ts.map +1 -0
  353. package/lib/typescript/utils/deviceManager.d.ts +66 -0
  354. package/lib/typescript/utils/deviceManager.d.ts.map +1 -0
  355. package/lib/typescript/utils/index.d.ts +3 -0
  356. package/lib/typescript/utils/index.d.ts.map +1 -0
  357. package/lib/typescript/utils/polyfills.d.ts +6 -0
  358. package/lib/typescript/utils/polyfills.d.ts.map +1 -0
  359. package/package.json +20 -4
@@ -0,0 +1,2510 @@
1
+ "use strict";
2
+
3
+ import React, { useState, useEffect, useCallback, useMemo } from 'react';
4
+ import { View, Text, TouchableOpacity, StyleSheet, ScrollView, ActivityIndicator, Platform, RefreshControl, Modal, TextInput, Image } from 'react-native';
5
+ import { useOxy } from "../context/OxyContext.js";
6
+ import { fontFamilies } from "../styles/fonts.js";
7
+ import { toast } from "../../lib/sonner.js";
8
+ import { Ionicons } from '@expo/vector-icons';
9
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
10
+ const FileManagementScreen = ({
11
+ onClose,
12
+ theme,
13
+ goBack,
14
+ navigate,
15
+ userId,
16
+ containerWidth = 400 // Fallback for when not provided by the router
17
+ }) => {
18
+ const {
19
+ user,
20
+ oxyServices
21
+ } = useOxy();
22
+
23
+ // Debug: log the actual container width
24
+ useEffect(() => {
25
+ console.log('[FileManagementScreen] Container width (full):', containerWidth);
26
+ // Padding structure:
27
+ // - containerWidth = full bottom sheet container width (measured from OxyProvider)
28
+ // - photoScrollContainer adds padding: 16 (32px total horizontal padding)
29
+ // - Available content width = containerWidth - 32
30
+ const availableContentWidth = containerWidth - 32;
31
+ console.log('[FileManagementScreen] Available content width:', availableContentWidth);
32
+ console.log('[FileManagementScreen] Spacing fix applied: 4px uniform gap both horizontal and vertical');
33
+ }, [containerWidth]);
34
+ const [files, setFiles] = useState([]);
35
+ const [loading, setLoading] = useState(true);
36
+ const [refreshing, setRefreshing] = useState(false);
37
+ const [uploading, setUploading] = useState(false);
38
+ const [uploadProgress, setUploadProgress] = useState(null);
39
+ const [deleting, setDeleting] = useState(null);
40
+ const [selectedFile, setSelectedFile] = useState(null);
41
+ const [showFileDetails, setShowFileDetails] = useState(false);
42
+ const [openedFile, setOpenedFile] = useState(null);
43
+ const [fileContent, setFileContent] = useState(null);
44
+ const [loadingFileContent, setLoadingFileContent] = useState(false);
45
+ const [showFileDetailsInViewer, setShowFileDetailsInViewer] = useState(false);
46
+ const [viewMode, setViewMode] = useState('all');
47
+ const [searchQuery, setSearchQuery] = useState('');
48
+ const [filteredFiles, setFilteredFiles] = useState([]);
49
+ const [isDragging, setIsDragging] = useState(false);
50
+ const [photoDimensions, setPhotoDimensions] = useState({});
51
+ const [loadingDimensions, setLoadingDimensions] = useState(false);
52
+ const [hoveredPreview, setHoveredPreview] = useState(null);
53
+
54
+ // Memoize theme-related calculations to prevent unnecessary recalculations
55
+ const themeStyles = useMemo(() => {
56
+ const isDarkTheme = theme === 'dark';
57
+ return {
58
+ isDarkTheme,
59
+ textColor: isDarkTheme ? '#FFFFFF' : '#000000',
60
+ backgroundColor: isDarkTheme ? '#121212' : '#f2f2f2',
61
+ secondaryBackgroundColor: isDarkTheme ? '#222222' : '#FFFFFF',
62
+ borderColor: isDarkTheme ? '#444444' : '#E0E0E0',
63
+ primaryColor: '#007AFF',
64
+ dangerColor: '#FF3B30',
65
+ successColor: '#34C759'
66
+ };
67
+ }, [theme]);
68
+
69
+ // Extract commonly used theme variables
70
+ const backgroundColor = themeStyles.backgroundColor;
71
+ const borderColor = themeStyles.borderColor;
72
+ const targetUserId = userId || user?.id;
73
+ const loadFiles = useCallback(async (isRefresh = false) => {
74
+ if (!targetUserId) return;
75
+ try {
76
+ if (isRefresh) {
77
+ setRefreshing(true);
78
+ } else {
79
+ setLoading(true);
80
+ }
81
+ const response = await oxyServices.listUserFiles(targetUserId);
82
+ setFiles(response.files || []);
83
+ } catch (error) {
84
+ console.error('Failed to load files:', error);
85
+ toast.error(error.message || 'Failed to load files');
86
+ } finally {
87
+ setLoading(false);
88
+ setRefreshing(false);
89
+ }
90
+ }, [targetUserId, oxyServices]);
91
+
92
+ // Filter files based on search query and view mode
93
+ useEffect(() => {
94
+ let filteredByMode = files;
95
+
96
+ // Filter by view mode first
97
+ if (viewMode === 'photos') {
98
+ filteredByMode = files.filter(file => file.contentType.startsWith('image/'));
99
+ }
100
+
101
+ // Then filter by search query
102
+ if (!searchQuery.trim()) {
103
+ setFilteredFiles(filteredByMode);
104
+ } else {
105
+ const query = searchQuery.toLowerCase();
106
+ const filtered = filteredByMode.filter(file => file.filename.toLowerCase().includes(query) || file.contentType.toLowerCase().includes(query) || file.metadata?.description && file.metadata.description.toLowerCase().includes(query));
107
+ setFilteredFiles(filtered);
108
+ }
109
+ }, [files, searchQuery, viewMode]);
110
+
111
+ // Load photo dimensions for justified grid
112
+ const loadPhotoDimensions = useCallback(async photos => {
113
+ if (photos.length === 0) return;
114
+ setLoadingDimensions(true);
115
+ const newDimensions = {
116
+ ...photoDimensions
117
+ };
118
+ let hasNewDimensions = false;
119
+
120
+ // Only load dimensions for photos we don't have yet
121
+ const photosToLoad = photos.filter(photo => !newDimensions[photo.id]);
122
+ if (photosToLoad.length === 0) {
123
+ setLoadingDimensions(false);
124
+ return;
125
+ }
126
+ try {
127
+ await Promise.all(photosToLoad.map(async photo => {
128
+ try {
129
+ const downloadUrl = oxyServices.getFileDownloadUrl(photo.id);
130
+ if (Platform.OS === 'web') {
131
+ const img = new window.Image();
132
+ await new Promise((resolve, reject) => {
133
+ img.onload = () => {
134
+ newDimensions[photo.id] = {
135
+ width: img.naturalWidth,
136
+ height: img.naturalHeight
137
+ };
138
+ hasNewDimensions = true;
139
+ resolve();
140
+ };
141
+ img.onerror = () => {
142
+ // Fallback dimensions for failed loads
143
+ newDimensions[photo.id] = {
144
+ width: 1,
145
+ height: 1
146
+ };
147
+ hasNewDimensions = true;
148
+ resolve();
149
+ };
150
+ img.src = downloadUrl;
151
+ });
152
+ } else {
153
+ // For mobile, use Image.getSize from react-native
154
+ await new Promise(resolve => {
155
+ Image.getSize(downloadUrl, (width, height) => {
156
+ newDimensions[photo.id] = {
157
+ width,
158
+ height
159
+ };
160
+ hasNewDimensions = true;
161
+ resolve();
162
+ }, () => {
163
+ // Fallback dimensions
164
+ newDimensions[photo.id] = {
165
+ width: 1,
166
+ height: 1
167
+ };
168
+ hasNewDimensions = true;
169
+ resolve();
170
+ });
171
+ });
172
+ }
173
+ } catch (error) {
174
+ // Fallback dimensions for any errors
175
+ newDimensions[photo.id] = {
176
+ width: 1,
177
+ height: 1
178
+ };
179
+ hasNewDimensions = true;
180
+ }
181
+ }));
182
+ if (hasNewDimensions) {
183
+ setPhotoDimensions(newDimensions);
184
+ }
185
+ } catch (error) {
186
+ console.error('Error loading photo dimensions:', error);
187
+ } finally {
188
+ setLoadingDimensions(false);
189
+ }
190
+ }, [oxyServices, photoDimensions]);
191
+
192
+ // Create justified rows from photos with responsive algorithm
193
+ const createJustifiedRows = useCallback((photos, containerWidth) => {
194
+ if (photos.length === 0) return [];
195
+ const rows = [];
196
+ const photosPerRow = 3; // Fixed 3 photos per row for consistency
197
+
198
+ for (let i = 0; i < photos.length; i += photosPerRow) {
199
+ const rowPhotos = photos.slice(i, i + photosPerRow);
200
+ rows.push(rowPhotos);
201
+ }
202
+ return rows;
203
+ }, []);
204
+ const processFileUploads = async selectedFiles => {
205
+ if (selectedFiles.length === 0) return;
206
+ try {
207
+ // Show initial progress
208
+ setUploadProgress({
209
+ current: 0,
210
+ total: selectedFiles.length
211
+ });
212
+
213
+ // Validate file sizes (example: 50MB limit per file)
214
+ const maxSize = 50 * 1024 * 1024; // 50MB
215
+ const oversizedFiles = selectedFiles.filter(file => file.size > maxSize);
216
+ if (oversizedFiles.length > 0) {
217
+ const fileList = oversizedFiles.map(f => f.name).join('\n');
218
+ window.alert(`File Size Limit\n\nThe following files are too large (max 50MB):\n${fileList}`);
219
+ return;
220
+ }
221
+
222
+ // Option 1: Bulk upload (faster, all-or-nothing) for 5 or fewer files
223
+ if (selectedFiles.length <= 5) {
224
+ const filenames = selectedFiles.map(f => f.name);
225
+ const response = await oxyServices.uploadFiles(selectedFiles, filenames, {
226
+ userId: targetUserId,
227
+ uploadDate: new Date().toISOString()
228
+ });
229
+ toast.success(`${response.files.length} file(s) uploaded successfully`);
230
+ // Small delay to ensure backend processing is complete
231
+ setTimeout(async () => {
232
+ await loadFiles();
233
+ }, 500);
234
+ } else {
235
+ // Option 2: Individual uploads for better progress and error handling
236
+ let successCount = 0;
237
+ let failureCount = 0;
238
+ const errors = [];
239
+ for (let i = 0; i < selectedFiles.length; i++) {
240
+ const file = selectedFiles[i];
241
+ setUploadProgress({
242
+ current: i + 1,
243
+ total: selectedFiles.length
244
+ });
245
+ try {
246
+ await oxyServices.uploadFile(file, file.name, {
247
+ userId: targetUserId,
248
+ uploadDate: new Date().toISOString()
249
+ });
250
+ successCount++;
251
+ } catch (error) {
252
+ failureCount++;
253
+ errors.push(`${file.name}: ${error.message || 'Upload failed'}`);
254
+ }
255
+ }
256
+
257
+ // Show results summary
258
+ if (successCount > 0) {
259
+ toast.success(`${successCount} file(s) uploaded successfully`);
260
+ }
261
+ if (failureCount > 0) {
262
+ const errorMessage = `${failureCount} file(s) failed to upload${errors.length > 0 ? ':\n' + errors.slice(0, 3).join('\n') + (errors.length > 3 ? '\n...' : '') : ''}`;
263
+ toast.error(errorMessage);
264
+ }
265
+
266
+ // Small delay to ensure backend processing is complete
267
+ setTimeout(async () => {
268
+ await loadFiles();
269
+ }, 500);
270
+ }
271
+ } catch (error) {
272
+ console.error('Upload error:', error);
273
+ toast.error(error.message || 'Failed to upload files');
274
+ } finally {
275
+ setUploadProgress(null);
276
+ }
277
+ };
278
+ const handleFileUpload = async () => {
279
+ try {
280
+ setUploading(true);
281
+ setUploadProgress(null);
282
+ if (Platform.OS === 'web') {
283
+ // Web file picker implementation
284
+ const input = document.createElement('input');
285
+ input.type = 'file';
286
+ input.multiple = true;
287
+ input.accept = '*/*';
288
+ input.onchange = async e => {
289
+ const selectedFiles = Array.from(e.target.files);
290
+ await processFileUploads(selectedFiles);
291
+ };
292
+ input.click();
293
+ } else {
294
+ // Mobile - show info that file picker can be added
295
+ const installCommand = 'npm install expo-document-picker';
296
+ const message = `Mobile File Upload\n\nTo enable file uploads on mobile, install expo-document-picker:\n\n${installCommand}\n\nThen import and use DocumentPicker.getDocumentAsync() in this method.`;
297
+ if (window.confirm(`${message}\n\nWould you like to copy the install command?`)) {
298
+ toast.info(`Install: ${installCommand}`);
299
+ } else {
300
+ toast.info('Mobile file upload requires expo-document-picker');
301
+ }
302
+ }
303
+ } catch (error) {
304
+ toast.error(error.message || 'Failed to upload file');
305
+ } finally {
306
+ setUploading(false);
307
+ setUploadProgress(null);
308
+ }
309
+ };
310
+ const handleFileDelete = async (fileId, filename) => {
311
+ // Use web-compatible confirmation dialog
312
+ const confirmed = window.confirm(`Are you sure you want to delete "${filename}"? This action cannot be undone.`);
313
+ if (!confirmed) {
314
+ console.log('Delete cancelled by user');
315
+ return;
316
+ }
317
+ try {
318
+ console.log('Deleting file:', {
319
+ fileId,
320
+ filename
321
+ });
322
+ console.log('Target user ID:', targetUserId);
323
+ console.log('Current user ID:', user?.id);
324
+ setDeleting(fileId);
325
+ const result = await oxyServices.deleteFile(fileId);
326
+ console.log('Delete result:', result);
327
+ toast.success('File deleted successfully');
328
+
329
+ // Reload files after successful deletion
330
+ setTimeout(async () => {
331
+ await loadFiles();
332
+ }, 500);
333
+ } catch (error) {
334
+ console.error('Delete error:', error);
335
+ console.error('Error details:', error.response?.data || error.message);
336
+
337
+ // Provide specific error messages
338
+ if (error.message?.includes('File not found') || error.message?.includes('404')) {
339
+ toast.error('File not found. It may have already been deleted.');
340
+ // Still reload files to refresh the list
341
+ setTimeout(async () => {
342
+ await loadFiles();
343
+ }, 500);
344
+ } else if (error.message?.includes('permission') || error.message?.includes('403')) {
345
+ toast.error('You do not have permission to delete this file.');
346
+ } else {
347
+ toast.error(error.message || 'Failed to delete file');
348
+ }
349
+ } finally {
350
+ setDeleting(null);
351
+ }
352
+ };
353
+
354
+ // Drag and drop handlers for web
355
+ const handleDragOver = e => {
356
+ if (Platform.OS === 'web' && user?.id === targetUserId) {
357
+ e.preventDefault();
358
+ setIsDragging(true);
359
+ }
360
+ };
361
+ const handleDragLeave = e => {
362
+ if (Platform.OS === 'web') {
363
+ e.preventDefault();
364
+ setIsDragging(false);
365
+ }
366
+ };
367
+ const handleDrop = async e => {
368
+ if (Platform.OS === 'web' && user?.id === targetUserId) {
369
+ e.preventDefault();
370
+ setIsDragging(false);
371
+ setUploading(true);
372
+ try {
373
+ const files = Array.from(e.dataTransfer.files);
374
+ await processFileUploads(files);
375
+ } catch (error) {
376
+ toast.error(error.message || 'Failed to upload files');
377
+ } finally {
378
+ setUploading(false);
379
+ }
380
+ }
381
+ };
382
+ const handleFileDownload = async (fileId, filename) => {
383
+ try {
384
+ if (Platform.OS === 'web') {
385
+ console.log('Downloading file:', {
386
+ fileId,
387
+ filename
388
+ });
389
+
390
+ // Use the public download URL method
391
+ const downloadUrl = oxyServices.getFileDownloadUrl(fileId);
392
+ console.log('Download URL:', downloadUrl);
393
+ try {
394
+ // Method 1: Try simple link download first
395
+ const link = document.createElement('a');
396
+ link.href = downloadUrl;
397
+ link.download = filename;
398
+ link.target = '_blank';
399
+ document.body.appendChild(link);
400
+ link.click();
401
+ document.body.removeChild(link);
402
+ toast.success('File download started');
403
+ } catch (linkError) {
404
+ console.warn('Link download failed, trying fetch method:', linkError);
405
+
406
+ // Method 2: Fallback to fetch download
407
+ const response = await fetch(downloadUrl);
408
+ if (!response.ok) {
409
+ if (response.status === 404) {
410
+ throw new Error('File not found. It may have been deleted.');
411
+ } else {
412
+ throw new Error(`Download failed: ${response.status} ${response.statusText}`);
413
+ }
414
+ }
415
+ const blob = await response.blob();
416
+ const url = window.URL.createObjectURL(blob);
417
+ const link = document.createElement('a');
418
+ link.href = url;
419
+ link.download = filename;
420
+ document.body.appendChild(link);
421
+ link.click();
422
+ document.body.removeChild(link);
423
+
424
+ // Clean up the blob URL
425
+ window.URL.revokeObjectURL(url);
426
+ toast.success('File downloaded successfully');
427
+ }
428
+ } else {
429
+ toast.info('File download not implemented for mobile yet');
430
+ }
431
+ } catch (error) {
432
+ console.error('Download error:', error);
433
+ toast.error(error.message || 'Failed to download file');
434
+ }
435
+ };
436
+ const formatFileSize = bytes => {
437
+ if (bytes === 0) return '0 Bytes';
438
+ const k = 1024;
439
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
440
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
441
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
442
+ };
443
+ const getFileIcon = contentType => {
444
+ if (contentType.startsWith('image/')) return 'image';
445
+ if (contentType.startsWith('video/')) return 'videocam';
446
+ if (contentType.startsWith('audio/')) return 'musical-notes';
447
+ if (contentType.includes('pdf')) return 'document-text';
448
+ if (contentType.includes('word') || contentType.includes('doc')) return 'document';
449
+ if (contentType.includes('excel') || contentType.includes('sheet')) return 'grid';
450
+ if (contentType.includes('zip') || contentType.includes('archive')) return 'archive';
451
+ return 'document-outline';
452
+ };
453
+ const handleFileOpen = async file => {
454
+ try {
455
+ setLoadingFileContent(true);
456
+ setOpenedFile(file);
457
+
458
+ // For text files, images, and other viewable content, try to load the content
459
+ if (file.contentType.startsWith('text/') || file.contentType.includes('json') || file.contentType.includes('xml') || file.contentType.includes('javascript') || file.contentType.includes('typescript') || file.contentType.startsWith('image/') || file.contentType.includes('pdf') || file.contentType.startsWith('video/') || file.contentType.startsWith('audio/')) {
460
+ try {
461
+ const downloadUrl = oxyServices.getFileDownloadUrl(file.id);
462
+ const response = await fetch(downloadUrl);
463
+ if (response.ok) {
464
+ if (file.contentType.startsWith('image/') || file.contentType.includes('pdf') || file.contentType.startsWith('video/') || file.contentType.startsWith('audio/')) {
465
+ // For images, PDFs, videos, and audio, we'll use the URL directly
466
+ setFileContent(downloadUrl);
467
+ } else {
468
+ // For text files, get the content
469
+ const content = await response.text();
470
+ setFileContent(content);
471
+ }
472
+ } else {
473
+ if (response.status === 404) {
474
+ toast.error('File not found. It may have been deleted.');
475
+ } else {
476
+ toast.error(`Failed to load file: ${response.status} ${response.statusText}`);
477
+ }
478
+ setFileContent(null);
479
+ }
480
+ } catch (error) {
481
+ console.error('Failed to load file content:', error);
482
+ if (error.message?.includes('404') || error.message?.includes('not found')) {
483
+ toast.error('File not found. It may have been deleted.');
484
+ } else {
485
+ toast.error('Failed to load file content');
486
+ }
487
+ setFileContent(null);
488
+ }
489
+ } else {
490
+ // For non-viewable files, don't load content
491
+ setFileContent(null);
492
+ }
493
+ } catch (error) {
494
+ console.error('Failed to open file:', error);
495
+ toast.error(error.message || 'Failed to open file');
496
+ } finally {
497
+ setLoadingFileContent(false);
498
+ }
499
+ };
500
+ const handleCloseFile = () => {
501
+ setOpenedFile(null);
502
+ setFileContent(null);
503
+ setShowFileDetailsInViewer(false);
504
+ // Don't reset view mode when closing a file
505
+ };
506
+ const showFileDetailsModal = file => {
507
+ setSelectedFile(file);
508
+ setShowFileDetails(true);
509
+ };
510
+ const renderSimplePhotoItem = useCallback((photo, index) => {
511
+ const downloadUrl = oxyServices.getFileDownloadUrl(photo.id);
512
+
513
+ // Calculate photo item width based on actual container size from bottom sheet
514
+ let itemsPerRow = 3; // Default for mobile
515
+ if (containerWidth > 768) itemsPerRow = 4; // Desktop/tablet
516
+ else if (containerWidth > 480) itemsPerRow = 3; // Large mobile
517
+
518
+ // Account for the photoScrollContainer padding (16px on each side = 32px total)
519
+ const scrollContainerPadding = 32; // Total horizontal padding from photoScrollContainer
520
+ const gaps = (itemsPerRow - 1) * 4; // Gap between items (4px)
521
+ const availableWidth = containerWidth - scrollContainerPadding;
522
+ const itemWidth = (availableWidth - gaps) / itemsPerRow;
523
+ return /*#__PURE__*/_jsx(TouchableOpacity, {
524
+ style: [styles.simplePhotoItem, {
525
+ width: itemWidth,
526
+ height: itemWidth,
527
+ marginRight: (index + 1) % itemsPerRow === 0 ? 0 : 4
528
+ }],
529
+ onPress: () => handleFileOpen(photo),
530
+ activeOpacity: 0.8,
531
+ children: /*#__PURE__*/_jsx(View, {
532
+ style: styles.simplePhotoContainer,
533
+ children: Platform.OS === 'web' ? /*#__PURE__*/_jsx("img", {
534
+ src: downloadUrl,
535
+ alt: photo.filename,
536
+ style: {
537
+ width: '100%',
538
+ height: '100%',
539
+ objectFit: 'cover',
540
+ borderRadius: 8,
541
+ transition: 'transform 0.2s ease'
542
+ },
543
+ loading: "lazy",
544
+ onError: e => {
545
+ console.error('Photo failed to load:', e);
546
+ },
547
+ onMouseEnter: e => {
548
+ e.currentTarget.style.transform = 'scale(1.05)';
549
+ },
550
+ onMouseLeave: e => {
551
+ e.currentTarget.style.transform = 'scale(1)';
552
+ }
553
+ }) : /*#__PURE__*/_jsx(Image, {
554
+ source: {
555
+ uri: downloadUrl
556
+ },
557
+ style: styles.simplePhotoImage,
558
+ resizeMode: "cover",
559
+ onError: e => {
560
+ console.error('Photo failed to load:', e);
561
+ }
562
+ })
563
+ })
564
+ }, photo.id);
565
+ }, [oxyServices, containerWidth]);
566
+ const renderJustifiedPhotoItem = useCallback((photo, width, height, isLast) => {
567
+ const downloadUrl = oxyServices.getFileDownloadUrl(photo.id);
568
+ return /*#__PURE__*/_jsx(TouchableOpacity, {
569
+ style: [styles.justifiedPhotoItem, {
570
+ width,
571
+ height
572
+ }],
573
+ onPress: () => handleFileOpen(photo),
574
+ activeOpacity: 0.8,
575
+ children: /*#__PURE__*/_jsx(View, {
576
+ style: styles.justifiedPhotoContainer,
577
+ children: Platform.OS === 'web' ? /*#__PURE__*/_jsx("img", {
578
+ src: downloadUrl,
579
+ alt: photo.filename,
580
+ style: {
581
+ width: '100%',
582
+ height: '100%',
583
+ objectFit: 'cover',
584
+ borderRadius: 6,
585
+ transition: 'transform 0.2s ease, box-shadow 0.2s ease'
586
+ },
587
+ loading: "lazy",
588
+ onError: e => {
589
+ console.error('Photo failed to load:', e);
590
+ },
591
+ onMouseEnter: e => {
592
+ e.currentTarget.style.transform = 'scale(1.02)';
593
+ e.currentTarget.style.boxShadow = '0 8px 25px rgba(0,0,0,0.15)';
594
+ e.currentTarget.style.zIndex = '10';
595
+ },
596
+ onMouseLeave: e => {
597
+ e.currentTarget.style.transform = 'scale(1)';
598
+ e.currentTarget.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)';
599
+ e.currentTarget.style.zIndex = '1';
600
+ }
601
+ }) : /*#__PURE__*/_jsx(Image, {
602
+ source: {
603
+ uri: downloadUrl
604
+ },
605
+ style: styles.justifiedPhotoImage,
606
+ resizeMode: "cover",
607
+ onError: e => {
608
+ console.error('Photo failed to load:', e);
609
+ }
610
+ })
611
+ })
612
+ }, photo.id);
613
+ }, [oxyServices]);
614
+ useEffect(() => {
615
+ loadFiles();
616
+ }, [loadFiles]);
617
+ const renderFileItem = file => {
618
+ const isImage = file.contentType.startsWith('image/');
619
+ const isPDF = file.contentType.includes('pdf');
620
+ const isVideo = file.contentType.startsWith('video/');
621
+ const isAudio = file.contentType.startsWith('audio/');
622
+ const hasPreview = isImage || isPDF || isVideo;
623
+ const borderColor = themeStyles.borderColor;
624
+ return /*#__PURE__*/_jsxs(View, {
625
+ style: [styles.fileItem, {
626
+ backgroundColor: themeStyles.secondaryBackgroundColor,
627
+ borderColor
628
+ }],
629
+ children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
630
+ style: styles.fileContent,
631
+ onPress: () => handleFileOpen(file),
632
+ children: [/*#__PURE__*/_jsx(View, {
633
+ style: styles.filePreviewContainer,
634
+ children: hasPreview ? /*#__PURE__*/_jsxs(View, {
635
+ style: styles.filePreview,
636
+ ...(Platform.OS === 'web' && {
637
+ onMouseEnter: () => setHoveredPreview(file.id),
638
+ onMouseLeave: () => setHoveredPreview(null)
639
+ }),
640
+ children: [isImage && (Platform.OS === 'web' ? /*#__PURE__*/_jsx("img", {
641
+ src: oxyServices.getFileDownloadUrl(file.id),
642
+ style: {
643
+ width: '100%',
644
+ height: '100%',
645
+ objectFit: 'cover',
646
+ borderRadius: 8,
647
+ transition: 'transform 0.2s ease',
648
+ transform: hoveredPreview === file.id ? 'scale(1.05)' : 'scale(1)'
649
+ },
650
+ onError: e => {
651
+ // Show fallback icon if image fails to load
652
+ e.currentTarget.style.display = 'none';
653
+ const fallbackElement = e.currentTarget.parentElement?.querySelector('[data-fallback="true"]');
654
+ if (fallbackElement) {
655
+ fallbackElement.style.display = 'flex';
656
+ }
657
+ }
658
+ }) : /*#__PURE__*/_jsx(Image, {
659
+ source: {
660
+ uri: oxyServices.getFileDownloadUrl(file.id)
661
+ },
662
+ style: styles.previewImage,
663
+ resizeMode: "cover",
664
+ onError: () => {
665
+ // For React Native, you might want to set an error state
666
+ console.warn('Failed to load image preview for file:', file.id);
667
+ }
668
+ })), isPDF && /*#__PURE__*/_jsxs(View, {
669
+ style: styles.pdfPreview,
670
+ children: [/*#__PURE__*/_jsx(Ionicons, {
671
+ name: "document",
672
+ size: 32,
673
+ color: themeStyles.primaryColor
674
+ }), /*#__PURE__*/_jsx(Text, {
675
+ style: [styles.pdfLabel, {
676
+ color: themeStyles.primaryColor
677
+ }],
678
+ children: "PDF"
679
+ })]
680
+ }), isVideo && /*#__PURE__*/_jsxs(View, {
681
+ style: styles.videoPreview,
682
+ children: [/*#__PURE__*/_jsx(Ionicons, {
683
+ name: "play-circle",
684
+ size: 32,
685
+ color: themeStyles.primaryColor
686
+ }), /*#__PURE__*/_jsx(Text, {
687
+ style: [styles.videoLabel, {
688
+ color: themeStyles.primaryColor
689
+ }],
690
+ children: "VIDEO"
691
+ })]
692
+ }), /*#__PURE__*/_jsx(View, {
693
+ style: [styles.fallbackIcon, {
694
+ display: isImage ? 'none' : 'flex'
695
+ }],
696
+ ...(Platform.OS === 'web' && {
697
+ 'data-fallback': 'true'
698
+ }),
699
+ children: /*#__PURE__*/_jsx(Ionicons, {
700
+ name: getFileIcon(file.contentType),
701
+ size: 32,
702
+ color: themeStyles.primaryColor
703
+ })
704
+ }), Platform.OS === 'web' && hoveredPreview === file.id && isImage && /*#__PURE__*/_jsx(View, {
705
+ style: styles.previewOverlay,
706
+ children: /*#__PURE__*/_jsx(Ionicons, {
707
+ name: "eye",
708
+ size: 24,
709
+ color: "#FFFFFF"
710
+ })
711
+ })]
712
+ }) : /*#__PURE__*/_jsx(View, {
713
+ style: styles.fileIconContainer,
714
+ children: /*#__PURE__*/_jsx(Ionicons, {
715
+ name: getFileIcon(file.contentType),
716
+ size: 32,
717
+ color: themeStyles.primaryColor
718
+ })
719
+ })
720
+ }), /*#__PURE__*/_jsxs(View, {
721
+ style: styles.fileInfo,
722
+ children: [/*#__PURE__*/_jsx(Text, {
723
+ style: [styles.fileName, {
724
+ color: themeStyles.textColor
725
+ }],
726
+ numberOfLines: 1,
727
+ children: file.filename
728
+ }), /*#__PURE__*/_jsxs(Text, {
729
+ style: [styles.fileDetails, {
730
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
731
+ }],
732
+ children: [formatFileSize(file.length), " \u2022 ", new Date(file.uploadDate).toLocaleDateString()]
733
+ }), file.metadata?.description && /*#__PURE__*/_jsx(Text, {
734
+ style: [styles.fileDescription, {
735
+ color: themeStyles.isDarkTheme ? '#AAAAAA' : '#888888'
736
+ }],
737
+ numberOfLines: 2,
738
+ children: file.metadata.description
739
+ })]
740
+ })]
741
+ }), /*#__PURE__*/_jsxs(View, {
742
+ style: styles.fileActions,
743
+ children: [hasPreview && /*#__PURE__*/_jsx(TouchableOpacity, {
744
+ style: [styles.actionButton, {
745
+ backgroundColor: themeStyles.isDarkTheme ? '#333333' : '#F0F0F0'
746
+ }],
747
+ onPress: () => handleFileOpen(file),
748
+ children: /*#__PURE__*/_jsx(Ionicons, {
749
+ name: "eye",
750
+ size: 20,
751
+ color: themeStyles.primaryColor
752
+ })
753
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
754
+ style: [styles.actionButton, {
755
+ backgroundColor: themeStyles.isDarkTheme ? '#333333' : '#F0F0F0'
756
+ }],
757
+ onPress: () => handleFileDownload(file.id, file.filename),
758
+ children: /*#__PURE__*/_jsx(Ionicons, {
759
+ name: "download",
760
+ size: 20,
761
+ color: themeStyles.primaryColor
762
+ })
763
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
764
+ style: [styles.actionButton, {
765
+ backgroundColor: themeStyles.isDarkTheme ? '#400000' : '#FFEBEE'
766
+ }],
767
+ onPress: () => {
768
+ handleFileDelete(file.id, file.filename);
769
+ },
770
+ disabled: deleting === file.id,
771
+ children: deleting === file.id ? /*#__PURE__*/_jsx(ActivityIndicator, {
772
+ size: "small",
773
+ color: themeStyles.dangerColor
774
+ }) : /*#__PURE__*/_jsx(Ionicons, {
775
+ name: "trash",
776
+ size: 20,
777
+ color: themeStyles.dangerColor
778
+ })
779
+ })]
780
+ })]
781
+ }, file.id);
782
+ };
783
+ const renderPhotoItem = (photo, index) => {
784
+ const downloadUrl = oxyServices.getFileDownloadUrl(photo.id);
785
+
786
+ // Calculate photo item width based on actual container size from bottom sheet
787
+ let itemsPerRow = 3; // Default for mobile
788
+ if (containerWidth > 768) itemsPerRow = 6; // Tablet/Desktop
789
+ else if (containerWidth > 480) itemsPerRow = 4; // Large mobile
790
+
791
+ // Account for the photoScrollContainer padding (16px on each side = 32px total)
792
+ const scrollContainerPadding = 32; // Total horizontal padding from photoScrollContainer
793
+ const gaps = (itemsPerRow - 1) * 4; // Gap between items
794
+ const availableWidth = containerWidth - scrollContainerPadding;
795
+ const itemWidth = (availableWidth - gaps) / itemsPerRow;
796
+ return /*#__PURE__*/_jsx(TouchableOpacity, {
797
+ style: [styles.photoItem, {
798
+ width: itemWidth,
799
+ height: itemWidth
800
+ }],
801
+ onPress: () => handleFileOpen(photo),
802
+ activeOpacity: 0.8,
803
+ children: /*#__PURE__*/_jsx(View, {
804
+ style: styles.photoContainer,
805
+ children: Platform.OS === 'web' ? /*#__PURE__*/_jsx("img", {
806
+ src: downloadUrl,
807
+ alt: photo.filename,
808
+ style: {
809
+ width: '100%',
810
+ height: '100%',
811
+ objectFit: 'cover',
812
+ borderRadius: 8,
813
+ transition: 'transform 0.2s ease'
814
+ },
815
+ loading: "lazy",
816
+ onError: e => {
817
+ console.error('Photo failed to load:', e);
818
+ // Could replace with placeholder image
819
+ },
820
+ onMouseEnter: e => {
821
+ e.currentTarget.style.transform = 'scale(1.02)';
822
+ },
823
+ onMouseLeave: e => {
824
+ e.currentTarget.style.transform = 'scale(1)';
825
+ }
826
+ }) : /*#__PURE__*/_jsx(Image, {
827
+ source: {
828
+ uri: downloadUrl
829
+ },
830
+ style: styles.photoImage,
831
+ resizeMode: "cover",
832
+ onError: e => {
833
+ console.error('Photo failed to load:', e);
834
+ }
835
+ })
836
+ })
837
+ }, photo.id);
838
+ };
839
+ const renderPhotoGrid = useCallback(() => {
840
+ const photos = filteredFiles.filter(file => file.contentType.startsWith('image/'));
841
+ if (photos.length === 0) {
842
+ return /*#__PURE__*/_jsxs(View, {
843
+ style: styles.emptyState,
844
+ children: [/*#__PURE__*/_jsx(Ionicons, {
845
+ name: "images-outline",
846
+ size: 64,
847
+ color: themeStyles.isDarkTheme ? '#666666' : '#CCCCCC'
848
+ }), /*#__PURE__*/_jsx(Text, {
849
+ style: [styles.emptyStateTitle, {
850
+ color: themeStyles.textColor
851
+ }],
852
+ children: "No Photos Yet"
853
+ }), /*#__PURE__*/_jsx(Text, {
854
+ style: [styles.emptyStateDescription, {
855
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
856
+ }],
857
+ children: user?.id === targetUserId ? `Upload photos to get started. You can select multiple photos at once${Platform.OS === 'web' ? ' or drag & drop them here.' : '.'}` : "This user hasn't uploaded any photos yet"
858
+ }), user?.id === targetUserId && /*#__PURE__*/_jsx(TouchableOpacity, {
859
+ style: [styles.emptyStateButton, {
860
+ backgroundColor: themeStyles.primaryColor
861
+ }],
862
+ onPress: handleFileUpload,
863
+ disabled: uploading,
864
+ children: uploading ? /*#__PURE__*/_jsx(ActivityIndicator, {
865
+ size: "small",
866
+ color: "#FFFFFF"
867
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
868
+ children: [/*#__PURE__*/_jsx(Ionicons, {
869
+ name: "cloud-upload",
870
+ size: 20,
871
+ color: "#FFFFFF"
872
+ }), /*#__PURE__*/_jsx(Text, {
873
+ style: styles.emptyStateButtonText,
874
+ children: "Upload Photos"
875
+ })]
876
+ })
877
+ })]
878
+ });
879
+ }
880
+ return /*#__PURE__*/_jsxs(ScrollView, {
881
+ style: styles.scrollView,
882
+ contentContainerStyle: styles.photoScrollContainer,
883
+ refreshControl: /*#__PURE__*/_jsx(RefreshControl, {
884
+ refreshing: refreshing,
885
+ onRefresh: () => loadFiles(true),
886
+ tintColor: themeStyles.primaryColor
887
+ }),
888
+ showsVerticalScrollIndicator: false,
889
+ children: [loadingDimensions && /*#__PURE__*/_jsxs(View, {
890
+ style: styles.dimensionsLoadingIndicator,
891
+ children: [/*#__PURE__*/_jsx(ActivityIndicator, {
892
+ size: "small",
893
+ color: themeStyles.primaryColor
894
+ }), /*#__PURE__*/_jsx(Text, {
895
+ style: [styles.dimensionsLoadingText, {
896
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
897
+ }],
898
+ children: "Loading photo layout..."
899
+ })]
900
+ }), /*#__PURE__*/_jsx(JustifiedPhotoGrid, {
901
+ photos: photos,
902
+ photoDimensions: photoDimensions,
903
+ loadPhotoDimensions: loadPhotoDimensions,
904
+ createJustifiedRows: createJustifiedRows,
905
+ renderJustifiedPhotoItem: renderJustifiedPhotoItem,
906
+ renderSimplePhotoItem: renderPhotoItem,
907
+ textColor: themeStyles.textColor,
908
+ containerWidth: containerWidth
909
+ })]
910
+ });
911
+ }, [filteredFiles, themeStyles, user?.id, targetUserId, uploading, handleFileUpload, refreshing, loadFiles, loadingDimensions, photoDimensions, loadPhotoDimensions, createJustifiedRows, renderJustifiedPhotoItem, renderPhotoItem, containerWidth]);
912
+
913
+ // Separate component for the photo grid to optimize rendering
914
+ const JustifiedPhotoGrid = /*#__PURE__*/React.memo(({
915
+ photos,
916
+ photoDimensions,
917
+ loadPhotoDimensions,
918
+ createJustifiedRows,
919
+ renderJustifiedPhotoItem,
920
+ renderSimplePhotoItem,
921
+ textColor,
922
+ containerWidth
923
+ }) => {
924
+ // Load dimensions for new photos
925
+ React.useEffect(() => {
926
+ loadPhotoDimensions(photos);
927
+ }, [photos.map(p => p.id).join(','), loadPhotoDimensions]);
928
+
929
+ // Group photos by date
930
+ const photosByDate = React.useMemo(() => {
931
+ return photos.reduce((groups, photo) => {
932
+ const date = new Date(photo.uploadDate).toDateString();
933
+ if (!groups[date]) {
934
+ groups[date] = [];
935
+ }
936
+ groups[date].push(photo);
937
+ return groups;
938
+ }, {});
939
+ }, [photos]);
940
+ const sortedDates = React.useMemo(() => {
941
+ return Object.keys(photosByDate).sort((a, b) => new Date(b).getTime() - new Date(a).getTime());
942
+ }, [photosByDate]);
943
+ return /*#__PURE__*/_jsx(_Fragment, {
944
+ children: sortedDates.map(date => {
945
+ const dayPhotos = photosByDate[date];
946
+ const justifiedRows = createJustifiedRows(dayPhotos, containerWidth);
947
+ return /*#__PURE__*/_jsxs(View, {
948
+ style: styles.photoDateSection,
949
+ children: [/*#__PURE__*/_jsx(Text, {
950
+ style: [styles.photoDateHeader, {
951
+ color: themeStyles.textColor
952
+ }],
953
+ children: new Date(date).toLocaleDateString('en-US', {
954
+ weekday: 'long',
955
+ year: 'numeric',
956
+ month: 'long',
957
+ day: 'numeric'
958
+ })
959
+ }), /*#__PURE__*/_jsx(View, {
960
+ style: styles.justifiedPhotoGrid,
961
+ children: justifiedRows.map((row, rowIndex) => {
962
+ // Calculate row height based on available width
963
+ const gap = 4;
964
+ let totalAspectRatio = 0;
965
+
966
+ // Calculate total aspect ratio for this row
967
+ row.forEach(photo => {
968
+ const dimensions = photoDimensions[photo.id];
969
+ const aspectRatio = dimensions ? dimensions.width / dimensions.height : 1.33; // Default 4:3 ratio
970
+ totalAspectRatio += aspectRatio;
971
+ });
972
+
973
+ // Calculate the height that makes the row fill the available width
974
+ // Account for photoScrollContainer padding (32px total) and gaps between photos
975
+ const scrollContainerPadding = 32;
976
+ const availableWidth = containerWidth - scrollContainerPadding - gap * (row.length - 1);
977
+ const calculatedHeight = availableWidth / totalAspectRatio;
978
+
979
+ // Clamp height for visual consistency
980
+ const rowHeight = Math.max(120, Math.min(calculatedHeight, 300));
981
+ return /*#__PURE__*/_jsx(View, {
982
+ style: [styles.justifiedPhotoRow, {
983
+ height: rowHeight,
984
+ maxWidth: containerWidth - 32,
985
+ // Account for scroll container padding
986
+ gap: 4 // Add horizontal gap between photos in row
987
+ }],
988
+ children: row.map((photo, photoIndex) => {
989
+ const dimensions = photoDimensions[photo.id];
990
+ const aspectRatio = dimensions ? dimensions.width / dimensions.height : 1.33; // Default 4:3 ratio
991
+
992
+ const photoWidth = rowHeight * aspectRatio;
993
+ const isLast = photoIndex === row.length - 1;
994
+ return renderJustifiedPhotoItem(photo, photoWidth, rowHeight, isLast);
995
+ })
996
+ }, `row-${rowIndex}`);
997
+ })
998
+ })]
999
+ }, date);
1000
+ })
1001
+ });
1002
+ });
1003
+ const renderFileDetailsModal = () => {
1004
+ const backgroundColor = themeStyles.backgroundColor;
1005
+ const borderColor = themeStyles.borderColor;
1006
+ return /*#__PURE__*/_jsx(Modal, {
1007
+ visible: showFileDetails,
1008
+ animationType: "slide",
1009
+ presentationStyle: "pageSheet",
1010
+ onRequestClose: () => setShowFileDetails(false),
1011
+ children: /*#__PURE__*/_jsxs(View, {
1012
+ style: [styles.modalContainer, {
1013
+ backgroundColor
1014
+ }],
1015
+ children: [/*#__PURE__*/_jsxs(View, {
1016
+ style: [styles.modalHeader, {
1017
+ borderBottomColor: borderColor
1018
+ }],
1019
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
1020
+ style: styles.modalCloseButton,
1021
+ onPress: () => setShowFileDetails(false),
1022
+ children: /*#__PURE__*/_jsx(Ionicons, {
1023
+ name: "close",
1024
+ size: 24,
1025
+ color: themeStyles.textColor
1026
+ })
1027
+ }), /*#__PURE__*/_jsx(Text, {
1028
+ style: [styles.modalTitle, {
1029
+ color: themeStyles.textColor
1030
+ }],
1031
+ children: "File Details"
1032
+ }), /*#__PURE__*/_jsx(View, {
1033
+ style: styles.modalPlaceholder
1034
+ })]
1035
+ }), selectedFile && /*#__PURE__*/_jsx(ScrollView, {
1036
+ style: styles.modalContent,
1037
+ children: /*#__PURE__*/_jsxs(View, {
1038
+ style: [styles.fileDetailCard, {
1039
+ backgroundColor: themeStyles.secondaryBackgroundColor,
1040
+ borderColor
1041
+ }],
1042
+ children: [/*#__PURE__*/_jsx(View, {
1043
+ style: styles.fileDetailIcon,
1044
+ children: /*#__PURE__*/_jsx(Ionicons, {
1045
+ name: getFileIcon(selectedFile.contentType),
1046
+ size: 64,
1047
+ color: themeStyles.primaryColor
1048
+ })
1049
+ }), /*#__PURE__*/_jsx(Text, {
1050
+ style: [styles.fileDetailName, {
1051
+ color: themeStyles.textColor
1052
+ }],
1053
+ children: selectedFile.filename
1054
+ }), /*#__PURE__*/_jsxs(View, {
1055
+ style: styles.fileDetailInfo,
1056
+ children: [/*#__PURE__*/_jsxs(View, {
1057
+ style: styles.detailRow,
1058
+ children: [/*#__PURE__*/_jsx(Text, {
1059
+ style: [styles.detailLabel, {
1060
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1061
+ }],
1062
+ children: "Size:"
1063
+ }), /*#__PURE__*/_jsx(Text, {
1064
+ style: [styles.detailValue, {
1065
+ color: themeStyles.textColor
1066
+ }],
1067
+ children: formatFileSize(selectedFile.length)
1068
+ })]
1069
+ }), /*#__PURE__*/_jsxs(View, {
1070
+ style: styles.detailRow,
1071
+ children: [/*#__PURE__*/_jsx(Text, {
1072
+ style: [styles.detailLabel, {
1073
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1074
+ }],
1075
+ children: "Type:"
1076
+ }), /*#__PURE__*/_jsx(Text, {
1077
+ style: [styles.detailValue, {
1078
+ color: themeStyles.textColor
1079
+ }],
1080
+ children: selectedFile.contentType
1081
+ })]
1082
+ }), /*#__PURE__*/_jsxs(View, {
1083
+ style: styles.detailRow,
1084
+ children: [/*#__PURE__*/_jsx(Text, {
1085
+ style: [styles.detailLabel, {
1086
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1087
+ }],
1088
+ children: "Uploaded:"
1089
+ }), /*#__PURE__*/_jsx(Text, {
1090
+ style: [styles.detailValue, {
1091
+ color: themeStyles.textColor
1092
+ }],
1093
+ children: new Date(selectedFile.uploadDate).toLocaleString()
1094
+ })]
1095
+ }), selectedFile.metadata?.description && /*#__PURE__*/_jsxs(View, {
1096
+ style: styles.detailRow,
1097
+ children: [/*#__PURE__*/_jsx(Text, {
1098
+ style: [styles.detailLabel, {
1099
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1100
+ }],
1101
+ children: "Description:"
1102
+ }), /*#__PURE__*/_jsx(Text, {
1103
+ style: [styles.detailValue, {
1104
+ color: themeStyles.textColor
1105
+ }],
1106
+ children: selectedFile.metadata.description
1107
+ })]
1108
+ })]
1109
+ }), /*#__PURE__*/_jsxs(View, {
1110
+ style: styles.modalActions,
1111
+ children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
1112
+ style: [styles.modalActionButton, {
1113
+ backgroundColor: themeStyles.primaryColor
1114
+ }],
1115
+ onPress: () => {
1116
+ handleFileDownload(selectedFile.id, selectedFile.filename);
1117
+ setShowFileDetails(false);
1118
+ },
1119
+ children: [/*#__PURE__*/_jsx(Ionicons, {
1120
+ name: "download",
1121
+ size: 20,
1122
+ color: "#FFFFFF"
1123
+ }), /*#__PURE__*/_jsx(Text, {
1124
+ style: styles.modalActionText,
1125
+ children: "Download"
1126
+ })]
1127
+ }), user?.id === targetUserId && /*#__PURE__*/_jsxs(TouchableOpacity, {
1128
+ style: [styles.modalActionButton, {
1129
+ backgroundColor: themeStyles.dangerColor
1130
+ }],
1131
+ onPress: () => {
1132
+ setShowFileDetails(false);
1133
+ handleFileDelete(selectedFile.id, selectedFile.filename);
1134
+ },
1135
+ children: [/*#__PURE__*/_jsx(Ionicons, {
1136
+ name: "trash",
1137
+ size: 20,
1138
+ color: "#FFFFFF"
1139
+ }), /*#__PURE__*/_jsx(Text, {
1140
+ style: styles.modalActionText,
1141
+ children: "Delete"
1142
+ })]
1143
+ })]
1144
+ })]
1145
+ })
1146
+ })]
1147
+ })
1148
+ });
1149
+ };
1150
+ const renderFileViewer = () => {
1151
+ if (!openedFile) return null;
1152
+ const backgroundColor = themeStyles.backgroundColor;
1153
+ const borderColor = themeStyles.borderColor;
1154
+ const isImage = openedFile.contentType.startsWith('image/');
1155
+ const isText = openedFile.contentType.startsWith('text/') || openedFile.contentType.includes('json') || openedFile.contentType.includes('xml') || openedFile.contentType.includes('javascript') || openedFile.contentType.includes('typescript');
1156
+ const isPDF = openedFile.contentType.includes('pdf');
1157
+ const isVideo = openedFile.contentType.startsWith('video/');
1158
+ const isAudio = openedFile.contentType.startsWith('audio/');
1159
+ return /*#__PURE__*/_jsxs(View, {
1160
+ style: [styles.fileViewerContainer, {
1161
+ backgroundColor
1162
+ }],
1163
+ children: [/*#__PURE__*/_jsxs(View, {
1164
+ style: [styles.fileViewerHeader, {
1165
+ borderBottomColor: borderColor
1166
+ }],
1167
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
1168
+ style: styles.backButton,
1169
+ onPress: handleCloseFile,
1170
+ children: /*#__PURE__*/_jsx(Ionicons, {
1171
+ name: "arrow-back",
1172
+ size: 24,
1173
+ color: themeStyles.textColor
1174
+ })
1175
+ }), /*#__PURE__*/_jsxs(View, {
1176
+ style: styles.fileViewerTitleContainer,
1177
+ children: [/*#__PURE__*/_jsx(Text, {
1178
+ style: [styles.fileViewerTitle, {
1179
+ color: themeStyles.textColor
1180
+ }],
1181
+ numberOfLines: 1,
1182
+ children: openedFile.filename
1183
+ }), /*#__PURE__*/_jsxs(Text, {
1184
+ style: [styles.fileViewerSubtitle, {
1185
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1186
+ }],
1187
+ children: [formatFileSize(openedFile.length), " \u2022 ", openedFile.contentType]
1188
+ })]
1189
+ }), /*#__PURE__*/_jsxs(View, {
1190
+ style: styles.fileViewerActions,
1191
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
1192
+ style: [styles.actionButton, {
1193
+ backgroundColor: themeStyles.isDarkTheme ? '#333333' : '#F0F0F0'
1194
+ }],
1195
+ onPress: () => handleFileDownload(openedFile.id, openedFile.filename),
1196
+ children: /*#__PURE__*/_jsx(Ionicons, {
1197
+ name: "download",
1198
+ size: 20,
1199
+ color: themeStyles.primaryColor
1200
+ })
1201
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
1202
+ style: [styles.actionButton, {
1203
+ backgroundColor: showFileDetailsInViewer ? themeStyles.primaryColor : themeStyles.isDarkTheme ? '#333333' : '#F0F0F0'
1204
+ }],
1205
+ onPress: () => setShowFileDetailsInViewer(!showFileDetailsInViewer),
1206
+ children: /*#__PURE__*/_jsx(Ionicons, {
1207
+ name: showFileDetailsInViewer ? "chevron-up" : "information-circle",
1208
+ size: 20,
1209
+ color: showFileDetailsInViewer ? "#FFFFFF" : themeStyles.primaryColor
1210
+ })
1211
+ })]
1212
+ })]
1213
+ }), showFileDetailsInViewer && /*#__PURE__*/_jsxs(View, {
1214
+ style: [styles.fileDetailsSection, {
1215
+ backgroundColor: themeStyles.secondaryBackgroundColor,
1216
+ borderColor
1217
+ }],
1218
+ children: [/*#__PURE__*/_jsxs(View, {
1219
+ style: styles.fileDetailsSectionHeader,
1220
+ children: [/*#__PURE__*/_jsx(Text, {
1221
+ style: [styles.fileDetailsSectionTitle, {
1222
+ color: themeStyles.textColor
1223
+ }],
1224
+ children: "File Details"
1225
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
1226
+ style: styles.fileDetailsSectionToggle,
1227
+ onPress: () => setShowFileDetailsInViewer(false),
1228
+ children: /*#__PURE__*/_jsx(Ionicons, {
1229
+ name: "chevron-up",
1230
+ size: 20,
1231
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1232
+ })
1233
+ })]
1234
+ }), /*#__PURE__*/_jsxs(View, {
1235
+ style: styles.fileDetailInfo,
1236
+ children: [/*#__PURE__*/_jsxs(View, {
1237
+ style: styles.detailRow,
1238
+ children: [/*#__PURE__*/_jsx(Text, {
1239
+ style: [styles.detailLabel, {
1240
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1241
+ }],
1242
+ children: "File Name:"
1243
+ }), /*#__PURE__*/_jsx(Text, {
1244
+ style: [styles.detailValue, {
1245
+ color: themeStyles.textColor
1246
+ }],
1247
+ children: openedFile.filename
1248
+ })]
1249
+ }), /*#__PURE__*/_jsxs(View, {
1250
+ style: styles.detailRow,
1251
+ children: [/*#__PURE__*/_jsx(Text, {
1252
+ style: [styles.detailLabel, {
1253
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1254
+ }],
1255
+ children: "Size:"
1256
+ }), /*#__PURE__*/_jsx(Text, {
1257
+ style: [styles.detailValue, {
1258
+ color: themeStyles.textColor
1259
+ }],
1260
+ children: formatFileSize(openedFile.length)
1261
+ })]
1262
+ }), /*#__PURE__*/_jsxs(View, {
1263
+ style: styles.detailRow,
1264
+ children: [/*#__PURE__*/_jsx(Text, {
1265
+ style: [styles.detailLabel, {
1266
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1267
+ }],
1268
+ children: "Type:"
1269
+ }), /*#__PURE__*/_jsx(Text, {
1270
+ style: [styles.detailValue, {
1271
+ color: themeStyles.textColor
1272
+ }],
1273
+ children: openedFile.contentType
1274
+ })]
1275
+ }), /*#__PURE__*/_jsxs(View, {
1276
+ style: styles.detailRow,
1277
+ children: [/*#__PURE__*/_jsx(Text, {
1278
+ style: [styles.detailLabel, {
1279
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1280
+ }],
1281
+ children: "Uploaded:"
1282
+ }), /*#__PURE__*/_jsx(Text, {
1283
+ style: [styles.detailValue, {
1284
+ color: themeStyles.textColor
1285
+ }],
1286
+ children: new Date(openedFile.uploadDate).toLocaleString()
1287
+ })]
1288
+ }), openedFile.metadata?.description && /*#__PURE__*/_jsxs(View, {
1289
+ style: styles.detailRow,
1290
+ children: [/*#__PURE__*/_jsx(Text, {
1291
+ style: [styles.detailLabel, {
1292
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1293
+ }],
1294
+ children: "Description:"
1295
+ }), /*#__PURE__*/_jsx(Text, {
1296
+ style: [styles.detailValue, {
1297
+ color: themeStyles.textColor
1298
+ }],
1299
+ children: openedFile.metadata.description
1300
+ })]
1301
+ }), /*#__PURE__*/_jsxs(View, {
1302
+ style: styles.detailRow,
1303
+ children: [/*#__PURE__*/_jsx(Text, {
1304
+ style: [styles.detailLabel, {
1305
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1306
+ }],
1307
+ children: "File ID:"
1308
+ }), /*#__PURE__*/_jsx(Text, {
1309
+ style: [styles.detailValue, {
1310
+ color: themeStyles.textColor,
1311
+ fontSize: 12,
1312
+ fontFamily: Platform.OS === 'web' ? 'monospace' : 'Courier'
1313
+ }],
1314
+ children: openedFile.id
1315
+ })]
1316
+ })]
1317
+ }), /*#__PURE__*/_jsxs(View, {
1318
+ style: styles.fileDetailsActions,
1319
+ children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
1320
+ style: [styles.fileDetailsActionButton, {
1321
+ backgroundColor: themeStyles.primaryColor
1322
+ }],
1323
+ onPress: () => handleFileDownload(openedFile.id, openedFile.filename),
1324
+ children: [/*#__PURE__*/_jsx(Ionicons, {
1325
+ name: "download",
1326
+ size: 16,
1327
+ color: "#FFFFFF"
1328
+ }), /*#__PURE__*/_jsx(Text, {
1329
+ style: styles.fileDetailsActionText,
1330
+ children: "Download"
1331
+ })]
1332
+ }), user?.id === targetUserId && /*#__PURE__*/_jsxs(TouchableOpacity, {
1333
+ style: [styles.fileDetailsActionButton, {
1334
+ backgroundColor: themeStyles.dangerColor
1335
+ }],
1336
+ onPress: () => {
1337
+ handleCloseFile();
1338
+ handleFileDelete(openedFile.id, openedFile.filename);
1339
+ },
1340
+ children: [/*#__PURE__*/_jsx(Ionicons, {
1341
+ name: "trash",
1342
+ size: 16,
1343
+ color: "#FFFFFF"
1344
+ }), /*#__PURE__*/_jsx(Text, {
1345
+ style: styles.fileDetailsActionText,
1346
+ children: "Delete"
1347
+ })]
1348
+ })]
1349
+ })]
1350
+ }), /*#__PURE__*/_jsx(ScrollView, {
1351
+ style: [styles.fileViewerContent, showFileDetailsInViewer && styles.fileViewerContentWithDetails],
1352
+ contentContainerStyle: styles.fileViewerContentContainer,
1353
+ children: loadingFileContent ? /*#__PURE__*/_jsxs(View, {
1354
+ style: styles.fileViewerLoading,
1355
+ children: [/*#__PURE__*/_jsx(ActivityIndicator, {
1356
+ size: "large",
1357
+ color: themeStyles.primaryColor
1358
+ }), /*#__PURE__*/_jsx(Text, {
1359
+ style: [styles.fileViewerLoadingText, {
1360
+ color: themeStyles.textColor
1361
+ }],
1362
+ children: "Loading file content..."
1363
+ })]
1364
+ }) : isImage && fileContent ? /*#__PURE__*/_jsx(View, {
1365
+ style: styles.imageContainer,
1366
+ children: Platform.OS === 'web' ? /*#__PURE__*/_jsx("img", {
1367
+ src: fileContent,
1368
+ alt: openedFile.filename,
1369
+ style: {
1370
+ maxWidth: '100%',
1371
+ maxHeight: '80vh',
1372
+ objectFit: 'contain',
1373
+ borderRadius: 8
1374
+ },
1375
+ onError: e => {
1376
+ console.error('Image failed to load:', e);
1377
+ }
1378
+ }) : /*#__PURE__*/_jsx(Image, {
1379
+ source: {
1380
+ uri: fileContent
1381
+ },
1382
+ style: {
1383
+ width: '100%',
1384
+ height: 400,
1385
+ resizeMode: 'contain',
1386
+ borderRadius: 8
1387
+ },
1388
+ onError: e => {
1389
+ console.error('Image failed to load:', e);
1390
+ }
1391
+ })
1392
+ }) : isText && fileContent ? /*#__PURE__*/_jsx(View, {
1393
+ style: [styles.textContainer, {
1394
+ backgroundColor: themeStyles.secondaryBackgroundColor,
1395
+ borderColor
1396
+ }],
1397
+ children: /*#__PURE__*/_jsx(ScrollView, {
1398
+ style: {
1399
+ flex: 1
1400
+ },
1401
+ nestedScrollEnabled: true,
1402
+ children: /*#__PURE__*/_jsx(Text, {
1403
+ style: [styles.textContent, {
1404
+ color: themeStyles.textColor
1405
+ }],
1406
+ children: fileContent
1407
+ })
1408
+ })
1409
+ }) : isPDF && fileContent && Platform.OS === 'web' ? /*#__PURE__*/_jsx(View, {
1410
+ style: styles.pdfContainer,
1411
+ children: /*#__PURE__*/_jsx("iframe", {
1412
+ src: fileContent,
1413
+ width: "100%",
1414
+ height: "600px",
1415
+ style: {
1416
+ border: 'none',
1417
+ borderRadius: 8
1418
+ },
1419
+ title: openedFile.filename
1420
+ })
1421
+ }) : isVideo && fileContent ? /*#__PURE__*/_jsx(View, {
1422
+ style: styles.mediaContainer,
1423
+ children: Platform.OS === 'web' ? /*#__PURE__*/_jsxs("video", {
1424
+ controls: true,
1425
+ style: {
1426
+ width: '100%',
1427
+ maxHeight: '70vh',
1428
+ borderRadius: 8
1429
+ },
1430
+ children: [/*#__PURE__*/_jsx("source", {
1431
+ src: fileContent,
1432
+ type: openedFile.contentType
1433
+ }), "Your browser does not support the video tag."]
1434
+ }) : /*#__PURE__*/_jsx(Text, {
1435
+ style: [styles.unsupportedText, {
1436
+ color: themeStyles.textColor
1437
+ }],
1438
+ children: "Video playback not supported on mobile"
1439
+ })
1440
+ }) : isAudio && fileContent ? /*#__PURE__*/_jsx(View, {
1441
+ style: styles.mediaContainer,
1442
+ children: Platform.OS === 'web' ? /*#__PURE__*/_jsxs("audio", {
1443
+ controls: true,
1444
+ style: {
1445
+ width: '100%',
1446
+ borderRadius: 8
1447
+ },
1448
+ children: [/*#__PURE__*/_jsx("source", {
1449
+ src: fileContent,
1450
+ type: openedFile.contentType
1451
+ }), "Your browser does not support the audio tag."]
1452
+ }) : /*#__PURE__*/_jsx(Text, {
1453
+ style: [styles.unsupportedText, {
1454
+ color: themeStyles.textColor
1455
+ }],
1456
+ children: "Audio playback not supported on mobile"
1457
+ })
1458
+ }) : /*#__PURE__*/_jsxs(View, {
1459
+ style: styles.unsupportedFileContainer,
1460
+ children: [/*#__PURE__*/_jsx(Ionicons, {
1461
+ name: getFileIcon(openedFile.contentType),
1462
+ size: 64,
1463
+ color: themeStyles.isDarkTheme ? '#666666' : '#CCCCCC'
1464
+ }), /*#__PURE__*/_jsx(Text, {
1465
+ style: [styles.unsupportedFileTitle, {
1466
+ color: themeStyles.textColor
1467
+ }],
1468
+ children: "Preview Not Available"
1469
+ }), /*#__PURE__*/_jsxs(Text, {
1470
+ style: [styles.unsupportedFileDescription, {
1471
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1472
+ }],
1473
+ children: ["This file type cannot be previewed in the browser.", '\n', "Download the file to view its contents."]
1474
+ }), /*#__PURE__*/_jsxs(TouchableOpacity, {
1475
+ style: [styles.downloadButtonLarge, {
1476
+ backgroundColor: themeStyles.primaryColor
1477
+ }],
1478
+ onPress: () => handleFileDownload(openedFile.id, openedFile.filename),
1479
+ children: [/*#__PURE__*/_jsx(Ionicons, {
1480
+ name: "download",
1481
+ size: 20,
1482
+ color: "#FFFFFF"
1483
+ }), /*#__PURE__*/_jsx(Text, {
1484
+ style: styles.downloadButtonText,
1485
+ children: "Download File"
1486
+ })]
1487
+ })]
1488
+ })
1489
+ })]
1490
+ });
1491
+ };
1492
+ const renderEmptyState = () => /*#__PURE__*/_jsxs(View, {
1493
+ style: styles.emptyState,
1494
+ children: [/*#__PURE__*/_jsx(Ionicons, {
1495
+ name: "folder-open-outline",
1496
+ size: 64,
1497
+ color: themeStyles.isDarkTheme ? '#666666' : '#CCCCCC'
1498
+ }), /*#__PURE__*/_jsx(Text, {
1499
+ style: [styles.emptyStateTitle, {
1500
+ color: themeStyles.textColor
1501
+ }],
1502
+ children: "No Files Yet"
1503
+ }), /*#__PURE__*/_jsx(Text, {
1504
+ style: [styles.emptyStateDescription, {
1505
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1506
+ }],
1507
+ children: user?.id === targetUserId ? `Upload files to get started. You can select multiple files at once${Platform.OS === 'web' ? ' or drag & drop them here.' : '.'}` : "This user hasn't uploaded any files yet"
1508
+ }), user?.id === targetUserId && /*#__PURE__*/_jsx(TouchableOpacity, {
1509
+ style: [styles.emptyStateButton, {
1510
+ backgroundColor: themeStyles.primaryColor
1511
+ }],
1512
+ onPress: handleFileUpload,
1513
+ disabled: uploading,
1514
+ children: uploading ? /*#__PURE__*/_jsx(ActivityIndicator, {
1515
+ size: "small",
1516
+ color: "#FFFFFF"
1517
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
1518
+ children: [/*#__PURE__*/_jsx(Ionicons, {
1519
+ name: "cloud-upload",
1520
+ size: 20,
1521
+ color: "#FFFFFF"
1522
+ }), /*#__PURE__*/_jsx(Text, {
1523
+ style: styles.emptyStateButtonText,
1524
+ children: "Upload Files"
1525
+ })]
1526
+ })
1527
+ })]
1528
+ });
1529
+ if (loading) {
1530
+ return /*#__PURE__*/_jsxs(View, {
1531
+ style: [styles.container, styles.centerContent, {
1532
+ backgroundColor
1533
+ }],
1534
+ children: [/*#__PURE__*/_jsx(ActivityIndicator, {
1535
+ size: "large",
1536
+ color: themeStyles.primaryColor
1537
+ }), /*#__PURE__*/_jsx(Text, {
1538
+ style: [styles.loadingText, {
1539
+ color: themeStyles.textColor
1540
+ }],
1541
+ children: "Loading files..."
1542
+ })]
1543
+ });
1544
+ }
1545
+
1546
+ // If a file is opened, show the file viewer
1547
+ if (openedFile) {
1548
+ return /*#__PURE__*/_jsxs(_Fragment, {
1549
+ children: [renderFileViewer(), renderFileDetailsModal()]
1550
+ });
1551
+ }
1552
+ return /*#__PURE__*/_jsxs(View, {
1553
+ style: [styles.container, {
1554
+ backgroundColor
1555
+ }, isDragging && Platform.OS === 'web' && styles.dragOverlay],
1556
+ ...(Platform.OS === 'web' && user?.id === targetUserId ? {
1557
+ onDragOver: handleDragOver,
1558
+ onDragLeave: handleDragLeave,
1559
+ onDrop: handleDrop
1560
+ } : {}),
1561
+ children: [/*#__PURE__*/_jsxs(View, {
1562
+ style: [styles.header, {
1563
+ borderBottomColor: borderColor,
1564
+ backgroundColor: themeStyles.isDarkTheme ? '#1A1A1A' : '#FFFFFF',
1565
+ shadowColor: '#000000',
1566
+ shadowOffset: {
1567
+ width: 0,
1568
+ height: 2
1569
+ },
1570
+ shadowOpacity: themeStyles.isDarkTheme ? 0.3 : 0.1,
1571
+ shadowRadius: 8,
1572
+ elevation: 4
1573
+ }],
1574
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
1575
+ style: [styles.backButton, {
1576
+ backgroundColor: themeStyles.isDarkTheme ? '#2A2A2A' : '#F8F9FA',
1577
+ borderRadius: 12
1578
+ }],
1579
+ onPress: onClose || goBack,
1580
+ children: /*#__PURE__*/_jsx(Ionicons, {
1581
+ name: "arrow-back",
1582
+ size: 22,
1583
+ color: themeStyles.textColor
1584
+ })
1585
+ }), /*#__PURE__*/_jsxs(View, {
1586
+ style: styles.headerTitleContainer,
1587
+ children: [/*#__PURE__*/_jsx(Text, {
1588
+ style: [styles.headerTitle, {
1589
+ color: themeStyles.textColor
1590
+ }],
1591
+ children: viewMode === 'photos' ? 'Photos' : 'File Management'
1592
+ }), /*#__PURE__*/_jsxs(Text, {
1593
+ style: [styles.headerSubtitle, {
1594
+ color: themeStyles.isDarkTheme ? '#AAAAAA' : '#666666'
1595
+ }],
1596
+ children: [filteredFiles.length, " ", filteredFiles.length === 1 ? 'item' : 'items']
1597
+ })]
1598
+ }), /*#__PURE__*/_jsxs(View, {
1599
+ style: styles.headerActions,
1600
+ children: [/*#__PURE__*/_jsxs(View, {
1601
+ style: [styles.viewModeToggle, {
1602
+ backgroundColor: themeStyles.isDarkTheme ? '#2A2A2A' : '#F8F9FA',
1603
+ borderWidth: 1,
1604
+ borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA',
1605
+ shadowColor: '#000000',
1606
+ shadowOffset: {
1607
+ width: 0,
1608
+ height: 1
1609
+ },
1610
+ shadowOpacity: themeStyles.isDarkTheme ? 0.3 : 0.05,
1611
+ shadowRadius: 4,
1612
+ elevation: 2
1613
+ }],
1614
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
1615
+ style: [styles.viewModeButton, viewMode === 'all' && {
1616
+ backgroundColor: themeStyles.primaryColor,
1617
+ shadowColor: themeStyles.primaryColor,
1618
+ shadowOffset: {
1619
+ width: 0,
1620
+ height: 2
1621
+ },
1622
+ shadowOpacity: 0.3,
1623
+ shadowRadius: 4,
1624
+ elevation: 3
1625
+ }],
1626
+ onPress: () => setViewMode('all'),
1627
+ children: /*#__PURE__*/_jsx(Ionicons, {
1628
+ name: "folder",
1629
+ size: 18,
1630
+ color: viewMode === 'all' ? '#FFFFFF' : themeStyles.textColor
1631
+ })
1632
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
1633
+ style: [styles.viewModeButton, viewMode === 'photos' && {
1634
+ backgroundColor: themeStyles.primaryColor,
1635
+ shadowColor: themeStyles.primaryColor,
1636
+ shadowOffset: {
1637
+ width: 0,
1638
+ height: 2
1639
+ },
1640
+ shadowOpacity: 0.3,
1641
+ shadowRadius: 4,
1642
+ elevation: 3
1643
+ }],
1644
+ onPress: () => setViewMode('photos'),
1645
+ children: /*#__PURE__*/_jsx(Ionicons, {
1646
+ name: "images",
1647
+ size: 18,
1648
+ color: viewMode === 'photos' ? '#FFFFFF' : themeStyles.textColor
1649
+ })
1650
+ })]
1651
+ }), user?.id === targetUserId && /*#__PURE__*/_jsx(TouchableOpacity, {
1652
+ style: [styles.uploadButton, {
1653
+ backgroundColor: themeStyles.primaryColor,
1654
+ shadowColor: themeStyles.primaryColor,
1655
+ shadowOffset: {
1656
+ width: 0,
1657
+ height: 3
1658
+ },
1659
+ shadowOpacity: 0.4,
1660
+ shadowRadius: 6,
1661
+ elevation: 5,
1662
+ transform: uploading ? [{
1663
+ scale: 0.95
1664
+ }] : [{
1665
+ scale: 1
1666
+ }]
1667
+ }],
1668
+ onPress: handleFileUpload,
1669
+ disabled: uploading,
1670
+ children: uploading ? /*#__PURE__*/_jsxs(View, {
1671
+ style: styles.uploadProgress,
1672
+ children: [/*#__PURE__*/_jsx(ActivityIndicator, {
1673
+ size: "small",
1674
+ color: "#FFFFFF"
1675
+ }), uploadProgress && /*#__PURE__*/_jsxs(Text, {
1676
+ style: styles.uploadProgressText,
1677
+ children: [uploadProgress.current, "/", uploadProgress.total]
1678
+ })]
1679
+ }) : /*#__PURE__*/_jsx(Ionicons, {
1680
+ name: "add",
1681
+ size: 26,
1682
+ color: "#FFFFFF"
1683
+ })
1684
+ })]
1685
+ })]
1686
+ }), files.length > 0 && (viewMode === 'all' || files.some(f => f.contentType.startsWith('image/'))) && /*#__PURE__*/_jsxs(View, {
1687
+ style: [styles.searchContainer, {
1688
+ backgroundColor: themeStyles.isDarkTheme ? '#1A1A1A' : '#FFFFFF',
1689
+ borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA',
1690
+ shadowColor: '#000000',
1691
+ shadowOffset: {
1692
+ width: 0,
1693
+ height: 1
1694
+ },
1695
+ shadowOpacity: themeStyles.isDarkTheme ? 0.2 : 0.05,
1696
+ shadowRadius: 4,
1697
+ elevation: 2
1698
+ }],
1699
+ children: [/*#__PURE__*/_jsx(Ionicons, {
1700
+ name: "search",
1701
+ size: 22,
1702
+ color: themeStyles.isDarkTheme ? '#888888' : '#666666'
1703
+ }), /*#__PURE__*/_jsx(TextInput, {
1704
+ style: [styles.searchInput, {
1705
+ color: themeStyles.textColor
1706
+ }],
1707
+ placeholder: viewMode === 'photos' ? 'Search photos...' : 'Search files...',
1708
+ placeholderTextColor: themeStyles.isDarkTheme ? '#888888' : '#999999',
1709
+ value: searchQuery,
1710
+ onChangeText: setSearchQuery
1711
+ }), searchQuery.length > 0 && /*#__PURE__*/_jsx(TouchableOpacity, {
1712
+ onPress: () => setSearchQuery(''),
1713
+ style: styles.searchClearButton,
1714
+ children: /*#__PURE__*/_jsx(Ionicons, {
1715
+ name: "close-circle",
1716
+ size: 22,
1717
+ color: themeStyles.isDarkTheme ? '#888888' : '#666666'
1718
+ })
1719
+ })]
1720
+ }), files.length > 0 && /*#__PURE__*/_jsxs(View, {
1721
+ style: [styles.statsContainer, {
1722
+ backgroundColor: themeStyles.isDarkTheme ? '#1A1A1A' : '#FFFFFF',
1723
+ borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA',
1724
+ shadowColor: '#000000',
1725
+ shadowOffset: {
1726
+ width: 0,
1727
+ height: 1
1728
+ },
1729
+ shadowOpacity: themeStyles.isDarkTheme ? 0.2 : 0.05,
1730
+ shadowRadius: 4,
1731
+ elevation: 2
1732
+ }],
1733
+ children: [/*#__PURE__*/_jsxs(View, {
1734
+ style: styles.statItem,
1735
+ children: [/*#__PURE__*/_jsx(Text, {
1736
+ style: [styles.statValue, {
1737
+ color: themeStyles.textColor
1738
+ }],
1739
+ children: filteredFiles.length
1740
+ }), /*#__PURE__*/_jsx(Text, {
1741
+ style: [styles.statLabel, {
1742
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1743
+ }],
1744
+ children: searchQuery.length > 0 ? 'Found' : filteredFiles.length === 1 ? viewMode === 'photos' ? 'Photo' : 'File' : viewMode === 'photos' ? 'Photos' : 'Files'
1745
+ })]
1746
+ }), /*#__PURE__*/_jsxs(View, {
1747
+ style: styles.statItem,
1748
+ children: [/*#__PURE__*/_jsx(Text, {
1749
+ style: [styles.statValue, {
1750
+ color: themeStyles.textColor
1751
+ }],
1752
+ children: formatFileSize(filteredFiles.reduce((total, file) => total + file.length, 0))
1753
+ }), /*#__PURE__*/_jsx(Text, {
1754
+ style: [styles.statLabel, {
1755
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1756
+ }],
1757
+ children: searchQuery.length > 0 ? 'Size' : 'Total Size'
1758
+ })]
1759
+ }), searchQuery.length > 0 && /*#__PURE__*/_jsxs(View, {
1760
+ style: styles.statItem,
1761
+ children: [/*#__PURE__*/_jsx(Text, {
1762
+ style: [styles.statValue, {
1763
+ color: themeStyles.textColor
1764
+ }],
1765
+ children: files.length
1766
+ }), /*#__PURE__*/_jsx(Text, {
1767
+ style: [styles.statLabel, {
1768
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1769
+ }],
1770
+ children: "Total"
1771
+ })]
1772
+ })]
1773
+ }), viewMode === 'photos' ? renderPhotoGrid() : /*#__PURE__*/_jsx(ScrollView, {
1774
+ style: styles.scrollView,
1775
+ contentContainerStyle: styles.scrollContainer,
1776
+ refreshControl: /*#__PURE__*/_jsx(RefreshControl, {
1777
+ refreshing: refreshing,
1778
+ onRefresh: () => loadFiles(true),
1779
+ tintColor: themeStyles.primaryColor
1780
+ }),
1781
+ children: filteredFiles.length === 0 && searchQuery.length > 0 ? /*#__PURE__*/_jsxs(View, {
1782
+ style: styles.emptyState,
1783
+ children: [/*#__PURE__*/_jsx(Ionicons, {
1784
+ name: "search",
1785
+ size: 64,
1786
+ color: themeStyles.isDarkTheme ? '#666666' : '#CCCCCC'
1787
+ }), /*#__PURE__*/_jsx(Text, {
1788
+ style: [styles.emptyStateTitle, {
1789
+ color: themeStyles.textColor
1790
+ }],
1791
+ children: "No Results Found"
1792
+ }), /*#__PURE__*/_jsxs(Text, {
1793
+ style: [styles.emptyStateDescription, {
1794
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1795
+ }],
1796
+ children: ["No files match your search for \"", searchQuery, "\""]
1797
+ }), /*#__PURE__*/_jsxs(TouchableOpacity, {
1798
+ style: [styles.emptyStateButton, {
1799
+ backgroundColor: themeStyles.primaryColor
1800
+ }],
1801
+ onPress: () => setSearchQuery(''),
1802
+ children: [/*#__PURE__*/_jsx(Ionicons, {
1803
+ name: "refresh",
1804
+ size: 20,
1805
+ color: "#FFFFFF"
1806
+ }), /*#__PURE__*/_jsx(Text, {
1807
+ style: styles.emptyStateButtonText,
1808
+ children: "Clear Search"
1809
+ })]
1810
+ })]
1811
+ }) : filteredFiles.length === 0 ? renderEmptyState() : /*#__PURE__*/_jsx(_Fragment, {
1812
+ children: filteredFiles.map(renderFileItem)
1813
+ })
1814
+ }), renderFileDetailsModal(), isDragging && Platform.OS === 'web' && /*#__PURE__*/_jsx(View, {
1815
+ style: styles.dragDropOverlay,
1816
+ children: /*#__PURE__*/_jsxs(View, {
1817
+ style: styles.dragDropContent,
1818
+ children: [/*#__PURE__*/_jsx(Ionicons, {
1819
+ name: "cloud-upload",
1820
+ size: 64,
1821
+ color: themeStyles.primaryColor
1822
+ }), /*#__PURE__*/_jsx(Text, {
1823
+ style: [styles.dragDropTitle, {
1824
+ color: themeStyles.primaryColor
1825
+ }],
1826
+ children: "Drop files to upload"
1827
+ }), /*#__PURE__*/_jsxs(Text, {
1828
+ style: [styles.dragDropSubtitle, {
1829
+ color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
1830
+ }],
1831
+ children: ["Release to upload", uploadProgress ? ` (${uploadProgress.current}/${uploadProgress.total})` : ' multiple files']
1832
+ })]
1833
+ })
1834
+ })]
1835
+ });
1836
+ };
1837
+ const styles = StyleSheet.create({
1838
+ container: {
1839
+ flex: 1
1840
+ },
1841
+ dragOverlay: {
1842
+ backgroundColor: 'rgba(0, 122, 255, 0.1)',
1843
+ borderWidth: 2,
1844
+ borderColor: '#007AFF',
1845
+ borderStyle: 'dashed'
1846
+ },
1847
+ centerContent: {
1848
+ justifyContent: 'center',
1849
+ alignItems: 'center'
1850
+ },
1851
+ header: {
1852
+ flexDirection: 'row',
1853
+ alignItems: 'center',
1854
+ justifyContent: 'space-between',
1855
+ paddingHorizontal: 24,
1856
+ paddingVertical: 20,
1857
+ borderBottomWidth: 1,
1858
+ position: 'relative'
1859
+ },
1860
+ backButton: {
1861
+ padding: 12,
1862
+ borderRadius: 12,
1863
+ alignItems: 'center',
1864
+ justifyContent: 'center',
1865
+ minWidth: 44,
1866
+ minHeight: 44
1867
+ },
1868
+ headerTitleContainer: {
1869
+ flex: 1,
1870
+ alignItems: 'center',
1871
+ justifyContent: 'center',
1872
+ marginHorizontal: 16
1873
+ },
1874
+ headerTitle: {
1875
+ fontSize: 22,
1876
+ fontWeight: '700',
1877
+ fontFamily: fontFamilies.phuduBold,
1878
+ letterSpacing: -0.5,
1879
+ lineHeight: 28
1880
+ },
1881
+ headerSubtitle: {
1882
+ fontSize: 13,
1883
+ fontWeight: '500',
1884
+ fontFamily: fontFamilies.phuduMedium,
1885
+ marginTop: 2,
1886
+ letterSpacing: 0.2
1887
+ },
1888
+ uploadButton: {
1889
+ width: 44,
1890
+ height: 44,
1891
+ borderRadius: 22,
1892
+ alignItems: 'center',
1893
+ justifyContent: 'center'
1894
+ },
1895
+ uploadProgress: {
1896
+ alignItems: 'center',
1897
+ justifyContent: 'center'
1898
+ },
1899
+ uploadProgressText: {
1900
+ color: '#FFFFFF',
1901
+ fontSize: 10,
1902
+ fontWeight: '600',
1903
+ marginTop: 2
1904
+ },
1905
+ searchContainer: {
1906
+ flexDirection: 'row',
1907
+ alignItems: 'center',
1908
+ paddingHorizontal: 20,
1909
+ paddingVertical: 16,
1910
+ marginHorizontal: 24,
1911
+ marginTop: 20,
1912
+ borderRadius: 16,
1913
+ borderWidth: 1,
1914
+ gap: 16
1915
+ },
1916
+ searchInput: {
1917
+ flex: 1,
1918
+ fontSize: 16,
1919
+ fontFamily: fontFamilies.phudu,
1920
+ lineHeight: 20
1921
+ },
1922
+ searchClearButton: {
1923
+ padding: 4,
1924
+ borderRadius: 12,
1925
+ alignItems: 'center',
1926
+ justifyContent: 'center'
1927
+ },
1928
+ searchIcon: {
1929
+ marginRight: 8
1930
+ },
1931
+ statsContainer: {
1932
+ flexDirection: 'row',
1933
+ paddingHorizontal: 24,
1934
+ paddingVertical: 20,
1935
+ marginHorizontal: 24,
1936
+ marginTop: 20,
1937
+ borderRadius: 16,
1938
+ borderWidth: 1
1939
+ },
1940
+ statItem: {
1941
+ flex: 1,
1942
+ alignItems: 'center',
1943
+ paddingVertical: 4
1944
+ },
1945
+ statValue: {
1946
+ fontSize: 28,
1947
+ fontWeight: '800',
1948
+ fontFamily: fontFamilies.phuduBold,
1949
+ letterSpacing: -0.5,
1950
+ lineHeight: 32
1951
+ },
1952
+ statLabel: {
1953
+ fontSize: 15,
1954
+ fontWeight: '500',
1955
+ fontFamily: fontFamilies.phuduMedium,
1956
+ marginTop: 4,
1957
+ letterSpacing: 0.3
1958
+ },
1959
+ scrollView: {
1960
+ flex: 1
1961
+ },
1962
+ scrollContainer: {
1963
+ padding: 20
1964
+ },
1965
+ fileItem: {
1966
+ flexDirection: 'row',
1967
+ alignItems: 'center',
1968
+ padding: 16,
1969
+ marginBottom: 12,
1970
+ borderRadius: 12,
1971
+ borderWidth: 1
1972
+ },
1973
+ fileContent: {
1974
+ flexDirection: 'row',
1975
+ alignItems: 'center',
1976
+ flex: 1
1977
+ },
1978
+ fileIconContainer: {
1979
+ width: 50,
1980
+ height: 50,
1981
+ alignItems: 'center',
1982
+ justifyContent: 'center',
1983
+ marginRight: 12
1984
+ },
1985
+ filePreviewContainer: {
1986
+ width: 60,
1987
+ height: 60,
1988
+ marginRight: 12
1989
+ },
1990
+ filePreview: {
1991
+ width: '100%',
1992
+ height: '100%',
1993
+ borderRadius: 8,
1994
+ backgroundColor: '#F5F5F5',
1995
+ alignItems: 'center',
1996
+ justifyContent: 'center',
1997
+ overflow: 'hidden',
1998
+ position: 'relative'
1999
+ },
2000
+ previewImage: {
2001
+ width: '100%',
2002
+ height: '100%',
2003
+ borderRadius: 8
2004
+ },
2005
+ pdfPreview: {
2006
+ alignItems: 'center',
2007
+ justifyContent: 'center',
2008
+ width: '100%',
2009
+ height: '100%',
2010
+ backgroundColor: '#FF6B6B20'
2011
+ },
2012
+ pdfLabel: {
2013
+ fontSize: 8,
2014
+ fontWeight: 'bold',
2015
+ marginTop: 2
2016
+ },
2017
+ videoPreview: {
2018
+ alignItems: 'center',
2019
+ justifyContent: 'center',
2020
+ width: '100%',
2021
+ height: '100%',
2022
+ backgroundColor: '#4ECDC420'
2023
+ },
2024
+ videoLabel: {
2025
+ fontSize: 8,
2026
+ fontWeight: 'bold',
2027
+ marginTop: 2
2028
+ },
2029
+ fallbackIcon: {
2030
+ position: 'absolute',
2031
+ top: 0,
2032
+ left: 0,
2033
+ right: 0,
2034
+ bottom: 0,
2035
+ alignItems: 'center',
2036
+ justifyContent: 'center',
2037
+ backgroundColor: '#F5F5F5',
2038
+ borderRadius: 8
2039
+ },
2040
+ previewOverlay: {
2041
+ position: 'absolute',
2042
+ top: 0,
2043
+ left: 0,
2044
+ right: 0,
2045
+ bottom: 0,
2046
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
2047
+ alignItems: 'center',
2048
+ justifyContent: 'center',
2049
+ borderRadius: 8
2050
+ },
2051
+ fileInfo: {
2052
+ flex: 1
2053
+ },
2054
+ fileName: {
2055
+ fontSize: 16,
2056
+ fontWeight: '600',
2057
+ marginBottom: 4
2058
+ },
2059
+ fileDetails: {
2060
+ fontSize: 14,
2061
+ marginBottom: 2
2062
+ },
2063
+ fileDescription: {
2064
+ fontSize: 12,
2065
+ fontStyle: 'italic'
2066
+ },
2067
+ fileActions: {
2068
+ flexDirection: 'row',
2069
+ gap: 8
2070
+ },
2071
+ actionButton: {
2072
+ width: 40,
2073
+ height: 40,
2074
+ borderRadius: 20,
2075
+ alignItems: 'center',
2076
+ justifyContent: 'center'
2077
+ },
2078
+ emptyState: {
2079
+ alignItems: 'center',
2080
+ paddingVertical: 60,
2081
+ paddingHorizontal: 40
2082
+ },
2083
+ emptyStateTitle: {
2084
+ fontSize: 24,
2085
+ fontWeight: 'bold',
2086
+ fontFamily: fontFamilies.phuduBold,
2087
+ marginTop: 16,
2088
+ marginBottom: 8
2089
+ },
2090
+ emptyStateDescription: {
2091
+ fontSize: 16,
2092
+ textAlign: 'center',
2093
+ lineHeight: 24,
2094
+ marginBottom: 32
2095
+ },
2096
+ emptyStateButton: {
2097
+ flexDirection: 'row',
2098
+ alignItems: 'center',
2099
+ paddingHorizontal: 24,
2100
+ paddingVertical: 12,
2101
+ borderRadius: 24,
2102
+ gap: 8
2103
+ },
2104
+ emptyStateButtonText: {
2105
+ color: '#FFFFFF',
2106
+ fontSize: 16,
2107
+ fontWeight: '600'
2108
+ },
2109
+ loadingText: {
2110
+ fontSize: 16,
2111
+ marginTop: 16
2112
+ },
2113
+ // Modal styles
2114
+ modalContainer: {
2115
+ flex: 1
2116
+ },
2117
+ modalHeader: {
2118
+ flexDirection: 'row',
2119
+ alignItems: 'center',
2120
+ justifyContent: 'space-between',
2121
+ paddingHorizontal: 20,
2122
+ paddingVertical: 16,
2123
+ borderBottomWidth: 1
2124
+ },
2125
+ modalCloseButton: {
2126
+ padding: 8
2127
+ },
2128
+ modalTitle: {
2129
+ fontSize: 18,
2130
+ fontWeight: '600',
2131
+ fontFamily: fontFamilies.phuduSemiBold
2132
+ },
2133
+ modalPlaceholder: {
2134
+ width: 40
2135
+ },
2136
+ modalContent: {
2137
+ flex: 1,
2138
+ padding: 20
2139
+ },
2140
+ fileDetailCard: {
2141
+ padding: 24,
2142
+ borderRadius: 16,
2143
+ borderWidth: 1,
2144
+ alignItems: 'center'
2145
+ },
2146
+ fileDetailIcon: {
2147
+ marginBottom: 16
2148
+ },
2149
+ fileDetailName: {
2150
+ fontSize: 20,
2151
+ fontWeight: 'bold',
2152
+ fontFamily: fontFamilies.phuduBold,
2153
+ textAlign: 'center',
2154
+ marginBottom: 24
2155
+ },
2156
+ fileDetailInfo: {
2157
+ width: '100%',
2158
+ marginBottom: 32
2159
+ },
2160
+ detailRow: {
2161
+ flexDirection: 'row',
2162
+ justifyContent: 'space-between',
2163
+ alignItems: 'flex-start',
2164
+ marginBottom: 12,
2165
+ flexWrap: 'wrap'
2166
+ },
2167
+ detailLabel: {
2168
+ fontSize: 16,
2169
+ fontWeight: '500',
2170
+ flex: 1,
2171
+ minWidth: 100
2172
+ },
2173
+ detailValue: {
2174
+ fontSize: 16,
2175
+ flex: 2,
2176
+ textAlign: 'right'
2177
+ },
2178
+ modalActions: {
2179
+ flexDirection: 'row',
2180
+ gap: 12,
2181
+ width: '100%'
2182
+ },
2183
+ modalActionButton: {
2184
+ flex: 1,
2185
+ flexDirection: 'row',
2186
+ alignItems: 'center',
2187
+ justifyContent: 'center',
2188
+ paddingVertical: 16,
2189
+ borderRadius: 12,
2190
+ gap: 8
2191
+ },
2192
+ modalActionText: {
2193
+ color: '#FFFFFF',
2194
+ fontSize: 16,
2195
+ fontWeight: '600'
2196
+ },
2197
+ // Drag and Drop styles
2198
+ dragDropOverlay: {
2199
+ position: 'absolute',
2200
+ top: 0,
2201
+ left: 0,
2202
+ right: 0,
2203
+ bottom: 0,
2204
+ backgroundColor: 'rgba(0, 0, 0, 0.8)',
2205
+ justifyContent: 'center',
2206
+ alignItems: 'center',
2207
+ zIndex: 1000
2208
+ },
2209
+ dragDropContent: {
2210
+ alignItems: 'center',
2211
+ backgroundColor: 'rgba(255, 255, 255, 0.9)',
2212
+ padding: 40,
2213
+ borderRadius: 20,
2214
+ borderWidth: 3,
2215
+ borderColor: '#007AFF',
2216
+ borderStyle: 'dashed'
2217
+ },
2218
+ dragDropTitle: {
2219
+ fontSize: 24,
2220
+ fontWeight: 'bold',
2221
+ marginTop: 16,
2222
+ marginBottom: 8
2223
+ },
2224
+ dragDropSubtitle: {
2225
+ fontSize: 16,
2226
+ textAlign: 'center'
2227
+ },
2228
+ // File Viewer styles
2229
+ fileViewerContainer: {
2230
+ flex: 1
2231
+ },
2232
+ fileViewerHeader: {
2233
+ flexDirection: 'row',
2234
+ alignItems: 'center',
2235
+ paddingHorizontal: 20,
2236
+ paddingVertical: 16,
2237
+ borderBottomWidth: 1
2238
+ },
2239
+ fileViewerTitleContainer: {
2240
+ flex: 1,
2241
+ marginHorizontal: 16
2242
+ },
2243
+ fileViewerTitle: {
2244
+ fontSize: 18,
2245
+ fontWeight: '600',
2246
+ fontFamily: fontFamilies.phuduSemiBold,
2247
+ marginBottom: 2
2248
+ },
2249
+ fileViewerSubtitle: {
2250
+ fontSize: 14
2251
+ },
2252
+ fileViewerActions: {
2253
+ flexDirection: 'row',
2254
+ gap: 8
2255
+ },
2256
+ fileViewerContent: {
2257
+ flex: 1
2258
+ },
2259
+ fileViewerContentWithDetails: {
2260
+ paddingBottom: 20
2261
+ },
2262
+ fileViewerContentContainer: {
2263
+ flexGrow: 1,
2264
+ padding: 20
2265
+ },
2266
+ fileViewerLoading: {
2267
+ flex: 1,
2268
+ justifyContent: 'center',
2269
+ alignItems: 'center'
2270
+ },
2271
+ fileViewerLoadingText: {
2272
+ fontSize: 16,
2273
+ marginTop: 16
2274
+ },
2275
+ imageContainer: {
2276
+ alignItems: 'center',
2277
+ justifyContent: 'center',
2278
+ flex: 1
2279
+ },
2280
+ textContainer: {
2281
+ flex: 1,
2282
+ borderRadius: 12,
2283
+ borderWidth: 1,
2284
+ padding: 16,
2285
+ minHeight: 200,
2286
+ maxHeight: '80%'
2287
+ },
2288
+ textContent: {
2289
+ fontSize: 14,
2290
+ fontFamily: Platform.OS === 'web' ? 'monospace' : 'Courier',
2291
+ lineHeight: 20
2292
+ },
2293
+ unsupportedFileContainer: {
2294
+ flex: 1,
2295
+ justifyContent: 'center',
2296
+ alignItems: 'center',
2297
+ paddingVertical: 60,
2298
+ paddingHorizontal: 40
2299
+ },
2300
+ unsupportedFileTitle: {
2301
+ fontSize: 24,
2302
+ fontWeight: 'bold',
2303
+ fontFamily: fontFamilies.phuduBold,
2304
+ marginTop: 16,
2305
+ marginBottom: 8,
2306
+ textAlign: 'center'
2307
+ },
2308
+ unsupportedFileDescription: {
2309
+ fontSize: 16,
2310
+ textAlign: 'center',
2311
+ lineHeight: 24,
2312
+ marginBottom: 32
2313
+ },
2314
+ downloadButtonLarge: {
2315
+ flexDirection: 'row',
2316
+ alignItems: 'center',
2317
+ paddingHorizontal: 24,
2318
+ paddingVertical: 16,
2319
+ borderRadius: 24,
2320
+ gap: 8
2321
+ },
2322
+ downloadButtonText: {
2323
+ color: '#FFFFFF',
2324
+ fontSize: 16,
2325
+ fontWeight: '600'
2326
+ },
2327
+ pdfContainer: {
2328
+ flex: 1,
2329
+ alignItems: 'center',
2330
+ justifyContent: 'center'
2331
+ },
2332
+ mediaContainer: {
2333
+ flex: 1,
2334
+ alignItems: 'center',
2335
+ justifyContent: 'center',
2336
+ padding: 20
2337
+ },
2338
+ unsupportedText: {
2339
+ fontSize: 16,
2340
+ textAlign: 'center',
2341
+ fontStyle: 'italic'
2342
+ },
2343
+ // File Details in Viewer styles
2344
+ fileDetailsSection: {
2345
+ margin: 16,
2346
+ marginTop: 0,
2347
+ padding: 20,
2348
+ borderRadius: 12,
2349
+ borderWidth: 1
2350
+ },
2351
+ fileDetailsSectionTitle: {
2352
+ fontSize: 18,
2353
+ fontWeight: '600',
2354
+ fontFamily: fontFamilies.phuduSemiBold,
2355
+ flex: 1
2356
+ },
2357
+ fileDetailsSectionHeader: {
2358
+ flexDirection: 'row',
2359
+ alignItems: 'center',
2360
+ justifyContent: 'space-between',
2361
+ marginBottom: 16
2362
+ },
2363
+ fileDetailsSectionToggle: {
2364
+ padding: 4
2365
+ },
2366
+ fileDetailsActions: {
2367
+ flexDirection: 'row',
2368
+ gap: 12,
2369
+ marginTop: 16
2370
+ },
2371
+ fileDetailsActionButton: {
2372
+ flex: 1,
2373
+ flexDirection: 'row',
2374
+ alignItems: 'center',
2375
+ justifyContent: 'center',
2376
+ paddingVertical: 12,
2377
+ borderRadius: 8,
2378
+ gap: 6
2379
+ },
2380
+ fileDetailsActionText: {
2381
+ color: '#FFFFFF',
2382
+ fontSize: 14,
2383
+ fontWeight: '600'
2384
+ },
2385
+ // Header styles
2386
+ headerActions: {
2387
+ flexDirection: 'row',
2388
+ alignItems: 'center',
2389
+ gap: 16
2390
+ },
2391
+ viewModeToggle: {
2392
+ flexDirection: 'row',
2393
+ borderRadius: 24,
2394
+ padding: 3,
2395
+ overflow: 'hidden'
2396
+ },
2397
+ viewModeButton: {
2398
+ paddingHorizontal: 14,
2399
+ paddingVertical: 10,
2400
+ borderRadius: 20,
2401
+ minWidth: 44,
2402
+ alignItems: 'center',
2403
+ justifyContent: 'center',
2404
+ marginHorizontal: 1
2405
+ },
2406
+ // Photo Grid styles
2407
+ photoScrollContainer: {
2408
+ padding: 16
2409
+ },
2410
+ photoDateSection: {
2411
+ marginBottom: 24
2412
+ },
2413
+ photoDateHeader: {
2414
+ fontSize: 18,
2415
+ fontWeight: '600',
2416
+ fontFamily: fontFamilies.phuduSemiBold,
2417
+ marginBottom: 12,
2418
+ paddingHorizontal: 4
2419
+ },
2420
+ photoGrid: {
2421
+ flexDirection: 'row',
2422
+ flexWrap: 'wrap',
2423
+ gap: 4,
2424
+ justifyContent: 'flex-start'
2425
+ },
2426
+ photoItem: {
2427
+ borderRadius: 8,
2428
+ overflow: 'hidden'
2429
+ },
2430
+ photoContainer: {
2431
+ width: '100%',
2432
+ height: '100%',
2433
+ position: 'relative',
2434
+ borderRadius: 8,
2435
+ overflow: 'hidden'
2436
+ },
2437
+ photoImage: {
2438
+ width: '100%',
2439
+ height: '100%'
2440
+ },
2441
+ // Justified Grid styles
2442
+ dimensionsLoadingIndicator: {
2443
+ flexDirection: 'row',
2444
+ alignItems: 'center',
2445
+ justifyContent: 'center',
2446
+ paddingVertical: 16,
2447
+ gap: 8
2448
+ },
2449
+ dimensionsLoadingText: {
2450
+ fontSize: 14,
2451
+ fontStyle: 'italic'
2452
+ },
2453
+ justifiedPhotoGrid: {
2454
+ gap: 4
2455
+ },
2456
+ justifiedPhotoRow: {
2457
+ flexDirection: 'row'
2458
+ },
2459
+ justifiedPhotoItem: {
2460
+ borderRadius: 6,
2461
+ overflow: 'hidden',
2462
+ position: 'relative'
2463
+ },
2464
+ justifiedPhotoContainer: {
2465
+ width: '100%',
2466
+ height: '100%',
2467
+ position: 'relative',
2468
+ borderRadius: 6,
2469
+ overflow: 'hidden',
2470
+ backgroundColor: '#F5F5F5'
2471
+ },
2472
+ justifiedPhotoImage: {
2473
+ width: '100%',
2474
+ height: '100%',
2475
+ borderRadius: 6
2476
+ },
2477
+ // Simple Photo Grid styles
2478
+ simplePhotoItem: {
2479
+ borderRadius: 8,
2480
+ overflow: 'hidden',
2481
+ backgroundColor: '#F5F5F5'
2482
+ },
2483
+ simplePhotoContainer: {
2484
+ width: '100%',
2485
+ height: '100%',
2486
+ position: 'relative',
2487
+ borderRadius: 8,
2488
+ overflow: 'hidden'
2489
+ },
2490
+ simplePhotoImage: {
2491
+ width: '100%',
2492
+ height: '100%',
2493
+ borderRadius: 8
2494
+ },
2495
+ // Loading skeleton styles
2496
+ photoSkeletonGrid: {
2497
+ flexDirection: 'row',
2498
+ flexWrap: 'wrap',
2499
+ gap: 4,
2500
+ marginTop: 20
2501
+ },
2502
+ photoSkeletonItem: {
2503
+ width: '32%',
2504
+ aspectRatio: 1,
2505
+ borderRadius: 8,
2506
+ marginBottom: 4
2507
+ }
2508
+ });
2509
+ export default FileManagementScreen;
2510
+ //# sourceMappingURL=FileManagementScreen.js.map