Compare commits
No commits in common. "main" and "v2.8.0" have entirely different histories.
1
.github/FUNDING.yml
vendored
|
@ -1 +0,0 @@
|
||||||
|
|
65
README.md
|
@ -20,13 +20,13 @@
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
Simple QR is an open-source app to scan, create and store QR codes with a simple UI and experience. No backend service connected. No data collected. No ads.
|
Simple QR is a FOSS app to scan, create and store QR codes with a simple UI and experience. No backend service connected. No data collected. No ads.
|
||||||
|
|
||||||
It's now available on the following platforms.
|
It's now available on the following platforms.
|
||||||
|
|
||||||
| Google Play | GitHub | IzzyOnDroid |
|
| App Store | Google Play | GitHub | IzzyOnDroid |
|
||||||
|:-:|:-:|:-:|
|
|:-:|:-:|:-:|:-:|
|
||||||
| [<img src="https://raw.githubusercontent.com/tomfong/simple-qr/main/.github/images/google-play-badge.png" height="50">](https://play.google.com/store/apps/details?id=com.tomfong.simpleqr) | [<img src="https://raw.githubusercontent.com/tomfong/simple-qr/main/.github/images/github-badge.png" height="50">](https://github.com/tomfong/simple-qr/releases/latest) | [<img src="https://raw.githubusercontent.com/tomfong/simple-qr/main/.github/images/IzzyOnDroid-badge.png" height="50">](https://apt.izzysoft.de/fdroid/index/apk/com.tomfong.simpleqr) |
|
| [<img src="https://raw.githubusercontent.com/tomfong/simple-qr/main/.github/images/appstore-badge.png" height="50">](https://apps.apple.com/us/app/simple-qr-by-tom-fong/id1621121553) | [<img src="https://raw.githubusercontent.com/tomfong/simple-qr/main/.github/images/google-play-badge.png" height="50">](https://play.google.com/store/apps/details?id=com.tomfong.simpleqr) | [<img src="https://raw.githubusercontent.com/tomfong/simple-qr/main/.github/images/github-badge.png" height="50">](https://github.com/tomfong/simple-qr/releases/latest) | [<img src="https://raw.githubusercontent.com/tomfong/simple-qr/main/.github/images/IzzyOnDroid-badge.png" height="50">](https://apt.izzysoft.de/fdroid/index/apk/com.tomfong.simpleqr) |
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ By using the app, you can
|
||||||
|
|
||||||
2. Import image files and scan the QR Code on it.
|
2. Import image files and scan the QR Code on it.
|
||||||
|
|
||||||
3. Create QR code from templates, which includes Free Text, URL, vCard Contact, Phone Number, Message, Email, Wi-Fi and Geolocation.
|
3. Create QR code from templates, which includes Free Text, URL, vCard Contact, Phone Number, Message, Email and Wi-Fi.
|
||||||
|
|
||||||
4. Automatically log results that you scan, create or view again. These logged records can be bookmarked for quick access, and also backupable.
|
4. Automatically log results that you scan, create or view again. These logged records can be bookmarked for quick access, and also backupable.
|
||||||
|
|
||||||
|
@ -46,12 +46,11 @@ By using the app, you can
|
||||||
* Execute base64 encoding/decoding on it.
|
* Execute base64 encoding/decoding on it.
|
||||||
* Use it as a content to generate a new shareable QR code.
|
* Use it as a content to generate a new shareable QR code.
|
||||||
* Do corresponding tasks if it is a
|
* Do corresponding tasks if it is a
|
||||||
* URL: Browse website / Open application
|
* URL: Browse website
|
||||||
* vCard contact: Add contact
|
* vCard contact: Add contact
|
||||||
* Phone number: Phone call, add contact
|
* Phone number: Phone call, add contact
|
||||||
* Message: Send message, add contact
|
* Message: Send message, add contact
|
||||||
* Email: Send email
|
* Email: Send email
|
||||||
* Geolocation: Open map
|
|
||||||
|
|
||||||
6. Customize the generated QR code, e.g. error correction level, color, margin and screen brightness.
|
6. Customize the generated QR code, e.g. error correction level, color, margin and screen brightness.
|
||||||
|
|
||||||
|
@ -64,13 +63,11 @@ By using the app, you can
|
||||||
### Languages Supported
|
### Languages Supported
|
||||||
|
|
||||||
* English (en)
|
* English (en)
|
||||||
* Chinese (Hong Kong) 中文 (香港) (zh-HK)
|
* Traditional Chinese 正體中文 (zh)
|
||||||
* Chinese (Simplified) 简体中文 (zh-CN)
|
* Simplified Chinese 简体中文 (zh-CN)
|
||||||
* German Deutsch (de)
|
* German Deutsch (de)
|
||||||
* French Français (fr)
|
* French Français (fr)
|
||||||
* Italian Italiano (it)
|
* Italian Italiano (it)
|
||||||
* Portuguese (Brazil) (pt-BR)
|
|
||||||
* Russian Русский (ru)
|
|
||||||
|
|
||||||
You are welcomed to help translate the app into more languages (refer to this <a href="#how-to-help-translate">section</a>)
|
You are welcomed to help translate the app into more languages (refer to this <a href="#how-to-help-translate">section</a>)
|
||||||
|
|
||||||
|
@ -78,8 +75,10 @@ You are welcomed to help translate the app into more languages (refer to this <a
|
||||||
|
|
||||||
* Sponsor the project.
|
* Sponsor the project.
|
||||||
|
|
||||||
[](https://github.com/sponsors/tomfong?frequency=one-time)
|
<div>
|
||||||
[](https://www.buymeacoffee.com/tomfong)
|
<a href="https://linktr.ee/tomfonghk"><img src="https://raw.githubusercontent.com/tomfong/simple-qr/main/.github/images/Paypal-badge.png" width="170" alt="tomfong"/></a>
|
||||||
|
<a href="https://www.buymeacoffee.com/tomfong"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" height="50" width="180" alt="tomfong" /></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
* Star the project.
|
* Star the project.
|
||||||
|
|
||||||
|
@ -87,7 +86,7 @@ You are welcomed to help translate the app into more languages (refer to this <a
|
||||||
|
|
||||||
* Open issues to report bugs or share any new ideas.
|
* Open issues to report bugs or share any new ideas.
|
||||||
|
|
||||||
[](https://github.com/tomfong/simple-qr/issues)
|
[](https://github.com/tomfong/simple-qr/issues)
|
||||||
|
|
||||||
* Translate the app into different languages.
|
* Translate the app into different languages.
|
||||||
|
|
||||||
|
@ -104,10 +103,17 @@ You are welcomed to help translate the app into more languages (refer to this <a
|
||||||
* <b>DO NOT</b> change the order.
|
* <b>DO NOT</b> change the order.
|
||||||
4. Email the JSON to me (tomfong.dev@gmail.com) after you finish.
|
4. Email the JSON to me (tomfong.dev@gmail.com) after you finish.
|
||||||
|
|
||||||
### Build the project
|
### Build the project (Android)
|
||||||
|
|
||||||
1. Run ```npm install``` to install all dependencies.
|
1. Run ```npm install``` to install all dependencies
|
||||||
2. Run ```npm run build```
|
2. Run ```npm run sync``` and ```npm run copy:an```
|
||||||
|
3. In ```android/app/src/main/res/values/styles.xml```, change
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar">
|
||||||
|
<item name="android:background">#00a5aa</item>
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
### Contributors
|
### Contributors
|
||||||
|
|
||||||
|
@ -117,23 +123,24 @@ Thank you the following contributors who have made the app better!
|
||||||
|:-:|:-:|:-:|
|
|:-:|:-:|:-:|
|
||||||
| mondstern | [mondlicht-und-sterne](https://github.com/mondlicht-und-sterne) | German language translation |
|
| mondstern | [mondlicht-und-sterne](https://github.com/mondlicht-und-sterne) | German language translation |
|
||||||
| Valentino Bocchetti | [luftmensch-luftmensch](https://github.com/luftmensch-luftmensch) | Italian language translation |
|
| Valentino Bocchetti | [luftmensch-luftmensch](https://github.com/luftmensch-luftmensch) | Italian language translation |
|
||||||
| Smooth-E | [Smooth-E](https://github.com/Smooth-E) | Russian language translation |
|
|
||||||
| Daniel Ribeiro | [drcsj](https://github.com/drcsj) | Portuguese (Brazil) language translation |
|
|
||||||
|
|
||||||
## Framework
|
## Framework
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
Ionic CLI : 7.2.0
|
Ionic CLI : 6.20.1
|
||||||
Ionic Framework : @ionic/angular 7.8.2
|
Ionic Framework : @ionic/angular 6.2.7
|
||||||
@angular-devkit/build-angular : 16.2.13
|
@angular-devkit/build-angular : 13.3.9
|
||||||
@angular-devkit/schematics : 16.2.13
|
@angular-devkit/schematics : 13.3.9
|
||||||
@angular/cli : 16.2.13
|
@angular/cli : 13.3.9
|
||||||
@ionic/angular-toolkit : 9.0.0
|
@ionic/angular-toolkit : 6.1.0
|
||||||
|
|
||||||
Capacitor CLI : 5.7.4
|
Capacitor CLI : 3.8.0
|
||||||
@capacitor/android : 5.7.4
|
@capacitor/android : 3.8.0
|
||||||
@capacitor/core : 5.7.4
|
@capacitor/core : 3.8.0
|
||||||
@capacitor/ios : 5.7.4
|
@capacitor/ios : 3.8.0
|
||||||
|
|
||||||
|
NodeJS : v16.15.1
|
||||||
|
npm : 8.11.0
|
||||||
```
|
```
|
||||||
|
|
||||||
## Privacy Policy
|
## Privacy Policy
|
||||||
|
|
2
android/.idea/compiler.xml
generated
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<bytecodeTargetLevel target="17" />
|
<bytecodeTargetLevel target="11" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
13
android/.idea/misc.xml
generated
|
@ -1,17 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="DesignSurface">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<option name="filePathToZoomLevelMap">
|
|
||||||
<map>
|
|
||||||
<entry key="app/src/main/res/drawable/ic_baseline_qr_code_24.xml" value="0.2485" />
|
|
||||||
<entry key="app/src/main/res/drawable/ic_launcher_background.xml" value="0.2485" />
|
|
||||||
<entry key="app/src/main/res/drawable/splash_background.xml" value="0.2485" />
|
|
||||||
<entry key="app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" value="0.2485" />
|
|
||||||
<entry key="app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" value="0.2485" />
|
|
||||||
</map>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace "com.tomfong.simpleqr"
|
|
||||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
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 4010000
|
versionCode 2080000
|
||||||
versionName "4.1.0"
|
versionName "2.8.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.
|
||||||
|
@ -31,8 +30,6 @@ 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')
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_17
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_17
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ dependencies {
|
||||||
implementation project(':capacitor-filesystem')
|
implementation project(':capacitor-filesystem')
|
||||||
implementation project(':capacitor-haptics')
|
implementation project(':capacitor-haptics')
|
||||||
implementation project(':capacitor-keyboard')
|
implementation project(':capacitor-keyboard')
|
||||||
implementation project(':capacitor-preferences')
|
|
||||||
implementation project(':capacitor-splash-screen')
|
implementation project(':capacitor-splash-screen')
|
||||||
implementation project(':capacitor-status-bar')
|
implementation project(':capacitor-status-bar')
|
||||||
implementation project(':capacitor-toast')
|
implementation project(':capacitor-toast')
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
{
|
|
||||||
"version": 3,
|
|
||||||
"artifactType": {
|
|
||||||
"type": "APK",
|
|
||||||
"kind": "Directory"
|
|
||||||
},
|
|
||||||
"applicationId": "com.tomfong.simpleqr",
|
|
||||||
"variantName": "release",
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"type": "SINGLE",
|
|
||||||
"filters": [],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 4010000,
|
|
||||||
"versionName": "4.1.0",
|
|
||||||
"outputFile": "app-release.apk"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"elementType": "File"
|
|
||||||
}
|
|
|
@ -1,16 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" >
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.tomfong.simpleqr">
|
||||||
|
|
||||||
<application
|
<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">
|
||||||
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">
|
<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">
|
||||||
|
|
||||||
|
@ -24,29 +15,13 @@
|
||||||
<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_MEDIA_IMAGES"/>
|
|
||||||
<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.READ_CONTACTS" />
|
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||||
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
|
||||||
<uses-sdk tools:overrideLibrary="com.google.zxing.client.android" />
|
<uses-sdk tools:overrideLibrary="com.google.zxing.client.android" />
|
||||||
<uses-feature
|
|
||||||
android:name="android.hardware.camera"
|
|
||||||
android:required="true" />
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pkg": "@capacitor-community/contacts",
|
"pkg": "@capacitor-community/contacts",
|
||||||
"classpath": "getcapacitor.community.contacts.ContactsPlugin"
|
"classpath": "ch.byrds.capacitor.contacts.Contacts"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pkg": "@capacitor-community/screen-brightness",
|
"pkg": "@capacitor-community/screen-brightness",
|
||||||
|
@ -39,10 +39,6 @@
|
||||||
"pkg": "@capacitor/keyboard",
|
"pkg": "@capacitor/keyboard",
|
||||||
"classpath": "com.capacitorjs.plugins.keyboard.KeyboardPlugin"
|
"classpath": "com.capacitorjs.plugins.keyboard.KeyboardPlugin"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"pkg": "@capacitor/preferences",
|
|
||||||
"classpath": "com.capacitorjs.plugins.preferences.PreferencesPlugin"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"pkg": "@capacitor/splash-screen",
|
"pkg": "@capacitor/splash-screen",
|
||||||
"classpath": "com.capacitorjs.plugins.splashscreen.SplashScreenPlugin"
|
"classpath": "com.capacitorjs.plugins.splashscreen.SplashScreenPlugin"
|
||||||
|
|
|
@ -2,20 +2,4 @@ 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
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 {
|
|
||||||
|
|
||||||
public MyQSTileService() {}
|
|
||||||
|
|
||||||
// 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");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<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>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<item android:drawable="@color/colorPrimary"/>
|
|
||||||
<item android:gravity="center" android:drawable="@drawable/splash"/>
|
|
||||||
</layer-list>
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
<color tools:ignore="UnusedResources" name="colorPrimary">#00a5aa</color>
|
|
||||||
<color tools:ignore="UnusedResources" name="colorPrimaryDark">#00a5aa</color>
|
|
||||||
<color tools:ignore="UnusedResources" name="colorAccent">#00a5aa</color>
|
|
||||||
</resources>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version='1.0' encoding='utf-8'?>
|
|
||||||
<resources>
|
|
||||||
<string name="app_name">Simple QR</string>
|
|
||||||
<string name="title_activity_main">Simple QR</string>
|
|
||||||
<string name="package_name">com.tomfong.simpleqr</string>
|
|
||||||
<string name="custom_url_scheme">com.tomfong.simpleqr</string>
|
|
||||||
</resources>
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
|
|
||||||
<!-- Base application theme. -->
|
|
||||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
|
||||||
<!-- Customize your theme here. -->
|
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
|
||||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
|
||||||
<item name="colorAccent">@color/colorAccent</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
|
|
||||||
<item name="windowActionBar">false</item>
|
|
||||||
<item name="windowNoTitle">true</item>
|
|
||||||
<item name="android:background">@null</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="AppTheme.NoActionBarLaunch" parent="Theme.SplashScreen">
|
|
||||||
<item name="android:background">@drawable/splash_background</item>
|
|
||||||
<item name="android:windowBackground">@drawable/splash_background</item>
|
|
||||||
</style>
|
|
||||||
</resources>
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
<color tools:ignore="UnusedResources" name="colorPrimary">#00a5aa</color>
|
|
||||||
<color tools:ignore="UnusedResources" name="colorPrimaryDark">#00a5aa</color>
|
|
||||||
<color tools:ignore="UnusedResources" name="colorAccent">#00a5aa</color>
|
|
||||||
</resources>
|
|
|
@ -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.DayNight.NoActionBar">
|
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.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">
|
|
||||||
<item name="android:background">@drawable/splash_background</item>
|
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar">
|
||||||
<item name="android:windowBackground">@drawable/splash_background</item>
|
<item name="android:background">#00a5aa</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
<color tools:ignore="UnusedResources" name="colorPrimary">#00a5aa</color>
|
|
||||||
<color tools:ignore="UnusedResources" name="colorPrimaryDark">#00a5aa</color>
|
|
||||||
<color tools:ignore="UnusedResources" name="colorAccent">#00a5aa</color>
|
|
||||||
</resources>
|
|
|
@ -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.DayNight.NoActionBar">
|
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.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">
|
|
||||||
<item name="android:background">@drawable/splash_background</item>
|
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar">
|
||||||
<item name="android:windowBackground">@drawable/splash_background</item>
|
<item name="android:background">#00a5aa</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
<color tools:ignore="UnusedResources" name="colorPrimary">#00a5aa</color>
|
|
||||||
<color tools:ignore="UnusedResources" name="colorPrimaryDark">#00a5aa</color>
|
|
||||||
<color tools:ignore="UnusedResources" name="colorAccent">#00a5aa</color>
|
|
||||||
</resources>
|
|
|
@ -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.DayNight.NoActionBar">
|
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.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">
|
|
||||||
<item name="android:background">@drawable/splash_background</item>
|
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar">
|
||||||
<item name="android:windowBackground">@drawable/splash_background</item>
|
<item name="android:background">#00a5aa</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
<color tools:ignore="UnusedResources" name="colorPrimary">#00a5aa</color>
|
|
||||||
<color tools:ignore="UnusedResources" name="colorPrimaryDark">#00a5aa</color>
|
|
||||||
<color tools:ignore="UnusedResources" name="colorAccent">#00a5aa</color>
|
|
||||||
</resources>
|
|
|
@ -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.DayNight.NoActionBar">
|
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.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">
|
|
||||||
<item name="android:background">@drawable/splash_background</item>
|
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar">
|
||||||
<item name="android:windowBackground">@drawable/splash_background</item>
|
<item name="android:background">#00a5aa</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
<color tools:ignore="UnusedResources" name="colorPrimary">#00a5aa</color>
|
|
||||||
<color tools:ignore="UnusedResources" name="colorPrimaryDark">#00a5aa</color>
|
|
||||||
<color tools:ignore="UnusedResources" name="colorAccent">#00a5aa</color>
|
|
||||||
</resources>
|
|
|
@ -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.DayNight.NoActionBar">
|
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.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">
|
|
||||||
<item name="android:background">@drawable/splash_background</item>
|
<style name="AppTheme.NoActionBarLaunch" parent="AppTheme.NoActionBar">
|
||||||
<item name="android:windowBackground">@drawable/splash_background</item>
|
<item name="android:background">#00a5aa</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:8.0.2'
|
classpath 'com.android.tools.build:gradle:4.2.1'
|
||||||
classpath 'com.google.gms:google-services:4.3.15'
|
classpath 'com.google.gms:google-services:4.3.5'
|
||||||
|
|
||||||
// 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,11 +20,10 @@ apply from: "variables.gradle"
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
jcenter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,6 @@ project(':capacitor-haptics').projectDir = new File('../node_modules/@capacitor/
|
||||||
include ':capacitor-keyboard'
|
include ':capacitor-keyboard'
|
||||||
project(':capacitor-keyboard').projectDir = new File('../node_modules/@capacitor/keyboard/android')
|
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'
|
include ':capacitor-splash-screen'
|
||||||
project(':capacitor-splash-screen').projectDir = new File('../node_modules/@capacitor/splash-screen/android')
|
project(':capacitor-splash-screen').projectDir = new File('../node_modules/@capacitor/splash-screen/android')
|
||||||
|
|
||||||
|
|
|
@ -20,4 +20,5 @@ org.gradle.jvmargs=-Xmx1536m
|
||||||
# Android operating system, and which are packaged with your app's APK
|
# Android operating system, and which are packaged with your app's APK
|
||||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
|
# Automatically convert third-party libraries to use AndroidX
|
||||||
|
android.enableJetifier=true
|
||||||
|
|
|
@ -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-8.0.2-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-all.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
ext {
|
ext {
|
||||||
minSdkVersion = 22
|
minSdkVersion = 23
|
||||||
compileSdkVersion = 33
|
compileSdkVersion = 31
|
||||||
targetSdkVersion = 33
|
targetSdkVersion = 31
|
||||||
androidxActivityVersion = '1.7.0'
|
androidxActivityVersion = '1.2.0'
|
||||||
androidxAppCompatVersion = '1.6.1'
|
androidxAppCompatVersion = '1.2.0'
|
||||||
androidxCoordinatorLayoutVersion = '1.2.0'
|
androidxCoordinatorLayoutVersion = '1.1.0'
|
||||||
androidxCoreVersion = '1.10.0'
|
androidxCoreVersion = '1.3.2'
|
||||||
androidxFragmentVersion = '1.5.6'
|
androidxFragmentVersion = '1.3.0'
|
||||||
junitVersion = '4.13.2'
|
junitVersion = '4.13.1'
|
||||||
androidxJunitVersion = '1.1.5'
|
androidxJunitVersion = '1.1.2'
|
||||||
androidxEspressoCoreVersion = '3.5.1'
|
androidxEspressoCoreVersion = '3.3.0'
|
||||||
cordovaAndroidVersion = '10.1.1'
|
cordovaAndroidVersion = '7.0.0'
|
||||||
coreSplashScreenVersion = '1.0.0'
|
|
||||||
androidxWebkitVersion = '1.6.1'
|
|
||||||
}
|
}
|
||||||
|
|
40
angular.json
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"$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": {
|
||||||
|
@ -30,10 +31,7 @@
|
||||||
"output": "./svg"
|
"output": "./svg"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": ["src/theme/variables.scss", "src/global.scss"],
|
||||||
"src/theme/variables.scss",
|
|
||||||
"src/global.scss"
|
|
||||||
],
|
|
||||||
"scripts": [],
|
"scripts": [],
|
||||||
"aot": false,
|
"aot": false,
|
||||||
"vendorChunk": true,
|
"vendorChunk": true,
|
||||||
|
@ -82,7 +80,8 @@
|
||||||
"production": {
|
"production": {
|
||||||
"browserTarget": "app:build:production"
|
"browserTarget": "app:build:production"
|
||||||
},
|
},
|
||||||
"ci": {}
|
"ci": {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"extract-i18n": {
|
"extract-i18n": {
|
||||||
|
@ -134,15 +133,36 @@
|
||||||
"devServerTarget": "app:serve:ci"
|
"devServerTarget": "app:serve:ci"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"ionic-cordova-build": {
|
||||||
|
"builder": "@ionic/angular-toolkit:cordova-build",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "app:build"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"browserTarget": "app:build:production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ionic-cordova-serve": {
|
||||||
|
"builder": "@ionic/angular-toolkit:cordova-serve",
|
||||||
|
"options": {
|
||||||
|
"cordovaBuildTarget": "app:ionic-cordova-build",
|
||||||
|
"devServerTarget": "app:serve"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"cordovaBuildTarget": "app:ionic-cordova-build:production",
|
||||||
|
"devServerTarget": "app:serve:production"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cli": {
|
"cli": {
|
||||||
"schematicCollections": [
|
"defaultCollection": "@ionic/angular-toolkit"
|
||||||
"@ionic/angular-toolkit"
|
|
||||||
],
|
|
||||||
"analytics": false
|
|
||||||
},
|
},
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"@ionic/angular-toolkit:component": {
|
"@ionic/angular-toolkit:component": {
|
||||||
|
@ -152,4 +172,4 @@
|
||||||
"styleext": "scss"
|
"styleext": "scss"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ Mit der App ist das möglich
|
||||||
|
|
||||||
* QR-Code und andere Barcodes in Sekundenschnelle zu scannen, einschließlich UPC, EAN, Code 39/128, ITF, Codabar, Aztec, Data Matrix, PDF417, MaxiCode und GS1 DataBar.
|
* QR-Code und andere Barcodes in Sekundenschnelle zu scannen, einschließlich UPC, EAN, Code 39/128, ITF, Codabar, Aztec, Data Matrix, PDF417, MaxiCode und GS1 DataBar.
|
||||||
* Bilddateien zu importieren und den darauf befindlichen QR-Code zu scannen.
|
* Bilddateien zu importieren und den darauf befindlichen QR-Code zu scannen.
|
||||||
* QR-Codes aus Vorlagen,die Freitext, URL, vCard-Kontakt, Telefonnummer, Nachricht, Geolokalisierung, E-Mail und WLAN enthalten, zu erstellen.
|
* QR-Codes aus Vorlagen,die Freitext, URL, vCard-Kontakt, Telefonnummer, Nachricht, E-Mail und WLAN enthalten, zu erstellen.
|
||||||
* Gescannte Ergebnissen, die gescannt wurden, erstellt oder erneut angezeigt wurden zu protokollieren. Diese protokollierten Aufzeichnungen können für schnellen Zugriff mit einem Lesezeichen versehen und auch gesichert werden.
|
* Gescannte Ergebnissen, die gescannt wurden, erstellt oder erneut angezeigt wurden zu protokollieren. Diese protokollierten Aufzeichnungen können für schnellen Zugriff mit einem Lesezeichen versehen und auch gesichert werden.
|
||||||
* Aufgaben auf dem Ergebnis mit einem Fingertipp zu erledigen, einschließlich, aber nicht beschränkt auf
|
* Aufgaben auf dem Ergebnis mit einem Fingertipp zu erledigen, einschließlich, aber nicht beschränkt auf
|
||||||
* Verwenden als Schlüsselwort für die Websuche.
|
* Verwenden als Schlüsselwort für die Websuche.
|
||||||
|
@ -19,6 +19,5 @@ Mit der App ist das möglich
|
||||||
* Telefonnummer: Telefonanruf, Kontakt hinzufügen
|
* Telefonnummer: Telefonanruf, Kontakt hinzufügen
|
||||||
* Nachricht: Nachricht senden, Kontakt hinzufügen
|
* Nachricht: Nachricht senden, Kontakt hinzufügen
|
||||||
* E-Mail: E-Mail senden
|
* E-Mail: E-Mail senden
|
||||||
* Geolokalisierung: Karte öffnen
|
|
||||||
* Passen Sie den generierten QR-Code an, z. Fehlerkorrekturstufe, Farbe, Rand und Bildschirmhelligkeit.
|
* Passen Sie den generierten QR-Code an, z. Fehlerkorrekturstufe, Farbe, Rand und Bildschirmhelligkeit.
|
||||||
* Die App anzupassen, z.B. App-Startseite, Sprache und Farbthema etc.
|
* Die App anzupassen, z.B. App-Startseite, Sprache und Farbthema etc.
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
* 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.
|
|
|
@ -1 +0,0 @@
|
||||||
* Bug fix
|
|
|
@ -1,3 +0,0 @@
|
||||||
* Support Ecosia
|
|
||||||
* Support CSV export
|
|
||||||
* Bug fix
|
|
|
@ -1,2 +0,0 @@
|
||||||
* Support Open Food Facts
|
|
||||||
* Bug fix
|
|
|
@ -1,3 +0,0 @@
|
||||||
* Support Russian language
|
|
||||||
* Allow user to manually save a record if auto logging is off
|
|
||||||
* Minor update on UI
|
|
|
@ -1,4 +0,0 @@
|
||||||
* Upgrade framework, improve performance and fix known bugs
|
|
||||||
* Support Brave Search
|
|
||||||
* Support open URL automatically
|
|
||||||
* Allow user to further edit QR code content
|
|
|
@ -1 +0,0 @@
|
||||||
* Fix import image issue
|
|
|
@ -1,3 +0,0 @@
|
||||||
* Support geolocation QR code
|
|
||||||
* Support Portuguese (Brazil) language
|
|
||||||
* Disable auto URL opening by default
|
|
|
@ -1,12 +1,12 @@
|
||||||
<i>Simple QR</i> is an open-source app to scan, create and store QR codes with a simple UI and experience. No backend service connected. No data collected. No ads.
|
<i>Simple QR</i> is a FOSS app to scan, create and store QR codes with a simple UI and experience. No backend service connected. No data collected. No ads.
|
||||||
|
|
||||||
English, French, German, Itanlian, Russian, Traditional Chinese and Simplified Chinese are supported.
|
English, French, German, Itanlian, Traditional Chinese and Simplified Chinese are supported.
|
||||||
|
|
||||||
By using the app, you can:
|
By using the app, you can:
|
||||||
|
|
||||||
* Scan QR Code and other barcodes in a second, including UPC, EAN, Code 39/128, ITF, Codabar, Aztec, Data Matrix, PDF417, MaxiCode and GS1 DataBar.
|
* Scan QR Code and other barcodes in a second, including UPC, EAN, Code 39/128, ITF, Codabar, Aztec, Data Matrix, PDF417, MaxiCode and GS1 DataBar.
|
||||||
* Import image files and scan the QR Code on it.
|
* Import image files and scan the QR Code on it.
|
||||||
* Create QR code from templates, which includes Free Text, URL, vCard Contact, Phone Number, Message, Email, Wi-Fi and Geolocation.
|
* Create QR code from templates, which includes Free Text, URL, vCard Contact, Phone Number, Message, Email and Wi-Fi.
|
||||||
* Automatically log results that you scan, create or view again. These logged records can be bookmarked for quick access, and also backupable.
|
* Automatically log results that you scan, create or view again. These logged records can be bookmarked for quick access, and also backupable.
|
||||||
* Do tasks on the result with a tap, including but not limited to
|
* Do tasks on the result with a tap, including but not limited to
|
||||||
* Use it as a keyword to do web search.
|
* Use it as a keyword to do web search.
|
||||||
|
@ -14,11 +14,10 @@ By using the app, you can:
|
||||||
* Execute base64 encoding/decoding on it.
|
* Execute base64 encoding/decoding on it.
|
||||||
* Generate a new shareable QR code by using it as the content.
|
* Generate a new shareable QR code by using it as the content.
|
||||||
* Do corresponding tasks if it is a
|
* Do corresponding tasks if it is a
|
||||||
* URL: Browse website / Open application
|
* URL: Browse website
|
||||||
* vCard contact: Add contact
|
* vCard contact: Add contact
|
||||||
* Phone number: Phone call, add contact
|
* Phone number: Phone call, add contact
|
||||||
* Message: Send message, add contact
|
* Message: Send message, add contact
|
||||||
* Email: Send email
|
* Email: Send email
|
||||||
* Geolocation: Open map
|
|
||||||
* Customize the generated QR code, e.g. error correction level, color, margin and screen brightness.
|
* Customize the generated QR code, e.g. error correction level, color, margin and screen brightness.
|
||||||
* Customize the app, e.g. app initial page, language and color theme etc.
|
* Customize the app, e.g. app initial page, language and color theme etc.
|
||||||
|
|
2
ios/.gitignore
vendored
|
@ -1,9 +1,9 @@
|
||||||
App/build
|
App/build
|
||||||
App/Pods
|
App/Pods
|
||||||
|
App/Podfile.lock
|
||||||
App/App/public
|
App/App/public
|
||||||
DerivedData
|
DerivedData
|
||||||
xcuserdata
|
xcuserdata
|
||||||
|
|
||||||
# Cordova plugins for Capacitor
|
# Cordova plugins for Capacitor
|
||||||
capacitor-cordova-ios-plugins
|
capacitor-cordova-ios-plugins
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
1B75189429375EAB00800D38 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
|
||||||
2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = "<group>"; };
|
2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = "<group>"; };
|
||||||
50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = "<group>"; };
|
50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = "<group>"; };
|
||||||
504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -161,7 +160,6 @@
|
||||||
de,
|
de,
|
||||||
fr,
|
fr,
|
||||||
it,
|
it,
|
||||||
ru,
|
|
||||||
);
|
);
|
||||||
mainGroup = 504EC2FB1FED79650016851F;
|
mainGroup = 504EC2FB1FED79650016851F;
|
||||||
productRefGroup = 504EC3051FED79650016851F /* Products */;
|
productRefGroup = 504EC3051FED79650016851F /* Products */;
|
||||||
|
@ -270,7 +268,6 @@
|
||||||
D26FE7F9283D1E6C002A61AE /* fr */,
|
D26FE7F9283D1E6C002A61AE /* fr */,
|
||||||
D26FE7FA283D1E76002A61AE /* de */,
|
D26FE7FA283D1E76002A61AE /* de */,
|
||||||
D29D2E2A2847C31D00566DFF /* it */,
|
D29D2E2A2847C31D00566DFF /* it */,
|
||||||
1B75189429375EAB00800D38 /* ru */,
|
|
||||||
);
|
);
|
||||||
name = InfoPlist.strings;
|
name = InfoPlist.strings;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -327,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 = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -379,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 = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||||
|
@ -397,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 = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
MARKETING_VERSION = 4.1.0;
|
MARKETING_VERSION = 2.8.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)";
|
||||||
|
@ -420,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 = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
MARKETING_VERSION = 4.1.0;
|
MARKETING_VERSION = 2.8.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";
|
||||||
|
|
|
@ -46,6 +46,15 @@ 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
After Width: | Height: | Size: 588 B |
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 743 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 3 KiB |
After Width: | Height: | Size: 2.7 KiB |
|
@ -1,14 +1,116 @@
|
||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "AppIcon-512@2x.png",
|
"size" : "20x20",
|
||||||
"idiom" : "universal",
|
"idiom" : "iphone",
|
||||||
"platform" : "ios",
|
"filename" : "AppIcon-20x20@2x.png",
|
||||||
"size" : "1024x1024"
|
"scale" : "2x"
|
||||||
}
|
},
|
||||||
],
|
{
|
||||||
"info" : {
|
"size" : "20x20",
|
||||||
"author" : "xcode",
|
"idiom" : "iphone",
|
||||||
"version" : 1
|
"filename" : "AppIcon-20x20@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "AppIcon-29x29@2x-1.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "AppIcon-29x29@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "AppIcon-40x40@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "AppIcon-40x40@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "60x60",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "AppIcon-60x60@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "60x60",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "AppIcon-60x60@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "20x20",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "AppIcon-20x20@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "20x20",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "AppIcon-20x20@2x-1.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "AppIcon-29x29@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "AppIcon-29x29@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "AppIcon-40x40@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "AppIcon-40x40@2x-1.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "76x76",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "AppIcon-76x76@1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "76x76",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "AppIcon-76x76@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "83.5x83.5",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"filename" : "AppIcon-83.5x83.5@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "1024x1024",
|
||||||
|
"idiom" : "ios-marketing",
|
||||||
|
"filename" : "AppIcon-512@2x.png",
|
||||||
|
"scale" : "1x"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -22,6 +22,11 @@
|
||||||
<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>
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
"CFBundleDisplayName" = "Simple QR";
|
|
||||||
"CFBundleName" = "Simple QR";
|
|
||||||
"NSCameraUsageDescription" = "Simple QR использует камеру для сканирования QR-кода и штрих-кодов";
|
|
||||||
"NSContactsUsageDescription" = "Simple QR использует Контакты для добавления контакта";
|
|
||||||
"NSPhotoLibraryAddUsageDescription" = "Simple QR использует библиотеку фотографий для сохранения изображения QR-кода";
|
|
||||||
"NSPhotoLibraryUsageDescription" = "Simple QR использует библиотеку фотографий для импорта изображений и сканирования QR-кода.";
|
|
|
@ -1,6 +1,4 @@
|
||||||
require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers'
|
platform :ios, '12.0'
|
||||||
|
|
||||||
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
|
||||||
|
@ -21,7 +19,6 @@ def capacitor_pods
|
||||||
pod 'CapacitorFilesystem', :path => '../../node_modules/@capacitor/filesystem'
|
pod 'CapacitorFilesystem', :path => '../../node_modules/@capacitor/filesystem'
|
||||||
pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics'
|
pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics'
|
||||||
pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard'
|
pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard'
|
||||||
pod 'CapacitorPreferences', :path => '../../node_modules/@capacitor/preferences'
|
|
||||||
pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
|
pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
|
||||||
pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar'
|
pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar'
|
||||||
pod 'CapacitorToast', :path => '../../node_modules/@capacitor/toast'
|
pod 'CapacitorToast', :path => '../../node_modules/@capacitor/toast'
|
||||||
|
@ -32,8 +29,3 @@ target 'App' do
|
||||||
capacitor_pods
|
capacitor_pods
|
||||||
# Add your Pods here
|
# Add your Pods here
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
post_install do |installer|
|
|
||||||
assertDeploymentTarget(installer)
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,112 +0,0 @@
|
||||||
PODS:
|
|
||||||
- Capacitor (5.7.4):
|
|
||||||
- CapacitorCordova
|
|
||||||
- CapacitorApp (5.0.7):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorCamera (5.0.9):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorClipboard (5.0.7):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorCommunityBarcodeScanner (4.0.1):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorCommunityContacts (5.0.5):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorCommunityScreenBrightness (5.0.0):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorCordova (5.7.4)
|
|
||||||
- CapacitorDevice (5.0.7):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorFilesystem (5.2.1):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorHaptics (5.0.7):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorKeyboard (5.0.8):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorPreferences (5.0.7):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorSplashScreen (5.0.7):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorStatusBar (5.0.7):
|
|
||||||
- Capacitor
|
|
||||||
- CapacitorToast (5.0.7):
|
|
||||||
- Capacitor
|
|
||||||
- CordovaPlugins (5.7.4):
|
|
||||||
- CapacitorCordova
|
|
||||||
|
|
||||||
DEPENDENCIES:
|
|
||||||
- "Capacitor (from `../../node_modules/@capacitor/ios`)"
|
|
||||||
- "CapacitorApp (from `../../node_modules/@capacitor/app`)"
|
|
||||||
- "CapacitorCamera (from `../../node_modules/@capacitor/camera`)"
|
|
||||||
- "CapacitorClipboard (from `../../node_modules/@capacitor/clipboard`)"
|
|
||||||
- "CapacitorCommunityBarcodeScanner (from `../../node_modules/@capacitor-community/barcode-scanner`)"
|
|
||||||
- "CapacitorCommunityContacts (from `../../node_modules/@capacitor-community/contacts`)"
|
|
||||||
- "CapacitorCommunityScreenBrightness (from `../../node_modules/@capacitor-community/screen-brightness`)"
|
|
||||||
- "CapacitorCordova (from `../../node_modules/@capacitor/ios`)"
|
|
||||||
- "CapacitorDevice (from `../../node_modules/@capacitor/device`)"
|
|
||||||
- "CapacitorFilesystem (from `../../node_modules/@capacitor/filesystem`)"
|
|
||||||
- "CapacitorHaptics (from `../../node_modules/@capacitor/haptics`)"
|
|
||||||
- "CapacitorKeyboard (from `../../node_modules/@capacitor/keyboard`)"
|
|
||||||
- "CapacitorPreferences (from `../../node_modules/@capacitor/preferences`)"
|
|
||||||
- "CapacitorSplashScreen (from `../../node_modules/@capacitor/splash-screen`)"
|
|
||||||
- "CapacitorStatusBar (from `../../node_modules/@capacitor/status-bar`)"
|
|
||||||
- "CapacitorToast (from `../../node_modules/@capacitor/toast`)"
|
|
||||||
- CordovaPlugins (from `../capacitor-cordova-ios-plugins`)
|
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
|
||||||
Capacitor:
|
|
||||||
:path: "../../node_modules/@capacitor/ios"
|
|
||||||
CapacitorApp:
|
|
||||||
:path: "../../node_modules/@capacitor/app"
|
|
||||||
CapacitorCamera:
|
|
||||||
:path: "../../node_modules/@capacitor/camera"
|
|
||||||
CapacitorClipboard:
|
|
||||||
:path: "../../node_modules/@capacitor/clipboard"
|
|
||||||
CapacitorCommunityBarcodeScanner:
|
|
||||||
:path: "../../node_modules/@capacitor-community/barcode-scanner"
|
|
||||||
CapacitorCommunityContacts:
|
|
||||||
:path: "../../node_modules/@capacitor-community/contacts"
|
|
||||||
CapacitorCommunityScreenBrightness:
|
|
||||||
:path: "../../node_modules/@capacitor-community/screen-brightness"
|
|
||||||
CapacitorCordova:
|
|
||||||
:path: "../../node_modules/@capacitor/ios"
|
|
||||||
CapacitorDevice:
|
|
||||||
:path: "../../node_modules/@capacitor/device"
|
|
||||||
CapacitorFilesystem:
|
|
||||||
:path: "../../node_modules/@capacitor/filesystem"
|
|
||||||
CapacitorHaptics:
|
|
||||||
:path: "../../node_modules/@capacitor/haptics"
|
|
||||||
CapacitorKeyboard:
|
|
||||||
:path: "../../node_modules/@capacitor/keyboard"
|
|
||||||
CapacitorPreferences:
|
|
||||||
:path: "../../node_modules/@capacitor/preferences"
|
|
||||||
CapacitorSplashScreen:
|
|
||||||
:path: "../../node_modules/@capacitor/splash-screen"
|
|
||||||
CapacitorStatusBar:
|
|
||||||
:path: "../../node_modules/@capacitor/status-bar"
|
|
||||||
CapacitorToast:
|
|
||||||
:path: "../../node_modules/@capacitor/toast"
|
|
||||||
CordovaPlugins:
|
|
||||||
:path: "../capacitor-cordova-ios-plugins"
|
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
|
||||||
Capacitor: 4fe9adf012caceb4c71ffea2f1f4d005cdcbeea7
|
|
||||||
CapacitorApp: 17fecd0e6cb23feafac7eb0939417389038b0979
|
|
||||||
CapacitorCamera: 4892c5c392f60039d853dde78bc50ba19fbd113e
|
|
||||||
CapacitorClipboard: 45e5e25f2271f98712985d422776cdc5a779cca1
|
|
||||||
CapacitorCommunityBarcodeScanner: 7feb206489c8555a8ca0c74c57ddf49ead774eb8
|
|
||||||
CapacitorCommunityContacts: e8fbc4d669c9478a29f1e104818b4c16e158b2e0
|
|
||||||
CapacitorCommunityScreenBrightness: b2d9c6fffee6b684994cd69f727f2090e2f05c6d
|
|
||||||
CapacitorCordova: a6e87fccc0307dee7aec1560ec9398485f2b0ce7
|
|
||||||
CapacitorDevice: fc91bdb484dc0e70755e9b621cd557afe642613a
|
|
||||||
CapacitorFilesystem: 9f3e3c7fea2fff12f46dd5b07a2914f2103e4cfc
|
|
||||||
CapacitorHaptics: 7c7c206f0c96a628fed073830c96d28c4b2e772e
|
|
||||||
CapacitorKeyboard: aec619a578235c6ce279075009a2689c2cf5c42c
|
|
||||||
CapacitorPreferences: 77ac427e98db83bace772455f8ba447430382c4c
|
|
||||||
CapacitorSplashScreen: dd3de3f3644710fa2a697cfb91ec262eece4d242
|
|
||||||
CapacitorStatusBar: f390fbb49b82ffb754ea4b3cf71dc8b048baf3e7
|
|
||||||
CapacitorToast: c8bb89eeb59a23c1fc298f138cc06c8ff4d90ac1
|
|
||||||
CordovaPlugins: 5495649167d6829fea7bc7eacd2034646aee5bd1
|
|
||||||
|
|
||||||
PODFILE CHECKSUM: dc80e3587547d0d302dad43090af30e2a96d6c5a
|
|
||||||
|
|
||||||
COCOAPODS: 1.11.3
|
|
24811
package-lock.json
generated
133
package.json
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "simple-qr",
|
"name": "simple-qr",
|
||||||
"version": "4.1.0",
|
"version": "2.8.0",
|
||||||
"author": "Tom Fong",
|
"author": "Tom Fong",
|
||||||
|
"homepage": "https://tomfong.github.io",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"build:an": "ionic cap build android --prod --no-open",
|
"build:an": "ionic cap build android --prod",
|
||||||
"build:ios": "ionic cap build ios --prod --no-open",
|
"build:ios": "ionic cap build ios --prod",
|
||||||
"build": "ionic cap build android --prod --no-open && ionic cap build ios --prod --no-open",
|
|
||||||
"sync": "ionic cap sync --prod --no-build",
|
"sync": "ionic cap sync --prod --no-build",
|
||||||
"copy:an": "ionic cap copy android --prod",
|
"copy:an": "ionic cap copy android --prod",
|
||||||
"copy:ios": "ionic cap copy ios --prod",
|
"copy:ios": "ionic cap copy ios --prod",
|
||||||
|
@ -16,90 +16,91 @@
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^16.1.3",
|
"@angular/animations": "^13.3.5",
|
||||||
"@angular/cdk": "^16.1.3",
|
"@angular/cdk": "^13.3.5",
|
||||||
"@angular/common": "^16.1.3",
|
"@angular/common": "^13.3.5",
|
||||||
"@angular/core": "^16.1.3",
|
"@angular/core": "^13.3.5",
|
||||||
"@angular/forms": "^16.2.12",
|
"@angular/forms": "^13.3.11",
|
||||||
"@angular/localize": "^16.2.12",
|
"@angular/localize": "^13.3.11",
|
||||||
"@angular/material": "^16.1.3",
|
"@angular/material": "^13.3.5",
|
||||||
"@angular/material-moment-adapter": "^16.2.14",
|
"@angular/material-moment-adapter": "^13.3.9",
|
||||||
"@angular/platform-browser": "^16.1.3",
|
"@angular/platform-browser": "^13.3.5",
|
||||||
"@angular/platform-browser-dynamic": "^16.2.12",
|
"@angular/platform-browser-dynamic": "^13.3.11",
|
||||||
"@angular/router": "^16.2.12",
|
"@angular/router": "^13.3.11",
|
||||||
"@awesome-cordova-plugins/aes-256": "^6.6.0",
|
"@awesome-cordova-plugins/aes-256": "^5.45.0",
|
||||||
"@awesome-cordova-plugins/chooser": "^6.6.0",
|
"@awesome-cordova-plugins/chooser": "^5.45.0",
|
||||||
"@awesome-cordova-plugins/core": "^6.6.0",
|
"@awesome-cordova-plugins/core": "^5.45.0",
|
||||||
"@awesome-cordova-plugins/screen-orientation": "^6.6.0",
|
"@awesome-cordova-plugins/screen-orientation": "^5.45.0",
|
||||||
"@awesome-cordova-plugins/sms": "^6.6.0",
|
"@awesome-cordova-plugins/sms": "^5.45.0",
|
||||||
"@awesome-cordova-plugins/social-sharing": "^6.6.0",
|
"@awesome-cordova-plugins/social-sharing": "^5.45.0",
|
||||||
"@awesome-cordova-plugins/theme-detection": "^6.6.0",
|
"@awesome-cordova-plugins/theme-detection": "^5.45.0",
|
||||||
"@capacitor-community/barcode-scanner": "^4.0.1",
|
"@capacitor-community/barcode-scanner": "^2.1.1",
|
||||||
"@capacitor-community/contacts": "^5.0.5",
|
"@capacitor-community/contacts": "^1.1.3",
|
||||||
"@capacitor-community/screen-brightness": "^5.0.0",
|
"@capacitor-community/screen-brightness": "^1.0.1",
|
||||||
"@capacitor/android": "^5.7.4",
|
"@capacitor/android": "^3.8.0",
|
||||||
"@capacitor/app": "^5.0.7",
|
"@capacitor/app": "^1.1.1",
|
||||||
"@capacitor/camera": "^5.0.9",
|
"@capacitor/camera": "^1.3.1",
|
||||||
"@capacitor/clipboard": "^5.0.7",
|
"@capacitor/clipboard": "^1.0.8",
|
||||||
"@capacitor/core": "^5.7.4",
|
"@capacitor/core": "^3.8.0",
|
||||||
"@capacitor/device": "^5.0.7",
|
"@capacitor/device": "^1.1.2",
|
||||||
"@capacitor/filesystem": "^5.2.1",
|
"@capacitor/filesystem": "^1.1.0",
|
||||||
"@capacitor/haptics": "^5.0.7",
|
"@capacitor/haptics": "^1.1.4",
|
||||||
"@capacitor/ios": "^5.7.4",
|
"@capacitor/ios": "^3.8.0",
|
||||||
"@capacitor/keyboard": "^5.0.8",
|
"@capacitor/keyboard": "^1.2.3",
|
||||||
"@capacitor/preferences": "^5.0.7",
|
"@capacitor/splash-screen": "^1.2.2",
|
||||||
"@capacitor/splash-screen": "^5.0.7",
|
"@capacitor/status-bar": "^1.0.8",
|
||||||
"@capacitor/status-bar": "^5.0.7",
|
"@capacitor/toast": "^1.0.8",
|
||||||
"@capacitor/toast": "^5.0.7",
|
"@ionic/angular": "^6.2.7",
|
||||||
"@ionic/angular": "^7.8.2",
|
"@ionic/storage": "^3.0.6",
|
||||||
"@ionic/storage": "^4.0.0",
|
"@ionic/storage-angular": "^3.0.6",
|
||||||
"@ionic/storage-angular": "^4.0.0",
|
"@ng-bootstrap/ng-bootstrap": "^11.0.1",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^15.1.2",
|
"@ngx-translate/core": "^13.0.0",
|
||||||
"@ngx-translate/core": "^15.0.0",
|
"@ngx-translate/http-loader": "^6.0.0",
|
||||||
"@ngx-translate/http-loader": "^8.0.0",
|
"@techiediaries/ngx-qrcode": "^9.1.0",
|
||||||
"angularx-qrcode": "^16.0.2",
|
"bootstrap": "^4.6.2",
|
||||||
"bootstrap": "^5.3.3",
|
|
||||||
"cordova-plugin-aes256-encryption": "^2.0.1",
|
"cordova-plugin-aes256-encryption": "^2.0.1",
|
||||||
"cordova-plugin-chooser": "^1.3.2",
|
"cordova-plugin-chooser": "^1.3.2",
|
||||||
"cordova-plugin-screen-orientation": "^3.0.4",
|
"cordova-plugin-screen-orientation": "^3.0.2",
|
||||||
"cordova-plugin-theme-detection": "^1.3.0",
|
"cordova-plugin-theme-detection": "^1.3.0",
|
||||||
"cordova-plugin-x-socialsharing": "^6.0.4",
|
"cordova-plugin-x-socialsharing": "^6.0.4",
|
||||||
"cordova-sms-plugin": "^1.0.3",
|
"cordova-sms-plugin": "^1.0.2",
|
||||||
"date-fns": "2.29.3",
|
|
||||||
"es6-promise-plugin": "^4.2.2",
|
"es6-promise-plugin": "^4.2.2",
|
||||||
"human-signals": "^2.1.0",
|
"human-signals": "^2.1.0",
|
||||||
"jsqr": "^1.4.0",
|
"jsqr": "^1.4.0",
|
||||||
"material-design-icons": "^3.0.1",
|
"material-design-icons": "^3.0.1",
|
||||||
|
"moment": "^2.29.4",
|
||||||
"osenv": "^0.1.5",
|
"osenv": "^0.1.5",
|
||||||
"properties-parser": "^0.3.1",
|
"properties-parser": "^0.3.1",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^6.6.7",
|
||||||
"strip-final-newline": "^2.0.0",
|
"strip-final-newline": "^2.0.0",
|
||||||
"tslib": "^2.6.2",
|
"tslib": "^2.4.0",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
"zone.js": "^0.13.3"
|
"zone.js": "^0.11.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^16.2.13",
|
"@angular-devkit/build-angular": "^13.3.9",
|
||||||
"@angular/cli": "^16.2.13",
|
"@angular/cli": "^13.3.9",
|
||||||
"@angular/compiler": "^16.1.3",
|
"@angular/compiler": "^13.3.5",
|
||||||
"@angular/compiler-cli": "^16.1.3",
|
"@angular/compiler-cli": "^13.3.5",
|
||||||
"@angular/language-service": "^16.2.12",
|
"@angular/language-service": "^13.3.11",
|
||||||
"@capacitor/cli": "^5.7.4",
|
"@capacitor/cli": "^3.8.0",
|
||||||
"@ionic/angular-toolkit": "^9.0.0",
|
"@ionic/angular-toolkit": "^6.1.0",
|
||||||
"@ionic/cli": "^7.2.0",
|
"@types/jasmine": "^3.10.6",
|
||||||
"@types/jasmine": "^3.10.18",
|
"@types/jasminewd2": "^2.0.10",
|
||||||
"@types/jasminewd2": "^2.0.13",
|
|
||||||
"@types/node": "^12.20.55",
|
"@types/node": "^12.20.55",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
|
"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.3",
|
"karma": "^6.4.0",
|
||||||
"karma-chrome-launcher": "^3.2.0",
|
"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",
|
||||||
"karma-jasmine": "^4.0.2",
|
"karma-jasmine": "^4.0.2",
|
||||||
"karma-jasmine-html-reporter": "^1.7.0",
|
"karma-jasmine-html-reporter": "^1.7.0",
|
||||||
|
"protractor": "~7.0.0",
|
||||||
"ts-node": "~8.3.0",
|
"ts-node": "~8.3.0",
|
||||||
"typescript": "^5.1.6"
|
"tslint": "~6.1.0",
|
||||||
|
"typescript": "~4.5.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,10 +48,6 @@ const routes: Routes = [
|
||||||
path: 'setting-auto-brightness',
|
path: 'setting-auto-brightness',
|
||||||
loadChildren: () => import('./pages/setting-auto-brightness/setting-auto-brightness.module').then(m => m.SettingAutoBrightnessPageModule)
|
loadChildren: () => import('./pages/setting-auto-brightness/setting-auto-brightness.module').then(m => m.SettingAutoBrightnessPageModule)
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'setting-auto-open-url',
|
|
||||||
loadChildren: () => import('./pages/setting-auto-open-url/setting-auto-open-url.module').then(m => m.SettingAutoOpenUrlPageModule)
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'setting-start-page',
|
path: 'setting-start-page',
|
||||||
loadChildren: () => import('./pages/setting-start-page/setting-start-page.module').then(m => m.SettingStartPagePageModule)
|
loadChildren: () => import('./pages/setting-start-page/setting-start-page.module').then(m => m.SettingStartPagePageModule)
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { App } from '@capacitor/app';
|
|
||||||
import { SplashScreen } from '@capacitor/splash-screen';
|
|
||||||
import { Toast } from '@capacitor/toast';
|
|
||||||
import { Platform } from '@ionic/angular';
|
import { Platform } from '@ionic/angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { EnvService } from './services/env.service';
|
import { EnvService } from './services/env.service';
|
||||||
|
@ -20,29 +17,5 @@ export class AppComponent {
|
||||||
) {
|
) {
|
||||||
translate.addLangs(this.env.languages);
|
translate.addLangs(this.env.languages);
|
||||||
translate.setDefaultLang('en');
|
translate.setDefaultLang('en');
|
||||||
if (this.platform.is('ios')) {
|
|
||||||
App.addListener('appStateChange', async ({ isActive }) => {
|
|
||||||
if (env.isDebugging) {
|
|
||||||
this.presentToast(`App state changed. Is active?: ${isActive}`, "short", "bottom");
|
|
||||||
}
|
|
||||||
if (isActive) {
|
|
||||||
setTimeout(async () => {
|
|
||||||
await SplashScreen.hide();
|
|
||||||
}, 300);
|
|
||||||
} else {
|
|
||||||
await SplashScreen.show({
|
|
||||||
autoHide: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async presentToast(msg: string, duration: "short" | "long", pos: "top" | "center" | "bottom") {
|
|
||||||
await Toast.show({
|
|
||||||
text: msg,
|
|
||||||
duration: duration,
|
|
||||||
position: pos
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,14 @@ import { ScreenOrientation } from '@awesome-cordova-plugins/screen-orientation/n
|
||||||
|
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
|
import { HistoryTutorialPageModule } from './modals/history-tutorial/history-tutorial.module';
|
||||||
import { DatePipe } from '@angular/common';
|
import { DatePipe } from '@angular/common';
|
||||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { EnvService } from './services/env.service';
|
import { EnvService } from './services/env.service';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { BookmarkTutorialPageModule } from './modals/bookmark-tutorial/bookmark-tutorial.module';
|
||||||
import { QrCodePageModule } from './modals/qr-code/qr-code.module';
|
import { QrCodePageModule } from './modals/qr-code/qr-code.module';
|
||||||
|
|
||||||
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
||||||
|
@ -37,7 +39,7 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
IonicModule.forRoot({ innerHTMLTemplatesEnabled: true }),
|
IonicModule.forRoot(),
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
|
@ -49,6 +51,8 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
IonicStorageModule.forRoot(),
|
IonicStorageModule.forRoot(),
|
||||||
|
HistoryTutorialPageModule,
|
||||||
|
BookmarkTutorialPageModule,
|
||||||
QrCodePageModule,
|
QrCodePageModule,
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
|
|
40
src/app/modals/bookmark-tutorial/bookmark-tutorial.module.ts
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
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 {}
|
53
src/app/modals/bookmark-tutorial/bookmark-tutorial.page.html
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<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>
|
18
src/app/modals/bookmark-tutorial/bookmark-tutorial.page.scss
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
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;
|
||||||
|
}
|
65
src/app/modals/bookmark-tutorial/bookmark-tutorial.page.ts
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
39
src/app/modals/history-tutorial/history-tutorial.module.ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
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 {}
|
53
src/app/modals/history-tutorial/history-tutorial.page.html
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<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>
|
18
src/app/modals/history-tutorial/history-tutorial.page.scss
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
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;
|
||||||
|
}
|
65
src/app/modals/history-tutorial/history-tutorial.page.ts
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,7 +8,11 @@ import { QrCodePage } from './qr-code.page';
|
||||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||||
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { QRCodeModule } from 'angularx-qrcode';
|
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 { NgxQRCodeModule } from '@techiediaries/ngx-qrcode';
|
||||||
|
|
||||||
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
||||||
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
|
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
|
||||||
|
@ -19,7 +23,7 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
IonicModule,
|
IonicModule,
|
||||||
QRCodeModule,
|
NgxQRCodeModule,
|
||||||
TranslateModule.forChild({
|
TranslateModule.forChild({
|
||||||
loader: {
|
loader: {
|
||||||
provide: TranslateLoader,
|
provide: TranslateLoader,
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
<div class="d-flex align-items-center justify-content-top flex-column" style="height: 100%;">
|
<div class="d-flex align-items-center justify-content-top flex-column" style="height: 100%;">
|
||||||
<ion-row>
|
<ion-row>
|
||||||
<ion-col class="ion-text-center ion-padding" style="max-width: 100% !important;">
|
<ion-col class="ion-text-center ion-padding" style="max-width: 100% !important;">
|
||||||
<qrcode [elementType]="qrElementType" [qrdata]="qrCodeContent" [width]="defaultWidth"
|
<ngx-qrcode [elementType]="qrElementType" [value]="qrCodeContent" [width]="defaultWidth"
|
||||||
[errorCorrectionLevel]="errorCorrectionLevel" [colorDark]="qrColorDark" [colorLight]="qrColorLight"
|
[errorCorrectionLevel]="errorCorrectionLevel" [colorDark]="qrColorDark" [colorLight]="qrColorLight"
|
||||||
[margin]="env.qrCodeMargin" #qrcode [hidden]="isSharing">
|
[margin]="env.qrCodeMargin" #qrcode [hidden]="isSharing">
|
||||||
</qrcode>
|
</ngx-qrcode>
|
||||||
<div class="d-flex flex-column align-items-center" *ngIf="isSharing">
|
<div class="d-flex flex-column align-items-center" *ngIf="isSharing">
|
||||||
<ion-spinner class="my-3"></ion-spinner>
|
<ion-spinner class="my-3"></ion-spinner>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,11 +6,10 @@ import { Haptics, ImpactStyle } from '@capacitor/haptics';
|
||||||
import { Toast } from '@capacitor/toast';
|
import { Toast } from '@capacitor/toast';
|
||||||
import { LoadingController, ModalController, Platform } from '@ionic/angular';
|
import { LoadingController, ModalController, Platform } from '@ionic/angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { NgxQrcodeElementTypes, NgxQrcodeErrorCorrectionLevels, QrcodeComponent } from '@techiediaries/ngx-qrcode';
|
||||||
import { EnvService } from 'src/app/services/env.service';
|
import { EnvService } from 'src/app/services/env.service';
|
||||||
import { ScreenBrightness } from '@capacitor-community/screen-brightness';
|
import { ScreenBrightness } from '@capacitor-community/screen-brightness';
|
||||||
import { rgbToHex } from 'src/app/utils/helpers';
|
import { rgbToHex } from 'src/app/utils/helpers';
|
||||||
import { Preferences } from '@capacitor/preferences';
|
|
||||||
import { QRCodeComponent, QRCodeElementType } from 'angularx-qrcode';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-qr-code',
|
selector: 'app-qr-code',
|
||||||
|
@ -21,11 +20,11 @@ export class QrCodePage {
|
||||||
|
|
||||||
modal: HTMLIonModalElement;
|
modal: HTMLIonModalElement;
|
||||||
|
|
||||||
@ViewChild('qrcode') qrcodeElement: QRCodeComponent;
|
@ViewChild('qrcode') qrcodeElement: QrcodeComponent;
|
||||||
|
|
||||||
@Input() qrCodeContent: string;
|
@Input() qrCodeContent: string;
|
||||||
qrElementType: QRCodeElementType = "canvas";
|
qrElementType: NgxQrcodeElementTypes = NgxQrcodeElementTypes.CANVAS;
|
||||||
errorCorrectionLevel: 'low' | 'medium' | 'quartile' | 'high' | 'L' | 'M' | 'Q' | 'H';
|
errorCorrectionLevel: NgxQrcodeErrorCorrectionLevels;
|
||||||
scale: number = 0.8;
|
scale: number = 0.8;
|
||||||
readonly MAX_WIDTH = 350;
|
readonly MAX_WIDTH = 350;
|
||||||
defaultWidth: number = window.innerHeight * 0.32 > this.MAX_WIDTH ? this.MAX_WIDTH : window.innerHeight * 0.32;
|
defaultWidth: number = window.innerHeight * 0.32 > this.MAX_WIDTH ? this.MAX_WIDTH : window.innerHeight * 0.32;
|
||||||
|
@ -64,6 +63,7 @@ export class QrCodePage {
|
||||||
if (this.qrcodeElement.width > this.MAX_WIDTH) {
|
if (this.qrcodeElement.width > this.MAX_WIDTH) {
|
||||||
this.qrcodeElement.width = this.MAX_WIDTH;
|
this.qrcodeElement.width = this.MAX_WIDTH;
|
||||||
}
|
}
|
||||||
|
this.qrcodeElement.createQRCode();
|
||||||
}, 500)
|
}, 500)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@ export class QrCodePage {
|
||||||
if (this.qrcodeElement.width > this.MAX_WIDTH) {
|
if (this.qrcodeElement.width > this.MAX_WIDTH) {
|
||||||
this.qrcodeElement.width = this.MAX_WIDTH;
|
this.qrcodeElement.width = this.MAX_WIDTH;
|
||||||
}
|
}
|
||||||
|
this.qrcodeElement.createQRCode();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.modal.onDidDismiss().then(
|
this.modal.onDidDismiss().then(
|
||||||
|
@ -130,25 +131,25 @@ export class QrCodePage {
|
||||||
setErrorCorrectionLevel() {
|
setErrorCorrectionLevel() {
|
||||||
switch (this.env.errorCorrectionLevel) {
|
switch (this.env.errorCorrectionLevel) {
|
||||||
case 'L':
|
case 'L':
|
||||||
this.errorCorrectionLevel = 'low';
|
this.errorCorrectionLevel = NgxQrcodeErrorCorrectionLevels.LOW;
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
this.errorCorrectionLevel = 'medium';
|
this.errorCorrectionLevel = NgxQrcodeErrorCorrectionLevels.MEDIUM;
|
||||||
break;
|
break;
|
||||||
case 'Q':
|
case 'Q':
|
||||||
this.errorCorrectionLevel = 'quartile';
|
this.errorCorrectionLevel = NgxQrcodeErrorCorrectionLevels.QUARTILE;
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
this.errorCorrectionLevel = 'high';
|
this.errorCorrectionLevel = NgxQrcodeErrorCorrectionLevels.HIGH;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.errorCorrectionLevel = 'medium';
|
this.errorCorrectionLevel = NgxQrcodeErrorCorrectionLevels.MEDIUM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async onErrorCorrectionLevelChange() {
|
async onErrorCorrectionLevelChange() {
|
||||||
this.setErrorCorrectionLevel();
|
this.setErrorCorrectionLevel();
|
||||||
await Preferences.set({ key: this.env.KEY_ERROR_CORRECTION_LEVEL, value: this.env.errorCorrectionLevel });
|
await this.env.storageSet("error-correction-level", this.env.errorCorrectionLevel);
|
||||||
if (this.qrcodeElement != null) {
|
if (this.qrcodeElement != null) {
|
||||||
this.qrcodeElement.errorCorrectionLevel = this.errorCorrectionLevel;
|
this.qrcodeElement.errorCorrectionLevel = this.errorCorrectionLevel;
|
||||||
} else {
|
} else {
|
||||||
|
@ -168,6 +169,7 @@ export class QrCodePage {
|
||||||
this.isSharing = true;
|
this.isSharing = true;
|
||||||
const currentWidth = this.qrcodeElement.width;
|
const currentWidth = this.qrcodeElement.width;
|
||||||
this.qrcodeElement.width = 1000;
|
this.qrcodeElement.width = 1000;
|
||||||
|
this.qrcodeElement.createQRCode();
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
const canvases = document.querySelectorAll("canvas") as NodeListOf<HTMLCanvasElement>;
|
const canvases = document.querySelectorAll("canvas") as NodeListOf<HTMLCanvasElement>;
|
||||||
const canvas = canvases[canvases.length - 1];
|
const canvas = canvases[canvases.length - 1];
|
||||||
|
@ -180,6 +182,7 @@ export class QrCodePage {
|
||||||
await this.socialSharing.share(this.translate.instant('MSG.SHARE_QR'), this.translate.instant('SIMPLE_QR'), this.qrImageDataUrl, null).then(
|
await this.socialSharing.share(this.translate.instant('MSG.SHARE_QR'), this.translate.instant('SIMPLE_QR'), this.qrImageDataUrl, null).then(
|
||||||
_ => {
|
_ => {
|
||||||
this.qrcodeElement.width = currentWidth;
|
this.qrcodeElement.width = currentWidth;
|
||||||
|
this.qrcodeElement.createQRCode();
|
||||||
delete this.qrImageDataUrl;
|
delete this.qrImageDataUrl;
|
||||||
this.isSharing = false;
|
this.isSharing = false;
|
||||||
loading2.dismiss();
|
loading2.dismiss();
|
||||||
|
@ -190,6 +193,7 @@ export class QrCodePage {
|
||||||
this.presentToast("Error when call SocialSharing.share: " + JSON.stringify(err), "long", "top");
|
this.presentToast("Error when call SocialSharing.share: " + JSON.stringify(err), "long", "top");
|
||||||
}
|
}
|
||||||
this.qrcodeElement.width = currentWidth;
|
this.qrcodeElement.width = currentWidth;
|
||||||
|
this.qrcodeElement.createQRCode();
|
||||||
delete this.qrImageDataUrl;
|
delete this.qrImageDataUrl;
|
||||||
this.isSharing = false;
|
this.isSharing = false;
|
||||||
loading2.dismiss();
|
loading2.dismiss();
|
||||||
|
@ -237,7 +241,7 @@ export class QrCodePage {
|
||||||
|
|
||||||
async tapHaptic() {
|
async tapHaptic() {
|
||||||
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
|
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
|
||||||
await Haptics.impact({ style: ImpactStyle.Light })
|
await Haptics.impact({ style: ImpactStyle.Medium })
|
||||||
.catch(async err => {
|
.catch(async err => {
|
||||||
if (this.env.debugMode === 'on') {
|
if (this.env.debugMode === 'on') {
|
||||||
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
|
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<ion-header>
|
<ion-header>
|
||||||
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
|
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
|
||||||
<ion-buttons slot="start">
|
<ion-buttons slot="start">
|
||||||
<ion-back-button text="" defaultHref="tabs/setting">
|
<ion-back-button text="">
|
||||||
</ion-back-button>
|
</ion-back-button>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
<ion-title>{{ 'ABOUT' | translate }}</ion-title>
|
<ion-title>{{ 'ABOUT' | translate }}</ion-title>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { Preferences } from '@capacitor/preferences';
|
|
||||||
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';
|
||||||
|
@ -90,7 +89,7 @@ export class AboutPage {
|
||||||
if (this.env.debugMode != 'on') {
|
if (this.env.debugMode != 'on') {
|
||||||
if (this.tapAppVersionTimes >= 5) {
|
if (this.tapAppVersionTimes >= 5) {
|
||||||
this.env.debugMode = 'on';
|
this.env.debugMode = 'on';
|
||||||
await Preferences.set({ key: this.env.KEY_DEBUG_MODE, value: 'on' });
|
await this.env.storageSet("debug-mode-on", 'on');
|
||||||
await Toast.show({
|
await Toast.show({
|
||||||
text: this.translate.instant("MSG.DEBUG_MODE_ON"),
|
text: this.translate.instant("MSG.DEBUG_MODE_ON"),
|
||||||
duration: "short",
|
duration: "short",
|
||||||
|
|
|
@ -25,22 +25,20 @@
|
||||||
|
|
||||||
<ion-row class="ion-padding-horizontal">
|
<ion-row class="ion-padding-horizontal">
|
||||||
<ion-col>
|
<ion-col>
|
||||||
<mat-form-field [class]="ngMatThemeClass" color="accent" appearance="outline" [floatLabel]="'always'">
|
<mat-form-field [class]="ngMatThemeClass" color="accent" appearance="legacy">
|
||||||
<mat-label>{{ 'CONTENT_TYPE' | translate}}</mat-label>
|
<mat-label>{{ 'CONTENT_TYPE' | translate}}</mat-label>
|
||||||
<mat-select [(ngModel)]="contentType">
|
<mat-select [(ngModel)]="contentType">
|
||||||
<mat-select-trigger>
|
<mat-select-trigger>
|
||||||
<div class="d-flex">
|
<div style="display: flex; align-items: center;">
|
||||||
<mat-icon class="me-3" [fontIcon]="getIcon(contentType)">
|
<mat-icon style="margin-right: 16px; vertical-align: middle;">
|
||||||
|
{{ getIcon(contentType) }}
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
<span>{{ getText(contentType) }}</span>
|
<span>{{ getText(contentType) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</mat-select-trigger>
|
</mat-select-trigger>
|
||||||
<mat-option [value]="type.value" *ngFor="let type of contentTypes">
|
<mat-option [value]="type.value" *ngFor="let type of contentTypes">
|
||||||
<div class="d-flex">
|
<mat-icon>{{ getIcon(type.value) }}</mat-icon>
|
||||||
<mat-icon class="me-3" [fontIcon]="getIcon(type.value)">
|
<span>{{ type.text }}</span>
|
||||||
</mat-icon>
|
|
||||||
<span>{{ type.text }}</span>
|
|
||||||
</div>
|
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
@ -71,7 +69,7 @@
|
||||||
<mat-label>{{ 'EMAIL_RECIPIENT' | translate}}</mat-label>
|
<mat-label>{{ 'EMAIL_RECIPIENT' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="toEmails[i]" type="email" maxlength="254" #emailToInput>
|
<input matInput [(ngModel)]="toEmails[i]" type="email" maxlength="254" #emailToInput>
|
||||||
<mat-hint align="end">{{ emailToInput.value?.length || 0 }}/254</mat-hint>
|
<mat-hint align="end">{{ emailToInput.value?.length || 0 }}/254</mat-hint>
|
||||||
<mat-icon matSuffix color="accent" fontIcon="alternate_email"></mat-icon>
|
<mat-icon matSuffix color="accent">alternate_email</mat-icon>
|
||||||
<mat-hint>{{'MSG.EMAIL_MAX_LENGTH' | translate}}</mat-hint>
|
<mat-hint>{{'MSG.EMAIL_MAX_LENGTH' | translate}}</mat-hint>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
|
@ -100,7 +98,7 @@
|
||||||
<mat-label>{{ 'CC' | translate}}</mat-label>
|
<mat-label>{{ 'CC' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="ccEmails[i]" type="email" maxlength="254" #emailCcInput>
|
<input matInput [(ngModel)]="ccEmails[i]" type="email" maxlength="254" #emailCcInput>
|
||||||
<mat-hint align="end">{{ emailCcInput.value?.length || 0 }}/254</mat-hint>
|
<mat-hint align="end">{{ emailCcInput.value?.length || 0 }}/254</mat-hint>
|
||||||
<mat-icon matSuffix color="accent" fontIcon="alternate_email"></mat-icon>
|
<mat-icon matSuffix color="accent">alternate_email</mat-icon>
|
||||||
<mat-hint>{{'MSG.EMAIL_MAX_LENGTH' | translate}}</mat-hint>
|
<mat-hint>{{'MSG.EMAIL_MAX_LENGTH' | translate}}</mat-hint>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
|
@ -129,7 +127,7 @@
|
||||||
<mat-label>{{ 'BCC' | translate}}</mat-label>
|
<mat-label>{{ 'BCC' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="bccEmails[i]" type="email" maxlength="254" #emailBccInput>
|
<input matInput [(ngModel)]="bccEmails[i]" type="email" maxlength="254" #emailBccInput>
|
||||||
<mat-hint align="end">{{ emailBccInput.value?.length || 0 }}/254</mat-hint>
|
<mat-hint align="end">{{ emailBccInput.value?.length || 0 }}/254</mat-hint>
|
||||||
<mat-icon matSuffix color="accent" fontIcon="alternate_email"></mat-icon>
|
<mat-icon matSuffix color="accent">alternate_email</mat-icon>
|
||||||
<mat-hint>{{'MSG.EMAIL_MAX_LENGTH' | translate}}</mat-hint>
|
<mat-hint>{{'MSG.EMAIL_MAX_LENGTH' | translate}}</mat-hint>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
|
@ -184,7 +182,7 @@
|
||||||
<mat-label>{{ 'EMAIL_RECIPIENT' | translate}}</mat-label>
|
<mat-label>{{ 'EMAIL_RECIPIENT' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="toEmails[0]" type="email" maxlength="254" #emailToInput>
|
<input matInput [(ngModel)]="toEmails[0]" type="email" maxlength="254" #emailToInput>
|
||||||
<mat-hint align="end">{{ emailToInput.value?.length || 0 }}/254</mat-hint>
|
<mat-hint align="end">{{ emailToInput.value?.length || 0 }}/254</mat-hint>
|
||||||
<mat-icon matSuffix color="accent" fontIcon="alternate_email"></mat-icon>
|
<mat-icon matSuffix color="accent">alternate_email</mat-icon>
|
||||||
<mat-hint>{{'MSG.EMAIL_MAX_LENGTH' | translate}}</mat-hint>
|
<mat-hint>{{'MSG.EMAIL_MAX_LENGTH' | translate}}</mat-hint>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
|
@ -215,32 +213,13 @@
|
||||||
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngIf="contentType === 'geo'">
|
|
||||||
<ion-row class="ion-padding-horizontal" [@inAnimation]>
|
|
||||||
<ion-col>
|
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
|
||||||
<mat-label>{{ 'LATITUDE' | translate}}</mat-label>
|
|
||||||
<input matInput [(ngModel)]="latitude" type="number" #latitudeInput>
|
|
||||||
</mat-form-field>
|
|
||||||
</ion-col>
|
|
||||||
</ion-row>
|
|
||||||
<ion-row class="ion-padding-horizontal" [@inAnimation]>
|
|
||||||
<ion-col>
|
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
|
||||||
<mat-label>{{ 'LONGITUDE' | translate}}</mat-label>
|
|
||||||
<input matInput [(ngModel)]="longitude" type="number" #longitudeInput>
|
|
||||||
</mat-form-field>
|
|
||||||
</ion-col>
|
|
||||||
</ion-row>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container *ngIf="contentType === 'phone'">
|
<ng-container *ngIf="contentType === 'phone'">
|
||||||
<ion-row class="ion-padding-horizontal" [@inAnimation]>
|
<ion-row class="ion-padding-horizontal" [@inAnimation]>
|
||||||
<ion-col>
|
<ion-col>
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'PHONE_NUMBER' | translate}}</mat-label>
|
<mat-label>{{ 'PHONE_NUMBER' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="phoneNumber" type="tel" #phoneNumberInput>
|
<input matInput [(ngModel)]="phoneNumber" type="tel" #phoneNumberInput>
|
||||||
<mat-icon matSuffix color="accent" fontIcon="call"></mat-icon>
|
<mat-icon matSuffix color="accent">call</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -252,7 +231,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'PHONE_NUMBER' | translate}}</mat-label>
|
<mat-label>{{ 'PHONE_NUMBER' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="phoneNumber" type="tel" #phoneNumberInput>
|
<input matInput [(ngModel)]="phoneNumber" type="tel" #phoneNumberInput>
|
||||||
<mat-icon matSuffix color="accent" fontIcon="call"></mat-icon>
|
<mat-icon matSuffix color="accent">call</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -275,7 +254,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'URL' | translate}}</mat-label>
|
<mat-label>{{ 'URL' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="url" type="url" #urlInput maxlength="1817">
|
<input matInput [(ngModel)]="url" type="url" #urlInput maxlength="1817">
|
||||||
<mat-icon matSuffix color="accent" fontIcon="link"></mat-icon>
|
<mat-icon matSuffix color="accent">link</mat-icon>
|
||||||
<mat-hint align="end">{{ (urlInput.value?.length) || 0 }}/1817</mat-hint>
|
<mat-hint align="end">{{ (urlInput.value?.length) || 0 }}/1817</mat-hint>
|
||||||
<mat-hint>{{'MSG.CREATE_QRCODE_MAX_LENGTH' | translate}}</mat-hint>
|
<mat-hint>{{'MSG.CREATE_QRCODE_MAX_LENGTH' | translate}}</mat-hint>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
@ -299,7 +278,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'FIRST_NAME' | translate}}</mat-label>
|
<mat-label>{{ 'FIRST_NAME' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="firstName" #firstNameInput />
|
<input matInput [(ngModel)]="firstName" #firstNameInput />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="badge"></mat-icon>
|
<mat-icon matSuffix color="accent">badge</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -308,7 +287,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'LAST_NAME' | translate}}</mat-label>
|
<mat-label>{{ 'LAST_NAME' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="lastName" #lastNameInput />
|
<input matInput [(ngModel)]="lastName" #lastNameInput />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="badge"></mat-icon>
|
<mat-icon matSuffix color="accent">badge</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -327,7 +306,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'MOBILE_PHONE_NUMBER' | translate}}</mat-label>
|
<mat-label>{{ 'MOBILE_PHONE_NUMBER' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="mobilePhoneNumber" #mobilePhoneInput type="tel" />
|
<input matInput [(ngModel)]="mobilePhoneNumber" #mobilePhoneInput type="tel" />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="call"></mat-icon>
|
<mat-icon matSuffix color="accent">call</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -336,7 +315,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'HOME_PHONE_NUMBER' | translate}}</mat-label>
|
<mat-label>{{ 'HOME_PHONE_NUMBER' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="homePhoneNumber" #homePhoneInput type="tel" />
|
<input matInput [(ngModel)]="homePhoneNumber" #homePhoneInput type="tel" />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="call"></mat-icon>
|
<mat-icon matSuffix color="accent">call</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -345,7 +324,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'WORK_PHONE_NUMBER' | translate}}</mat-label>
|
<mat-label>{{ 'WORK_PHONE_NUMBER' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="workPhoneNumber" #workPhoneInput type="tel" />
|
<input matInput [(ngModel)]="workPhoneNumber" #workPhoneInput type="tel" />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="call"></mat-icon>
|
<mat-icon matSuffix color="accent">call</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -354,7 +333,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'FAX_NUMBER' | translate}}</mat-label>
|
<mat-label>{{ 'FAX_NUMBER' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="faxNumber" #faxInput type="tel" />
|
<input matInput [(ngModel)]="faxNumber" #faxInput type="tel" />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="print"></mat-icon>
|
<mat-icon matSuffix color="accent">print</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -363,7 +342,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'EMAIL_ADDRESS' | translate}}</mat-label>
|
<mat-label>{{ 'EMAIL_ADDRESS' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="email" #emailInput type="email" />
|
<input matInput [(ngModel)]="email" #emailInput type="email" />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="alternate_email"></mat-icon>
|
<mat-icon matSuffix color="accent">alternate_email</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -382,7 +361,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'ORGANIZATION' | translate}}</mat-label>
|
<mat-label>{{ 'ORGANIZATION' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="organization" #organizationInput type="text" />
|
<input matInput [(ngModel)]="organization" #organizationInput type="text" />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="business"></mat-icon>
|
<mat-icon matSuffix color="accent">business</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -391,7 +370,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'JOB_TITLE' | translate}}</mat-label>
|
<mat-label>{{ 'JOB_TITLE' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="jobTitle" #jobTitleInput type="text" />
|
<input matInput [(ngModel)]="jobTitle" #jobTitleInput type="text" />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="business"></mat-icon>
|
<mat-icon matSuffix color="accent">business</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -410,7 +389,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'STREET' | translate}}</mat-label>
|
<mat-label>{{ 'STREET' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="street" #streetInput type="text" />
|
<input matInput [(ngModel)]="street" #streetInput type="text" />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="home"></mat-icon>
|
<mat-icon matSuffix color="accent">home</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -419,7 +398,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'CITY' | translate}}</mat-label>
|
<mat-label>{{ 'CITY' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="city" #cityInput type="text" />
|
<input matInput [(ngModel)]="city" #cityInput type="text" />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="home"></mat-icon>
|
<mat-icon matSuffix color="accent">home</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -428,7 +407,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'STATE' | translate}}</mat-label>
|
<mat-label>{{ 'STATE' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="state" #stateInput type="text" />
|
<input matInput [(ngModel)]="state" #stateInput type="text" />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="home"></mat-icon>
|
<mat-icon matSuffix color="accent">home</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -437,7 +416,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'POSTAL_CODE' | translate}}</mat-label>
|
<mat-label>{{ 'POSTAL_CODE' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="postalCode" #postalCodeInput type="text" />
|
<input matInput [(ngModel)]="postalCode" #postalCodeInput type="text" />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="home"></mat-icon>
|
<mat-icon matSuffix color="accent">home</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -446,7 +425,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'COUNTRY' | translate}}</mat-label>
|
<mat-label>{{ 'COUNTRY' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="country" #countryInput type="text" />
|
<input matInput [(ngModel)]="country" #countryInput type="text" />
|
||||||
<mat-icon matSuffix color="accent" fontIcon="home"></mat-icon>
|
<mat-icon matSuffix color="accent">home</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -466,7 +445,7 @@
|
||||||
<mat-label>{{ 'DATE_OF_BIRTH' | translate}}</mat-label>
|
<mat-label>{{ 'DATE_OF_BIRTH' | translate}}</mat-label>
|
||||||
<input [ngModel]="birthday | date:'yyyy-MM-dd'" (ngModelChange)="birthday = $event" matInput type="date"
|
<input [ngModel]="birthday | date:'yyyy-MM-dd'" (ngModelChange)="birthday = $event" matInput type="date"
|
||||||
[max]="today">
|
[max]="today">
|
||||||
<mat-icon matSuffix color="accent" fontIcon="cake"></mat-icon>
|
<mat-icon matSuffix color="accent">cake</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -487,7 +466,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'WEBSITE' | translate}}</mat-label>
|
<mat-label>{{ 'WEBSITE' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="personalUrl" type="url" #personalUrlInput>
|
<input matInput [(ngModel)]="personalUrl" type="url" #personalUrlInput>
|
||||||
<mat-icon matSuffix color="accent" fontIcon="link"></mat-icon>
|
<mat-icon matSuffix color="accent">link</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
@ -499,7 +478,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'WIFI_SSID' | translate}}</mat-label>
|
<mat-label>{{ 'WIFI_SSID' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="ssid" #ssidInput maxlength="32">
|
<input matInput [(ngModel)]="ssid" #ssidInput maxlength="32">
|
||||||
<mat-icon matSuffix color="accent" fontIcon="wifi"></mat-icon>
|
<mat-icon matSuffix color="accent">wifi</mat-icon>
|
||||||
<mat-hint align="end">{{ (ssidInput.value?.length) || 0 }}/32</mat-hint>
|
<mat-hint align="end">{{ (ssidInput.value?.length) || 0 }}/32</mat-hint>
|
||||||
<mat-hint>{{'MSG.SSID_MAX_LENGTH' | translate}}</mat-hint>
|
<mat-hint>{{'MSG.SSID_MAX_LENGTH' | translate}}</mat-hint>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
@ -510,7 +489,7 @@
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent">
|
||||||
<mat-label>{{ 'PASSWORD' | translate}}</mat-label>
|
<mat-label>{{ 'PASSWORD' | translate}}</mat-label>
|
||||||
<input matInput [(ngModel)]="wifiPassword" #wifiPasswordInput type="password">
|
<input matInput [(ngModel)]="wifiPassword" #wifiPasswordInput type="password">
|
||||||
<mat-icon matSuffix color="accent" fontIcon="lock"></mat-icon>
|
<mat-icon matSuffix color="accent">lock</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
|
|
@ -4,8 +4,8 @@ import { Router } from '@angular/router';
|
||||||
import { Haptics, ImpactStyle, NotificationType } from '@capacitor/haptics';
|
import { Haptics, ImpactStyle, NotificationType } from '@capacitor/haptics';
|
||||||
import { AlertController, LoadingController, ToastController } from '@ionic/angular';
|
import { AlertController, LoadingController, ToastController } from '@ionic/angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { format } from 'date-fns';
|
import * as moment from 'moment';
|
||||||
import { EnvService, QrCreateContentTypeType } from 'src/app/services/env.service';
|
import { EnvService } from 'src/app/services/env.service';
|
||||||
import { Toast } from '@capacitor/toast';
|
import { Toast } from '@capacitor/toast';
|
||||||
import { fadeIn } from 'src/app/utils/animations';
|
import { fadeIn } from 'src/app/utils/animations';
|
||||||
import { SplashScreen } from '@capacitor/splash-screen';
|
import { SplashScreen } from '@capacitor/splash-screen';
|
||||||
|
@ -23,7 +23,6 @@ export class GeneratePage {
|
||||||
freeTxtText: string = "Free Text";
|
freeTxtText: string = "Free Text";
|
||||||
urlText: string = "URL";
|
urlText: string = "URL";
|
||||||
contactText: string = "vCard Contact";
|
contactText: string = "vCard Contact";
|
||||||
geolocationText: string = "Geolocation";
|
|
||||||
phoneText: string = "Phone";
|
phoneText: string = "Phone";
|
||||||
smsText: string = "Message";
|
smsText: string = "Message";
|
||||||
emailW3CText: string = "Email (W3C Standard)";
|
emailW3CText: string = "Email (W3C Standard)";
|
||||||
|
@ -38,9 +37,6 @@ export class GeneratePage {
|
||||||
emailSubject: string = "";
|
emailSubject: string = "";
|
||||||
emailBody: string = "";
|
emailBody: string = "";
|
||||||
|
|
||||||
latitude: number = 0;
|
|
||||||
longitude: number = 0;
|
|
||||||
|
|
||||||
phoneNumber: string = "";
|
phoneNumber: string = "";
|
||||||
|
|
||||||
smsMessage: string = "";
|
smsMessage: string = "";
|
||||||
|
@ -61,7 +57,7 @@ export class GeneratePage {
|
||||||
state: string = "";
|
state: string = "";
|
||||||
postalCode: string = "";
|
postalCode: string = "";
|
||||||
country: string = "";
|
country: string = "";
|
||||||
birthday: string;
|
birthday: Date;
|
||||||
gender: "M" | "F" | "O" = "O";
|
gender: "M" | "F" | "O" = "O";
|
||||||
personalUrl: string = "";
|
personalUrl: string = "";
|
||||||
|
|
||||||
|
@ -88,18 +84,17 @@ export class GeneratePage {
|
||||||
{ text: this.wpaText, value: "WPA" },
|
{ text: this.wpaText, value: "WPA" },
|
||||||
]
|
]
|
||||||
|
|
||||||
contentTypes: { text: string, value: QrCreateContentTypeType }[] = [
|
contentTypes: { text: string, value: "freeText" | "url" | "contact" | "phone" | "sms" | "emailW3C" | "emailDocomo" | "wifi" }[] = [
|
||||||
{ text: this.freeTxtText, value: 'freeText' },
|
{ text: this.freeTxtText, value: 'freeText' },
|
||||||
{ text: this.emailW3CText, value: 'emailW3C' },
|
{ text: this.emailW3CText, value: 'emailW3C' },
|
||||||
{ text: this.emailDocomoText, value: 'emailDocomo' },
|
{ text: this.emailDocomoText, value: 'emailDocomo' },
|
||||||
{ text: this.geolocationText, value: 'geo' },
|
|
||||||
{ text: this.phoneText, value: 'phone' },
|
{ text: this.phoneText, value: 'phone' },
|
||||||
{ text: this.smsText, value: 'sms' },
|
{ text: this.smsText, value: 'sms' },
|
||||||
{ text: this.urlText, value: 'url' },
|
{ text: this.urlText, value: 'url' },
|
||||||
{ text: this.contactText, value: 'contact' },
|
{ text: this.contactText, value: 'contact' },
|
||||||
{ text: this.wifiText, value: 'wifi' },
|
{ text: this.wifiText, value: 'wifi' },
|
||||||
];
|
];
|
||||||
contentType: QrCreateContentTypeType = "freeText";
|
contentType: "freeText" | "url" | "contact" | "phone" | "sms" | "emailW3C" | "emailDocomo" | "wifi" = "freeText";
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public translate: TranslateService,
|
public translate: TranslateService,
|
||||||
|
@ -111,14 +106,9 @@ export class GeneratePage {
|
||||||
|
|
||||||
async ionViewDidEnter() {
|
async ionViewDidEnter() {
|
||||||
await SplashScreen.hide()
|
await SplashScreen.hide()
|
||||||
if (this.env.editingContent) {
|
|
||||||
this.qrCodeContent = this.env.resultContent;
|
|
||||||
this.env.editingContent = false;
|
|
||||||
}
|
|
||||||
this.freeTxtText = this.translate.instant("FREE_TEXT");
|
this.freeTxtText = this.translate.instant("FREE_TEXT");
|
||||||
this.urlText = this.translate.instant("URL");
|
this.urlText = this.translate.instant("URL");
|
||||||
this.contactText = this.translate.instant("VCARD_CONTACT");
|
this.contactText = this.translate.instant("VCARD_CONTACT");
|
||||||
this.geolocationText = this.translate.instant("GEOLOCATION");
|
|
||||||
this.phoneText = this.translate.instant("PHONE_NO");
|
this.phoneText = this.translate.instant("PHONE_NO");
|
||||||
this.smsText = this.translate.instant("MESSAGE");
|
this.smsText = this.translate.instant("MESSAGE");
|
||||||
this.emailW3CText = this.translate.instant("EMAIL_W3C_STANDARD");
|
this.emailW3CText = this.translate.instant("EMAIL_W3C_STANDARD");
|
||||||
|
@ -128,7 +118,6 @@ export class GeneratePage {
|
||||||
{ text: this.freeTxtText, value: 'freeText' },
|
{ text: this.freeTxtText, value: 'freeText' },
|
||||||
{ text: this.emailW3CText, value: 'emailW3C' },
|
{ text: this.emailW3CText, value: 'emailW3C' },
|
||||||
{ text: this.emailDocomoText, value: 'emailDocomo' },
|
{ text: this.emailDocomoText, value: 'emailDocomo' },
|
||||||
{ text: this.geolocationText, value: 'geo' },
|
|
||||||
{ text: this.phoneText, value: 'phone' },
|
{ text: this.phoneText, value: 'phone' },
|
||||||
{ text: this.smsText, value: 'sms' },
|
{ text: this.smsText, value: 'sms' },
|
||||||
{ text: this.urlText, value: 'url' },
|
{ text: this.urlText, value: 'url' },
|
||||||
|
@ -202,9 +191,6 @@ export class GeneratePage {
|
||||||
this.emailSubject = "";
|
this.emailSubject = "";
|
||||||
this.emailBody = "";
|
this.emailBody = "";
|
||||||
|
|
||||||
this.latitude = 0;
|
|
||||||
this.longitude = 0;
|
|
||||||
|
|
||||||
this.phoneNumber = "";
|
this.phoneNumber = "";
|
||||||
|
|
||||||
this.smsMessage = "";
|
this.smsMessage = "";
|
||||||
|
@ -273,9 +259,6 @@ export class GeneratePage {
|
||||||
this.qrCodeContent = `MATMSG:TO:${this.toEmails[0]};SUB:${this.emailSubject};BODY:${this.emailBody};;`;
|
this.qrCodeContent = `MATMSG:TO:${this.toEmails[0]};SUB:${this.emailSubject};BODY:${this.emailBody};;`;
|
||||||
this.qrCodeContent = encodeURI(this.qrCodeContent);
|
this.qrCodeContent = encodeURI(this.qrCodeContent);
|
||||||
break;
|
break;
|
||||||
case "geo":
|
|
||||||
this.qrCodeContent = `geo:${this.latitude},${this.longitude}`;
|
|
||||||
break;
|
|
||||||
case "phone":
|
case "phone":
|
||||||
this.qrCodeContent = "tel:";
|
this.qrCodeContent = "tel:";
|
||||||
this.qrCodeContent += this.phoneNumber;
|
this.qrCodeContent += this.phoneNumber;
|
||||||
|
@ -312,8 +295,8 @@ export class GeneratePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async processQrCode(loading: HTMLIonLoadingElement): Promise<void> {
|
async processQrCode(loading: HTMLIonLoadingElement): Promise<void> {
|
||||||
this.env.resultContent = this.qrCodeContent;
|
this.env.result = this.qrCodeContent;
|
||||||
this.env.resultContentFormat = "";
|
this.env.resultFormat = "";
|
||||||
this.qrCodeContent = '';
|
this.qrCodeContent = '';
|
||||||
this.env.recordSource = "create";
|
this.env.recordSource = "create";
|
||||||
this.env.detailedRecordSource = "create";
|
this.env.detailedRecordSource = "create";
|
||||||
|
@ -337,10 +320,9 @@ export class GeneratePage {
|
||||||
vCard += `ORG:${this.organization.trim()}\n`;
|
vCard += `ORG:${this.organization.trim()}\n`;
|
||||||
vCard += `TITLE:${this.jobTitle.trim()}\n`;
|
vCard += `TITLE:${this.jobTitle.trim()}\n`;
|
||||||
vCard += `ADR:;;${this.street.trim()};${this.city.trim()};${this.state.trim()};${this.postalCode.trim()};${this.country.trim()}\n`;
|
vCard += `ADR:;;${this.street.trim()};${this.city.trim()};${this.state.trim()};${this.postalCode.trim()};${this.country.trim()}\n`;
|
||||||
if (this.birthday != null) {
|
console.log("birthday => " + this.birthday)
|
||||||
const find = '-';
|
if (this.birthday && this.birthday !== null && this.birthday !== undefined) {
|
||||||
const re = new RegExp(find, 'g');
|
vCard += `BDAY:${moment(this.birthday).format('YYYYMMDD')}\n`;
|
||||||
vCard += `BDAY:${this.birthday.replace(re, "")}\n`;
|
|
||||||
}
|
}
|
||||||
vCard += `URL:${this.personalUrl.trim()}\n`;
|
vCard += `URL:${this.personalUrl.trim()}\n`;
|
||||||
vCard += `GENDER:${this.gender}\n`;
|
vCard += `GENDER:${this.gender}\n`;
|
||||||
|
@ -358,10 +340,10 @@ export class GeneratePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
get today() {
|
get today() {
|
||||||
return format(new Date(), "yyyy-MM-dd");
|
return moment().format("YYYY-MM-DD");
|
||||||
}
|
}
|
||||||
|
|
||||||
getIcon(type: QrCreateContentTypeType): string {
|
getIcon(type: "freeText" | "url" | "contact" | "phone" | "sms" | "emailW3C" | "emailDocomo" | "wifi"): string {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "freeText":
|
case "freeText":
|
||||||
return "format_align_left";
|
return "format_align_left";
|
||||||
|
@ -369,8 +351,6 @@ export class GeneratePage {
|
||||||
return "link";
|
return "link";
|
||||||
case "contact":
|
case "contact":
|
||||||
return "contact_phone";
|
return "contact_phone";
|
||||||
case "geo":
|
|
||||||
return "location_on";
|
|
||||||
case "phone":
|
case "phone":
|
||||||
return "call";
|
return "call";
|
||||||
case "sms":
|
case "sms":
|
||||||
|
@ -386,7 +366,7 @@ export class GeneratePage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getText(type: QrCreateContentTypeType): string {
|
getText(type: "freeText" | "url" | "contact" | "phone" | "sms" | "emailW3C" | "emailDocomo" | "wifi"): string {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "freeText":
|
case "freeText":
|
||||||
return this.freeTxtText;
|
return this.freeTxtText;
|
||||||
|
@ -394,8 +374,6 @@ export class GeneratePage {
|
||||||
return this.urlText;
|
return this.urlText;
|
||||||
case "contact":
|
case "contact":
|
||||||
return this.contactText;
|
return this.contactText;
|
||||||
case "geo":
|
|
||||||
return this.geolocationText;
|
|
||||||
case "phone":
|
case "phone":
|
||||||
return this.phoneText;
|
return this.phoneText;
|
||||||
case "sms":
|
case "sms":
|
||||||
|
@ -464,7 +442,7 @@ export class GeneratePage {
|
||||||
|
|
||||||
async tapHaptic() {
|
async tapHaptic() {
|
||||||
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
|
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
|
||||||
await Haptics.impact({ style: ImpactStyle.Light })
|
await Haptics.impact({ style: ImpactStyle.Medium })
|
||||||
.catch(async err => {
|
.catch(async err => {
|
||||||
if (this.env.debugMode === 'on') {
|
if (this.env.debugMode === 'on') {
|
||||||
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
|
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<ion-title>{{ 'SIMPLE_QR' | translate}}</ion-title>
|
<ion-title>{{ 'SIMPLE_QR' | translate}}</ion-title>
|
||||||
<ion-buttons slot="end">
|
<ion-buttons slot="end">
|
||||||
<ion-button (click)="tapHaptic(); goSetting()" fill="clear">
|
<ion-button (click)="tapHaptic(); goSetting()" fill="clear">
|
||||||
{{ 'MORE' | translate }}
|
{{ 'SETTING' | translate }}
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
<ion-title *ngIf="segmentModel === 'bookmarks'">{{ 'BOOKMARKS' | translate }}</ion-title>
|
<ion-title *ngIf="segmentModel === 'bookmarks'">{{ 'BOOKMARKS' | translate }}</ion-title>
|
||||||
<ion-buttons slot="end">
|
<ion-buttons slot="end">
|
||||||
<ion-button (click)="tapHaptic(); goSetting()" fill="clear" color="primary">
|
<ion-button (click)="tapHaptic(); goSetting()" fill="clear" color="primary">
|
||||||
{{ 'MORE' | translate }}
|
{{ 'SETTING' | translate }}
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
|
@ -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="none" *ngIf="env.showNumberOfRecords == 'on'">
|
<ion-list-header class="ion-padding-horizontal" lines="full">
|
||||||
<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>
|
||||||
|
|
|
@ -2,13 +2,14 @@ import { ChangeDetectorRef, Component } from '@angular/core';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { AlertController, IonItemSliding, LoadingController, ModalController, PopoverController, ToastController } from '@ionic/angular';
|
import { AlertController, IonItemSliding, LoadingController, ModalController, PopoverController, ToastController } from '@ionic/angular';
|
||||||
import { EnvService } from 'src/app/services/env.service';
|
import { EnvService } from 'src/app/services/env.service';
|
||||||
import { format, Locale } from 'date-fns';
|
import * as moment from 'moment';
|
||||||
import { de, enUS, fr, it, ptBR, ru, zhCN, zhHK } from 'date-fns/locale';
|
|
||||||
import { ScanRecord } from 'src/app/models/scan-record';
|
import { ScanRecord } from 'src/app/models/scan-record';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { Bookmark } from 'src/app/models/bookmark';
|
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 { Haptics, ImpactStyle } from '@capacitor/haptics';
|
||||||
import { Toast } from '@capacitor/toast';
|
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 { fastFadeIn, flyOut } from 'src/app/utils/animations';
|
||||||
import { SplashScreen } from '@capacitor/splash-screen';
|
import { SplashScreen } from '@capacitor/splash-screen';
|
||||||
|
|
||||||
|
@ -98,6 +99,19 @@ export class HistoryPage {
|
||||||
async ionViewDidEnter() {
|
async ionViewDidEnter() {
|
||||||
await SplashScreen.hide()
|
await SplashScreen.hide()
|
||||||
this.segmentModel = this.env.historyPageStartSegment;
|
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() {
|
ionViewWillLeave() {
|
||||||
|
@ -120,46 +134,41 @@ export class HistoryPage {
|
||||||
return bookmark.id;
|
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 {
|
maskDatetimeAndSource(date: Date, source: 'create' | 'view' | 'scan' | undefined): string {
|
||||||
if (!date) {
|
if (!date) {
|
||||||
return "-";
|
return "-";
|
||||||
}
|
}
|
||||||
let locale: Locale;
|
const momentObj = moment(date);
|
||||||
switch (this.env.language) {
|
if (this.env.language != 'en') {
|
||||||
case "de":
|
momentObj.locale(this.env.language.toLowerCase());
|
||||||
locale = de;
|
|
||||||
break;
|
|
||||||
case "en":
|
|
||||||
locale = enUS;
|
|
||||||
break;
|
|
||||||
case "fr":
|
|
||||||
locale = fr;
|
|
||||||
break;
|
|
||||||
case "it":
|
|
||||||
locale = it;
|
|
||||||
break;
|
|
||||||
case "pt-BR":
|
|
||||||
locale = ptBR;
|
|
||||||
break;
|
|
||||||
case "ru":
|
|
||||||
locale = ru;
|
|
||||||
break;
|
|
||||||
case "zh-CN":
|
|
||||||
locale = zhCN;
|
|
||||||
break;
|
|
||||||
case "zh-HK":
|
|
||||||
locale = zhHK;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
locale = enUS;
|
|
||||||
}
|
}
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case 'create':
|
case 'create':
|
||||||
return `${this.translate.instant("CREATED")} ${this.translate.instant("AT")} ${format(date, "PP pp", { locale: locale })}`;
|
return `${this.translate.instant("CREATED")} ${this.translate.instant("AT")} ${momentObj.format("ll LTS")}`;
|
||||||
case 'view':
|
case 'view':
|
||||||
return `${this.translate.instant("VIEWED")} ${this.translate.instant("AT")} ${format(date, "PP pp", { locale: locale })}`;
|
return `${this.translate.instant("VIEWED")} ${this.translate.instant("AT")} ${momentObj.format("ll LTS")}`;
|
||||||
case 'scan':
|
case 'scan':
|
||||||
return `${this.translate.instant("SCANNED")} ${this.translate.instant("AT")} ${format(date, "PP pp", { locale: locale })}`;
|
return `${this.translate.instant("SCANNED")} ${this.translate.instant("AT")} ${momentObj.format("ll LTS")}`;
|
||||||
|
default:
|
||||||
|
return momentObj.format("ll LTS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +213,7 @@ export class HistoryPage {
|
||||||
case "RSS_EXPANDED":
|
case "RSS_EXPANDED":
|
||||||
return this.translate.instant("BARCODE_TYPE.RSS").trim();
|
return this.translate.instant("BARCODE_TYPE.RSS").trim();
|
||||||
default:
|
default:
|
||||||
return this.env.resultContentFormat;
|
return this.env.resultFormat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,8 +225,8 @@ export class HistoryPage {
|
||||||
this.changeDetectorRef.detectChanges();
|
this.changeDetectorRef.detectChanges();
|
||||||
this.changeDetectorRef.reattach();
|
this.changeDetectorRef.reattach();
|
||||||
const loading = await this.presentLoading(this.translate.instant('PLEASE_WAIT'));
|
const loading = await this.presentLoading(this.translate.instant('PLEASE_WAIT'));
|
||||||
this.env.resultContent = data;
|
this.env.result = data;
|
||||||
this.env.resultContentFormat = "";
|
this.env.resultFormat = "";
|
||||||
this.env.recordSource = "view";
|
this.env.recordSource = "view";
|
||||||
this.env.detailedRecordSource = source;
|
this.env.detailedRecordSource = source;
|
||||||
this.env.viewResultFrom = "/tabs/history";
|
this.env.viewResultFrom = "/tabs/history";
|
||||||
|
@ -229,6 +238,19 @@ export class HistoryPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async segmentChanged(ev: any) {
|
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();
|
this.firstLoadItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +530,7 @@ export class HistoryPage {
|
||||||
|
|
||||||
async tapHaptic() {
|
async tapHaptic() {
|
||||||
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
|
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
|
||||||
await Haptics.impact({ style: ImpactStyle.Light })
|
await Haptics.impact({ style: ImpactStyle.Medium })
|
||||||
.catch(async err => {
|
.catch(async err => {
|
||||||
if (this.env.debugMode === 'on') {
|
if (this.env.debugMode === 'on') {
|
||||||
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
|
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { ImportImagePageRoutingModule } from './import-image-routing.module';
|
||||||
import { ImportImagePage } from './import-image.page';
|
import { ImportImagePage } from './import-image.page';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||||
|
|
||||||
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
||||||
|
@ -28,6 +29,7 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
ImportImagePageRoutingModule,
|
ImportImagePageRoutingModule,
|
||||||
|
MatButtonModule,
|
||||||
],
|
],
|
||||||
declarations: [ImportImagePage]
|
declarations: [ImportImagePage]
|
||||||
})
|
})
|
||||||
|
|
|
@ -96,21 +96,13 @@ export class ImportImagePage {
|
||||||
});
|
});
|
||||||
await alert.present();
|
await alert.present();
|
||||||
}
|
}
|
||||||
},
|
|
||||||
async err => {
|
|
||||||
getPictureLoading.dismiss();
|
|
||||||
if (this.env.debugMode === 'on') {
|
|
||||||
await Toast.show({ text: 'Err when Camera.requestPermissions: ' + JSON.stringify(err), position: "bottom", duration: "long" })
|
|
||||||
} else {
|
|
||||||
Toast.show({ text: 'Unknown Error', position: "bottom", duration: "short" })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async processQrCode(scannedData: string, loading: HTMLIonLoadingElement): Promise<void> {
|
async processQrCode(scannedData: string, loading: HTMLIonLoadingElement): Promise<void> {
|
||||||
this.env.resultContent = scannedData;
|
this.env.result = scannedData;
|
||||||
this.env.resultContentFormat = "QR_CODE";
|
this.env.resultFormat = "QR_CODE";
|
||||||
this.env.recordSource = "scan";
|
this.env.recordSource = "scan";
|
||||||
this.env.detailedRecordSource = "scan-image";
|
this.env.detailedRecordSource = "scan-image";
|
||||||
this.env.viewResultFrom = "/tabs/import-image";
|
this.env.viewResultFrom = "/tabs/import-image";
|
||||||
|
@ -204,7 +196,7 @@ export class ImportImagePage {
|
||||||
|
|
||||||
async tapHaptic() {
|
async tapHaptic() {
|
||||||
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
|
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
|
||||||
await Haptics.impact({ style: ImpactStyle.Light })
|
await Haptics.impact({ style: ImpactStyle.Medium })
|
||||||
.catch(async err => {
|
.catch(async err => {
|
||||||
if (this.env.debugMode === 'on') {
|
if (this.env.debugMode === 'on') {
|
||||||
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
|
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Preferences } from '@capacitor/preferences';
|
|
||||||
import { AlertController, IonRouterOutlet, Platform } from '@ionic/angular';
|
import { AlertController, IonRouterOutlet, Platform } from '@ionic/angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { EnvService } from 'src/app/services/env.service';
|
import { EnvService } from 'src/app/services/env.service';
|
||||||
|
@ -51,45 +50,26 @@ export class LandingPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async confirmExitApp(): Promise<void> {
|
async confirmExitApp(): Promise<void> {
|
||||||
if (this.env.showExitAppAlert == "on") {
|
const alert = await this.alertController.create({
|
||||||
const alert = await this.alertController.create({
|
header: this.translate.instant('EXIT_APP'),
|
||||||
header: this.translate.instant('EXIT_APP'),
|
message: this.translate.instant('MSG.EXIT_APP'),
|
||||||
message: this.translate.instant('MSG.EXIT_APP'),
|
cssClass: ['alert-bg'],
|
||||||
inputs: [
|
buttons: [
|
||||||
{
|
{
|
||||||
type: "checkbox",
|
text: this.translate.instant('EXIT'),
|
||||||
label: this.translate.instant("MSG.TUTORIAL_NOT_SHOW_AGAIN"),
|
handler: () => {
|
||||||
checked: false,
|
navigator['app'].exitApp();
|
||||||
handler: async (result) => {
|
|
||||||
if (result.checked) {
|
|
||||||
this.env.showExitAppAlert = "off";
|
|
||||||
} else {
|
|
||||||
this.env.showExitAppAlert = "on";
|
|
||||||
}
|
|
||||||
await Preferences.set({ key: this.env.KEY_SHOW_EXIT_APP_ALERT, value: this.env.showExitAppAlert });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
},
|
||||||
cssClass: ['alert-bg', 'alert-input-no-border'],
|
{
|
||||||
buttons: [
|
text: this.translate.instant('RATE_THE_APP'),
|
||||||
{
|
handler: () => {
|
||||||
text: this.translate.instant('EXIT'),
|
this.openGooglePlay();
|
||||||
handler: () => {
|
|
||||||
navigator['app'].exitApp();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: this.translate.instant('RATE_THE_APP'),
|
|
||||||
handler: () => {
|
|
||||||
this.openGooglePlay();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
});
|
]
|
||||||
await alert.present();
|
});
|
||||||
} else {
|
await alert.present();
|
||||||
navigator['app'].exitApp();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { IonicModule } from '@ionic/angular';
|
||||||
import { ResultPageRoutingModule } from './result-routing.module';
|
import { ResultPageRoutingModule } from './result-routing.module';
|
||||||
|
|
||||||
import { ResultPage } from './result.page';
|
import { ResultPage } from './result.page';
|
||||||
|
import { NgxQRCodeModule } from '@techiediaries/ngx-qrcode';
|
||||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||||
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
<ion-col>
|
<ion-col>
|
||||||
<ion-badge class="p-2" color="primary">
|
<ion-badge class="p-2" color="primary">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<mat-icon class="me-2" *ngIf="contentTypeIcon != ''" [fontIcon]="contentTypeIcon">
|
<mat-icon *ngIf="contentTypeIcon != ''" style="margin-right: 16px;">
|
||||||
|
{{ contentTypeIcon }}
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
<span>{{ contentTypeText }}</span>
|
<span>{{ contentTypeText }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -27,7 +28,7 @@
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
|
||||||
<ng-container *ngIf="qrCodeContent && qrCodeContent.trim().length > 0" [ngTemplateOutlet]="contentBlock"
|
<ng-container *ngIf="qrCodeContent && qrCodeContent.trim().length > 0" [ngTemplateOutlet]="contentBlock"
|
||||||
[ngTemplateOutletContext]="{ label: barcodeFormat + ('CONTENT' | translate), content: qrCodeContent, hint: env.resultContentFormat, showEdit: true }">
|
[ngTemplateOutletContext]="{ label: barcodeFormat + ('CONTENT' | translate), content: qrCodeContent, hint: env.resultFormat }">
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngIf="base64Encoded && qrCodeContent && qrCodeContent.trim().length > 0"
|
<ng-container *ngIf="base64Encoded && qrCodeContent && qrCodeContent.trim().length > 0"
|
||||||
|
@ -96,15 +97,6 @@
|
||||||
[ngTemplateOutletContext]="{ label: 'HIDDEN_NETWORK_?' | translate, content: wifiHidden === true? ('YES' | translate) : ('NO' | translate) }">
|
[ngTemplateOutletContext]="{ label: 'HIDDEN_NETWORK_?' | translate, content: wifiHidden === true? ('YES' | translate) : ('NO' | translate) }">
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngIf="contentType === 'geo' && qrCodeContent && qrCodeContent.trim().length > 0 && latitude != null"
|
|
||||||
[ngTemplateOutlet]="contentBlock" [ngTemplateOutletContext]="{ label: 'LATITUDE' | translate, content: latitude }">
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container *ngIf="contentType === 'geo' && qrCodeContent && qrCodeContent.trim().length > 0 && longitude != null"
|
|
||||||
[ngTemplateOutlet]="contentBlock"
|
|
||||||
[ngTemplateOutletContext]="{ label: 'LONGITUDE' | translate, content: longitude }">
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<div class="ion-padding-horizontal ion-margin-horizontal ion-padding-bottom">
|
<div class="ion-padding-horizontal ion-margin-horizontal ion-padding-bottom">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -114,34 +106,18 @@
|
||||||
[ngStyle]="env.colorTheme === 'dark'? {'background-color': '#222428'} : (env.colorTheme === 'black'? {'background-color': '#000000'} : {'background-color': '#F0F0F0'})">
|
[ngStyle]="env.colorTheme === 'dark'? {'background-color': '#222428'} : (env.colorTheme === 'black'? {'background-color': '#000000'} : {'background-color': '#F0F0F0'})">
|
||||||
|
|
||||||
<ng-container *ngIf="env.resultPageButtons === 'icon-only'">
|
<ng-container *ngIf="env.resultPageButtons === 'icon-only'">
|
||||||
<ion-row *ngIf="contentType === 'freeText' && env.showOpenFoodFactsButton === 'on' && isValidEan"
|
<ion-row *ngIf="contentType === 'url' && env.showBrowseButton === 'on' && isHttp" class="d-flex justify-content-center">
|
||||||
class="d-flex justify-content-center">
|
|
||||||
<ion-button (click)="tapHaptic(); searchOpenFoodFacts()" [color]="'primary'" fill="clear">
|
|
||||||
<ion-icon name="fast-food"></ion-icon>
|
|
||||||
</ion-button>
|
|
||||||
</ion-row>
|
|
||||||
|
|
||||||
<ion-row *ngIf="contentType === 'url' && env.showBrowseButton === 'on' && isHttp"
|
|
||||||
class="d-flex justify-content-center">
|
|
||||||
<ion-button (click)="tapHaptic(); browseWebsite()" [color]="'primary'" fill="clear">
|
<ion-button (click)="tapHaptic(); browseWebsite()" [color]="'primary'" fill="clear">
|
||||||
<ion-icon name="globe"></ion-icon>
|
<ion-icon name="globe"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
|
||||||
<ion-row *ngIf="contentType === 'url' && env.showOpenUrlButton === 'on' && !isHttp"
|
<ion-row *ngIf="contentType === 'url' && env.showOpenUrlButton === 'on' && !isHttp" class="d-flex justify-content-center">
|
||||||
class="d-flex justify-content-center">
|
<ion-button *ngIf="" (click)="tapHaptic(); openLink()" [color]="'primary'" fill="clear">
|
||||||
<ion-button (click)="tapHaptic(); openLink()" [color]="'primary'" fill="clear">
|
|
||||||
<ion-icon name="open"></ion-icon>
|
<ion-icon name="open"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
|
||||||
<ion-row *ngIf="contentType === 'geo' && env.showOpenUrlButton === 'on'"
|
|
||||||
class="d-flex justify-content-center">
|
|
||||||
<ion-button (click)="tapHaptic(); openLink()" [color]="'primary'" fill="clear">
|
|
||||||
<ion-icon name="map"></ion-icon>
|
|
||||||
</ion-button>
|
|
||||||
</ion-row>
|
|
||||||
|
|
||||||
<ion-row *ngIf="contentType === 'contact' && env.showAddContactButton === 'on'"
|
<ion-row *ngIf="contentType === 'contact' && env.showAddContactButton === 'on'"
|
||||||
class="d-flex justify-content-center">
|
class="d-flex justify-content-center">
|
||||||
<ion-button (click)="tapHaptic(); addContact()" [color]="'primary'" fill="clear">
|
<ion-button (click)="tapHaptic(); addContact()" [color]="'primary'" fill="clear">
|
||||||
|
@ -188,156 +164,124 @@
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
|
||||||
<ion-row class="ion-padding-horizontal">
|
<ion-row class="ion-padding-horizontal justify-content-around">
|
||||||
<div class="d-flex justify-content-between detailed-action-button-container">
|
<ion-button *ngIf="env.showSearchButton === 'on'" (click)="tapHaptic(); webSearch()"
|
||||||
<ion-button
|
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="clear"
|
||||||
*ngIf="!resultSaved && this.env.scanRecordLogging == 'off' && this.qrCodeContent != null && this.qrCodeContent != '' "
|
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
||||||
(click)="tapHaptic(); saveRecord()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="clear">
|
<ion-icon *ngIf="env.searchEngine === 'google'" slot="icon-only" name="logo-google">
|
||||||
<ion-icon slot="icon-only" src="assets/icon/history.svg"></ion-icon>
|
</ion-icon>
|
||||||
</ion-button>
|
<ion-icon *ngIf="env.searchEngine === 'bing'" slot="icon-only" src="assets/icon/microsoft-bing.svg">
|
||||||
<ion-button *ngIf="env.showSearchButton === 'on'" (click)="tapHaptic(); webSearch()"
|
</ion-icon>
|
||||||
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="clear"
|
<ion-icon *ngIf="env.searchEngine === 'yahoo'" slot="icon-only" src="assets/icon/yahoo.svg">
|
||||||
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
</ion-icon>
|
||||||
<ion-icon *ngIf="env.searchEngine === 'google'" slot="icon-only" name="logo-google">
|
<ion-icon *ngIf="env.searchEngine === 'duckduckgo'" slot="icon-only" src="assets/icon/duck-duck-go.svg">
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
<ion-icon *ngIf="env.searchEngine === 'bing'" slot="icon-only" src="assets/icon/microsoft-bing.svg">
|
<ion-icon *ngIf="env.searchEngine === 'yandex'" slot="icon-only" src="assets/icon/yandex.svg">
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
<ion-icon *ngIf="env.searchEngine === 'yahoo'" slot="icon-only" src="assets/icon/yahoo.svg">
|
</ion-button>
|
||||||
</ion-icon>
|
<ion-button *ngIf="env.showCopyButton === 'on'" (click)="tapHaptic(); copyText()"
|
||||||
<ion-icon *ngIf="env.searchEngine === 'duckduckgo'" slot="icon-only" src="assets/icon/duck-duck-go.svg">
|
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="clear"
|
||||||
</ion-icon>
|
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
||||||
<ion-icon *ngIf="env.searchEngine === 'yandex'" slot="icon-only" src="assets/icon/yandex.svg">
|
<ion-icon slot="icon-only" name="copy"></ion-icon>
|
||||||
</ion-icon>
|
</ion-button>
|
||||||
<ion-icon *ngIf="env.searchEngine === 'ecosia'" slot="icon-only" src="assets/icon/ecosia.svg">
|
<ion-button *ngIf="env.showBase64Button === 'on'" (click)="tapHaptic(); base64()"
|
||||||
</ion-icon>
|
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="clear"
|
||||||
<ion-icon *ngIf="env.searchEngine === 'brave'" slot="icon-only" src="assets/icon/brave-search.svg">
|
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
||||||
</ion-icon>
|
<ion-icon slot="icon-only" name="code-working"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button *ngIf="env.showCopyButton === 'on'" (click)="tapHaptic(); copyText()"
|
<ion-button *ngIf="env.showEnlargeButton === 'on'" (click)="tapHaptic(); enlarge()"
|
||||||
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="clear"
|
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="clear"
|
||||||
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
||||||
<ion-icon slot="icon-only" name="copy"></ion-icon>
|
<ion-icon slot="icon-only" name="qr-code-sharp"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button *ngIf="env.showBase64Button === 'on'" (click)="tapHaptic(); base64()"
|
<ion-button *ngIf="env.showBookmarkButton === 'on'" (click)="tapHaptic(); handleBookmark()"
|
||||||
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="clear"
|
[color]="!bookmarked? (env.colorTheme === 'light'? 'dark' : 'light') : 'warning'" fill="clear"
|
||||||
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
||||||
<ion-icon slot="icon-only" name="code-working"></ion-icon>
|
<ion-icon slot="icon-only" name="bookmark"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button *ngIf="env.showEnlargeButton === 'on'" (click)="tapHaptic(); enlarge()"
|
|
||||||
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="clear"
|
|
||||||
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
|
||||||
<ion-icon slot="icon-only" name="qr-code-sharp"></ion-icon>
|
|
||||||
</ion-button>
|
|
||||||
<ion-button *ngIf="env.showBookmarkButton === 'on'" (click)="tapHaptic(); handleBookmark()"
|
|
||||||
[color]="!bookmarked? (env.colorTheme === 'light'? 'dark' : 'light') : 'warning'" fill="clear"
|
|
||||||
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
|
||||||
<ion-icon slot="icon-only" name="bookmark"></ion-icon>
|
|
||||||
</ion-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</ion-row>
|
</ion-row>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngIf="env.resultPageButtons === 'detailed'">
|
<ng-container *ngIf="env.resultPageButtons === 'detailed'">
|
||||||
<ion-row class="ion-padding-horizontal py-2">
|
<ion-row class="ion-padding-horizontal py-2">
|
||||||
<div class="d-flex justify-content-between detailed-action-button-container">
|
<div class="d-flex justify-content-between detailed-action-button-container">
|
||||||
<ion-button class="pe-1"
|
<ion-button class="pr-1" *ngIf="contentType === 'url' && env.showBrowseButton === 'on' && isHttp"
|
||||||
*ngIf="!resultSaved && this.env.scanRecordLogging == 'off' && this.qrCodeContent != null && this.qrCodeContent != '' "
|
|
||||||
(click)="tapHaptic(); saveRecord()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
|
||||||
shape="round" [@inAnimation]>
|
|
||||||
<ion-icon class="pe-2" src="assets/icon/history.svg"></ion-icon>
|
|
||||||
<ion-label>{{ 'SAVE' | translate }}</ion-label>
|
|
||||||
</ion-button>
|
|
||||||
<ion-button class="pe-1"
|
|
||||||
*ngIf="contentType === 'freeText' && env.showOpenFoodFactsButton === 'on' && isValidEan"
|
|
||||||
(click)="tapHaptic(); searchOpenFoodFacts()" [color]="env.colorTheme === 'light'? 'dark' : 'light'"
|
|
||||||
fill="outline" shape="round" [@inAnimation]>
|
|
||||||
<ion-icon class="pe-2" name="fast-food"></ion-icon>
|
|
||||||
<ion-label>Facts</ion-label>
|
|
||||||
</ion-button>
|
|
||||||
<ion-button class="pe-1" *ngIf="contentType === 'url' && env.showBrowseButton === 'on' && isHttp"
|
|
||||||
(click)="tapHaptic(); browseWebsite()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
(click)="tapHaptic(); browseWebsite()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
||||||
shape="round" [@inAnimation]>
|
shape="round" [@inAnimation]>
|
||||||
<ion-icon class="pe-2" name="globe"></ion-icon>
|
<ion-icon class="pr-2" name="globe"></ion-icon>
|
||||||
<ion-label>{{ 'BROWSE' | translate}}</ion-label>
|
<ion-label>{{ 'BROWSE' | translate}}</ion-label>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button class="pe-1"
|
<ion-button class="pr-1" *ngIf="contentType === 'url' && env.showOpenUrlButton === 'on' && !isHttp"
|
||||||
*ngIf="(contentType === 'url' || contentType === 'geo') && env.showOpenUrlButton === 'on' && !isHttp"
|
|
||||||
(click)="tapHaptic(); openLink()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
(click)="tapHaptic(); openLink()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
||||||
shape="round" [@inAnimation]>
|
shape="round" [@inAnimation]>
|
||||||
<ion-icon class="pe-2" [name]="contentType === 'geo'? 'map' : 'open'"></ion-icon>
|
<ion-icon class="pr-2" name="open"></ion-icon>
|
||||||
<ion-label>{{ 'OPEN' | translate}}</ion-label>
|
<ion-label>{{ 'OPEN' | translate}}</ion-label>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button class="pe-1"
|
<ion-button class="pr-1"
|
||||||
*ngIf="(contentType === 'contact' || contentType === 'phone' || contentType === 'sms') && env.showAddContactButton === 'on'"
|
*ngIf="(contentType === 'contact' || contentType === 'phone' || contentType === 'sms') && env.showAddContactButton === 'on'"
|
||||||
(click)="tapHaptic(); addContact()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
(click)="tapHaptic(); addContact()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
||||||
shape="round" [@inAnimation]>
|
shape="round" [@inAnimation]>
|
||||||
<ion-icon class="pe-2" name="person-add-sharp"></ion-icon>
|
<ion-icon class="pr-2" name="person-add-sharp"></ion-icon>
|
||||||
<ion-label>{{ 'ADD' | translate}}</ion-label>
|
<ion-label>{{ 'ADD' | translate}}</ion-label>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button class="pe-1" *ngIf="contentType === 'phone' && env.showCallButton === 'on'"
|
<ion-button class="pr-1" *ngIf="contentType === 'phone' && env.showCallButton === 'on'"
|
||||||
(click)="tapHaptic(); callPhone()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
(click)="tapHaptic(); callPhone()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
||||||
shape="round" [@inAnimation]>
|
shape="round" [@inAnimation]>
|
||||||
<ion-icon class="pe-2" name="call"></ion-icon>
|
<ion-icon class="pr-2" name="call"></ion-icon>
|
||||||
<ion-label>{{ 'CALL' | translate}}</ion-label>
|
<ion-label>{{ 'CALL' | translate}}</ion-label>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button class="pe-1" *ngIf="contentType === 'sms' && smsContent && env.showSendMessageButton === 'on'"
|
<ion-button class="pr-1" *ngIf="contentType === 'sms' && smsContent && env.showSendMessageButton === 'on'"
|
||||||
(click)="tapHaptic(); sendSms()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
(click)="tapHaptic(); sendSms()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
||||||
shape="round" [@inAnimation]>
|
shape="round" [@inAnimation]>
|
||||||
<ion-icon class="pe-2" name="send"></ion-icon>
|
<ion-icon class="pr-2" name="send"></ion-icon>
|
||||||
<ion-label>{{ 'SEND' | translate}}</ion-label>
|
<ion-label>{{ 'SEND' | translate}}</ion-label>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button class="pe-1"
|
<ion-button class="pr-1"
|
||||||
*ngIf="(contentType === 'emailW3C' || contentType === 'emailDocomo') && env.showSendEmailButton === 'on'"
|
*ngIf="(contentType === 'emailW3C' || contentType === 'emailDocomo') && env.showSendEmailButton === 'on'"
|
||||||
(click)="tapHaptic(); sendEmail()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
(click)="tapHaptic(); sendEmail()" [color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline"
|
||||||
shape="round" [@inAnimation]>
|
shape="round" [@inAnimation]>
|
||||||
<ion-icon class="pe-2" name="mail"></ion-icon>
|
<ion-icon class="pr-2" name="mail"></ion-icon>
|
||||||
<ion-label>{{ 'SEND' | translate}}</ion-label>
|
<ion-label>{{ 'SEND' | translate}}</ion-label>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button class="pe-1" *ngIf="env.showSearchButton === 'on'" (click)="tapHaptic(); webSearch()"
|
<ion-button class="pr-1" *ngIf="env.showSearchButton === 'on'" (click)="tapHaptic(); webSearch()"
|
||||||
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline" shape="round" [@inAnimation]
|
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline" shape="round" [@inAnimation]
|
||||||
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
||||||
<ion-icon class="pe-2" *ngIf="env.searchEngine === 'google'" slot="icon-only" name="logo-google">
|
<ion-icon class="pr-2" *ngIf="env.searchEngine === 'google'" slot="icon-only" name="logo-google">
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
<ion-icon class="pe-2" *ngIf="env.searchEngine === 'bing'" slot="icon-only"
|
<ion-icon class="pr-2" *ngIf="env.searchEngine === 'bing'" slot="icon-only"
|
||||||
src="assets/icon/microsoft-bing.svg">
|
src="assets/icon/microsoft-bing.svg">
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
<ion-icon class="pe-2" *ngIf="env.searchEngine === 'yahoo'" slot="icon-only" src="assets/icon/yahoo.svg">
|
<ion-icon class="pr-2" *ngIf="env.searchEngine === 'yahoo'" slot="icon-only" src="assets/icon/yahoo.svg">
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
<ion-icon class="pe-2" *ngIf="env.searchEngine === 'duckduckgo'" slot="icon-only"
|
<ion-icon class="pr-2" *ngIf="env.searchEngine === 'duckduckgo'" slot="icon-only"
|
||||||
src="assets/icon/duck-duck-go.svg">
|
src="assets/icon/duck-duck-go.svg">
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
<ion-icon class="pe-2" *ngIf="env.searchEngine === 'yandex'" slot="icon-only" src="assets/icon/yandex.svg">
|
<ion-icon class="pr-2" *ngIf="env.searchEngine === 'yandex'" slot="icon-only" src="assets/icon/yandex.svg">
|
||||||
</ion-icon>
|
|
||||||
<ion-icon class="pe-2" *ngIf="env.searchEngine === 'ecosia'" slot="icon-only" src="assets/icon/ecosia.svg">
|
|
||||||
</ion-icon>
|
|
||||||
<ion-icon class="pe-2" *ngIf="env.searchEngine === 'brave'" slot="icon-only"
|
|
||||||
src="assets/icon/brave-search.svg">
|
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
<ion-label>{{ 'SEARCH' | translate}}</ion-label>
|
<ion-label>{{ 'SEARCH' | translate}}</ion-label>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button class="pe-1" *ngIf="env.showCopyButton === 'on'" (click)="tapHaptic(); copyText()"
|
<ion-button class="pr-1" *ngIf="env.showCopyButton === 'on'" (click)="tapHaptic(); copyText()"
|
||||||
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline" shape="round" [@inAnimation]
|
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline" shape="round" [@inAnimation]
|
||||||
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
||||||
<ion-icon class="pe-2" slot="icon-only" name="copy"></ion-icon>
|
<ion-icon class="pr-2" slot="icon-only" name="copy"></ion-icon>
|
||||||
<ion-label>{{ 'COPY' | translate}}</ion-label>
|
<ion-label>{{ 'COPY' | translate}}</ion-label>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button class="pe-1" *ngIf="env.showBase64Button === 'on'" (click)="tapHaptic(); base64()"
|
<ion-button class="pr-1" *ngIf="env.showBase64Button === 'on'" (click)="tapHaptic(); base64()"
|
||||||
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline" shape="round" [@inAnimation]
|
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline" shape="round" [@inAnimation]
|
||||||
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
||||||
<ion-icon class="pe-2" slot="icon-only" name="code-working"></ion-icon>
|
<ion-icon class="pr-2" slot="icon-only" name="code-working"></ion-icon>
|
||||||
<ion-label>{{ 'BASE64' | translate}}</ion-label>
|
<ion-label>{{ 'BASE64' | translate}}</ion-label>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button class="pe-1" *ngIf="env.showEnlargeButton === 'on'" (click)="tapHaptic(); enlarge()"
|
<ion-button class="pr-1" *ngIf="env.showEnlargeButton === 'on'" (click)="tapHaptic(); enlarge()"
|
||||||
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline" shape="round" [@inAnimation]
|
[color]="env.colorTheme === 'light'? 'dark' : 'light'" fill="outline" shape="round" [@inAnimation]
|
||||||
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
[disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
||||||
<ion-icon class="pe-2" slot="icon-only" name="qr-code-sharp"></ion-icon>
|
<ion-icon class="pr-2" slot="icon-only" name="qr-code-sharp"></ion-icon>
|
||||||
<ion-label>{{ 'SHOW' | translate}}</ion-label>
|
<ion-label>{{ 'SHOW' | translate}}</ion-label>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button *ngIf="env.showBookmarkButton === 'on'" (click)="tapHaptic(); handleBookmark()"
|
<ion-button *ngIf="env.showBookmarkButton === 'on'" (click)="tapHaptic(); handleBookmark()"
|
||||||
[color]="!bookmarked? (env.colorTheme === 'light'? 'dark' : 'light') : 'warning'" fill="outline" shape="round"
|
[color]="!bookmarked? (env.colorTheme === 'light'? 'dark' : 'light') : 'warning'" fill="outline" shape="round"
|
||||||
[@inAnimation] [disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
[@inAnimation] [disabled]="!qrCodeContent || (qrCodeContent && qrCodeContent.trim().length <= 0)">
|
||||||
<ion-icon class="pe-2" slot="icon-only" name="bookmark"></ion-icon>
|
<ion-icon class="pr-2" slot="icon-only" name="bookmark"></ion-icon>
|
||||||
<ion-label *ngIf="!bookmarked">{{ 'BOOKMARK' | translate}}</ion-label>
|
<ion-label *ngIf="!bookmarked">{{ 'BOOKMARK' | translate}}</ion-label>
|
||||||
<ion-label *ngIf="bookmarked">{{ 'BOOKMARKED' | translate}}</ion-label>
|
<ion-label *ngIf="bookmarked">{{ 'BOOKMARKED' | translate}}</ion-label>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
|
@ -347,7 +291,7 @@
|
||||||
|
|
||||||
</ion-footer>
|
</ion-footer>
|
||||||
|
|
||||||
<ng-template #contentBlock let-label="label" let-content="content" let-hint="hint" let-showEdit="showEdit">
|
<ng-template #contentBlock let-label="label" let-content="content" let-hint="hint">
|
||||||
<ion-row class="ion-padding-horizontal" [@inAnimation]>
|
<ion-row class="ion-padding-horizontal" [@inAnimation]>
|
||||||
<ion-col>
|
<ion-col>
|
||||||
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent" [floatLabel]="'always'"
|
<mat-form-field [class]="ngMatThemeClass" appearance="outline" color="accent" [floatLabel]="'always'"
|
||||||
|
@ -357,10 +301,6 @@
|
||||||
[cdkAutosizeMaxRows]="20" readonly>
|
[cdkAutosizeMaxRows]="20" readonly>
|
||||||
</textarea>
|
</textarea>
|
||||||
<mat-hint *ngIf="hint && hint != ''" style="opacity: 0.5;">{{ hint }}</mat-hint>
|
<mat-hint *ngIf="hint && hint != ''" style="opacity: 0.5;">{{ hint }}</mat-hint>
|
||||||
<button mat-button color="primary" (click)="editContent()" *ngIf="showEdit" class="m-0 p-0 mt-3"
|
|
||||||
style="background-color: transparent !important; color: var(--ion-color-primary) !important;">
|
|
||||||
{{ 'EDIT' | translate }}
|
|
||||||
</button>
|
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import { Component, QueryList, ViewChildren } from '@angular/core';
|
import { Component, OnInit, QueryList, ViewChildren } from '@angular/core';
|
||||||
import { Clipboard } from '@capacitor/clipboard';
|
import { Clipboard } from '@capacitor/clipboard';
|
||||||
import { ContactInput, Contacts, EmailInput, EmailType, PhoneInput, PhoneType } from '@capacitor-community/contacts';
|
import { Contacts, ContactType, EmailAddress, NewContact, PhoneNumber } from '@capacitor-community/contacts'
|
||||||
import { SMS } from '@awesome-cordova-plugins/sms/ngx';
|
import { SMS } from '@awesome-cordova-plugins/sms/ngx';
|
||||||
import { Haptics, ImpactStyle } from '@capacitor/haptics';
|
import { Haptics, ImpactStyle } from '@capacitor/haptics';
|
||||||
import { AlertController, LoadingController, ModalController, Platform } from '@ionic/angular';
|
import { AlertController, LoadingController, ModalController, Platform } from '@ionic/angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { NgxQrcodeElementTypes, NgxQrcodeErrorCorrectionLevels } from '@techiediaries/ngx-qrcode';
|
||||||
import { VCardContact } from 'src/app/models/v-card-contact';
|
import { VCardContact } from 'src/app/models/v-card-contact';
|
||||||
import { EnvService, QrResultContentTypeType } from 'src/app/services/env.service';
|
import { EnvService } from 'src/app/services/env.service';
|
||||||
import { Toast } from '@capacitor/toast';
|
import { Toast } from '@capacitor/toast';
|
||||||
import { MatFormField } from '@angular/material/form-field';
|
import { MatFormField } from '@angular/material/form-field';
|
||||||
import { BarcodeScanner } from '@capacitor-community/barcode-scanner';
|
import { BarcodeScanner } from '@capacitor-community/barcode-scanner';
|
||||||
import { QrCodePage } from 'src/app/modals/qr-code/qr-code.page';
|
import { QrCodePage } from 'src/app/modals/qr-code/qr-code.page';
|
||||||
import { fadeIn } from 'src/app/utils/animations';
|
import { fadeIn } from 'src/app/utils/animations';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { QRCodeElementType } from 'angularx-qrcode';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-result',
|
selector: 'app-result',
|
||||||
|
@ -23,11 +23,11 @@ import { QRCodeElementType } from 'angularx-qrcode';
|
||||||
})
|
})
|
||||||
export class ResultPage {
|
export class ResultPage {
|
||||||
|
|
||||||
contentType: QrResultContentTypeType = "freeText";
|
contentType: "freeText" | "url" | "contact" | "phone" | "sms" | "emailW3C" | "emailDocomo" | "wifi" = "freeText";
|
||||||
|
|
||||||
qrCodeContent: string;
|
qrCodeContent: string;
|
||||||
qrElementType: QRCodeElementType = "canvas";
|
qrElementType: NgxQrcodeElementTypes = NgxQrcodeElementTypes.CANVAS;
|
||||||
errorCorrectionLevel: 'low' | 'medium' | 'quartile' | 'high' | 'L' | 'M' | 'Q' | 'H' = 'low';
|
errorCorrectionLevel: NgxQrcodeErrorCorrectionLevels = NgxQrcodeErrorCorrectionLevels.LOW;
|
||||||
qrMargin: number = 3;
|
qrMargin: number = 3;
|
||||||
|
|
||||||
phoneNumber: string;
|
phoneNumber: string;
|
||||||
|
@ -45,9 +45,6 @@ export class ResultPage {
|
||||||
wifiEncryption: 'NONE' | 'WEP' | 'WPA';
|
wifiEncryption: 'NONE' | 'WEP' | 'WPA';
|
||||||
wifiHidden: boolean = false;
|
wifiHidden: boolean = false;
|
||||||
|
|
||||||
latitude: number;
|
|
||||||
longitude: number;
|
|
||||||
|
|
||||||
base64Encoded: boolean = false;
|
base64Encoded: boolean = false;
|
||||||
base64EncodedText: string = "";
|
base64EncodedText: string = "";
|
||||||
base64Decoded: boolean = false;
|
base64Decoded: boolean = false;
|
||||||
|
@ -57,8 +54,6 @@ export class ResultPage {
|
||||||
|
|
||||||
showQrFirst: boolean = false;
|
showQrFirst: boolean = false;
|
||||||
|
|
||||||
resultSaved: boolean = false;
|
|
||||||
|
|
||||||
@ViewChildren(MatFormField) formFields: QueryList<MatFormField>;
|
@ViewChildren(MatFormField) formFields: QueryList<MatFormField>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -86,27 +81,18 @@ export class ResultPage {
|
||||||
this.showQrFirst = true;
|
this.showQrFirst = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.qrCodeContent = this.env.resultContent;
|
this.qrCodeContent = this.env.result;
|
||||||
this.setContentType();
|
this.setContentType();
|
||||||
}
|
}
|
||||||
|
|
||||||
async ionViewDidEnter(): Promise<void> {
|
async ionViewDidEnter(): Promise<void> {
|
||||||
if (this.contentType == 'url' && this.env.autoOpenUrl == 'on' && this.env.recordSource == 'scan') {
|
if (this.showQrFirst) {
|
||||||
setTimeout(() => {
|
|
||||||
this.presentToast(this.translate.instant("AUTO_OPEN_URL"), "short", "bottom");
|
|
||||||
if (this.isHttp) {
|
|
||||||
this.browseWebsite();
|
|
||||||
} else {
|
|
||||||
this.openLink();
|
|
||||||
}
|
|
||||||
}, 300);
|
|
||||||
} else if (this.showQrFirst) {
|
|
||||||
this.showQrFirst = false;
|
this.showQrFirst = false;
|
||||||
if (this.qrCodeContent && this.qrCodeContent.trim().length > 0) {
|
if (this.qrCodeContent && this.qrCodeContent.trim().length > 0) {
|
||||||
await this.enlarge();
|
await this.enlarge();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.env.scanRecordLogging == 'on' && this.qrCodeContent != null && this.qrCodeContent != "") {
|
if (this.env.scanRecordLogging == 'on') {
|
||||||
await this.env.saveScanRecord(this.qrCodeContent);
|
await this.env.saveScanRecord(this.qrCodeContent);
|
||||||
}
|
}
|
||||||
if (this.env.bookmarks.find(x => x.text == this.qrCodeContent)) {
|
if (this.env.bookmarks.find(x => x.text == this.qrCodeContent)) {
|
||||||
|
@ -118,14 +104,6 @@ export class ResultPage {
|
||||||
this.reset();
|
this.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveRecord() {
|
|
||||||
if (this.qrCodeContent != null && this.qrCodeContent != "") {
|
|
||||||
await this.env.saveScanRecord(this.qrCodeContent);
|
|
||||||
}
|
|
||||||
this.resultSaved = true;
|
|
||||||
this.presentToast(this.translate.instant("SAVED"), "short", "bottom");
|
|
||||||
}
|
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.contentType = "freeText";
|
this.contentType = "freeText";
|
||||||
delete this.qrCodeContent;
|
delete this.qrCodeContent;
|
||||||
|
@ -141,15 +119,12 @@ export class ResultPage {
|
||||||
delete this.wifiPassword
|
delete this.wifiPassword
|
||||||
delete this.wifiEncryption
|
delete this.wifiEncryption
|
||||||
delete this.wifiHidden
|
delete this.wifiHidden
|
||||||
delete this.latitude
|
|
||||||
delete this.longitude
|
|
||||||
this.base64Encoded = false;
|
this.base64Encoded = false;
|
||||||
this.base64EncodedText = "";
|
this.base64EncodedText = "";
|
||||||
this.base64Decoded = false;
|
this.base64Decoded = false;
|
||||||
this.base64DecodedText = "";
|
this.base64DecodedText = "";
|
||||||
this.bookmarked = false;
|
this.bookmarked = false;
|
||||||
this.showQrFirst = false;
|
this.showQrFirst = false;
|
||||||
this.resultSaved = false;
|
|
||||||
delete this.env.recordSource;
|
delete this.env.recordSource;
|
||||||
delete this.env.detailedRecordSource;
|
delete this.env.detailedRecordSource;
|
||||||
delete this.env.viewResultFrom;
|
delete this.env.viewResultFrom;
|
||||||
|
@ -162,7 +137,6 @@ export class ResultPage {
|
||||||
const emailW3CPrefix = "MAILTO:";
|
const emailW3CPrefix = "MAILTO:";
|
||||||
const emailDoconoPrefix = "MATMSG:";
|
const emailDoconoPrefix = "MATMSG:";
|
||||||
const wifiPrefix = "WIFI:";
|
const wifiPrefix = "WIFI:";
|
||||||
const geoPrefix = "GEO:";
|
|
||||||
const content0 = this.qrCodeContent.trim();
|
const content0 = this.qrCodeContent.trim();
|
||||||
const tContent = this.qrCodeContent.trim().toUpperCase();
|
const tContent = this.qrCodeContent.trim().toUpperCase();
|
||||||
if (tContent.substr(0, contactPrefix.length) === contactPrefix) {
|
if (tContent.substr(0, contactPrefix.length) === contactPrefix) {
|
||||||
|
@ -189,10 +163,6 @@ export class ResultPage {
|
||||||
} else if (tContent.substr(0, wifiPrefix.length) === wifiPrefix) {
|
} else if (tContent.substr(0, wifiPrefix.length) === wifiPrefix) {
|
||||||
this.contentType = "wifi";
|
this.contentType = "wifi";
|
||||||
this.prepareWifi();
|
this.prepareWifi();
|
||||||
} else if (tContent.substring(0, geoPrefix.length) === geoPrefix) {
|
|
||||||
this.contentType = "geo";
|
|
||||||
this.latitude = +tContent.substring(geoPrefix.length, tContent.indexOf(","));
|
|
||||||
this.longitude = +tContent.substring(tContent.indexOf(",") + 1);
|
|
||||||
} else if (this.isValidUrl(content0)) {
|
} else if (this.isValidUrl(content0)) {
|
||||||
this.contentType = "url";
|
this.contentType = "url";
|
||||||
} else {
|
} else {
|
||||||
|
@ -202,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";
|
||||||
}
|
}
|
||||||
|
@ -220,15 +190,6 @@ export class ResultPage {
|
||||||
return "#ffffff";
|
return "#ffffff";
|
||||||
}
|
}
|
||||||
|
|
||||||
editContent() {
|
|
||||||
this.env.editingContent = true;
|
|
||||||
this.router.navigate(['tabs/generate'], { replaceUrl: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
searchOpenFoodFacts() {
|
|
||||||
window.open(`https://world.openfoodfacts.org/product/${this.qrCodeContent}`, '_system', 'location=yes');
|
|
||||||
}
|
|
||||||
|
|
||||||
browseWebsite() {
|
browseWebsite() {
|
||||||
window.open(this.qrCodeContent, '_system', 'location=yes');
|
window.open(this.qrCodeContent, '_system', 'location=yes');
|
||||||
}
|
}
|
||||||
|
@ -243,140 +204,107 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
async addContact(): Promise<void> {
|
async addContact(): Promise<void> {
|
||||||
let contactInput: ContactInput = {};
|
let newContact = null;
|
||||||
if (this.contentType === "contact") {
|
if (this.contentType === "contact") {
|
||||||
const phoneNumbers: PhoneInput[] = [];
|
const phoneNumbers = [];
|
||||||
if (this.vCardContact?.defaultPhoneNumber != null) {
|
if (this.vCardContact?.defaultPhoneNumber != null) {
|
||||||
const phoneNumber: PhoneInput = {
|
const phoneNumber = { number: this.vCardContact?.defaultPhoneNumber } as PhoneNumber;
|
||||||
type: PhoneType.Mobile,
|
|
||||||
label: 'mobile',
|
|
||||||
number: this.vCardContact?.defaultPhoneNumber,
|
|
||||||
isPrimary: true,
|
|
||||||
};
|
|
||||||
phoneNumbers.push(phoneNumber);
|
phoneNumbers.push(phoneNumber);
|
||||||
}
|
}
|
||||||
if (this.vCardContact?.homePhoneNumber != null) {
|
if (this.vCardContact?.homePhoneNumber != null) {
|
||||||
const phoneNumber: PhoneInput = {
|
const phoneNumber = { number: this.vCardContact?.homePhoneNumber } as PhoneNumber;
|
||||||
type: PhoneType.Home,
|
|
||||||
label: 'home',
|
|
||||||
number: this.vCardContact?.homePhoneNumber,
|
|
||||||
};
|
|
||||||
phoneNumbers.push(phoneNumber);
|
phoneNumbers.push(phoneNumber);
|
||||||
}
|
}
|
||||||
if (this.vCardContact?.workPhoneNumber != null) {
|
if (this.vCardContact?.workPhoneNumber != null) {
|
||||||
const phoneNumber: PhoneInput = {
|
const phoneNumber = { number: this.vCardContact?.homePhoneNumber } as PhoneNumber;
|
||||||
type: PhoneType.Work,
|
|
||||||
label: 'work',
|
|
||||||
number: this.vCardContact?.workPhoneNumber,
|
|
||||||
};
|
|
||||||
phoneNumbers.push(phoneNumber);
|
phoneNumbers.push(phoneNumber);
|
||||||
}
|
}
|
||||||
if (this.vCardContact?.mobilePhoneNumber != null) {
|
if (this.vCardContact?.mobilePhoneNumber != null) {
|
||||||
const phoneNumber: PhoneInput = {
|
const phoneNumber = { number: this.vCardContact?.mobilePhoneNumber } as PhoneNumber;
|
||||||
type: PhoneType.Mobile,
|
|
||||||
label: 'mobile',
|
|
||||||
number: this.vCardContact?.mobilePhoneNumber,
|
|
||||||
};
|
|
||||||
phoneNumbers.push(phoneNumber);
|
phoneNumbers.push(phoneNumber);
|
||||||
}
|
}
|
||||||
const emails: EmailInput[] = [];
|
const emails = [];
|
||||||
if (this.vCardContact?.defaultEmail != null) {
|
if (this.vCardContact?.defaultEmail != null) {
|
||||||
const emailInput: EmailInput = {
|
const address = { address: this.vCardContact?.defaultEmail } as EmailAddress;
|
||||||
type: EmailType.Home,
|
emails.push(address);
|
||||||
label: 'home',
|
|
||||||
isPrimary: true,
|
|
||||||
address: this.vCardContact?.defaultEmail,
|
|
||||||
};
|
|
||||||
emails.push(emailInput);
|
|
||||||
}
|
}
|
||||||
if (this.vCardContact?.homeEmail != null) {
|
if (this.vCardContact?.homeEmail != null) {
|
||||||
const emailInput: EmailInput = {
|
const address = { address: this.vCardContact?.homeEmail } as EmailAddress;
|
||||||
type: EmailType.Home,
|
emails.push(address);
|
||||||
label: 'home',
|
|
||||||
address: this.vCardContact?.homeEmail,
|
|
||||||
};
|
|
||||||
emails.push(emailInput);
|
|
||||||
}
|
}
|
||||||
if (this.vCardContact?.workEmail != null) {
|
if (this.vCardContact?.workEmail != null) {
|
||||||
const emailInput: EmailInput = {
|
const address = { address: this.vCardContact?.workEmail } as EmailAddress;
|
||||||
type: EmailType.Work,
|
emails.push(address);
|
||||||
label: 'work',
|
|
||||||
address: this.vCardContact?.workEmail,
|
|
||||||
};
|
|
||||||
emails.push(emailInput);
|
|
||||||
}
|
}
|
||||||
contactInput.phones = phoneNumbers;
|
newContact = {
|
||||||
contactInput.emails = emails;
|
contactType: ContactType.Person,
|
||||||
contactInput.name = {
|
givenName: this.vCardContact?.givenName ?? this.vCardContact?.fullName ?? '',
|
||||||
given: this.vCardContact?.givenName ?? this.vCardContact?.fullName ?? '',
|
familyName: this.vCardContact?.familyName,
|
||||||
family: this.vCardContact?.familyName,
|
phoneNumbers: phoneNumbers,
|
||||||
};
|
emailAddresses: emails
|
||||||
|
} as NewContact;
|
||||||
} else if (this.contentType === "sms" || this.contentType === "phone") {
|
} else if (this.contentType === "sms" || this.contentType === "phone") {
|
||||||
const phones: PhoneInput[] = [
|
const phoneNumbers = [];
|
||||||
{
|
const phoneNumber = { number: this.phoneNumber } as PhoneNumber;
|
||||||
type: PhoneType.Mobile,
|
phoneNumbers.push(phoneNumber);
|
||||||
label: 'mobile',
|
newContact = {
|
||||||
number: this.phoneNumber,
|
contactType: ContactType.Person,
|
||||||
isPrimary: true,
|
phoneNumbers: phoneNumbers
|
||||||
}
|
} as NewContact;
|
||||||
];
|
|
||||||
contactInput.phones = phones;
|
|
||||||
}
|
}
|
||||||
if (this.platform.is('ios')) {
|
if (newContact != null) {
|
||||||
// TODO: iOS contact handling
|
await Contacts.getPermissions().then(
|
||||||
// await Contacts.checkPermissions().then(
|
async permission => {
|
||||||
// async permission => {
|
if (permission.granted) {
|
||||||
// if (permission.contacts == 'granted') {
|
await Contacts.saveContact(newContact).then(
|
||||||
// await this.saveContact(newContact);
|
_ => {
|
||||||
// } else {
|
if (this.isIOS) {
|
||||||
// const alert = await this.alertController.create({
|
this.presentToast(this.translate.instant('MSG.SAVED_CONTACT'), "short", "bottom");
|
||||||
// header: this.translate.instant("PERMISSION_REQUIRED"),
|
} else {
|
||||||
// message: this.translate.instant("MSG.CONTACT_PERMISSION"),
|
this.presentToast(this.translate.instant('MSG.SAVING_CONTACT'), "short", "bottom");
|
||||||
// buttons: [
|
}
|
||||||
// {
|
}
|
||||||
// text: this.translate.instant("SETTING"),
|
)
|
||||||
// handler: () => {
|
.catch(
|
||||||
// BarcodeScanner.openAppSettings();
|
err => {
|
||||||
// return true;
|
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");
|
||||||
// text: this.translate.instant("CLOSE"),
|
}
|
||||||
// handler: () => {
|
}
|
||||||
// return true;
|
)
|
||||||
// }
|
} else {
|
||||||
// }
|
const alert = await this.alertController.create({
|
||||||
// ],
|
header: this.translate.instant("PERMISSION_REQUIRED"),
|
||||||
// cssClass: ['alert-bg']
|
message: this.translate.instant("MSG.CONTACT_PERMISSION"),
|
||||||
// });
|
buttons: [
|
||||||
// await alert.present();
|
{
|
||||||
// }
|
text: this.translate.instant("SETTING"),
|
||||||
// }
|
handler: () => {
|
||||||
// );
|
BarcodeScanner.openAppSettings();
|
||||||
} else { // Android doesn't need to get permission
|
return true;
|
||||||
await this.saveContact(contactInput);
|
}
|
||||||
}
|
},
|
||||||
}
|
{
|
||||||
|
text: this.translate.instant("CLOSE"),
|
||||||
private async saveContact(contactInput: ContactInput) {
|
handler: () => {
|
||||||
await Contacts.createContact({ contact: contactInput }).then(
|
return true;
|
||||||
_ => {
|
}
|
||||||
this.presentToast(this.translate.instant('MSG.SAVED_CONTACT'), "short", "bottom");
|
}
|
||||||
}
|
],
|
||||||
).catch(
|
cssClass: ['alert-bg']
|
||||||
err => {
|
});
|
||||||
if (this.env.isDebugging) {
|
await alert.present();
|
||||||
this.presentToast("Error when call Contacts.createContact: " + 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> {
|
||||||
|
@ -462,12 +390,6 @@ export class ResultPage {
|
||||||
case 'yandex':
|
case 'yandex':
|
||||||
searchUrl = this.env.YANDEX_SEARCH_URL;
|
searchUrl = this.env.YANDEX_SEARCH_URL;
|
||||||
break;
|
break;
|
||||||
case 'ecosia':
|
|
||||||
searchUrl = this.env.ECOSIA_SEARCH_URL;
|
|
||||||
break;
|
|
||||||
case 'brave':
|
|
||||||
searchUrl = this.env.BRAVE_SEARCH_URL;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
searchUrl = this.env.GOOGLE_SEARCH_URL;
|
searchUrl = this.env.GOOGLE_SEARCH_URL;
|
||||||
break;
|
break;
|
||||||
|
@ -649,7 +571,7 @@ export class ResultPage {
|
||||||
} else if (!failEncoded && failDecoded) {
|
} else if (!failEncoded && failDecoded) {
|
||||||
await this.presentToast(this.translate.instant('MSG.NOT_BASE64_DE'), "short", "center");
|
await this.presentToast(this.translate.instant('MSG.NOT_BASE64_DE'), "short", "center");
|
||||||
}
|
}
|
||||||
// setTimeout(() => this.formFields?.forEach(ff => ff.updateOutlineGap()), 100);
|
setTimeout(() => this.formFields?.forEach(ff => ff.updateOutlineGap()), 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
generateVCardContact(): void {
|
generateVCardContact(): void {
|
||||||
|
@ -684,6 +606,7 @@ export class ResultPage {
|
||||||
lines.forEach(
|
lines.forEach(
|
||||||
line => {
|
line => {
|
||||||
const tLine = line.trim();
|
const tLine = line.trim();
|
||||||
|
console.log(tLine);
|
||||||
if (tLine.toUpperCase().substr(0, fullNameId1.length) === fullNameId1) {
|
if (tLine.toUpperCase().substr(0, fullNameId1.length) === fullNameId1) {
|
||||||
this.vCardContact.fullName = tLine.substr(fullNameId1.length);
|
this.vCardContact.fullName = tLine.substr(fullNameId1.length);
|
||||||
} else if (tLine.toUpperCase().substr(0, fullNameId2.length) === fullNameId2) {
|
} else if (tLine.toUpperCase().substr(0, fullNameId2.length) === fullNameId2) {
|
||||||
|
@ -880,6 +803,15 @@ export class ResultPage {
|
||||||
await alert.present();
|
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 {
|
get contentTypeText(): string {
|
||||||
switch (this.contentType) {
|
switch (this.contentType) {
|
||||||
case 'freeText':
|
case 'freeText':
|
||||||
|
@ -890,8 +822,6 @@ export class ResultPage {
|
||||||
return this.translate.instant("EMAIL_W3C_STANDARD");
|
return this.translate.instant("EMAIL_W3C_STANDARD");
|
||||||
case 'emailDocomo':
|
case 'emailDocomo':
|
||||||
return this.translate.instant("EMAIL_NTT_DOCOMO");
|
return this.translate.instant("EMAIL_NTT_DOCOMO");
|
||||||
case 'geo':
|
|
||||||
return this.translate.instant("GEOLOCATION");
|
|
||||||
case 'phone':
|
case 'phone':
|
||||||
return this.translate.instant("PHONE_NO");
|
return this.translate.instant("PHONE_NO");
|
||||||
case 'sms':
|
case 'sms':
|
||||||
|
@ -913,8 +843,6 @@ export class ResultPage {
|
||||||
return "link";
|
return "link";
|
||||||
case "contact":
|
case "contact":
|
||||||
return "contact_phone";
|
return "contact_phone";
|
||||||
case 'geo':
|
|
||||||
return "location_on";
|
|
||||||
case "phone":
|
case "phone":
|
||||||
return "call";
|
return "call";
|
||||||
case "sms":
|
case "sms":
|
||||||
|
@ -931,7 +859,7 @@ export class ResultPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
get barcodeFormat(): string {
|
get barcodeFormat(): string {
|
||||||
switch (this.env.resultContentFormat) {
|
switch (this.env.resultFormat) {
|
||||||
case "UPC_A":
|
case "UPC_A":
|
||||||
return this.translate.instant("BARCODE_TYPE.UPC");
|
return this.translate.instant("BARCODE_TYPE.UPC");
|
||||||
case "UPC_E":
|
case "UPC_E":
|
||||||
|
@ -971,36 +899,10 @@ export class ResultPage {
|
||||||
case "RSS_EXPANDED":
|
case "RSS_EXPANDED":
|
||||||
return this.translate.instant("BARCODE_TYPE.RSS");
|
return this.translate.instant("BARCODE_TYPE.RSS");
|
||||||
default:
|
default:
|
||||||
return this.env.resultContentFormat;
|
return this.env.resultFormat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get isValidEan(): boolean {
|
|
||||||
if (this.qrCodeContent == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const isValidLength = this.qrCodeContent.length === 18 || this.qrCodeContent.length === 14 || this.qrCodeContent.length === 13 || this.qrCodeContent.length === 8 || this.qrCodeContent.length === 5;
|
|
||||||
return isValidLength && /^\d+$/.test(this.qrCodeContent) && this.testEanChecksum(this.qrCodeContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private testEanChecksum(text: string): boolean {
|
|
||||||
const digits = text.slice(0, -1);
|
|
||||||
const checkDigit = parseInt(text.slice(-1));
|
|
||||||
if (isNaN(checkDigit)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
let sum = 0;
|
|
||||||
for (let i = digits.length - 1; i >= 0; i--) {
|
|
||||||
const digit = parseInt(digits.charAt(i));
|
|
||||||
if (isNaN(digit)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
sum += (digit * (1 + (2 * (i % 2)))) | 0;
|
|
||||||
}
|
|
||||||
sum = (10 - (sum % 10)) % 10;
|
|
||||||
return sum === checkDigit;
|
|
||||||
}
|
|
||||||
|
|
||||||
get finalContactName(): string {
|
get finalContactName(): string {
|
||||||
if (!this.vCardContact) {
|
if (!this.vCardContact) {
|
||||||
return '';
|
return '';
|
||||||
|
@ -1059,7 +961,7 @@ export class ResultPage {
|
||||||
|
|
||||||
async tapHaptic() {
|
async tapHaptic() {
|
||||||
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
|
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
|
||||||
await Haptics.impact({ style: ImpactStyle.Light })
|
await Haptics.impact({ style: ImpactStyle.Medium })
|
||||||
.catch(async err => {
|
.catch(async err => {
|
||||||
if (this.env.debugMode === 'on') {
|
if (this.env.debugMode === 'on') {
|
||||||
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
|
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
|
||||||
|
|
|
@ -109,7 +109,7 @@ export class ScanPage {
|
||||||
async (result: ScanResult) => {
|
async (result: ScanResult) => {
|
||||||
if (result.hasContent) {
|
if (result.hasContent) {
|
||||||
const text = result.content;
|
const text = result.content;
|
||||||
if (text == null || text?.trim()?.length <= 0 || text == "") {
|
if (text === undefined || text === null || (text && text.trim().length <= 0) || text === "") {
|
||||||
this.presentToast(this.translate.instant('MSG.QR_CODE_VALUE_NOT_EMPTY'), "short", "center");
|
this.presentToast(this.translate.instant('MSG.QR_CODE_VALUE_NOT_EMPTY'), "short", "center");
|
||||||
this.scanQr();
|
this.scanQr();
|
||||||
return;
|
return;
|
||||||
|
@ -137,8 +137,8 @@ export class ScanPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async processQrCode(scannedData: string, format: string, loading: HTMLIonLoadingElement): Promise<void> {
|
async processQrCode(scannedData: string, format: string, loading: HTMLIonLoadingElement): Promise<void> {
|
||||||
this.env.resultContent = scannedData;
|
this.env.result = scannedData;
|
||||||
this.env.resultContentFormat = format;
|
this.env.resultFormat = format;
|
||||||
this.env.recordSource = "scan";
|
this.env.recordSource = "scan";
|
||||||
this.env.detailedRecordSource = "scan-camera";
|
this.env.detailedRecordSource = "scan-camera";
|
||||||
this.env.viewResultFrom = "/tabs/scan";
|
this.env.viewResultFrom = "/tabs/scan";
|
||||||
|
@ -205,7 +205,7 @@ export class ScanPage {
|
||||||
|
|
||||||
async tapHaptic() {
|
async tapHaptic() {
|
||||||
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
|
if (this.env.vibration === 'on' || this.env.vibration === 'on-haptic') {
|
||||||
await Haptics.impact({ style: ImpactStyle.Light })
|
await Haptics.impact({ style: ImpactStyle.Medium })
|
||||||
.catch(async err => {
|
.catch(async err => {
|
||||||
if (this.env.debugMode === 'on') {
|
if (this.env.debugMode === 'on') {
|
||||||
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
|
await Toast.show({ text: 'Err when Haptics.impact: ' + JSON.stringify(err), position: "top", duration: "long" })
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<ion-header>
|
<ion-header>
|
||||||
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
|
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
|
||||||
<ion-buttons slot="start">
|
<ion-buttons slot="start">
|
||||||
<ion-back-button text="" defaultHref="tabs/setting">
|
<ion-back-button text="">
|
||||||
</ion-back-button>
|
</ion-back-button>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
<ion-title>{{ 'AUTO_MAX_BRIGHTNESS' | translate }}</ion-title>
|
<ion-title>{{ 'AUTO_MAX_BRIGHTNESS' | translate }}</ion-title>
|
||||||
|
@ -21,17 +21,29 @@
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
<ion-item class="ion-no-padding ripple-parent" detail="false" lines="none">
|
<ion-radio-group [(ngModel)]="env.autoMaxBrightness" (ionChange)="saveAutoMaxBrightness()">
|
||||||
<ion-label class="ion-padding-start">
|
<ion-item class="ion-no-padding ripple-parent" detail="false" lines="none">
|
||||||
<p class="ion-padding pre-line">
|
<ion-label class="ion-padding-start">
|
||||||
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
|
<p class="ion-padding pre-line">
|
||||||
{{ (env.autoMaxBrightness == 'on'? 'TURNED_ON' : 'TURNED_OFF') | translate }}
|
<ion-text [color]="env.colorTheme === 'light'? 'dark' : 'light'" style="font-size: large;">
|
||||||
</ion-text>
|
{{ 'TURN_ON' | translate }}
|
||||||
</p>
|
</ion-text>
|
||||||
</ion-label>
|
</p>
|
||||||
<ion-toggle class="ion-padding-end" slot="end" [ngModel]="env.autoMaxBrightness == 'on'? true : false"
|
</ion-label>
|
||||||
(ngModelChange)="onAutoMaxBrightnessChange($event)">
|
<ion-radio class="ion-margin-end" slot="end" [value]="'on'" [color]="'primary'">
|
||||||
</ion-toggle>
|
</ion-radio>
|
||||||
</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>
|
|
@ -1,7 +1,5 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { Haptics, ImpactStyle } from '@capacitor/haptics';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { Preferences } from '@capacitor/preferences';
|
|
||||||
import { Toast } from '@capacitor/toast';
|
|
||||||
import { EnvService } from 'src/app/services/env.service';
|
import { EnvService } from 'src/app/services/env.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -15,20 +13,8 @@ export class SettingAutoBrightnessPage {
|
||||||
public env: EnvService,
|
public env: EnvService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
async onAutoMaxBrightnessChange(ev: any) {
|
async saveAutoMaxBrightness() {
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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" })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<ion-header>
|
<ion-header>
|
||||||
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
|
<ion-toolbar [color]="env.colorTheme === 'black'? 'black' : 'dark'">
|
||||||
<ion-buttons slot="start">
|
<ion-buttons slot="start">
|
||||||
<ion-back-button text="" defaultHref="tabs/setting">
|
<ion-back-button text="">
|
||||||
</ion-back-button>
|
</ion-back-button>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
<ion-title>{{ 'AUTO_KILL_BACKGROUND' | translate }}</ion-title>
|
<ion-title>{{ 'AUTO_KILL_BACKGROUND' | translate }}</ion-title>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { Preferences } from '@capacitor/preferences';
|
|
||||||
import { EnvService } from 'src/app/services/env.service';
|
import { EnvService } from 'src/app/services/env.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -14,6 +13,6 @@ export class SettingAutoExitPage{
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
async saveAutoExitAppMin() {
|
async saveAutoExitAppMin() {
|
||||||
await Preferences.set({ key: this.env.KEY_AUTO_EXIT_MIN, value: JSON.stringify(this.env.autoExitAppMin) });
|
await this.env.storageSet("autoExitAppMin", this.env.autoExitAppMin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|