feat: Add game activity status (Experimental)
All checks were successful
Queue Release Build / prepare (push) Successful in 21s
Deploy Web Apps / deploy (push) Successful in 5m14s
Queue Release Build / build-windows (push) Successful in 16m18s
Queue Release Build / build-linux (push) Successful in 29m20s
Queue Release Build / finalize (push) Successful in 36s
All checks were successful
Queue Release Build / prepare (push) Successful in 21s
Deploy Web Apps / deploy (push) Successful in 5m14s
Queue Release Build / build-windows (push) Successful in 16m18s
Queue Release Build / build-linux (push) Successful in 29m20s
Queue Release Build / finalize (push) Successful in 36s
This commit is contained in:
@@ -3,15 +3,24 @@ import {
|
||||
computed,
|
||||
effect,
|
||||
inject,
|
||||
OnDestroy,
|
||||
signal
|
||||
} from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { NgIcon, provideIcons } from '@ng-icons/core';
|
||||
import { lucideCheck, lucideChevronDown } from '@ng-icons/lucide';
|
||||
import {
|
||||
lucideCheck,
|
||||
lucideChevronDown,
|
||||
lucideGamepad2
|
||||
} from '@ng-icons/lucide';
|
||||
import { UserAvatarComponent } from '../user-avatar/user-avatar.component';
|
||||
import { UserStatusService } from '../../../core/services/user-status.service';
|
||||
import { User, UserStatus } from '../../../shared-kernel';
|
||||
import {
|
||||
GameActivity,
|
||||
User,
|
||||
UserStatus
|
||||
} from '../../../shared-kernel';
|
||||
import {
|
||||
EditableProfileAvatarSource,
|
||||
ProfileAvatarFacade,
|
||||
@@ -22,6 +31,8 @@ import {
|
||||
import { UsersActions } from '../../../store/users/users.actions';
|
||||
import { selectUsersEntities } from '../../../store/users/users.selectors';
|
||||
import { ThemeNodeDirective } from '../../../domains/theme';
|
||||
import { formatGameActivityElapsed } from '../../../domains/game-activity';
|
||||
import { ExternalLinkService } from '../../../core/platform/external-link.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-profile-card',
|
||||
@@ -32,10 +43,10 @@ import { ThemeNodeDirective } from '../../../domains/theme';
|
||||
UserAvatarComponent,
|
||||
ThemeNodeDirective
|
||||
],
|
||||
viewProviders: [provideIcons({ lucideCheck, lucideChevronDown })],
|
||||
viewProviders: [provideIcons({ lucideCheck, lucideChevronDown, lucideGamepad2 })],
|
||||
templateUrl: './profile-card.component.html'
|
||||
})
|
||||
export class ProfileCardComponent {
|
||||
export class ProfileCardComponent implements OnDestroy {
|
||||
readonly user = signal<User>({ id: '', oderId: '', username: '', displayName: '', status: 'offline', role: 'member', joinedAt: 0 });
|
||||
readonly displayedUser = computed(() => {
|
||||
const snapshot = this.user();
|
||||
@@ -52,6 +63,7 @@ export class ProfileCardComponent {
|
||||
readonly editingField = signal<'displayName' | 'description' | null>(null);
|
||||
readonly displayNameDraft = signal('');
|
||||
readonly descriptionDraft = signal('');
|
||||
readonly activityNow = signal(Date.now());
|
||||
|
||||
readonly statusOptions: { value: UserStatus | null; label: string; color: string }[] = [
|
||||
{ value: null, label: 'Online', color: 'bg-green-500' },
|
||||
@@ -65,6 +77,8 @@ export class ProfileCardComponent {
|
||||
private readonly userStatus = inject(UserStatusService);
|
||||
private readonly profileAvatar = inject(ProfileAvatarFacade);
|
||||
private readonly profileAvatarEditor = inject(ProfileAvatarEditorService);
|
||||
private readonly externalLinks = inject(ExternalLinkService);
|
||||
private readonly activityTimer = setInterval(() => this.activityNow.set(Date.now()), 1_000);
|
||||
private readonly syncProfileDrafts = effect(
|
||||
() => {
|
||||
const user = this.displayedUser();
|
||||
@@ -115,6 +129,24 @@ export class ProfileCardComponent {
|
||||
}
|
||||
}
|
||||
|
||||
gameActivityElapsed(): string {
|
||||
const activity = this.displayedUser().gameActivity;
|
||||
|
||||
return activity ? formatGameActivityElapsed(activity.startedAt, this.activityNow()) : '';
|
||||
}
|
||||
|
||||
openGameStore(activity: GameActivity, event: Event): void {
|
||||
event.stopPropagation();
|
||||
|
||||
if (activity.store?.url) {
|
||||
this.externalLinks.open(activity.store.url);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
clearInterval(this.activityTimer);
|
||||
}
|
||||
|
||||
toggleStatusMenu(): void {
|
||||
this.showStatusMenu.update((isOpen) => !isOpen);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user