Skip to content

Commit

Permalink
Merge pull request #517 from jellyfin/refactor/time
Browse files Browse the repository at this point in the history
Refactor/time - Refactor time slider
  • Loading branch information
heyhippari authored Jan 8, 2021
2 parents bf8dd05 + 0c3e997 commit eeb76c5
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 138 deletions.
80 changes: 80 additions & 0 deletions components/Item/TimeSlider.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<template>
<v-slider
min="0"
:max="runtime"
validate-on-blur
:step="0"
:value="sliderValue"
hide-details
thumb-label
@end="onPositionChange"
@change="onPositionChange"
@mousedown="onClick"
@mouseup="onClick"
@input="onInputChange"
>
<template #prepend>
<span class="mt-1">
{{ formatTime(realPosition) }}
</span>
</template>
<template #thumb-label>
{{ formatTime(sliderValue) }}
</template>
<template #append>
<span class="mt-1">
{{ formatTime(runtime) }}
</span>
</template>
</v-slider>
</template>

<script lang="ts">
import Vue from 'vue';
import { mapActions, mapGetters } from 'vuex';
import timeUtils from '~/mixins/timeUtils';
export default Vue.extend({
mixins: [timeUtils],
data() {
return {
clicked: false,
currentInput: 0
};
},
computed: {
...mapGetters('playbackManager', ['getCurrentItem']),
sliderValue: {
get(): number {
if (!this.clicked) {
return this.$store.state.playbackManager.currentTime;
}
return this.currentInput;
}
},
runtime(): number {
return this.ticksToMs(this.getCurrentItem.RunTimeTicks) / 1000;
},
realPosition: {
get(): number {
return this.$store.state.playbackManager.currentTime;
}
}
},
methods: {
...mapActions('playbackManager', ['changeCurrentTime']),
onPositionChange(value: number): void {
if (!this.clicked) {
this.changeCurrentTime({ time: value });
}
},
onInputChange(value: number): void {
this.currentInput = value;
},
onClick(): void {
this.currentInput = this.realPosition;
this.clicked = !this.clicked;
}
}
});
</script>
76 changes: 1 addition & 75 deletions components/Layout/AudioControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,33 +59,7 @@
<v-icon>mdi-repeat-off</v-icon>
</v-btn>
</div>
<v-slider
:value="sliderValue"
hide-details
:max="runtime"
validate-on-blur
thumb-label
:step="0"
@end="onPositionChange"
@change="onPositionChange"
@mousedown="onClick"
@mouseup="onClick"
@input="onInputChange"
>
<template #prepend>
<span class="mt-1">
{{ getRuntime(realPosition) }}
</span>
</template>
<template #thumb-label>
{{ getRuntime(sliderValue) }}
</template>
<template #append>
<span class="mt-1">
{{ getRuntime(runtime) }}
</span>
</template>
</v-slider>
<time-slider />
</div>
</v-col>
<v-col cols="3" class="d-none d-md-flex align-center justify-end">
Expand Down Expand Up @@ -131,32 +105,13 @@ import { PlaybackStatus } from '~/store/playbackManager';
export default Vue.extend({
mixins: [timeUtils, imageHelper],
data() {
return {
clicked: false,
currentInput: 0
};
},
computed: {
...mapGetters('playbackManager', ['getCurrentItem']),
runtime(): number {
return this.ticksToMs(this.getCurrentItem.RunTimeTicks) / 1000;
},
isPaused(): boolean {
return this.$store.state.playbackManager.status === PlaybackStatus.paused;
},
sliderValue: {
get(): number {
if (!this.clicked) {
return this.$store.state.playbackManager.currentTime;
}
return this.currentInput;
}
},
realPosition: {
get(): number {
return this.$store.state.playbackManager.currentTime;
}
}
},
methods: {
Expand All @@ -176,35 +131,6 @@ export default Vue.extend({
element
});
},
getRuntime(seconds: number): string {
const minutes = Math.floor(seconds / 60);
seconds = Math.floor(seconds - minutes * 60);
/**
* Formats the second number
* E.g. 7 -> 07
*
* @param {string} seconds - Number to format
* @returns {string} Formatted seconds number
*/
function formatSeconds(seconds: string): string {
return ('0' + seconds).slice(-2);
}
return `${minutes}:${formatSeconds(seconds.toString())}`;
},
onPositionChange(value: number): void {
if (!this.clicked) {
this.changeCurrentTime({ time: value });
}
},
onInputChange(value: number): void {
this.currentInput = value;
},
onClick(): void {
this.currentInput = this.realPosition;
this.clicked = !this.clicked;
},
stopPlayback(): void {
this.setLastItemIndex();
this.resetCurrentItemIndex();
Expand Down
64 changes: 1 addition & 63 deletions components/Players/PlayerManager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -106,34 +106,7 @@

<div class="px-4 osd-bottom">
<div>
<v-slider
min="0"
:max="runtime"
validate-on-blur
:step="0"
:value="sliderValue"
hide-details
thumb-label
@end="onPositionChange"
@change="onPositionChange"
@mousedown="onClick"
@mouseup="onClick"
@input="onInputChange"
>
<template #prepend>
<span class="mt-1">
{{ getRuntime(realPosition) }}
</span>
</template>
<template #thumb-label>
{{ getRuntime(sliderValue) }}
</template>
<template #append>
<span class="mt-1">
{{ getRuntime(runtime) }}
</span>
</template>
</v-slider>
<time-slider />
<div class="d-flex justify-space-between">
<div>
<v-btn icon @click="setPreviousTrack">
Expand Down Expand Up @@ -213,9 +186,6 @@ export default Vue.extend({
currentPosition(): number {
return this.$store.state.playbackManager.currentTime;
},
runtime(): number {
return this.ticksToMs(this.getCurrentItem.RunTimeTicks) / 1000;
},
currentItemName(): string {
switch (this.getCurrentItem.Type) {
case 'Episode':
Expand Down Expand Up @@ -383,38 +353,6 @@ export default Vue.extend({
} else {
this.pause();
}
},
getRuntime(seconds: number): string {
let minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
minutes = minutes - hours * 60;
seconds = Math.floor(seconds - (minutes * 60 + hours * 60 * 60));
/**
* Formats the second number
* E.g. 7 -> 07
*
* @param {string} seconds - Number to format
* @returns {string} Formatted seconds number
*/
function formatSeconds(seconds: string): string {
return ('0' + seconds).slice(-2);
}
if (hours)
return `${hours}:${minutes}:${formatSeconds(seconds.toString())}`;
return `${minutes}:${formatSeconds(seconds.toString())}`;
},
onPositionChange(value: number): void {
if (!this.clicked) {
this.changeCurrentTime({ time: value });
}
},
onInputChange(value: number): void {
this.currentInput = value;
},
onClick(): void {
this.currentInput = this.realPosition;
this.clicked = !this.clicked;
}
}
});
Expand Down
14 changes: 14 additions & 0 deletions mixins/__tests__/timeUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,18 @@ describe('timeUtils', () => {
test('converts time from ticks to ms', () => {
expect(TestComponent.msToTicks(1)).toEqual(10000);
});

test('formats time properly', () => {
expect(TestComponent.formatTime(5)).toEqual('0:05');

expect(TestComponent.formatTime(10)).toEqual('0:10');

expect(TestComponent.formatTime(65)).toEqual('1:05');

expect(TestComponent.formatTime(70)).toEqual('1:10');

expect(TestComponent.formatTime(3665)).toEqual('1:01:05');

expect(TestComponent.formatTime(4210)).toEqual('1:10:10');
});
});
26 changes: 26 additions & 0 deletions mixins/timeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,21 @@ declare module '@nuxt/types' {
interface Context {
ticksToMs: (ticks: number) => number;
msToTicks: (ms: number) => number;
formatTime: (seconds: number) => number;
}

interface NuxtAppOptions {
ticksToMs: (ticks: number) => number;
msToTicks: (ms: number) => number;
formatTime: (seconds: number) => number;
}
}

declare module 'vue/types/vue' {
interface Vue {
ticksToMs: (ticks: number | null | undefined) => number;
msToTicks: (ms: number) => number;
formatTime: (seconds: number) => number;
}
}

Expand All @@ -66,6 +69,29 @@ const timeUtils = Vue.extend({
*/
msToTicks(ms: number): number {
return msToTicks(ms);
},
formatTime(seconds: number): string {
let minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
minutes = minutes - hours * 60;
seconds = Math.floor(seconds - (minutes * 60 + hours * 60 * 60));

/**
* Formats Time
* E.g. 7 -> 07
*
* @param {number} number - Number to format
* @returns {string} Formated seconds number
*/
function formatDigits(number: number): string {
return ('0' + number).slice(-2);
}

if (hours) {
return `${hours}:${formatDigits(minutes)}:${formatDigits(seconds)}`;
} else {
return `${minutes}:${formatDigits(seconds)}`;
}
}
}
});
Expand Down

0 comments on commit eeb76c5

Please sign in to comment.