Merge pull request #58 from tomfong/post-v3.0.1-dev

v3.1.0
This commit is contained in:
Tom Fong 2022-10-18 12:59:08 +08:00 committed by GitHub
commit 9263e05a2d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 3193 additions and 5437 deletions

View file

@ -103,11 +103,10 @@ You are welcomed to help translate the app into more languages (refer to this <a
* <b>DO NOT</b> change the order.
4. Email the JSON to me (tomfong.dev@gmail.com) after you finish.
### Build the project (Android)
### Build the project
1. Run ```npm install``` to install all dependencies.
2. Run ```npm run build:an``` or ```npm run build:ios``` (for first time).
3. Run ```npm run sync``` and ```npm run copy:an``` or ```npm run copy:ios```.
2. Run ```npm run build```
### Contributors
@ -122,10 +121,10 @@ Thank you the following contributors who have made the app better!
```sh
Ionic CLI : 6.20.1
Ionic Framework : @ionic/angular 6.2.8
@angular-devkit/build-angular : 14.2.3
@angular-devkit/schematics : 13.3.9
@angular/cli : 14.2.3
Ionic Framework : @ionic/angular 6.3.2
@angular-devkit/build-angular : 14.2.6
@angular-devkit/schematics : 14.2.6
@angular/cli : 14.2.6
@ionic/angular-toolkit : 6.1.0
Capacitor CLI : 4.3.0
@ -134,7 +133,7 @@ Thank you the following contributors who have made the app better!
@capacitor/ios : 4.3.0
NodeJS : v16.15.1
npm : 8.11.0
npm : 8.19.2
```
## Privacy Policy

View file

@ -6,8 +6,8 @@ android {
applicationId "com.tomfong.simpleqr"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 3000100
versionName "3.0.1"
versionCode 3010000
versionName "3.1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.

View file

@ -19,6 +19,7 @@ dependencies {
implementation project(':capacitor-filesystem')
implementation project(':capacitor-haptics')
implementation project(':capacitor-keyboard')
implementation project(':capacitor-preferences')
implementation project(':capacitor-splash-screen')
implementation project(':capacitor-status-bar')
implementation project(':capacitor-toast')

View file

@ -1,7 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.tomfong.simpleqr">
<application android:hardwareAccelerated="true" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:requestLegacyExternalStorage="true" android:largeHeap="true">
<application
android:hardwareAccelerated="true"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:requestLegacyExternalStorage="true"
android:largeHeap="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:name="com.tomfong.simpleqr.MainActivity" android:label="@string/title_activity_main" android:theme="@style/AppTheme.NoActionBarLaunch" android:launchMode="singleTask" android:exported="true">

View file

@ -39,6 +39,10 @@
"pkg": "@capacitor/keyboard",
"classpath": "com.capacitorjs.plugins.keyboard.KeyboardPlugin"
},
{
"pkg": "@capacitor/preferences",
"classpath": "com.capacitorjs.plugins.preferences.PreferencesPlugin"
},
{
"pkg": "@capacitor/splash-screen",
"classpath": "com.capacitorjs.plugins.splashscreen.SplashScreenPlugin"

View file

@ -11,6 +11,8 @@ import androidx.annotation.RequiresApi;
@RequiresApi(api = Build.VERSION_CODES.N)
public class MyQSTileService extends TileService {
public MyQSTileService() {}
// Called when the user adds your tile.
@Override
public void onTileAdded() {

View file

@ -32,6 +32,9 @@ project(':capacitor-haptics').projectDir = new File('../node_modules/@capacitor/
include ':capacitor-keyboard'
project(':capacitor-keyboard').projectDir = new File('../node_modules/@capacitor/keyboard/android')
include ':capacitor-preferences'
project(':capacitor-preferences').projectDir = new File('../node_modules/@capacitor/preferences/android')
include ':capacitor-splash-screen'
project(':capacitor-splash-screen').projectDir = new File('../node_modules/@capacitor/splash-screen/android')

View file

@ -396,7 +396,7 @@
INFOPLIST_FILE = App/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 3.0.1;
MARKETING_VERSION = 3.1.0;
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
PRODUCT_BUNDLE_IDENTIFIER = com.tomfong.simpleqr;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -419,7 +419,7 @@
INFOPLIST_FILE = App/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 3.0.1;
MARKETING_VERSION = 3.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tomfong.simpleqr;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Simple QR";

View file

@ -21,6 +21,7 @@ def capacitor_pods
pod 'CapacitorFilesystem', :path => '../../node_modules/@capacitor/filesystem'
pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics'
pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard'
pod 'CapacitorPreferences', :path => '../../node_modules/@capacitor/preferences'
pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar'
pod 'CapacitorToast', :path => '../../node_modules/@capacitor/toast'

6101
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{
"name": "simple-qr",
"version": "3.0.1",
"version": "3.1.0",
"author": "Tom Fong",
"homepage": "https://tomfong.github.io",
"scripts": {
@ -21,37 +21,38 @@
"@angular/cdk": "^14.2.2",
"@angular/common": "^14.2.3",
"@angular/core": "^14.2.3",
"@angular/forms": "^14.2.3",
"@angular/localize": "^14.2.3",
"@angular/forms": "^14.2.6",
"@angular/localize": "^14.2.6",
"@angular/material": "^14.2.2",
"@angular/material-moment-adapter": "^14.2.2",
"@angular/material-moment-adapter": "^14.2.5",
"@angular/platform-browser": "^14.2.3",
"@angular/platform-browser-dynamic": "^14.2.3",
"@angular/router": "^14.2.3",
"@awesome-cordova-plugins/aes-256": "^5.45.0",
"@awesome-cordova-plugins/chooser": "^5.45.0",
"@awesome-cordova-plugins/core": "^5.45.0",
"@awesome-cordova-plugins/screen-orientation": "^5.45.0",
"@awesome-cordova-plugins/sms": "^5.45.0",
"@awesome-cordova-plugins/social-sharing": "^5.45.0",
"@awesome-cordova-plugins/theme-detection": "^5.45.0",
"@angular/platform-browser-dynamic": "^14.2.6",
"@angular/router": "^14.2.6",
"@awesome-cordova-plugins/aes-256": "^6.0.1",
"@awesome-cordova-plugins/chooser": "^6.0.1",
"@awesome-cordova-plugins/core": "^6.0.1",
"@awesome-cordova-plugins/screen-orientation": "^6.0.1",
"@awesome-cordova-plugins/sms": "^6.0.1",
"@awesome-cordova-plugins/social-sharing": "^6.0.1",
"@awesome-cordova-plugins/theme-detection": "^6.0.1",
"@capacitor-community/barcode-scanner": "^3.0.0",
"@capacitor-community/contacts": "^2.0.0-0",
"@capacitor-community/screen-brightness": "^2.0.0-0",
"@capacitor/android": "^4.3.0",
"@capacitor/app": "^4.0.1",
"@capacitor/camera": "^4.1.1",
"@capacitor/camera": "^4.1.2",
"@capacitor/clipboard": "^4.0.1",
"@capacitor/core": "^4.3.0",
"@capacitor/device": "^4.0.1",
"@capacitor/filesystem": "^4.1.1",
"@capacitor/filesystem": "^4.1.2",
"@capacitor/haptics": "^4.0.1",
"@capacitor/ios": "^4.3.0",
"@capacitor/keyboard": "^4.0.1",
"@capacitor/splash-screen": "^4.0.1",
"@capacitor/preferences": "^4.0.1",
"@capacitor/splash-screen": "^4.1.0",
"@capacitor/status-bar": "^4.0.1",
"@capacitor/toast": "^4.0.1",
"@ionic/angular": "^6.2.8",
"@ionic/angular": "^6.3.2",
"@ionic/storage": "^3.0.6",
"@ionic/storage-angular": "^3.0.6",
"@ng-bootstrap/ng-bootstrap": "^13.0.0",
@ -79,11 +80,11 @@
"zone.js": "^0.11.8"
},
"devDependencies": {
"@angular-devkit/build-angular": "^14.2.3",
"@angular/cli": "^14.2.3",
"@angular-devkit/build-angular": "^14.2.6",
"@angular/cli": "^14.2.6",
"@angular/compiler": "^14.2.3",
"@angular/compiler-cli": "^14.2.3",
"@angular/language-service": "^14.2.3",
"@angular/language-service": "^14.2.6",
"@capacitor/cli": "^4.3.0",
"@ionic/angular-toolkit": "^6.1.0",
"@ionic/cli": "6.20.1",

View file

@ -19,14 +19,12 @@ import { ScreenOrientation } from '@awesome-cordova-plugins/screen-orientation/n
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatFormFieldModule } from '@angular/material/form-field';
import { HistoryTutorialPageModule } from './modals/history-tutorial/history-tutorial.module';
import { DatePipe } from '@angular/common';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatButtonModule } from '@angular/material/button';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { EnvService } from './services/env.service';
import { FormsModule } from '@angular/forms';
import { BookmarkTutorialPageModule } from './modals/bookmark-tutorial/bookmark-tutorial.module';
import { QrCodePageModule } from './modals/qr-code/qr-code.module';
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
@ -51,8 +49,6 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
}
}),
IonicStorageModule.forRoot(),
HistoryTutorialPageModule,
BookmarkTutorialPageModule,
QrCodePageModule,
BrowserAnimationsModule,
MatFormFieldModule,

View file

@ -1,40 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { BookmarkTutorialPage } from './bookmark-tutorial.page';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HttpClient } from '@angular/common/http';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
MatSelectModule,
TranslateModule.forChild({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
}),
],
declarations: [BookmarkTutorialPage]
})
export class BookmarkTutorialPageModule {}

View file

@ -1,57 +0,0 @@
<ion-header class="ion-no-border">
<ion-toolbar [color]="color">
</ion-toolbar>
</ion-header>
<ion-content [color]="color" #content>
<ion-list-header class="mt-4 ml-3" style="font-size: x-large;">{{ 'TUTORIAL' | translate }}</ion-list-header>
<ion-item class="content-item ion-no-padding" lines="none" [color]="color">
<ion-icon class="ion-padding-horizontal" src="assets/icon/swipe-left.svg"
[color]="'primary'"></ion-icon>
<ion-label>
<p class="ion-padding">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="white-space: normal;">
{{ 'MSG.TUTORIAL_SWIPE_LEFT' | translate }}
</ion-text>
</p>
</ion-label>
</ion-item>
<ion-item class="content-item ion-no-padding" lines="none" [color]="color">
<ion-icon class="ion-padding-horizontal" src="assets/icon/swipe-right.svg"
[color]="'primary'"></ion-icon>
<ion-label>
<p class="ion-padding">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="white-space: normal;">
{{ 'MSG.BOOKMARK_TUTORIAL_SWIPE_RIGHT' | translate }}
</ion-text>
</p>
</ion-label>
</ion-item>
</ion-content>
<ion-footer>
<ion-item lines="none" [color]="color" style="--ripple-color: transparent;">
<ion-checkbox class="ion-margin-horizontal" [(ngModel)]="env.notShowBookmarkTutorial"
[color]="'primary'" (ionChange)="saveBookmarkTutorialShowing()"></ion-checkbox>
<ion-label>
<p class="ion-padding">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="white-space: normal;">
{{ 'MSG.TUTORIAL_NOT_SHOW_AGAIN' | translate }}
</ion-text>
</p>
</ion-label>
</ion-item>
<ion-toolbar [color]="color" style="border: none;">
<ion-row class="d-flex align-items-center justify-content-end">
<ion-button class="ion-margin-horizontal ion-margin-bottom" fill="clear" (click)="tapHaptic(); closeModal()" color="primary">
{{ 'OK' | translate }}
</ion-button>
</ion-row>
</ion-toolbar>
</ion-footer>

View file

@ -1,18 +0,0 @@
mat-form-field {
width: 100%;
}
.content-item {
padding-left: 16px;
padding-right: 16px;
}
ion-footer {
&.footer-md::before {
background-image: none;
}
}
.footer-ios ion-toolbar:first-of-type {
--border-width: 0 !important;
}

View file

@ -1,65 +0,0 @@
import { Component, ViewChild } from '@angular/core';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { Toast } from '@capacitor/toast';
import { ModalController } from '@ionic/angular';
import { TranslateService } from '@ngx-translate/core';
import { EnvService } from 'src/app/services/env.service';
@Component({
selector: 'app-bookmark-tutorial',
templateUrl: './bookmark-tutorial.page.html',
styleUrls: ['./bookmark-tutorial.page.scss'],
})
export class BookmarkTutorialPage {
@ViewChild('content') contentEl: HTMLIonContentElement;
constructor(
public modalController: ModalController,
public translate: TranslateService,
public env: EnvService,
) {
setTimeout(
() => {
this.contentEl.scrollToBottom(500);
}, 750
);
}
async saveBookmarkTutorialShowing() {
if (this.env.notShowBookmarkTutorial === true) {
await this.env.storageSet("not-show-bookmark-tutorial", 'yes');
} else {
await this.env.storageSet("not-show-bookmark-tutorial", 'no');
}
}
async tapHaptic() {
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
await Haptics.impact({ style: ImpactStyle.Medium })
.catch(async err => {
if (this.env.debugMode === 'on') {
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
}
})
}
}
closeModal(): void {
this.modalController.dismiss();
}
get color() {
switch (this.env.colorTheme) {
case 'dark':
return 'dark';
case 'light':
return 'white';
case 'black':
return 'black';
default:
return 'white';
}
}
}

View file

@ -1,39 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { HistoryTutorialPage } from './history-tutorial.page';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HttpClient } from '@angular/common/http';
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
MatSelectModule,
TranslateModule.forChild({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
}),
],
declarations: [HistoryTutorialPage]
})
export class HistoryTutorialPageModule {}

View file

@ -1,57 +0,0 @@
<ion-header class="ion-no-border">
<ion-toolbar [color]="color">
</ion-toolbar>
</ion-header>
<ion-content [color]="color" #content>
<ion-list-header class="mt-4 ml-3" style="font-size: x-large;">{{ 'TUTORIAL' | translate }}</ion-list-header>
<ion-item class="content-item ion-no-padding" lines="none" [color]="color">
<ion-icon class="ion-padding-horizontal" src="assets/icon/swipe-left.svg"
[color]="'primary'"></ion-icon>
<ion-label>
<p class="ion-padding">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="white-space: normal;">
{{ 'MSG.TUTORIAL_SWIPE_LEFT' | translate }}
</ion-text>
</p>
</ion-label>
</ion-item>
<ion-item class="content-item ion-no-padding" lines="none" [color]="color">
<ion-icon class="ion-padding-horizontal" src="assets/icon/swipe-right.svg"
[color]="'primary'"></ion-icon>
<ion-label>
<p class="ion-padding">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="white-space: normal;">
{{ 'MSG.TUTORIAL_SWIPE_RIGHT' | translate }}
</ion-text>
</p>
</ion-label>
</ion-item>
</ion-content>
<ion-footer>
<ion-item lines="none" [color]="color" style="--ripple-color: transparent;">
<ion-checkbox class="ion-margin-horizontal" [(ngModel)]="env.notShowHistoryTutorial"
[color]="'primary'" (ionChange)="saveHistoryTutorialShowing()"></ion-checkbox>
<ion-label>
<p class="ion-padding">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="white-space: normal;">
{{ 'MSG.TUTORIAL_NOT_SHOW_AGAIN' | translate }}
</ion-text>
</p>
</ion-label>
</ion-item>
<ion-toolbar [color]="color" style="border: none;">
<ion-row class="d-flex align-items-center justify-content-end">
<ion-button class="ion-margin-horizontal ion-margin-bottom" fill="clear" (click)="tapHaptic(); closeModal()" color="primary">
{{ 'OK' | translate }}
</ion-button>
</ion-row>
</ion-toolbar>
</ion-footer>

View file

@ -1,18 +0,0 @@
mat-form-field {
width: 100%;
}
.content-item {
padding-left: 16px;
padding-right: 16px;
}
ion-footer {
&.footer-md::before {
background-image: none;
}
}
.footer-ios ion-toolbar:first-of-type {
--border-width: 0 !important;
}

View file

@ -1,65 +0,0 @@
import { Component, ViewChild } from '@angular/core';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { Toast } from '@capacitor/toast';
import { ModalController, ToastController } from '@ionic/angular';
import { TranslateService } from '@ngx-translate/core';
import { EnvService } from 'src/app/services/env.service';
@Component({
selector: 'app-history-tutorial',
templateUrl: './history-tutorial.page.html',
styleUrls: ['./history-tutorial.page.scss'],
})
export class HistoryTutorialPage {
@ViewChild('content') contentEl: HTMLIonContentElement;
constructor(
public modalController: ModalController,
public translate: TranslateService,
public env: EnvService,
) {
setTimeout(
() => {
this.contentEl.scrollToBottom(500);
}, 750
);
}
async saveHistoryTutorialShowing() {
if (this.env.notShowHistoryTutorial === true) {
await this.env.storageSet("not-show-history-tutorial", 'yes');
} else {
await this.env.storageSet("not-show-history-tutorial", 'no');
}
}
async tapHaptic() {
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
await Haptics.impact({ style: ImpactStyle.Medium })
.catch(async err => {
if (this.env.debugMode === 'on') {
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
}
})
}
}
closeModal(): void {
this.modalController.dismiss();
}
get color() {
switch (this.env.colorTheme) {
case 'dark':
return 'dark';
case 'light':
return 'white';
case 'black':
return 'black';
default:
return 'white';
}
}
}

View file

@ -10,6 +10,7 @@ import { NgxQrcodeElementTypes, NgxQrcodeErrorCorrectionLevels, QrcodeComponent
import { EnvService } from 'src/app/services/env.service';
import { ScreenBrightness } from '@capacitor-community/screen-brightness';
import { rgbToHex } from 'src/app/utils/helpers';
import { Preferences } from '@capacitor/preferences';
@Component({
selector: 'app-qr-code',
@ -149,7 +150,7 @@ export class QrCodePage {
async onErrorCorrectionLevelChange() {
this.setErrorCorrectionLevel();
await this.env.storageSet("error-correction-level", this.env.errorCorrectionLevel);
await Preferences.set({ key: this.env.KEY_ERROR_CORRECTION_LEVEL, value: this.env.errorCorrectionLevel });
if (this.qrcodeElement != null) {
this.qrcodeElement.errorCorrectionLevel = this.errorCorrectionLevel;
} else {

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'ABOUT' | translate }}</ion-title>

View file

@ -1,4 +1,5 @@
import { Component } from '@angular/core';
import { Preferences } from '@capacitor/preferences';
import { Toast } from '@capacitor/toast';
import { AlertController, Platform } from '@ionic/angular';
import { TranslateService } from '@ngx-translate/core';
@ -89,7 +90,7 @@ export class AboutPage {
if (this.env.debugMode != 'on') {
if (this.tapAppVersionTimes >= 5) {
this.env.debugMode = 'on';
await this.env.storageSet("debug-mode-on", 'on');
await Preferences.set({ key: this.env.KEY_DEBUG_MODE, value: 'on' });
await Toast.show({
text: this.translate.instant("MSG.DEBUG_MODE_ON"),
duration: "short",

View file

@ -4,7 +4,6 @@ import { Router } from '@angular/router';
import { Haptics, ImpactStyle, NotificationType } from '@capacitor/haptics';
import { AlertController, LoadingController, ToastController } from '@ionic/angular';
import { TranslateService } from '@ngx-translate/core';
// import * as moment from 'moment';
import { format } from 'date-fns';
import { EnvService } from 'src/app/services/env.service';
import { Toast } from '@capacitor/toast';
@ -296,8 +295,8 @@ export class GeneratePage {
}
async processQrCode(loading: HTMLIonLoadingElement): Promise<void> {
this.env.result = this.qrCodeContent;
this.env.resultFormat = "";
this.env.resultContent = this.qrCodeContent;
this.env.resultContentFormat = "";
this.qrCodeContent = '';
this.env.recordSource = "create";
this.env.detailedRecordSource = "create";

View file

@ -6,7 +6,7 @@
<ion-title>{{ 'SIMPLE_QR' | translate}}</ion-title>
<ion-buttons slot="end">
<ion-button (click)="tapHaptic(); goSetting()" fill="clear">
{{ 'SETTING' | translate }}
{{ 'MORE' | translate }}
</ion-button>
</ion-buttons>
</ion-toolbar>
@ -17,7 +17,7 @@
<ion-title *ngIf="segmentModel === 'bookmarks'">{{ 'BOOKMARKS' | translate }}</ion-title>
<ion-buttons slot="end">
<ion-button (click)="tapHaptic(); goSetting()" fill="clear" color="primary">
{{ 'SETTING' | translate }}
{{ 'MORE' | translate }}
</ion-button>
</ion-buttons>
</ion-toolbar>

View file

@ -7,10 +7,8 @@ import { de, enUS, fr, it, zhCN, zhHK } from 'date-fns/locale';
import { ScanRecord } from 'src/app/models/scan-record';
import { TranslateService } from '@ngx-translate/core';
import { Bookmark } from 'src/app/models/bookmark';
import { HistoryTutorialPage } from 'src/app/modals/history-tutorial/history-tutorial.page';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { Toast } from '@capacitor/toast';
import { BookmarkTutorialPage } from 'src/app/modals/bookmark-tutorial/bookmark-tutorial.page';
import { fastFadeIn, flyOut } from 'src/app/utils/animations';
import { SplashScreen } from '@capacitor/splash-screen';
@ -100,19 +98,6 @@ export class HistoryPage {
async ionViewDidEnter() {
await SplashScreen.hide()
this.segmentModel = this.env.historyPageStartSegment;
if (this.segmentModel == 'history') {
if (this.env.notShowHistoryTutorial === false) {
this.env.notShowHistoryTutorial = true;
this.env.storageSet("not-show-history-tutorial", 'yes');
await this.showHistoryTutorial();
}
} else if (this.segmentModel == 'bookmarks') {
if (this.env.notShowBookmarkTutorial === false) {
this.env.notShowBookmarkTutorial = true;
this.env.storageSet("not-show-bookmark-tutorial", 'yes');
await this.showBookmarkTutorial();
}
}
}
ionViewWillLeave() {
@ -135,24 +120,6 @@ export class HistoryPage {
return bookmark.id;
}
async showHistoryTutorial() {
const modal = await this.modalController.create({
component: HistoryTutorialPage,
componentProps: {
}
});
modal.present();
}
async showBookmarkTutorial() {
const modal = await this.modalController.create({
component: BookmarkTutorialPage,
componentProps: {
}
});
modal.present();
}
maskDatetimeAndSource(date: Date, source: 'create' | 'view' | 'scan' | undefined): string {
if (!date) {
return "-";
@ -231,7 +198,7 @@ export class HistoryPage {
case "RSS_EXPANDED":
return this.translate.instant("BARCODE_TYPE.RSS").trim();
default:
return this.env.resultFormat;
return this.env.resultContentFormat;
}
}
@ -243,8 +210,8 @@ export class HistoryPage {
this.changeDetectorRef.detectChanges();
this.changeDetectorRef.reattach();
const loading = await this.presentLoading(this.translate.instant('PLEASE_WAIT'));
this.env.result = data;
this.env.resultFormat = "";
this.env.resultContent = data;
this.env.resultContentFormat = "";
this.env.recordSource = "view";
this.env.detailedRecordSource = source;
this.env.viewResultFrom = "/tabs/history";
@ -256,19 +223,6 @@ export class HistoryPage {
}
async segmentChanged(ev: any) {
if (ev?.detail?.value == 'history') {
if (this.env.notShowHistoryTutorial === false) {
this.env.notShowHistoryTutorial = true;
this.env.storageSet("not-show-history-tutorial", 'yes');
await this.showHistoryTutorial();
}
} else if (ev?.detail?.value == 'bookmarks') {
if (this.env.notShowBookmarkTutorial === false) {
this.env.notShowBookmarkTutorial = true;
this.env.storageSet("not-show-bookmark-tutorial", 'yes');
await this.showBookmarkTutorial();
}
}
this.firstLoadItems();
}

View file

@ -101,8 +101,8 @@ export class ImportImagePage {
}
async processQrCode(scannedData: string, loading: HTMLIonLoadingElement): Promise<void> {
this.env.result = scannedData;
this.env.resultFormat = "QR_CODE";
this.env.resultContent = scannedData;
this.env.resultContentFormat = "QR_CODE";
this.env.recordSource = "scan";
this.env.detailedRecordSource = "scan-image";
this.env.viewResultFrom = "/tabs/import-image";

View file

@ -28,7 +28,7 @@
</ion-row>
<ng-container *ngIf="qrCodeContent && qrCodeContent.trim().length > 0" [ngTemplateOutlet]="contentBlock"
[ngTemplateOutletContext]="{ label: barcodeFormat + ('CONTENT' | translate), content: qrCodeContent, hint: env.resultFormat }">
[ngTemplateOutletContext]="{ label: barcodeFormat + ('CONTENT' | translate), content: qrCodeContent, hint: env.resultContentFormat }">
</ng-container>
<ng-container *ngIf="base64Encoded && qrCodeContent && qrCodeContent.trim().length > 0"
@ -178,6 +178,8 @@
</ion-icon>
<ion-icon *ngIf="env.searchEngine === 'yandex'" slot="icon-only" src="assets/icon/yandex.svg">
</ion-icon>
<ion-icon *ngIf="env.searchEngine === 'ecosia'" slot="icon-only" src="assets/icon/ecosia.svg">
</ion-icon>
</ion-button>
<ion-button *ngIf="env.showCopyButton === 'on'" (click)="tapHaptic(); copyText()"
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="clear"
@ -258,6 +260,8 @@
</ion-icon>
<ion-icon class="pr-2" *ngIf="env.searchEngine === 'yandex'" slot="icon-only" src="assets/icon/yandex.svg">
</ion-icon>
<ion-icon class="pr-2" *ngIf="env.searchEngine === 'ecosia'" slot="icon-only" src="assets/icon/ecosia.svg">
</ion-icon>
<ion-label>{{ 'SEARCH' | translate}}</ion-label>
</ion-button>
<ion-button class="pr-1" *ngIf="env.showCopyButton === 'on'" (click)="tapHaptic(); copyText()"

View file

@ -1,4 +1,4 @@
import { Component, OnInit, QueryList, ViewChildren } from '@angular/core';
import { Component, QueryList, ViewChildren } from '@angular/core';
import { Clipboard } from '@capacitor/clipboard';
import { Contacts, ContactType, EmailAddress, NewContact, PhoneNumber } from '@capacitor-community/contacts'
import { SMS } from '@awesome-cordova-plugins/sms/ngx';
@ -81,7 +81,7 @@ export class ResultPage {
this.showQrFirst = true;
}
}
this.qrCodeContent = this.env.result;
this.qrCodeContent = this.env.resultContent;
this.setContentType();
}
@ -92,7 +92,7 @@ export class ResultPage {
await this.enlarge();
}
}
if (this.env.scanRecordLogging == 'on') {
if (this.env.scanRecordLogging == 'on' && this.qrCodeContent != null && this.qrCodeContent != "") {
await this.env.saveScanRecord(this.qrCodeContent);
}
if (this.env.bookmarks.find(x => x.text == this.qrCodeContent)) {
@ -397,6 +397,9 @@ export class ResultPage {
case 'yandex':
searchUrl = this.env.YANDEX_SEARCH_URL;
break;
case 'ecosia':
searchUrl = this.env.ECOSIA_SEARCH_URL;
break;
default:
searchUrl = this.env.GOOGLE_SEARCH_URL;
break;
@ -613,7 +616,6 @@ export class ResultPage {
lines.forEach(
line => {
const tLine = line.trim();
console.log(tLine);
if (tLine.toUpperCase().substr(0, fullNameId1.length) === fullNameId1) {
this.vCardContact.fullName = tLine.substr(fullNameId1.length);
} else if (tLine.toUpperCase().substr(0, fullNameId2.length) === fullNameId2) {
@ -810,15 +812,6 @@ export class ResultPage {
await alert.present();
}
// async removeBookmark() {
// await this.env.deleteBookmark(this.qrCodeContent);
// if (this.env.bookmarks.find(x => x.text === this.qrCodeContent)) {
// this.bookmarked = true;
// } else {
// this.bookmarked = false;
// }
// }
get contentTypeText(): string {
switch (this.contentType) {
case 'freeText':
@ -866,7 +859,7 @@ export class ResultPage {
}
get barcodeFormat(): string {
switch (this.env.resultFormat) {
switch (this.env.resultContentFormat) {
case "UPC_A":
return this.translate.instant("BARCODE_TYPE.UPC");
case "UPC_E":
@ -906,7 +899,7 @@ export class ResultPage {
case "RSS_EXPANDED":
return this.translate.instant("BARCODE_TYPE.RSS");
default:
return this.env.resultFormat;
return this.env.resultContentFormat;
}
}

View file

@ -109,7 +109,7 @@ export class ScanPage {
async (result: ScanResult) => {
if (result.hasContent) {
const text = result.content;
if (text === undefined || text === null || (text && text.trim().length <= 0) || text === "") {
if (text == null || text?.trim()?.length <= 0 || text == "") {
this.presentToast(this.translate.instant('MSG.QR_CODE_VALUE_NOT_EMPTY'), "short", "center");
this.scanQr();
return;
@ -137,8 +137,8 @@ export class ScanPage {
}
async processQrCode(scannedData: string, format: string, loading: HTMLIonLoadingElement): Promise<void> {
this.env.result = scannedData;
this.env.resultFormat = format;
this.env.resultContent = scannedData;
this.env.resultContentFormat = format;
this.env.recordSource = "scan";
this.env.detailedRecordSource = "scan-camera";
this.env.viewResultFrom = "/tabs/scan";

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'AUTO_MAX_BRIGHTNESS' | translate }}</ion-title>

View file

@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { Preferences } from '@capacitor/preferences';
import { Toast } from '@capacitor/toast';
import { EnvService } from 'src/app/services/env.service';
@ -15,12 +16,12 @@ export class SettingAutoBrightnessPage {
) { }
async saveAutoMaxBrightness() {
await this.env.storageSet("auto-max-brightness", this.env.autoMaxBrightness);
await Preferences.set({ key: this.env.KEY_AUTO_MAX_BRIGHTNESS, value: this.env.autoMaxBrightness });
}
async onAutoMaxBrightnessChange(ev: any) {
this.env.autoMaxBrightness = ev ? 'on' : 'off';
await this.env.storageSet("auto-max-brightness", this.env.autoMaxBrightness);
await Preferences.set({ key: this.env.KEY_AUTO_MAX_BRIGHTNESS, value: this.env.autoMaxBrightness });
await this.tapHaptic();
}

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'AUTO_KILL_BACKGROUND' | translate }}</ion-title>

View file

@ -1,4 +1,5 @@
import { Component } from '@angular/core';
import { Preferences } from '@capacitor/preferences';
import { EnvService } from 'src/app/services/env.service';
@Component({
@ -13,6 +14,6 @@ export class SettingAutoExitPage{
) { }
async saveAutoExitAppMin() {
await this.env.storageSet("autoExitAppMin", this.env.autoExitAppMin);
await Preferences.set({ key: this.env.KEY_AUTO_EXIT_MIN, value: JSON.stringify(this.env.autoExitAppMin) });
}
}

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'AUTO_QR_CODE_POPUP' | translate }}</ion-title>

View file

@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { Preferences } from '@capacitor/preferences';
import { Toast } from '@capacitor/toast';
import { EnvService } from 'src/app/services/env.service';
@ -16,31 +17,31 @@ export class SettingAutoQrPage {
async onShowQrAfterCameraScanChange(ev: any) {
this.env.showQrAfterCameraScan = ev ? 'on' : 'off';
await this.env.storageSet("show-qr-after-camera-scan", this.env.showQrAfterCameraScan);
await Preferences.set({ key: this.env.KEY_SHOW_QR_AFTER_CAMERA_SCAN, value: this.env.showQrAfterCameraScan });
await this.tapHaptic();
}
async onShowQrAfterImageScanChange(ev: any) {
this.env.showQrAfterImageScan = ev ? 'on' : 'off';
await this.env.storageSet("show-qr-after-image-scan", this.env.showQrAfterImageScan);
await Preferences.set({ key: this.env.KEY_SHOW_QR_AFTER_IMAGE_SCAN, value: this.env.showQrAfterImageScan });
await this.tapHaptic();
}
async onShowQrAfterCreateChange(ev: any) {
this.env.showQrAfterCreate = ev ? 'on' : 'off';
await this.env.storageSet("show-qr-after-create", this.env.showQrAfterCreate);
await Preferences.set({ key: this.env.KEY_SHOW_QR_AFTER_CREATE, value: this.env.showQrAfterCreate });
await this.tapHaptic();
}
async onShowQrAfterLogViewChange(ev: any) {
this.env.showQrAfterLogView = ev ? 'on' : 'off';
await this.env.storageSet("show-qr-after-log-view", this.env.showQrAfterLogView);
await Preferences.set({ key: this.env.KEY_SHOW_QR_AFTER_LOG_VIEW, value: this.env.showQrAfterLogView });
await this.tapHaptic();
}
async onShowQrAfterBookmarkViewChange(ev: any) {
this.env.showQrAfterBookmarkView = ev ? 'on' : 'off';
await this.env.storageSet("show-qr-after-bookmark-view", this.env.showQrAfterBookmarkView);
await Preferences.set({ key: this.env.KEY_SHOW_QR_AFTER_BOOKMARK_VIEW, value: this.env.showQrAfterBookmarkView });
await this.tapHaptic();
}

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'COLOR_THEME' | translate }}</ion-title>

View file

@ -1,5 +1,6 @@
import { OverlayContainer } from '@angular/cdk/overlay';
import { Component } from '@angular/core';
import { Preferences } from '@capacitor/preferences';
import { TranslateService } from '@ngx-translate/core';
import { EnvService } from 'src/app/services/env.service';
@ -18,7 +19,7 @@ export class SettingColorPage {
async saveColorTheme() {
await this.env.toggleColorTheme();
await this.env.storageSet("color", this.env.selectedColorTheme);
await Preferences.set({ key: this.env.KEY_COLOR, value: this.env.selectedColorTheme });
}
}

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'DEBUG_MODE' | translate }}</ion-title>

View file

@ -1,4 +1,5 @@
import { Component } from '@angular/core';
import { Preferences } from '@capacitor/preferences';
import { TranslateService } from '@ngx-translate/core';
import { EnvService } from 'src/app/services/env.service';
@ -15,7 +16,7 @@ export class SettingDebugPage {
) { }
async saveDebugMode() {
await this.env.storageSet("debug-mode-on", this.env.debugMode);
await Preferences.set({ key: this.env.KEY_DEBUG_MODE, value: this.env.debugMode });
}
}

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'LANGUAGE' | translate }}</ion-title>

View file

@ -1,4 +1,5 @@
import { Component } from '@angular/core';
import { Preferences } from '@capacitor/preferences';
import { TranslateService } from '@ngx-translate/core';
import { EnvService } from 'src/app/services/env.service';
@ -16,6 +17,6 @@ export class SettingLanguagePage {
async saveLanguage() {
this.env.toggleLanguageChange();
await this.env.storageSet("language", this.env.selectedLanguage);
await Preferences.set({ key: this.env.KEY_LANGUAGE, value: this.env.selectedLanguage });
}
}

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'SCREEN_ORIENTATION' | translate }}</ion-title>

View file

@ -1,4 +1,5 @@
import { Component } from '@angular/core';
import { Preferences } from '@capacitor/preferences';
import { EnvService } from 'src/app/services/env.service';
@Component({
@ -14,6 +15,6 @@ export class SettingOrientationPage {
async saveOrientation() {
await this.env.toggleOrientationChange();
await this.env.storageSet("orientation", this.env.orientation);
await Preferences.set({ key: this.env.KEY_ORIENTATION, value: this.env.orientation });
}
}

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'QR_CODE_STYLE' | translate }}</ion-title>

View file

@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { Preferences } from '@capacitor/preferences';
import { Toast } from '@capacitor/toast';
import { AlertController, Platform } from '@ionic/angular';
import { TranslateService } from '@ngx-translate/core';
@ -68,35 +69,35 @@ export class SettingQrPage {
async saveErrorCorrectionLevel() {
this.setErrorCorrectionLevel();
await this.env.storageSet("error-correction-level", this.env.errorCorrectionLevel);
await Preferences.set({ key: this.env.KEY_ERROR_CORRECTION_LEVEL, value: this.env.errorCorrectionLevel });
}
async saveQrCodeDarkR() {
await this.env.storageSet("qrCodeDarkR", this.env.qrCodeDarkR);
await Preferences.set({ key: this.env.KEY_QR_CODE_DARK_R, value: JSON.stringify(this.env.qrCodeDarkR) });
}
async saveQrCodeDarkG() {
await this.env.storageSet("qrCodeDarkG", this.env.qrCodeDarkG);
await Preferences.set({ key: this.env.KEY_QR_CODE_DARK_G, value: JSON.stringify(this.env.qrCodeDarkG) });
}
async saveQrCodeDarkB() {
await this.env.storageSet("qrCodeDarkB", this.env.qrCodeDarkB);
await Preferences.set({ key: this.env.KEY_QR_CODE_DARK_B, value: JSON.stringify(this.env.qrCodeDarkB) });
}
async saveQrCodeLightR() {
await this.env.storageSet("qrCodeLightR", this.env.qrCodeLightR);
await Preferences.set({ key: this.env.KEY_QR_CODE_LIGHT_R, value: JSON.stringify(this.env.qrCodeLightR) });
}
async saveQrCodeLightG() {
await this.env.storageSet("qrCodeLightG", this.env.qrCodeLightG);
await Preferences.set({ key: this.env.KEY_QR_CODE_LIGHT_G, value: JSON.stringify(this.env.qrCodeLightG) });
}
async saveQrCodeLightB() {
await this.env.storageSet("qrCodeLightB", this.env.qrCodeLightB);
await Preferences.set({ key: this.env.KEY_QR_CODE_LIGHT_B, value: JSON.stringify(this.env.qrCodeLightB) });
}
async saveQrCodeMargin() {
await this.env.storageSet("qrCodeMargin", this.env.qrCodeMargin);
await Preferences.set({ key: this.env.KEY_QR_CODE_MARGIN, value: JSON.stringify(this.env.qrCodeMargin) });
}
async resetDefault() {

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'LOG_BACKUP_AND_RESTORE' | translate }}</ion-title>
@ -11,7 +11,8 @@
<ion-content>
<div class="ion-padding-vertical">
<ion-list-header class="ion-margin-start ion-padding-horizontal">{{ 'INITIAL_SEGMENT' | translate }}</ion-list-header>
<ion-list-header class="ion-margin-start ion-padding-horizontal">{{ 'INITIAL_SEGMENT' | translate }}
</ion-list-header>
<ion-radio-group [(ngModel)]="env.historyPageStartSegment" (ionChange)="saveHistoryPageStartSegment()">
<ion-item class="ion-no-padding ripple-parent py-1 mt-2" detail="false" lines="none">
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" src="assets/icon/history.svg">
@ -43,7 +44,46 @@
</div>
<div class="ion-padding-vertical">
<ion-list-header class="ion-margin-start ion-padding-horizontal">{{ 'AUTO_LOGGING' | translate }}</ion-list-header>
<ion-list-header class="ion-margin-start ion-padding-horizontal">{{ 'MANAGE_RECORDS' | translate }}
</ion-list-header>
<div class="ion-padding-horizontal pt-3 d-flex justify-content-center align-content-start flex-column">
<ion-button id="open-tutorial-modal" class="ion-padding-horizontal" color="primary">
{{ 'VIEW_INSTRUCTIONS' | translate }}
</ion-button>
</div>
</div>
<ion-modal #tutorialModal trigger="open-tutorial-modal" [initialBreakpoint]="0.8" [breakpoints]="[0, 0.8]">
<ng-template>
<ion-content [color]="color">
<ion-list-header class="mt-4 ml-3" style="font-size: x-large;">{{ 'TUTORIAL' | translate }}</ion-list-header>
<ion-item class="content-item ion-no-padding" lines="none" [color]="color">
<ion-icon class="ion-padding-horizontal" src="assets/icon/swipe-left.svg" [color]="'primary'"></ion-icon>
<ion-label>
<p class="ion-padding">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="white-space: normal;">
{{ 'MSG.TUTORIAL_SWIPE_LEFT' | translate }}
</ion-text>
</p>
</ion-label>
</ion-item>
<ion-item class="content-item ion-no-padding" lines="none" [color]="color">
<ion-icon class="ion-padding-horizontal" src="assets/icon/swipe-right.svg" [color]="'primary'"></ion-icon>
<ion-label>
<p class="ion-padding">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="white-space: normal;">
{{ 'MSG.TUTORIAL_SWIPE_RIGHT' | translate }}
</ion-text>
</p>
</ion-label>
</ion-item>
</ion-content>
</ng-template>
</ion-modal>
<div class="ion-padding-vertical">
<ion-list-header class="ion-margin-start ion-padding-horizontal">{{ 'AUTO_LOGGING' | translate }}
</ion-list-header>
<ion-item class="ion-no-padding" lines="none">
<ion-label class="ion-padding-start">
<p class="ion-padding-horizontal">
@ -68,7 +108,8 @@
</div>
<div class="ion-padding-vertical">
<ion-list-header class="ion-margin-start ion-padding-horizontal">{{ 'RECORDS_LIMIT' | translate }}</ion-list-header>
<ion-list-header class="ion-margin-start ion-padding-horizontal">{{ 'RECORDS_LIMIT' | translate }}
</ion-list-header>
<ion-item class="ion-no-padding" lines="none">
<ion-label class="ion-padding-start">
<p class="ion-padding-horizontal">
@ -149,14 +190,14 @@
</p>
</ion-label>
</ion-item>
<div class="ion-padding-horizontal pt-3 d-flex justify-content-center align-content-start flex-column">
<div class="ion-padding-horizontal pt-2 d-flex justify-content-center align-content-start flex-column">
<ion-button class="ion-padding-horizontal" color="primary" (click)="onBackup()">
{{ 'BACKUP' | translate }}
</ion-button>
</div>
</div>
<div class="ion-padding-vertical">
<div class="ion-padding-vertical mb-2">
<ion-list-header class="ion-margin-start ion-padding-horizontal">{{ 'RESTORE' | translate }}</ion-list-header>
<ion-item class="ion-no-padding" lines="none">
<ion-label class="ion-padding-start">
@ -167,11 +208,48 @@
</p>
</ion-label>
</ion-item>
<div class="ion-padding-horizontal pt-3 d-flex justify-content-center align-content-start flex-column">
<div class="ion-padding-horizontal pt-2 d-flex justify-content-center align-content-start flex-column">
<ion-button class="ion-padding-horizontal" color="primary" (click)="onRestore()">
{{ 'RESTORE' | translate }}
</ion-button>
</div>
</div>
<div class="ion-padding-vertical mb-2">
<ion-list-header class="ion-margin-start ion-padding-horizontal">{{ 'EXPORT' | translate }}</ion-list-header>
<ion-item class="ion-no-padding" lines="none">
<ion-label class="ion-padding-start">
<p class="ion-padding-horizontal">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="white-space: normal;">
{{ 'MSG.EXPORT_TO_CSV_EXPLAIN' | translate }}
</ion-text>
</p>
</ion-label>
</ion-item>
<div class="ion-padding-horizontal pt-2 d-flex justify-content-center align-content-start flex-column">
<ion-button class="ion-padding-horizontal" color="primary" (click)="onExportToCsv()">
{{ 'EXPORT_TO_CSV' | translate }}
</ion-button>
</div>
</div>
<!-- TODO: Import from CSV -->
<div class="ion-padding-vertical mb-1">
<ion-list-header class="ion-margin-start ion-padding-horizontal">{{ 'IMPORT' | translate }}</ion-list-header>
<ion-item class="ion-no-padding" lines="none">
<ion-label class="ion-padding-start">
<p class="ion-padding-horizontal">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="white-space: normal;">
{{ 'MSG.IMPORT_FROM_CSV_EXPLAIN' | translate }}
</ion-text>
</p>
</ion-label>
</ion-item>
<div class="ion-padding-horizontal pt-2 d-flex justify-content-center align-content-start flex-column">
<ion-button class="ion-padding-horizontal" color="primary" disabled="true" (click)="onImportFromCsv()">
{{ 'COMING_SOON' | translate }}
</ion-button>
</div>
</div>
</ion-content>

View file

@ -0,0 +1,8 @@
mat-form-field {
width: 100%;
}
.content-item {
padding-left: 16px;
padding-right: 16px;
}

View file

@ -1,5 +1,5 @@
import { Component } from '@angular/core';
import { AlertController, LoadingController, Platform } from '@ionic/angular';
import { AlertController, LoadingController, ModalController, Platform } from '@ionic/angular';
import { TranslateService } from '@ngx-translate/core';
import { EnvService } from 'src/app/services/env.service';
import { Clipboard } from '@capacitor/clipboard';
@ -12,6 +12,8 @@ import { ScanRecord } from 'src/app/models/scan-record';
import { Bookmark } from 'src/app/models/bookmark';
import { SocialSharing } from '@awesome-cordova-plugins/social-sharing/ngx';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { Preferences } from '@capacitor/preferences';
import { de, enUS, fr, it, zhCN, zhHK } from 'date-fns/locale';
@Component({
selector: 'app-setting-record',
@ -30,7 +32,8 @@ export class SettingRecordPage {
private loadingController: LoadingController,
private chooser: Chooser,
private socialSharing: SocialSharing,
private platform: Platform
private platform: Platform,
private modalController: ModalController,
) { }
ionViewDidEnter() {
@ -42,17 +45,17 @@ export class SettingRecordPage {
}
async saveHistoryPageStartSegment() {
await this.env.storageSet("history-page-start-segment", this.env.historyPageStartSegment);
await Preferences.set({ key: this.env.KEY_HISTORY_PAGE_START_SEGMENT, value: this.env.historyPageStartSegment });
}
async onScanRecordLoggingChange(ev: any) {
this.env.scanRecordLogging = ev ? 'on' : 'off';
await this.env.storageSet("scan-record-logging", this.env.scanRecordLogging);
await Preferences.set({ key: this.env.KEY_SCAN_RECORD_LOGGING, value: this.env.scanRecordLogging });
await this.tapHaptic();
}
async saveRecordsLimit() {
await this.env.storageSet("recordsLimit", this.env.recordsLimit);
await Preferences.set({ key: this.env.KEY_RECORDS_LIMIT, value: JSON.stringify(this.env.recordsLimit) });
if (this.env.recordsLimit != -1 && !this.preventRecordsLimitToast) {
this.presentToast(this.translate.instant("MSG.DELETE_OVERFLOWED_RECORDS"), "short", "bottom");
}
@ -60,7 +63,7 @@ export class SettingRecordPage {
async onShowNumberOfRecordsChange(ev: any) {
this.env.showNumberOfRecords = ev ? 'on' : 'off';
await this.env.storageSet("showNumberOfRecords", this.env.showNumberOfRecords);
await Preferences.set({ key: this.env.KEY_SHOW_NUMBER_OF_RECORDS, value: this.env.showNumberOfRecords });
await this.tapHaptic();
}
@ -295,6 +298,146 @@ export class SettingRecordPage {
});
}
async onExportToCsv() {
const loading = await this.presentLoading(this.translate.instant("EXPORTING"));
const now = format(new Date(), "yyyyMMddHHmmss");
const filename = `simpleqr-${now}.csv`;
let rawCsvData: string;
switch (this.env.language) {
case "de":
rawCsvData = "ID,Inhalt,Erstellt um,Quelle,Barcode-Typ,Lesezeichen gesetzt?,Etikett\r\n";
break;
case "en":
rawCsvData = "ID,Content,Created at,Source,Barcode Type,Bookmarked?,Tag\r\n";
break;
case "fr":
rawCsvData = "ID,Le contenu,Créé à,La source,Type de code-barres,En signet?,Étiquette\r\n";
break;
case "it":
rawCsvData = "ID,Contenuto,Creato a,Fonte,Tipo di codice a barre,Aggiunto ai preferiti?,Etichetta\r\n";
break;
case "zh-CN":
rawCsvData = "ID,内容,建立于,来源,条码类型,已书签?,标签\r\n";
break;
case "zh-HK":
rawCsvData = "ID,内容,建立於,來源,條碼類型,已書籤?,標籤\r\n";
break;
default:
rawCsvData = "ID,Content,Created at,Source,Barcode Type,Bookmarked?,Tag\r\n";
}
this.env.scanRecords.forEach(r => {
rawCsvData += `${r.id},"${r.text?.split('"').join('') ?? ""}","${this.maskDatetime(r.createdAt)}",${this.maskSource(r.source)},${r.barcodeType ?? ''},`
const bookmark = this.env.bookmarks.find(b => b.text == r.text);
if (bookmark != null) {
rawCsvData += `TRUE,"${bookmark.tag?.split('"').join('') ?? ""}"\r\n`;
} else {
rawCsvData += "FALSE, \r\n";
}
});
await Filesystem.writeFile({
path: `${filename}`,
data: rawCsvData,
directory: Directory.External,
encoding: Encoding.UTF8,
recursive: true
}).then(
async result => {
loading.dismiss();
const loading2 = await this.presentLoading(this.translate.instant("PLEASE_WAIT"));
await this.socialSharing.share(null, filename, result.uri, null).then(() => {
loading2.dismiss();
}).catch(
err => {
loading2.dismiss();
if (this.env.isDebugging) {
this.presentToast("Error when SocialSharing.share: " + JSON.stringify(err), "long", "top");
}
}
);
}
).catch(
err => {
loading.dismiss();
if (this.env.isDebugging) {
this.presentToast("Error when call Filesystem.writeFile: " + JSON.stringify(err), "long", "top");
} else {
this.presentToast("Error!", "short", "bottom");
}
}
);
}
async onImportFromCsv() {
// TODO: Import from CSV
}
maskDatetime(date: Date): string {
if (!date) {
return "-";
}
let locale: Locale;
switch (this.env.language) {
case "de":
locale = de;
break;
case "en":
locale = enUS;
break;
case "fr":
locale = fr;
break;
case "it":
locale = it;
break;
case "zh-CN":
locale = zhCN;
break;
case "zh-HK":
locale = zhHK;
break;
default:
locale = enUS;
}
return format(date, "PP pp", { locale: locale });
}
maskSource(source: 'create' | 'view' | 'scan' | undefined): string {
if (source == null) {
return "-";
}
let locale: Locale;
switch (this.env.language) {
case "de":
locale = de;
break;
case "en":
locale = enUS;
break;
case "fr":
locale = fr;
break;
case "it":
locale = it;
break;
case "zh-CN":
locale = zhCN;
break;
case "zh-HK":
locale = zhHK;
break;
default:
locale = enUS;
}
switch (source) {
case 'create':
return `${this.translate.instant("CREATED")}`;
case 'view':
return `${this.translate.instant("VIEWED")}`;
case 'scan':
return `${this.translate.instant("SCANNED")}`;
}
}
async presentToast(msg: string, duration: "short" | "long", pos: "top" | "center" | "bottom") {
await Toast.show({
text: msg,
@ -322,6 +465,19 @@ export class SettingRecordPage {
}
}
get color() {
switch (this.env.colorTheme) {
case 'dark':
return 'dark';
case 'light':
return 'white';
case 'black':
return 'black';
default:
return 'white';
}
}
get isIOS() {
return this.platform.is('ios');
}

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'TASK_BUTTON_LAYOUT' | translate }}</ion-title>
@ -72,6 +72,9 @@
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" *ngIf="env.searchEngine === 'yandex'"
src="assets/icon/yandex.svg">
</ion-icon>
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" *ngIf="env.searchEngine === 'ecosia'"
src="assets/icon/ecosia.svg">
</ion-icon>
<ion-label>
<p class="ion-padding pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">

View file

@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { Preferences } from '@capacitor/preferences';
import { Toast } from '@capacitor/toast';
import { EnvService } from 'src/app/services/env.service';
@ -15,72 +16,72 @@ export class SettingResultButtonsPage {
) { }
async saveResultPageButtons() {
await this.env.storageSet("result-page-buttons", this.env.resultPageButtons);
await Preferences.set({ key: this.env.KEY_RESULT_PAGE_BUTTONS, value: this.env.resultPageButtons });
}
async onSearchButtonChange(ev: any) {
this.env.showSearchButton = ev ? 'on' : 'off';
await this.env.storageSet("showSearchButton", this.env.showSearchButton);
await Preferences.set({ key: this.env.KEY_SHOW_SEARCH_BUTTON, value: this.env.showSearchButton });
await this.tapHaptic();
}
async onCopyButtonChange(ev: any) {
this.env.showCopyButton = ev ? 'on' : 'off';
await this.env.storageSet("showCopyButton", this.env.showCopyButton);
await Preferences.set({ key: this.env.KEY_SHOW_COPY_BUTTON, value: this.env.showCopyButton });
await this.tapHaptic();
}
async onBase64ButtonChange(ev: any) {
this.env.showBase64Button = ev ? 'on' : 'off';
await this.env.storageSet("showBase64Button", this.env.showBase64Button);
await Preferences.set({ key: this.env.KEY_SHOW_BASE64_BUTTON, value: this.env.showBase64Button });
await this.tapHaptic();
}
async onEnlargeButtonChange(ev: any) {
this.env.showEnlargeButton = ev ? 'on' : 'off';
await this.env.storageSet("showEnlargeButton", this.env.showEnlargeButton);
await Preferences.set({ key: this.env.KEY_SHOW_ENLARGE_BUTTON, value: this.env.showEnlargeButton });
await this.tapHaptic();
}
async onBookmarkButtonChange(ev: any) {
this.env.showBookmarkButton = ev ? 'on' : 'off';
await this.env.storageSet("showBookmarkButton", this.env.showBookmarkButton);
await Preferences.set({ key: this.env.KEY_SHOW_BOOKMARK_BUTTON, value: this.env.showBookmarkButton });
await this.tapHaptic();
}
async onOpenUrlButtonChange(ev: any) {
this.env.showOpenUrlButton = ev ? 'on' : 'off';
await this.env.storageSet("showOpenUrlButton", this.env.showOpenUrlButton);
await Preferences.set({ key: this.env.KEY_SHOW_OPEN_URL_BUTTON, value: this.env.showOpenUrlButton });
await this.tapHaptic();
}
async onBrowseButtonChange(ev: any) {
this.env.showBrowseButton = ev ? 'on' : 'off';
await this.env.storageSet("showBrowseButton", this.env.showBrowseButton);
await Preferences.set({ key: this.env.KEY_SHOW_BROWSE_BUTTON, value: this.env.showBrowseButton });
await this.tapHaptic();
}
async onAddContactButtonChange(ev: any) {
this.env.showAddContactButton = ev ? 'on' : 'off';
await this.env.storageSet("showAddContactButton", this.env.showAddContactButton);
await Preferences.set({ key: this.env.KEY_SHOW_ADD_CONTACT_BUTTON, value: this.env.showAddContactButton });
await this.tapHaptic();
}
async onCallButtonChange(ev: any) {
this.env.showCallButton = ev ? 'on' : 'off';
await this.env.storageSet("showCallButton", this.env.showCallButton);
await Preferences.set({ key: this.env.KEY_SHOW_CALL_BUTTON, value: this.env.showCallButton });
await this.tapHaptic();
}
async onSendMessageButtonChange(ev: any) {
this.env.showSendMessageButton = ev ? 'on' : 'off';
await this.env.storageSet("showSendMessageButton", this.env.showSendMessageButton);
await Preferences.set({ key: this.env.KEY_SHOW_SEND_MESSAGE_BUTTON, value: this.env.showSendMessageButton });
await this.tapHaptic();
}
async onSendEmailButtonChange(ev: any) {
this.env.showSendEmailButton = ev ? 'on' : 'off';
await this.env.storageSet("showSendEmailButton", this.env.showSendEmailButton);
await Preferences.set({ key: this.env.KEY_SHOW_SEND_EMAIL_BUTTON, value: this.env.showSendEmailButton });
await this.tapHaptic();
}

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'QR_CODE_AND_DECODED_RESULT' | translate }}</ion-title>
@ -73,6 +73,9 @@
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" *ngIf="env.searchEngine === 'yandex'"
src="assets/icon/yandex.svg">
</ion-icon>
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" *ngIf="env.searchEngine === 'ecosia'"
src="assets/icon/ecosia.svg">
</ion-icon>
<ion-label>
<p class="ion-padding pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'SEARCH_ENGINE' | translate }}</ion-title>
@ -31,12 +31,12 @@
</ion-text>
</p>
</ion-label>
<ion-radio class="ion-margin-end" slot="end" [value]="'google'"
[color]="'primary'">
<ion-radio class="ion-margin-end" slot="end" [value]="'google'" [color]="'primary'">
</ion-radio>
</ion-item>
<ion-item class="ion-no-padding ripple-parent" detail="false" lines="none">
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" src="assets/icon/microsoft-bing.svg"></ion-icon>
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'"
src="assets/icon/microsoft-bing.svg"></ion-icon>
<ion-label>
<p class="ion-padding pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
@ -44,12 +44,12 @@
</ion-text>
</p>
</ion-label>
<ion-radio class="ion-margin-end" slot="end" [value]="'bing'"
[color]="'primary'">
<ion-radio class="ion-margin-end" slot="end" [value]="'bing'" [color]="'primary'">
</ion-radio>
</ion-item>
<ion-item class="ion-no-padding ripple-parent" detail="false" lines="none">
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" src="assets/icon/yahoo.svg"></ion-icon>
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" src="assets/icon/yahoo.svg">
</ion-icon>
<ion-label>
<p class="ion-padding pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
@ -57,12 +57,12 @@
</ion-text>
</p>
</ion-label>
<ion-radio class="ion-margin-end" slot="end" [value]="'yahoo'"
[color]="'primary'">
<ion-radio class="ion-margin-end" slot="end" [value]="'yahoo'" [color]="'primary'">
</ion-radio>
</ion-item>
<ion-item class="ion-no-padding ripple-parent" detail="false" lines="none">
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" src="assets/icon/duck-duck-go.svg"></ion-icon>
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" src="assets/icon/duck-duck-go.svg">
</ion-icon>
<ion-label>
<p class="ion-padding pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
@ -70,12 +70,12 @@
</ion-text>
</p>
</ion-label>
<ion-radio class="ion-margin-end" slot="end" [value]="'duckduckgo'"
[color]="'primary'">
<ion-radio class="ion-margin-end" slot="end" [value]="'duckduckgo'" [color]="'primary'">
</ion-radio>
</ion-item>
<ion-item class="ion-no-padding ripple-parent" detail="false" lines="none">
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" src="assets/icon/yandex.svg"></ion-icon>
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" src="assets/icon/yandex.svg">
</ion-icon>
<ion-label>
<p class="ion-padding pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
@ -83,10 +83,22 @@
</ion-text>
</p>
</ion-label>
<ion-radio class="ion-margin-end" slot="end" [value]="'yandex'"
[color]="'primary'">
<ion-radio class="ion-margin-end" slot="end" [value]="'yandex'" [color]="'primary'">
</ion-radio>
</ion-item>
<ion-item class="ion-no-padding ripple-parent" detail="false" lines="none">
<ion-icon class="ion-margin-start ion-padding-horizontal" [color]="'primary'" src="assets/icon/ecosia.svg">
</ion-icon>
<ion-label>
<p class="ion-padding pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
{{ 'ECOSIA' | translate }}
</ion-text>
</p>
</ion-label>
<ion-radio class="ion-margin-end" slot="end" [value]="'ecosia'" [color]="'primary'">
</ion-radio>
</ion-item>
</ion-radio-group>
</ion-content>
</ion-content>

View file

@ -1,4 +1,5 @@
import { Component } from '@angular/core';
import { Preferences } from '@capacitor/preferences';
import { TranslateService } from '@ngx-translate/core';
import { EnvService } from 'src/app/services/env.service';
@ -15,7 +16,7 @@ export class SettingSearchEnginePage {
) { }
async saveSearchEngine() {
await this.env.storageSet("search-engine", this.env.searchEngine);
await Preferences.set({ key: this.env.KEY_SEARCH_ENGINE, value: this.env.searchEngine });
}

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'APP_INITIAL_PAGE' | translate }}</ion-title>

View file

@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { Preferences } from '@capacitor/preferences';
import { Toast } from '@capacitor/toast';
import { EnvService } from 'src/app/services/env.service';
import { fadeIn } from 'src/app/utils/animations';
@ -17,12 +18,12 @@ export class SettingStartPagePage {
) { }
async saveStartPage() {
await this.env.storageSet("start-page", this.env.startPage);
await Preferences.set({ key: this.env.KEY_START_PAGE, value: this.env.startPage });
}
async onStartPageHeaderChange(ev: any) {
this.env.startPageHeader = ev ? 'on' : 'off';
await this.env.storageSet("start-page-header", this.env.startPageHeader);
await Preferences.set({ key: this.env.KEY_START_PAGE_HEADER, value: this.env.startPageHeader });
await this.tapHaptic();
}

View file

@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
<ion-buttons slot="start">
<ion-back-button text="">
<ion-back-button text="" defaultHref="tabs/setting">
</ion-back-button>
</ion-buttons>
<ion-title>{{ 'VIBRATION' | translate }}</ion-title>

View file

@ -1,4 +1,5 @@
import { Component } from '@angular/core';
import { Preferences } from '@capacitor/preferences';
import { EnvService } from 'src/app/services/env.service';
@Component({
@ -13,6 +14,6 @@ export class SettingVibrationPage {
) { }
async saveVibration() {
await this.env.storageSet("vibration", this.env.vibration);
await Preferences.set({ key: this.env.KEY_VIBRATION, value: this.env.vibration });
}
}

View file

@ -1,6 +1,7 @@
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { Preferences } from '@capacitor/preferences';
import { SplashScreen } from '@capacitor/splash-screen';
import { Toast } from '@capacitor/toast';
import { AlertController, Platform } from '@ionic/angular';
@ -60,32 +61,37 @@ export class TabsPage {
}
async ionViewDidEnter() {
await SplashScreen.hide()
if (this.env.firstAppLoad) {
this.env.firstAppLoad = false;
await this.router.navigate([this.env.startPage], { replaceUrl: true });
await this.loadPatchNote();
this.env.initObservable.subscribe(async value => {
console.log(`tabs.page.ts - ionViewDidEnter() - initObservable value: ${value}`)
if (value) {
console.log(`tabs.page.ts - ionViewDidEnter() - env.startPage: ${this.env.startPage}`)
await this.router.navigate([this.env.startPage], { replaceUrl: true });
await this.loadPatchNote();
}
});
}
}
async loadPatchNote() {
const storageKey = this.platform.is('ios') ? this.env.IOS_PATCH_NOTE_STORAGE_KEY : this.env.AN_PATCH_NOTE_STORAGE_KEY;
await this.env.storageGet(storageKey).then(
async value => {
if (value != null) {
this.env.notShowUpdateNotes = (value === 'yes' ? true : false);
const storageKey = this.platform.is('ios') ? this.env.KEY_IOS_NOT_SHOW_UPDATE_NOTES : this.env.KEY_ANDROID_NOT_SHOW_UPDATE_NOTES;
await Preferences.get({ key: storageKey }).then(
async result => {
if (result.value != null) {
this.env.notShowUpdateNotes = result.value == 'yes';
} else {
this.env.notShowUpdateNotes = false;
}
await this.env.storageSet(storageKey, 'yes');
if (this.env.notShowUpdateNotes === false) {
await Preferences.set({ key: storageKey, value: 'yes' });
if (!this.env.notShowUpdateNotes) {
this.env.notShowUpdateNotes = true;
await this.showUpdateNotes();
const versionWording = this.translate.instant("VERSION_VERSION") as string;
await this.presentToast(versionWording.replace("{version}", this.env.appVersionNumber), "short", 'bottom');
}
}
);
)
}
async showUpdateNotes() {

File diff suppressed because it is too large Load diff

View file

@ -45,6 +45,7 @@
"CLOSE": "Schließen",
"COLOR": "Farbe",
"COLOR_THEME": "Farbthema",
"COMING_SOON": "Bald verfügbar",
"CONTACT_METHOD": "Kontakt Methode",
"CONTACT_NAME": "Kontakt Name",
"CONTENT": "Inhalt",
@ -65,6 +66,7 @@
"DETAILED": "Detailliert",
"DONE": "Erledigt",
"DUCK_DUCK_GO": "DuckDuckGo",
"ECOSIA": "Ecosia",
"EDIT": "Bearbeiten",
"EMAIL_ADDRESS": "Email Adresse",
"EMAIL_BODY": "Email Stelle",
@ -77,6 +79,9 @@
"ERROR_CORRECTION_LEVEL": "Fehlerkorrektur-Level",
"EXIT": "Beenden",
"EXIT_APP": "App beenden",
"EXPORT": "Exportieren",
"EXPORTING": "Exportieren",
"EXPORT_TO_CSV": "In CSV exportieren",
"FAX_NUMBER": "Fax Nummer",
"FEMALE": "Weiblich",
"FIRST_NAME": "Vorname",
@ -108,11 +113,13 @@
"LOG": "Protokoll",
"LOG_BACKUP_AND_RESTORE": "Protokoll, Sicherung und Wiederherstellung",
"MALE": "Männlich",
"MANAGE_RECORDS": "Aufzeichnungen verwalten",
"MARGIN": "Rand",
"MESSAGE": "Nachricht",
"MESSAGE_CONTENT": "Inhalt der Nachricht",
"MICROSOFT_BING": "Microsoft Bing",
"MOBILE_PHONE_NUMBER": "Mobiltelefon Nummer",
"MORE": "Mehr",
"NAME": "Name",
"NO": "Nein",
"NONE": "Keine",
@ -127,6 +134,7 @@
"OPEN": "Öffnen",
"OPEN_URL": "Öffne URL",
"OPEN_WITH_...": "Öffnen mit...",
"OPTIMIZING_DATA_...": "Optimierung der Daten...",
"ORGANIZATION": "Organization",
"ORIGINAL": "Original",
"OTHERS": "Andere",
@ -200,6 +208,7 @@
"VIEW_GITHUB": "GitHub anzeigen",
"VIEW_LOG": "Protokoll anzeigen",
"VIEW_STORE_AND_SOURCE_CODE": "Store und Quellcode anzeigen",
"VIEW_INSTRUCTIONS": "Anweisungen anzeigen",
"WEBSITE": "Website",
"WIFI": "WiFi",
"WIFI_ENCRYPTION": "WiFi Verschlüsselung",
@ -221,7 +230,6 @@
"BACKUP_SUCCESSFULLY": "<p>Die Sicherung wurde erfolgreich durchgeführt. Bitte speichere die Sicherungsdatei und bewahre das folgende Geheimnis sicher auf</p><p>{secret}</p>",
"BARCODE_TYPE": "Scanne<ul><li>QR Code</li><li>1D Barcode</li><li>Aztec Code</li><li>Data Matrix</li><li>PDF417</li></ul>Bild importieren<ul><li>QR Code</li></ul>Erstelle<ul><li>QR Code</li></ul>",
"BOOKMARKED": "Erfolgreich mit Lesezeichen versehen",
"BOOKMARK_TUTORIAL_SWIPE_RIGHT": "Wische nach rechts, um das Tag des entsprechenden Lesezeichens zu bearbeiten.",
"BUTTON_DISPLAY_EXPLAIN": "Ein- und Ausblenden der Aufgabenschaltflächen.",
"BUTTON_STYLE_EXPLAIN": "Wähle den Stil der Aufgabenschaltflächen.",
"CAMERA_PERMISSION": "Um das Scannen zu aktivieren, muss man der Kamera die Erlaubnis erteilen.",
@ -236,8 +244,10 @@
"EMAIL_SUBJECT_MAX_LENGTH": "Max. 78 Zeichen",
"ERROR_CORRECTION_LEVEL_EXPLAIN": "<p>Der QR-Code verfügt über eine Fehlerkorrekturfunktion, die es ermöglicht, Daten wiederherzustellen, selbst wenn der Code beschädigt ist.</p><br><p>Es stehen 4 Stufen zur Verfügung:</p><p>Level L stellt 7 % der Datenbytes wieder her.</p><p>Level M stellt 15 % der Datenbytes wieder her.</p><p>Level Q stellt 25 % der Datenbytes wieder her.</p><p>Level H stellt 30 % der Datenbytes wieder her.</p><br><p>Bitte beachte, dass eine Erhöhung der Level die Fehlerkorrekturfähigkeit verbessern kann, aber auch die Größe des QR-Codes erhöht. Daher wird für allgemeine Fälle die Level M empfohlen.</p>",
"EXIT_APP": "<p>Bist du sicher, dass du die App beenden willst?</p><p>Wenn dir Simple QR gefällt, bewerte es bitte im Store.</p>",
"EXPORT_TO_CSV_EXPLAIN": "Sie können alle Datensätze und Lesezeichen in eine CSV-Datei exportieren.",
"FAILED_SAVING_CONTACT": "Kontakt konnte nicht gespeichert werden",
"FAIL_PREPARE_SMS": "Nachricht konnte nicht gesendet werden",
"IMPORT_FROM_CSV_EXPLAIN": "Sie können Datensätze und Lesezeichen aus einer CSV-Datei mit dem von Simple QR definierten Format importieren. Wenn Sie Daten zwischen Android und iOS übertragen möchten, verwenden Sie bitte diese Funktion.",
"INPUT_TAG": "Bitte gib dem Lesezeichen einen Tag",
"INVALID_BK_FILE": "Dies ist keine gültige Sicherungsdatei.",
"NOT_BASE64_DE": "Daten können nicht Base64-dekodiert werden",
@ -279,7 +289,7 @@
"TAG_MAX_LENGTH_EXPLAIN": "Die Länge des Tags darf 30 Zeichen nicht überschreiten.",
"TUTORIAL_NOT_SHOW_AGAIN": "Nicht wieder zeigen",
"TUTORIAL_SWIPE_LEFT": "Wische nach links, um den entsprechenden Datensatz zu löschen.",
"TUTORIAL_SWIPE_RIGHT": "Wische nach rechts, um den Text des entsprechenden Datensatzes mit einem Lesezeichen zu versehen.",
"TUTORIAL_SWIPE_RIGHT": "Wische nach rechts, um den Text des entsprechenden Datensatzes mit einem Lesezeichen zu versehen / Bearbeiten Sie das Label des entsprechenden Lesezeichens.",
"UNDO_DELETE": "Du kannst die Löschung rückgängig machen",
"VIBRATION_EXPLAIN": "Vibration oder haptisches Feedback geben. Bitte beachte, dass nicht alle Geräte diese Funktion unterstützen."
},
@ -295,7 +305,7 @@
"UPC": "Universeller Produktcode "
},
"UPDATE": {
"UPDATE_NOTES_ANDROID": "<p>Diese Version bringt Ihnen mehrere Updates und neue Funktionen. Bitte überprüfen Sie GitHub für Details.</p><p>Android-Benutzer können jetzt die Kachel Simple QR im Bereich Schnelleinstellungen für einen schnellen Zugriff aktivieren.</p>",
"UPDATE_NOTES_IOS": "Diese Version bringt Ihnen mehrere Updates und neue Funktionen. Bitte überprüfen Sie GitHub für Details."
"UPDATE_NOTES_ANDROID": "<p>Diese Version bringt Ihnen mehrere Updates und neue Funktionen. Bitte überprüfen Sie GitHub für Details.</p><p>Starting from this version, you can use Ecosia as search engine, export records to CSV and enjoy more reliable data logging.</p>",
"UPDATE_NOTES_IOS": "<p>Diese Version bringt Ihnen mehrere Updates und neue Funktionen. Bitte überprüfen Sie GitHub für Details.</p><p>Starting from this version, you can use Ecosia as search engine, export records to CSV and enjoy more reliable data logging.</p>"
}
}

View file

@ -45,6 +45,7 @@
"CLOSE": "Close",
"COLOR": "Color",
"COLOR_THEME": "Color Theme",
"COMING_SOON": "Coming soon",
"CONTACT_METHOD": "Contact Method",
"CONTACT_NAME": "Contact Name",
"CONTENT": "Content",
@ -65,6 +66,7 @@
"DETAILED": "Detailed",
"DONE": "Done",
"DUCK_DUCK_GO": "DuckDuckGo",
"ECOSIA": "Ecosia",
"EDIT": "Edit",
"EMAIL_ADDRESS": "Email Address",
"EMAIL_BODY": "Email Body",
@ -77,6 +79,9 @@
"ERROR_CORRECTION_LEVEL": "Error Correction Level",
"EXIT": "Exit",
"EXIT_APP": "Exit App",
"EXPORT": "Export",
"EXPORTING": "Exporting",
"EXPORT_TO_CSV": "Export to CSV",
"FAX_NUMBER": "Fax Number",
"FEMALE": "Female",
"FIRST_NAME": "First Name",
@ -108,11 +113,13 @@
"LOG": "Log",
"LOG_BACKUP_AND_RESTORE": "Log, Backup & Restore",
"MALE": "Male",
"MANAGE_RECORDS": "Manage Records",
"MARGIN": "Margin",
"MESSAGE": "Message",
"MESSAGE_CONTENT": "Message Content",
"MICROSOFT_BING": "Microsoft Bing",
"MOBILE_PHONE_NUMBER": "Mobile Phone Number",
"MORE": "More",
"NAME": "Name",
"NO": "No",
"NONE": "None",
@ -127,6 +134,7 @@
"OPEN": "Open",
"OPEN_URL": "Open URL",
"OPEN_WITH_...": "Open with...",
"OPTIMIZING_DATA_...": "Optimizing data...",
"ORGANIZATION": "Organization",
"ORIGINAL": "Original",
"OTHERS": "Others",
@ -200,6 +208,7 @@
"VIEW_GITHUB": "View GitHub",
"VIEW_LOG": "View Log",
"VIEW_STORE_AND_SOURCE_CODE": "View Store & Source Code",
"VIEW_INSTRUCTIONS": "View Instructions",
"WEBSITE": "Website",
"WIFI": "WiFi",
"WIFI_ENCRYPTION": "WiFi Encryption",
@ -221,7 +230,6 @@
"BACKUP_SUCCESSFULLY": "<p>Successfully backed up. Please save the backup file and keep the following secret securely</p><p>{secret}</p>",
"BARCODE_TYPE": "Scan<ul><li>QR Code</li><li>1D Barcode</li><li>Aztec Code</li><li>Data Matrix</li><li>PDF417</li></ul>Import Image<ul><li>QR Code</li></ul>Create<ul><li>QR Code</li></ul>",
"BOOKMARKED": "Bookmarked Successfully",
"BOOKMARK_TUTORIAL_SWIPE_RIGHT": "Swipe right to edit the tag of corresponding bookmark.",
"BUTTON_DISPLAY_EXPLAIN": "Show or hide the task buttons.",
"BUTTON_STYLE_EXPLAIN": "Choose the style of the task buttons.",
"CAMERA_PERMISSION": "To enable scanning, you must grant Camera permission.",
@ -236,8 +244,10 @@
"EMAIL_SUBJECT_MAX_LENGTH": "Max. 78 characters",
"ERROR_CORRECTION_LEVEL_EXPLAIN": "<p>QR code has error correction capability to restore data even if the code is damaged.</p><br><p>There are 4 levels available:</p><p>Level L restores 7% of data bytes.</p><p>Level M restores 15% of data bytes.</p><p>Level Q restores 25% of data bytes.</p><p>Level H restores 30% of data bytes.</p><br><p>Please be reminded that raising the level can improve error correction capability but also increases the QR code size. Therefore, for general cases, level M is recommended.</p>",
"EXIT_APP": "<p>Are you sure to exit the app?</p><p>If you like Simple QR, please rate it on the store.</p>",
"EXPORT_TO_CSV_EXPLAIN": "You can export all records and bookmarks to a CSV file.",
"FAILED_SAVING_CONTACT": "Failed to save contact",
"FAIL_PREPARE_SMS": "Failed to send message",
"IMPORT_FROM_CSV_EXPLAIN": "You can import records and bookmarks from a CSV file with the format defined by Simple QR. If you want to transfer data between Android and iOS, please use this function.",
"INPUT_TAG": "Please give a tag to the bookmark",
"INVALID_BK_FILE": "This is not a valid backup file.",
"NOT_BASE64_DE": "Data cannot be Base64 decoded",
@ -279,7 +289,7 @@
"TAG_MAX_LENGTH_EXPLAIN": "The length of the tag must not exceed 30 characters.",
"TUTORIAL_NOT_SHOW_AGAIN": "Do not show again",
"TUTORIAL_SWIPE_LEFT": "Swipe left to delete corresponding record.",
"TUTORIAL_SWIPE_RIGHT": "Swipe right to bookmark the text of corresponding record.",
"TUTORIAL_SWIPE_RIGHT": "Swipe right to bookmark the text of corresponding record / edit the tag of corresponding bookmark.",
"UNDO_DELETE": "You can undo the deletion",
"VIBRATION_EXPLAIN": "Provide vibration or haptic feedback. Please note that not all devices support this feature."
},
@ -295,7 +305,7 @@
"UPC": "Universal Product Code "
},
"UPDATE": {
"UPDATE_NOTES_ANDROID": "<p>This release brings you several updates and new features. Please check GitHub for details.</p><p>Android users can now enable the Simple QR tile in the Quick Settings panel for quick access.</p>",
"UPDATE_NOTES_IOS": "This release brings you several updates and new features. Please check GitHub for details."
"UPDATE_NOTES_ANDROID": "<p>This release brings you several updates and new features. Please check GitHub for details.</p><p>Starting from this version, you can use Ecosia as search engine, export records to CSV and enjoy more reliable data logging.</p>",
"UPDATE_NOTES_IOS": "<p>This release brings you several updates and new features. Please check GitHub for details.</p><p>Starting from this version, you can use Ecosia as search engine, export records to CSV and enjoy more reliable data logging.</p>"
}
}

View file

@ -45,6 +45,7 @@
"CLOSE": "Fermer",
"COLOR": "Couleur",
"COLOR_THEME": "Thème de couleur",
"COMING_SOON": "Bientôt disponible",
"CONTACT_METHOD": "Méthode de contact",
"CONTACT_NAME": "Nom du contact",
"CONTENT": "Le contenu",
@ -65,6 +66,7 @@
"DETAILED": "Détaillé",
"DONE": "Fini",
"DUCK_DUCK_GO": "DuckDuckGo",
"ECOSIA": "Ecosia",
"EDIT": "Modifier",
"EMAIL_ADDRESS": "Adresse e-mail",
"EMAIL_BODY": "Corps de l'e-mail",
@ -77,6 +79,9 @@
"ERROR_CORRECTION_LEVEL": "Niveau de correction d'erreur",
"EXIT": "Quitter",
"EXIT_APP": "Quitter l'application",
"EXPORT": "Exporter",
"EXPORTING": "Exportation",
"EXPORT_TO_CSV": "Exporter vers CSV",
"FAX_NUMBER": "Numéro de fax",
"FEMALE": "Femelle",
"FIRST_NAME": "Prénom",
@ -108,11 +113,13 @@
"LOG": "Registre",
"LOG_BACKUP_AND_RESTORE": "Journalisation, sauvegarde et restauration",
"MALE": "Mâle",
"MANAGE_RECORDS": "Gérer les enregistrements",
"MARGIN": "Marge",
"MESSAGE": "Message",
"MESSAGE_CONTENT": "Contenu du message",
"MICROSOFT_BING": "Microsoft Bing",
"MOBILE_PHONE_NUMBER": "Numéro de portable",
"MORE": "Plus",
"NAME": "Nom",
"NO": "Non",
"NONE": "Aucun",
@ -127,6 +134,7 @@
"OPEN": "Ouvrir",
"OPEN_URL": "Ouvrir l'URL",
"OPEN_WITH_...": "Ouvrir avec...",
"OPTIMIZING_DATA_...": "Optimiser les données...",
"ORGANIZATION": "Organisme",
"ORIGINAL": "Original",
"OTHERS": "Autres",
@ -200,6 +208,7 @@
"VIEW_GITHUB": "Afficher le GitHub",
"VIEW_LOG": "Afficher le journal",
"VIEW_STORE_AND_SOURCE_CODE": "Afficher le magasin et le code source",
"VIEW_INSTRUCTIONS": "Afficher les instructions",
"WEBSITE": "Site Web",
"WIFI": "Wi-Fi",
"WIFI_ENCRYPTION": "Cryptage Wi-Fi",
@ -221,7 +230,6 @@
"BACKUP_SUCCESSFULLY": "<p>Sauvegarde réussie. Veuillez enregistrer le fichier de sauvegarde et conserver le secret suivant en toute sécurité</p><p>{secret}</p>",
"BARCODE_TYPE": "Scanner<ul><li>Code QR</li><li>Code-barres 1D</li><li>Code aztèque</li><li>Data Matrix</li><li>PDF417</li></ul>Importer une image<ul><li>Code QR</li></ul>Créer<ul><li>Code QR</li></ul>",
"BOOKMARKED": "Mis en signet avec succès",
"BOOKMARK_TUTORIAL_SWIPE_RIGHT": "Balayez vers la droite pour modifier la balise du signet correspondant.",
"BUTTON_DISPLAY_EXPLAIN": "Afficher ou masquer les boutons de tâche.",
"BUTTON_STYLE_EXPLAIN": "Choisissez le style des boutons de tâche.",
"CAMERA_PERMISSION": "Pour activer la numérisation, vous devez accorder l'autorisation Caméra.",
@ -236,8 +244,10 @@
"EMAIL_SUBJECT_MAX_LENGTH": "Max. 78 caractères",
"ERROR_CORRECTION_LEVEL_EXPLAIN": "<p>Le code QR a une capacité de correction d'erreur pour restaurer les données même si le code est endommagé.</p><br><p>Il existe 4 niveaux disponibles :</p><p>Le niveau L restaure 7 % des octets de données.</p><p>Le niveau M restaure 15 % des octets de données.</p><p>Le niveau Q restaure 25 % des octets de données.</p><p>Le niveau H restaure 30 % des octets de données.</p><br><p>N'oubliez pas que l'augmentation du niveau peut améliorer la capacité de correction des erreurs, mais augmente également la taille du code QR. Par conséquent, pour les cas généraux, le niveau M est recommandé.</p>",
"EXIT_APP": "<p>Voulez-vous vraiment quitter l'application ?</p><p>Si vous aimez Simple QR, veuillez l'évaluer sur la magasin.</p>",
"EXPORT_TO_CSV_EXPLAIN": "Vous pouvez exporter tous les enregistrements et signets dans un fichier CSV.",
"FAILED_SAVING_CONTACT": "Échec de l'enregistrement des contacts",
"FAIL_PREPARE_SMS": "Échec de l'envoi du message",
"IMPORT_FROM_CSV_EXPLAIN": "Vous pouvez importer des enregistrements et des signets à partir d'un fichier CSV au format défini par Simple QR. Si vous souhaitez transférer des données entre Android et iOS, veuillez utiliser cette fonction.",
"INPUT_TAG": "Veuillez donner une étiquette au signet",
"INVALID_BK_FILE": "Ce fichier de sauvegarde n'est pas valide.",
"NOT_BASE64_DE": "Les données ne peuvent pas être décodées en Base64",
@ -279,7 +289,7 @@
"TAG_MAX_LENGTH_EXPLAIN": "La longueur de la balise ne doit pas dépasser 30 caractères.",
"TUTORIAL_NOT_SHOW_AGAIN": "Ne pas montrer de nouveau",
"TUTORIAL_SWIPE_LEFT": "Balayez vers la gauche pour supprimer l'enregistrement correspondant.",
"TUTORIAL_SWIPE_RIGHT": "Balayez vers la droite pour mettre en signet le texte de l'enregistrement correspondant.",
"TUTORIAL_SWIPE_RIGHT": "Balayez vers la droite pour mettre en signet le texte de l'enregistrement / modifier la balise du signet correspondant.",
"UNDO_DELETE": "Vous pouvez annuler la suppression",
"VIBRATION_EXPLAIN": "Fournir des vibrations ou un retour haptique. Veuillez noter que tous les appareils ne prennent pas en charge cette fonctionnalité."
},
@ -295,7 +305,7 @@
"UPC": "Code produit universel"
},
"UPDATE": {
"UPDATE_NOTES_ANDROID": "<p>Cette version vous apporte plusieurs mises à jour et nouvelles fonctionnalités. Veuillez consulter GitHub pour plus de détails.</p><p>Les utilisateurs d'Android peuvent désormais activer la vignette Simple QR dans le panneau Paramètres rapides pour un accès rapide.</p>",
"UPDATE_NOTES_IOS": "Cette version vous apporte plusieurs mises à jour et nouvelles fonctionnalités. Veuillez consulter GitHub pour plus de détails."
"UPDATE_NOTES_ANDROID": "<p>Cette version vous apporte plusieurs mises à jour et nouvelles fonctionnalités. Veuillez consulter GitHub pour plus de détails.</p><p>Starting from this version, you can use Ecosia as search engine, export records to CSV and enjoy more reliable data logging.</p>",
"UPDATE_NOTES_IOS": "<p>Cette version vous apporte plusieurs mises à jour et nouvelles fonctionnalités. Veuillez consulter GitHub pour plus de détails.</p><p>Starting from this version, you can use Ecosia as search engine, export records to CSV and enjoy more reliable data logging.</p>"
}
}

View file

@ -45,6 +45,7 @@
"CLOSE": "Chiudi",
"COLOR": "Colore",
"COLOR_THEME": "Tema colore",
"COMING_SOON": "Prossimamente",
"CONTACT_METHOD": "Metodi di contatto",
"CONTACT_NAME": "Nome",
"CONTENT": "Contenuto",
@ -65,6 +66,7 @@
"DETAILED": "Dettagli",
"DONE": "Completato",
"DUCK_DUCK_GO": "DuckDuckGo",
"ECOSIA": "Ecosia",
"EDIT": "Modifica",
"EMAIL_ADDRESS": "Email",
"EMAIL_BODY": "Corpo della mail",
@ -77,6 +79,9 @@
"ERROR_CORRECTION_LEVEL": "Errore di correttezza",
"EXIT": "Esci",
"EXIT_APP": "Esci dall'app",
"EXPORT": "Esporta",
"EXPORTING": "Esportazione in corso",
"EXPORT_TO_CSV": "Esporta in CSV",
"FAX_NUMBER": "Numero fax",
"FEMALE": "Donna",
"FIRST_NAME": "Nome",
@ -108,11 +113,13 @@
"LOG": "Log",
"LOG_BACKUP_AND_RESTORE": "Logga, Esegui backup & Ripristina",
"MALE": "Uomo",
"MANAGE_RECORDS": "Gestisci record",
"MARGIN": "Margine",
"MESSAGE": "Messaggio",
"MESSAGE_CONTENT": "Contenuto del messaggio",
"MICROSOFT_BING": "Microsoft Bing",
"MOBILE_PHONE_NUMBER": "Numero di telefono cellulare",
"MORE": "Più",
"NAME": "Nome",
"NO": "No",
"NONE": "Nessuno",
@ -127,6 +134,7 @@
"OPEN": "Aprire",
"OPEN_URL": "Aprire l'URL",
"OPEN_WITH_...": "Apri con...",
"OPTIMIZING_DATA_...": "Ottimizzazione dei dati...",
"ORGANIZATION": "Organizzazione",
"ORIGINAL": "Orginale",
"OTHERS": "Altri",
@ -200,6 +208,7 @@
"VIEW_GITHUB": "Visualizza GitHub",
"VIEW_LOG": "Visualizza Log",
"VIEW_STORE_AND_SOURCE_CODE": "Visualizza Store & Codice Sorgente",
"VIEW_INSTRUCTIONS": "Visualizza le istruzioni",
"WEBSITE": "Sito Web",
"WIFI": "WiFi",
"WIFI_ENCRYPTION": "Crittografia WiFi",
@ -221,7 +230,6 @@
"BACKUP_SUCCESSFULLY": "<p>Backup riuscito. Si prega di salvare il file di backup e salvare la seguente chiave segreta in modo sicuro</p><p>{secret}</p>",
"BARCODE_TYPE": "Scannerizzazione<ul><li>Codice QR</li><li>Codice a barre 1D</li><li>Codice Aztec</li><li>Matrice di Dati</li><li>PDF417</li></ul>Importa Immagine<ul><li>Codice QR</li></ul>Crea<ul><li>Codice QR</li></ul>",
"BOOKMARKED": "Segnalibro salvato con successo",
"BOOKMARK_TUTORIAL_SWIPE_RIGHT": "Scorri verso destra per modificare il tag del segnalibro corrispondente.",
"BUTTON_DISPLAY_EXPLAIN": "Mostra o nascondi il pulsante operazione.",
"BUTTON_STYLE_EXPLAIN": "Scegli lo stile del pulsante operazione.",
"CAMERA_PERMISSION": "Per abilitare la scansione, è necessario concedere l'autorizzazione Fotocamera.",
@ -236,8 +244,10 @@
"EMAIL_SUBJECT_MAX_LENGTH": "Massimo 78 caratteri",
"ERROR_CORRECTION_LEVEL_EXPLAIN": "<p>Il codice QR ha la capacità di correzione degli errori per ripristinare i dati anche se il codice è danneggiato.</p><br><p>Sono disponibili 4 livelli::</p><p>Il Livello L recupera il 7% di byte di dati.</p><p>Il Livello M recupera il 15% dei byte di dati.</p><p>Il Livello Q recupera il 25% di byte di dati.</p><p>Il Livello H recupera il 30% di byte di dati.</p><br><p>Si ricorda che l'innalzamento del livello può migliorare la capacità di correzione degli errori, ma aumenta anche la dimensione del codice QR. Pertanto, per i casi generali, si raccomanda il livello M.</p>",
"EXIT_APP": "<p>Sei sicuro di voler uscire?</p><p>Se ti piace Simple QR, valutala sullo store</p>",
"EXPORT_TO_CSV_EXPLAIN": "Puoi esportare tutti i record e i segnalibri in un file CSV.",
"FAILED_SAVING_CONTACT": "Salvataggio dei dati fallito",
"FAIL_PREPARE_SMS": "Impossibile inviare il messaggio",
"IMPORT_FROM_CSV_EXPLAIN": "Puoi importare record e segnalibri da un file CSV con il formato definito da Simple QR. Se desideri trasferire dati tra Android e iOS, utilizza questa funzione.",
"INPUT_TAG": "Si prega di dare un tag al segnalibro",
"INVALID_BK_FILE": "Backup non valido.",
"NOT_BASE64_DE": "I dati non possono essere decodificati in Base64",
@ -279,7 +289,7 @@
"TAG_MAX_LENGTH_EXPLAIN": "La lunghezza del tag non deve superare i 30 caratteri.",
"TUTORIAL_NOT_SHOW_AGAIN": "Non mostrare di nuovo",
"TUTORIAL_SWIPE_LEFT": "Scorri verso sinistra per eliminare il record corrispondente.",
"TUTORIAL_SWIPE_RIGHT": "Scorri verso destra per aggiungere ai segnalibri il testo del record corrispondente.",
"TUTORIAL_SWIPE_RIGHT": "Scorri verso destra per aggiungere ai segnalibri il testo del record / modificare il tag del segnalibro corrispondente.",
"UNDO_DELETE": "È possibile annullare l'eliminazione",
"VIBRATION_EXPLAIN": "Fornire vibrazioni o feedback tattile. Tieni presente che non tutti i dispositivi supportano questa funzione."
},
@ -295,7 +305,7 @@
"UPC": "Codice Prodotto Universale "
},
"UPDATE": {
"UPDATE_NOTES_ANDROID": "<p>Questa versione offre numerosi aggiornamenti e nuove funzionalità. Si prega di controllare GitHub per i dettagli.</p><p>Gli utenti Android possono ora abilitare il riquadro Simple QR nel pannello Impostazioni rapide per un rapido accesso.</p>",
"UPDATE_NOTES_IOS": "Questa versione offre numerosi aggiornamenti e nuove funzionalità. Si prega di controllare GitHub per i dettagli."
"UPDATE_NOTES_ANDROID": "<p>Questa versione offre numerosi aggiornamenti e nuove funzionalità. Si prega di controllare GitHub per i dettagli.</p><p>Starting from this version, you can use Ecosia as search engine, export records to CSV and enjoy more reliable data logging.</p>",
"UPDATE_NOTES_IOS": "<p>Questa versione offre numerosi aggiornamenti e nuove funzionalità. Si prega di controllare GitHub per i dettagli.</p><p>Starting from this version, you can use Ecosia as search engine, export records to CSV and enjoy more reliable data logging.</p>"
}
}

View file

@ -45,6 +45,7 @@
"CLOSE": "关闭",
"COLOR": "颜色",
"COLOR_THEME": "颜色主题",
"COMING_SOON": "即将推出",
"CONTACT_METHOD": "联络方法",
"CONTACT_NAME": "联络人名称",
"CONTENT": "内容",
@ -65,6 +66,7 @@
"DETAILED": "详细说明",
"DONE": "完成",
"DUCK_DUCK_GO": "DuckDuckGo",
"ECOSIA": "Ecosia",
"EDIT": "修改",
"EMAIL_ADDRESS": "电邮地址",
"EMAIL_BODY": "电邮内容",
@ -77,6 +79,9 @@
"ERROR_CORRECTION_LEVEL": "容错等级",
"EXIT": "离开",
"EXIT_APP": "离开程序",
"EXPORT": "导出",
"EXPORTING": "导出中",
"EXPORT_TO_CSV": "导出到CSV",
"FAX_NUMBER": "传真号码",
"FEMALE": "女性",
"FIRST_NAME": "名字",
@ -108,11 +113,13 @@
"LOG": "记录",
"LOG_BACKUP_AND_RESTORE": "记录、备份与还原",
"MALE": "男性",
"MANAGE_RECORDS": "管理记录",
"MARGIN": "边距",
"MESSAGE": "信息",
"MESSAGE_CONTENT": "信息内容",
"MICROSOFT_BING": "Microsoft Bing",
"MOBILE_PHONE_NUMBER": "手提电话号码",
"MORE": "更多",
"NAME": "姓名",
"NO": "否",
"NONE": "没有",
@ -127,6 +134,7 @@
"OPEN": "打开",
"OPEN_URL": "打开网址",
"OPEN_WITH_...": "以下方式打开",
"OPTIMIZING_DATA_...": "优化数据...",
"ORGANIZATION": "组织",
"ORIGINAL": "原始",
"OTHERS": "其他",
@ -200,6 +208,7 @@
"VIEW_GITHUB": "查看 GitHub",
"VIEW_LOG": "查看记录",
"VIEW_STORE_AND_SOURCE_CODE": "查看商店及源代码",
"VIEW_INSTRUCTIONS": "查看说明",
"WEBSITE": "网站",
"WIFI": "WiFi",
"WIFI_ENCRYPTION": "安全性",
@ -221,7 +230,6 @@
"BACKUP_SUCCESSFULLY": "<p>成功备份。请妥善保存备份档及以下密码</p><p>{secret}</p>",
"BARCODE_TYPE": "扫描<ul><li>QR 码</li><li>一维条码</li><li>Aztec 码</li><li>数据矩阵码</li><li>PDF417 条码</li></ul>汇入图片<ul><li>QR 码</li></ul>建立<ul><li>QR 码</li></ul>",
"BOOKMARKED": "成功加入书签",
"BOOKMARK_TUTORIAL_SWIPE_RIGHT": "向右划项目可修改标签",
"BUTTON_DISPLAY_EXPLAIN": "显示或隐藏行动按键。",
"BUTTON_STYLE_EXPLAIN": "选择行动按键的样式。",
"CAMERA_PERMISSION": "要使用扫描功能您必须授权「简易QR」使用相机。 ",
@ -236,8 +244,10 @@
"EMAIL_SUBJECT_MAX_LENGTH": "最多 78 个字元",
"ERROR_CORRECTION_LEVEL_EXPLAIN": "<p>QR 码具有容错能力,即使图形有破损,仍然可以被机器读取内容。</p><br><p>容错率分为四个等级:</p><p>L 等级可容错 7% 的字码;</p><p>M 等级可容错 15% 的字码;</p><p>Q 等级可容错 25% 的字码;</p><p>H 等级可容错 30% 的字码。</p><br><p>容错率愈高QR 码图形面积则愈大。因此,在一般情况下建议使用 M 等级。</p>",
"EXIT_APP": "<p>确定要离开?</p><p>若您喜欢简易QR欢迎前往商店评分。</p> ",
"EXPORT_TO_CSV_EXPLAIN": "您可以将所有扫描记录及书签导出到CSV档案。",
"FAILED_SAVING_CONTACT": "无法新增联络人",
"FAIL_PREPARE_SMS": "无法传送信息",
"IMPORT_FROM_CSV_EXPLAIN": "您可以从简易QR定义的CSV档案导入记录和书签。若您想在Android和iOS设备之间传输数据请使用此功能。",
"INPUT_TAG": "请为此书签输入一个标签",
"INVALID_BK_FILE": "这不是有效的备份档",
"NOT_BASE64_DE": "内容不能被 Base64 解码",
@ -279,7 +289,7 @@
"TAG_MAX_LENGTH_EXPLAIN": "标签长度不能多于 30 个字元。",
"TUTORIAL_NOT_SHOW_AGAIN": "下次不再提醒",
"TUTORIAL_SWIPE_LEFT": "向左划项目可删除相关记录",
"TUTORIAL_SWIPE_RIGHT": "向右划项目可将相关记录的文字加入书签",
"TUTORIAL_SWIPE_RIGHT": "向右划项目可将相关记录的文字加入书签 / 修改标签",
"UNDO_DELETE": "您可在数秒内复原记录",
"VIBRATION_EXPLAIN": "提供震动或触感反馈。请注意,并非所有设备皆支援此功能。"
},
@ -295,7 +305,7 @@
"UPC": "通用产品代码"
},
"UPDATE": {
"UPDATE_NOTES_ANDROID": "<p>此版本为您带来多项更新和新功能,详情请查看 GitHub。</p><p>Android 用户现在可以在快速设定面板中加入简易 QR 按键以进行快速启动。</p>",
"UPDATE_NOTES_IOS": "此版本为您带来多项更新和新功能,详情请查看 GitHub。"
"UPDATE_NOTES_ANDROID": "<p>此版本为您带来多项更新和新功能,详情请查看 GitHub。</p><p>Starting from this version, you can use Ecosia as search engine, export records to CSV and enjoy more reliable data logging.</p>",
"UPDATE_NOTES_IOS": "<p>此版本为您带来多项更新和新功能,详情请查看 GitHub。</p><p>Starting from this version, you can use Ecosia as search engine, export records to CSV and enjoy more reliable data logging.</p>"
}
}

View file

@ -45,6 +45,7 @@
"CLOSE": "關閉",
"COLOR": "顏色",
"COLOR_THEME": "顏色主題",
"COMING_SOON": "即將推出",
"CONTACT_METHOD": "聯絡方法",
"CONTACT_NAME": "聯絡人名稱",
"CONTENT": "内容",
@ -65,6 +66,7 @@
"DETAILED": "詳細說明",
"DONE": "完成",
"DUCK_DUCK_GO": "DuckDuckGo",
"ECOSIA": "Ecosia",
"EDIT": "修改",
"EMAIL_ADDRESS": "電郵地址",
"EMAIL_BODY": "電郵內容",
@ -77,6 +79,9 @@
"ERROR_CORRECTION_LEVEL": "容錯等級",
"EXIT": "離開",
"EXIT_APP": "離開程式",
"EXPORT": "匯出",
"EXPORTING": "匯出中",
"EXPORT_TO_CSV": "匯出至CSV",
"FAX_NUMBER": "傳真號碼",
"FEMALE": "女性",
"FIRST_NAME": "名字",
@ -108,11 +113,13 @@
"LOG": "記錄",
"LOG_BACKUP_AND_RESTORE": "記錄、備份與還原",
"MALE": "男性",
"MANAGE_RECORDS": "管理記錄",
"MARGIN": "邊距",
"MESSAGE": "信息",
"MESSAGE_CONTENT": "信息內容",
"MICROSOFT_BING": "Microsoft Bing",
"MOBILE_PHONE_NUMBER": "手提電話號碼",
"MORE": "更多",
"NAME": "姓名",
"NO": "否",
"NONE": "沒有",
@ -127,6 +134,7 @@
"OPEN": "打開",
"OPEN_URL": "打開網址",
"OPEN_WITH_...": "用以下方式打開",
"OPTIMIZING_DATA_...": "最佳化數據...",
"ORGANIZATION": "組織",
"ORIGINAL": "原始",
"OTHERS": "其他",
@ -200,6 +208,7 @@
"VIEW_GITHUB": "查看 GitHub",
"VIEW_LOG": "查看記錄",
"VIEW_STORE_AND_SOURCE_CODE": "查看商店及源代碼",
"VIEW_INSTRUCTIONS": "查看說明",
"WEBSITE": "網站",
"WIFI": "WiFi",
"WIFI_ENCRYPTION": "安全性",
@ -221,7 +230,6 @@
"BACKUP_SUCCESSFULLY": "<p>成功備份。請妥善保存備份檔及以下密碼</p><p>{secret}</p>",
"BARCODE_TYPE": "掃描<ul><li>QR 碼</li><li>一維條碼</li><li>Aztec 碼</li><li>數據矩陣碼</li><li>PDF417 條碼</li></ul>匯入圖片<ul><li>QR 碼</li></ul>建立<ul><li>QR 碼</li></ul>",
"BOOKMARKED": "成功加入書籤",
"BOOKMARK_TUTORIAL_SWIPE_RIGHT": "向右劃項目可修改標籤",
"BUTTON_DISPLAY_EXPLAIN": "顯示或隱藏行動按鍵。",
"BUTTON_STYLE_EXPLAIN": "選擇行動按鍵的樣式。",
"CAMERA_PERMISSION": "要使用掃描功能您必須授權「簡易QR」使用相機。",
@ -236,8 +244,10 @@
"EMAIL_SUBJECT_MAX_LENGTH": "最多 78 個字元",
"ERROR_CORRECTION_LEVEL_EXPLAIN": "<p>QR 碼具有容錯能力,即使圖形有破損,仍然可以被機器讀取內容。</p><br><p>容錯率分為四個等級:</p><p>L 等級可容錯 7% 的字碼;</p><p>M 等級可容錯 15% 的字碼;</p><p>Q 等級可容錯 25% 的字碼;</p><p>H 等級可容錯 30% 的字碼。</p><br><p>容錯率愈高QR 碼圖形面積則愈大。因此,在一般情況下建議使用 M 等級。</p>",
"EXIT_APP": "<p>確定要離開?</p><p>若您喜歡簡易QR歡迎前往商店評分。</p>",
"EXPORT_TO_CSV_EXPLAIN": "您可以將所有掃描記錄及書籤匯出至CSV檔案。",
"FAILED_SAVING_CONTACT": "無法新增聯絡人",
"FAIL_PREPARE_SMS": "無法傳送信息",
"IMPORT_FROM_CSV_EXPLAIN": "您可以從簡易QR定義的CSV檔案匯入記錄和書籤。若您想在Android和iOS設備之間傳輸數據請使用此功能。",
"INPUT_TAG": "請為此書籤輸入一個標籤",
"INVALID_BK_FILE": "這不是有效的備份檔",
"NOT_BASE64_DE": "內容不能被 Base64 解碼",
@ -279,7 +289,7 @@
"TAG_MAX_LENGTH_EXPLAIN": "標籤長度不能多於 30 個字元。",
"TUTORIAL_NOT_SHOW_AGAIN": "下次不再提醒",
"TUTORIAL_SWIPE_LEFT": "向左劃項目可刪除相關記錄",
"TUTORIAL_SWIPE_RIGHT": "向右劃項目可將相關記錄的文字加入書籤",
"TUTORIAL_SWIPE_RIGHT": "向右劃項目可將相關記錄的文字加入書籤 / 修改標籤",
"UNDO_DELETE": "您可在數秒內還原記錄",
"VIBRATION_EXPLAIN": "提供震動或觸感反饋。請注意,並非所有設備皆支援此功能。"
},
@ -295,7 +305,7 @@
"UPC": "通用產品代碼"
},
"UPDATE": {
"UPDATE_NOTES_ANDROID": "<p>此版本為您帶來多項更新和新功能,詳情請查看 GitHub。</p><p>Android 用戶現在可以在快速設定面板中加入簡易 QR 按鍵以進行快速啟動。</p>",
"UPDATE_NOTES_IOS": "此版本為您帶來多項更新和新功能,詳情請查看 GitHub。"
"UPDATE_NOTES_ANDROID": "<p>此版本為您帶來多項更新和新功能,詳情請查看 GitHub。</p><p>Starting from this version, you can use Ecosia as search engine, export records to CSV and enjoy more reliable data logging.</p>",
"UPDATE_NOTES_IOS": "<p>此版本為您帶來多項更新和新功能,詳情請查看 GitHub。</p><p>Starting from this version, you can use Ecosia as search engine, export records to CSV and enjoy more reliable data logging.</p>"
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.1 KiB