Merge pull request #60 from tomfong/post-v3.1.0-dev

v3.2.0
This commit is contained in:
Tom Fong 2022-11-21 12:10:57 +08:00 committed by GitHub
commit d4b42cb09a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 749 additions and 11291 deletions

View file

@ -63,7 +63,7 @@ By using the app, you can
### Languages Supported
* English (en)
* Traditional Chinese 正體中文 (zh)
* Traditional Chinese (Hong Kong) 中文 (香港) (zh-HK)
* Simplified Chinese 简体中文 (zh-CN)
* German Deutsch (de)
* French Français (fr)
@ -120,20 +120,20 @@ Thank you the following contributors who have made the app better!
## Framework
```sh
Ionic CLI : 6.20.1
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 CLI : 6.20.4
Ionic Framework : @ionic/angular 6.3.7
@angular-devkit/build-angular : 14.2.10
@angular-devkit/schematics : 14.2.10
@angular/cli : 14.2.10
@ionic/angular-toolkit : 6.1.0
Capacitor CLI : 4.3.0
@capacitor/android : 4.3.0
@capacitor/core : 4.3.0
@capacitor/ios : 4.3.0
Capacitor CLI : 4.5.0
@capacitor/android : 4.5.0
@capacitor/core : 4.5.0
@capacitor/ios : 4.5.0
NodeJS : v16.15.1
npm : 8.19.2
npm : 9.1.1
```
## Privacy Policy

View file

@ -6,8 +6,8 @@ android {
applicationId "com.tomfong.simpleqr"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 3010000
versionName "3.1.0"
versionCode 3020000
versionName "3.2.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

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<color tools:ignore="UnusedResources" name="colorPrimary">#00a5aa</color>
<color tools:ignore="UnusedResources" name="colorPrimaryDark">#00a5aa</color>
<color tools:ignore="UnusedResources" name="colorAccent">#00a5aa</color>
</resources>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<color tools:ignore="UnusedResources" name="colorPrimary">#00a5aa</color>
<color tools:ignore="UnusedResources" name="colorPrimaryDark">#00a5aa</color>
<color tools:ignore="UnusedResources" name="colorAccent">#00a5aa</color>
</resources>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<color tools:ignore="UnusedResources" name="colorPrimary">#00a5aa</color>
<color tools:ignore="UnusedResources" name="colorPrimaryDark">#00a5aa</color>
<color tools:ignore="UnusedResources" name="colorAccent">#00a5aa</color>
</resources>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<color tools:ignore="UnusedResources" name="colorPrimary">#00a5aa</color>
<color tools:ignore="UnusedResources" name="colorPrimaryDark">#00a5aa</color>
<color tools:ignore="UnusedResources" name="colorAccent">#00a5aa</color>
</resources>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<color tools:ignore="UnusedResources" name="colorPrimary">#00a5aa</color>
<color tools:ignore="UnusedResources" name="colorPrimaryDark">#00a5aa</color>
<color tools:ignore="UnusedResources" name="colorAccent">#00a5aa</color>
</resources>

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.1.0;
MARKETING_VERSION = 3.2.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.1.0;
MARKETING_VERSION = 3.2.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tomfong.simpleqr;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Simple QR";

11619
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.1.0",
"version": "3.2.0",
"author": "Tom Fong",
"homepage": "https://tomfong.github.io",
"scripts": {
@ -21,41 +21,41 @@
"@angular/cdk": "^14.2.2",
"@angular/common": "^14.2.3",
"@angular/core": "^14.2.3",
"@angular/forms": "^14.2.6",
"@angular/localize": "^14.2.6",
"@angular/forms": "^14.2.11",
"@angular/localize": "^14.2.11",
"@angular/material": "^14.2.2",
"@angular/material-moment-adapter": "^14.2.5",
"@angular/material-moment-adapter": "^14.2.7",
"@angular/platform-browser": "^14.2.3",
"@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",
"@angular/platform-browser-dynamic": "^14.2.11",
"@angular/router": "^14.2.11",
"@awesome-cordova-plugins/aes-256": "^6.2.0",
"@awesome-cordova-plugins/chooser": "^6.2.0",
"@awesome-cordova-plugins/core": "^6.2.0",
"@awesome-cordova-plugins/screen-orientation": "^6.2.0",
"@awesome-cordova-plugins/sms": "^6.2.0",
"@awesome-cordova-plugins/social-sharing": "^6.2.0",
"@awesome-cordova-plugins/theme-detection": "^6.2.0",
"@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.2",
"@capacitor/clipboard": "^4.0.1",
"@capacitor/core": "^4.3.0",
"@capacitor/device": "^4.0.1",
"@capacitor/filesystem": "^4.1.2",
"@capacitor/haptics": "^4.0.1",
"@capacitor/ios": "^4.3.0",
"@capacitor/keyboard": "^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.3.2",
"@capacitor-community/screen-brightness": "^4.0.0",
"@capacitor/android": "^4.5.0",
"@capacitor/app": "^4.1.1",
"@capacitor/camera": "^4.1.4",
"@capacitor/clipboard": "^4.1.0",
"@capacitor/core": "^4.5.0",
"@capacitor/device": "^4.1.0",
"@capacitor/filesystem": "^4.1.4",
"@capacitor/haptics": "^4.1.0",
"@capacitor/ios": "^4.5.0",
"@capacitor/keyboard": "^4.1.0",
"@capacitor/preferences": "^4.0.2",
"@capacitor/splash-screen": "^4.1.2",
"@capacitor/status-bar": "^4.1.0",
"@capacitor/toast": "^4.1.0",
"@ionic/angular": "^6.3.7",
"@ionic/storage": "^3.0.6",
"@ionic/storage-angular": "^3.0.6",
"@ng-bootstrap/ng-bootstrap": "^13.0.0",
"@ng-bootstrap/ng-bootstrap": "^13.1.1",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
"@techiediaries/ngx-qrcode": "^9.1.0",
@ -75,17 +75,17 @@
"properties-parser": "^0.3.1",
"rxjs": "^6.6.7",
"strip-final-newline": "^2.0.0",
"tslib": "^2.4.0",
"tslib": "^2.4.1",
"uuid": "^8.3.2",
"zone.js": "^0.11.8"
},
"devDependencies": {
"@angular-devkit/build-angular": "^14.2.6",
"@angular/cli": "^14.2.6",
"@angular-devkit/build-angular": "^14.2.10",
"@angular/cli": "^14.2.10",
"@angular/compiler": "^14.2.3",
"@angular/compiler-cli": "^14.2.3",
"@angular/language-service": "^14.2.6",
"@capacitor/cli": "^4.3.0",
"@angular/language-service": "^14.2.11",
"@capacitor/cli": "^4.5.0",
"@ionic/angular-toolkit": "^6.1.0",
"@ionic/cli": "6.20.1",
"@types/jasmine": "^3.10.6",

View file

@ -1,4 +1,7 @@
import { Component } from '@angular/core';
import { App } from '@capacitor/app';
import { SplashScreen } from '@capacitor/splash-screen';
import { Toast } from '@capacitor/toast';
import { Platform } from '@ionic/angular';
import { TranslateService } from '@ngx-translate/core';
import { EnvService } from './services/env.service';
@ -17,5 +20,29 @@ export class AppComponent {
) {
translate.addLangs(this.env.languages);
translate.setDefaultLang('en');
if (this.platform.is('ios')) {
App.addListener('appStateChange', async ({ isActive }) => {
if (env.isDebugging) {
this.presentToast(`App state changed. Is active?: ${isActive}`, "short", "bottom");
}
if (isActive) {
setTimeout(async () => {
await SplashScreen.hide();
}, 300);
} else {
await SplashScreen.show({
autoHide: false
});
}
});
}
}
async presentToast(msg: string, duration: "short" | "long", pos: "top" | "center" | "bottom") {
await Toast.show({
text: msg,
duration: duration,
position: pos
});
}
}

View file

@ -106,6 +106,12 @@
[ngStyle]="env.colorTheme === 'dark'? {'background-color': '#222428'} : (env.colorTheme === 'black'? {'background-color': '#000000'} : {'background-color': '#F0F0F0'})">
<ng-container *ngIf="env.resultPageButtons === 'icon-only'">
<ion-row *ngIf="contentType === 'freeText' && env.showOpenFoodFactsButton === 'on' && isValidEan" class="d-flex justify-content-center">
<ion-button (click)="tapHaptic(); searchOpenFoodFacts()" [color]="'primary'" fill="clear">
<ion-icon name="fast-food"></ion-icon>
</ion-button>
</ion-row>
<ion-row *ngIf="contentType === 'url' && env.showBrowseButton === 'on' && isHttp" class="d-flex justify-content-center">
<ion-button (click)="tapHaptic(); browseWebsite()" [color]="'primary'" fill="clear">
<ion-icon name="globe"></ion-icon>
@ -207,6 +213,12 @@
<ng-container *ngIf="env.resultPageButtons === 'detailed'">
<ion-row class="ion-padding-horizontal py-2">
<div class="d-flex justify-content-between detailed-action-button-container">
<ion-button class="pr-1" *ngIf="contentType === 'freeText' && env.showOpenFoodFactsButton === 'on' && isValidEan"
(click)="tapHaptic(); searchOpenFoodFacts()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
shape="round" [@inAnimation]>
<ion-icon class="pr-2" name="fast-food"></ion-icon>
<ion-label>Facts</ion-label>
</ion-button>
<ion-button class="pr-1" *ngIf="contentType === 'url' && env.showBrowseButton === 'on' && isHttp"
(click)="tapHaptic(); browseWebsite()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
shape="round" [@inAnimation]>

View file

@ -190,6 +190,10 @@ export class ResultPage {
return "#ffffff";
}
searchOpenFoodFacts() {
window.open(`https://world.openfoodfacts.org/product/${this.qrCodeContent}`, '_system', 'location=yes');
}
browseWebsite() {
window.open(this.qrCodeContent, '_system', 'location=yes');
}
@ -903,6 +907,32 @@ export class ResultPage {
}
}
get isValidEan(): boolean {
if (this.qrCodeContent == null) {
return false;
}
const isValidLength = this.qrCodeContent.length === 18 || this.qrCodeContent.length === 14 || this.qrCodeContent.length === 13 || this.qrCodeContent.length === 8 || this.qrCodeContent.length === 5;
return isValidLength && /^\d+$/.test(this.qrCodeContent) && this.testEanChecksum(this.qrCodeContent);
}
private testEanChecksum(text: string): boolean {
const digits = text.slice(0, -1);
const checkDigit = parseInt(text.slice(-1));
if (isNaN(checkDigit)) {
return false;
}
let sum = 0;
for (let i = digits.length - 1; i >= 0; i--) {
const digit = parseInt(digits.charAt(i));
if (isNaN(digit)) {
return false;
}
sum += (digit * (1 + (2 * (i % 2)))) | 0;
}
sum = (10 - (sum % 10)) % 10;
return sum === checkDigit;
}
get finalContactName(): string {
if (!this.vCardContact) {
return '';

View file

@ -75,7 +75,7 @@
<ion-label class="ion-padding-start">
<p class="ion-padding pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
正體中文 (zh)
中文 (香港) (zh-HK)
</ion-text>
</p>
</ion-label>

View file

@ -215,7 +215,7 @@
</div>
</div>
<div class="ion-padding-vertical mb-2">
<div class="ion-padding-vertical mb-1">
<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">
@ -234,7 +234,7 @@
</div>
<!-- TODO: Import from CSV -->
<div class="ion-padding-vertical mb-1">
<!-- <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">
@ -246,10 +246,10 @@
</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 class="ion-padding-horizontal" color="primary" (click)="onImportFromCsv()">
{{ 'IMPORT_FROM_CSV' | translate }}
</ion-button>
</div>
</div>
</div> -->
</ion-content>

View file

@ -326,12 +326,17 @@ export class SettingRecordPage {
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 ?? ''},`
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`;
rawCsvData += `"TRUE","${bookmark.tag?.split('"').join('') ?? ""}"\r\n`;
} else {
rawCsvData += "FALSE, \r\n";
rawCsvData += `"FALSE",""\r\n`;
}
});
this.env.bookmarks.forEach(b => {
if (this.env.scanRecords.findIndex(r => r.text == b.text) == -1) {
rawCsvData += `"-","${b.text?.split('"').join('') ?? ""}","${this.maskDatetime(b.createdAt)}","-","-","TRUE","${b.tag?.split('"').join('') ?? ""}"\r\n`
}
});
await Filesystem.writeFile({
@ -367,9 +372,86 @@ export class SettingRecordPage {
);
}
async onImportFromCsv() {
// TODO: Import from CSV
}
// async onImportFromCsv() {
// // TODO: Import from CSV
// const loading1 = await this.presentLoading(this.translate.instant("PLEASE_WAIT"));
// await this.chooser.getFile().then(
// async (value: ChooserResult) => {
// if (value == null) {
// loading1.dismiss();
// return;
// }
// if (!value.name.toLowerCase().endsWith(".csv")) {
// loading1.dismiss();
// this.presentToast(`${this.translate.instant("MSG.INVALID_CSV_FILE")} (1)`, "short", "bottom");
// return;
// }
// await Filesystem.readFile({
// path: value.uri,
// encoding: Encoding.UTF8
// }).then(
// async value => {
// loading1.dismiss();
// const loading2 = await this.presentLoading(this.translate.instant("DECODING"));
// const data = value.data;
// if (data.length == 0) {
// loading2.dismiss();
// this.presentToast(`${this.translate.instant("MSG.INVALID_CSV_FILE")} (2)`, "short", "bottom");
// return;
// }
// const lines = data.split("\r\n");
// if (lines.length <= 1) {
// loading2.dismiss();
// this.presentToast(`${this.translate.instant("MSG.INVALID_CSV_FILE")} (3)`, "short", "bottom");
// return;
// }
// const scanRecords = [];
// for (var i = 1; i < lines.length; i++) {
// const line = lines[i];
// if (line.length == 0) {
// loading2.dismiss();
// this.presentToast(`${this.translate.instant("MSG.INVALID_CSV_FILE")} (4)`, "short", "bottom");
// return;
// }
// const items = line.split(`","`);
// if (items.length != 7) {
// loading2.dismiss();
// this.presentToast(`${this.translate.instant("MSG.INVALID_CSV_FILE")} (5)`, "short", "bottom");
// return;
// }
// const id = items[0].replace(`"`, "");
// if (isNaN(parseInt(id))) {
// loading2.dismiss();
// this.presentToast(`${this.translate.instant("MSG.INVALID_CSV_FILE")} (6)`, "short", "bottom");
// return;
// }
// }
// if (scanRecords.length > 0) {
// await this.env.saveRestoredScanRecords(scanRecords);
// }
// }
// ).catch(
// err => {
// loading1.dismiss();
// if (this.env.debugMode === 'on') {
// this.presentToast('Failed to read file', "long", "bottom");
// } else {
// this.presentToast(this.translate.instant("MSG.IMPORT_FAILED"), "short", "bottom");
// }
// }
// )
// }
// ).catch(
// err => {
// loading1.dismiss();
// if (this.env.isDebugging) {
// this.presentToast("Error when call Chooser.getFile: " + JSON.stringify(err), "long", "top");
// } else {
// this.presentToast(this.translate.instant("MSG.IMPORT_FAILED"), "short", "bottom");
// }
// }
// )
// }
maskDatetime(date: Date): string {
if (!date) {

View file

@ -237,4 +237,19 @@
</ion-toggle>
</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'" name="fast-food">
</ion-icon>
<ion-label>
<p class="ion-padding pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
Open Food Facts
</ion-text>
</p>
</ion-label>
<ion-toggle class="ion-padding-end" slot="end" [ngModel]="env.showOpenFoodFactsButton == 'on'? true : false"
(ngModelChange)="onOpenFoodFactsButtonChange($event)">
</ion-toggle>
</ion-item>
</ion-content>

View file

@ -85,6 +85,12 @@ export class SettingResultButtonsPage {
await this.tapHaptic();
}
async onOpenFoodFactsButtonChange(ev: any) {
this.env.showOpenFoodFactsButton = ev ? 'on' : 'off';
await Preferences.set({ key: this.env.KEY_SHOW_OPEN_FOOD_FACTS_BUTTON, value: this.env.showOpenFoodFactsButton });
await this.tapHaptic();
}
async tapHaptic() {
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
await Haptics.impact({ style: ImpactStyle.Light })

View file

@ -31,7 +31,7 @@ export declare type ResultPageButtonsType = 'detailed' | 'icon-only';
})
export class EnvService {
public appVersionNumber: string = '3.1.0';
public appVersionNumber: string = '3.2.0';
public startPage: TabPageType = "/tabs/scan";
public historyPageStartSegment: HistoryPageSegmentType = 'history';
@ -74,6 +74,7 @@ export class EnvService {
public showCallButton: OnOffType = 'on';
public showSendMessageButton: OnOffType = 'on';
public showSendEmailButton: OnOffType = 'on';
public showOpenFoodFactsButton: OnOffType = 'on';
public debugMode: OnOffType = 'off';
public autoExitAppMin: 1 | 3 | 5 | -1 = -1;
@ -117,12 +118,13 @@ export class EnvService {
public readonly KEY_SHOW_CALL_BUTTON = "showCallButton";
public readonly KEY_SHOW_SEND_MESSAGE_BUTTON = "showSendMessageButton";
public readonly KEY_SHOW_SEND_EMAIL_BUTTON = "showSendEmailButton";
public readonly KEY_SHOW_OPEN_FOOD_FACTS_BUTTON = "showOpenFoodFactsButton";
public readonly KEY_AUTO_EXIT_MIN = "autoExitAppMin";
public readonly KEY_ANDROID_NOT_SHOW_UPDATE_NOTES = "not-show-update-notes-v30100";
public readonly KEY_IOS_NOT_SHOW_UPDATE_NOTES = "not-show-update-notes-v30100";
public readonly KEY_ANDROID_PREV_NOT_SHOW_UPDATE_NOTES = "not-show-update-notes-v30001";
public readonly KEY_IOS_PREV_NOT_SHOW_UPDATE_NOTES = "not-show-update-notes-v30001";
public readonly KEY_ANDROID_NOT_SHOW_UPDATE_NOTES = "not-show-update-notes-v30200";
public readonly KEY_IOS_NOT_SHOW_UPDATE_NOTES = "not-show-update-notes-v30200";
public readonly KEY_ANDROID_PREV_NOT_SHOW_UPDATE_NOTES = "not-show-update-notes-v30100";
public readonly KEY_IOS_PREV_NOT_SHOW_UPDATE_NOTES = "not-show-update-notes-v30100";
public readonly APP_FOLDER_NAME: string = 'SimpleQR';
@ -1148,6 +1150,15 @@ export class EnvService {
}
}
);
await Preferences.get({ key: this.KEY_SHOW_OPEN_FOOD_FACTS_BUTTON }).then(
async result => {
if (result.value != null) {
this.showOpenFoodFactsButton = result.value as OnOffType;
} else {
this.showOpenFoodFactsButton = 'on';
}
}
);
await Preferences.get({ key: this.KEY_AUTO_EXIT_MIN }).then(
async result => {
if (result.value != null) {
@ -1202,6 +1213,7 @@ export class EnvService {
this.showCallButton = 'on';
this.showSendMessageButton = 'on';
this.showSendEmailButton = 'on';
this.showOpenFoodFactsButton = 'on';
this.scanRecords = [];
this.bookmarks = [];
this.debugMode = 'off';
@ -1334,6 +1346,9 @@ export class EnvService {
this.showSendEmailButton = 'on';
await Preferences.set({ key: this.KEY_SHOW_SEND_EMAIL_BUTTON, value: this.showSendEmailButton });
this.showOpenFoodFactsButton = 'on';
await Preferences.set({ key: this.KEY_SHOW_OPEN_FOOD_FACTS_BUTTON, value: this.showOpenFoodFactsButton });
this.debugMode = 'off';
await Preferences.set({ key: this.KEY_DEBUG_MODE, value: this.debugMode });

View file

@ -97,6 +97,7 @@
"HOME_PHONE_NUMBER": "Telefonnummer zu Hause",
"ICON_ONLY": "Nur Icon",
"IMPORT": "Importieren",
"IMPORT_FROM_CSV": "Aus CSV importieren",
"IMPORT_IMAGE": "Bild importieren",
"INITIAL_SEGMENT": "Erstes Segment",
"JOB_TITLE": "Berufsbezeichnung",
@ -247,9 +248,11 @@
"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_FAILED": "Importieren fehlgeschlagen",
"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.",
"INVALID_CSV_FILE": "Dies ist keine gültige CSV-Datei.",
"NOT_BASE64_DE": "Daten können nicht Base64-dekodiert werden",
"NOT_BASE64_EN": "Daten können nicht Base64-kodiert werden",
"NOT_BASE64_EN_DE": "Daten können nicht mit Base64 kodiert und dekodiert werden",
@ -305,7 +308,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>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>"
"UPDATE_NOTES_ANDROID": "<p>Diese Version bringt Ihnen mehrere Updates und neue Funktionen. Bitte überprüfen Sie GitHub für Details.</p>",
"UPDATE_NOTES_IOS": "<p>Diese Version bringt Ihnen mehrere Updates und neue Funktionen. Bitte überprüfen Sie GitHub für Details.</p>"
}
}

View file

@ -97,6 +97,7 @@
"HOME_PHONE_NUMBER": "Home Phone Number",
"ICON_ONLY": "Icon Only",
"IMPORT": "Import",
"IMPORT_FROM_CSV": "Import from CSV",
"IMPORT_IMAGE": "Import Image",
"INITIAL_SEGMENT": "Initial Segment",
"JOB_TITLE": "Job Title",
@ -247,9 +248,11 @@
"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_FAILED": "Failed to import",
"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.",
"INVALID_CSV_FILE": "This is not a valid CSV file.",
"NOT_BASE64_DE": "Data cannot be Base64 decoded",
"NOT_BASE64_EN": "Data cannot be Base64 encoded",
"NOT_BASE64_EN_DE": "Data cannot be Base64 encoded and decoded",
@ -305,7 +308,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>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>"
"UPDATE_NOTES_ANDROID": "<p>This release brings you several updates and new features. Please check GitHub for details.</p>",
"UPDATE_NOTES_IOS": "<p>This release brings you several updates and new features. Please check GitHub for details.</p>"
}
}

View file

@ -97,6 +97,7 @@
"HOME_PHONE_NUMBER": "Numéro de téléphone résidentiel",
"ICON_ONLY": "Icône uniquement",
"IMPORT": "Importer",
"IMPORT_FROM_CSV": "Importer depuis CSV",
"IMPORT_IMAGE": "Importer une image",
"INITIAL_SEGMENT": "Segment initial",
"JOB_TITLE": "Titre d'emploi",
@ -247,9 +248,11 @@
"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_FAILED": "Échec de l'importation",
"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.",
"INVALID_CSV_FILE": "Ce fichier CSV n'est pas valide.",
"NOT_BASE64_DE": "Les données ne peuvent pas être décodées en Base64",
"NOT_BASE64_EN": "Les données ne peuvent pas être encodées en Base64",
"NOT_BASE64_EN_DE": "Les données ne peuvent pas être encodées et décodées en Base64",
@ -305,7 +308,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>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>"
"UPDATE_NOTES_ANDROID": "<p>Cette version vous apporte plusieurs mises à jour et nouvelles fonctionnalités. Veuillez consulter GitHub pour plus de détails.</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>"
}
}

View file

@ -97,6 +97,7 @@
"HOME_PHONE_NUMBER": "Numero di telefono di casa",
"ICON_ONLY": "Disponibile solo icona",
"IMPORT": "Importa",
"IMPORT_FROM_CSV": "Importa da CSV",
"IMPORT_IMAGE": "Importa immagine",
"INITIAL_SEGMENT": "Segmento iniziale",
"JOB_TITLE": "Titolo di lavoro",
@ -247,9 +248,11 @@
"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_FAILED": "Impossibile importare",
"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.",
"INVALID_CSV_FILE": "CSV non valido.",
"NOT_BASE64_DE": "I dati non possono essere decodificati in Base64",
"NOT_BASE64_EN": "I dati non possono essere decodificati in Base64",
"NOT_BASE64_EN_DE": "I dati non possono essere decodificati in Base64",
@ -305,7 +308,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>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>"
"UPDATE_NOTES_ANDROID": "<p>Questa versione offre numerosi aggiornamenti e nuove funzionalità. Si prega di controllare GitHub per i dettagli.</p>",
"UPDATE_NOTES_IOS": "<p>Questa versione offre numerosi aggiornamenti e nuove funzionalità. Si prega di controllare GitHub per i dettagli.</p>"
}
}

View file

@ -96,8 +96,9 @@
"HOME_ADDRESS": "家居地址",
"HOME_PHONE_NUMBER": "家居电话号码",
"ICON_ONLY": "仅限图示",
"IMPORT": "汇入",
"IMPORT_IMAGE": "汇入图片",
"IMPORT": "导入",
"IMPORT_FROM_CSV": "从CSV导入",
"IMPORT_IMAGE": "导入图片",
"INITIAL_SEGMENT": "起始分页",
"JOB_TITLE": "职位名称",
"LANGUAGE": "语言",
@ -228,7 +229,7 @@
"BACKUP_FAILED": "备份失败",
"BACKUP_FAILED_2": "备份失败。请确保已允许「简易QR」存取储存空间",
"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>",
"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": "成功加入书签",
"BUTTON_DISPLAY_EXPLAIN": "显示或隐藏行动按键。",
"BUTTON_STYLE_EXPLAIN": "选择行动按键的样式。",
@ -247,9 +248,11 @@
"EXPORT_TO_CSV_EXPLAIN": "您可以将所有扫描记录及书签导出到CSV档案。",
"FAILED_SAVING_CONTACT": "无法新增联络人",
"FAIL_PREPARE_SMS": "无法传送信息",
"IMPORT_FAILED": "导入失敗",
"IMPORT_FROM_CSV_EXPLAIN": "您可以从简易QR定义的CSV档案导入记录和书签。若您想在Android和iOS设备之间传输数据请使用此功能。",
"INPUT_TAG": "请为此书签输入一个标签",
"INVALID_BK_FILE": "这不是有效的备份档",
"INVALID_CSV_FILE": "这不是有效的CSV档",
"NOT_BASE64_DE": "内容不能被 Base64 解码",
"NOT_BASE64_EN": "内容不能被 Base64 编码",
"NOT_BASE64_EN_DE": "内容不能被 Base64 编码及解码",
@ -275,7 +278,7 @@
"SAVED_CONTACT": "已新增联络人",
"SAVING_CONTACT": "正在新增联络人",
"SCAN_QR_FROM_IMAGE": "简易 QR 使用「cozmo/jsQR」模组扫描图片里 QR 码。请注意,",
"SCAN_QR_FROM_IMAGE_R1": "入图片时您必须授权程序存取储存空间或相簿。",
"SCAN_QR_FROM_IMAGE_R1": "入图片时您必须授权程序存取储存空间或相簿。",
"SCAN_QR_FROM_IMAGE_R2": "请确保所选择的图片并非透明背景。建议选择非相机摄取的图片。",
"SCAN_QR_FROM_IMAGE_R3": "若要扫描整张图片,请取消或略过相片编辑步骤。(如适用)",
"SEARCH": "您想搜索哪一个内容?",
@ -305,7 +308,7 @@
"UPC": "通用产品代码"
},
"UPDATE": {
"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>"
"UPDATE_NOTES_ANDROID": "<p>此版本为您带来多项更新和新功能,详情请查看 GitHub。</p>",
"UPDATE_NOTES_IOS": "<p>此版本为您带来多项更新和新功能,详情请查看 GitHub。</p>"
}
}

View file

@ -97,6 +97,7 @@
"HOME_PHONE_NUMBER": "家居電話號碼",
"ICON_ONLY": "僅限圖示",
"IMPORT": "匯入",
"IMPORT_FROM_CSV": "從CSV匯入",
"IMPORT_IMAGE": "匯入圖片",
"INITIAL_SEGMENT": "起始分頁",
"JOB_TITLE": "職位名稱",
@ -247,9 +248,11 @@
"EXPORT_TO_CSV_EXPLAIN": "您可以將所有掃描記錄及書籤匯出至CSV檔案。",
"FAILED_SAVING_CONTACT": "無法新增聯絡人",
"FAIL_PREPARE_SMS": "無法傳送信息",
"IMPORT_FAILED": "匯入失敗",
"IMPORT_FROM_CSV_EXPLAIN": "您可以從簡易QR定義的CSV檔案匯入記錄和書籤。若您想在Android和iOS設備之間傳輸數據請使用此功能。",
"INPUT_TAG": "請為此書籤輸入一個標籤",
"INVALID_BK_FILE": "這不是有效的備份檔",
"INVALID_CSV_FILE": "這不是有效的CSV檔",
"NOT_BASE64_DE": "內容不能被 Base64 解碼",
"NOT_BASE64_EN": "內容不能被 Base64 編碼",
"NOT_BASE64_EN_DE": "內容不能被 Base64 編碼及解碼",
@ -305,7 +308,7 @@
"UPC": "通用產品代碼"
},
"UPDATE": {
"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>"
"UPDATE_NOTES_ANDROID": "<p>此版本為您帶來多項更新和新功能,詳情請查看 GitHub。</p>",
"UPDATE_NOTES_IOS": "<p>此版本為您帶來多項更新和新功能,詳情請查看 GitHub。</p>"
}
}

View file

@ -4,7 +4,7 @@
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 271 236" style="enable-background: new 0 0 271 236;">
<style type="text/css">
.frame {
fill: #00acc1;
fill: #00a5aa;
fill-opacity: 0.5;
}
</style>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Before After
Before After

View file

@ -45,20 +45,20 @@ $app-black-theme: mat.define-dark-theme(
:root {
/** primary **/
--ion-color-primary: #00acc1;
--ion-color-primary: #00a5aa;
--ion-color-primary-rgb: 0, 172, 193;
--ion-color-primary-contrast: #ffffff;
--ion-color-primary-contrast-rgb: 255, 255, 255;
--ion-color-primary-shade: #00acc1;
--ion-color-primary-tint: #00acc1;
--ion-color-primary-shade: #00a5aa;
--ion-color-primary-tint: #00a5aa;
/** secondary **/
--ion-color-secondary: #00acc1;
--ion-color-secondary: #00a5aa;
--ion-color-secondary-rgb: 0, 172, 193;
--ion-color-secondary-contrast: #ffffff;
--ion-color-secondary-contrast-rgb: 255, 255, 255;
--ion-color-secondary-shade: #00acc1;
--ion-color-secondary-tint: #00acc1;
--ion-color-secondary-shade: #00a5aa;
--ion-color-secondary-tint: #00a5aa;
/** tertiary **/
--ion-color-tertiary: #5260ff;
@ -214,12 +214,12 @@ $app-black-theme: mat.define-dark-theme(
}
body.dark {
--ion-color-primary: #00acc1;
--ion-color-primary: #00a5aa;
--ion-color-primary-rgb: 0, 172, 193;
--ion-color-primary-contrast: #ffffff;
--ion-color-primary-contrast-rgb: 255, 255, 255;
--ion-color-primary-shade: #00acc1;
--ion-color-primary-tint: #00acc1;
--ion-color-primary-shade: #00a5aa;
--ion-color-primary-tint: #00a5aa;
/** secondary **/
--ion-color-secondary: #1b89cd;