From 72955eb106bcdb78b8abe1a49bf8906c6c393a80 Mon Sep 17 00:00:00 2001 From: eitanfr <> Date: Tue, 15 Aug 2017 18:55:44 +0300 Subject: [PATCH 1/2] restore old infinite scroll --- package.json | 1 - .../chat/chat-view/chat-view.component.html | 30 ++---- .../chat/chat-view/chat-view.component.scss | 16 +-- src/app/chat/chat-view/chat-view.component.ts | 100 +++++++++++------- 4 files changed, 74 insertions(+), 73 deletions(-) diff --git a/package.json b/package.json index 81e9812..42312f7 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "@angular/platform-browser-dynamic": "^4.1.0", "@angular/router": "^4.0.0", "@angular/service-worker": "^1.0.0-beta.14", - "angular2-virtual-scroll": "eitanfr/angular2-virtual-scroll#077f2afd622d9fb6aaa81774fe7f96e8f3750685", "apollo-angular": "^0.13.0", "apollo-client": "^1.3.0", "core-js": "^2.4.1", diff --git a/src/app/chat/chat-view/chat-view.component.html b/src/app/chat/chat-view/chat-view.component.html index 1bb8b1c..2bf2063 100644 --- a/src/app/chat/chat-view/chat-view.component.html +++ b/src/app/chat/chat-view/chat-view.component.html @@ -7,27 +7,13 @@ -
-
- +
+
+
- - - -
- -
- - - - - -
+ + +
@@ -39,3 +25,7 @@ + + + + diff --git a/src/app/chat/chat-view/chat-view.component.scss b/src/app/chat/chat-view/chat-view.component.scss index d3e6e6b..fdfa322 100644 --- a/src/app/chat/chat-view/chat-view.component.scss +++ b/src/app/chat/chat-view/chat-view.component.scss @@ -18,7 +18,7 @@ } .message-scroller { - overflow: scroll; + overflow: auto; position: absolute; height: 100%; width: 100%; @@ -41,17 +41,9 @@ } .loading-spinner { - width: 100px; - height: 100px; -} - -virtual-scroll, -[virtualScroll] { - overflow: hidden; - overflow-y: auto; - width: 100%; - height: 100%; - display: block; + display: flex; + justify-content: center; + margin-top: 15px; } .message-input { diff --git a/src/app/chat/chat-view/chat-view.component.ts b/src/app/chat/chat-view/chat-view.component.ts index 31fa462..9b500b9 100644 --- a/src/app/chat/chat-view/chat-view.component.ts +++ b/src/app/chat/chat-view/chat-view.component.ts @@ -7,10 +7,10 @@ import { ViewChild, ViewEncapsulation } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { ChatService } from '../services/chat/chat.service'; -import { MessagesQuery } from '../../graphql/types/types'; -import { ChangeEvent, VirtualScrollComponent } from 'angular2-virtual-scroll'; +import {ActivatedRoute, Router} from '@angular/router'; +import {ChatService} from '../services/chat/chat.service'; +import {MessagesQuery} from '../../graphql/types/types'; +import {Observable} from 'rxjs/Observable'; @Component({ @@ -23,24 +23,22 @@ import { ChangeEvent, VirtualScrollComponent } from 'angular2-virtual-scroll'; export class ChatViewComponent implements OnInit, OnDestroy { @ViewChild('chatContent') chatContent: any; - @ViewChild(VirtualScrollComponent) virtualScroll: VirtualScrollComponent; @ViewChild('messageInput') messageInput: any; - private readonly PAGE_MESSAGE_COUNT = 100; - private readonly LOAD_ITEMS_NUM_TRIGGER = 40; + private readonly PAGE_MESSAGE_COUNT = 80; + private readonly PAGE_PERCENT_LOAD_MORE_TRIGGER = 0.3; + private readonly MAX_PAGE_LOAD_MORE_PIXEL_LEN = 3500; + public channel: MessagesQuery.Channel; - private routeParamsSub; - private messagesSub; public model = {message: undefined}; - private chatContentScrollSubscription; public isFirstLoad = true; public messages; - private scrollValue: ChangeEvent; - public isLoadingMore; public keepIndexOnItemsChange = false; - public scrollItems: any; - public loadingMessages = false; + public initialLoading = false; + private routeParamsSub; + private messagesSub; + private chatContentScrollSubscription; constructor(private router: Router, private route: ActivatedRoute, @@ -76,8 +74,8 @@ export class ChatViewComponent implements OnInit, OnDestroy { ); this.messagesSub = messagesQueryObservable.subscribe(({data, loading}) => { - this.loadingMessages = loading && !data; - if (this.loadingMessages) { + this.initialLoading = loading && !data; + if (this.initialLoading) { this.cd.markForCheck(); return; } @@ -87,6 +85,7 @@ export class ChatViewComponent implements OnInit, OnDestroy { return; } + const oldScrollHeight = this.chatContent.nativeElement.scrollHeight; this.messages = data.messages.messagesArray; if (this.isFirstLoad) { @@ -94,28 +93,66 @@ export class ChatViewComponent implements OnInit, OnDestroy { this.channel = data.messages.channel; this.chatService.subscribeToMessageAdded(this.channel.id); - this.scrollToBottom(); + setTimeout(() => { + this.addScrollListener(); + this.scrollToBottom(); + }, 0); + } + + if (!this.chatService.isLoadingMoreMessages() && this.isScrolledToBottom()) { + setTimeout(() => { + this.scrollToBottom(); + }, 0); + } + + if (this.isScrolledToTop()) { + setTimeout(() => { + this.chatContent.nativeElement.scrollTop = this.chatContent.nativeElement.scrollHeight - oldScrollHeight; + }, 0); } if (!this.isFirstLoad && this.messages && this.isScrolledToBottom()) { this.scrollToBottom(); } - this.cd.markForCheck(); }); + + this.scrollToBottom(); this.cd.markForCheck(); }); } - isScrolledToBottom(): boolean { - if (this.scrollValue) { - return this.scrollValue.end === this.messages.length - 1; + addScrollListener() { + const currentPageHeight = this.chatContent.nativeElement.scrollHeight; + const pagePixelLenForLoadMore = Math.min(currentPageHeight * this.PAGE_PERCENT_LOAD_MORE_TRIGGER , this.MAX_PAGE_LOAD_MORE_PIXEL_LEN); + + if (!this.chatContentScrollSubscription) { + this.chatContentScrollSubscription = Observable.fromEvent(this.chatContent.nativeElement, 'scroll').subscribe(() => { + this.onScrollChange(pagePixelLenForLoadMore); + }); + } + } + + onScrollChange(pagePixelLenForLoadMore) { + if (this.chatContent.nativeElement.scrollTop < pagePixelLenForLoadMore) { + if (!this.chatService.isLoadingMoreMessages()) { + this.loadMoreMessages(); + this.cd.markForCheck(); + } } - return false; + } + + isScrolledToBottom(): boolean { + const chatElement = this.chatContent.nativeElement; + return chatElement.scrollTop + chatElement.clientHeight >= chatElement.scrollHeight; + } + + isScrolledToTop(): boolean { + return this.chatContent.nativeElement.scrollTop === 0; } scrollToBottom() { - setTimeout(() => this.virtualScroll.scrollInto(this.messages[this.messages.length - 1]), 1); + this.chatContent.nativeElement.scrollTop = this.chatContent.nativeElement.scrollHeight; } sendMessage() { @@ -127,27 +164,10 @@ export class ChatViewComponent implements OnInit, OnDestroy { } } - isLoadMoreNeeded() { - const scrollValue = this.scrollValue; - return !this.isLoadingMore && scrollValue && scrollValue.start < this.LOAD_ITEMS_NUM_TRIGGER; - } - loadMoreMessages() { return this.chatService.loadMoreMessages(this.channel.id, this.PAGE_MESSAGE_COUNT); } - scrollValueChanged(scrollValue) { - this.scrollValue = scrollValue; - if (this.messages && !this.isFirstLoad && this.isLoadMoreNeeded()) { - this.isLoadingMore = true; - this.keepIndexOnItemsChange = true; - this.loadMoreMessages().then(() => { - this.isLoadingMore = false; - }); - } - } - - unsubscribeChannel() { this.chatService.unsubscribeMessagesSubscription(); if (this.messagesSub) { From 2b6b10041bf5f831b9a241f715f316bac2efa313 Mon Sep 17 00:00:00 2001 From: eitanfr <> Date: Sun, 27 Aug 2017 15:57:40 +0300 Subject: [PATCH 2/2] after merge --- src/app/chat/chat-view/chat-view.component.ts | 4 ++-- src/app/chat/chat.module.ts | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/app/chat/chat-view/chat-view.component.ts b/src/app/chat/chat-view/chat-view.component.ts index 0480914..fbda263 100644 --- a/src/app/chat/chat-view/chat-view.component.ts +++ b/src/app/chat/chat-view/chat-view.component.ts @@ -78,8 +78,8 @@ export class ChatViewComponent implements OnInit, OnDestroy { this.channelSub = channelObservable.subscribe((result) => { const channelData = result.data; const channelLoading = result.loading; - this.loadingMessages = channelLoading && !channelData; - if (this.loadingMessages) { + this.initialLoading = channelLoading && !channelData; + if (this.initialLoading) { this.cd.markForCheck(); return; } diff --git a/src/app/chat/chat.module.ts b/src/app/chat/chat.module.ts index 5bb281c..0b45eb2 100644 --- a/src/app/chat/chat.module.ts +++ b/src/app/chat/chat.module.ts @@ -12,14 +12,12 @@ import { MainSidenavComponent } from './main-sidenav/main-sidenav.component'; import { ChannelsService } from './services/channels/channels.service'; import { ChatService } from './services/chat/chat.service'; import { ChannelNotFoundComponent } from './channel-not-found/channel-not-found.component'; -import { VirtualScrollModule } from 'angular2-virtual-scroll'; @NgModule({ imports: [ CommonModule, SharedModule, ChatRoutingModule, - VirtualScrollModule, ], declarations: [ MainPageComponent,