Skip to content

Commit 6b59c40

Browse files
committed
(feat) add infinite rooms
1 parent 387745f commit 6b59c40

File tree

3 files changed

+101
-21
lines changed

3 files changed

+101
-21
lines changed

demo/src/ChatContainer.vue

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@
5454
:loading-rooms="loadingRooms"
5555
:messages="messages"
5656
:messages-loaded="messagesLoaded"
57+
:rooms-loaded="roomsLoaded"
5758
:menu-actions="menuActions"
5859
:room-message="roomMessage"
60+
@fetch-more-rooms="fetchMoreRooms"
5961
@fetch-messages="fetchMessages"
6062
@send-message="sendMessage"
6163
@edit-message="editMessage"
@@ -94,17 +96,21 @@ export default {
9496
9597
data() {
9698
return {
97-
perPage: 20,
99+
roomsPerPage: 10,
98100
rooms: [],
99-
allUsers: [],
101+
startRooms: null,
102+
endRooms: null,
103+
roomsLoaded: false,
100104
loadingRooms: true,
105+
allUsers: [],
101106
loadingLastMessageByRoom: 0,
102107
selectedRoom: null,
108+
messagesPerPage: 20,
103109
messages: [],
104110
messagesLoaded: false,
105111
roomMessage: '',
106-
start: null,
107-
end: null,
112+
startMessages: null,
113+
endMessages: null,
108114
roomsListeners: [],
109115
listeners: [],
110116
typingMessageCache: '',
@@ -140,31 +146,45 @@ export default {
140146
this.loadingRooms = true
141147
this.loadingLastMessageByRoom = 0
142148
this.rooms = []
149+
this.roomsLoaded = false
150+
this.startRooms = null
151+
this.endRooms = null
143152
this.roomsListeners.forEach(listener => listener())
153+
this.roomsListeners = []
144154
this.resetMessages()
145155
},
146156
147157
resetMessages() {
148158
this.messages = []
149159
this.messagesLoaded = false
150-
this.start = null
151-
this.end = null
160+
this.startMessages = null
161+
this.endMessages = null
152162
this.listeners.forEach(listener => listener())
153163
this.listeners = []
154164
},
155165
156-
async fetchRooms() {
166+
fetchRooms() {
157167
this.resetRooms()
168+
this.fetchMoreRooms()
169+
},
158170
159-
const query = roomsRef.where(
160-
'users',
161-
'array-contains',
162-
this.currentUserId
163-
)
171+
async fetchMoreRooms() {
172+
if (this.endRooms && !this.startRooms) return (this.roomsLoaded = true)
173+
174+
let query = roomsRef
175+
.where('users', 'array-contains', this.currentUserId)
176+
.limit(this.roomsPerPage)
177+
178+
if (this.startRooms) query = query.startAfter(this.startRooms)
164179
165180
const rooms = await query.get()
166181
// this.incrementDbCounter('Fetch Rooms', rooms.size)
167182
183+
if (rooms.empty) this.roomsLoaded = true
184+
185+
if (this.startRooms) this.endRooms = this.startRooms
186+
this.startRooms = rooms.docs[rooms.docs.length - 1]
187+
168188
const roomUserIds = []
169189
rooms.forEach(room => {
170190
room.data().users.forEach(userId => {
@@ -285,13 +305,14 @@ export default {
285305
fetchMessages({ room, options = {} }) {
286306
if (options.reset) this.resetMessages()
287307
288-
if (this.end && !this.start) return (this.messagesLoaded = true)
308+
if (this.endMessages && !this.startMessages)
309+
return (this.messagesLoaded = true)
289310
290311
let ref = messagesRef(room.roomId)
291312
292-
let query = ref.orderBy('timestamp', 'desc').limit(this.perPage)
313+
let query = ref.orderBy('timestamp', 'desc').limit(this.messagesPerPage)
293314
294-
if (this.start) query = query.startAfter(this.start)
315+
if (this.startMessages) query = query.startAfter(this.startMessages)
295316
296317
this.selectedRoom = room.roomId
297318
@@ -301,13 +322,15 @@ export default {
301322
302323
if (messages.empty) this.messagesLoaded = true
303324
304-
if (this.start) this.end = this.start
305-
this.start = messages.docs[messages.docs.length - 1]
325+
if (this.startMessages) this.endMessages = this.startMessages
326+
this.startMessages = messages.docs[messages.docs.length - 1]
306327
307328
let listenerQuery = ref.orderBy('timestamp')
308329
309-
if (this.start) listenerQuery = listenerQuery.startAfter(this.start)
310-
if (this.end) listenerQuery = listenerQuery.endAt(this.end)
330+
if (this.startMessages)
331+
listenerQuery = listenerQuery.startAfter(this.startMessages)
332+
if (this.endMessages)
333+
listenerQuery = listenerQuery.endAt(this.endMessages)
311334
312335
if (options.reset) this.messages = []
313336

src/ChatWindow/ChatWindow.vue

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
:current-user-id="currentUserId"
77
:rooms="orderedRooms"
88
:loading-rooms="loadingRooms"
9+
:rooms-loaded="roomsLoaded"
910
:room="room"
1011
:text-messages="t"
1112
:show-add-room="showAddRoom"
1213
:show-rooms-list="showRoomsList"
1314
:text-formatting="textFormatting"
1415
:is-mobile="isMobile"
1516
@fetch-room="fetchRoom"
17+
@fetch-more-rooms="fetchMoreRooms"
18+
@loading-more-rooms="loadingMoreRooms = $event"
1619
@add-room="addRoom"
1720
>
1821
<template v-for="(index, name) in $scopedSlots" v-slot:[name]="data">
@@ -92,6 +95,7 @@ export default {
9295
currentUserId: { type: [String, Number], default: '' },
9396
rooms: { type: Array, default: () => [] },
9497
loadingRooms: { type: Boolean, default: false },
98+
roomsLoaded: { type: Boolean, default: false },
9599
roomId: { type: [String, Number], default: null },
96100
loadFirstRoom: { type: Boolean, default: true },
97101
messages: { type: Array, default: () => [] },
@@ -122,6 +126,7 @@ export default {
122126
data() {
123127
return {
124128
room: {},
129+
loadingMoreRooms: false,
125130
showRoomsList: true,
126131
isMobile: false
127132
}
@@ -139,6 +144,7 @@ export default {
139144
}
140145
141146
if (
147+
!this.loadingMoreRooms &&
142148
this.loadFirstRoom &&
143149
newVal[0] &&
144150
(!oldVal || newVal.length !== oldVal.length)
@@ -240,6 +246,9 @@ export default {
240246
this.fetchMessages({ reset: true })
241247
if (this.isMobile) this.showRoomsList = false
242248
},
249+
fetchMoreRooms() {
250+
this.$emit('fetch-more-rooms')
251+
},
243252
roomInfo() {
244253
this.$emit('room-info', this.room)
245254
},
@@ -262,7 +271,10 @@ export default {
262271
this.$emit('open-file', { message, action })
263272
},
264273
menuActionHandler(ev) {
265-
this.$emit('menu-action-handler', { action: ev, roomId: this.room.roomId })
274+
this.$emit('menu-action-handler', {
275+
action: ev,
276+
roomId: this.room.roomId
277+
})
266278
},
267279
messageActionHandler(ev) {
268280
this.$emit('message-action-handler', {

src/ChatWindow/RoomsList.vue

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,25 @@
126126
</div>
127127
</slot>
128128
</div>
129+
<transition name="vac-fade-message">
130+
<infinite-loading
131+
v-if="rooms.length"
132+
spinner="spiral"
133+
@infinite="loadMoreRooms"
134+
>
135+
<div slot="spinner">
136+
<loader :show="true" :infinite="true"></loader>
137+
</div>
138+
<div slot="no-results"></div>
139+
<div slot="no-more"></div>
140+
</infinite-loading>
141+
</transition>
129142
</div>
130143
</div>
131144
</template>
132145

133146
<script>
147+
import InfiniteLoading from 'vue-infinite-loading'
134148
import Loader from './Loader'
135149
import SvgIcon from './SvgIcon'
136150
import FormatMessage from './FormatMessage'
@@ -140,7 +154,7 @@ import typingText from '../utils/typingText'
140154
141155
export default {
142156
name: 'rooms-list',
143-
components: { Loader, SvgIcon, FormatMessage },
157+
components: { InfiniteLoading, Loader, SvgIcon, FormatMessage },
144158
145159
props: {
146160
currentUserId: { type: [String, Number], required: true },
@@ -151,19 +165,39 @@ export default {
151165
isMobile: { type: Boolean, required: true },
152166
rooms: { type: Array, required: true },
153167
loadingRooms: { type: Boolean, required: true },
168+
roomsLoaded: { type: Boolean, required: true },
154169
room: { type: Object, required: true }
155170
},
156171
157172
data() {
158173
return {
159174
filteredRooms: this.rooms || [],
175+
infiniteState: null,
176+
loadingMoreRooms: false,
160177
selectedRoomId: ''
161178
}
162179
},
163180
164181
watch: {
165182
rooms(val) {
166183
this.filteredRooms = val
184+
185+
if (this.infiniteState) {
186+
this.infiniteState.loaded()
187+
setTimeout(() => (this.loadingMoreRooms = false), 0)
188+
}
189+
},
190+
191+
loadingRooms(val) {
192+
if (val) this.infiniteState = null
193+
},
194+
195+
roomsLoaded() {
196+
if (this.infiniteState) this.infiniteState.complete()
197+
},
198+
199+
loadingMoreRooms(val) {
200+
this.$emit('loading-more-rooms', val)
167201
},
168202
169203
room: {
@@ -187,6 +221,17 @@ export default {
187221
if (!this.isMobile) this.selectedRoomId = room.roomId
188222
this.$emit('fetch-room', { room })
189223
},
224+
loadMoreRooms(infiniteState) {
225+
if (this.loadingMoreRooms) return
226+
227+
if (this.roomsLoaded) {
228+
return infiniteState.complete()
229+
}
230+
231+
this.infiniteState = infiniteState
232+
this.$emit('fetch-more-rooms')
233+
this.loadingMoreRooms = true
234+
},
190235
addRoom() {
191236
this.$emit('add-room')
192237
},

0 commit comments

Comments
 (0)