Merge pull request #54 from tomfong/post-v2.8.0-dev

3.0.0
This commit is contained in:
Tom Fong 2022-09-23 19:19:57 +08:00 committed by GitHub
commit 07b99da79c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 3948 additions and 3424 deletions

View file

@ -105,15 +105,9 @@ You are welcomed to help translate the app into more languages (refer to this <a
### Build the project (Android) ### Build the project (Android)
1. Run ```npm install``` to install all dependencies 1. Run ```npm install``` to install all dependencies.
2. Run ```npm run sync``` and ```npm run copy:an``` 2. Run ```npm run build:an``` or ```npm run build:ios``` (for first time).
3. In ```android/app/src/main/res/values/styles.xml```, change 3. Run ```npm run sync``` and ```npm run copy:an``` or ```npm run copy:ios```.
```xml
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar">
<item name="android:background">#00a5aa</item>
</style>
```
### Contributors ### Contributors
@ -128,16 +122,16 @@ Thank you the following contributors who have made the app better!
```sh ```sh
Ionic CLI : 6.20.1 Ionic CLI : 6.20.1
Ionic Framework : @ionic/angular 6.2.7 Ionic Framework : @ionic/angular 6.2.8
@angular-devkit/build-angular : 13.3.9 @angular-devkit/build-angular : 14.2.3
@angular-devkit/schematics : 13.3.9 @angular-devkit/schematics : 13.3.9
@angular/cli : 13.3.9 @angular/cli : 14.2.3
@ionic/angular-toolkit : 6.1.0 @ionic/angular-toolkit : 6.1.0
Capacitor CLI : 3.8.0 Capacitor CLI : 4.3.0
@capacitor/android : 3.8.0 @capacitor/android : 4.3.0
@capacitor/core : 3.8.0 @capacitor/core : 4.3.0
@capacitor/ios : 3.8.0 @capacitor/ios : 4.3.0
NodeJS : v16.15.1 NodeJS : v16.15.1
npm : 8.11.0 npm : 8.11.0

View file

@ -1,5 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="app/src/main/res/drawable/ic_launcher_background.xml" value="0.2485" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>

View file

@ -6,8 +6,8 @@ android {
applicationId "com.tomfong.simpleqr" applicationId "com.tomfong.simpleqr"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 2080000 versionCode 3000000
versionName "2.8.0" versionName "3.0.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions { aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
@ -30,6 +30,8 @@ repositories {
} }
dependencies { dependencies {
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
implementation project(':capacitor-android') implementation project(':capacitor-android')

View file

@ -2,8 +2,8 @@
android { android {
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_11
} }
} }

View file

@ -15,13 +15,23 @@
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
</provider> </provider>
<service
android:name=".MyQSTileService"
android:label="@string/app_name"
android:icon="@drawable/ic_baseline_qr_code_24"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
android:exported="true">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
</application> </application>
<!-- Permissions --> <!-- Permissions -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-sdk tools:overrideLibrary="com.google.zxing.client.android" /> <uses-sdk tools:overrideLibrary="com.google.zxing.client.android" />
</manifest> </manifest>

View file

@ -2,4 +2,20 @@ package com.tomfong.simpleqr;
import com.getcapacitor.BridgeActivity; import com.getcapacitor.BridgeActivity;
public class MainActivity extends BridgeActivity {} public class MainActivity extends BridgeActivity {
static boolean active = false;
@Override
public void onStart() {
super.onStart();
active = true;
}
@Override
public void onStop() {
super.onStop();
active = false;
}
}

View file

@ -0,0 +1,61 @@
package com.tomfong.simpleqr;
import android.content.Intent;
import android.os.Build;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
import android.util.Log;
import androidx.annotation.RequiresApi;
@RequiresApi(api = Build.VERSION_CODES.N)
public class MyQSTileService extends TileService {
// Called when the user adds your tile.
@Override
public void onTileAdded() {
super.onTileAdded();
Log.println(Log.INFO,"MyQSTileService","onTileAdded");
}
// Called when your app can update your tile.
@Override
public void onStartListening() {
super.onStartListening();
Log.println(Log.INFO,"MyQSTileService","onStartListening");
Tile tile = this.getQsTile();
if (MainActivity.active) {
tile.setState(Tile.STATE_ACTIVE);
} else {
tile.setState(Tile.STATE_INACTIVE);
}
tile.updateTile();
}
// Called when your app can no longer update your tile.
@Override
public void onStopListening() {
super.onStopListening();
Log.println(Log.INFO,"MyQSTileService","onStopListening");
}
// Called when the user taps on your tile in an active or inactive state.
@Override
public void onClick() {
super.onClick();
Log.println(Log.INFO,"MyQSTileService","onClick");
Tile tile = this.getQsTile();
Intent intent = new Intent(this.getApplicationContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityAndCollapse(intent);
tile.setState(Tile.STATE_ACTIVE);
tile.updateTile();
}
// Called when the user removes your tile.
@Override
public void onTileRemoved() {
super.onTileRemoved();
Log.println(Log.INFO,"MyQSTileService","onTileRemoved");
}
}

View file

@ -0,0 +1,15 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M3,11h8V3H3V11zM5,5h4v4H5V5z"/>
<path android:fillColor="@android:color/white" android:pathData="M3,21h8v-8H3V21zM5,15h4v4H5V15z"/>
<path android:fillColor="@android:color/white" android:pathData="M13,3v8h8V3H13zM19,9h-4V5h4V9z"/>
<path android:fillColor="@android:color/white" android:pathData="M19,19h2v2h-2z"/>
<path android:fillColor="@android:color/white" android:pathData="M13,13h2v2h-2z"/>
<path android:fillColor="@android:color/white" android:pathData="M15,15h2v2h-2z"/>
<path android:fillColor="@android:color/white" android:pathData="M13,17h2v2h-2z"/>
<path android:fillColor="@android:color/white" android:pathData="M15,19h2v2h-2z"/>
<path android:fillColor="@android:color/white" android:pathData="M17,17h2v2h-2z"/>
<path android:fillColor="@android:color/white" android:pathData="M17,13h2v2h-2z"/>
<path android:fillColor="@android:color/white" android:pathData="M19,15h2v2h-2z"/>
</vector>

View file

@ -9,14 +9,13 @@
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
</style> </style>
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.NoActionBar"> <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
<item name="android:background">@null</item> <item name="android:background">@null</item>
</style> </style>
<style name="AppTheme.NoActionBarLaunch" parent="Theme.SplashScreen">
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar"> <item name="android:background">@drawable/splash</item>
<item name="android:background">#00a5aa</item>
</style> </style>
</resources> </resources>

View file

@ -9,14 +9,14 @@
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
</style> </style>
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.NoActionBar"> <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
<item name="android:background">@null</item> <item name="android:background">@null</item>
</style> </style>
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar"> <style name="AppTheme.NoActionBarLaunch" parent="Theme.SplashScreen">
<item name="android:background">#00a5aa</item> <item name="android:background">@drawable/splash</item>
</style> </style>
</resources> </resources>

View file

@ -9,14 +9,14 @@
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
</style> </style>
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.NoActionBar"> <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
<item name="android:background">@null</item> <item name="android:background">@null</item>
</style> </style>
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar"> <style name="AppTheme.NoActionBarLaunch" parent="Theme.SplashScreen">
<item name="android:background">#00a5aa</item> <item name="android:background">@drawable/splash</item>
</style> </style>
</resources> </resources>

View file

@ -9,14 +9,14 @@
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
</style> </style>
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.NoActionBar"> <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
<item name="android:background">@null</item> <item name="android:background">@null</item>
</style> </style>
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar"> <style name="AppTheme.NoActionBarLaunch" parent="Theme.SplashScreen">
<item name="android:background">#00a5aa</item> <item name="android:background">@drawable/splash</item>
</style> </style>
</resources> </resources>

View file

@ -9,14 +9,14 @@
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
</style> </style>
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.NoActionBar"> <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
<item name="android:background">@null</item> <item name="android:background">@null</item>
</style> </style>
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar"> <style name="AppTheme.NoActionBarLaunch" parent="Theme.SplashScreen">
<item name="android:background">#00a5aa</item> <item name="android:background">@drawable/splash</item>
</style> </style>
</resources> </resources>

View file

@ -4,11 +4,11 @@ buildscript {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.2.1' classpath 'com.android.tools.build:gradle:7.2.1'
classpath 'com.google.gms:google-services:4.3.5' classpath 'com.google.gms:google-services:4.3.13'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
@ -20,10 +20,11 @@ apply from: "variables.gradle"
allprojects { allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
} }
task clean(type: Delete) { task clean(type: Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }

View file

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View file

@ -1,14 +1,16 @@
ext { ext {
minSdkVersion = 23 minSdkVersion = 22
compileSdkVersion = 31 compileSdkVersion = 32
targetSdkVersion = 31 targetSdkVersion = 32
androidxActivityVersion = '1.2.0' androidxActivityVersion = '1.4.0'
androidxAppCompatVersion = '1.2.0' androidxAppCompatVersion = '1.4.2'
androidxCoordinatorLayoutVersion = '1.1.0' androidxCoordinatorLayoutVersion = '1.2.0'
androidxCoreVersion = '1.3.2' androidxCoreVersion = '1.8.0'
androidxFragmentVersion = '1.3.0' androidxFragmentVersion = '1.4.1'
junitVersion = '4.13.1' junitVersion = '4.13.2'
androidxJunitVersion = '1.1.2' androidxJunitVersion = '1.1.3'
androidxEspressoCoreVersion = '3.3.0' androidxEspressoCoreVersion = '3.4.0'
cordovaAndroidVersion = '7.0.0' cordovaAndroidVersion = '10.1.1'
coreSplashScreenVersion = '1.0.0-rc01'
androidxWebkitVersion = '1.4.0'
} }

View file

@ -1,7 +1,6 @@
{ {
"$schema": "./node_modules/@angular/cli/lib/config/schema.json", "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1, "version": 1,
"defaultProject": "app",
"newProjectRoot": "projects", "newProjectRoot": "projects",
"projects": { "projects": {
"app": { "app": {
@ -162,7 +161,10 @@
} }
}, },
"cli": { "cli": {
"defaultCollection": "@ionic/angular-toolkit" "schematicCollections": [
"@ionic/angular-toolkit"
],
"analytics": false
}, },
"schematics": { "schematics": {
"@ionic/angular-toolkit:component": { "@ionic/angular-toolkit:component": {

View file

@ -0,0 +1,4 @@
* Upgraded framework, improved performance and fixed known bugs.
* Support quick access tile in the Quick Settings panel.
* More customizable UI.
* Removed Read/Write Contacts permission.

View file

@ -324,7 +324,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -376,7 +376,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
@ -394,9 +394,9 @@
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = G23992CVBU; DEVELOPMENT_TEAM = G23992CVBU;
INFOPLIST_FILE = App/Info.plist; INFOPLIST_FILE = App/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 2.8.0; MARKETING_VERSION = 3.0.0;
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
PRODUCT_BUNDLE_IDENTIFIER = com.tomfong.simpleqr; PRODUCT_BUNDLE_IDENTIFIER = com.tomfong.simpleqr;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -417,9 +417,9 @@
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = G23992CVBU; DEVELOPMENT_TEAM = G23992CVBU;
INFOPLIST_FILE = App/Info.plist; INFOPLIST_FILE = App/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 2.8.0; MARKETING_VERSION = 3.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tomfong.simpleqr; PRODUCT_BUNDLE_IDENTIFIER = com.tomfong.simpleqr;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Simple QR"; PROVISIONING_PROFILE_SPECIFIER = "Simple QR";

View file

@ -46,15 +46,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler) return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
} }
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
let statusBarRect = UIApplication.shared.statusBarFrame
guard let touchPoint = event?.allTouches?.first?.location(in: self.window) else { return }
if statusBarRect.contains(touchPoint) {
NotificationCenter.default.post(name: .capacitorStatusBarTapped, object: nil)
}
}
} }

View file

@ -22,11 +22,6 @@
<string>$(CURRENT_PROJECT_VERSION)</string> <string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>Simple QR uses Camera to scan barcodes</string> <string>Simple QR uses Camera to scan barcodes</string>
<key>NSContactsUsageDescription</key> <key>NSContactsUsageDescription</key>

View file

@ -1,4 +1,6 @@
platform :ios, '12.0' require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers'
platform :ios, '13.0'
use_frameworks! use_frameworks!
# workaround to avoid Xcode caching of Pods that requires # workaround to avoid Xcode caching of Pods that requires
@ -29,3 +31,8 @@ target 'App' do
capacitor_pods capacitor_pods
# Add your Pods here # Add your Pods here
end end
post_install do |installer|
assertDeploymentTarget(installer)
end

6665
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{ {
"name": "simple-qr", "name": "simple-qr",
"version": "2.8.0", "version": "3.0.0",
"author": "Tom Fong", "author": "Tom Fong",
"homepage": "https://tomfong.github.io", "homepage": "https://tomfong.github.io",
"scripts": { "scripts": {
@ -16,17 +16,17 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "^13.3.5", "@angular/animations": "^14.2.3",
"@angular/cdk": "^13.3.5", "@angular/cdk": "^14.2.2",
"@angular/common": "^13.3.5", "@angular/common": "^14.2.3",
"@angular/core": "^13.3.5", "@angular/core": "^14.2.3",
"@angular/forms": "^13.3.11", "@angular/forms": "^14.2.3",
"@angular/localize": "^13.3.11", "@angular/localize": "^14.2.3",
"@angular/material": "^13.3.5", "@angular/material": "^14.2.2",
"@angular/material-moment-adapter": "^13.3.9", "@angular/material-moment-adapter": "^14.2.2",
"@angular/platform-browser": "^13.3.5", "@angular/platform-browser": "^14.2.3",
"@angular/platform-browser-dynamic": "^13.3.11", "@angular/platform-browser-dynamic": "^14.2.3",
"@angular/router": "^13.3.11", "@angular/router": "^14.2.3",
"@awesome-cordova-plugins/aes-256": "^5.45.0", "@awesome-cordova-plugins/aes-256": "^5.45.0",
"@awesome-cordova-plugins/chooser": "^5.45.0", "@awesome-cordova-plugins/chooser": "^5.45.0",
"@awesome-cordova-plugins/core": "^5.45.0", "@awesome-cordova-plugins/core": "^5.45.0",
@ -34,23 +34,23 @@
"@awesome-cordova-plugins/sms": "^5.45.0", "@awesome-cordova-plugins/sms": "^5.45.0",
"@awesome-cordova-plugins/social-sharing": "^5.45.0", "@awesome-cordova-plugins/social-sharing": "^5.45.0",
"@awesome-cordova-plugins/theme-detection": "^5.45.0", "@awesome-cordova-plugins/theme-detection": "^5.45.0",
"@capacitor-community/barcode-scanner": "^2.1.1", "@capacitor-community/barcode-scanner": "^3.0.0",
"@capacitor-community/contacts": "^1.1.3", "@capacitor-community/contacts": "^2.0.0-0",
"@capacitor-community/screen-brightness": "^1.0.1", "@capacitor-community/screen-brightness": "^2.0.0-0",
"@capacitor/android": "^3.8.0", "@capacitor/android": "^4.3.0",
"@capacitor/app": "^1.1.1", "@capacitor/app": "^4.0.1",
"@capacitor/camera": "^1.3.1", "@capacitor/camera": "^4.1.1",
"@capacitor/clipboard": "^1.0.8", "@capacitor/clipboard": "^4.0.1",
"@capacitor/core": "^3.8.0", "@capacitor/core": "^4.3.0",
"@capacitor/device": "^1.1.2", "@capacitor/device": "^4.0.1",
"@capacitor/filesystem": "^1.1.0", "@capacitor/filesystem": "^4.1.1",
"@capacitor/haptics": "^1.1.4", "@capacitor/haptics": "^4.0.1",
"@capacitor/ios": "^3.8.0", "@capacitor/ios": "^4.3.0",
"@capacitor/keyboard": "^1.2.3", "@capacitor/keyboard": "^4.0.1",
"@capacitor/splash-screen": "^1.2.2", "@capacitor/splash-screen": "^4.0.1",
"@capacitor/status-bar": "^1.0.8", "@capacitor/status-bar": "^4.0.1",
"@capacitor/toast": "^1.0.8", "@capacitor/toast": "^4.0.1",
"@ionic/angular": "^6.2.7", "@ionic/angular": "^6.2.8",
"@ionic/storage": "^3.0.6", "@ionic/storage": "^3.0.6",
"@ionic/storage-angular": "^3.0.6", "@ionic/storage-angular": "^3.0.6",
"@ng-bootstrap/ng-bootstrap": "^11.0.1", "@ng-bootstrap/ng-bootstrap": "^11.0.1",
@ -78,12 +78,12 @@
"zone.js": "^0.11.8" "zone.js": "^0.11.8"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "^13.3.9", "@angular-devkit/build-angular": "^14.2.3",
"@angular/cli": "^13.3.9", "@angular/cli": "^14.2.3",
"@angular/compiler": "^13.3.5", "@angular/compiler": "^14.2.3",
"@angular/compiler-cli": "^13.3.5", "@angular/compiler-cli": "^14.2.3",
"@angular/language-service": "^13.3.11", "@angular/language-service": "^14.2.3",
"@capacitor/cli": "^3.8.0", "@capacitor/cli": "^4.3.0",
"@ionic/angular-toolkit": "^6.1.0", "@ionic/angular-toolkit": "^6.1.0",
"@types/jasmine": "^3.10.6", "@types/jasmine": "^3.10.6",
"@types/jasminewd2": "^2.0.10", "@types/jasminewd2": "^2.0.10",
@ -92,7 +92,7 @@
"codelyzer": "^6.0.2", "codelyzer": "^6.0.2",
"jasmine-core": "~3.8.0", "jasmine-core": "~3.8.0",
"jasmine-spec-reporter": "~5.0.0", "jasmine-spec-reporter": "~5.0.0",
"karma": "^6.4.0", "karma": "^6.4.1",
"karma-chrome-launcher": "^3.1.1", "karma-chrome-launcher": "^3.1.1",
"karma-coverage": "~2.0.3", "karma-coverage": "~2.0.3",
"karma-coverage-istanbul-reporter": "~3.0.2", "karma-coverage-istanbul-reporter": "~3.0.2",
@ -101,6 +101,6 @@
"protractor": "~7.0.0", "protractor": "~7.0.0",
"ts-node": "~8.3.0", "ts-node": "~8.3.0",
"tslint": "~6.1.0", "tslint": "~6.1.0",
"typescript": "~4.5.5" "typescript": "~4.8.3"
} }
} }

View file

@ -1,3 +1,7 @@
<ion-header class="ion-no-border">
<ion-toolbar [color]="color">
</ion-toolbar>
</ion-header>
<ion-content [color]="color" #content> <ion-content [color]="color" #content>
<ion-list-header class="mt-4 ml-3" style="font-size: x-large;">{{ 'TUTORIAL' | translate }}</ion-list-header> <ion-list-header class="mt-4 ml-3" style="font-size: x-large;">{{ 'TUTORIAL' | translate }}</ion-list-header>

View file

@ -1,3 +1,7 @@
<ion-header class="ion-no-border">
<ion-toolbar [color]="color">
</ion-toolbar>
</ion-header>
<ion-content [color]="color" #content> <ion-content [color]="color" #content>
<ion-list-header class="mt-4 ml-3" style="font-size: x-large;">{{ 'TUTORIAL' | translate }}</ion-list-header> <ion-list-header class="mt-4 ml-3" style="font-size: x-large;">{{ 'TUTORIAL' | translate }}</ion-list-header>

View file

@ -96,7 +96,7 @@
<ng-container <ng-container
*ngIf="segmentModel === 'history' && env.viewingScanRecords && env.viewingScanRecords.length > 0 && !isLoading"> *ngIf="segmentModel === 'history' && env.viewingScanRecords && env.viewingScanRecords.length > 0 && !isLoading">
<ion-list> <ion-list>
<ion-list-header class="ion-padding-horizontal" lines="full"> <ion-list-header class="ion-padding-horizontal" lines="none" *ngIf="env.showNumberOfRecords == 'on'">
<div class="ion-padding-horizontal" *ngIf="env.recordsLimit !== -1"> <div class="ion-padding-horizontal" *ngIf="env.recordsLimit !== -1">
{{ 'NUMBER_OF_RECORDS' | translate }}: {{ env.scanRecords.length }} / {{ denominator }} {{ 'NUMBER_OF_RECORDS' | translate }}: {{ env.scanRecords.length }} / {{ denominator }}
</div> </div>

View file

@ -172,16 +172,16 @@ export class ResultPage {
private isValidUrl(text: string): boolean { private isValidUrl(text: string): boolean {
let url: URL; let url: URL;
try { try {
url = new URL(text); url = new URL(text);
} catch (_) { } catch (_) {
return false; return false;
} }
return url.protocol != null && url.protocol.length > 0; return url.protocol != null && url.protocol.length > 0;
} }
get qrColorDark(): string { get qrColorDark(): string {
return "#222428"; return "#222428";
} }
@ -204,7 +204,7 @@ export class ResultPage {
const tContent = this.qrCodeContent.trim().toUpperCase(); const tContent = this.qrCodeContent.trim().toUpperCase();
if (tContent.substring(0, urlPrefix1.length) === urlPrefix1 || tContent.substring(0, urlPrefix2.length) === urlPrefix2) { if (tContent.substring(0, urlPrefix1.length) === urlPrefix1 || tContent.substring(0, urlPrefix2.length) === urlPrefix2) {
return true; return true;
} }
return false; return false;
} }
@ -258,55 +258,62 @@ export class ResultPage {
} as NewContact; } as NewContact;
} }
if (newContact != null) { if (newContact != null) {
await Contacts.getPermissions().then( if (this.platform.is('ios')) {
async permission => { await Contacts.getPermissions().then(
if (permission.granted) { async permission => {
await Contacts.saveContact(newContact).then( if (permission.granted) {
_ => { await this.saveContact(newContact);
if (this.isIOS) { } else {
this.presentToast(this.translate.instant('MSG.SAVED_CONTACT'), "short", "bottom"); const alert = await this.alertController.create({
} else { header: this.translate.instant("PERMISSION_REQUIRED"),
this.presentToast(this.translate.instant('MSG.SAVING_CONTACT'), "short", "bottom"); message: this.translate.instant("MSG.CONTACT_PERMISSION"),
} buttons: [
} {
) text: this.translate.instant("SETTING"),
.catch( handler: () => {
err => { BarcodeScanner.openAppSettings();
if (this.env.isDebugging) { return true;
this.presentToast("Error when call Contacts.saveContact: " + JSON.stringify(err), "long", "top"); }
} else { },
this.presentToast(this.translate.instant('MSG.FAILED_SAVING_CONTACT'), "short", "bottom"); {
text: this.translate.instant("CLOSE"),
handler: () => {
return true;
}
} }
} ],
) cssClass: ['alert-bg']
} else { });
const alert = await this.alertController.create({ await alert.present();
header: this.translate.instant("PERMISSION_REQUIRED"), }
message: this.translate.instant("MSG.CONTACT_PERMISSION"),
buttons: [
{
text: this.translate.instant("SETTING"),
handler: () => {
BarcodeScanner.openAppSettings();
return true;
}
},
{
text: this.translate.instant("CLOSE"),
handler: () => {
return true;
}
}
],
cssClass: ['alert-bg']
});
await alert.present();
} }
} );
); } else { // Android doesn't need to get permission
await this.saveContact(newContact);
}
} }
} }
private async saveContact(newContact: any) {
await Contacts.saveContact(newContact).then(
_ => {
if (this.isIOS) {
this.presentToast(this.translate.instant('MSG.SAVED_CONTACT'), "short", "bottom");
} else {
this.presentToast(this.translate.instant('MSG.SAVING_CONTACT'), "short", "bottom");
}
}
).catch(
err => {
if (this.env.isDebugging) {
this.presentToast("Error when call Contacts.saveContact: " + JSON.stringify(err), "long", "top");
} else {
this.presentToast(this.translate.instant('MSG.FAILED_SAVING_CONTACT'), "short", "bottom");
}
}
);
}
async callPhone(): Promise<void> { async callPhone(): Promise<void> {
window.open(this.qrCodeContent); window.open(this.qrCodeContent);
} }

View file

@ -21,29 +21,17 @@
</ion-label> </ion-label>
</ion-item> </ion-item>
<ion-radio-group [(ngModel)]="env.autoMaxBrightness" (ionChange)="saveAutoMaxBrightness()"> <ion-item class="ion-no-padding ripple-parent" detail="false" lines="none">
<ion-item class="ion-no-padding ripple-parent" detail="false" lines="none"> <ion-label class="ion-padding-start">
<ion-label class="ion-padding-start"> <p class="ion-padding pre-line">
<p class="ion-padding pre-line"> <ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;"> {{ (env.autoMaxBrightness == 'on'? 'TURNED_ON' : 'TURNED_OFF') | translate }}
{{ 'TURN_ON' | translate }} </ion-text>
</ion-text> </p>
</p> </ion-label>
</ion-label> <ion-toggle class="ion-padding-end" slot="end" [ngModel]="env.autoMaxBrightness == 'on'? true : false"
<ion-radio class="ion-margin-end" slot="end" [value]="'on'" [color]="'primary'"> (ngModelChange)="onAutoMaxBrightnessChange($event)">
</ion-radio> </ion-toggle>
</ion-item> </ion-item>
<ion-item class="ion-no-padding ripple-parent" detail="false" lines="none">
<ion-label class="ion-padding-start">
<p class="ion-padding pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
{{ 'TURN_OFF' | translate }}
</ion-text>
</p>
</ion-label>
<ion-radio class="ion-margin-end" slot="end" [value]="'off'" [color]="'primary'">
</ion-radio>
</ion-item>
</ion-radio-group>
</ion-content> </ion-content>

View file

@ -1,5 +1,6 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { Toast } from '@capacitor/toast';
import { EnvService } from 'src/app/services/env.service'; import { EnvService } from 'src/app/services/env.service';
@Component({ @Component({
@ -17,4 +18,20 @@ export class SettingAutoBrightnessPage {
await this.env.storageSet("auto-max-brightness", this.env.autoMaxBrightness); await this.env.storageSet("auto-max-brightness", this.env.autoMaxBrightness);
} }
async onAutoMaxBrightnessChange(ev: any) {
this.env.autoMaxBrightness = ev ? 'on' : 'off';
await this.env.storageSet("auto-max-brightness", this.env.autoMaxBrightness);
await this.tapHaptic();
}
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" })
}
})
}
}
} }

View file

@ -53,30 +53,18 @@
</p> </p>
</ion-label> </ion-label>
</ion-item> </ion-item>
<ion-radio-group [(ngModel)]="env.scanRecordLogging" (ionChange)="saveScanRecord()"> <ion-item class="ion-no-padding ripple-parent" detail="false" lines="none">
<ion-item class="ion-no-padding ripple-parent py-1" detail="false" lines="none"> <ion-label class="ion-padding-start">
<ion-label class="ion-padding-start"> <p class="ion-padding pre-line">
<p class="ion-padding-horizontal pre-line"> <ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;"> {{ (env.scanRecordLogging == 'on'? 'TURNED_ON' : 'TURNED_OFF') | translate }}
{{ 'TURN_ON' | translate }} </ion-text>
</ion-text> </p>
</p> </ion-label>
</ion-label> <ion-toggle class="ion-padding-end" slot="end" [ngModel]="env.scanRecordLogging == 'on'? true : false"
<ion-radio class="ion-margin-end" slot="end" [value]="'on'" [color]="'primary'"> (ngModelChange)="onScanRecordLoggingChange($event)">
</ion-radio> </ion-toggle>
</ion-item> </ion-item>
<ion-item class="ion-no-padding ripple-parent py-1" detail="false" lines="none">
<ion-label class="ion-padding-start">
<p class="ion-padding-horizontal pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
{{ 'TURN_OFF' | translate }}
</ion-text>
</p>
</ion-label>
<ion-radio class="ion-margin-end" slot="end" [value]="'off'" [color]="'primary'">
</ion-radio>
</ion-item>
</ion-radio-group>
</div> </div>
<div class="ion-padding-vertical"> <div class="ion-padding-vertical">
@ -136,6 +124,18 @@
</ion-radio> </ion-radio>
</ion-item> </ion-item>
</ion-radio-group> </ion-radio-group>
<ion-item class="ion-no-padding ripple-parent py-1 pt-2" detail="false" lines="none">
<ion-label class="ion-padding-start">
<p class="ion-padding-horizontal pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
{{ 'SHOW_NUMBER_OR_RECORDS' | translate }}
</ion-text>
</p>
</ion-label>
<ion-toggle class="ion-padding-end" slot="end" [ngModel]="env.showNumberOfRecords == 'on'? true : false"
(ngModelChange)="onShowNumberOfRecordsChange($event)">
</ion-toggle>
</ion-item>
</div> </div>
<div class="ion-padding-vertical mb-2"> <div class="ion-padding-vertical mb-2">

View file

@ -11,6 +11,7 @@ import { Chooser, ChooserResult } from '@awesome-cordova-plugins/chooser/ngx';
import { ScanRecord } from 'src/app/models/scan-record'; import { ScanRecord } from 'src/app/models/scan-record';
import { Bookmark } from 'src/app/models/bookmark'; import { Bookmark } from 'src/app/models/bookmark';
import { SocialSharing } from '@awesome-cordova-plugins/social-sharing/ngx'; import { SocialSharing } from '@awesome-cordova-plugins/social-sharing/ngx';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
@Component({ @Component({
selector: 'app-setting-record', selector: 'app-setting-record',
@ -44,8 +45,10 @@ export class SettingRecordPage {
await this.env.storageSet("history-page-start-segment", this.env.historyPageStartSegment); await this.env.storageSet("history-page-start-segment", this.env.historyPageStartSegment);
} }
async saveScanRecord() { async onScanRecordLoggingChange(ev: any) {
this.env.scanRecordLogging = ev ? 'on' : 'off';
await this.env.storageSet("scan-record-logging", this.env.scanRecordLogging); await this.env.storageSet("scan-record-logging", this.env.scanRecordLogging);
await this.tapHaptic();
} }
async saveRecordsLimit() { async saveRecordsLimit() {
@ -55,6 +58,12 @@ export class SettingRecordPage {
} }
} }
async onShowNumberOfRecordsChange(ev: any) {
this.env.showNumberOfRecords = ev ? 'on' : 'off';
await this.env.storageSet("showNumberOfRecords", this.env.showNumberOfRecords);
await this.tapHaptic();
}
async onBackup() { async onBackup() {
const loading1 = await this.presentLoading(this.translate.instant("ENCRYPTING")); const loading1 = await this.presentLoading(this.translate.instant("ENCRYPTING"));
const backup = { const backup = {
@ -302,6 +311,17 @@ export class SettingRecordPage {
return loading; return loading;
} }
async tapHaptic() {
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
await Haptics.impact({ style: ImpactStyle.Light })
.catch(async err => {
if (this.env.debugMode === 'on') {
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
}
})
}
}
get isIOS() { get isIOS() {
return this.platform.is('ios'); return this.platform.is('ios');
} }

View file

@ -110,28 +110,17 @@
</ion-label> </ion-label>
</ion-item> </ion-item>
<ion-radio-group [(ngModel)]="env.startPageHeader" (ionChange)="saveStartPageHeader()"> <ion-item class="ion-no-padding ripple-parent" detail="false" lines="none">
<ion-item class="ion-no-padding ripple-parent" detail="false" lines="none"> <ion-label class="ion-padding-start">
<ion-label class="ion-padding-start"> <p class="ion-padding pre-line">
<p class="ion-padding pre-line"> <ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;"> {{ (env.startPageHeader == 'on'? 'TURNED_ON' : 'TURNED_OFF') | translate }}
{{ 'TURN_ON' | translate }} </ion-text>
</ion-text> </p>
</p> </ion-label>
</ion-label> <ion-toggle class="ion-padding-end" slot="end" [ngModel]="env.startPageHeader == 'on'? true : false"
<ion-radio class="ion-margin-end" slot="end" [value]="'on'" [color]="'primary'"> (ngModelChange)="onStartPageHeaderChange($event)">
</ion-radio> </ion-toggle>
</ion-item> </ion-item>
<ion-item class="ion-no-padding ripple-parent" detail="false" lines="none">
<ion-label class="ion-padding-start">
<p class="ion-padding pre-line">
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
{{ 'TURN_OFF' | translate }}
</ion-text>
</p>
</ion-label>
<ion-radio class="ion-margin-end" slot="end" [value]="'off'" [color]="'primary'">
</ion-radio>
</ion-item>
</ion-radio-group>
</ion-content> </ion-content>

View file

@ -1,4 +1,6 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { Toast } from '@capacitor/toast';
import { EnvService } from 'src/app/services/env.service'; import { EnvService } from 'src/app/services/env.service';
import { fadeIn } from 'src/app/utils/animations'; import { fadeIn } from 'src/app/utils/animations';
@ -18,7 +20,21 @@ export class SettingStartPagePage {
await this.env.storageSet("start-page", this.env.startPage); await this.env.storageSet("start-page", this.env.startPage);
} }
async saveStartPageHeader() { async onStartPageHeaderChange(ev: any) {
this.env.startPageHeader = ev ? 'on' : 'off';
await this.env.storageSet("start-page-header", this.env.startPageHeader); await this.env.storageSet("start-page-header", this.env.startPageHeader);
await this.tapHaptic();
} }
async tapHaptic() {
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
await Haptics.impact({ style: ImpactStyle.Light })
.catch(async err => {
if (this.env.debugMode === 'on') {
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
}
})
}
}
} }

View file

@ -1,6 +1,7 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { Haptics, ImpactStyle } from '@capacitor/haptics'; import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { SplashScreen } from '@capacitor/splash-screen';
import { Toast } from '@capacitor/toast'; import { Toast } from '@capacitor/toast';
import { AlertController, Platform } from '@ionic/angular'; import { AlertController, Platform } from '@ionic/angular';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -59,10 +60,11 @@ export class TabsPage {
} }
async ionViewDidEnter() { async ionViewDidEnter() {
await SplashScreen.hide()
if (this.env.firstAppLoad) { if (this.env.firstAppLoad) {
this.env.firstAppLoad = false; this.env.firstAppLoad = false;
await this.loadPatchNote();
await this.router.navigate([this.env.startPage], { replaceUrl: true }); await this.router.navigate([this.env.startPage], { replaceUrl: true });
await this.loadPatchNote();
} }
} }
@ -79,6 +81,8 @@ export class TabsPage {
if (this.env.notShowUpdateNotes === false) { if (this.env.notShowUpdateNotes === false) {
this.env.notShowUpdateNotes = true; this.env.notShowUpdateNotes = true;
await this.showUpdateNotes(); await this.showUpdateNotes();
const versionWording = this.translate.instant("VERSION_VERSION") as string;
await this.presentToast(versionWording.replace("{version}", this.env.appVersionNumber), "short", 'bottom');
} }
} }
); );

View file

@ -20,7 +20,7 @@ export declare type LanguageType = 'de' | 'en' | 'fr' | 'it' | 'zh-CN' | 'zh-HK'
}) })
export class EnvService { export class EnvService {
public appVersionNumber: string = '2.8.0'; public appVersionNumber: string = '3.0.0';
public startPage: "/tabs/scan" | "/tabs/generate" | "/tabs/import-image" | "/tabs/history" | "/tabs/setting" = "/tabs/scan"; public startPage: "/tabs/scan" | "/tabs/generate" | "/tabs/import-image" | "/tabs/history" | "/tabs/setting" = "/tabs/scan";
public historyPageStartSegment: 'history' | 'bookmarks' = 'history'; public historyPageStartSegment: 'history' | 'bookmarks' = 'history';
@ -32,6 +32,7 @@ export class EnvService {
public selectedColorTheme: 'default' | 'light' | 'dark' | 'black' = 'default'; public selectedColorTheme: 'default' | 'light' | 'dark' | 'black' = 'default';
public scanRecordLogging: 'on' | 'off' = 'on'; public scanRecordLogging: 'on' | 'off' = 'on';
public recordsLimit: 30 | 50 | 100 | -1 = -1; public recordsLimit: 30 | 50 | 100 | -1 = -1;
public showNumberOfRecords: 'on' | 'off' = 'on';
public autoMaxBrightness: 'on' | 'off' = 'on'; public autoMaxBrightness: 'on' | 'off' = 'on';
public errorCorrectionLevel: 'L' | 'M' | 'Q' | 'H' = 'M'; public errorCorrectionLevel: 'L' | 'M' | 'Q' | 'H' = 'M';
public qrCodeLightR: number = 255; public qrCodeLightR: number = 255;
@ -78,10 +79,10 @@ export class EnvService {
public readonly APP_STORE_URL: string = "https://apps.apple.com/us/app/simple-qr-by-tom-fong/id1621121553"; public readonly APP_STORE_URL: string = "https://apps.apple.com/us/app/simple-qr-by-tom-fong/id1621121553";
public readonly GITHUB_RELEASE_URL: string = "https://github.com/tomfong/simple-qr/releases"; public readonly GITHUB_RELEASE_URL: string = "https://github.com/tomfong/simple-qr/releases";
public readonly PRIVACY_POLICY: string = "https://www.privacypolicies.com/live/771b1123-99bb-4bfe-815e-1046c0437a0f"; public readonly PRIVACY_POLICY: string = "https://www.privacypolicies.com/live/771b1123-99bb-4bfe-815e-1046c0437a0f";
public readonly AN_PREV_PATCH_NOTE_STORAGE_KEY = "not-show-update-notes-v20700"; public readonly AN_PREV_PATCH_NOTE_STORAGE_KEY = "not-show-update-notes-v20800";
public readonly IOS_PREV_PATCH_NOTE_STORAGE_KEY = "not-show-update-notes-v20700"; public readonly IOS_PREV_PATCH_NOTE_STORAGE_KEY = "not-show-update-notes-v20800";
public readonly AN_PATCH_NOTE_STORAGE_KEY = "not-show-update-notes-v20800"; public readonly AN_PATCH_NOTE_STORAGE_KEY = "not-show-update-notes-v30000";
public readonly IOS_PATCH_NOTE_STORAGE_KEY = "not-show-update-notes-v20800"; public readonly IOS_PATCH_NOTE_STORAGE_KEY = "not-show-update-notes-v30000";
private _storage: Storage | null = null; private _storage: Storage | null = null;
private _scannedData: string = ''; private _scannedData: string = '';
@ -267,6 +268,15 @@ export class EnvService {
} }
} }
); );
this._storage.get("showNumberOfRecords").then(
value => {
if (value !== null && value !== undefined) {
this.showNumberOfRecords = value;
} else {
this.showNumberOfRecords = 'on';
}
}
);
this._storage.get("vibration").then( this._storage.get("vibration").then(
value => { value => {
if (value !== null && value !== undefined) { if (value !== null && value !== undefined) {
@ -562,6 +572,7 @@ export class EnvService {
await this.toggleColorTheme(); await this.toggleColorTheme();
this.scanRecordLogging = 'on'; this.scanRecordLogging = 'on';
this.recordsLimit = -1; this.recordsLimit = -1;
this.showNumberOfRecords = 'on';
this.autoMaxBrightness = 'on'; this.autoMaxBrightness = 'on';
this.errorCorrectionLevel = 'M'; this.errorCorrectionLevel = 'M';
this.qrCodeLightR = 255; this.qrCodeLightR = 255;
@ -630,6 +641,9 @@ export class EnvService {
this.recordsLimit = -1; this.recordsLimit = -1;
await this.storageSet("recordsLimit", this.recordsLimit); await this.storageSet("recordsLimit", this.recordsLimit);
this.showNumberOfRecords = 'on';
await this.storageSet("showNumberOfRecords", this.showNumberOfRecords);
this.autoMaxBrightness = 'on'; this.autoMaxBrightness = 'on';
await this.storageSet("auto-max-brightness", this.autoMaxBrightness); await this.storageSet("auto-max-brightness", this.autoMaxBrightness);

View file

@ -120,7 +120,7 @@
"NOT_PROVIDED": "Nicht vorgesehen", "NOT_PROVIDED": "Nicht vorgesehen",
"NOT_TO_DISCLOSE": "Nicht bekannt geben", "NOT_TO_DISCLOSE": "Nicht bekannt geben",
"NO_LIMIT": "Keine Begrenzung", "NO_LIMIT": "Keine Begrenzung",
"NUMBER_OF_RECORDS": "Anzahl der Aufzeichnungen", "NUMBER_OF_RECORDS": "Anzahl der Datensätze",
"OK": "OK", "OK": "OK",
"ONLY_DELETE_DATA": "Nur Daten löschen", "ONLY_DELETE_DATA": "Nur Daten löschen",
"ONLY_RESET_SETTING": "Nur Einstellung zurücksetzen", "ONLY_RESET_SETTING": "Nur Einstellung zurücksetzen",
@ -172,6 +172,7 @@
"SHARE": "Teile", "SHARE": "Teile",
"SHARING": "Teilen", "SHARING": "Teilen",
"SHOW": "Zeige", "SHOW": "Zeige",
"SHOW_NUMBER_OR_RECORDS": "Zeige die Anzahl der Datensätze an",
"SHOW_QR_CODE": "Zeige QR Code", "SHOW_QR_CODE": "Zeige QR Code",
"SIMPLE_QR": "Simple QR", "SIMPLE_QR": "Simple QR",
"STATE": "Staat", "STATE": "Staat",
@ -184,12 +185,15 @@
"TASK_BUTTON_LAYOUT": "Aufgaben-Schaltflächen-Layout", "TASK_BUTTON_LAYOUT": "Aufgaben-Schaltflächen-Layout",
"TURN_OFF": "Ausschalten", "TURN_OFF": "Ausschalten",
"TURN_ON": "Anschalten", "TURN_ON": "Anschalten",
"TURNED_OFF": "Ausgeschaltet",
"TURNED_ON": "Angeschaltet",
"TUTORIAL": "Anleitung", "TUTORIAL": "Anleitung",
"UNDO": "Rückgängig", "UNDO": "Rückgängig",
"UNKNOWN": "Unbekannt", "UNKNOWN": "Unbekannt",
"UPDATE_SUCCESSFULLY": "Erfolgreich aktualisiert", "UPDATE_SUCCESSFULLY": "Erfolgreich aktualisiert",
"URL": "URL", "URL": "URL",
"VCARD_CONTACT": "vCard Kontakt", "VCARD_CONTACT": "vCard Kontakt",
"VERSION_VERSION": "Version {version}",
"VIBRATION": "Vibration", "VIBRATION": "Vibration",
"VIEWED": "Gesehen", "VIEWED": "Gesehen",
"VIEW_BOOKMARK": "Lesezeichen ansehen", "VIEW_BOOKMARK": "Lesezeichen ansehen",
@ -291,7 +295,7 @@
"UPC": "Universeller Produktcode " "UPC": "Universeller Produktcode "
}, },
"UPDATE": { "UPDATE": {
"UPDATE_NOTES_ANDROID": "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>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_IOS": "Diese Version bringt Ihnen mehrere Updates und neue Funktionen. Bitte überprüfen Sie GitHub für Details."
} }
} }

View file

@ -172,6 +172,7 @@
"SHARE": "Share", "SHARE": "Share",
"SHARING": "Sharing", "SHARING": "Sharing",
"SHOW": "Show", "SHOW": "Show",
"SHOW_NUMBER_OR_RECORDS": "Show Number of Records",
"SHOW_QR_CODE": "Show QR Code", "SHOW_QR_CODE": "Show QR Code",
"SIMPLE_QR": "Simple QR", "SIMPLE_QR": "Simple QR",
"STATE": "State", "STATE": "State",
@ -184,12 +185,15 @@
"TASK_BUTTON_LAYOUT": "Task Button Layout", "TASK_BUTTON_LAYOUT": "Task Button Layout",
"TURN_OFF": "Turn Off", "TURN_OFF": "Turn Off",
"TURN_ON": "Turn On", "TURN_ON": "Turn On",
"TURNED_OFF": "Turned Off",
"TURNED_ON": "Turned On",
"TUTORIAL": "Tutorial", "TUTORIAL": "Tutorial",
"UNDO": "Undo", "UNDO": "Undo",
"UNKNOWN": "Unknown", "UNKNOWN": "Unknown",
"UPDATE_SUCCESSFULLY": "Update Successfully", "UPDATE_SUCCESSFULLY": "Update Successfully",
"URL": "URL", "URL": "URL",
"VCARD_CONTACT": "vCard Contact", "VCARD_CONTACT": "vCard Contact",
"VERSION_VERSION": "Version {version}",
"VIBRATION": "Vibration", "VIBRATION": "Vibration",
"VIEWED": "Viewed", "VIEWED": "Viewed",
"VIEW_BOOKMARK": "View Bookmark", "VIEW_BOOKMARK": "View Bookmark",
@ -291,7 +295,7 @@
"UPC": "Universal Product Code " "UPC": "Universal Product Code "
}, },
"UPDATE": { "UPDATE": {
"UPDATE_NOTES_ANDROID": "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>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_IOS": "This release brings you several updates and new features. Please check GitHub for details."
} }
} }

View file

@ -172,6 +172,7 @@
"SHARE": "Partager", "SHARE": "Partager",
"SHARING": "Partager", "SHARING": "Partager",
"SHOW": "Afficher", "SHOW": "Afficher",
"SHOW_NUMBER_OR_RECORDS": "Afficher le nombre d'enregistrements",
"SHOW_QR_CODE": "Afficher le code QR", "SHOW_QR_CODE": "Afficher le code QR",
"SIMPLE_QR": "Simple QR", "SIMPLE_QR": "Simple QR",
"STATE": "Etat", "STATE": "Etat",
@ -184,12 +185,15 @@
"TASK_BUTTON_LAYOUT": "Disposition des boutons de tâche", "TASK_BUTTON_LAYOUT": "Disposition des boutons de tâche",
"TURN_OFF": "Éteindre", "TURN_OFF": "Éteindre",
"TURN_ON": "Allumer", "TURN_ON": "Allumer",
"TURNED_OFF": "Désactivé",
"TURNED_ON": "Activée",
"TUTORIAL": "Didacticiel", "TUTORIAL": "Didacticiel",
"UNDO": "Annuler", "UNDO": "Annuler",
"UNKNOWN": "Inconnu", "UNKNOWN": "Inconnu",
"UPDATE_SUCCESSFULLY": "Mise à jour réussie", "UPDATE_SUCCESSFULLY": "Mise à jour réussie",
"URL": "URL", "URL": "URL",
"VCARD_CONTACT": "Contact vCard", "VCARD_CONTACT": "Contact vCard",
"VERSION_VERSION": "Version {version}",
"VIBRATION": "Vibration", "VIBRATION": "Vibration",
"VIEWED": "Vu", "VIEWED": "Vu",
"VIEW_BOOKMARK": "Afficher le signet", "VIEW_BOOKMARK": "Afficher le signet",
@ -291,7 +295,7 @@
"UPC": "Code produit universel" "UPC": "Code produit universel"
}, },
"UPDATE": { "UPDATE": {
"UPDATE_NOTES_ANDROID": "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>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_IOS": "Cette version vous apporte plusieurs mises à jour et nouvelles fonctionnalités. Veuillez consulter GitHub pour plus de détails."
} }
} }

View file

@ -172,6 +172,7 @@
"SHARE": "Condividi", "SHARE": "Condividi",
"SHARING": "Condividendo", "SHARING": "Condividendo",
"SHOW": "Mostra", "SHOW": "Mostra",
"SHOW_NUMBER_OR_RECORDS": "Mostra il numero di record",
"SHOW_QR_CODE": "Mostra il Codice QR", "SHOW_QR_CODE": "Mostra il Codice QR",
"SIMPLE_QR": "Simple QR", "SIMPLE_QR": "Simple QR",
"STATE": "Stato", "STATE": "Stato",
@ -184,12 +185,15 @@
"TASK_BUTTON_LAYOUT": "Disposizione Pulsante Operazione", "TASK_BUTTON_LAYOUT": "Disposizione Pulsante Operazione",
"TURN_OFF": "Spegni", "TURN_OFF": "Spegni",
"TURN_ON": "Accendi", "TURN_ON": "Accendi",
"TURNED_OFF": "Spento",
"TURNED_ON": "Acceso",
"TUTORIAL": "Guida", "TUTORIAL": "Guida",
"UNDO": "Annulla", "UNDO": "Annulla",
"UNKNOWN": "Sconosciuto", "UNKNOWN": "Sconosciuto",
"UPDATE_SUCCESSFULLY": "Aggiornamento completato con successo", "UPDATE_SUCCESSFULLY": "Aggiornamento completato con successo",
"URL": "URL", "URL": "URL",
"VCARD_CONTACT": "Contatto vCard", "VCARD_CONTACT": "Contatto vCard",
"VERSION_VERSION": "Versione {version}",
"VIBRATION": "Vibrazione", "VIBRATION": "Vibrazione",
"VIEWED": "Visualizzati", "VIEWED": "Visualizzati",
"VIEW_BOOKMARK": "Visualizza segnalibri", "VIEW_BOOKMARK": "Visualizza segnalibri",
@ -291,7 +295,7 @@
"UPC": "Codice Prodotto Universale " "UPC": "Codice Prodotto Universale "
}, },
"UPDATE": { "UPDATE": {
"UPDATE_NOTES_ANDROID": "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>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_IOS": "Questa versione offre numerosi aggiornamenti e nuove funzionalità. Si prega di controllare GitHub per i dettagli."
} }
} }

View file

@ -172,6 +172,7 @@
"SHARE": "分享", "SHARE": "分享",
"SHARING": "正在分享", "SHARING": "正在分享",
"SHOW": "显示", "SHOW": "显示",
"SHOW_NUMBER_OR_RECORDS": "显示记录数量",
"SHOW_QR_CODE": "显示 QR 码", "SHOW_QR_CODE": "显示 QR 码",
"SIMPLE_QR": "简易QR", "SIMPLE_QR": "简易QR",
"STATE": "州", "STATE": "州",
@ -184,12 +185,15 @@
"TASK_BUTTON_LAYOUT": "行动按键布局", "TASK_BUTTON_LAYOUT": "行动按键布局",
"TURN_OFF": "关闭", "TURN_OFF": "关闭",
"TURN_ON": "开启", "TURN_ON": "开启",
"TURNED_OFF": "已关闭",
"TURNED_ON": "已开启",
"TUTORIAL": "教学", "TUTORIAL": "教学",
"UNDO": "复原", "UNDO": "复原",
"UNKNOWN": "未知", "UNKNOWN": "未知",
"UPDATE_SUCCESSFULLY": "更新成功", "UPDATE_SUCCESSFULLY": "更新成功",
"URL": "网址", "URL": "网址",
"VCARD_CONTACT": "vCard 联络人", "VCARD_CONTACT": "vCard 联络人",
"VERSION_VERSION": "版本 {version}",
"VIBRATION": "震动效果", "VIBRATION": "震动效果",
"VIEWED": "查看", "VIEWED": "查看",
"VIEW_BOOKMARK": "查看书签", "VIEW_BOOKMARK": "查看书签",
@ -291,7 +295,7 @@
"UPC": "通用产品代码" "UPC": "通用产品代码"
}, },
"UPDATE": { "UPDATE": {
"UPDATE_NOTES_ANDROID": "此版本为您带来多项更新和新功能,详情请查看 GitHub。", "UPDATE_NOTES_ANDROID": "<p>此版本为您带来多项更新和新功能,详情请查看 GitHub。</p><p>Android 用户现在可以在快速设定面板中加入简易 QR 按键以进行快速启动。</p>",
"UPDATE_NOTES_IOS": "此版本为您带来多项更新和新功能,详情请查看 GitHub。" "UPDATE_NOTES_IOS": "此版本为您带来多项更新和新功能,详情请查看 GitHub。"
} }
} }

View file

@ -172,6 +172,7 @@
"SHARE": "分享", "SHARE": "分享",
"SHARING": "正在分享", "SHARING": "正在分享",
"SHOW": "顯示", "SHOW": "顯示",
"SHOW_NUMBER_OR_RECORDS": "顯示記錄數量",
"SHOW_QR_CODE": "顯示 QR 碼", "SHOW_QR_CODE": "顯示 QR 碼",
"SIMPLE_QR": "簡易QR", "SIMPLE_QR": "簡易QR",
"STATE": "州", "STATE": "州",
@ -184,12 +185,15 @@
"TASK_BUTTON_LAYOUT": "行動按鍵佈局", "TASK_BUTTON_LAYOUT": "行動按鍵佈局",
"TURN_OFF": "關閉", "TURN_OFF": "關閉",
"TURN_ON": "開啟", "TURN_ON": "開啟",
"TURNED_OFF": "已關閉",
"TURNED_ON": "已開啟",
"TUTORIAL": "教學", "TUTORIAL": "教學",
"UNDO": "還原", "UNDO": "還原",
"UNKNOWN": "未知", "UNKNOWN": "未知",
"UPDATE_SUCCESSFULLY": "更新成功", "UPDATE_SUCCESSFULLY": "更新成功",
"URL": "網址", "URL": "網址",
"VCARD_CONTACT": "vCard 聯絡人", "VCARD_CONTACT": "vCard 聯絡人",
"VERSION_VERSION": "版本 {version}",
"VIBRATION": "震動效果", "VIBRATION": "震動效果",
"VIEWED": "查看", "VIEWED": "查看",
"VIEW_BOOKMARK": "查看書籤", "VIEW_BOOKMARK": "查看書籤",
@ -291,7 +295,7 @@
"UPC": "通用產品代碼" "UPC": "通用產品代碼"
}, },
"UPDATE": { "UPDATE": {
"UPDATE_NOTES_ANDROID": "此版本為您帶來多項更新和新功能,詳情請查看 GitHub。", "UPDATE_NOTES_ANDROID": "<p>此版本為您帶來多項更新和新功能,詳情請查看 GitHub。</p><p>Android 用戶現在可以在快速設定面板中加入簡易 QR 按鍵以進行快速啟動。</p>",
"UPDATE_NOTES_IOS": "此版本為您帶來多項更新和新功能,詳情請查看 GitHub。" "UPDATE_NOTES_IOS": "此版本為您帶來多項更新和新功能,詳情請查看 GitHub。"
} }
} }

View file

@ -10,7 +10,7 @@
"experimentalDecorators": true, "experimentalDecorators": true,
"moduleResolution": "node", "moduleResolution": "node",
"importHelpers": true, "importHelpers": true,
"target": "es5", "target": "es2020",
"module": "es2020", "module": "es2020",
"lib": ["es2018", "dom"] "lib": ["es2018", "dom"]
}, },