mirror of
https://github.com/janishutz/MusicPlayerV2.git
synced 2025-11-25 13:04:23 +00:00
lots of progress on client display integration
This commit is contained in:
@@ -26,9 +26,10 @@ let changedStatus = [];
|
|||||||
|
|
||||||
let currentDetails = {
|
let currentDetails = {
|
||||||
'songQueue': [],
|
'songQueue': [],
|
||||||
'currentlyPlaying': '',
|
'playingSong': {},
|
||||||
'pos': 0,
|
'pos': 0,
|
||||||
'isPlaying': false
|
'isPlaying': false,
|
||||||
|
'queuePos': 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let connectedMain = {};
|
let connectedMain = {};
|
||||||
@@ -84,7 +85,7 @@ const sendUpdate = ( update ) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const allowedTypes = [ 'playingSong', 'isPlaying', 'songQueue', 'pos' ];
|
const allowedTypes = [ 'playingSong', 'isPlaying', 'songQueue', 'pos', 'queuePos' ];
|
||||||
app.post( '/statusUpdate', ( req, res ) => {
|
app.post( '/statusUpdate', ( req, res ) => {
|
||||||
if ( allowedTypes.includes( req.body.type ) ) {
|
if ( allowedTypes.includes( req.body.type ) ) {
|
||||||
currentDetails[ req.body.type ] = req.body.data;
|
currentDetails[ req.body.type ] = req.body.data;
|
||||||
@@ -110,8 +111,8 @@ app.get( '/clientStatusUpdate/:status', ( req, res ) => {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
app.get( '/openSongs', ( req, res ) => {
|
app.get( '/openSongs', ( req, res ) => {
|
||||||
res.send( '{ "data": [ "/home/janis/Music/KB2022" ] }' );
|
// res.send( '{ "data": [ "/home/janis/Music/KB2022" ] }' );
|
||||||
// res.send( '{ "data": [ "/mnt/storage/SORTED/Music/audio/KB2022" ] }' );
|
res.send( '{ "data": [ "/mnt/storage/SORTED/Music/audio/KB2022" ] }' );
|
||||||
// res.send( { 'data': dialog.showOpenDialogSync( { properties: [ 'openDirectory' ], title: 'Open music library folder' } ) } );
|
// res.send( { 'data': dialog.showOpenDialogSync( { properties: [ 'openDirectory' ], title: 'Open music library folder' } ) } );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,52 @@
|
|||||||
|
:root, :root.light {
|
||||||
|
--primary-color: #2c3e50;
|
||||||
|
--accent-background: rgb(30, 30, 82);
|
||||||
|
--secondary-color: white;
|
||||||
|
--background-color: white;
|
||||||
|
--popup-color: rgb(224, 224, 224);
|
||||||
|
--accent-color: #42b983;
|
||||||
|
--hover-color: rgb(165, 165, 165);
|
||||||
|
--accent-background-hover: rgb(124, 140, 236);
|
||||||
|
--overlay-color: rgba(0, 0, 0, 0.7);
|
||||||
|
--border-color: rgb(100, 100, 100);
|
||||||
|
--highlight-backdrop: rgb(143, 134, 192);
|
||||||
|
--hint-color: rgb(174, 210, 221);
|
||||||
|
--PI: 3.14159265358979;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.dark {
|
||||||
|
--primary-color: white;
|
||||||
|
--accent-background: rgb(56, 56, 112);
|
||||||
|
--secondary-color: white;
|
||||||
|
--background-color: rgb(32, 32, 32);
|
||||||
|
--popup-color: rgb(58, 58, 58);
|
||||||
|
--accent-color: #42b983;
|
||||||
|
--hover-color: rgb(83, 83, 83);
|
||||||
|
--accent-background-hover: #4380a8;
|
||||||
|
--overlay-color: rgba(104, 104, 104, 0.575);
|
||||||
|
--border-color: rgb(190, 190, 190);
|
||||||
|
--highlight-backdrop: rgb(85, 63, 207);
|
||||||
|
--hint-color: rgb(88, 91, 110);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media ( prefers-color-scheme: dark ) {
|
||||||
|
:root {
|
||||||
|
--primary-color: white;
|
||||||
|
--accent-background: rgb(56, 56, 112);
|
||||||
|
--secondary-color: white;
|
||||||
|
--background-color: rgb(32, 32, 32);
|
||||||
|
--popup-color: rgb(58, 58, 58);
|
||||||
|
--accent-color: #42b983;
|
||||||
|
--hover-color: rgb(83, 83, 83);
|
||||||
|
--accent-background-hover: #4380a8;
|
||||||
|
--overlay-color: rgba(104, 104, 104, 0.575);
|
||||||
|
--border-color: rgb(190, 190, 190);
|
||||||
|
--highlight-backdrop: rgb(85, 63, 207);
|
||||||
|
--hint-color: rgb(88, 91, 110);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.material-symbols-outlined {
|
.material-symbols-outlined {
|
||||||
font-variation-settings:
|
font-variation-settings:
|
||||||
'FILL' 0,
|
'FILL' 0,
|
||||||
@@ -6,89 +55,119 @@
|
|||||||
'opsz' 24
|
'opsz' 24
|
||||||
}
|
}
|
||||||
|
|
||||||
.voting-wrapper {
|
body, html {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playing-symbols {
|
||||||
|
position: absolute;
|
||||||
|
left: 10vw;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 5vw;
|
||||||
|
height: 5vw;
|
||||||
|
background-color: rgba( 0, 0, 0, 0.6 );
|
||||||
|
}
|
||||||
|
|
||||||
|
.playing-symbols-wrapper {
|
||||||
|
width: 4vw;
|
||||||
|
height: 5vw;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
.voting {
|
.playing-bar {
|
||||||
border-radius: 500px;
|
height: 60%;
|
||||||
border: 1px black solid;
|
background-color: white;
|
||||||
font-size: 150%;
|
width: 10%;
|
||||||
cursor: pointer;
|
border-radius: 50px;
|
||||||
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.voting-counter {
|
#bar-1 {
|
||||||
|
animation: music-playing 0.9s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bar-2 {
|
||||||
|
animation: music-playing 0.9s infinite ease-in-out;
|
||||||
|
animation-delay: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bar-3 {
|
||||||
|
animation: music-playing 0.9s infinite ease-in-out;
|
||||||
|
animation-delay: 0.6s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes music-playing {
|
||||||
|
0% {
|
||||||
|
transform: scaleY( 1 );
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scaleY( 0.5 );
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scaleY( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.song-list-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.song-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 80%;
|
||||||
|
margin: 2px;
|
||||||
|
padding: 1vh;
|
||||||
|
border: 1px var( --border-color ) solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.song-details-wrapper {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 150%;
|
display: block;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-right: 10px;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
.song-list .song-image {
|
||||||
display: flex;
|
width: 5vw;
|
||||||
align-items: center;
|
height: 5vw;
|
||||||
justify-content: center;
|
object-fit: cover;
|
||||||
flex-direction: column;
|
object-position: center;
|
||||||
|
font-size: 5vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.pause-icon {
|
||||||
justify-content: flex-start;
|
width: 5vw;
|
||||||
}
|
height: 5vw;
|
||||||
|
object-fit: cover;
|
||||||
.input {
|
object-position: center;
|
||||||
width: 30vw;
|
font-size: 5vw !important;
|
||||||
padding: 20px;
|
user-select: none;
|
||||||
border-radius: 20px;
|
|
||||||
border: none;
|
|
||||||
margin-bottom: 1vh;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry {
|
|
||||||
border: black 2px solid;
|
|
||||||
padding: 1% 10%;
|
|
||||||
width: 40vw;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected {
|
|
||||||
background-color: green;
|
|
||||||
}
|
|
||||||
|
|
||||||
.comment {
|
|
||||||
width: 50%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: 5vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-bar {
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
background-color: lightgray;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 0;
|
|
||||||
padding-top: 0.5vh;
|
|
||||||
padding-bottom: 5vh,
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
display: block !important;
|
|
||||||
}
|
}
|
||||||
@@ -11,8 +11,24 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="content" id="app">
|
<div class="content" id="app">
|
||||||
<div class="wrapper" v-if="hasLoaded">
|
<h1>Ok</h1>
|
||||||
<h1>Ok</h1>
|
<div class="song-list-wrapper" v-if="hasLoaded">
|
||||||
|
<div v-for="song in songQueue" class="song-list">
|
||||||
|
<span class="material-symbols-outlined song-image" v-if="!song.hasCoverArt && ( playingSong.filename !== song.filename || isPlaying )">music_note</span>
|
||||||
|
<img v-else-if="song.hasCoverArt && ( playingSong.filename !== song.filename || isPlaying )" :src="'/getSongCover?filename=' + song.filename" class="song-image">
|
||||||
|
<div v-if="playingSong.filename === song.filename && isPlaying" class="playing-symbols">
|
||||||
|
<div class="playing-symbols-wrapper">
|
||||||
|
<div class="playing-bar" id="bar-1"></div>
|
||||||
|
<div class="playing-bar" id="bar-2"></div>
|
||||||
|
<div class="playing-bar" id="bar-3"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="material-symbols-outlined pause-icon" v-if="!isPlaying && playingSong.filename === song.filename">pause</span>
|
||||||
|
<div class="song-details-wrapper">
|
||||||
|
<h3>{{ song.title }}</h3>
|
||||||
|
<p>{{ song.artist }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- <img :src="" alt=""> -->
|
<!-- <img :src="" alt=""> -->
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
|
|||||||
@@ -5,15 +5,27 @@ createApp( {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
hasLoaded: false,
|
hasLoaded: false,
|
||||||
songs: {},
|
songs: [],
|
||||||
playingSong: {},
|
playingSong: {},
|
||||||
isPlaying: false,
|
isPlaying: false,
|
||||||
|
pos: 0,
|
||||||
|
queuePos: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
songQueue() {
|
||||||
|
let ret = [];
|
||||||
|
for ( let song in this.songs ) {
|
||||||
|
if ( parseInt( song ) >= this.queuePos ) {
|
||||||
|
ret.push( this.songs[ song ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
connect() {
|
connect() {
|
||||||
let source = new EventSource( '/clientDisplayNotifier', { withCredentials: true } );
|
let source = new EventSource( '/clientDisplayNotifier', { withCredentials: true } );
|
||||||
let self = this;
|
|
||||||
|
|
||||||
source.onmessage = ( e ) => {
|
source.onmessage = ( e ) => {
|
||||||
let data;
|
let data;
|
||||||
@@ -23,18 +35,22 @@ createApp( {
|
|||||||
data = { 'type': e.data };
|
data = { 'type': e.data };
|
||||||
}
|
}
|
||||||
if ( data.type === 'basics' ) {
|
if ( data.type === 'basics' ) {
|
||||||
console.log( 'basics' );
|
this.isPlaying = data.data.isPlaying ?? false;
|
||||||
console.log( data.data );
|
this.playingSong = data.data.playingSong ?? {};
|
||||||
|
this.songs = data.data.songQueue ?? [];
|
||||||
|
this.pos = data.data.pos ?? 0;
|
||||||
|
this.queuePos = data.data.queuePos ?? 0;
|
||||||
} else if ( data.type === 'pos' ) {
|
} else if ( data.type === 'pos' ) {
|
||||||
|
this.pos = data.data;
|
||||||
} else if ( data.type === 'isPlaying' ) {
|
} else if ( data.type === 'isPlaying' ) {
|
||||||
|
this.isPlaying = data.data;
|
||||||
} else if ( data.type === 'songQueue' ) {
|
} else if ( data.type === 'songQueue' ) {
|
||||||
|
this.songs = data.data;
|
||||||
} else if ( data.type === 'currentlyPlaying' ) {
|
} else if ( data.type === 'playingSong' ) {
|
||||||
|
this.playingSong = data.data;
|
||||||
|
} else if ( data.type === 'queuePos' ) {
|
||||||
|
this.queuePos = data.data;
|
||||||
}
|
}
|
||||||
console.log( data.data );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
source.onopen = () => {
|
source.onopen = () => {
|
||||||
|
|||||||
@@ -76,7 +76,9 @@
|
|||||||
|
|
||||||
.fancy-view-song-art {
|
.fancy-view-song-art {
|
||||||
height: 40vh;
|
height: 40vh;
|
||||||
width: auto;
|
width: 40vh;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: center;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,12 @@
|
|||||||
<style>
|
<style>
|
||||||
.playing-symbols {
|
.playing-symbols {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 9.95vw;
|
left: 10%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
margin: 0;
|
||||||
width: 5vw;
|
width: 5vw;
|
||||||
height: 5vw;
|
height: 5vw;
|
||||||
background-color: rgba( 0, 0, 0, 0.6 );
|
background-color: rgba( 0, 0, 0, 0.6 );
|
||||||
@@ -56,7 +57,7 @@
|
|||||||
|
|
||||||
.playing-bar {
|
.playing-bar {
|
||||||
height: 60%;
|
height: 60%;
|
||||||
background-color: var( --primary-color );
|
background-color: white;
|
||||||
width: 10%;
|
width: 10%;
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
@@ -226,6 +227,17 @@
|
|||||||
this.$emit( 'com', { 'type': 'pause' } );
|
this.$emit( 'com', { 'type': 'pause' } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let fetchOptions = {
|
||||||
|
method: 'post',
|
||||||
|
body: JSON.stringify( { 'type': 'queuePos', 'data': this.songPos } ),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'charset': 'utf-8'
|
||||||
|
},
|
||||||
|
};
|
||||||
|
fetch( 'http://localhost:8081/statusUpdate', fetchOptions ).catch( err => {
|
||||||
|
console.error( err );
|
||||||
|
} );
|
||||||
} else if ( status.type === 'previous' ) {
|
} else if ( status.type === 'previous' ) {
|
||||||
if ( this.songPos > 0 ) {
|
if ( this.songPos > 0 ) {
|
||||||
this.songPos -= 1;
|
this.songPos -= 1;
|
||||||
@@ -291,6 +303,17 @@
|
|||||||
this.isLoadingSongs = false;
|
this.isLoadingSongs = false;
|
||||||
this.hasLoadedSongs = true;
|
this.hasLoadedSongs = true;
|
||||||
this.$emit( 'com', { 'type': 'songsLoaded' } );
|
this.$emit( 'com', { 'type': 'songsLoaded' } );
|
||||||
|
let fetchOptions = {
|
||||||
|
method: 'post',
|
||||||
|
body: JSON.stringify( { 'type': 'songQueue', 'data': this.songQueue } ),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'charset': 'utf-8'
|
||||||
|
},
|
||||||
|
};
|
||||||
|
fetch( 'http://localhost:8081/statusUpdate', fetchOptions ).catch( err => {
|
||||||
|
console.error( err );
|
||||||
|
} );
|
||||||
} );
|
} );
|
||||||
} else if ( res.status === 404 ) {
|
} else if ( res.status === 404 ) {
|
||||||
this.isLoadingSongs = false;
|
this.isLoadingSongs = false;
|
||||||
@@ -312,6 +335,17 @@
|
|||||||
}
|
}
|
||||||
this.currentlyPlaying = song.filename;
|
this.currentlyPlaying = song.filename;
|
||||||
this.update( { 'type': 'playback', 'status': true } );
|
this.update( { 'type': 'playback', 'status': true } );
|
||||||
|
let fetchOptions = {
|
||||||
|
method: 'post',
|
||||||
|
body: JSON.stringify( { 'type': 'queuePos', 'data': this.songPos } ),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'charset': 'utf-8'
|
||||||
|
},
|
||||||
|
};
|
||||||
|
fetch( 'http://localhost:8081/statusUpdate', fetchOptions ).catch( err => {
|
||||||
|
console.error( err );
|
||||||
|
} );
|
||||||
},
|
},
|
||||||
pause( song ) {
|
pause( song ) {
|
||||||
this.update( { 'type': 'playback', 'status': false } );
|
this.update( { 'type': 'playback', 'status': false } );
|
||||||
|
|||||||
@@ -184,6 +184,8 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
musicPlayer.currentTime = 0;
|
musicPlayer.currentTime = 0;
|
||||||
this.control( 'play' );
|
this.control( 'play' );
|
||||||
|
this.playbackPos = musicPlayer.currentTime;
|
||||||
|
this.sendUpdate( 'pos' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,6 +250,7 @@ export default {
|
|||||||
this.playbackPosBeautified += secondCount;
|
this.playbackPosBeautified += secondCount;
|
||||||
}
|
}
|
||||||
}, 0.02 );
|
}, 0.02 );
|
||||||
|
this.sendUpdate( 'isPlaying' );
|
||||||
} else if ( action === 'pause' ) {
|
} else if ( action === 'pause' ) {
|
||||||
this.$emit( 'update', { 'type': 'playback', 'status': false } );
|
this.$emit( 'update', { 'type': 'playback', 'status': false } );
|
||||||
musicPlayer.pause();
|
musicPlayer.pause();
|
||||||
@@ -255,8 +258,11 @@ export default {
|
|||||||
clearInterval( this.progressTracker );
|
clearInterval( this.progressTracker );
|
||||||
} catch ( err ) {};
|
} catch ( err ) {};
|
||||||
this.isPlaying = false;
|
this.isPlaying = false;
|
||||||
|
this.sendUpdate( 'isPlaying' );
|
||||||
} else if ( action === 'replay10' ) {
|
} else if ( action === 'replay10' ) {
|
||||||
musicPlayer.currentTime = musicPlayer.currentTime > 10 ? musicPlayer.currentTime - 10 : 0;
|
musicPlayer.currentTime = musicPlayer.currentTime > 10 ? musicPlayer.currentTime - 10 : 0;
|
||||||
|
this.playbackPos = musicPlayer.currentTime;
|
||||||
|
this.sendUpdate( 'pos' );
|
||||||
} else if ( action === 'forward10' ) {
|
} else if ( action === 'forward10' ) {
|
||||||
if ( musicPlayer.currentTime < ( musicPlayer.duration - 10 ) ) {
|
if ( musicPlayer.currentTime < ( musicPlayer.duration - 10 ) ) {
|
||||||
musicPlayer.currentTime = musicPlayer.currentTime + 10;
|
musicPlayer.currentTime = musicPlayer.currentTime + 10;
|
||||||
@@ -265,6 +271,8 @@ export default {
|
|||||||
this.control( 'next' );
|
this.control( 'next' );
|
||||||
} else {
|
} else {
|
||||||
musicPlayer.currentTime = 0;
|
musicPlayer.currentTime = 0;
|
||||||
|
this.playbackPos = musicPlayer.currentTime;
|
||||||
|
this.sendUpdate( 'pos' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ( action === 'reset' ) {
|
} else if ( action === 'reset' ) {
|
||||||
|
|||||||
Reference in New Issue
Block a user