aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app/components/post-page/post-page.component.ts46
-rw-r--r--src/app/components/post/post.component.css21
-rw-r--r--src/app/components/post/post.component.html38
-rw-r--r--src/app/components/post/post.component.ts82
-rw-r--r--src/assets/icons/tabler-icon-edit.svg76
-rw-r--r--src/assets/icons/tabler-icon-trash.svg90
6 files changed, 304 insertions, 49 deletions
diff --git a/src/app/components/post-page/post-page.component.ts b/src/app/components/post-page/post-page.component.ts
index e159c69..0babfdf 100644
--- a/src/app/components/post-page/post-page.component.ts
+++ b/src/app/components/post-page/post-page.component.ts
@@ -7,7 +7,6 @@ import { CommentService } from 'src/app/services/comment.service';
import { PostService } from 'src/app/services/post.service';
import { TokenService } from 'src/app/services/token.service';
import { Post } from 'src/models/post.model';
-import { CloudinaryService } from 'src/app/services/cloudinary.service';
@Component({
selector: 'app-post-page',
@@ -18,22 +17,17 @@ export class PostPageComponent implements OnInit {
private _title = 'Post';
public dataArrived = false;
public loggedIn = false;
- public editable = false;
- public editingPost = false;
public postId: Guid;
public post: Post;
- public files: File[];
- public editPostFormGroup: FormGroup;
public addCommentFormGroup: FormGroup;
- constructor(private _titleService: Title, private _router: Router, private _fb: FormBuilder, private _tokenService: TokenService, private _postService: PostService, private _commentService: CommentService, private _cloudinaryService: CloudinaryService){
+ constructor(private _titleService: Title, private _router: Router, private _fb: FormBuilder, private _tokenService: TokenService, private _postService: PostService, private _commentService: CommentService) {
this._titleService.setTitle(this._title);
}
ngOnInit(): void {
this.loggedIn = this._tokenService.getTokenFromSessionStorage() !== '';
this.postId = Guid.parse(this._router.url.substring(6));
- this.files = [];
// Gets the post and the logged in user and compares them,
// to determine if the current post is made by the user
@@ -41,52 +35,19 @@ export class PostPageComponent implements OnInit {
next: (result: object) => {
this.post = result as Post;
this.post.fileURLs = Object.values(result)[7];
- if (this.loggedIn) {
- this.editable = this.post.creatorUsername === this._tokenService.getUsernameFromSessionStorageToken();
- this.editPostFormGroup.get('newPostMessage')?.setValue(this.post.message);
- }
- if (this.post.fileURLs.length > 0) {
- this.loadFiles();
- }
- else {
- this.dataArrived = true;
- }
+
+ this.dataArrived = true;
},
error: () => {
this._router.navigate(['/not-found']);
}
});
- this.editPostFormGroup = this._fb.group({
- newPostMessage: new FormControl(''),
- fileUpload: new FormControl('')
- });
-
this.addCommentFormGroup = this._fb.group({
newComment: new FormControl('')
});
}
- private loadFiles(): void {
- for (const fileURL of this.post.fileURLs) {
- this._cloudinaryService.getFileRequest(fileURL).subscribe({
- next: (result: object) => {
- const file = result as File;
- const tmp = {
- name: fileURL.match('(?<=\/)(?:.(?!\/))+$')?.pop() ?? 'Attachment'
- };
-
- Object.assign(file, tmp);
- this.files.push(file);
-
- if (this.files.length === this.post.fileURLs.length) {
- this.dataArrived = true;
- }
- }
- });
- }
- }
-
addComment(): void {
if (!this.loggedIn) {
this._router.navigate(['/login']);
@@ -97,7 +58,6 @@ export class PostPageComponent implements OnInit {
if (newComment !== '' && newComment !== null) {
this._commentService.createCommentWithSessionStorageRequest(this.postId, newComment).subscribe({
next: () => {
- this.editPostFormGroup.reset();
this.reloadPage();
}
});
diff --git a/src/app/components/post/post.component.css b/src/app/components/post/post.component.css
index c5919fd..1015564 100644
--- a/src/app/components/post/post.component.css
+++ b/src/app/components/post/post.component.css
@@ -32,3 +32,24 @@
height: 1.2em;
width: 1.2em;
}
+
+/* Edit */
+
+#attachments-btns img, .file-button > input {
+ height: 1.4em;
+ width: 1.4em;
+}
+
+.file-button {
+ position: relative;
+}
+
+.file-button > img {
+ position: absolute;
+ pointer-events: none;
+}
+
+.file-button > input {
+ font-size: inherit;
+ color: transparent;
+}
diff --git a/src/app/components/post/post.component.html b/src/app/components/post/post.component.html
index 133b747..1831c5e 100644
--- a/src/app/components/post/post.component.html
+++ b/src/app/components/post/post.component.html
@@ -13,14 +13,36 @@
@{{ user.userName }}
</span>
</summary>
- <article class="message margin-top-bot-small">
+ <article class="message margin-top-bot-small" *ngIf="!editingPost">
{{ post.message }}
</article>
- <section class="flex-row flexible-children">
+ <section class="flex-row flexible-children" *ngIf="!editingPost">
<figure *ngFor="let fileURL of post.fileURLs">
<app-post-attachment [paramURL]="fileURL"></app-post-attachment>
</figure>
</section>
+ <form [formGroup]="editPostFormGroup" *ngIf="editingPost">
+ <textarea class="textarea-new-msg full-width faded-slim-border border-bottom-only padding-small" rows="1" formControlName="newPostMessage" placeholder="What's on your mind?"></textarea>
+ <section class="flex-row flex-justify-start flex-center-align-children top-bot-padding-bigger">
+ <div class="file-button hover-half-opacity click-effect">
+ <img src="/assets/icons/tabler-icon-paperclip.svg">
+ <input type="file" formControlName="fileUpload" (change)="onFileUpload($event)" multiple>
+ </div>
+ </section>
+ </form>
+ <section class="flex-row bot-padding-bigger" *ngIf="editingPost">
+ <div *ngFor="let file of files" class="form-attachment faded-slim-border flexible flex-row flex-no-wrap flex-center-align-items padding-small margin-top-bot-small">
+ <div class="flexible">
+ {{ file.name ? file.name : 'Attachment' }}
+ </div>
+ <div class="flex-col hover-half-opacity border-radius-small click-effect" (click)="removeAttachment(file.name)">
+ <img src="/assets/icons/tabler-icon-x.svg">
+ </div>
+ </div>
+ </section>
+ <button class="faded-slim-border full-width padding-small lighter-hover click-effect border-radius-smaller margin-bot-bigger" *ngIf="editingPost" (click)="editPost()">
+ Update Post
+ </button>
<section class="post-details flex-row flex-justify-end font-size-dot7 faded-slim-border border-bottom-only">
<time class="flex-row flex-center-align-items">
<img class="img-height-font-size" src="/assets/icons/tabler-icon-calendar-time.svg">&nbsp;
@@ -35,15 +57,21 @@
</span>
</summary>
</section>
- <section class="flex-row flexible-children justify-children-center flex-center-align-children">
- <button class="padding-small lighter-hover click-effect border-radius-smaller" (click)="goToPostPage()">
+ <section class="flex-row justify-children-center flex-center-align-children">
+ <button class="padding-small lighter-hover click-effect border-radius-smaller" (click)="toggleEditing()">
+ <img src="/assets/icons/tabler-icon-edit.svg">
+ </button>
+ <button class="flexible padding-small lighter-hover click-effect border-radius-smaller" (click)="goToPostPage()">
<img src="/assets/icons/tabler-icon-message-2.svg">
&nbsp;Comment
</button>
- <button class="padding-small lighter-hover click-effect border-radius-smaller" (click)="goToPostPage()">
+ <button class="flexible padding-small lighter-hover click-effect border-radius-smaller" (click)="goToPostPage()">
<img src="/assets/icons/tabler-icon-link.svg">
&nbsp;Share
</button>
+ <button class="padding-small lighter-hover click-effect border-radius-smaller" (click)="deletePost()">
+ <img src="/assets/icons/tabler-icon-trash.svg">
+ </button>
</section>
</main>
<aside class="rating flex-col flex-center-align-items">
diff --git a/src/app/components/post/post.component.ts b/src/app/components/post/post.component.ts
index 58dad4f..5c79658 100644
--- a/src/app/components/post/post.component.ts
+++ b/src/app/components/post/post.component.ts
@@ -1,6 +1,8 @@
import { Component, Input, OnInit } from '@angular/core';
+import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { Router } from '@angular/router';
import { Guid } from 'guid-typescript';
+import { CloudinaryService } from 'src/app/services/cloudinary.service';
import { PostService } from 'src/app/services/post.service';
import { RatingService } from 'src/app/services/rating.service';
import { UserService } from 'src/app/services/user.service';
@@ -22,10 +24,14 @@ export class PostComponent implements OnInit {
@Input() paramId: string;
@Input() index: number;
public loggedIn = false;
+ public loggedInAuthor = false;
+ public editingPost = false;
+ public files: File[];
+ public editPostFormGroup: FormGroup;
private upvoteBtns: HTMLCollectionOf<HTMLElement>;
private downvoteBtns: HTMLCollectionOf<HTMLElement>;
- constructor(private _postService: PostService, private _ratingServe: RatingService, private _userService: UserService, private _router: Router, private _tokenService: TokenService)
+ constructor(private _postService: PostService, private _ratingServe: RatingService, private _userService: UserService, private _router: Router, private _tokenService: TokenService, private _cloudinaryService: CloudinaryService, private _fb: FormBuilder)
{ }
ngOnInit(): void {
@@ -33,6 +39,7 @@ export class PostComponent implements OnInit {
this.post = this._postService.getDefaultPost();
this.user = this._userService.getDefaultUser();
+ this.files = [];
this._postService.getPostRequest(Guid.parse(this.paramId)).subscribe({
next: (result: object) => {
@@ -49,6 +56,11 @@ export class PostComponent implements OnInit {
this.loadUser();
}
});
+
+ this.editPostFormGroup = this._fb.group({
+ newPostMessage: new FormControl(''),
+ fileUpload: new FormControl('')
+ });
}
private loadUser(): void {
@@ -58,6 +70,14 @@ export class PostComponent implements OnInit {
if (this.loggedIn) {
this.highlightButtonsOnInit();
+
+ this.loggedInAuthor = this._tokenService.getUsernameFromSessionStorageToken() === this.post.creatorUsername;
+ this.editPostFormGroup.get('newPostMessage')?.setValue(this.post.message);
+
+ if (this.post.fileURLs.length > 0) {
+ this.loadFiles();
+ return;
+ }
}
this.loaded = true;
@@ -65,6 +85,26 @@ export class PostComponent implements OnInit {
});
}
+ private loadFiles(): void {
+ for (const fileURL of this.post.fileURLs) {
+ this._cloudinaryService.getFileRequest(fileURL).subscribe({
+ next: (result: object) => {
+ const file = result as File;
+ const tmp = {
+ name: fileURL.match('(?<=\/)(?:.(?!\/))+$')?.pop() ?? 'Attachment'
+ };
+
+ Object.assign(file, tmp);
+ this.files.push(file);
+
+ if (this.files.length === this.post.fileURLs.length) {
+ this.loaded = true;
+ }
+ }
+ });
+ }
+ }
+
goToAuthorProfile(): void {
this._router.navigate(['/profile/' + this.user.userName]);
}
@@ -73,6 +113,46 @@ export class PostComponent implements OnInit {
this._router.navigate(['/post/' + this.post.postId]);
}
+ toggleEditing(): void {
+ this.editingPost = !this.editingPost;
+ }
+
+ onFileUpload(event: any): void {
+ this.files.push(...event.target.files);
+ this.editPostFormGroup.get('fileUpload')?.reset();
+ }
+
+ removeAttachment(fileName: string): void {
+ this.files = this.files.filter(x => x.name !== fileName);
+ }
+
+ editPost(): void {
+ const newMessage = this.editPostFormGroup.get('newPostMessage')?.value;
+
+ if (newMessage !== '') {
+ this._postService.putPostWithSessionStorageRequest(Guid.parse(this.paramId), newMessage, this.files).subscribe({
+ next: () => {
+ this.reloadPage();
+ }
+ });
+ this.loaded = false;
+ }
+ }
+
+ deletePost(): void {
+ this._postService.deletePostWithSessionStorage(Guid.parse(this.paramId)).subscribe({
+ next: () => {
+ this._router.navigate(['/profile/' + this._tokenService.getUsernameFromSessionStorageToken()]);
+ }
+ });
+ }
+
+ private reloadPage(): void {
+ this._router.routeReuseStrategy.shouldReuseRoute = () => false;
+ this._router.onSameUrlNavigation = 'reload';
+ this._router.navigate([this._router.url]);
+ }
+
votePost(isLike: boolean): void {
if (!this.loggedIn) {
this._router.navigate(['/login']);
diff --git a/src/assets/icons/tabler-icon-edit.svg b/src/assets/icons/tabler-icon-edit.svg
new file mode 100644
index 0000000..e12e396
--- /dev/null
+++ b/src/assets/icons/tabler-icon-edit.svg
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ class="icon icon-tabler icon-tabler-edit"
+ width="24"
+ height="24"
+ viewBox="0 0 24 24"
+ stroke-width="2"
+ stroke="currentColor"
+ fill="none"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ version="1.1"
+ id="svg10"
+ sodipodi:docname="tabler-icon-edit.svg"
+ inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
+ <metadata
+ id="metadata16">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs14" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1053"
+ id="namedview12"
+ showgrid="false"
+ inkscape:zoom="37.541667"
+ inkscape:cx="12"
+ inkscape:cy="12"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg10" />
+ <path
+ stroke="none"
+ d="M0 0h24v24H0z"
+ fill="none"
+ id="path2" />
+ <path
+ d="M 9,7 H 6 A 2,2 0 0 0 4,9 v 9 a 2,2 0 0 0 2,2 h 9 a 2,2 0 0 0 2,-2 v -3"
+ id="path4"
+ style="stroke:#ffeede" />
+ <path
+ d="m 9,15 h 3 l 8.5,-8.5 a 2.1213203,2.1213203 0 0 0 -3,-3 L 9,12 v 3"
+ id="path6"
+ style="stroke:#ffeede" />
+ <line
+ x1="16"
+ y1="5"
+ x2="19"
+ y2="8"
+ id="line8"
+ style="stroke:#ffeede" />
+</svg>
diff --git a/src/assets/icons/tabler-icon-trash.svg b/src/assets/icons/tabler-icon-trash.svg
new file mode 100644
index 0000000..eee68f7
--- /dev/null
+++ b/src/assets/icons/tabler-icon-trash.svg
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ class="icon icon-tabler icon-tabler-trash"
+ width="24"
+ height="24"
+ viewBox="0 0 24 24"
+ stroke-width="2"
+ stroke="currentColor"
+ fill="none"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ version="1.1"
+ id="svg14"
+ sodipodi:docname="tabler-icon-trash.svg"
+ inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
+ <metadata
+ id="metadata20">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs18" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1053"
+ id="namedview16"
+ showgrid="false"
+ inkscape:zoom="37.541667"
+ inkscape:cx="12"
+ inkscape:cy="12"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg14" />
+ <path
+ stroke="none"
+ d="M0 0h24v24H0z"
+ fill="none"
+ id="path2" />
+ <line
+ x1="4"
+ y1="7"
+ x2="20"
+ y2="7"
+ id="line4"
+ style="stroke:#ffeede" />
+ <line
+ x1="10"
+ y1="11"
+ x2="10"
+ y2="17"
+ id="line6"
+ style="stroke:#ffeede" />
+ <line
+ x1="14"
+ y1="11"
+ x2="14"
+ y2="17"
+ id="line8"
+ style="stroke:#ffeede" />
+ <path
+ d="m 5,7 1,12 a 2,2 0 0 0 2,2 h 8 a 2,2 0 0 0 2,-2 L 19,7"
+ id="path10"
+ style="stroke:#ffeede" />
+ <path
+ d="M 9,7 V 4 a 1,1 0 0 1 1,-1 h 4 a 1,1 0 0 1 1,1 v 3"
+ id="path12"
+ style="stroke:#ffeede" />
+</svg>