30
30
</room-header >
31
31
32
32
<div
33
+ id =" messages-list"
33
34
ref =" scrollContainer"
34
35
class =" vac-container-scroll"
35
36
@scroll =" onContainerScroll"
53
54
</div >
54
55
</div >
55
56
</transition >
56
- <transition name =" vac-fade-message" >
57
- <infinite-loading
58
- v-if =" messages.length"
59
- :class =" { 'vac-infinite-loading': !messagesLoaded }"
60
- force-use-infinite-wrapper =" .vac-container-scroll"
61
- web-component-name =" vue-advanced-chat"
62
- spinner =" spiral"
63
- direction =" top"
64
- :distance =" 40"
65
- @infinite =" loadMoreMessages"
66
- >
67
- <template #spinner >
68
- <loader :show =" true" :infinite =" true" >
69
- <template v-for =" (idx , name ) in $scopedSlots " #[name ]=" data " >
70
- <slot :name =" name" v-bind =" data" />
71
- </template >
72
- </loader >
73
- </template >
74
- <template #no-results >
75
- <div />
76
- </template >
77
- <template #no-more >
78
- <div />
57
+ <div
58
+ v-if =" messages.length && !messagesLoaded"
59
+ id =" infinite-loader-messages"
60
+ >
61
+ <loader :show =" true" :infinite =" true" >
62
+ <template v-for =" (idx , name ) in $scopedSlots " #[name ]=" data " >
63
+ <slot :name =" name" v-bind =" data" />
79
64
</template >
80
- </infinite-loading >
81
- </transition >
65
+ </loader >
66
+ </div >
82
67
<transition-group :key =" roomId" name =" vac-fade-message" tag =" span" >
83
68
<div v-for =" (m, i) in messages" :key =" m.indexId || m._id" >
84
69
<message
316
301
</template >
317
302
318
303
<script >
319
- import InfiniteLoading from ' vue-infinite-loading'
320
304
import vClickOutside from ' v-click-outside'
321
305
import { Database } from ' emoji-picker-element'
322
306
@@ -335,7 +319,7 @@ import Message from '../Message/Message'
335
319
import filteredItems from ' ../../utils/filter-items'
336
320
import Recorder from ' ../../utils/recorder'
337
321
338
- const { detectMobile , iOSDevice } = require (' ../../utils/mobile-detection' )
322
+ const { detectMobile } = require (' ../../utils/mobile-detection' )
339
323
340
324
const debounce = (func , delay ) => {
341
325
let inDebounce
@@ -350,7 +334,6 @@ const debounce = (func, delay) => {
350
334
export default {
351
335
name: ' Room' ,
352
336
components: {
353
- InfiniteLoading,
354
337
Loader,
355
338
SvgIcon,
356
339
EmojiPickerContainer,
@@ -422,6 +405,8 @@ export default {
422
405
messageReply: null ,
423
406
infiniteState: null ,
424
407
loadingMessages: false ,
408
+ observer: null ,
409
+ showLoader: true ,
425
410
loadingMoreMessages: false ,
426
411
files: [],
427
412
fileDialog: false ,
@@ -502,6 +487,7 @@ export default {
502
487
} else {
503
488
if (this .infiniteState ) this .infiniteState .loaded ()
504
489
this .focusTextarea (true )
490
+ setTimeout (() => this .initIntersectionObserver ())
505
491
}
506
492
},
507
493
room: {
@@ -596,6 +582,47 @@ export default {
596
582
},
597
583
598
584
methods: {
585
+ initIntersectionObserver () {
586
+ if (this .observer ) {
587
+ this .showLoader = true
588
+ this .observer .disconnect ()
589
+ }
590
+
591
+ const loader = document .getElementById (' infinite-loader-messages' )
592
+
593
+ if (loader) {
594
+ const options = {
595
+ root: document .getElementById (' messages-list' ),
596
+ rootMargin: ' 60px' ,
597
+ threshold: 0
598
+ }
599
+
600
+ this .observer = new IntersectionObserver (entries => {
601
+ if (entries[0 ].isIntersecting ) {
602
+ this .loadMoreMessages ()
603
+ }
604
+ }, options)
605
+
606
+ this .observer .observe (loader)
607
+ }
608
+ },
609
+ preventTopScroll () {
610
+ const container = this .$refs .scrollContainer
611
+ const prevScrollHeight = container .scrollHeight
612
+
613
+ const observer = new ResizeObserver (_ => {
614
+ if (container .scrollHeight !== prevScrollHeight) {
615
+ this .$refs .scrollContainer .scrollTo ({
616
+ top: container .scrollHeight - prevScrollHeight
617
+ })
618
+ observer .disconnect ()
619
+ }
620
+ })
621
+
622
+ for (var i = 0 ; i < container .children .length ; i++ ) {
623
+ observer .observe (container .children [i])
624
+ }
625
+ },
599
626
getTextareaRef () {
600
627
return this .$refs .roomTextarea
601
628
},
@@ -962,26 +989,25 @@ export default {
962
989
963
990
this .resetMessage (true )
964
991
},
965
- loadMoreMessages (infiniteState ) {
966
- if (this .loadingMessages ) {
967
- this .infiniteState = infiniteState
968
- return
969
- }
992
+ loadMoreMessages () {
993
+ if (this .loadingMessages ) return
970
994
971
995
setTimeout (
972
996
() => {
973
997
if (this .loadingMoreMessages ) return
974
998
975
999
if (this .messagesLoaded || ! this .room .roomId ) {
976
- return infiniteState .complete ()
1000
+ this .loadingMoreMessages = false
1001
+ this .showLoader = false
1002
+ return
977
1003
}
978
1004
979
- this .infiniteState = infiniteState
1005
+ this .preventTopScroll ()
980
1006
this .$emit (' fetch-messages' )
981
1007
this .loadingMoreMessages = true
982
1008
},
983
- // prevent scroll bouncing issue on iOS devices
984
- iOSDevice () ? 500 : 0
1009
+ // prevent scroll bouncing speed
1010
+ 500
985
1011
)
986
1012
},
987
1013
messageActionHandler ({ action, message }) {
0 commit comments