@syra.fm/sdk 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/lib/commonjs/client.js +268 -0
  2. package/lib/commonjs/client.js.map +1 -0
  3. package/lib/commonjs/errors.js +22 -0
  4. package/lib/commonjs/errors.js.map +1 -0
  5. package/lib/commonjs/index.js +63 -0
  6. package/lib/commonjs/index.js.map +1 -0
  7. package/lib/commonjs/index.native.js +28 -0
  8. package/lib/commonjs/index.native.js.map +1 -0
  9. package/lib/commonjs/live/assets/icons/spaces-icon.js +42 -0
  10. package/lib/commonjs/live/assets/icons/spaces-icon.js.map +1 -0
  11. package/lib/commonjs/live/assets/icons/syra-icon.js +43 -0
  12. package/lib/commonjs/live/assets/icons/syra-icon.js.map +1 -0
  13. package/lib/commonjs/live/components/AnimatedPulse.js +38 -0
  14. package/lib/commonjs/live/components/AnimatedPulse.js.map +1 -0
  15. package/lib/commonjs/live/components/AnimatedSpeakerRing.js +90 -0
  16. package/lib/commonjs/live/components/AnimatedSpeakerRing.js.map +1 -0
  17. package/lib/commonjs/live/components/CreateRoomSheet.js +688 -0
  18. package/lib/commonjs/live/components/CreateRoomSheet.js.map +1 -0
  19. package/lib/commonjs/live/components/InsightsPanel.js +333 -0
  20. package/lib/commonjs/live/components/InsightsPanel.js.map +1 -0
  21. package/lib/commonjs/live/components/LiveRoomSheet.js +1195 -0
  22. package/lib/commonjs/live/components/LiveRoomSheet.js.map +1 -0
  23. package/lib/commonjs/live/components/MiniRoomBar.js +161 -0
  24. package/lib/commonjs/live/components/MiniRoomBar.js.map +1 -0
  25. package/lib/commonjs/live/components/PanelHeader.js +57 -0
  26. package/lib/commonjs/live/components/PanelHeader.js.map +1 -0
  27. package/lib/commonjs/live/components/PodcastStreamPicker.js +1190 -0
  28. package/lib/commonjs/live/components/PodcastStreamPicker.js.map +1 -0
  29. package/lib/commonjs/live/components/RecordingCard.js +192 -0
  30. package/lib/commonjs/live/components/RecordingCard.js.map +1 -0
  31. package/lib/commonjs/live/components/RecordingsPanel.js +304 -0
  32. package/lib/commonjs/live/components/RecordingsPanel.js.map +1 -0
  33. package/lib/commonjs/live/components/RoomCard.js +553 -0
  34. package/lib/commonjs/live/components/RoomCard.js.map +1 -0
  35. package/lib/commonjs/live/components/StreamConfigModal.js +656 -0
  36. package/lib/commonjs/live/components/StreamConfigModal.js.map +1 -0
  37. package/lib/commonjs/live/components/StreamConfigPanel.js +822 -0
  38. package/lib/commonjs/live/components/StreamConfigPanel.js.map +1 -0
  39. package/lib/commonjs/live/context/LiveConfigContext.js +46 -0
  40. package/lib/commonjs/live/context/LiveConfigContext.js.map +1 -0
  41. package/lib/commonjs/live/context/LiveRoomContext.js +195 -0
  42. package/lib/commonjs/live/context/LiveRoomContext.js.map +1 -0
  43. package/lib/commonjs/live/hooks/useActiveSpeakers.js +35 -0
  44. package/lib/commonjs/live/hooks/useActiveSpeakers.js.map +1 -0
  45. package/lib/commonjs/live/hooks/useRoomAudio.js +129 -0
  46. package/lib/commonjs/live/hooks/useRoomAudio.js.map +1 -0
  47. package/lib/commonjs/live/hooks/useRoomConnection.js +177 -0
  48. package/lib/commonjs/live/hooks/useRoomConnection.js.map +1 -0
  49. package/lib/commonjs/live/hooks/useRoomManager.js +37 -0
  50. package/lib/commonjs/live/hooks/useRoomManager.js.map +1 -0
  51. package/lib/commonjs/live/hooks/useRoomUsers.js +52 -0
  52. package/lib/commonjs/live/hooks/useRoomUsers.js.map +1 -0
  53. package/lib/commonjs/live/index.js +310 -0
  54. package/lib/commonjs/live/index.js.map +1 -0
  55. package/lib/commonjs/live/services/livekitService.js +20 -0
  56. package/lib/commonjs/live/services/livekitService.js.map +1 -0
  57. package/lib/commonjs/live/services/spaceSocketService.js +181 -0
  58. package/lib/commonjs/live/services/spaceSocketService.js.map +1 -0
  59. package/lib/commonjs/live/services/spacesService.js +642 -0
  60. package/lib/commonjs/live/services/spacesService.js.map +1 -0
  61. package/lib/commonjs/live/types.js +6 -0
  62. package/lib/commonjs/live/types.js.map +1 -0
  63. package/lib/commonjs/live/validation.js +238 -0
  64. package/lib/commonjs/live/validation.js.map +1 -0
  65. package/lib/commonjs/package.json +1 -0
  66. package/lib/commonjs/schema.js +102 -0
  67. package/lib/commonjs/schema.js.map +1 -0
  68. package/lib/module/client.js +264 -0
  69. package/lib/module/client.js.map +1 -0
  70. package/lib/module/errors.js +17 -0
  71. package/lib/module/errors.js.map +1 -0
  72. package/lib/module/index.js +6 -0
  73. package/lib/module/index.js.map +1 -0
  74. package/lib/module/index.native.js +5 -0
  75. package/lib/module/index.native.js.map +1 -0
  76. package/lib/module/live/assets/icons/spaces-icon.js +34 -0
  77. package/lib/module/live/assets/icons/spaces-icon.js.map +1 -0
  78. package/lib/module/live/assets/icons/syra-icon.js +36 -0
  79. package/lib/module/live/assets/icons/syra-icon.js.map +1 -0
  80. package/lib/module/live/components/AnimatedPulse.js +33 -0
  81. package/lib/module/live/components/AnimatedPulse.js.map +1 -0
  82. package/lib/module/live/components/AnimatedSpeakerRing.js +85 -0
  83. package/lib/module/live/components/AnimatedSpeakerRing.js.map +1 -0
  84. package/lib/module/live/components/CreateRoomSheet.js +682 -0
  85. package/lib/module/live/components/CreateRoomSheet.js.map +1 -0
  86. package/lib/module/live/components/InsightsPanel.js +327 -0
  87. package/lib/module/live/components/InsightsPanel.js.map +1 -0
  88. package/lib/module/live/components/LiveRoomSheet.js +1189 -0
  89. package/lib/module/live/components/LiveRoomSheet.js.map +1 -0
  90. package/lib/module/live/components/MiniRoomBar.js +154 -0
  91. package/lib/module/live/components/MiniRoomBar.js.map +1 -0
  92. package/lib/module/live/components/PanelHeader.js +52 -0
  93. package/lib/module/live/components/PanelHeader.js.map +1 -0
  94. package/lib/module/live/components/PodcastStreamPicker.js +1183 -0
  95. package/lib/module/live/components/PodcastStreamPicker.js.map +1 -0
  96. package/lib/module/live/components/RecordingCard.js +187 -0
  97. package/lib/module/live/components/RecordingCard.js.map +1 -0
  98. package/lib/module/live/components/RecordingsPanel.js +298 -0
  99. package/lib/module/live/components/RecordingsPanel.js.map +1 -0
  100. package/lib/module/live/components/RoomCard.js +548 -0
  101. package/lib/module/live/components/RoomCard.js.map +1 -0
  102. package/lib/module/live/components/StreamConfigModal.js +650 -0
  103. package/lib/module/live/components/StreamConfigModal.js.map +1 -0
  104. package/lib/module/live/components/StreamConfigPanel.js +816 -0
  105. package/lib/module/live/components/StreamConfigPanel.js.map +1 -0
  106. package/lib/module/live/context/LiveConfigContext.js +40 -0
  107. package/lib/module/live/context/LiveConfigContext.js.map +1 -0
  108. package/lib/module/live/context/LiveRoomContext.js +189 -0
  109. package/lib/module/live/context/LiveRoomContext.js.map +1 -0
  110. package/lib/module/live/hooks/useActiveSpeakers.js +31 -0
  111. package/lib/module/live/hooks/useActiveSpeakers.js.map +1 -0
  112. package/lib/module/live/hooks/useRoomAudio.js +125 -0
  113. package/lib/module/live/hooks/useRoomAudio.js.map +1 -0
  114. package/lib/module/live/hooks/useRoomConnection.js +173 -0
  115. package/lib/module/live/hooks/useRoomConnection.js.map +1 -0
  116. package/lib/module/live/hooks/useRoomManager.js +32 -0
  117. package/lib/module/live/hooks/useRoomManager.js.map +1 -0
  118. package/lib/module/live/hooks/useRoomUsers.js +46 -0
  119. package/lib/module/live/hooks/useRoomUsers.js.map +1 -0
  120. package/lib/module/live/index.js +38 -0
  121. package/lib/module/live/index.js.map +1 -0
  122. package/lib/module/live/services/livekitService.js +16 -0
  123. package/lib/module/live/services/livekitService.js.map +1 -0
  124. package/lib/module/live/services/spaceSocketService.js +176 -0
  125. package/lib/module/live/services/spaceSocketService.js.map +1 -0
  126. package/lib/module/live/services/spacesService.js +639 -0
  127. package/lib/module/live/services/spacesService.js.map +1 -0
  128. package/lib/module/live/types.js +4 -0
  129. package/lib/module/live/types.js.map +1 -0
  130. package/lib/module/live/validation.js +229 -0
  131. package/lib/module/live/validation.js.map +1 -0
  132. package/lib/module/package.json +1 -0
  133. package/lib/module/schema.js +99 -0
  134. package/lib/module/schema.js.map +1 -0
  135. package/{dist/types → lib/typescript/commonjs}/client.d.ts +36 -1
  136. package/lib/typescript/commonjs/client.d.ts.map +1 -0
  137. package/{dist/types → lib/typescript/commonjs}/errors.d.ts +1 -0
  138. package/lib/typescript/commonjs/errors.d.ts.map +1 -0
  139. package/lib/typescript/commonjs/index.d.ts +6 -0
  140. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  141. package/lib/typescript/commonjs/index.native.d.ts +3 -0
  142. package/lib/typescript/commonjs/index.native.d.ts.map +1 -0
  143. package/lib/typescript/commonjs/live/assets/icons/spaces-icon.d.ts +13 -0
  144. package/lib/typescript/commonjs/live/assets/icons/spaces-icon.d.ts.map +1 -0
  145. package/lib/typescript/commonjs/live/assets/icons/syra-icon.d.ts +13 -0
  146. package/lib/typescript/commonjs/live/assets/icons/syra-icon.d.ts.map +1 -0
  147. package/lib/typescript/commonjs/live/components/AnimatedPulse.d.ts +8 -0
  148. package/lib/typescript/commonjs/live/components/AnimatedPulse.d.ts.map +1 -0
  149. package/lib/typescript/commonjs/live/components/AnimatedSpeakerRing.d.ts +10 -0
  150. package/lib/typescript/commonjs/live/components/AnimatedSpeakerRing.d.ts.map +1 -0
  151. package/lib/typescript/commonjs/live/components/CreateRoomSheet.d.ts +26 -0
  152. package/lib/typescript/commonjs/live/components/CreateRoomSheet.d.ts.map +1 -0
  153. package/lib/typescript/commonjs/live/components/InsightsPanel.d.ts +11 -0
  154. package/lib/typescript/commonjs/live/components/InsightsPanel.d.ts.map +1 -0
  155. package/lib/typescript/commonjs/live/components/LiveRoomSheet.d.ts +11 -0
  156. package/lib/typescript/commonjs/live/components/LiveRoomSheet.d.ts.map +1 -0
  157. package/lib/typescript/commonjs/live/components/MiniRoomBar.d.ts +15 -0
  158. package/lib/typescript/commonjs/live/components/MiniRoomBar.d.ts.map +1 -0
  159. package/lib/typescript/commonjs/live/components/PanelHeader.d.ts +10 -0
  160. package/lib/typescript/commonjs/live/components/PanelHeader.d.ts.map +1 -0
  161. package/lib/typescript/commonjs/live/components/PodcastStreamPicker.d.ts +54 -0
  162. package/lib/typescript/commonjs/live/components/PodcastStreamPicker.d.ts.map +1 -0
  163. package/lib/typescript/commonjs/live/components/RecordingCard.d.ts +11 -0
  164. package/lib/typescript/commonjs/live/components/RecordingCard.d.ts.map +1 -0
  165. package/lib/typescript/commonjs/live/components/RecordingsPanel.d.ts +12 -0
  166. package/lib/typescript/commonjs/live/components/RecordingsPanel.d.ts.map +1 -0
  167. package/lib/typescript/commonjs/live/components/RoomCard.d.ts +38 -0
  168. package/lib/typescript/commonjs/live/components/RoomCard.d.ts.map +1 -0
  169. package/lib/typescript/commonjs/live/components/StreamConfigModal.d.ts +11 -0
  170. package/lib/typescript/commonjs/live/components/StreamConfigModal.d.ts.map +1 -0
  171. package/lib/typescript/commonjs/live/components/StreamConfigPanel.d.ts +13 -0
  172. package/lib/typescript/commonjs/live/components/StreamConfigPanel.d.ts.map +1 -0
  173. package/lib/typescript/commonjs/live/context/LiveConfigContext.d.ts +78 -0
  174. package/lib/typescript/commonjs/live/context/LiveConfigContext.d.ts.map +1 -0
  175. package/lib/typescript/commonjs/live/context/LiveRoomContext.d.ts +12 -0
  176. package/lib/typescript/commonjs/live/context/LiveRoomContext.d.ts.map +1 -0
  177. package/lib/typescript/commonjs/live/hooks/useActiveSpeakers.d.ts +3 -0
  178. package/lib/typescript/commonjs/live/hooks/useActiveSpeakers.d.ts.map +1 -0
  179. package/lib/typescript/commonjs/live/hooks/useRoomAudio.d.ts +16 -0
  180. package/lib/typescript/commonjs/live/hooks/useRoomAudio.d.ts.map +1 -0
  181. package/lib/typescript/commonjs/live/hooks/useRoomConnection.d.ts +29 -0
  182. package/lib/typescript/commonjs/live/hooks/useRoomConnection.d.ts.map +1 -0
  183. package/lib/typescript/commonjs/live/hooks/useRoomManager.d.ts +11 -0
  184. package/lib/typescript/commonjs/live/hooks/useRoomManager.d.ts.map +1 -0
  185. package/lib/typescript/commonjs/live/hooks/useRoomUsers.d.ts +5 -0
  186. package/lib/typescript/commonjs/live/hooks/useRoomUsers.d.ts.map +1 -0
  187. package/lib/typescript/commonjs/live/index.d.ts +24 -0
  188. package/lib/typescript/commonjs/live/index.d.ts.map +1 -0
  189. package/lib/typescript/commonjs/live/services/livekitService.d.ts +7 -0
  190. package/lib/typescript/commonjs/live/services/livekitService.d.ts.map +1 -0
  191. package/lib/typescript/commonjs/live/services/spaceSocketService.d.ts +69 -0
  192. package/lib/typescript/commonjs/live/services/spaceSocketService.d.ts.map +1 -0
  193. package/lib/typescript/commonjs/live/services/spacesService.d.ts +181 -0
  194. package/lib/typescript/commonjs/live/services/spacesService.d.ts.map +1 -0
  195. package/lib/typescript/commonjs/live/types.d.ts +100 -0
  196. package/lib/typescript/commonjs/live/types.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/live/validation.d.ts +658 -0
  198. package/lib/typescript/commonjs/live/validation.d.ts.map +1 -0
  199. package/lib/typescript/commonjs/package.json +1 -0
  200. package/{dist/types → lib/typescript/commonjs}/schema.d.ts +305 -0
  201. package/lib/typescript/commonjs/schema.d.ts.map +1 -0
  202. package/lib/typescript/module/client.d.ts +141 -0
  203. package/lib/typescript/module/client.d.ts.map +1 -0
  204. package/lib/typescript/module/errors.d.ts +9 -0
  205. package/lib/typescript/module/errors.d.ts.map +1 -0
  206. package/lib/typescript/module/index.d.ts +6 -0
  207. package/lib/typescript/module/index.d.ts.map +1 -0
  208. package/lib/typescript/module/index.native.d.ts +3 -0
  209. package/lib/typescript/module/index.native.d.ts.map +1 -0
  210. package/lib/typescript/module/live/assets/icons/spaces-icon.d.ts +13 -0
  211. package/lib/typescript/module/live/assets/icons/spaces-icon.d.ts.map +1 -0
  212. package/lib/typescript/module/live/assets/icons/syra-icon.d.ts +13 -0
  213. package/lib/typescript/module/live/assets/icons/syra-icon.d.ts.map +1 -0
  214. package/lib/typescript/module/live/components/AnimatedPulse.d.ts +8 -0
  215. package/lib/typescript/module/live/components/AnimatedPulse.d.ts.map +1 -0
  216. package/lib/typescript/module/live/components/AnimatedSpeakerRing.d.ts +10 -0
  217. package/lib/typescript/module/live/components/AnimatedSpeakerRing.d.ts.map +1 -0
  218. package/lib/typescript/module/live/components/CreateRoomSheet.d.ts +26 -0
  219. package/lib/typescript/module/live/components/CreateRoomSheet.d.ts.map +1 -0
  220. package/lib/typescript/module/live/components/InsightsPanel.d.ts +11 -0
  221. package/lib/typescript/module/live/components/InsightsPanel.d.ts.map +1 -0
  222. package/lib/typescript/module/live/components/LiveRoomSheet.d.ts +11 -0
  223. package/lib/typescript/module/live/components/LiveRoomSheet.d.ts.map +1 -0
  224. package/lib/typescript/module/live/components/MiniRoomBar.d.ts +15 -0
  225. package/lib/typescript/module/live/components/MiniRoomBar.d.ts.map +1 -0
  226. package/lib/typescript/module/live/components/PanelHeader.d.ts +10 -0
  227. package/lib/typescript/module/live/components/PanelHeader.d.ts.map +1 -0
  228. package/lib/typescript/module/live/components/PodcastStreamPicker.d.ts +54 -0
  229. package/lib/typescript/module/live/components/PodcastStreamPicker.d.ts.map +1 -0
  230. package/lib/typescript/module/live/components/RecordingCard.d.ts +11 -0
  231. package/lib/typescript/module/live/components/RecordingCard.d.ts.map +1 -0
  232. package/lib/typescript/module/live/components/RecordingsPanel.d.ts +12 -0
  233. package/lib/typescript/module/live/components/RecordingsPanel.d.ts.map +1 -0
  234. package/lib/typescript/module/live/components/RoomCard.d.ts +38 -0
  235. package/lib/typescript/module/live/components/RoomCard.d.ts.map +1 -0
  236. package/lib/typescript/module/live/components/StreamConfigModal.d.ts +11 -0
  237. package/lib/typescript/module/live/components/StreamConfigModal.d.ts.map +1 -0
  238. package/lib/typescript/module/live/components/StreamConfigPanel.d.ts +13 -0
  239. package/lib/typescript/module/live/components/StreamConfigPanel.d.ts.map +1 -0
  240. package/lib/typescript/module/live/context/LiveConfigContext.d.ts +78 -0
  241. package/lib/typescript/module/live/context/LiveConfigContext.d.ts.map +1 -0
  242. package/lib/typescript/module/live/context/LiveRoomContext.d.ts +12 -0
  243. package/lib/typescript/module/live/context/LiveRoomContext.d.ts.map +1 -0
  244. package/lib/typescript/module/live/hooks/useActiveSpeakers.d.ts +3 -0
  245. package/lib/typescript/module/live/hooks/useActiveSpeakers.d.ts.map +1 -0
  246. package/lib/typescript/module/live/hooks/useRoomAudio.d.ts +16 -0
  247. package/lib/typescript/module/live/hooks/useRoomAudio.d.ts.map +1 -0
  248. package/lib/typescript/module/live/hooks/useRoomConnection.d.ts +29 -0
  249. package/lib/typescript/module/live/hooks/useRoomConnection.d.ts.map +1 -0
  250. package/lib/typescript/module/live/hooks/useRoomManager.d.ts +11 -0
  251. package/lib/typescript/module/live/hooks/useRoomManager.d.ts.map +1 -0
  252. package/lib/typescript/module/live/hooks/useRoomUsers.d.ts +5 -0
  253. package/lib/typescript/module/live/hooks/useRoomUsers.d.ts.map +1 -0
  254. package/lib/typescript/module/live/index.d.ts +24 -0
  255. package/lib/typescript/module/live/index.d.ts.map +1 -0
  256. package/lib/typescript/module/live/services/livekitService.d.ts +7 -0
  257. package/lib/typescript/module/live/services/livekitService.d.ts.map +1 -0
  258. package/lib/typescript/module/live/services/spaceSocketService.d.ts +69 -0
  259. package/lib/typescript/module/live/services/spaceSocketService.d.ts.map +1 -0
  260. package/lib/typescript/module/live/services/spacesService.d.ts +181 -0
  261. package/lib/typescript/module/live/services/spacesService.d.ts.map +1 -0
  262. package/lib/typescript/module/live/types.d.ts +100 -0
  263. package/lib/typescript/module/live/types.d.ts.map +1 -0
  264. package/lib/typescript/module/live/validation.d.ts +658 -0
  265. package/lib/typescript/module/live/validation.d.ts.map +1 -0
  266. package/lib/typescript/module/package.json +1 -0
  267. package/lib/typescript/module/schema.d.ts +1072 -0
  268. package/lib/typescript/module/schema.d.ts.map +1 -0
  269. package/package.json +133 -21
  270. package/src/client.test.ts +185 -0
  271. package/src/client.ts +125 -0
  272. package/src/index.native.ts +2 -0
  273. package/src/index.ts +4 -0
  274. package/src/live/assets/icons/spaces-icon.tsx +15 -0
  275. package/src/live/assets/icons/syra-icon.tsx +13 -0
  276. package/src/live/assets/sounds/intro.mp3 +0 -0
  277. package/src/live/components/AnimatedPulse.tsx +52 -0
  278. package/src/live/components/AnimatedSpeakerRing.tsx +101 -0
  279. package/src/live/components/CreateRoomSheet.tsx +654 -0
  280. package/src/live/components/InsightsPanel.tsx +202 -0
  281. package/src/live/components/LiveRoomSheet.tsx +969 -0
  282. package/src/live/components/MiniRoomBar.tsx +166 -0
  283. package/src/live/components/PanelHeader.tsx +36 -0
  284. package/src/live/components/PodcastStreamPicker.tsx +1155 -0
  285. package/src/live/components/RecordingCard.tsx +154 -0
  286. package/src/live/components/RecordingsPanel.tsx +251 -0
  287. package/src/live/components/RoomCard.tsx +494 -0
  288. package/src/live/components/StreamConfigModal.tsx +600 -0
  289. package/src/live/components/StreamConfigPanel.tsx +729 -0
  290. package/src/live/context/LiveConfigContext.tsx +96 -0
  291. package/src/live/context/LiveRoomContext.tsx +235 -0
  292. package/src/live/hooks/useActiveSpeakers.ts +39 -0
  293. package/src/live/hooks/useRoomAudio.ts +103 -0
  294. package/src/live/hooks/useRoomConnection.ts +162 -0
  295. package/src/live/hooks/useRoomManager.ts +17 -0
  296. package/src/live/hooks/useRoomUsers.ts +52 -0
  297. package/src/live/index.ts +92 -0
  298. package/src/live/services/livekitService.ts +11 -0
  299. package/src/live/services/spaceSocketService.ts +136 -0
  300. package/src/live/services/spacesService.ts +692 -0
  301. package/src/live/types.ts +119 -0
  302. package/src/live/validation.ts +279 -0
  303. package/src/schema.ts +34 -0
  304. package/dist/cjs/client.js +0 -185
  305. package/dist/cjs/errors.js +0 -16
  306. package/dist/cjs/index.js +0 -14
  307. package/dist/cjs/package.json +0 -3
  308. package/dist/cjs/schema.js +0 -62
  309. package/dist/esm/client.js +0 -181
  310. package/dist/esm/errors.js +0 -12
  311. package/dist/esm/index.js +0 -3
  312. package/dist/esm/package.json +0 -3
  313. package/dist/esm/schema.js +0 -59
  314. package/dist/types/index.d.ts +0 -5
@@ -0,0 +1,1183 @@
1
+ "use strict";
2
+
3
+ import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
+ import { View, Text, StyleSheet, TouchableOpacity, TextInput, FlatList, ActivityIndicator, Linking } from 'react-native';
5
+ import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
6
+ import { useLiveConfig } from "../context/LiveConfigContext.js";
7
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
+ const SEARCH_DEBOUNCE_MS = 350;
9
+
10
+ /** Public Syra web base — the "Open in Syra" affordance links to `/podcasts/:id`. */
11
+ const SYRA_WEB_BASE_URL = 'https://syra.fm';
12
+
13
+ /**
14
+ * English source copy for every user-facing string in the picker. Hosts with an
15
+ * i18n layer (the Mention frontend) inject `t` via `useLiveConfig()` and these
16
+ * are never read; hosts without one (the standalone live-rooms app) fall back to
17
+ * these. Keys mirror the `agora.podcastStream.*` entries in the app locale files.
18
+ */
19
+ const DEFAULT_STRINGS = {
20
+ 'agora.podcastStream.disclaimer': "You're responsible for having the rights to stream this audio into your room.",
21
+ 'agora.podcastStream.searchPlaceholder': 'Search podcasts',
22
+ 'agora.podcastStream.searchHint': 'Search for a podcast to stream',
23
+ 'agora.podcastStream.pinnedTitle': 'Stream my pinned podcast',
24
+ 'agora.podcastStream.emptyShows': 'No podcasts found',
25
+ 'agora.podcastStream.emptyEpisodes': 'No episodes found',
26
+ 'agora.podcastStream.errorShows': "Couldn't load podcasts. Check your connection and try again.",
27
+ 'agora.podcastStream.errorEpisodes': "Couldn't load episodes. Check your connection and try again.",
28
+ 'agora.podcastStream.retry': 'Retry',
29
+ 'agora.podcastStream.openInSyra': 'Open in Syra',
30
+ 'agora.podcastStream.openFailed': "Couldn't open Syra",
31
+ 'agora.podcastStream.addToQueue': 'Add to queue',
32
+ 'agora.podcastStream.removeFromQueue': 'Remove from queue',
33
+ 'agora.podcastStream.playQueue': 'Play episodes',
34
+ 'agora.podcastStream.clearQueue': 'Clear',
35
+ // Music (listening party). Streaming a full track into a room is a broadcast —
36
+ // the disclaimer makes the host's rights responsibility explicit.
37
+ 'agora.musicStream.disclaimer': "You're responsible for having the rights to broadcast this music into your room.",
38
+ 'agora.musicStream.searchPlaceholder': 'Search music',
39
+ 'agora.musicStream.searchHint': 'Search for a track to play',
40
+ 'agora.musicStream.empty': 'No tracks found',
41
+ 'agora.musicStream.error': "Couldn't load music. Check your connection and try again.",
42
+ 'agora.musicStream.retry': 'Retry',
43
+ 'agora.musicStream.addToQueue': 'Add to queue',
44
+ 'agora.musicStream.removeFromQueue': 'Remove from queue',
45
+ 'agora.musicStream.playQueue': 'Play tracks',
46
+ 'agora.musicStream.clearQueue': 'Clear'
47
+ };
48
+
49
+ /** One episode selected for the up-next queue. The show id is always known here. */
50
+
51
+ function formatDuration(seconds) {
52
+ if (!seconds || seconds <= 0) return '';
53
+ const total = Math.floor(seconds);
54
+ const hours = Math.floor(total / 3600);
55
+ const minutes = Math.floor(total % 3600 / 60);
56
+ const secs = total % 60;
57
+ const paddedSecs = String(secs).padStart(2, '0');
58
+ if (hours > 0) {
59
+ return `${hours}:${String(minutes).padStart(2, '0')}:${paddedSecs}`;
60
+ }
61
+ return `${minutes}:${paddedSecs}`;
62
+ }
63
+ function formatDate(iso) {
64
+ if (!iso) return '';
65
+ const date = new Date(iso);
66
+ if (Number.isNaN(date.getTime())) return '';
67
+ return date.toLocaleDateString(undefined, {
68
+ year: 'numeric',
69
+ month: 'short',
70
+ day: 'numeric'
71
+ });
72
+ }
73
+ const ShowRow = /*#__PURE__*/memo(function ShowRow({
74
+ show,
75
+ theme,
76
+ AvatarComponent,
77
+ onSelect
78
+ }) {
79
+ return /*#__PURE__*/_jsxs(TouchableOpacity, {
80
+ style: styles.row,
81
+ activeOpacity: 0.7,
82
+ onPress: () => onSelect(show),
83
+ children: [/*#__PURE__*/_jsx(AvatarComponent, {
84
+ size: 44,
85
+ source: show.artworkUrl,
86
+ shape: "squircle"
87
+ }), /*#__PURE__*/_jsxs(View, {
88
+ style: styles.rowText,
89
+ children: [/*#__PURE__*/_jsx(Text, {
90
+ style: [styles.rowTitle, {
91
+ color: theme.colors.text
92
+ }],
93
+ numberOfLines: 1,
94
+ children: show.title
95
+ }), !!show.author && /*#__PURE__*/_jsx(Text, {
96
+ style: [styles.rowSubtitle, {
97
+ color: theme.colors.textSecondary
98
+ }],
99
+ numberOfLines: 1,
100
+ children: show.author
101
+ })]
102
+ }), /*#__PURE__*/_jsx(MaterialCommunityIcons, {
103
+ name: "chevron-right",
104
+ size: 22,
105
+ color: theme.colors.textSecondary
106
+ })]
107
+ });
108
+ });
109
+ const EpisodeRow = /*#__PURE__*/memo(function EpisodeRow({
110
+ episode,
111
+ theme,
112
+ AvatarComponent,
113
+ onSelect,
114
+ queueEnabled,
115
+ isQueued,
116
+ onToggleQueue,
117
+ queueActionLabel
118
+ }) {
119
+ const meta = [formatDuration(episode.durationSec), formatDate(episode.publishedAt)].filter(Boolean).join(' · ');
120
+ return /*#__PURE__*/_jsxs(View, {
121
+ style: styles.row,
122
+ children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
123
+ style: styles.rowMain,
124
+ activeOpacity: 0.7,
125
+ onPress: () => onSelect(episode),
126
+ children: [/*#__PURE__*/_jsx(AvatarComponent, {
127
+ size: 44,
128
+ source: episode.artworkUrl,
129
+ shape: "squircle"
130
+ }), /*#__PURE__*/_jsxs(View, {
131
+ style: styles.rowText,
132
+ children: [/*#__PURE__*/_jsx(Text, {
133
+ style: [styles.rowTitle, {
134
+ color: theme.colors.text
135
+ }],
136
+ numberOfLines: 2,
137
+ children: episode.title
138
+ }), !!meta && /*#__PURE__*/_jsx(Text, {
139
+ style: [styles.rowSubtitle, {
140
+ color: theme.colors.textSecondary
141
+ }],
142
+ numberOfLines: 1,
143
+ children: meta
144
+ })]
145
+ }), /*#__PURE__*/_jsx(MaterialCommunityIcons, {
146
+ name: "play-circle",
147
+ size: 26,
148
+ color: theme.colors.primary
149
+ })]
150
+ }), queueEnabled && /*#__PURE__*/_jsx(TouchableOpacity, {
151
+ style: styles.queueBtn,
152
+ activeOpacity: 0.7,
153
+ hitSlop: 8,
154
+ onPress: () => onToggleQueue(episode),
155
+ accessibilityRole: "button",
156
+ accessibilityLabel: queueActionLabel,
157
+ children: /*#__PURE__*/_jsx(MaterialCommunityIcons, {
158
+ name: isQueued ? 'check-circle' : 'plus-circle-outline',
159
+ size: 24,
160
+ color: isQueued ? theme.colors.primary : theme.colors.textSecondary
161
+ })
162
+ })]
163
+ });
164
+ });
165
+
166
+ /** Failed-request state (distinct from empty) with a Retry affordance. */
167
+ const ErrorState = /*#__PURE__*/memo(function ErrorState({
168
+ theme,
169
+ message,
170
+ retryLabel,
171
+ onRetry
172
+ }) {
173
+ return /*#__PURE__*/_jsxs(View, {
174
+ style: styles.stateBox,
175
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
176
+ name: "wifi-off",
177
+ size: 32,
178
+ color: theme.colors.textSecondary
179
+ }), /*#__PURE__*/_jsx(Text, {
180
+ style: [styles.stateText, {
181
+ color: theme.colors.textSecondary
182
+ }],
183
+ children: message
184
+ }), /*#__PURE__*/_jsxs(TouchableOpacity, {
185
+ style: [styles.retryBtn, {
186
+ borderColor: theme.colors.border
187
+ }],
188
+ activeOpacity: 0.7,
189
+ onPress: onRetry,
190
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
191
+ name: "refresh",
192
+ size: 16,
193
+ color: theme.colors.primary
194
+ }), /*#__PURE__*/_jsx(Text, {
195
+ style: [styles.retryText, {
196
+ color: theme.colors.primary
197
+ }],
198
+ children: retryLabel
199
+ })]
200
+ })]
201
+ });
202
+ });
203
+
204
+ /**
205
+ * Self-contained two-level podcast picker for the live-room stream setup. Level 1
206
+ * is a debounced Syra show search; tapping a show drills into Level 2, its episode
207
+ * list. Tapping an episode reports `(syraPodcastId, episodeId)` to the parent — the
208
+ * picker owns NO room/stream logic. Ships inside @syra.fm/live, so it depends only
209
+ * on `useLiveConfig()` injection and never imports from a host app (`@/`).
210
+ *
211
+ * UX affordances (all backend-field-free): a host copyright disclaimer, an honest
212
+ * error+Retry state distinct from empty results, a one-tap "stream my pinned
213
+ * podcast" quick-start row (when the host exposes `getPinnedPodcast`), and an
214
+ * "Open in Syra" deep link on the episode-list header.
215
+ */
216
+ export function PodcastStreamPicker({
217
+ onSelectEpisode,
218
+ onStartQueue
219
+ }) {
220
+ const {
221
+ useTheme,
222
+ roomsService,
223
+ AvatarComponent,
224
+ toast,
225
+ t,
226
+ getPinnedPodcast
227
+ } = useLiveConfig();
228
+ const theme = useTheme();
229
+ const tr = useCallback(key => t ? t(key) : DEFAULT_STRINGS[key] ?? key, [t]);
230
+
231
+ // Up-next queue: only offered when the host wired the multi-episode start.
232
+ const queueEnabled = !!onStartQueue;
233
+ const [queued, setQueued] = useState([]);
234
+ const queuedIds = useMemo(() => new Set(queued.map(q => q.episodeId)), [queued]);
235
+
236
+ // Level 1 — show search
237
+ const [query, setQuery] = useState('');
238
+ const [shows, setShows] = useState([]);
239
+ const [showsNextOffset, setShowsNextOffset] = useState(0);
240
+ const [showsHasMore, setShowsHasMore] = useState(false);
241
+ const [showsLoading, setShowsLoading] = useState(false);
242
+ const [showsLoadingMore, setShowsLoadingMore] = useState(false);
243
+ const [showsError, setShowsError] = useState(false);
244
+ const showsSeqRef = useRef(0);
245
+ const debounceRef = useRef(null);
246
+
247
+ // Pinned-podcast quick-start (only when the host exposes profile media).
248
+ const [pinnedPodcast, setPinnedPodcast] = useState(null);
249
+
250
+ // Level 2 — episode list
251
+ const [selectedShow, setSelectedShow] = useState(null);
252
+ const [episodes, setEpisodes] = useState([]);
253
+ const [episodesNextOffset, setEpisodesNextOffset] = useState(0);
254
+ const [episodesHasMore, setEpisodesHasMore] = useState(false);
255
+ const [episodesLoading, setEpisodesLoading] = useState(false);
256
+ const [episodesLoadingMore, setEpisodesLoadingMore] = useState(false);
257
+ const [episodesError, setEpisodesError] = useState(false);
258
+ const episodesSeqRef = useRef(0);
259
+ const runSearch = useCallback(async (rawQuery, offset) => {
260
+ const trimmed = rawQuery.trim();
261
+ if (!trimmed) {
262
+ showsSeqRef.current += 1;
263
+ setShows([]);
264
+ setShowsHasMore(false);
265
+ setShowsNextOffset(0);
266
+ setShowsLoading(false);
267
+ setShowsLoadingMore(false);
268
+ setShowsError(false);
269
+ return;
270
+ }
271
+ const seq = offset === 0 ? showsSeqRef.current += 1 : showsSeqRef.current;
272
+ if (offset === 0) {
273
+ setShowsLoading(true);
274
+ setShowsError(false);
275
+ } else {
276
+ setShowsLoadingMore(true);
277
+ }
278
+ const result = await roomsService.searchPodcasts(trimmed, offset);
279
+ if (seq !== showsSeqRef.current) return; // superseded by a newer query
280
+
281
+ if (!result.ok) {
282
+ // Only replace the list on a fresh search; a load-more failure keeps the
283
+ // rows the host already has and simply stops paginating.
284
+ if (offset === 0) {
285
+ setShows([]);
286
+ setShowsError(true);
287
+ }
288
+ setShowsHasMore(false);
289
+ setShowsLoading(false);
290
+ setShowsLoadingMore(false);
291
+ return;
292
+ }
293
+ setShows(prev => offset === 0 ? result.items : [...prev, ...result.items]);
294
+ setShowsHasMore(result.hasMore);
295
+ setShowsNextOffset(result.offset + result.items.length);
296
+ setShowsLoading(false);
297
+ setShowsLoadingMore(false);
298
+ }, [roomsService]);
299
+ const handleQueryChange = useCallback(text => {
300
+ setQuery(text);
301
+ if (debounceRef.current) clearTimeout(debounceRef.current);
302
+ // Show the spinner for the debounce window so a fresh query never briefly
303
+ // renders the "No podcasts found" empty state before the request fires.
304
+ if (text.trim()) {
305
+ setShowsLoading(true);
306
+ setShowsError(false);
307
+ }
308
+ debounceRef.current = setTimeout(() => {
309
+ runSearch(text, 0);
310
+ }, SEARCH_DEBOUNCE_MS);
311
+ }, [runSearch]);
312
+ const handleClearQuery = useCallback(() => {
313
+ if (debounceRef.current) clearTimeout(debounceRef.current);
314
+ setQuery('');
315
+ runSearch('', 0);
316
+ }, [runSearch]);
317
+ const handleShowsEndReached = useCallback(() => {
318
+ if (showsLoading || showsLoadingMore || !showsHasMore) return;
319
+ runSearch(query, showsNextOffset);
320
+ }, [showsLoading, showsLoadingMore, showsHasMore, runSearch, query, showsNextOffset]);
321
+ const loadEpisodes = useCallback(async (syraPodcastId, offset) => {
322
+ const seq = offset === 0 ? episodesSeqRef.current += 1 : episodesSeqRef.current;
323
+ if (offset === 0) {
324
+ setEpisodesLoading(true);
325
+ setEpisodesError(false);
326
+ } else {
327
+ setEpisodesLoadingMore(true);
328
+ }
329
+ const result = await roomsService.getPodcastEpisodes(syraPodcastId, offset);
330
+ if (seq !== episodesSeqRef.current) return; // superseded by a newer show
331
+
332
+ if (!result.ok) {
333
+ if (offset === 0) {
334
+ setEpisodes([]);
335
+ setEpisodesError(true);
336
+ }
337
+ setEpisodesHasMore(false);
338
+ setEpisodesLoading(false);
339
+ setEpisodesLoadingMore(false);
340
+ return;
341
+ }
342
+ setEpisodes(prev => offset === 0 ? result.items : [...prev, ...result.items]);
343
+ setEpisodesHasMore(result.hasMore);
344
+ setEpisodesNextOffset(result.offset + result.items.length);
345
+ setEpisodesLoading(false);
346
+ setEpisodesLoadingMore(false);
347
+ }, [roomsService]);
348
+ const handleSelectShow = useCallback(show => {
349
+ episodesSeqRef.current += 1;
350
+ setSelectedShow(show);
351
+ setEpisodes([]);
352
+ setEpisodesHasMore(false);
353
+ setEpisodesNextOffset(0);
354
+ setEpisodesError(false);
355
+ loadEpisodes(show.syraPodcastId, 0);
356
+ }, [loadEpisodes]);
357
+ const handleSelectPinned = useCallback(() => {
358
+ if (!pinnedPodcast) return;
359
+ handleSelectShow({
360
+ syraPodcastId: pinnedPodcast.syraPodcastId,
361
+ title: pinnedPodcast.title ?? tr('agora.podcastStream.pinnedTitle'),
362
+ artworkUrl: pinnedPodcast.artworkUrl
363
+ });
364
+ }, [pinnedPodcast, handleSelectShow, tr]);
365
+ const handleBack = useCallback(() => {
366
+ episodesSeqRef.current += 1;
367
+ setSelectedShow(null);
368
+ setEpisodes([]);
369
+ setEpisodesHasMore(false);
370
+ setEpisodesNextOffset(0);
371
+ setEpisodesLoading(false);
372
+ setEpisodesLoadingMore(false);
373
+ setEpisodesError(false);
374
+ }, []);
375
+ const handleEpisodesEndReached = useCallback(() => {
376
+ if (!selectedShow || episodesLoading || episodesLoadingMore || !episodesHasMore) return;
377
+ loadEpisodes(selectedShow.syraPodcastId, episodesNextOffset);
378
+ }, [selectedShow, episodesLoading, episodesLoadingMore, episodesHasMore, loadEpisodes, episodesNextOffset]);
379
+ const handleSelectEpisode = useCallback(episode => {
380
+ if (!selectedShow) return;
381
+ onSelectEpisode(selectedShow.syraPodcastId, episode.episodeId);
382
+ }, [selectedShow, onSelectEpisode]);
383
+
384
+ // Toggle an episode in/out of the local up-next queue. Items keep their own
385
+ // show id, so a host can queue across multiple shows before launching.
386
+ const handleToggleQueue = useCallback(episode => {
387
+ if (!selectedShow) return;
388
+ const showId = selectedShow.syraPodcastId;
389
+ setQueued(prev => prev.some(q => q.episodeId === episode.episodeId) ? prev.filter(q => q.episodeId !== episode.episodeId) : [...prev, {
390
+ syraPodcastId: showId,
391
+ episodeId: episode.episodeId
392
+ }]);
393
+ }, [selectedShow]);
394
+ const handleClearQueue = useCallback(() => setQueued([]), []);
395
+ const handleStartQueue = useCallback(() => {
396
+ if (queued.length === 0) return;
397
+ onStartQueue?.(queued);
398
+ setQueued([]);
399
+ }, [queued, onStartQueue]);
400
+ const handleOpenInSyra = useCallback(() => {
401
+ if (!selectedShow) return;
402
+ Linking.openURL(`${SYRA_WEB_BASE_URL}/podcasts/${selectedShow.syraPodcastId}`).catch(() => toast.error(tr('agora.podcastStream.openFailed')));
403
+ }, [selectedShow, toast, tr]);
404
+
405
+ // Resolve the viewer's pinned podcast once on mount (host-provided; optional).
406
+ useEffect(() => {
407
+ if (!getPinnedPodcast) return;
408
+ let cancelled = false;
409
+ getPinnedPodcast().then(podcast => {
410
+ if (!cancelled) setPinnedPodcast(podcast);
411
+ }, () => {
412
+ if (!cancelled) setPinnedPodcast(null);
413
+ });
414
+ return () => {
415
+ cancelled = true;
416
+ };
417
+ }, [getPinnedPodcast]);
418
+
419
+ // Cancel any pending debounced search when the picker unmounts.
420
+ useEffect(() => {
421
+ return () => {
422
+ if (debounceRef.current) clearTimeout(debounceRef.current);
423
+ };
424
+ }, []);
425
+ const hasQuery = query.trim().length > 0;
426
+ const showQueueFooter = queueEnabled && queued.length > 0;
427
+ const listContentStyle = showQueueFooter ? [styles.listContent, styles.listContentWithFooter] : styles.listContent;
428
+
429
+ // Floats over the bottom of either level; queued items persist across shows
430
+ // so the host can review/launch after adding from multiple shows.
431
+ const queueFooter = showQueueFooter ? /*#__PURE__*/_jsxs(View, {
432
+ style: [styles.queueFooter, {
433
+ backgroundColor: theme.colors.background,
434
+ borderTopColor: theme.colors.border
435
+ }],
436
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
437
+ style: styles.queueClearBtn,
438
+ activeOpacity: 0.7,
439
+ hitSlop: 8,
440
+ onPress: handleClearQueue,
441
+ accessibilityRole: "button",
442
+ children: /*#__PURE__*/_jsx(Text, {
443
+ style: [styles.queueClearText, {
444
+ color: theme.colors.textSecondary
445
+ }],
446
+ children: tr('agora.podcastStream.clearQueue')
447
+ })
448
+ }), /*#__PURE__*/_jsxs(TouchableOpacity, {
449
+ style: [styles.queuePlayBtn, {
450
+ backgroundColor: theme.colors.primary
451
+ }],
452
+ activeOpacity: 0.85,
453
+ onPress: handleStartQueue,
454
+ accessibilityRole: "button",
455
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
456
+ name: "play",
457
+ size: 18,
458
+ color: "#FFFFFF"
459
+ }), /*#__PURE__*/_jsxs(Text, {
460
+ style: styles.queuePlayText,
461
+ children: [tr('agora.podcastStream.playQueue'), " (", queued.length, ")"]
462
+ })]
463
+ })]
464
+ }) : null;
465
+ if (selectedShow) {
466
+ return /*#__PURE__*/_jsxs(View, {
467
+ style: styles.container,
468
+ children: [/*#__PURE__*/_jsxs(View, {
469
+ style: styles.backHeader,
470
+ children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
471
+ style: styles.backHeaderMain,
472
+ activeOpacity: 0.7,
473
+ onPress: handleBack,
474
+ hitSlop: 8,
475
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
476
+ name: "chevron-left",
477
+ size: 24,
478
+ color: theme.colors.text
479
+ }), /*#__PURE__*/_jsx(Text, {
480
+ style: [styles.backTitle, {
481
+ color: theme.colors.text
482
+ }],
483
+ numberOfLines: 1,
484
+ children: selectedShow.title
485
+ })]
486
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
487
+ style: styles.openBtn,
488
+ activeOpacity: 0.7,
489
+ onPress: handleOpenInSyra,
490
+ hitSlop: 8,
491
+ accessibilityRole: "link",
492
+ accessibilityLabel: tr('agora.podcastStream.openInSyra'),
493
+ children: /*#__PURE__*/_jsx(MaterialCommunityIcons, {
494
+ name: "open-in-new",
495
+ size: 20,
496
+ color: theme.colors.textSecondary
497
+ })
498
+ })]
499
+ }), episodesLoading ? /*#__PURE__*/_jsx(View, {
500
+ style: styles.stateBox,
501
+ children: /*#__PURE__*/_jsx(ActivityIndicator, {
502
+ size: "small",
503
+ color: theme.colors.primary
504
+ })
505
+ }) : episodesError ? /*#__PURE__*/_jsx(ErrorState, {
506
+ theme: theme,
507
+ message: tr('agora.podcastStream.errorEpisodes'),
508
+ retryLabel: tr('agora.podcastStream.retry'),
509
+ onRetry: () => loadEpisodes(selectedShow.syraPodcastId, 0)
510
+ }) : episodes.length === 0 ? /*#__PURE__*/_jsxs(View, {
511
+ style: styles.stateBox,
512
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
513
+ name: "playlist-remove",
514
+ size: 32,
515
+ color: theme.colors.textSecondary
516
+ }), /*#__PURE__*/_jsx(Text, {
517
+ style: [styles.stateText, {
518
+ color: theme.colors.textSecondary
519
+ }],
520
+ children: tr('agora.podcastStream.emptyEpisodes')
521
+ })]
522
+ }) : /*#__PURE__*/_jsx(FlatList, {
523
+ data: episodes,
524
+ keyExtractor: item => item.episodeId,
525
+ renderItem: ({
526
+ item
527
+ }) => /*#__PURE__*/_jsx(EpisodeRow, {
528
+ episode: item,
529
+ theme: theme,
530
+ AvatarComponent: AvatarComponent,
531
+ onSelect: handleSelectEpisode,
532
+ queueEnabled: queueEnabled,
533
+ isQueued: queuedIds.has(item.episodeId),
534
+ onToggleQueue: handleToggleQueue,
535
+ queueActionLabel: tr(queuedIds.has(item.episodeId) ? 'agora.podcastStream.removeFromQueue' : 'agora.podcastStream.addToQueue')
536
+ }),
537
+ showsVerticalScrollIndicator: false,
538
+ keyboardShouldPersistTaps: "handled",
539
+ onEndReached: handleEpisodesEndReached,
540
+ onEndReachedThreshold: 0.4,
541
+ contentContainerStyle: listContentStyle,
542
+ ListFooterComponent: episodesLoadingMore ? /*#__PURE__*/_jsx(View, {
543
+ style: styles.footerLoader,
544
+ children: /*#__PURE__*/_jsx(ActivityIndicator, {
545
+ size: "small",
546
+ color: theme.colors.primary
547
+ })
548
+ }) : null
549
+ }), queueFooter]
550
+ });
551
+ }
552
+ return /*#__PURE__*/_jsxs(View, {
553
+ style: styles.container,
554
+ children: [/*#__PURE__*/_jsxs(View, {
555
+ style: styles.disclaimer,
556
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
557
+ name: "shield-alert-outline",
558
+ size: 15,
559
+ color: theme.colors.textSecondary
560
+ }), /*#__PURE__*/_jsx(Text, {
561
+ style: [styles.disclaimerText, {
562
+ color: theme.colors.textSecondary
563
+ }],
564
+ children: tr('agora.podcastStream.disclaimer')
565
+ })]
566
+ }), /*#__PURE__*/_jsx(View, {
567
+ style: styles.searchWrap,
568
+ children: /*#__PURE__*/_jsxs(View, {
569
+ style: [styles.searchRow, {
570
+ backgroundColor: `${theme.colors.card}80`,
571
+ borderColor: theme.colors.border
572
+ }],
573
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
574
+ name: "magnify",
575
+ size: 18,
576
+ color: theme.colors.textSecondary
577
+ }), /*#__PURE__*/_jsx(TextInput, {
578
+ style: [styles.searchInput, {
579
+ color: theme.colors.text
580
+ }],
581
+ placeholder: tr('agora.podcastStream.searchPlaceholder'),
582
+ placeholderTextColor: theme.colors.textSecondary,
583
+ value: query,
584
+ onChangeText: handleQueryChange,
585
+ autoCapitalize: "none",
586
+ autoCorrect: false,
587
+ returnKeyType: "search"
588
+ }), query.length > 0 && /*#__PURE__*/_jsx(TouchableOpacity, {
589
+ onPress: handleClearQuery,
590
+ hitSlop: 8,
591
+ children: /*#__PURE__*/_jsx(MaterialCommunityIcons, {
592
+ name: "close-circle",
593
+ size: 18,
594
+ color: theme.colors.textSecondary
595
+ })
596
+ })]
597
+ })
598
+ }), !hasQuery ? /*#__PURE__*/_jsxs(View, {
599
+ children: [pinnedPodcast && /*#__PURE__*/_jsxs(TouchableOpacity, {
600
+ style: [styles.pinnedRow, {
601
+ backgroundColor: `${theme.colors.primary}14`,
602
+ borderColor: theme.colors.border
603
+ }],
604
+ activeOpacity: 0.7,
605
+ onPress: handleSelectPinned,
606
+ children: [/*#__PURE__*/_jsx(View, {
607
+ style: [styles.pinnedIcon, {
608
+ backgroundColor: `${theme.colors.primary}22`
609
+ }],
610
+ children: /*#__PURE__*/_jsx(MaterialCommunityIcons, {
611
+ name: "flash",
612
+ size: 20,
613
+ color: theme.colors.primary
614
+ })
615
+ }), /*#__PURE__*/_jsxs(View, {
616
+ style: styles.rowText,
617
+ children: [/*#__PURE__*/_jsx(Text, {
618
+ style: [styles.rowTitle, {
619
+ color: theme.colors.text
620
+ }],
621
+ numberOfLines: 1,
622
+ children: tr('agora.podcastStream.pinnedTitle')
623
+ }), !!pinnedPodcast.title && /*#__PURE__*/_jsx(Text, {
624
+ style: [styles.rowSubtitle, {
625
+ color: theme.colors.textSecondary
626
+ }],
627
+ numberOfLines: 1,
628
+ children: pinnedPodcast.title
629
+ })]
630
+ }), /*#__PURE__*/_jsx(MaterialCommunityIcons, {
631
+ name: "chevron-right",
632
+ size: 22,
633
+ color: theme.colors.textSecondary
634
+ })]
635
+ }), /*#__PURE__*/_jsxs(View, {
636
+ style: styles.stateBox,
637
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
638
+ name: "podcast",
639
+ size: 32,
640
+ color: theme.colors.textSecondary
641
+ }), /*#__PURE__*/_jsx(Text, {
642
+ style: [styles.stateText, {
643
+ color: theme.colors.textSecondary
644
+ }],
645
+ children: tr('agora.podcastStream.searchHint')
646
+ })]
647
+ })]
648
+ }) : showsError ? /*#__PURE__*/_jsx(ErrorState, {
649
+ theme: theme,
650
+ message: tr('agora.podcastStream.errorShows'),
651
+ retryLabel: tr('agora.podcastStream.retry'),
652
+ onRetry: () => runSearch(query, 0)
653
+ }) : showsLoading ? /*#__PURE__*/_jsx(View, {
654
+ style: styles.stateBox,
655
+ children: /*#__PURE__*/_jsx(ActivityIndicator, {
656
+ size: "small",
657
+ color: theme.colors.primary
658
+ })
659
+ }) : shows.length === 0 ? /*#__PURE__*/_jsxs(View, {
660
+ style: styles.stateBox,
661
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
662
+ name: "magnify-close",
663
+ size: 32,
664
+ color: theme.colors.textSecondary
665
+ }), /*#__PURE__*/_jsx(Text, {
666
+ style: [styles.stateText, {
667
+ color: theme.colors.textSecondary
668
+ }],
669
+ children: tr('agora.podcastStream.emptyShows')
670
+ })]
671
+ }) : /*#__PURE__*/_jsx(FlatList, {
672
+ data: shows,
673
+ keyExtractor: item => item.syraPodcastId,
674
+ renderItem: ({
675
+ item
676
+ }) => /*#__PURE__*/_jsx(ShowRow, {
677
+ show: item,
678
+ theme: theme,
679
+ AvatarComponent: AvatarComponent,
680
+ onSelect: handleSelectShow
681
+ }),
682
+ showsVerticalScrollIndicator: false,
683
+ keyboardShouldPersistTaps: "handled",
684
+ onEndReached: handleShowsEndReached,
685
+ onEndReachedThreshold: 0.4,
686
+ contentContainerStyle: listContentStyle,
687
+ ListFooterComponent: showsLoadingMore ? /*#__PURE__*/_jsx(View, {
688
+ style: styles.footerLoader,
689
+ children: /*#__PURE__*/_jsx(ActivityIndicator, {
690
+ size: "small",
691
+ color: theme.colors.primary
692
+ })
693
+ }) : null
694
+ }), queueFooter]
695
+ });
696
+ }
697
+ const MusicTrackRow = /*#__PURE__*/memo(function MusicTrackRow({
698
+ track,
699
+ theme,
700
+ AvatarComponent,
701
+ onSelect,
702
+ isQueued,
703
+ onToggleQueue,
704
+ queueActionLabel
705
+ }) {
706
+ const meta = [track.artist, formatDuration(track.durationSec)].filter(Boolean).join(' · ');
707
+ return /*#__PURE__*/_jsxs(View, {
708
+ style: styles.row,
709
+ children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
710
+ style: styles.rowMain,
711
+ activeOpacity: 0.7,
712
+ onPress: () => onSelect(track),
713
+ children: [/*#__PURE__*/_jsx(AvatarComponent, {
714
+ size: 44,
715
+ source: track.artworkUrl,
716
+ shape: "squircle"
717
+ }), /*#__PURE__*/_jsxs(View, {
718
+ style: styles.rowText,
719
+ children: [/*#__PURE__*/_jsx(Text, {
720
+ style: [styles.rowTitle, {
721
+ color: theme.colors.text
722
+ }],
723
+ numberOfLines: 2,
724
+ children: track.title
725
+ }), !!meta && /*#__PURE__*/_jsx(Text, {
726
+ style: [styles.rowSubtitle, {
727
+ color: theme.colors.textSecondary
728
+ }],
729
+ numberOfLines: 1,
730
+ children: meta
731
+ })]
732
+ }), /*#__PURE__*/_jsx(MaterialCommunityIcons, {
733
+ name: "play-circle",
734
+ size: 26,
735
+ color: theme.colors.primary
736
+ })]
737
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
738
+ style: styles.queueBtn,
739
+ activeOpacity: 0.7,
740
+ hitSlop: 8,
741
+ onPress: () => onToggleQueue(track),
742
+ accessibilityRole: "button",
743
+ accessibilityLabel: queueActionLabel,
744
+ children: /*#__PURE__*/_jsx(MaterialCommunityIcons, {
745
+ name: isQueued ? 'check-circle' : 'plus-circle-outline',
746
+ size: 24,
747
+ color: isQueued ? theme.colors.primary : theme.colors.textSecondary
748
+ })
749
+ })]
750
+ });
751
+ });
752
+ /**
753
+ * Self-contained single-level music picker for the live-room "listening party".
754
+ * A debounced Syra catalog search; tapping a track reports its `trackId` to the
755
+ * parent (the picker owns NO room/stream logic and never sees an audio URL — the
756
+ * backend resolves the playable source server-side). Ships inside the shared
757
+ * package, so it depends only on `useLiveConfig()` injection and never imports
758
+ * from a host app (`@/`).
759
+ *
760
+ * Mirrors {@link PodcastStreamPicker}: a host copyright/broadcast disclaimer, an
761
+ * honest error+Retry state distinct from empty results, and an optional up-next
762
+ * queue (per-row "+" plus a floating "Play (N)" footer).
763
+ */
764
+ export function MusicPicker({
765
+ onSelectTrack,
766
+ onStartQueue
767
+ }) {
768
+ const {
769
+ useTheme,
770
+ roomsService,
771
+ AvatarComponent,
772
+ t
773
+ } = useLiveConfig();
774
+ const theme = useTheme();
775
+ const tr = useCallback(key => t ? t(key) : DEFAULT_STRINGS[key] ?? key, [t]);
776
+ const queueEnabled = !!onStartQueue;
777
+ const [queued, setQueued] = useState([]);
778
+ const queuedIds = useMemo(() => new Set(queued), [queued]);
779
+ const [query, setQuery] = useState('');
780
+ const [tracks, setTracks] = useState([]);
781
+ const [nextOffset, setNextOffset] = useState(0);
782
+ const [hasMore, setHasMore] = useState(false);
783
+ const [loading, setLoading] = useState(false);
784
+ const [loadingMore, setLoadingMore] = useState(false);
785
+ const [error, setError] = useState(false);
786
+ const seqRef = useRef(0);
787
+ const debounceRef = useRef(null);
788
+ const runSearch = useCallback(async (rawQuery, offset) => {
789
+ const trimmed = rawQuery.trim();
790
+ if (!trimmed) {
791
+ seqRef.current += 1;
792
+ setTracks([]);
793
+ setHasMore(false);
794
+ setNextOffset(0);
795
+ setLoading(false);
796
+ setLoadingMore(false);
797
+ setError(false);
798
+ return;
799
+ }
800
+ const seq = offset === 0 ? seqRef.current += 1 : seqRef.current;
801
+ if (offset === 0) {
802
+ setLoading(true);
803
+ setError(false);
804
+ } else {
805
+ setLoadingMore(true);
806
+ }
807
+ const result = await roomsService.searchMusic(trimmed, offset);
808
+ if (seq !== seqRef.current) return; // superseded by a newer query
809
+
810
+ if (!result.ok) {
811
+ if (offset === 0) {
812
+ setTracks([]);
813
+ setError(true);
814
+ }
815
+ setHasMore(false);
816
+ setLoading(false);
817
+ setLoadingMore(false);
818
+ return;
819
+ }
820
+ setTracks(prev => offset === 0 ? result.items : [...prev, ...result.items]);
821
+ setHasMore(result.hasMore);
822
+ setNextOffset(result.offset + result.items.length);
823
+ setLoading(false);
824
+ setLoadingMore(false);
825
+ }, [roomsService]);
826
+ const handleQueryChange = useCallback(text => {
827
+ setQuery(text);
828
+ if (debounceRef.current) clearTimeout(debounceRef.current);
829
+ if (text.trim()) {
830
+ setLoading(true);
831
+ setError(false);
832
+ }
833
+ debounceRef.current = setTimeout(() => {
834
+ runSearch(text, 0);
835
+ }, SEARCH_DEBOUNCE_MS);
836
+ }, [runSearch]);
837
+ const handleClearQuery = useCallback(() => {
838
+ if (debounceRef.current) clearTimeout(debounceRef.current);
839
+ setQuery('');
840
+ runSearch('', 0);
841
+ }, [runSearch]);
842
+ const handleEndReached = useCallback(() => {
843
+ if (loading || loadingMore || !hasMore) return;
844
+ runSearch(query, nextOffset);
845
+ }, [loading, loadingMore, hasMore, runSearch, query, nextOffset]);
846
+ const handleSelectTrack = useCallback(track => onSelectTrack(track.trackId), [onSelectTrack]);
847
+ const handleToggleQueue = useCallback(track => {
848
+ setQueued(prev => prev.includes(track.trackId) ? prev.filter(id => id !== track.trackId) : [...prev, track.trackId]);
849
+ }, []);
850
+ const handleClearQueue = useCallback(() => setQueued([]), []);
851
+ const handleStartQueue = useCallback(() => {
852
+ if (queued.length === 0) return;
853
+ onStartQueue?.(queued);
854
+ setQueued([]);
855
+ }, [queued, onStartQueue]);
856
+
857
+ // Cancel any pending debounced search when the picker unmounts.
858
+ useEffect(() => {
859
+ return () => {
860
+ if (debounceRef.current) clearTimeout(debounceRef.current);
861
+ };
862
+ }, []);
863
+ const hasQuery = query.trim().length > 0;
864
+ const showQueueFooter = queueEnabled && queued.length > 0;
865
+ const listContentStyle = showQueueFooter ? [styles.listContent, styles.listContentWithFooter] : styles.listContent;
866
+ const queueFooter = showQueueFooter ? /*#__PURE__*/_jsxs(View, {
867
+ style: [styles.queueFooter, {
868
+ backgroundColor: theme.colors.background,
869
+ borderTopColor: theme.colors.border
870
+ }],
871
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
872
+ style: styles.queueClearBtn,
873
+ activeOpacity: 0.7,
874
+ hitSlop: 8,
875
+ onPress: handleClearQueue,
876
+ accessibilityRole: "button",
877
+ children: /*#__PURE__*/_jsx(Text, {
878
+ style: [styles.queueClearText, {
879
+ color: theme.colors.textSecondary
880
+ }],
881
+ children: tr('agora.musicStream.clearQueue')
882
+ })
883
+ }), /*#__PURE__*/_jsxs(TouchableOpacity, {
884
+ style: [styles.queuePlayBtn, {
885
+ backgroundColor: theme.colors.primary
886
+ }],
887
+ activeOpacity: 0.85,
888
+ onPress: handleStartQueue,
889
+ accessibilityRole: "button",
890
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
891
+ name: "play",
892
+ size: 18,
893
+ color: "#FFFFFF"
894
+ }), /*#__PURE__*/_jsxs(Text, {
895
+ style: styles.queuePlayText,
896
+ children: [tr('agora.musicStream.playQueue'), " (", queued.length, ")"]
897
+ })]
898
+ })]
899
+ }) : null;
900
+ return /*#__PURE__*/_jsxs(View, {
901
+ style: styles.container,
902
+ children: [/*#__PURE__*/_jsxs(View, {
903
+ style: styles.disclaimer,
904
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
905
+ name: "shield-alert-outline",
906
+ size: 15,
907
+ color: theme.colors.textSecondary
908
+ }), /*#__PURE__*/_jsx(Text, {
909
+ style: [styles.disclaimerText, {
910
+ color: theme.colors.textSecondary
911
+ }],
912
+ children: tr('agora.musicStream.disclaimer')
913
+ })]
914
+ }), /*#__PURE__*/_jsx(View, {
915
+ style: styles.searchWrap,
916
+ children: /*#__PURE__*/_jsxs(View, {
917
+ style: [styles.searchRow, {
918
+ backgroundColor: `${theme.colors.card}80`,
919
+ borderColor: theme.colors.border
920
+ }],
921
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
922
+ name: "magnify",
923
+ size: 18,
924
+ color: theme.colors.textSecondary
925
+ }), /*#__PURE__*/_jsx(TextInput, {
926
+ style: [styles.searchInput, {
927
+ color: theme.colors.text
928
+ }],
929
+ placeholder: tr('agora.musicStream.searchPlaceholder'),
930
+ placeholderTextColor: theme.colors.textSecondary,
931
+ value: query,
932
+ onChangeText: handleQueryChange,
933
+ autoCapitalize: "none",
934
+ autoCorrect: false,
935
+ returnKeyType: "search"
936
+ }), query.length > 0 && /*#__PURE__*/_jsx(TouchableOpacity, {
937
+ onPress: handleClearQuery,
938
+ hitSlop: 8,
939
+ children: /*#__PURE__*/_jsx(MaterialCommunityIcons, {
940
+ name: "close-circle",
941
+ size: 18,
942
+ color: theme.colors.textSecondary
943
+ })
944
+ })]
945
+ })
946
+ }), !hasQuery ? /*#__PURE__*/_jsxs(View, {
947
+ style: styles.stateBox,
948
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
949
+ name: "music-note",
950
+ size: 32,
951
+ color: theme.colors.textSecondary
952
+ }), /*#__PURE__*/_jsx(Text, {
953
+ style: [styles.stateText, {
954
+ color: theme.colors.textSecondary
955
+ }],
956
+ children: tr('agora.musicStream.searchHint')
957
+ })]
958
+ }) : error ? /*#__PURE__*/_jsx(ErrorState, {
959
+ theme: theme,
960
+ message: tr('agora.musicStream.error'),
961
+ retryLabel: tr('agora.musicStream.retry'),
962
+ onRetry: () => runSearch(query, 0)
963
+ }) : loading ? /*#__PURE__*/_jsx(View, {
964
+ style: styles.stateBox,
965
+ children: /*#__PURE__*/_jsx(ActivityIndicator, {
966
+ size: "small",
967
+ color: theme.colors.primary
968
+ })
969
+ }) : tracks.length === 0 ? /*#__PURE__*/_jsxs(View, {
970
+ style: styles.stateBox,
971
+ children: [/*#__PURE__*/_jsx(MaterialCommunityIcons, {
972
+ name: "magnify-close",
973
+ size: 32,
974
+ color: theme.colors.textSecondary
975
+ }), /*#__PURE__*/_jsx(Text, {
976
+ style: [styles.stateText, {
977
+ color: theme.colors.textSecondary
978
+ }],
979
+ children: tr('agora.musicStream.empty')
980
+ })]
981
+ }) : /*#__PURE__*/_jsx(FlatList, {
982
+ data: tracks,
983
+ keyExtractor: item => item.trackId,
984
+ renderItem: ({
985
+ item
986
+ }) => /*#__PURE__*/_jsx(MusicTrackRow, {
987
+ track: item,
988
+ theme: theme,
989
+ AvatarComponent: AvatarComponent,
990
+ onSelect: handleSelectTrack,
991
+ isQueued: queuedIds.has(item.trackId),
992
+ onToggleQueue: handleToggleQueue,
993
+ queueActionLabel: tr(queuedIds.has(item.trackId) ? 'agora.musicStream.removeFromQueue' : 'agora.musicStream.addToQueue')
994
+ }),
995
+ showsVerticalScrollIndicator: false,
996
+ keyboardShouldPersistTaps: "handled",
997
+ onEndReached: handleEndReached,
998
+ onEndReachedThreshold: 0.4,
999
+ contentContainerStyle: listContentStyle,
1000
+ ListFooterComponent: loadingMore ? /*#__PURE__*/_jsx(View, {
1001
+ style: styles.footerLoader,
1002
+ children: /*#__PURE__*/_jsx(ActivityIndicator, {
1003
+ size: "small",
1004
+ color: theme.colors.primary
1005
+ })
1006
+ }) : null
1007
+ }), queueFooter]
1008
+ });
1009
+ }
1010
+ const styles = StyleSheet.create({
1011
+ container: {
1012
+ flex: 1
1013
+ },
1014
+ disclaimer: {
1015
+ flexDirection: 'row',
1016
+ alignItems: 'flex-start',
1017
+ gap: 8,
1018
+ paddingHorizontal: 16,
1019
+ paddingTop: 12
1020
+ },
1021
+ disclaimerText: {
1022
+ flex: 1,
1023
+ fontSize: 12,
1024
+ lineHeight: 16
1025
+ },
1026
+ searchWrap: {
1027
+ paddingHorizontal: 16,
1028
+ paddingTop: 12,
1029
+ paddingBottom: 8
1030
+ },
1031
+ searchRow: {
1032
+ flexDirection: 'row',
1033
+ alignItems: 'center',
1034
+ gap: 8,
1035
+ borderWidth: 1,
1036
+ borderRadius: 10,
1037
+ paddingHorizontal: 12,
1038
+ paddingVertical: 10
1039
+ },
1040
+ searchInput: {
1041
+ flex: 1,
1042
+ fontSize: 15,
1043
+ padding: 0
1044
+ },
1045
+ backHeader: {
1046
+ flexDirection: 'row',
1047
+ alignItems: 'center',
1048
+ paddingHorizontal: 12,
1049
+ paddingTop: 12,
1050
+ paddingBottom: 8
1051
+ },
1052
+ backHeaderMain: {
1053
+ flex: 1,
1054
+ flexDirection: 'row',
1055
+ alignItems: 'center',
1056
+ gap: 2
1057
+ },
1058
+ backTitle: {
1059
+ flex: 1,
1060
+ fontSize: 16,
1061
+ fontWeight: '600'
1062
+ },
1063
+ openBtn: {
1064
+ padding: 6,
1065
+ marginLeft: 4
1066
+ },
1067
+ listContent: {
1068
+ paddingBottom: 24
1069
+ },
1070
+ listContentWithFooter: {
1071
+ paddingBottom: 88
1072
+ },
1073
+ row: {
1074
+ flexDirection: 'row',
1075
+ alignItems: 'center',
1076
+ gap: 12,
1077
+ paddingHorizontal: 16,
1078
+ paddingVertical: 10
1079
+ },
1080
+ rowMain: {
1081
+ flex: 1,
1082
+ flexDirection: 'row',
1083
+ alignItems: 'center',
1084
+ gap: 12
1085
+ },
1086
+ queueBtn: {
1087
+ padding: 4
1088
+ },
1089
+ pinnedRow: {
1090
+ flexDirection: 'row',
1091
+ alignItems: 'center',
1092
+ gap: 12,
1093
+ marginHorizontal: 16,
1094
+ marginTop: 4,
1095
+ marginBottom: 8,
1096
+ paddingHorizontal: 12,
1097
+ paddingVertical: 10,
1098
+ borderWidth: 1,
1099
+ borderRadius: 12
1100
+ },
1101
+ pinnedIcon: {
1102
+ width: 44,
1103
+ height: 44,
1104
+ borderRadius: 12,
1105
+ alignItems: 'center',
1106
+ justifyContent: 'center'
1107
+ },
1108
+ rowText: {
1109
+ flex: 1,
1110
+ gap: 2
1111
+ },
1112
+ rowTitle: {
1113
+ fontSize: 15,
1114
+ fontWeight: '600'
1115
+ },
1116
+ rowSubtitle: {
1117
+ fontSize: 13
1118
+ },
1119
+ stateBox: {
1120
+ alignItems: 'center',
1121
+ justifyContent: 'center',
1122
+ gap: 10,
1123
+ paddingVertical: 40
1124
+ },
1125
+ stateText: {
1126
+ fontSize: 14,
1127
+ textAlign: 'center',
1128
+ paddingHorizontal: 32
1129
+ },
1130
+ retryBtn: {
1131
+ flexDirection: 'row',
1132
+ alignItems: 'center',
1133
+ gap: 6,
1134
+ borderWidth: 1,
1135
+ borderRadius: 10,
1136
+ paddingHorizontal: 16,
1137
+ paddingVertical: 8,
1138
+ marginTop: 4
1139
+ },
1140
+ retryText: {
1141
+ fontSize: 14,
1142
+ fontWeight: '600'
1143
+ },
1144
+ footerLoader: {
1145
+ paddingVertical: 16
1146
+ },
1147
+ queueFooter: {
1148
+ position: 'absolute',
1149
+ left: 0,
1150
+ right: 0,
1151
+ bottom: 0,
1152
+ flexDirection: 'row',
1153
+ alignItems: 'center',
1154
+ gap: 12,
1155
+ paddingHorizontal: 16,
1156
+ paddingTop: 12,
1157
+ paddingBottom: 16,
1158
+ borderTopWidth: 1
1159
+ },
1160
+ queueClearBtn: {
1161
+ paddingVertical: 8,
1162
+ paddingHorizontal: 4
1163
+ },
1164
+ queueClearText: {
1165
+ fontSize: 14,
1166
+ fontWeight: '600'
1167
+ },
1168
+ queuePlayBtn: {
1169
+ flex: 1,
1170
+ flexDirection: 'row',
1171
+ alignItems: 'center',
1172
+ justifyContent: 'center',
1173
+ gap: 8,
1174
+ paddingVertical: 12,
1175
+ borderRadius: 12
1176
+ },
1177
+ queuePlayText: {
1178
+ color: '#FFFFFF',
1179
+ fontSize: 15,
1180
+ fontWeight: '700'
1181
+ }
1182
+ });
1183
+ //# sourceMappingURL=PodcastStreamPicker.js.map