@ozdao/martyrs 0.2.492 → 0.2.494

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 (341) hide show
  1. package/dist/_virtual/index.cjs +4 -4
  2. package/dist/_virtual/index.js +4 -4
  3. package/dist/_virtual/index2.cjs +4 -4
  4. package/dist/_virtual/index2.js +4 -4
  5. package/dist/builder.cjs +53 -90
  6. package/dist/builder.js +54 -91
  7. package/dist/{crud-B-kQw3Z5.cjs → crud-JN_LFj01.cjs} +3 -0
  8. package/dist/{crud-Cwx5VlSm.js → crud-sE7GLPbj.js} +3 -0
  9. package/dist/globals.server.cjs +322 -3
  10. package/dist/globals.server.js +303 -1
  11. package/dist/{globals.verifier-D68mHEBl.cjs → globals.verifier-C0zj_LLo.cjs} +8 -1
  12. package/dist/{globals.verifier-CWFz5Gh2.js → globals.verifier-DFqKQ7hK.js} +8 -1
  13. package/dist/inventory.server.cjs +2 -2
  14. package/dist/inventory.server.js +2 -2
  15. package/dist/{main-SZQ1QjeP.js → main-CJm5myDI.js} +631 -607
  16. package/dist/{main-MzmGbSxs.cjs → main-DTaE01lg.cjs} +6 -6
  17. package/dist/martyrs/src/components/Calendar/Calendar.vue2.cjs +1 -1
  18. package/dist/martyrs/src/components/Calendar/Calendar.vue2.cjs.map +1 -1
  19. package/dist/martyrs/src/components/Calendar/Calendar.vue2.js +1 -1
  20. package/dist/martyrs/src/components/Calendar/Calendar.vue2.js.map +1 -1
  21. package/dist/martyrs/src/components/Feed/Feed.vue.cjs +33 -7
  22. package/dist/martyrs/src/components/Feed/Feed.vue.cjs.map +1 -1
  23. package/dist/martyrs/src/components/Feed/Feed.vue.js +33 -7
  24. package/dist/martyrs/src/components/Feed/Feed.vue.js.map +1 -1
  25. package/dist/martyrs/src/components/Field/{Field.vue2.cjs → Field.vue.cjs} +2 -2
  26. package/dist/martyrs/src/components/Field/{Field.vue2.js.map → Field.vue.cjs.map} +1 -1
  27. package/dist/martyrs/src/components/Field/{Field.vue2.js → Field.vue.js} +2 -2
  28. package/dist/martyrs/src/components/Field/Field.vue.js.map +1 -0
  29. package/dist/martyrs/src/components/FieldBig/FieldBig.vue.cjs +1 -1
  30. package/dist/martyrs/src/components/FieldBig/FieldBig.vue.js +1 -1
  31. package/dist/martyrs/src/components/FieldTags/FieldTags.vue.cjs +1 -1
  32. package/dist/martyrs/src/components/FieldTags/FieldTags.vue.js +1 -1
  33. package/dist/martyrs/src/components/Menu/{Menu.vue.cjs → Menu.vue2.cjs} +2 -2
  34. package/dist/martyrs/src/components/Menu/Menu.vue2.cjs.map +1 -0
  35. package/dist/martyrs/src/components/Menu/{Menu.vue.js → Menu.vue2.js} +2 -2
  36. package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +1 -0
  37. package/dist/martyrs/src/components/Menu/MenuItem.vue.js +2 -2
  38. package/dist/martyrs/src/components/Menu/MenuItem.vue.js.map +1 -1
  39. package/dist/martyrs/src/components/PhotoViewer/PhotoViewer.vue.js +4 -4
  40. package/dist/martyrs/src/modules/auth/views/components/pages/EnterCode.vue.cjs +1 -1
  41. package/dist/martyrs/src/modules/auth/views/components/pages/EnterCode.vue.js +1 -1
  42. package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.cjs +1 -1
  43. package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +1 -1
  44. package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.cjs +1 -1
  45. package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +1 -1
  46. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +2 -2
  47. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +2 -2
  48. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.cjs +1 -1
  49. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.js +1 -1
  50. package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.cjs +1 -1
  51. package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +1 -1
  52. package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.cjs +1 -1
  53. package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +1 -1
  54. package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.cjs +1 -1
  55. package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +1 -1
  56. package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.cjs +1 -1
  57. package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.js +1 -1
  58. package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.cjs +2 -2
  59. package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.js +2 -2
  60. package/dist/martyrs/src/modules/constructor/components/elements/Card.vue.cjs +1 -1
  61. package/dist/martyrs/src/modules/constructor/components/elements/Card.vue.js +1 -1
  62. package/dist/martyrs/src/modules/constructor/components/elements/Embed.vue.cjs +1 -1
  63. package/dist/martyrs/src/modules/constructor/components/elements/Embed.vue.js +1 -1
  64. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.cjs +1 -1
  65. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +1 -1
  66. package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.cjs +1 -1
  67. package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js +1 -1
  68. package/dist/martyrs/src/modules/events/components/pages/Event.vue.cjs +1 -1
  69. package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +1 -1
  70. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.cjs +1 -1
  71. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +1 -1
  72. package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.cjs +1 -1
  73. package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.js +1 -1
  74. package/dist/martyrs/src/modules/globals/views/components/blocks/BlockSearch.vue.cjs +1 -1
  75. package/dist/martyrs/src/modules/globals/views/components/blocks/BlockSearch.vue.js +1 -1
  76. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs +5 -1
  77. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs.map +1 -1
  78. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js +5 -1
  79. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js.map +1 -1
  80. package/dist/martyrs/src/modules/icons/entities/IconTime.vue.cjs +2 -2
  81. package/dist/martyrs/src/modules/icons/entities/IconTime.vue.js +2 -2
  82. package/dist/martyrs/src/modules/icons/navigation/IconChevronLeft.vue.cjs +2 -2
  83. package/dist/martyrs/src/modules/icons/navigation/IconChevronLeft.vue.js +2 -2
  84. package/dist/martyrs/src/modules/icons/navigation/IconChevronRight.vue.cjs +2 -2
  85. package/dist/martyrs/src/modules/icons/navigation/IconChevronRight.vue.js +2 -2
  86. package/dist/martyrs/src/modules/icons/pages/IconsPage.vue.js +6 -6
  87. package/dist/martyrs/src/modules/icons/pages/IconsPage.vue.js.map +1 -1
  88. package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.cjs +1 -1
  89. package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.js +1 -1
  90. package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.cjs +1 -1
  91. package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js +1 -1
  92. package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.cjs +1 -1
  93. package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.cjs +1 -1
  94. package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js +1 -1
  95. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.cjs +22 -15
  96. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.cjs.map +1 -1
  97. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js +23 -16
  98. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js.map +1 -1
  99. package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.cjs +2 -2
  100. package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.cjs.map +1 -1
  101. package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.js +2 -2
  102. package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.js.map +1 -1
  103. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.cjs +31 -13
  104. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.cjs.map +1 -1
  105. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js +33 -15
  106. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js.map +1 -1
  107. package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.cjs +39 -22
  108. package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.cjs.map +1 -1
  109. package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js +39 -22
  110. package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js.map +1 -1
  111. package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.cjs +1 -1
  112. package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.js +1 -1
  113. package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.cjs +1 -1
  114. package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.js +1 -1
  115. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.cjs +385 -125
  116. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.cjs.map +1 -1
  117. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js +391 -131
  118. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js.map +1 -1
  119. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.cjs +24 -7
  120. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.cjs.map +1 -1
  121. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js +25 -8
  122. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js.map +1 -1
  123. package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.cjs +99 -87
  124. package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.cjs.map +1 -1
  125. package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js +111 -99
  126. package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js.map +1 -1
  127. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.cjs +21 -0
  128. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.cjs.map +1 -0
  129. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js +21 -0
  130. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js.map +1 -0
  131. package/dist/martyrs/src/modules/music/components/pages/Album.vue.cjs +442 -210
  132. package/dist/martyrs/src/modules/music/components/pages/Album.vue.cjs.map +1 -1
  133. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +445 -213
  134. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js.map +1 -1
  135. package/dist/martyrs/src/modules/music/components/pages/Artist.vue.cjs +92 -117
  136. package/dist/martyrs/src/modules/music/components/pages/Artist.vue.cjs.map +1 -1
  137. package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js +93 -118
  138. package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js.map +1 -1
  139. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.cjs +72 -113
  140. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.cjs.map +1 -1
  141. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js +78 -119
  142. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js.map +1 -1
  143. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.cjs +15 -12
  144. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.cjs.map +1 -1
  145. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js +15 -12
  146. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js.map +1 -1
  147. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.cjs +558 -429
  148. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.cjs.map +1 -1
  149. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +560 -431
  150. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js.map +1 -1
  151. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.cjs +146 -284
  152. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.cjs.map +1 -1
  153. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js +149 -287
  154. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js.map +1 -1
  155. package/dist/martyrs/src/modules/music/components/pages/Track.vue.cjs +460 -63
  156. package/dist/martyrs/src/modules/music/components/pages/Track.vue.cjs.map +1 -1
  157. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +462 -65
  158. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js.map +1 -1
  159. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.cjs +126 -136
  160. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.cjs.map +1 -1
  161. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js +129 -139
  162. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js.map +1 -1
  163. package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.cjs +18 -15
  164. package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.cjs.map +1 -1
  165. package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.js +18 -15
  166. package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.js.map +1 -1
  167. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.cjs +28 -23
  168. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.cjs.map +1 -1
  169. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js +29 -24
  170. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js.map +1 -1
  171. package/dist/martyrs/src/modules/music/music.client.cjs +3 -6
  172. package/dist/martyrs/src/modules/music/music.client.cjs.map +1 -1
  173. package/dist/martyrs/src/modules/music/music.client.js +9 -12
  174. package/dist/martyrs/src/modules/music/music.client.js.map +1 -1
  175. package/dist/martyrs/src/modules/music/router/music.cjs +27 -1
  176. package/dist/martyrs/src/modules/music/router/music.cjs.map +1 -1
  177. package/dist/martyrs/src/modules/music/router/music.js +27 -1
  178. package/dist/martyrs/src/modules/music/router/music.js.map +1 -1
  179. package/dist/martyrs/src/modules/music/store/artists.cjs +6 -4
  180. package/dist/martyrs/src/modules/music/store/artists.cjs.map +1 -1
  181. package/dist/martyrs/src/modules/music/store/artists.js +6 -4
  182. package/dist/martyrs/src/modules/music/store/artists.js.map +1 -1
  183. package/dist/martyrs/src/modules/music/store/player.cjs +5 -0
  184. package/dist/martyrs/src/modules/music/store/player.cjs.map +1 -1
  185. package/dist/martyrs/src/modules/music/store/player.js +5 -0
  186. package/dist/martyrs/src/modules/music/store/player.js.map +1 -1
  187. package/dist/martyrs/src/modules/music/store/tracks.cjs +22 -0
  188. package/dist/martyrs/src/modules/music/store/tracks.cjs.map +1 -1
  189. package/dist/martyrs/src/modules/music/store/tracks.js +22 -0
  190. package/dist/martyrs/src/modules/music/store/tracks.js.map +1 -1
  191. package/dist/martyrs/src/modules/orders/components/blocks/CardOrderBackoffice.vue.js +2 -2
  192. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +2 -2
  193. package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.cjs +1 -1
  194. package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +1 -1
  195. package/dist/martyrs/src/modules/orders/components/sections/FormAddCustomer.vue.cjs +1 -1
  196. package/dist/martyrs/src/modules/orders/components/sections/FormAddCustomer.vue.js +1 -1
  197. package/dist/martyrs/src/modules/orders/components/sections/FormCustomerDetails.vue.cjs +1 -1
  198. package/dist/martyrs/src/modules/orders/components/sections/FormCustomerDetails.vue.js +1 -1
  199. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs +1 -1
  200. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +1 -1
  201. package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js +2 -2
  202. package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.cjs +1 -1
  203. package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.js +1 -1
  204. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +1 -1
  205. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +1 -1
  206. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs +1 -1
  207. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +1 -1
  208. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.cjs +1 -1
  209. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
  210. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.cjs +1 -1
  211. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +1 -1
  212. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.cjs +1 -1
  213. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +1 -1
  214. package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.cjs +1 -1
  215. package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +1 -1
  216. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.cjs +1 -1
  217. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +1 -1
  218. package/dist/martyrs/src/modules/organizations/router/organizations.cjs +1 -1
  219. package/dist/martyrs/src/modules/organizations/router/organizations.js +1 -1
  220. package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.cjs +1 -1
  221. package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js +1 -1
  222. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.cjs +1 -1
  223. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +1 -1
  224. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs +1 -1
  225. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +1 -1
  226. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.cjs +1 -1
  227. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +1 -1
  228. package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.cjs +1 -1
  229. package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.js +1 -1
  230. package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.cjs +1 -1
  231. package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js +1 -1
  232. package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.cjs +1 -1
  233. package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.js +1 -1
  234. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.cjs +4 -3
  235. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.cjs.map +1 -1
  236. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.js +4 -3
  237. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttBar.vue.js.map +1 -1
  238. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttChart.vue.cjs +37 -70
  239. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttChart.vue.cjs.map +1 -1
  240. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttChart.vue.js +38 -71
  241. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttChart.vue.js.map +1 -1
  242. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.cjs +2 -1
  243. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.cjs.map +1 -1
  244. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js +6 -5
  245. package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js.map +1 -1
  246. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.cjs +45 -52
  247. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.cjs.map +1 -1
  248. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js +46 -53
  249. package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js.map +1 -1
  250. package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.cjs +1 -1
  251. package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.js +1 -1
  252. package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.cjs +1 -1
  253. package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.js +1 -1
  254. package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.cjs +1 -1
  255. package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +1 -1
  256. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.cjs +1 -1
  257. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +1 -1
  258. package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.cjs +1 -1
  259. package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.js +1 -1
  260. package/dist/martyrs/src/modules/wallet/views/components/blocks/CardDeposit.vue.cjs +1 -1
  261. package/dist/martyrs/src/modules/wallet/views/components/blocks/CardDeposit.vue.js +1 -1
  262. package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.cjs +1 -1
  263. package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.js +1 -1
  264. package/dist/martyrs.cjs.js +1 -1
  265. package/dist/martyrs.css +1 -1
  266. package/dist/martyrs.es.js +1 -1
  267. package/dist/music.server.cjs +124 -31
  268. package/dist/music.server.js +124 -31
  269. package/dist/organizations.server.cjs +1 -1
  270. package/dist/organizations.server.js +1 -1
  271. package/dist/products.server.cjs +2 -2
  272. package/dist/products.server.js +2 -2
  273. package/dist/rents.server.cjs +3 -3
  274. package/dist/rents.server.js +3 -3
  275. package/dist/style.css +373 -80
  276. package/dist/{web-D7lZjuC0.js → web-Dkk0_7TA.js} +1 -1
  277. package/dist/{web-D-YZ9KHz.cjs → web-stVkXd0l.cjs} +1 -1
  278. package/package.json +1 -1
  279. package/src/builder/modes/ssr.prod.js +21 -5
  280. package/src/builder/rspack/rspack.config.spa.client.js +0 -44
  281. package/src/builder/rspack/rspack.config.ssr.client.js +40 -40
  282. package/src/components/Calendar/Calendar.vue +378 -377
  283. package/src/components/Feed/Feed.vue +28 -2
  284. package/src/modules/globals/controllers/classes/crud/crud.policies.js +5 -0
  285. package/src/modules/globals/controllers/classes/globals.validator.js +8 -1
  286. package/src/modules/globals/views/components/layouts/Client.vue +7 -0
  287. package/src/modules/music/README.md +8 -0
  288. package/src/modules/music/components/SidebarMusic.vue +6 -9
  289. package/src/modules/music/components/cards/AlbumCard.vue +20 -14
  290. package/src/modules/music/components/cards/ArtistCard.vue +1 -1
  291. package/src/modules/music/components/cards/PlaylistCard.vue +31 -11
  292. package/src/modules/music/components/cards/TrackListCard.vue +24 -13
  293. package/src/modules/music/components/forms/PlaylistForm.vue +417 -107
  294. package/src/modules/music/components/forms/SearchForm.vue +31 -8
  295. package/src/modules/music/components/forms/TrackForm.vue +50 -32
  296. package/src/modules/music/components/layouts/MusicBottomPlayer.vue +17 -0
  297. package/src/modules/music/components/pages/Album.vue +373 -186
  298. package/src/modules/music/components/pages/Artist.vue +54 -94
  299. package/src/modules/music/components/pages/MusicHome.vue +59 -56
  300. package/src/modules/music/components/pages/MusicLibrary.vue +13 -11
  301. package/src/modules/music/components/pages/Playlist.vue +495 -379
  302. package/src/modules/music/components/pages/SearchResults.vue +185 -313
  303. package/src/modules/music/components/pages/Track.vue +363 -69
  304. package/src/modules/music/components/player/MusicPlayer.vue +368 -97
  305. package/src/modules/music/components/player/TrackProgress.vue +76 -22
  306. package/src/modules/music/components/player/VolumeControl.vue +61 -28
  307. package/src/modules/music/controllers/search.controller.js +3 -0
  308. package/src/modules/music/controllers/stream.controller.js +11 -3
  309. package/src/modules/music/middlewares/playlists.verifier.js +1 -1
  310. package/src/modules/music/music.client.js +3 -6
  311. package/src/modules/music/music.server.js +8 -4
  312. package/src/modules/music/router/music.js +8 -1
  313. package/src/modules/music/routes/albums.routes.js +37 -5
  314. package/src/modules/music/routes/artists.routes.js +14 -4
  315. package/src/modules/music/routes/genres.routes.js +5 -1
  316. package/src/modules/music/routes/playlists.routes.js +42 -9
  317. package/src/modules/music/routes/tracks.routes.js +27 -2
  318. package/src/modules/music/store/artists.js +6 -2
  319. package/src/modules/music/store/player.js +6 -0
  320. package/src/modules/music/store/tracks.js +31 -0
  321. package/src/modules/music/websocket/streaming.handler.js +7 -1
  322. package/src/modules/rents/controllers/services/rents.services.js +2 -2
  323. package/src/modules/rents/views/components/pages/Gant/GanttBar.vue +4 -3
  324. package/src/modules/rents/views/components/pages/Gant/GanttChart.vue +42 -40
  325. package/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue +3 -1
  326. package/src/modules/rents/views/components/pages/Rents.vue +60 -56
  327. package/dist/globals.websocket-DzvdIBf6.js +0 -306
  328. package/dist/globals.websocket-k6_B1T7k.cjs +0 -322
  329. package/dist/martyrs/src/components/Field/Field.vue2.cjs.map +0 -1
  330. package/dist/martyrs/src/components/Menu/Menu.vue.cjs.map +0 -1
  331. package/dist/martyrs/src/components/Menu/Menu.vue.js.map +0 -1
  332. package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.cjs +0 -69
  333. package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.cjs.map +0 -1
  334. package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.js +0 -69
  335. package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.js.map +0 -1
  336. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.cjs +0 -104
  337. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.cjs.map +0 -1
  338. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.js +0 -104
  339. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.js.map +0 -1
  340. package/src/modules/music/components/cards/TrackCard.vue +0 -86
  341. package/src/modules/music/components/layouts/MusicLayout.vue +0 -83
@@ -73,7 +73,10 @@ const actions = {
73
73
  state.isPlaying = false;
74
74
  });
75
75
  }
76
+ console.log("Player: Attempting to log play event for track:", track._id);
77
+ console.log("Player: WebSocket connected?", globals_websocket.default.isSocketConnected());
76
78
  if (globals_websocket.default.isSocketConnected()) {
79
+ console.log("Player: Sending startPlaying event via WebSocket");
77
80
  globals_websocket.default.send({
78
81
  module: "music-streaming",
79
82
  action: "startPlaying",
@@ -83,6 +86,8 @@ const actions = {
83
86
  deviceInfo: navigator.userAgent
84
87
  }
85
88
  });
89
+ } else {
90
+ console.log("Player: WebSocket not connected, play count will not be incremented");
86
91
  }
87
92
  },
88
93
  togglePlay() {
@@ -1 +1 @@
1
- {"version":3,"file":"player.cjs","sources":["../../../../../../src/modules/music/store/player.js"],"sourcesContent":["// store/player.js\nimport globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';\nimport { reactive } from 'vue';\n\n// State\nexport const state = reactive({\n currentTrack: null,\n queue: [],\n isPlaying: false,\n volume: 0.7,\n muted: false,\n currentTime: 0,\n duration: 0,\n repeat: 'none', // 'none', 'all', 'one'\n shuffle: false,\n initialQueue: [], // To keep original order when shuffle is toggled\n audioElement: null,\n audioContext: null,\n listeningPartyId: null,\n syncInProgress: false,\n});\n\n// Actions\nexport const actions = {\n initializeAudio() {\n if (typeof window !== 'undefined') {\n if (!state.audioElement) {\n state.audioElement = new Audio();\n state.audioElement.volume = state.volume;\n\n // Set up audio context if available\n try {\n const AudioContext = window.AudioContext || window.webkitAudioContext;\n if (AudioContext) {\n state.audioContext = new AudioContext();\n }\n } catch (e) {\n console.error('AudioContext not supported', e);\n }\n\n // Add event listeners\n state.audioElement.addEventListener('timeupdate', () => {\n state.currentTime = state.audioElement.currentTime;\n\n // Sync playback with listening party every 5 seconds\n if (state.listeningPartyId && !state.syncInProgress && state.isPlaying && state.currentTime % 5 < 0.1) {\n this.syncPartyPlayback();\n }\n });\n\n state.audioElement.addEventListener('loadedmetadata', () => {\n state.duration = state.audioElement.duration;\n });\n\n state.audioElement.addEventListener('ended', () => {\n this.playNext();\n });\n\n state.audioElement.addEventListener('play', () => {\n state.isPlaying = true;\n });\n\n state.audioElement.addEventListener('pause', () => {\n state.isPlaying = false;\n });\n }\n }\n },\n\n async playTrack(track) {\n if (!state.audioElement) {\n this.initializeAudio();\n }\n\n // If track is already playing, just toggle play/pause\n if (state.currentTrack && state.currentTrack._id === track._id) {\n return this.togglePlay();\n }\n\n // Set the current track\n state.currentTrack = track;\n\n // Generate stream URL\n const streamUrl = `${process.env.API_URL}/api/stream/${track._id}`;\n\n // Set up audio element\n state.audioElement.src = streamUrl;\n state.audioElement.load();\n const playPromise = state.audioElement.play();\n\n // Handle autoplay restrictions\n if (playPromise !== undefined) {\n playPromise.catch(error => {\n console.error('Autoplay prevented:', error);\n state.isPlaying = false;\n });\n }\n\n // Log play via WebSocket if connected\n if (globalWebSocket.isSocketConnected()) {\n globalWebSocket.send({\n module: 'music-streaming',\n action: 'startPlaying',\n data: {\n trackId: track._id,\n from: 'player',\n deviceInfo: navigator.userAgent,\n },\n });\n }\n },\n\n togglePlay() {\n if (!state.currentTrack || !state.audioElement) return;\n\n if (state.isPlaying) {\n state.audioElement.pause();\n } else {\n state.audioElement.play().catch(error => {\n console.error('Play failed:', error);\n });\n }\n\n state.isPlaying = !state.isPlaying;\n\n // Sync with listening party if active\n if (state.listeningPartyId) {\n this.syncPartyPlayback();\n }\n },\n\n setVolume(volume) {\n state.volume = volume;\n if (state.audioElement) {\n state.audioElement.volume = volume;\n }\n },\n\n toggleMute() {\n state.muted = !state.muted;\n if (state.audioElement) {\n state.audioElement.muted = state.muted;\n }\n },\n\n seek(time) {\n if (state.audioElement) {\n state.audioElement.currentTime = time;\n state.currentTime = time;\n\n // Sync with listening party if active\n if (state.listeningPartyId) {\n this.syncPartyPlayback();\n }\n }\n },\n\n // Queue management\n setQueue(tracks, startIndex = 0) {\n state.queue = [...tracks];\n state.initialQueue = [...tracks];\n\n if (startIndex > 0 && startIndex < tracks.length) {\n // Rearrange queue to start from the selected track\n const tracksToPlay = state.queue.splice(startIndex);\n state.queue = [...tracksToPlay, ...state.queue];\n }\n\n // If shuffle is on, randomize the queue except the first track\n if (state.shuffle && state.queue.length > 1) {\n const firstTrack = state.queue[0];\n const remainingTracks = state.queue.slice(1);\n this.shuffleArray(remainingTracks);\n state.queue = [firstTrack, ...remainingTracks];\n }\n\n // Start playing the first track in queue\n if (state.queue.length > 0) {\n this.playTrack(state.queue[0]);\n }\n },\n\n addToQueue(track) {\n state.queue.push(track);\n state.initialQueue.push(track);\n\n // If nothing is playing, start this track\n if (!state.currentTrack) {\n this.playTrack(track);\n }\n },\n\n removeFromQueue(index) {\n if (index >= 0 && index < state.queue.length) {\n state.queue.splice(index, 1);\n }\n },\n\n clearQueue() {\n state.queue = [];\n state.initialQueue = [];\n\n if (state.audioElement) {\n state.audioElement.pause();\n state.audioElement.src = '';\n }\n\n state.currentTrack = null;\n state.isPlaying = false;\n },\n\n playNext() {\n if (state.queue.length <= 1) {\n // Only one track or empty queue\n if (state.repeat === 'one' || state.repeat === 'all') {\n // Replay the current track\n this.seek(0);\n state.audioElement.play().catch(e => console.error(e));\n } else {\n // Stop playback\n state.isPlaying = false;\n }\n return;\n }\n\n if (state.repeat !== 'one') {\n // Move to next track\n state.queue.shift(); // Remove current track from queue\n\n // If queue is empty after removing current track and repeat is on\n if (state.queue.length === 0 && state.repeat === 'all') {\n state.queue = [...state.initialQueue];\n }\n\n // Play the next track if available\n if (state.queue.length > 0) {\n this.playTrack(state.queue[0]);\n } else {\n state.currentTrack = null;\n state.isPlaying = false;\n }\n } else {\n // Repeat one - just seek to beginning\n this.seek(0);\n state.audioElement.play().catch(e => console.error(e));\n }\n },\n\n playPrevious() {\n // If we're more than 3 seconds into the track, restart it\n if (state.currentTime > 3) {\n this.seek(0);\n return;\n }\n\n // Otherwise go to previous track if we have history\n // Implementation depends on how track history is managed\n // For simplicity, let's just go back to the beginning of the current track\n this.seek(0);\n },\n\n toggleRepeat() {\n // Cycle through repeat modes: none -> all -> one -> none...\n if (state.repeat === 'none') {\n state.repeat = 'all';\n } else if (state.repeat === 'all') {\n state.repeat = 'one';\n } else {\n state.repeat = 'none';\n }\n },\n\n toggleShuffle() {\n state.shuffle = !state.shuffle;\n\n if (state.shuffle) {\n // Save the current track\n const currentTrack = state.queue[0];\n\n // Shuffle the rest of the queue\n const remainingTracks = state.queue.slice(1);\n this.shuffleArray(remainingTracks);\n\n // Reconstruct queue with current track at the front\n state.queue = [currentTrack, ...remainingTracks];\n } else {\n // Restore original order but keep current track at front\n if (state.currentTrack) {\n const currentTrackIndex = state.initialQueue.findIndex(track => track._id === state.currentTrack._id);\n\n if (currentTrackIndex !== -1) {\n const tracksToPlay = state.initialQueue.slice(currentTrackIndex);\n const previousTracks = state.initialQueue.slice(0, currentTrackIndex);\n state.queue = [...tracksToPlay, ...previousTracks];\n } else {\n state.queue = [...state.initialQueue];\n }\n } else {\n state.queue = [...state.initialQueue];\n }\n }\n },\n\n shuffleArray(array) {\n for (let i = array.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [array[i], array[j]] = [array[j], array[i]];\n }\n return array;\n },\n\n // Listening party features\n joinListeningParty(partyId) {\n state.listeningPartyId = partyId;\n\n if (globalWebSocket.isSocketConnected()) {\n globalWebSocket.send({\n module: 'music-streaming',\n action: 'joinListeningParty',\n data: { partyId },\n });\n\n // Set up event listener for party playback sync\n globalWebSocket.addEventListener('partyPlaybackSync', this.handlePartySync.bind(this), {\n module: 'music-streaming',\n });\n }\n },\n\n leaveListeningParty() {\n state.listeningPartyId = null;\n\n // Remove event listener for party sync\n if (globalWebSocket.isSocketConnected()) {\n globalWebSocket.removeEventListener('partyPlaybackSync');\n }\n },\n\n syncPartyPlayback() {\n if (!state.listeningPartyId || !state.currentTrack || !globalWebSocket.isSocketConnected()) {\n return;\n }\n\n globalWebSocket.send({\n module: 'music-streaming',\n action: 'syncPartyPlayback',\n data: {\n trackId: state.currentTrack._id,\n position: state.currentTime,\n isPlaying: state.isPlaying,\n },\n });\n },\n\n handlePartySync(data) {\n if (!state.listeningPartyId) return;\n\n state.syncInProgress = true;\n\n // If different track is playing in the party\n if (data.trackId !== state.currentTrack?._id) {\n // Find track in queue or load it\n const trackInQueue = state.queue.find(track => track._id === data.trackId);\n\n if (trackInQueue) {\n this.playTrack(trackInQueue);\n } else {\n // Need to fetch the track from the API\n fetch(`${process.env.API_URL}/api/tracks/${data.trackId}`)\n .then(response => response.json())\n .then(track => {\n this.playTrack(track);\n })\n .catch(error => {\n console.error('Error fetching party track:', error);\n });\n }\n }\n\n // Sync playback position with some tolerance (2 seconds)\n if (Math.abs(state.currentTime - data.position) > 2) {\n this.seek(data.position);\n }\n\n // Sync play/pause state\n if (state.isPlaying !== data.isPlaying) {\n this.togglePlay();\n }\n\n // Reset sync flag after a short delay\n setTimeout(() => {\n state.syncInProgress = false;\n }, 1000);\n },\n};\n"],"names":["reactive","globalWebSocket"],"mappings":"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"}
1
+ {"version":3,"file":"player.cjs","sources":["../../../../../../src/modules/music/store/player.js"],"sourcesContent":["// store/player.js\nimport globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';\nimport { reactive } from 'vue';\n\n// State\nexport const state = reactive({\n currentTrack: null,\n queue: [],\n isPlaying: false,\n volume: 0.7,\n muted: false,\n currentTime: 0,\n duration: 0,\n repeat: 'none', // 'none', 'all', 'one'\n shuffle: false,\n initialQueue: [], // To keep original order when shuffle is toggled\n audioElement: null,\n audioContext: null,\n listeningPartyId: null,\n syncInProgress: false,\n});\n\n// Actions\nexport const actions = {\n initializeAudio() {\n if (typeof window !== 'undefined') {\n if (!state.audioElement) {\n state.audioElement = new Audio();\n state.audioElement.volume = state.volume;\n\n // Set up audio context if available\n try {\n const AudioContext = window.AudioContext || window.webkitAudioContext;\n if (AudioContext) {\n state.audioContext = new AudioContext();\n }\n } catch (e) {\n console.error('AudioContext not supported', e);\n }\n\n // Add event listeners\n state.audioElement.addEventListener('timeupdate', () => {\n state.currentTime = state.audioElement.currentTime;\n\n // Sync playback with listening party every 5 seconds\n if (state.listeningPartyId && !state.syncInProgress && state.isPlaying && state.currentTime % 5 < 0.1) {\n this.syncPartyPlayback();\n }\n });\n\n state.audioElement.addEventListener('loadedmetadata', () => {\n state.duration = state.audioElement.duration;\n });\n\n state.audioElement.addEventListener('ended', () => {\n this.playNext();\n });\n\n state.audioElement.addEventListener('play', () => {\n state.isPlaying = true;\n });\n\n state.audioElement.addEventListener('pause', () => {\n state.isPlaying = false;\n });\n }\n }\n },\n\n async playTrack(track) {\n if (!state.audioElement) {\n this.initializeAudio();\n }\n\n // If track is already playing, just toggle play/pause\n if (state.currentTrack && state.currentTrack._id === track._id) {\n return this.togglePlay();\n }\n\n // Set the current track\n state.currentTrack = track;\n\n // Generate stream URL\n const streamUrl = `${process.env.API_URL}/api/stream/${track._id}`;\n\n // Set up audio element\n state.audioElement.src = streamUrl;\n state.audioElement.load();\n const playPromise = state.audioElement.play();\n\n // Handle autoplay restrictions\n if (playPromise !== undefined) {\n playPromise.catch(error => {\n console.error('Autoplay prevented:', error);\n state.isPlaying = false;\n });\n }\n\n // Log play via WebSocket if connected\n console.log('Player: Attempting to log play event for track:', track._id);\n console.log('Player: WebSocket connected?', globalWebSocket.isSocketConnected());\n \n if (globalWebSocket.isSocketConnected()) {\n console.log('Player: Sending startPlaying event via WebSocket');\n globalWebSocket.send({\n module: 'music-streaming',\n action: 'startPlaying',\n data: {\n trackId: track._id,\n from: 'player',\n deviceInfo: navigator.userAgent,\n },\n });\n } else {\n console.log('Player: WebSocket not connected, play count will not be incremented');\n }\n },\n\n togglePlay() {\n if (!state.currentTrack || !state.audioElement) return;\n\n if (state.isPlaying) {\n state.audioElement.pause();\n } else {\n state.audioElement.play().catch(error => {\n console.error('Play failed:', error);\n });\n }\n\n state.isPlaying = !state.isPlaying;\n\n // Sync with listening party if active\n if (state.listeningPartyId) {\n this.syncPartyPlayback();\n }\n },\n\n setVolume(volume) {\n state.volume = volume;\n if (state.audioElement) {\n state.audioElement.volume = volume;\n }\n },\n\n toggleMute() {\n state.muted = !state.muted;\n if (state.audioElement) {\n state.audioElement.muted = state.muted;\n }\n },\n\n seek(time) {\n if (state.audioElement) {\n state.audioElement.currentTime = time;\n state.currentTime = time;\n\n // Sync with listening party if active\n if (state.listeningPartyId) {\n this.syncPartyPlayback();\n }\n }\n },\n\n // Queue management\n setQueue(tracks, startIndex = 0) {\n state.queue = [...tracks];\n state.initialQueue = [...tracks];\n\n if (startIndex > 0 && startIndex < tracks.length) {\n // Rearrange queue to start from the selected track\n const tracksToPlay = state.queue.splice(startIndex);\n state.queue = [...tracksToPlay, ...state.queue];\n }\n\n // If shuffle is on, randomize the queue except the first track\n if (state.shuffle && state.queue.length > 1) {\n const firstTrack = state.queue[0];\n const remainingTracks = state.queue.slice(1);\n this.shuffleArray(remainingTracks);\n state.queue = [firstTrack, ...remainingTracks];\n }\n\n // Start playing the first track in queue\n if (state.queue.length > 0) {\n this.playTrack(state.queue[0]);\n }\n },\n\n addToQueue(track) {\n state.queue.push(track);\n state.initialQueue.push(track);\n\n // If nothing is playing, start this track\n if (!state.currentTrack) {\n this.playTrack(track);\n }\n },\n\n removeFromQueue(index) {\n if (index >= 0 && index < state.queue.length) {\n state.queue.splice(index, 1);\n }\n },\n\n clearQueue() {\n state.queue = [];\n state.initialQueue = [];\n\n if (state.audioElement) {\n state.audioElement.pause();\n state.audioElement.src = '';\n }\n\n state.currentTrack = null;\n state.isPlaying = false;\n },\n\n playNext() {\n if (state.queue.length <= 1) {\n // Only one track or empty queue\n if (state.repeat === 'one' || state.repeat === 'all') {\n // Replay the current track\n this.seek(0);\n state.audioElement.play().catch(e => console.error(e));\n } else {\n // Stop playback\n state.isPlaying = false;\n }\n return;\n }\n\n if (state.repeat !== 'one') {\n // Move to next track\n state.queue.shift(); // Remove current track from queue\n\n // If queue is empty after removing current track and repeat is on\n if (state.queue.length === 0 && state.repeat === 'all') {\n state.queue = [...state.initialQueue];\n }\n\n // Play the next track if available\n if (state.queue.length > 0) {\n this.playTrack(state.queue[0]);\n } else {\n state.currentTrack = null;\n state.isPlaying = false;\n }\n } else {\n // Repeat one - just seek to beginning\n this.seek(0);\n state.audioElement.play().catch(e => console.error(e));\n }\n },\n\n playPrevious() {\n // If we're more than 3 seconds into the track, restart it\n if (state.currentTime > 3) {\n this.seek(0);\n return;\n }\n\n // Otherwise go to previous track if we have history\n // Implementation depends on how track history is managed\n // For simplicity, let's just go back to the beginning of the current track\n this.seek(0);\n },\n\n toggleRepeat() {\n // Cycle through repeat modes: none -> all -> one -> none...\n if (state.repeat === 'none') {\n state.repeat = 'all';\n } else if (state.repeat === 'all') {\n state.repeat = 'one';\n } else {\n state.repeat = 'none';\n }\n },\n\n toggleShuffle() {\n state.shuffle = !state.shuffle;\n\n if (state.shuffle) {\n // Save the current track\n const currentTrack = state.queue[0];\n\n // Shuffle the rest of the queue\n const remainingTracks = state.queue.slice(1);\n this.shuffleArray(remainingTracks);\n\n // Reconstruct queue with current track at the front\n state.queue = [currentTrack, ...remainingTracks];\n } else {\n // Restore original order but keep current track at front\n if (state.currentTrack) {\n const currentTrackIndex = state.initialQueue.findIndex(track => track._id === state.currentTrack._id);\n\n if (currentTrackIndex !== -1) {\n const tracksToPlay = state.initialQueue.slice(currentTrackIndex);\n const previousTracks = state.initialQueue.slice(0, currentTrackIndex);\n state.queue = [...tracksToPlay, ...previousTracks];\n } else {\n state.queue = [...state.initialQueue];\n }\n } else {\n state.queue = [...state.initialQueue];\n }\n }\n },\n\n shuffleArray(array) {\n for (let i = array.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [array[i], array[j]] = [array[j], array[i]];\n }\n return array;\n },\n\n // Listening party features\n joinListeningParty(partyId) {\n state.listeningPartyId = partyId;\n\n if (globalWebSocket.isSocketConnected()) {\n globalWebSocket.send({\n module: 'music-streaming',\n action: 'joinListeningParty',\n data: { partyId },\n });\n\n // Set up event listener for party playback sync\n globalWebSocket.addEventListener('partyPlaybackSync', this.handlePartySync.bind(this), {\n module: 'music-streaming',\n });\n }\n },\n\n leaveListeningParty() {\n state.listeningPartyId = null;\n\n // Remove event listener for party sync\n if (globalWebSocket.isSocketConnected()) {\n globalWebSocket.removeEventListener('partyPlaybackSync');\n }\n },\n\n syncPartyPlayback() {\n if (!state.listeningPartyId || !state.currentTrack || !globalWebSocket.isSocketConnected()) {\n return;\n }\n\n globalWebSocket.send({\n module: 'music-streaming',\n action: 'syncPartyPlayback',\n data: {\n trackId: state.currentTrack._id,\n position: state.currentTime,\n isPlaying: state.isPlaying,\n },\n });\n },\n\n handlePartySync(data) {\n if (!state.listeningPartyId) return;\n\n state.syncInProgress = true;\n\n // If different track is playing in the party\n if (data.trackId !== state.currentTrack?._id) {\n // Find track in queue or load it\n const trackInQueue = state.queue.find(track => track._id === data.trackId);\n\n if (trackInQueue) {\n this.playTrack(trackInQueue);\n } else {\n // Need to fetch the track from the API\n fetch(`${process.env.API_URL}/api/tracks/${data.trackId}`)\n .then(response => response.json())\n .then(track => {\n this.playTrack(track);\n })\n .catch(error => {\n console.error('Error fetching party track:', error);\n });\n }\n }\n\n // Sync playback position with some tolerance (2 seconds)\n if (Math.abs(state.currentTime - data.position) > 2) {\n this.seek(data.position);\n }\n\n // Sync play/pause state\n if (state.isPlaying !== data.isPlaying) {\n this.togglePlay();\n }\n\n // Reset sync flag after a short delay\n setTimeout(() => {\n state.syncInProgress = false;\n }, 1000);\n },\n};\n"],"names":["reactive","globalWebSocket"],"mappings":"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"}
@@ -71,7 +71,10 @@ const actions = {
71
71
  state.isPlaying = false;
72
72
  });
73
73
  }
74
+ console.log("Player: Attempting to log play event for track:", track._id);
75
+ console.log("Player: WebSocket connected?", globalWebSocket.isSocketConnected());
74
76
  if (globalWebSocket.isSocketConnected()) {
77
+ console.log("Player: Sending startPlaying event via WebSocket");
75
78
  globalWebSocket.send({
76
79
  module: "music-streaming",
77
80
  action: "startPlaying",
@@ -81,6 +84,8 @@ const actions = {
81
84
  deviceInfo: navigator.userAgent
82
85
  }
83
86
  });
87
+ } else {
88
+ console.log("Player: WebSocket not connected, play count will not be incremented");
84
89
  }
85
90
  },
86
91
  togglePlay() {
@@ -1 +1 @@
1
- {"version":3,"file":"player.js","sources":["../../../../../../src/modules/music/store/player.js"],"sourcesContent":["// store/player.js\nimport globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';\nimport { reactive } from 'vue';\n\n// State\nexport const state = reactive({\n currentTrack: null,\n queue: [],\n isPlaying: false,\n volume: 0.7,\n muted: false,\n currentTime: 0,\n duration: 0,\n repeat: 'none', // 'none', 'all', 'one'\n shuffle: false,\n initialQueue: [], // To keep original order when shuffle is toggled\n audioElement: null,\n audioContext: null,\n listeningPartyId: null,\n syncInProgress: false,\n});\n\n// Actions\nexport const actions = {\n initializeAudio() {\n if (typeof window !== 'undefined') {\n if (!state.audioElement) {\n state.audioElement = new Audio();\n state.audioElement.volume = state.volume;\n\n // Set up audio context if available\n try {\n const AudioContext = window.AudioContext || window.webkitAudioContext;\n if (AudioContext) {\n state.audioContext = new AudioContext();\n }\n } catch (e) {\n console.error('AudioContext not supported', e);\n }\n\n // Add event listeners\n state.audioElement.addEventListener('timeupdate', () => {\n state.currentTime = state.audioElement.currentTime;\n\n // Sync playback with listening party every 5 seconds\n if (state.listeningPartyId && !state.syncInProgress && state.isPlaying && state.currentTime % 5 < 0.1) {\n this.syncPartyPlayback();\n }\n });\n\n state.audioElement.addEventListener('loadedmetadata', () => {\n state.duration = state.audioElement.duration;\n });\n\n state.audioElement.addEventListener('ended', () => {\n this.playNext();\n });\n\n state.audioElement.addEventListener('play', () => {\n state.isPlaying = true;\n });\n\n state.audioElement.addEventListener('pause', () => {\n state.isPlaying = false;\n });\n }\n }\n },\n\n async playTrack(track) {\n if (!state.audioElement) {\n this.initializeAudio();\n }\n\n // If track is already playing, just toggle play/pause\n if (state.currentTrack && state.currentTrack._id === track._id) {\n return this.togglePlay();\n }\n\n // Set the current track\n state.currentTrack = track;\n\n // Generate stream URL\n const streamUrl = `${process.env.API_URL}/api/stream/${track._id}`;\n\n // Set up audio element\n state.audioElement.src = streamUrl;\n state.audioElement.load();\n const playPromise = state.audioElement.play();\n\n // Handle autoplay restrictions\n if (playPromise !== undefined) {\n playPromise.catch(error => {\n console.error('Autoplay prevented:', error);\n state.isPlaying = false;\n });\n }\n\n // Log play via WebSocket if connected\n if (globalWebSocket.isSocketConnected()) {\n globalWebSocket.send({\n module: 'music-streaming',\n action: 'startPlaying',\n data: {\n trackId: track._id,\n from: 'player',\n deviceInfo: navigator.userAgent,\n },\n });\n }\n },\n\n togglePlay() {\n if (!state.currentTrack || !state.audioElement) return;\n\n if (state.isPlaying) {\n state.audioElement.pause();\n } else {\n state.audioElement.play().catch(error => {\n console.error('Play failed:', error);\n });\n }\n\n state.isPlaying = !state.isPlaying;\n\n // Sync with listening party if active\n if (state.listeningPartyId) {\n this.syncPartyPlayback();\n }\n },\n\n setVolume(volume) {\n state.volume = volume;\n if (state.audioElement) {\n state.audioElement.volume = volume;\n }\n },\n\n toggleMute() {\n state.muted = !state.muted;\n if (state.audioElement) {\n state.audioElement.muted = state.muted;\n }\n },\n\n seek(time) {\n if (state.audioElement) {\n state.audioElement.currentTime = time;\n state.currentTime = time;\n\n // Sync with listening party if active\n if (state.listeningPartyId) {\n this.syncPartyPlayback();\n }\n }\n },\n\n // Queue management\n setQueue(tracks, startIndex = 0) {\n state.queue = [...tracks];\n state.initialQueue = [...tracks];\n\n if (startIndex > 0 && startIndex < tracks.length) {\n // Rearrange queue to start from the selected track\n const tracksToPlay = state.queue.splice(startIndex);\n state.queue = [...tracksToPlay, ...state.queue];\n }\n\n // If shuffle is on, randomize the queue except the first track\n if (state.shuffle && state.queue.length > 1) {\n const firstTrack = state.queue[0];\n const remainingTracks = state.queue.slice(1);\n this.shuffleArray(remainingTracks);\n state.queue = [firstTrack, ...remainingTracks];\n }\n\n // Start playing the first track in queue\n if (state.queue.length > 0) {\n this.playTrack(state.queue[0]);\n }\n },\n\n addToQueue(track) {\n state.queue.push(track);\n state.initialQueue.push(track);\n\n // If nothing is playing, start this track\n if (!state.currentTrack) {\n this.playTrack(track);\n }\n },\n\n removeFromQueue(index) {\n if (index >= 0 && index < state.queue.length) {\n state.queue.splice(index, 1);\n }\n },\n\n clearQueue() {\n state.queue = [];\n state.initialQueue = [];\n\n if (state.audioElement) {\n state.audioElement.pause();\n state.audioElement.src = '';\n }\n\n state.currentTrack = null;\n state.isPlaying = false;\n },\n\n playNext() {\n if (state.queue.length <= 1) {\n // Only one track or empty queue\n if (state.repeat === 'one' || state.repeat === 'all') {\n // Replay the current track\n this.seek(0);\n state.audioElement.play().catch(e => console.error(e));\n } else {\n // Stop playback\n state.isPlaying = false;\n }\n return;\n }\n\n if (state.repeat !== 'one') {\n // Move to next track\n state.queue.shift(); // Remove current track from queue\n\n // If queue is empty after removing current track and repeat is on\n if (state.queue.length === 0 && state.repeat === 'all') {\n state.queue = [...state.initialQueue];\n }\n\n // Play the next track if available\n if (state.queue.length > 0) {\n this.playTrack(state.queue[0]);\n } else {\n state.currentTrack = null;\n state.isPlaying = false;\n }\n } else {\n // Repeat one - just seek to beginning\n this.seek(0);\n state.audioElement.play().catch(e => console.error(e));\n }\n },\n\n playPrevious() {\n // If we're more than 3 seconds into the track, restart it\n if (state.currentTime > 3) {\n this.seek(0);\n return;\n }\n\n // Otherwise go to previous track if we have history\n // Implementation depends on how track history is managed\n // For simplicity, let's just go back to the beginning of the current track\n this.seek(0);\n },\n\n toggleRepeat() {\n // Cycle through repeat modes: none -> all -> one -> none...\n if (state.repeat === 'none') {\n state.repeat = 'all';\n } else if (state.repeat === 'all') {\n state.repeat = 'one';\n } else {\n state.repeat = 'none';\n }\n },\n\n toggleShuffle() {\n state.shuffle = !state.shuffle;\n\n if (state.shuffle) {\n // Save the current track\n const currentTrack = state.queue[0];\n\n // Shuffle the rest of the queue\n const remainingTracks = state.queue.slice(1);\n this.shuffleArray(remainingTracks);\n\n // Reconstruct queue with current track at the front\n state.queue = [currentTrack, ...remainingTracks];\n } else {\n // Restore original order but keep current track at front\n if (state.currentTrack) {\n const currentTrackIndex = state.initialQueue.findIndex(track => track._id === state.currentTrack._id);\n\n if (currentTrackIndex !== -1) {\n const tracksToPlay = state.initialQueue.slice(currentTrackIndex);\n const previousTracks = state.initialQueue.slice(0, currentTrackIndex);\n state.queue = [...tracksToPlay, ...previousTracks];\n } else {\n state.queue = [...state.initialQueue];\n }\n } else {\n state.queue = [...state.initialQueue];\n }\n }\n },\n\n shuffleArray(array) {\n for (let i = array.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [array[i], array[j]] = [array[j], array[i]];\n }\n return array;\n },\n\n // Listening party features\n joinListeningParty(partyId) {\n state.listeningPartyId = partyId;\n\n if (globalWebSocket.isSocketConnected()) {\n globalWebSocket.send({\n module: 'music-streaming',\n action: 'joinListeningParty',\n data: { partyId },\n });\n\n // Set up event listener for party playback sync\n globalWebSocket.addEventListener('partyPlaybackSync', this.handlePartySync.bind(this), {\n module: 'music-streaming',\n });\n }\n },\n\n leaveListeningParty() {\n state.listeningPartyId = null;\n\n // Remove event listener for party sync\n if (globalWebSocket.isSocketConnected()) {\n globalWebSocket.removeEventListener('partyPlaybackSync');\n }\n },\n\n syncPartyPlayback() {\n if (!state.listeningPartyId || !state.currentTrack || !globalWebSocket.isSocketConnected()) {\n return;\n }\n\n globalWebSocket.send({\n module: 'music-streaming',\n action: 'syncPartyPlayback',\n data: {\n trackId: state.currentTrack._id,\n position: state.currentTime,\n isPlaying: state.isPlaying,\n },\n });\n },\n\n handlePartySync(data) {\n if (!state.listeningPartyId) return;\n\n state.syncInProgress = true;\n\n // If different track is playing in the party\n if (data.trackId !== state.currentTrack?._id) {\n // Find track in queue or load it\n const trackInQueue = state.queue.find(track => track._id === data.trackId);\n\n if (trackInQueue) {\n this.playTrack(trackInQueue);\n } else {\n // Need to fetch the track from the API\n fetch(`${process.env.API_URL}/api/tracks/${data.trackId}`)\n .then(response => response.json())\n .then(track => {\n this.playTrack(track);\n })\n .catch(error => {\n console.error('Error fetching party track:', error);\n });\n }\n }\n\n // Sync playback position with some tolerance (2 seconds)\n if (Math.abs(state.currentTime - data.position) > 2) {\n this.seek(data.position);\n }\n\n // Sync play/pause state\n if (state.isPlaying !== data.isPlaying) {\n this.togglePlay();\n }\n\n // Reset sync flag after a short delay\n setTimeout(() => {\n state.syncInProgress = false;\n }, 1000);\n },\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"player.js","sources":["../../../../../../src/modules/music/store/player.js"],"sourcesContent":["// store/player.js\nimport globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';\nimport { reactive } from 'vue';\n\n// State\nexport const state = reactive({\n currentTrack: null,\n queue: [],\n isPlaying: false,\n volume: 0.7,\n muted: false,\n currentTime: 0,\n duration: 0,\n repeat: 'none', // 'none', 'all', 'one'\n shuffle: false,\n initialQueue: [], // To keep original order when shuffle is toggled\n audioElement: null,\n audioContext: null,\n listeningPartyId: null,\n syncInProgress: false,\n});\n\n// Actions\nexport const actions = {\n initializeAudio() {\n if (typeof window !== 'undefined') {\n if (!state.audioElement) {\n state.audioElement = new Audio();\n state.audioElement.volume = state.volume;\n\n // Set up audio context if available\n try {\n const AudioContext = window.AudioContext || window.webkitAudioContext;\n if (AudioContext) {\n state.audioContext = new AudioContext();\n }\n } catch (e) {\n console.error('AudioContext not supported', e);\n }\n\n // Add event listeners\n state.audioElement.addEventListener('timeupdate', () => {\n state.currentTime = state.audioElement.currentTime;\n\n // Sync playback with listening party every 5 seconds\n if (state.listeningPartyId && !state.syncInProgress && state.isPlaying && state.currentTime % 5 < 0.1) {\n this.syncPartyPlayback();\n }\n });\n\n state.audioElement.addEventListener('loadedmetadata', () => {\n state.duration = state.audioElement.duration;\n });\n\n state.audioElement.addEventListener('ended', () => {\n this.playNext();\n });\n\n state.audioElement.addEventListener('play', () => {\n state.isPlaying = true;\n });\n\n state.audioElement.addEventListener('pause', () => {\n state.isPlaying = false;\n });\n }\n }\n },\n\n async playTrack(track) {\n if (!state.audioElement) {\n this.initializeAudio();\n }\n\n // If track is already playing, just toggle play/pause\n if (state.currentTrack && state.currentTrack._id === track._id) {\n return this.togglePlay();\n }\n\n // Set the current track\n state.currentTrack = track;\n\n // Generate stream URL\n const streamUrl = `${process.env.API_URL}/api/stream/${track._id}`;\n\n // Set up audio element\n state.audioElement.src = streamUrl;\n state.audioElement.load();\n const playPromise = state.audioElement.play();\n\n // Handle autoplay restrictions\n if (playPromise !== undefined) {\n playPromise.catch(error => {\n console.error('Autoplay prevented:', error);\n state.isPlaying = false;\n });\n }\n\n // Log play via WebSocket if connected\n console.log('Player: Attempting to log play event for track:', track._id);\n console.log('Player: WebSocket connected?', globalWebSocket.isSocketConnected());\n \n if (globalWebSocket.isSocketConnected()) {\n console.log('Player: Sending startPlaying event via WebSocket');\n globalWebSocket.send({\n module: 'music-streaming',\n action: 'startPlaying',\n data: {\n trackId: track._id,\n from: 'player',\n deviceInfo: navigator.userAgent,\n },\n });\n } else {\n console.log('Player: WebSocket not connected, play count will not be incremented');\n }\n },\n\n togglePlay() {\n if (!state.currentTrack || !state.audioElement) return;\n\n if (state.isPlaying) {\n state.audioElement.pause();\n } else {\n state.audioElement.play().catch(error => {\n console.error('Play failed:', error);\n });\n }\n\n state.isPlaying = !state.isPlaying;\n\n // Sync with listening party if active\n if (state.listeningPartyId) {\n this.syncPartyPlayback();\n }\n },\n\n setVolume(volume) {\n state.volume = volume;\n if (state.audioElement) {\n state.audioElement.volume = volume;\n }\n },\n\n toggleMute() {\n state.muted = !state.muted;\n if (state.audioElement) {\n state.audioElement.muted = state.muted;\n }\n },\n\n seek(time) {\n if (state.audioElement) {\n state.audioElement.currentTime = time;\n state.currentTime = time;\n\n // Sync with listening party if active\n if (state.listeningPartyId) {\n this.syncPartyPlayback();\n }\n }\n },\n\n // Queue management\n setQueue(tracks, startIndex = 0) {\n state.queue = [...tracks];\n state.initialQueue = [...tracks];\n\n if (startIndex > 0 && startIndex < tracks.length) {\n // Rearrange queue to start from the selected track\n const tracksToPlay = state.queue.splice(startIndex);\n state.queue = [...tracksToPlay, ...state.queue];\n }\n\n // If shuffle is on, randomize the queue except the first track\n if (state.shuffle && state.queue.length > 1) {\n const firstTrack = state.queue[0];\n const remainingTracks = state.queue.slice(1);\n this.shuffleArray(remainingTracks);\n state.queue = [firstTrack, ...remainingTracks];\n }\n\n // Start playing the first track in queue\n if (state.queue.length > 0) {\n this.playTrack(state.queue[0]);\n }\n },\n\n addToQueue(track) {\n state.queue.push(track);\n state.initialQueue.push(track);\n\n // If nothing is playing, start this track\n if (!state.currentTrack) {\n this.playTrack(track);\n }\n },\n\n removeFromQueue(index) {\n if (index >= 0 && index < state.queue.length) {\n state.queue.splice(index, 1);\n }\n },\n\n clearQueue() {\n state.queue = [];\n state.initialQueue = [];\n\n if (state.audioElement) {\n state.audioElement.pause();\n state.audioElement.src = '';\n }\n\n state.currentTrack = null;\n state.isPlaying = false;\n },\n\n playNext() {\n if (state.queue.length <= 1) {\n // Only one track or empty queue\n if (state.repeat === 'one' || state.repeat === 'all') {\n // Replay the current track\n this.seek(0);\n state.audioElement.play().catch(e => console.error(e));\n } else {\n // Stop playback\n state.isPlaying = false;\n }\n return;\n }\n\n if (state.repeat !== 'one') {\n // Move to next track\n state.queue.shift(); // Remove current track from queue\n\n // If queue is empty after removing current track and repeat is on\n if (state.queue.length === 0 && state.repeat === 'all') {\n state.queue = [...state.initialQueue];\n }\n\n // Play the next track if available\n if (state.queue.length > 0) {\n this.playTrack(state.queue[0]);\n } else {\n state.currentTrack = null;\n state.isPlaying = false;\n }\n } else {\n // Repeat one - just seek to beginning\n this.seek(0);\n state.audioElement.play().catch(e => console.error(e));\n }\n },\n\n playPrevious() {\n // If we're more than 3 seconds into the track, restart it\n if (state.currentTime > 3) {\n this.seek(0);\n return;\n }\n\n // Otherwise go to previous track if we have history\n // Implementation depends on how track history is managed\n // For simplicity, let's just go back to the beginning of the current track\n this.seek(0);\n },\n\n toggleRepeat() {\n // Cycle through repeat modes: none -> all -> one -> none...\n if (state.repeat === 'none') {\n state.repeat = 'all';\n } else if (state.repeat === 'all') {\n state.repeat = 'one';\n } else {\n state.repeat = 'none';\n }\n },\n\n toggleShuffle() {\n state.shuffle = !state.shuffle;\n\n if (state.shuffle) {\n // Save the current track\n const currentTrack = state.queue[0];\n\n // Shuffle the rest of the queue\n const remainingTracks = state.queue.slice(1);\n this.shuffleArray(remainingTracks);\n\n // Reconstruct queue with current track at the front\n state.queue = [currentTrack, ...remainingTracks];\n } else {\n // Restore original order but keep current track at front\n if (state.currentTrack) {\n const currentTrackIndex = state.initialQueue.findIndex(track => track._id === state.currentTrack._id);\n\n if (currentTrackIndex !== -1) {\n const tracksToPlay = state.initialQueue.slice(currentTrackIndex);\n const previousTracks = state.initialQueue.slice(0, currentTrackIndex);\n state.queue = [...tracksToPlay, ...previousTracks];\n } else {\n state.queue = [...state.initialQueue];\n }\n } else {\n state.queue = [...state.initialQueue];\n }\n }\n },\n\n shuffleArray(array) {\n for (let i = array.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [array[i], array[j]] = [array[j], array[i]];\n }\n return array;\n },\n\n // Listening party features\n joinListeningParty(partyId) {\n state.listeningPartyId = partyId;\n\n if (globalWebSocket.isSocketConnected()) {\n globalWebSocket.send({\n module: 'music-streaming',\n action: 'joinListeningParty',\n data: { partyId },\n });\n\n // Set up event listener for party playback sync\n globalWebSocket.addEventListener('partyPlaybackSync', this.handlePartySync.bind(this), {\n module: 'music-streaming',\n });\n }\n },\n\n leaveListeningParty() {\n state.listeningPartyId = null;\n\n // Remove event listener for party sync\n if (globalWebSocket.isSocketConnected()) {\n globalWebSocket.removeEventListener('partyPlaybackSync');\n }\n },\n\n syncPartyPlayback() {\n if (!state.listeningPartyId || !state.currentTrack || !globalWebSocket.isSocketConnected()) {\n return;\n }\n\n globalWebSocket.send({\n module: 'music-streaming',\n action: 'syncPartyPlayback',\n data: {\n trackId: state.currentTrack._id,\n position: state.currentTime,\n isPlaying: state.isPlaying,\n },\n });\n },\n\n handlePartySync(data) {\n if (!state.listeningPartyId) return;\n\n state.syncInProgress = true;\n\n // If different track is playing in the party\n if (data.trackId !== state.currentTrack?._id) {\n // Find track in queue or load it\n const trackInQueue = state.queue.find(track => track._id === data.trackId);\n\n if (trackInQueue) {\n this.playTrack(trackInQueue);\n } else {\n // Need to fetch the track from the API\n fetch(`${process.env.API_URL}/api/tracks/${data.trackId}`)\n .then(response => response.json())\n .then(track => {\n this.playTrack(track);\n })\n .catch(error => {\n console.error('Error fetching party track:', error);\n });\n }\n }\n\n // Sync playback position with some tolerance (2 seconds)\n if (Math.abs(state.currentTime - data.position) > 2) {\n this.seek(data.position);\n }\n\n // Sync play/pause state\n if (state.isPlaying !== data.isPlaying) {\n this.togglePlay();\n }\n\n // Reset sync flag after a short delay\n setTimeout(() => {\n state.syncInProgress = false;\n }, 1000);\n },\n};\n"],"names":[],"mappings":"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"}
@@ -10,6 +10,7 @@ const state = vue.reactive({
10
10
  featured: [],
11
11
  userTracks: [],
12
12
  currentTrack: null,
13
+ relatedTracks: [],
13
14
  isLoading: false,
14
15
  loadingPopular: false,
15
16
  loadingRecent: false,
@@ -177,6 +178,27 @@ const actions = {
177
178
  console.error("Error fetching user tracks:", error);
178
179
  return [];
179
180
  }
181
+ },
182
+ async fetchRelatedTracks(trackUrl) {
183
+ try {
184
+ if (state.currentTrack && state.currentTrack.artist) {
185
+ const artistId = typeof state.currentTrack.artist === "object" ? state.currentTrack.artist._id : state.currentTrack.artist;
186
+ const queryParams = new URLSearchParams();
187
+ queryParams.append("artist", artistId);
188
+ queryParams.append("limit", "5");
189
+ const response = await fetch(`${process.env.API_URL}/api/tracks/read?${queryParams.toString()}`);
190
+ const tracks = await response.json();
191
+ const relatedTracks = tracks.filter((track) => track._id !== state.currentTrack._id);
192
+ state.relatedTracks = relatedTracks;
193
+ return relatedTracks;
194
+ }
195
+ state.relatedTracks = [];
196
+ return [];
197
+ } catch (error) {
198
+ console.error("Error fetching related tracks:", error);
199
+ state.relatedTracks = [];
200
+ return [];
201
+ }
180
202
  }
181
203
  };
182
204
  exports.actions = actions;
@@ -1 +1 @@
1
- {"version":3,"file":"tracks.cjs","sources":["../../../../../../src/modules/music/store/tracks.js"],"sourcesContent":["// store/tracks.js\nimport Store from '@martyrs/src/modules/globals/views/classes/globals.store.js';\nimport { reactive } from 'vue';\n\n// Create store instance\nconst trackStore = new Store(`${process.env.API_URL}/api/tracks`);\n\n// State\nexport const state = reactive({\n tracks: [],\n popular: [],\n recent: [],\n featured: [],\n userTracks: [],\n currentTrack: null,\n isLoading: false,\n loadingPopular: false,\n loadingRecent: false,\n loadingFeatured: false,\n});\n\n// Actions\nexport const actions = {\n async fetchTracks(options = {}) {\n state.isLoading = true;\n try {\n const tracks = await trackStore.read(options);\n state.tracks = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching tracks:', error);\n return [];\n } finally {\n state.isLoading = false;\n }\n },\n\n async fetchPopularTracks(options = {}) {\n state.loadingPopular = true;\n try {\n // Обрабатываем options от Feed компонента\n const queryParams = new URLSearchParams();\n queryParams.append('limit', options.limit || 10);\n \n if (options.skip) queryParams.append('skip', options.skip);\n if (options.search) queryParams.append('search', options.search);\n \n const response = await fetch(`${process.env.API_URL}/api/tracks/popular?${queryParams.toString()}`);\n const tracks = await response.json();\n state.popular = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching popular tracks:', error);\n return [];\n } finally {\n state.loadingPopular = false;\n }\n },\n\n async fetchRecentTracks(limit = 10) {\n state.loadingRecent = true;\n try {\n const response = await fetch(`${process.env.API_URL}/api/tracks/recent?limit=${limit}`);\n const tracks = await response.json();\n state.recent = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching recent tracks:', error);\n return [];\n } finally {\n state.loadingRecent = false;\n }\n },\n\n async fetchTracksByGenre(genreId, limit = 20) {\n try {\n const response = await fetch(`${process.env.API_URL}/api/tracks/genre/${genreId}?limit=${limit}`);\n return await response.json();\n } catch (error) {\n console.error('Error fetching tracks by genre:', error);\n return [];\n }\n },\n\n async fetchTrackByUrl(url) {\n try {\n const response = await fetch(`${process.env.API_URL}/api/tracks/url/${url}`);\n const track = await response.json();\n state.currentTrack = track;\n return track;\n } catch (error) {\n console.error('Error fetching track by URL:', error);\n return null;\n }\n },\n\n // Improved createTrack action with better error handling\n async createTrack(trackData) {\n console.log('Creating track with data:', trackData);\n\n // Validate required fields to prevent silent failures\n const requiredFields = ['title', 'artist', 'genre', 'fileUrl'];\n const missingFields = requiredFields.filter(field => !trackData[field]);\n\n if (missingFields.length > 0) {\n const error = new Error(`Missing required fields: ${missingFields.join(', ')}`);\n console.error(error);\n throw error;\n }\n\n // Ensure proper structure for owner and creator fields\n if (!trackData.owner || !trackData.owner.target || !trackData.owner.type) {\n console.error('Track data missing owner information');\n throw new Error('Owner information is required');\n }\n\n if (!trackData.creator || !trackData.creator.target || !trackData.creator.type) {\n console.error('Track data missing creator information');\n throw new Error('Creator information is required');\n }\n\n try {\n console.log('Calling API to create track...');\n\n // Check what API URL we're using\n console.log('API URL:', trackStore.apiUrl);\n\n // Use a timeout to detect hanging requests\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => reject(new Error('Request timed out after 15 seconds')), 15000);\n });\n\n // Race between the actual request and the timeout\n const createdTrack = await Promise.race([trackStore.create(trackData), timeoutPromise]);\n\n console.log('Track created successfully, server response:', createdTrack);\n\n // Check if the response is what we expect\n if (!createdTrack || !createdTrack._id) {\n console.error('API returned success but without expected track data:', createdTrack);\n throw new Error('Invalid response from server');\n }\n\n // Update local state\n state.tracks.unshift(createdTrack);\n state.userTracks.unshift(createdTrack);\n\n console.log('Local state updated with new track');\n return createdTrack;\n } catch (error) {\n console.error('Error creating track:', error);\n\n // Enhanced error logging\n if (error.response) {\n console.error('Error response:', error.response);\n }\n\n // Format the error for better user feedback\n const formattedError = new Error(error.message || 'Failed to create track. Please try again.');\n formattedError.originalError = error;\n\n // Set a global error\n setError({\n message: formattedError.message,\n errorCode: error.errorCode || 'TRACK_CREATE_FAILED',\n });\n\n throw formattedError;\n }\n },\n\n async updateTrack(trackData) {\n try {\n const updatedTrack = await trackStore.update(trackData);\n\n // Update local state\n const index = state.tracks.findIndex(t => t._id === updatedTrack._id);\n if (index !== -1) {\n state.tracks[index] = updatedTrack;\n }\n\n const userIndex = state.userTracks.findIndex(t => t._id === updatedTrack._id);\n if (userIndex !== -1) {\n state.userTracks[userIndex] = updatedTrack;\n }\n\n if (state.currentTrack && state.currentTrack._id === updatedTrack._id) {\n state.currentTrack = updatedTrack;\n }\n\n return updatedTrack;\n } catch (error) {\n console.error('Error updating track:', error);\n throw error;\n }\n },\n\n async deleteTrack(trackId) {\n try {\n await trackStore.delete({ _id: trackId });\n\n // Update local state\n state.tracks = state.tracks.filter(t => t._id !== trackId);\n state.userTracks = state.userTracks.filter(t => t._id !== trackId);\n\n if (state.currentTrack && state.currentTrack._id === trackId) {\n state.currentTrack = null;\n }\n\n return true;\n } catch (error) {\n console.error('Error deleting track:', error);\n throw error;\n }\n },\n\n async fetchUserTracks(userId) {\n try {\n const options = {\n creator: userId,\n limit: 100,\n };\n console.log('fetchUserTracks', userId);\n const tracks = await trackStore.read(options);\n state.userTracks = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching user tracks:', error);\n return [];\n }\n },\n};\n"],"names":["Store","reactive"],"mappings":"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"}
1
+ {"version":3,"file":"tracks.cjs","sources":["../../../../../../src/modules/music/store/tracks.js"],"sourcesContent":["// store/tracks.js\nimport Store from '@martyrs/src/modules/globals/views/classes/globals.store.js';\nimport { reactive } from 'vue';\n\n// Create store instance\nconst trackStore = new Store(`${process.env.API_URL}/api/tracks`);\n\n// State\nexport const state = reactive({\n tracks: [],\n popular: [],\n recent: [],\n featured: [],\n userTracks: [],\n currentTrack: null,\n relatedTracks: [],\n isLoading: false,\n loadingPopular: false,\n loadingRecent: false,\n loadingFeatured: false,\n});\n\n// Actions\nexport const actions = {\n async fetchTracks(options = {}) {\n state.isLoading = true;\n try {\n const tracks = await trackStore.read(options);\n state.tracks = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching tracks:', error);\n return [];\n } finally {\n state.isLoading = false;\n }\n },\n\n async fetchPopularTracks(options = {}) {\n state.loadingPopular = true;\n try {\n // Обрабатываем options от Feed компонента\n const queryParams = new URLSearchParams();\n queryParams.append('limit', options.limit || 10);\n \n if (options.skip) queryParams.append('skip', options.skip);\n if (options.search) queryParams.append('search', options.search);\n \n const response = await fetch(`${process.env.API_URL}/api/tracks/popular?${queryParams.toString()}`);\n const tracks = await response.json();\n state.popular = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching popular tracks:', error);\n return [];\n } finally {\n state.loadingPopular = false;\n }\n },\n\n async fetchRecentTracks(limit = 10) {\n state.loadingRecent = true;\n try {\n const response = await fetch(`${process.env.API_URL}/api/tracks/recent?limit=${limit}`);\n const tracks = await response.json();\n state.recent = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching recent tracks:', error);\n return [];\n } finally {\n state.loadingRecent = false;\n }\n },\n\n async fetchTracksByGenre(genreId, limit = 20) {\n try {\n const response = await fetch(`${process.env.API_URL}/api/tracks/genre/${genreId}?limit=${limit}`);\n return await response.json();\n } catch (error) {\n console.error('Error fetching tracks by genre:', error);\n return [];\n }\n },\n\n async fetchTrackByUrl(url) {\n try {\n const response = await fetch(`${process.env.API_URL}/api/tracks/url/${url}`);\n const track = await response.json();\n state.currentTrack = track;\n return track;\n } catch (error) {\n console.error('Error fetching track by URL:', error);\n return null;\n }\n },\n\n // Improved createTrack action with better error handling\n async createTrack(trackData) {\n console.log('Creating track with data:', trackData);\n\n // Validate required fields to prevent silent failures\n const requiredFields = ['title', 'artist', 'genre', 'fileUrl'];\n const missingFields = requiredFields.filter(field => !trackData[field]);\n\n if (missingFields.length > 0) {\n const error = new Error(`Missing required fields: ${missingFields.join(', ')}`);\n console.error(error);\n throw error;\n }\n\n // Ensure proper structure for owner and creator fields\n if (!trackData.owner || !trackData.owner.target || !trackData.owner.type) {\n console.error('Track data missing owner information');\n throw new Error('Owner information is required');\n }\n\n if (!trackData.creator || !trackData.creator.target || !trackData.creator.type) {\n console.error('Track data missing creator information');\n throw new Error('Creator information is required');\n }\n\n try {\n console.log('Calling API to create track...');\n\n // Check what API URL we're using\n console.log('API URL:', trackStore.apiUrl);\n\n // Use a timeout to detect hanging requests\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => reject(new Error('Request timed out after 15 seconds')), 15000);\n });\n\n // Race between the actual request and the timeout\n const createdTrack = await Promise.race([trackStore.create(trackData), timeoutPromise]);\n\n console.log('Track created successfully, server response:', createdTrack);\n\n // Check if the response is what we expect\n if (!createdTrack || !createdTrack._id) {\n console.error('API returned success but without expected track data:', createdTrack);\n throw new Error('Invalid response from server');\n }\n\n // Update local state\n state.tracks.unshift(createdTrack);\n state.userTracks.unshift(createdTrack);\n\n console.log('Local state updated with new track');\n return createdTrack;\n } catch (error) {\n console.error('Error creating track:', error);\n\n // Enhanced error logging\n if (error.response) {\n console.error('Error response:', error.response);\n }\n\n // Format the error for better user feedback\n const formattedError = new Error(error.message || 'Failed to create track. Please try again.');\n formattedError.originalError = error;\n\n // Set a global error\n setError({\n message: formattedError.message,\n errorCode: error.errorCode || 'TRACK_CREATE_FAILED',\n });\n\n throw formattedError;\n }\n },\n\n async updateTrack(trackData) {\n try {\n const updatedTrack = await trackStore.update(trackData);\n\n // Update local state\n const index = state.tracks.findIndex(t => t._id === updatedTrack._id);\n if (index !== -1) {\n state.tracks[index] = updatedTrack;\n }\n\n const userIndex = state.userTracks.findIndex(t => t._id === updatedTrack._id);\n if (userIndex !== -1) {\n state.userTracks[userIndex] = updatedTrack;\n }\n\n if (state.currentTrack && state.currentTrack._id === updatedTrack._id) {\n state.currentTrack = updatedTrack;\n }\n\n return updatedTrack;\n } catch (error) {\n console.error('Error updating track:', error);\n throw error;\n }\n },\n\n async deleteTrack(trackId) {\n try {\n await trackStore.delete({ _id: trackId });\n\n // Update local state\n state.tracks = state.tracks.filter(t => t._id !== trackId);\n state.userTracks = state.userTracks.filter(t => t._id !== trackId);\n\n if (state.currentTrack && state.currentTrack._id === trackId) {\n state.currentTrack = null;\n }\n\n return true;\n } catch (error) {\n console.error('Error deleting track:', error);\n throw error;\n }\n },\n\n async fetchUserTracks(userId) {\n try {\n const options = {\n creator: userId,\n limit: 100,\n };\n console.log('fetchUserTracks', userId);\n const tracks = await trackStore.read(options);\n state.userTracks = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching user tracks:', error);\n return [];\n }\n },\n\n async fetchRelatedTracks(trackUrl) {\n try {\n // Если есть currentTrack, ищем треки того же артиста\n if (state.currentTrack && state.currentTrack.artist) {\n const artistId = typeof state.currentTrack.artist === 'object' \n ? state.currentTrack.artist._id \n : state.currentTrack.artist;\n \n const queryParams = new URLSearchParams();\n queryParams.append('artist', artistId);\n queryParams.append('limit', '5');\n \n const response = await fetch(`${process.env.API_URL}/api/tracks/read?${queryParams.toString()}`);\n const tracks = await response.json();\n \n // Исключаем текущий трек\n const relatedTracks = tracks.filter(track => track._id !== state.currentTrack._id);\n state.relatedTracks = relatedTracks;\n return relatedTracks;\n }\n \n state.relatedTracks = [];\n return [];\n } catch (error) {\n console.error('Error fetching related tracks:', error);\n state.relatedTracks = [];\n return [];\n }\n },\n};\n"],"names":["Store","reactive"],"mappings":"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"}
@@ -8,6 +8,7 @@ const state = reactive({
8
8
  featured: [],
9
9
  userTracks: [],
10
10
  currentTrack: null,
11
+ relatedTracks: [],
11
12
  isLoading: false,
12
13
  loadingPopular: false,
13
14
  loadingRecent: false,
@@ -175,6 +176,27 @@ const actions = {
175
176
  console.error("Error fetching user tracks:", error);
176
177
  return [];
177
178
  }
179
+ },
180
+ async fetchRelatedTracks(trackUrl) {
181
+ try {
182
+ if (state.currentTrack && state.currentTrack.artist) {
183
+ const artistId = typeof state.currentTrack.artist === "object" ? state.currentTrack.artist._id : state.currentTrack.artist;
184
+ const queryParams = new URLSearchParams();
185
+ queryParams.append("artist", artistId);
186
+ queryParams.append("limit", "5");
187
+ const response = await fetch(`${process.env.API_URL}/api/tracks/read?${queryParams.toString()}`);
188
+ const tracks = await response.json();
189
+ const relatedTracks = tracks.filter((track) => track._id !== state.currentTrack._id);
190
+ state.relatedTracks = relatedTracks;
191
+ return relatedTracks;
192
+ }
193
+ state.relatedTracks = [];
194
+ return [];
195
+ } catch (error) {
196
+ console.error("Error fetching related tracks:", error);
197
+ state.relatedTracks = [];
198
+ return [];
199
+ }
178
200
  }
179
201
  };
180
202
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"tracks.js","sources":["../../../../../../src/modules/music/store/tracks.js"],"sourcesContent":["// store/tracks.js\nimport Store from '@martyrs/src/modules/globals/views/classes/globals.store.js';\nimport { reactive } from 'vue';\n\n// Create store instance\nconst trackStore = new Store(`${process.env.API_URL}/api/tracks`);\n\n// State\nexport const state = reactive({\n tracks: [],\n popular: [],\n recent: [],\n featured: [],\n userTracks: [],\n currentTrack: null,\n isLoading: false,\n loadingPopular: false,\n loadingRecent: false,\n loadingFeatured: false,\n});\n\n// Actions\nexport const actions = {\n async fetchTracks(options = {}) {\n state.isLoading = true;\n try {\n const tracks = await trackStore.read(options);\n state.tracks = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching tracks:', error);\n return [];\n } finally {\n state.isLoading = false;\n }\n },\n\n async fetchPopularTracks(options = {}) {\n state.loadingPopular = true;\n try {\n // Обрабатываем options от Feed компонента\n const queryParams = new URLSearchParams();\n queryParams.append('limit', options.limit || 10);\n \n if (options.skip) queryParams.append('skip', options.skip);\n if (options.search) queryParams.append('search', options.search);\n \n const response = await fetch(`${process.env.API_URL}/api/tracks/popular?${queryParams.toString()}`);\n const tracks = await response.json();\n state.popular = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching popular tracks:', error);\n return [];\n } finally {\n state.loadingPopular = false;\n }\n },\n\n async fetchRecentTracks(limit = 10) {\n state.loadingRecent = true;\n try {\n const response = await fetch(`${process.env.API_URL}/api/tracks/recent?limit=${limit}`);\n const tracks = await response.json();\n state.recent = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching recent tracks:', error);\n return [];\n } finally {\n state.loadingRecent = false;\n }\n },\n\n async fetchTracksByGenre(genreId, limit = 20) {\n try {\n const response = await fetch(`${process.env.API_URL}/api/tracks/genre/${genreId}?limit=${limit}`);\n return await response.json();\n } catch (error) {\n console.error('Error fetching tracks by genre:', error);\n return [];\n }\n },\n\n async fetchTrackByUrl(url) {\n try {\n const response = await fetch(`${process.env.API_URL}/api/tracks/url/${url}`);\n const track = await response.json();\n state.currentTrack = track;\n return track;\n } catch (error) {\n console.error('Error fetching track by URL:', error);\n return null;\n }\n },\n\n // Improved createTrack action with better error handling\n async createTrack(trackData) {\n console.log('Creating track with data:', trackData);\n\n // Validate required fields to prevent silent failures\n const requiredFields = ['title', 'artist', 'genre', 'fileUrl'];\n const missingFields = requiredFields.filter(field => !trackData[field]);\n\n if (missingFields.length > 0) {\n const error = new Error(`Missing required fields: ${missingFields.join(', ')}`);\n console.error(error);\n throw error;\n }\n\n // Ensure proper structure for owner and creator fields\n if (!trackData.owner || !trackData.owner.target || !trackData.owner.type) {\n console.error('Track data missing owner information');\n throw new Error('Owner information is required');\n }\n\n if (!trackData.creator || !trackData.creator.target || !trackData.creator.type) {\n console.error('Track data missing creator information');\n throw new Error('Creator information is required');\n }\n\n try {\n console.log('Calling API to create track...');\n\n // Check what API URL we're using\n console.log('API URL:', trackStore.apiUrl);\n\n // Use a timeout to detect hanging requests\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => reject(new Error('Request timed out after 15 seconds')), 15000);\n });\n\n // Race between the actual request and the timeout\n const createdTrack = await Promise.race([trackStore.create(trackData), timeoutPromise]);\n\n console.log('Track created successfully, server response:', createdTrack);\n\n // Check if the response is what we expect\n if (!createdTrack || !createdTrack._id) {\n console.error('API returned success but without expected track data:', createdTrack);\n throw new Error('Invalid response from server');\n }\n\n // Update local state\n state.tracks.unshift(createdTrack);\n state.userTracks.unshift(createdTrack);\n\n console.log('Local state updated with new track');\n return createdTrack;\n } catch (error) {\n console.error('Error creating track:', error);\n\n // Enhanced error logging\n if (error.response) {\n console.error('Error response:', error.response);\n }\n\n // Format the error for better user feedback\n const formattedError = new Error(error.message || 'Failed to create track. Please try again.');\n formattedError.originalError = error;\n\n // Set a global error\n setError({\n message: formattedError.message,\n errorCode: error.errorCode || 'TRACK_CREATE_FAILED',\n });\n\n throw formattedError;\n }\n },\n\n async updateTrack(trackData) {\n try {\n const updatedTrack = await trackStore.update(trackData);\n\n // Update local state\n const index = state.tracks.findIndex(t => t._id === updatedTrack._id);\n if (index !== -1) {\n state.tracks[index] = updatedTrack;\n }\n\n const userIndex = state.userTracks.findIndex(t => t._id === updatedTrack._id);\n if (userIndex !== -1) {\n state.userTracks[userIndex] = updatedTrack;\n }\n\n if (state.currentTrack && state.currentTrack._id === updatedTrack._id) {\n state.currentTrack = updatedTrack;\n }\n\n return updatedTrack;\n } catch (error) {\n console.error('Error updating track:', error);\n throw error;\n }\n },\n\n async deleteTrack(trackId) {\n try {\n await trackStore.delete({ _id: trackId });\n\n // Update local state\n state.tracks = state.tracks.filter(t => t._id !== trackId);\n state.userTracks = state.userTracks.filter(t => t._id !== trackId);\n\n if (state.currentTrack && state.currentTrack._id === trackId) {\n state.currentTrack = null;\n }\n\n return true;\n } catch (error) {\n console.error('Error deleting track:', error);\n throw error;\n }\n },\n\n async fetchUserTracks(userId) {\n try {\n const options = {\n creator: userId,\n limit: 100,\n };\n console.log('fetchUserTracks', userId);\n const tracks = await trackStore.read(options);\n state.userTracks = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching user tracks:', error);\n return [];\n }\n },\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tracks.js","sources":["../../../../../../src/modules/music/store/tracks.js"],"sourcesContent":["// store/tracks.js\nimport Store from '@martyrs/src/modules/globals/views/classes/globals.store.js';\nimport { reactive } from 'vue';\n\n// Create store instance\nconst trackStore = new Store(`${process.env.API_URL}/api/tracks`);\n\n// State\nexport const state = reactive({\n tracks: [],\n popular: [],\n recent: [],\n featured: [],\n userTracks: [],\n currentTrack: null,\n relatedTracks: [],\n isLoading: false,\n loadingPopular: false,\n loadingRecent: false,\n loadingFeatured: false,\n});\n\n// Actions\nexport const actions = {\n async fetchTracks(options = {}) {\n state.isLoading = true;\n try {\n const tracks = await trackStore.read(options);\n state.tracks = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching tracks:', error);\n return [];\n } finally {\n state.isLoading = false;\n }\n },\n\n async fetchPopularTracks(options = {}) {\n state.loadingPopular = true;\n try {\n // Обрабатываем options от Feed компонента\n const queryParams = new URLSearchParams();\n queryParams.append('limit', options.limit || 10);\n \n if (options.skip) queryParams.append('skip', options.skip);\n if (options.search) queryParams.append('search', options.search);\n \n const response = await fetch(`${process.env.API_URL}/api/tracks/popular?${queryParams.toString()}`);\n const tracks = await response.json();\n state.popular = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching popular tracks:', error);\n return [];\n } finally {\n state.loadingPopular = false;\n }\n },\n\n async fetchRecentTracks(limit = 10) {\n state.loadingRecent = true;\n try {\n const response = await fetch(`${process.env.API_URL}/api/tracks/recent?limit=${limit}`);\n const tracks = await response.json();\n state.recent = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching recent tracks:', error);\n return [];\n } finally {\n state.loadingRecent = false;\n }\n },\n\n async fetchTracksByGenre(genreId, limit = 20) {\n try {\n const response = await fetch(`${process.env.API_URL}/api/tracks/genre/${genreId}?limit=${limit}`);\n return await response.json();\n } catch (error) {\n console.error('Error fetching tracks by genre:', error);\n return [];\n }\n },\n\n async fetchTrackByUrl(url) {\n try {\n const response = await fetch(`${process.env.API_URL}/api/tracks/url/${url}`);\n const track = await response.json();\n state.currentTrack = track;\n return track;\n } catch (error) {\n console.error('Error fetching track by URL:', error);\n return null;\n }\n },\n\n // Improved createTrack action with better error handling\n async createTrack(trackData) {\n console.log('Creating track with data:', trackData);\n\n // Validate required fields to prevent silent failures\n const requiredFields = ['title', 'artist', 'genre', 'fileUrl'];\n const missingFields = requiredFields.filter(field => !trackData[field]);\n\n if (missingFields.length > 0) {\n const error = new Error(`Missing required fields: ${missingFields.join(', ')}`);\n console.error(error);\n throw error;\n }\n\n // Ensure proper structure for owner and creator fields\n if (!trackData.owner || !trackData.owner.target || !trackData.owner.type) {\n console.error('Track data missing owner information');\n throw new Error('Owner information is required');\n }\n\n if (!trackData.creator || !trackData.creator.target || !trackData.creator.type) {\n console.error('Track data missing creator information');\n throw new Error('Creator information is required');\n }\n\n try {\n console.log('Calling API to create track...');\n\n // Check what API URL we're using\n console.log('API URL:', trackStore.apiUrl);\n\n // Use a timeout to detect hanging requests\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => reject(new Error('Request timed out after 15 seconds')), 15000);\n });\n\n // Race between the actual request and the timeout\n const createdTrack = await Promise.race([trackStore.create(trackData), timeoutPromise]);\n\n console.log('Track created successfully, server response:', createdTrack);\n\n // Check if the response is what we expect\n if (!createdTrack || !createdTrack._id) {\n console.error('API returned success but without expected track data:', createdTrack);\n throw new Error('Invalid response from server');\n }\n\n // Update local state\n state.tracks.unshift(createdTrack);\n state.userTracks.unshift(createdTrack);\n\n console.log('Local state updated with new track');\n return createdTrack;\n } catch (error) {\n console.error('Error creating track:', error);\n\n // Enhanced error logging\n if (error.response) {\n console.error('Error response:', error.response);\n }\n\n // Format the error for better user feedback\n const formattedError = new Error(error.message || 'Failed to create track. Please try again.');\n formattedError.originalError = error;\n\n // Set a global error\n setError({\n message: formattedError.message,\n errorCode: error.errorCode || 'TRACK_CREATE_FAILED',\n });\n\n throw formattedError;\n }\n },\n\n async updateTrack(trackData) {\n try {\n const updatedTrack = await trackStore.update(trackData);\n\n // Update local state\n const index = state.tracks.findIndex(t => t._id === updatedTrack._id);\n if (index !== -1) {\n state.tracks[index] = updatedTrack;\n }\n\n const userIndex = state.userTracks.findIndex(t => t._id === updatedTrack._id);\n if (userIndex !== -1) {\n state.userTracks[userIndex] = updatedTrack;\n }\n\n if (state.currentTrack && state.currentTrack._id === updatedTrack._id) {\n state.currentTrack = updatedTrack;\n }\n\n return updatedTrack;\n } catch (error) {\n console.error('Error updating track:', error);\n throw error;\n }\n },\n\n async deleteTrack(trackId) {\n try {\n await trackStore.delete({ _id: trackId });\n\n // Update local state\n state.tracks = state.tracks.filter(t => t._id !== trackId);\n state.userTracks = state.userTracks.filter(t => t._id !== trackId);\n\n if (state.currentTrack && state.currentTrack._id === trackId) {\n state.currentTrack = null;\n }\n\n return true;\n } catch (error) {\n console.error('Error deleting track:', error);\n throw error;\n }\n },\n\n async fetchUserTracks(userId) {\n try {\n const options = {\n creator: userId,\n limit: 100,\n };\n console.log('fetchUserTracks', userId);\n const tracks = await trackStore.read(options);\n state.userTracks = tracks;\n return tracks;\n } catch (error) {\n console.error('Error fetching user tracks:', error);\n return [];\n }\n },\n\n async fetchRelatedTracks(trackUrl) {\n try {\n // Если есть currentTrack, ищем треки того же артиста\n if (state.currentTrack && state.currentTrack.artist) {\n const artistId = typeof state.currentTrack.artist === 'object' \n ? state.currentTrack.artist._id \n : state.currentTrack.artist;\n \n const queryParams = new URLSearchParams();\n queryParams.append('artist', artistId);\n queryParams.append('limit', '5');\n \n const response = await fetch(`${process.env.API_URL}/api/tracks/read?${queryParams.toString()}`);\n const tracks = await response.json();\n \n // Исключаем текущий трек\n const relatedTracks = tracks.filter(track => track._id !== state.currentTrack._id);\n state.relatedTracks = relatedTracks;\n return relatedTracks;\n }\n \n state.relatedTracks = [];\n return [];\n } catch (error) {\n console.error('Error fetching related tracks:', error);\n state.relatedTracks = [];\n return [];\n }\n },\n};\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { ref, createElementBlock, openBlock, createVNode, createElementVNode, createCommentVNode, toDisplayString, Fragment, renderList, createBlock, Transition, withCtx, createTextVNode, withModifiers } from "vue";
2
2
  import _sfc_main$1 from "../../../globals/views/components/blocks/CardHeader.vue.js";
3
- import IconTime from "../../../icons/entities/IconTime.vue.js";
3
+ import IconClock from "../../../icons/entities/IconTime.vue.js";
4
4
  const _hoisted_1 = { class: "bg-light pos-relative pd-medium radius-medium" };
5
5
  const _hoisted_2 = { class: "mn-b-small pd-small bg-white radius-small flex-nowrap flex" };
6
6
  const _hoisted_3 = { class: "w-100" };
@@ -90,7 +90,7 @@ const _sfc_main = {
90
90
  }, toDisplayString(!spoiler.value ? `+${__props.order.positions.length - 2} more` : `Hide`), 1)) : createCommentVNode("", true)
91
91
  ]),
92
92
  createElementVNode("div", _hoisted_11, [
93
- createVNode(IconTime, {
93
+ createVNode(IconClock, {
94
94
  class: "i-semi t-transp",
95
95
  fill: "rgb(var(--black)"
96
96
  }),
@@ -3,7 +3,7 @@ import { useRouter, useRoute } from "vue-router";
3
3
  import _sfc_main$2 from "../../../../components/Button/Button.vue.js";
4
4
  import Select from "../../../../components/Select/Select.vue2.js";
5
5
  import _sfc_main$1 from "../../../../components/Popup/Popup.vue.js";
6
- import IconTime from "../../../icons/entities/IconTime.vue.js";
6
+ import IconClock from "../../../icons/entities/IconTime.vue.js";
7
7
  import _sfc_main$3 from "../blocks/CardOrderItem.vue.js";
8
8
  import _sfc_main$5 from "../../../organizations/components/blocks/CardOrganization.vue.js";
9
9
  import _sfc_main$6 from "../../../chats/components/pages/ChatPage.vue.js";
@@ -337,7 +337,7 @@ const _sfc_main = {
337
337
  ]),
338
338
  unref(route).meta.context !== "user" && unref(route).meta.context !== "root" ? (openBlock(), createElementBlock("div", _hoisted_24, [
339
339
  createElementVNode("div", _hoisted_25, [
340
- createVNode(IconTime, {
340
+ createVNode(IconClock, {
341
341
  class: "i-semi t-transp",
342
342
  fill: "rgb(var(--black)"
343
343
  }),
@@ -2,7 +2,7 @@
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
3
  const vue = require("vue");
4
4
  const vueRouter = require("vue-router");
5
- ;/* empty css */
5
+ ;/* empty css */
6
6
  const Button = require("../../../../components/Button/Button.vue.cjs");
7
7
  const Tab = require("../../../../components/Tab/Tab.vue2.cjs");
8
8
  const Popup = require("../../../../components/Popup/Popup.vue.cjs");
@@ -1,6 +1,6 @@
1
1
  import { getCurrentInstance, computed, ref, onMounted, createElementBlock, openBlock, createVNode, createBlock, createCommentVNode, withCtx, createElementVNode, createTextVNode, unref, Fragment, renderList, toDisplayString, normalizeClass } from "vue";
2
2
  import { useRoute, useRouter } from "vue-router";
3
- /* empty css */
3
+ /* empty css */
4
4
  import _sfc_main$2 from "../../../../components/Button/Button.vue.js";
5
5
  import _sfc_main$3 from "../../../../components/Tab/Tab.vue2.js";
6
6
  import _sfc_main$4 from "../../../../components/Popup/Popup.vue.js";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
3
3
  const vue = require("vue");
4
4
  const vueRouter = require("vue-router");
5
5
  const Block = require("../../../../components/Block/Block.vue.cjs");
6
- ;/* empty css */
6
+ ;/* empty css */
7
7
  const clickOutside = require("../../../../components/FieldPhone/click-outside.cjs");
8
8
  ;/* empty css */
9
9
  const Feed = require("../../../../components/Feed/Feed.vue.cjs");
@@ -1,7 +1,7 @@
1
1
  import { ref, createElementBlock, openBlock, Fragment, createVNode, withCtx, withDirectives, createBlock, createCommentVNode, unref, isRef, renderList, createTextVNode } from "vue";
2
2
  import { useRoute } from "vue-router";
3
3
  import _sfc_main$1 from "../../../../components/Block/Block.vue.js";
4
- /* empty css */
4
+ /* empty css */
5
5
  import clickOutside from "../../../../components/FieldPhone/click-outside.js";
6
6
  /* empty css */
7
7
  import _sfc_main$4 from "../../../../components/Feed/Feed.vue.js";
@@ -2,7 +2,7 @@
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
3
  const vue = require("vue");
4
4
  const Block = require("../../../../components/Block/Block.vue.cjs");
5
- const Field = require("../../../../components/Field/Field.vue2.cjs");
5
+ const Field = require("../../../../components/Field/Field.vue.cjs");
6
6
  const FieldPhone = require("../../../../components/FieldPhone/FieldPhone.vue.cjs");
7
7
  const Select = require("../../../../components/Select/Select.vue2.cjs");
8
8
  const _hoisted_1 = { class: "gap-thin flex-justify-between flex-nowrap flex" };
@@ -1,6 +1,6 @@
1
1
  import { ref, createBlock, openBlock, withCtx, createVNode, createElementVNode, unref, isRef } from "vue";
2
2
  import _sfc_main$1 from "../../../../components/Block/Block.vue.js";
3
- import Field from "../../../../components/Field/Field.vue2.js";
3
+ import Field from "../../../../components/Field/Field.vue.js";
4
4
  import _sfc_main$2 from "../../../../components/FieldPhone/FieldPhone.vue.js";
5
5
  import Select from "../../../../components/Select/Select.vue2.js";
6
6
  const _hoisted_1 = { class: "gap-thin flex-justify-between flex-nowrap flex" };
@@ -6,7 +6,7 @@ const vueRouter = require("vue-router");
6
6
  ;/* empty css */
7
7
  ;/* empty css */
8
8
  ;/* empty css */
9
- const Field = require("../../../../components/Field/Field.vue2.cjs");
9
+ const Field = require("../../../../components/Field/Field.vue.cjs");
10
10
  const Radio = require("../../../../components/Radio/Radio.vue.cjs");
11
11
  ;/* empty css */
12
12
  ;/* empty css */
@@ -4,7 +4,7 @@ import { useRoute } from "vue-router";
4
4
  /* empty css */
5
5
  /* empty css */
6
6
  /* empty css */
7
- import Field from "../../../../components/Field/Field.vue2.js";
7
+ import Field from "../../../../components/Field/Field.vue.js";
8
8
  import _sfc_main$2 from "../../../../components/Radio/Radio.vue.js";
9
9
  /* empty css */
10
10
  /* empty css */
@@ -4,7 +4,7 @@ import _sfc_main$4 from "../../../orders/components/blocks/CardOrderItem.vue.js"
4
4
  import _sfc_main$1 from "../../../../components/Chips/Chips.vue.js";
5
5
  import PlaceholderOrganizationPic from "../../../icons/placeholders/PlaceholderOrganizationPic.vue.js";
6
6
  import _sfc_main$3 from "../../../icons/entities/IconShopcart.vue.js";
7
- import IconTime from "../../../icons/entities/IconTime.vue.js";
7
+ import IconClock from "../../../icons/entities/IconTime.vue.js";
8
8
  import _sfc_main$2 from "../elements/ButtonToggleMembership.vue.js";
9
9
  const _hoisted_1 = { class: "h-4r flex pos-relative" };
10
10
  const _hoisted_2 = ["src"];
@@ -117,7 +117,7 @@ const _sfc_main = {
117
117
  ])
118
118
  ]),
119
119
  __props.showProducts && __props.organization.products ? (openBlock(), createElementBlock("div", _hoisted_8, [
120
- createVNode(IconTime, { class: "i-medium t-transp mn-r-micro" }),
120
+ createVNode(IconClock, { class: "i-medium t-transp mn-r-micro" }),
121
121
  createElementVNode("span", _hoisted_9, toDisplayString(__props.organization.distance ? __props.organization.distance > 50 ? "3-5 days" : Math.ceil((5 + 5 + 3 * __props.organization.distance) / 5) * 5 + "-" + Math.ceil((15 + 5 + 3 * __props.organization.distance) / 5) * 5 + " MIN" : "Unavailable"), 1),
122
122
  __props.organization.distance && __props.organization.distance < 50 ? (openBlock(), createElementBlock("span", _hoisted_10, "|")) : createCommentVNode("", true),
123
123
  __props.organization.distance && __props.organization.distance < 50 ? (openBlock(), createElementBlock("span", _hoisted_11, toDisplayString(__props.organization.distance ? __props.organization.distance.toFixed(1) + "KM" : ""), 1)) : createCommentVNode("", true),
@@ -7,7 +7,7 @@ require("vue-i18n");
7
7
  ;/* empty css */
8
8
  const UploadImage = require("../../../../components/UploadImage/UploadImage.vue.cjs");
9
9
  ;/* empty css */
10
- const Field = require("../../../../components/Field/Field.vue2.cjs");
10
+ const Field = require("../../../../components/Field/Field.vue.cjs");
11
11
  ;/* empty css */
12
12
  const Checkbox = require("../../../../components/Checkbox/Checkbox.vue.cjs");
13
13
  require("../../../../../../node_modules/.pnpm/@googlemaps_js-api-loader@1.16.8/node_modules/@googlemaps/js-api-loader/dist/index.cjs");
@@ -5,7 +5,7 @@ import "vue-i18n";
5
5
  /* empty css */
6
6
  import _sfc_main$3 from "../../../../components/UploadImage/UploadImage.vue.js";
7
7
  /* empty css */
8
- import Field from "../../../../components/Field/Field.vue2.js";
8
+ import Field from "../../../../components/Field/Field.vue.js";
9
9
  /* empty css */
10
10
  import _sfc_main$8 from "../../../../components/Checkbox/Checkbox.vue.js";
11
11
  import "../../../../../../node_modules/.pnpm/@googlemaps_js-api-loader@1.16.8/node_modules/@googlemaps/js-api-loader/dist/index.js";
@@ -8,7 +8,7 @@ const Feed = require("../../../../components/Feed/Feed.vue.cjs");
8
8
  const Popup = require("../../../../components/Popup/Popup.vue.cjs");
9
9
  const SectionPageTitle = require("../../../globals/views/components/sections/SectionPageTitle.vue.cjs");
10
10
  const MembersAdd = require("../sections/MembersAdd.vue.cjs");
11
- ;/* empty css */
11
+ ;/* empty css */
12
12
  require("../../../../components/Menu/MenuItem.vue.cjs");
13
13
  const CardUser = require("../../../auth/views/components/blocks/CardUser.vue.cjs");
14
14
  const CardDepartment = require("../blocks/CardDepartment.vue.cjs");
@@ -6,7 +6,7 @@ import _sfc_main$4 from "../../../../components/Feed/Feed.vue.js";
6
6
  import _sfc_main$2 from "../../../../components/Popup/Popup.vue.js";
7
7
  import _sfc_main$1 from "../../../globals/views/components/sections/SectionPageTitle.vue.js";
8
8
  import _sfc_main$3 from "../sections/MembersAdd.vue.js";
9
- /* empty css */
9
+ /* empty css */
10
10
  import "../../../../components/Menu/MenuItem.vue.js";
11
11
  import _sfc_main$5 from "../../../auth/views/components/blocks/CardUser.vue.js";
12
12
  import CardDepartment from "../blocks/CardDepartment.vue.js";