diff --git a/src/player/Player.vue b/src/player/Player.vue index 04d1634..1610f9a 100644 --- a/src/player/Player.vue +++ b/src/player/Player.vue @@ -47,19 +47,36 @@
- - - - - - - +
+ + + + + + + + + + +
+ + +
+ Volume + +
+
Repeat @@ -96,6 +113,10 @@ height: auto; max-height: 100px; } + .b-icon { + display: flex; + align-items: center; + } diff --git a/src/player/store.ts b/src/player/store.ts index f862310..0ce7c57 100644 --- a/src/player/store.ts +++ b/src/player/store.ts @@ -8,6 +8,9 @@ const storedQueueIndex = parseInt(localStorage.getItem('queueIndex') || '-1') if (storedQueueIndex > -1 && storedQueueIndex < storedQueue.length) { audio.src = storedQueue[storedQueueIndex].url } +const storedVolume = parseFloat(localStorage.getItem('player.volume') || '1.0') +const storedMuteState = localStorage.getItem('player.mute') === 'true' +audio.volume = storedMuteState ? 0.0 : storedVolume const mediaSession: MediaSession | undefined = navigator.mediaSession interface State { @@ -19,6 +22,8 @@ interface State { currentTime: number; // position of current track in seconds repeat: boolean; shuffle: boolean; + mute: boolean; + volume: number; // integer between 0 and 1 representing the volume of the player } export const playerModule: Module = { @@ -32,6 +37,8 @@ export const playerModule: Module = { currentTime: 0, repeat: localStorage.getItem('player.repeat') !== 'false', shuffle: localStorage.getItem('player.shuffle') === 'true', + mute: storedMuteState, + volume: storedVolume, }, mutations: { @@ -55,6 +62,10 @@ export const playerModule: Module = { state.shuffle = enable localStorage.setItem('player.shuffle', enable) }, + setMute(state, enable) { + state.mute = enable + localStorage.setItem('player.mute', enable) + }, setQueue(state, queue) { state.queue = queue state.queueIndex = -1 @@ -102,6 +113,11 @@ export const playerModule: Module = { setScrobbled(state) { state.scrobbled = true }, + setVolume(state, value: number) { + state.volume = value + state.mute = value <= 0.0 + localStorage.setItem('player.volume', String(value)) + }, }, actions: { @@ -170,12 +186,20 @@ export const playerModule: Module = { toggleShuffle({ commit, state }) { commit('setShuffle', !state.shuffle) }, + toggleMute({ commit, state }) { + commit('setMute', !state.mute) + audio.volume = state.mute ? 0.0 : state.volume + }, addToQueue({ commit }, track) { commit('addToQueue', track) }, setNextInQueue({ commit }, track) { commit('setNextInQueue', track) }, + setVolume({ commit }, value) { + audio.volume = value + commit('setVolume', value) + }, }, getters: { diff --git a/src/shared/components/Icon.vue b/src/shared/components/Icon.vue index cd0277b..f2394a9 100644 --- a/src/shared/components/Icon.vue +++ b/src/shared/components/Icon.vue @@ -28,6 +28,8 @@ BIconPersonCircle, BIconRss, BIconX, + BIconVolumeUpFill, + BIconVolumeMuteFill, } from 'bootstrap-vue' export default Vue.extend({ @@ -56,6 +58,8 @@ BIconPersonCircle, BIconRss, BIconX, + BIconVolumeUpFill, + BIconVolumeMuteFill, }, props: { icon: { type: String, required: true } diff --git a/src/style/main.scss b/src/style/main.scss index 9cec8f1..bf50d6b 100644 --- a/src/style/main.scss +++ b/src/style/main.scss @@ -34,6 +34,9 @@ $dropdown-divider-bg: $theme-elevation-2; $input-bg: $theme-elevation-2; $input-border-color: $theme-elevation-2; $input-color: $theme-text; +$custom-range-track-height: 0.1rem; +$custom-range-thumb-bg: $theme-text; +$custom-range-track-bg: $theme-text-muted; // Other $progress-bg: rgb(35, 35, 35);