@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.
- package/dist/martyrs/dist/main-B9o1iBAZ.js +943 -0
- package/dist/martyrs/dist/main-B9o1iBAZ.js.map +1 -0
- package/dist/martyrs/dist/web-BF3ijvEr.js +55 -0
- package/dist/martyrs/dist/web-BF3ijvEr.js.map +1 -0
- package/dist/martyrs/src/components/BottomSheet/BottomSheet.vue.js +96 -0
- package/dist/martyrs/src/components/BottomSheet/BottomSheet.vue.js.map +1 -0
- package/dist/martyrs/src/modules/core/views/components/layouts/App.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js +1 -0
- package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/sections/Walkthrough.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.js +1 -1
- package/dist/martyrs/src/modules/events/events.client.js +15 -12
- package/dist/martyrs/src/modules/events/events.client.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/blocks/ActionButtons.vue.js +95 -0
- package/dist/martyrs/src/modules/music/components/blocks/ActionButtons.vue.js.map +1 -0
- package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js +5 -2
- package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js +24 -24
- package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js +31 -6
- package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +120 -205
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js +9 -13
- package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +166 -245
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +135 -220
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/FullscreenPlayer.vue.js +171 -0
- package/dist/martyrs/src/modules/music/components/player/FullscreenPlayer.vue.js.map +1 -0
- package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js +31 -153
- package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/PlayerControls.vue.js +96 -0
- package/dist/martyrs/src/modules/music/components/player/PlayerControls.vue.js.map +1 -0
- package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js +55 -27
- package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/player/tonar.png.js +5 -0
- package/dist/martyrs/src/modules/music/components/player/tonar.png.js.map +1 -0
- package/dist/martyrs/src/modules/music/store/albums.js +8 -2
- package/dist/martyrs/src/modules/music/store/albums.js.map +1 -1
- package/dist/martyrs/src/modules/music/store/player.js +83 -65
- package/dist/martyrs/src/modules/music/store/player.js.map +1 -1
- package/dist/martyrs/src/modules/music/store/tracks.js +4 -13
- package/dist/martyrs/src/modules/music/store/tracks.js.map +1 -1
- package/dist/martyrs/src/modules/notifications/notifications.client.js +2 -2
- package/dist/martyrs.css +1 -1
- package/dist/music.server.js +33 -6
- 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
- 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
- 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
- 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
- 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
- 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
- package/dist/node_modules/.pnpm/{@capacitor_core@7.0.1 → @capacitor_core@7.4.4}/node_modules/@capacitor/core/dist/index.js +2 -1
- package/dist/node_modules/.pnpm/@capacitor_core@7.4.4/node_modules/@capacitor/core/dist/index.js.map +1 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/dist/style.css +214 -138
- package/package.json +1 -1
- package/src/components/BottomSheet/BottomSheet.vue +4 -4
- package/src/modules/LAYOUT.MD +767 -0
- package/src/modules/core/views/components/layouts/Client.vue +1 -1
- package/src/modules/events/events.client.js +3 -0
- package/src/modules/music/components/blocks/ActionButtons.vue +74 -0
- package/src/modules/music/components/cards/AlbumCard.vue +1 -1
- package/src/modules/music/components/cards/ArtistCardSmall.vue +8 -6
- package/src/modules/music/components/layouts/MusicBottomPlayer.vue +94 -4
- package/src/modules/music/components/pages/Album.vue +55 -67
- package/src/modules/music/components/pages/MusicHome.vue +4 -6
- package/src/modules/music/components/pages/Playlist.vue +61 -70
- package/src/modules/music/components/pages/Track.vue +54 -71
- package/src/modules/music/components/player/FullscreenPlayer.vue +248 -0
- package/src/modules/music/components/player/MusicPlayer.vue +21 -216
- package/src/modules/music/components/player/PlayerControls.vue +112 -0
- package/src/modules/music/components/player/Visualizer.vue +151 -0
- package/src/modules/music/components/player/VolumeControl.vue +75 -23
- package/src/modules/music/components/player/tonar.png +0 -0
- package/src/modules/music/routes/albums.routes.js +13 -12
- package/src/modules/music/routes/tracks.routes.js +39 -0
- package/src/modules/music/store/albums.js +10 -2
- package/src/modules/music/store/player.js +101 -89
- package/src/modules/music/store/tracks.js +5 -21
- package/src/styles/config.scss +6 -6
- 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
- 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
- package/dist/node_modules/.pnpm/@capacitor_core@7.0.1/node_modules/@capacitor/core/dist/index.js.map +0 -1
- /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
|
|
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
|
-
<
|
|
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
|
-
<
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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 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>
|