From b6a8296eee6212ab64a858ca89327a51be932bac Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 13 Jan 2020 09:25:34 +0100 Subject: [PATCH 01/19] Moved 'What does the level mean?' to the about page --- src/app/components/about/about.component.html | 47 ++++++++++++++++++- src/app/components/about/about.component.sass | 10 +++- src/app/components/about/about.component.ts | 15 +++++- src/app/components/feed/feed.component.ts | 12 ++--- .../components/profile/profile.component.html | 45 +----------------- .../components/profile/profile.component.sass | 8 ---- .../components/profile/profile.component.ts | 13 +---- 7 files changed, 76 insertions(+), 74 deletions(-) diff --git a/src/app/components/about/about.component.html b/src/app/components/about/about.component.html index f0d7f9d..d03061a 100644 --- a/src/app/components/about/about.component.html +++ b/src/app/components/about/about.component.html @@ -1,5 +1,6 @@
+

Greenvironment






Keep it clean and green!

@@ -9,7 +10,51 @@

What's Greenvironment?

-

We, the greenviroment team want to create a network for environmentalists who care for our nature and our planet as much as we do.

+

We, the greenviroment team want to create a network for environmentalists who care for our nature and our planet as much as we do.

+
+

What does the level mean?

+

There are different levels you can reach through green behaviour. + Collect 100 points to level up! The levels are called: +

+ + + + + + + + + + + +
level {{level.level}} level name {{level.name}}
+
+

How to level up?

+

There is an always growing list of things you can do, + to support your environment + and earn points to level up at the same time. + You can get a different amount of points + for differnet actions you can see in the list below: +

+ + + + + + + + + + + + + + + + + +
points {{action.points}} action {{action.name}}

We believe, that together we can do amazing things to protect our environment and keep it clean and green.

diff --git a/src/app/components/about/about.component.sass b/src/app/components/about/about.component.sass index 90e88b1..be12ffc 100644 --- a/src/app/components/about/about.component.sass +++ b/src/app/components/about/about.component.sass @@ -1,7 +1,5 @@ @import '../../../styles/mixins.sass' @import '../../../styles/vars.sass' -@import '~@angular/material/theming' -@import '../../../styles/greenvironment-material-theme.scss' #about position: fixed @@ -28,3 +26,11 @@ width: 100% max-width: 30em margin-bottom: 1em + +.mat-table + width: 100% + max-width: 690px + margin: 0 auto + text-align: left +.mat-header-cell + padding-right: 0.5em diff --git a/src/app/components/about/about.component.ts b/src/app/components/about/about.component.ts index 88f7f9f..4b81aa9 100644 --- a/src/app/components/about/about.component.ts +++ b/src/app/components/about/about.component.ts @@ -1,4 +1,8 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { Actionlist } from 'src/app/models/actionlist'; +import { Levellist } from 'src/app/models/levellist'; +import {MatSort} from '@angular/material/sort'; +import {MatTableDataSource} from '@angular/material/table'; @Component({ selector: 'app-about', @@ -6,10 +10,19 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./about.component.sass'] }) export class AboutComponent implements OnInit { + actionlist: Actionlist = new Actionlist(); + levellist: Levellist = new Levellist(); + + displayedColumns = ['points', 'name']; + dataSource = new MatTableDataSource(this.actionlist.Actions); + displayedLevelColumns = ['level', 'name']; + levelSource = this.levellist.levels; constructor() { } + @ViewChild(MatSort, {static: true}) sort: MatSort; ngOnInit() { + this.dataSource.sort = this.sort; } } diff --git a/src/app/components/feed/feed.component.ts b/src/app/components/feed/feed.component.ts index 73094f0..400c4d3 100644 --- a/src/app/components/feed/feed.component.ts +++ b/src/app/components/feed/feed.component.ts @@ -36,12 +36,12 @@ export class FeedComponent implements OnInit { this.data.currentUserInfo.subscribe(user => { this.user = user; this.loggedIn = user.loggedIn; - this.feedService.getAllPostsRaw().subscribe(response => { - this.loading = false; - this.feedNew = this.feedService.renderAllPosts(response.json()); - this.parentSelectedPostList = this.feedNew; - this.feedMostLiked = this.feedNew; - }); + }); + this.feedService.getAllPostsRaw().subscribe(response => { + this.loading = false; + this.feedNew = this.feedService.renderAllPosts(response.json()); + this.parentSelectedPostList = this.feedNew; + this.feedMostLiked = this.feedNew; }); } diff --git a/src/app/components/profile/profile.component.html b/src/app/components/profile/profile.component.html index 12bad54..7dad600 100644 --- a/src/app/components/profile/profile.component.html +++ b/src/app/components/profile/profile.component.html @@ -60,50 +60,7 @@
-
-

What does the level mean?

-

There are different levels you can reach through green behaviour. - Collect 100 points to level up! The levels are called: -

- - - - - - - - - - - -
level {{level.level}} level name {{level.name}}
-
-

How to level up?

-

There is an always growing list of things you can do, - to support your environment - and earn points to level up at the same time. - You can get a different amount of points - for differnet actions you can see in the list below: -

- - - - - - - - - - - - - - - - - -
points {{action.points}} action {{action.name}}
+ - action - {{action.name}} - + action + {{action.name}} + + + + + description + {{action.description}} + diff --git a/src/app/components/about/about.component.ts b/src/app/components/about/about.component.ts index c27f304..d2907cd 100644 --- a/src/app/components/about/about.component.ts +++ b/src/app/components/about/about.component.ts @@ -3,6 +3,7 @@ import { Activitylist } from 'src/app/models/activity'; import { Levellist } from 'src/app/models/levellist'; import {MatSort} from '@angular/material/sort'; import {MatTableDataSource} from '@angular/material/table'; +import { ActivityService } from 'src/app/services/activity/activity.service'; @Component({ selector: 'app-about', @@ -13,16 +14,21 @@ export class AboutComponent implements OnInit { actionlist: Activitylist = new Activitylist(); levellist: Levellist = new Levellist(); - displayedColumns = ['points', 'name']; + displayedColumns = ['points', 'name', 'description']; dataSource = new MatTableDataSource(this.actionlist.Actions); displayedLevelColumns = ['level', 'name']; levelSource = this.levellist.levels; - constructor() { } + constructor(private activityService: ActivityService) { } @ViewChild(MatSort, {static: true}) sort: MatSort; ngOnInit() { - this.dataSource.sort = this.sort; + this.activityService.getActivitys(); + this.activityService.activitylist.subscribe(response => { + this.actionlist = response; + this.dataSource = new MatTableDataSource(this.actionlist.Actions); + this.dataSource.sort = this.sort; + }); } } diff --git a/src/app/components/feed/feed.component.html b/src/app/components/feed/feed.component.html index c51821b..1584af1 100644 --- a/src/app/components/feed/feed.component.html +++ b/src/app/components/feed/feed.component.html @@ -13,14 +13,14 @@

What did you do? - + nothing ;) - - {{action.name}} + + {{action.name}} - @@ -44,12 +44,7 @@
-
- -
-
- -
+
diff --git a/src/app/components/feed/feed.component.ts b/src/app/components/feed/feed.component.ts index e0d703d..9665fc9 100644 --- a/src/app/components/feed/feed.component.ts +++ b/src/app/components/feed/feed.component.ts @@ -3,6 +3,7 @@ import { Post } from 'src/app/models/post'; import { FeedService } from 'src/app/services/feed/feed.service'; import { Activitylist } from 'src/app/models/activity'; import { DatasharingService } from '../../services/datasharing.service'; +import { ActivityService } from 'src/app/services/activity/activity.service'; import { User } from 'src/app/models/user'; @Component({ @@ -12,70 +13,57 @@ import { User } from 'src/app/models/user'; }) export class FeedComponent implements OnInit { loading = true; + checked: boolean; // if the "I protected the environment."-box is checked - empty: boolean; - // points value of the green action + empty: any; + // id of the green activity value: any; - viewNew = true; - viewMostLiked = false; - - feedNew: Array; - feedMostLiked: Array; parentSelectedPostList: Array; - actionlist: Activitylist = new Activitylist(); loggedIn = false; - userId: number; user: User; - constructor(private feedService: FeedService, private data: DatasharingService) { } + constructor( + private feedService: FeedService, + private data: DatasharingService, + private activityService: ActivityService + ) { } ngOnInit() { this.data.currentUserInfo.subscribe(user => { this.user = user; this.loggedIn = user.loggedIn; }); - this.feedService.getAllPostsRaw().subscribe(response => { - this.loading = false; - this.feedNew = this.feedService.renderAllPosts(response.json()); - this.parentSelectedPostList = this.feedNew; - this.feedMostLiked = this.feedNew; + this.activityService.getActivitys(); + this.activityService.activitylist.subscribe(response => { + this.actionlist = response; + }); + this.feedService.getNewPosts(); + this.feedService.posts.subscribe(response => { + if (response.length > 0) {this.loading = false; } + this.parentSelectedPostList = response; }); - } - createPost(pElement) { - this.feedService.createPost(pElement.value); + createPost(pElement, activityId: string) { + if (pElement && activityId) { + this.feedService.createPostActivity(pElement.value, activityId); pElement.value = ''; - this.feedService.getAllPostsRaw().subscribe(response => { - this.feedNew = this.feedService.renderAllPosts(response.json()); - this.parentSelectedPostList = this.feedNew; - this.feedMostLiked = this.feedNew; }); + this.empty = ''; + } else if (pElement) { + this.feedService.createPost(pElement.value); + pElement.value = ''; + this.empty = ''; + } } showNew() { - this.feedService.getAllPostsRaw().subscribe(response => { - this.feedNew = this.feedService.renderAllPosts(response.json()); - this.parentSelectedPostList = this.feedNew; }); - this.viewNew = true; - this.viewMostLiked = false; + this.feedService.getNewPosts(); } showMostLiked() { - this.feedService.getAllPostsRaw().subscribe(response => { - this.feedMostLiked = this.feedService.renderAllPosts(response.json()); - this.parentSelectedPostList = this.feedMostLiked; }); - this.viewNew = false; - this.viewMostLiked = true; + this.feedService.getMostLikedPosts(); } - - - refresh($event) { - this.feedService.getAllPostsRaw().subscribe(response => { - this.parentSelectedPostList = this.feedService.renderAllPosts(response.json()); - }); - } - } diff --git a/src/app/components/feed/postlist/postlist.component.html b/src/app/components/feed/postlist/postlist.component.html index 6d6d510..40945c7 100644 --- a/src/app/components/feed/postlist/postlist.component.html +++ b/src/app/components/feed/postlist/postlist.component.html @@ -56,6 +56,11 @@ keyboard_arrow_down {{post.downvotes}} +
+ + {{post.activity.points}} points earned through {{post.activity.name}} + +
diff --git a/src/app/components/feed/postlist/postlist.component.sass b/src/app/components/feed/postlist/postlist.component.sass index 12f3e95..fd49ccb 100644 --- a/src/app/components/feed/postlist/postlist.component.sass +++ b/src/app/components/feed/postlist/postlist.component.sass @@ -20,5 +20,15 @@ max-width: 100% height: auto border-radius: 4px + .mat-button + min-width: 32px !important + padding: 0 + margin: 0 + margin-left: 8px + + .activity-info + display: contents + .span + margin-left: 32px diff --git a/src/app/components/home/home.component.ts b/src/app/components/home/home.component.ts index 9149fc1..22abaab 100644 --- a/src/app/components/home/home.component.ts +++ b/src/app/components/home/home.component.ts @@ -17,7 +17,6 @@ export class HomeComponent implements OnInit { this.data.currentUserInfo.subscribe(user => { this.loggedIn = user.loggedIn; }); - this.feedService.getAllPosts(); } } diff --git a/src/app/models/activity.ts b/src/app/models/activity.ts index 966e56b..9751b0e 100644 --- a/src/app/models/activity.ts +++ b/src/app/models/activity.ts @@ -1,10 +1,18 @@ -export interface Action { +export class Activity { id: number; name: string; + description: string; points: number; + + constructor(id: number, name: string, description: string, points: number) { + this.id = id; + this.name = name; + this.description = description; + this.points = points; + } } export class Activitylist { - Actions: Action[] = new Array(); + Actions: Activity[] = new Array(); } diff --git a/src/app/models/post.ts b/src/app/models/post.ts index b0d6818..68ddec1 100644 --- a/src/app/models/post.ts +++ b/src/app/models/post.ts @@ -1,4 +1,5 @@ import { Author } from './author'; +import { Activity } from './activity'; export class Post { id: number; @@ -10,6 +11,7 @@ export class Post { userVote: string; deletable: boolean; author: Author; + activity: Activity; // TODO: constructor properties need normal names constructor( @@ -21,7 +23,8 @@ export class Post { pUserVote: string, pDeletable: boolean, pDate: string, - pAuthor: Author + pAuthor: Author, + pactivity: Activity ) { this.id = pId; this.content = pContent; @@ -32,5 +35,6 @@ export class Post { this.deletable = pDeletable; this.date = pDate; this.author = pAuthor; + this.activity = pactivity; } } diff --git a/src/app/services/activity/activity.service.ts b/src/app/services/activity/activity.service.ts index d19f03a..4e4f43f 100644 --- a/src/app/services/activity/activity.service.ts +++ b/src/app/services/activity/activity.service.ts @@ -1,16 +1,16 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; -import { Activitylist } from 'src/app/models/activity'; +import { Activitylist, Activity } from 'src/app/models/activity'; import { environment } from 'src/environments/environment'; import { Http } from '@angular/http'; + @Injectable({ providedIn: 'root' }) export class ActivityService { - private activitylist = new BehaviorSubject(new Activitylist()); - currentActivityList = this.activitylist.asObservable(); + public activitylist = new BehaviorSubject(new Activitylist()); constructor(private http: Http) { } @@ -19,53 +19,34 @@ export class ActivityService { } public getActivitys() { - const headers = new Headers(); - headers.set('Content-Type', 'application/json'); - this.http.post(environment.graphQLUrl, this.buildJson()).subscribe(result => { - // push onto subject - this.activitylist.next(this.renderActivity(result.json())); - }); + if (this.activitylist.getValue().Actions.length < 1) { + const headers = new Headers(); + headers.set('Content-Type', 'application/json'); + this.http.post(environment.graphQLUrl, this.buildJson()).subscribe(result => { + // push onto subject + this.activitylist.next(this.renderActivity(result.json())); + }); + } } - public buildJson(id: string): any { - const body = {query: `query($userId: ID) { - getUser(userId:$userId){ - id - handle - name - profilePicture - points - level - friendCount - groupCount - joinedAt - friends{ - id - } - posts{ - id, - content, - htmlContent, - upvotes, - downvotes, - userVote, - deletable, - author{ - name, - handle, - id}, - createdAt - } - } - }`, variables: { - userId: id, + public buildJson(): any { + const body = {query: `query{getActivities{ + id name description points + }}`, variables: { + }}; return body; } public renderActivity(response: any): Activitylist { const activitylist = new Activitylist(); - // activitylist.push(); + for (const activity of response.data.getActivities) { + activitylist.Actions.push(new Activity( + activity.id, + activity.name, + activity.description, + activity.points)); + } return activitylist; } } diff --git a/src/app/services/feed/feed.service.ts b/src/app/services/feed/feed.service.ts index e609837..3867512 100644 --- a/src/app/services/feed/feed.service.ts +++ b/src/app/services/feed/feed.service.ts @@ -3,29 +3,88 @@ import { Http } from '@angular/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 } from 'rxjs'; +import { User } from 'src/app/models/user'; @Injectable({ providedIn: 'root' }) export class FeedService { - posts: Array; + public posts: BehaviorSubject = new BehaviorSubject(new Array()); + public newPosts: BehaviorSubject = new BehaviorSubject(new Array()); + public mostLikedPosts: BehaviorSubject = new BehaviorSubject(new Array()); constructor(private http: Http) { } public createPost(pContent: String) { - const url = environment.graphQLUrl; const headers = new Headers(); headers.set('Content-Type', 'application/json'); const body = {query: `mutation($content: String!) { - createPost(content: $content) {id} + createPost(content: $content) { + id, + content, + htmlContent, + upvotes, + downvotes, + userVote, + deletable, + activity{ + id + name + description + points + }, + author{ + name, + handle, + id}, + createdAt} }`, variables: { content: pContent }}; + return this.http.post(environment.graphQLUrl, body).subscribe(response => { + const updatedposts = this.newPosts.getValue(); + updatedposts.unshift(this.renderPost(response.json())); + this.newPosts.next(updatedposts); + }); + } - this.http.post(url, body).subscribe(response => { - }); + public createPostActivity(pContent: String, activityId: String) { + const headers = new Headers(); + headers.set('Content-Type', 'application/json'); + + const body = {query: `mutation($content: String!, $id: ID) { + createPost(content: $content activityId: $id) { + id, + content, + htmlContent, + upvotes, + downvotes, + userVote, + deletable, + activity{ + id + name + description + points + }, + author{ + name, + handle, + id}, + createdAt} + }`, variables: { + content: pContent, + id: activityId + }}; + return this.http.post(environment.graphQLUrl, body).subscribe(response => { + const updatedposts = this.newPosts.getValue(); + updatedposts.unshift(this.renderPost(response.json())); + this.newPosts.next(updatedposts); + }); } public upvote(pPostID: number): any { @@ -71,26 +130,31 @@ export class FeedService { return this.http.post(environment.graphQLUrl, body); } - public getAllPosts(): Array { - const url = environment.graphQLUrl; - - const headers = new Headers(); - headers.set('Content-Type', 'application/json'); - - this.http.post(url, this.getBodyForGetAllPosts()) - .subscribe(response => { - this.posts = this.renderAllPosts(response.json()); + public getNewPosts() { + if (this.newPosts.getValue().length === 0) { + const headers = new Headers(); + headers.set('Content-Type', 'application/json'); + this.http.post(environment.graphQLUrl, this.buildJsonNew()) + .subscribe(response => { + this.newPosts.next(this.renderAllPosts(response.json())); + this.posts.next(this.newPosts.getValue()); }); - return this.posts; + } else {this.posts.next(this.newPosts.getValue()); } } - public getAllPostsRaw(): any { - const headers = new Headers(); - headers.set('Content-Type', 'application/json'); - return this.http.post(environment.graphQLUrl, this.getBodyForGetAllPosts()); + public getMostLikedPosts() { + if (this.mostLikedPosts.getValue().length === 0) { + const headers = new Headers(); + headers.set('Content-Type', 'application/json'); + this.http.post(environment.graphQLUrl, this.buildJsonMostLiked()) + .subscribe(response => { + this.mostLikedPosts.next(this.renderAllPosts(response.json())); + this.posts.next(this.mostLikedPosts.getValue()); + }); + } else {this.posts.next(this.mostLikedPosts.getValue()); } } - getBodyForGetAllPosts() { + buildJsonNew() { const body = {query: `{ getPosts (first: 1000, offset: 0) { id, @@ -99,7 +163,13 @@ export class FeedService { upvotes, downvotes, userVote, - deletable + deletable, + activity{ + id + name + description + points + }, author{ name, handle, @@ -110,6 +180,56 @@ export class FeedService { return body; } + buildJsonMostLiked() { + const body = {query: `{ + getPosts (first: 1000, offset: 0, sort: TOP) { + id, + content, + htmlContent, + upvotes, + downvotes, + userVote, + deletable, + activity{ + id + name + description + points + }, + author{ + name, + handle, + id}, + createdAt} + }`, variables: { + }}; + return body; + } + + public renderPost(response: any): Post { + const post = response.data.createPost; + const id: number = post.id; + const content: string = post.content; + const htmlContent: string = post.htmlContent; + const upvotes: number = post.upvotes; + const downvotes: number = post.downvotes; + const userVote: string = post.userVote; + const deletable: boolean = post.deletable; + const author = new Author(post.author.id, post.author.name, post.author.handle); + const temp = new Date(Number(post.createdAt)); + const date = temp.toLocaleString('en-GB'); + let activity: Activity; + if (post.activity) { + activity = new Activity( + post.activity.id, + post.activity.name, + post.activity.description, + post.activity.points); + } else { activity = null; } + + return new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, date, author, activity); + } + public renderAllPosts(pResponse: any): Array { const posts = new Array(); // let options = {year: 'numeric', month: 'short', day: 'numeric', hour: '' } @@ -124,8 +244,15 @@ export class FeedService { const author = new Author(post.author.id, post.author.name, post.author.handle); const temp = new Date(Number(post.createdAt)); const date = temp.toLocaleString('en-GB'); - - posts.push(new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, date, author)); + let activity: Activity; + if (post.activity) { + activity = new Activity( + post.activity.id, + post.activity.name, + post.activity.description, + post.activity.points); + } else { activity = null; } + posts.push(new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, date, author, activity)); } return posts; } diff --git a/src/app/services/profile/profile.service.ts b/src/app/services/profile/profile.service.ts index d92944d..e8735b1 100644 --- a/src/app/services/profile/profile.service.ts +++ b/src/app/services/profile/profile.service.ts @@ -5,6 +5,7 @@ import { Author } from 'src/app/models/author'; import { environment } from 'src/environments/environment'; import { User } from 'src/app/models/user'; import { Observable, Subject } from 'rxjs'; +import { Activity } from 'src/app/models/activity'; @Injectable({ providedIn: 'root' @@ -49,6 +50,12 @@ export class ProfileService { downvotes, userVote, deletable, + activity{ + id + name + description + points + }, author{ name, handle, @@ -88,7 +95,17 @@ export class ProfileService { const author = new Author(post.author.id, post.author.name, post.author.handle); const ptemp = new Date(Number(post.createdAt)); const pdate = ptemp.toLocaleString('en-GB'); - posts.push(new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, pdate, author)); + let activity: Activity; + if (post.activity) { + activity = new Activity( + post.activity.id, + post.activity.name, + post.activity.description, + post.activity.points); + } else { activity = null; } + + // tslint:disable-next-line: max-line-length + posts.push(new Post(id, content, htmlContent, upvotes, downvotes, userVote, deletable, pdate, author, activity)); } profile.posts = posts; return profile; From 5b90ac638e3e589edd17380376e992301bcca1a1 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 13 Jan 2020 19:22:05 +0100 Subject: [PATCH 04/19] post is visible immediately --- src/app/services/feed/feed.service.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/services/feed/feed.service.ts b/src/app/services/feed/feed.service.ts index 3867512..6e94178 100644 --- a/src/app/services/feed/feed.service.ts +++ b/src/app/services/feed/feed.service.ts @@ -49,6 +49,7 @@ export class FeedService { const updatedposts = this.newPosts.getValue(); updatedposts.unshift(this.renderPost(response.json())); this.newPosts.next(updatedposts); + this.posts.next(this.newPosts.getValue()); }); } @@ -84,6 +85,7 @@ export class FeedService { const updatedposts = this.newPosts.getValue(); updatedposts.unshift(this.renderPost(response.json())); this.newPosts.next(updatedposts); + this.posts.next(this.newPosts.getValue()); }); } From 740efb49ba09d1560371241f9d0428e9661f19ca Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 13 Jan 2020 19:52:33 +0100 Subject: [PATCH 05/19] improved posts --- src/app/components/feed/feed.component.html | 6 +++--- src/app/components/feed/feed.component.ts | 7 +++++-- src/app/components/feed/postlist/postlist.component.html | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/app/components/feed/feed.component.html b/src/app/components/feed/feed.component.html index 1584af1..de81a86 100644 --- a/src/app/components/feed/feed.component.html +++ b/src/app/components/feed/feed.component.html @@ -9,14 +9,14 @@

- I protected the environment. + I protected the environment.

What did you do? nothing ;) - {{action.name}} + {{action.name}} ({{action.description}}) @@ -37,7 +37,7 @@
- + New Most Liked diff --git a/src/app/components/feed/feed.component.ts b/src/app/components/feed/feed.component.ts index 9665fc9..d242979 100644 --- a/src/app/components/feed/feed.component.ts +++ b/src/app/components/feed/feed.component.ts @@ -14,7 +14,8 @@ import { User } from 'src/app/models/user'; export class FeedComponent implements OnInit { loading = true; - checked: boolean; // if the "I protected the environment."-box is checked + checked = false; // if the "I protected the environment."-box is checked + view = 'new'; empty: any; // id of the green activity value: any; @@ -48,14 +49,16 @@ export class FeedComponent implements OnInit { } createPost(pElement, activityId: string) { - if (pElement && activityId) { + if (pElement && activityId && this.checked) { this.feedService.createPostActivity(pElement.value, activityId); pElement.value = ''; this.empty = ''; + this.view = 'new'; } else if (pElement) { this.feedService.createPost(pElement.value); pElement.value = ''; this.empty = ''; + this.view = 'new'; } } diff --git a/src/app/components/feed/postlist/postlist.component.html b/src/app/components/feed/postlist/postlist.component.html index 40945c7..c182e2c 100644 --- a/src/app/components/feed/postlist/postlist.component.html +++ b/src/app/components/feed/postlist/postlist.component.html @@ -58,7 +58,7 @@ {{post.downvotes}}
- {{post.activity.points}} points earned through {{post.activity.name}} + {{post.activity.points}} points earned through {{post.activity.name}}
From 240c0d2ab46b86d3191d41d01d0b19fe95dab762 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 14 Jan 2020 14:20:11 +0100 Subject: [PATCH 06/19] WIP: infinite scrolling --- package-lock.json | 13 +++++++++++++ package.json | 1 + src/app/app.module.ts | 3 +++ src/app/components/feed/feed.component.html | 8 ++++++-- src/app/components/feed/feed.component.sass | 1 + src/app/components/feed/feed.component.ts | 8 +++++++- src/app/services/feed/feed.service.ts | 2 +- 7 files changed, 32 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4be04a3..82a6089 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9337,6 +9337,14 @@ "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, + "ngx-infinite-scroll": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ngx-infinite-scroll/-/ngx-infinite-scroll-8.0.1.tgz", + "integrity": "sha512-YpgkTPDNT7UCEp0GRX178V1nF+M2slCPJ2TX3CpvPZb5AR99JYwj/fNivcue5lN51oUaTySEG27qjVU73vKhjw==", + "requires": { + "opencollective-postinstall": "^2.0.2" + } + }, "ngx-socket-io": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ngx-socket-io/-/ngx-socket-io-2.1.1.tgz", @@ -9823,6 +9831,11 @@ "is-wsl": "^1.1.0" } }, + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==" + }, "opn": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", diff --git a/package.json b/package.json index abb61d3..388a508 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "graphql-tag": "^2.10.0", "hammerjs": "^2.0.8", "js-sha512": "^0.8.0", + "ngx-infinite-scroll": "^8.0.1", "ngx-socket-io": "^2.1.1", "node-sass": "^4.13.0", "rxjs": "~6.3.3", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 595c8f7..f2300c3 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -30,6 +30,8 @@ import { AboutComponent } from './components/about/about.component'; import { ChatcontactsComponent } from './components/chatmanager/chatcontacts/chatcontacts.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import {MatTableModule} from '@angular/material/table'; +import { InfiniteScrollModule } from 'ngx-infinite-scroll'; + import { MatSliderModule } from '@angular/material/slider'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -114,6 +116,7 @@ const appRoutes: Routes = [ SocketIoModule.forRoot(config), GraphQLModule, HttpClientModule, + InfiniteScrollModule, MatDatepickerModule, MatNativeDateModule, RouterModule.forRoot( diff --git a/src/app/components/feed/feed.component.html b/src/app/components/feed/feed.component.html index de81a86..4d2ac35 100644 --- a/src/app/components/feed/feed.component.html +++ b/src/app/components/feed/feed.component.html @@ -1,4 +1,8 @@ -
+
@@ -45,7 +49,7 @@
- +
\ No newline at end of file diff --git a/src/app/components/feed/feed.component.sass b/src/app/components/feed/feed.component.sass index 2780ae2..c3d660c 100644 --- a/src/app/components/feed/feed.component.sass +++ b/src/app/components/feed/feed.component.sass @@ -8,6 +8,7 @@ #home width: 100% height: 100% + overflow-y: scroll #complete-feed box-sizing: border-box diff --git a/src/app/components/feed/feed.component.ts b/src/app/components/feed/feed.component.ts index d242979..9483348 100644 --- a/src/app/components/feed/feed.component.ts +++ b/src/app/components/feed/feed.component.ts @@ -43,7 +43,9 @@ export class FeedComponent implements OnInit { }); this.feedService.getNewPosts(); this.feedService.posts.subscribe(response => { - if (response.length > 0) {this.loading = false; } + if (response.length > 0) { + // this.loading = false; + } this.parentSelectedPostList = response; }); } @@ -62,6 +64,10 @@ export class FeedComponent implements OnInit { } } + onScroll() { + console.log('scrolled'); + } + showNew() { this.feedService.getNewPosts(); } diff --git a/src/app/services/feed/feed.service.ts b/src/app/services/feed/feed.service.ts index 6e94178..84f9d7c 100644 --- a/src/app/services/feed/feed.service.ts +++ b/src/app/services/feed/feed.service.ts @@ -158,7 +158,7 @@ export class FeedService { buildJsonNew() { const body = {query: `{ - getPosts (first: 1000, offset: 0) { + getPosts (first: 3, offset: 0) { id, content, htmlContent, From 8d24b5fecbee70c504bd4ea857f3927743d6c554 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 14 Jan 2020 17:31:28 +0100 Subject: [PATCH 07/19] Add infinite scrolling --- src/app/components/feed/feed.component.ts | 7 +- src/app/services/feed/feed.service.ts | 89 ++++++++++++----------- 2 files changed, 52 insertions(+), 44 deletions(-) diff --git a/src/app/components/feed/feed.component.ts b/src/app/components/feed/feed.component.ts index 9483348..71d542c 100644 --- a/src/app/components/feed/feed.component.ts +++ b/src/app/components/feed/feed.component.ts @@ -41,7 +41,7 @@ export class FeedComponent implements OnInit { this.activityService.activitylist.subscribe(response => { this.actionlist = response; }); - this.feedService.getNewPosts(); + this.feedService.getPosts('NEW'); this.feedService.posts.subscribe(response => { if (response.length > 0) { // this.loading = false; @@ -66,13 +66,14 @@ export class FeedComponent implements OnInit { onScroll() { console.log('scrolled'); + this.feedService.getNextPosts(); } showNew() { - this.feedService.getNewPosts(); + this.feedService.getPosts('NEW'); } showMostLiked() { - this.feedService.getMostLikedPosts(); + this.feedService.getPosts('TOP'); } } diff --git a/src/app/services/feed/feed.service.ts b/src/app/services/feed/feed.service.ts index 84f9d7c..aa776de 100644 --- a/src/app/services/feed/feed.service.ts +++ b/src/app/services/feed/feed.service.ts @@ -15,6 +15,9 @@ export class FeedService { public posts: BehaviorSubject = new BehaviorSubject(new Array()); public newPosts: BehaviorSubject = new BehaviorSubject(new Array()); public mostLikedPosts: BehaviorSubject = new BehaviorSubject(new Array()); + private activePostList = 'NEW'; + private mostLikedOffset = 0; + private newOffset = 0; constructor(private http: Http) { } @@ -49,7 +52,7 @@ export class FeedService { const updatedposts = this.newPosts.getValue(); updatedposts.unshift(this.renderPost(response.json())); this.newPosts.next(updatedposts); - this.posts.next(this.newPosts.getValue()); + this.setPost('NEW'); }); } @@ -85,7 +88,7 @@ export class FeedService { const updatedposts = this.newPosts.getValue(); updatedposts.unshift(this.renderPost(response.json())); this.newPosts.next(updatedposts); - this.posts.next(this.newPosts.getValue()); + this.setPost('NEW'); }); } @@ -132,59 +135,61 @@ export class FeedService { return this.http.post(environment.graphQLUrl, body); } - public getNewPosts() { - if (this.newPosts.getValue().length === 0) { + public getPosts(sort: string) { + if ((sort === 'NEW' && this.newPosts.getValue().length === 0) || + (sort === 'TOP' && this.mostLikedPosts.getValue().length === 0)) { const headers = new Headers(); headers.set('Content-Type', 'application/json'); - this.http.post(environment.graphQLUrl, this.buildJsonNew()) + this.http.post(environment.graphQLUrl, this.buildJson(sort, 0)) .subscribe(response => { - this.newPosts.next(this.renderAllPosts(response.json())); - this.posts.next(this.newPosts.getValue()); + if (sort === 'NEW') { + this.newPosts.next(this.renderAllPosts(response.json())); + } else if (sort === 'TOP') { + this.mostLikedPosts.next(this.renderAllPosts(response.json())); + } + this.setPost(sort); }); - } else {this.posts.next(this.newPosts.getValue()); } + } this.setPost(sort); } - public getMostLikedPosts() { - if (this.mostLikedPosts.getValue().length === 0) { + public getNextPosts() { + if (this.activePostList === 'NEW') { + this.newOffset += 10; + const headers = new Headers(); + headers.set('Content-Type', 'application/json'); + this.http.post(environment.graphQLUrl, this.buildJson(this.activePostList, this.newOffset)) + .subscribe(response => { + let updatedposts = this.newPosts.getValue(); + updatedposts = updatedposts.concat(this.renderAllPosts(response.json())); + this.newPosts.next(updatedposts); + this.setPost('NEW'); + }); + } else if (this.activePostList === 'TOP') { + this.mostLikedOffset += 10; const headers = new Headers(); headers.set('Content-Type', 'application/json'); - this.http.post(environment.graphQLUrl, this.buildJsonMostLiked()) + this.http.post(environment.graphQLUrl, this.buildJson(this.activePostList, this.mostLikedOffset)) .subscribe(response => { - this.mostLikedPosts.next(this.renderAllPosts(response.json())); - this.posts.next(this.mostLikedPosts.getValue()); + let updatedposts = this.mostLikedPosts.getValue(); + updatedposts = updatedposts.concat(this.renderAllPosts(response.json())); + this.mostLikedPosts.next(updatedposts); + this.setPost('TOP'); }); - } else {this.posts.next(this.mostLikedPosts.getValue()); } + } } - buildJsonNew() { - const body = {query: `{ - getPosts (first: 3, offset: 0) { - id, - content, - htmlContent, - upvotes, - downvotes, - userVote, - deletable, - activity{ - id - name - description - points - }, - author{ - name, - handle, - id}, - createdAt} - }`, variables: { - }}; - return body; + setPost(sort: string) { + this.activePostList = sort; + if (sort === 'NEW') { + this.posts.next(this.newPosts.getValue()); + } else if (sort === 'TOP') { + this.posts.next(this.mostLikedPosts.getValue()); + } } - buildJsonMostLiked() { - const body = {query: `{ - getPosts (first: 1000, offset: 0, sort: TOP) { + buildJson(sort: string, offset: number) { + const body = {query: `query($offset: Int, $sort: SortType){ + getPosts (first: 10, offset: $offset, sort: $sort) { id, content, htmlContent, @@ -204,6 +209,8 @@ export class FeedService { id}, createdAt} }`, variables: { + offset, + sort }}; return body; } From 20958851e3b7b52e42dfb83f15ed32d1d2109e1c Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 14 Jan 2020 20:29:38 +0100 Subject: [PATCH 08/19] Fix post loading animation in feed --- src/app/components/feed/feed.component.html | 5 ++++- src/app/components/feed/feed.component.ts | 11 ++++++++++- src/app/services/feed/feed.service.ts | 12 ++++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/app/components/feed/feed.component.html b/src/app/components/feed/feed.component.html index 4d2ac35..f8e49a9 100644 --- a/src/app/components/feed/feed.component.html +++ b/src/app/components/feed/feed.component.html @@ -49,7 +49,10 @@ infinite-scroll
- +
+ + +
\ No newline at end of file diff --git a/src/app/components/feed/feed.component.ts b/src/app/components/feed/feed.component.ts index 71d542c..d09566c 100644 --- a/src/app/components/feed/feed.component.ts +++ b/src/app/components/feed/feed.component.ts @@ -12,7 +12,8 @@ import { User } from 'src/app/models/user'; styleUrls: ['./feed.component.sass'] }) export class FeedComponent implements OnInit { - loading = true; + loadingNew = true; + loadingMostLiked = true; checked = false; // if the "I protected the environment."-box is checked view = 'new'; @@ -48,6 +49,13 @@ export class FeedComponent implements OnInit { } this.parentSelectedPostList = response; }); + this.feedService.newPostsAvailable.subscribe(response => { + this.loadingNew = response; + }); + this.feedService.topPostsAvailable.subscribe(response => { + console.log(response); + this.loadingMostLiked = response; + }); } createPost(pElement, activityId: string) { @@ -74,6 +82,7 @@ export class FeedComponent implements OnInit { } showMostLiked() { + this.view = 'mostLiked'; this.feedService.getPosts('TOP'); } } diff --git a/src/app/services/feed/feed.service.ts b/src/app/services/feed/feed.service.ts index aa776de..45f8c85 100644 --- a/src/app/services/feed/feed.service.ts +++ b/src/app/services/feed/feed.service.ts @@ -12,6 +12,8 @@ import { User } from 'src/app/models/user'; }) export class FeedService { + public newPostsAvailable = new BehaviorSubject(true); + public topPostsAvailable = new BehaviorSubject(true); public posts: BehaviorSubject = new BehaviorSubject(new Array()); public newPosts: BehaviorSubject = new BehaviorSubject(new Array()); public mostLikedPosts: BehaviorSubject = new BehaviorSubject(new Array()); @@ -153,7 +155,7 @@ export class FeedService { } public getNextPosts() { - if (this.activePostList === 'NEW') { + if (this.activePostList === 'NEW' && this.newPostsAvailable) { this.newOffset += 10; const headers = new Headers(); headers.set('Content-Type', 'application/json'); @@ -161,10 +163,13 @@ export class FeedService { .subscribe(response => { let updatedposts = this.newPosts.getValue(); updatedposts = updatedposts.concat(this.renderAllPosts(response.json())); + if (this.renderAllPosts(response.json()).length < 1) { + this.newPostsAvailable.next(false); + } this.newPosts.next(updatedposts); this.setPost('NEW'); }); - } else if (this.activePostList === 'TOP') { + } else if (this.activePostList === 'TOP' && this.topPostsAvailable) { this.mostLikedOffset += 10; const headers = new Headers(); headers.set('Content-Type', 'application/json'); @@ -172,6 +177,9 @@ export class FeedService { .subscribe(response => { let updatedposts = this.mostLikedPosts.getValue(); updatedposts = updatedposts.concat(this.renderAllPosts(response.json())); + if (this.renderAllPosts(response.json()).length < 1) { + this.topPostsAvailable.next(false); + } this.mostLikedPosts.next(updatedposts); this.setPost('TOP'); }); From f8ad256a8f5983efc90c3b79289785423b155386 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 14 Jan 2020 20:46:24 +0100 Subject: [PATCH 09/19] Fix most liked button --- src/app/components/feed/feed.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/components/feed/feed.component.ts b/src/app/components/feed/feed.component.ts index d09566c..64efd5d 100644 --- a/src/app/components/feed/feed.component.ts +++ b/src/app/components/feed/feed.component.ts @@ -82,7 +82,6 @@ export class FeedComponent implements OnInit { } showMostLiked() { - this.view = 'mostLiked'; this.feedService.getPosts('TOP'); } } From 8218dd3e384f245397ec31b6d444fb118916005d Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 14 Jan 2020 21:16:35 +0100 Subject: [PATCH 10/19] fixes: #138 --- src/app/components/feed/feed.component.html | 2 +- .../main-navigation.component.html | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/app/components/feed/feed.component.html b/src/app/components/feed/feed.component.html index f8e49a9..8dd1575 100644 --- a/src/app/components/feed/feed.component.html +++ b/src/app/components/feed/feed.component.html @@ -49,7 +49,7 @@ infinite-scroll
-
+
diff --git a/src/app/components/main-navigation/main-navigation.component.html b/src/app/components/main-navigation/main-navigation.component.html index 1936530..586c6d4 100644 --- a/src/app/components/main-navigation/main-navigation.component.html +++ b/src/app/components/main-navigation/main-navigation.component.html @@ -41,18 +41,18 @@ Greenvironment From 02b06f4f6f5af4070a6733aef1b09945b510e38a Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 15 Jan 2020 15:32:19 +0100 Subject: [PATCH 11/19] Add profile hover animation --- src/app/components/group/group.component.sass | 2 + .../components/profile/profile.component.html | 7 +++- .../components/profile/profile.component.sass | 40 ++++++++++++++----- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/app/components/group/group.component.sass b/src/app/components/group/group.component.sass index 34fa7d0..0de5d38 100644 --- a/src/app/components/group/group.component.sass +++ b/src/app/components/group/group.component.sass @@ -49,6 +49,8 @@ $mat-card-header-size: 100px !default border-radius: 50% flex-shrink: 0 background-size: cover + &:hover + height: 200 // Makes `` tags behave like `background-size: cover`. Not supported // in IE, but we're using it as a progressive enhancement. object-fit: cover diff --git a/src/app/components/profile/profile.component.html b/src/app/components/profile/profile.component.html index 7dad600..892cc83 100644 --- a/src/app/components/profile/profile.component.html +++ b/src/app/components/profile/profile.component.html @@ -3,7 +3,12 @@ -
+
+ + camera_alt +
+ + {{userProfile.username}} - - - -
+ + + +
{{post.author.name}} diff --git a/src/app/components/feed/postlist/postlist.component.sass b/src/app/components/feed/postlist/postlist.component.sass index fd49ccb..431c00e 100644 --- a/src/app/components/feed/postlist/postlist.component.sass +++ b/src/app/components/feed/postlist/postlist.component.sass @@ -8,7 +8,7 @@ outline: none user-select: none ::ng-deep .mat-card-header-text - margin: 0px + margin-top: 10px .mat-card-subtitle display: contents a:hover @@ -31,4 +31,13 @@ .span margin-left: 32px - +$mat-card-header-size: 100px !default +.profile-picture + height: $mat-card-header-size + width: $mat-card-header-size + border-radius: 50% + flex-shrink: 0 + background-size: cover + transition-duration: 0.5s + z-index: 10 + object-fit: cover diff --git a/src/app/models/author.ts b/src/app/models/author.ts index 3fa8e67..cc5f07a 100644 --- a/src/app/models/author.ts +++ b/src/app/models/author.ts @@ -2,10 +2,12 @@ export class Author { id: number; name: string; handle: string; + profilePicture: string; - constructor(pId: number, pName: string, pHandle: string) { + constructor(pId: number, pName: string, pHandle: string, pic: string) { this.id = pId; this.name = pName; this.handle = pHandle; + this.profilePicture = pic; } } diff --git a/src/app/services/feed/feed.service.ts b/src/app/services/feed/feed.service.ts index 45f8c85..1f39cdc 100644 --- a/src/app/services/feed/feed.service.ts +++ b/src/app/services/feed/feed.service.ts @@ -45,6 +45,7 @@ export class FeedService { author{ name, handle, + profilePicture, id}, createdAt} }`, variables: { @@ -80,6 +81,7 @@ export class FeedService { author{ name, handle, + profilePicture, id}, createdAt} }`, variables: { @@ -214,6 +216,7 @@ export class FeedService { author{ name, handle, + profilePicture, id}, createdAt} }`, variables: { @@ -232,7 +235,13 @@ export class FeedService { const downvotes: number = post.downvotes; const userVote: string = post.userVote; const deletable: boolean = post.deletable; - const author = new Author(post.author.id, post.author.name, post.author.handle); + let profilePicture: string; + if (post.author.profilePicture) { + profilePicture = environment.greenvironmentUrl + post.author.profilePicture; + } else { + profilePicture = 'assets/images/account_circle-24px.svg'; + } + const author = new Author(post.author.id, post.author.name, post.author.handle, profilePicture); const temp = new Date(Number(post.createdAt)); const date = temp.toLocaleString('en-GB'); let activity: Activity; @@ -258,7 +267,13 @@ export class FeedService { const downvotes: number = post.downvotes; const userVote: string = post.userVote; const deletable: boolean = post.deletable; - const author = new Author(post.author.id, post.author.name, post.author.handle); + let profilePicture: string; + if (post.author.profilePicture) { + profilePicture = environment.greenvironmentUrl + post.author.profilePicture; + } else { + profilePicture = 'assets/images/account_circle-24px.svg'; + } + const author = new Author(post.author.id, post.author.name, post.author.handle, profilePicture); const temp = new Date(Number(post.createdAt)); const date = temp.toLocaleString('en-GB'); let activity: Activity; diff --git a/src/app/services/profile/profile.service.ts b/src/app/services/profile/profile.service.ts index 67069a7..1a28185 100644 --- a/src/app/services/profile/profile.service.ts +++ b/src/app/services/profile/profile.service.ts @@ -59,6 +59,7 @@ export class ProfileService { author{ name, handle, + profilePicture id}, createdAt } @@ -97,7 +98,13 @@ export class ProfileService { const downvotes: number = post.downvotes; const userVote: string = post.userVote; const deletable: boolean = post.deletable; - const author = new Author(post.author.id, post.author.name, post.author.handle); + let profilePicture: string; + if (post.author.profilePicture) { + profilePicture = environment.greenvironmentUrl + post.author.profilePicture; + } else { + profilePicture = 'assets/images/account_circle-24px.svg'; + } + const author = new Author(post.author.id, post.author.name, post.author.handle, profilePicture); const ptemp = new Date(Number(post.createdAt)); const pdate = ptemp.toLocaleString('en-GB'); let activity: Activity;