@ozdao/martyrs 0.2.565 → 0.2.566

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 (99) hide show
  1. package/dist/martyrs/dist/main-B9o1iBAZ.js +943 -0
  2. package/dist/martyrs/dist/main-B9o1iBAZ.js.map +1 -0
  3. package/dist/martyrs/dist/web-BF3ijvEr.js +55 -0
  4. package/dist/martyrs/dist/web-BF3ijvEr.js.map +1 -0
  5. package/dist/martyrs/src/components/BottomSheet/BottomSheet.vue.js +96 -0
  6. package/dist/martyrs/src/components/BottomSheet/BottomSheet.vue.js.map +1 -0
  7. package/dist/martyrs/src/modules/core/views/components/layouts/App.vue.js +1 -1
  8. package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js +1 -0
  9. package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js.map +1 -1
  10. package/dist/martyrs/src/modules/core/views/components/sections/Walkthrough.vue.js +1 -1
  11. package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.js +1 -1
  12. package/dist/martyrs/src/modules/events/events.client.js +15 -12
  13. package/dist/martyrs/src/modules/events/events.client.js.map +1 -1
  14. package/dist/martyrs/src/modules/music/components/blocks/ActionButtons.vue.js +95 -0
  15. package/dist/martyrs/src/modules/music/components/blocks/ActionButtons.vue.js.map +1 -0
  16. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js +5 -2
  17. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js.map +1 -1
  18. package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js +24 -24
  19. package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js.map +1 -1
  20. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js +31 -6
  21. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js.map +1 -1
  22. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +120 -205
  23. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js.map +1 -1
  24. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js +9 -13
  25. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js.map +1 -1
  26. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +166 -245
  27. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js.map +1 -1
  28. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +135 -220
  29. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js.map +1 -1
  30. package/dist/martyrs/src/modules/music/components/player/FullscreenPlayer.vue.js +171 -0
  31. package/dist/martyrs/src/modules/music/components/player/FullscreenPlayer.vue.js.map +1 -0
  32. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js +31 -153
  33. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js.map +1 -1
  34. package/dist/martyrs/src/modules/music/components/player/PlayerControls.vue.js +96 -0
  35. package/dist/martyrs/src/modules/music/components/player/PlayerControls.vue.js.map +1 -0
  36. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js +55 -27
  37. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js.map +1 -1
  38. package/dist/martyrs/src/modules/music/components/player/tonar.png.js +5 -0
  39. package/dist/martyrs/src/modules/music/components/player/tonar.png.js.map +1 -0
  40. package/dist/martyrs/src/modules/music/store/albums.js +8 -2
  41. package/dist/martyrs/src/modules/music/store/albums.js.map +1 -1
  42. package/dist/martyrs/src/modules/music/store/player.js +83 -65
  43. package/dist/martyrs/src/modules/music/store/player.js.map +1 -1
  44. package/dist/martyrs/src/modules/music/store/tracks.js +4 -13
  45. package/dist/martyrs/src/modules/music/store/tracks.js.map +1 -1
  46. package/dist/martyrs/src/modules/notifications/notifications.client.js +2 -2
  47. package/dist/martyrs.css +1 -1
  48. package/dist/music.server.js +33 -6
  49. 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
  50. 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
  51. 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
  52. 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
  53. 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
  54. 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
  55. package/dist/node_modules/.pnpm/{@capacitor_core@7.0.1 → @capacitor_core@7.4.4}/node_modules/@capacitor/core/dist/index.js +2 -1
  56. package/dist/node_modules/.pnpm/@capacitor_core@7.4.4/node_modules/@capacitor/core/dist/index.js.map +1 -0
  57. 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
  58. 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
  59. 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
  60. 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
  61. 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
  62. 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
  63. 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
  64. 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
  65. 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
  66. 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
  67. 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
  68. 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
  69. 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
  70. package/dist/style.css +214 -138
  71. package/package.json +1 -1
  72. package/src/components/BottomSheet/BottomSheet.vue +4 -4
  73. package/src/modules/LAYOUT.MD +767 -0
  74. package/src/modules/core/views/components/layouts/Client.vue +1 -1
  75. package/src/modules/events/events.client.js +3 -0
  76. package/src/modules/music/components/blocks/ActionButtons.vue +74 -0
  77. package/src/modules/music/components/cards/AlbumCard.vue +1 -1
  78. package/src/modules/music/components/cards/ArtistCardSmall.vue +8 -6
  79. package/src/modules/music/components/layouts/MusicBottomPlayer.vue +94 -4
  80. package/src/modules/music/components/pages/Album.vue +55 -67
  81. package/src/modules/music/components/pages/MusicHome.vue +4 -6
  82. package/src/modules/music/components/pages/Playlist.vue +61 -70
  83. package/src/modules/music/components/pages/Track.vue +54 -71
  84. package/src/modules/music/components/player/FullscreenPlayer.vue +248 -0
  85. package/src/modules/music/components/player/MusicPlayer.vue +21 -216
  86. package/src/modules/music/components/player/PlayerControls.vue +112 -0
  87. package/src/modules/music/components/player/Visualizer.vue +151 -0
  88. package/src/modules/music/components/player/VolumeControl.vue +75 -23
  89. package/src/modules/music/components/player/tonar.png +0 -0
  90. package/src/modules/music/routes/albums.routes.js +13 -12
  91. package/src/modules/music/routes/tracks.routes.js +39 -0
  92. package/src/modules/music/store/albums.js +10 -2
  93. package/src/modules/music/store/player.js +101 -89
  94. package/src/modules/music/store/tracks.js +5 -21
  95. package/src/styles/config.scss +6 -6
  96. 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
  97. 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
  98. package/dist/node_modules/.pnpm/@capacitor_core@7.0.1/node_modules/@capacitor/core/dist/index.js.map +0 -1
  99. /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
@@ -13,7 +13,7 @@
13
13
  </div>
14
14
 
15
15
  <!-- Track Content -->
16
- <div v-if="track" class="track-content cols-2-fit-content mobile:cols-1 gap-big">
16
+ <div v-if="track" class="track-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 track-cover-section">
19
19
  <!-- Cover with Play Overlay -->
@@ -62,78 +62,18 @@
62
62
  <!-- Track Title -->
63
63
  <h1 class="h1 mn-b-medium">{{ track.title }}</h1>
64
64
  <!-- Action Buttons -->
65
- <div class="flex gap-small mn-b-medium">
66
- <Button
67
- @click="playTrack"
68
- color="primary"
69
- size="medium"
70
- class="flex-1 t-white bg-black radius-thin flex-center gap-thin"
71
- >
72
- <IconPlay v-if="!isPlaying" fill="rgb(var(--white))" class="i-medium" />
73
- <IconPause v-else fill="rgb(var(--white))" class="i-medium" />
74
- {{ !isPlaying ? 'Play' : 'Pause'}}
75
- </Button>
76
-
77
- <Button
78
- @click="addToQueue"
79
- color="primary"
80
- size="medium"
81
- class="flex-1 bg-light radius-thin flex-center gap-thin"
82
- >
83
- <IconAdd class="i-medium" />
84
- Add to Queue
85
- </Button>
86
-
87
- <Button
88
- @click="toggleFavorite"
89
- color="primary"
90
- size="medium"
91
- class="flex-1 bg-light radius-thin flex-center gap-thin"
92
- >
93
- <IconLike class="i-medium" :fill="isFavorite ? 'rgb(var(--main)':'rgb(var(--black)'" />
94
- {{isFavorite ? 'Liked' : 'Like'}}
95
- </Button>
96
-
97
- <Dropdown :label="{component: IconEllipsis, class: 'bg-light radius-thin pd-thin i-big' }" v-model="showDropdown" class="relative">
98
- <template #trigger>
99
- <Button color="transp" size="medium" class="w-3r h-3r radius-full">
100
- <IconEllipsis class="w-1-25r h-1-25r" />
101
- </Button>
102
- </template>
103
- <template #default>
104
- <div class="dropdown-menu bg-dark pd-small radius-medium shadow-big mn-t-thin">
105
- <Button @click="showAddToPlaylistModal = true" color="transp" size="small" class="w-100 justify-start">
106
- Add to Playlist
107
- </Button>
108
- <Button @click="copyLink" color="transp" size="small" class="w-100 justify-start">
109
- Copy Link
110
- </Button>
111
- <template v-if="isOwner">
112
- <hr class="mn-v-thin border-dark-transp-10" />
113
- <Button @click="editTrack" color="transp" size="small" class="w-100 justify-start">
114
- Edit Track
115
- </Button>
116
- <Button @click="deleteTrack" color="danger" size="small" class="w-100 justify-start">
117
- Delete Track
118
- </Button>
119
- </template>
120
- </div>
121
- </template>
122
- </Dropdown>
123
- </div>
65
+ <ActionButtons :buttons="actionButtons" />
124
66
 
125
67
  <!-- Artist Card -->
126
68
  <div class="artists-section mn-b-medium">
127
69
  <h3 class="t-medium mn-b-small" v-if="track.artist">Artist</h3>
128
- <div class="flex flex-column gap-small">
129
- <ArtistCardSmall
130
- :key="track.artist._id"
131
- :artist="track.artist"
132
- :is-following="isFollowingArtist"
133
- :show-follow-button="!isOwner"
134
- @toggle-follow="toggleFollowArtist"
135
- />
136
- </div>
70
+ <ArtistCardSmall
71
+ :key="track.artist._id"
72
+ :artist="track.artist"
73
+ :is-following="isFollowingArtist"
74
+ :show-follow-button="!isOwner"
75
+ @toggle-follow="toggleFollowArtist"
76
+ />
137
77
  </div>
138
78
 
139
79
  <!-- Metadata Cards -->
@@ -302,6 +242,7 @@ import IconEye from '@martyrs/src/modules/icons/actions/IconShow.vue';
302
242
  import IconVerified from '@martyrs/src/modules/icons/navigation/IconCheckmark.vue';
303
243
 
304
244
  // Components
245
+ import ActionButtons from '../blocks/ActionButtons.vue';
305
246
  import TrackListCard from '../cards/TrackListCard.vue';
306
247
  import ArtistCardSmall from '../cards/ArtistCardSmall.vue';
307
248
  // import PlaylistSelector from '../forms/PlaylistSelector.vue';
@@ -321,7 +262,6 @@ const emits = defineEmits(['page-loading', 'page-loaded']);
321
262
 
322
263
  // State
323
264
  const hasLoaded = ref(false);
324
- const showDropdown = ref(false);
325
265
  const showAddToPlaylistModal = ref(false);
326
266
  const isFavorite = ref(false);
327
267
  const isFollowingArtist = ref(false);
@@ -338,6 +278,50 @@ const isOwner = computed(() => {
338
278
  return track.value?.owner?.target === authState.user?._id;
339
279
  });
340
280
 
281
+ const actionButtons = computed(() => {
282
+ const buttons = [
283
+ {
284
+ type: 'button',
285
+ class: 't-white bg-black',
286
+ icon: isPlaying.value ? IconPause : IconPlay,
287
+ iconFill: 'rgb(var(--white))',
288
+ text: isPlaying.value ? 'Pause' : 'Play',
289
+ action: playTrack
290
+ },
291
+ {
292
+ type: 'button',
293
+ class: 'bg-light',
294
+ icon: IconAdd,
295
+ text: 'Add to Queue',
296
+ action: addToQueue
297
+ },
298
+ {
299
+ type: 'button',
300
+ class: 'bg-light',
301
+ icon: IconLike,
302
+ iconFill: isFavorite.value ? 'rgb(var(--main))' : 'rgb(var(--black))',
303
+ text: isFavorite.value ? 'Liked' : 'Like',
304
+ action: toggleFavorite
305
+ },
306
+ {
307
+ type: 'dropdown',
308
+ items: [
309
+ { text: 'Add to Playlist', action: () => showAddToPlaylistModal.value = true },
310
+ { text: 'Copy Link', action: copyLink }
311
+ ]
312
+ }
313
+ ];
314
+
315
+ if (isOwner.value) {
316
+ const items = buttons[3].items;
317
+ items.push({ separator: true });
318
+ items.push({ text: 'Edit Track', action: editTrack });
319
+ items.push({ text: 'Delete Track', action: deleteTrack, color: 'danger' });
320
+ }
321
+
322
+ return buttons;
323
+ });
324
+
341
325
  // Format helpers
342
326
  const formatDuration = (seconds) => {
343
327
  if (!seconds) return '0:00';
@@ -410,7 +394,6 @@ const deleteTrack = async () => {
410
394
 
411
395
  const copyLink = () => {
412
396
  navigator.clipboard.writeText(window.location.href);
413
- showDropdown.value = false;
414
397
  };
415
398
 
416
399
  // Data fetching
@@ -0,0 +1,248 @@
1
+ <template>
2
+ <section
3
+ class="o-y-scroll o-x-hidden bg-light pd-small pos-relative z-index-2 t-center t-black w-100 h-100"
4
+ >
5
+
6
+ <div
7
+ class="pos-relative gap-small flex-nowrap flex-column flex-center flex z-index-1"
8
+ >
9
+ <!-- COVER -->
10
+ <div class="mn-b-thin h-max-30r br-2px br-solid br-black-transp-10 radius-extra w-100 pos-relative aspect-1x1 flex-center flex "
11
+ style="
12
+ background: linear-gradient(180deg, #BDBDBD 0%, #D9D9D9 79.69%, #A5A5A5 100%);
13
+ box-shadow: 0 2px 0px 2px #aaaaaa;
14
+ "
15
+ >
16
+
17
+ <div class="pos-relative">
18
+ <div class="radioTonarWrapper" :class="{'activeTonar': playerState.isPlaying}">
19
+ <img
20
+ class="radioTonar z-index-2"
21
+ src="./tonar.png"
22
+ :class="{'playingTonar': playerState.isPlaying}"
23
+ >
24
+ </div>
25
+ <div
26
+ ref="disk"
27
+ :class="['radius-100 rotate-gradient flex-center flex']"
28
+ :style="{
29
+ transform: `rotate(${playerState.rotationAngle}deg)`,
30
+ width: '24rem',
31
+ height: '24rem',
32
+ border: '3px solid var(--black)',
33
+ 'box-shadow': 'rgba(0,0,0,0.5) 0 0 64px 0px'
34
+ }"
35
+ class="pos-relative z-index-1"
36
+ >
37
+ <div
38
+ v-for="i in 11"
39
+ :key="i"
40
+ :style="{
41
+ border: '1px solid rgba(0,0,0,0.25)',
42
+ position: 'absolute',
43
+ width: 23 - i * 1 + 'rem',
44
+ height: 23 - i * 1 + 'rem',
45
+ 'border-radius': '100%',
46
+ 'box-shadow': 'rgb(47 47 47 / 18%) 0px 0px 5px 10px'
47
+ }"
48
+ >
49
+ </div>
50
+
51
+ <div
52
+ :style="{
53
+ width: '10rem',
54
+ height: '10rem',
55
+ backgroundImage: `url('${playerState.currentTrack?.coverUrl || playerState.currentTrack?.album?.coverArt}')`,
56
+ backgroundPosition: 'center center',
57
+ backgroundSize: '106%',
58
+ }"
59
+ class="radius-extra br-solid br-black-transp-10 br-1px"
60
+ >
61
+ </div>
62
+ </div>
63
+
64
+ </div>
65
+
66
+ </div>
67
+
68
+ <!-- NOW PLAYING -->
69
+ <div
70
+ class="pd-thin bg-white radius-medium o-hidden w-100 pos-relative"
71
+ >
72
+ <p class="mn-l-auto mn-b-thin mn-r-auto radius-big pd-thin bg-second w-min">NOW&nbsp;PLAYING</p>
73
+ <!-- SONG -->
74
+ <Marquee
75
+ v-if="playerState.currentTrack"
76
+ class="h2 uppercase mn-b-thin"
77
+ :gradient="true"
78
+ :gradientColor="'rgb(var(--white))'"
79
+ :clone="true"
80
+ gradient-length="10%"
81
+ >
82
+ {{ playerState.currentTrack.title + '\xa0\xa0'}}
83
+ </Marquee>
84
+
85
+ <!-- AUTHOR -->
86
+ <p
87
+ v-if="playerState.currentTrack"
88
+ class="h3 uppercase t-transp"
89
+ >
90
+ {{ playerState.currentTrack.artist?.name || 'Unknown Artist' }}
91
+ </p>
92
+ </div>
93
+
94
+ <!-- LIKES -->
95
+ <div
96
+ class="pd-thin bg-white radius-medium w-100 pos-relative flex flex-v-center gap-thin"
97
+ >
98
+ <div v-if="authState.user" class="flex-nowrap flex gap-thin flex-v-center">
99
+ <IconLike
100
+ @click="toggleLike()"
101
+ :isLiked="isLiked"
102
+ fill="rgb(var(--black))"
103
+ class="i-medium cursor-pointer"
104
+ :class="{'no-events': isLoading}"
105
+ />
106
+ <p class="t-semi h4">{{ isLiked ? 'Liked' : 'Like' }}</p>
107
+ </div>
108
+
109
+ <p class="t-semi h4" :class="{'mn-l-auto': authState.user}">{{ likesCount }} {{ likesCount === 1 ? 'person' : 'people' }} liked</p>
110
+ </div>
111
+
112
+ <!-- CONTROLS -->
113
+ <div
114
+ class="gap-thin flex-center flex-nowrap flex pd-small bg-white radius-medium o-hidden w-100 pos-relative"
115
+ >
116
+ <PlayerControls />
117
+ </div>
118
+
119
+ <!-- VOLUME -->
120
+ <div class="pd-thin bg-white radius-medium w-100 pos-relative">
121
+ <VolumeControl />
122
+ </div>
123
+
124
+
125
+ <!-- QUEUE LIST -->
126
+ <div
127
+ v-if="playerState.queue.length > 0"
128
+ class="mn-b-small bg-white radius-medium o-hidden w-100 pos-relative"
129
+ >
130
+
131
+ <div class="pd-regular w-100 gap-thin flex-nowrap flex flex-v-center">
132
+ <IconEvents :fill="'rgb(var(--black))'" class="t-transp i-medium"/>
133
+ <p class="w-100 t-transp t-left">QUEUE</p>
134
+ </div>
135
+
136
+ <TrackListCard
137
+ v-for="(track, index) in playerState.queue.slice(0, 10)"
138
+ :key="track._id || index"
139
+ :track="track"
140
+ :index="index"
141
+ :showCover="true"
142
+ :showAlbum="false"
143
+ />
144
+
145
+ </div>
146
+
147
+ </div>
148
+
149
+ </section>
150
+ </template>
151
+
152
+ <script setup>
153
+ import { ref, computed, onMounted } from 'vue';
154
+
155
+ import { Text, Tooltip, Marquee } from '@ozdao/martyrs';
156
+ import IconLike from '@martyrs/src/modules/icons/navigation/IconLike.vue';
157
+ import IconEvents from '@martyrs/src/modules/icons/entities/IconEvents.vue';
158
+
159
+ import TrackListCard from '../cards/TrackListCard.vue';
160
+ import VolumeControl from './VolumeControl.vue';
161
+ import PlayerControls from './PlayerControls.vue';
162
+ import { state as playerState, actions as playerActions } from '../../store/player.js';
163
+ import { state as authState } from '@martyrs/src/modules/auth/views/store/auth.js';
164
+
165
+ const isLiked = ref(false);
166
+ const isLoading = ref(false);
167
+ const likesCount = ref(0);
168
+
169
+ async function toggleLike() {
170
+ // TODO: Implement likes integration with community module
171
+ isLiked.value = !isLiked.value;
172
+ likesCount.value += isLiked.value ? 1 : -1;
173
+ }
174
+
175
+ onMounted(() => {
176
+ if ('mediaSession' in navigator) {
177
+ navigator.mediaSession.setActionHandler('pause', () => playerActions.togglePlay());
178
+ navigator.mediaSession.setActionHandler('play', () => playerActions.togglePlay());
179
+ navigator.mediaSession.setActionHandler('stop', () => playerActions.togglePlay());
180
+ navigator.mediaSession.setActionHandler('previoustrack', () => playerActions.playPrevious());
181
+ navigator.mediaSession.setActionHandler('nexttrack', () => playerActions.playNext());
182
+ }
183
+ });
184
+
185
+ </script>
186
+
187
+
188
+ <style lang="scss" scoped>
189
+ .radioTonarWrapper {
190
+ width: 15rem;
191
+ position: absolute;
192
+ z-index: 30;
193
+ transform: rotate(253deg);
194
+ transform-origin: 75% center;
195
+ top: 0;
196
+ right: -2.5rem;
197
+ transition: transform 1s ease-in-out;
198
+ }
199
+
200
+ .radioTonar {
201
+ width: 15rem;
202
+ transform-origin: 75% center;
203
+ }
204
+
205
+ .activeTonar {
206
+ transform: rotate(285deg);
207
+ }
208
+
209
+ .playingTonar {
210
+ animation: playingTonar 2s ease-in-out infinite;
211
+ }
212
+
213
+ @keyframes playingTonar {
214
+ 0%, 100% {
215
+ transform: rotate(0deg);
216
+ }
217
+ 25% {
218
+ transform: rotate(2deg);
219
+ }
220
+ 50% {
221
+ transform: rotate(-2deg);
222
+ }
223
+ }
224
+
225
+ @property --a {
226
+ syntax: '<angle>';
227
+ inherits: false;
228
+ initial-value: 0deg;
229
+ }
230
+
231
+ @property --b {
232
+ syntax: '<angle>';
233
+ inherits: false;
234
+ initial-value: 0deg;
235
+ }
236
+
237
+ .rotate-gradient {
238
+ --a: 0deg;
239
+ --b: 0deg;
240
+ transition: --a 0.5s, --b 0.5s;
241
+
242
+ background:
243
+ conic-gradient(from var(--a), rgba(255, 255, 255, 0.1), rgba(0, 0, 0, 0.33), rgba(255, 255, 255, 0.1)),
244
+ linear-gradient(180deg, rgba(0, 0, 0, 1) 0%, rgba(255, 255, 255, 0.1) 50%, rgba(0, 0, 0, 1) 100%),
245
+ linear-gradient(180deg, #000 0%, rgba(10, 10, 10, 0.00) 100%),
246
+ #000;
247
+ }
248
+ </style>