Skip to content

Commit

Permalink
implemented notifications, various bug fixes, finished... I hope
Browse files Browse the repository at this point in the history
  • Loading branch information
WAPEETY committed Jun 22, 2024
1 parent b29d44a commit 6960f68
Show file tree
Hide file tree
Showing 15 changed files with 226 additions and 53 deletions.
12 changes: 10 additions & 2 deletions angular/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ export class ChatSocket extends Socket {
}
}

@Injectable()
export class NotificationListener extends Socket {
constructor() {
super({ url: environment.SOCKET_URI + '/notifications', options: {} });
}
}


@NgModule({
declarations: [
AppComponent
Expand All @@ -55,8 +63,8 @@ export class ChatSocket extends Socket {
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true},
PriceListener,
ChatSocket
//... more
ChatSocket,
NotificationListener
],
bootstrap: [AppComponent]
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,19 @@ <h1>Private chat:</h1>
<mat-panel-title>
Chat {{item.key}}
</mat-panel-title>
<mat-panel-description>
</mat-panel-description>
</mat-expansion-panel-header>
<app-message *ngFor="let message of item.value.messages" [message]="message"
<div>
<app-message *ngFor="let message of item.value.messages" [message]="message"
[isOwner]="message.sender === book.owner" [isMe]="message.sender === user_uid"
[ngClass]="{'mine': message.sender === user_uid}"></app-message>
</div>
</mat-expansion-panel>
</mat-accordion>
</mat-accordion>
</div>
<form class="chat_form" [formGroup]="privateChatForm" (ngSubmit)="onPrivateChatSubmit()">
<mat-form-field>
<input class="send_textarea" matInput placeholder="Type a private message" formControlName="message">
<input class="send_textarea" matInput placeholder="Type a private message"
formControlName="message">
</mat-form-field>
<button mat-raised-button color="primary" type="submit">Send</button>
</form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
}

.chat-container {
height: 65vh;
height: 60vh;
display: flex;
flex-direction: column;
overflow-y: scroll;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class BookDetailsComponent {
privateChat = false;
publicChatMessages: any[] = [];
privateChatMessages: any[] = [];
privateChats: {[id: string]: any} = {};
privateChats: { [id: string]: any } = {};
user_uid = '';
publicChatForm: FormGroup = new FormGroup({
message: new FormControl('',
Expand All @@ -53,8 +53,8 @@ export class BookDetailsComponent {
activePrivateChat: string | null = null;

constructor(
public bookService: BookService,
public acRoute: ActivatedRoute,
public bookService: BookService,
public acRoute: ActivatedRoute,
public auth: AuthService,
public storage: LocalStorageService,
public router: Router,
Expand Down Expand Up @@ -92,12 +92,12 @@ export class BookDetailsComponent {
this.listen_price.on('priceUpdate', (data: any) => {
if (data._id === id) {
this.hasBid = true;
if(data.offer){
if (data.offer) {
this.lastBid = data;
}
else{
else {
console.log('no bid');
this.lastBid = {offer: {value: this.book!['start_price']}}
this.lastBid = { offer: { value: this.book!['start_price'] } }
}
}
});
Expand All @@ -116,7 +116,7 @@ export class BookDetailsComponent {

onBid(price: number) {
const id = this.acRoute.snapshot.paramMap.get('uuid');

const observer = {
next: (data: any) => {
this.snackBar.open('Bid successfully placed', 'Close', {
Expand Down Expand Up @@ -154,12 +154,12 @@ export class BookDetailsComponent {

const now = new Date().toISOString();

if(this.book.open_date > now){
if (this.book.open_date > now) {
this.isOpen = false;
return;
}this.book['_id']
} this.book['_id']

if(this.book.close_date < now){
if (this.book.close_date < now) {
this.isOpen = false;
this.past = true;
return;
Expand All @@ -168,21 +168,21 @@ export class BookDetailsComponent {
this.isOpen = true;
}

forceSockets(){
forceSockets() {
setTimeout(() => {
if(this.book){
if(!this.lastBid){
if (this.book) {
if (!this.lastBid) {

const val = this.book.offers.length > 0 ? this.book.offers[this.book.offers.length - 1].value : this.book.start_price;

this.lastBid = {offer: {value: val}}
this.lastBid = { offer: { value: val } }
console.log('no bid');
}
}

// if(!this.publicChat || !this.privateChat){
// this.startChats();
// }
if (!this.publicChat || !this.privateChat) {
this.startChats();
}
}, 5000);
}

Expand All @@ -197,8 +197,8 @@ export class BookDetailsComponent {
this.router.navigate(['/books/edit', this.book!._id]);
}

onBan(){
onBan() {

const observer = {
next: (res: any) => {
this.snackBar.open('Book banned', '', {
Expand All @@ -217,28 +217,28 @@ export class BookDetailsComponent {
this.bookService.deleteBook(String(this.book?._id)).subscribe(observer);
}

startChats(){
if(!this.book){
startChats() {
if (!this.book) {
console.log('Missing book');
return;
}

this.chat.on('message', (data: any) => {
console.log(data);
if(!data.buyer){
if (!data.buyer) {
console.log('public chat');
this.publicChat = data._id;
if(data.messages.length > 1){
if (data.messages.length > 1) {
this.publicChatMessages = [this.publicChatMessages, ...data.messages];
}
else{
else {
console.log('adding messages');
this.publicChatMessages = [...new Set([...this.publicChatMessages, ...data.messages])];
}

setTimeout(() => {
const element = document.getElementById('public-chat');
if(element){
if (element) {
element.scrollTop = element.scrollHeight;
}
}, 100);
Expand All @@ -252,6 +252,13 @@ export class BookDetailsComponent {
let oldMessages = this.privateChats[data._id].messages;
this.privateChats[data._id].messages = [...oldMessages, ...data.messages];
}

setTimeout(() => {
const element = document.getElementById('private-chat');
if (element) {
element.scrollTop = element.scrollHeight;
}
}, 100);
}
});

Expand All @@ -265,14 +272,14 @@ export class BookDetailsComponent {
this.chat.on('error', (data: any) => {
console.error(data.message);
});

this.chat.emit('auth', {
jwt: this.storage.getAuth().accessToken.jwt
});
}

onPublicChatSubmit(){
if(!this.publicChatForm.valid){
onPublicChatSubmit() {
if (!this.publicChatForm.valid) {
return;
}

Expand All @@ -287,25 +294,25 @@ export class BookDetailsComponent {
sendPublicMessage(message: {
chatId: string,
text: string
}){
if(!this.publicChat){
}) {
if (!this.publicChat) {
console.error('no public chat');
return;
}

this.chat.emit('message', message);
}

onPrivateChatOpen(id: string){
onPrivateChatOpen(id: string) {
this.activePrivateChat = id;
}

onPrivateChatSubmit(){
if(!this.privateChatForm.valid){
onPrivateChatSubmit() {
if (!this.privateChatForm.valid) {
return;
}

if(!this.activePrivateChat){
if (!this.activePrivateChat) {
console.error('no active private chat');
this.snackBar.open('Open a chat to send a private message', 'Close', {
duration: 2000
Expand All @@ -324,8 +331,8 @@ export class BookDetailsComponent {
sendPrivateMessage(message: {
chatId: string,
text: string
}){
if(!this.activePrivateChat){
}) {
if (!this.activePrivateChat) {
console.error('no active private chat');
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
<mat-icon>person</mat-icon>
<span>Sign in</span>
</button>
<button mat-stroked-button *ngIf="this.LoggedIn"
class="notification-button"
(matBadge)="notifications.length"
matBadgePosition="before"
matBadgeColor="accent"
(click)="openNotificationDialog($event)"
>
<mat-icon>notifications</mat-icon>
</button>
<button mat-stroked-button routerLink="/profile" *ngIf="this.LoggedIn">
<mat-icon>person</mat-icon>
<span>{{this.username}}</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,12 @@ mat-toolbar{
}
.color-green{
color: #33AA33;
}

mat-icon{
margin: 0 !important;
}

.notification-button{
margin-right: 10px;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { NotificationListener } from 'src/app/app.module';
import { AuthService } from 'src/app/common/services/auth/auth.service';
import { LocalStorageService } from 'src/app/common/services/storage/local-storage.service';
import { NotificationDialogComponent } from '../notification-dialog/notification-dialog.component';

@Component({
selector: 'app-navbar',
Expand All @@ -11,24 +14,58 @@ export class NavbarComponent implements AfterViewInit {
@ViewChild('signin') cmp!: ElementRef;
LoggedIn: boolean = false;
username: string = '';
notifications: any[] = [];

constructor(
private authService: AuthService,
private storageService: LocalStorageService,
private notificationListener: NotificationListener,
public storage: LocalStorageService,
private dialog: MatDialog
) {
this.LoggedIn = this.authService.isAuthenticated();
this.username = this.storageService.getUserName();
}


openNotificationDialog(event: MouseEvent) {
const dialogConfig = {
position: {
left: `${event.clientX - 150}px`,
top: `${event.clientY}px`
},
data: this.notifications
};

this.dialog.open(NotificationDialogComponent, dialogConfig).afterClosed().subscribe
(result => {
if(result) this.notifications = result;
});
}

generateRandomColor(): string {
const colors = ["red","blue","yellow","green"];
const colors = ["red", "blue", "yellow", "green"];
const randomIndex = Math.floor(Math.random() * colors.length);
return colors[randomIndex];
}

ngOnInit(): void {
this.notificationListener.on('notification', (data: any) => {
console.log(data);
this.notifications.push(data);
});

this.notificationListener.emit('auth', {
jwt: this.storage.getAuth().accessToken.jwt
});
}

ngAfterViewInit(): void {
this.cmp.nativeElement.classList.add("color-"+this.generateRandomColor());
this.cmp.nativeElement.classList.add("color-" + this.generateRandomColor());
}

randomColor = this.generateRandomColor();

ngOnDestroy(): void {
this.notificationListener.off('notification');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<div class="main">
<div class="nonotifications" *ngIf="data.length === 0">
<span>You have 0 notifications</span>
</div>
<div class="row" *ngFor="let notification of data">
<div class="col-12">
<div class="notification">
<div class="notification-content">
<div class="notification-message">
<span>{{notification.message}}</span>
</div>
</div>
<div>
<mat-icon color="accent" (click)="pop(notification._id)">close</mat-icon>
</div>
</div>
</div>
</div>
</div>
Loading

0 comments on commit 6960f68

Please sign in to comment.