Refactor postlist and feed

master
trivernis 5 years ago
parent 9ddc7de6ef
commit 300b84ea85

@ -1,6 +1,6 @@
import {Component, OnInit} from '@angular/core';
import {Post} from 'src/app/models/post';
import {FeedService} from 'src/app/services/feed/feed.service';
import {FeedService, Sort} from 'src/app/services/feed/feed.service';
import {Activitylist} from 'src/app/models/activity';
import {DatasharingService} from '../../services/datasharing.service';
import {ActivityService} from 'src/app/services/activity/activity.service';
@ -47,32 +47,33 @@ export class FeedComponent implements OnInit {
this.activityService.activitylist.subscribe(response => {
this.actionlist = response;
});
this.feedService.getPosts('NEW');
this.feedService.getPosts(Sort.NEW);
this.feedService.posts.subscribe(response => {
this.parentSelectedPostList = response;
});
this.feedService.newPostsAvailable.subscribe(response => {
this.loadingNew = response;
});
this.feedService.topPostsAvailable.subscribe(response => {
console.log(response);
this.loadingMostLiked = response;
this.feedService.postsAvailable.subscribe(available => {
this.loadingMostLiked = this.loadingNew = available;
});
}
createPost(pElement, activityId: string) {
if (pElement && activityId && this.checked) {
this.feedService.createPostActivity(pElement.value, activityId).subscribe(() => {
pElement.value = '';
/**
* Creates a new post
* @param postElement
* @param activityId
*/
createPost(postElement, activityId: string) {
if (postElement && activityId && this.checked) {
this.feedService.createPostActivity(postElement.value, activityId).subscribe(() => {
postElement.value = '';
this.textInputValue = '';
this.view = 'new';
}, (error: IErrorResponse) => {
this.errorOccurred = true;
this.errorMessage = error.error.errors[0].message;
});
} else if (pElement) {
this.feedService.createPost(pElement.value).subscribe(() => {
pElement.value = '';
} else if (postElement) {
this.feedService.createPost(postElement.value).subscribe(() => {
postElement.value = '';
this.textInputValue = '';
this.view = 'new';
}, (error: IErrorResponse) => {
@ -82,17 +83,25 @@ export class FeedComponent implements OnInit {
}
}
/**
* Fetches the next posts when scrolled
*/
onScroll() {
console.log('scrolled');
this.feedService.getNextPosts();
}
/**
* Shows the feed sorted by new
*/
showNew() {
this.feedService.getPosts('NEW');
this.feedService.getPosts(Sort.NEW);
}
/**
* Shows the feed sorted by top
*/
showMostLiked() {
this.feedService.getPosts('TOP');
this.feedService.getPosts(Sort.TOP);
}
/**

@ -1,24 +1,3 @@
<!--<div class="feeditem" *ngFor = "let post of childPostList" [class.selected]="post === selectedPost">
<div class="itemhead">
<div class="usertag">
<span class="title">{{post.author.name}}</span>
<span class="handle"><a href="profile/{{post.author.id}}">@{{post.author.handle}}</a></span>
</div>
<span class="date">{{post.date}}</span>
</div>
<div class="itembody">
<div class='text'>
<p [innerHTML]="post.htmlContent" id="content"></p>
</div>
<div class="vote">
<button id="down" type='submit'><span><i class="fa fa-thumbs-o-down fa-2x" aria-hidden="true" (click)="voteDown(post)"></i></span></button>
<span id="downvotes">{{post.downvotes}}</span>
<button id="up" type='submit'><span><i class="fa fa-thumbs-o-up fa-2x" aria-hidden="true" (click)="voteUp(post)"></i></span></button>
<span id="upvotes">{{post.upvotes}}</span>
</div>
</div>
</div>-->
<mat-card class="post" *ngFor="let post of childPostList" [class.selected]="post === selectedPost" tabindex="0">
<mat-card-header>
<div mat-card-avatar>
@ -34,17 +13,14 @@
</button>
</mat-menu>
</div>
<!-- <div mat-card-avatar class="example-header-image"></div> -->
<mat-card-title>
{{post.author.name}}
<!--<a class="mat-card-subtitle" routerLink="/profile/{{post.author.id}}">@{{post.author.handle}}</a>-->
<a class="mat-card-subtitle" (click)="showUserProfile(this.post)">@{{post.author.handle}}</a>
<p class="mat-card-subtitle">&nbsp; {{post.date}}</p>
</mat-card-title>
<mat-card-subtitle>
</mat-card-subtitle>
</mat-card-header>
<!--<img mat-card-image src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu">-->
<mat-card-content>
<p [innerHTML]="post.htmlContent"></p>
</mat-card-content>
@ -66,4 +42,3 @@
</div>
</mat-card-actions>
</mat-card>

@ -10,7 +10,7 @@ import {Router} from '@angular/router';
})
export class PostlistComponent implements OnInit {
@Input() childPostList: Array<Post>;
@Input() childPostList: Post[];
@Output() voteEvent = new EventEmitter<boolean>();
selectedPost: Post;

@ -13,28 +13,27 @@ export class Post {
author: Author;
activity: Activity;
// TODO: constructor properties need normal names
constructor(
pId: number,
pContent: string,
pHtmlContent: string,
pUpvotes: number,
pDownvotes: number,
pUserVote: string,
pDeletable: boolean,
pDate: string,
pAuthor: Author,
pactivity: Activity
id: number,
content: string,
htmlContent: string,
upvotes: number,
downvotes: number,
userVotes: string,
deletable: boolean,
date: string,
author: Author,
activity: Activity
) {
this.id = pId;
this.content = pContent;
this.htmlContent = pHtmlContent;
this.upvotes = pUpvotes;
this.downvotes = pDownvotes;
this.userVote = pUserVote;
this.deletable = pDeletable;
this.date = pDate;
this.author = pAuthor;
this.activity = pactivity;
this.id = id;
this.content = content;
this.htmlContent = htmlContent;
this.upvotes = upvotes;
this.downvotes = downvotes;
this.userVote = userVotes;
this.deletable = deletable;
this.date = date;
this.author = author;
this.activity = activity;
}
}

@ -6,139 +6,202 @@ import {environment} from 'src/environments/environment';
import {Activity} from 'src/app/models/activity';
import {BehaviorSubject} from 'rxjs';
import {tap} from 'rxjs/operators';
import {BaseService} from '../base.service';
const createPostGqlQuery = `mutation($content: String!) {
createPost(content: $content) {
id,
content,
htmlContent,
upvotes,
downvotes,
userVote,
deletable,
activity{
id
name
description
points
},
author{
name,
handle,
profilePicture,
id},
createdAt}
}`;
const createPostActivityGqlQuery = `mutation($content: String!, $id: ID) {
createPost(content: $content activityId: $id) {
id,
content,
htmlContent,
upvotes,
downvotes,
userVote,
deletable,
activity{
id
name
description
points
},
author{
name,
handle,
profilePicture,
id},
createdAt}
}`;
const upvotePostGqlQuery = `mutation($postId: ID!) {
vote(postId: $postId, type: UPVOTE) {
post{userVote upvotes downvotes}
}
}`;
const downvotePostGqlQuery = `mutation($postId: ID!) {
vote(postId: $postId, type: DOWNVOTE) {
post{userVote upvotes downvotes}
}
}`;
const getPostGqlQuery = `query($first: Int, $offset: Int, $sort: SortType){
getPosts (first: $first, offset: $offset, sort: $sort) {
id,
content,
htmlContent,
upvotes,
downvotes,
userVote,
deletable,
activity{
id
name
description
points
},
author{
name,
handle,
profilePicture,
id},
createdAt}
}`;
export enum Sort {
NEW = 'NEW',
TOP = 'TOP',
}
@Injectable({
providedIn: 'root'
})
export class FeedService {
export class FeedService extends BaseService {
constructor(private http: HttpClient) {
super();
}
public newPostsAvailable = new BehaviorSubject<boolean>(true);
public topPostsAvailable = new BehaviorSubject<boolean>(true);
public postsAvailable = new BehaviorSubject<boolean>(true);
public posts: BehaviorSubject<Post[]> = new BehaviorSubject([]);
public newPosts: BehaviorSubject<Post[]> = new BehaviorSubject([]);
public mostLikedPosts: BehaviorSubject<Post[]> = new BehaviorSubject([]);
private activePostList = 'NEW';
private mostLikedOffset = 0;
private newOffset = 0;
private activePostList: Sort = Sort.NEW;
private offset = 0;
private offsetStep = 10;
constructor(private http: HttpClient) {
/**
* Builds the body for a getPost request
* @param sort
* @param offset
* @param first
*/
private static buildGetPostBody(sort: string, offset: number, first: number = 10) {
return {
query: getPostGqlQuery, variables: {
first,
offset,
sort
}
};
}
/**
* Creates a new post
* @param pContent
*/
public createPost(pContent: String) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
const body = {
query: `mutation($content: String!) {
createPost(content: $content) {
id,
content,
htmlContent,
upvotes,
downvotes,
userVote,
deletable,
activity{
id
name
description
points
},
author{
name,
handle,
profilePicture,
id},
createdAt}
}`, variables: {
query: createPostGqlQuery,
variables: {
content: pContent
}
};
return this.http.post(environment.graphQLUrl, body).pipe(tap(response => {
const updatedposts = this.newPosts.getValue();
updatedposts.unshift(this.renderPost(response));
this.newPosts.next(updatedposts);
this.setPost('NEW');
}));
return this.createPostRequest(body);
}
/**
* Creates a post with an activity
* @param pContent
* @param activityId
*/
public createPostActivity(pContent: String, activityId: String) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
const body = {
query: `mutation($content: String!, $id: ID) {
createPost(content: $content activityId: $id) {
id,
content,
htmlContent,
upvotes,
downvotes,
userVote,
deletable,
activity{
id
name
description
points
},
author{
name,
handle,
profilePicture,
id},
createdAt}
}`, variables: {
query: createPostActivityGqlQuery, variables: {
content: pContent,
id: activityId
}
};
return this.http.post(environment.graphQLUrl, body).pipe(tap(response => {
const updatedposts = this.newPosts.getValue();
updatedposts.unshift(this.renderPost(response));
this.newPosts.next(updatedposts);
this.setPost('NEW');
}));
return this.createPostRequest(body);
}
public upvote(postId: number): any {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
/**
* Creates a new post with a given request.
* @param body
*/
private createPostRequest(body: { variables: any; query: string }) {
return this.http.post(environment.graphQLUrl, body, {headers: this.headers})
.pipe(tap(response => {
if (this.activePostList === Sort.NEW) {
const updatedPosts = this.posts.getValue();
updatedPosts.push(this.constructPost(response));
this.posts.next(updatedPosts);
}
}));
}
/**
* Upvotes a post
* @param postId
*/
public upvote(postId: number): any {
const body = {
query: `mutation($postId: ID!) {
vote(postId: $postId, type: UPVOTE) {
post{userVote upvotes downvotes}
}
}`, variables: {
query: upvotePostGqlQuery, variables: {
postId
}
};
return this.http.post(environment.graphQLUrl, body);
return this.http.post(environment.graphQLUrl, body, {headers: this.headers});
}
public downvote(pPostID: number): any {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
/**
* Downvotes a post
* @param postId
*/
public downvote(postId: number): any {
const body = {
query: `mutation($postId: ID!) {
vote(postId: $postId, type: DOWNVOTE) {
post{userVote upvotes downvotes}
}
}`, variables: {
postId: pPostID
query: downvotePostGqlQuery, variables: {
postId
}
};
return this.http.post(environment.graphQLUrl, body);
return this.http.post(environment.graphQLUrl, body, {headers: this.headers});
}
/**
* Deletes a post
* @param pPostID
*/
public deletePost(pPostID: number): any {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
const body = {
query: `mutation($postId: ID!) {
deletePost(postId: $postId)
@ -147,108 +210,43 @@ export class FeedService {
}
};
return this.http.post(environment.graphQLUrl, body);
return this.http.post(environment.graphQLUrl, body, {headers: this.headers});
}
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.buildJson(sort, 0))
.subscribe(response => {
if (sort === 'NEW') {
this.newPosts.next(this.renderAllPosts(response));
} else if (sort === 'TOP') {
this.mostLikedPosts.next(this.renderAllPosts(response));
}
this.setPost(sort);
});
}
this.setPost(sort);
/**
* Resets the post list and fetches new posts for the given sorting
* @param sort
*/
public getPosts(sort: Sort) {
this.offset = 0;
this.postsAvailable.next(true);
this.posts.next([]);
return this.http.post(environment.graphQLUrl, FeedService.buildGetPostBody(sort, 0),
{headers: this.headers}).subscribe(response => {
this.posts.next(this.constructAllPosts(response));
this.activePostList = sort;
});
}
/**
* Fetches the next posts for the current sorting
*/
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));
if (this.renderAllPosts(response).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.buildJson(this.activePostList, this.mostLikedOffset))
.subscribe(response => {
let updatedposts = this.mostLikedPosts.getValue();
updatedposts = updatedposts.concat(this.renderAllPosts(response));
if (this.renderAllPosts(response).length < 1) {
this.topPostsAvailable.next(false);
}
this.mostLikedPosts.next(updatedposts);
this.setPost('TOP');
});
}
}
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());
}
}
buildJson(sort: string, offset: number) {
const body = {
query: `query($offset: Int, $sort: SortType){
getPosts (first: 10, offset: $offset, sort: $sort) {
id,
content,
htmlContent,
upvotes,
downvotes,
userVote,
deletable,
activity{
id
name
description
points
},
author{
name,
handle,
profilePicture,
id},
createdAt}
}`, variables: {
offset,
sort
}
};
return body;
this.offset += this.offsetStep;
const body = FeedService.buildGetPostBody(this.activePostList, this.offset);
this.http.post(environment.graphQLUrl, body, {headers: this.headers})
.subscribe(response => {
const posts = this.constructAllPosts(response);
const updatedPostList = this.posts.getValue().concat(posts);
this.posts.next(updatedPostList);
if (posts.length < this.offsetStep) {
this.postsAvailable.next(false);
}
});
}
public renderPost(response: any): Post {
public constructPost(response: any): Post {
const post = response.data.createPost;
const id: number = post.id;
const content: string = post.content;
const htmlContent: string = post.htmlContent;
const upvotes: number = post.upvotes;
const downvotes: number = post.downvotes;
const userVote: string = post.userVote;
const deletable: boolean = post.deletable;
let profilePicture: string;
if (post.author.profilePicture) {
profilePicture = environment.greenvironmentUrl + post.author.profilePicture;
@ -269,20 +267,22 @@ export class FeedService {
activity = null;
}
return new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, date, author, activity);
return new Post(
post.id,
post.content,
post.htmlContent,
post.upvotes,
post.downvotes,
post.userVote,
post.deletable,
date,
author,
activity);
}
public renderAllPosts(pResponse: any): Array<Post> {
public constructAllPosts(response: any): Post[] {
const posts = new Array<Post>();
// let options = {year: 'numeric', month: 'short', day: 'numeric', hour: '' }
for (const post of pResponse.data.getPosts) {
const id: number = post.id;
const content: string = post.content;
const htmlContent: string = post.htmlContent;
const upvotes: number = post.upvotes;
const downvotes: number = post.downvotes;
const userVote: string = post.userVote;
const deletable: boolean = post.deletable;
for (const post of response.data.getPosts) {
let profilePicture: string;
if (post.author.profilePicture) {
profilePicture = environment.greenvironmentUrl + post.author.profilePicture;
@ -302,7 +302,17 @@ export class FeedService {
} else {
activity = null;
}
posts.push(new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, date, author, activity));
posts.push(new Post(
post.id,
post.content,
post.htmlContent,
post.upvotes,
post.downvotes,
post.userVote,
post.deletable,
date,
author,
activity));
}
return posts;
}

Loading…
Cancel
Save