Skip to content

Commit 096643b

Browse files
committed
Add chat-room example
1 parent 1aa28dd commit 096643b

File tree

5 files changed

+150
-191
lines changed

5 files changed

+150
-191
lines changed

example/src/App.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ body {
2929
}
3030
3131
#nav {
32-
padding: 1em 0;
3332
@media (max-width: 640px) {
3433
padding: 0;
3534
}

example/src/common/user.js

Lines changed: 1 addition & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -1,178 +1,7 @@
11
import { Random } from './mock'
22

3-
const topTypeArr = [
4-
'NoHair',
5-
'Eyepatch',
6-
'Hat',
7-
'Hijab',
8-
'Turban',
9-
'WinterHat1',
10-
'WinterHat2',
11-
'WinterHat3',
12-
'WinterHat4',
13-
'LongHairBigHair',
14-
'LongHairBob',
15-
'LongHairBun',
16-
'LongHairCurly',
17-
'LongHairCurvy',
18-
'LongHairDreads',
19-
'LongHairFrida',
20-
'LongHairFro',
21-
'LongHairFroBand',
22-
'LongHairNotTooLong',
23-
'LongHairShavedSides',
24-
'LongHairMiaWallace',
25-
'LongHairStraight',
26-
'LongHairStraight2',
27-
'LongHairStraightStrand',
28-
'ShortHairDreads01',
29-
'ShortHairDreads02',
30-
'ShortHairFrizzle',
31-
'ShortHairShaggyMullet',
32-
'ShortHairShortCurly',
33-
'ShortHairShortFlat',
34-
'ShortHairShortRound',
35-
'ShortHairShortWaved',
36-
'ShortHairSides',
37-
'ShortHairTheCaesar',
38-
'ShortHairTheCaesarSidePart'
39-
]
40-
const accessoriesTypeArr = [
41-
'Blank',
42-
'Kurt',
43-
'Prescription01',
44-
'Prescription02',
45-
'Round',
46-
'Sunglasses',
47-
'Wayfarers'
48-
]
49-
const facialHairTypeArr = [
50-
'Blank',
51-
'BeardMedium',
52-
'BeardLight',
53-
'BeardMagestic',
54-
'MoustacheFancy',
55-
'MoustacheMagnum'
56-
]
57-
const facialHairColor = [
58-
'Auburn',
59-
'Black',
60-
'Blonde',
61-
'BlondeGolden',
62-
'Brown',
63-
'BrownDark',
64-
'Platinum',
65-
'Red'
66-
]
67-
const clotheTypeArr = [
68-
'BlazerShirt',
69-
'BlazerSweater',
70-
'CollarSweater',
71-
'GraphicShirt',
72-
'Hoodie',
73-
'Overall',
74-
'ShirtCrewNeck',
75-
'ShirtScoopNeck',
76-
'ShirtVNeck'
77-
]
78-
const clotheColor = [
79-
'Black',
80-
'Blue01',
81-
'Blue02',
82-
'Blue03',
83-
'Gray01',
84-
'Gray02',
85-
'Heather',
86-
'PastelBlue',
87-
'PastelGreen',
88-
'PastelOrange',
89-
'PastelRed',
90-
'PastelYellow',
91-
'Pink',
92-
'Red',
93-
'White'
94-
]
95-
const graphicTypeArr = [
96-
'Bat',
97-
'Cumbia',
98-
'Deer',
99-
'Diamond',
100-
'Hola',
101-
'Pizza',
102-
'Resist',
103-
'Selena',
104-
'Bear',
105-
'SkullOutline',
106-
'Skull'
107-
]
108-
const eyeTypeArr = [
109-
'Close',
110-
'Cry',
111-
'Default',
112-
'Dizzy',
113-
'EyeRoll',
114-
'Happy',
115-
'Hearts',
116-
'Side',
117-
'Squint',
118-
'Surprised',
119-
'Wink',
120-
'WinkWacky'
121-
]
122-
const eyebrowTypeArr = [
123-
'Angry',
124-
'AngryNatural',
125-
'Default',
126-
'DefaultNatural',
127-
'FlatNatural',
128-
'RaisedExcited',
129-
'RaisedExcitedNatural',
130-
'SadConcerned',
131-
'SadConcernedNatural',
132-
'UnibrowNatural',
133-
'UpDown',
134-
'UpDownNatural'
135-
]
136-
const mouthTypeArr = [
137-
'Concerned',
138-
'Default',
139-
'Disbelief',
140-
'Eating',
141-
'Grimace',
142-
'Sad',
143-
'ScreamOpen',
144-
'Serious',
145-
'Smile',
146-
'Tongue',
147-
'Twinkle',
148-
'Vomit'
149-
]
150-
const skinColorArr = [
151-
'Tanned',
152-
'Yellow',
153-
'Pale',
154-
'Light',
155-
'Brown',
156-
'DarkBrown',
157-
'Black'
158-
]
159-
1603
const getRandomAvatar = () => {
161-
return 'https://avataaars.io/?' + [
162-
'avatarStyle=Transparent',
163-
`topType=${Random.pick(topTypeArr)}`,
164-
`accessoriesType=${Random.pick(accessoriesTypeArr)}`,
165-
`hatColor=${Random.pick(facialHairTypeArr)}`,
166-
`facialHairType=${Random.pick(facialHairTypeArr)}`,
167-
`facialHairColor=${Random.pick(facialHairColor)}`,
168-
`clotheType=${Random.pick(clotheTypeArr)}`,
169-
`clotheColor=${Random.pick(clotheColor)}`,
170-
`graphicType=${Random.pick(graphicTypeArr)}`,
171-
`eyeType=${Random.pick(eyeTypeArr)}`,
172-
`eyebrowType=${Random.pick(eyebrowTypeArr)}`,
173-
`mouthType=${Random.pick(mouthTypeArr)}`,
174-
`skinColor=${Random.pick(skinColorArr)}`
175-
].join('&')
4+
return `https://avatars1.githubusercontent.com/u/${Random.integer(10000, 99999)}`
1765
}
1776

1787
export default () => {

example/src/views/chat-room/Item.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export default {
5353
padding-left: 1em;
5454
font-size: 16px;
5555
.name {
56-
color: #9b4cca;
56+
padding-bottom: .2em;
5757
}
5858
.content {
5959
position: relative;

example/src/views/chat-room/Main.vue

Lines changed: 131 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<github-corner />
44

55
<div class="main">
6+
<h3>{{ messages.length }}</h3>
67
<div class="list">
78
<virtual-list class="stream scroll-touch" ref="vsl"
89
:size="80"
@@ -11,8 +12,14 @@
1112
:data-sources="messages"
1213
:data-component="messageComponent"
1314
:item-class="'stream-item'"
14-
@totop="eventTotop"
15-
/>
15+
@resized="onItemRendered"
16+
@totop="onTotop"
17+
>
18+
<div slot="header" class="header">
19+
<div class="spinner" v-show="!finished"></div>
20+
<div class="finished" v-show="finished">No more data</div>
21+
</div>
22+
</virtual-list>
1623
</div>
1724
<massage-eidtor />
1825
</div>
@@ -22,7 +29,7 @@
2229
<script>
2330
import Item from './Item'
2431
import Editor from './Editor'
25-
import { getMessages } from './util'
32+
import { getMessages, getSids } from './util'
2633
2734
export default {
2835
name: 'chat-room',
@@ -33,26 +40,80 @@ export default {
3340
3441
data () {
3542
return {
43+
finished: false,
3644
messages: [],
3745
messageComponent: Item,
3846
}
3947
},
4048
4149
created () {
42-
getMessages(3).then((messages) => {
50+
this.param = {
51+
pageSize: 10,
52+
isFirstPageReady: false,
53+
}
54+
55+
// first page request
56+
getMessages(this.param.pageSize).then((messages) => {
4357
this.messages = this.messages.concat(messages)
4458
})
4559
},
4660
47-
mounted () {
48-
// if (this.$refs.vsl) {
49-
// this.$refs.vsl.scrollToBottom()
50-
// }
51-
},
61+
// mounted () {
62+
// window.vsl = this.$refs.vsl
63+
// },
5264
5365
methods: {
54-
eventTotop () {
55-
console.log('eventTotop')
66+
onTotop () {
67+
// get next page
68+
getMessages(this.param.pageSize, true).then((messages) => {
69+
if (!messages.length) {
70+
this.finished = true
71+
return
72+
}
73+
74+
this.setVirtualListToOffset(1)
75+
76+
const sids = getSids(messages)
77+
this.messages = messages.concat(this.messages)
78+
this.$nextTick(() => {
79+
const vsl = this.$refs.vsl
80+
const offset = sids.reduce((previousValue, currentSid) => {
81+
const previousSize = typeof previousValue === 'string' ? vsl.getSize(previousValue) : previousValue
82+
return previousSize + this.$refs.vsl.getSize(currentSid)
83+
})
84+
this.setVirtualListToOffset(offset)
85+
})
86+
})
87+
},
88+
89+
onItemRendered () {
90+
if (!this.$refs.vsl) {
91+
return
92+
}
93+
94+
// first page items are all mounted, scroll to bottom
95+
if (!this.param.isFirstPageReady && this.$refs.vsl.getSizes() >= this.param.pageSize) {
96+
this.param.isFirstPageReady = true
97+
this.setVirtualListToBottom()
98+
}
99+
},
100+
101+
setVirtualListToIndex (index) {
102+
if (this.$refs.vsl) {
103+
this.$refs.vsl.scrollToIndex(index)
104+
}
105+
},
106+
107+
setVirtualListToOffset (offset) {
108+
if (this.$refs.vsl) {
109+
this.$refs.vsl.scrollToOffset(offset)
110+
}
111+
},
112+
113+
setVirtualListToBottom () {
114+
if (this.$refs.vsl) {
115+
this.$refs.vsl.scrollToBottom()
116+
}
56117
}
57118
}
58119
}
@@ -75,4 +136,63 @@ export default {
75136
padding: 1em;
76137
}
77138
}
139+
.header {
140+
padding: .5em;
141+
.finished {
142+
font-size: 14px;
143+
text-align: center;
144+
}
145+
.spinner {
146+
font-size: 10px;
147+
margin: 0px auto;
148+
text-indent: -9999em;
149+
width: 15px;
150+
height: 15px;
151+
border-radius: 50%;
152+
background: #ffffff;
153+
background: linear-gradient(to right, #ccc 10%, rgba(255, 255, 255, 0) 42%);
154+
position: relative;
155+
animation: load3 1.4s infinite linear;
156+
transform: translateZ(0);
157+
}
158+
.spinner:before {
159+
width: 50%;
160+
height: 50%;
161+
background: #ccc;
162+
border-radius: 100% 0 0 0;
163+
position: absolute;
164+
top: 0;
165+
left: 0;
166+
content: '';
167+
}
168+
.spinner:after {
169+
background: #ffffff;
170+
width: 75%;
171+
height: 75%;
172+
border-radius: 50%;
173+
content: '';
174+
margin: auto;
175+
position: absolute;
176+
top: 0;
177+
left: 0;
178+
bottom: 0;
179+
right: 0;
180+
}
181+
@-webkit-keyframes load3 {
182+
0% {
183+
transform: rotate(0deg);
184+
}
185+
100% {
186+
transform: rotate(360deg);
187+
}
188+
}
189+
@keyframes load3 {
190+
0% {
191+
transform: rotate(0deg);
192+
}
193+
100% {
194+
transform: rotate(360deg);
195+
}
196+
}
197+
}
78198
</style>

0 commit comments

Comments
 (0)