mirror of
https://github.com/tomfong/simple-qr.git
synced 2025-06-28 12:09:58 +00:00
commit
9263e05a2d
67 changed files with 3193 additions and 5437 deletions
15
README.md
15
README.md
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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">
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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')
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
6101
package-lock.json
generated
File diff suppressed because it is too large
Load diff
41
package.json
41
package.json
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {}
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
|
@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {}
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
|
@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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()"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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) });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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>
|
|
@ -0,0 +1,8 @@
|
|||
mat-form-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.content-item {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
}
|
|
@ -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');
|
||||
}
|
||||
|
|
|
@ -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;">
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;">
|
||||
|
|
|
@ -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>
|
|
@ -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 });
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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>"
|
||||
}
|
||||
}
|
|
@ -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>"
|
||||
}
|
||||
}
|
|
@ -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>"
|
||||
}
|
||||
}
|
|
@ -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>"
|
||||
}
|
||||
}
|
|
@ -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>"
|
||||
}
|
||||
}
|
|
@ -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>"
|
||||
}
|
||||
}
|
4
src/assets/icon/ecosia.svg
Normal file
4
src/assets/icon/ecosia.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 6.1 KiB |
Loading…
Add table
Add a link
Reference in a new issue