Merge branch 'master' of Software_Engineering_I/greenvironment-frontend into max_dev

master
Max_ES 5 years ago committed by Gitea
commit 194e6a3411

@ -6,7 +6,21 @@ html, body
height: 100% height: 100%
::ng-deep body
scrollbar-color: #aaa #ddd
scrollbar-width: thin
.dark-theme
scrollbar-color: #ddd #666
::ng-deep ::-webkit-scrollbar
width: 4px
::ng-deep ::-webkit-scrollbar-track
background: #ddd
.dark-theme
background: #666
::ng-deep ::-webkit-scrollbar-thumb
background: #aaa
.dark-theme
background: #ddd

@ -6,8 +6,6 @@ import {SocketIoConfig, SocketIoModule} from 'ngx-socket-io';
import {HttpModule} from '@angular/http'; import {HttpModule} from '@angular/http';
import {AppComponent} from './app.component'; import {AppComponent} from './app.component';
import {DocumentListComponent} from './components/document-list/document-list.component';
import {DocumentComponent} from './components/document/document.component';
import {RegisterComponent} from './components/register/register.component'; import {RegisterComponent} from './components/register/register.component';
import {LoginComponent} from './components/login/login.component'; import {LoginComponent} from './components/login/login.component';
import {ChatComponent} from './components/chat/chat.component'; import {ChatComponent} from './components/chat/chat.component';
@ -81,8 +79,6 @@ const appRoutes: Routes = [
@NgModule({ @NgModule({
declarations: [ declarations: [
AppComponent, AppComponent,
DocumentListComponent,
DocumentComponent,
RegisterComponent, RegisterComponent,
LoginComponent, LoginComponent,
ChatComponent, ChatComponent,

@ -51,7 +51,6 @@ export class ChatmanagerComponent implements OnInit {
refresh() { refresh() {
this.chatService.getAllChatsRaw() this.chatService.getAllChatsRaw()
.subscribe(response => { .subscribe(response => {
console.log(response);
this.parentChats = this.chatService.renderAllChats(response.json()); this.parentChats = this.chatService.renderAllChats(response.json());
}); });
} }

@ -1,5 +0,0 @@
<div class='sidenav'>
<span (click)='newDoc()'>New Document</span>
<span [class.selected]='docId === currentDoc' (click)='loadDoc(docId)'
*ngFor='let docId of documents | async'>{{ docId }}</span>
</div>

@ -1,28 +0,0 @@
.sidenav {
position: fixed;
height: 100%;
width: 220px;
top: 0;
left: 0;
background-color: #111111;
overflow-x: hidden;
padding-top: 20px;
span {
padding: 6px 8px 6px 16px;
text-decoration: none;
font-size: 25px;
font-family: 'Roboto', Tahoma, Geneva, Verdana, sans-serif;
color: #818181;
display: block;
}
.selected {
color: #e1e1e1;
}
:hover {
color: #f1f1f1;
cursor: pointer;
}
}

@ -1,25 +0,0 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {DocumentListComponent} from './document-list.component';
describe('DocumentListComponent', () => {
let component: DocumentListComponent;
let fixture: ComponentFixture<DocumentListComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DocumentListComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DocumentListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -1,36 +0,0 @@
import {Component, OnDestroy, OnInit} from '@angular/core';
import {Observable, Subscription} from 'rxjs';
import {DocumentService} from 'src/app/services/document.service';
@Component({
selector: 'app-document-list',
templateUrl: './document-list.component.html',
styleUrls: ['./document-list.component.scss']
})
export class DocumentListComponent implements OnInit, OnDestroy {
documents: Observable<string[]>;
currentDoc: string;
private _docSub: Subscription;
constructor(private documentService: DocumentService) {
}
ngOnInit() {
this.documents = this.documentService.documents;
this._docSub = this.documentService.currentDocument.subscribe(doc => this.currentDoc = doc.id);
}
ngOnDestroy() {
this._docSub.unsubscribe();
}
loadDoc(id: string) {
this.documentService.getDocument(id);
}
newDoc() {
this.documentService.newDocument();
}
}

@ -1 +0,0 @@
<textarea [(ngModel)]='document.doc' (keyup)='editDoc()' placeholder='Start typing...'></textarea>

@ -1,12 +0,0 @@
textarea {
position: fixed;
width: calc(100% - 235px);
height: 100%;
right: 0;
top: 0;
font-size: 18pt;
padding-top: 20px;
resize: none;
border: none;
padding: 20px 0px 20px 15px;
}

@ -1,25 +0,0 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {DocumentComponent} from './document.component';
describe('DocumentComponent', () => {
let component: DocumentComponent;
let fixture: ComponentFixture<DocumentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DocumentComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DocumentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -1,32 +0,0 @@
import {Component, OnDestroy, OnInit} from '@angular/core';
import {DocumentService} from 'src/app/services/document.service';
import {Subscription} from 'rxjs';
import {Document} from 'src/app/models/document';
import {startWith} from 'rxjs/operators';
@Component({
selector: 'app-document',
templateUrl: './document.component.html',
styleUrls: ['./document.component.scss']
})
export class DocumentComponent implements OnInit, OnDestroy {
document: Document;
private _docSub: Subscription;
constructor(private documentService: DocumentService) {
}
ngOnInit() {
this._docSub = this.documentService.currentDocument.pipe(
startWith({id: '', doc: 'Select an existing document or create a new one to get started'})
).subscribe(document => this.document = document);
}
ngOnDestroy() {
this._docSub.unsubscribe();
}
editDoc() {
this.documentService.editDocument(this.document);
}
}

@ -1,6 +1,6 @@
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {Post} from 'src/app/models/post'; 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 {Activitylist} from 'src/app/models/activity';
import {DatasharingService} from '../../services/datasharing.service'; import {DatasharingService} from '../../services/datasharing.service';
import {ActivityService} from 'src/app/services/activity/activity.service'; import {ActivityService} from 'src/app/services/activity/activity.service';
@ -39,7 +39,6 @@ export class FeedComponent implements OnInit {
} }
ngOnInit() { ngOnInit() {
console.log('init feedcomponent');
this.data.currentUserInfo.subscribe(user => { this.data.currentUserInfo.subscribe(user => {
this.user = user; this.user = user;
this.loggedIn = user.loggedIn; this.loggedIn = user.loggedIn;
@ -48,33 +47,41 @@ export class FeedComponent implements OnInit {
this.activityService.activitylist.subscribe(response => { this.activityService.activitylist.subscribe(response => {
this.actionlist = response; this.actionlist = response;
}); });
this.feedService.getPosts('NEW'); this.feedService.getPosts(Sort.NEW);
this.feedService.posts.subscribe(response => { this.feedService.posts.subscribe(response => {
this.parentSelectedPostList = response; this.parentSelectedPostList = response;
}); });
this.feedService.newPostsAvailable.subscribe(response => { this.feedService.postsAvailable.subscribe(available => {
this.loadingNew = response; this.loadingMostLiked = this.loadingNew = available;
});
this.feedService.topPostsAvailable.subscribe(response => {
this.loadingMostLiked = response;
}); });
} }
createPost(pElement, activityId: string) { /**
if (pElement && activityId && this.checked) { * Creates a new post
this.feedService.createPostActivity(pElement.value, activityId).subscribe(() => { * @param postElement
pElement.value = ''; * @param activityId
*/
createPost(postElement, activityId: string) {
if (postElement && activityId && this.checked) {
this.feedService.createPostActivity(postElement.value, activityId).subscribe(() => {
postElement.value = '';
this.textInputValue = ''; this.textInputValue = '';
this.view = 'new'; this.checked = false;
if (this.view !== 'new') {
this.showNew();
}
}, (error: IErrorResponse) => { }, (error: IErrorResponse) => {
this.errorOccurred = true; this.errorOccurred = true;
this.errorMessage = error.error.errors[0].message; this.errorMessage = error.error.errors[0].message;
}); });
} else if (pElement) { } else if (postElement) {
this.feedService.createPost(pElement.value).subscribe(() => { this.feedService.createPost(postElement.value).subscribe(() => {
pElement.value = ''; postElement.value = '';
this.textInputValue = ''; this.textInputValue = '';
this.view = 'new'; this.checked = false;
if (this.view !== 'new') {
this.showNew();
}
}, (error: IErrorResponse) => { }, (error: IErrorResponse) => {
this.errorOccurred = true; this.errorOccurred = true;
this.errorMessage = error.error.errors[0].message; this.errorMessage = error.error.errors[0].message;
@ -82,16 +89,27 @@ export class FeedComponent implements OnInit {
} }
} }
/**
* Fetches the next posts when scrolled
*/
onScroll() { onScroll() {
this.feedService.getNextPosts(); this.feedService.getNextPosts();
} }
/**
* Shows the feed sorted by new
*/
showNew() { showNew() {
this.feedService.getPosts('NEW'); this.view = 'new';
this.feedService.getPosts(Sort.NEW);
} }
/**
* Shows the feed sorted by top
*/
showMostLiked() { showMostLiked() {
this.feedService.getPosts('TOP'); this.view = 'mostliked';
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 class="post" *ngFor="let post of childPostList" [class.selected]="post === selectedPost" tabindex="0">
<mat-card-header> <mat-card-header>
<div mat-card-avatar> <div mat-card-avatar>
@ -34,17 +13,14 @@
</button> </button>
</mat-menu> </mat-menu>
</div> </div>
<!-- <div mat-card-avatar class="example-header-image"></div> -->
<mat-card-title> <mat-card-title>
{{post.author.name}} {{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> <a class="mat-card-subtitle" (click)="showUserProfile(this.post)">@{{post.author.handle}}</a>
<p class="mat-card-subtitle">&nbsp; {{post.date}}</p> <p class="mat-card-subtitle">&nbsp; {{post.date}}</p>
</mat-card-title> </mat-card-title>
<mat-card-subtitle> <mat-card-subtitle>
</mat-card-subtitle> </mat-card-subtitle>
</mat-card-header> </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> <mat-card-content>
<p [innerHTML]="post.htmlContent"></p> <p [innerHTML]="post.htmlContent"></p>
</mat-card-content> </mat-card-content>
@ -66,4 +42,3 @@
</div> </div>
</mat-card-actions> </mat-card-actions>
</mat-card> </mat-card>

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

@ -32,8 +32,6 @@ export class DialogCreateEventComponent {
name = name.trim(); name = name.trim();
if (name && date && time) { if (name && date && time) {
date = date + ' ' + time; date = date + ' ' + time;
console.log(date);
console.log(new Date(date).getTime().toString());
this.group.createEvent(name, (new Date(date)).getTime().toString(), this.groupId); this.group.createEvent(name, (new Date(date)).getTime().toString(), this.groupId);
this.dialogRef.close(); this.dialogRef.close();
} }
@ -69,7 +67,6 @@ export class GroupComponent implements OnInit {
const possibleID = this.router.url.substr(this.router.url.lastIndexOf('/') + 1); const possibleID = this.router.url.substr(this.router.url.lastIndexOf('/') + 1);
if (this.id !== possibleID && this.id && this.router.url.includes('group/')) { if (this.id !== possibleID && this.id && this.router.url.includes('group/')) {
// reload the group // reload the group
console.log('search for group id: ' + this.router.url.substr(this.router.url.lastIndexOf('/') + 1));
this.ngOnInit(); this.ngOnInit();
} }
} }

@ -121,7 +121,6 @@ export class MainNavigationComponent implements OnInit {
}` }`
}; };
this.http.post(url, body).subscribe(response => { this.http.post(url, body).subscribe(response => {
console.log(response.text());
}); });
this.loggedIn = false; this.loggedIn = false;
const user = new User(); const user = new User();
@ -131,12 +130,10 @@ export class MainNavigationComponent implements OnInit {
} }
acceptRequest(id: number) { acceptRequest(id: number) {
console.log('try to accept request from id: ' + id);
const headers = new Headers(); const headers = new Headers();
headers.set('Content-Type', 'application/json'); headers.set('Content-Type', 'application/json');
this.http.post(environment.graphQLUrl, this.requestservice.buildJsonAcceptRequest(id)) this.http.post(environment.graphQLUrl, this.requestservice.buildJsonAcceptRequest(id))
.subscribe(response => { .subscribe(response => {
console.log(response);
for (let i = 0; i < this.user.receivedRequests.length; i++) { for (let i = 0; i < this.user.receivedRequests.length; i++) {
if (this.user.receivedRequests[i].senderUserID === id) { if (this.user.receivedRequests[i].senderUserID === id) {
this.user.receivedRequests.splice(i, 1); this.user.receivedRequests.splice(i, 1);
@ -151,7 +148,6 @@ export class MainNavigationComponent implements OnInit {
headers.set('Content-Type', 'application/json'); headers.set('Content-Type', 'application/json');
this.http.post(environment.graphQLUrl, this.requestservice.buildJsonDenyRequest(id)) this.http.post(environment.graphQLUrl, this.requestservice.buildJsonDenyRequest(id))
.subscribe(response => { .subscribe(response => {
console.log(response);
for (let i = 0; i < this.user.receivedRequests.length; i++) { for (let i = 0; i < this.user.receivedRequests.length; i++) {
if (this.user.receivedRequests[i].senderUserID === id) { if (this.user.receivedRequests[i].senderUserID === id) {
this.user.receivedRequests.splice(i, 1); this.user.receivedRequests.splice(i, 1);

@ -54,7 +54,7 @@ export class DialogFileUploadComponent {
}, (error) => { }, (error) => {
this.uploading = false; this.uploading = false;
this.errorOccurred = true; this.errorOccurred = true;
console.log(error); console.error(error);
if (error.error) { if (error.error) {
this.errorMessage = error.error.error; this.errorMessage = error.error.error;
} else { } else {

@ -60,7 +60,6 @@ export class ProfileComponent implements OnInit {
this.userProfile = response; this.userProfile = response;
// tslint:disable-next-line:max-line-length // tslint:disable-next-line:max-line-length
this.userProfile.allowedToSendRequest = this.requestService.isAllowedToSendRequest(this.userProfile.userID, this.self); this.userProfile.allowedToSendRequest = this.requestService.isAllowedToSendRequest(this.userProfile.userID, this.self);
console.log(this.userProfile.allowedToSendRequest);
this.ownProfile = this.userProfile.userID === this.self.userID; this.ownProfile = this.userProfile.userID === this.self.userID;
this.rankname = this.levellist.getLevelName(this.userProfile.level); this.rankname = this.levellist.getLevelName(this.userProfile.level);
} else { } else {

@ -44,8 +44,6 @@ export class SearchComponent implements OnInit {
if (this.category === 'user') { if (this.category === 'user') {
this.loading = true; this.loading = true;
this.findUser(searchWord); this.findUser(searchWord);
} else if (this.category === 'groupe') {
console.log('search group');
} }
} }
} }

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

@ -1,14 +1,38 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {HttpHeaders} from '@angular/common/http'; import { HttpErrorResponse, HttpHeaders} from '@angular/common/http';
import {delay, mergeMap, retryWhen} from 'rxjs/operators';
import {Observable, of, throwError} from 'rxjs';
const httpTooManyCode = 429;
const httpHeaderRateRetry = 'Retry-After';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export abstract class BaseService { export abstract class BaseService {
protected headers: HttpHeaders; protected headers: HttpHeaders;
protected constructor() { protected constructor() {
this.headers = new HttpHeaders(); this.headers = new HttpHeaders();
this.headers.set('Content-Type', 'application/json'); this.headers.set('Content-Type', 'application/json');
} }
/**
* Retries a request according to the rate limit
* @param maxRetry
*/
protected retryRated(maxRetry = 3) {
let retries = maxRetry;
return (src: Observable<any>) => {
return src.pipe(retryWhen(errors => errors.pipe(mergeMap(error => {
if (error.status === httpTooManyCode) {
const retryAfter = Number(error.headers.get(httpHeaderRateRetry) || 1) * 1000;
return of(error.status).pipe(delay(retryAfter));
} else if (retries-- > 0) {
return of(error).pipe(delay(10000));
}
return throwError(error);
}))
));
};
}
} }

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

@ -77,7 +77,9 @@ export class ProfileService extends BaseService {
public getUserData(userId: string) { public getUserData(userId: string) {
const headers = new Headers(); const headers = new Headers();
headers.set('Content-Type', 'application/json'); headers.set('Content-Type', 'application/json');
this.http.post(environment.graphQLUrl, ProfileService.buildGetProfileBody(userId)).subscribe(result => { this.http.post(environment.graphQLUrl, ProfileService.buildGetProfileBody(userId))
.pipe(this.retryRated())
.subscribe(result => {
this.proflile.next(this.getProfileData(result)); this.proflile.next(this.getProfileData(result));
return this.proflile; return this.proflile;
}); });

@ -26,7 +26,6 @@ export class RegisterService {
return this.http.post(url, this.buildJson(registration)) return this.http.post(url, this.buildJson(registration))
.subscribe(response => { .subscribe(response => {
console.log(response.text());
this.registerSuccess(); this.registerSuccess();
this.updateUserInfo(response.json()); this.updateUserInfo(response.json());
}, errorCb }, errorCb
@ -34,8 +33,6 @@ export class RegisterService {
} }
public registerSuccess() { public registerSuccess() {
console.log('alles supi dupi');
// do routing
this.router.navigateByUrl(''); this.router.navigateByUrl('');
} }

@ -101,6 +101,7 @@ export class SearchService extends BaseService {
*/ */
public search(query: string): Observable<ISearchRequestResult> { public search(query: string): Observable<ISearchRequestResult> {
const body = SearchService.buildRequestBody(query); const body = SearchService.buildRequestBody(query);
return this.http.post<ISearchRequestResult>(environment.graphQLUrl, body, {headers: this.headers}); return this.http.post<ISearchRequestResult>(environment.graphQLUrl, body, {headers: this.headers})
.pipe(this.retryRated());
} }
} }

@ -62,6 +62,7 @@ export class SelfService extends BaseService {
headers.set('Content-Type', 'application/json'); headers.set('Content-Type', 'application/json');
return this.http.post(url, SelfService.buildGetSelfBody(), {headers: this.headers}) return this.http.post(url, SelfService.buildGetSelfBody(), {headers: this.headers})
.pipe(this.retryRated())
.pipe(tap(response => { .pipe(tap(response => {
this.updateUserInfo(response); this.updateUserInfo(response);
})); }));
@ -74,7 +75,8 @@ export class SelfService extends BaseService {
public changeProfilePicture(file: any) { public changeProfilePicture(file: any) {
const formData: any = new FormData(); const formData: any = new FormData();
formData.append('profilePicture', file); formData.append('profilePicture', file);
return this.http.post<IFileUploadResult>(environment.greenvironmentUrl + '/upload', formData); return this.http.post<IFileUploadResult>(environment.greenvironmentUrl + '/upload', formData)
.pipe(this.retryRated());
} }
/** /**

@ -20,9 +20,7 @@ export class SettingsService {
const headers = new Headers(); const headers = new Headers();
headers.set('Content-Type', 'application/json'); headers.set('Content-Type', 'application/json');
const body = this.buildJsonDarkMode('darkmode: ' + '\'' + active + '\''); const body = this.buildJsonDarkMode('darkmode: ' + '\'' + active + '\'');
this.http.post(url, body).subscribe(response => { this.http.post(url, body).subscribe();
console.log(response.text());
});
} }
public buildJsonDarkMode(setting_: string): any { public buildJsonDarkMode(setting_: string): any {

@ -36,6 +36,7 @@ export class SocialService extends BaseService {
*/ */
createGroup(name: string) { createGroup(name: string) {
const body = SocialService.buildGroupCreateBody(name); const body = SocialService.buildGroupCreateBody(name);
return this.http.post(environment.graphQLUrl, body, {headers: this.headers}); return this.http.post(environment.graphQLUrl, body, {headers: this.headers})
.pipe(this.retryRated());
} }
} }

@ -48,4 +48,4 @@
"type": "image/png" "type": "image/png"
} }
] ]
} }

@ -1,8 +1,5 @@
::-webkit-scrollbar @mixin gridPosition($rowStart, $rowEnd, $columnStart, $columnEnd)
width: 4px grid-row-start: $rowStart
grid-row-end: $rowEnd
::-webkit-scrollbar-track grid-column-start: $columnStart
background: #ddd grid-column-end: $columnEnd
::-webkit-scrollbar-thumb
background: #666

Loading…
Cancel
Save