@ozdao/martyrs 0.2.495 → 0.2.497
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.
- package/dist/_virtual/index.cjs +4 -4
- package/dist/_virtual/index.js +4 -4
- package/dist/_virtual/index2.cjs +4 -4
- package/dist/_virtual/index2.js +4 -4
- package/dist/builder.cjs +43 -42
- package/dist/builder.js +45 -44
- package/dist/globals.server.cjs +13 -2
- package/dist/globals.server.js +13 -2
- package/dist/martyrs/src/components/Block/Block.vue.cjs +1 -1
- package/dist/martyrs/src/components/Block/Block.vue.js +1 -1
- package/dist/martyrs/src/components/Button/{Button.vue.cjs → Button.vue2.cjs} +2 -2
- package/dist/martyrs/src/components/Button/Button.vue2.cjs.map +1 -0
- package/dist/martyrs/src/components/Button/{Button.vue.js → Button.vue2.js} +2 -2
- package/dist/martyrs/src/components/Button/{Button.vue.cjs.map → Button.vue2.js.map} +1 -1
- package/dist/martyrs/src/components/Chips/{Chips.vue.cjs → Chips.vue2.cjs} +2 -2
- package/dist/martyrs/src/components/Chips/Chips.vue2.cjs.map +1 -0
- package/dist/martyrs/src/components/Chips/{Chips.vue.js → Chips.vue2.js} +2 -2
- package/dist/martyrs/src/components/Chips/Chips.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.cjs → Dropdown.vue2.cjs} +2 -2
- package/dist/martyrs/src/components/Dropdown/Dropdown.vue2.cjs.map +1 -0
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.js → Dropdown.vue2.js} +2 -2
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.cjs.map → Dropdown.vue2.js.map} +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.cjs +2 -2
- package/dist/martyrs/src/components/Feed/Feed.vue.js +2 -2
- package/dist/martyrs/src/components/FieldTags/FieldTags.vue.cjs +1 -1
- package/dist/martyrs/src/components/FieldTags/FieldTags.vue.js +1 -1
- package/dist/martyrs/src/components/Select/{Select.vue2.cjs → Select.vue.cjs} +2 -2
- package/dist/martyrs/src/components/Select/{Select.vue2.js.map → Select.vue.cjs.map} +1 -1
- package/dist/martyrs/src/components/Select/{Select.vue2.js → Select.vue.js} +2 -2
- package/dist/martyrs/src/components/Select/Select.vue.js.map +1 -0
- package/dist/martyrs/src/components/Tooltip/{Tooltip.vue2.cjs → Tooltip.vue.cjs} +2 -2
- package/dist/martyrs/src/components/Tooltip/{Tooltip.vue2.js.map → Tooltip.vue.cjs.map} +1 -1
- package/dist/martyrs/src/components/Tooltip/{Tooltip.vue2.js → Tooltip.vue.js} +2 -2
- package/dist/martyrs/src/components/Tooltip/Tooltip.vue.js.map +1 -0
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditAccount.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditAccount.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.js +1 -1
- package/dist/martyrs/src/modules/community/components/blocks/CardBlogpost.vue.cjs +1 -1
- package/dist/martyrs/src/modules/community/components/blocks/CardBlogpost.vue.js +1 -1
- package/dist/martyrs/src/modules/community/components/layouts/Community.vue.cjs +1 -1
- package/dist/martyrs/src/modules/community/components/layouts/Community.vue.js +1 -1
- package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.cjs +2 -2
- package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.js +2 -2
- package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.cjs +2 -2
- package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.js +2 -2
- package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/elements/ButtonJoin.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/elements/ButtonJoin.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.cjs +3 -3
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +3 -3
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.cjs +3 -3
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +3 -3
- package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.cjs +3 -3
- package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.js +3 -3
- package/dist/martyrs/src/modules/globals/views/components/blocks/PopupAuth.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/PopupAuth.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/Header.vue.cjs +2 -2
- package/dist/martyrs/src/modules/globals/views/components/partials/Header.vue.js +2 -2
- package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/NavigationBar.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/NavigationBar.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.cjs +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.cjs +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.cjs +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.cjs +3 -3
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js +3 -3
- package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.cjs +95 -0
- package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.cjs.map +1 -0
- package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js +95 -0
- package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js.map +1 -0
- package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.cjs +2 -2
- package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.cjs +2 -2
- package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.cjs +2 -2
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.cjs +87 -140
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +97 -150
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.cjs +2 -2
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.cjs +86 -136
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +102 -152
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.cjs +147 -159
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +172 -184
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/TrackCreate.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/pages/TrackCreate.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.cjs +14 -19
- package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js +15 -20
- package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.cjs +2 -2
- package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.cjs +2 -2
- package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/router/music.cjs +4 -4
- package/dist/martyrs/src/modules/music/router/music.js +4 -4
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderUser.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderUser.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.cjs +3 -3
- package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +3 -3
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormAddCustomer.vue.cjs +2 -2
- package/dist/martyrs/src/modules/orders/components/sections/FormAddCustomer.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/sections/FormCustomerDetails.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormCustomerDetails.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs +2 -2
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/sections/FormPayment.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormPayment.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.cjs +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.cjs +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/sections/DetailsTabSection.vue.cjs +2 -2
- package/dist/martyrs/src/modules/organizations/components/sections/DetailsTabSection.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.cjs +2 -2
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +1 -1
- package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.cjs +1 -1
- package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js +1 -1
- package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.cjs +2 -2
- package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/pages/views/components/partials/SidebarPages.vue.cjs +1 -1
- package/dist/martyrs/src/modules/pages/views/components/partials/SidebarPages.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/ProductDiscounts.vue.cjs +2 -2
- package/dist/martyrs/src/modules/products/components/blocks/ProductDiscounts.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs +3 -3
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +3 -3
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.cjs +2 -2
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.cjs +2 -2
- package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.cjs +2 -2
- package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/sections/ProductConfigurator.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductConfigurator.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductsRecommended.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductsRecommended.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.cjs +2 -2
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js +2 -2
- package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.cjs +2 -2
- package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.js +2 -2
- package/dist/martyrs/src/modules/spots/components/blocks/CardSpot.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/CardSpot.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/Map.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/Map.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.cjs +2 -2
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.cjs +2 -2
- package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.js +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.cjs +5 -5
- package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.js +5 -5
- package/dist/martyrs.css +1 -1
- package/dist/style.css +98 -81
- package/package.json +1 -1
- package/src/builder/rspack/rspack.config.ssr.client.js +41 -41
- package/src/modules/globals/controllers/classes/globals.websocket.js +11 -2
- package/src/modules/music/README.md +2 -0
- package/src/modules/music/components/cards/ArtistCardSmall.vue +92 -0
- package/src/modules/music/components/pages/Album.vue +20 -56
- package/src/modules/music/components/pages/Artist.vue +1 -1
- package/src/modules/music/components/pages/Playlist.vue +26 -44
- package/src/modules/music/components/pages/Track.vue +51 -74
- package/src/modules/music/components/player/MusicPlayer.vue +24 -21
- package/src/modules/music/components/player/TrackProgress.vue +9 -8
- package/src/modules/music/components/player/VolumeControl.vue +3 -2
- package/src/styles/base/all.scss +1 -0
- package/dist/martyrs/src/components/Button/Button.vue.js.map +0 -1
- package/dist/martyrs/src/components/Chips/Chips.vue.cjs.map +0 -1
- package/dist/martyrs/src/components/Chips/Chips.vue.js.map +0 -1
- package/dist/martyrs/src/components/Dropdown/Dropdown.vue.js.map +0 -1
- package/dist/martyrs/src/components/Select/Select.vue2.cjs.map +0 -1
- package/dist/martyrs/src/components/Tooltip/Tooltip.vue2.cjs.map +0 -1
|
@@ -2,10 +2,10 @@
|
|
|
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
|
-
const Button = require("../../../../components/Button/Button.
|
|
5
|
+
const Button = require("../../../../components/Button/Button.vue2.cjs");
|
|
6
6
|
;/* empty css */
|
|
7
7
|
const Media = require("../../../../components/Media/Media.vue.cjs");
|
|
8
|
-
const Dropdown = require("../../../../components/Dropdown/Dropdown.
|
|
8
|
+
const Dropdown = require("../../../../components/Dropdown/Dropdown.vue2.cjs");
|
|
9
9
|
const Feed = require("../../../../components/Feed/Feed.vue.cjs");
|
|
10
10
|
const Popup = require("../../../../components/Popup/Popup.vue.cjs");
|
|
11
11
|
const IconPlay = require("../../../icons/navigation/IconPlay.vue.cjs");
|
|
@@ -15,10 +15,10 @@ const IconCalendar = ;/* empty css */
|
|
|
15
15
|
const IconTime = require("../../../icons/entities/IconTime.vue.cjs");
|
|
16
16
|
const IconShow = require("../../../icons/actions/IconShow.vue.cjs");
|
|
17
17
|
const IconRefresh = require("../../../icons/navigation/IconRefresh.vue.cjs");
|
|
18
|
-
const IconCheckmark = require("../../../icons/navigation/IconCheckmark.vue.cjs");
|
|
19
18
|
const TrackListCard = require("../cards/TrackListCard.vue.cjs");
|
|
20
19
|
const PlaylistCard = require("../cards/PlaylistCard.vue.cjs");
|
|
21
20
|
const PlaylistForm = require("../forms/PlaylistForm.vue.cjs");
|
|
21
|
+
const ArtistCardSmall = require("../cards/ArtistCardSmall.vue.cjs");
|
|
22
22
|
const playlists = require("../../store/playlists.cjs");
|
|
23
23
|
require("../../store/tracks.cjs");
|
|
24
24
|
const player = require("../../store/player.cjs");
|
|
@@ -33,7 +33,7 @@ const _hoisted_3 = {
|
|
|
33
33
|
key: 1,
|
|
34
34
|
class: "playlist-content cols-2-fit-content mobile:cols-1 gap-big"
|
|
35
35
|
};
|
|
36
|
-
const _hoisted_4 = { class: "pos-sticky pos-t-0 mobile:pos-relative playlist-cover-section" };
|
|
36
|
+
const _hoisted_4 = { class: "pos-sticky w-max-30r pos-t-0 mobile:pos-relative playlist-cover-section" };
|
|
37
37
|
const _hoisted_5 = { class: "cover-container relative mn-b-medium radius-big overflow-hidden shadow-big" };
|
|
38
38
|
const _hoisted_6 = { class: "stats-grid grid cols-2 gap-small" };
|
|
39
39
|
const _hoisted_7 = { class: "stat-card bg-light pd-medium radius-medium t-center" };
|
|
@@ -44,68 +44,60 @@ const _hoisted_11 = { class: "playlist-details-section" };
|
|
|
44
44
|
const _hoisted_12 = { class: "flex items-center gap-small mn-b-small" };
|
|
45
45
|
const _hoisted_13 = {
|
|
46
46
|
key: 0,
|
|
47
|
-
class: "
|
|
47
|
+
class: "bg-light t-medium pd-thin radius-thin uppercase t-small t-uppercase"
|
|
48
48
|
};
|
|
49
49
|
const _hoisted_14 = {
|
|
50
50
|
key: 1,
|
|
51
|
-
class: "
|
|
51
|
+
class: "bg-light t-medium pd-thin radius-thin uppercase t-small t-uppercase"
|
|
52
52
|
};
|
|
53
53
|
const _hoisted_15 = { class: "h1 mn-b-medium" };
|
|
54
54
|
const _hoisted_16 = { class: "flex gap-small mn-b-medium" };
|
|
55
55
|
const _hoisted_17 = { class: "dropdown-menu bg-white pd-small radius-medium shadow-big mn-t-thin" };
|
|
56
|
-
const _hoisted_18 = { class: "
|
|
57
|
-
const _hoisted_19 = { class: "
|
|
58
|
-
const _hoisted_20 = {
|
|
59
|
-
const _hoisted_21 = {
|
|
60
|
-
key: 1,
|
|
61
|
-
class: "w-4r h-4r radius-full bg-primary flex-center"
|
|
62
|
-
};
|
|
63
|
-
const _hoisted_22 = { class: "flex items-center gap-thin" };
|
|
64
|
-
const _hoisted_23 = { class: "t-large" };
|
|
65
|
-
const _hoisted_24 = { class: "t-small t-transp" };
|
|
66
|
-
const _hoisted_25 = {
|
|
56
|
+
const _hoisted_18 = { class: "artists-section mn-b-medium" };
|
|
57
|
+
const _hoisted_19 = { class: "flex flex-col gap-small" };
|
|
58
|
+
const _hoisted_20 = {
|
|
67
59
|
key: 0,
|
|
68
60
|
class: "collaborators-section mn-b-big"
|
|
69
61
|
};
|
|
70
|
-
const
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
-
const
|
|
62
|
+
const _hoisted_21 = { class: "flex flex-wrap gap-small" };
|
|
63
|
+
const _hoisted_22 = { class: "t-small" };
|
|
64
|
+
const _hoisted_23 = { class: "metadata-grid grid cols-2 gap-small mn-b-medium" };
|
|
65
|
+
const _hoisted_24 = { class: "metadata-card bg-light pd-medium radius-medium flex items-center gap-medium" };
|
|
66
|
+
const _hoisted_25 = { class: "t-medium" };
|
|
67
|
+
const _hoisted_26 = { class: "metadata-card bg-light pd-medium radius-medium flex items-center gap-medium" };
|
|
68
|
+
const _hoisted_27 = { class: "t-medium" };
|
|
69
|
+
const _hoisted_28 = { class: "metadata-card bg-light pd-medium radius-medium flex items-center gap-medium" };
|
|
70
|
+
const _hoisted_29 = { class: "t-medium" };
|
|
71
|
+
const _hoisted_30 = { class: "metadata-card bg-light pd-medium radius-medium flex items-center gap-medium" };
|
|
72
|
+
const _hoisted_31 = { class: "t-medium" };
|
|
73
|
+
const _hoisted_32 = {
|
|
82
74
|
key: 1,
|
|
83
75
|
class: "tags-section mn-b-medium"
|
|
84
76
|
};
|
|
85
|
-
const
|
|
86
|
-
const
|
|
77
|
+
const _hoisted_33 = { class: "flex gap-thin flex-wrap" };
|
|
78
|
+
const _hoisted_34 = {
|
|
87
79
|
key: 2,
|
|
88
80
|
class: "description-section bg-light pd-medium radius-medium mn-b-medium"
|
|
89
81
|
};
|
|
90
|
-
const
|
|
91
|
-
const
|
|
82
|
+
const _hoisted_35 = { class: "t-transp" };
|
|
83
|
+
const _hoisted_36 = {
|
|
92
84
|
key: 2,
|
|
93
85
|
class: "tracks-section mn-t-big"
|
|
94
86
|
};
|
|
95
|
-
const
|
|
96
|
-
const
|
|
87
|
+
const _hoisted_37 = { class: "bg-light radius-medium o-hidden" };
|
|
88
|
+
const _hoisted_38 = {
|
|
97
89
|
key: 3,
|
|
98
90
|
class: "empty-section mn-t-big"
|
|
99
91
|
};
|
|
100
|
-
const
|
|
101
|
-
const
|
|
92
|
+
const _hoisted_39 = { class: "empty-tracks t-center pd-big bg-light radius-medium" };
|
|
93
|
+
const _hoisted_40 = {
|
|
102
94
|
key: 4,
|
|
103
95
|
class: "more-playlists-section mn-t-big"
|
|
104
96
|
};
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
const
|
|
97
|
+
const _hoisted_41 = { class: "flex justify-between items-center mn-b-medium" };
|
|
98
|
+
const _hoisted_42 = { class: "flex flex-nowrap gap-small o-x-scroll overscroll-behavior-x-contain scroll-behavior-smooth scroll-snap-type-x-mandatory scroll-hide" };
|
|
99
|
+
const _hoisted_43 = { class: "t-transp mn-b-medium" };
|
|
100
|
+
const _hoisted_44 = { class: "flex justify-end gap-small" };
|
|
109
101
|
const _sfc_main = {
|
|
110
102
|
__name: "Playlist",
|
|
111
103
|
emits: ["page-loading", "page-loaded"],
|
|
@@ -140,24 +132,6 @@ const _sfc_main = {
|
|
|
140
132
|
const totalSeconds = playlistTracks.value.reduce((sum, track) => sum + (track.duration || 0), 0);
|
|
141
133
|
return formatDuration(totalSeconds);
|
|
142
134
|
});
|
|
143
|
-
const getOwnerData = (playlist2) => {
|
|
144
|
-
if (!playlist2) return null;
|
|
145
|
-
const owner = playlist2.creator?.target || playlist2.owner?.target;
|
|
146
|
-
return typeof owner === "object" ? owner : null;
|
|
147
|
-
};
|
|
148
|
-
const getOwnerId = (playlist2) => {
|
|
149
|
-
if (!playlist2) return null;
|
|
150
|
-
const owner = playlist2.creator?.target || playlist2.owner?.target;
|
|
151
|
-
return typeof owner === "object" ? owner._id : owner;
|
|
152
|
-
};
|
|
153
|
-
const getPlaylistOwnerName = (playlist2) => {
|
|
154
|
-
if (!playlist2) return "Unknown";
|
|
155
|
-
const owner = getOwnerData(playlist2);
|
|
156
|
-
if (owner) {
|
|
157
|
-
return owner.profile?.name || owner.name || "Unknown";
|
|
158
|
-
}
|
|
159
|
-
return "Unknown";
|
|
160
|
-
};
|
|
161
135
|
const getOwnerProfileLink = (owner) => {
|
|
162
136
|
if (!owner || !owner.target) return { name: "music-home" };
|
|
163
137
|
const targetId = typeof owner.target === "object" ? owner.target._id : owner.target;
|
|
@@ -338,7 +312,7 @@ const _sfc_main = {
|
|
|
338
312
|
]),
|
|
339
313
|
vue.createElementVNode("div", _hoisted_11, [
|
|
340
314
|
vue.createElementVNode("div", _hoisted_12, [
|
|
341
|
-
_cache[10] || (_cache[10] = vue.createElementVNode("span", { class: "
|
|
315
|
+
_cache[10] || (_cache[10] = vue.createElementVNode("span", { class: "bg-light t-medium pd-thin radius-thin uppercase t-small t-uppercase" }, " Playlist ", -1)),
|
|
342
316
|
playlist.value.isCollaborative ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_13, " Collaborative ")) : vue.createCommentVNode("", true),
|
|
343
317
|
playlist.value.status === "published" ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_14, " Published ")) : vue.createCommentVNode("", true)
|
|
344
318
|
]),
|
|
@@ -406,7 +380,7 @@ const _sfc_main = {
|
|
|
406
380
|
onClick: addToQueue,
|
|
407
381
|
color: "transp",
|
|
408
382
|
size: "small",
|
|
409
|
-
class: "w-100 justify-start"
|
|
383
|
+
class: "w-100 t-nowrap justify-start"
|
|
410
384
|
}, {
|
|
411
385
|
default: vue.withCtx(() => _cache[13] || (_cache[13] = [
|
|
412
386
|
vue.createTextVNode(" Add to Queue ")
|
|
@@ -417,7 +391,7 @@ const _sfc_main = {
|
|
|
417
391
|
onClick: copyLink,
|
|
418
392
|
color: "transp",
|
|
419
393
|
size: "small",
|
|
420
|
-
class: "w-100 justify-start"
|
|
394
|
+
class: "w-100 t-nowrap justify-start"
|
|
421
395
|
}, {
|
|
422
396
|
default: vue.withCtx(() => _cache[14] || (_cache[14] = [
|
|
423
397
|
vue.createTextVNode(" Copy Link ")
|
|
@@ -430,7 +404,7 @@ const _sfc_main = {
|
|
|
430
404
|
onClick: editPlaylist,
|
|
431
405
|
color: "transp",
|
|
432
406
|
size: "small",
|
|
433
|
-
class: "w-100 justify-start"
|
|
407
|
+
class: "w-100 t-nowrap justify-start"
|
|
434
408
|
}, {
|
|
435
409
|
default: vue.withCtx(() => _cache[15] || (_cache[15] = [
|
|
436
410
|
vue.createTextVNode(" Edit Playlist ")
|
|
@@ -442,7 +416,7 @@ const _sfc_main = {
|
|
|
442
416
|
onClick: toggleCollaborative,
|
|
443
417
|
color: "transp",
|
|
444
418
|
size: "small",
|
|
445
|
-
class: "w-100 justify-start"
|
|
419
|
+
class: "t-nowrap w-100 justify-start"
|
|
446
420
|
}, {
|
|
447
421
|
default: vue.withCtx(() => [
|
|
448
422
|
vue.createTextVNode(vue.toDisplayString(playlist.value.isCollaborative ? "Make Private" : "Make Collaborative"), 1)
|
|
@@ -454,7 +428,7 @@ const _sfc_main = {
|
|
|
454
428
|
onClick: deletePlaylist,
|
|
455
429
|
color: "danger",
|
|
456
430
|
size: "small",
|
|
457
|
-
class: "w-100 justify-start"
|
|
431
|
+
class: "t-nowrap w-100 justify-start"
|
|
458
432
|
}, {
|
|
459
433
|
default: vue.withCtx(() => _cache[16] || (_cache[16] = [
|
|
460
434
|
vue.createTextVNode(" Delete Playlist ")
|
|
@@ -470,48 +444,23 @@ const _sfc_main = {
|
|
|
470
444
|
vue.createElementVNode("div", _hoisted_18, [
|
|
471
445
|
_cache[18] || (_cache[18] = vue.createElementVNode("h3", { class: "t-medium mn-b-small" }, "Created by", -1)),
|
|
472
446
|
vue.createElementVNode("div", _hoisted_19, [
|
|
473
|
-
vue.createVNode(
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
]),
|
|
486
|
-
vue.createElementVNode("div", null, [
|
|
487
|
-
vue.createElementVNode("div", _hoisted_22, [
|
|
488
|
-
vue.createElementVNode("span", _hoisted_23, vue.toDisplayString(getPlaylistOwnerName(playlist.value)), 1),
|
|
489
|
-
getOwnerData(playlist.value)?.isVerified ? (vue.openBlock(), vue.createBlock(IconCheckmark.default, {
|
|
490
|
-
key: 0,
|
|
491
|
-
class: "w-1r h-1r t-primary"
|
|
492
|
-
})) : vue.createCommentVNode("", true)
|
|
493
|
-
]),
|
|
494
|
-
vue.createElementVNode("span", _hoisted_24, vue.toDisplayString(playlist.value.creator?.type || "User"), 1)
|
|
495
|
-
])
|
|
496
|
-
]),
|
|
497
|
-
_: 1
|
|
498
|
-
}, 8, ["to"]),
|
|
499
|
-
!isOwner.value && vue.unref(auth.state).user ? (vue.openBlock(), vue.createBlock(Button.default, {
|
|
500
|
-
key: 0,
|
|
501
|
-
onClick: _cache[1] || (_cache[1] = () => toggleFollowUser(getOwnerId(playlist.value))),
|
|
502
|
-
color: followedUsers.value.includes(getOwnerId(playlist.value)) ? "primary" : "transp",
|
|
503
|
-
size: "small"
|
|
504
|
-
}, {
|
|
505
|
-
default: vue.withCtx(() => [
|
|
506
|
-
vue.createTextVNode(vue.toDisplayString(followedUsers.value.includes(getOwnerId(playlist.value)) ? "Following" : "Follow"), 1)
|
|
507
|
-
]),
|
|
508
|
-
_: 1
|
|
509
|
-
}, 8, ["color"])) : vue.createCommentVNode("", true)
|
|
447
|
+
vue.createVNode(ArtistCardSmall.default, {
|
|
448
|
+
artist: {
|
|
449
|
+
_id: playlist.value.creator.target,
|
|
450
|
+
to: { name: "User Profile", params: { _id: playlist.value.creator.target } },
|
|
451
|
+
photoUrl: null,
|
|
452
|
+
name: playlist.value.creator.target,
|
|
453
|
+
isVerified: false
|
|
454
|
+
},
|
|
455
|
+
"is-following": followedUsers.value.includes(playlist.value.creator.target),
|
|
456
|
+
"show-follow-button": !isOwner.value,
|
|
457
|
+
onToggleFollow: _cache[1] || (_cache[1] = ($event) => toggleFollowUser(playlist.value.creator.target))
|
|
458
|
+
}, null, 8, ["artist", "is-following", "show-follow-button"])
|
|
510
459
|
])
|
|
511
460
|
]),
|
|
512
|
-
playlist.value.collaborators && playlist.value.collaborators.length > 0 ? (vue.openBlock(), vue.createElementBlock("div",
|
|
461
|
+
playlist.value.collaborators && playlist.value.collaborators.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_20, [
|
|
513
462
|
_cache[19] || (_cache[19] = vue.createElementVNode("h3", { class: "t-medium mn-b-small" }, "Collaborators", -1)),
|
|
514
|
-
vue.createElementVNode("div",
|
|
463
|
+
vue.createElementVNode("div", _hoisted_21, [
|
|
515
464
|
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(playlist.value.collaborators, (collaborator) => {
|
|
516
465
|
return vue.openBlock(), vue.createElementBlock("div", {
|
|
517
466
|
key: collaborator._id || collaborator,
|
|
@@ -522,44 +471,45 @@ const _sfc_main = {
|
|
|
522
471
|
url: collaborator.photoUrl,
|
|
523
472
|
class: "i-regular radius-full object-cover"
|
|
524
473
|
}, null, 8, ["url"])) : vue.createCommentVNode("", true),
|
|
525
|
-
vue.createElementVNode("span",
|
|
474
|
+
vue.createElementVNode("span", _hoisted_22, vue.toDisplayString(collaborator.name || collaborator.profile?.name || "User"), 1)
|
|
526
475
|
]);
|
|
527
476
|
}), 128))
|
|
528
477
|
])
|
|
529
478
|
])) : vue.createCommentVNode("", true),
|
|
530
|
-
vue.createElementVNode("
|
|
531
|
-
|
|
479
|
+
_cache[26] || (_cache[26] = vue.createElementVNode("h3", { class: "t-medium mn-b-small" }, "Metadata", -1)),
|
|
480
|
+
vue.createElementVNode("div", _hoisted_23, [
|
|
481
|
+
vue.createElementVNode("div", _hoisted_24, [
|
|
532
482
|
vue.createVNode(IconCalendar.default, { class: "i-medium t-primary" }),
|
|
533
483
|
vue.createElementVNode("div", null, [
|
|
534
484
|
_cache[20] || (_cache[20] = vue.createElementVNode("div", { class: "t-small t-transp t-uppercase" }, "Created", -1)),
|
|
535
|
-
vue.createElementVNode("div",
|
|
485
|
+
vue.createElementVNode("div", _hoisted_25, vue.toDisplayString(formatDate(playlist.value.createdAt)), 1)
|
|
536
486
|
])
|
|
537
487
|
]),
|
|
538
|
-
vue.createElementVNode("div",
|
|
488
|
+
vue.createElementVNode("div", _hoisted_26, [
|
|
539
489
|
vue.createVNode(IconTime.default, { class: "i-medium t-primary" }),
|
|
540
490
|
vue.createElementVNode("div", null, [
|
|
541
491
|
_cache[21] || (_cache[21] = vue.createElementVNode("div", { class: "t-small t-transp t-uppercase" }, "Duration", -1)),
|
|
542
|
-
vue.createElementVNode("div",
|
|
492
|
+
vue.createElementVNode("div", _hoisted_27, vue.toDisplayString(totalDuration.value), 1)
|
|
543
493
|
])
|
|
544
494
|
]),
|
|
545
|
-
vue.createElementVNode("div",
|
|
495
|
+
vue.createElementVNode("div", _hoisted_28, [
|
|
546
496
|
vue.createVNode(IconRefresh.default, { class: "i-medium t-primary" }),
|
|
547
497
|
vue.createElementVNode("div", null, [
|
|
548
498
|
_cache[22] || (_cache[22] = vue.createElementVNode("div", { class: "t-small t-transp t-uppercase" }, "Updated", -1)),
|
|
549
|
-
vue.createElementVNode("div",
|
|
499
|
+
vue.createElementVNode("div", _hoisted_29, vue.toDisplayString(formatDate(playlist.value.updatedAt)), 1)
|
|
550
500
|
])
|
|
551
501
|
]),
|
|
552
|
-
vue.createElementVNode("div",
|
|
502
|
+
vue.createElementVNode("div", _hoisted_30, [
|
|
553
503
|
vue.createVNode(IconShow.default, { class: "i-medium t-primary" }),
|
|
554
504
|
vue.createElementVNode("div", null, [
|
|
555
505
|
_cache[23] || (_cache[23] = vue.createElementVNode("div", { class: "t-small t-transp t-uppercase" }, "Visibility", -1)),
|
|
556
|
-
vue.createElementVNode("div",
|
|
506
|
+
vue.createElementVNode("div", _hoisted_31, vue.toDisplayString(playlist.value.isPublic ? "Public" : "Private"), 1)
|
|
557
507
|
])
|
|
558
508
|
])
|
|
559
509
|
]),
|
|
560
|
-
playlist.value.tags && playlist.value.tags.length ? (vue.openBlock(), vue.createElementBlock("div",
|
|
510
|
+
playlist.value.tags && playlist.value.tags.length ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_32, [
|
|
561
511
|
_cache[24] || (_cache[24] = vue.createElementVNode("h3", { class: "t-medium mn-b-small" }, "Tags", -1)),
|
|
562
|
-
vue.createElementVNode("div",
|
|
512
|
+
vue.createElementVNode("div", _hoisted_33, [
|
|
563
513
|
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(playlist.value.tags, (tag) => {
|
|
564
514
|
return vue.openBlock(), vue.createElementBlock("span", {
|
|
565
515
|
key: tag,
|
|
@@ -568,14 +518,14 @@ const _sfc_main = {
|
|
|
568
518
|
}), 128))
|
|
569
519
|
])
|
|
570
520
|
])) : vue.createCommentVNode("", true),
|
|
571
|
-
playlist.value.description ? (vue.openBlock(), vue.createElementBlock("div",
|
|
521
|
+
playlist.value.description ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_34, [
|
|
572
522
|
_cache[25] || (_cache[25] = vue.createElementVNode("h3", { class: "t-medium mn-b-small" }, "About", -1)),
|
|
573
|
-
vue.createElementVNode("p",
|
|
523
|
+
vue.createElementVNode("p", _hoisted_35, vue.toDisplayString(playlist.value.description), 1)
|
|
574
524
|
])) : vue.createCommentVNode("", true)
|
|
575
525
|
])
|
|
576
526
|
])) : vue.createCommentVNode("", true),
|
|
577
|
-
!_ctx.isLoading && playlist.value && playlistTracks.value.length ? (vue.openBlock(), vue.createElementBlock("section",
|
|
578
|
-
_cache[
|
|
527
|
+
!_ctx.isLoading && playlist.value && playlistTracks.value.length ? (vue.openBlock(), vue.createElementBlock("section", _hoisted_36, [
|
|
528
|
+
_cache[27] || (_cache[27] = vue.createElementVNode("h2", { class: "h2 mn-b-medium" }, "Tracklist", -1)),
|
|
579
529
|
vue.createVNode(Feed.default, {
|
|
580
530
|
store: {
|
|
581
531
|
read: () => _ctx.Promise.resolve(playlistTracks.value),
|
|
@@ -592,7 +542,7 @@ const _sfc_main = {
|
|
|
592
542
|
}
|
|
593
543
|
}, {
|
|
594
544
|
default: vue.withCtx(({ items }) => [
|
|
595
|
-
vue.createElementVNode("div",
|
|
545
|
+
vue.createElementVNode("div", _hoisted_37, [
|
|
596
546
|
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(items, (track, index) => {
|
|
597
547
|
return vue.openBlock(), vue.createBlock(TrackListCard.default, {
|
|
598
548
|
key: track._id,
|
|
@@ -608,38 +558,38 @@ const _sfc_main = {
|
|
|
608
558
|
]),
|
|
609
559
|
_: 1
|
|
610
560
|
}, 8, ["store", "items"])
|
|
611
|
-
])) : !_ctx.isLoading && playlist.value && !playlistTracks.value.length ? (vue.openBlock(), vue.createElementBlock("section",
|
|
612
|
-
vue.createElementVNode("div",
|
|
613
|
-
_cache[
|
|
614
|
-
_cache[
|
|
561
|
+
])) : !_ctx.isLoading && playlist.value && !playlistTracks.value.length ? (vue.openBlock(), vue.createElementBlock("section", _hoisted_38, [
|
|
562
|
+
vue.createElementVNode("div", _hoisted_39, [
|
|
563
|
+
_cache[29] || (_cache[29] = vue.createElementVNode("h3", { class: "mn-b-small" }, "This playlist is empty", -1)),
|
|
564
|
+
_cache[30] || (_cache[30] = vue.createElementVNode("p", { class: "t-transp t-medium mn-b-medium" }, "Add some tracks to get started", -1)),
|
|
615
565
|
isOwner.value || isCollaborator.value ? (vue.openBlock(), vue.createBlock(Button.default, {
|
|
616
566
|
key: 0,
|
|
617
567
|
onClick: _cache[2] || (_cache[2] = ($event) => _ctx.$router.push({ name: "music-search" })),
|
|
618
568
|
color: "primary",
|
|
619
569
|
size: "medium"
|
|
620
570
|
}, {
|
|
621
|
-
default: vue.withCtx(() => _cache[
|
|
571
|
+
default: vue.withCtx(() => _cache[28] || (_cache[28] = [
|
|
622
572
|
vue.createTextVNode(" Find Tracks ")
|
|
623
573
|
])),
|
|
624
574
|
_: 1
|
|
625
575
|
})) : vue.createCommentVNode("", true)
|
|
626
576
|
])
|
|
627
577
|
])) : vue.createCommentVNode("", true),
|
|
628
|
-
!_ctx.isLoading && playlist.value && morePlaylists.value.length ? (vue.openBlock(), vue.createElementBlock("section",
|
|
629
|
-
vue.createElementVNode("div",
|
|
630
|
-
_cache[
|
|
578
|
+
!_ctx.isLoading && playlist.value && morePlaylists.value.length ? (vue.openBlock(), vue.createElementBlock("section", _hoisted_40, [
|
|
579
|
+
vue.createElementVNode("div", _hoisted_41, [
|
|
580
|
+
_cache[32] || (_cache[32] = vue.createElementVNode("h2", { class: "h2" }, "More Playlists", -1)),
|
|
631
581
|
playlist.value.creator ? (vue.openBlock(), vue.createBlock(_component_router_link, {
|
|
632
582
|
key: 0,
|
|
633
583
|
to: getOwnerProfileLink(playlist.value.creator),
|
|
634
584
|
class: "t-primary hover-opacity"
|
|
635
585
|
}, {
|
|
636
|
-
default: vue.withCtx(() => _cache[
|
|
586
|
+
default: vue.withCtx(() => _cache[31] || (_cache[31] = [
|
|
637
587
|
vue.createTextVNode(" See all ")
|
|
638
588
|
])),
|
|
639
589
|
_: 1
|
|
640
590
|
}, 8, ["to"])) : vue.createCommentVNode("", true)
|
|
641
591
|
]),
|
|
642
|
-
vue.createElementVNode("div",
|
|
592
|
+
vue.createElementVNode("div", _hoisted_42, [
|
|
643
593
|
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(morePlaylists.value, (relatedPlaylist) => {
|
|
644
594
|
return vue.openBlock(), vue.createElementBlock("li", {
|
|
645
595
|
key: relatedPlaylist._id,
|
|
@@ -674,15 +624,15 @@ const _sfc_main = {
|
|
|
674
624
|
class: "bg-white pd-medium w-m-25r radius-medium"
|
|
675
625
|
}, {
|
|
676
626
|
default: vue.withCtx(() => [
|
|
677
|
-
_cache[
|
|
678
|
-
vue.createElementVNode("p",
|
|
679
|
-
vue.createElementVNode("div",
|
|
627
|
+
_cache[35] || (_cache[35] = vue.createElementVNode("h3", { class: "mn-b-medium" }, "Delete Playlist", -1)),
|
|
628
|
+
vue.createElementVNode("p", _hoisted_43, 'Are you sure you want to delete "' + vue.toDisplayString(playlist.value.title) + '"? This action cannot be undone.', 1),
|
|
629
|
+
vue.createElementVNode("div", _hoisted_44, [
|
|
680
630
|
vue.createVNode(Button.default, {
|
|
681
631
|
onClick: _cache[5] || (_cache[5] = ($event) => showDeleteModal.value = false),
|
|
682
632
|
color: "transp",
|
|
683
633
|
size: "medium"
|
|
684
634
|
}, {
|
|
685
|
-
default: vue.withCtx(() => _cache[
|
|
635
|
+
default: vue.withCtx(() => _cache[33] || (_cache[33] = [
|
|
686
636
|
vue.createTextVNode(" Cancel ")
|
|
687
637
|
])),
|
|
688
638
|
_: 1
|
|
@@ -692,7 +642,7 @@ const _sfc_main = {
|
|
|
692
642
|
color: "danger",
|
|
693
643
|
size: "medium"
|
|
694
644
|
}, {
|
|
695
|
-
default: vue.withCtx(() => _cache[
|
|
645
|
+
default: vue.withCtx(() => _cache[34] || (_cache[34] = [
|
|
696
646
|
vue.createTextVNode(" Delete Playlist ")
|
|
697
647
|
])),
|
|
698
648
|
_: 1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Playlist.vue.cjs","sources":["../../../../../../../src/modules/music/components/pages/Playlist.vue"],"sourcesContent":["<template>\n <div class=\"playlist-page pd-small\">\n <!-- Not Found -->\n <div v-if=\"hasLoaded && !playlist\" class=\"t-center pd-big\">\n <h2 class=\"\">Playlist not found</h2>\n <p class=\"t-transp t-medium\">The playlist you're looking for doesn't exist or has been removed.</p>\n </div>\n \n <!-- Playlist Content -->\n <div v-if=\"playlist\" class=\"playlist-content cols-2-fit-content mobile:cols-1 gap-big\">\n <!-- Left Column - Cover & Stats -->\n <div class=\"pos-sticky pos-t-0 mobile:pos-relative playlist-cover-section\">\n <!-- Cover -->\n <div class=\"cover-container relative mn-b-medium radius-big overflow-hidden shadow-big\">\n <Media \n :url=\"playlist.coverUrl || '/assets/placeholder-playlist.jpg'\"\n :alt=\"playlist.title\"\n class=\"aspect-1x1 w-100 radius-medium o-hidden\"\n />\n </div>\n\n <!-- Quick Stats -->\n <div class=\"stats-grid grid cols-2 gap-small\">\n <div class=\"stat-card bg-light pd-medium radius-medium t-center\">\n <div class=\" mn-b-thin\">{{ playlistTracks.length }}</div>\n <div class=\"t-small t-transp t-uppercase\">Tracks</div>\n </div>\n <div class=\"stat-card bg-light pd-medium radius-medium t-center\">\n <div class=\" mn-b-thin\">{{ formatNumber(playlist.followers || 0) }}</div>\n <div class=\"t-small t-transp t-uppercase\">Followers</div>\n </div>\n </div>\n </div>\n\n <!-- Right Column - Playlist Details -->\n <div class=\"playlist-details-section\">\n <!-- Playlist Type Badge -->\n <div class=\"flex items-center gap-small mn-b-small\">\n <span class=\"badge bg-primary-transp-20 t-primary pd-thin-big radius-small t-small t-uppercase\">\n Playlist\n </span>\n <span v-if=\"playlist.isCollaborative\" class=\"badge bg-secondary-transp-20 t-secondary pd-thin-big radius-small t-small\">\n Collaborative\n </span>\n <span v-if=\"playlist.status === 'published'\" class=\"badge bg-success-transp-20 t-success pd-thin-big radius-small t-small\">\n Published\n </span>\n </div>\n\n <!-- Playlist Title -->\n <h1 class=\"h1 mn-b-medium\">{{ playlist.title }}</h1>\n\n <!-- Action Buttons -->\n <div class=\"flex gap-small mn-b-medium\">\n <Button\n @click=\"playPlaylist\"\n color=\"primary\"\n size=\"medium\"\n class=\"flex-1 t-white bg-black radius-thin flex-center gap-thin\"\n >\n <IconPlay fill=\"rgb(var(--white))\" class=\"i-medium\" />\n Play All\n </Button>\n\n <Button\n @click=\"shufflePlay\"\n color=\"primary\"\n size=\"medium\"\n class=\"flex-1 bg-light radius-thin flex-center gap-thin\"\n >\n <IconShuffle class=\"i-medium\" />\n Shuffle\n </Button>\n\n <Button\n @click=\"toggleFollow\"\n color=\"primary\"\n size=\"medium\"\n class=\"flex-1 bg-light radius-thin flex-center gap-thin\"\n >\n {{isFollowing ? 'Follow' : 'Unfollow'}}\n </Button>\n\n \n <Dropdown :label=\"{component: IconEllipsis, class: 'bg-light radius-thin pd-thin i-big' }\" v-model=\"showDropdown\" class=\"relative\">\n <template #trigger>\n <Button color=\"transp\" size=\"medium\" class=\"w-3r h-3r radius-full\">\n <IconEllipsis class=\"w-1-25r h-1-25r\" />\n </Button>\n </template>\n <template #default>\n <div class=\"dropdown-menu bg-white pd-small radius-medium shadow-big mn-t-thin\">\n <Button @click=\"addToQueue\" color=\"transp\" size=\"small\" class=\"w-100 justify-start\">\n Add to Queue\n </Button>\n <Button @click=\"copyLink\" color=\"transp\" size=\"small\" class=\"w-100 justify-start\">\n Copy Link\n </Button>\n <template v-if=\"isOwner || isCollaborator\">\n <hr class=\"mn-v-thin border-dark-transp-10\" />\n <Button @click=\"editPlaylist\" color=\"transp\" size=\"small\" class=\"w-100 justify-start\">\n Edit Playlist\n </Button>\n <Button v-if=\"isOwner\" @click=\"toggleCollaborative\" color=\"transp\" size=\"small\" class=\"w-100 justify-start\">\n {{ playlist.isCollaborative ? 'Make Private' : 'Make Collaborative' }}\n </Button>\n <Button v-if=\"isOwner\" @click=\"deletePlaylist\" color=\"danger\" size=\"small\" class=\"w-100 justify-start\">\n Delete Playlist\n </Button>\n </template>\n </div>\n </template>\n </Dropdown>\n </div>\n\n <!-- Owner/Creator Card -->\n <div class=\"owner-section mn-b-big\">\n <h3 class=\"t-medium mn-b-small\">Created by</h3>\n <div class=\"owner-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <router-link \n :to=\"getOwnerProfileLink(playlist.creator || playlist.owner)\"\n class=\"flex items-center gap-medium flex-1 hover-opacity\"\n >\n <div class=\"owner-avatar\">\n <Media \n v-if=\"getOwnerData(playlist)?.photoUrl\"\n :url=\"getOwnerData(playlist).photoUrl\"\n :alt=\"getOwnerData(playlist)?.name\"\n class=\"w-4r h-4r radius-full object-cover\"\n />\n <div v-else class=\"w-4r h-4r radius-full bg-primary flex-center \">\n {{ getPlaylistOwnerName(playlist).charAt(0) }}\n </div>\n </div>\n <div>\n <div class=\"flex items-center gap-thin\">\n <span class=\"t-large \">{{ getPlaylistOwnerName(playlist) }}</span>\n <IconVerified v-if=\"getOwnerData(playlist)?.isVerified\" class=\"w-1r h-1r t-primary\" />\n </div>\n <span class=\"t-small t-transp\">{{ playlist.creator?.type || 'User' }}</span>\n </div>\n </router-link>\n <Button \n v-if=\"!isOwner && authState.user\"\n @click=\"() => toggleFollowUser(getOwnerId(playlist))\"\n :color=\"followedUsers.includes(getOwnerId(playlist)) ? 'primary' : 'transp'\"\n size=\"small\"\n >\n {{ followedUsers.includes(getOwnerId(playlist)) ? 'Following' : 'Follow' }}\n </Button>\n </div>\n </div>\n\n <!-- Collaborators -->\n <div v-if=\"playlist.collaborators && playlist.collaborators.length > 0\" class=\"collaborators-section mn-b-big\">\n <h3 class=\"t-medium mn-b-small\">Collaborators</h3>\n <div class=\"flex flex-wrap gap-small\">\n <div \n v-for=\"collaborator in playlist.collaborators\"\n :key=\"collaborator._id || collaborator\"\n class=\"collaborator-chip bg-light pd-thin-big radius-full flex items-center gap-thin\"\n >\n <Media \n v-if=\"collaborator.photoUrl\"\n :url=\"collaborator.photoUrl\"\n class=\"i-regular radius-full object-cover\"\n />\n <span class=\"t-small\">{{ collaborator.name || collaborator.profile?.name || 'User' }}</span>\n </div>\n </div>\n </div>\n\n <!-- Metadata Cards -->\n <div class=\"metadata-grid grid cols-2 gap-small mn-b-big\">\n <!-- Created Date -->\n <div class=\"metadata-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <IconCalendar class=\"i-medium t-primary\" />\n <div>\n <div class=\"t-small t-transp t-uppercase\">Created</div>\n <div class=\"t-medium \">{{ formatDate(playlist.createdAt) }}</div>\n </div>\n </div>\n\n <!-- Total Duration -->\n <div class=\"metadata-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <IconClock class=\"i-medium t-primary\" />\n <div>\n <div class=\"t-small t-transp t-uppercase\">Duration</div>\n <div class=\"t-medium \">{{ totalDuration }}</div>\n </div>\n </div>\n\n <!-- Updated Date -->\n <div class=\"metadata-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <IconRefresh class=\"i-medium t-primary\" />\n <div>\n <div class=\"t-small t-transp t-uppercase\">Updated</div>\n <div class=\"t-medium \">{{ formatDate(playlist.updatedAt) }}</div>\n </div>\n </div>\n\n <!-- Visibility -->\n <div class=\"metadata-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <IconEye class=\"i-medium t-primary\" />\n <div>\n <div class=\"t-small t-transp t-uppercase\">Visibility</div>\n <div class=\"t-medium \">{{ playlist.isPublic ? 'Public' : 'Private' }}</div>\n </div>\n </div>\n </div>\n\n <!-- Tags -->\n <div v-if=\"playlist.tags && playlist.tags.length\" class=\"tags-section mn-b-medium\">\n <h3 class=\"t-medium mn-b-small\">Tags</h3>\n <div class=\"flex gap-thin flex-wrap\">\n <span \n v-for=\"tag in playlist.tags\" \n :key=\"tag\"\n class=\"tag bg-light t-transp pd-thin-big radius-small t-small hover-bg-light cursor-pointer\"\n >\n #{{ tag }}\n </span>\n </div>\n </div>\n\n <!-- Description -->\n <div v-if=\"playlist.description\" class=\"description-section bg-light pd-medium radius-medium mn-b-medium\">\n <h3 class=\"t-medium mn-b-small\">About</h3>\n <p class=\"t-transp\">{{ playlist.description }}</p>\n </div>\n </div>\n </div>\n\n <!-- Playlist Tracks -->\n <section v-if=\"!isLoading && playlist && playlistTracks.length\" class=\"tracks-section mn-t-big\">\n <h2 class=\"h2 mn-b-medium\">Tracklist</h2>\n <Feed\n :store=\"{\n read: () => Promise.resolve(playlistTracks),\n state: { isLoading: false }\n }\"\n :external=\"true\"\n :items=\"playlistTracks\"\n :states=\"{\n empty: {\n title: 'No tracks in playlist',\n description: 'Add some tracks to get started',\n class: 'pd-medium t-center'\n }\n }\"\n >\n <template #default=\"{ items }\">\n <div class=\"bg-light radius-medium o-hidden\">\n <TrackListCard\n v-for=\"(track, index) in items\"\n :key=\"track._id\"\n :track=\"track\"\n :index=\"index + 1\"\n :showAlbum=\"true\"\n :showCover=\"true\"\n :canRemove=\"isOwner || isCollaborator\"\n @remove=\"() => removeTrack(track._id)\"\n />\n </div>\n </template>\n </Feed>\n </section>\n\n <!-- Empty State -->\n <section v-else-if=\"!isLoading && playlist && !playlistTracks.length\" class=\"empty-section mn-t-big\">\n <div class=\"empty-tracks t-center pd-big bg-light radius-medium\">\n <h3 class=\" mn-b-small\">This playlist is empty</h3>\n <p class=\"t-transp t-medium mn-b-medium\">Add some tracks to get started</p>\n \n <Button \n v-if=\"isOwner || isCollaborator\"\n @click=\"$router.push({ name: 'music-search' })\"\n color=\"primary\"\n size=\"medium\"\n >\n Find Tracks\n </Button>\n </div>\n </section>\n\n <!-- More Playlists -->\n <section v-if=\"!isLoading && playlist && morePlaylists.length\" class=\"more-playlists-section mn-t-big\">\n <div class=\"flex justify-between items-center mn-b-medium\">\n <h2 class=\"h2\">More Playlists</h2>\n <router-link \n v-if=\"playlist.creator\"\n :to=\"getOwnerProfileLink(playlist.creator)\" \n class=\"t-primary hover-opacity\"\n >\n See all\n </router-link>\n </div>\n <div class=\"flex flex-nowrap gap-small o-x-scroll overscroll-behavior-x-contain scroll-behavior-smooth scroll-snap-type-x-mandatory scroll-hide\">\n <li v-for=\"relatedPlaylist in morePlaylists\" :key=\"relatedPlaylist._id\" class=\"flex-none scroll-snap-align-start\">\n <PlaylistCard :playlist=\"relatedPlaylist\" class=\"w-min-15r transition-cubic-in-out\" />\n </li>\n </div>\n </section>\n\n <!-- Edit Playlist Modal -->\n <Popup \n :isPopupOpen=\"showEditModal && (isOwner || isCollaborator)\"\n @close-popup=\"showEditModal = false\" \n class=\"bg-white pd-medium w-m-30r radius-medium\"\n >\n <PlaylistForm \n :editMode=\"true\"\n :url=\"playlist.url\"\n @cancel=\"showEditModal = false\"\n @updated=\"handlePlaylistUpdated\"\n />\n </Popup>\n\n <!-- Delete Confirmation Modal -->\n <Popup \n :isPopupOpen=\"showDeleteModal\"\n @close-popup=\"showDeleteModal = false\" \n class=\"bg-white pd-medium w-m-25r radius-medium\"\n >\n <h3 class=\"mn-b-medium\">Delete Playlist</h3>\n <p class=\"t-transp mn-b-medium\">Are you sure you want to delete \"{{ playlist.title }}\"? This action cannot be undone.</p>\n \n <div class=\"flex justify-end gap-small\">\n <Button \n @click=\"showDeleteModal = false\"\n color=\"transp\"\n size=\"medium\"\n >\n Cancel\n </Button>\n \n <Button \n @click=\"confirmDelete\"\n color=\"danger\"\n size=\"medium\"\n >\n Delete Playlist\n </Button>\n </div>\n </Popup>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed, onMounted, watch } from 'vue';\nimport { useRoute, useRouter } from 'vue-router';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport Loader from '@martyrs/src/components/Loader/Loader.vue';\nimport Media from '@martyrs/src/components/Media/Media.vue';\nimport Dropdown from '@martyrs/src/components/Dropdown/Dropdown.vue';\nimport Feed from '@martyrs/src/components/Feed/Feed.vue';\nimport Popup from '@martyrs/src/components/Popup/Popup.vue';\n\n// Icons\nimport IconPlay from '@martyrs/src/modules/icons/navigation/IconPlay.vue';\nimport IconLike from '@martyrs/src/modules/icons/navigation/IconLike.vue';\nimport IconEllipsis from '@martyrs/src/modules/icons/navigation/IconEllipsis.vue';\nimport IconShuffle from '@martyrs/src/modules/icons/navigation/IconShuffle.vue';\nimport IconCalendar from '@martyrs/src/modules/icons/entities/IconCalendar.vue';\nimport IconClock from '@martyrs/src/modules/icons/entities/IconTime.vue';\nimport IconEye from '@martyrs/src/modules/icons/actions/IconShow.vue';\nimport IconRefresh from '@martyrs/src/modules/icons/navigation/IconRefresh.vue';\nimport IconVerified from '@martyrs/src/modules/icons/navigation/IconCheckmark.vue';\n\n// Components\nimport TrackListCard from '../cards/TrackListCard.vue';\nimport PlaylistCard from '../cards/PlaylistCard.vue';\nimport PlaylistForm from '../forms/PlaylistForm.vue';\n\n// Store\nimport { state as playlistsState, actions as playlistsActions } from '../../store/playlists.js';\nimport { state as tracksState, actions as tracksActions } from '../../store/tracks.js';\nimport { actions as playerActions } from '../../store/player.js';\nimport { state as authState } from '@martyrs/src/modules/auth/views/store/auth.js';\nimport * as globals from '@martyrs/src/modules/globals/views/store/globals.js';\n\nconst route = useRoute();\nconst router = useRouter();\n\n// Emits\nconst emits = defineEmits(['page-loading', 'page-loaded']);\n\n// State\nconst hasLoaded = ref(false);\nconst isFollowing = ref(false);\nconst showDropdown = ref(false);\nconst showEditModal = ref(false);\nconst showDeleteModal = ref(false);\nconst followedUsers = ref([]);\nconst morePlaylists = ref([]);\n\n// Clear state\nplaylistsState.currentPlaylist = null;\nplaylistsState.currentPlaylistTracks = [];\n\n// Computed\nconst playlist = computed(() => playlistsState.currentPlaylist);\nconst playlistTracks = computed(() => playlistsState.currentPlaylistTracks || []);\n\nconst isOwner = computed(() => {\n if (!playlist.value || !authState.user) return false;\n \n const ownerId = playlist.value.owner?.target?._id || playlist.value.owner?.target;\n return ownerId === authState.user._id;\n});\n\nconst isCollaborator = computed(() => {\n if (!playlist.value || !authState.user) return false;\n \n return playlist.value.collaborators?.some(collab => \n (collab._id || collab) === authState.user._id\n );\n});\n\nconst totalDuration = computed(() => {\n if (!playlistTracks.value.length) return '0:00';\n const totalSeconds = playlistTracks.value.reduce((sum, track) => sum + (track.duration || 0), 0);\n return formatDuration(totalSeconds);\n});\n\n// Helper functions\nconst getOwnerData = (playlist) => {\n if (!playlist) return null;\n const owner = playlist.creator?.target || playlist.owner?.target;\n return typeof owner === 'object' ? owner : null;\n};\n\nconst getOwnerId = (playlist) => {\n if (!playlist) return null;\n const owner = playlist.creator?.target || playlist.owner?.target;\n return typeof owner === 'object' ? owner._id : owner;\n};\n\nconst getPlaylistOwnerName = (playlist) => {\n if (!playlist) return 'Unknown';\n \n const owner = getOwnerData(playlist);\n if (owner) {\n return owner.profile?.name || owner.name || 'Unknown';\n }\n \n return 'Unknown';\n};\n\nconst getOwnerProfileLink = (owner) => {\n if (!owner || !owner.target) return { name: 'music-home' };\n \n const targetId = typeof owner.target === 'object' ? owner.target._id : owner.target;\n \n if (owner.type === 'user' || owner.type === 'User') {\n return { name: 'User Profile', params: { _id: targetId } };\n } else if (owner.type === 'organization' || owner.type === 'Organization') {\n return { name: 'Organizatio', params: { _id: targetId } };\n }\n \n return { name: 'music-home' };\n};\n\n// Format helpers\nconst formatDate = (dateString) => {\n if (!dateString) return 'Unknown';\n return new Date(dateString).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n });\n};\n\nconst formatDuration = (seconds) => {\n if (!seconds) return '0:00';\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = Math.floor(seconds % 60);\n \n if (h > 0) {\n return `${h}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;\n }\n return `${m}:${s.toString().padStart(2, '0')}`;\n};\n\nconst formatNumber = (num) => {\n if (!num) return '0';\n if (num >= 1000000) {\n return (num / 1000000).toFixed(1) + 'M';\n } else if (num >= 1000) {\n return (num / 1000).toFixed(1) + 'K';\n }\n return num.toString();\n};\n\n// Actions\nconst playPlaylist = () => {\n if (playlistTracks.value && playlistTracks.value.length > 0) {\n playerActions.setQueue(playlistTracks.value);\n }\n};\n\nconst shufflePlay = () => {\n if (playlistTracks.value && playlistTracks.value.length > 0) {\n const shuffled = [...playlistTracks.value].sort(() => Math.random() - 0.5);\n playerActions.setQueue(shuffled);\n }\n};\n\nconst toggleFollow = async () => {\n isFollowing.value = !isFollowing.value;\n // TODO: Implement actual following\n try {\n if (isFollowing.value) {\n await playlistsActions.followPlaylist(playlist.value._id);\n } else {\n await playlistsActions.unfollowPlaylist(playlist.value._id);\n }\n } catch (error) {\n console.error('Error toggling follow:', error);\n isFollowing.value = !isFollowing.value; // Revert on error\n }\n};\n\nconst toggleFollowUser = (userId) => {\n const index = followedUsers.value.indexOf(userId);\n if (index > -1) {\n followedUsers.value.splice(index, 1);\n } else {\n followedUsers.value.push(userId);\n }\n // TODO: Implement actual following\n};\n\nconst addToQueue = () => {\n if (playlistTracks.value && playlistTracks.value.length > 0) {\n playlistTracks.value.forEach(track => {\n playerActions.addToQueue(track);\n });\n showDropdown.value = false;\n }\n};\n\nconst editPlaylist = () => {\n showEditModal.value = true;\n showDropdown.value = false;\n};\n\nconst toggleCollaborative = async () => {\n try {\n const updatedData = {\n _id: playlist.value._id,\n isCollaborative: !playlist.value.isCollaborative\n };\n \n await playlistsActions.updatePlaylist(updatedData);\n showDropdown.value = false;\n } catch (error) {\n console.error('Error updating playlist:', error);\n }\n};\n\nconst deletePlaylist = () => {\n showDeleteModal.value = true;\n showDropdown.value = false;\n};\n\nconst confirmDelete = async () => {\n try {\n await playlistsActions.deletePlaylist(playlist.value._id);\n router.push({ name: 'music-library' });\n } catch (error) {\n console.error('Error deleting playlist:', error);\n globals.actions.setError({\n message: 'Failed to delete playlist'\n });\n }\n};\n\nconst removeTrack = async (trackId) => {\n try {\n await playlistsActions.removeTrackFromPlaylist(playlist.value._id, trackId);\n // Refresh playlist data\n await fetchPlaylistData();\n } catch (error) {\n console.error('Error removing track:', error);\n globals.actions.setError({\n message: 'Failed to remove track'\n });\n }\n};\n\nconst copyLink = () => {\n navigator.clipboard.writeText(window.location.href);\n showDropdown.value = false;\n};\n\nconst handlePlaylistUpdated = () => {\n showEditModal.value = false;\n fetchPlaylistData();\n};\n\n// Data fetching\nconst fetchPlaylistData = async () => {\n try {\n await playlistsActions.fetchPlaylistByUrl(route.params.url);\n \n // Check if following\n if (authState.user && playlist.value) {\n // TODO: Check if user is following this playlist\n }\n \n // Fetch more playlists from the same creator\n if (playlist.value?.creator?.target) {\n const creatorId = typeof playlist.value.creator.target === 'object' \n ? playlist.value.creator.target._id \n : playlist.value.creator.target;\n \n const playlists = await playlistsActions.fetchPlaylists({\n 'creator.target': creatorId,\n isPublic: true,\n limit: 6\n });\n \n // Filter out current playlist\n morePlaylists.value = playlists.filter(p => p._id !== playlist.value._id).slice(0, 5);\n }\n } catch (error) {\n console.error('Error fetching playlist data:', error);\n }\n};\n\n// Lifecycle\nonMounted(async () => {\n emits('page-loading');\n \n await fetchPlaylistData();\n \n hasLoaded.value = true;\n emits('page-loaded');\n});\n</script>"],"names":["useRoute","useRouter","ref","playlistsState","computed","authState","playlist","playerActions","playlistsActions","globals.actions","playlists","onMounted"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Playlist.vue.cjs","sources":["../../../../../../../src/modules/music/components/pages/Playlist.vue"],"sourcesContent":["<template>\n <div class=\"playlist-page pd-small\">\n <!-- Not Found -->\n <div v-if=\"hasLoaded && !playlist\" class=\"t-center pd-big\">\n <h2 class=\"\">Playlist not found</h2>\n <p class=\"t-transp t-medium\">The playlist you're looking for doesn't exist or has been removed.</p>\n </div>\n \n <!-- Playlist Content -->\n <div v-if=\"playlist\" class=\"playlist-content cols-2-fit-content mobile:cols-1 gap-big\">\n <!-- Left Column - Cover & Stats -->\n <div class=\"pos-sticky w-max-30r pos-t-0 mobile:pos-relative playlist-cover-section\">\n <!-- Cover -->\n <div class=\"cover-container relative mn-b-medium radius-big overflow-hidden shadow-big\">\n <Media \n :url=\"playlist.coverUrl || '/assets/placeholder-playlist.jpg'\"\n :alt=\"playlist.title\"\n class=\"aspect-1x1 w-100 radius-medium o-hidden\"\n />\n </div>\n\n <!-- Quick Stats -->\n <div class=\"stats-grid grid cols-2 gap-small\">\n <div class=\"stat-card bg-light pd-medium radius-medium t-center\">\n <div class=\" mn-b-thin\">{{ playlistTracks.length }}</div>\n <div class=\"t-small t-transp t-uppercase\">Tracks</div>\n </div>\n <div class=\"stat-card bg-light pd-medium radius-medium t-center\">\n <div class=\" mn-b-thin\">{{ formatNumber(playlist.followers || 0) }}</div>\n <div class=\"t-small t-transp t-uppercase\">Followers</div>\n </div>\n </div>\n </div>\n\n <!-- Right Column - Playlist Details -->\n <div class=\"playlist-details-section\">\n <!-- Playlist Type Badge -->\n <div class=\"flex items-center gap-small mn-b-small\">\n <span class=\"bg-light t-medium pd-thin radius-thin uppercase t-small t-uppercase\">\n Playlist\n </span>\n <span v-if=\"playlist.isCollaborative\" class=\"bg-light t-medium pd-thin radius-thin uppercase t-small t-uppercase\">\n Collaborative\n </span>\n <span v-if=\"playlist.status === 'published'\" class=\"bg-light t-medium pd-thin radius-thin uppercase t-small t-uppercase\">\n Published\n </span>\n </div>\n\n <!-- Playlist Title -->\n <h1 class=\"h1 mn-b-medium\">{{ playlist.title }}</h1>\n\n <!-- Action Buttons -->\n <div class=\"flex gap-small mn-b-medium\">\n <Button\n @click=\"playPlaylist\"\n color=\"primary\"\n size=\"medium\"\n class=\"flex-1 t-white bg-black radius-thin flex-center gap-thin\"\n >\n <IconPlay fill=\"rgb(var(--white))\" class=\"i-medium\" />\n Play All\n </Button>\n\n <Button\n @click=\"shufflePlay\"\n color=\"primary\"\n size=\"medium\"\n class=\"flex-1 bg-light radius-thin flex-center gap-thin\"\n >\n <IconShuffle class=\"i-medium\" />\n Shuffle\n </Button>\n\n <Button\n @click=\"toggleFollow\"\n color=\"primary\"\n size=\"medium\"\n class=\"flex-1 bg-light radius-thin flex-center gap-thin\"\n >\n {{isFollowing ? 'Follow' : 'Unfollow'}}\n </Button>\n\n \n <Dropdown :label=\"{component: IconEllipsis, class: 'bg-light radius-thin pd-thin i-big' }\" v-model=\"showDropdown\" class=\"relative\">\n <template #trigger>\n <Button color=\"transp\" size=\"medium\" class=\"w-3r h-3r radius-full\">\n <IconEllipsis class=\"w-1-25r h-1-25r\" />\n </Button>\n </template>\n <template #default>\n <div class=\"dropdown-menu bg-white pd-small radius-medium shadow-big mn-t-thin\">\n <Button @click=\"addToQueue\" color=\"transp\" size=\"small\" class=\"w-100 t-nowrap justify-start\">\n Add to Queue\n </Button>\n <Button @click=\"copyLink\" color=\"transp\" size=\"small\" class=\"w-100 t-nowrap justify-start\">\n Copy Link\n </Button>\n <template v-if=\"isOwner || isCollaborator\">\n <hr class=\"mn-v-thin border-dark-transp-10\" />\n <Button @click=\"editPlaylist\" color=\"transp\" size=\"small\" class=\"w-100 t-nowrap justify-start\">\n Edit Playlist\n </Button>\n <Button v-if=\"isOwner\" @click=\"toggleCollaborative\" color=\"transp\" size=\"small\" class=\"t-nowrap w-100 justify-start\">\n {{ playlist.isCollaborative ? 'Make Private' : 'Make Collaborative' }}\n </Button>\n <Button v-if=\"isOwner\" @click=\"deletePlaylist\" color=\"danger\" size=\"small\" class=\"t-nowrap w-100 justify-start\">\n Delete Playlist\n </Button>\n </template>\n </div>\n </template>\n </Dropdown>\n </div>\n\n <div class=\"artists-section mn-b-medium\">\n <h3 class=\"t-medium mn-b-small\">Created by</h3>\n <div class=\"flex flex-col gap-small\">\n <ArtistCardSmall \n :artist=\"{\n _id: playlist.creator.target,\n to: { name: 'User Profile', params: { _id: playlist.creator.target } },\n photoUrl: null,\n name: playlist.creator.target,\n isVerified: false\n }\"\n :is-following=\"followedUsers.includes(playlist.creator.target)\"\n :show-follow-button=\"!isOwner\"\n @toggle-follow=\"toggleFollowUser(playlist.creator.target)\"\n />\n </div>\n </div>\n\n <!-- Collaborators -->\n <div v-if=\"playlist.collaborators && playlist.collaborators.length > 0\" class=\"collaborators-section mn-b-big\">\n <h3 class=\"t-medium mn-b-small\">Collaborators</h3>\n <div class=\"flex flex-wrap gap-small\">\n <div \n v-for=\"collaborator in playlist.collaborators\"\n :key=\"collaborator._id || collaborator\"\n class=\"collaborator-chip bg-light pd-thin-big radius-full flex items-center gap-thin\"\n >\n <Media \n v-if=\"collaborator.photoUrl\"\n :url=\"collaborator.photoUrl\"\n class=\"i-regular radius-full object-cover\"\n />\n <span class=\"t-small\">{{ collaborator.name || collaborator.profile?.name || 'User' }}</span>\n </div>\n </div>\n </div>\n\n <!-- Metadata Cards -->\n <h3 class=\"t-medium mn-b-small\">Metadata</h3>\n <div class=\"metadata-grid grid cols-2 gap-small mn-b-medium\">\n <!-- Created Date -->\n <div class=\"metadata-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <IconCalendar class=\"i-medium t-primary\" />\n <div>\n <div class=\"t-small t-transp t-uppercase\">Created</div>\n <div class=\"t-medium \">{{ formatDate(playlist.createdAt) }}</div>\n </div>\n </div>\n\n <!-- Total Duration -->\n <div class=\"metadata-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <IconClock class=\"i-medium t-primary\" />\n <div>\n <div class=\"t-small t-transp t-uppercase\">Duration</div>\n <div class=\"t-medium \">{{ totalDuration }}</div>\n </div>\n </div>\n\n <!-- Updated Date -->\n <div class=\"metadata-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <IconRefresh class=\"i-medium t-primary\" />\n <div>\n <div class=\"t-small t-transp t-uppercase\">Updated</div>\n <div class=\"t-medium \">{{ formatDate(playlist.updatedAt) }}</div>\n </div>\n </div>\n\n <!-- Visibility -->\n <div class=\"metadata-card bg-light pd-medium radius-medium flex items-center gap-medium\">\n <IconEye class=\"i-medium t-primary\" />\n <div>\n <div class=\"t-small t-transp t-uppercase\">Visibility</div>\n <div class=\"t-medium \">{{ playlist.isPublic ? 'Public' : 'Private' }}</div>\n </div>\n </div>\n </div>\n\n <!-- Tags -->\n <div v-if=\"playlist.tags && playlist.tags.length\" class=\"tags-section mn-b-medium\">\n <h3 class=\"t-medium mn-b-small\">Tags</h3>\n <div class=\"flex gap-thin flex-wrap\">\n <span \n v-for=\"tag in playlist.tags\" \n :key=\"tag\"\n class=\"tag bg-light t-transp pd-thin-big radius-small t-small hover-bg-light cursor-pointer\"\n >\n #{{ tag }}\n </span>\n </div>\n </div>\n\n <!-- Description -->\n <div v-if=\"playlist.description\" class=\"description-section bg-light pd-medium radius-medium mn-b-medium\">\n <h3 class=\"t-medium mn-b-small\">About</h3>\n <p class=\"t-transp\">{{ playlist.description }}</p>\n </div>\n </div>\n </div>\n\n <!-- Playlist Tracks -->\n <section v-if=\"!isLoading && playlist && playlistTracks.length\" class=\"tracks-section mn-t-big\">\n <h2 class=\"h2 mn-b-medium\">Tracklist</h2>\n <Feed\n :store=\"{\n read: () => Promise.resolve(playlistTracks),\n state: { isLoading: false }\n }\"\n :external=\"true\"\n :items=\"playlistTracks\"\n :states=\"{\n empty: {\n title: 'No tracks in playlist',\n description: 'Add some tracks to get started',\n class: 'pd-medium t-center'\n }\n }\"\n >\n <template #default=\"{ items }\">\n <div class=\"bg-light radius-medium o-hidden\">\n <TrackListCard\n v-for=\"(track, index) in items\"\n :key=\"track._id\"\n :track=\"track\"\n :index=\"index + 1\"\n :showAlbum=\"true\"\n :showCover=\"true\"\n :canRemove=\"isOwner || isCollaborator\"\n @remove=\"() => removeTrack(track._id)\"\n />\n </div>\n </template>\n </Feed>\n </section>\n\n <!-- Empty State -->\n <section v-else-if=\"!isLoading && playlist && !playlistTracks.length\" class=\"empty-section mn-t-big\">\n <div class=\"empty-tracks t-center pd-big bg-light radius-medium\">\n <h3 class=\" mn-b-small\">This playlist is empty</h3>\n <p class=\"t-transp t-medium mn-b-medium\">Add some tracks to get started</p>\n \n <Button \n v-if=\"isOwner || isCollaborator\"\n @click=\"$router.push({ name: 'music-search' })\"\n color=\"primary\"\n size=\"medium\"\n >\n Find Tracks\n </Button>\n </div>\n </section>\n\n <!-- More Playlists -->\n <section v-if=\"!isLoading && playlist && morePlaylists.length\" class=\"more-playlists-section mn-t-big\">\n <div class=\"flex justify-between items-center mn-b-medium\">\n <h2 class=\"h2\">More Playlists</h2>\n <router-link \n v-if=\"playlist.creator\"\n :to=\"getOwnerProfileLink(playlist.creator)\" \n class=\"t-primary hover-opacity\"\n >\n See all\n </router-link>\n </div>\n <div class=\"flex flex-nowrap gap-small o-x-scroll overscroll-behavior-x-contain scroll-behavior-smooth scroll-snap-type-x-mandatory scroll-hide\">\n <li v-for=\"relatedPlaylist in morePlaylists\" :key=\"relatedPlaylist._id\" class=\"flex-none scroll-snap-align-start\">\n <PlaylistCard :playlist=\"relatedPlaylist\" class=\"w-min-15r transition-cubic-in-out\" />\n </li>\n </div>\n </section>\n\n <!-- Edit Playlist Modal -->\n <Popup \n :isPopupOpen=\"showEditModal && (isOwner || isCollaborator)\"\n @close-popup=\"showEditModal = false\" \n class=\"bg-white pd-medium w-m-30r radius-medium\"\n >\n <PlaylistForm \n :editMode=\"true\"\n :url=\"playlist.url\"\n @cancel=\"showEditModal = false\"\n @updated=\"handlePlaylistUpdated\"\n />\n </Popup>\n\n <!-- Delete Confirmation Modal -->\n <Popup \n :isPopupOpen=\"showDeleteModal\"\n @close-popup=\"showDeleteModal = false\" \n class=\"bg-white pd-medium w-m-25r radius-medium\"\n >\n <h3 class=\"mn-b-medium\">Delete Playlist</h3>\n <p class=\"t-transp mn-b-medium\">Are you sure you want to delete \"{{ playlist.title }}\"? This action cannot be undone.</p>\n \n <div class=\"flex justify-end gap-small\">\n <Button \n @click=\"showDeleteModal = false\"\n color=\"transp\"\n size=\"medium\"\n >\n Cancel\n </Button>\n \n <Button \n @click=\"confirmDelete\"\n color=\"danger\"\n size=\"medium\"\n >\n Delete Playlist\n </Button>\n </div>\n </Popup>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed, onMounted, watch } from 'vue';\nimport { useRoute, useRouter } from 'vue-router';\nimport Button from '@martyrs/src/components/Button/Button.vue';\nimport Loader from '@martyrs/src/components/Loader/Loader.vue';\nimport Media from '@martyrs/src/components/Media/Media.vue';\nimport Dropdown from '@martyrs/src/components/Dropdown/Dropdown.vue';\nimport Feed from '@martyrs/src/components/Feed/Feed.vue';\nimport Popup from '@martyrs/src/components/Popup/Popup.vue';\n\n// Icons\nimport IconPlay from '@martyrs/src/modules/icons/navigation/IconPlay.vue';\nimport IconLike from '@martyrs/src/modules/icons/navigation/IconLike.vue';\nimport IconEllipsis from '@martyrs/src/modules/icons/navigation/IconEllipsis.vue';\nimport IconShuffle from '@martyrs/src/modules/icons/navigation/IconShuffle.vue';\nimport IconCalendar from '@martyrs/src/modules/icons/entities/IconCalendar.vue';\nimport IconClock from '@martyrs/src/modules/icons/entities/IconTime.vue';\nimport IconEye from '@martyrs/src/modules/icons/actions/IconShow.vue';\nimport IconRefresh from '@martyrs/src/modules/icons/navigation/IconRefresh.vue';\nimport IconVerified from '@martyrs/src/modules/icons/navigation/IconCheckmark.vue';\n\n// Components\nimport TrackListCard from '../cards/TrackListCard.vue';\nimport PlaylistCard from '../cards/PlaylistCard.vue';\nimport PlaylistForm from '../forms/PlaylistForm.vue';\nimport ArtistCardSmall from '../cards/ArtistCardSmall.vue';\n\n// Store\nimport { state as playlistsState, actions as playlistsActions } from '../../store/playlists.js';\nimport { state as tracksState, actions as tracksActions } from '../../store/tracks.js';\nimport { actions as playerActions } from '../../store/player.js';\nimport { state as authState } from '@martyrs/src/modules/auth/views/store/auth.js';\nimport * as globals from '@martyrs/src/modules/globals/views/store/globals.js';\n\nconst route = useRoute();\nconst router = useRouter();\n\n// Emits\nconst emits = defineEmits(['page-loading', 'page-loaded']);\n\n// State\nconst hasLoaded = ref(false);\nconst isFollowing = ref(false);\nconst showDropdown = ref(false);\nconst showEditModal = ref(false);\nconst showDeleteModal = ref(false);\nconst followedUsers = ref([]);\nconst morePlaylists = ref([]);\n\n// Clear state\nplaylistsState.currentPlaylist = null;\nplaylistsState.currentPlaylistTracks = [];\n\n// Computed\nconst playlist = computed(() => playlistsState.currentPlaylist);\nconst playlistTracks = computed(() => playlistsState.currentPlaylistTracks || []);\n\nconst isOwner = computed(() => {\n if (!playlist.value || !authState.user) return false;\n \n const ownerId = playlist.value.owner?.target?._id || playlist.value.owner?.target;\n return ownerId === authState.user._id;\n});\n\nconst isCollaborator = computed(() => {\n if (!playlist.value || !authState.user) return false;\n \n return playlist.value.collaborators?.some(collab => \n (collab._id || collab) === authState.user._id\n );\n});\n\nconst totalDuration = computed(() => {\n if (!playlistTracks.value.length) return '0:00';\n const totalSeconds = playlistTracks.value.reduce((sum, track) => sum + (track.duration || 0), 0);\n return formatDuration(totalSeconds);\n});\n\n// Helper functions\nconst getOwnerData = (playlist) => {\n if (!playlist) return null;\n const owner = playlist.creator?.target || playlist.owner?.target;\n return typeof owner === 'object' ? owner : null;\n};\n\nconst getOwnerId = (playlist) => {\n if (!playlist) return null;\n const owner = playlist.creator?.target || playlist.owner?.target;\n return typeof owner === 'object' ? owner._id : owner;\n};\n\nconst getPlaylistOwnerName = (playlist) => {\n if (!playlist) return 'Unknown';\n \n const owner = getOwnerData(playlist);\n if (owner) {\n return owner.profile?.name || owner.name || 'Unknown';\n }\n \n return 'Unknown';\n};\n\nconst getOwnerProfileLink = (owner) => {\n if (!owner || !owner.target) return { name: 'music-home' };\n \n const targetId = typeof owner.target === 'object' ? owner.target._id : owner.target;\n \n if (owner.type === 'user' || owner.type === 'User') {\n return { name: 'User Profile', params: { _id: targetId } };\n } else if (owner.type === 'organization' || owner.type === 'Organization') {\n return { name: 'Organizatio', params: { _id: targetId } };\n }\n \n return { name: 'music-home' };\n};\n\n// Format helpers\nconst formatDate = (dateString) => {\n if (!dateString) return 'Unknown';\n return new Date(dateString).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n });\n};\n\nconst formatDuration = (seconds) => {\n if (!seconds) return '0:00';\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = Math.floor(seconds % 60);\n \n if (h > 0) {\n return `${h}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;\n }\n return `${m}:${s.toString().padStart(2, '0')}`;\n};\n\nconst formatNumber = (num) => {\n if (!num) return '0';\n if (num >= 1000000) {\n return (num / 1000000).toFixed(1) + 'M';\n } else if (num >= 1000) {\n return (num / 1000).toFixed(1) + 'K';\n }\n return num.toString();\n};\n\n// Actions\nconst playPlaylist = () => {\n if (playlistTracks.value && playlistTracks.value.length > 0) {\n playerActions.setQueue(playlistTracks.value);\n }\n};\n\nconst shufflePlay = () => {\n if (playlistTracks.value && playlistTracks.value.length > 0) {\n const shuffled = [...playlistTracks.value].sort(() => Math.random() - 0.5);\n playerActions.setQueue(shuffled);\n }\n};\n\nconst toggleFollow = async () => {\n isFollowing.value = !isFollowing.value;\n // TODO: Implement actual following\n try {\n if (isFollowing.value) {\n await playlistsActions.followPlaylist(playlist.value._id);\n } else {\n await playlistsActions.unfollowPlaylist(playlist.value._id);\n }\n } catch (error) {\n console.error('Error toggling follow:', error);\n isFollowing.value = !isFollowing.value; // Revert on error\n }\n};\n\nconst toggleFollowUser = (userId) => {\n const index = followedUsers.value.indexOf(userId);\n if (index > -1) {\n followedUsers.value.splice(index, 1);\n } else {\n followedUsers.value.push(userId);\n }\n // TODO: Implement actual following\n};\n\nconst addToQueue = () => {\n if (playlistTracks.value && playlistTracks.value.length > 0) {\n playlistTracks.value.forEach(track => {\n playerActions.addToQueue(track);\n });\n showDropdown.value = false;\n }\n};\n\nconst editPlaylist = () => {\n showEditModal.value = true;\n showDropdown.value = false;\n};\n\nconst toggleCollaborative = async () => {\n try {\n const updatedData = {\n _id: playlist.value._id,\n isCollaborative: !playlist.value.isCollaborative\n };\n \n await playlistsActions.updatePlaylist(updatedData);\n showDropdown.value = false;\n } catch (error) {\n console.error('Error updating playlist:', error);\n }\n};\n\nconst deletePlaylist = () => {\n showDeleteModal.value = true;\n showDropdown.value = false;\n};\n\nconst confirmDelete = async () => {\n try {\n await playlistsActions.deletePlaylist(playlist.value._id);\n router.push({ name: 'music-library' });\n } catch (error) {\n console.error('Error deleting playlist:', error);\n globals.actions.setError({\n message: 'Failed to delete playlist'\n });\n }\n};\n\nconst removeTrack = async (trackId) => {\n try {\n await playlistsActions.removeTrackFromPlaylist(playlist.value._id, trackId);\n // Refresh playlist data\n await fetchPlaylistData();\n } catch (error) {\n console.error('Error removing track:', error);\n globals.actions.setError({\n message: 'Failed to remove track'\n });\n }\n};\n\nconst copyLink = () => {\n navigator.clipboard.writeText(window.location.href);\n showDropdown.value = false;\n};\n\nconst handlePlaylistUpdated = () => {\n showEditModal.value = false;\n fetchPlaylistData();\n};\n\n// Data fetching\nconst fetchPlaylistData = async () => {\n try {\n await playlistsActions.fetchPlaylistByUrl(route.params.url);\n \n // Check if following\n if (authState.user && playlist.value) {\n // TODO: Check if user is following this playlist\n }\n \n // Fetch more playlists from the same creator\n if (playlist.value?.creator?.target) {\n const creatorId = typeof playlist.value.creator.target === 'object' \n ? playlist.value.creator.target._id \n : playlist.value.creator.target;\n \n const playlists = await playlistsActions.fetchPlaylists({\n 'creator.target': creatorId,\n isPublic: true,\n limit: 6\n });\n \n // Filter out current playlist\n morePlaylists.value = playlists.filter(p => p._id !== playlist.value._id).slice(0, 5);\n }\n } catch (error) {\n console.error('Error fetching playlist data:', error);\n }\n};\n\n// Lifecycle\nonMounted(async () => {\n emits('page-loading');\n \n await fetchPlaylistData();\n \n hasLoaded.value = true;\n emits('page-loaded');\n});\n</script>"],"names":["useRoute","useRouter","ref","playlistsState","computed","authState","playerActions","playlistsActions","globals.actions","playlists","onMounted"],"mappings":"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"}
|