Skip to content

Commit e394034

Browse files
authored
Add about section in menu to include app info and licenses (#26)
* Add about section in menu to include app info and licenses Fixes #25 * Refactor i18n files to remove unused keys * Remove unused keys from i18n files
1 parent 988f5fb commit e394034

File tree

10 files changed

+637
-56
lines changed

10 files changed

+637
-56
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "authleu",
3-
"version": "2.1.1",
3+
"version": "2.1.2",
44
"author": "Leonardo 'Leu' Pereira <jlcvp@users.noreply.github.com>",
55
"homepage": "https://github.com/jlcvp/AuthLeu",
66
"description": "Open source authenticator and 2fa code generator to use across multiple devices and platforms",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<ion-header>
2+
<ion-toolbar>
3+
<ion-buttons slot="start">
4+
<ion-button (click)="dismissModal()">
5+
<ion-icon *ngIf="isMD" slot="icon-only" name="close-outline"></ion-icon>
6+
<ion-label *ngIf="!isMD">{{ "ABOUT_MODAL.CLOSE" | translate }}</ion-label>
7+
</ion-button>
8+
</ion-buttons>
9+
<ion-title>{{ "ABOUT_MODAL.TITLE" | translate }}</ion-title>
10+
</ion-toolbar>
11+
</ion-header>
12+
<ion-content>
13+
<ion-card>
14+
<ion-card-header>
15+
<ion-card-title>{{ "ABOUT_MODAL.VERSION_INFO_HEADER" | translate }}</ion-card-title>
16+
</ion-card-header>
17+
<ion-card-content>
18+
<p>{{ "ABOUT_MODAL.VERSION_INFO.VERSION" | translate }}:&emsp;{{ versionInfo.versionName }}</p>
19+
<p>{{ "ABOUT_MODAL.VERSION_INFO.BUILD_DATE" | translate }}:&emsp;{{ versionInfo.buildDate }}</p>
20+
<p>{{ "ABOUT_MODAL.VERSION_INFO.GIT_HASH" | translate }}:&emsp;{{ versionInfo.commitHash }}</p>
21+
</ion-card-content>
22+
</ion-card>
23+
24+
<ng-container *ngIf="licenses.length > 0">
25+
<ion-card>
26+
<ion-card-header>
27+
<ion-card-title>{{ "ABOUT_MODAL.LICENSES_HEADER" | translate }}</ion-card-title>
28+
</ion-card-header>
29+
<ion-card-content>
30+
<ion-accordion-group>
31+
<ion-accordion *ngFor="let license of licenses">
32+
<ion-item slot="header" color="light">
33+
<ion-label> {{ license.title }}</ion-label>
34+
</ion-item>
35+
<div class="ion-padding" slot="content">
36+
<p class="line-break">{{ license.body }}</p>
37+
</div>
38+
</ion-accordion>
39+
</ion-accordion-group>
40+
</ion-card-content>
41+
</ion-card>
42+
</ng-container>
43+
</ion-content>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.line-break {
2+
white-space: pre-line;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { HttpClient } from '@angular/common/http';
2+
import { Component } from '@angular/core';
3+
import { Config, ModalController } from '@ionic/angular';
4+
import { lastValueFrom } from 'rxjs';
5+
import { AppVersionInfo } from 'src/app/models/app-version.enum';
6+
import { AppConfigService } from 'src/app/services/app-config.service';
7+
8+
@Component({
9+
selector: 'app-about-modal',
10+
templateUrl: './about-modal.component.html',
11+
styleUrls: ['./about-modal.component.scss'],
12+
})
13+
export class AboutModalComponent {
14+
15+
isMD: boolean
16+
versionInfo: AppVersionInfo
17+
licenses: {title: string, body: string}[] = []
18+
19+
constructor(
20+
private modalController: ModalController,
21+
private httpClient: HttpClient,
22+
configService: AppConfigService,
23+
config: Config) {
24+
this.isMD = config.get('mode') !== 'ios'
25+
this.versionInfo = configService.versionInfo
26+
this.loadLicenses()
27+
}
28+
29+
async dismissModal() {
30+
await this.modalController.dismiss()
31+
}
32+
33+
private async loadLicenses() {
34+
const ngxscannerqrcodeLicense = await lastValueFrom(this.httpClient.get('assets/licenses/ngxqrcode.txt', {responseType: 'text'}))
35+
this.licenses.push({title: 'ngx-scanner-qrcode', body: ngxscannerqrcodeLicense})
36+
}
37+
}

src/app/home/home.module.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { CountdownTimerComponent } from './components/countdown-timer/countdown-
1313
import { TranslateModule } from '@ngx-translate/core'
1414
import { AccountSelectModalComponent } from './components/account-select-modal/account-select-modal.component';
1515
import { AccountModalComponent } from './components/account-modal/account-modal.component';
16+
import { AboutModalComponent } from './components/about-modal/about-modal.component';
1617

1718
@NgModule({
1819
imports: [
@@ -25,6 +26,14 @@ import { AccountModalComponent } from './components/account-modal/account-modal.
2526
NgxScannerQrcodeModule,
2627
TranslateModule.forChild()
2728
],
28-
declarations: [HomePage, AccountListComponent, AccountDetailComponent, CountdownTimerComponent, AccountSelectModalComponent, AccountModalComponent]
29+
declarations: [
30+
HomePage,
31+
AccountListComponent,
32+
AccountDetailComponent,
33+
CountdownTimerComponent,
34+
AccountSelectModalComponent,
35+
AccountModalComponent,
36+
AboutModalComponent
37+
]
2938
})
3039
export class HomePageModule {}

src/app/home/home.page.html

+5-6
Original file line numberDiff line numberDiff line change
@@ -73,21 +73,20 @@
7373
</ion-content>
7474
</ng-template>
7575
</ion-popover>
76+
<ion-item button detail="false" (click)="aboutAction()">
77+
<ion-icon slot="start" name="information-circle-outline"></ion-icon>
78+
<ion-label>{{ "CONFIG_MENU.ABOUT" | translate }}</ion-label>
79+
</ion-item>
7680
<ion-item button detail="false" (click)="logout()">
7781
<ion-icon slot="start" name="log-out-outline"></ion-icon>
7882
<ion-label>{{ "CONFIG_MENU.LOGOUT" | translate }}</ion-label>
7983
</ion-item>
8084
</ion-list>
8185
</ion-content>
82-
<ion-footer *ngIf="versionClickCount < 2;else clickableVersionInfo" class="ion-no-padding ion-no-margin ion-text-center" (click)="showVersionInfoAction()">
83-
<ion-note class="ion-no-padding ion-no-margin">{{ versionInfo.versionName }}</ion-note>
84-
</ion-footer>
85-
<ng-template #clickableVersionInfo>
86-
<ion-footer class="ion-no-padding ion-no-margin ion-text-center ion-activatable ripple-parent version-info" (click)="showVersionInfoAction()">
86+
<ion-footer class="ion-no-padding ion-no-margin ion-text-center ion-activatable ripple-parent version-info">
8787
<ion-ripple-effect></ion-ripple-effect>
8888
<ion-note class="ion-no-padding ion-no-margin">{{ versionInfo.versionName }}</ion-note>
8989
</ion-footer>
90-
</ng-template>
9190
</ng-template>
9291
</ion-popover>
9392
</ion-buttons>

src/app/home/home.page.ts

+8-20
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { LoggingService } from '../services/logging.service';
1515
import { AppVersionInfo } from '../models/app-version.enum';
1616
import { PasswordService } from './password.service';
1717
import { AccountModalComponent } from './components/account-modal/account-modal.component';
18+
import { AboutModalComponent } from './components/about-modal/about-modal.component';
1819

1920
@Component({
2021
selector: 'app-home',
@@ -36,7 +37,6 @@ export class HomePage implements OnInit {
3637
isWindowFocused: boolean = true
3738
hasLockedAccounts: boolean = true
3839
versionInfo: AppVersionInfo
39-
versionClickCount = 0
4040

4141
private encryptionOptions: EncryptionOptions = ENCRYPTION_OPTIONS_DEFAULT
4242
private systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)');
@@ -603,25 +603,13 @@ export class HomePage implements OnInit {
603603
return willInputPassword
604604
}
605605

606-
async showVersionInfoAction(): Promise<void> {
607-
this.versionClickCount += 1
608-
if(this.versionClickCount < 3) {
609-
return
610-
}
611-
if(this.versionClickCount === 3) {
612-
this.loggingService.enableConsole()
613-
}
614-
const versionInfo = this.configService.versionInfo
615-
const title = await firstValueFrom(this.translateService.get('HOME.VERSION_INFO.VERSION_INFO_TITLE'))
616-
const versionLabel = await firstValueFrom(this.translateService.get('HOME.VERSION_INFO.VERSION_LABEL'))
617-
const buildDateLabel = await firstValueFrom(this.translateService.get('HOME.VERSION_INFO.VERSION_DATE'))
618-
const gitHashLabel = await firstValueFrom(this.translateService.get('HOME.VERSION_INFO.GIT_HASH'))
619-
const message = `
620-
<p>${versionLabel}: ${versionInfo.versionName}</p>
621-
<p>${buildDateLabel}: ${versionInfo.buildDate}</p>
622-
<p>${gitHashLabel}: ${versionInfo.commitHash}</p>`
623-
624-
await this.showAlert(message, title)
606+
async aboutAction(): Promise<void> {
607+
// show about modal
608+
const modal = await this.modalController.create({
609+
component: AboutModalComponent,
610+
backdropDismiss: true
611+
})
612+
await modal.present()
625613
}
626614

627615
async enableLogging() {

src/assets/i18n/en.json

+13-14
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@
7979
"IMPORT_ACCOUNTS": "Import Backup",
8080
"LOGOUT": "Sign out",
8181
"PERIODIC_CHECK": "Periodic Password Check",
82-
"UNLOCK_ACCOUNTS": "Decrypt accounts"
82+
"UNLOCK_ACCOUNTS": "Decrypt accounts",
83+
"ABOUT": "About..."
8384
},
8485
"CRYPTO": {
8586
"ALREADY_DECRYPTED": "Data is already decrypted",
@@ -98,13 +99,6 @@
9899
"CONFIRM_LOGOUT_MESSAGE": "<p>All local or unsynchronized accounts will be deleted!</p><p><strong>This action cannot be undone.</strong></p>",
99100
"CONFIRM_LOGOUT_TITLE": "Are you sure you want to sign out?",
100101
"CONFIRM_LOGOUT_YES": "CLEAR LOCAL DATA AND SIGN OUT",
101-
"ENCRYPTION_ALERT": {
102-
"DONT_SHOW_AGAIN": "Do not show this again",
103-
"ENABLE_ENCRYPTION": "Enable encryption",
104-
"LATER": "Not now",
105-
"MESSAGE": "Enhance the security of your accounts by using the encryption feature.<p>Do you want to configure a password?</p>",
106-
"TITLE": "Security alert"
107-
},
108102
"ERRORS": {
109103
"ACCOUNTS_LOCKED": "Your accounts are encrypted. You won't be able to view the codes until they are decrypted using the encryption password.",
110104
"ACCOUNTS_LOCKED_TITLE": "Encrypted accounts detected",
@@ -136,12 +130,6 @@
136130
},
137131
"TITLE": "Password Confirmation"
138132
},
139-
"VERSION_INFO": {
140-
"GIT_HASH": "Commit hash",
141-
"VERSION_DATE": "Build date",
142-
"VERSION_INFO_TITLE": "Version Info",
143-
"VERSION_LABEL": "Version"
144-
},
145133
"UNLOCK_ACCOUNTS": "Enter Password"
146134
},
147135
"LOGIN": {
@@ -171,5 +159,16 @@
171159
},
172160
"UTILS": {
173161
"ERROR_INVALID_SEMVER_FORMAT": "Invalid SemVer format"
162+
},
163+
"ABOUT_MODAL": {
164+
"CLOSE": "Close",
165+
"TITLE": "About",
166+
"VERSION_INFO_HEADER": "Version Info",
167+
"VERSION_INFO": {
168+
"VERSION": "Version",
169+
"BUILD_DATE": "Build date",
170+
"GIT_HASH": "Commit hash"
171+
},
172+
"LICENSES_HEADER": "Third-party Licenses"
174173
}
175174
}

src/assets/i18n/pt.json

+13-14
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@
7979
"IMPORT_ACCOUNTS": "Importar Backup",
8080
"LOGOUT": "Sair",
8181
"PERIODIC_CHECK": "Re-checagem periódica",
82-
"UNLOCK_ACCOUNTS": "Decriptar contas"
82+
"UNLOCK_ACCOUNTS": "Decriptar contas",
83+
"ABOUT": "Sobre..."
8384
},
8485
"CRYPTO": {
8586
"ALREADY_DECRYPTED": "Os dados já estão descriptografados",
@@ -98,13 +99,6 @@
9899
"CONFIRM_LOGOUT_MESSAGE": "<p>Todas as contas locais e não sincronizadas serão excluídas!</p><p><strong>Esta ação não pode ser desfeita.</strong></p>",
99100
"CONFIRM_LOGOUT_TITLE": "Tem certeza de que deseja sair?",
100101
"CONFIRM_LOGOUT_YES": "LIMPAR DADOS LOCAIS E SAIR",
101-
"ENCRYPTION_ALERT": {
102-
"DONT_SHOW_AGAIN": "Não mostrar novamente",
103-
"ENABLE_ENCRYPTION": "Ativar criptografia",
104-
"LATER": "Mais tarde",
105-
"MESSAGE": "Para melhor proteger suas contas, é recomendável ativar a funcionalidade de criptografia de chaves.<p>Deseja configurar uma senha agora?</p>",
106-
"TITLE": "Alerta de segurança"
107-
},
108102
"ERRORS": {
109103
"ACCOUNTS_LOCKED": "Suas contas estão criptografadas. Não será possível gerar os códigos de acesso até que eles sejam descriptografados usando a senha de criptografia.",
110104
"ACCOUNTS_LOCKED_TITLE": "Contas criptografadas",
@@ -136,12 +130,6 @@
136130
},
137131
"TITLE": "Confirmação de Senha"
138132
},
139-
"VERSION_INFO": {
140-
"GIT_HASH": "Hash do commit",
141-
"VERSION_DATE": "Data de build",
142-
"VERSION_INFO_TITLE": "Informações de Versão",
143-
"VERSION_LABEL": "Versão"
144-
},
145133
"UNLOCK_ACCOUNTS": "Inserir Senha"
146134
},
147135
"LOGIN": {
@@ -171,5 +159,16 @@
171159
},
172160
"UTILS": {
173161
"ERROR_INVALID_SEMVER_FORMAT": "Formato SemVer inválido"
162+
},
163+
"ABOUT_MODAL": {
164+
"CLOSE": "Fechar",
165+
"TITLE": "Sobre",
166+
"VERSION_INFO_HEADER": "Informações de Versão",
167+
"VERSION_INFO": {
168+
"VERSION": "Número da versão",
169+
"BUILD_DATE": "Data de build",
170+
"GIT_HASH": "Hash do commit"
171+
},
172+
"LICENSES_HEADER": "Licenças"
174173
}
175174
}

0 commit comments

Comments
 (0)