forked from platypush/platypush
[media UI
] Component refactor.
- Fixed style of the floating control extensions panel. - Extracted `ProgressBar` and `ExtraControls` into separate components.
This commit is contained in:
parent
8e8bd7fb9f
commit
e0a9ccca24
6 changed files with 176 additions and 157 deletions
|
@ -3,7 +3,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6">
|
<div class="col-6 buttons">
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<button @click="$emit('previous')" title="Play previous track" v-if="buttons_.previous">
|
<button @click="$emit('previous')" title="Play previous track" v-if="buttons_.previous">
|
||||||
<i class="icon fa fa-step-backward"></i>
|
<i class="icon fa fa-step-backward"></i>
|
||||||
|
@ -21,43 +21,18 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-9 volume-container">
|
|
||||||
<VolumeSlider :value="status.volume" :range="volumeRange" :status="status"
|
<VolumeSlider :value="status.volume" :range="volumeRange" :status="status"
|
||||||
@mute="$emit('mute')" @unmute="$emit('unmute')"
|
@mute="$emit('mute')" @unmute="$emit('unmute')"
|
||||||
@set-volume="$emit('set-volume', $event)" />
|
@set-volume="$emit('set-volume', $event)" />
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-3 list-controls">
|
<ExtraControls :status="status" :buttons="buttons_"
|
||||||
<button @click="$emit('consume', !status.consume)" :class="{enabled: status.consume}"
|
@consume="$emit('consume', !status.consume)"
|
||||||
title="Toggle consume mode" v-if="buttons_.consume">
|
@random="$emit('random', !status.random)"
|
||||||
<i class="icon fa fa-utensils"></i>
|
@repeat="$emit('repeat', !status.repeat)" />
|
||||||
</button>
|
|
||||||
|
|
||||||
<button @click="$emit('random', !status.random)" :class="{enabled: status.random}"
|
|
||||||
title="Toggle shuffle" v-if="buttons_.random">
|
|
||||||
<i class="icon fa fa-random"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button @click="$emit('repeat', !status.repeat)" :class="{enabled: status.repeat}"
|
|
||||||
title="Toggle repeat" v-if="buttons_.repeat">
|
|
||||||
<i class="icon fa fa-redo"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-s-2 col-m-1 time">
|
<ProgressBar :elapsed="elapsed" :duration="duration" :status="status" @seek="$emit('seek', $event)" />
|
||||||
<span class="elapsed-time"
|
|
||||||
v-text="elapsed != null && (status.state === 'play' || status.state === 'pause') ? convertTime(elapsed) : '-:--'"></span>
|
|
||||||
</div>
|
|
||||||
<div class="col-s-8 col-m-10 time-bar">
|
|
||||||
<Slider :value="elapsed" :range="[0, duration]" :disabled="!duration || status.state === 'stop'"
|
|
||||||
@mouseup="$emit('seek', $event.target.value)" />
|
|
||||||
</div>
|
|
||||||
<div class="col-s-2 col-m-1 time">
|
|
||||||
<span class="total-time"
|
|
||||||
v-text="duration && status.state !== 'stop' ? convertTime(duration) : '-:--'"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -70,7 +45,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="track-container col-s-8 col-m-8 col-l-3">
|
<div class="track-container col-s-9 col-m-9 col-l-3">
|
||||||
<div class="track-info" v-if="track && status?.state !== 'stop'">
|
<div class="track-info" v-if="track && status?.state !== 'stop'">
|
||||||
<div class="title" v-if="status.state === 'play' || status.state === 'pause'">
|
<div class="title" v-if="status.state === 'play' || status.state === 'pause'">
|
||||||
<a :href="$route.fullPath" v-text="track.title?.length ? track.title : '[No Title]'"
|
<a :href="$route.fullPath" v-text="track.title?.length ? track.title : '[No Title]'"
|
||||||
|
@ -103,45 +78,25 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-1 time">
|
<ProgressBar :elapsed="elapsed" :duration="duration" :status="status" @seek="$emit('seek', $event)" />
|
||||||
<span class="elapsed-time"
|
|
||||||
v-text="elapsed != null && (status.state === 'play' || status.state === 'pause') ? convertTime(elapsed) : '-:--'"></span>
|
|
||||||
</div>
|
|
||||||
<div class="col-10">
|
|
||||||
<Slider :value="elapsed" :range="[0, duration]" :disabled="!duration || status.state === 'stop'"
|
|
||||||
@mouseup="$emit('seek', $event.target.value)" />
|
|
||||||
</div>
|
|
||||||
<div class="col-1 time">
|
|
||||||
<span class="total-time"
|
|
||||||
v-text="duration && status.state !== 'stop' ? convertTime(duration) : '-:--'"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-2 pull-right until tablet right-buttons">
|
<div class="col-1 until tablet right-controls">
|
||||||
<button @click="expanded = !expanded" :title="expanded ? 'Show more controls' : 'Hide extra controls'">
|
<button @click="expanded = !expanded" :title="expanded ? 'Show more controls' : 'Hide extra controls'">
|
||||||
<i class="fas" :class="[`fa-chevron-${expanded ? 'down' : 'up'}`]" />
|
<i class="fas" :class="[`fa-chevron-${expanded ? 'down' : 'up'}`]" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-3 pull-right from desktop">
|
<div class="col-3 from desktop right-controls">
|
||||||
<div class="row volume-container">
|
|
||||||
<VolumeSlider :value="status.volume" :range="volumeRange" :status="status"
|
<VolumeSlider :value="status.volume" :range="volumeRange" :status="status"
|
||||||
@mute="$emit('mute')" @unmute="$emit('unmute')"
|
@mute="$emit('mute')" @unmute="$emit('unmute')"
|
||||||
@set-volume="$emit('set-volume', $event)" />
|
@set-volume="$emit('set-volume', $event)" />
|
||||||
</div>
|
|
||||||
<div class="row list-controls">
|
|
||||||
<button @click="$emit('consume')" :class="{enabled: status.consume}" title="Toggle consume mode" v-if="buttons_.consume">
|
|
||||||
<i class="icon fa fa-utensils"></i>
|
|
||||||
</button>
|
|
||||||
<button @click="$emit('random')" :class="{enabled: status.random}" title="Toggle shuffle" v-if="buttons_.random">
|
|
||||||
<i class="icon fa fa-random"></i>
|
|
||||||
</button>
|
|
||||||
<button @click="$emit('repeat')" :class="{enabled: status.repeat}" title="Toggle repeat" v-if="buttons_.repeat">
|
|
||||||
<i class="icon fa fa-redo"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<ExtraControls :status="status" :buttons="buttons_"
|
||||||
|
@consume="$emit('consume', !status.consume)"
|
||||||
|
@random="$emit('random', !status.random)"
|
||||||
|
@repeat="$emit('repeat', !status.repeat)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -149,11 +104,12 @@
|
||||||
<script>
|
<script>
|
||||||
import Utils from "@/Utils"
|
import Utils from "@/Utils"
|
||||||
import MediaUtils from "@/components/Media/Utils";
|
import MediaUtils from "@/components/Media/Utils";
|
||||||
import Slider from "@/components/elements/Slider";
|
import ExtraControls from "./ExtraControls";
|
||||||
|
import ProgressBar from "./ProgressBar";
|
||||||
import VolumeSlider from "./VolumeSlider";
|
import VolumeSlider from "./VolumeSlider";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {Slider, VolumeSlider},
|
components: {ExtraControls, ProgressBar, VolumeSlider},
|
||||||
mixins: [Utils, MediaUtils],
|
mixins: [Utils, MediaUtils],
|
||||||
emits: [
|
emits: [
|
||||||
'consume',
|
'consume',
|
||||||
|
@ -282,10 +238,15 @@ button {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
display: none;
|
display: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
padding: .5em;
|
||||||
|
|
||||||
@include until($desktop) {
|
@include until($desktop) {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-top: .5em;
|
}
|
||||||
|
|
||||||
|
:deep(.extra-controls-container) {
|
||||||
|
@extend .pull-right;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
|
@ -293,34 +254,10 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttons {
|
.buttons {
|
||||||
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.volume-container,
|
|
||||||
.list-controls {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
button {
|
|
||||||
padding: 0 .25em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-controls {
|
|
||||||
margin-top: -.5em;
|
|
||||||
flex-flow: row-reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
&:first-child {
|
|
||||||
margin-left: .25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-right: .25em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.controls {
|
.controls {
|
||||||
|
@ -336,12 +273,6 @@ button {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.volume-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.track-container {
|
.track-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -380,24 +311,6 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
.playback-controls {
|
.playback-controls {
|
||||||
&.mobile {
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
@include until($tablet) {
|
|
||||||
display: flex !important;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.tablet {
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
@media screen and (min-width: $tablet) and (max-width: $desktop - 1) {
|
|
||||||
display: flex !important;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
@ -423,47 +336,25 @@ button {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-controls {
|
.right-controls {
|
||||||
height: 50%;
|
@extend .pull-right;
|
||||||
opacity: 0.7;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
flex-flow: row-reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile.right-buttons {
|
|
||||||
@include until ($desktop) {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
justify-content: flex-end;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
align-items: end;
|
||||||
}
|
|
||||||
|
|
||||||
.pull-right {
|
|
||||||
button {
|
button {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.extra-controls-container) {
|
||||||
|
@extend .pull-right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.seek-slider {
|
.seek-slider {
|
||||||
width: 75%;
|
width: 75%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.time {
|
|
||||||
font-size: .7em;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.elapsed-time {
|
|
||||||
text-align: right;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time-bar {
|
|
||||||
flex-grow: 1;
|
|
||||||
margin: 0 .5em;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<template>
|
||||||
|
<div class="extra-controls-container">
|
||||||
|
<button @click="$emit('consume')" :class="{enabled: status.consume}" title="Toggle consume mode" v-if="buttons.consume">
|
||||||
|
<i class="icon fa fa-utensils"></i>
|
||||||
|
</button>
|
||||||
|
<button @click="$emit('random')" :class="{enabled: status.random}" title="Toggle shuffle" v-if="buttons.random">
|
||||||
|
<i class="icon fa fa-random"></i>
|
||||||
|
</button>
|
||||||
|
<button @click="$emit('repeat')" :class="{enabled: status.repeat}" title="Toggle repeat" v-if="buttons.repeat">
|
||||||
|
<i class="icon fa fa-redo"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
emits: ['consume', 'random', 'repeat'],
|
||||||
|
props: {
|
||||||
|
status: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
|
||||||
|
buttons: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.extra-controls-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 0.7;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin: 0 .25em;
|
||||||
|
padding: 0;
|
||||||
|
background: none;
|
||||||
|
border: 0;
|
||||||
|
|
||||||
|
&.enabled {
|
||||||
|
color: $selected-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:disabled):hover {
|
||||||
|
color: $default-hover-fg;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,71 @@
|
||||||
|
<template>
|
||||||
|
<div class="progress-bar-container">
|
||||||
|
<div class="col-s-2 col-m-1 time">
|
||||||
|
<span class="elapsed-time"
|
||||||
|
v-text="elapsed != null && (status.state === 'play' || status.state === 'pause') ? convertTime(elapsed) : '-:--'"></span>
|
||||||
|
</div>
|
||||||
|
<div class="col-s-8 col-m-10 time-bar">
|
||||||
|
<Slider :value="elapsed" :range="[0, duration]" :disabled="!duration || status.state === 'stop'"
|
||||||
|
@input="$emit('seek', $event.target.value)" />
|
||||||
|
</div>
|
||||||
|
<div class="col-s-2 col-m-1 time">
|
||||||
|
<span class="total-time"
|
||||||
|
v-text="duration && status.state !== 'stop' ? convertTime(duration) : '-:--'"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MediaUtils from "@/components/Media/Utils";
|
||||||
|
import Slider from "@/components/elements/Slider";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {Slider},
|
||||||
|
emits: ['seek'],
|
||||||
|
mixins: [MediaUtils],
|
||||||
|
|
||||||
|
props: {
|
||||||
|
elapsed: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Current player status
|
||||||
|
status: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
$time-width: 2.5em;
|
||||||
|
|
||||||
|
.progress-bar-container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.time {
|
||||||
|
width: $time-width;
|
||||||
|
font-size: .7em;
|
||||||
|
position: relative;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.elapsed-time {
|
||||||
|
text-align: right;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-bar {
|
||||||
|
width: calc(100% - #{$time-width * 2} - 2em);
|
||||||
|
flex-grow: 1;
|
||||||
|
margin: 0 .5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -45,13 +45,15 @@ export default {
|
||||||
|
|
||||||
.volume-slider-container {
|
.volume-slider-container {
|
||||||
min-width: 15em;
|
min-width: 15em;
|
||||||
|
max-width: 25em;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
.volume-slider {
|
.volume-slider {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0 .5em 0 1em;
|
padding: 0 .5em 0 1em;
|
||||||
flex-grow: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
|
|
@ -120,7 +120,7 @@ export default {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
background: $default-bg-2;
|
background: none;
|
||||||
border: 0;
|
border: 0;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
|
|
||||||
|
|
|
@ -159,23 +159,23 @@ $width-ranges: (
|
||||||
.#{$name} {
|
.#{$name} {
|
||||||
&.from {
|
&.from {
|
||||||
@include until(nth($range, 1)) {
|
@include until(nth($range, 1)) {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.until {
|
&.until {
|
||||||
@include from(nth($range, 2)) {
|
@include from(nth($range, 2)) {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.only {
|
&.only {
|
||||||
@include until(nth($range, 1)) {
|
@include until(nth($range, 1)) {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include from(nth($range, 2)) {
|
@include from(nth($range, 2)) {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,13 +183,13 @@ $width-ranges: (
|
||||||
|
|
||||||
.mobile {
|
.mobile {
|
||||||
@include from($tablet) {
|
@include from($tablet) {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullhd {
|
.fullhd {
|
||||||
@include until($fullhd) {
|
@include until($fullhd) {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue