diff options
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/app-constants.module.ts | 1 | ||||
| -rw-r--r-- | src/app/components/feed/feed.component.html | 4 | ||||
| -rw-r--r-- | src/app/components/post/post.component.css | 5 | ||||
| -rw-r--r-- | src/app/components/post/post.component.html | 4 | ||||
| -rw-r--r-- | src/app/components/post/post.component.ts | 94 | ||||
| -rw-r--r-- | src/app/components/profile/profile.component.html | 4 | ||||
| -rw-r--r-- | src/app/services/post.service.ts | 2 | ||||
| -rw-r--r-- | src/app/services/rating.service.ts | 88 |
8 files changed, 183 insertions, 19 deletions
diff --git a/src/app/app-constants.module.ts b/src/app/app-constants.module.ts index d72af53..f8722f7 100644 --- a/src/app/app-constants.module.ts +++ b/src/app/app-constants.module.ts @@ -9,6 +9,7 @@ export class AppConstants { public static API_TECHNOLOGY_URL = AppConstants.BASE_API_URL + '/Technology'; public static API_POST_URL = AppConstants.BASE_API_URL + '/Post'; + public static API_RATING_URL = AppConstants.BASE_API_URL + '/Rating'; public static API_FEED_URL = AppConstants.BASE_API_URL + '/Feed'; public static API_COMMENT_URL = AppConstants.BASE_API_URL + '/Comment'; diff --git a/src/app/components/feed/feed.component.html b/src/app/components/feed/feed.component.html index 230c27b..5ff2dca 100644 --- a/src/app/components/feed/feed.component.html +++ b/src/app/components/feed/feed.component.html @@ -40,8 +40,8 @@ None of your friends have posted anything yet!<br> Try refreshing your page! </div> - <div *ngFor="let friendPost of posts" class="post"> - <app-post [paramId]="friendPost.postId.toString()"></app-post> + <div *ngFor="let friendPost of posts; let i = index" class="post"> + <app-post [paramId]="friendPost.postId.toString()" [index]="i"></app-post> </div> </section> </section> diff --git a/src/app/components/post/post.component.css b/src/app/components/post/post.component.css index 1b88c7d..07d931f 100644 --- a/src/app/components/post/post.component.css +++ b/src/app/components/post/post.component.css @@ -76,11 +76,6 @@ hr { /* Rating */ -/* Temporary, until ratings are implemented fully */ -.rating { - display: none !important; -} - .rating { display: flex; flex-direction: column; diff --git a/src/app/components/post/post.component.html b/src/app/components/post/post.component.html index 4ba4d43..1603ebf 100644 --- a/src/app/components/post/post.component.html +++ b/src/app/components/post/post.component.html @@ -30,13 +30,13 @@ </div> </section> <section class="rating"> - <button class="vote"> + <button class="vote" (click)="votePost(true)"> ᐃ </button> <summary class="score"> {{ votesNumber }} </summary> - <button class="vote"> + <button class="vote" (click)="votePost(false)"> ᐁ </button> </section> diff --git a/src/app/components/post/post.component.ts b/src/app/components/post/post.component.ts index fa5ac2f..4bb41a7 100644 --- a/src/app/components/post/post.component.ts +++ b/src/app/components/post/post.component.ts @@ -2,9 +2,11 @@ import { Component, Input, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { Guid } from 'guid-typescript'; import { PostService } from 'src/app/services/post.service'; +import { RatingService } from 'src/app/services/rating.service'; import { UserService } from 'src/app/services/user.service'; -import { User } from 'src/models/identity/user.model'; -import { Post } from 'src/models/post.model'; +import { User } from 'src/models/identity/user'; +import { Post } from 'src/models/post'; +import { TokenService } from '../../services/token.service'; @Component({ selector: 'app-post', @@ -18,22 +20,30 @@ export class PostComponent implements OnInit { public votesNumber: number; public timeCreated: string; @Input() paramId: string; + @Input() index: number; + public loggedIn = false; + private voteBtns: HTMLCollectionOf<HTMLElement>; - constructor(private _postService: PostService, private _userService: UserService, private _router: Router) - { } + constructor(private _postService: PostService, private _ratingServe: RatingService, private _userService: UserService, private _router: Router, private _tokenService: TokenService) { } ngOnInit(): void { + this.loggedIn = this._tokenService.getTokenFromSessionStorage() !== ''; + this.post = this._postService.getDefaultPost(); this.user = this._userService.getDefaultUser(); this._postService.getPostRequest(Guid.parse(this.paramId)).subscribe({ next: (result: object) => { Object.assign(this.post, result); + this.post.fileURLs = Object.values(result)[7]; - this.votesNumber = 23; + this.votesNumber = this.post.currentRating; + + this.voteBtns = document.getElementsByClassName('vote') as HTMLCollectionOf<HTMLElement>; + + this.timeCreated = new Date(this.post.timeCreated).toLocaleString('en-GB'); - this.timeCreated = new Date(this.post.timeCreated).toLocaleString('en-GB'); - this.loadUser(); + this.loadUser(); } }); } @@ -42,6 +52,9 @@ export class PostComponent implements OnInit { this._userService.getUserByUsernameRequest(this.post.creatorUsername).subscribe({ next: (result: object) => { Object.assign(this.user, result); + + this.highlightButtonsOnInit(); + this.loaded = true; } }); @@ -54,4 +67,71 @@ export class PostComponent implements OnInit { goToPostPage(): void { this._router.navigate(['/post/' + this.post.postId]); } + + votePost(isLike: boolean): void { + if (!this.loggedIn) { + this._router.navigate(['/login']); + return; + } + + this._ratingServe.getRatingByUserAndPostWithSessionStorageRequest(Guid.parse(this.paramId)).subscribe( + (x: object) => { + if (Object.values(x)[3] === isLike) { + this.deleteRating(Object.values(x)[0], isLike); + + this.changeColorOfVoteButton(false, false); + } + else { + this.putRating(isLike); + + this.changeColorOfVoteButton(isLike, !isLike); + } + }, + () => { + this.createRating(isLike); + + this.changeColorOfVoteButton(isLike, !isLike); + } + ); + } + + private createRating(isLike: boolean): void { + this._ratingServe.createRatingWithSessionStorageRequest(Guid.parse(this.paramId), isLike).subscribe( + () => { + this.votesNumber += -1 + Number(isLike) * 2; + } + ); +} + + private putRating(isLike: boolean): void { + this._ratingServe.putRatingWithSessionStorageRequest(Guid.parse(this.paramId), isLike).subscribe( + () => { + // when false -2 + 0 wjen true -2 + 4 + this.votesNumber += -2 + Number(isLike) * 4; + } + ); + } + + private deleteRating(ratingId: string, isLike: boolean): void { + this._ratingServe.deleteRatingFromSessionStorageRequest(Guid.parse(ratingId)).subscribe( + () => { + this.votesNumber += 1 - Number(isLike) * 2; + } + ); + } + + private changeColorOfVoteButton(isUpvoted: boolean, isDownvoted: boolean): void { + this.voteBtns.item(this.index * 2)!.style.backgroundColor = (isUpvoted) ? 'lightblue' : 'white'; + this.voteBtns.item((this.index * 2) + 1)!.style.backgroundColor = (isDownvoted) ? 'lightblue' : 'white'; + } + + private highlightButtonsOnInit(): void { + this._ratingServe.getRatingByUserAndPostWithSessionStorageRequest(Guid.parse(this.paramId)).subscribe( + (x: object) => { + const isLike: boolean = Object.values(x)[3]; + + this.changeColorOfVoteButton(isLike, !isLike); + } + ); + } } diff --git a/src/app/components/profile/profile.component.html b/src/app/components/profile/profile.component.html index 0e5f633..5c21cee 100644 --- a/src/app/components/profile/profile.component.html +++ b/src/app/components/profile/profile.component.html @@ -52,8 +52,8 @@ <div id="no-posts" *ngIf="userPosts.length === 0"> {{ user.firstName }} {{ user.lastName }} hasn't posted anything yet! </div> - <div *ngFor="let userPost of userPosts"> - <app-post [paramId]="userPost.postId.toString()"></app-post> + <div *ngFor="let userPost of userPosts; let i = index"> + <app-post [paramId]="userPost.postId.toString()" [index]="i"></app-post> </div> </div> </div> diff --git a/src/app/services/post.service.ts b/src/app/services/post.service.ts index eb613a6..c8bd892 100644 --- a/src/app/services/post.service.ts +++ b/src/app/services/post.service.ts @@ -15,7 +15,7 @@ export class PostService { { } getDefaultPost(): Post { - return new Post(Guid.createEmpty(), 'Gosho', 'Trapov', 'gosho_trapov', 'Your opinion on my idea?', new Date(), [], []); + return new Post(Guid.createEmpty(), 'Gosho', 'Trapov', 'gosho_trapov', 'Your opinion on my idea?', new Date(), [], [], 0); } /* Requests from session storage */ diff --git a/src/app/services/rating.service.ts b/src/app/services/rating.service.ts new file mode 100644 index 0000000..58ff1f4 --- /dev/null +++ b/src/app/services/rating.service.ts @@ -0,0 +1,88 @@ +import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import * as FormData from 'form-data'; +import { Guid } from 'guid-typescript'; +import { Observable } from 'rxjs'; +import { Post } from 'src/models/post'; +import { AppConstants } from '../app-constants.module'; +import { TokenService } from './token.service'; + + +@Injectable({ + providedIn: 'root' +}) +export class RatingService { + constructor(private _http: HttpClient, private _tokenService: TokenService) + { } + + createRatingWithSessionStorageRequest(postId: Guid, isLike: boolean): Observable<object> { + const userId = this._tokenService.getUserIdFromSessionStorageToken(); + const token = this._tokenService.getTokenFromSessionStorage(); + + return this.createRatingRequest(userId, token, postId, isLike); + } + + putRatingWithSessionStorageRequest(postId: Guid, isLike: boolean): Observable<object> { + const userId = this._tokenService.getUserIdFromSessionStorageToken(); + const token = this._tokenService.getTokenFromSessionStorage(); + + return this.putRatingRequest(userId, token, postId, isLike); + } + + getRatingByUserAndPostWithSessionStorageRequest(postId: Guid): Observable<object> { + const userId = this._tokenService.getUserIdFromSessionStorageToken(); + const token = this._tokenService.getTokenFromSessionStorage(); + + return this.getRatingByUserAndPostRequest(userId, token, postId); + } + + deleteRatingFromSessionStorageRequest(ratingId: Guid): Observable<object> { + const userId = this._tokenService.getUserIdFromSessionStorageToken(); + const token = this._tokenService.getTokenFromSessionStorage(); + + return this.deleteRatingRequest(userId, token, ratingId); + } + + createRatingRequest(userId: Guid, authToken: string, postId: Guid, isLike: boolean): Observable<object> { + const options = { + params: new HttpParams().set('UserId', userId.toString()), + headers: new HttpHeaders().set('Authorization', 'Bearer ' + authToken) + }; + const body = { + postId: postId.toString(), + isLike: isLike + }; + + return this._http.post(AppConstants.API_RATING_URL, body, options); + } + + putRatingRequest(userId: Guid, authToken: string, postId: Guid, isLike: boolean): Observable<object> { + const options = { + params: new HttpParams().set('UserId', userId.toString()).set('PostId', postId.toString()), + headers: new HttpHeaders().set('Authorization', 'Bearer ' + authToken) + }; + const body = { + isLike: isLike + }; + + return this._http.put(AppConstants.API_RATING_URL, body, options); + } + + getRatingByUserAndPostRequest(userId: Guid, authToken: string, postId: Guid): Observable<object> { + const options = { + params: new HttpParams().set('UserId', userId.toString()).set('PostId', postId.toString()), + headers: new HttpHeaders().set('Authorization', 'Bearer ' + authToken) + }; + + return this._http.get(AppConstants.API_RATING_URL + '/GetByUserAndPost', options); + } + + deleteRatingRequest(userId: Guid, authToken: string, ratingId: Guid): Observable<object> { + const options = { + params: new HttpParams().set('UserId', userId.toString()).set('RatingId', ratingId.toString()), + headers: new HttpHeaders().set('Authorization', 'Bearer ' + authToken) + }; + + return this._http.delete(AppConstants.API_RATING_URL, options); + } +} |
