This commit is contained in:
Benedek László 2024-05-09 23:02:55 +02:00
parent 8693c06757
commit ca2a763636
9 changed files with 133 additions and 41 deletions

View File

@ -4,39 +4,49 @@ import { AuthService } from '../auth/auth.service';
import { AngularFirestore, Reference } from '@angular/fire/compat/firestore';
import { User } from '../../../model/User';
import { UserService } from './user.service';
import { user } from '@angular/fire/auth';
import { DocumentReference } from '@angular/fire/firestore';
@Injectable({
providedIn: 'root'
})
export class PostService {
constructor(private auth: AuthService, private afs: AngularFirestore) { }
constructor(private auth: AuthService, private afs: AngularFirestore, private usersvc: UserService) { }
getFeed(length: Number, start: Number): Promise<Array<Post>> {
return new Promise<Array<Post>>((resolve, reject) => {
let posts = Array<Post>();
let result = Array<Post>();
if (this.auth.checkAllowed()) {
this.afs.collection<Post>('post').valueChanges({idField: 'id'}).subscribe(data => {
data.forEach(i => {
this.afs.doc((i as any).user).valueChanges().subscribe(user => {
posts.push({
this.usersvc.getCurrentUser()
.then(currentUser => {
// get posts
this.afs.collection<Post>('post').valueChanges({ idField: 'id' }).subscribe(posts => {
posts.forEach(post => {
// get the user who made this post
this.afs.doc((post as any).user).valueChanges().subscribe(user => {
// get how many likes it has
this.afs.collection('like', ref => ref.where('post', '==', this.afs.doc('/post/' + post.id).ref)).valueChanges().subscribe(likes => {
// check if we liked this post
let liked: boolean = likes.filter(like => (like as any).user.id == currentUser.username).length != 0;
result.push({
user: {
username: (user as User).username,
email: (user as User).email,
picture: (user as User).picture,
followed: (user as User).followed
},
content: i.content,
image: i.image,
likes: i.likes,
liked: i.liked,
id: i.id
content: post.content,
image: post.image,
likes: likes.length,
liked: liked,
id: post.id
})
})
});
});
resolve(posts);
resolve(result);
});
})
} else {
reject()
}
@ -48,24 +58,42 @@ export class PostService {
if (this.auth.checkAllowed()) {
if (username == undefined) {
this.auth.getUser().subscribe(cred => {
// get the user by id
this.afs.collection<User>('user', ref => ref.where('id', '==', cred?.uid)).valueChanges().subscribe(user => {
this.afs.collection<Post>('post', ref => ref.where('user', '==', this.afs.doc('/user/' + user[0].username).ref)).valueChanges({idField:'id'}).subscribe(data => {
data.forEach(i => {
i.user = user[0] as User;
// get their posts
this.afs.collection<Post>('post', ref => ref.where('user', '==', this.afs.doc('/user/' + user[0].username).ref)).valueChanges({ idField: 'id' }).subscribe(posts => {
posts.forEach(post => {
// get how many likes it has
this.afs.collection('like', ref => ref.where('post', '==', this.afs.doc('/post/' + post.id).ref)).valueChanges().subscribe(likes => {
// check if we liked this post
post.liked = likes.filter(like => (like as any).user.id == user[0].username).length != 0;
post.user = user[0] as User;
post.likes = likes.length;
})
resolve(posts)
})
resolve(data)
});
})
});
} else {
this.usersvc.getCurrentUser()
.then(currentUser => {
// get the user by username
this.afs.collection<User>('user').doc(username as string).valueChanges().subscribe(user => {
this.afs.collection<Post>('post', ref => ref.where('user', '==', this.afs.doc('/user/' + username).ref)).valueChanges({idField:'id'}).subscribe(data => {
data.forEach(i => {
i.user = user as User;
// get their posts
this.afs.collection<Post>('post', ref => ref.where('user', '==', this.afs.doc('/user/' + username).ref)).valueChanges({ idField: 'id' }).subscribe(posts => {
posts.forEach(post => {
// get how many likes it has
this.afs.collection('like', ref => ref.where('post', '==', this.afs.doc('/post/' + post.id).ref)).valueChanges().subscribe(likes => {
post.liked = likes.filter(like => (like as any).user.id == currentUser.username).length != 0;
post.user = user as User;
post.likes = likes.length;
})
resolve(posts)
})
resolve(data)
});
});
})
}
} else {
reject()
@ -96,6 +124,37 @@ export class PostService {
}
removePost(id: String) {
return this.afs.doc('/post/'+id).delete();
return this.afs.doc('/post/' + id).delete();
}
toggleLike(postId: String): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
if (this.auth.checkAllowed()) {
this.usersvc.getCurrentUser()
.then(user => {
let userRef = this.afs.doc('/user/' + user.username).ref;
let postRef = this.afs.doc('/post/' + postId).ref;
this.afs.collection('like', ref => ref.where('user', '==', userRef).where('post', '==', postRef)).get().subscribe(likes => {
if (likes.docs.length == 0) {
// like
this.afs.collection('like').add({
user: userRef,
post: postRef
})
resolve(true);
} else {
// dislike
likes.docs.forEach(likes => {
likes.ref.delete()
})
resolve(false);
}
})
})
.catch(() => reject())
} else {
reject();
}
});
}
}

View File

@ -2,7 +2,6 @@ import { Injectable } from '@angular/core';
import { User } from '../../../model/User';
import { AuthService } from '../auth/auth.service';
import { AngularFirestore } from '@angular/fire/compat/firestore';
import { user } from '@angular/fire/auth';
@Injectable({
providedIn: 'root'
@ -26,6 +25,19 @@ export class UserService {
});
}
getCurrentUser(): Promise<User> {
return new Promise<User>((resolve,reject)=>{
this.auth.getUser().subscribe(user => {
this.afs.collection<User>('user', ref => ref.where('id', '==', user?.uid)).valueChanges().subscribe(users=>{
if (users.length != 0)
resolve(users[0]);
else
reject();
})
});
});
}
createUser(username: String, email: String, id: String) {
return new Promise<void>((resolve, reject) => {
this.afs.collection('user').doc(username as string).set({

View File

@ -6,3 +6,12 @@ button {
display: block;
margin: 10px auto;
}
app-side-menu {
height: 100%;
display: block;
}
mat-sidenav-container {
height: 100%;
}

View File

@ -1,6 +1,7 @@
<div class="user-container outline">
<div [routerLink]="'/user/'+user?.username">
<img [src]="user?.picture" class="outline"> <span>{{user?.username}}</span>
<!-- <img [src]="user?.picture" class="outline"> -->
<span>{{user?.username}}</span>
</div>
<span [classList]="user?.followed ? 'follow followed' : 'follow'"></span>
<!-- <span [classList]="user?.followed ? 'follow followed' : 'follow'"></span> -->
</div>

View File

@ -16,6 +16,7 @@
}
span {
margin: 20px auto;
display: block;
width: 100%;
text-align: center;

View File

@ -3,7 +3,7 @@
<div>{{post?.content}}</div>
<img *ngIf="post?.image" [src]="post?.image" alt="">
<div class="icons">
<span [classList]="post?.liked ? 'likes liked' : 'likes'">{{post?.likes}}</span>
<span (click)="like()" [classList]="post?.liked ? 'likes liked' : 'likes'">{{post?.likes}}</span>
<span (click)="remove()" [classList]="isOwned ? 'owned' : ''"></span>
</div>
</div>

View File

@ -14,7 +14,6 @@ import { PostService } from '../../../services/data/post.service';
styleUrl: './post.component.scss'
})
export class PostComponent implements OnInit {
@Input() post: Post | undefined;
isOwned: boolean = false;
@ -38,4 +37,13 @@ export class PostComponent implements OnInit {
alert("failed to delete post");
})
}
like() {
this.postSv.toggleLike(this.post?.id as String)
.then((result)=>{
((this.post as Post).likes as number) += result ? 1 : -1;
(this.post as Post).liked = result;
})
.catch(()=>{alert('failed to toggle like on post')})
}
}

View File

@ -1,3 +1,4 @@
<div [routerLink]="'/user/'+user?.username">
<img [src]="user?.picture" class="outline"> <span>{{user?.username}}</span>
<!-- <img [src]="user?.picture" class="outline"> -->
<span>{{user?.username}}</span>
</div>

View File

@ -12,6 +12,7 @@ img {
span {
display: inline-block;
margin: 20px auto;
padding-left: 10px;
transform: translateY(-60%);
}