Skip to content

Commit 2e8edc6

Browse files
committed
update to the new API
1 parent 75ffdd8 commit 2e8edc6

File tree

5 files changed

+70
-26
lines changed

5 files changed

+70
-26
lines changed

src/App.vue

-4
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ html, body
1616
padding 0
1717
margin 0
1818
19-
html
20-
background #f1f1f1
21-
2219
body
23-
background #fff
2420
min-height 100vh
2521
2622
#app

src/api.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ export class API {
77
const res = await axios.get(`${API_ROOT}/all`)
88
return res.data
99
}
10+
11+
static async getPage(page = 1) {
12+
const res = await axios.get(`${API_ROOT}/pages/${page}`)
13+
return res.data
14+
}
1015

11-
static async vote(id, increment) {
12-
const res = await axios.post(`${API_ROOT}/vote`, { id, increment })
16+
static async vote(id, v) {
17+
const res = await axios.get(`${API_ROOT}/snippets/${id}/vote/${v}`)
1318
return res.data
1419
}
1520
}

src/components/Home.vue

+49-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<template>
22
<div>
33
<div class="nav">
4-
<label class="title">文言片語</label>
5-
<input class="search" placeholder="Search snippets..." v-model="searchText"/>
6-
<span @click="search" class="iconify" data-icon="mdi:search" data-inline="false"></span>
7-
<span @click="newSnippet" class="iconify" data-icon="mdi:plus" data-inline="false"></span>
4+
<div class="content">
5+
<label class="title">文言片語</label>
6+
<input class="search" placeholder="Search snippets..." v-model="searchText"/>
7+
<span @click="search" class="iconify" data-icon="mdi:search" data-inline="false"></span>
8+
<span @click="newSnippet" class="iconify" data-icon="mdi:plus" data-inline="false"></span>
9+
</div>
810
</div>
911
<div class="showcase">
1012
<snippet-preview
@@ -21,6 +23,7 @@
2123
</div>
2224
</div>
2325
<spinner v-show="loading"/>
26+
<div class="end-of-pages" v-if='endOfPages'>you reached the end :)</div>
2427
</div>
2528
</template>
2629

@@ -39,18 +42,28 @@ export default {
3942
},
4043
data() {
4144
return {
42-
loading: true,
45+
loading: false,
4346
searchText: '',
44-
snippets: {},
47+
snippets: [],
4548
page: 0,
46-
totalPage: -1,
49+
totalPages: 9999,
4750
editing: null
4851
}
4952
},
53+
computed: {
54+
endOfPages(){
55+
return this.page >= this.totalPages
56+
}
57+
},
5058
methods: {
51-
async fetch() {
59+
async fetchNext() {
60+
if (this.endOfPages || this.loading)
61+
return
5262
this.loading = true
53-
this.snippets = await API.getAll()
63+
const { snippets, totalPages, page } = await API.getPage(this.page + 1)
64+
this.snippets.push(...snippets)
65+
this.totalPages = totalPages
66+
this.page = page
5467
this.loading = false
5568
},
5669
async search() {
@@ -63,15 +76,24 @@ export default {
6376
this.$set(this.snippets, idx, snippet)
6477
}
6578
},
66-
mounted(){
67-
this.fetch()
79+
mounted() {
80+
this.page = 0
81+
this.fetchNext()
82+
83+
window.onscroll = () => {
84+
let bottomOfWindow = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop) + window.innerHeight === document.documentElement.offsetHeight
85+
86+
if (bottomOfWindow)
87+
this.fetchNext()
88+
}
6889
}
6990
}
7091
</script>
7192

7293
<style lang="stylus">
94+
$max-width = 85rem
95+
7396
.nav
74-
padding: 5px
7597
background: #f1f1f1
7698
border-bottom: 1px solid gainsboro
7799
position: fixed
@@ -81,8 +103,13 @@ export default {
81103
z-index: 1
82104
white-space: nowrap
83105
84-
*
85-
vertical-align: middle
106+
.content
107+
max-width $max-width
108+
margin 0 auto
109+
padding 5px
110+
111+
*
112+
vertical-align: middle
86113
87114
.iconify
88115
font-size: 1.5em
@@ -101,10 +128,11 @@ export default {
101128
font-size: 1.1em
102129
103130
.showcase
104-
margin-top: 3.6rem
105131
padding: 1rem
106132
display: grid
107133
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr))
134+
max-width $max-width
135+
margin 3.6rem auto 1rem auto
108136
109137
.modal
110138
z-index 2
@@ -121,4 +149,10 @@ export default {
121149
top 5rem
122150
bottom 5rem
123151
right 5rem
152+
153+
.end-of-pages
154+
padding 2rem
155+
opacity 0.3
156+
text-align center
157+
font-style italic
124158
</style>

src/components/IconButton.vue

+3
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ export default {
2626
2727
&:hover
2828
opacity: 1
29+
30+
&.active
31+
color: #E53
2932
</style>

src/components/SnippetPreview.vue

+11-5
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
<div class='footer'>
1818
<span class='votes'>{{snippet.votes}}</span>
1919

20-
<icon-button @click.native="voteUp" icon="thumb-up"/>
21-
<icon-button @click.native="voteDown" icon="thumb-down"/>
20+
<icon-button @click.native="voteUp" :class='{active: snippet.voted === 1}' icon="thumb-up"/>
21+
<icon-button @click.native="voteDown" :class='{active: snippet.voted === -1}' icon="thumb-down"/>
2222

2323
<div class='right-aligned'>
2424
<span class='token'>{{snippet.token}}</span>
@@ -45,11 +45,17 @@ export default {
4545
},
4646
methods: {
4747
async voteUp() {
48-
const data = await API.vote(this.snippet.id, +1)
48+
const data = await API.vote(
49+
this.snippet.id,
50+
this.snippet.voted === 1 ? 'reset' : 'up'
51+
)
4952
this.update(data)
5053
},
5154
async voteDown() {
52-
const data = await API.vote(this.snippet.id, -1)
55+
const data = await API.vote(
56+
this.snippet.id,
57+
this.snippet.voted === -1 ? 'reset' : 'down'
58+
)
5359
this.update(data)
5460
},
5561
update(data) {
@@ -77,7 +83,7 @@ export default {
7783

7884
<style lang="stylus" scope>
7985
.snippet-preview
80-
margin: 5px
86+
margin: 8px
8187
border-radius: 4px
8288
border: 1px solid gainsboro
8389
box-shadow: 1px 1px 1px rgba(0,0,0,0.1)

0 commit comments

Comments
 (0)