From 25b56d2d9c6286af9eaef94cbf65ce187f3a5897 Mon Sep 17 00:00:00 2001 From: Chneemann Date: Sat, 4 May 2024 10:46:12 +0200 Subject: [PATCH] added online status & last seen online --- .../contact-detail.component.html | 47 ++++++----- .../contact-detail.component.scss | 8 ++ .../contact-detail.component.ts | 77 ++++++++++++++++++- .../contacts/contacts.component.html | 15 ++-- .../contacts/contacts.component.scss | 8 ++ src/app/interfaces/user.interface.ts | 2 + src/app/services/login.service.ts | 16 +++- src/assets/img/offline.svg | 3 + src/assets/img/online.svg | 3 + 9 files changed, 147 insertions(+), 32 deletions(-) create mode 100644 src/assets/img/offline.svg create mode 100644 src/assets/img/online.svg diff --git a/src/app/components/contacts/contact-detail/contact-detail.component.html b/src/app/components/contacts/contact-detail/contact-detail.component.html index 9f57c0b..d525a45 100644 --- a/src/app/components/contacts/contact-detail/contact-detail.component.html +++ b/src/app/components/contacts/contact-detail/contact-detail.component.html @@ -11,7 +11,8 @@ src="./../../../../assets/img/arrow-left.svg" /> - @if (currentUserId) { + @if (currentUserId) { @for (user of checkUserData(currentUserId); track user) + {
+ @if(user.status) { + + } @else { + + }
- {{ firebaseService.getUserDetails(currentUserId, "initials") }} + {{ user.initials }}
- {{ firebaseService.getUserDetails(currentUserId, "firstName") }} - {{ firebaseService.getUserDetails(currentUserId, "lastName") }} + {{ user.firstName }} + {{ user.lastName }}
@@ -56,26 +59,22 @@
Contact Information

Email:

- - {{ firebaseService.getUserDetails(currentUserId, "email") }} + + {{ user.email }}

Phone:

- @if(firebaseService.getUserDetails(currentUserId, 'phone')[0] === '') { + @if(user.phone === '') { no phone } @else { - - {{ - firebaseService.getUserDetails(currentUserId, "phone") - }} + + {{ user.phone }} } +

Last seen online:

+ @if(user.status) { + Currently online + } @else { + {{ convertTimestamp(user.lastLogin) }} + }
@@ -84,5 +83,5 @@ [deleteContact]="deleteContact" [openEditDialog]="openEditDialog" > - } + }} diff --git a/src/app/components/contacts/contact-detail/contact-detail.component.scss b/src/app/components/contacts/contact-detail/contact-detail.component.scss index d974f55..e2fac36 100644 --- a/src/app/components/contacts/contact-detail/contact-detail.component.scss +++ b/src/app/components/contacts/contact-detail/contact-detail.component.scss @@ -48,6 +48,7 @@ display: flex; justify-content: center; align-items: center; + position: relative; width: 120px; min-width: 120px; height: 120px; @@ -59,6 +60,13 @@ color: var(--white); text-shadow: 1px 1px 2px var(--black); } + img { + position: absolute; + width: 24px; + height: 24px; + bottom: 0; + right: 0; + } } .word-wrap { diff --git a/src/app/components/contacts/contact-detail/contact-detail.component.ts b/src/app/components/contacts/contact-detail/contact-detail.component.ts index 82306b6..cd7d11a 100644 --- a/src/app/components/contacts/contact-detail/contact-detail.component.ts +++ b/src/app/components/contacts/contact-detail/contact-detail.component.ts @@ -6,6 +6,7 @@ import { ContactEditComponent } from '../contact-edit/contact-edit.component'; import { SharedService } from '../../../services/shared.service'; import { ContactNavComponent } from '../contact-nav/contact-nav.component'; import { FirebaseService } from '../../../services/firebase.service'; +import { LanguageService } from '../../../services/language.service'; @Component({ selector: 'app-contact-detail', standalone: true, @@ -26,13 +27,20 @@ export class ContactDetailComponent { constructor( private router: Router, public sharedService: SharedService, - public firebaseService: FirebaseService + public firebaseService: FirebaseService, + private languageService: LanguageService ) {} closeUserDetails() { this.router.navigate(['contacts']); } + checkUserData(userId: string) { + return this.firebaseService + .getAllUsers() + .filter((user) => user.id === userId); + } + toggleNav() { this.isMobileNavbarOpen = !this.isMobileNavbarOpen; } @@ -47,6 +55,73 @@ export class ContactDetailComponent { this.sharedService.isDeleteContactDialogOpen = true; } + convertTimestamp(timestamp: number) { + const date = new Date(timestamp); + const monthsEN = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec', + ]; + const monthsDE = [ + 'Jan', + 'Feb', + 'Mär', + 'Apr', + 'Mai', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Okt', + 'Nov', + 'Dez', + ]; + const months = + this.languageService.currentLang === 'de' ? monthsDE : monthsEN; + const year = date.getFullYear(); + const month = months[date.getMonth()]; + const day = date.getDate(); + + if (this.languageService.currentLang === 'de') { + const time = `${day}. ${month}. ${year}`; + return `${time} - ${this.convertTimestampHourDE(timestamp)}`; + } else { + const time = `${month}. ${day}, ${year}`; + return `${time} - ${this.convertTimestampHourEN(timestamp)}`; + } + } + + convertTimestampHourEN(timestamp: number) { + const date = new Date(timestamp * 1000); + let hour = date.getHours(); + const minute = ('0' + date.getMinutes()).slice(-2); + const second = ('0' + date.getMinutes()).slice(-2); + const period = hour >= 12 ? 'PM' : 'AM'; + hour = hour % 12 || 12; + + let hourWithNull = ('0' + hour).slice(-2); + + return `${hourWithNull}:${minute}:${second} ${period}`; + } + + convertTimestampHourDE(timestamp: number) { + const date = new Date(timestamp * 1000); + let hour = date.getHours(); + const minute = ('0' + date.getMinutes()).slice(-2); + const second = ('0' + date.getMinutes()).slice(-2); + + return `${hour}:${minute}:${second} Uhr`; + } + @HostListener('document:click', ['$event']) checkOpenContactEdit(event: MouseEvent) { const targetElement = event.target as HTMLElement; diff --git a/src/app/components/contacts/contacts.component.html b/src/app/components/contacts/contacts.component.html index 5a1d667..b043c0c 100644 --- a/src/app/components/contacts/contacts.component.html +++ b/src/app/components/contacts/contacts.component.html @@ -28,25 +28,30 @@
+ @if(user.status) { + + } @else { + + }
- {{ firebaseService.getUserDetails(user.id, "initials") }} + {{ user.initials }}

- {{ firebaseService.getUserDetails(user.id, "firstName") }} + {{ user.firstName }}

- {{ firebaseService.getUserDetails(user.id, "lastName") }} + {{ user.lastName }}

diff --git a/src/app/components/contacts/contacts.component.scss b/src/app/components/contacts/contacts.component.scss index 965571e..8fa39e0 100644 --- a/src/app/components/contacts/contacts.component.scss +++ b/src/app/components/contacts/contacts.component.scss @@ -97,6 +97,7 @@ display: flex; justify-content: center; align-items: center; + position: relative; width: 42px; min-width: 42px; height: 42px; @@ -108,6 +109,13 @@ color: var(--white); text-shadow: 1px 1px 2px var(--black); } + img { + position: absolute; + width: 12px; + height: 12px; + bottom: 0; + right: 0; + } } .details { diff --git a/src/app/interfaces/user.interface.ts b/src/app/interfaces/user.interface.ts index e5f6a6f..1412e50 100644 --- a/src/app/interfaces/user.interface.ts +++ b/src/app/interfaces/user.interface.ts @@ -7,4 +7,6 @@ export interface User { phone: string; initials: string; color: string; + status: boolean; + lastLogin: number; } diff --git a/src/app/services/login.service.ts b/src/app/services/login.service.ts index 61785f1..fa952e0 100644 --- a/src/app/services/login.service.ts +++ b/src/app/services/login.service.ts @@ -6,7 +6,7 @@ import { GoogleAuthProvider, } from 'firebase/auth'; import { FirebaseService } from './firebase.service'; -import { Firestore } from '@angular/fire/firestore'; +import { Firestore, collection, doc, updateDoc } from '@angular/fire/firestore'; import { SharedService } from './shared.service'; @Injectable({ providedIn: 'root', @@ -28,7 +28,9 @@ export class LoginService { this.getUserIdInLocalStorage( this.firebaseService.checkUserUID(user.uid)[0].id ); - window.location.reload(); + this.updateUserOnlineStatus( + this.firebaseService.checkUserUID(user.uid)[0].id + ); } else { console.error('No user with this UID was found!'); } @@ -60,6 +62,16 @@ export class LoginService { }); } + async updateUserOnlineStatus(userId: string) { + await updateDoc(doc(collection(this.firestore, 'users'), userId), { + status: true, + lastLogin: new Date().getTime(), + }).catch((err) => { + console.error(err); + }); + window.location.reload(); + } + getUserIdInLocalStorage(userId: string) { localStorage.setItem('currentUser', JSON.stringify(userId)); } diff --git a/src/assets/img/offline.svg b/src/assets/img/offline.svg new file mode 100644 index 0000000..d258d0f --- /dev/null +++ b/src/assets/img/offline.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/assets/img/online.svg b/src/assets/img/online.svg new file mode 100644 index 0000000..e321565 --- /dev/null +++ b/src/assets/img/online.svg @@ -0,0 +1,3 @@ + + +