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

master
Trivernis 5 years ago committed by Gitea
commit 1964aae1ea

@ -12,31 +12,12 @@ export class AppComponent implements OnInit {
constructor(private data: DatasharingService, private selfservice: SelfService) { }
userInfo: User;
loggedIn = false;
userID: number;
username: string;
handle: string;
email: string;
points: number;
level: number;
friendIDs: number[];
groupIDs: number[];
chatIDs: number[];
requestIDs: number[];
ngOnInit() {
this.data.currentUserInfo.subscribe(user => {
this.userInfo = user;
console.log(this.userInfo);
this.data.changeChatIDs(user.chatIDs);
if (user.loggedIn !== true) {
this.selfservice.checkIfLoggedIn();
}
});
if (this.loggedIn !== true) {
this.selfservice.checkIfLoggedIn();
}
}
}

@ -23,6 +23,7 @@ import { PostlistComponent } from './components/feed/postlist/postlist.component
import { GraphQLModule } from './graphql.module';
import { HttpClientModule } from '@angular/common/http';
import { ProfileComponent } from './components/profile/profile.component';
import { GroupComponent } from './components/group/group.component';
import { ImprintComponent } from './components/imprint/imprint.component';
import { AboutComponent } from './components/about/about.component';
import { ChatcontactsComponent } from './components/chatmanager/chatcontacts/chatcontacts.component';
@ -58,6 +59,8 @@ import { SearchComponent } from './components/search/search.component';
import {DomSanitizer} from '@angular/platform-browser';
import {MatIconRegistry} from '@angular/material/icon';
import {MatDialogModule} from '@angular/material/dialog';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatExpansionModule} from '@angular/material/expansion';
// import logo from 'src/assets/gv-new-logo.svg';
import logo from '!!raw-loader!./gv-new-logo-white.svg';
@ -68,6 +71,7 @@ const config: SocketIoConfig = { url: 'http://localhost:4444', options: {} };
const appRoutes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'profile/:id', component: ProfileComponent },
{ path: 'group/:id', component: GroupComponent },
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'about', component: AboutComponent },
@ -96,7 +100,8 @@ const appRoutes: Routes = [
ProfileComponent,
MainNavigationComponent,
SearchComponent,
DialogCreateGroupComponent
DialogCreateGroupComponent,
GroupComponent
],
imports: [
BrowserModule,
@ -134,6 +139,8 @@ const appRoutes: Routes = [
MatBadgeModule,
MatProgressSpinnerModule,
MatDialogModule,
MatTooltipModule,
MatExpansionModule
],
entryComponents: [ DialogCreateGroupComponent ],
providers: [],

@ -43,7 +43,6 @@ export class FeedComponent implements OnInit {
this.feedNew = this.feedService.renderAllPosts(response.json());
this.parentSelectedPostList = this.feedNew;
this.feedMostLiked = this.feedNew;
console.log(this.feedNew);
});
} else {
this.feedService.getAllPostsRaw().subscribe(response => {
@ -51,10 +50,8 @@ export class FeedComponent implements OnInit {
this.feedNew = this.feedService.renderAllPosts(response.json());
this.parentSelectedPostList = this.feedNew;
this.feedMostLiked = this.feedNew;
console.log(this.feedNew);
});
}
}
});
}
@ -69,7 +66,6 @@ export class FeedComponent implements OnInit {
}
showNew() {
console.log('showNew()');
this.feedService.getAllPostsRawByUserId(this.userId).subscribe(response => {
this.feedNew = this.feedService.renderAllPosts(response.json());
this.parentSelectedPostList = this.feedNew; });
@ -78,7 +74,6 @@ export class FeedComponent implements OnInit {
}
showMostLiked() {
console.log('showMostLiked()');
this.feedService.getAllPostsRawByUserId(this.userId).subscribe(response => {
this.feedMostLiked = this.feedService.renderAllPosts(response.json());
this.parentSelectedPostList = this.feedMostLiked; });
@ -90,7 +85,6 @@ export class FeedComponent implements OnInit {
refresh($event) {
this.feedService.getAllPostsRawByUserId(this.userId).subscribe(response => {
this.parentSelectedPostList = this.feedService.renderAllPosts(response.json());
console.log('Refresh');
});
}

@ -27,7 +27,7 @@
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item (click)="deletePost(post)">
<span>delete Post</span>
<span>delete post</span>
</button>
</mat-menu>
</div>
@ -46,12 +46,12 @@
<p [innerHTML]="post.htmlContent"></p>
</mat-card-content>
<mat-card-actions>
<button mat-button (click)="voteUp(post)">
<button mat-button (click)="voteUp(post)" matTooltip="vote up" matTooltipShowDelay="500">
<mat-icon aria-hidden="false" color="primary" *ngIf="post.userVote == 'UPVOTE'">keyboard_arrow_up</mat-icon>
<mat-icon aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'DOWNVOTE'">keyboard_arrow_up</mat-icon>
</button>
{{post.upvotes}}
<button mat-button (click)="voteDown(post)">
<button mat-button (click)="voteDown(post)" matTooltip="vote down" matTooltipShowDelay="500">
<mat-icon aria-hidden="false" color="primary" *ngIf="post.userVote == 'DOWNVOTE'">keyboard_arrow_down</mat-icon>
<mat-icon aria-hidden="false" *ngIf="!post.userVote || post.userVote == 'UPVOTE'">keyboard_arrow_down</mat-icon>
</button>

@ -5,10 +5,10 @@
box-sizing: border-box
width: 100%
margin-top: 0.5em
outline: none
user-select: none
::ng-deep .mat-card-header-text
margin: 0px
.mat-card-header
.mat-card-subtitle
display: contents
a:hover
@ -16,4 +16,9 @@
#button-box
text-align: right
margin-left: auto
::ng-deep img
max-width: 100%
height: auto
border-radius: 4px

@ -0,0 +1,28 @@
<div id="profile-page">
<div id="profilecontainer" *ngIf="!groupNotFound && !loading">
<mat-toolbar color="primary" id="toolbar">
<mat-toolbar-row>
<div class="profile-picture"></div>
<span id="username">{{groupProfile.name}}</span>
<span id="handle">created by {{groupProfile.creator.username}} @{{groupProfile.creator.handle}}</span>
<button mat-icon-button
class="request-button"
(click)="joinGroup(groupProfile)"
[disabled]="!groupProfile.allowedToJoinGroup">
<mat-icon>group_add</mat-icon>
</button>
</mat-toolbar-row>
<mat-toolbar-row>
<div id="info-box">
<span class="info">{{groupProfile.members.length}} member(s)</span>
</div>
</mat-toolbar-row>
</mat-toolbar>
</div>
<div id="profilecontainer" *ngIf="groupNotFound">
<h1>Group not found :(</h1>
</div>
<mat-spinner *ngIf="loading" style="margin:0 auto; margin-top: 10em;" diameter="100"></mat-spinner>
</div>

@ -0,0 +1,65 @@
@import '../../../styles/mixins.sass'
@import '../../../styles/vars.sass'
#profile-page
position: fixed
width: 100%
height: calc(100% - 56px)
overflow: scroll
#profile
padding: 2em
max-width: 1200px
margin: 0 auto
#profile-card-container
margin: 0 auto
width: 100%
max-width: 690px
.icon-box
text-align: right
width: 100%
.request-button
margin-top: 0.5em
margin-bottom: 0.5em
margin-left: auto
#toolbar
margin-top: 32px
.mat-toolbar-row
max-height: 40px
#info-box
font-size: 14px
margin-left: calc(100px + 0.5em)
.info
margin-right: 3em
#username
margin: 0 0.5em
#handle
font-size: 14px
.mat-table
width: 100%
max-width: 690px
margin: 0 auto
.mat-header-cell
padding-right: 0.5em
$mat-card-header-size: 100px !default
.profile-picture
background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg)
height: $mat-card-header-size
width: $mat-card-header-size
border-radius: 50%
flex-shrink: 0
background-size: cover
// Makes `<img>` tags behave like `background-size: cover`. Not supported
// in IE, but we're using it as a progressive enhancement.
object-fit: cover
#postlist
margin: 0.5em auto
padding: 0
max-width: 690px

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { GroupComponent } from './group.component';
describe('GroupComponent', () => {
let component: GroupComponent;
let fixture: ComponentFixture<GroupComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ GroupComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(GroupComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,64 @@
import { Component, OnInit, ViewChild} from '@angular/core';
import {Router, NavigationEnd} from '@angular/router';
import { User } from 'src/app/models/user';
import {MatSort} from '@angular/material/sort';
import { RequestService } from 'src/app/services/request/request.service';
import { DatasharingService } from '../../services/datasharing.service';
import { GroupService } from 'src/app/services/group/group.service';
import { Group } from 'src/app/models/group';
@Component({
selector: 'app-profile',
templateUrl: './group.component.html',
styleUrls: ['./group.component.sass']
})
export class GroupComponent implements OnInit {
groupProfile: Group = new Group();
self: User;
id: string;
groupNotFound = false;
loading = false;
constructor(
private router: Router,
private requestService: RequestService,
private data: DatasharingService,
private groupService: GroupService) {
router.events.forEach((event) => {
// check if url changes
if (event instanceof NavigationEnd) {
const possibleID = this.router.url.substr(this.router.url.lastIndexOf('/') + 1);
if (this.id !== possibleID && this.id && this.router.url.includes('group/')) {
// reload the group
console.log('search for group id: ' + this.router.url.substr(this.router.url.lastIndexOf('/') + 1));
this.ngOnInit();
}
}
});
}
@ViewChild(MatSort, {static: true}) sort: MatSort;
ngOnInit() {
this.loading = true;
this.id = this.router.url.substr(this.router.url.lastIndexOf('/') + 1);
this.data.currentUserInfo.subscribe(user => {
this.self = user;
});
this.groupService.getGroupData(this.id);
this.groupService.group.subscribe(response => {
if (response) {
this.groupProfile = response;
// tslint:disable-next-line:max-line-length
this.groupProfile.allowedToJoinGroup = this.requestService.isAllowedToJoinGroup(this.groupProfile.id, this.self);
} else { this.groupNotFound = true; }
this.loading = false;
});
}
public joinGroup(group: Group) {
group.allowedToJoinGroup = false;
this.requestService.joinGroup(group);
}
}

@ -26,19 +26,15 @@ export class LoginComponent implements OnInit {
}
public loginError(error: any) {
console.log(error.errors[0].message);
this.errorOccurred = true;
this.errorMessage = error.errors[0].message;
}
onClickSubmit(pEmail: string, pPasswordHash: string) {
console.log('try to login with mail adress:' + pEmail);
this.errorOccurred = false;
this.errorMessage = ' ';
this.login.email = pEmail.trim().toLowerCase();
this.login.passwordHash = sha512.sha512(pPasswordHash);
console.log(this.login.email);
this.loginService.login(this.login, error => this.loginError(error.json()));
}

@ -38,8 +38,8 @@
fxShow="true" fxHide.gt-sm="true">
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
</button>
<mat-icon svgIcon="logo" style="min-width: 35px;"></mat-icon>
<span>Greenvironment</span>
<mat-icon svgIcon="logo" style="min-width: 35px;" routerLink="" class="link"></mat-icon>
<span routerLink="" class="link">Greenvironment</span>
<nav mat-tab-nav-bar backgroundColor="primary" fxShow="true" fxHide.lt-md="true" routerLinkActive #rla="">
<div [hidden]="!loggedIn">
<a mat-tab-link class="link"

@ -4,6 +4,12 @@
.sidenav
width: 200px
.link
user-select: none
cursor: pointer
outline: none
.sidenav .mat-toolbar
//background: inherit

@ -65,7 +65,8 @@ export class MainNavigationComponent implements OnInit {
if (this.user.darkmode === true && this.lighttheme) {
this.toggleTheme();
this.darkModeButtonChecked = true;
} else if (!this.user.darkmode && !this.lighttheme) {
// IF user activated darkmode and logged in after that
} else if (this.user.loggedIn && !this.user.darkmode && !this.lighttheme) {
this.settingsService.setDarkModeActive(true);
}
this.updateLinks();

@ -1,115 +1,90 @@
<div id="profile-page">
<mat-toolbar color="primary">Profile</mat-toolbar>
<div id="profile">
<div id="profilecontainer" [hidden]="profileNotFound">
<div id="profile-card-container">
<mat-card class="mat-elevation-z8">
<mat-card-header>
<div mat-card-avatar class="profile-picture"></div>
<mat-card-title>{{userProfile.username}}</mat-card-title>
<mat-card-subtitle>{{userProfile.handle}}</mat-card-subtitle>
<div class="icon-box">
<button mat-icon-button
class="request-button"
(click)="sendFriendRequest(userProfile)"
[disabled]="!userProfile.allowedToSendRequest">
<mat-icon>person_add</mat-icon>
</button>
</div>
</mat-card-header>
<mat-card-content>
<table id="profile-table">
<tr>
<div class="mat-header-cell">name: </div>
<td>{{userProfile.username}}</td>
</tr>
<mat-divider></mat-divider>
<tr>
<div class="mat-header-cell">handle: </div>
<td>{{userProfile.handle}}</td>
</tr>
<mat-divider></mat-divider>
<tr>
<div class="mat-header-cell">profileID: </div>
<td>{{userProfile.userID}}</td>
</tr>
<mat-divider></mat-divider>
<tr>
<div class="mat-header-cell">points: </div>
<td>{{userProfile.points}}</td>
</tr>
<mat-divider></mat-divider>
<tr>
<div class="mat-header-cell">level: </div>
<td>{{userProfile.level}}</td>
</tr>
<mat-divider></mat-divider>
<tr>
<div class="mat-header-cell">level name: </div>
<td>{{rankname}}</td>
</tr>
</table>
</mat-card-content>
</mat-card>
</div>
<br>
<h1>What does the level mean?</h1>
<p>There are different levels you can reach through green behaviour.
Collect 100 points to level up! The levels are called:
</p>
<table mat-table [dataSource]="levelSource" class="mat-elevation-z8">
<ng-container matColumnDef="level">
<th mat-header-cell *matHeaderCellDef> level </th>
<td mat-cell *matCellDef="let level"> {{level.level}} </td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> level name </th>
<td mat-cell *matCellDef="let level"> {{level.name}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedLevelColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedLevelColumns;"></tr>
</table>
<div id="profilecontainer" *ngIf="!profileNotFound && !loading">
<mat-toolbar color="primary" id="toolbar">
<mat-toolbar-row>
<div class="profile-picture"></div>
<span id="username">{{userProfile.username}}</span>
<span id="handle">@{{userProfile.handle}}</span>
<button mat-icon-button
class="request-button"
(click)="sendFriendRequest(userProfile)"
[disabled]="!userProfile.allowedToSendRequest">
<mat-icon>person_add</mat-icon>
</button>
</mat-toolbar-row>
<mat-toolbar-row>
<div id="info-box">
<span class="info">{{rankname}} ({{userProfile.points}} points)</span>
<span class="info">{{userProfile.friendCount}} friends</span>
<span class="info">{{userProfile.groupCount}} groups</span>
<span class="info">joined on {{userProfile.joinedAt}}</span>
</div>
</mat-toolbar-row>
</mat-toolbar>
<div id="postlist">
<feed-postlist [childPostList]="this.userProfile.posts"></feed-postlist>
</div>
<div id="profile">
<br>
<h1>How to level up?</h1>
<p>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:
</p>
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<h1>What does the level mean?</h1>
<p>There are different levels you can reach through green behaviour.
Collect 100 points to level up! The levels are called:
</p>
<table mat-table [dataSource]="levelSource" class="mat-elevation-z8">
<ng-container matColumnDef="level">
<th mat-header-cell *matHeaderCellDef> level </th>
<td mat-cell *matCellDef="let level"> {{level.level}} </td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> level name </th>
<td mat-cell *matCellDef="let level"> {{level.name}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedLevelColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedLevelColumns;"></tr>
</table>
<br>
<h1>How to level up?</h1>
<p>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:
</p>
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<!-- Position Column -->
<ng-container matColumnDef="points">
<th mat-header-cell *matHeaderCellDef mat-sort-header> points </th>
<td mat-cell *matCellDef="let action"> {{action.points}} </td>
</ng-container>
<!-- Position Column -->
<ng-container matColumnDef="points">
<th mat-header-cell *matHeaderCellDef mat-sort-header> points </th>
<td mat-cell *matCellDef="let action"> {{action.points}} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> action </th>
<td mat-cell *matCellDef="let action"> {{action.name}} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> action </th>
<td mat-cell *matCellDef="let action"> {{action.name}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<!--<table style="width:100%">
<tr>
<th>points </th>
<th>action</th>
</tr>
<tr *ngFor= "let action of actionlist.actions">
<td>{{action.points}}</td>
<td>{{action.name}}</td>
</tr>
</table>-->
</div>
<div id="profilecontainer" *ngIf="profileNotFound">
<h1>Profile not found :(</h1>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<!--<table style="width:100%">
<tr>
<th>points </th>
<th>action</th>
</tr>
<tr *ngFor= "let action of actionlist.actions">
<td>{{action.points}}</td>
<td>{{action.name}}</td>
</tr>
</table>-->
</div>
</div>
<div id="profilecontainer" *ngIf="profileNotFound">
<h1>Profile not found :(</h1>
</div>
<mat-spinner *ngIf="loading" style="margin:0 auto; margin-top: 10em;" diameter="100"></mat-spinner>
</div>

@ -19,9 +19,24 @@
.icon-box
text-align: right
width: 100%
.request-button
margin-top: 0.5em
margin-bottom: 0.5em
.request-button
margin-top: 0.5em
margin-bottom: 0.5em
margin-left: auto
#toolbar
margin-top: 32px
.mat-toolbar-row
max-height: 40px
#info-box
font-size: 14px
margin-left: calc(100px + 0.5em)
.info
margin-right: 3em
#username
margin: 0 0.5em
#handle
font-size: 14px
.mat-table
width: 100%
@ -30,21 +45,21 @@
.mat-header-cell
padding-right: 0.5em
$mat-card-header-size: 100px !default
.profile-picture
background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg)
height: $mat-card-header-size
width: $mat-card-header-size
border-radius: 50%
flex-shrink: 0
background-size: cover
// Makes `<img>` tags behave like `background-size: cover`. Not supported
// in IE, but we're using it as a progressive enhancement.
object-fit: cover
#profile-table
width: 100%
.mat-table
display: block
.mat-cell,
.mat-header-cell
align-items: center
display: flex
min-height: 48px
padding: 0
flex: 1
overflow: hidden
word-wrap: break-word
#postlist
margin: 0.5em auto
padding: 0
max-width: 690px

@ -1,14 +1,13 @@
import { Component, OnInit, ViewChild} from '@angular/core';
import {Router, NavigationEnd} from '@angular/router';
import {Http, URLSearchParams, Headers} from '@angular/http';
import { User } from 'src/app/models/user';
import { Actionlist } from 'src/app/models/actionlist';
import { Levellist } from 'src/app/models/levellist';
import { environment } from 'src/environments/environment';
import {MatSort} from '@angular/material/sort';
import {MatTableDataSource} from '@angular/material/table';
import { RequestService } from 'src/app/services/request/request.service';
import { DatasharingService } from '../../services/datasharing.service';
import { ProfileService } from 'src/app/services/profile/profile.service';
@Component({
selector: 'app-profile',
@ -30,15 +29,18 @@ export class ProfileComponent implements OnInit {
displayedLevelColumns = ['level', 'name'];
levelSource = this.levellist.levels;
loading = false;
constructor(
private router: Router,
private http: Http,
private requestService: RequestService,
private data: DatasharingService) {
private data: DatasharingService,
private profileService: ProfileService) {
router.events.forEach((event) => {
// check if the user is on the profile page (of userY) and routes to the page of userY (e.g. his own page)
if (event instanceof NavigationEnd) {
if (this.id !== this.router.url.substr(this.router.url.lastIndexOf('/') + 1) && this.id) {
const possibleID = this.router.url.substr(this.router.url.lastIndexOf('/') + 1);
if (this.id !== possibleID && this.id && this.router.url.includes('profile/')) {
// reload the user
this.ngOnInit();
}
@ -48,65 +50,30 @@ export class ProfileComponent implements OnInit {
@ViewChild(MatSort, {static: true}) sort: MatSort;
ngOnInit() {
this.loading = true;
this.dataSource.sort = this.sort;
this.id = this.router.url.substr(this.router.url.lastIndexOf('/') + 1);
// let url = './graphql'
const url = environment.graphQLUrl;
const headers = new Headers();
headers.set('Content-Type', 'application/json');
this.http.post(url, this.buildJson(this.id))
.subscribe(response => {
console.log(response.text());
this.updateUserInfo(response.json());
});
this.data.currentUserInfo.subscribe(user => {
this.self = user;
});
}
public updateUserInfo(response: any) {
if (response.data.getUser != null) {
this.profileNotFound = false;
this.userProfile.loggedIn = true;
this.userProfile.userID = response.data.getUser.id;
this.userProfile.username = response.data.getUser.name;
this.userProfile.handle = response.data.getUser.handle;
this.userProfile.points = response.data.getUser.points;
this.userProfile.level = response.data.getUser.level;
this.rankname = this.levellist.getLevelName(this.userProfile.level);
// tslint:disable-next-line:max-line-length
this.userProfile.allowedToSendRequest = this.requestService.isAllowedToSendRequest(response.data.getUser.id, this.self);
this.data.currentUserInfo.subscribe(user => {
this.self = user;
});
if (this.self.loggedIn) {
this.profileService.getUserDataBySelfId(this.id, this.self.userID.toString());
} else {
this.profileNotFound = true;
this.profileService.getUserData(this.id);
}
this.profileService.proflile.subscribe(response => {
if (response) {
this.userProfile = response;
// tslint:disable-next-line:max-line-length
this.userProfile.allowedToSendRequest = this.requestService.isAllowedToSendRequest(this.userProfile.userID, this.self);
this.rankname = this.levellist.getLevelName(this.userProfile.level);
} else { this.profileNotFound = true; }
this.loading = false;
});
}
public sendFriendRequest(user: User) {
user.allowedToSendRequest = false;
this.requestService.sendFriendRequest(user);
}
public buildJson(id: string): any {
const body = {query: `query($userId: ID) {
getUser(userId:$userId){
id
handle
name
profilePicture
points
level
friendCount
friends{
id
}
posts{
content
}
}
}`, variables: {
userId: this.id
}};
return body;
}
}

@ -10,21 +10,16 @@
<mat-icon>search </mat-icon>
</button>
</mat-form-field>
<!--<mat-form-field id="category-chooser">
<mat-label>category</mat-label>
<mat-select value="user" #field (selectionChange)="changeCategory($event.value)">
<mat-option value="user">user</mat-option>
<mat-option value="group" disabled>group</mat-option>
</mat-select>
</mat-form-field>-->
</mat-toolbar>
<div id="friendlist">
<!--<div class="frienditem" *ngFor="let friend of friends"
[class.selected]="friend === selectedFriend" (click)="showFriendProfile(friend)">
<div class="picture">Pic</div>
<div class="name"><span>{{friend.name}}</span></div>
</div>-->
<mat-card class="friend-card" *ngFor="let user of foundUsers"
<mat-accordion>
<mat-expansion-panel *ngIf="foundUsers.length > 0" expanded>
<mat-expansion-panel-header>
<mat-panel-title>
Users
</mat-panel-title>
</mat-expansion-panel-header>
<div class="list">
<mat-card class="card" *ngFor="let user of foundUsers"
[class.selected]="user === selectedUser"
tabindex="0">
<mat-card-header>
@ -36,7 +31,28 @@
</div>
</mat-card-header>
</mat-card>
<mat-spinner *ngIf="loading" style="margin:0 auto; margin-top: 5em;" diameter="50"></mat-spinner>
</div>
</div>
</mat-expansion-panel>
<mat-expansion-panel *ngIf="foundGroups.length > 0" [expanded]="foundUsers.length < 1">
<mat-expansion-panel-header>
<mat-panel-title>
Groups
</mat-panel-title>
</mat-expansion-panel-header>
<div class="list">
<mat-card class="card" *ngFor="let group of foundGroups"
[class.selected]="group === selectedGroup"
tabindex="0">
<mat-card-header>
<div mat-card-avatar class="profile-picture" (click)="showGroupProfile(group)"></div>
<mat-card-title class="pointer" (click)="showGroupProfile(group)">{{group.name}}</mat-card-title>
<div class="icon-box">
<button mat-icon-button class="request-button" (click)="joinGroup(group)" [disabled]="!group.allowedToJoinGroup"><mat-icon>group_add</mat-icon></button>
</div>
</mat-card-header>
</mat-card>
</div>
</mat-expansion-panel>
</mat-accordion>
<mat-spinner *ngIf="loading" style="margin:0 auto; margin-top: 5em;" diameter="50"></mat-spinner>
</div>

@ -13,13 +13,15 @@
padding-left: 0.5em
padding-right: 0.5em
#friendlist
#list
padding: 0.5em
.friend-card
.card
box-sizing: border-box
width: 100%
margin-top: 0.5em
outline: none
user-select: none
/deep/ .mat-card-header-text
width: 1000%
margin: 0
@ -46,3 +48,9 @@
.icon-box
text-align: right
width: 100%
/deep/ .mat-expansion-panel
background: #e6e6e6
/deep/.dark-theme .mat-expansion-panel
background: #121212

@ -6,6 +6,7 @@ import { User } from 'src/app/models/user';
import {environment} from 'src/environments/environment';
import { Router } from '@angular/router';
import { DatasharingService } from '../../services/datasharing.service';
import { GroupInfo } from 'src/app/models/groupinfo';
@Component({
selector: 'home-search',
@ -17,7 +18,8 @@ export class SearchComponent implements OnInit {
searchValue = ' ';
category = 'user';
user: User;
foundUsers: Array<User>;
foundUsers: Array<User> = new Array();
foundGroups: Array<GroupInfo> = new Array();
constructor(
private searchService: SearchService,
@ -56,9 +58,13 @@ export class SearchComponent implements OnInit {
this.http.post(environment.graphQLUrl, this.searchService.buildJsonUser(name))
.subscribe(response => {
this.foundUsers = this.searchService.renderUsers(response.json());
this.foundGroups = this.searchService.renderGroups(response.json());
for (const foundUser of this.foundUsers) {
foundUser.allowedToSendRequest = this.requestService.isAllowedToSendRequest(foundUser.userID, this.user);
}
for (const foundGroup of this.foundGroups) {
foundGroup.allowedToJoinGroup = this.requestService.isAllowedToJoinGroup(foundGroup.id, this.user);
}
this.loading = false;
});
}
@ -67,9 +73,18 @@ export class SearchComponent implements OnInit {
this.router.navigate(['profile/' + user.userID]);
}
public showGroupProfile(group: GroupInfo) {
this.router.navigate(['group/' + group.id]);
}
public sendFriendRequest(user: User) {
user.allowedToSendRequest = false;
this.requestService.sendFriendRequest(user);
}
public joinGroup(group: GroupInfo) {
group.allowedToJoinGroup = false;
this.requestService.joinGroup(group);
}
}

@ -1,6 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { DatasharingService } from 'src/app/services/datasharing.service';
import { Http } from '@angular/http';
import { FriendInfo } from 'src/app/models/friendinfo';
import { Router } from '@angular/router';
import { User } from 'src/app/models/user';

@ -1,13 +1,13 @@
<mat-toolbar>
<span>Groups</span>
<div id="button-box">
<button mat-icon-button (click)="openDialog()"><mat-icon>group_add</mat-icon></button>
<button mat-icon-button (click)="openDialog()" matTooltip="create group" matTooltipPosition="left" matTooltipShowDelay="500"><mat-icon>group_add</mat-icon></button>
</div>
</mat-toolbar>
<div id="grouplist">
<mat-card class="group-card" *ngFor="let group of user.groups"
[class.selected]="group === selectedGroup">
[class.selected]="group === selectedGroup" (click)="showGroupProfile(group)">
<mat-card-header>
<div mat-card-avatar class="group-picture"></div>
<mat-card-title>{{group.name}}</mat-card-title>

@ -9,6 +9,7 @@
box-sizing: border-box
width: 100%
margin-top: 0.5em
cursor: pointer
.mat-card-subtitle
margin: 0

@ -1,9 +1,10 @@
import { Component, Inject, OnInit } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { GroupInfo } from 'src/app/models/groupinfo';
import {MatDialog, MatDialogRef} from '@angular/material/dialog';
import { SocialService } from 'src/app/services/social/social.service';
import { User } from 'src/app/models/user';
import { DatasharingService } from 'src/app/services/datasharing.service';
import { Router } from '@angular/router';
// DIALOG COMPONENT to create groups
@Component({
@ -25,7 +26,7 @@ export class DialogCreateGroupComponent {
if (name) {
this.social.createGroup(name);
this.dialogRef.close();
}
}
}
}
@ -38,13 +39,17 @@ export class DialogCreateGroupComponent {
})
export class GroupsComponent implements OnInit {
user: User;
constructor(public dialog: MatDialog, private data: DatasharingService) { }
constructor(public dialog: MatDialog, private data: DatasharingService, private router: Router) { }
ngOnInit() {
this.data.currentUserInfo.subscribe(user => {
this.user = user; });
}
public showGroupProfile(group: GroupInfo) {
this.router.navigate(['group/' + group.id]);
}
openDialog(): void {
const dialogRef = this.dialog.open(DialogCreateGroupComponent, {
width: '250px'

@ -0,0 +1,11 @@
import { User } from 'src/app/models/user';
export class Group {
id: number;
name: string;
handle: string;
creator: User = new User();
members: User[] = new Array();
admins: User[] = new Array();
allowedToJoinGroup = false;
}

@ -1,6 +1,7 @@
export class GroupInfo {
id: number;
name: string;
allowedToJoinGroup = false;
constructor(pId: number, pName: string) {
this.id = pId;

@ -1,6 +1,7 @@
import { FriendRequest } from 'src/app/models/friendRequest';
import { FriendInfo } from 'src/app/models/friendinfo';
import { GroupInfo } from 'src/app/models/groupinfo';
import { Post } from 'src/app/models/post';
export class User {
loggedIn = false;
@ -11,11 +12,15 @@ export class User {
points: number;
level: number;
profilePicture: string;
joinedAt: string;
friendCount: number;
groupCount: number;
darkmode = false;
friends: FriendInfo[] = new Array();
groups: GroupInfo[] = new Array();
posts: Post[] = new Array();
chatIDs: number[];
receivedRequests: FriendRequest[] = new Array();
sentRequestUserIDs: number[] = new Array(); // IDs of users that already received requests of the logged in user

@ -22,7 +22,6 @@ export class ChatService {
}
public getAllChats(): Array<Chat> {
console.log('Getting all chats ..');
const url = environment.graphQLUrl;
const headers = new Headers();
@ -36,7 +35,6 @@ export class ChatService {
}
public getAllChatsRaw(): any {
console.log('Getting all chats ..');
const url = 'https://greenvironment.net/graphql';
const headers = new Headers();
@ -47,7 +45,6 @@ export class ChatService {
public getChatsByID(pChatIDs: number[]): Array<Chat> {
this.chats = [];
console.log('Getting chats by ID..');
for (const chatId of pChatIDs) {
const url = environment.graphQLUrl;
@ -64,7 +61,6 @@ export class ChatService {
}
public getChatsByIDRaw(pChatIDs: number[]): any {
console.log('Getting chats by ID..');
for (const chatId of pChatIDs) {
const url = 'https://greenvironment.net/graphql';
@ -140,7 +136,6 @@ export class ChatService {
headers.set('Content-Type', 'application/json');
this.http.post(url, this.getBodyForGetMessagesInChat(pChatID)).subscribe(response => {
console.log('Downloading messages ...');
messages = this.renderMessages(response.json());
});
return messages;

@ -15,7 +15,6 @@ export class DatasharingService {
constructor() { }
changeUserInfo(pUserInfo: User) {
console.log('DatasharingService: user info updated');
this.userInfoSource.next(pUserInfo);
}

@ -25,7 +25,7 @@ export class FeedService {
}};
this.http.post(url, body).subscribe(response => {
console.log(response.text()); });
});
}
public upvote(pPostID: number): any {
@ -80,7 +80,6 @@ export class FeedService {
this.http.post(url, this.getBodyForGetAllPosts())
.subscribe(response => {
this.posts = this.renderAllPosts(response.json());
console.log(response);
});
return this.posts;
}
@ -93,7 +92,6 @@ export class FeedService {
this.http.post(url, this.getBodyForGetAllPostsByUserId(userId))
.subscribe(response => {
this.posts = this.renderAllPosts(response.json());
console.log(response);
});
return this.posts;
}

@ -0,0 +1,12 @@
import { TestBed } from '@angular/core/testing';
import { GroupService } from './group.service';
describe('GroupService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
it('should be created', () => {
const service: GroupService = TestBed.get(GroupService);
expect(service).toBeTruthy();
});
});

@ -0,0 +1,75 @@
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
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 { Group } from 'src/app/models/group';
@Injectable({
providedIn: 'root'
})
export class GroupService {
public group: Subject<any> = new Subject();
constructor(private http: Http) { }
public getGroupData(groupId: string) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
this.http.post(environment.graphQLUrl, this.buildGetGroupJson(groupId)).subscribe(result => {
// push onto subject
this.group.next(this.renderGroup(result.json()));
return this.group;
});
}
public buildGetGroupJson(id: string): any {
const body = {
query: `query($groupId: ID!) {
getGroup(groupId:$groupId){
id
name
creator{id name handle}
admins{id name handle}
members{id name handle}
}
}`, variables: {
groupId: id
}
};
return body;
}
public renderGroup(response: any): Group {
const group = new Group();
const members: User[] = new Array();
const admins: User[] = new Array();
if (response.data.getGroup != null) {
group.id = response.data.getGroup.id;
group.name = response.data.getGroup.name;
group.creator.userID = response.data.getGroup.creator.id;
group.creator.handle = response.data.getGroup.creator.handle;
group.creator.username = response.data.getGroup.creator.name;
for (const member of response.data.getGroup.members) {
const user = new User();
user.userID = member.id;
user.username = member.name;
user.handle = member.handle;
members.push(user);
}
group.members = members;
for (const admin of response.data.getGroup.admins) {
const user = new User();
user.userID = admin.id;
user.username = admin.name;
user.handle = admin.handle;
admins.push(user);
}
group.admins = admins;
return group;
}
return null;
}
}

@ -24,7 +24,6 @@ export class LoginService {
return this.http.post(environment.graphQLUrl, this.buildJson(login))
.subscribe(response => {
console.log(response.text());
this.loginSuccess();
this.updateUserInfo(response.json());
}, errorCb
@ -32,7 +31,6 @@ export class LoginService {
}
public loginSuccess() {
console.log('alles supi dupi');
this.router.navigateByUrl('');
}
@ -50,7 +48,6 @@ export class LoginService {
user.friends.push(new FriendInfo(friend.id, friend.name, friend.level));
}
for (const group of response.data.login.groups) {
console.log(group.name);
user.groups.push(new GroupInfo(group.id, group.name));
}
user.chatIDs = response.data.login.chats;

@ -0,0 +1,12 @@
import { TestBed } from '@angular/core/testing';
import { ProfileService } from './profile.service';
describe('ProfileService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
it('should be created', () => {
const service: ProfileService = TestBed.get(ProfileService);
expect(service).toBeTruthy();
});
});

@ -0,0 +1,145 @@
import { Injectable } from '@angular/core';
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 { User } from 'src/app/models/user';
import { Observable, Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ProfileService {
public proflile: Subject<any> = new Subject();
constructor(private http: Http) { }
public getUserData(userId: string) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
// return this.renderProfile(this.http.post(environment.graphQLUrl, this.buildGetProfileJson(userId)));
this.http.post(environment.graphQLUrl, this.buildGetProfileJson(userId)).subscribe(result => {
// push onto subject
this.proflile.next(this.renderProfile(result.json()));
return this.proflile;
});
}
public getUserDataBySelfId(userId: string, selfId: string) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
// return this.renderProfile(this.http.post(environment.graphQLUrl, this.buildGetProfileJson(userId)));
this.http.post(environment.graphQLUrl, this.buildGetProfileJsonBySelfId(userId, selfId)).subscribe(result => {
// push onto subject
this.proflile.next(this.renderProfile(result.json()));
return this.proflile;
});
}
public buildGetProfileJson(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,
author{
name,
handle,
id},
createdAt
}
}
}`, variables: {
userId: id
}};
return body;
}
public buildGetProfileJsonBySelfId(id: string, selfId: string): any {
const body = {query: `query($userId: ID, $selfId: ID!) {
getUser(userId:$userId){
id
handle
name
profilePicture
points
level
friendCount
groupCount
joinedAt
friends{
id
}
posts{
id,
content,
htmlContent,
upvotes,
downvotes,
userVote(userId: $selfId),
deletable(userId: $selfId)
author{
name,
handle,
id},
createdAt
}
}
}`, variables: {
userId: id,
selfId: selfId
}};
return body;
}
public renderProfile(response: any): User {
const posts = new Array<Post>();
const profile = new User();
if (response.data.getUser != null) {
profile.userID = response.data.getUser.id;
profile.username = response.data.getUser.name;
profile.handle = response.data.getUser.handle;
profile.points = response.data.getUser.points;
profile.level = response.data.getUser.level;
profile.friendCount = response.data.getUser.friendCount;
profile.groupCount = response.data.getUser.groupCount;
const temp = new Date(Number(response.data.getUser.joinedAt));
const date = temp.toLocaleString('en-GB');
profile.joinedAt = date;
for (const post of response.data.getUser.posts) {
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 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));
}
profile.posts = posts;
return profile;
}
return null;
}
}

@ -4,6 +4,7 @@ import {DatasharingService} from '../datasharing.service';
import {Router} from '@angular/router';
import {environment} from 'src/environments/environment';
import { User } from 'src/app/models/user';
import { GroupInfo } from 'src/app/models/groupinfo';
@Injectable({
@ -36,6 +37,19 @@ export class RequestService {
return true;
}
public isAllowedToJoinGroup(groupId: number, self: User): boolean {
// returns false if user is not logged in or is member of the group(Id)
if (!self.loggedIn) {
return false;
}
for (const group of self.groups) {
if (group.id === groupId) {
return false;
}
}
return true;
}
public sendFriendRequest(user: User) {
this.data.addSentRequestUserID(user.userID);
const headers = new Headers();
@ -45,6 +59,14 @@ export class RequestService {
});
}
public joinGroup(group: GroupInfo) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
this.http.post(environment.graphQLUrl, this.buildJsonJoinGroup(group.id))
.subscribe(response => {
});
}
public buildJsonRequest(id_: number, type_: String): any {
const body = {
query: `mutation($id: ID!, $type: RequestType) {
@ -60,6 +82,20 @@ export class RequestService {
return body;
}
public buildJsonJoinGroup(id_: number): any {
const body = {
query: `mutation($id: ID!) {
joinGroup(id: $id) {
id
}
}`
, variables: {
id: id_
}
};
return body;
}
public buildJsonAcceptRequest(id_: number): any {
const body = {
query: `mutation($id: ID!) {

@ -4,6 +4,7 @@ import {DatasharingService} from '../datasharing.service';
import {Router} from '@angular/router';
import {environment} from 'src/environments/environment';
import { User } from 'src/app/models/user';
import { GroupInfo } from 'src/app/models/groupinfo';
@Injectable({
providedIn: 'root'
@ -30,6 +31,14 @@ export class SearchService {
return users;
}
public renderGroups(pResponse: any): Array<GroupInfo> {
const groups = new Array<GroupInfo>();
for (const group of pResponse.data.search.groups) {
groups.push(new GroupInfo(group.id, group.name));
}
return groups;
}
public buildJsonUser(name_: String): any {
const body = {
query: `query($name: String!) {
@ -45,6 +54,12 @@ export class SearchService {
id
}
}
groups{
id
name
creator{id name handle}
members{id name handle}
}
}
}`
, variables: {

@ -18,31 +18,24 @@ export class SelfService {
constructor(private http: Http, private data: DatasharingService, private router: Router) { }
public checkIfLoggedIn() {
console.log('check if logged in...');
const url = environment.graphQLUrl;
const headers = new Headers();
headers.set('Content-Type', 'application/json');
return this.http.post(url, this.buildJson())
.subscribe(response => {
console.log(response.text());
this.stillLoggedIn();
this.updateUserInfo(response.json());
}, error => {
this.notLoggedIn();
console.log(error.text());
// this.fakeLogin();
}
);
}
public stillLoggedIn() {
console.log('user was logged in');
}
public notLoggedIn() {
console.log('user was not logged in');
}
public updateUserInfo(response: any) {
@ -59,7 +52,6 @@ export class SelfService {
user.friends.push(new FriendInfo(friend.id, friend.name, friend.level));
}
for (const group of response.data.getSelf.groups) {
console.log(group.name);
user.groups.push(new GroupInfo(group.id, group.name));
}
user.chatIDs = response.data.getSelf.chats;

@ -6,6 +6,39 @@
// Be sure that you only ever include this mixin once!
@include mat-core();
$md-gvgreen: (
50 : #e0f7e7,
100 : #b3ebc3,
200 : #80de9c,
300 : #4dd174,
400 : #26c756,
500 : #00bd38,
600 : #00b732,
700 : #00ae2b,
800 : #00a624,
900 : #009817,
A100 : #c3ffc9,
A200 : #90ff9a,
A400 : #5dff6b,
A700 : #44ff54,
contrast: (
50 : #000000,
100 : #000000,
200 : #000000,
300 : #000000,
400 : #000000,
500 : #ffffff,
600 : #ffffff,
700 : #ffffff,
800 : #ffffff,
900 : #ffffff,
A100 : #000000,
A200 : #000000,
A400 : #000000,
A700 : #000000,
)
);
// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/

Loading…
Cancel
Save