mirror of
https://github.com/jellyfin/jellyfin-vue.git
synced 2025-03-03 11:17:22 +00:00
refactor(up-next): cleanup code
This commit is contained in:
parent
a0ef0783d3
commit
f9b04e818c
@ -1,72 +1,140 @@
|
||||
<template>
|
||||
<v-fade-transition>
|
||||
<v-card class="container white--text pa-4">
|
||||
<div class="d-flex flex-column flex-grow-1">
|
||||
<v-card-title class="text-h6 pa-0 my-1 mx-0">
|
||||
{{ $t('dialog.upNext.nextItemPlayingIn') }}
|
||||
<span class="primary--text darken-2">
|
||||
 {{ timeLeft }} {{ $t('seconds').toLowerCase() }}
|
||||
</span>
|
||||
</v-card-title>
|
||||
<v-card-subtitle
|
||||
v-if="getCurrentItem.Type === 'Episode'"
|
||||
class="mt-1 mx-0 mb-2 text-truncate subtitle-1 pa-0"
|
||||
>
|
||||
{{ getNextItem.SeriesName }} -
|
||||
{{
|
||||
$t('seasonEpisodeAbbrev', {
|
||||
seasonNumber: getNextItem.ParentIndexNumber,
|
||||
episodeNumber: getNextItem.IndexNumber
|
||||
})
|
||||
}}
|
||||
<span v-if="$vuetify.breakpoint.smAndUp"> - </span> <br v-else />
|
||||
{{ getNextItem.Name }}
|
||||
</v-card-subtitle>
|
||||
<v-card-subtitle
|
||||
v-if="getCurrentItem.Type === 'Movie'"
|
||||
class="mt-1 mx-0 mb-2 text-truncate subtitle-1 pa-0"
|
||||
>
|
||||
{{ getNextItem.Name }}
|
||||
</v-card-subtitle>
|
||||
<div>
|
||||
{{ getRuntimeTime(getNextItem.RunTimeTicks) }}
|
||||
<span class="pl-4"
|
||||
>{{ $t('endsAt', { time: nextEndsAt(getNextItem.RunTimeTicks) }) }}
|
||||
</span>
|
||||
</div>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn class="primary darken-2" @click="$emit('startNext')">
|
||||
{{ $t('dialog.upNext.startNow') }}
|
||||
</v-btn>
|
||||
<v-btn @click="$emit('hide')"> {{ $t('dialog.upNext.hide') }}</v-btn>
|
||||
</v-card-actions>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-fade-transition>
|
||||
<v-container
|
||||
v-if="visible"
|
||||
class="up-next-dialog pointer-events-none pa-lg-6"
|
||||
>
|
||||
<v-row>
|
||||
<v-col
|
||||
cols="12"
|
||||
offset-md="6"
|
||||
md="6"
|
||||
offset-lg="8"
|
||||
lg="4"
|
||||
offset-xl="9"
|
||||
xl="3"
|
||||
>
|
||||
<v-card class="pointer-events-all">
|
||||
<v-card-title class="text-h6">
|
||||
<i18n path="dialog.upNext.nextItemPlayingIn" tag="span">
|
||||
<template #time>
|
||||
<span class="primary--text darken-2">
|
||||
{{ $tc('units.time.seconds', currentItemTimeLeft) }}
|
||||
</span>
|
||||
</template>
|
||||
</i18n>
|
||||
</v-card-title>
|
||||
<v-card-subtitle class="text-truncate subtitle-1">
|
||||
<span v-if="getCurrentItem.Type === 'Episode'">
|
||||
{{ getNextItem.SeriesName }} -
|
||||
{{
|
||||
$t('seasonEpisodeAbbrev', {
|
||||
seasonNumber: getNextItem.ParentIndexNumber,
|
||||
episodeNumber: getNextItem.IndexNumber
|
||||
})
|
||||
}}
|
||||
<span v-if="$vuetify.breakpoint.smAndUp"> - </span> <br v-else />
|
||||
{{ getNextItem.Name }}
|
||||
</span>
|
||||
<span v-if="getCurrentItem.Type === 'Movie'">
|
||||
{{ getNextItem.Name }}
|
||||
</span>
|
||||
</v-card-subtitle>
|
||||
<v-card-text>
|
||||
<span>
|
||||
{{ getRuntimeTime(getNextItem.RunTimeTicks) }}
|
||||
<span class="pl-4"
|
||||
>{{
|
||||
$t('endsAt', {
|
||||
time: getEndsAtTime(getNextItem.RunTimeTicks)
|
||||
})
|
||||
}}
|
||||
</span>
|
||||
</span>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn class="primary darken-2" depressed @click="setNextTrack()">
|
||||
{{ $t('dialog.upNext.startNow') }}
|
||||
</v-btn>
|
||||
<v-btn depressed outlined @click="isHiddenByUser = true">
|
||||
{{ $t('dialog.upNext.hide') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { mapGetters, mapState } from 'vuex';
|
||||
import timeUtils from '~/mixins/timeUtils';
|
||||
|
||||
export default Vue.extend({
|
||||
mixins: [timeUtils],
|
||||
props: {
|
||||
timeLeft: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
data() {
|
||||
return {
|
||||
isHiddenByUser: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('playbackManager', ['getNextItem', 'getCurrentItem'])
|
||||
},
|
||||
methods: {
|
||||
nextEndsAt(runtimeTicks: number): string {
|
||||
const seconds = this.ticksToMs(runtimeTicks) + this.timeLeft * 1000;
|
||||
...mapState('playbackManager', [
|
||||
'currentItemIndex',
|
||||
'currentTime',
|
||||
'isMinimized'
|
||||
]),
|
||||
...mapGetters('playbackManager', [
|
||||
'getCurrentlyPlayingMediaType',
|
||||
'getNextItem',
|
||||
'getCurrentItem',
|
||||
'setNextTrack'
|
||||
]),
|
||||
currentItemDuration(): number {
|
||||
return this.ticksToMs(this.getCurrentItem?.RunTimeTicks) / 1000;
|
||||
},
|
||||
currentItemTimeLeft(): number {
|
||||
return Math.round(this.currentItemDuration - this.currentTime);
|
||||
},
|
||||
visible(): boolean {
|
||||
if (
|
||||
this.isMinimized ||
|
||||
this.isHiddenByUser ||
|
||||
this.getCurrentlyPlayingMediaType !== 'Video' ||
|
||||
!this.getNextItem
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.$dateFns.format(Date.now() + seconds, 'p');
|
||||
if (this.currentItemTimeLeft <= this.nextUpDuration) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
nextUpDuration(): number {
|
||||
// If longer than 5 hours, set the duration to 9 minutes
|
||||
if (this.currentItemDuration >= 5 * 60 * 60) {
|
||||
return 540;
|
||||
}
|
||||
// If longer than 2 hours, set the duration to 3.5 minutes
|
||||
else if (this.currentItemDuration >= 2 * 60 * 60) {
|
||||
return 210;
|
||||
}
|
||||
// If longer than 45 minutes, set the duration to 2 minutes
|
||||
else if (this.currentItemDuration >= 45 * 60) {
|
||||
return 120;
|
||||
}
|
||||
|
||||
return 45;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentItemIndex(): void {
|
||||
this.isHiddenByUser = false;
|
||||
},
|
||||
visible(): void {
|
||||
this.$emit('change', this.visible);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -74,22 +142,10 @@ export default Vue.extend({
|
||||
<style lang="scss" scoped>
|
||||
@import '~vuetify/src/styles/styles.sass';
|
||||
|
||||
.container {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
.up-next-dialog {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
will-change: transform, opacity;
|
||||
background-color: rgba(map-get($shades, 'black'), 0.7);
|
||||
user-select: none;
|
||||
z-index: 6;
|
||||
-webkit-touch-callout: none;
|
||||
}
|
||||
|
||||
@media #{map-get($display-breakpoints, 'md-and-up')} {
|
||||
.container {
|
||||
width: 30em;
|
||||
margin: 0 2em 10em 0;
|
||||
}
|
||||
right: 0;
|
||||
z-index: 9999;
|
||||
}
|
||||
</style>
|
||||
|
@ -315,8 +315,8 @@ export default Vue.extend({
|
||||
if (this.getCurrentAudioTrack) {
|
||||
if (
|
||||
(this.sessionInfo?.TranscodingInfo?.AudioCodec &&
|
||||
this.getCurrentAudioTrack.Codec !==
|
||||
this.sessionInfo.TranscodingInfo.AudioCodec) ||
|
||||
this.getCurrentAudioTrack?.Codec !==
|
||||
this.sessionInfo?.TranscodingInfo?.AudioCodec) ||
|
||||
!this.sessionInfo?.TranscodingInfo?.IsAudioDirect
|
||||
) {
|
||||
return `${this.getCurrentAudioTrack.Codec} ➞ ${this.sessionInfo?.TranscodingInfo?.AudioCodec}`;
|
||||
@ -331,15 +331,19 @@ export default Vue.extend({
|
||||
return this.getCurrentSubtitleTrack?.Codec;
|
||||
},
|
||||
mediaAudioChannels(): string | null | undefined {
|
||||
if (
|
||||
this.sessionInfo?.TranscodingInfo?.AudioChannels &&
|
||||
this.getCurrentAudioTrack.Channels !==
|
||||
this.sessionInfo.TranscodingInfo.AudioChannels
|
||||
) {
|
||||
return `${this.getCurrentAudioTrack.Channels} ➞ ${this.sessionInfo?.TranscodingInfo?.AudioChannels}`;
|
||||
if (this.getCurrentAudioTrack) {
|
||||
if (
|
||||
this.sessionInfo?.TranscodingInfo?.AudioChannels &&
|
||||
this.getCurrentAudioTrack?.Channels !==
|
||||
this.sessionInfo?.TranscodingInfo?.AudioChannels
|
||||
) {
|
||||
return `${this.getCurrentAudioTrack.Channels} ➞ ${this.sessionInfo?.TranscodingInfo?.AudioChannels}`;
|
||||
}
|
||||
|
||||
return this.getCurrentAudioTrack?.Channels;
|
||||
}
|
||||
|
||||
return this.getCurrentAudioTrack?.Channels;
|
||||
return null;
|
||||
},
|
||||
mediaTotalBitrate(): string | null | undefined {
|
||||
if (
|
||||
|
@ -23,17 +23,12 @@
|
||||
v-show="!isMinimized && playbackData"
|
||||
@close-playback-data="playbackData = false"
|
||||
/>
|
||||
<up-next @change="setUpNextVisible" />
|
||||
<v-hover v-slot="{ hover }">
|
||||
<v-card class="player-card" width="100%">
|
||||
<v-container fill-height fluid class="pa-0 justify-center">
|
||||
<shaka-player ref="videoPlayer" />
|
||||
</v-container>
|
||||
<up-next
|
||||
v-if="showUpNext"
|
||||
:time-left="getTimeLeft"
|
||||
@hide="upNextUserHidden = true"
|
||||
@startNext="setNextTrack()"
|
||||
/>
|
||||
<!-- Mini Player Overlay -->
|
||||
<v-fade-transition>
|
||||
<v-overlay v-show="hover && isMinimized" absolute>
|
||||
@ -90,7 +85,9 @@
|
||||
<!-- Full Screen OSD -->
|
||||
<v-fade-transition>
|
||||
<v-overlay
|
||||
v-show="!isMinimized && showFullScreenOverlay"
|
||||
v-show="
|
||||
!isMinimized && showFullScreenOverlay && !isUpNextVisible
|
||||
"
|
||||
color="transparent"
|
||||
absolute
|
||||
>
|
||||
@ -267,7 +264,7 @@ export default Vue.extend({
|
||||
fullScreenVideo: false,
|
||||
keepOpen: false,
|
||||
playbackData: false,
|
||||
upNextUserHidden: false
|
||||
isUpNextVisible: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -275,52 +272,15 @@ export default Vue.extend({
|
||||
'getCurrentItem',
|
||||
'getPreviousItem',
|
||||
'getNextItem',
|
||||
'getCurrentlyPlayingMediaType',
|
||||
'getDuration',
|
||||
'getTimeLeft'
|
||||
'getCurrentlyPlayingMediaType'
|
||||
]),
|
||||
...mapState('clientSettings', ['darkMode']),
|
||||
...mapState('playbackManager', ['status', 'isMinimized', 'currentTime']),
|
||||
isPlaying(): boolean {
|
||||
return this.status !== PlaybackStatus.Stopped;
|
||||
},
|
||||
isPaused(): boolean {
|
||||
return this.status === PlaybackStatus.Paused;
|
||||
},
|
||||
showUpNext(): boolean {
|
||||
if (
|
||||
this.isMinimized ||
|
||||
this.upNextUserHidden ||
|
||||
this.getCurrentlyPlayingMediaType !== 'Video' ||
|
||||
!this.getNextItem
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// How many seconds left before showing upNext component
|
||||
// Default 45 seconds for 10-45 minute video
|
||||
let showUpNextAt = 45;
|
||||
|
||||
// 5h
|
||||
if (this.getDuration >= 5 * 60 * 60) {
|
||||
// 9 min
|
||||
showUpNextAt = 540;
|
||||
}
|
||||
// 2h
|
||||
else if (this.getDuration >= 2 * 60 * 60) {
|
||||
// 3:30 min
|
||||
showUpNextAt = 210;
|
||||
}
|
||||
// 45 min
|
||||
else if (this.getDuration >= 45 * 60) {
|
||||
// 2 min
|
||||
showUpNextAt = 120;
|
||||
}
|
||||
|
||||
if (this.getTimeLeft >= showUpNextAt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@ -346,125 +306,6 @@ export default Vue.extend({
|
||||
window.addEventListener('keydown', this.handleKeyPress);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'playbackManager/INCREASE_QUEUE_INDEX':
|
||||
case 'playbackManager/DECREASE_QUEUE_INDEX':
|
||||
case 'playbackManager/SET_CURRENT_ITEM_INDEX':
|
||||
this.upNextUserHidden = false;
|
||||
|
||||
// Report playback stop for the previous item
|
||||
if (
|
||||
state.playbackManager.currentTime !== null &&
|
||||
this.getPreviousItem?.Id
|
||||
) {
|
||||
this.$api.playState.reportPlaybackStopped(
|
||||
{
|
||||
playbackStopInfo: {
|
||||
ItemId: this.getPreviousItem.Id,
|
||||
PlaySessionId: state.playbackManager.playSessionId,
|
||||
PositionTicks: this.msToTicks(
|
||||
state.playbackManager.currentTime * 1000
|
||||
)
|
||||
}
|
||||
},
|
||||
{ progress: false }
|
||||
);
|
||||
}
|
||||
|
||||
// Then report the start of the next one
|
||||
if (this.getCurrentItem?.Id) {
|
||||
this.$api.playState.reportPlaybackStart(
|
||||
{
|
||||
playbackStartInfo: {
|
||||
CanSeek: true,
|
||||
ItemId: this.getCurrentItem.Id,
|
||||
PlaySessionId: state.playbackManager.playSessionId,
|
||||
MediaSourceId: state.playbackManager.currentMediaSource?.Id,
|
||||
AudioStreamIndex:
|
||||
state.playbackManager.currentAudioStreamIndex,
|
||||
SubtitleStreamIndex:
|
||||
state.playbackManager.currentSubtitleStreamIndex
|
||||
}
|
||||
},
|
||||
{ progress: false }
|
||||
);
|
||||
|
||||
this.updateMetadata();
|
||||
}
|
||||
|
||||
this.setLastProgressUpdate({ progress: new Date().getTime() });
|
||||
break;
|
||||
case 'playbackManager/SET_CURRENT_TIME': {
|
||||
if (state.playbackManager.status === PlaybackStatus.Playing) {
|
||||
const now = new Date().getTime();
|
||||
|
||||
if (
|
||||
this.getCurrentItem !== null &&
|
||||
now - state.playbackManager.lastProgressUpdate > 1000 &&
|
||||
state.playbackManager.currentTime !== null
|
||||
) {
|
||||
this.$api.playState.reportPlaybackProgress(
|
||||
{
|
||||
playbackProgressInfo: {
|
||||
ItemId: this.getCurrentItem.Id,
|
||||
PlaySessionId: state.playbackManager.playSessionId,
|
||||
IsPaused: false,
|
||||
PositionTicks: Math.round(
|
||||
this.msToTicks(state.playbackManager.currentTime * 1000)
|
||||
)
|
||||
}
|
||||
},
|
||||
{ progress: false }
|
||||
);
|
||||
|
||||
this.setLastProgressUpdate({ progress: new Date().getTime() });
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 'playbackManager/STOP_PLAYBACK':
|
||||
if (state.playbackManager.currentTime !== null) {
|
||||
this.$api.playState.reportPlaybackStopped(
|
||||
{
|
||||
playbackStopInfo: {
|
||||
ItemId: this.getPreviousItem.Id,
|
||||
PlaySessionId: state.playbackManager.playSessionId,
|
||||
PositionTicks: this.msToTicks(
|
||||
state.playbackManager.currentTime * 1000
|
||||
)
|
||||
}
|
||||
},
|
||||
{ progress: false }
|
||||
);
|
||||
|
||||
this.setLastProgressUpdate({ progress: 0 });
|
||||
|
||||
this.resetMetadata();
|
||||
|
||||
this.removeMediaHandlers();
|
||||
}
|
||||
|
||||
break;
|
||||
case 'playbackManager/PAUSE_PLAYBACK':
|
||||
if (state.playbackManager.currentTime !== null) {
|
||||
this.$api.playState.reportPlaybackProgress(
|
||||
{
|
||||
playbackProgressInfo: {
|
||||
ItemId: this.getCurrentItem.Id,
|
||||
PlaySessionId: state.playbackManager.playSessionId,
|
||||
IsPaused: true,
|
||||
PositionTicks: Math.round(
|
||||
this.msToTicks(state.playbackManager.currentTime * 1000)
|
||||
)
|
||||
}
|
||||
},
|
||||
{ progress: false }
|
||||
);
|
||||
|
||||
this.setLastProgressUpdate({ progress: new Date().getTime() });
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -493,6 +334,9 @@ export default Vue.extend({
|
||||
'skipBackward',
|
||||
'changeCurrentTime'
|
||||
]),
|
||||
setUpNextVisible(isVisible: boolean): void {
|
||||
this.isUpNextVisible = isVisible;
|
||||
},
|
||||
getOsdTimeoutDuration(): number {
|
||||
// If we're on mobile, the OSD timer must be longer, to account for the lack of pointer movement
|
||||
if (window.matchMedia('(pointer:fine)').matches) {
|
||||
@ -546,7 +390,6 @@ export default Vue.extend({
|
||||
this.setLastItemIndex();
|
||||
this.resetCurrentItemIndex();
|
||||
this.setNextTrack();
|
||||
this.upNextUserHidden = false;
|
||||
},
|
||||
handleKeyPress(e: KeyboardEvent): void {
|
||||
if (!this.isMinimized && this.isPlaying) {
|
||||
|
@ -37,7 +37,7 @@
|
||||
"details": "Details",
|
||||
"dialog": {
|
||||
"upNext": {
|
||||
"nextItemPlayingIn": "Next Item Playing in",
|
||||
"nextItemPlayingIn": "Starting in {time}",
|
||||
"startNow": "Start now",
|
||||
"hide": "Hide"
|
||||
}
|
||||
@ -70,6 +70,9 @@
|
||||
"bitrate": {
|
||||
"kbps": "{value} kbps",
|
||||
"mbps": "{value} Mbps"
|
||||
},
|
||||
"time": {
|
||||
"seconds": "{count} second | {count} seconds"
|
||||
}
|
||||
},
|
||||
"fullScreen": "Full screen",
|
||||
@ -316,7 +319,6 @@
|
||||
"name": "Search",
|
||||
"topResults": "Top results"
|
||||
},
|
||||
"seconds": "Seconds",
|
||||
"series": "Series",
|
||||
"server": "Server",
|
||||
"serverVersion": "Server version",
|
||||
|
@ -111,24 +111,14 @@ const timeUtils = Vue.extend({
|
||||
* Returns the end time of an item
|
||||
*
|
||||
* @param {number} ticks - Ticks of the item to calculate
|
||||
* @param {boolean} suffix - Whether to add or not the PM or AM prefix
|
||||
* @returns {string} The resulting string
|
||||
*/
|
||||
getEndsAtTime(ticks: number, suffix = true): string {
|
||||
getEndsAtTime(ticks: number): string {
|
||||
const ms = this.ticksToMs(ticks);
|
||||
const endTimeLong = new Date(Date.now() + ms);
|
||||
let format;
|
||||
|
||||
if (!suffix) {
|
||||
format = endTimeLong.toLocaleString(this.$i18n.locale, {
|
||||
hour: 'numeric',
|
||||
minute: 'numeric'
|
||||
});
|
||||
} else {
|
||||
format = this.$dateFns.format(Date.now() + ms, 'p', {
|
||||
locale: this.$i18n.locale
|
||||
});
|
||||
}
|
||||
const format = this.$dateFns.format(Date.now() + ms, 'p', {
|
||||
locale: this.$i18n.locale
|
||||
});
|
||||
|
||||
// TODO: Use a Date object
|
||||
return this.$t('endsAt', {
|
||||
|
@ -5,8 +5,8 @@ import {
|
||||
ChapterInfo,
|
||||
MediaSourceInfo
|
||||
} from '@jellyfin/client-axios';
|
||||
import isNil from 'lodash/isNil';
|
||||
import { RootState } from '.';
|
||||
import { ticksToMs } from '~/mixins/timeUtils';
|
||||
|
||||
export enum PlaybackStatus {
|
||||
Stopped,
|
||||
@ -83,10 +83,7 @@ export const getters: GetterTree<PlaybackManagerState, RootState> = {
|
||||
return rootGetters['items/getItems'](state.queue);
|
||||
},
|
||||
getCurrentItem: (state, _getters, _rootState, rootGetters) => {
|
||||
if (
|
||||
state.currentItemIndex !== null &&
|
||||
state.queue[state.currentItemIndex]
|
||||
) {
|
||||
if (!isNil(state.currentItemIndex) && state.queue[state.currentItemIndex]) {
|
||||
return rootGetters['items/getItem'](state.queue[state.currentItemIndex]);
|
||||
}
|
||||
|
||||
@ -96,7 +93,7 @@ export const getters: GetterTree<PlaybackManagerState, RootState> = {
|
||||
if (state.currentItemIndex === 0) {
|
||||
return null;
|
||||
} else if (
|
||||
state.lastItemIndex !== null &&
|
||||
!isNil(state.lastItemIndex) &&
|
||||
state.queue[state.lastItemIndex]
|
||||
) {
|
||||
return rootGetters['items/getItem'](state.queue[state.lastItemIndex]);
|
||||
@ -106,7 +103,7 @@ export const getters: GetterTree<PlaybackManagerState, RootState> = {
|
||||
},
|
||||
getNextItem: (state, _getters, _rootState, rootGetters) => {
|
||||
if (
|
||||
state.currentItemIndex !== null &&
|
||||
!isNil(state.currentItemIndex) &&
|
||||
state.currentItemIndex + 1 < state.queue.length
|
||||
) {
|
||||
return rootGetters['items/getItem'](
|
||||
@ -119,7 +116,7 @@ export const getters: GetterTree<PlaybackManagerState, RootState> = {
|
||||
return null;
|
||||
},
|
||||
getCurrentlyPlayingType: (state, _getters, _rootState, rootGetters) => {
|
||||
if (state.currentItemIndex !== null) {
|
||||
if (!isNil(state.currentItemIndex)) {
|
||||
return rootGetters['items/getItem'](state.queue?.[state.currentItemIndex])
|
||||
?.Type;
|
||||
}
|
||||
@ -127,7 +124,7 @@ export const getters: GetterTree<PlaybackManagerState, RootState> = {
|
||||
return null;
|
||||
},
|
||||
getCurrentlyPlayingMediaType: (state, _getters, _rootState, rootGetters) => {
|
||||
if (state.currentItemIndex !== null) {
|
||||
if (!isNil(state.currentItemIndex)) {
|
||||
return rootGetters['items/getItem'](state.queue?.[state.currentItemIndex])
|
||||
?.MediaType;
|
||||
}
|
||||
@ -135,7 +132,7 @@ export const getters: GetterTree<PlaybackManagerState, RootState> = {
|
||||
return null;
|
||||
},
|
||||
getCurrentItemSubtitleTracks: (state) => {
|
||||
if (state.currentMediaSource !== null) {
|
||||
if (!isNil(state.currentMediaSource)) {
|
||||
return state.currentMediaSource.MediaStreams?.filter((stream) => {
|
||||
return stream.Type === 'Subtitle';
|
||||
});
|
||||
@ -143,8 +140,8 @@ export const getters: GetterTree<PlaybackManagerState, RootState> = {
|
||||
},
|
||||
getCurrentVideoTrack: (state) => {
|
||||
if (
|
||||
state.currentMediaSource !== null &&
|
||||
state.currentVideoStreamIndex !== undefined
|
||||
!isNil(state.currentMediaSource) &&
|
||||
!isNil(state.currentVideoStreamIndex)
|
||||
) {
|
||||
return state.currentMediaSource.MediaStreams?.filter((stream) => {
|
||||
return stream.Type === 'Video';
|
||||
@ -155,8 +152,8 @@ export const getters: GetterTree<PlaybackManagerState, RootState> = {
|
||||
},
|
||||
getCurrentAudioTrack: (state) => {
|
||||
if (
|
||||
state.currentMediaSource !== null &&
|
||||
state.currentAudioStreamIndex !== undefined
|
||||
!isNil(state.currentMediaSource) &&
|
||||
!isNil(state.currentAudioStreamIndex)
|
||||
) {
|
||||
return state.currentMediaSource.MediaStreams?.filter((stream) => {
|
||||
return stream.Type === 'Audio';
|
||||
@ -167,40 +164,14 @@ export const getters: GetterTree<PlaybackManagerState, RootState> = {
|
||||
},
|
||||
getCurrentSubtitleTrack: (state) => {
|
||||
if (
|
||||
state.currentMediaSource !== null &&
|
||||
state.currentSubtitleStreamIndex !== undefined
|
||||
!isNil(state.currentMediaSource) &&
|
||||
!isNil(state.currentSubtitleStreamIndex)
|
||||
) {
|
||||
return state.currentMediaSource.MediaStreams?.filter((stream) => {
|
||||
return stream.Type === 'Subtitle';
|
||||
})[state.currentSubtitleStreamIndex];
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
getCurrentTime: (state) => {
|
||||
return state.currentTime;
|
||||
},
|
||||
getDuration: (state, _getters, _rootState, rootGetters) => {
|
||||
if (state.currentItemIndex !== null) {
|
||||
const currentItem = rootGetters['items/getItem'](
|
||||
state.queue?.[state.currentItemIndex]
|
||||
);
|
||||
|
||||
return ticksToMs(currentItem?.RunTimeTicks) / 1000;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
getTimeLeft: (state, _getters, _rootState, rootGetters) => {
|
||||
if (state.currentItemIndex !== null && state.currentTime !== null) {
|
||||
const currentItem = rootGetters['items/getItem'](
|
||||
state.queue?.[state.currentItemIndex]
|
||||
);
|
||||
const duration = ticksToMs(currentItem?.RunTimeTicks) / 1000;
|
||||
|
||||
return parseInt((duration - state.currentTime).toFixed());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user