improve volume control style
This commit is contained in:
parent
cc6a82116b
commit
23507436f6
@ -15,6 +15,7 @@
|
|||||||
"vue": "^2.6.12",
|
"vue": "^2.6.12",
|
||||||
"vue-infinite-loading": "2.4.5",
|
"vue-infinite-loading": "2.4.5",
|
||||||
"vue-router": "^3.5.1",
|
"vue-router": "^3.5.1",
|
||||||
|
"vue-slider-component": "3.2.11",
|
||||||
"vuex": "^3.6.2"
|
"vuex": "^3.6.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
1
src/global.d.ts
vendored
1
src/global.d.ts
vendored
@ -4,6 +4,7 @@ declare module '*.vue' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare module 'md5-es';
|
declare module 'md5-es';
|
||||||
|
declare module 'vue-slider-component';
|
||||||
|
|
||||||
type MediaSessionPlaybackState = 'none' | 'paused' | 'playing';
|
type MediaSessionPlaybackState = 'none' | 'paused' | 'playing';
|
||||||
|
|
||||||
|
@ -41,13 +41,15 @@
|
|||||||
<div class="col-auto col-sm p-0">
|
<div class="col-auto col-sm p-0">
|
||||||
<div class="d-flex flex-nowrap justify-content-end pr-3">
|
<div class="d-flex flex-nowrap justify-content-end pr-3">
|
||||||
<div class="m-0 d-none d-md-inline-flex align-items-center">
|
<div class="m-0 d-none d-md-inline-flex align-items-center">
|
||||||
<b-button variant="link" @click="toggleMute">
|
<b-button id="player-volume-btn" variant="link" title="Volume">
|
||||||
<Icon :icon="muteActive ? 'volume-mute-fill' : 'volume-up-fill'" />
|
<Icon :icon="muteActive ? 'volume-mute-fill' : 'volume-up-fill'" />
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-form-input type="range" min="0" max="1" step="0.05"
|
<b-popover target="player-volume-btn" placement="top" triggers="click blur" no-fade>
|
||||||
style="width: 120px; min-width: 0; padding-right: 0.75rem"
|
<Slider class="pt-2" style="height: 120px;" direction="btt"
|
||||||
:title="`Volume: ${Math.round(volume * 100)}%`"
|
:min="0" :max="1" :step="0.01" percent
|
||||||
:value="muteActive ? 0.0 : volume" @input="setVolume" />
|
:value="muteActive ? 0.0 : volume" @input="setVolume"
|
||||||
|
/>
|
||||||
|
</b-popover>
|
||||||
<b-button title="Shuffle"
|
<b-button title="Shuffle"
|
||||||
variant="link" class="m-0" :class="{ 'text-primary': shuffleActive }"
|
variant="link" class="m-0" :class="{ 'text-primary': shuffleActive }"
|
||||||
@click="toggleShuffle">
|
@click="toggleShuffle">
|
||||||
@ -61,12 +63,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<OverflowMenu class="d-md-none">
|
<OverflowMenu class="d-md-none">
|
||||||
<b-dropdown-text>
|
<b-dropdown-text>
|
||||||
<div class="d-flex justify-content-between">
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
<strong>Volume</strong>
|
<strong>Volume</strong>
|
||||||
<b-form-input
|
<Slider class="px-3" style="width: 120px;"
|
||||||
class="px-2" style="width: 120px"
|
:min="0" :max="1" :step="0.01" percent
|
||||||
type="range" min="0" max="1" step="0.05"
|
:value="muteActive ? 0.0 : volume" @input="setVolume"
|
||||||
:value="volume" @input="setVolume"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</b-dropdown-text>
|
</b-dropdown-text>
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
BIconPersonFill,
|
BIconPersonFill,
|
||||||
BIconRss,
|
BIconRss,
|
||||||
BIconX,
|
BIconX,
|
||||||
BIconVolumeUpFill,
|
|
||||||
BIconVolumeMuteFill,
|
BIconVolumeMuteFill,
|
||||||
|
BIconVolumeUpFill,
|
||||||
} from 'bootstrap-vue'
|
} from 'bootstrap-vue'
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
@ -56,8 +56,8 @@
|
|||||||
BIconPersonFill,
|
BIconPersonFill,
|
||||||
BIconRss,
|
BIconRss,
|
||||||
BIconX,
|
BIconX,
|
||||||
BIconVolumeUpFill,
|
|
||||||
BIconVolumeMuteFill,
|
BIconVolumeMuteFill,
|
||||||
|
BIconVolumeUpFill,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
icon: { type: String, required: true }
|
icon: { type: String, required: true }
|
||||||
|
54
src/shared/components/Slider.vue
Normal file
54
src/shared/components/Slider.vue
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<template>
|
||||||
|
<VueSlider
|
||||||
|
v-bind="$attrs"
|
||||||
|
:value="value"
|
||||||
|
:min="min"
|
||||||
|
:max="max"
|
||||||
|
:interval="step"
|
||||||
|
:tooltip-formatter="formatter"
|
||||||
|
@change="onInput"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<style>
|
||||||
|
@import '~vue-slider-component/theme/default.css';
|
||||||
|
.vue-slider-rail {
|
||||||
|
background-color: var(--secondary) !important;
|
||||||
|
}
|
||||||
|
.vue-slider-process {
|
||||||
|
background-color: var(--primary) !important;
|
||||||
|
}
|
||||||
|
.vue-slider-dot-tooltip-inner {
|
||||||
|
background-color: var(--primary);
|
||||||
|
border-color: var(--primary);
|
||||||
|
}
|
||||||
|
.vue-slider-dot-handle {
|
||||||
|
background-color: var(--text-body);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue'
|
||||||
|
import VueSlider from 'vue-slider-component'
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
components: {
|
||||||
|
VueSlider,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: { type: Number, required: true },
|
||||||
|
min: { type: Number, required: true },
|
||||||
|
max: { type: Number, required: true },
|
||||||
|
step: { type: Number, required: true },
|
||||||
|
percent: { type: Boolean, default: false },
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onInput(value: number) {
|
||||||
|
this.$emit('input', value)
|
||||||
|
},
|
||||||
|
formatter(value: number) {
|
||||||
|
return this.percent
|
||||||
|
? `${Math.round(((value - this.min) * 100) / (this.max - this.min))}%`
|
||||||
|
: `${value}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
@ -4,6 +4,7 @@ import ExternalLink from './ExternalLink.vue'
|
|||||||
import Icon from './Icon.vue'
|
import Icon from './Icon.vue'
|
||||||
import InfiniteLoader from './InfiniteLoader.vue'
|
import InfiniteLoader from './InfiniteLoader.vue'
|
||||||
import OverflowMenu from './OverflowMenu.vue'
|
import OverflowMenu from './OverflowMenu.vue'
|
||||||
|
import Slider from './Slider.vue'
|
||||||
import Tiles from './Tiles.vue'
|
import Tiles from './Tiles.vue'
|
||||||
import Tile from './Tile.vue'
|
import Tile from './Tile.vue'
|
||||||
import {
|
import {
|
||||||
@ -16,6 +17,7 @@ import {
|
|||||||
BFormTextarea,
|
BFormTextarea,
|
||||||
BModal,
|
BModal,
|
||||||
BOverlay,
|
BOverlay,
|
||||||
|
BPopover,
|
||||||
BProgress,
|
BProgress,
|
||||||
BSidebar,
|
BSidebar,
|
||||||
DropdownPlugin,
|
DropdownPlugin,
|
||||||
@ -30,6 +32,7 @@ Vue.component('BFormInput', BFormInput)
|
|||||||
Vue.component('BFormCheckbox', BFormCheckbox)
|
Vue.component('BFormCheckbox', BFormCheckbox)
|
||||||
Vue.component('BFormTextarea', BFormTextarea)
|
Vue.component('BFormTextarea', BFormTextarea)
|
||||||
Vue.component('BButton', BButton)
|
Vue.component('BButton', BButton)
|
||||||
|
Vue.component('BPopover', BPopover)
|
||||||
Vue.component('BProgress', BProgress)
|
Vue.component('BProgress', BProgress)
|
||||||
Vue.component('BOverlay', BOverlay)
|
Vue.component('BOverlay', BOverlay)
|
||||||
Vue.use(DropdownPlugin)
|
Vue.use(DropdownPlugin)
|
||||||
@ -40,6 +43,7 @@ const components = {
|
|||||||
Icon,
|
Icon,
|
||||||
InfiniteLoader,
|
InfiniteLoader,
|
||||||
OverflowMenu,
|
OverflowMenu,
|
||||||
|
Slider,
|
||||||
Tiles,
|
Tiles,
|
||||||
Tile,
|
Tile,
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,10 @@ $dropdown-link-hover-color: $theme-text-muted;
|
|||||||
$dropdown-border-color: $theme-elevation-2;
|
$dropdown-border-color: $theme-elevation-2;
|
||||||
$dropdown-divider-bg: $theme-elevation-2;
|
$dropdown-divider-bg: $theme-elevation-2;
|
||||||
|
|
||||||
|
// Popover
|
||||||
|
$popover-bg: $theme-elevation-1;
|
||||||
|
$popover-border-color: $theme-elevation-2;
|
||||||
|
|
||||||
// Form
|
// Form
|
||||||
$input-bg: $theme-elevation-2;
|
$input-bg: $theme-elevation-2;
|
||||||
$input-border-color: $theme-elevation-2;
|
$input-border-color: $theme-elevation-2;
|
||||||
@ -42,6 +46,7 @@ $custom-range-track-bg: $theme-text-muted;
|
|||||||
$progress-bg: rgb(35, 35, 35);
|
$progress-bg: rgb(35, 35, 35);
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
--text-body: #{$theme-text};
|
||||||
--text-muted: #{$theme-text-muted};
|
--text-muted: #{$theme-text-muted};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
yarn.lock
20
yarn.lock
@ -9482,6 +9482,11 @@ vm-browserify@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||||
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
||||||
|
|
||||||
|
vue-class-component@^7.1.0:
|
||||||
|
version "7.2.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-7.2.6.tgz#8471e037b8e4762f5a464686e19e5afc708502e4"
|
||||||
|
integrity sha512-+eaQXVrAm/LldalI272PpDe3+i4mPis0ORiMYxF6Ae4hyuCh15W8Idet7wPUEs4N4YptgFHGys4UrgNQOMyO6w==
|
||||||
|
|
||||||
vue-eslint-parser@^7.0.0:
|
vue-eslint-parser@^7.0.0:
|
||||||
version "7.1.0"
|
version "7.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-7.1.0.tgz#9cdbcc823e656b087507a1911732b867ac101e83"
|
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-7.1.0.tgz#9cdbcc823e656b087507a1911732b867ac101e83"
|
||||||
@ -9541,11 +9546,26 @@ vue-loader@^15.9.2:
|
|||||||
vue-hot-reload-api "^2.3.0"
|
vue-hot-reload-api "^2.3.0"
|
||||||
vue-style-loader "^4.1.0"
|
vue-style-loader "^4.1.0"
|
||||||
|
|
||||||
|
vue-property-decorator@^8.0.0:
|
||||||
|
version "8.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue-property-decorator/-/vue-property-decorator-8.5.1.tgz#571a91cf8d2b507f537d79bf8275af3184572fff"
|
||||||
|
integrity sha512-O6OUN2OMsYTGPvgFtXeBU3jPnX5ffQ9V4I1WfxFQ6dqz6cOUbR3Usou7kgFpfiXDvV7dJQSFcJ5yUPgOtPPm1Q==
|
||||||
|
dependencies:
|
||||||
|
vue-class-component "^7.1.0"
|
||||||
|
|
||||||
vue-router@^3.5.1:
|
vue-router@^3.5.1:
|
||||||
version "3.5.1"
|
version "3.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.5.1.tgz#edf3cf4907952d1e0583e079237220c5ff6eb6c9"
|
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.5.1.tgz#edf3cf4907952d1e0583e079237220c5ff6eb6c9"
|
||||||
integrity sha512-RRQNLT8Mzr8z7eL4p7BtKvRaTSGdCbTy2+Mm5HTJvLGYSSeG9gDzNasJPP/yOYKLy+/cLG/ftrqq5fvkFwBJEw==
|
integrity sha512-RRQNLT8Mzr8z7eL4p7BtKvRaTSGdCbTy2+Mm5HTJvLGYSSeG9gDzNasJPP/yOYKLy+/cLG/ftrqq5fvkFwBJEw==
|
||||||
|
|
||||||
|
vue-slider-component@3.2.11:
|
||||||
|
version "3.2.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue-slider-component/-/vue-slider-component-3.2.11.tgz#79e338dc5a32ca927a8f79ee55256197bd785235"
|
||||||
|
integrity sha512-2YyJW6TFnYk5FUvqQLvZcCJ+hthBXB819qNHtwnEUyDbOcTXV0n3Ou1ZphOi5FX9phlQIiC2NvjLuRAVmNq+Zw==
|
||||||
|
dependencies:
|
||||||
|
core-js "^3.6.5"
|
||||||
|
vue-property-decorator "^8.0.0"
|
||||||
|
|
||||||
vue-style-loader@^4.1.0, vue-style-loader@^4.1.2:
|
vue-style-loader@^4.1.0, vue-style-loader@^4.1.2:
|
||||||
version "4.1.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.2.tgz#dedf349806f25ceb4e64f3ad7c0a44fba735fcf8"
|
resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.2.tgz#dedf349806f25ceb4e64f3ad7c0a44fba735fcf8"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user