@ozdao/martyrs 0.2.565 → 0.2.567

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 (122) hide show
  1. package/dist/{main-B9o1iBAZ.js → main-BFvlam0J.js} +9 -6
  2. package/dist/martyrs/dist/main-BFvlam0J.js +943 -0
  3. package/dist/martyrs/dist/main-BFvlam0J.js.map +1 -0
  4. package/dist/martyrs/dist/web-CH5wzMHy.js +55 -0
  5. package/dist/martyrs/dist/web-CH5wzMHy.js.map +1 -0
  6. package/dist/martyrs/src/components/BottomSheet/BottomSheet.vue.js +96 -0
  7. package/dist/martyrs/src/components/BottomSheet/BottomSheet.vue.js.map +1 -0
  8. package/dist/martyrs/src/components/Feed/Carousel.vue.js +2 -2
  9. package/dist/martyrs/src/components/Feed/Carousel.vue.js.map +1 -1
  10. package/dist/martyrs/src/components/Feed/Feed.vue.js +6 -3
  11. package/dist/martyrs/src/components/Feed/Feed.vue.js.map +1 -1
  12. package/dist/martyrs/src/components/Menu/{Menu.vue2.js → Menu.vue.js} +2 -2
  13. package/dist/martyrs/src/components/Menu/Menu.vue.js.map +1 -0
  14. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +1 -1
  15. package/dist/martyrs/src/modules/community/components/sections/HotPosts.vue.js.map +1 -1
  16. package/dist/martyrs/src/modules/core/views/components/layouts/App.vue.js +1 -1
  17. package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js +1 -0
  18. package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js.map +1 -1
  19. package/dist/martyrs/src/modules/core/views/components/sections/Walkthrough.vue.js +1 -1
  20. package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.js +1 -1
  21. package/dist/martyrs/src/modules/events/components/sections/EventsHot.vue.js +17 -1
  22. package/dist/martyrs/src/modules/events/components/sections/EventsHot.vue.js.map +1 -1
  23. package/dist/martyrs/src/modules/events/events.client.js +15 -12
  24. package/dist/martyrs/src/modules/events/events.client.js.map +1 -1
  25. package/dist/martyrs/src/modules/music/components/blocks/ActionButtons.vue.js +95 -0
  26. package/dist/martyrs/src/modules/music/components/blocks/ActionButtons.vue.js.map +1 -0
  27. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js +5 -2
  28. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js.map +1 -1
  29. package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js +24 -24
  30. package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js.map +1 -1
  31. package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js +3 -3
  32. package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js.map +1 -1
  33. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js +31 -6
  34. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js.map +1 -1
  35. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +120 -205
  36. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js.map +1 -1
  37. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js +9 -13
  38. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js.map +1 -1
  39. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +166 -245
  40. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js.map +1 -1
  41. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +135 -220
  42. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js.map +1 -1
  43. package/dist/martyrs/src/modules/music/components/player/FullscreenPlayer.vue.js +171 -0
  44. package/dist/martyrs/src/modules/music/components/player/FullscreenPlayer.vue.js.map +1 -0
  45. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js +31 -153
  46. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js.map +1 -1
  47. package/dist/martyrs/src/modules/music/components/player/PlayerControls.vue.js +96 -0
  48. package/dist/martyrs/src/modules/music/components/player/PlayerControls.vue.js.map +1 -0
  49. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js +55 -27
  50. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js.map +1 -1
  51. package/dist/martyrs/src/modules/music/components/player/tonar.png.js +5 -0
  52. package/dist/martyrs/src/modules/music/components/player/tonar.png.js.map +1 -0
  53. package/dist/martyrs/src/modules/music/store/albums.js +8 -2
  54. package/dist/martyrs/src/modules/music/store/albums.js.map +1 -1
  55. package/dist/martyrs/src/modules/music/store/player.js +83 -65
  56. package/dist/martyrs/src/modules/music/store/player.js.map +1 -1
  57. package/dist/martyrs/src/modules/music/store/tracks.js +4 -13
  58. package/dist/martyrs/src/modules/music/store/tracks.js.map +1 -1
  59. package/dist/martyrs/src/modules/notifications/notifications.client.js +2 -2
  60. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +1 -1
  61. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
  62. package/dist/martyrs.css +1 -1
  63. package/dist/martyrs.es.js +1 -1
  64. package/dist/music.server.js +33 -6
  65. package/dist/node_modules/.pnpm/{@capacitor-mlkit_barcode-scanning@7.1.0_@capacitor_core@7.0.1 → @capacitor-mlkit_barcode-scanning@7.3.0_@capacitor_core@7.4.4}/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/definitions.js +1 -0
  66. package/dist/node_modules/.pnpm/@capacitor-mlkit_barcode-scanning@7.3.0_@capacitor_core@7.4.4/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/definitions.js.map +1 -0
  67. package/dist/node_modules/.pnpm/{@capacitor-mlkit_barcode-scanning@7.1.0_@capacitor_core@7.0.1 → @capacitor-mlkit_barcode-scanning@7.3.0_@capacitor_core@7.4.4}/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/index.js +1 -1
  68. package/dist/node_modules/.pnpm/{@capacitor-mlkit_barcode-scanning@7.1.0_@capacitor_core@7.0.1 → @capacitor-mlkit_barcode-scanning@7.3.0_@capacitor_core@7.4.4}/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/index.js.map +1 -1
  69. package/dist/node_modules/.pnpm/{@capacitor-mlkit_barcode-scanning@7.1.0_@capacitor_core@7.0.1 → @capacitor-mlkit_barcode-scanning@7.3.0_@capacitor_core@7.4.4}/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/web.js +16 -1
  70. package/dist/node_modules/.pnpm/@capacitor-mlkit_barcode-scanning@7.3.0_@capacitor_core@7.4.4/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/web.js.map +1 -0
  71. package/dist/node_modules/.pnpm/{@capacitor_core@7.0.1 → @capacitor_core@7.4.4}/node_modules/@capacitor/core/dist/index.js +2 -1
  72. package/dist/node_modules/.pnpm/@capacitor_core@7.4.4/node_modules/@capacitor/core/dist/index.js.map +1 -0
  73. package/dist/node_modules/.pnpm/{@capacitor_device@7.0.0_@capacitor_core@7.0.1 → @capacitor_device@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/device/dist/esm/index.js +1 -1
  74. package/dist/node_modules/.pnpm/{@capacitor_device@7.0.0_@capacitor_core@7.0.1 → @capacitor_device@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/device/dist/esm/index.js.map +1 -1
  75. package/dist/node_modules/.pnpm/{@capacitor_device@7.0.0_@capacitor_core@7.0.1 → @capacitor_device@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/device/dist/esm/web.js +1 -1
  76. package/dist/node_modules/.pnpm/{@capacitor_device@7.0.0_@capacitor_core@7.0.1 → @capacitor_device@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/device/dist/esm/web.js.map +1 -1
  77. package/dist/node_modules/.pnpm/{@capacitor_keyboard@7.0.0_@capacitor_core@7.0.1 → @capacitor_keyboard@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/keyboard/dist/esm/definitions.js.map +1 -1
  78. package/dist/node_modules/.pnpm/{@capacitor_keyboard@7.0.0_@capacitor_core@7.0.1 → @capacitor_keyboard@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/keyboard/dist/esm/index.js +1 -1
  79. package/dist/node_modules/.pnpm/{@capacitor_keyboard@7.0.0_@capacitor_core@7.0.1 → @capacitor_keyboard@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/keyboard/dist/esm/index.js.map +1 -1
  80. package/dist/node_modules/.pnpm/{@capacitor_push-notifications@7.0.0_@capacitor_core@7.0.1 → @capacitor_push-notifications@7.0.3_@capacitor_core@7.4.4}/node_modules/@capacitor/push-notifications/dist/esm/index.js +1 -1
  81. package/dist/node_modules/.pnpm/{@capacitor_push-notifications@7.0.0_@capacitor_core@7.0.1 → @capacitor_push-notifications@7.0.3_@capacitor_core@7.4.4}/node_modules/@capacitor/push-notifications/dist/esm/index.js.map +1 -1
  82. package/dist/node_modules/.pnpm/{capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.0.1 → capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.4.4}/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/index.js +1 -1
  83. package/dist/node_modules/.pnpm/{capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.0.1 → capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.4.4}/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/index.js.map +1 -1
  84. package/dist/node_modules/.pnpm/{capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.0.1 → capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.4.4}/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/web.js +1 -1
  85. package/dist/node_modules/.pnpm/{capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.0.1 → capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.4.4}/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/web.js.map +1 -1
  86. package/dist/style.css +221 -145
  87. package/dist/{web-BF3ijvEr.js → web-CH5wzMHy.js} +1 -1
  88. package/package.json +1 -1
  89. package/src/components/BottomSheet/BottomSheet.vue +4 -4
  90. package/src/components/Feed/Carousel.vue +1 -1
  91. package/src/components/Feed/Feed.vue +3 -3
  92. package/src/modules/LAYOUT.MD +767 -0
  93. package/src/modules/community/components/sections/HotPosts.vue +8 -4
  94. package/src/modules/core/views/components/layouts/Client.vue +1 -1
  95. package/src/modules/events/components/sections/EventsHot.vue +21 -4
  96. package/src/modules/events/events.client.js +3 -0
  97. package/src/modules/music/components/blocks/ActionButtons.vue +74 -0
  98. package/src/modules/music/components/cards/AlbumCard.vue +1 -1
  99. package/src/modules/music/components/cards/ArtistCardSmall.vue +8 -6
  100. package/src/modules/music/components/cards/TrackListCard.vue +6 -6
  101. package/src/modules/music/components/layouts/MusicBottomPlayer.vue +94 -4
  102. package/src/modules/music/components/pages/Album.vue +55 -67
  103. package/src/modules/music/components/pages/MusicHome.vue +4 -6
  104. package/src/modules/music/components/pages/Playlist.vue +61 -70
  105. package/src/modules/music/components/pages/Track.vue +54 -71
  106. package/src/modules/music/components/player/FullscreenPlayer.vue +248 -0
  107. package/src/modules/music/components/player/MusicPlayer.vue +21 -216
  108. package/src/modules/music/components/player/PlayerControls.vue +112 -0
  109. package/src/modules/music/components/player/Visualizer.vue +151 -0
  110. package/src/modules/music/components/player/VolumeControl.vue +75 -23
  111. package/src/modules/music/components/player/tonar.png +0 -0
  112. package/src/modules/music/routes/albums.routes.js +13 -12
  113. package/src/modules/music/routes/tracks.routes.js +39 -0
  114. package/src/modules/music/store/albums.js +10 -2
  115. package/src/modules/music/store/player.js +101 -89
  116. package/src/modules/music/store/tracks.js +5 -21
  117. package/src/styles/config.scss +6 -6
  118. package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +0 -1
  119. package/dist/node_modules/.pnpm/@capacitor-mlkit_barcode-scanning@7.1.0_@capacitor_core@7.0.1/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/definitions.js.map +0 -1
  120. package/dist/node_modules/.pnpm/@capacitor-mlkit_barcode-scanning@7.1.0_@capacitor_core@7.0.1/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/web.js.map +0 -1
  121. package/dist/node_modules/.pnpm/@capacitor_core@7.0.1/node_modules/@capacitor/core/dist/index.js.map +0 -1
  122. /package/dist/node_modules/.pnpm/{@capacitor_keyboard@7.0.0_@capacitor_core@7.0.1 → @capacitor_keyboard@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/keyboard/dist/esm/definitions.js +0 -0
@@ -63,13 +63,17 @@ const props = defineProps({
63
63
  </script>
64
64
 
65
65
  <style lang="scss">
66
- .slider-hotpost :deep(.carousel__slide ) {
67
- flex: 0 0 25%;
66
+ .slider-hotpost {
67
+ .carousel__slide {
68
+ flex: 0 0 33%;
69
+ }
68
70
  }
69
71
 
70
72
  @media screen and (max-width: 1025px) {
71
- .slider-hotpost :deep(.carousel__slide ) {
72
- flex: 0 0 75%;
73
+ .slider-hotpost {
74
+ .carousel__slide {
75
+ flex: 0 0 75%;
76
+ }
73
77
  }
74
78
  }
75
79
  </style>
@@ -13,7 +13,7 @@
13
13
  }"
14
14
  >
15
15
  <transition name="moveFromTop" appear>
16
- <Loader v-if="!page || store.core.state.loading" class="pos-fixed"/>
16
+ <Loader v-if="!page || store.core.state.loading" :centered="true" class="pos-fixed"/>
17
17
  </transition>
18
18
 
19
19
  <transition
@@ -16,8 +16,8 @@
16
16
  class="slider-hotpost flex-child-default"
17
17
  >
18
18
  <template v-slot="{ item }">
19
- <router-link
20
- :to="{name: 'Event', params: {url: item.url}}"
19
+ <router-link
20
+ :to="getEventPath(item)"
21
21
  class="cursor-pointer pos-relative flex flex-justify-end flex-column h-25r bg-semi radius-medium o-hidden pd-medium t-white bg-dark"
22
22
  >
23
23
  <Media
@@ -42,12 +42,15 @@
42
42
  </template>
43
43
 
44
44
  <script setup>
45
- import { ref, onMounted, defineProps } from 'vue'
45
+ import { ref, onMounted, defineProps, computed } from 'vue'
46
+ import { useRoute } from 'vue-router'
46
47
  import Carousel from '@martyrs/src/components/Feed/Carousel.vue'
47
48
  import Media from '@martyrs/src/components/Media/Media.vue'
48
- import * as events from '@martyrs/src/modules/events/store/events.js';
49
+ import * as events from '@martyrs/src/modules/events/store/events.js';
49
50
  import * as auth from '@martyrs/src/modules/auth/views/store/auth.js'
50
51
 
52
+ const route = useRoute()
53
+
51
54
  const props = defineProps({
52
55
  skip: {
53
56
  type: Number,
@@ -68,8 +71,22 @@ const props = defineProps({
68
71
  status: {
69
72
  type: String,
70
73
  default: 'featured'
74
+ },
75
+ organization: {
76
+ type: String
71
77
  }
72
78
  })
79
+
80
+ const getEventPath = (item) => {
81
+ if (route.meta.context === 'backoffice') {
82
+ return `/backoffice/events/${item.url}`
83
+ }
84
+ if (route.meta.context === 'organization' || props.organization) {
85
+ const orgId = props.organization || route.params._id
86
+ return `/organizations/${orgId}/events/${item.url}`
87
+ }
88
+ return `/events/${item.url}`
89
+ }
73
90
  </script>
74
91
 
75
92
  <style lang="scss">
@@ -14,6 +14,7 @@ import EditEvent from './components/pages/EditEvent.vue';
14
14
  import Event from './components/pages/Event.vue';
15
15
  import EventsPage from './components/pages/Events.vue';
16
16
  import FeaturedEvents from './components/sections/FeaturedEvents.vue';
17
+ import EventsHot from './components/sections/EventsHot.vue';
17
18
  import Feed from './components/sections/Feed.vue';
18
19
  import List from './components/sections/List.vue';
19
20
 
@@ -44,6 +45,7 @@ const ModuleEvents = {
44
45
  Feed,
45
46
  List,
46
47
  FeaturedEvents,
48
+ EventsHot,
47
49
  // Layouts
48
50
  EventsLayout,
49
51
  // Pages
@@ -64,6 +66,7 @@ export {
64
66
  EventsLayout,
65
67
  EventsPage,
66
68
  FeaturedEvents,
69
+ EventsHot,
67
70
  Feed,
68
71
  initializeEvents,
69
72
  List,
@@ -0,0 +1,74 @@
1
+ <template>
2
+ <div class="flex gap-small mn-b-medium">
3
+ <template v-for="(button, index) in buttons" :key="index">
4
+ <!-- Regular button -->
5
+ <Button
6
+ v-if="button.type !== 'dropdown'"
7
+ :class="['flex-1 radius-thin flex-center gap-thin', button.class]"
8
+ @click="button.action"
9
+ >
10
+ <component
11
+ v-if="button.icon"
12
+ :is="button.icon"
13
+ :fill="button.iconFill"
14
+ class="i-medium"
15
+ />
16
+ {{ button.text }}
17
+ </Button>
18
+
19
+ <!-- Dropdown button -->
20
+ <Dropdown
21
+ v-else
22
+ :label="{component: IconEllipsis, class: 'bg-light radius-thin pd-thin i-big' }"
23
+ v-model="dropdownOpen"
24
+ class="relative"
25
+ >
26
+ <template #trigger>
27
+ <Button color="transp" size="medium" class="w-3r h-3r radius-full">
28
+ <IconEllipsis class="i-medium" />
29
+ </Button>
30
+ </template>
31
+ <template #default>
32
+ <div class="dropdown-menu bg-white pd-small radius-medium shadow-big mn-t-thin">
33
+ <template v-for="(item, idx) in button.items" :key="idx">
34
+ <hr v-if="item.separator" class="mn-v-thin border-dark-transp-10" />
35
+ <Button
36
+ v-else
37
+ @click="handleDropdownClick(item.action)"
38
+ :color="item.color || 'transp'"
39
+ size="small"
40
+ class="w-100 justify-start"
41
+ :class="item.class"
42
+ >
43
+ {{ item.text }}
44
+ </Button>
45
+ </template>
46
+ </div>
47
+ </template>
48
+ </Dropdown>
49
+ </template>
50
+ </div>
51
+ </template>
52
+
53
+ <script setup>
54
+ import { ref } from 'vue';
55
+ import Button from '@martyrs/src/components/Button/Button.vue';
56
+ import Dropdown from '@martyrs/src/components/Dropdown/Dropdown.vue';
57
+ import IconEllipsis from '@martyrs/src/modules/icons/navigation/IconEllipsis.vue';
58
+
59
+ const props = defineProps({
60
+ buttons: {
61
+ type: Array,
62
+ required: true
63
+ }
64
+ });
65
+
66
+ const dropdownOpen = ref(false);
67
+
68
+ const handleDropdownClick = (action) => {
69
+ if (action) {
70
+ action();
71
+ }
72
+ dropdownOpen.value = false;
73
+ };
74
+ </script>
@@ -21,7 +21,7 @@
21
21
  </div>
22
22
  </div>
23
23
  <div class="album-info pd-medium bg-light">
24
- <h3 class="mn-b-thin t-medium t-truncate">{{ album.title }}</h3>
24
+ <h3 class="mn-b-thin t-medium t-truncate" style="height: 1.50rem">{{ album.title }}</h3>
25
25
  <p class="t-transp t-small t-truncate">{{ albumInfo }}</p>
26
26
  </div>
27
27
  </router-link>
@@ -1,9 +1,11 @@
1
1
  <!-- components/cards/ArtistCard.vue -->
2
2
  <template>
3
- <div class="artist-card bg-light pd-medium radius-medium flex flex-center gap-big">
4
- <router-link
5
- :to="artist.url ? { name: 'artist', params: { url: artist.url } } : artist.to"
6
- class="flex flex-v-center gap-thin flex-1 hover-opacity"
3
+ <router-link
4
+ :to="artist.url ? { name: 'artist', params: { url: artist.url } } : artist.to"
5
+ class="artist-card bg-light pd-medium radius-medium flex flex-v-center flex-justify-between gap-thin flex-1 hover-opacity"
6
+ >
7
+ <div
8
+ class="flex flex-nowrap flex-v-center gap-thin"
7
9
  >
8
10
  <div class="artist-avatar">
9
11
  <Media
@@ -24,7 +26,7 @@
24
26
  </div>
25
27
  <span class="t-small t-transp">{{ artistType }}</span>
26
28
  </div>
27
- </router-link>
29
+ </div>
28
30
 
29
31
  <Button
30
32
  v-if="showFollowButton"
@@ -35,7 +37,7 @@
35
37
  >
36
38
  {{ isFollowing ? 'Following' : 'Follow' }}
37
39
  </Button>
38
- </div>
40
+ </router-link>
39
41
  </template>
40
42
 
41
43
  <script setup>
@@ -40,9 +40,9 @@
40
40
 
41
41
  <div class="track-info">
42
42
  <div class="track-name " :class="{'t-main': isPlaying(track)}">
43
- <router-link
43
+ <router-link
44
44
  v-if="track.url"
45
- :to="{ name: 'track', params: { url: track.url } }"
45
+ :to="'/music/tracks/' + track.url"
46
46
  class="hover-t-main hover-t-underline"
47
47
  :class="{'t-main': isPlaying(track)}"
48
48
  @click.stop
@@ -52,9 +52,9 @@
52
52
  <span v-else>{{ track.title }}</span>
53
53
  </div>
54
54
  <div :class="{'t-main': isPlaying(track)}" class="track-artist t-transp t-small">
55
- <router-link
55
+ <router-link
56
56
  v-if="track.artist && track.artist._id"
57
- :to="{ name: 'artist', params: { url: track.artist.url } }"
57
+ :to="'/music/artists/' + track.artist.url"
58
58
  class="t-transp hover-t-underline"
59
59
  @click.stop
60
60
  >
@@ -66,9 +66,9 @@
66
66
  </div>
67
67
 
68
68
  <div v-if="showAlbum" class="track-album w-15r mobile:w-0 mobile:hidden t-transp t-truncate">
69
- <router-link
69
+ <router-link
70
70
  v-if="track.album && track.album._id"
71
- :to="{ name: 'album', params: { url: track.album.url } }"
71
+ :to="'/music/albums/' + track.album.url"
72
72
  class="t-transp hover-t-underline"
73
73
  @click.stop
74
74
  >
@@ -1,17 +1,107 @@
1
1
  <!-- components/layouts/MusicBottomPlayer.vue -->
2
2
  <template>
3
- <MusicPlayer v-if="currentTrack" class="pos-absolute pos-b-0 w-100" />
3
+ <div>
4
+ <MusicPlayer v-if="currentTrack && !showFullPlayer" class="pos-absolute pos-b-0 w-100" />
5
+
6
+ <BottomSheet
7
+ v-if="showFullPlayer"
8
+ :show="showFullPlayer"
9
+ @toggle="playerActions.toggleFullPlayer()"
10
+ >
11
+ <FullscreenPlayer />
12
+ </BottomSheet>
13
+ </div>
4
14
  </template>
5
15
 
6
16
  <script setup>
7
- import { computed } from 'vue';
17
+ import { computed, watch } from 'vue';
18
+ import { useRoute } from 'vue-router';
8
19
  import MusicPlayer from '../player/MusicPlayer.vue';
20
+ import FullscreenPlayer from '../player/FullscreenPlayer.vue';
21
+ import BottomSheet from '@martyrs/src/components/BottomSheet/BottomSheet.vue';
9
22
 
10
23
  // Import store modules
11
- import { state as playerState } from '../../store/player.js';
24
+ import { state as playerState, actions as playerActions } from '../../store/player.js';
25
+
26
+ const route = useRoute();
12
27
 
13
28
  // Current track from player store
14
29
  const currentTrack = computed(() => {
15
30
  return playerState.currentTrack;
16
31
  });
17
- </script>
32
+
33
+ // Fullscreen player state
34
+ const showFullPlayer = computed(() => {
35
+ return playerState.showFullPlayer;
36
+ });
37
+
38
+ // Close fullscreen player on route change
39
+ watch(() => route.path, () => {
40
+ if (playerState.showFullPlayer) {
41
+ playerActions.toggleFullPlayer();
42
+ }
43
+ });
44
+ </script>
45
+
46
+ <style>
47
+ /* Shared control button styles for both players */
48
+ .control-btn {
49
+ background: none;
50
+ border: none;
51
+ color: rgb(var(--grey));
52
+ cursor: pointer;
53
+ padding: 8px;
54
+ border-radius: 50%;
55
+ transition: all 0.2s ease;
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: center;
59
+ }
60
+
61
+ .control-icon {
62
+ width: 16px;
63
+ height: 16px;
64
+ }
65
+
66
+ .control-btn.primary {
67
+ background: rgb(var(--second));
68
+ color: rgb(var(--white));
69
+ width: 32px;
70
+ height: 32px;
71
+ }
72
+
73
+ .play-icon {
74
+ width: 14px;
75
+ height: 14px;
76
+ fill: rgb(var(--white));
77
+ }
78
+
79
+ .control-btn.primary:hover {
80
+ background: rgb(var(--second));
81
+ transform: scale(1.06);
82
+ }
83
+
84
+ .control-btn.secondary:hover {
85
+ color: rgb(var(--white));
86
+ background: rgba(var(--black),0.1);
87
+ }
88
+
89
+ .control-btn.secondary:hover .control-icon {
90
+ fill: rgb(var(--white));
91
+ }
92
+
93
+ .control-btn.active {
94
+ color: rgb(var(--main));
95
+ background: rgba(var(--second),0.1);
96
+ }
97
+
98
+ .control-btn.active .control-icon {
99
+ fill: rgb(var(--main));
100
+ }
101
+
102
+ .control-btn.active:hover {
103
+ color: rgb(var(--main));
104
+ opacity: 0.8;
105
+ background: rgba(var(--second),0.2);
106
+ }
107
+ </style>
@@ -13,14 +13,14 @@
13
13
  </div>
14
14
 
15
15
  <!-- Album Content -->
16
- <div v-if="album" class="album-content cols-2-fit-content mobile:cols-1 gap-big">
16
+ <div v-if="album" class="album-content cols-2 mobile:cols-1 gap-big">
17
17
  <!-- Left Column - Cover & Stats -->
18
18
  <div class="pos-sticky pos-t-0 mobile:pos-relative album-cover-section">
19
19
  <!-- Cover -->
20
20
  <Media
21
21
  :url="album.coverArt || '/logo/logo-placeholder.jpg'"
22
22
  :alt="album.title"
23
- class="aspect-1x1 w-100 w-max-30r mn-b-small radius-medium o-hidden"
23
+ class="aspect-1x1 w-100 mn-b-small radius-medium o-hidden"
24
24
  />
25
25
  <!-- Quick Stats -->
26
26
  <div class="stats-grid grid cols-2 gap-small">
@@ -51,67 +51,7 @@
51
51
  <h1 class="h1 mn-b-medium">{{ album.title }}</h1>
52
52
 
53
53
  <!-- Action Buttons -->
54
- <div class="flex gap-small mn-b-medium">
55
- <Button
56
- @click="playAlbum"
57
- color="primary"
58
- size="medium"
59
- class="flex-1 t-white bg-black radius-thin flex-center gap-thin"
60
- >
61
- <IconPlay fill="rgb(var(--white))" class="i-medium" />
62
- Play All
63
- </Button>
64
-
65
- <Button
66
- @click="shufflePlay"
67
- color="primary"
68
- size="medium"
69
- class="flex-1 bg-light radius-thin flex-center gap-thin"
70
- >
71
- <IconShuffle class="i-medium" />
72
- Shuffle
73
- </Button>
74
-
75
- <Button
76
- @click="toggleFavorite"
77
- color="primary"
78
- size="medium"
79
- class="flex-1 bg-light radius-thin flex-center gap-thin"
80
- >
81
- <IconLike class="i-medium" :fill="isFavorite ? 'rgb(var(--main)':'rgb(var(--black)'" />
82
- {{isFavorite ? 'Liked' : 'Like'}}
83
- </Button>
84
-
85
- <Dropdown :label="{component: IconEllipsis, class: 'bg-light radius-thin pd-thin i-big' }" v-model="showDropdown" class="relative">
86
- <template #trigger>
87
- <Button color="transp" size="medium" class="w-3r h-3r radius-full">
88
- <IconEllipsis class="w-1-25r h-1-25r" />
89
- </Button>
90
- </template>
91
- <template #default>
92
- <div class="dropdown-menu bg-white pd-small radius-medium shadow-big mn-t-thin">
93
- <Button @click="addToQueue" color="transp" size="small" class="w-100 justify-start">
94
- Add to Queue
95
- </Button>
96
- <Button @click="copyLink" color="transp" size="small" class="w-100 justify-start">
97
- Copy Link
98
- </Button>
99
- <Button @click="addToPlaylist" color="transp" size="small" class="w-100 justify-start">
100
- Add to Playlist
101
- </Button>
102
- <template v-if="isOwner">
103
- <hr class="mn-v-thin border-dark-transp-10" />
104
- <Button @click="editAlbum" color="transp" size="small" class="w-100 justify-start">
105
- Edit Album
106
- </Button>
107
- <Button @click="deleteAlbum" color="danger" size="small" class="w-100 justify-start">
108
- Delete Album
109
- </Button>
110
- </template>
111
- </div>
112
- </template>
113
- </Dropdown>
114
- </div>
54
+ <ActionButtons :buttons="actionButtons" />
115
55
 
116
56
  <!-- Artists Cards -->
117
57
  <div class="artists-section mn-b-medium">
@@ -239,7 +179,7 @@
239
179
  <div class="flex flex-nowrap gap-small o-x-scroll overscroll-behavior-x-contain scroll-behavior-smooth scroll-snap-type-x-mandatory scroll-hide"
240
180
  >
241
181
  <li v-for="relatedAlbum in moreAlbums" :key="album._id" class="flex-none scroll-snap-align-start">
242
- <AlbumCard :album="relatedAlbum" class="w-min-15r transition-cubic-in-out" />
182
+ <AlbumCard :album="relatedAlbum" class="w-15r transition-cubic-in-out" />
243
183
  </li>
244
184
  </div>
245
185
  </section>
@@ -267,6 +207,7 @@ import IconDisc from '@martyrs/src/modules/icons/entities/IconMusic.vue';
267
207
  import IconVerified from '@martyrs/src/modules/icons/navigation/IconCheckmark.vue';
268
208
 
269
209
  // Components
210
+ import ActionButtons from '../blocks/ActionButtons.vue';
270
211
  import TrackListCard from '../cards/TrackListCard.vue';
271
212
  import AlbumCard from '../cards/AlbumCard.vue';
272
213
  import ArtistCardSmall from '../cards/ArtistCardSmall.vue';
@@ -285,7 +226,6 @@ const emits = defineEmits(['page-loading', 'page-loaded']);
285
226
  // State
286
227
  const hasLoaded = ref(false);
287
228
  const isFavorite = ref(false);
288
- const showDropdown = ref(false);
289
229
  const followedArtists = ref([]);
290
230
  const moreAlbums = ref([]);
291
231
 
@@ -307,6 +247,51 @@ const totalDuration = computed(() => {
307
247
  return formatDuration(totalSeconds);
308
248
  });
309
249
 
250
+ const actionButtons = computed(() => {
251
+ const buttons = [
252
+ {
253
+ type: 'button',
254
+ class: 't-white bg-black',
255
+ icon: IconPlay,
256
+ iconFill: 'rgb(var(--white))',
257
+ text: 'Play All',
258
+ action: playAlbum
259
+ },
260
+ {
261
+ type: 'button',
262
+ class: 'bg-light',
263
+ icon: IconShuffle,
264
+ text: 'Shuffle',
265
+ action: shufflePlay
266
+ },
267
+ {
268
+ type: 'button',
269
+ class: 'bg-light',
270
+ icon: IconLike,
271
+ iconFill: isFavorite.value ? 'rgb(var(--main))' : 'rgb(var(--black))',
272
+ text: isFavorite.value ? 'Liked' : 'Like',
273
+ action: toggleFavorite
274
+ },
275
+ {
276
+ type: 'dropdown',
277
+ items: [
278
+ { text: 'Add to Queue', action: addToQueue },
279
+ { text: 'Copy Link', action: copyLink },
280
+ { text: 'Add to Playlist', action: addToPlaylist }
281
+ ]
282
+ }
283
+ ];
284
+
285
+ if (isOwner.value) {
286
+ const items = buttons[3].items;
287
+ items.push({ separator: true });
288
+ items.push({ text: 'Edit Album', action: editAlbum });
289
+ items.push({ text: 'Delete Album', action: deleteAlbum, color: 'danger' });
290
+ }
291
+
292
+ return buttons;
293
+ });
294
+
310
295
  // Format helpers
311
296
  const formatDate = (dateString) => {
312
297
  if (!dateString) return 'Unknown';
@@ -373,10 +358,14 @@ const addToQueue = () => {
373
358
  albumTracks.value.forEach(track => {
374
359
  playerActions.addToQueue(track);
375
360
  });
376
- showDropdown.value = false;
377
361
  }
378
362
  };
379
363
 
364
+ const addToPlaylist = () => {
365
+ // TODO: Implement add to playlist
366
+ console.log('Add album to playlist');
367
+ };
368
+
380
369
  const editAlbum = () => {
381
370
  router.push({ name: 'album-edit', params: { url: album.value.url } });
382
371
  };
@@ -394,7 +383,6 @@ const deleteAlbum = async () => {
394
383
 
395
384
  const copyLink = () => {
396
385
  navigator.clipboard.writeText(window.location.href);
397
- showDropdown.value = false;
398
386
  };
399
387
 
400
388
  // Data fetching
@@ -41,7 +41,7 @@
41
41
  class="flex flex-nowrap gap-small o-x-scroll overscroll-behavior-x-contain scroll-behavior-smooth scroll-snap-type-x-mandatory scroll-hide"
42
42
  >
43
43
  <li v-for="album in items" :key="album._id" class="flex-none scroll-snap-align-start">
44
- <AlbumCard :album="album" class="w-min-15r transition-cubic-in-out" />
44
+ <AlbumCard :album="album" class="w-15r transition-cubic-in-out" />
45
45
  </li>
46
46
 
47
47
  </Feed>
@@ -79,9 +79,9 @@
79
79
  horizontal: true
80
80
  }"
81
81
  v-slot="{ items }"
82
- class="gap-zero"
82
+ class="gap-zero bg-light radius-medium o-hidden"
83
83
  >
84
- <div class="bg-light radius-medium o-hidden">
84
+ <div class="">
85
85
  <TrackListCard
86
86
  v-for="(track, index) in items"
87
87
  :key="track._id"
@@ -169,9 +169,7 @@
169
169
  v-slot="{ items }"
170
170
  class="cols-6 mobile:cols-3 gap-small"
171
171
  >
172
- <li class="flex-child-default w-100" v-for="artist in items" :key="artist._id">
173
- <ArtistCard :artist="artist" class="hover-scale-1 flex-child-default transition-cubic-in-out" />
174
- </li>
172
+ <ArtistCard v-for="artist in items" :key="artist._id" :artist="artist" class="hover-scale-1 transition-cubic-in-out" />
175
173
  </Feed>
176
174
  </section>
177
175
  </div>