@oxyhq/services 5.4.0 → 5.4.2

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