diff --git a/src/app/components/account-detail/account-detail.component.html b/src/app/components/account-detail/account-detail.component.html
index aaf40c3..26e1004 100644
--- a/src/app/components/account-detail/account-detail.component.html
+++ b/src/app/components/account-detail/account-detail.component.html
@@ -22,7 +22,7 @@
- {{timer}}s
+
diff --git a/src/app/components/account-detail/account-detail.component.ts b/src/app/components/account-detail/account-detail.component.ts
index 593af26..41861a9 100644
--- a/src/app/components/account-detail/account-detail.component.ts
+++ b/src/app/components/account-detail/account-detail.component.ts
@@ -1,7 +1,9 @@
-import { Component, Input } from '@angular/core';
+import { Component, Input, ViewChild } from '@angular/core';
import { ToastController } from '@ionic/angular';
import { Account2FA } from 'src/app/models/account2FA.model';
import { OtpService } from 'src/app/services/otp.service';
+import { CountdownTimerComponent } from '../countdown-timer/countdown-timer.component';
+import { debounceTime, pipe } from 'rxjs';
@Component({
selector: 'app-account-detail',
@@ -9,17 +11,18 @@ import { OtpService } from 'src/app/services/otp.service';
styleUrls: ['./account-detail.component.scss'],
})
export class AccountDetailComponent {
+ @ViewChild(CountdownTimerComponent) countdownTimer!: CountdownTimerComponent;
- private timerRefreshInterval: any
private _account?: Account2FA
- timer: number = 0
private _token = '000 000'
-
+ private _tokenCountdown = 30
+ private debounceTimeout: any
@Input() set account(value: Account2FA | undefined) {
this._account = value
+ this.updateTokenCountdown()
this.updateCode()
- this.updateTimer()
}
+
get account(): Account2FA | undefined {
return this._account
}
@@ -54,6 +57,17 @@ export class AccountDetailComponent {
return this._token
}
+ private set tokenCountdown(value: number) {
+ this._tokenCountdown = value
+ setTimeout(() => {
+ this.countdownTimer?.startTimer()
+ }, 50);
+ }
+
+ get tokenCountdown(): number {
+ return this._tokenCountdown
+ }
+
async copyCode(evt: any) {
if(!this.account) {
return
@@ -70,24 +84,11 @@ export class AccountDetailComponent {
await toast.present()
}
- updateTimer() {
- if(this.timerRefreshInterval) {
- clearInterval(this.timerRefreshInterval)
- }
- if(this.account) {
- this.timer = this.account.getNextRollingTimeLeft()
- this.timerRefreshInterval = setInterval(() => {
- if(!this.account) {
- clearInterval(this.timerRefreshInterval)
- this.timer = NaN
- } else {
- this.timer = this.account.getNextRollingTimeLeft()
- if (this.timer == this.account.interval) { // new code needed
- this.updateCode()
- }
- }
- }, 500) // for precision purposes update every 500ms
- }
+ timerEnd() {
+ setTimeout(() => {
+ this.updateCode()
+ this.updateTokenCountdown()
+ }, 1000);
}
updateCode() {
@@ -96,4 +97,13 @@ export class AccountDetailComponent {
this.token = this.otpService.generateTOTP(this.account.secret, this.account.interval)
}
}
+
+ private updateTokenCountdown() {
+ if(!this.debounceTimeout) {
+ this.debounceTimeout = setTimeout(() => {
+ this.tokenCountdown = this.account?.getNextRollingTimeLeft() || this.account?.interval || 30
+ this.debounceTimeout = undefined
+ }, 150)
+ }
+ }
}
diff --git a/src/app/components/countdown-timer/countdown-timer.component.html b/src/app/components/countdown-timer/countdown-timer.component.html
index 5219430..5233275 100644
--- a/src/app/components/countdown-timer/countdown-timer.component.html
+++ b/src/app/components/countdown-timer/countdown-timer.component.html
@@ -1,3 +1 @@
-
- countdown-timer works!
-
+{{timerLabel}}s
\ No newline at end of file
diff --git a/src/app/components/countdown-timer/countdown-timer.component.ts b/src/app/components/countdown-timer/countdown-timer.component.ts
index 2d42875..2056300 100644
--- a/src/app/components/countdown-timer/countdown-timer.component.ts
+++ b/src/app/components/countdown-timer/countdown-timer.component.ts
@@ -1,14 +1,59 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-countdown-timer',
templateUrl: './countdown-timer.component.html',
styleUrls: ['./countdown-timer.component.scss'],
})
-export class CountdownTimerComponent implements OnInit {
+export class CountdownTimerComponent {
+ private timerRefreshInterval: any
+ private _timerStartTime = 0
+ private _seconds = 0
+ @Input() set seconds(value: number) {
+ this._seconds = value
+ this.timerLabel = value
+ this.stopTimer()
+ }
+ get seconds(): number {
+ return this._seconds
+ }
+
+ @Output() timerEnd = new EventEmitter();
+
+ timerLabel: number = 0;
constructor() { }
- ngOnInit() {}
+ public startTimer() {
+ this.setupTimerInterval()
+ }
+
+ private stopTimer() {
+ if(this.timerRefreshInterval) {
+ clearInterval(this.timerRefreshInterval)
+ }
+ }
+
+ private setupTimerInterval() {
+ if(this.timerRefreshInterval) {
+ clearInterval(this.timerRefreshInterval)
+ }
+
+ this.timerLabel = this.seconds // reset timer label
+ this._timerStartTime = Date.now() // reset timer start time
+
+ this.timerRefreshInterval = setInterval(() => {
+ this.updateTimerLabel()
+ if(this.timerLabel <= 0) {
+ clearInterval(this.timerRefreshInterval)
+ this.timerEnd.emit()
+ }
+ }, 250) // for precision purposes check every 250ms
+ }
+
+ private updateTimerLabel() {
+ const elapsedTime = Math.ceil((Date.now() - this._timerStartTime)/1000)
+ this.timerLabel = this.seconds - elapsedTime
+ }
}
diff --git a/src/app/home/home.module.ts b/src/app/home/home.module.ts
index 83b7925..bdfc9ea 100644
--- a/src/app/home/home.module.ts
+++ b/src/app/home/home.module.ts
@@ -9,6 +9,7 @@ import { AccountFilterPipe } from '../pipes/account-filter.pipe';
import { NgxScannerQrcodeModule } from 'ngx-scanner-qrcode';
import { AccountListComponent } from '../components/account-list/account-list.component';
import { AccountDetailComponent } from '../components/account-detail/account-detail.component';
+import { CountdownTimerComponent } from '../components/countdown-timer/countdown-timer.component';
@NgModule({
@@ -20,8 +21,7 @@ import { AccountDetailComponent } from '../components/account-detail/account-det
HomePageRoutingModule,
AccountFilterPipe,
NgxScannerQrcodeModule,
-
],
- declarations: [HomePage, AccountListComponent, AccountDetailComponent]
+ declarations: [HomePage, AccountListComponent, AccountDetailComponent, CountdownTimerComponent]
})
export class HomePageModule {}
diff --git a/src/app/models/account2FA.model.ts b/src/app/models/account2FA.model.ts
index 1ea1a23..2aaed27 100644
--- a/src/app/models/account2FA.model.ts
+++ b/src/app/models/account2FA.model.ts
@@ -71,7 +71,7 @@ export class Account2FA implements IAccount2FA {
}
getNextRollingTimeLeft(): number {
- return (this.interval || 30) - (Math.floor(Date.now() / 1000) % (this.interval || 30));
+ return this.interval - (Math.ceil(Date.now() / 1000) % this.interval);
}
typeErased(): Object {