diff --git a/package-lock.json b/package-lock.json index 4be04a3..82a6089 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9337,6 +9337,14 @@ "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, + "ngx-infinite-scroll": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ngx-infinite-scroll/-/ngx-infinite-scroll-8.0.1.tgz", + "integrity": "sha512-YpgkTPDNT7UCEp0GRX178V1nF+M2slCPJ2TX3CpvPZb5AR99JYwj/fNivcue5lN51oUaTySEG27qjVU73vKhjw==", + "requires": { + "opencollective-postinstall": "^2.0.2" + } + }, "ngx-socket-io": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ngx-socket-io/-/ngx-socket-io-2.1.1.tgz", @@ -9823,6 +9831,11 @@ "is-wsl": "^1.1.0" } }, + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==" + }, "opn": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", diff --git a/package.json b/package.json index abb61d3..388a508 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "graphql-tag": "^2.10.0", "hammerjs": "^2.0.8", "js-sha512": "^0.8.0", + "ngx-infinite-scroll": "^8.0.1", "ngx-socket-io": "^2.1.1", "node-sass": "^4.13.0", "rxjs": "~6.3.3", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 595c8f7..f2300c3 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -30,6 +30,8 @@ import { AboutComponent } from './components/about/about.component'; import { ChatcontactsComponent } from './components/chatmanager/chatcontacts/chatcontacts.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import {MatTableModule} from '@angular/material/table'; +import { InfiniteScrollModule } from 'ngx-infinite-scroll'; + import { MatSliderModule } from '@angular/material/slider'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -114,6 +116,7 @@ const appRoutes: Routes = [ SocketIoModule.forRoot(config), GraphQLModule, HttpClientModule, + InfiniteScrollModule, MatDatepickerModule, MatNativeDateModule, RouterModule.forRoot( diff --git a/src/app/components/feed/feed.component.html b/src/app/components/feed/feed.component.html index de81a86..f8e49a9 100644 --- a/src/app/components/feed/feed.component.html +++ b/src/app/components/feed/feed.component.html @@ -1,4 +1,8 @@ -
+
@@ -45,7 +49,10 @@
- +
+ + +
\ No newline at end of file diff --git a/src/app/components/feed/feed.component.sass b/src/app/components/feed/feed.component.sass index 2780ae2..c3d660c 100644 --- a/src/app/components/feed/feed.component.sass +++ b/src/app/components/feed/feed.component.sass @@ -8,6 +8,7 @@ #home width: 100% height: 100% + overflow-y: scroll #complete-feed box-sizing: border-box diff --git a/src/app/components/feed/feed.component.ts b/src/app/components/feed/feed.component.ts index d242979..d09566c 100644 --- a/src/app/components/feed/feed.component.ts +++ b/src/app/components/feed/feed.component.ts @@ -12,7 +12,8 @@ import { User } from 'src/app/models/user'; styleUrls: ['./feed.component.sass'] }) export class FeedComponent implements OnInit { - loading = true; + loadingNew = true; + loadingMostLiked = true; checked = false; // if the "I protected the environment."-box is checked view = 'new'; @@ -41,11 +42,20 @@ export class FeedComponent implements OnInit { this.activityService.activitylist.subscribe(response => { this.actionlist = response; }); - this.feedService.getNewPosts(); + this.feedService.getPosts('NEW'); this.feedService.posts.subscribe(response => { - if (response.length > 0) {this.loading = false; } + if (response.length > 0) { + // this.loading = false; + } this.parentSelectedPostList = response; }); + this.feedService.newPostsAvailable.subscribe(response => { + this.loadingNew = response; + }); + this.feedService.topPostsAvailable.subscribe(response => { + console.log(response); + this.loadingMostLiked = response; + }); } createPost(pElement, activityId: string) { @@ -62,11 +72,17 @@ export class FeedComponent implements OnInit { } } + onScroll() { + console.log('scrolled'); + this.feedService.getNextPosts(); + } + showNew() { - this.feedService.getNewPosts(); + this.feedService.getPosts('NEW'); } showMostLiked() { - this.feedService.getMostLikedPosts(); + this.view = 'mostLiked'; + this.feedService.getPosts('TOP'); } } diff --git a/src/app/services/feed/feed.service.ts b/src/app/services/feed/feed.service.ts index 6e94178..45f8c85 100644 --- a/src/app/services/feed/feed.service.ts +++ b/src/app/services/feed/feed.service.ts @@ -12,9 +12,14 @@ import { User } from 'src/app/models/user'; }) export class FeedService { + public newPostsAvailable = new BehaviorSubject(true); + public topPostsAvailable = new BehaviorSubject(true); public posts: BehaviorSubject = new BehaviorSubject(new Array()); public newPosts: BehaviorSubject = new BehaviorSubject(new Array()); public mostLikedPosts: BehaviorSubject = new BehaviorSubject(new Array()); + private activePostList = 'NEW'; + private mostLikedOffset = 0; + private newOffset = 0; constructor(private http: Http) { } @@ -49,7 +54,7 @@ export class FeedService { const updatedposts = this.newPosts.getValue(); updatedposts.unshift(this.renderPost(response.json())); this.newPosts.next(updatedposts); - this.posts.next(this.newPosts.getValue()); + this.setPost('NEW'); }); } @@ -85,7 +90,7 @@ export class FeedService { const updatedposts = this.newPosts.getValue(); updatedposts.unshift(this.renderPost(response.json())); this.newPosts.next(updatedposts); - this.posts.next(this.newPosts.getValue()); + this.setPost('NEW'); }); } @@ -132,59 +137,67 @@ export class FeedService { return this.http.post(environment.graphQLUrl, body); } - public getNewPosts() { - if (this.newPosts.getValue().length === 0) { + public getPosts(sort: string) { + if ((sort === 'NEW' && this.newPosts.getValue().length === 0) || + (sort === 'TOP' && this.mostLikedPosts.getValue().length === 0)) { const headers = new Headers(); headers.set('Content-Type', 'application/json'); - this.http.post(environment.graphQLUrl, this.buildJsonNew()) + this.http.post(environment.graphQLUrl, this.buildJson(sort, 0)) .subscribe(response => { - this.newPosts.next(this.renderAllPosts(response.json())); - this.posts.next(this.newPosts.getValue()); + if (sort === 'NEW') { + this.newPosts.next(this.renderAllPosts(response.json())); + } else if (sort === 'TOP') { + this.mostLikedPosts.next(this.renderAllPosts(response.json())); + } + this.setPost(sort); }); - } else {this.posts.next(this.newPosts.getValue()); } + } this.setPost(sort); } - public getMostLikedPosts() { - if (this.mostLikedPosts.getValue().length === 0) { + public getNextPosts() { + if (this.activePostList === 'NEW' && this.newPostsAvailable) { + this.newOffset += 10; + const headers = new Headers(); + headers.set('Content-Type', 'application/json'); + this.http.post(environment.graphQLUrl, this.buildJson(this.activePostList, this.newOffset)) + .subscribe(response => { + let updatedposts = this.newPosts.getValue(); + updatedposts = updatedposts.concat(this.renderAllPosts(response.json())); + if (this.renderAllPosts(response.json()).length < 1) { + this.newPostsAvailable.next(false); + } + this.newPosts.next(updatedposts); + this.setPost('NEW'); + }); + } else if (this.activePostList === 'TOP' && this.topPostsAvailable) { + this.mostLikedOffset += 10; const headers = new Headers(); headers.set('Content-Type', 'application/json'); - this.http.post(environment.graphQLUrl, this.buildJsonMostLiked()) + this.http.post(environment.graphQLUrl, this.buildJson(this.activePostList, this.mostLikedOffset)) .subscribe(response => { - this.mostLikedPosts.next(this.renderAllPosts(response.json())); - this.posts.next(this.mostLikedPosts.getValue()); + let updatedposts = this.mostLikedPosts.getValue(); + updatedposts = updatedposts.concat(this.renderAllPosts(response.json())); + if (this.renderAllPosts(response.json()).length < 1) { + this.topPostsAvailable.next(false); + } + this.mostLikedPosts.next(updatedposts); + this.setPost('TOP'); }); - } else {this.posts.next(this.mostLikedPosts.getValue()); } + } } - buildJsonNew() { - const body = {query: `{ - getPosts (first: 1000, offset: 0) { - id, - content, - htmlContent, - upvotes, - downvotes, - userVote, - deletable, - activity{ - id - name - description - points - }, - author{ - name, - handle, - id}, - createdAt} - }`, variables: { - }}; - return body; + setPost(sort: string) { + this.activePostList = sort; + if (sort === 'NEW') { + this.posts.next(this.newPosts.getValue()); + } else if (sort === 'TOP') { + this.posts.next(this.mostLikedPosts.getValue()); + } } - buildJsonMostLiked() { - const body = {query: `{ - getPosts (first: 1000, offset: 0, sort: TOP) { + buildJson(sort: string, offset: number) { + const body = {query: `query($offset: Int, $sort: SortType){ + getPosts (first: 10, offset: $offset, sort: $sort) { id, content, htmlContent, @@ -204,6 +217,8 @@ export class FeedService { id}, createdAt} }`, variables: { + offset, + sort }}; return body; }