Add post reporting function

master
Max 5 years ago
parent 74a1b7a7ea
commit e112023dc3

@ -1,16 +1,23 @@
<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 (click)="showUserProfile(this.post)"> <div mat-card-avatar (click)="showUserProfile(this.post)">
<img class="profile-picture" [src]="post.author.profilePicture"/> <img class="profile-picture" [src]="post.author.profilePicture" />
</div> </div>
<div id="button-box"> <div id="button-box">
<button mat-icon-button [matMenuTriggerFor]="menu" id="menu-button" *ngIf="post.deletable"> <button mat-icon-button [matMenuTriggerFor]="menu" id="menu-button" *ngIf="loggedIn">
<mat-icon>more_vert</mat-icon> <mat-icon>more_vert</mat-icon>
</button> </button>
<mat-menu #menu="matMenu"> <mat-menu #menu="matMenu">
<button mat-menu-item (click)="deletePost(post)"> <button *ngIf="post.deletable" mat-menu-item (click)="deletePost(post)">
<span>delete post</span> <span>delete post</span>
</button> </button>
<button mat-menu-item [matMenuTriggerFor]="reportMenu">report</button>
</mat-menu>
<mat-menu #reportMenu="matMenu">
<button *ngFor="let reason of reportReasons" mat-menu-item [matTooltip]="reason.description"
matTooltipShowDelay="200" (click)="reportPost(reason, post)">
{{reason.name}}
</button>
</mat-menu> </mat-menu>
</div> </div>
<mat-card-title> <mat-card-title>
@ -22,10 +29,11 @@
</mat-card-subtitle> </mat-card-subtitle>
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content>
<mat-spinner *ngIf="post.mediaLoading && post.mediaType === 'IMAGE'" style="margin:0 auto; margin-top: 2em;" diameter="50"></mat-spinner> <mat-spinner *ngIf="post.mediaLoading && post.mediaType === 'IMAGE'" style="margin:0 auto; margin-top: 2em;"
diameter="50"></mat-spinner>
<div class="postMedia"> <div class="postMedia">
<div [hidden]="post.mediaLoading"> <div [hidden]="post.mediaLoading">
<img *ngIf="post.mediaType === 'IMAGE'" [src]="post.mediaUrl" (load)="onLoad(this.post)" alt="post image"/> <img *ngIf="post.mediaType === 'IMAGE'" [src]="post.mediaUrl" (load)="onLoad(this.post)" alt="post image" />
</div> </div>
<video *ngIf="post.mediaType === 'VIDEO'" controls> <video *ngIf="post.mediaType === 'VIDEO'" controls>
<source [src]="post.mediaUrl" type="video/webm"> <source [src]="post.mediaUrl" type="video/webm">
@ -41,13 +49,17 @@
</div> </div>
<div class="postVoteButtons"> <div class="postVoteButtons">
<button mat-button (click)="voteUp(post)" matTooltip="vote up" matTooltipShowDelay="500"> <button mat-button (click)="voteUp(post)" matTooltip="vote up" matTooltipShowDelay="500">
<mat-icon class="voteButton voted" aria-hidden="false" color="primary" *ngIf="post.userVote == 'UPVOTE'">thumb_up</mat-icon> <mat-icon class="voteButton voted" aria-hidden="false" color="primary" *ngIf="post.userVote == 'UPVOTE'">
<mat-icon class="voteButton" aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'DOWNVOTE'">thumb_up</mat-icon> thumb_up</mat-icon>
<mat-icon class="voteButton" aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'DOWNVOTE'">thumb_up
</mat-icon>
</button> </button>
<div class="voteCount">{{post.upvotes}}</div> <div class="voteCount">{{post.upvotes}}</div>
<button mat-button (click)="voteDown(post)" matTooltip="vote down" matTooltipShowDelay="500"> <button mat-button (click)="voteDown(post)" matTooltip="vote down" matTooltipShowDelay="500">
<mat-icon class="voteButton voted" aria-hidden="false" color="primary" *ngIf="post.userVote == 'DOWNVOTE'">thumb_down</mat-icon> <mat-icon class="voteButton voted" aria-hidden="false" color="primary" *ngIf="post.userVote == 'DOWNVOTE'">
<mat-icon class="voteButton" aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'UPVOTE'">thumb_down</mat-icon> thumb_down</mat-icon>
<mat-icon class="voteButton" aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'UPVOTE'">thumb_down
</mat-icon>
</button> </button>
<div class="voteCount">{{post.downvotes}}</div> <div class="voteCount">{{post.downvotes}}</div>
</div> </div>

@ -1,7 +1,10 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } 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 } from 'src/app/services/feed/feed.service';
import {Router} from '@angular/router'; import { Router } from '@angular/router';
import { DatasharingService } from 'src/app/services/datasharing.service';
import { ActivityService } from 'src/app/services/activity/activity.service';
import { ReportReason } from 'src/app/models/reportReason';
@Component({ @Component({
selector: 'feed-postlist', selector: 'feed-postlist',
@ -13,11 +16,23 @@ export class PostlistComponent implements OnInit {
@Input() childPostList: Post[]; @Input() childPostList: Post[];
@Output() voteEvent = new EventEmitter<boolean>(); @Output() voteEvent = new EventEmitter<boolean>();
selectedPost: Post; selectedPost: Post;
loggedIn = false;
reportReasons: ReportReason[] = new Array();
constructor(private feedService: FeedService, private router: Router) { constructor(private feedService: FeedService,
private data: DatasharingService,
private router: Router,
private activityService: ActivityService) {
} }
ngOnInit() { ngOnInit() {
this.data.currentUser.subscribe(user => {
this.loggedIn = user.loggedIn;
});
this.activityService.getReportReasons();
this.activityService.reportReasonList.subscribe(response => {
this.reportReasons = response;
});
} }
voteUp(pPost: Post) { voteUp(pPost: Post) {
@ -49,6 +64,10 @@ export class PostlistComponent implements OnInit {
}); });
} }
reportPost(reason: ReportReason, post: Post) {
this.feedService.reportPost(reason.id, post.id).subscribe();
}
onLoad(post: Post) { onLoad(post: Post) {
post.mediaLoading = false; post.mediaLoading = false;
} }

@ -134,7 +134,7 @@
</div> </div>
<mat-card-title class="pointer" (click)="showUserProfile(user)">{{user.username}}</mat-card-title> <mat-card-title class="pointer" (click)="showUserProfile(user)">{{user.username}}</mat-card-title>
<mat-card-subtitle class="pointer" (click)="showUserProfile(user)">{{user.handle}}</mat-card-subtitle> <mat-card-subtitle class="pointer" (click)="showUserProfile(user)">{{user.handle}}</mat-card-subtitle>
<mat-card-subtitle *ngIf="user.isGroupAdmin" class="pointer" (click)="showUserProfile(user)">[admin] <mat-card-subtitle hidden class="pointer" (click)="showUserProfile(user)">[admin]
</mat-card-subtitle> </mat-card-subtitle>
<div id="icon-box" *ngIf="isCreator"> <div id="icon-box" *ngIf="isCreator">
<button mat-icon-button [matMenuTriggerFor]="menu"> <button mat-icon-button [matMenuTriggerFor]="menu">

@ -0,0 +1,11 @@
export class ReportReason {
id: number;
name: string;
description: string;
constructor(id: number, name: string, describtion: string) {
this.id = id;
this.name = name;
this.description = describtion;
}
}

@ -1,10 +1,11 @@
import {Injectable} from '@angular/core'; import { Injectable } from '@angular/core';
import {BehaviorSubject} from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import {Activity, Activitylist} from 'src/app/models/activity'; import { Activity, Activitylist } from 'src/app/models/activity';
import {Level, LevelList} from 'src/app/models/levellist'; import { Level, LevelList } from 'src/app/models/levellist';
import {environment} from 'src/environments/environment'; import { ReportReason } from 'src/app/models/reportReason';
import {HttpClient, HttpErrorResponse} from '@angular/common/http'; import { environment } from 'src/environments/environment';
import {BaseService} from '../base.service'; import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { BaseService } from '../base.service';
@Injectable({ @Injectable({
@ -14,6 +15,7 @@ export class ActivityService extends BaseService {
public activitylist = new BehaviorSubject<Activitylist>(new Activitylist()); public activitylist = new BehaviorSubject<Activitylist>(new Activitylist());
public levelList = new BehaviorSubject<LevelList>(new LevelList()); public levelList = new BehaviorSubject<LevelList>(new LevelList());
public reportReasonList = new BehaviorSubject<ReportReason[]>(new Array());
constructor(http: HttpClient) { constructor(http: HttpClient) {
super(http); super(http);
@ -37,13 +39,22 @@ export class ActivityService extends BaseService {
return body; return body;
} }
private static buildGetReportReasonsBody(): any {
const body = {
query: `query{getReportReasons {
id name description
}}`, variables: {}
};
return body;
}
changeUserInfo(pActivitylist: Activitylist) { changeUserInfo(pActivitylist: Activitylist) {
this.activitylist.next(pActivitylist); this.activitylist.next(pActivitylist);
} }
public getActivities() { public getActivities() {
if (this.activitylist.getValue().Actions.length < 1) { if (this.activitylist.getValue().Actions.length < 1) {
this.http.post(environment.graphQLUrl, ActivityService.buildGetActivityBody(), {headers: this.headers}) this.http.post(environment.graphQLUrl, ActivityService.buildGetActivityBody(), { headers: this.headers })
.pipe(this.retryRated()) .pipe(this.retryRated())
.subscribe(result => { .subscribe(result => {
// push onto subject // push onto subject
@ -54,7 +65,7 @@ export class ActivityService extends BaseService {
public getLevels() { public getLevels() {
if (this.levelList.getValue().levels.length < 1) { if (this.levelList.getValue().levels.length < 1) {
this.http.post(environment.graphQLUrl, ActivityService.buildGetLevelsBody(), {headers: this.headers}) this.http.post(environment.graphQLUrl, ActivityService.buildGetLevelsBody(), { headers: this.headers })
.pipe(this.retryRated()) .pipe(this.retryRated())
.subscribe(result => { .subscribe(result => {
// push onto subject // push onto subject
@ -63,6 +74,17 @@ export class ActivityService extends BaseService {
} }
} }
public getReportReasons() {
if (this.reportReasonList.getValue().length < 1) {
this.http.post(environment.graphQLUrl, ActivityService.buildGetReportReasonsBody(), { headers: this.headers })
.pipe(this.retryRated())
.subscribe(result => {
// push onto subject
this.reportReasonList.next(this.renderReportReasons(result));
});
}
}
public renderActivity(response: any): Activitylist { public renderActivity(response: any): Activitylist {
const activitylist = new Activitylist(); const activitylist = new Activitylist();
for (const activity of response.data.getActivities) { for (const activity of response.data.getActivities) {
@ -86,5 +108,16 @@ export class ActivityService extends BaseService {
} }
return levelList; return levelList;
} }
public renderReportReasons(response: any): ReportReason[] {
const reportReasons: ReportReason[] = new Array();
for (const reason of response.data.getReportReasons) {
reportReasons.push(new ReportReason(
reason.id,
reason.name,
reason.description));
}
return reportReasons;
}
} }

@ -1,14 +1,14 @@
import {Injectable} from '@angular/core'; import { Injectable } from '@angular/core';
import {HttpClient, HttpErrorResponse} 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, Observable} from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import {tap} from 'rxjs/operators'; import { tap } from 'rxjs/operators';
import {BaseService} from '../base.service'; import { BaseService } from '../base.service';
import {formatDate} from '@angular/common'; import { formatDate } from '@angular/common';
import {IFileUploadResult} from '../../models/interfaces/IFileUploadResult'; import { IFileUploadResult } from '../../models/interfaces/IFileUploadResult';
import { IErrorResponse } from 'src/app/models/interfaces/IErrorResponse'; import { IErrorResponse } from 'src/app/models/interfaces/IErrorResponse';
const createPostGqlQuery = `mutation($content: String!, $type: PostType) { const createPostGqlQuery = `mutation($content: String!, $type: PostType) {
@ -71,6 +71,12 @@ const downvotePostGqlQuery = `mutation($postId: ID!) {
} }
}`; }`;
const reportPostGqlQuery = `mutation($reasonId: ID!, $postId: ID!) {
reportPost(postId: $postId, reasonId: $reasonId) {
id
}
}`;
const getPostsGqlQuery = `query($first: Int, $offset: Int, $sort: SortType){ const getPostsGqlQuery = `query($first: Int, $offset: Int, $sort: SortType){
getPosts (first: $first, offset: $offset, sort: $sort) { getPosts (first: $first, offset: $offset, sort: $sort) {
id, id,
@ -300,6 +306,22 @@ export class FeedService extends BaseService {
return this.postGraphql(body); return this.postGraphql(body);
} }
/**
* reports a post
* @param postId
* @param reasonId
*/
public reportPost(reasonId: number, postId: number): any {
const body = {
query: reportPostGqlQuery, variables: {
postId,
reasonId
}
};
return this.postGraphql(body);
}
/** /**
* Deletes a post * Deletes a post
* @param pPostID * @param pPostID
@ -312,7 +334,7 @@ export class FeedService extends BaseService {
postId: pPostID postId: pPostID
} }
}; };
return this.http.post(environment.graphQLUrl, body, {headers: this.headers}) return this.http.post(environment.graphQLUrl, body, { headers: this.headers })
.pipe(this.retryRated()); .pipe(this.retryRated());
} }
@ -325,7 +347,7 @@ export class FeedService extends BaseService {
this.postsAvailable.next(true); this.postsAvailable.next(true);
this.posts.next([]); this.posts.next([]);
return this.http.post(environment.graphQLUrl, FeedService.buildGetPostBody(sort, 0), return this.http.post(environment.graphQLUrl, FeedService.buildGetPostBody(sort, 0),
{headers: this.headers}) { headers: this.headers })
.pipe(this.retryRated()) .pipe(this.retryRated())
.subscribe(response => { .subscribe(response => {
this.posts.next(this.constructAllPosts(response.data.getPosts)); this.posts.next(this.constructAllPosts(response.data.getPosts));
@ -339,7 +361,7 @@ export class FeedService extends BaseService {
public getNextPosts() { public getNextPosts() {
this.offset += this.offsetStep; this.offset += this.offsetStep;
const body = FeedService.buildGetPostBody(this.activePostList, this.offset); const body = FeedService.buildGetPostBody(this.activePostList, this.offset);
this.http.post(environment.graphQLUrl, body, {headers: this.headers}) this.http.post(environment.graphQLUrl, body, { headers: this.headers })
.pipe(this.retryRated()) .pipe(this.retryRated())
.subscribe(response => { .subscribe(response => {
const posts = this.constructAllPosts(response.data.getPosts); const posts = this.constructAllPosts(response.data.getPosts);

@ -95,6 +95,9 @@ export class GroupService extends BaseService {
groupId groupId
} }
}; };
const group = this.group.getValue();
group.admins = [];
this.group.next(group);
return this.postGraphql(body, null, 0) return this.postGraphql(body, null, 0)
.pipe(tap(response => { .pipe(tap(response => {
const group = this.group.getValue(); const group = this.group.getValue();

Loading…
Cancel
Save