mirror of
https://github.com/janishutz/MusicPlayer.git
synced 2026-09-10 14:25:24 +02:00
feat: basic player component
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
<script setup lang="ts">
|
||||
import ProgressBar from './ProgressBar.vue';
|
||||
import {
|
||||
beautifyTime
|
||||
} from '@/ts/util/time';
|
||||
import player from '@/ts/player';
|
||||
|
||||
const playbackPercentage = player.playbackPercentage;
|
||||
const duration = player.duration;
|
||||
const repeatMode = player.repeat;
|
||||
const shuffleMode = player.shuffle;
|
||||
|
||||
const seek = () => {
|
||||
player.seekTo( playbackPercentage.value );
|
||||
};
|
||||
|
||||
const toggleRepeatMode = () => {
|
||||
switch ( repeatMode.value ) {
|
||||
case 'one':
|
||||
player.setRepeat( 'all' );
|
||||
break;
|
||||
case 'off':
|
||||
player.setRepeat( 'one' );
|
||||
break;
|
||||
case 'all':
|
||||
player.setRepeat( 'off' );
|
||||
}
|
||||
};
|
||||
|
||||
const openShareMenu = () => {
|
||||
alert( 'Share menu not yet implemented' );
|
||||
};
|
||||
|
||||
// TODO: Button availability
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mp-player">
|
||||
<div class="controls">
|
||||
<i class="fa-solid fa-backward-step" @click="player.prev"></i>
|
||||
<i class="fa-solid fa-arrow-rotate-left quick-seek" @click="player.back10"></i>
|
||||
<div :class="['play-pause', 'paused']">
|
||||
<i class="fa-solid fa-play" @click="player.play"></i>
|
||||
<i class="fa-solid fa-pause" @click="player.pause"></i>
|
||||
</div>
|
||||
<i class="fa-solid fa-arrow-rotate-right quick-seek" @click="player.skip10"></i>
|
||||
<i class="fa-solid fa-forward-step" @click="player.next"></i>
|
||||
</div>
|
||||
|
||||
<div class="time">
|
||||
<!-- TODO: Probably needs to be a computed -->
|
||||
<p class="current">
|
||||
{{ beautifyTime( playbackPercentage * duration ) }}
|
||||
</p>
|
||||
<p class="duration">
|
||||
{{ beautifyTime( duration ) }}
|
||||
</p>
|
||||
</div>
|
||||
<ProgressBar v-model="playbackPercentage" @move-end="seek" />
|
||||
<div class="bottom-bar">
|
||||
<!-- FA being a POS means need to make own mods to it -->
|
||||
<i
|
||||
:class="[
|
||||
'fa-solid',
|
||||
'fa-repeat',
|
||||
'repeat',
|
||||
repeatMode === 'one' ? 'once' : undefined,
|
||||
repeatMode === 'all' ? 'all' : undefined
|
||||
]"
|
||||
@click="toggleRepeatMode"
|
||||
></i>
|
||||
<i class="fa-solid fa-share-from-square" @click="openShareMenu"></i>
|
||||
<i
|
||||
:class="['fa-solid', 'fa-shuffle', shuffleMode ? 'active' : undefined]"
|
||||
@click="player.setShuffle( !shuffleMode )"
|
||||
></i>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/scss/components/player.scss';
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ref,
|
||||
useTemplateRef
|
||||
} from 'vue';
|
||||
|
||||
const val = defineModel<number>( {
|
||||
'required': true,
|
||||
'default': 0.5
|
||||
} );
|
||||
const offset = ref( -1 );
|
||||
const bar = useTemplateRef( 'bar' );
|
||||
|
||||
const start = ( ev: MouseEvent ) => {
|
||||
offset.value = ev.x - bar.value!.offsetLeft;
|
||||
val.value = offset.value / bar.value!.clientWidth;
|
||||
emit( 'move-start' );
|
||||
};
|
||||
|
||||
const move = ( ev: MouseEvent ) => {
|
||||
if ( offset.value > -1 ) {
|
||||
val.value = Math.max( 0, Math.min( ev.x / bar.value!.clientWidth, 1 ) );
|
||||
}
|
||||
};
|
||||
|
||||
const end = () => {
|
||||
offset.value = -1;
|
||||
emit( 'move-end' );
|
||||
};
|
||||
|
||||
const emit = defineEmits<{
|
||||
( e: 'move-end' ): void;
|
||||
( e: 'move-start' ): void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="progressbar">
|
||||
<div ref="bar" class="back">
|
||||
<div :style="`width: ${ val * 100 }%;`"></div>
|
||||
</div>
|
||||
<div
|
||||
:class="['click-target', offset >= 0 ? 'active' : undefined]"
|
||||
@mousedown="start"
|
||||
@mousemove="move"
|
||||
@mouseup="end"
|
||||
@mouseleave="end"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/scss/components/progressbar.scss';
|
||||
</style>
|
||||
Reference in New Issue
Block a user