Add post reporting function

master
Max 4 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-header>
<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 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>
</button>
<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>
</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>
</div>
<mat-card-title>
@ -22,10 +29,11 @@
</mat-card-subtitle>
</mat-card-header>
<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 [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>
<video *ngIf="post.mediaType === 'VIDEO'" controls>
<source [src]="post.mediaUrl" type="video/webm">
@ -41,13 +49,17 @@
</div>
<div class="postVoteButtons">
<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" aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'DOWNVOTE'">thumb_up</mat-icon>
<mat-icon class="voteButton voted" aria-hidden="false" color="primary" *ngIf="post.userVote == 'UPVOTE'">
thumb_up</mat-icon>
<mat-icon class="voteButton" aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'DOWNVOTE'">thumb_up
</mat-icon>
</button>
<div class="voteCount">{{post.upvotes}}</div>
<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" aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'UPVOTE'">thumb_down</mat-icon>
<mat-icon class="voteButton voted" aria-hidden="false" color="primary" *ngIf="post.userVote == 'DOWNVOTE'">
thumb_down</mat-icon>
<mat-icon class="voteButton" aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'UPVOTE'">thumb_down
</mat-icon>
</button>
<div class="voteCount">{{post.downvotes}}</div>
</div>
@ -57,4 +69,4 @@
</span>
</div>
</mat-card-actions>
</mat-card>
</mat-card>

@ -1,7 +1,10 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {Post} from 'src/app/models/post';
import {FeedService} from 'src/app/services/feed/feed.service';
import {Router} from '@angular/router';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Post } from 'src/app/models/post';
import { FeedService } from 'src/app/services/feed/feed.service';
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({
selector: 'feed-postlist',
@ -13,11 +16,23 @@ export class PostlistComponent implements OnInit {
@Input() childPostList: Post[];
@Output() voteEvent = new EventEmitter<boolean>();
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() {
this.data.currentUser.subscribe(user => {
this.loggedIn = user.loggedIn;
});
this.activityService.getReportReasons();
this.activityService.reportReasonList.subscribe(response => {
this.reportReasons = response;
});
}
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) {
post.mediaLoading = false;
}

@ -134,7 +134,7 @@
</div>
<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 *ngIf="user.isGroupAdmin" class="pointer" (click)="showUserProfile(user)">[admin]
<mat-card-subtitle hidden class="pointer" (click)="showUserProfile(user)">[admin]
</mat-card-subtitle>
<div id="icon-box" *ngIf="isCreator">
<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 {BehaviorSubject} from 'rxjs';
import {Activity, Activitylist} from 'src/app/models/activity';
import {Level, LevelList} from 'src/app/models/levellist';
import {environment} from 'src/environments/environment';
import {HttpClient, HttpErrorResponse} from '@angular/common/http';
import {BaseService} from '../base.service';
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { Activity, Activitylist } from 'src/app/models/activity';
import { Level, LevelList } from 'src/app/models/levellist';
import { ReportReason } from 'src/app/models/reportReason';
import { environment } from 'src/environments/environment';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { BaseService } from '../base.service';
@Injectable({
@ -14,6 +15,7 @@ export class ActivityService extends BaseService {
public activitylist = new BehaviorSubject<Activitylist>(new Activitylist());
public levelList = new BehaviorSubject<LevelList>(new LevelList());
public reportReasonList = new BehaviorSubject<ReportReason[]>(new Array());
constructor(http: HttpClient) {
super(http);
@ -37,29 +39,49 @@ export class ActivityService extends BaseService {
return body;
}
private static buildGetReportReasonsBody(): any {
const body = {
query: `query{getReportReasons {
id name description
}}`, variables: {}
};
return body;
}
changeUserInfo(pActivitylist: Activitylist) {
this.activitylist.next(pActivitylist);
}
public getActivities() {
if (this.activitylist.getValue().Actions.length < 1) {
this.http.post(environment.graphQLUrl, ActivityService.buildGetActivityBody(), {headers: this.headers})
.pipe(this.retryRated())
.subscribe(result => {
// push onto subject
this.activitylist.next(this.renderActivity(result));
});
this.http.post(environment.graphQLUrl, ActivityService.buildGetActivityBody(), { headers: this.headers })
.pipe(this.retryRated())
.subscribe(result => {
// push onto subject
this.activitylist.next(this.renderActivity(result));
});
}
}
public getLevels() {
if (this.levelList.getValue().levels.length < 1) {
this.http.post(environment.graphQLUrl, ActivityService.buildGetLevelsBody(), {headers: this.headers})
.pipe(this.retryRated())
.subscribe(result => {
// push onto subject
this.levelList.next(this.renderLevels(result));
});
this.http.post(environment.graphQLUrl, ActivityService.buildGetLevelsBody(), { headers: this.headers })
.pipe(this.retryRated())
.subscribe(result => {
// push onto subject
this.levelList.next(this.renderLevels(result));
});
}
}
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));
});
}
}
@ -86,5 +108,16 @@ export class ActivityService extends BaseService {
}
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 {HttpClient, HttpErrorResponse} from '@angular/common/http';
import {Post} from 'src/app/models/post';
import {Author} from 'src/app/models/author';
import {environment} from 'src/environments/environment';
import {Activity} from 'src/app/models/activity';
import {BehaviorSubject, Observable} from 'rxjs';
import {tap} from 'rxjs/operators';
import {BaseService} from '../base.service';
import {formatDate} from '@angular/common';
import {IFileUploadResult} from '../../models/interfaces/IFileUploadResult';
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Post } from 'src/app/models/post';
import { Author } from 'src/app/models/author';
import { environment } from 'src/environments/environment';
import { Activity } from 'src/app/models/activity';
import { BehaviorSubject, Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { BaseService } from '../base.service';
import { formatDate } from '@angular/common';
import { IFileUploadResult } from '../../models/interfaces/IFileUploadResult';
import { IErrorResponse } from 'src/app/models/interfaces/IErrorResponse';
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){
getPosts (first: $first, offset: $offset, sort: $sort) {
id,
@ -196,23 +202,23 @@ export class FeedService extends BaseService {
this.setPostingState(true);
if (file) {
return this.postGraphql(body, null, 0)
.pipe(tap(response => {
const updatedPosts = this.posts.getValue();
const post = this.constructPost(response);
this.uploadPostImage(post.id, file).subscribe((result) => {
if (result.success) {
if (this.activePostList === Sort.NEW) {
post.mediaUrl = result.fileName;
post.mediaType = result.fileName.endsWith('.png') ? 'IMAGE' : 'VIDEO';
updatedPosts.unshift(post);
this.posts.next(updatedPosts);
this.setPostingState(false);
.pipe(tap(response => {
const updatedPosts = this.posts.getValue();
const post = this.constructPost(response);
this.uploadPostImage(post.id, file).subscribe((result) => {
if (result.success) {
if (this.activePostList === Sort.NEW) {
post.mediaUrl = result.fileName;
post.mediaType = result.fileName.endsWith('.png') ? 'IMAGE' : 'VIDEO';
updatedPosts.unshift(post);
this.posts.next(updatedPosts);
this.setPostingState(false);
}
} else {
console.error(result.error);
this.setPostingError(result.error);
this.deletePost(post.id).subscribe();
}
} else {
console.error(result.error);
this.setPostingError(result.error);
this.deletePost(post.id).subscribe();
}
}, error => {
console.error(error);
this.setPostingError(error);
@ -221,21 +227,21 @@ export class FeedService extends BaseService {
}, (error: IErrorResponse) => {
this.setPostingError(error.error.errors[0].message);
}
));
));
} else if (!file) {
return this.postGraphql(body, null, 0)
.pipe(tap(response => {
this.setPostingState(false);
const updatedPosts = this.posts.getValue();
if (this.activePostList === Sort.NEW) {
const post = this.constructPost(response);
updatedPosts.unshift(post);
this.posts.next(updatedPosts);
}
}, (error: IErrorResponse) => {
console.log(error);
this.setPostingError(error.error.errors[0].message);
}));
.pipe(tap(response => {
this.setPostingState(false);
const updatedPosts = this.posts.getValue();
if (this.activePostList === Sort.NEW) {
const post = this.constructPost(response);
updatedPosts.unshift(post);
this.posts.next(updatedPosts);
}
}, (error: IErrorResponse) => {
console.log(error);
this.setPostingError(error.error.errors[0].message);
}));
}
}
@ -300,6 +306,22 @@ export class FeedService extends BaseService {
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
* @param pPostID
@ -312,7 +334,7 @@ export class FeedService extends BaseService {
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());
}
@ -325,7 +347,7 @@ export class FeedService extends BaseService {
this.postsAvailable.next(true);
this.posts.next([]);
return this.http.post(environment.graphQLUrl, FeedService.buildGetPostBody(sort, 0),
{headers: this.headers})
{ headers: this.headers })
.pipe(this.retryRated())
.subscribe(response => {
this.posts.next(this.constructAllPosts(response.data.getPosts));
@ -339,7 +361,7 @@ export class FeedService extends BaseService {
public getNextPosts() {
this.offset += this.offsetStep;
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())
.subscribe(response => {
const posts = this.constructAllPosts(response.data.getPosts);

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

Loading…
Cancel
Save