diff --git a/src/web/components/DropdownBase.vue b/src/web/components/DropdownBase.vue new file mode 100644 index 0000000..9272697 --- /dev/null +++ b/src/web/components/DropdownBase.vue @@ -0,0 +1,39 @@ + + + + + + {{ label }} + + + + + + + + + + + + + + + diff --git a/src/web/components/splatoon/SplatfestHistoryDialog.vue b/src/web/components/splatoon/SplatfestHistoryDialog.vue index 6e68778..737077c 100644 --- a/src/web/components/splatoon/SplatfestHistoryDialog.vue +++ b/src/web/components/splatoon/SplatfestHistoryDialog.vue @@ -1,5 +1,5 @@ - + @@ -8,11 +8,16 @@ - + + + {{ region.name }} + + @@ -54,40 +59,35 @@ import Vue from 'vue'; import { mapGetters } from 'vuex'; import analytics from '@/web/support/analytics'; import Modal from '@/web/components/Modal.vue'; -import Dropdown from '@/web/components/Dropdown.vue'; +import DropdownBase from '@/web/components/DropdownBase.vue'; import SplatfestBox from './SplatfestBox.vue'; import SplatfestResultsBox from './SplatfestResultsBox.vue'; export default { - components: { Modal, Dropdown, SplatfestBox, SplatfestResultsBox }, + components: { Modal, DropdownBase, SplatfestBox, SplatfestResultsBox }, filters: { resultsIn(time) { return Vue.i18n.translate('splatfest.results_in', { time }); }, }, - data() { - return { - region: 'na', - }; - }, + props: ['region'], computed: { ...mapGetters('splatoon', ['now']), - ...mapGetters('splatoon/regions', { initialRegion: 'selectedKey' }), - allSplatfests() { - return { - na: this.$store.getters['splatoon/splatfests/na/allSplatfests'], - eu: this.$store.getters['splatoon/splatfests/eu/allSplatfests'], - jp: this.$store.getters['splatoon/splatfests/jp/allSplatfests'], - }; - }, regions() { return this.$store.state.splatoon.regions.all.map(({ key }) => { let name = (key) ? this.$t(`regions.${key}.name`) : this.$t('regions.global.name'); - return { key, name }; + let route = (key) ? `/splatfests/${key}` : '/splatfests'; + return { key, name, route }; }); }, + selectedRegion() { + let key = this.region || null; + return this.regions.find(r => r.key === key); + }, festivals() { - return this.allSplatfests[this.region]; + if (this.region) + return this.$store.getters[`splatoon/splatfests/${this.region}/allSplatfests`]; + return this.$store.getters['splatoon/splatfests/allSplatfests']; }, }, watch: { @@ -95,10 +95,6 @@ export default { this.scrollToTop(); }, }, - created() { - if (this.initialRegion) - this.region = this.initialRegion; - }, mounted() { analytics.event('Splatfest History', 'Open'); }, diff --git a/src/web/router.js b/src/web/router.js index cb7a33a..6f50b0a 100644 --- a/src/web/router.js +++ b/src/web/router.js @@ -37,8 +37,9 @@ const routes = [ // Splatfests { - path: 'splatfests', + path: 'splatfests/:region(na|eu|jp)?', component: require('./components/splatoon/SplatfestHistoryDialog.vue').default, + props: true, }, // Other/misc diff --git a/src/web/store/splatoon/splatfests.js b/src/web/store/splatoon/splatfests.js index 1c12b85..6a03c38 100644 --- a/src/web/store/splatoon/splatfests.js +++ b/src/web/store/splatoon/splatfests.js @@ -1,6 +1,44 @@ export const namespaced = true; export const getters = { + allSplatfests(state, getters, { splatoon }) { + let now = splatoon.now; + let data = splatoon.data.festivals; + + if (now && data) { + let splatfests = { }; + + for (let region of ['na', 'eu', 'jp']) { + let { festivals, results } = data[region]; + + for (let festival of festivals) { + if (splatfests[festival.festival_id]) { + splatfests[festival.festival_id].regions.push(region); + continue; + } + + let state; + if (festival.times.start > now) + state = 'upcoming'; + else if (festival.times.end > now) + state = 'active'; + else + state = 'past'; + + splatfests[festival.festival_id] = { + ...festival, + regions: [region], + state, + results: results.find(r => r.festival_id === festival.festival_id), + }; + } + } + + return Object.values(splatfests) + .sort((a, b) => b.times.start - a.times.start); + } + }, + anyRegionHasCurrentSplatfest(state, getters, rootState, rootGetters) { return rootGetters['splatoon/splatfests/na/currentSplatfest'] || rootGetters['splatoon/splatfests/eu/currentSplatfest'] @@ -21,29 +59,9 @@ function generateModule(region) { return { namespaced: true, getters: { - allSplatfests(state, getters, { splatoon }) { - let now = splatoon.now; - let data = splatoon.data.festivals && splatoon.data.festivals[region]; - - if (now && data) { - let { festivals, results } = data; - - return festivals.map(festival => { - let state; - if (festival.times.start > now) - state = 'upcoming'; - else if (festival.times.end > now) - state = 'active'; - else - state = 'past'; - - return { - ...festival, - state, - results: results.find(r => r.festival_id === festival.festival_id), - }; - }); - } + allSplatfests(state, getters, rootState, rootGetters) { + return rootGetters['splatoon/splatfests/allSplatfests'] + && rootGetters['splatoon/splatfests/allSplatfests'].filter(s => s.regions.includes(region)); }, currentSplatfest(state, getters, { splatoon }) { let now = splatoon.now;