Commit abe0093a authored by Evan You's avatar Evan You

simplify store actions

parent 74736699
......@@ -27,7 +27,6 @@
<script>
import Spinner from './Spinner.vue'
import NewsItem from './NewsItem.vue'
import { fetchInitialData } from '../store'
export default {
name: 'NewsList',
......@@ -76,7 +75,9 @@ export default {
methods: {
loadItems (to, from) {
this.loading = true
fetchInitialData(this.type).then(() => {
this.$store.dispatch('FETCH_DATA_FOR_TYPE', {
type: this.type
}).then(() => {
if (this.page < 0 || this.page > this.maxPage) {
this.$router.replace(`/${this.type}/1`)
return
......
......@@ -8,8 +8,8 @@ export default context => {
// call prefetch hooks on components matched by the route
const s = isDev && Date.now()
return Promise.all(router.getMatchedComponents().map(component => {
if (component.prefetch) {
return component.prefetch(store)
if (component.preFetch) {
return component.preFetch(store)
}
})).then(() => {
isDev && console.log(`data pre-fetch: ${Date.now() - s}ms`)
......
......@@ -36,7 +36,7 @@ function createServerSideAPI () {
// warm the cache every 15 min, since the front page changes quite often
warmCache()
function warmCache () {
fetchItems((api.__topIds__ || []).slice(0, 30))
fetchItems((api.__ids__.top || []).slice(0, 30))
setTimeout(warmCache, 1000 * 60 * 15)
}
......@@ -60,7 +60,7 @@ export function fetchIdsByType (type) {
export function watchTopIds (cb) {
api.child(`topstories`).on('value', snapshot => {
const ids = snapshot.val()
api.__topIds__ = ids
api.__ids__ && (api.__ids__.top = ids)
cb(ids)
})
}
......
......@@ -22,16 +22,12 @@ const store = new Vuex.Store({
},
actions: {
FETCH_ACTIVE_IDS: ({ commit, state }) => {
const type = state.activeType
return fetchIdsByType(type).then(ids => {
commit('SET_IDS', { type, ids })
})
},
FETCH_ACTIVE_ITEMS: ({ commit, state, getters }) => {
return fetchItems(getters.activeIds).then(items => {
commit('SET_ITEMS', { items })
})
FETCH_DATA_FOR_TYPE: ({ commit, dispatch, state, getters }, { type }) => {
commit('SET_ACTIVE_TYPE', { type })
return fetchIdsByType(type)
.then(ids => commit('SET_LIST', { type, ids }))
.then(() => fetchItems(getters.activeIds.filter(id => !state.items[id])))
.then(items => commit('SET_ITEMS', { items }))
}
},
......@@ -39,12 +35,16 @@ const store = new Vuex.Store({
SET_ACTIVE_TYPE: (state, { type }) => {
state.activeType = type
},
SET_IDS: (state, { type, ids }) => {
SET_LIST: (state, { type, ids }) => {
state.lists[type] = ids
},
SET_ITEMS: (state, { items }) => {
items.forEach(item => {
Vue.set(state.items, item.id, item)
if (item) {
Vue.set(state.items, item.id, item)
}
})
}
},
......@@ -61,25 +61,11 @@ const store = new Vuex.Store({
return []
}
},
activeItems (state, getters) {
return getters.activeIds.map(id => state.items[id]).filter(_ => _)
}
}
})
// watch for realtime top IDs updates on the client
if (typeof window !== 'undefined') {
watchTopIds(ids => {
store.commit('SET_IDS', { type: 'top', ids })
store.dispatch('FETCH_ACTIVE_ITEMS')
})
}
export function fetchInitialData (type) {
store.commit('SET_ACTIVE_TYPE', { type })
return store
.dispatch('FETCH_ACTIVE_IDS')
.then(() => store.dispatch('FETCH_ACTIVE_ITEMS'))
}
export default store
import NewsList from '../components/NewsList.vue'
import { fetchInitialData } from '../store'
// factory function for creating root-level list views
// since they share most of the logic except for the type of items to display.
......@@ -9,8 +8,9 @@ export function createListView (type) {
components: {
NewsList
},
prefetch () {
return fetchInitialData(type)
// this will be called during SSR to pre-fetch data into the store!
preFetch (store) {
return store.dispatch('FETCH_DATA_FOR_TYPE', { type })
},
created () {
this.$store.commit('SET_ACTIVE_TYPE', { type })
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment