aboutsummaryrefslogtreecommitdiff
path: root/src/app/components/feed
diff options
context:
space:
mode:
authortranstrike <transtrike@gmail.com>2021-02-12 19:04:53 +0200
committertranstrike <transtrike@gmail.com>2021-02-12 19:04:53 +0200
commitbcd88af53b1a920d728ec98b45daa9ac2e2c0917 (patch)
treefd27eef086822b0f02f74364cac0b940956d2458 /src/app/components/feed
parent1d1f05e3f74d70a558b4847a9107afa7952131cf (diff)
downloadDevHive-Angular-bcd88af53b1a920d728ec98b45daa9ac2e2c0917.tar
DevHive-Angular-bcd88af53b1a920d728ec98b45daa9ac2e2c0917.tar.gz
DevHive-Angular-bcd88af53b1a920d728ec98b45daa9ac2e2c0917.zip
Moved from DevHive
Diffstat (limited to 'src/app/components/feed')
-rw-r--r--src/app/components/feed/feed.component.css179
-rw-r--r--src/app/components/feed/feed.component.html52
-rw-r--r--src/app/components/feed/feed.component.ts122
3 files changed, 353 insertions, 0 deletions
diff --git a/src/app/components/feed/feed.component.css b/src/app/components/feed/feed.component.css
new file mode 100644
index 0000000..cb155c6
--- /dev/null
+++ b/src/app/components/feed/feed.component.css
@@ -0,0 +1,179 @@
+#feed-page {
+ height: 100%;
+ max-width: 40em;
+ box-sizing: border-box;
+ border: .5em solid var(--bg-color);
+
+ margin: 0 auto;
+
+ display: flex;
+}
+
+@media screen and (max-width: 750px) {
+ #profile-bar {
+ display: none !important;
+ }
+ #top-bar-profile-pic {
+ display: initial;
+ }
+}
+@media screen and (min-width: 750px) {
+ #profile-bar {
+ display: initial;
+ }
+ #top-bar-profile-pic {
+ display: none !important;
+ }
+}
+
+/* Content */
+
+#feed-content {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
+
+/* Profile bar */
+
+#profile-bar {
+ width: 20%;
+ height: fit-content;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ box-sizing: border-box;
+ background-color: var(--bg-color);
+
+ margin-right: .5em;
+ padding-bottom: 1em;
+ padding: .5em;
+ border-radius: .6em;
+}
+
+#profile-bar-profile-pic {
+ width: 7em;
+ height: 7em;
+ box-sizing: border-box;
+ padding: .5em;
+}
+
+#profile-bar-name {
+ text-align: center;
+}
+
+#profile-bar-username {
+ margin: .5em 0;
+}
+
+#profile-bar > #profile-info {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+/* Top bar */
+
+#top-bar {
+ display: flex;
+ flex-direction: column;
+ width: 98%;
+ margin: 0 auto;
+ margin-bottom: .5em;
+ box-sizing: border-box;
+}
+
+#top-bar-profile-pic {
+ height: 2.5em;
+ width: 2.5em;
+ margin-right: .5em;
+}
+
+#top-bar-profile-pic > img {
+ height: inherit;
+ width: inherit;
+}
+
+#top-bar-open-chat {
+ /* Until implemented */
+ display: none;
+}
+
+#main-content {
+ display: flex;
+}
+
+/* Create post */
+
+#create-post-form {
+ width: 100%;
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ box-sizing: border-box;
+}
+
+#form-inputs {
+ display: flex;
+}
+
+#top-bar-create-post {
+ flex: 1;
+ font-size: inherit;
+ width: 100%;
+ height: 100%;
+ margin: 0 auto;
+ box-sizing: border-box;
+ border: 2px solid var(--bg-color);
+ border-radius: .6em;
+}
+
+#file-upload {
+ font-size: inherit;
+ color: transparent;
+ width: 1.5em;
+ height: 1.5em;
+}
+
+#file-upload:hover {
+ cursor: pointer;
+}
+
+#file-upload::-webkit-file-upload-button {
+ visibility: hidden;
+}
+
+#attachment-img {
+ height: 1.5em;
+ width: 1.5em;
+ position: absolute;
+ right: .4em;
+ pointer-events: none;
+}
+
+/* Posts */
+
+#no-posts-msg {
+ width: 100%;
+ margin-top: 1em;
+ color: gray;
+ text-align: center;
+}
+
+/* Elements, that act as buttons */
+
+#profile-bar > #profile-info:hover,
+#top-bar-profile-pic:hover {
+ cursor: pointer;
+}
+
+/* Can't copy text from */
+
+#profile-bar,
+.vote {
+ -webkit-user-select: none; /* Safari */
+ -moz-user-select: none; /* Firefox */
+ -ms-user-select: none; /* IE10+/Edge */
+ user-select: none; /* Standard */
+}
diff --git a/src/app/components/feed/feed.component.html b/src/app/components/feed/feed.component.html
new file mode 100644
index 0000000..1a03dcc
--- /dev/null
+++ b/src/app/components/feed/feed.component.html
@@ -0,0 +1,52 @@
+<app-loading *ngIf="!dataArrived"></app-loading>
+
+<div id="feed-page" *ngIf="dataArrived">
+ <nav id="profile-bar" class="round-image rounded-border">
+ <div id="profile-info" (click)="goToProfile()">
+ <img id="profile-bar-profile-pic" class="round-image" [src]="user.profilePictureURL" alt=""/>
+ <div id="profile-bar-name">
+ {{ user.firstName }} {{ user.lastName }}
+ </div>
+ <div id="profile-bar-username">
+ @{{ user.userName }}
+ </div>
+ </div>
+ <button class="submit-btn" (click)="goToSettings()">Settings</button>
+ <button class="submit-btn" (click)="logout()">Logout</button>
+ </nav>
+ <div id="feed-content">
+ <nav id="top-bar">
+ <div id="main-content">
+ <img id="top-bar-profile-pic" class="round-image" [src]="user.profilePictureURL" alt="" (click)="goToProfile()">
+ <form id="create-post-form" class="rounded-border" [formGroup]="createPostFormGroup" (ngSubmit)="createPost()">
+ <div id="form-inputs">
+ <input id="top-bar-create-post" type="text" formControlName="newPostMessage" placeholder="What's on your mind?"/>
+ <input type="submit" style="display: none" /> <!-- You need this element, so when you press enter the request is sent -->
+ <img id="attachment-img" src="assets/images/paper-clip.png">
+ <input id="file-upload" type="file" formControlName="fileUpload" (change)="onFileUpload($event)" multiple>
+ </div>
+ <div class="form-attachments">
+ <div *ngFor="let file of files" class="form-attachment">
+ {{ file.name ? file.name : 'Attachment' }}
+ <div class="remove-form-attachment" (click)="removeAttachment(file.name)">
+ ☒
+ </div>
+ </div>
+ </div>
+ </form>
+ <a id="top-bar-open-chat" href="">
+ <img src="assets/images/feed/chat-pic.png" alt=""/>
+ </a>
+ </div>
+ </nav>
+ <div id="posts" class="scroll-standalone" (scroll)="onScroll($event)">
+ <div id="no-posts-msg" *ngIf="posts.length === 0">
+ 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>
+ </div>
+ </div>
+</div>
diff --git a/src/app/components/feed/feed.component.ts b/src/app/components/feed/feed.component.ts
new file mode 100644
index 0000000..b412b3c
--- /dev/null
+++ b/src/app/components/feed/feed.component.ts
@@ -0,0 +1,122 @@
+import { Component, OnInit } from '@angular/core';
+import { Title } from '@angular/platform-browser';
+import { Router } from '@angular/router';
+import { User } from 'src/models/identity/user';
+import { UserService } from '../../services/user.service';
+import { AppConstants } from 'src/app/app-constants.module';
+import { HttpErrorResponse } from '@angular/common/http';
+import { FeedService } from 'src/app/services/feed.service';
+import { Post } from 'src/models/post';
+import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
+import { PostService } from 'src/app/services/post.service';
+import { TokenService } from 'src/app/services/token.service';
+
+@Component({
+ selector: 'app-feed',
+ templateUrl: './feed.component.html',
+ styleUrls: ['./feed.component.css']
+})
+export class FeedComponent implements OnInit {
+ private _title = 'Feed';
+ private _timeLoaded: string; // we send the time to the api as a string
+ private _currentPage: number;
+ public dataArrived = false;
+ public user: User;
+ public posts: Post[];
+ public createPostFormGroup: FormGroup;
+ public files: File[];
+
+ constructor(private _titleService: Title, private _fb: FormBuilder, private _router: Router, private _userService: UserService, private _feedService: FeedService, private _postService: PostService, private _tokenService: TokenService) {
+ this._titleService.setTitle(this._title);
+ }
+
+ ngOnInit(): void {
+ if (!this._tokenService.getTokenFromSessionStorage()) {
+ this._router.navigate(['/login']);
+ return;
+ }
+
+ this._currentPage = 1;
+ this.posts = [];
+ this.user = this._userService.getDefaultUser();
+ this.files = [];
+
+ const now = new Date();
+ now.setHours(now.getHours() + 2); // accounting for eastern european timezone
+ this._timeLoaded = now.toISOString();
+
+ this.createPostFormGroup = this._fb.group({
+ newPostMessage: new FormControl(''),
+ fileUpload: new FormControl('')
+ });
+
+ this._userService.getUserFromSessionStorageRequest().subscribe(
+ (res: object) => {
+ Object.assign(this.user, res);
+ this.loadFeed();
+ },
+ (err: HttpErrorResponse) => {
+ this.logout();
+ }
+ );
+ }
+
+ private loadFeed(): void {
+ this._feedService.getUserFeedFromSessionStorageRequest(this._currentPage++, this._timeLoaded, AppConstants.PAGE_SIZE).subscribe(
+ (result: object) => {
+ this.posts.push(...Object.values(result)[0]);
+ this.finishUserLoading();
+ },
+ (err) => {
+ this.finishUserLoading();
+ }
+ );
+ }
+
+ private finishUserLoading(): void {
+ this.dataArrived = true;
+ }
+
+ goToProfile(): void {
+ this._router.navigate(['/profile/' + this.user.userName]);
+ }
+
+ goToSettings(): void {
+ this._router.navigate(['/profile/' + this.user.userName + '/settings']);
+ }
+
+ logout(): void {
+ this._tokenService.logoutUserFromSessionStorage();
+ this._router.navigate(['/login']);
+ }
+
+ onFileUpload(event: any): void {
+ this.files.push(...event.target.files);
+ this.createPostFormGroup.get('fileUpload')?.reset();
+ }
+
+ removeAttachment(fileName: string): void {
+ this.files = this.files.filter(x => x.name !== fileName);
+ }
+
+ createPost(): void {
+ const postMessage = this.createPostFormGroup.get('newPostMessage')?.value;
+ this.dataArrived = false;
+
+ this._postService.createPostWithSessionStorageRequest(postMessage, this.files).subscribe(
+ (result: object) => {
+ this.goToProfile();
+ },
+ (err: HttpErrorResponse) => {
+ this.dataArrived = true;
+ }
+ );
+ }
+
+ onScroll(event: any): void {
+ // Detects when the element has reached the bottom, thx https://stackoverflow.com/a/50038429/12036073
+ if (event.target.offsetHeight + event.target.scrollTop >= event.target.scrollHeight && this._currentPage > 0) {
+ this.loadFeed();
+ }
+ }
+}