Files
marketplaces/src/app/components/telegram-login/telegram-login.component.ts

135 lines
3.5 KiB
TypeScript
Raw Normal View History

2026-03-25 15:32:50 +04:00
import { Component, ChangeDetectionStrategy, inject, signal, computed, effect, OnDestroy } from '@angular/core';
2026-02-28 17:18:24 +04:00
import { AuthService } from '../../services/auth.service';
2026-03-25 15:32:50 +04:00
import { CartService } from '../../services/cart.service';
2026-02-28 17:18:24 +04:00
import { TranslatePipe } from '../../i18n/translate.pipe';
2026-03-25 15:32:50 +04:00
import { getDiscountedPrice } from '../../utils/item.utils';
2026-02-28 17:18:24 +04:00
@Component({
selector: 'app-telegram-login',
imports: [TranslatePipe],
templateUrl: './telegram-login.component.html',
styleUrls: ['./telegram-login.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
2026-03-25 15:32:50 +04:00
export class TelegramLoginComponent implements OnDestroy {
2026-02-28 17:18:24 +04:00
private authService = inject(AuthService);
2026-03-25 15:32:50 +04:00
private cartService = inject(CartService);
2026-02-28 17:18:24 +04:00
showDialog = this.authService.showLoginDialog;
status = this.authService.status;
2026-03-25 15:32:50 +04:00
2026-02-28 17:18:24 +04:00
loginUrl = signal('');
2026-06-01 00:47:26 +04:00
webSessionID = signal('');
2026-03-25 15:32:50 +04:00
qrStatus = signal<'loading' | 'ready' | 'expired' | 'error'>('loading');
encodedQrUrl = computed(() => encodeURIComponent(this.loginUrl()));
2026-02-28 17:18:24 +04:00
2026-06-01 00:47:26 +04:00
private readonly pollIntervalMs = 5000;
2026-02-28 17:18:24 +04:00
private pollTimer?: ReturnType<typeof setInterval>;
2026-03-25 15:32:50 +04:00
constructor() {
2026-06-19 01:57:27 +04:00
console.log('TelegramLoginComponent initialized');
2026-03-25 15:32:50 +04:00
effect(() => {
if (this.showDialog()) {
this.initQrLogin();
} else {
this.stopPolling();
}
});
2026-02-28 17:18:24 +04:00
}
ngOnDestroy(): void {
this.stopPolling();
}
close(): void {
this.authService.hideLogin();
this.stopPolling();
}
openTelegramLogin(): void {
2026-06-01 00:47:26 +04:00
const url = this.loginUrl();
if (!url) return;
window.open(url, '_blank');
2026-03-25 15:32:50 +04:00
if (!this.pollTimer) {
2026-06-01 00:47:26 +04:00
const webSessionID = this.webSessionID();
if (webSessionID) {
this.startPolling(webSessionID);
2026-04-14 23:14:26 +04:00
}
2026-03-25 15:32:50 +04:00
}
2026-02-28 17:18:24 +04:00
}
2026-03-25 15:32:50 +04:00
refreshQr(): void {
2026-02-28 17:18:24 +04:00
this.stopPolling();
2026-03-25 15:32:50 +04:00
this.initQrLogin();
}
private initQrLogin(): void {
this.qrStatus.set('loading');
2026-06-01 00:47:26 +04:00
this.loginUrl.set('');
this.webSessionID.set('');
this.authService.createWebSession().subscribe({
2026-03-25 15:32:50 +04:00
next: (res) => {
this.loginUrl.set(res.url);
2026-06-01 00:47:26 +04:00
this.webSessionID.set(res.webSessionID);
2026-03-25 15:32:50 +04:00
this.qrStatus.set('ready');
2026-06-01 00:47:26 +04:00
this.startPolling(res.webSessionID);
2026-03-25 15:32:50 +04:00
},
error: () => {
this.qrStatus.set('error');
}
});
}
2026-06-01 00:47:26 +04:00
private startPolling(webSessionID: string): void {
2026-03-25 15:32:50 +04:00
this.stopPolling();
2026-06-01 00:47:26 +04:00
if (!webSessionID) return;
2026-03-25 15:32:50 +04:00
2026-02-28 17:18:24 +04:00
let checks = 0;
this.pollTimer = setInterval(() => {
checks++;
2026-03-25 15:32:50 +04:00
if (checks > 100) {
2026-02-28 17:18:24 +04:00
this.stopPolling();
2026-03-25 15:32:50 +04:00
this.qrStatus.set('expired');
2026-02-28 17:18:24 +04:00
return;
}
2026-03-25 15:32:50 +04:00
2026-06-01 00:47:26 +04:00
this.authService.checkSessionOnce(webSessionID).subscribe({
next: (session) => {
if (session?.active) {
this.stopPolling();
this.syncCartAndComplete(session.sessionId);
2026-03-25 15:32:50 +04:00
}
},
error: () => {
// Network error — keep polling
}
});
2026-06-01 00:47:26 +04:00
}, this.pollIntervalMs);
2026-02-28 17:18:24 +04:00
}
2026-03-25 15:32:50 +04:00
private syncCartAndComplete(sessionId: string): void {
const cartItems = this.cartService.items().map(item => ({
itemID: item.itemID,
quantity: item.quantity,
colour: item.colour || '',
size: item.size || '',
price: item.discount > 0
? item.price * (1 - item.discount / 100)
: item.price,
}));
this.authService.syncCart(sessionId, cartItems).subscribe(() => {
this.authService.onTelegramLoginComplete();
});
}
2026-02-28 17:18:24 +04:00
private stopPolling(): void {
if (this.pollTimer) {
clearInterval(this.pollTimer);
this.pollTimer = undefined;
}
}
}