Commit d365791d authored by Sebastien Chopin's avatar Sebastien Chopin

Create distinct view for each category

parent c9313029
......@@ -19,147 +19,135 @@
</template>
<script>
import { watchList } from '../../api'
import Item from '../../components/Item.vue'
const camelize = str => str.charAt(0).toUpperCase() + str.slice(1)
const TYPES = ['top', 'new', 'show', 'ask', 'job']
export default {
name: 'item-list',
validate({params: {type, page = 0}}) {
return TYPES.includes(type) && /^[0-9]+$/.test(page)
},
components: {
Item
},
head() {
return {
title: camelize(this.$route.params.type)
}
},
data() {
return {
transition: 'slide-right',
displayedPage: Number(this.$route.params.page) || 1,
displayedItems: this.$store.getters.activeItems,
type: this.$route.params.type
}
},
fetch({store, params}) {
return store.dispatch('FETCH_LIST_DATA', {type: params.type})
import { watchList } from '../api'
import Item from './Item.vue'
export default {
name: 'item-list',
components: {
Item
},
props: {
type: String
},
data() {
return {
transition: 'slide-right',
displayedPage: Number(this.$route.params.page) || 1,
displayedItems: this.$store.getters.activeItems
}
},
computed: {
page() {
return Number(this.$route.params.page) || 1
},
computed: {
page() {
return Number(this.$route.params.page) || 1
},
maxPage() {
const {itemsPerPage, lists} = this.$store.state
return Math.ceil(lists[this.type].length / itemsPerPage)
},
hasMore() {
return this.page < this.maxPage
}
maxPage() {
const {itemsPerPage, lists} = this.$store.state
return Math.ceil(lists[this.type].length / itemsPerPage)
},
hasMore() {
return this.page < this.maxPage
}
},
beforeMount() {
if (this.$root._isMounted) {
this.loadItems(this.page)
}
// watch the current list for realtime updates
this.unwatchList = watchList(this.type, ids => {
this.$store.commit('SET_LIST', {type: this.type, ids})
this.$store.dispatch('ENSURE_ACTIVE_ITEMS').then(() => {
this.displayedItems = this.$store.getters.activeItems
})
beforeMount() {
if (this.$root._isMounted) {
this.loadItems(this.page)
}
// watch the current list for realtime updates
this.unwatchList = watchList(this.type, ids => {
this.$store.commit('SET_LIST', {type: this.type, ids})
this.$store.dispatch('ENSURE_ACTIVE_ITEMS').then(() => {
this.displayedItems = this.$store.getters.activeItems
})
},
beforeDestroy() {
this.unwatchList()
},
})
},
watch: {
page(to, from) {
this.loadItems(to, from)
}
},
beforeDestroy() {
this.unwatchList()
},
methods: {
loadItems(to = this.page, from = -1) {
this.$nuxt.$loading.start()
this.$store.dispatch('FETCH_LIST_DATA', {
type: this.type
}).then(() => {
if (this.page < 0 || this.page > this.maxPage) {
this.$router.replace(`/${this.type}/1`)
return
}
this.transition = from === -1
? null
: to > from ? 'slide-left' : 'slide-right'
this.displayedPage = to
this.displayedItems = this.$store.getters.activeItems
this.$nuxt.$loading.finish()
})
}
watch: {
page(to, from) {
this.loadItems(to, from)
}
},
methods: {
loadItems(to = this.page, from = -1) {
this.$nuxt.$loading.start()
this.$store.dispatch('FETCH_LIST_DATA', {
type: this.type
}).then(() => {
if (this.page < 0 || this.page > this.maxPage) {
this.$router.replace(`/${this.type}/1`)
return
}
this.transition = from === -1
? null
: to > from ? 'slide-left' : 'slide-right'
this.displayedPage = to
this.displayedItems = this.$store.getters.activeItems
this.$nuxt.$loading.finish()
})
}
}
}
</script>
<style lang="stylus">
.news-view
padding-top 45px
.news-list-nav, .news-list
background-color #fff
border-radius 2px
.news-list-nav
padding 15px 30px
position fixed
text-align center
top 55px
left 0
right 0
z-index 998
box-shadow 0 1px 2px rgba(0, 0, 0, .1)
a
margin 0 1em
.disabled
color #ccc
.news-view
padding-top 45px
.news-list-nav, .news-list
background-color #fff
border-radius 2px
.news-list-nav
padding 15px 30px
position fixed
text-align center
top 55px
left 0
right 0
z-index 998
box-shadow 0 1px 2px rgba(0, 0, 0, .1)
a
margin 0 1em
.disabled
color #ccc
.news-list
position absolute
margin 30px 0
width 100%
transition all .5s cubic-bezier(.55, 0, .1, 1)
ul
list-style-type none
padding 0
margin 0
.slide-left-enter, .slide-right-leave-to
opacity 0
transform translate(30px, 0)
.slide-left-leave-to, .slide-right-enter
opacity 0
transform translate(-30px, 0)
.item-move, .item-enter-active, .item-leave-active
transition all .5s cubic-bezier(.55, 0, .1, 1)
.item-enter
opacity 0
transform translate(30px, 0)
.item-leave-active
position absolute
opacity 0
transform translate(30px, 0)
@media (max-width 600px)
.news-list
position absolute
margin 30px 0
width 100%
transition all .5s cubic-bezier(.55, 0, .1, 1)
ul
list-style-type none
padding 0
margin 0
.slide-left-enter, .slide-right-leave-to
opacity 0
transform translate(30px, 0)
.slide-left-leave-to, .slide-right-enter
opacity 0
transform translate(-30px, 0)
.item-move, .item-enter-active, .item-leave-active
transition all .5s cubic-bezier(.55, 0, .1, 1)
.item-enter
opacity 0
transform translate(30px, 0)
.item-leave-active
position absolute
opacity 0
transform translate(30px, 0)
@media (max-width 600px)
.news-list
margin 10px 0
margin 10px 0
</style>
import ItemList from './ItemList.vue'
const camelize = str => str.charAt(0).toUpperCase() + str.slice(1)
// This is a factory function for dynamically creating root-level list views,
// since they share most of the logic except for the type of items to display.
// They are essentially higher order components wrapping ItemList.vue.
export default function createListView (type) {
return {
name: `${type}-stories-view`,
fetch ({ store }) {
return store.dispatch('FETCH_LIST_DATA', { type })
},
head: {
title: camelize(type),
},
render (h) {
return h(ItemList, { props: { type }})
}
}
}
<script>
import createListView from '~components/createListView'
export default createListView('ask')
</script>
<script>
import createListView from '~components/createListView'
export default createListView('job')
</script>
<script>
import createListView from '~components/createListView'
export default createListView('new')
</script>
<script>
import createListView from '~components/createListView'
export default createListView('show')
</script>
<script>
import createListView from '~components/createListView'
export default createListView('top')
</script>
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