1
1
<template >
2
2
<div >
3
3
<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 >
8
10
</div >
9
11
<div class =" showcase" >
10
12
<snippet-preview
21
23
</div >
22
24
</div >
23
25
<spinner v-show =" loading" />
26
+ <div class =" end-of-pages" v-if =' endOfPages' >you reached the end :)</div >
24
27
</div >
25
28
</template >
26
29
@@ -39,18 +42,28 @@ export default {
39
42
},
40
43
data () {
41
44
return {
42
- loading: true ,
45
+ loading: false ,
43
46
searchText: ' ' ,
44
- snippets: {} ,
47
+ snippets: [] ,
45
48
page: 0 ,
46
- totalPage : - 1 ,
49
+ totalPages : 9999 ,
47
50
editing: null
48
51
}
49
52
},
53
+ computed: {
54
+ endOfPages (){
55
+ return this .page >= this .totalPages
56
+ }
57
+ },
50
58
methods: {
51
- async fetch () {
59
+ async fetchNext () {
60
+ if (this .endOfPages || this .loading )
61
+ return
52
62
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
54
67
this .loading = false
55
68
},
56
69
async search () {
@@ -63,15 +76,24 @@ export default {
63
76
this .$set (this .snippets , idx, snippet)
64
77
}
65
78
},
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
+ }
68
89
}
69
90
}
70
91
</script >
71
92
72
93
<style lang="stylus">
94
+ $max-width = 85rem
95
+
73
96
.nav
74
- padding : 5px
75
97
background : #f1 f1 f1
76
98
border-bottom : 1px solid gainsboro
77
99
position : fixed
@@ -81,8 +103,13 @@ export default {
81
103
z-index : 1
82
104
white-space : nowrap
83
105
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
86
113
87
114
.iconify
88
115
font-size : 1.5em
@@ -101,10 +128,11 @@ export default {
101
128
font-size : 1.1em
102
129
103
130
.showcase
104
- margin-top : 3.6rem
105
131
padding : 1rem
106
132
display : grid
107
133
grid-template-columns : repeat (auto - fill , minmax (18rem , 1 fr ))
134
+ max-width $max-width
135
+ margin 3.6rem auto 1rem auto
108
136
109
137
.modal
110
138
z-index 2
@@ -121,4 +149,10 @@ export default {
121
149
top 5rem
122
150
bottom 5rem
123
151
right 5rem
152
+
153
+ .end-of-pages
154
+ padding 2rem
155
+ opacity 0.3
156
+ text-align center
157
+ font-style italic
124
158
</style >
0 commit comments