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

master
Max_ES 5 years ago committed by Gitea
commit 2bcd1f3fbc

@ -6,30 +6,45 @@
<div [hidden]="!loggedIn">
<mat-card>
<mat-card-content>
<div id="inputPreviewWrapper">
<h2 *ngIf="localFileUrl">Preview:</h2>
<img *ngIf="fileType == 'image'" id="inputPreview" [src]="localFileUrl"/>
<video *ngIf="fileType == 'video'" [src]="localFileUrl" controls="" class="html5-video-player">
Your browser does not support playing HTML5 video.
</video>
<div id="inputPreviewWrapper" *ngIf="localFileUrl">
<h2>Preview:</h2>
<div id="media-box">
<button class="discard-button" mat-button mat-icon-button (click)="discardFile()"
matTooltip="discard file"
matTooltipShowDelay="200"
[disabled]="posting">
<mat-icon>close</mat-icon>
</button>
<img *ngIf="fileType == 'image'" id="inputPreview" [src]="localFileUrl"/>
<video *ngIf="fileType == 'video'" [src]="localFileUrl" id="inputPreview" controls="" class="html5-video-player">
Your browser does not support playing HTML5 video.
</video>
</div>
</div>
<mat-form-field id="input">
<textarea matInput #content type="text" (input)="onTextInputChange()" [(ngModel)]="textInputValue"
mat-autosize="true" matAutosizeMaxRows="3" placeholder="post something"></textarea>
<button mat-button matSuffix mat-icon-button (click)="name.click()"
<mat-form-field class="input">
<textarea matInput #content type="text" (input)="onTextInputChange()" [(ngModel)]="textInputValue" [disabled]="posting"
mat-autosize="true" matAutosizeMaxRows="3" placeholder="post something"></textarea>
</mat-form-field>
<input style="display: none" id="input-file" type="file" accept="video/*,image/*" (change)="onFileInputChange($event)" #name>
<div class="input">
<div class="left">
<p id="check">
<mat-checkbox color="primary" [(ngModel)]="checked" checked="checked" [disabled]="posting">I protected the environment.
</mat-checkbox>
</p>
</div>
<div class="right">
<button mat-button mat-icon-button (click)="name.click()"
matTooltip="upload a picture or video (up to 10MB)"
matTooltipShowDelay="200">
matTooltipShowDelay="200"
[disabled]="posting">
<mat-icon>attach_file</mat-icon>
</button>
<input style="display: none" id="input-file" type="file" accept="video/*,image/*" (change)="onFileInputChange($event)" #name>
</mat-form-field>
<p id="check">
<mat-checkbox color="primary" [(ngModel)]="checked" checked="checked">I protected the environment.
</mat-checkbox>
</p>
</div>
</div>
<mat-form-field id="action-chooser" *ngIf="checked">
<mat-label>What did you do?</mat-label>
<mat-select [(ngModel)]="activityId" name="action">
<mat-select [(ngModel)]="activityId" name="action" [disabled]="posting">
<mat-option>nothing ;)</mat-option>
<mat-option *ngFor="let action of actionlist.Actions" [value]="action.id" [matTooltip]="action.description"
matTooltipShowDelay="200">
@ -38,7 +53,8 @@
</mat-select>
</mat-form-field>
<mat-error *ngIf="errorOccurred && textInputValue">{{getErrorMessage()}}</mat-error>
<button mat-raised-button *ngIf="textInputValue" color="primary" id="post-button"
<mat-progress-bar id="progress-bar" *ngIf="posting" mode="indeterminate"></mat-progress-bar>
<button mat-raised-button *ngIf="textInputValue" color="primary" id="post-button" [disabled]="posting"
(click)=createPost(content,activityId)>
POST
</button>

@ -27,23 +27,26 @@
#feedlist
width: 100%
#input
.input
width: 100%
padding-left: 0.5em
padding-right: 0.5em
.mat-icon
transform: scale(1.5)
.left, .right
display: inline-block
width: 50%
.left
text-align: left
.right
text-align: right
#inputPreview
max-width: 75%
max-height: 100%
max-width: 100%
max-height: 45vh
width: auto
border-radius: 4px
mask-mode: luminance
outline: none
user-select: none
::ng-deep video
width: 100%
max-height: 40vh
outline: none
user-select: none
#inputPreviewWrapper
@ -51,6 +54,19 @@
text-align: center
max-height: 512px
margin-bottom: 1em
#media-box
position: relative
width: 100%
::ng-deep .light-theme .discard-button
margin: 0.5em
position: absolute
background: hsla(255,100%,100%,0.3)
::ng-deep .dark-theme .discard-button
margin: 0.5em
position: absolute
background: hsla(0,0%,0%,0.3)
#progress-bar
margin-top: 1em
#action-chooser
width: 100%
@ -60,6 +76,10 @@
#check
margin: 0
padding-left: 0.5em
display: contents
#button-box
text-align: right
margin-left: auto
#post-button
width: 100%

@ -1,4 +1,4 @@
import {Component, OnInit} from '@angular/core';
import {Component, OnInit, ViewChild} from '@angular/core';
import {Post} from 'src/app/models/post';
import {FeedService, Sort} from 'src/app/services/feed/feed.service';
import {Activitylist} from 'src/app/models/activity';
@ -17,11 +17,13 @@ export class FeedComponent implements OnInit {
loadingNew = true;
loadingMostLiked = true;
// file upload variables
@ViewChild('name', {static: false}) fileInput;
public uploading = false;
public profilePictureUrl: BehaviorSubject<string | null>;
private file;
fileType;
public localFileUrl;
posting = false;
checked = false; // if the "I protected the environment."-box is checked
view = 'new';
@ -70,7 +72,9 @@ export class FeedComponent implements OnInit {
*/
createPost(postElement, activityId: string) {
if (postElement && activityId && this.checked) {
this.posting = true;
this.feedService.createPostActivity(postElement.value, activityId, this.file).subscribe(() => {
this.posting = false;
postElement.value = '';
this.textInputValue = '';
this.checked = false;
@ -81,11 +85,15 @@ export class FeedComponent implements OnInit {
this.showNew();
}
}, (error: IErrorResponse) => {
this.posting = false;
this.errorOccurred = true;
this.errorMessage = error.error.errors[0].message;
});
} else if (postElement) {
this.feedService.createPost(postElement.value, this.file).subscribe(() => {
this.posting = true;
this.feedService.createPost(postElement.value, this.file).subscribe((result) => {
console.log('response in component');
this.posting = false;
postElement.value = '';
this.textInputValue = '';
this.checked = false;
@ -96,12 +104,22 @@ export class FeedComponent implements OnInit {
this.showNew();
}
}, (error: IErrorResponse) => {
console.log('an error occured in component');
console.log(error);
this.posting = false;
this.errorOccurred = true;
this.errorMessage = error.error.errors[0].message;
});
}
}
discardFile() {
this.file = null;
this.localFileUrl = null;
this.fileType = null;
this.fileInput.nativeElement.value = '';
}
onFileInputChange(event) {
this.errorOccurred = false;
this.errorMessage = '';
@ -119,7 +137,7 @@ export class FeedComponent implements OnInit {
}
/**
* Fetches the next posts when scrolled
* Fetches the next posts when scrolled down
*/
onScroll() {
this.feedService.getNextPosts();

@ -60,16 +60,19 @@ $mat-card-header-size: 40px !default
display: block
margin-left: auto
margin-right: auto
margin-bottom: 0.5em
::ng-deep video
width: 100%
max-height: 40vh
outline: none
user-select: none
margin-bottom: 0.5em
::ng-deep audio
width: 100%
max-height: 40vh
outline: none
user-select: none
margin-bottom: 0.5em
.mat-button
min-width: 32px !important

@ -54,7 +54,7 @@ $mat-card-header-size: 100px !default
#icon
display: none
position: absolute
z-index: 11
z-index: 100
color: white
$mat-card-header-size: 100px !default

@ -17,7 +17,7 @@
</button>
</mat-menu>
</div>
<div mat-card-avatar (click)="showGroupProfile(group)">
<div mat-card-avatar (click)="showFriendProfile(group)">
<img class="profile-picture" [src]="friend.profilePicture"/>
</div>
<mat-card-title (click)="showFriendProfile(friend)">{{friend.name}}</mat-card-title>

@ -1,5 +1,6 @@
import {Author} from './author';
import {Activity} from './activity';
import { environment } from 'src/environments/environment';
export class Post {
id: number;
@ -39,7 +40,7 @@ export class Post {
this.author = author;
this.activity = activity;
if (media) {
this.mediaUrl = media.url;
this.mediaUrl = environment.greenvironmentUrl + media.url;
this.mediaType = media.type;
}
}

@ -10,8 +10,8 @@ import {BaseService} from '../base.service';
import {formatDate} from '@angular/common';
import {IFileUploadResult} from '../../models/interfaces/IFileUploadResult';
const createPostGqlQuery = `mutation($content: String!) {
createPost(content: $content) {
const createPostGqlQuery = `mutation($content: String!, $type: PostType) {
createPost(content: $content, type: $type) {
id,
content,
htmlContent,
@ -34,8 +34,8 @@ const createPostGqlQuery = `mutation($content: String!) {
createdAt}
}`;
const createPostActivityGqlQuery = `mutation($content: String!, $id: ID) {
createPost(content: $content activityId: $id) {
const createPostActivityGqlQuery = `mutation($content: String!, $id: ID, $type: PostType) {
createPost(content: $content activityId: $id, type: $type) {
id,
content,
htmlContent,
@ -70,7 +70,7 @@ const downvotePostGqlQuery = `mutation($postId: ID!) {
}
}`;
const getPostGqlQuery = `query($first: Int, $offset: Int, $sort: SortType){
const getPostsGqlQuery = `query($first: Int, $offset: Int, $sort: SortType){
getPosts (first: $first, offset: $offset, sort: $sort) {
id,
content,
@ -122,7 +122,7 @@ export class FeedService extends BaseService {
*/
private static buildGetPostBody(sort: string, offset: number, first: number = 10) {
return {
query: getPostGqlQuery, variables: {
query: getPostsGqlQuery, variables: {
first,
offset,
sort
@ -145,10 +145,15 @@ export class FeedService extends BaseService {
* @param file
*/
public createPost(pContent: String, file?: File) {
let type: string;
if (file) { type = 'MEDIA'; } else {
type = 'TEXT';
}
const body = {
query: createPostGqlQuery,
variables: {
content: pContent
content: pContent,
type
}
};
return this.createPostRequest(body, file);
@ -161,10 +166,15 @@ export class FeedService extends BaseService {
* @param file
*/
public createPostActivity(pContent: String, activityId: String, file?: File) {
let type: string;
if (file) { type = 'MEDIA'; } else {
type = 'TEXT';
}
const body = {
query: createPostActivityGqlQuery, variables: {
content: pContent,
id: activityId
id: activityId,
type
}
};
return this.createPostRequest(body, file);
@ -176,26 +186,34 @@ export class FeedService extends BaseService {
* @param file - a file that is being uploaded with the post
*/
private createPostRequest(body: { variables: any; query: string }, file?: File) {
return this.postGraphql(body, null, 0)
if (file) {
return this.postGraphql(body, null, 0)
.pipe(tap(response => {
const updatedPosts = this.posts.getValue();
if (this.activePostList === Sort.NEW) {
const updatedPosts = this.posts.getValue();
const post = this.constructPost(response);
updatedPosts.unshift(post);
if (file) {
this.uploadPostImage(post.id, file).subscribe((result) => {
post.mediaUrl = result.fileName;
post.mediaType = result.fileName.endsWith('.png') ? 'IMAGE' : 'VIDEO';
this.posts.next(updatedPosts);
}, error => {
console.error(error);
this.deletePost(post.id);
});
} else {
this.uploadPostImage(post.id, file).subscribe((result) => {
post.mediaUrl = result.fileName;
post.mediaType = result.fileName.endsWith('.png') ? 'IMAGE' : 'VIDEO';
updatedPosts.unshift(post);
this.posts.next(updatedPosts);
}
}, error => {
console.error(error);
this.deletePost(post.id);
});
}
}));
} else if (!file) {
return this.postGraphql(body, null, 0)
.pipe(tap(response => {
const updatedPosts = this.posts.getValue();
if (this.activePostList === Sort.NEW) {
const post = this.constructPost(response);
updatedPosts.unshift(post);
this.posts.next(updatedPosts);
}
}));
}
}
/**

Loading…
Cancel
Save