mirror of
https://github.com/janishutz/MusicPlayerV2.git
synced 2025-11-25 21:14:22 +00:00
basically done
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="isShowingWarning" class="warning">
|
||||
<h3>WARNING!</h3>
|
||||
<p>A client display is being tampered with!</p>
|
||||
<p>A desktop notification with a warning has already been dispatched.</p>
|
||||
<button @click="dismissNotification()">Ok</button>
|
||||
|
||||
<div class="flash"></div>
|
||||
</div>
|
||||
<div class="player">
|
||||
<div :class="'main-player' + ( isShowingFullScreenPlayer ? ' full-screen' : '' )">
|
||||
<div :class="'song-name-wrapper' + ( isShowingFullScreenPlayer ? ' full-screen' : '' )" @click="controlUI( 'show' )">
|
||||
@@ -100,6 +108,7 @@
|
||||
const isConnectedToNotifier = ref( false );
|
||||
const popup = ref( popupModule );
|
||||
const roomName = ref( '' );
|
||||
const isShowingWarning = ref( false );
|
||||
let currentlyOpenPopup = '';
|
||||
|
||||
const emits = defineEmits( [ 'playerStateChange' ] );
|
||||
@@ -194,12 +203,17 @@
|
||||
popup.value.openPopup( {
|
||||
title: 'Define a share name',
|
||||
popupType: 'input',
|
||||
subtitle: 'A share allows others to join your playlist and see the current song, the playback position and the upcoming songs. You can get the link to the page, once the share is set up. Please choose a name, which will then be part of the URL with which others can join the share',
|
||||
subtitle: 'A share allows others to join your playlist and see the current song, the playback position and the upcoming songs. You can get the link to the page, once the share is set up. Please choose a name, which will then be part of the URL with which others can join the share. The anti tamper feature notifies you, whenever a user leaves the fancy view.',
|
||||
data: [
|
||||
{
|
||||
name: 'Share Name',
|
||||
dataType: 'text',
|
||||
id: 'roomName'
|
||||
},
|
||||
{
|
||||
name: 'Use Anti-Tamper?',
|
||||
dataType: 'checkbox',
|
||||
id: 'useAntiTamper'
|
||||
}
|
||||
]
|
||||
} );
|
||||
@@ -377,7 +391,6 @@
|
||||
if ( pos.value > 0 && !hasStarted ) {
|
||||
getDetails();
|
||||
playingSong = player.getPlayingSong();
|
||||
console.log( pos.value );
|
||||
prepNiceDurationTime( playingSong );
|
||||
notificationHandler.emit( 'playlist-index-update', currentlyPlayingSongIndex.value );
|
||||
notificationHandler.emit( 'playback-update', isPlaying.value );
|
||||
@@ -472,8 +485,8 @@
|
||||
player.prepare( 0 );
|
||||
isPlaying.value = true;
|
||||
startProgressTracker();
|
||||
notificationHandler.emit( 'playlist-update', playlist.value );
|
||||
}
|
||||
notificationHandler.emit( 'playlist-update', playlist.value );
|
||||
}
|
||||
|
||||
emits( 'playerStateChange', isShowingFullScreenPlayer.value ? 'show' : 'hide' );
|
||||
@@ -495,9 +508,13 @@
|
||||
}
|
||||
} );
|
||||
|
||||
const dismissNotification = () => {
|
||||
isShowingWarning.value = false;
|
||||
}
|
||||
|
||||
const popupReturnHandler = ( data: any ) => {
|
||||
if ( currentlyOpenPopup === 'create-share' ) {
|
||||
notificationHandler.connect( data.roomName ).then( () => {
|
||||
notificationHandler.connect( data.roomName, data.useAntiTamper ?? false ).then( () => {
|
||||
roomName.value = notificationHandler.getRoomName();
|
||||
isConnectedToNotifier.value = true;
|
||||
notificationHandler.emit( 'playlist-index-update', currentlyPlayingSongIndex.value );
|
||||
@@ -505,6 +522,10 @@
|
||||
notificationHandler.emit( 'playback-start-update', new Date().getTime() - pos.value * 1000 );
|
||||
notificationHandler.emit( 'playlist-update', playlist.value );
|
||||
notifications.value.createNotification( 'Joined share "' + data.roomName + '"!', 5, 'ok', 'normal' );
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
notificationHandler.registerListener( 'tampering-msg', ( _ ) => {
|
||||
isShowingWarning.value = true;
|
||||
} );
|
||||
} ).catch( e => {
|
||||
if ( e === 'ERR_CONFLICT' ) {
|
||||
notifications.value.createNotification( 'A share with this name exists already!', 5, 'error', 'normal' );
|
||||
@@ -517,6 +538,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener( 'beforeunload', () => {
|
||||
notificationHandler.disconnect();
|
||||
} );
|
||||
|
||||
defineExpose( {
|
||||
logIntoAppleMusic,
|
||||
getPlaylists,
|
||||
@@ -764,4 +789,49 @@
|
||||
position: fixed;
|
||||
bottom: -50%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
.warning {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 40vw;
|
||||
height: 50vh;
|
||||
font-size: 2vh;
|
||||
background-color: rgb(255, 0, 0);
|
||||
color: white;
|
||||
position: fixed;
|
||||
right: 1vh;
|
||||
top: 1vh;
|
||||
flex-direction: column;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.warning h3 {
|
||||
font-size: 4vh;
|
||||
}
|
||||
|
||||
.warning .flash {
|
||||
background-color: rgba(255, 0, 0, 0.4);
|
||||
animation: flashing linear infinite 1s;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
@keyframes flashing {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -6,7 +6,9 @@
|
||||
<button @click="openSearch()" v-if="$props.isLoggedIntoAppleMusic" class="small-buttons" title="Search Apple Music for the song"><span class="material-symbols-outlined">search</span></button>
|
||||
<p v-if="!hasSelectedSongs">Please select at least one song to proceed</p>
|
||||
<div class="playlist-box" id="pl-box">
|
||||
<!-- TODO: Allow adding more songs with search on Apple Music or loading from local disk -->
|
||||
<!-- TODO: Allow editing additionalInfo. Think also how to make it persist over reloads... Export to JSON and then best-guess add them? Very easy for Apple Music 'cause ID, but how for local songs? -->
|
||||
<!-- TODO: Allow deleting songs, as well as whole playlist -->
|
||||
<!-- TODO: Handle long AppleMusic Playlists, as AppleMusic doesn't automatically load all songs of a playlist -->
|
||||
<div class="song" v-for="song in computedPlaylist" v-bind:key="song.id"
|
||||
:class="( song.id === ( $props.playlist ? $props.playlist [ $props.currentlyPlaying ?? 0 ].id : '' ) && isPlaying ? 'playing' : ' not-playing' )
|
||||
+ ( ( !isPlaying && ( song.id === ( $props.playlist ? $props.playlist [ $props.currentlyPlaying ?? 0 ].id : '' ) ) ) ? ' active-song' : '' )">
|
||||
@@ -186,7 +188,7 @@
|
||||
|
||||
<style scoped>
|
||||
.playlist-box {
|
||||
height: calc( 100% - 100px );
|
||||
height: calc( 100% - 150px );
|
||||
width: 100%;
|
||||
overflow-y: scroll;
|
||||
display: flex;
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
|
||||
const closePopupReturn = () => {
|
||||
for ( let el in popupContent.value.data ) {
|
||||
if ( !data.value[ popupContent.value.data[ parseInt( el ) ].id ] ) {
|
||||
if ( !data.value[ popupContent.value.data[ parseInt( el ) ].id ] && popupContent.value.data[ parseInt( el ) ].dataType !== 'checkbox' ) {
|
||||
isShowingIncomplete.value = true;
|
||||
return;
|
||||
}
|
||||
@@ -150,6 +150,11 @@
|
||||
}
|
||||
isShowingPopup.value = true;
|
||||
popupContent.value = popupConfig;
|
||||
for ( const el in popupContent.value.data ) {
|
||||
if ( popupContent.value.data[ parseInt( el ) ].dataType === 'checkbox' ) {
|
||||
data.value[ popupContent.value.data[ parseInt( el ) ].id ] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose( {
|
||||
|
||||
Reference in New Issue
Block a user