Skip to content

Commit

Permalink
Update user component
Browse files Browse the repository at this point in the history
  • Loading branch information
miladsoft committed Sep 14, 2024
1 parent 750b6ce commit cf8893a
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 150 deletions.
66 changes: 13 additions & 53 deletions src/app/layout/common/user/user.component.html
Original file line number Diff line number Diff line change
@@ -1,54 +1,34 @@
<!-- Button -->
<button mat-icon-button [matMenuTriggerFor]="userActions">
<span class="relative">
@if (showAvatar && user.avatar) {
<img class="h-7 w-7 rounded-full" [src]="user.avatar" />
}
@if (!showAvatar || !user.avatar) {
<ng-container *ngIf="metadata?.picture; else defaultAvatar">
<img class="h-7 w-7 rounded-full" [src]="metadata?.picture" alt="User Avatar" />
</ng-container>
<ng-template #defaultAvatar>
<mat-icon [svgIcon]="'heroicons_outline:user-circle'"></mat-icon>
}
<span
class="absolute bottom-0 right-0 h-2 w-2 rounded-full"
[ngClass]="{
'mb-px mr-px': !showAvatar || !user.avatar,
'bg-green-500': user.status === 'online',
'bg-amber-500': user.status === 'away',
'bg-red-500': user.status === 'busy',
'bg-gray-400': user.status === 'not-visible',
}"
></span>
</ng-template>
</span>
</button>

<mat-menu [xPosition]="'before'" #userActions="matMenu">
<button mat-menu-item>
<span class="flex flex-col leading-none">
<span>Signed in as</span>
<span class="mt-1.5 text-md font-medium">{{ user.email }}</span>
<span>Logged in as</span>
<span class="mt-1.5 text-md font-medium">{{ metadata?.name || 'Unknown User' }}</span>
</span>
</button>
<mat-divider class="my-2"></mat-divider>
<button mat-menu-item>
<button mat-menu-item (click)="profile()">
<mat-icon [svgIcon]="'heroicons_outline:user-circle'"></mat-icon>
<span>Profile</span>
</button>
<!-- Settings with submenu -->
<button mat-menu-item [matMenuTriggerFor]="settingsMenu">
<mat-icon [svgIcon]="'heroicons_outline:cog-8-tooth'"></mat-icon>
<span>Settings</span>
</button>
<button mat-menu-item [matMenuTriggerFor]="userStatus">
<mat-icon
[svgIcon]="'heroicons_outline:ellipsis-horizontal-circle'"
></mat-icon>
<span>Status</span>
</button>
<mat-divider class="my-2"></mat-divider>
<button mat-menu-item (click)="signOut()">
<mat-icon
[svgIcon]="'heroicons_outline:arrow-right-on-rectangle'"
></mat-icon>
<span>Sign out</span>
<button mat-menu-item (click)="logout()">
<mat-icon [svgIcon]="'heroicons_outline:arrow-right-on-rectangle'"></mat-icon>
<span>logout</span>
</button>
</mat-menu>

Expand All @@ -72,29 +52,9 @@

<!-- Layout Selection -->
<button mat-menu-item (click)="setLayout('classic')">
<span>Classic Layout</span>
<span>Classic Layout</span>
</button>
<button mat-menu-item (click)="setLayout('modern')">
<span>Modern Layout</span>
</button>
</mat-menu>

<!-- Status Menu -->
<mat-menu class="user-status-menu" #userStatus="matMenu">
<button mat-menu-item (click)="updateUserStatus('online')">
<span class="mr-3 inline-flex h-4 w-4 rounded-full bg-green-500"></span>
<span>Online</span>
</button>
<button mat-menu-item (click)="updateUserStatus('away')">
<span class="mr-3 inline-flex h-4 w-4 rounded-full bg-amber-500"></span>
<span>Away</span>
</button>
<button mat-menu-item (click)="updateUserStatus('busy')">
<span class="mr-3 inline-flex h-4 w-4 rounded-full bg-red-500"></span>
<span>Busy</span>
</button>
<button mat-menu-item (click)="updateUserStatus('not-visible')">
<span class="mr-3 inline-flex h-4 w-4 rounded-full bg-gray-400"></span>
<span>Invisible</span>
<span>Modern Layout</span>
</button>
</mat-menu>
152 changes: 55 additions & 97 deletions src/app/layout/common/user/user.component.ts
Original file line number Diff line number Diff line change
@@ -1,157 +1,115 @@
import { AngorConfig, AngorConfigService, Scheme, Theme, Themes } from '@angor/services/config';
import { BooleanInput } from '@angular/cdk/coercion';
import { NgClass } from '@angular/common';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
Input,
OnDestroy,
OnInit,
ViewEncapsulation,
} from '@angular/core';
import { AngorConfig, AngorConfigService, Scheme, Theme, Themes } from '@angor/services/config';
import { Subject, takeUntil } from 'rxjs';
import { Router } from '@angular/router';
import { UserService } from 'app/core/user/user.service';
import { SignerService } from 'app/services/signer.service';
import { NostrService } from 'app/services/nostr.service';
import { NgClass, CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatDividerModule } from '@angular/material/divider';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { Router } from '@angular/router';
import { UserService } from 'app/core/user/user.service';
import { User } from 'app/core/user/user.types';
import { Subject, takeUntil } from 'rxjs';

@Component({
selector: 'user',
templateUrl: './user.component.html',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
exportAs: 'user',
standalone: true,
imports: [
MatButtonModule,
MatMenuModule,
MatIconModule,
NgClass,
MatDividerModule,
CommonModule
],
})
export class UserComponent implements OnInit, OnDestroy {
/* eslint-disable @typescript-eslint/naming-convention */
static ngAcceptInputType_showAvatar: BooleanInput;
/* eslint-enable @typescript-eslint/naming-convention */

@Input() showAvatar: boolean = true;
user: User;
user: any;
isLoading: boolean = true;
errorMessage: string | null = null;
metadata: any;

private _unsubscribeAll: Subject<any> = new Subject<any>();
config: AngorConfig;
layout: string;
scheme: 'dark' | 'light';
theme: string;
themes: Themes;
/**
* Constructor
*/

constructor(
private _changeDetectorRef: ChangeDetectorRef,
private _router: Router,
private _userService: UserService,
private _angorConfigService: AngorConfigService
private _angorConfigService: AngorConfigService,
private _nostrService: NostrService,
private _signerService: SignerService
) { }

) {}

/**
* On init
*/
ngOnInit(): void {
// Subscribe to user changes
this.user = {
id: '1',
name: 'Test User',
email: '[email protected]',
avatar: '/images/avatars/male-06.jpg',
status: 'online'
};
this.loadUserProfile();

this._angorConfigService.config$
this._angorConfigService.config$
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((config: AngorConfig) => {
localStorage.setItem('angorConfig', JSON.stringify(config));

this.config = config;
});
}

/**
* On destroy
*/
ngOnDestroy(): void {
// Unsubscribe from all subscriptions
this._unsubscribeAll.next(null);
this._unsubscribeAll.complete();
}
private async loadUserProfile(): Promise<void> {
this.isLoading = true;
this.errorMessage = null;
const publicKey = this._signerService.getPublicKey();

/**
* Update the user status
*
* @param status
*/
updateUserStatus(status: string): void {
// Return if user is not available
if (!this.user) {
if (!publicKey) {
this.errorMessage = 'No public key found. Please log in again.';
this.isLoading = false;
return;
}

// Update the user
this._userService
.update({
...this.user,
status,
})
.subscribe();
try {
const metadata = await this._nostrService.fetchMetadata(publicKey);
this.metadata = metadata;
} catch (error) {
console.error('Failed to load profile data:', error);
this.errorMessage = 'Failed to load profile data. Please try again later.';
} finally {
this.isLoading = false;
this._changeDetectorRef.markForCheck(); // Trigger change detection to update the view
}
}

ngOnDestroy(): void {
this._unsubscribeAll.next(null);
this._unsubscribeAll.complete();
}

/**
* Sign out
*/
signOut(): void {
logout(): void {
this._router.navigate(['/logout']);
}

/**
* Set the layout on the config
*
* @param layout
*/
setLayout(layout: string): void {
// Clear the 'layout' query param to allow layout changes
this._router
.navigate([], {
queryParams: {
layout: null,
},
queryParamsHandling: 'merge',
})
.then(() => {
// Set the config
this._angorConfigService.config = { layout };
});
}
profile(): void {
this._router.navigate(['/profile']);
}

/**
* Set the scheme on the config
*
* @param scheme
*/
setScheme(scheme: Scheme): void {
this._angorConfigService.config = { scheme };
}
setLayout(layout: string): void {
this._angorConfigService.config = { layout };
}

/**
* Set the theme on the config
*
* @param theme
*/
setTheme(theme: Theme): void {
this._angorConfigService.config = { theme };
}
setScheme(scheme: Scheme): void {
this._angorConfigService.config = { scheme };
}

setTheme(theme: Theme): void {
this._angorConfigService.config = { theme };
}
}

0 comments on commit cf8893a

Please sign in to comment.