mirror of
https://github.com/Xevion/the-office.git
synced 2025-12-09 16:08:50 -06:00
redo episode data loading to use Vuex, fix isFetched to use .loaded (MERGE_EPISODE), implement Promise (.then) for FETCH_EPISODE
This commit is contained in:
@@ -7,13 +7,8 @@
|
||||
<b-card class="mb-4">
|
||||
<template v-if="ready">
|
||||
<h3>"{{ episode.title }}"</h3>
|
||||
<span>
|
||||
{{ episode.description }}
|
||||
</span>
|
||||
<CharacterList
|
||||
v-if="episode && episode.characters"
|
||||
:characters="episode.characters"
|
||||
></CharacterList>
|
||||
<span>{{ episode.description }}</span>
|
||||
<CharacterList v-if="episode && episode.characters" :characters="episode.characters"></CharacterList>
|
||||
</template>
|
||||
<template v-else>
|
||||
<Skeleton style="width: 30%;"></Skeleton>
|
||||
@@ -22,25 +17,15 @@
|
||||
<Skeleton style="width: 69%; height: 40%;"></Skeleton>
|
||||
</template>
|
||||
</b-card>
|
||||
<div v-if="episode != null">
|
||||
<b-card
|
||||
v-for="(scene, sceneIndex) in episode.scenes"
|
||||
:key="`scene-${sceneIndex}`"
|
||||
class="mb-1"
|
||||
body-class="p-0"
|
||||
>
|
||||
<div v-if="ready">
|
||||
<b-card v-for="(scene, sceneIndex) in episode.scenes" :key="`scene-${sceneIndex}`" class="mb-1"
|
||||
body-class="p-0">
|
||||
<b-card-text class="my-2">
|
||||
<QuoteList
|
||||
:quotes="scene.quotes"
|
||||
:sceneIndex="sceneIndex"
|
||||
></QuoteList>
|
||||
<span
|
||||
v-if="scene.deleted"
|
||||
class="mt-n2 mb-4 text-muted deleted-scene pl-2"
|
||||
:footer="`Deleted Scene ${scene.deleted}`"
|
||||
>
|
||||
Deleted Scene {{ scene.deleted }}
|
||||
</span>
|
||||
<QuoteList :quotes="scene.quotes" :sceneIndex="sceneIndex"></QuoteList>
|
||||
<span v-if="scene.deleted" class="mt-n2 mb-4 text-muted deleted-scene pl-2"
|
||||
:footer="`Deleted Scene ${scene.deleted}`">
|
||||
Deleted Scene {{ scene.deleted }}
|
||||
</span>
|
||||
</b-card-text>
|
||||
</b-card>
|
||||
</div>
|
||||
@@ -51,6 +36,7 @@
|
||||
.breadcrumb-skeleton {
|
||||
background-color: $grey-3;
|
||||
height: 48px;
|
||||
|
||||
& > .card-body {
|
||||
padding: 0 0 0 1em;
|
||||
display: flex;
|
||||
@@ -72,10 +58,10 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import QuoteList from "./QuoteList.vue";
|
||||
import CharacterList from "./CharacterList.vue";
|
||||
import Skeleton from './Skeleton.vue';
|
||||
import {types} from "@/mutation_types";
|
||||
|
||||
export default {
|
||||
name: "Episode",
|
||||
@@ -84,47 +70,45 @@ export default {
|
||||
CharacterList,
|
||||
Skeleton,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
episode: null,
|
||||
};
|
||||
created() {
|
||||
this.fetch();
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.$nextTick(() => {
|
||||
this.fetch();
|
||||
// this.$store.dispatch(types.FETCH_EPISODE, {season: this.params.season, episode: this.params.episode})
|
||||
})
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getEpisode() {
|
||||
const path = `${process.env.VUE_APP_API_URL}/api/episode/\
|
||||
${this.$route.params.season}/${this.$route.params.episode}/`;
|
||||
axios
|
||||
.get(path)
|
||||
.then((res) => {
|
||||
this.episode = res.data;
|
||||
// Scroll
|
||||
fetch() {
|
||||
// Fetch the episode, then scroll - already fetched episode should scroll immediately
|
||||
this.$store.dispatch(types.FETCH_EPISODE, {season: this.params.season, episode: this.params.episode})
|
||||
.then(() => {
|
||||
// Force update, as for some reason it doesn't update naturally. I hate it too.
|
||||
this.$forceUpdate()
|
||||
|
||||
// Scroll down to quote
|
||||
if (this.$route.hash) {
|
||||
this.$nextTick(() => {
|
||||
const section = document.getElementById(this.$route.hash.substring(1));
|
||||
this.$scrollTo(section, 500, {easing: "ease-in"});
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getEpisode();
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.episode = null;
|
||||
this.$nextTick(() => {
|
||||
this.getEpisode();
|
||||
})
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
episode() {
|
||||
return this.$store.getters.getEpisode(this.params.season, this.params.episode)
|
||||
// return this.$store.state.quoteData[this.params.season - 1].episodes[this.params.episode - 1];
|
||||
},
|
||||
params() {
|
||||
return this.$route.params
|
||||
},
|
||||
ready() {
|
||||
return this.episode !== null
|
||||
return this.$store.getters.isFetched(this.params.season, this.params.episode)
|
||||
},
|
||||
breadcrumbs() {
|
||||
return [
|
||||
|
||||
@@ -10,9 +10,9 @@ const episodeCount = [6, 22, 23, 14, 26, 24, 24, 24, 23];
|
||||
const baseData = Array.from({length: 9}, (x, season) => {
|
||||
// Array of null values representing each episode
|
||||
const episodeData = Array.from({length: episodeCount[season]}, (x, episode) => {
|
||||
return { episode_id: episode + 1, loaded: false }
|
||||
return {episode_id: episode + 1, loaded: false}
|
||||
})
|
||||
return {season_id: season + 1, episodes: episodeData };
|
||||
return {season_id: season + 1, episodes: episodeData};
|
||||
})
|
||||
|
||||
export default new Vuex.Store({
|
||||
@@ -30,43 +30,48 @@ export default new Vuex.Store({
|
||||
const s = payload.season - 1;
|
||||
const e = payload.episode - 1;
|
||||
state.quoteData[s].episodes[e] = Object.assign(state.quoteData[s].episodes[e], payload.episodeData);
|
||||
if (payload.episodeData.scenes !== null)
|
||||
state.quoteData[s].episodes[e].loaded = true;
|
||||
},
|
||||
[types.SET_PRELOADED](state, status) {
|
||||
state.preloaded = status;
|
||||
},
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
// Perform async API call to fetch specific Episode data
|
||||
[types.FETCH_EPISODE]({commit}, season, episode) {
|
||||
const path = `${process.env.VUE_APP_API_URL}/api/episode/${season}/${episode}/`;
|
||||
|
||||
axios.get(path)
|
||||
.then((res) => {
|
||||
// Push episode data
|
||||
commit(types.SET_EPISODE, {season: season, episode: episode, data: res.data})
|
||||
})
|
||||
.catch((error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
});
|
||||
[types.FETCH_EPISODE]({commit}, payload) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const path = `${process.env.VUE_APP_API_URL}/api/episode/${payload.season}/${payload.episode}/`;
|
||||
axios.get(path)
|
||||
.then((res) => {
|
||||
// Push episode data
|
||||
commit(types.MERGE_EPISODE, {
|
||||
season: payload.season,
|
||||
episode: payload.episode,
|
||||
episodeData: res.data
|
||||
})
|
||||
resolve()
|
||||
})
|
||||
.catch((error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
reject()
|
||||
});
|
||||
})
|
||||
},
|
||||
[types.PRELOAD]({commit}) {
|
||||
const path = `${process.env.VUE_APP_API_URL}/api/episodes/`;
|
||||
console.log('preload axios')
|
||||
axios.get(path)
|
||||
.then((res) => {
|
||||
for (const season of res.data) {
|
||||
for (const season of res.data)
|
||||
for (const episode of season.episodes) {
|
||||
// Create payload and commit for each episode
|
||||
commit(
|
||||
types.MERGE_EPISODE,
|
||||
{
|
||||
season: season.season_id,
|
||||
episode: episode.episode_id,
|
||||
episodeData: episode
|
||||
}
|
||||
)
|
||||
}
|
||||
commit(types.MERGE_EPISODE, {
|
||||
season: season.season_id,
|
||||
episode: episode.episode_id,
|
||||
episodeData: episode
|
||||
})
|
||||
}
|
||||
|
||||
commit(types.SET_PRELOADED, true);
|
||||
@@ -80,7 +85,8 @@ export default new Vuex.Store({
|
||||
getters: {
|
||||
// Check whether a episode has been fetched yet
|
||||
isFetched: (state) => (season, episode) => {
|
||||
return state.quoteData[season - 1].episodes[episode] !== null;
|
||||
const ep = state.quoteData[season - 1].episodes[episode - 1];
|
||||
return ep !== null && ep.loaded;
|
||||
},
|
||||
// Get the number of episodes present for a given season
|
||||
getEpisodeCount: (state) => (season) => {
|
||||
@@ -88,9 +94,9 @@ export default new Vuex.Store({
|
||||
},
|
||||
// return Episode data if present
|
||||
getEpisode: (state, getters) => (season, episode) => {
|
||||
if (getters.isFetched(season, episode))
|
||||
return state.quoteData[season]
|
||||
else
|
||||
if (getters.isFetched(season, episode)) {
|
||||
return state.quoteData[season - 1].episodes[episode - 1];
|
||||
} else
|
||||
return null
|
||||
},
|
||||
// return true if a specific episode is valid
|
||||
|
||||
Reference in New Issue
Block a user