mirror of
https://github.com/jellyfin/jellyfin-vue.git
synced 2024-10-07 03:23:37 +00:00
Merge 'master' into 'refactor-img-mixin'
This commit is contained in:
commit
dd06b0ee8d
@ -2,13 +2,12 @@
|
||||
<v-menu offset-y>
|
||||
<template #activator="{ on, attrs }">
|
||||
<div class="d-flex align-center" v-bind="attrs" v-on="on">
|
||||
<v-avatar size="48" color="primary" class="mr-4">
|
||||
<v-img
|
||||
v-if="userImage"
|
||||
:src="userImage"
|
||||
:alt="$auth.user.Name"
|
||||
></v-img>
|
||||
<v-icon v-else dark>mdi-account</v-icon>
|
||||
<v-avatar :size="avatarSize" color="primary" class="mr-4">
|
||||
<v-img :src="userImage" :alt="$auth.user.Name">
|
||||
<template #placeholder>
|
||||
<v-icon dark>mdi-account</v-icon>
|
||||
</template>
|
||||
</v-img>
|
||||
</v-avatar>
|
||||
<h1 class="font-weight-light pb-1">
|
||||
{{ $auth.user.Name }}
|
||||
@ -35,6 +34,7 @@ import { mapActions } from 'vuex';
|
||||
export default Vue.extend({
|
||||
data() {
|
||||
return {
|
||||
avatarSize: 48,
|
||||
menuItems: [
|
||||
{
|
||||
title: this.$t('logout'),
|
||||
@ -48,13 +48,11 @@ export default Vue.extend({
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
userImage: {
|
||||
get() {
|
||||
if (this.$auth.user?.PrimaryImageTag) {
|
||||
return `${this.$axios.defaults.baseURL}/Users/${this.$auth.user.Id}/Images/Primary/?tag=${this.$auth.user.PrimaryImageTag}&maxWidth=36`;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
userImage(): string {
|
||||
if (this.$auth.user?.PrimaryImageTag) {
|
||||
return `${this.$axios.defaults.baseURL}/Users/${this.$auth.user.Id}/Images/Primary/?tag=${this.$auth.user.PrimaryImageTag}&maxWidth=${this.avatarSize}`;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1,7 +1,16 @@
|
||||
<template>
|
||||
<v-container fill-height fluid class="pa-0">
|
||||
<div ref="videoContainer">
|
||||
<video ref="videoPlayer" :poster="poster" autoplay></video>
|
||||
<video
|
||||
ref="videoPlayer"
|
||||
:poster="poster"
|
||||
autoplay
|
||||
@playing="onVideoPlaying"
|
||||
@timeupdate="onVideoProgress"
|
||||
@pause="onVideoPause"
|
||||
@play="onVideoProgress"
|
||||
@ended="onVideoStopped"
|
||||
></video>
|
||||
</div>
|
||||
</v-container>
|
||||
</template>
|
||||
@ -17,6 +26,8 @@ import shaka from 'shaka-player/dist/shaka-player.ui';
|
||||
import muxjs from 'mux.js';
|
||||
import { mapActions } from 'vuex';
|
||||
import 'shaka-player/dist/controls.css';
|
||||
import { PlaybackInfoResponse } from '@jellyfin/client-axios';
|
||||
import timeUtils from '~/mixins/timeUtils';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
@ -26,6 +37,7 @@ declare global {
|
||||
}
|
||||
|
||||
export default Vue.extend({
|
||||
mixins: [timeUtils],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
@ -38,6 +50,8 @@ export default Vue.extend({
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
playbackInfo: {} as PlaybackInfoResponse,
|
||||
lastProgressUpdate: 0,
|
||||
source: '',
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
player: null as any,
|
||||
@ -51,27 +65,24 @@ export default Vue.extend({
|
||||
try {
|
||||
await this.player.load(newSource);
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Error code', e.code, 'object', e);
|
||||
this.pushSnackbarMessage({
|
||||
message: this.$t('unexpectedError'),
|
||||
error: 'error'
|
||||
});
|
||||
// No need to actually process the error here, the error handler will do this for us
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
try {
|
||||
const response = await this.$api.mediaInfo.getPostedPlaybackInfo({
|
||||
itemId: this.$route.params.itemId,
|
||||
userId: this.$auth.user.Id,
|
||||
...this.$playbackProfile
|
||||
});
|
||||
this.playbackInfo = (
|
||||
await this.$api.mediaInfo.getPostedPlaybackInfo({
|
||||
itemId: this.$route.params.itemId,
|
||||
userId: this.$auth.user.Id,
|
||||
playbackInfoDto: { DeviceProfile: this.$playbackProfile }
|
||||
})
|
||||
).data;
|
||||
|
||||
let mediaSource;
|
||||
if (response?.data?.MediaSources) {
|
||||
mediaSource = response.data.MediaSources[0];
|
||||
if (this.playbackInfo?.MediaSources) {
|
||||
mediaSource = this.playbackInfo.MediaSources[0];
|
||||
} else {
|
||||
throw new Error("This item can't be played.");
|
||||
}
|
||||
@ -113,6 +124,8 @@ export default Vue.extend({
|
||||
this.$refs.videoContainer,
|
||||
this.$refs.videoPlayer
|
||||
);
|
||||
// Register player events
|
||||
this.player.addEventListener('error', this.onPlayerError);
|
||||
} else {
|
||||
this.$nuxt.error({
|
||||
message: this.$t('browserNotSupported') as string
|
||||
@ -128,12 +141,99 @@ export default Vue.extend({
|
||||
beforeDestroy() {
|
||||
if (this.player) {
|
||||
window.muxjs = undefined;
|
||||
this.onVideoStopped(); // Report that the playback is stopping
|
||||
this.player.removeEventListener('error', this.onPlayerError);
|
||||
this.player.unload();
|
||||
this.player.destroy();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('snackbar', ['pushSnackbarMessage'])
|
||||
...mapActions('snackbar', ['pushSnackbarMessage']),
|
||||
onVideoPlaying(_event: Event) {
|
||||
// TODO: Move to playback manager
|
||||
this.$api.playState.reportPlaybackStart(
|
||||
{
|
||||
playbackStartInfo: {
|
||||
CanSeek: true,
|
||||
ItemId: this.item.Id,
|
||||
PlaySessionId: this.playbackInfo.PlaySessionId,
|
||||
MediaSourceId: this.playbackInfo.MediaSources?.[0].Id,
|
||||
AudioStreamIndex: 0, // TODO: Don't hardcode this
|
||||
SubtitleStreamIndex: 0 // TODO: Don't hardcode this
|
||||
}
|
||||
},
|
||||
{ progress: false }
|
||||
);
|
||||
|
||||
this.lastProgressUpdate = new Date().getTime();
|
||||
},
|
||||
onVideoProgress(_event?: Event) {
|
||||
// TODO: Move to playback manager
|
||||
const now = new Date().getTime();
|
||||
|
||||
if (now - this.lastProgressUpdate > 1000) {
|
||||
const currentTime = (this.$refs.videoPlayer as HTMLVideoElement)
|
||||
.currentTime;
|
||||
|
||||
this.$api.playState.reportPlaybackProgress(
|
||||
{
|
||||
playbackProgressInfo: {
|
||||
ItemId: this.item.Id,
|
||||
PlaySessionId: this.playbackInfo.PlaySessionId,
|
||||
IsPaused: false,
|
||||
PositionTicks: Math.round(this.msToTicks(currentTime * 1000))
|
||||
}
|
||||
},
|
||||
{ progress: false }
|
||||
);
|
||||
|
||||
this.lastProgressUpdate = new Date().getTime();
|
||||
}
|
||||
},
|
||||
onVideoPause(_event?: Event) {
|
||||
// TODO: Move to playback manager
|
||||
const currentTime = (this.$refs.videoPlayer as HTMLVideoElement)
|
||||
.currentTime;
|
||||
|
||||
this.$api.playState.reportPlaybackProgress(
|
||||
{
|
||||
playbackProgressInfo: {
|
||||
ItemId: this.item.Id,
|
||||
PlaySessionId: this.playbackInfo.PlaySessionId,
|
||||
IsPaused: true,
|
||||
PositionTicks: Math.round(this.msToTicks(currentTime * 1000))
|
||||
}
|
||||
},
|
||||
{ progress: false }
|
||||
);
|
||||
},
|
||||
onVideoStopped(_event?: Event) {
|
||||
// TODO: Move to playback manager
|
||||
const currentTime = (this.$refs.videoPlayer as HTMLVideoElement)
|
||||
.currentTime;
|
||||
|
||||
this.$api.playState.reportPlaybackStopped(
|
||||
{
|
||||
playbackStopInfo: {
|
||||
ItemId: this.item.Id,
|
||||
PlaySessionId: this.playbackInfo.PlaySessionId,
|
||||
PositionTicks: this.msToTicks(currentTime * 1000)
|
||||
}
|
||||
},
|
||||
{ progress: false }
|
||||
);
|
||||
|
||||
this.lastProgressUpdate = 0;
|
||||
|
||||
if (event !== undefined) {
|
||||
// We're coming from a real end of playback event, so avoid staying on the video screen after playback
|
||||
// TODO: Once in the playback manager, move this to the end of the queue
|
||||
this.$router.back();
|
||||
}
|
||||
},
|
||||
onPlayerError(event: Event) {
|
||||
this.$emit('error', event);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -94,5 +94,15 @@
|
||||
"numberTracks": "{number} skladeb",
|
||||
"nextUp": "Další v pořadí",
|
||||
"latestLibrary": "Nejnovější {libraryName}",
|
||||
"darkModeToggle": "Přepnout tmavý režim"
|
||||
"darkModeToggle": "Přepnout tmavý režim",
|
||||
"errors": {
|
||||
"messages": {
|
||||
"videoPlayerError": "Ve video přehrávači došlo k nezvratné chybě.",
|
||||
"errorCode": "Kód chyby: {errorCode}"
|
||||
},
|
||||
"anErrorHappened": "Došlo k chybě"
|
||||
},
|
||||
"buttons": {
|
||||
"ok": "Ok"
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,9 @@
|
||||
"badRequest": "Bad request. Try again",
|
||||
"biography": "Biography",
|
||||
"browserNotSupported": "Your browser is not supported for playing this file.",
|
||||
"buttons": {
|
||||
"ok": "Ok"
|
||||
},
|
||||
"byArtist": "By",
|
||||
"changeServer": "Change server",
|
||||
"changeUser": "Change user",
|
||||
@ -19,6 +22,13 @@
|
||||
"dislikes": "Dislikes",
|
||||
"endDate": "End date",
|
||||
"endsAt": "Ends at {time}",
|
||||
"errors": {
|
||||
"anErrorHappened": "An error happened",
|
||||
"messages": {
|
||||
"errorCode": "Error code: {errorCode}",
|
||||
"videoPlayerError": "The video player encountered an unrecoverable error."
|
||||
}
|
||||
},
|
||||
"episodeNumber": "Episode {episodeNumber}",
|
||||
"failedToRefreshItems": "Failed to refresh items",
|
||||
"favorite": "Favorite",
|
||||
@ -47,9 +57,8 @@
|
||||
"networks": "Networks",
|
||||
"nextUp": "Next up",
|
||||
"noNetworkConnection": "No network connection",
|
||||
"noResultsFound": "No results found",
|
||||
"numberTracks": "{number} tracks",
|
||||
"noResultsFound": "There is nothing here",
|
||||
"numberTracks": "{number} tracks",
|
||||
"parentalRatings": "Parental Ratings",
|
||||
"password": "Password",
|
||||
"play": "Play",
|
||||
|
@ -84,5 +84,15 @@
|
||||
"required": "Este campo es obligatorio"
|
||||
},
|
||||
"shuffleAll": "Mezclar todo",
|
||||
"libraries": "Bibliotecas"
|
||||
"libraries": "Bibliotecas",
|
||||
"errors": {
|
||||
"messages": {
|
||||
"errorCode": "Código de error: {errorCode}"
|
||||
},
|
||||
"anErrorHappened": "Ocurrió un error"
|
||||
},
|
||||
"darkModeToggle": "Cambiar a modo oscuro",
|
||||
"buttons": {
|
||||
"ok": "Vale"
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
"rating": "Beoordeling",
|
||||
"releaseDate": "Publicatiedatum",
|
||||
"serverAddress": "Server adres",
|
||||
"serverAddressMustBeUrl": "Server adres moet een geldige URL zijn",
|
||||
"serverAddressMustBeUrl": "Server adres moet een geldig adres zijn",
|
||||
"serverAddressRequired": "Server adres is verplicht",
|
||||
"serverNotFound": "Server niet gevonden",
|
||||
"settings": "Instellingen",
|
||||
@ -59,7 +59,7 @@
|
||||
"connect": "Verbinden",
|
||||
"changeServer": "Verander van server",
|
||||
"browserNotSupported": "Uw browser kan dit bestandstype niet afspelen.",
|
||||
"studios": "Studios",
|
||||
"studios": "Studio's",
|
||||
"series": "Series",
|
||||
"selectUser": "Selecteer een gebruiker",
|
||||
"noResultsFound": "Er is hier niets",
|
||||
@ -75,5 +75,12 @@
|
||||
"artists": "Artiesten",
|
||||
"artist": "Artiest",
|
||||
"albums": "Albums",
|
||||
"actors": "Acteurs"
|
||||
"actors": "Acteurs",
|
||||
"libraries": "Bibliotheken",
|
||||
"byArtist": "Door",
|
||||
"viewDetails": "Bekijk details",
|
||||
"validation": {
|
||||
"required": "Dit veld is vereist",
|
||||
"mustBeUrl": "Dit veld moet een geldige URL zijn"
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
"home": "Domov",
|
||||
"incorrectUsernameOrPassword": "Nesprávne používateľské meno alebo heslo",
|
||||
"itemNotFound": "Položka nebola nájdená",
|
||||
"libraryEmpty": "Knižnica je prázdna",
|
||||
"libraryEmpty": "Táto knižnica je prázdna",
|
||||
"libraryNotFound": "Knižnica nebola nájdená",
|
||||
"login": "Prihlásenie",
|
||||
"logout": "Odhlásenie",
|
||||
@ -23,7 +23,7 @@
|
||||
"rating": "Hodnotenie",
|
||||
"releaseDate": "Dátum vydania",
|
||||
"serverAddress": "Adresa servera",
|
||||
"serverAddressMustBeUrl": "Adresa servera musí byť platná URL",
|
||||
"serverAddressMustBeUrl": "Adresa servera musí byť platná adresa",
|
||||
"serverAddressRequired": "Adresa servera je požadovaná",
|
||||
"serverNotFound": "Server nebol nájdený",
|
||||
"settings": "Nastavenia",
|
||||
@ -32,28 +32,66 @@
|
||||
"upNext": "Nasleduje",
|
||||
"username": "Používateľské meno",
|
||||
"usernameRequired": "Používateľské meno je požadované",
|
||||
"youMayAlsoLike": "",
|
||||
"youMayAlsoLike": "Mohlo by sa vám páčiť",
|
||||
"years": "Roky",
|
||||
"videoTypes": "Typy videa",
|
||||
"parentalRatings": "Rodičovské hodnotenie",
|
||||
"genres": "Žánre",
|
||||
"themeVideo": "Úvodné video",
|
||||
"themeSong": "Úvodná zvučka",
|
||||
"specialFeatures": "Special Features",
|
||||
"themeVideo": "Tématické video",
|
||||
"themeSong": "Tématická hudba",
|
||||
"specialFeatures": "Bonusový materiál",
|
||||
"trailer": "Trailer",
|
||||
"subtitles": "Titulky",
|
||||
"features": "Features",
|
||||
"dislikes": "Nepáči sa mi",
|
||||
"likes": "Páči sa mi",
|
||||
"favorite": "Obľúbené",
|
||||
"resumable": "Možné pokračovať",
|
||||
"resumable": "Pozastaviteľný",
|
||||
"unplayed": "Neprehrané",
|
||||
"played": "Prehrané",
|
||||
"status": "Stav",
|
||||
"filtersNotFound": "Filtre sa nedajú načitať",
|
||||
"filtersNotFound": "Filtre sa nedajú načítať",
|
||||
"unhandledException": "Neošetrená výnimka",
|
||||
"shows": "Seriály",
|
||||
"serverVersionTooLow": "Verzia serveru musí byt 10.7.0 nebo novšia",
|
||||
"noNetworkConnection": "Žiadne pripojenie k sieti",
|
||||
"browserNotSupported": "Prehrávanie tohto súboru nie je podporované vo vašom prehliadači."
|
||||
"browserNotSupported": "Prehrávanie tohto súboru nie je podporované vo vašom prehliadači.",
|
||||
"nextUp": "Nasleduje",
|
||||
"networks": "Siete",
|
||||
"name": "Názov",
|
||||
"moreLikeArtist": "Podobné ako {artist}",
|
||||
"manualLogin": "Manuálne prihlásenie",
|
||||
"loginAs": "Prihlásiť sa ako {name}",
|
||||
"liked": "Páči sa mi to",
|
||||
"libraries": "Knižnice",
|
||||
"latestLibrary": "Najnovšie {libraryName}",
|
||||
"filter": "Filter",
|
||||
"failedToRefreshItems": "Obnovenie položiek zlyhalo",
|
||||
"disc": "Disk {discNumber}",
|
||||
"darkModeToggle": "Prepnúť na tmavý režim",
|
||||
"connect": "Pripojiť",
|
||||
"collections": "Kolekcie",
|
||||
"changeUser": "Zmeniť používateľa",
|
||||
"changeServer": "Zmeniť server",
|
||||
"byArtist": "Od",
|
||||
"biography": "Biografia",
|
||||
"artists": "Interpreti",
|
||||
"artist": "Interpret",
|
||||
"albums": "Albumy",
|
||||
"actors": "Herci",
|
||||
"viewDetails": "Zobraziť detaily",
|
||||
"validation": {
|
||||
"required": "Toto pole je vyžadované",
|
||||
"mustBeUrl": "Toto pole musí byť platná URL"
|
||||
},
|
||||
"unliked": "Nepáči sa mi to",
|
||||
"unableGetRelated": "Načítanie súvisiacich položiek nebolo možné",
|
||||
"studios": "Štúdiá",
|
||||
"sortByType": "Podľa {type}",
|
||||
"shuffleAll": "Zamiešať všetko",
|
||||
"series": "Seriály",
|
||||
"selectUser": "Vybrať používateľa",
|
||||
"selectServer": "Vybrať server",
|
||||
"numberTracks": "{number} stôp",
|
||||
"noResultsFound": "Nič tu nie je"
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ const imageHelper = Vue.extend({
|
||||
} else if (maxHeight) {
|
||||
params.maxHeight = maxHeight;
|
||||
}
|
||||
|
||||
url.search = stringify(params);
|
||||
|
||||
return url.toString();
|
||||
|
36
mixins/modalHelper.ts
Normal file
36
mixins/modalHelper.ts
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Helpers for modals
|
||||
*
|
||||
* @mixin
|
||||
*/
|
||||
import Vue from 'vue';
|
||||
|
||||
declare module '@nuxt/types' {
|
||||
interface Context {
|
||||
smallModalWidth: () => string | number;
|
||||
}
|
||||
|
||||
interface NuxtAppOptions {
|
||||
smallModalWidth: () => string | number;
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'vue/types/vue' {
|
||||
interface Vue {
|
||||
smallModalWidth: () => string | number;
|
||||
}
|
||||
}
|
||||
|
||||
const modalHelper = Vue.extend({
|
||||
computed: {
|
||||
smallModalWidth(): string | number {
|
||||
if (this.$vuetify.breakpoint.smAndDown) {
|
||||
return '90%';
|
||||
} else {
|
||||
return 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default modalHelper;
|
@ -79,9 +79,9 @@
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-jsdoc": "^30.7.8",
|
||||
"eslint-plugin-nuxt": "^2.0.0",
|
||||
"eslint-plugin-prettier": "^3.2.0",
|
||||
"eslint-plugin-prettier": "^3.3.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"husky": "^4.3.5",
|
||||
"husky": "^4.3.6",
|
||||
"jest": "^26.6.3",
|
||||
"jest-canvas-mock": "^2.3.0",
|
||||
"lint-staged": "^10.5.3",
|
||||
|
@ -4,22 +4,52 @@
|
||||
v-if="item.MediaType === 'Video' || item.MediaType === 'Audio'"
|
||||
:item="item"
|
||||
:poster="poster"
|
||||
@error="handleShakaPlayerError"
|
||||
/>
|
||||
|
||||
<v-dialog v-model="errorDialog" :width="smallModalWidth">
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
{{ $t('errors.anErrorHappened') }}
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text>
|
||||
<p>{{ $t('errors.messages.videoPlayerError') }}</p>
|
||||
|
||||
<p class="mb-0">
|
||||
{{ $t('errors.messages.errorCode', { errorCode }) }}
|
||||
</p>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<v-btn color="primary" text @click="dismissError">
|
||||
{{ $t('buttons.ok') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { Route } from 'vue-router';
|
||||
import { BaseItemDto, ImageType } from '@jellyfin/client-axios';
|
||||
import modalHelper from '~/mixins/modalHelper';
|
||||
import imageHelper from '~/mixins/imageHelper';
|
||||
|
||||
export default Vue.extend({
|
||||
mixins: [imageHelper],
|
||||
mixins: [imageHelper, modalHelper],
|
||||
layout: 'fullpage',
|
||||
data() {
|
||||
return {
|
||||
poster: '',
|
||||
item: [] as BaseItemDto
|
||||
errorCode: '',
|
||||
errorDialog: false,
|
||||
fromRoute: null as null | Route,
|
||||
item: [] as BaseItemDto,
|
||||
poster: ''
|
||||
};
|
||||
},
|
||||
async beforeMount() {
|
||||
@ -45,6 +75,20 @@ export default Vue.extend({
|
||||
message: error
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleShakaPlayerError(error: any) {
|
||||
if (error?.detail?.severity === 1) {
|
||||
// This error is recoverable, ignore for now
|
||||
} else {
|
||||
this.errorCode = error?.detail?.code;
|
||||
this.errorDialog = true;
|
||||
}
|
||||
},
|
||||
dismissError() {
|
||||
this.errorDialog = false;
|
||||
this.$router.back();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -6,7 +6,13 @@ import {
|
||||
} from '@jellyfin/client-axios';
|
||||
|
||||
export interface TvShowsState {
|
||||
/**
|
||||
* seasons: Stores an array of all seasons
|
||||
*/
|
||||
seasons: BaseItemDto[];
|
||||
/**
|
||||
* seasonEpisodes: Stores an array for each season containing all the season episodes
|
||||
*/
|
||||
seasonEpisodes: BaseItemDto[][];
|
||||
}
|
||||
|
||||
@ -15,17 +21,20 @@ export const state = (): TvShowsState => ({
|
||||
seasonEpisodes: []
|
||||
});
|
||||
|
||||
type MutationPayload = TvShowsState;
|
||||
type MutationPayload = {
|
||||
seasons: BaseItemDto[];
|
||||
seasonEpisodes: BaseItemDto[];
|
||||
};
|
||||
|
||||
export const mutations: MutationTree<TvShowsState> = {
|
||||
ADD_TVSHOW_SEASONS(state: TvShowsState, { seasons }: MutationPayload) {
|
||||
state.seasons.push(...seasons);
|
||||
state.seasons = seasons;
|
||||
},
|
||||
ADD_TVSHOW_SEASON_EPISODES(
|
||||
state: TvShowsState,
|
||||
{ seasonEpisodes }: MutationPayload
|
||||
) {
|
||||
state.seasonEpisodes.push(...seasonEpisodes);
|
||||
state.seasonEpisodes.push(seasonEpisodes);
|
||||
},
|
||||
CLEAR_TVSHOWS_SEASONS(state: TvShowsState) {
|
||||
state.seasons = [];
|
||||
|
16
yarn.lock
16
yarn.lock
@ -5411,10 +5411,10 @@ eslint-plugin-nuxt@^2.0.0:
|
||||
semver "^7.3.2"
|
||||
vue-eslint-parser "^7.1.1"
|
||||
|
||||
eslint-plugin-prettier@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.2.0.tgz#af391b2226fa0e15c96f36c733f6e9035dbd952c"
|
||||
integrity sha512-kOUSJnFjAUFKwVxuzy6sA5yyMx6+o9ino4gCdShzBNx4eyFRudWRYKCFolKjoM40PEiuU6Cn7wBLfq3WsGg7qg==
|
||||
eslint-plugin-prettier@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.0.tgz#61e295349a65688ffac0b7808ef0a8244bdd8d40"
|
||||
integrity sha512-tMTwO8iUWlSRZIwS9k7/E4vrTsfvsrcM5p1eftyuqWH25nKsz/o6/54I7jwQ/3zobISyC7wMy9ZsFwgTxOcOpQ==
|
||||
dependencies:
|
||||
prettier-linter-helpers "^1.0.0"
|
||||
|
||||
@ -6810,10 +6810,10 @@ human-signals@^1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
|
||||
integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
|
||||
|
||||
husky@^4.3.5:
|
||||
version "4.3.5"
|
||||
resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.5.tgz#ab8d2a0eb6b62fef2853ee3d442c927d89290902"
|
||||
integrity sha512-E5S/1HMoDDaqsH8kDF5zeKEQbYqe3wL9zJDyqyYqc8I4vHBtAoxkDBGXox0lZ9RI+k5GyB728vZdmnM4bYap+g==
|
||||
husky@^4.3.6:
|
||||
version "4.3.6"
|
||||
resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.6.tgz#ebd9dd8b9324aa851f1587318db4cccb7665a13c"
|
||||
integrity sha512-o6UjVI8xtlWRL5395iWq9LKDyp/9TE7XMOTvIpEVzW638UcGxTmV5cfel6fsk/jbZSTlvfGVJf2svFtybcIZag==
|
||||
dependencies:
|
||||
chalk "^4.0.0"
|
||||
ci-info "^2.0.0"
|
||||
|
Loading…
Reference in New Issue
Block a user