Skip to content

Commit 8db2ee9

Browse files
committed
realtime updates
1 parent 55122ca commit 8db2ee9

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed

src/components/NewsList.vue

+14-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
<script>
2828
import Spinner from './Spinner.vue'
2929
import NewsItem from './NewsItem.vue'
30+
import { watchList } from '../store/api'
3031
3132
export default {
3233
name: 'NewsList',
@@ -46,7 +47,9 @@ export default {
4647
loading: false,
4748
transition: 'slide-left',
4849
// if this is the initial render, directly render with the store state
49-
// otherwise this is a page switch, start with blank and wait for data load
50+
// otherwise this is a page switch, start with blank and wait for data load.
51+
// we need these local state so that we can precisely control the timing
52+
// of the transitions.
5053
displayedPage: isInitialRender ? Number(this.$store.state.route.params.page) || 1 : -1,
5154
displayedItems: isInitialRender ? this.$store.getters.activeItems : []
5255
}
@@ -69,6 +72,16 @@ export default {
6972
if (this.$root._isMounted) {
7073
this.loadItems(this.page)
7174
}
75+
this.unwatchList = watchList(this.type, ids => {
76+
this.$store.commit('SET_LIST', { type: this.type, ids })
77+
this.$store.dispatch('FETCH_ACTIVE_ITEMS').then(() => {
78+
this.displayedItems = this.$store.getters.activeItems
79+
})
80+
})
81+
},
82+
83+
destroyed () {
84+
this.unwatchList()
7285
},
7386
7487
watch: {

src/store/api.js

+16
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,19 @@ export function fetchItem (id, forceRefresh) {
7171
export function fetchItems (ids) {
7272
return Promise.all(ids.map(id => fetchItem(id)))
7373
}
74+
75+
export function watchList (type, cb) {
76+
let first = true
77+
const ref = api.child(`${type}stories`)
78+
const handler = snapshot => {
79+
if (first) {
80+
first = false
81+
} else {
82+
cb(snapshot.val())
83+
}
84+
}
85+
ref.on('value', handler)
86+
return () => {
87+
ref.off('value', handler)
88+
}
89+
}

src/store/index.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,16 @@ const store = new Vuex.Store({
2626
commit('SET_ACTIVE_TYPE', { type })
2727
return fetchIdsByType(type)
2828
.then(ids => commit('SET_LIST', { type, ids }))
29-
.then(() => fetchItems(getters.activeIds.filter(id => !state.items[id])))
30-
.then(items => commit('SET_ITEMS', { items }))
29+
.then(() => dispatch('FETCH_ACTIVE_ITEMS'))
30+
},
31+
32+
FETCH_ACTIVE_ITEMS: ({ commit, state, getters }) => {
33+
const ids = getters.activeIds.filter(id => !state.items[id])
34+
if (ids.length) {
35+
return fetchItems(ids).then(items => commit('SET_ITEMS', { items }))
36+
} else {
37+
return Promise.resolve()
38+
}
3139
}
3240
},
3341

0 commit comments

Comments
 (0)