Compare commits

...

36 Commits
v1.6 ... master

Author SHA1 Message Date
Skylar Ittner 6391d9261d Update jQuery to fix SNYK-JS-JQUERY-174006 4 years ago
Skylar Ittner 5dd6ec9403 Update version code 5 years ago
Skylar Ittner c617940c40 Update netsyms.com api url 5 years ago
Skylar Ittner c1ffdc7a5d Update version number 5 years ago
Skylar Ittner d006684147 Fix bug where account switching failed to actually switch accounts 5 years ago
Skylar Ittner 07614c76f6 Fix Android resource issue 6 years ago
Skylar Ittner 5c549225c7 Bump version 2.0 => 2.0.1 6 years ago
Skylar Ittner 36acd0ff06 Allow business account setup without pairing code, close #16, close #21 6 years ago
Skylar Ittner 7963613cd3 Further improve setup UX 6 years ago
Skylar Ittner 136e7fa660 Add back buttons to setup pages 6 years ago
Skylar Ittner ae9fdb2654 Improve L&F, fix bug with secure connection checkbox 6 years ago
Skylar Ittner 21479f2940 Add loading error screen 6 years ago
Skylar Ittner e808b7bbf7 Replace testing URL with actual URL 6 years ago
Skylar Ittner f48ab5e6b9 Remove old app data, rename project, update logo 6 years ago
Skylar Ittner c340976cf8 Update README.md, remove unused images 6 years ago
Skylar Ittner 177831374a Fix status bar text color 6 years ago
Skylar Ittner 35f1e10b7c Fix "Error: null" message 6 years ago
Skylar Ittner dd772dba93 Change package name and bump version to 2.0 6 years ago
Skylar Ittner 9ce6a31d18 Cleanup java 6 years ago
Skylar Ittner c5bc67a257 Rebrand to "Netsyms Apps" 6 years ago
Skylar Ittner 8b5edbd369 Add setup for personal netsyms.com accounts (close #15) 6 years ago
Skylar Ittner 4345405b78 Fix Java imports 6 years ago
Skylar Ittner b59171a0b9 Fix home screen bug, add account switcher (close #19, close #20) 6 years ago
Skylar Ittner 44a0da1f2b Make script tags work when inside pages 6 years ago
Skylar Ittner 2c3092ecb4 Add notification manager to home page 6 years ago
Skylar Ittner 6f79fb7b2a Improve settings, add OTP countdown 6 years ago
Skylar Ittner ee5e2b4a50 Add some settings and credits 6 years ago
Skylar Ittner ba185f32b3 Add pull to refresh on home screen 6 years ago
Skylar Ittner 21c5113b88 Fix back button behavior 6 years ago
Skylar Ittner 5691744543 Improve manual OTP UX 6 years ago
Skylar Ittner d7c00945a7 Add OTP feature to redesign 6 years ago
Skylar Ittner 0b85c8a7f6 Working: initial setup tool, app list, using Apps 6 years ago
Skylar Ittner d248aa5934 Use Java background task for fetching notifications, close #18 6 years ago
Skylar Ittner 9cb914512b Backup user data to NativeStorage 6 years ago
Skylar Ittner 675248dfd3 Add background notification checking and display (close #17) 6 years ago
Skylar Ittner 27a0904ec7 Fix version number 6 years ago

4
.gitignore vendored

@ -1,4 +1,6 @@
nbproject/private
platforms
plugins
node_modules
node_modules
/www/old/
build.json

@ -1,23 +1,23 @@
Business Mobile
Netsyms Mobile
===============
A mobile app for easy and secure access to the Business Apps on the go.
A mobile app for easy and secure access to the Netsyms Apps on the go.
https://netsyms.biz/apps/bizmobile
https://netsyms.biz/apps/netsymsmobile
Features
--------
**Simple Pairing**
Scan a QR code displayed in AccountHub with the app, enter your password, and
**Simple Pairing**
Scan a QR code displayed in AccountHub with the app, enter your password, and
everything is setup automatically.
**Full Access**
Access all features of all Business Apps from one place.
**Full Access**
Access all features of all Netsyms Apps from one place.
**Barcode Scanning**
**Barcode Scanning**
Use your device camera to scan barcodes into BinStack and other apps.
**Secure**
If the device is lost, Apps access can be revoked from AccountHub by deleting the
**Secure**
If the device is lost, Apps access can be revoked from AccountHub by deleting the
pairing code.

@ -1,10 +1,10 @@
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.netsyms.BusinessMobile" version="1.6" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>Business</name>
<widget id="com.netsyms.apps.Mobile" version="2.0.3" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>Netsyms</name>
<description>
Mobile client for the Netsyms Business Apps.
Securely use the Netsyms Apps from your phone or tablet.
</description>
<author email="admin@netsyms.com" href="https://netsyms.com">
<author email="skylar@netsyms.com" href="https://netsyms.com">
Netsyms Technologies
</author>
<content src="index.html" />
@ -26,10 +26,14 @@
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="HeaderColor" value="#2196f3" />
<preference name="StatusBarBackgroundColor" value="#1976d2" />
<preference name="stopOnTerminate" value="false" />
<preference name="startOnBoot" value="true" />
<preference name="forceReload" value="true" />
<preference name="minimumFetchInterval" value="1" />
<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application">
<application android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" />
</edit-config>
<resource-file src="res/android/values/ic_launcher_background.xml" target="app/src/main/res/values/ic_launcher_background.xml" />
<resource-file src="res/android/drawable/ic_launcher_background.xml" target="app/src/main/res/drawable/ic_launcher_background.xml" />
<resource-file src="res/android/drawable/ic_launcher_foreground.xml" target="app/src/main/res/drawable/ic_launcher_foreground.xml" />
<resource-file src="res/android/mipmap-anydpi-v26/ic_launcher.xml" target="app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" />
<resource-file src="res/android/mipmap-anydpi-v26/ic_launcher_round.xml" target="app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" />
@ -43,6 +47,11 @@
<resource-file src="res/android/mipmap-xxhdpi/ic_launcher_round.png" target="app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png" />
<resource-file src="res/android/mipmap-xxxhdpi/ic_launcher.png" target="app/src/main/res/mipmap-xxxhdpi/ic_launcher.png" />
<resource-file src="res/android/mipmap-xxxhdpi/ic_launcher_round.png" target="app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png" />
<resource-file src="res/android/drawable-hdpi/ic_notification.png" target="app/src/main/res/drawable-hdpi/ic_notification.png" />
<resource-file src="res/android/drawable-mdpi/ic_notification.png" target="app/src/main/res/drawable-mdpi/ic_notification.png" />
<resource-file src="res/android/drawable-xhdpi/ic_notification.png" target="app/src/main/res/drawable-xhdpi/ic_notification.png" />
<resource-file src="res/android/drawable-xxhdpi/ic_notification.png" target="app/src/main/res/drawable-xxhdpi/ic_notification.png" />
<resource-file src="src/android/BackgroundFetchHeadlessTask.java" target="app/src/main/java/com/transistorsoft/cordova/backgroundfetch/BackgroundFetchHeadlessTask.java" />
<splash density="port-ldpi" src="res/screen/android/splash-port-ldpi.png" />
<splash density="port-mdpi" src="res/screen/android/splash-port-mdpi.png" />
<splash density="port-hdpi" src="res/screen/android/splash-port-hdpi.png" />
@ -57,13 +66,13 @@
<splash density="land-xxxhdpi" src="res/screen/android/splash-land-xxxhdpi.png" />
</platform>
<preference name="AutoHideSplashScreen" value="false" />
<plugin name="cordova-plugin-add-swift-support" spec="^1.7.1" />
<plugin name="cordova-plugin-whitelist" spec="^1.3.2" />
<plugin name="cordova-plugin-headercolor" spec="^1.0.0" />
<plugin name="cordova-plugin-app-version" spec="^0.1.9" />
<plugin name="cordova-plugin-file" spec="^6.0.1" />
<plugin name="cordova-plugin-headercolor" spec="^1.0.0" />
<plugin name="cordova-plugin-statusbar" spec="^2.4.1" />
<plugin name="cordova-plugin-whitelist" spec="^1.3.2" />
<plugin name="cordova-plugin-add-swift-support" spec="^1.7.1" />
<plugin name="cordova-plugin-zeroconf" spec="^1.3.1" />
<plugin name="cordova-plugin-statusbar" spec="^2.4.1" />
<plugin name="phonegap-plugin-barcodescanner" spec="^7.1.0">
<variable name="ANDROID_SUPPORT_V4_VERSION" value="27.+" />
</plugin>
@ -72,5 +81,9 @@
<plugin name="cordova-plugin-dialogs" spec="^2.0.1" />
<plugin name="cordova-plugin-inappbrowser" spec="^2.0.2" />
<plugin name="cordova-plugin-splashscreen" spec="^5.0.2" />
<engine name="android" spec="^7.1.0" />
<plugin name="cordova-plugin-nativestorage" spec="^2.3.2" />
<plugin name="cordova-plugin-local-notification" spec="^0.9.0-beta.2" />
<plugin name="cordova-plugin-background-fetch" spec="^5.4.1" />
<engine name="browser" spec="^5.0.4" />
<engine name="android" spec="^7.1.2" />
</widget>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 25 KiB

@ -46,7 +46,7 @@ made subject to such option by the copyright holder.
<!--
Generated file; DO NOT EDIT.
-->
<project name="BusinessMobile" basedir="..">
<project name="NetsymsMobile" basedir="..">
<property file="nbproject/configs/${config}.properties" />
<scriptdef name="checkVersion" language="javascript">
@ -59,7 +59,7 @@ made subject to such option by the copyright holder.
}
]]>
</scriptdef>
<scriptdef name="forDevice" language="javascript">
<![CDATA[
var dev = project.getProperty("device");
@ -77,7 +77,7 @@ made subject to such option by the copyright holder.
</or>
</condition>
</target>
<target name="upgrade-to-cordova-project" depends="check-cordova-project,check-cordova-version" unless="cordova.project">
<echo level="info" message="${cordova.command} -d create ${java.io.tmpdir}/nb_temp_project com.coolappz.${project.name} ${project.name}" />
<delete dir="${java.io.tmpdir}/nb_temp_project"/>
@ -85,8 +85,8 @@ made subject to such option by the copyright holder.
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/>
<arg value="create"/>
<arg value="${java.io.tmpdir}/nb_temp_project"/>
<arg value="create"/>
<arg value="${java.io.tmpdir}/nb_temp_project"/>
<arg value="com.coolappz.${project.name}"/>
<arg value="${project.name}" />
</exec>
@ -106,8 +106,8 @@ made subject to such option by the copyright holder.
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/>
<arg value="create"/>
<arg value="www_nb_temp"/>
<arg value="create"/>
<arg value="www_nb_temp"/>
<arg value="com.coolappz.${project.name}"/>
<arg value="${project.name}" />
</exec>
@ -117,26 +117,26 @@ made subject to such option by the copyright holder.
<delete dir="www_nb_temp"/>
<delete file="www/config.xml"/>
</target>
<taskdef
classname="org.netbeans.modules.cordova.updatetask.ReadConfigTask"
<taskdef
classname="org.netbeans.modules.cordova.updatetask.ReadConfigTask"
classpath="${update.task.jar}"
name="readconfig"/>
<taskdef
classname="org.netbeans.modules.cordova.updatetask.PluginTask"
<taskdef
classname="org.netbeans.modules.cordova.updatetask.PluginTask"
classpath="${update.task.jar}"
name="plugintask"/>
<target name="check-cordova-version">
<property environment="env"/>
<property environment="env"/>
<checkVersion first="${cordova.version}" property="cordova.ver.3"/>
<fail message="Cordova version 3 or greater required." unless="cordova.ver.3"/>
<readconfig/>
<forDevice/>
</target>
<target name="check-android-template">
<available file="platforms/android" property="android.generated.exists"/>
</target>
@ -144,27 +144,27 @@ made subject to such option by the copyright holder.
<target name="check-ios-template">
<available file="platforms/ios" property="ios.generated.exists"/>
</target>
<target name="create-android" depends="check-android-template,check-cordova-version,upgrade-to-cordova-project" unless="android.generated.exists">
<echo level="info" message="${cordova.command} -d platform add android"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/>
<arg value="platform"/>
<arg value="add"/>
<arg value="platform"/>
<arg value="add"/>
<arg value="android"/>
</exec>
</target>
<target name="create-ios" depends="check-ios-template,check-cordova-version,upgrade-to-cordova-project" unless="ios.generated.exists">
<echo level="info" message="${cordova.command} -d platform add ios"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" dir="." failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/>
<arg value="platform"/>
<arg value="add"/>
<arg value="platform"/>
<arg value="add"/>
<arg value="ios"/>
</exec>
</target>
@ -178,23 +178,23 @@ made subject to such option by the copyright holder.
<exec executable="xcodebuild" dir="platforms/ios" failonerror="true">
<arg value="-project"/>
<arg value="${project.name}.xcodeproj"/>
<arg value="ARCHS=${ios.build.arch}"/>
<arg value="ARCHS=${ios.build.arch}"/>
<arg value="-target"/>
<arg value="${project.name}"/>
<arg value="-configuration"/>
<arg value="-configuration"/>
<arg value="Release"/>
<arg value="-sdk"/>
<arg value="-sdk"/>
<arg value="${ios.build.sdk}" />
<arg value="build"/>
<arg value="CONFIGURATION_BUILD_DIR=${path}"/>
</exec>
</target>
<target name="build-ios-ipa" if="build.for.device">
<exec executable="xcrun" dir="platforms/ios/build" failonerror="true">
<env key="CODESIGN_ALLOCATE" value="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate" />
<arg value="-sdk"/>
<arg value="${ios.build.sdk}" />
<arg value="${ios.build.sdk}" />
<arg value="PackageApplication"/>
<arg value="-v"/>
<arg value="${project.name}.app"/>
@ -208,15 +208,15 @@ made subject to such option by the copyright holder.
<available file="${basedir}/platforms/ios/build/${project.name}.ipa" property="ipa.found"/>
<fail unless="ipa.found" message="PackageApplication failed."/>
</target>
<target name="sim-ios" depends="build-ios,ios-run-device,ios-run-simulator">
</target>
<target name="ios-run-device" if="build.for.device">
<echo>
Install "${basedir}/platforms/ios/build/${project.name}.ipa" through iTunes and run it.
</echo>
Install "${basedir}/platforms/ios/build/${project.name}.ipa" through iTunes and run it.
</echo>
<exec executable="open" failonerror="true">
<arg value="${basedir}/platforms/ios/build/${project.name}.ipa"/>
</exec>
@ -228,13 +228,13 @@ made subject to such option by the copyright holder.
</exec>
<exec executable="${ios.sim.exec}" dir="platforms/ios/build">
<arg line="launch ${project.name}.app ${ios.device.args} --exit"/>
</exec>
</exec>
</target>
<target name="update-plugins">
<plugintask/>
</target>
</target>
<target name="update-android">
<echo level="info" message="${cordova.command} prepare android"/>
@ -244,9 +244,9 @@ made subject to such option by the copyright holder.
<arg value="prepare"/>
<arg value="android"/>
</exec>
</target>
</target>
<target name="update-ios">
<echo level="info" message="${cordova.command} prepare ios"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
@ -255,21 +255,21 @@ made subject to such option by the copyright holder.
<arg value="prepare"/>
<arg value="ios"/>
</exec>
</target>
<target name="rebuild-android" depends="clean-android,build-android"/>
</target>
<target name="rebuild-android" depends="clean-android,build-android"/>
<target name="build-android" depends="create-android,update-plugins">
<echo level="info" message="${cordova.command} -d build android"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
<env key="${cordova.path.key}" path="${cordova.path.value}:${android.sdk.home}/tools:${android.sdk.home}/platform-tools:${jdk.home}/bin:${ant.home}/bin:${jdk.home}/bin"/>
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/>
<arg value="build"/>
<arg value="android"/>
<arg value="-d"/>
<arg value="build"/>
<arg value="android"/>
</exec>
</target>
</target>
<target name="sim-android" depends="create-android,update-plugins">
<echo level="info" message="${cordova.command} -d ${android.target.device.arg} android"/>
<exec executable="${cordova.command}" resolveexecutable="true" searchpath="true" failonerror="true">
@ -277,16 +277,16 @@ made subject to such option by the copyright holder.
<env key="JAVA_HOME" path="${jdk.home}"/>
<arg value="-d"/>
<arg value="${android.target.device.arg}"/>
<arg value="android"/>
<arg value="android"/>
</exec>
</target>
<target name="clean-android" depends="check-android-template" if="android.generated.exists">
<exec executable="./gradlew" dir="platforms/android">
<arg value="clean" />
</exec>
</target>
<target name="clean-ios" depends="check-ios-template" if="ios.generated.exists">
<exec executable="platforms/ios/cordova/clean" />
</target>

@ -9,4 +9,7 @@ cordova-plugin-headercolor=https://github.com/tomloprod/cordova-plugin-headercol
cordova-plugin-inappbrowser=https://github.com/apache/cordova-plugin-inappbrowser.git
cordova-plugin-app-version=https://github.com/whiteoctober/cordova-plugin-app-version.git
cordova-plugin-zeroconf=https://github.com/becvert/cordova-plugin-zeroconf.git
cordova-plugin-file=https://github.com/apache/cordova-plugin-file.git
cordova-plugin-file=https://github.com/apache/cordova-plugin-file.git
cordova-plugin-local-notification=https://github.com/katzer/cordova-plugin-local-notifications.git
cordova-plugin-background-fetch=https://github.com/transistorsoft/cordova-plugin-background-fetch.git
cordova-plugin-nativestorage=https://github.com/TheCocoaProject/cordova-plugin-nativestorage.git

@ -1,8 +1,8 @@
auxiliary.org-netbeans-modules-cordova.cordova_5f_build_5f_script_5f_version=52
auxiliary.org-netbeans-modules-cordova.phonegap=false
file.reference.BusinessMobile-test=test
file.reference.BusinessMobile-www=www
file.reference.NetsymsMobile-test=test
file.reference.NetsymsMobile-www=www
files.encoding=UTF-8
project.licensePath=./nbproject/mplheader.txt
site.root.folder=${file.reference.BusinessMobile-www}
test.folder=${file.reference.BusinessMobile-test}
project.licensePath=nbproject/mplheader.txt
site.root.folder=${file.reference.NetsymsMobile-www}
test.folder=${file.reference.NetsymsMobile-test}

@ -3,7 +3,7 @@
<type>org.netbeans.modules.web.clientproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/clientside-project/1">
<name>BusinessMobile</name>
<name>NetsymsMobile</name>
</data>
</configuration>
</project>

@ -1,15 +1,18 @@
{
"name": "com.netsyms.BusinessMobile",
"displayName": "Business for Mobile",
"version": "1.5.0",
"description": "Mobile client for the Netsyms Business Apps.",
"name": "com.netsyms.apps.Mobile",
"displayName": "Netsyms Apps for Mobile",
"version": "2.0.1",
"description": "Securely use the Netsyms Apps from your phone or tablet.",
"main": "index.html",
"author": "Netsyms Technologies",
"license": "MPL-2.0",
"dependencies": {
"cordova-android": "^7.1.0",
"cordova-android": "^7.1.2",
"cordova-browser": "^5.0.4",
"cordova-plugin-add-swift-support": "^1.7.1",
"cordova-plugin-app-version": "^0.1.9",
"cordova-plugin-background-fetch": "^5.4.1",
"cordova-plugin-badge": "^0.8.7",
"cordova-plugin-console": "^1.1.0",
"cordova-plugin-device": "^2.0.1",
"cordova-plugin-dialog": "0.0.1",
@ -17,6 +20,8 @@
"cordova-plugin-file": "^6.0.1",
"cordova-plugin-headercolor": "^1.0.0",
"cordova-plugin-inappbrowser": "^2.0.2",
"cordova-plugin-local-notification": "^0.9.0-beta.2",
"cordova-plugin-nativestorage": "^2.3.2",
"cordova-plugin-splashscreen": "^5.0.2",
"cordova-plugin-statusbar": "^2.4.1",
"cordova-plugin-whitelist": "^1.3.2",
@ -39,9 +44,13 @@
"cordova-plugin-device": {},
"cordova-plugin-dialogs": {},
"cordova-plugin-inappbrowser": {},
"cordova-plugin-splashscreen": {}
"cordova-plugin-splashscreen": {},
"cordova-plugin-nativestorage": {},
"cordova-plugin-local-notification": {},
"cordova-plugin-background-fetch": {}
},
"platforms": [
"browser",
"android"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1,23 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="60"
android:viewportHeight="60">
<group android:translateX="6"
android:translateY="6">
<path
android:pathData="M0,0h48v48h-48z"
android:strokeAlpha="0"
android:strokeWidth="8.06694221"
android:fillColor="#0d87f6"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="m18.9031,9.2872c-0.1596,0.014 -0.3055,0.044 -0.4348,0.093 -2.0694,0.7831 -4.1011,7.8462 -5.0107,9.8633 -0.9096,2.017 -4.8582,8.2167 -4.0752,10.2861 0.7831,2.0694 7.8463,4.1011 9.8633,5.0106 2.0171,0.9097 8.2167,4.8583 10.2861,4.0752 2.0694,-0.7831 4.1011,-7.8462 5.0107,-9.8632 0.9096,-2.0171 4.8583,-8.2168 4.0752,-10.2862 -0.7831,-2.0694 -7.8462,-4.1011 -9.8633,-5.0106 -1.8909,-0.8528 -7.4577,-4.3768 -9.8513,-4.1686z"
android:strokeAlpha="1"
android:strokeWidth="0.61330891"
android:fillColor="#0d87f6"
android:strokeColor="#ffffff"
android:fillAlpha="1"/>
</group>
</vector>

@ -1,44 +1,44 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="798.444"
android:viewportHeight="792.0944">
<group android:translateX="206.33473"
android:translateY="194.06314">
<path
android:pathData="M111.7,150.1L172,150.1A12.9,12.9 60.8,0 1,184.8 162.9L184.8,391.1A12.9,12.9 0,0 1,172 404L111.7,404A12.9,12.9 130.2,0 1,98.9 391.1L98.9,162.9A12.9,12.9 52.1,0 1,111.7 150.1z"
android:strokeColor="#00000000"
android:fillAlpha="0.39215686"
android:fillColor="#ffffff"
android:strokeWidth="5"
android:strokeAlpha="1"/>
<path
android:pathData="M212.8,211.2L273,211.2A12.9,12.9 60.8,0 1,285.8 224L285.8,391.1A12.9,12.9 0,0 1,273 404L212.8,404A12.9,12.9 119.2,0 1,199.9 391.1L199.9,224A12.9,12.9 0,0 1,212.8 211.2z"
android:strokeColor="#00000000"
android:fillAlpha="0.39215686"
android:fillColor="#ffffff"
android:strokeWidth="5"
android:strokeAlpha="1"/>
<path
android:pathData="M12.9,262.7L73.1,262.7A12.9,12.9 128.5,0 1,85.9 275.5L85.9,391.1A12.9,12.9 128.5,0 1,73.1 404L12.9,404A12.9,12.9 129.4,0 1,-0 391.1L-0,275.5A12.9,12.9 129.4,0 1,12.9 262.7z"
android:strokeColor="#00000000"
android:fillAlpha="0.39215686"
android:fillColor="#ffffff"
android:strokeWidth="5"
android:strokeAlpha="1"/>
<path
android:pathData="M312.7,-0L372.9,-0A12.9,12.9 53.5,0 1,385.8 12.9L385.8,391.1A12.9,12.9 0,0 1,372.9 404L312.7,404A12.9,12.9 0,0 1,299.9 391.1L299.9,12.9A12.9,12.9 53.5,0 1,312.7 -0z"
android:strokeColor="#00000000"
android:fillAlpha="0.39215686"
android:fillColor="#ffffff"
android:strokeWidth="5"
android:strokeAlpha="1"/>
<path
android:pathData="m147.8,51.5a18.8,18.8 108.7,0 0,-18.8 18.7,18.8 18.8,58.3 0,0 2.3,9L57.3,263.8a18.8,18.8 59.3,0 0,-15.9 18.5,18.8 18.8,0 0,0 18.7,18.8 18.8,18.8 78.9,0 0,18.8 -18.7,18.8 18.8,59.3 0,0 -4,-11.6l71.6,-179 76,230a18.8,18.8 110.6,0 0,-4.3 11.9,18.8 18.8,122.9 0,0 18.7,18.8 18.8,18.8 74.2,0 0,18.8 -18.7,18.8 18.8,60.9 0,0 -6,-13.7L327,146.7a18.8,18.8 0,0 0,17.4 -18.7,18.8 18.8,61.1 0,0 -18.7,-18.8 18.8,18.8 61.1,0 0,-18.8 18.7,18.8 18.8,108.7 0,0 3.1,10.4L236.5,303.5 163,81.1a18.8,18.8 104.1,0 0,3.5 -10.8,18.8 18.8,108.7 0,0 -18.7,-18.8z"
android:fillAlpha="1"
android:strokeColor="#d8edff"
android:fillColor="#d8edff"
android:strokeWidth="6.59239769"
android:strokeAlpha="1"/>
android:viewportWidth="1163.6364"
android:viewportHeight="1163.6364">
<group android:translateX="325.81818"
android:translateY="325.81818">
<path
android:pathData="m198.563,65.838c-0.615,0 -1.144,-0 -1.572,0.158 -3.427,1.296 -6.794,12.993 -8.3,16.335 -1.506,3.341 -8.046,13.593 -6.749,17.021 1.297,3.426 12.995,6.793 16.335,8.3 3.341,1.506 13.615,8.046 17.042,6.749 3.427,-1.296 6.794,-12.995 8.3,-16.335 1.506,-3.342 8.046,-13.614 6.749,-17.042 -1.297,-3.427 -12.992,-6.794 -16.332,-8.3 -2.923,-1.318 -11.166,-6.475 -15.473,-6.883zM151.95,146.228c-0.615,0 -1.144,-0 -1.572,0.158 -3.427,1.296 -6.794,12.991 -8.3,16.332 -1.506,3.34 -8.046,13.594 -6.749,17.021 1.297,3.428 12.995,6.794 16.335,8.3 3.341,1.506 13.593,8.049 17.021,6.752 3.427,-1.298 6.794,-12.994 8.3,-16.335 1.506,-3.34 8.046,-13.614 6.749,-17.042 -1.297,-3.428 -12.995,-6.794 -16.335,-8.3 -2.923,-1.318 -11.142,-6.475 -15.448,-6.883zM237.163,147.843c-0.615,0 -1.141,0.013 -1.569,0.137 -3.427,1.296 -6.794,12.991 -8.3,16.332 -1.506,3.34 -8.049,13.617 -6.752,17.045 1.297,3.427 12.995,6.79 16.335,8.297 3.341,1.506 13.593,8.049 17.021,6.752 3.427,-1.296 6.794,-12.993 8.3,-16.335 1.506,-3.341 8.046,-13.614 6.749,-17.042 -1.297,-3.427 -12.992,-6.794 -16.332,-8.3 -2.923,-1.319 -11.145,-6.487 -15.452,-6.883zM422.045,160.701c-0.615,0 -1.144,0.013 -1.572,0.137 -3.427,1.298 -6.794,12.992 -8.3,16.332 -1.506,3.341 -8.046,13.618 -6.749,17.045 1.297,3.427 12.995,6.794 16.335,8.3 3.341,1.507 13.615,8.046 17.042,6.749 3.427,-1.296 6.794,-12.992 8.3,-16.332 1.506,-3.341 8.049,-13.618 6.752,-17.045 -1.297,-3.427 -12.995,-6.793 -16.335,-8.3 -2.923,-1.318 -11.166,-6.475 -15.473,-6.883zM240.757,227.406c-0.615,0 -1.141,0.01 -1.569,0.134 -3.427,1.298 -6.794,12.996 -8.3,16.338 -1.506,3.34 -8.049,13.614 -6.752,17.042 1.297,3.426 12.995,6.794 16.335,8.3 3.341,1.506 13.615,8.047 17.042,6.749 3.427,-1.296 6.794,-12.995 8.3,-16.335 1.506,-3.341 8.049,-13.616 6.752,-17.042 -1.297,-3.428 -12.995,-6.793 -16.335,-8.3 -2.923,-1.318 -11.166,-6.475 -15.473,-6.883zM113.407,226.65c-0.615,0 -1.165,-0 -1.594,0.158 -3.427,1.296 -6.794,12.993 -8.3,16.335 -1.506,3.341 -8.025,13.594 -6.728,17.021 1.297,3.427 12.992,6.792 16.332,8.3 3.341,1.506 13.593,8.046 17.021,6.749 3.427,-1.296 6.794,-12.991 8.3,-16.332 1.506,-3.341 8.049,-13.596 6.752,-17.024 -1.297,-3.427 -12.995,-6.79 -16.335,-8.297 -2.923,-1.317 -11.142,-6.511 -15.448,-6.908zM385.081,239.476c-0.615,0 -1.165,-0 -1.594,0.158 -3.427,1.298 -6.794,12.991 -8.3,16.332 -1.506,3.34 -8.025,13.593 -6.728,17.021 1.297,3.427 12.995,6.794 16.335,8.3 3.341,1.507 13.593,8.05 17.021,6.752 3.427,-1.298 6.794,-12.994 8.3,-16.335 1.506,-3.34 8.046,-13.594 6.749,-17.021 -1.297,-3.428 -12.992,-6.794 -16.332,-8.3 -2.923,-1.319 -11.145,-6.508 -15.451,-6.905zM74.772,311.831c-0.615,0 -1.144,0.01 -1.572,0.134 -3.427,1.298 -6.794,12.994 -8.3,16.335 -1.506,3.34 -8.049,13.614 -6.752,17.042 1.297,3.428 12.995,6.794 16.335,8.3 3.341,1.506 13.618,8.049 17.045,6.752 3.427,-1.298 6.794,-12.994 8.3,-16.335 1.506,-3.34 8.025,-13.615 6.728,-17.042 -1.297,-3.428 -12.995,-6.794 -16.335,-8.3 -2.923,-1.319 -11.142,-6.475 -15.448,-6.883zM253.233,311.831c-0.615,0 -1.144,0.01 -1.572,0.134 -3.427,1.298 -6.794,12.994 -8.3,16.335 -1.506,3.34 -8.046,13.614 -6.749,17.042 1.297,3.428 12.995,6.794 16.335,8.3 3.341,1.506 13.615,8.049 17.042,6.752 3.427,-1.298 6.794,-12.994 8.3,-16.335 1.506,-3.34 8.046,-13.615 6.749,-17.042 -1.297,-3.428 -12.992,-6.794 -16.332,-8.3 -2.923,-1.319 -11.166,-6.475 -15.473,-6.883zM338.482,317.478c-0.615,0 -1.144,0.013 -1.572,0.137 -3.427,1.298 -6.794,12.994 -8.3,16.335 -1.506,3.341 -8.046,13.614 -6.749,17.042 1.297,3.426 12.995,6.794 16.335,8.3 3.341,1.506 13.615,8.05 17.042,6.752 3.427,-1.296 6.794,-12.995 8.3,-16.335 1.506,-3.341 8.046,-13.616 6.749,-17.042 -1.297,-3.428 -12.992,-6.792 -16.332,-8.3 -2.923,-1.317 -11.166,-6.475 -15.473,-6.883zM298.975,397.426c-0.615,0 -1.165,-0 -1.594,0.158 -3.427,1.298 -6.794,12.994 -8.3,16.335 -1.506,3.341 -8.049,13.594 -6.752,17.021 1.297,3.427 12.995,6.794 16.335,8.3 3.341,1.506 13.618,8.05 17.045,6.752 3.427,-1.296 6.794,-12.995 8.3,-16.335 1.506,-3.341 8.046,-13.594 6.749,-17.021 -1.297,-3.428 -12.995,-6.794 -16.335,-8.3 -2.923,-1.318 -11.142,-6.511 -15.448,-6.908z"
android:strokeAlpha="1"
android:strokeWidth="11.33235741"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M-2521.377,-590.781l531.981,230.764l-141.472,326.136l-531.981,-230.764z"
android:strokeAlpha="1"
android:strokeWidth="11.87444973"
android:fillColor="#78bff8"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M-1810.385,-660.711l-531.981,-230.764l141.472,-326.136l531.981,230.764z"
android:strokeAlpha="1"
android:strokeWidth="11.87444973"
android:fillColor="#78bff8"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M-2146.024,-292.892l230.764,-531.981l326.136,141.472l-230.764,531.981z"
android:strokeAlpha="1"
android:strokeWidth="11.87444973"
android:fillColor="#78bff8"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M-2786.024,-572.892l230.764,-531.981l326.136,141.472l-230.764,531.981z"
android:strokeAlpha="1"
android:strokeWidth="11.87444973"
android:fillColor="#78bff8"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
</group>
</vector>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
</adaptive-icon>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#2196F3</color>
</resources>

@ -0,0 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="app_name">Netsyms</string>
<string name="launcher_name">@string/app_name</string>
<string name="activity_name">@string/launcher_name</string>
</resources>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 57 KiB

@ -0,0 +1,171 @@
package com.transistorsoft.cordova.backgroundfetch;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Build;
import android.provider.Settings;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.netsyms.apps.Mobile.MainActivity;
import com.netsyms.apps.Mobile.R;
import com.transistorsoft.tsbackgroundfetch.BackgroundFetch;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class BackgroundFetchHeadlessTask implements HeadlessTask {
private static final String PREFS_NAME = "NativeStorage";
private static final String KEY = "accounts";
private static String shownNotifications = "";
public final String NOTIFICATION_CHANNEL_ID = "background-channel-id";
public static String getValue(Context context, String key, String defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, Activity.MODE_PRIVATE);
return settings.getString(key, defaultValue);
}
/**
* https://stackoverflow.com/a/34691486
*
* @param urlString
* @return
* @throws IOException
*/
public static String getStringFromURL(String urlString) throws IOException {
HttpURLConnection urlConnection = null;
URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setDoOutput(true);
urlConnection.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
String jsonString = sb.toString();
return jsonString;
}
@Override
public void onFetch(Context context) {
Log.d(BackgroundFetch.TAG, "Notification Poller: onFetch");
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
String accountjson = getValue(context, KEY, null).replaceAll("\\\\", "");
accountjson = accountjson.substring(1, accountjson.length() - 1);
//Log.d(BackgroundFetch.TAG, "Notification Poller: Account JSON: " + accountjson);
try {
JSONArray accounts = new JSONArray(accountjson);
for (int i = 0; i < accounts.length(); i++) {
try {
JSONObject acct = accounts.getJSONObject(i);
Log.d(BackgroundFetch.TAG, "Notification Poller: Account " + i + " URL: " + acct.getString("syncurl"));
String notificationString = getStringFromURL(acct.getString("syncurl") + "?key=" + acct.getString("key") + "&username=" + acct.getString("username") + "&action=checknotifications");
//Log.d(BackgroundFetch.TAG, "Notification Poller: Account " + i + " JSON: " + notificationString);
JSONArray notifications = new JSONObject(notificationString).getJSONArray("notifications");
Log.d(BackgroundFetch.TAG, "Notification Poller: Account " + i + " JSON parsed: " + notifications.length() + " notifications");
for (int j = 0; j < notifications.length(); j++) {
JSONObject notif = notifications.getJSONObject(j);
Log.d(BackgroundFetch.TAG, "Notification Poller: Procesing notification ID " + notif.getString("id") + " with title " + notif.getString("title"));
if (notif.getBoolean("seen") || shownNotifications.contains("|" + i + ":" + notif.getString("id") + "|")) {
continue;
}
Intent intent = new Intent(context, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder b = new NotificationCompat.Builder(context);
b.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(notif.getString("title"))
.setContentText(notif.getString("content"))
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.setContentIntent(contentIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setVisibility(Notification.VISIBILITY_PRIVATE);
// Create alternate notification for lockscreen
NotificationCompat.Builder lockb = new NotificationCompat.Builder(context);
if (notif.getBoolean("sensitive") == true) {
lockb
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("Contents hidden")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
} else {
lockb
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(notif.getString("title"))
.setContentText(notif.getString("content"))
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
}
b.setPublicVersion(lockb.build());
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Background Notifications";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, name, importance);
channel.enableLights(true);
channel.enableVibration(true);
channel.setLightColor(Color.rgb(33, 150, 243));
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
b.setChannelId(NOTIFICATION_CHANNEL_ID);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(Integer.parseInt(notif.getString("id")), b.build());
Log.d(BackgroundFetch.TAG, "Notification Poller: Shown notification " + notif.getString("id"));
shownNotifications += "|" + i + ":" + notif.getString("id") + "|";
}
} catch (Exception e) {
Log.d(BackgroundFetch.TAG, "Notification Poller: Exception: " + e.getMessage());
Log.d(BackgroundFetch.TAG, "Notification Poller: Stack trace: " + Log.getStackTraceString(e));
}
}
} catch (Exception e) {
Log.d(BackgroundFetch.TAG, "Notification Poller: Exception: " + e.getMessage());
Log.d(BackgroundFetch.TAG, "Notification Poller: Stack trace: " + Log.getStackTraceString(e));
} finally {
BackgroundFetch.getInstance(context).finish();
}
}
}
);
thread.start();
}
}

@ -15,6 +15,12 @@
display: initial;
}
@media screen and (max-width: 767px) {
#navbar-collapse {
display: none;
}
}
#swipe-nav {
display: none;
visibility: visible;
@ -72,4 +78,42 @@
left: 0;
background-color: rgba(0,0,0,0.5);
z-index: 9999998;
}
#swipe-nav .swipe-list {
margin-top: 5px;
margin-bottom: 10px;
padding-left: 0px;
list-style-type: none;
padding: 3px;
}
#swipe-nav .swipe-list .nav-item {
color: #424242;
padding-top: 5px;
padding-bottom: 5px;
}
#swipe-nav .swipe-list .nav-item a:focus,a:active {
background-color: #e0e0e0;
}
#swipe-nav .swipe-list .nav-item i.fa {
font-size: 120%;
margin-right: 10px;
margin-left: 5px;
}
#swipe-nav .swipe-list .nav-item a {
display: inline-block;
color: #424242;
font-size: 110%;
text-decoration: none;
width: 100%;
padding-top: 15px;
padding-bottom: 15px;
}
#swipe-nav .swipe-list .nav-item a:hover {
text-decoration: none;
}

@ -1,148 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
html, body {
height: 100%;
}
.app-dock-container {
display: flex;
height: 100%;
}
.app-dock {
margin: 0 auto 10px auto;
display: flex;
justify-content: space-evenly;
flex-wrap: wrap;
align-items: center;
justify-content: center;
height: 100%;
}
.app-icon {
border: 1px solid grey;
border-radius: 20%;
}
.app-dock-item {
padding: 0px 10px 2px 10px;
min-width: 100px;
max-width: 50%;
width: 120px;
margin: 15px;
}
.app-dock-item p {
margin-bottom: 0px;
font-size: 120%;
color: #555;
}
.app-dock-item p img {
width: 80px;
height: 80px;
display: block;
background: url(../img/app-icon-bg.svg) no-repeat;
background-size: 90%;
background-position: 50%;
margin: 0 auto;
}
.app-dock-item p span {
display: block;
text-align: center;
}
/* https://stackoverflow.com/a/23536146 */
.navbar-collapse.collapse {
display: block!important;
}
.navbar-nav>li, .navbar-nav {
float: left !important;
}
.navbar-nav.navbar-right:last-child {
margin-right: -15px !important;
}
.navbar-right {
float: right!important;
}
/* /stackoverflow */
.nav {
color: white;
margin-right: 0px;
height: 30px;
margin-top: -4px;
font-size: 20px;
margin-left: 5px;
}
.navbar-right span {
color: white;
font-size: 18px;
margin-top: -4px;
}
.navbar-brand img {
margin-right: 15px;
height: 30px;
margin-top: -4px;
margin-left: -10px;
display: inline-block;
}
.navbar-right li a img {
height: 30px;
margin-top: 6px;
display: inline-block;
}
@media (min-width: 768px) {
.navbar-right {
margin-top: -6px;
}
.navbar-right li a img {
margin-top: -1px;
}
}
#manual_setup {
margin-top: 15px;
}
#navbar {
min-height: 56px;
}
.loading-text {
font-size: 18px;
}
.circle-btn {
display: flex;
align-items: center;
justify-content: center;
align-content: center;
border-radius: 50%;
height: 5rem;
width: 5rem;
position: fixed;
bottom: 0;
right: 0;
margin: 2rem;
z-index: 99999;
}
.circle-btn img {
height: 3rem;
width: 3rem;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,14 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
A tiny bit of CSS to inject into apps even if injectcode = false.
This hides items in the app with the class mobile-app-hide.
*/
.mobile-app-hide {
display: none;
visibility: hidden;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -1,29 +0,0 @@
/*
Roboto font family
Downloaded from Google Web Fonts
Apache 2.0 License
*/
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(../fonts/Roboto-Light.ttf) format('truetype');
}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(../fonts/Roboto-Regular.ttf) format('truetype');
}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 500;
src: local('Roboto Medium'), local('Roboto-Medium'), url(../fonts/Roboto-Medium.ttf) format('truetype');
}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 700;
src: local('Roboto Bold'), local('Roboto-Bold'), url(../fonts/Roboto-Bold.ttf) format('truetype');
}

@ -1,76 +0,0 @@
/*
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
@media screen and (max-width: 767px) {
.navbar, .navbar-brand {
min-height: 56px;
height: 56px;
}
.navbar-brand {
font-size: 20px;
margin-top: -4px;
}
.navbar-toggle {
border: 0px solid white;
margin-top: 11px;
margin-bottom: 11px;
}
#navbar-collapse {
display: none;
}
button.navbar-toggle[data-toggle="collapse"] {
float: left;
margin-left: 15px;
}
.navbar-header .navbar-brand {
margin-left: -20px;
}
.navbar-header .navbar-brand img {
display: none;
}
}
#swipe-nav ul {
margin-bottom: 10px;
padding-left: 2px;
list-style-type: none;
padding: 3px;
}
#swipe-nav ul li {
color: #424242;
padding-top: 5px;
padding-bottom: 5px;
}
#swipe-nav ul li a:focus,a:active {
background-color: #e0e0e0;
}
#swipe-nav ul li i.fa {
font-size: 120%;
margin-right: 10px;
margin-left: 5px;
}
#swipe-nav ul li a {
display: inline-block;
color: #424242;
font-size: 110%;
text-decoration: none;
width: 100%;
padding-top: 10px;
padding-bottom: 10px;
}
#swipe-nav ul li a:hover {
text-decoration: none;
}

@ -1,48 +0,0 @@
/*
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
@media screen and (max-width: 767px) {
#navbar-collapse {
display: none;
}
}
#swipe-nav .swipe-list {
margin-top: 5px;
margin-bottom: 10px;
padding-left: 0px;
list-style-type: none;
padding: 3px;
}
#swipe-nav .swipe-list .nav-item {
color: #424242;
padding-top: 5px;
padding-bottom: 5px;
}
#swipe-nav .swipe-list .nav-item a:focus,a:active {
background-color: #e0e0e0;
}
#swipe-nav .swipe-list .nav-item i.fa {
font-size: 120%;
margin-right: 10px;
margin-left: 5px;
}
#swipe-nav .swipe-list .nav-item a {
display: inline-block;
color: #424242;
font-size: 110%;
text-decoration: none;
width: 100%;
padding-top: 15px;
padding-bottom: 15px;
}
#swipe-nav .swipe-list .nav-item a:hover {
text-decoration: none;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,31 @@
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: local('Material Icons'),
local('MaterialIcons-Regular'),
url(./MaterialIcons-Regular.woff2) format('woff2'),
url(./MaterialIcons-Regular.woff) format('woff');
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px; /* Preferred icon size */
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
/* Support for Firefox. */
-moz-osx-font-smoothing: grayscale;
}

@ -1,4 +0,0 @@
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>

Before

Width:  |  Height:  |  Size: 199 B

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
fill="#000000"
height="24"
viewBox="0 0 24 24"
width="24"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="ic_arrow-back.svg">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="640"
inkscape:window-height="480"
id="namedview8"
showgrid="false"
inkscape:zoom="10.125"
inkscape:cx="-6.0246914"
inkscape:cy="11.802469"
inkscape:current-layer="svg2" />
<path
d="M0 0h24v24H0z"
fill="none"
id="path4" />
<path
d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"
id="path6"
style="fill:#ffffff;fill-opacity:1" />
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

@ -1,4 +0,0 @@
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M21 2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7v2H8v2h8v-2h-2v-2h7c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H3V4h18v12z"/>
</svg>

Before

Width:  |  Height:  |  Size: 274 B

@ -1,4 +0,0 @@
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/>
</svg>

Before

Width:  |  Height:  |  Size: 389 B

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
fill="#000000"
height="24"
viewBox="0 0 24 24"
width="24"
id="svg3421"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="ic_settings.svg">
<metadata
id="metadata3431">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs3429" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="640"
inkscape:window-height="480"
id="namedview3427"
showgrid="false"
inkscape:zoom="33.083333"
inkscape:cx="11.969773"
inkscape:cy="12"
inkscape:current-layer="svg3421" />
<path
d="M0 0h24v24H0z"
fill="none"
id="path3423" />
<path
d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"
id="path3425"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

@ -1,4 +0,0 @@
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M12.65 10C11.83 7.67 9.61 6 7 6c-3.31 0-6 2.69-6 6s2.69 6 6 6c2.61 0 4.83-1.67 5.65-4H17v4h4v-4h2v-4H12.65zM7 14c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/>
</svg>

Before

Width:  |  Height:  |  Size: 320 B

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="512" height="512" version="1.1" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -540.36)"><rect y="540.36" width="512" height="512" rx="50" ry="50" fill="#fff"/><g transform="translate(.61385 9.1477)"><g><rect x="145.69" y="726.61" width="100.27" height="296.34" rx="15" ry="15" fill="#1976d2"/><rect x="263.58" y="797.95" width="100.27" height="225" rx="15" ry="15" fill="#9e9e9e"/><rect x="30.27" y="858.02" width="100.27" height="164.93" rx="15" ry="15" fill="#9e9e9e"/><rect x="380.23" y="551.48" width="100.27" height="471.47" rx="15" ry="15" fill="#64b5f6"/></g><path transform="translate(0 540.36)" d="m195.89 55.102a24.749 24.749 0 0 0-24.816 24.682 24.749 24.749 0 0 0 3.0234 11.867l-97.42 243.43a24.749 24.749 0 0 0-21.021 24.383 24.749 24.749 0 0 0 24.68 24.816 24.749 24.749 0 0 0 24.816-24.682 24.749 24.749 0 0 0-5.2422-15.287l94.438-235.97 100.25 303.25a24.749 24.749 0 0 0-5.6309 15.625 24.749 24.749 0 0 0 24.68 24.816 24.749 24.749 0 0 0 24.816-24.68 24.749 24.749 0 0 0-7.8633-18.119l101.57-228.59a24.749 24.749 0 0 0 22.949-24.609 24.749 24.749 0 0 0-24.682-24.816 24.749 24.749 0 0 0-24.816 24.68 24.749 24.749 0 0 0 4.1055 13.689l-96.789 217.83-96.938-293.25a24.749 24.749 0 0 0 4.5781-14.248 24.749 24.749 0 0 0-24.682-24.816z" fill="#2196f3" stroke="#fff" stroke-width="7"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="512" height="512" version="1.1" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><rect y="-7.3828e-6" width="512" height="512" rx="70" ry="70" fill="#2196f3"/><path d="m198.56 65.838c-0.61516 0-1.1439-2.09e-4 -1.5723 0.15846-3.4273 1.2964-6.7936 12.993-8.3001 16.335-1.5064 3.3408-8.046 13.593-6.7492 17.021 1.2969 3.4258 12.995 6.7929 16.335 8.3001 3.3406 1.5061 13.615 8.0456 17.042 6.7492 3.4273-1.2964 6.7938-12.996 8.3001-16.335 1.5065-3.3419 8.0461-13.614 6.7492-17.042-1.297-3.4269-12.992-6.794-16.332-8.3001-2.9229-1.318-11.166-6.4753-15.473-6.8833zm-46.614 80.39c-0.61524 0-1.1438-1.9e-4 -1.5723 0.15845-3.4273 1.2964-6.7936 12.991-8.3001 16.332-1.5064 3.3397-8.046 13.594-6.7492 17.021 1.2969 3.428 12.995 6.794 16.335 8.3001 3.3406 1.5061 13.593 8.0486 17.021 6.7522 3.4273-1.2976 6.7938-12.994 8.3001-16.335 1.5065-3.3396 8.0461-13.614 6.7492-17.042-1.2969-3.428-12.995-6.794-16.335-8.3001-2.9229-1.318-11.142-6.4753-15.448-6.8832zm85.213 1.6149c-0.61515 0-1.1409 0.0125-1.5692 0.13713-3.4273 1.2964-6.7936 12.991-8.3001 16.332-1.5064 3.3396-8.049 13.617-6.7522 17.045 1.2969 3.4269 12.995 6.7898 16.335 8.2971 3.3405 1.5061 13.593 8.0486 17.021 6.7522 3.4272-1.2964 6.7937-12.993 8.3001-16.335 1.5065-3.3408 8.0461-13.614 6.7492-17.042-1.2969-3.4269-12.992-6.794-16.332-8.3001-2.9229-1.3191-11.145-6.4866-15.452-6.8832zm184.88 12.858c-0.61527 0-1.1439 0.0125-1.5723 0.13712-3.4273 1.2976-6.7936 12.992-8.3001 16.332-1.5064 3.3408-8.046 13.618-6.7492 17.045 1.2969 3.4269 12.995 6.794 16.335 8.3001 3.3406 1.5072 13.615 8.0456 17.042 6.7492 3.4273-1.2964 6.7937-12.992 8.3001-16.332 1.5065-3.3408 8.0492-13.618 6.7522-17.045-1.2969-3.4269-12.995-6.7929-16.335-8.3001-2.9229-1.318-11.166-6.4753-15.473-6.8832zm-181.29 66.705c-0.61513 0-1.1408 0.01-1.5692 0.13401-3.4273 1.2976-6.7937 12.996-8.3001 16.338-1.5064 3.3397-8.0491 13.614-6.7522 17.042 1.2969 3.4258 12.995 6.794 16.335 8.3001 3.3406 1.5061 13.615 8.0467 17.042 6.7492 3.4273-1.2964 6.7938-12.995 8.3001-16.335 1.5065-3.3408 8.0492-13.616 6.7522-17.042-1.2969-3.428-12.995-6.7929-16.335-8.3001-2.9229-1.318-11.166-6.4753-15.473-6.8832zm-127.35-0.75646c-0.61517 0-1.1652-2e-4 -1.5936 0.15845-3.4273 1.2964-6.7936 12.993-8.3001 16.335-1.5063 3.3408-8.0247 13.594-6.7279 17.021 1.297 3.4269 12.992 6.7918 16.332 8.3001 3.3405 1.5061 13.593 8.0456 17.021 6.7492 3.4273-1.2964 6.7937-12.991 8.3001-16.332 1.5065-3.3408 8.0492-13.596 6.7522-17.024-1.2969-3.4269-12.995-6.7899-16.335-8.2971-2.9229-1.3168-11.142-6.511-15.448-6.9076zm271.67 12.826c-0.61515 0-1.1652-2e-4 -1.5936 0.15845-3.4273 1.2976-6.7936 12.991-8.3001 16.332-1.5064 3.3396-8.0247 13.593-6.7278 17.021 1.297 3.4269 12.995 6.794 16.335 8.3001 3.3406 1.5072 13.593 8.0498 17.021 6.7522 3.4273-1.2976 6.7938-12.994 8.3001-16.335 1.5064-3.3397 8.0461-13.594 6.7492-17.021-1.2969-3.428-12.992-6.794-16.332-8.3001-2.9229-1.3191-11.145-6.5079-15.451-6.9046zm-310.31 72.355c-0.61524 0-1.1439 0.01-1.5723 0.13402-3.4273 1.2976-6.7936 12.994-8.3001 16.335-1.5064 3.3396-8.049 13.614-6.7522 17.042 1.297 3.428 12.995 6.794 16.335 8.3001 3.3406 1.5061 13.618 8.0486 17.045 6.7522 3.4273-1.2976 6.7938-12.994 8.3001-16.335 1.5065-3.3396 8.0248-13.615 6.7279-17.042-1.2969-3.428-12.995-6.794-16.335-8.3001-2.9229-1.3191-11.142-6.4753-15.448-6.8833zm178.46 0c-0.61524 0-1.1439 0.01-1.5723 0.13402-3.4273 1.2976-6.7936 12.994-8.3001 16.335-1.5064 3.3396-8.046 13.614-6.7492 17.042 1.2969 3.428 12.995 6.794 16.335 8.3001 3.3406 1.5061 13.615 8.0486 17.042 6.7522 3.4273-1.2976 6.7938-12.994 8.3001-16.335 1.5064-3.3396 8.0461-13.615 6.7492-17.042-1.2969-3.428-12.992-6.794-16.332-8.3001-2.9229-1.3191-11.166-6.4753-15.473-6.8833zm85.248 5.6469c-0.61526 0-1.1439 0.0125-1.5723 0.13712-3.4273 1.2976-6.7937 12.994-8.3001 16.335-1.5064 3.3408-8.046 13.614-6.7492 17.042 1.297 3.4258 12.995 6.794 16.335 8.3001 3.3406 1.5061 13.615 8.0498 17.042 6.7522 3.4273-1.2964 6.7937-12.996 8.3001-16.335 1.5064-3.3408 8.0461-13.616 6.7492-17.042-1.2969-3.428-12.992-6.7918-16.332-8.3001-2.9229-1.3168-11.166-6.4753-15.473-6.8832zm-39.507 79.948c-0.61519 0-1.1652-2.1e-4 -1.5936 0.15843-3.4273 1.2976-6.7936 12.994-8.3001 16.335-1.5063 3.3408-8.0491 13.594-6.7522 17.021 1.2969 3.4269 12.995 6.794 16.335 8.3001 3.3406 1.5061 13.618 8.0498 17.045 6.7522 3.4272-1.2964 6.7938-12.995 8.3001-16.335 1.5064-3.3408 8.0461-13.594 6.7492-17.021-1.2969-3.428-12.995-6.794-16.335-8.3001-2.9229-1.318-11.142-6.511-15.448-6.9076z" fill="#fff"/><g transform="translate(-2442.8 -889.49)" fill="#78bff8"><rect transform="rotate(23.45)" x="46.829" y="305.29" width="579.88" height="355.5"/><rect transform="rotate(203.45)" x="-671.27" y="41.806" width="579.88" height="355.5"/><rect transform="rotate(-66.55)" x="-429.2" y="509.73" width="579.88" height="355.5"/><rect transform="rotate(-66.55)" x="-427.02" y="-188.84" width="579.88" height="355.5"/></g></svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="512" height="512" version="1.1" viewBox="0 0 135.47 135.47" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -161.53)"><g transform="translate(1.7769 -4.861)"><rect x="13.04" y="181.84" width="105.83" height="19.844" rx="5" ry="5" fill="#9e9e9e"/><circle cx="27.253" cy="191.77" r="4.8315" fill="#4caf50" stroke="#fff" stroke-width=".86719"/></g><g transform="translate(3.9123 -4.861)"><rect x="63.821" y="207.04" width="52.917" height="79.375" rx="5" ry="5" fill="#9e9e9e"/><circle cx="90.279" cy="254.57" r="4.8315" fill="#4caf50" stroke="#fff" stroke-width=".86719"/><path d="m77.311 224.06c9.4913 0.0175 18.983-0.0368 28.474 0.03 0.59908 0.13588-1.5556 0.0589-2.076 0.0891-9.0779 0.0278-18.156 0.0138-27.234 2e-3 -0.39246-0.0403-2.0443 0.0493-1.7494-0.0873 0.86063-0.0421 1.7242-0.0232 2.5851-0.0342zm0-9.2876h25.937c1.662 0 3 1.338 3 3v12.708c0 1.662-1.338 3-3 3h-25.937c-1.662 0-3-1.338-3-3v-12.708c0-1.662 1.338-3 3-3z" fill="none" stroke="#fff" stroke-width="1.1361"/><rect x="63.821" y="207.04" width="52.917" height="79.375" rx="5" ry="5" fill="#9e9e9e"/><circle cx="90.279" cy="254.57" r="4.8315" fill="#4caf50" stroke="#fff" stroke-width=".86719"/><path d="m77.311 224.06c9.4913 0.0175 18.983-0.0368 28.474 0.03 0.59908 0.13588-1.5556 0.0589-2.076 0.0891-9.0779 0.0278-18.156 0.0138-27.234 2e-3 -0.39246-0.0403-2.0443 0.0493-1.7494-0.0873 0.86063-0.0421 1.7242-0.0232 2.5851-0.0342zm0-9.2876h25.937c1.662 0 3 1.338 3 3v12.708c0 1.662-1.338 3-3 3h-25.937c-1.662 0-3-1.338-3-3v-12.708c0-1.662 1.338-3 3-3z" fill="none" stroke="#fff" stroke-width="1.1361"/></g><g><rect x="14.817" y="202.18" width="46.302" height="26.458" rx="5" ry="5" fill="#9e9e9e"/><circle cx="22.225" cy="221.06" r="2.3746" fill="#4caf50" stroke="#fff" stroke-width=".86719"/></g><g><rect x="14.817" y="233.68" width="46.302" height="47.869" rx="5" ry="5" fill="#9e9e9e"/><g transform="translate(-.0063038 -7.6294e-6)" fill="#4caf50" stroke="#fff" stroke-width=".86719"><circle cx="50.321" cy="257.62" r="2.3746"/><circle cx="37.974" cy="257.62" r="2.3746"/><circle cx="25.627" cy="257.62" r="2.3746"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@ -1,108 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
width="512"
height="512"
viewBox="0 0 512.00001 512.00001"
id="svg2"
version="1.1">
<defs
id="defs4">
<pattern
height="8.15625"
patternTransform="translate(201.25 133.47)"
patternUnits="userSpaceOnUse"
width="8.6875"
id="pattern6179">
<path
d="m1.9375 0.5c-0.8781 0.7454-1.4375 1.8526-1.4375 3.0938 0 2.2424 1.82 4.0624 4.0625 4.0624 1.5819 0 2.9541-0.9292 3.625-2.25-0.7084 0.6014-1.6237 1-2.625 1-2.2425 0-4.0625-1.82-4.0625-4.0624 0-0.6607 0.1573-1.2922 0.4375-1.8438z"
style="opacity:.32394;stroke-opacity:0;fill:#eeeeec"
id="path6174" />
</pattern>
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
transform="translate(0,-540.36216)">
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.74509804"
id="rect4726"
width="512"
height="512"
x="0"
y="540.36218"
rx="50"
ry="50" />
<g
transform="translate(0,-2.2617187e-5)"
id="layer1-9">
<g
transform="translate(0.61384869,9.1476514)"
id="g4610">
<g
style="fill:#dcdcdc;fill-opacity:1"
id="g4528">
<rect
y="726.60608"
x="145.6884"
height="296.34189"
width="100.27342"
id="rect4194-3"
style="fill:#dcdcdc;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:5, 5;stroke-dashoffset:0;stroke-opacity:1"
rx="15"
ry="15" />
<rect
y="797.948"
x="263.57608"
height="225"
width="100.27342"
id="rect4194-6"
style="fill:#dcdcdc;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:5, 5;stroke-dashoffset:0;stroke-opacity:1"
rx="15"
ry="15" />
<rect
y="858.0174"
x="30.26951"
height="164.93059"
width="100.27342"
id="rect4194-6-7"
style="fill:#dcdcdc;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:5, 5;stroke-dashoffset:0;stroke-opacity:1"
rx="15"
ry="15" />
<rect
y="551.48108"
x="380.22937"
height="471.46692"
width="100.27342"
id="rect4194"
style="fill:#dcdcdc;fill-opacity:1;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:5, 5;stroke-dashoffset:0;stroke-opacity:1"
rx="15"
ry="15" />
</g>
<g
id="g4568">
<path
style="fill:#bce0fc;fill-opacity:1;stroke:#ffffff;stroke-width:7;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m 195.89258,55.101562 a 24.748737,24.748737 0 0 0 -24.81641,24.681641 24.748737,24.748737 0 0 0 3.02344,11.867188 L 76.679688,335.07617 a 24.748737,24.748737 0 0 0 -21.021485,24.38281 24.748737,24.748737 0 0 0 24.679688,24.81641 24.748737,24.748737 0 0 0 24.816409,-24.68164 24.748737,24.748737 0 0 0 -5.242191,-15.28711 l 94.437501,-235.9707 100.24609,303.2539 a 24.748737,24.748737 0 0 0 -5.63086,15.625 24.748737,24.748737 0 0 0 24.67969,24.81641 24.748737,24.748737 0 0 0 24.81641,-24.67969 24.748737,24.748737 0 0 0 -7.86328,-18.11914 L 432.16602,180.64453 a 24.748737,24.748737 0 0 0 22.94921,-24.60937 24.748737,24.748737 0 0 0 -24.68164,-24.81641 24.748737,24.748737 0 0 0 -24.8164,24.67969 24.748737,24.748737 0 0 0 4.10547,13.68945 L 312.93359,387.41602 215.99609,94.166016 a 24.748737,24.748737 0 0 0 4.57813,-14.248047 24.748737,24.748737 0 0 0 -24.68164,-24.816407 z"
transform="translate(0,540.36219)"
id="circle4572" />
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
id="svg2"
viewBox="0 0 403.11311 352.57208"
height="352.57208"
width="403.11313">
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(-146.20776,-255.22513)"
id="layer1">
<path
id="rect4361"
d="m 347.66381,255.22727 c -2.39231,-0.0413 -4.73078,0.51333 -6.84028,1.73125 -0.17129,0.0989 -0.33632,0.20489 -0.50152,0.31068 -3.46803,1.83238 -6.64163,4.83846 -8.9265,8.79597 L 149.3802,581.32449 c -1.6698,2.89218 -2.66186,5.942 -3.01901,8.90436 -0.0972,0.63442 -0.15343,1.27896 -0.15343,1.93506 0,0.0717 0.006,0.14227 0.007,0.21374 -0.0963,5.80318 2.31129,11.01809 6.93341,13.68667 2.80598,1.62003 6.01719,2.06551 9.22115,1.49768 1.09798,0.15203 2.22613,0.23511 3.38007,0.23511 l 364.02986,0 c 1.15394,0 2.28208,-0.0831 3.38006,-0.23511 3.20397,0.56784 6.41517,0.12236 9.22115,-1.49768 4.62213,-2.66858 7.02968,-7.88349 6.93342,-13.68667 10e-4,-0.0715 0.007,-0.14204 0.007,-0.21374 0,-0.65241 -0.0551,-1.29339 -0.15114,-1.92438 -0.35605,-2.9657 -1.34949,-6.01938 -3.0213,-8.91504 L 364.13287,266.06517 c -2.28487,-3.95751 -5.45847,-6.96359 -8.9265,-8.79597 -0.1652,-0.10579 -0.33023,-0.21179 -0.50151,-0.31068 -2.13906,-1.23499 -4.51373,-1.78539 -6.94105,-1.72667 -0.0333,-8.1e-4 -0.0667,-0.004 -0.1,-0.005 z m 0.1,45.01872 159.51359,276.28473 -319.0264,0 159.51281,-276.28473 z"
style="opacity:0.5;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<g
id="text4409"
style="font-style:normal;font-weight:normal;font-size:278.96676636px;line-height:125%;font-family:sans-serif;letter-spacing:-54.46826553px;word-spacing:0px;opacity:0.5;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
id="path4414"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:278.96676636px;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;letter-spacing:-54.46826553px;word-spacing:0px;opacity:0.5;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 360.21586,429.25521 q 0,20.10017 -1.49418,36.61102 -1.49418,16.27157 -3.73546,32.54313 l -14.4438,0 q -2.24128,-16.27156 -3.73546,-32.54313 -1.49419,-16.51085 -1.49419,-36.61102 l 0,-44.98609 24.90309,0 0,44.98609 z m 4.23352,107.91877 q 0,6.46077 -4.48255,11.24653 -4.48255,4.78575 -12.20252,4.78575 -7.71995,0 -12.20251,-4.78575 -4.48255,-4.78576 -4.48255,-11.24653 0,-6.46076 4.48255,-11.24652 4.48256,-4.78576 12.20251,-4.78576 7.71997,0 12.20252,4.78576 4.48255,4.78576 4.48255,11.24652 z" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

@ -1,78 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="512"
height="512"
viewBox="0 0 512.00001 512.00001"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="logo.svg"
inkscape:export-filename="/home/skylar/Documents/Projects/Sources/WebAppTemplate/static/img/logo.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="-493.3276 : 245.89848 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="464.45088 : 245.89848 : 1"
inkscape:persp3d-origin="-14.438371 : 160.56515 : 1"
id="perspective4236" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.49497475"
inkscape:cx="-135.9681"
inkscape:cy="352.66131"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-540.36216)">
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.74509804"
id="rect4726"
width="512"
height="512"
x="0"
y="540.36218"
rx="50"
ry="50" />
<path
id="path4348"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:9.87128067;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 132.93564,682.51771 213.96788,-43.14304 0,313.97496 -213.96788,-37.9643 z m 213.96788,-43.14304 0,313.97496 32.16084,-45.18373 0,-217.44396 z m -213.96788,43.14304 213.96788,-43.14304 32.16084,51.34727 -167.21823,22.47784 z m 78.91049,30.68207 167.21823,-22.47784 0,217.44396 -167.21823,-19.77968 z m -78.91049,-30.68207 0,232.86762 78.91049,-26.99911 0,-175.18644 z m 0,232.86762 213.96788,37.9643 32.16084,-45.18373 -167.21823,-19.77968 z"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2"
viewBox="0 0 403.11274 163.29169"
height="163.29169"
width="403.11276"
inkscape:version="0.91 r13725"
sodipodi:docname="noaccounts.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="842"
id="namedview4274"
showgrid="false"
inkscape:zoom="1.1913066"
inkscape:cx="111.56795"
inkscape:cy="18.120005"
inkscape:window-x="1024"
inkscape:window-y="156"
inkscape:window-maximized="1"
inkscape:current-layer="g4375"
fit-margin-top="20"
fit-margin-bottom="20"
fit-margin-left="88.539"
fit-margin-right="88.539" />
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
style="fill:#ffffff"
id="g4375"
transform="matrix(10.274307,0,0,10.274307,94.587448,-48.471738)">
<path
id="path4365"
d="M 0,0 24,0 24,24 0,24 Z"
inkscape:connector-curvature="0"
style="fill:none" />
<path
id="path4467"
d="m 7.9464545,12.664364 q -1.242192,0 -2.121099,-0.878908 -0.878907,-0.878908 -0.878907,-2.1210988 0,-1.24219 0.878907,-2.121099 0.878907,-0.878909 2.121099,-0.878909 1.242191,0 2.1210985,0.878909 0.878907,0.878909 0.878907,2.121099 0,1.2421908 -0.878907,2.1210988 -0.8789075,0.878908 -2.1210985,0.878908 z m 8.4140785,2.500007 1.945322,1.945316 q 0.07031,0.07032 0.07031,0.179689 0,0.101563 -0.07031,0.171875 l -1.062505,1.062503 q -0.07031,0.07032 -0.171874,0.07032 -0.109379,0 -0.179687,-0.07032 l -1.945322,-1.945317 -1.945313,1.945317 q -0.07031,0.07032 -0.179688,0.07032 -0.101566,0 -0.171874,-0.07032 l -1.062504,-1.062503 q -0.07031,-0.07032 -0.07031,-0.171875 0,-0.109375 0.07031,-0.179689 l 1.945314,-1.945316 -1.945314,-1.945318 q -0.07031,-0.07032 -0.07031,-0.179687 0,-0.101563 0.07031,-0.171876 l 1.062504,-1.062502 q 0.07031,-0.07032 0.171874,-0.07032 0.109372,0 0.179688,0.07032 l 1.945313,1.945316 1.945322,-1.945316 q 0.07031,-0.07032 0.179687,-0.07032 0.101559,0 0.171874,0.07032 l 1.062505,1.062502 q 0.07031,0.07032 0.07031,0.171876 0,0.109374 -0.07031,0.179687 z m -3.890628,0 -1.414073,1.414066 q -0.289059,0.289063 -0.289059,0.710939 0,0.414064 0.289059,0.703126 l 0.64844,0.64844 q -0.164061,0.02344 -0.343748,0.02344 l -6.8281395,0 q -0.94532,0 -1.515632,-0.539064 -0.570313,-0.539064 -0.570313,-1.484378 0,-0.414064 0.02737,-0.808596 0.02737,-0.394533 0.10938,-0.851565 0.08203,-0.457032 0.207028,-0.847658 0.125005,-0.390626 0.335943,-0.761721 0.210938,-0.371094 0.484372,-0.632814 0.27344,-0.261719 0.667968,-0.41797 0.394536,-0.15625 0.871102,-0.15625 0.148436,0 0.304685,0.132812 1.203127,0.953128 2.492196,0.953128 1.289061,0 2.4921955,-0.953128 0.156248,-0.132812 0.304684,-0.132812 0.218751,0 0.445315,0.04688 -0.218751,0.210937 -0.320317,0.390625 -0.101559,0.179688 -0.101559,0.437502 0,0.421876 0.289059,0.710938 z"
inkscape:connector-curvature="0"
style="opacity:0.5;fill:#000000;fill-opacity:1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2"
viewBox="0 0 403.11274 163.29169"
height="163.29169"
width="403.11276"
inkscape:version="0.91 r13725"
sodipodi:docname="nokeys.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="842"
id="namedview4274"
showgrid="false"
inkscape:zoom="1.6847619"
inkscape:cx="193.17345"
inkscape:cy="81.645645"
inkscape:window-x="1024"
inkscape:window-y="1024"
inkscape:window-maximized="1"
inkscape:current-layer="g4375"
fit-margin-top="20"
fit-margin-bottom="20"
fit-margin-left="88.539"
fit-margin-right="88.539" />
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
style="fill:#ffffff"
id="g4375"
transform="matrix(10.274307,0,0,10.274307,94.587448,-48.471738)">
<path
id="path4365"
d="M 0,0 24,0 24,24 0,24 Z"
inkscape:connector-curvature="0"
style="fill:none" />
<path
id="path4367"
d="m 11.061302,10.664366 c -0.82,-2.3300004 -3.0399999,-4.0000004 -5.6499999,-4.0000004 -3.31,0 -6,2.69 -6,6.0000004 0,3.31 2.69,6 6,6 2.61,0 4.8299999,-1.67 5.6499999,-4 l 4.35,0 0,4 4,0 0,-4 2,0 0,-4 -10.35,0 z m -5.6499999,4 c -1.1,0 -2,-0.9 -2,-2 0,-1.1 0.9,-2 2,-2 1.1,0 2,0.9 2,2 0,1.1 -0.9,2 -2,2 z"
inkscape:connector-curvature="0"
style="opacity:0.5;fill:#000000;fill-opacity:1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

@ -2,50 +2,40 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html>
<head>
<title>Netsyms Business for Mobile</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/bootstrap.min.css" />
<link rel="stylesheet" href="css/font-awesome.min.css" />
<link rel="stylesheet" href="css/material-color.min.css" />
<link rel="stylesheet" href="css/app.css" />
<script src="cordova.js"></script>
<script src="js/polyfills.js"></script>
<script src="js/jquery-3.2.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/accounts.js"></script>
<script src="js/app.js"></script>
</head>
<body>
<div id="modal-load-box" class="container" style='z-index: 1000;'>
</div>
<nav class="navbar navbar-inverse navbar-fixed-top" id="navbar">
<div class="container-fluid">
<div class="nav navbar-nav navbar-left" id="navbar-header">
<span class="navbar-brand" id="navbar-title" style="color: white;">Business</span>
</div>
<ul class="nav navbar-nav navbar-right" id="navbar-buttons">
</ul>
</div>
</nav>
<div id="content-zone" class="container" style="margin-top: 75px;">
<div class="app-dock-container">
<div class="app-dock" id="app-dock">
<div style="margin-top: 50px;">
<img src="img/loader.gif" style="width: 65px; height: 65px;" alt=""/>
</div>
<div style="width: 100%;"></div>
<p class="loading-text">Loading...</p>
</div>
</div>
</div>
</body>
</html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="theme-color" content="#2196f3">
<link rel="stylesheet" href="vendor/css/framework7.min.css">
<link rel="stylesheet" href="fonts/material.css">
<title>Netsyms Apps for Mobile</title>
<div id="app">
<!-- <div class="statusbar"></div> -->
<div class="view view-main"></div>
</div>
<script src="cordova.js"></script>
<script src="vendor/js/jquery-3.4.1.min.js"></script>
<script src="vendor/js/framework7.min.js"></script>
<script src="vendor/js/fontawesome/fontawesome.min.js"></script>
<script src="vendor/js/fontawesome/solid.min.js"></script>
<script src="vendor/js/fontawesome/regular.min.js"></script>
<script src="vendor/js/jsOTP.min.js"></script>
<script src="js/polyfills.js"></script>
<script src="js/material-palette.js"></script>
<script src="js/notifications.js"></script>
<script src="js/accounts.js"></script>
<script src="js/home.js"></script>
<script src="js/otp.js"></script>
<script src="js/app.js"></script>
<script src="js/settings.js"></script>
<script src="routes.js"></script>
<script src="js/main.js"></script>

@ -30,15 +30,33 @@ function getaccounts() {
function saveaccounts(accounts) {
localStorage.setItem("accounts", JSON.stringify(accounts));
NativeStorage.setItem("accounts", JSON.stringify(accounts));
}
function recoveraccounts(callback) {
NativeStorage.getItem("accounts", function (data) {
if (data == null || data == "" || data == "[]") {
callback(false);
return;
}
localStorage.setItem("accounts", data);
callback(true);
}, function () {
callback(false);
});
}
/**
* Switch to a different account.
* @param {int} account The selected account index from localStorage.getItem('accounts')
* @param {boolean} showmsg [HAS NO EFFECT] Whether to show the "switched accounts" alert dialog. Default True.
* @returns {undefined}
*/
function switchaccount(account) {
// If there isn't an accounts list yet, this shouldi take us back to the setup
function switchaccount(account, showmsg) {
if (typeof showmsg != 'boolean') {
showmsg = true;
}
// If there isn't an accounts list yet, this should take us back to the setup
if (!isconfigvalid()) {
restartApplication();
}
@ -53,10 +71,15 @@ function switchaccount(account) {
localStorage.setItem("syncurl", accountinfo['syncurl']);
localStorage.setItem("key", accountinfo['key']);
accountid = account;
restartApplication();
if (showmsg == true) {
//navigator.notification.alert("Successfully switched accounts.", null, "Switched", 'OK');
}
}
/**
* Add a Business Apps account.
* Add an Apps account.
* @param {String} username
* @param {String} password
* @param {String} url
@ -71,7 +94,7 @@ function addaccount(username, password, url, key) {
}
/**
* Remove a Business Apps account.
* Remove an Apps account.
* @param {Number} Account index
*/
function rmaccount(id) {
@ -90,7 +113,6 @@ function rmaccount(id) {
* succeeds.
*/
function getuserinfo(callback) {
$(".loading-text").text("Loading account...");
if (localStorage.getItem("username") === null
|| localStorage.getItem("password") === null
|| localStorage.getItem("syncurl") === null
@ -104,18 +126,17 @@ function getuserinfo(callback) {
action: "user_info"
}, function (data) {
if (data.status === 'OK') {
$(".loading-text").text("Loading...");
userinfo = data.info;
if (typeof callback == 'function') {
callback();
}
} else {
router.navigate("/loaderror");
navigator.notification.alert(data.msg, null, "Error", 'Dismiss');
openscreen("homeloaderror");
}
}, "json").fail(function () {
navigator.notification.alert("Could not connect to the server. Try again later.", null, "Error", 'Dismiss');
openscreen("homeloaderror");
router.navigate("/loaderror");
});
}
@ -128,4 +149,51 @@ function passwd(newpass) {
var accounts = getaccounts();
accounts[accountid]["password"] = newpass;
saveaccounts(accounts);
}
function openAccountSwitcher(reload) {
if (typeof reload == 'undefined') {
reload = false;
}
var accounts = getaccounts();
var noaccounts = (accounts.length == 0);
for (var i = 0; i < accounts.length; i++) {
accounts[i]["id"] = i;
// Escape HTML characters
accounts[i]["username"] = $('<div/>').html(accounts[i]["username"]).html();
var synckey = accounts[i]["key"];
var stars = "";
for (var j = 0; j < synckey.length - 6; j++) {
stars += "*";
}
accounts[i]["synckey"] = $('<div/>').html(synckey.slice(0, 3) + stars + synckey.slice(-3)).html();
accounts[i]["syncurl"] = $('<div/>').html(accounts[i]["syncurl"].replace("/mobile/index.php", "")).html();
accounts[i]["showsyncurl"] = false;
accounts[i]["showtypestring"] = true;
if (accounts[i]["syncurl"].includes(".netsyms.biz")) {
accounts[i]["type"] = "Business";
accounts[i]["icon"] = "business";
} else if (accounts[i]["syncurl"].includes(".netsyms.com")) {
accounts[i]["type"] = "Personal";
accounts[i]["icon"] = "personal";
} else {
accounts[i]["type"] = "Self-hosted";
accounts[i]["icon"] = "selfhosted";
accounts[i]["showsyncurl"] = true;
accounts[i]["showtypestring"] = false;
}
if (localStorage.getItem("username") == accounts[i]['username']) {
accounts[i]["active"] = true;
}
}
router.navigate("/settings/accounts", {
context: {
accounts: accounts,
noaccounts: noaccounts
},
reloadCurrent: reload
});
}

@ -27,7 +27,6 @@ $.cssHooks.backgroundColor = {
}
}
function openmenu() {
if ($('#swipe-nav').css('display') == 'none') {
$('#swipe-shader').show("fade", {}, 300);
@ -50,9 +49,8 @@ function togglemenu() {
}
}
$(document).ready(function () {
$.fx.off = __JQUERYFXOFF__;
var bootstrap_version = $.fn.tooltip.Constructor.VERSION;
if (typeof navbar_breakpoint != "undefined") {
var nav_breakpoint = navbar_breakpoint;
} else {
@ -66,15 +64,11 @@ $(document).ready(function () {
var logo = "__LOGO__";
parent.postMessage("setcolor " + menucolor, "*");
parent.postMessage('load_bs_version ' + bootstrap_version + ' ' + nav_breakpoint, '*');
parent.postMessage("load_css " + nav_breakpoint, "*");
if (bootstrap_version.startsWith("4")) {
pages = pages.replace(/\s?py-[a-z]{2}-0/g, ""); // Issue #12
$('#navbar-right').html("<span class='nav-item py-" + nav_breakpoint + "-0'><a class='nav-link py-" + nav_breakpoint + "-0' onclick='quitapp()'><i class='fas fa-sign-out-alt fa-fw'></i> Back to Menu</a></span>");
body.append("<div id='swipe-nav'><div id='swipe-header' style='background-color: " + menucolor + "; color: " + textcolor + "'><a href='./app.php'><img id='swipe-appicon' src='" + logo + "' /></a> <div id='swipe-username'><i class='fa fa-user fa-fw'></i> " + username + "</div></div>\n<div id='swipe-pages' class='swipe-list'>" + pages + "</div><div class='swipe-list'><span class='nav-item'><a class='nav-link' onclick='quitapp()'><i class='fas fa-sign-out-alt fa-fw'></i> Back to Menu</a></span></div></div>");
} else {
body.append("<div id='swipe-nav'><div id='swipe-header' style='background-color: " + menucolor + "; color: " + textcolor + "'><a href='./app.php'><img id='swipe-appicon' src='" + logo + "' /></a> <div id='swipe-username'><i class='fa fa-user fa-fw'></i> " + username + "</div></div>\n<ul id='swipe-pages'>" + pages + "</ul><ul><li><a onclick='quitapp()'><i class='fa fa-sign-out fa-fw'></i> Back to Menu</a></li></ul></div>");
}
pages = pages.replace(/\s?py-[a-z]{2}-0/g, ""); // Issue #12
$('#navbar-right').html("<span class='nav-item py-" + nav_breakpoint + "-0'><a class='nav-link py-" + nav_breakpoint + "-0' onclick='quitapp()'><i class='fas fa-sign-out-alt fa-fw'></i> Back to Menu</a></span>");
body.append("<div id='swipe-nav'><div id='swipe-header' style='background-color: " + menucolor + "; color: " + textcolor + "'><a href='./app.php'><img id='swipe-appicon' src='" + logo + "' /></a> <div id='swipe-username'><i class='fa fa-user fa-fw'></i> " + username + "</div></div>\n<div id='swipe-pages' class='swipe-list'>" + pages + "</div><div class='swipe-list'><span class='nav-item'><a class='nav-link' onclick='quitapp()'><i class='fas fa-sign-out-alt fa-fw'></i> Back to Menu</a></span></div></div>");
body.append("<div id='swipe-shader'></div>");
$(".navbar-brand").attr("href", "#");
@ -97,6 +91,7 @@ $(document).ready(function () {
closemenu();
});
window.addEventListener('message', function (event) {
if (event.data.startsWith("coderesult~|~")) {
var data = event.data.split("~|~");
@ -118,6 +113,8 @@ $(document).ready(function () {
console.log("app: keepalive ping " + d.status);
});
}, 1000 * 60);
parent.postMessage('done_loading', '*');
});
function quitapp() {

@ -1,244 +1,154 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Switches the app to the given screen.
* @param {String} screenname The name of the screen to show.
* @param {String} effect FADE, SLIDE, or nothing
* @returns {undefined}
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
function openscreen(screenname, effect) {
if (effect === 'FADE') {
$('#content-zone').fadeOut(300, function () {
$('#content-zone').load("views/" + screenname + ".html", function () {
$('#content-zone').fadeIn(300);
});
});
} else if (effect === 'SLIDE') {
$('#content-zone').slideToggle('400', function () {
$('#content-zone').load("views/" + screenname + ".html", function () {
$('#content-zone').slideToggle('400');
});
});
} else {
$('#content-zone').load("views/" + screenname + ".html");
}
currentscreen = screenname;
}
function openfragment(fragment, target, effect) {
if (effect === 'FADE') {
$(target).fadeOut('slow', function () {
$(target).load("views/" + fragment + ".html", function () {
$(target).fadeIn('slow');
});
});
} else if (effect === 'SLIDE') {
$(target).slideToggle('400', function () {
$(target).load("views/" + fragment + ".html", function () {
$(target).slideToggle('400');
});
});
} else {
$(target).load("views/" + fragment + ".html");
}
}
/**
* Add button to the top navbar.
* @param String screenid openscreen(screenid)
* @param String icon The filename of the icon to show: <img src="icons/icon"...
* @param String title Text to show next to the icon on large screens.
* @returns {undefined}
*/
function addnavbarbtn(screenid, icon, title) {
$('#navbar-buttons').append('<li><a onclick="openscreen(\'' + screenid + '\', \'FADE\')"><img src="icons/' + icon + '" alt="" /> <span class="hidden-xs">' + title + '</span></a></li>');
}
/**
* Set the navbar options.
*
* @param String title Text to display
* @param boolean showarrow True if the back arrow should be visible
* @param Stringn backscreen The screen to open when the title is pressed, false or null for none
* @returns {undefined}
*/
function setnavbartitle(title, showarrow, backscreen) {
var arrow = "";
if (showarrow === true) {
arrow = '<img src="icons/ic_arrow-back.svg" />';
}
var onclick = "";
if (backscreen !== null && backscreen !== false) {
onclick = ' onclick=\'openscreen("' + backscreen + '", "FADE");\'';
}
$("#navbar-header").html('<span class="navbar-brand" id="navbar-title" style="color: white;"' + onclick + '>' + arrow + title + '</span>');
}
/**
* Set the navbar.
* @param {String,boolean} type false if no navbar, "home" for the home screen,
* "settings" for settings, "app" for a custom title, or anything else for
* a simple one.
* @param {String} screentitle The title to show if type == "app"
* @param {String} returnscreen Where to go back to. Defaults to "home".
* @returns {undefined}
*/
function setnavbar(type, screentitle, returnscreen) {
var navbar = $('#navbar-header');
var btns = $('#navbar-buttons');
if (type == false) {
$('#navbar').css('display', 'none');
$('#content-zone').css('margin-top', '0px');
} else {
if (cordova.platformId == 'android') {
StatusBar.backgroundColorByHexString("#1976d2");
window.plugins.headerColor.tint("#2196f3");
} else {
StatusBar.backgroundColorByHexString("#2196f3");
}
$('#navbar').css('display', 'initial');
$('#content-zone').css('margin-top', '75px');
if (returnscreen === undefined) {
returnscreen = "home";
_returnscreen = null;
} else {
_returnscreen = returnscreen;
}
btns.html("");
switch (type) {
case "home":
setnavbartitle("Business", false, false);
addnavbarbtn("mobilecode", "ic_desktop_windows.svg", "Code Login");
addnavbarbtn("otp", "ic_vpn_key.svg", "2-factor Auth");
addnavbarbtn("settings", "ic_settings.svg", "Settings");
break;
case "setup":
setnavbartitle("Business", false, false);
addnavbarbtn("otp", "ic_vpn_key.svg", "2-factor Auth");
addnavbarbtn("settings", "ic_settings.svg", "Settings");
break;
case "settings":
setnavbartitle("Settings", true, "home");
break;
case "otp":
setnavbartitle("Auth Keys", true, "home");
break;
case "app":
setnavbartitle(screentitle, true, returnscreen);
break;
default:
setnavbartitle("Business", false, false);
break;
}
}
}
/**
* Thanks to https://stackoverflow.com/a/13542669
* @param {type} color
* @param {type} percent
* @returns {String}
*/
function shadeColor2(color, percent) {
var f = parseInt(color.slice(1), 16), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = f >> 16, G = f >> 8 & 0x00FF, B = f & 0x0000FF;
return "#" + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
}
var historyctr = -1;
/**
* Load the app.html view and open an app with native Android UI elements
* @param String id Application ID
* Open an app with native Android UI elements
* @param String api Path to the mobile API
* @param String url Base URL of the app
* @param String icon URL to the app icon
* @param String title Friendly app name
* @param boolean injectcode (optional, default true) Whether or not to inject UI modification code into the app
* @param boolean shownavbar (optional, default false) Whether or not to show the navbar at the top of the screen.
* @returns {undefined}
*/
function openapp(id, api, url, icon, title, injectcode, shownavbar) {
$('#content-zone').fadeOut(300, function () {
$('#content-zone').load("views/app.html", function () {
$('#content-zone').fadeIn(300, function () {
launchapp(id, api, url, icon, title, injectcode, shownavbar);
function launchapp(api, url, icon, title) {
app.dialog.progress("Loading...").setText(title);
router.navigate({
name: 'app'
});
$.post(url + api, {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
password: localStorage.getItem("password"),
action: "start_session"
}, function (data) {
if (data.status === 'OK') {
$('#appframe').on("load", function () {
app.dialog.close();
historyctr++;
// Do this right away so it's a bit harder to glitch
$('#appframe').contents().find('.navbar-right').html("<li><a onclick='quitapp()'><i class='fas fa-sign-out-alt fa-fw'></i> Back to Menu</a></li>");
$.get("js/polyfills.js", function (script) {
$('#appframe').contents().find('body').append("<script>" + script + "<\/script>");
$.get("vendor/js/jquery-ui.min.js", function (script) {
$('#appframe').contents().find('body').append("<script>" + script + "<\/script>");
$.get("vendor/js/hammer.min.js", function (script) {
$('#appframe').contents().find('body').append("<script>" + script + "<\/script>");
$.get("js/app-inject.js", function (script) {
script = script.replace("__USERNAME__", userinfo.realname);
script = script.replace("__LOGO__", icon);
$('#appframe').contents().find('body').append("<script>" + script + "<\/script>");
});
});
});
});
});
});
$('#appframe').attr('src', url);
} else {
navigator.notification.alert(data.msg, null, "Error", 'Dismiss');
router.back();
}
}, "json").fail(function () {
navigator.notification.alert("Could not connect to the server. Try again later.", null, "Error", 'Dismiss');
router.back();
});
}
/**
* Opens a modal dialog over the top of everything else.
* @param {String} filename views/[filename].html
* @param {String} modalselector [#id-of-the-modal]
* @returns {undefined}
*/
function openmodal(filename, modalselector) {
$('#modal-load-box').load("views/" + filename + ".html", null, function (x) {
$(modalselector).css('z-index', 9999999);
$(modalselector).modal('show');
});
function navigateApp(src) {
$('#appframe').attr('src', './' + src);
}
/**
* Close a modal (see openmodal)
* @param {String} modalselector
* @returns {undefined}
*/
function closemodal(modalselector) {
$(modalselector).modal('hide');
}
function restartApplication() {
navigator.splashscreen.show();
// We're doing the timeout so we don't run afoul of server-side rate limiting
var scanningactive = false;
var dedup = [];
window.addEventListener('message', function (event) {
console.log("app event: " + event.data);
setTimeout(function () {
window.location = "index.html";
}, 3000);
}
// Handle back button to close things
document.addEventListener("backbutton", function (event) {
if (isconfigvalid()) {
if ($("#appframe").length && historyctr > 0) {
console.log("going back");
var iframe = document.getElementById("appframe");
iframe.contentWindow.postMessage("goback", "*");
historyctr--;
} else if (_returnscreen != null) {
openscreen(_returnscreen, "FADE");
_returnscreen = null;
dedup = [];
}, 500);
if (dedup.includes(event.data)) {
return;
}
dedup.push(event.data);
if (event.data == "quit") {
router.back();
if (cordova.platformId == 'android') {
StatusBar.backgroundColorByHexString("#1976d2");
} else {
openscreen("home", "FADE");
}
} else {
if (_returnscreen != null) {
openscreen(_returnscreen, "FADE");
_returnscreen = null;
StatusBar.backgroundColorByHexString("#2196f3");
}
}
}, false);
document.addEventListener("deviceready", function () {
if (cordova.platformId == 'android') {
StatusBar.backgroundColorByHexString("#1976d2");
}
// Enable/disable jQuery animations depending on user preference
$.fx.off = !(localStorage.getItem("animations") === null || localStorage.getItem("animations") === "true");
/* Fade out alerts */
$(".alert .close").click(function (e) {
$(this).parent().fadeOut("slow");
});
if (isconfigvalid()) {
getuserinfo(function () {
openscreen("home");
} else if (event.data == "done_loading") {
app.dialog.close();
} else if (event.data == "goneback") {
historyctr -= 1;
} else if (event.data.startsWith("load_css ")) {
var nav_breakpoint = event.data.split(" ", 2)[1];
$.get("css/app-inject.css", function (style) {
var break_px = "767";
switch (nav_breakpoint) {
case "sm":
break_px = "575";
break;
case "md":
break_px = "767";
break;
case "lg":
break_px = "991";
break;
case "xl":
break_px = "1199";
break;
}
style = style.replace("max-width: 767px", "max-width: " + break_px + "px");
$('#appframe').contents().find('head').append("<style>" + style + "</style>");
});
} else {
openscreen("setup1");
} else if (event.data.startsWith("setcolor ")) {
var color = event.data.split(" ", 2)[1];
if (cordova.platformId == 'android') {
window.plugins.headerColor.tint(color);
for (var swatch in _PALETTE) {
if (color == _PALETTE[swatch]["shade_500"]) {
StatusBar.backgroundColorByHexString(_PALETTE[swatch]["shade_700"]);
return;
}
}
StatusBar.backgroundColorByHexString(shadeColor2(color, -0.1));
} else {
StatusBar.backgroundColorByHexString(color);
}
} else if (event.data.startsWith("scancode ")) {
var callbackcode = event.data.split(" ").slice(1).join(" ");
console.log("got scancode " + callbackcode);
try {
if (scanningactive) {
console.log("Scanner already active, ignoring request.");
return;
}
scanningactive = true;
cordova.plugins.barcodeScanner.scan(
function (result) {
scanningactive = false;
if (!result.cancelled) {
var iframe = document.getElementById("appframe");
iframe.contentWindow.postMessage("coderesult~|~" + callbackcode + "~|~" + result.text, "*");
}
},
function (error) {
scanningactive = false;
navigator.notification.alert("Scanning failed: " + error, null, "Error", 'Dismiss');
},
{
"showFlipCameraButton": true,
"prompt": "Scan Code"
}
);
} catch (ex) {
scanningactive = false;
navigator.notification.alert(ex.message, null, "Error", 'Dismiss');
}
}
setTimeout(navigator.splashscreen.hide, 500);
}, false);

File diff suppressed because one or more lines are too long

@ -0,0 +1,116 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
function loadHomePage(reload) {
if (typeof reload == 'undefined') {
reload = false;
}
$.post(localStorage.getItem("syncurl"), {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
action: "listapps"
}, function (data) {
if (data.status === 'OK') {
if (!reload) {
loadingProgressDialog.setProgress(70);
}
var appcards = [];
Object.keys(data.apps).forEach(function (k) {
var app = data.apps[k];
var iconurl = app.icon;
if (!app.icon.startsWith("http")) {
iconurl = app.url + app.icon;
}
if (!app.card) {
return;
}
appcards.push({
api: app.mobileapi,
url: app.url,
icon: iconurl,
title: app.title,
text: app.card.string,
color: app.card.color
});
});
if (!reload) {
loadingProgressDialog.setProgress(80);
loadingProgressDialog.setText('Notifications');
}
getNotifications(function (notifs) {
notifications = [];
if (notifs != false) {
Object.keys(notifs).forEach(function (k) {
var notif = notifs[k];
if (!notif.seen) {
notifications.push(notif);
}
});
}
if (notifications == []) {
notifications = false;
}
if (reload) {
// Make it seem like it's doing something on fast connections
setTimeout(function () {
app.ptr.done();
router.navigate("/home", {
context: {
appcards: appcards,
notifications: notifications,
unreadnotifications: (notifications != false && notifications != []),
homeloaded: true
},
reloadCurrent: true
});
}, 500);
} else {
loadingProgressDialog.setText('Home');
loadingProgressDialog.setProgress(90);
router.navigate("/home", {
context: {
appcards: appcards,
notifications: notifications,
unreadnotifications: (notifications != false && notifications != []),
homeloaded: true
}
});
$(".view-main").on("click", "#applist .applist-item", function () {
launchapp($(this).data("api"), $(this).data("url"), $(this).data("icon"), $(this).data("title"));
});
loadingProgressDialog.setProgress(100);
loadingProgressDialog.close();
}
});
} else {
if (reload) {
app.ptr.done();
return;
}
loadingProgressDialog.close();
app.dialog.alert(data.msg, "Error", function () {
restartApplication();
});
}
}, "json").fail(function () {
loadingProgressDialog.close();
app.dialog.alert("Could not connect to the server. Try again later.", "Error", function () {
restartApplication();
});
});
}
$(".view-main").on("ptr:refresh", ".ptr-content", function () {
loadHomePage(true);
});
$(".view-main").on("swipeout:deleted", ".notificationlist-item", function () {
var id = $(this).data("id");
deleteNotification(id);
});

File diff suppressed because one or more lines are too long

@ -0,0 +1,148 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var $$ = Dom7;
var shown_notifications = [];
var app = new Framework7({
root: "#app",
name: "Netsyms",
id: "com.netsyms.BusinessMobile",
routes: routes,
dialog: {
buttonOK: "Dismiss"
}
});
var mainView = app.views.create('.view-main', {
url: "/"
});
var router = mainView.router;
var loadingProgressDialog;
/**
* Thanks to https://stackoverflow.com/a/13542669
* @param {type} color
* @param {type} percent
* @returns {String}
*/
function shadeColor2(color, percent) {
var f = parseInt(color.slice(1), 16), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = f >> 16, G = f >> 8 & 0x00FF, B = f & 0x0000FF;
return "#" + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
}
/**
* Load the app.html view and open an app with nativeish Android UI elements
* @param String id Application ID
* @param String api Path to the mobile API
* @param String url Base URL of the app
* @param String icon URL to the app icon
* @param String title Friendly app name
* @param boolean injectcode (optional, default true) Whether or not to inject UI modification code into the app
* @param boolean shownavbar (optional, default false) Whether or not to show the navbar at the top of the screen.
* @returns {undefined}
*/
function openapp(id, api, url, icon, title, injectcode, shownavbar) {
$('#content-zone').fadeOut(300, function () {
$('#content-zone').load("views/app.html", function () {
$('#content-zone').fadeIn(300, function () {
launchapp(id, api, url, icon, title, injectcode, shownavbar);
});
});
});
}
function restartApplication() {
navigator.splashscreen.show();
// We're doing the timeout so we don't run afoul of server-side rate limiting
setTimeout(function () {
window.location = "index.html";
}, 3000);
}
// Handle back button to close things
document.addEventListener("backbutton", function (event) {
if (isconfigvalid()) {
if ($("#appframe").length && historyctr > 0) {
console.log("going back");
var iframe = document.getElementById("appframe");
iframe.contentWindow.postMessage("goback", "*");
historyctr--;
} else {
if (cordova.platformId == 'android') {
StatusBar.backgroundColorByHexString("#1976d2");
} else {
StatusBar.backgroundColorByHexString("#2196f3");
}
router.back();
}
} else {
router.back();
}
}, false);
document.addEventListener("deviceready", function () {
if (cordova.platformId == 'android') {
StatusBar.backgroundColorByHexString("#1976d2");
StatusBar.styleLightContent();
}
if (isconfigvalid()) {
loadingProgressDialog = app.dialog.progress('Loading...', 0);
loadingProgressDialog.setText('');
loadingProgressDialog.setProgress(20);
loadingProgressDialog.setText('Account');
getuserinfo(function () {
loadingProgressDialog.setProgress(50);
loadingProgressDialog.setText('Notifications');
// Setup notification sync
initNotifications();
loadingProgressDialog.setProgress(60);
// Load homepage/dashboard
loadingProgressDialog.setText('Apps');
loadHomePage(false);
});
} else {
// Try to recover data from NativeStorage back to localStorage
recoveraccounts(function (ok) {
if (ok) {
// Success, restart app to reload from localStorage
restartApplication();
} else {
// No account data found, open setup
router.navigate({
name: 'setup0'
});
}
})
}
setTimeout(navigator.splashscreen.hide, 500);
}, false);
router.on("pageBeforeIn", function (pagedata) {
app.progressbar.hide();
});
router.on("pageInit", function (pagedata) {
pagedata.$el.find('script').each(function (el) {
if ($$(this).attr('src')) {
var s = document.createElement('script');
s.src = $$(this).attr('src');
$$('head').append(s);
} else {
eval($$(this).text());
}
});
app.progressbar.hide();
switch (pagedata.name) {
case "settings":
updateSettingsData();
break;
}
});

@ -0,0 +1,140 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
function getNotifications(callback) {
var notifications = [];
$.post(localStorage.getItem("syncurl"), {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
action: "checknotifications"
}, function (data) {
if (data.status === 'OK') {
for (var i = 0; i < data.notifications.length; i++) {
var n = data.notifications[i];
notifications.push({
id: n.id,
title: n.title,
text: n.content,
sensitive: n.sensitive,
seen: n.seen
});
}
callback(notifications);
return;
}
if (typeof callback == 'function') {
callback(false);
}
}, "json").fail(function () {
if (typeof callback == 'function') {
callback(false);
}
});
}
function displayNotifications(callback) {
getNotifications(function (notifications) {
if (notifications != false) {
for (var i = 0; i < notifications.length; i++) {
var n = notifications[i];
if (n.seen || shown_notifications.includes(n.id)) {
continue;
}
cordova.plugins.notification.local.schedule([{
title: n.title,
text: n.text,
// actions: [
// {id: 'mark_read', title: "Mark Read"}
// ],
id: n.id,
lockscreen: !n.sensitive
}]);
shown_notifications.push(n.id);
}
if (typeof callback == 'function') {
callback();
}
return;
}
if (typeof callback == 'function') {
callback();
}
});
}
function deleteNotification(id) {
$.post(localStorage.getItem("syncurl"), {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
password: localStorage.getItem("password"),
action: "deletenotification",
id: id
});
}
function readNotification(id) {
$.post(localStorage.getItem("syncurl"), {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
password: localStorage.getItem("password"),
action: "readnotification",
id: id
});
}
function initForegroundNotifications() {
cordova.plugins.notification.local.setDefaults({
led: true,
color: '#2196F3',
vibrate: true,
smallIcon: "res://ic_notification"
});
cordova.plugins.notification.local.on("mark_read", function (notification) {
$.post(localStorage.getItem("syncurl"), {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
password: localStorage.getItem("password"),
action: "readnotification",
id: notification.id
});
});
setInterval(displayNotifications, 30 * 1000);
if (typeof cordova.plugins.notification.local.launchDetails === 'undefined') {
displayNotifications();
}
}
function initBackgroundNotifications() {
var BackgroundFetch = window.BackgroundFetch;
// Your background-fetch handler.
var fetchCallback = function () {
console.log('[js] BackgroundFetch event received');
displayNotifications(function () {
BackgroundFetch.finish();
});
};
var failureCallback = function (error) {
console.log('- BackgroundFetch failed', error);
};
BackgroundFetch.configure(fetchCallback, failureCallback, {
minimumFetchInterval: 1,
stopOnTerminate: false,
startOnBoot: true,
forceReload: false,
enableHeadless: true
});
}
function initNotifications() {
initForegroundNotifications();
initBackgroundNotifications();
}

@ -0,0 +1,196 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
var totp = new jsOTP.totp();
function parseOTP(jsontext, reload) {
var keys = [];
if (jsontext !== null && jsontext != "") {
var keys = JSON.parse(jsontext || "[]");
if (keys.length > 0) {
//$("#nokeys").css("display", "none");
}
var tmpldata = [];
for (var i = 0; i < keys.length; i++) {
var code = totp.getOtp(keys[i]["secret"]);
// Escape HTML characters
var label = $('<div/>').html(keys[i]["label"]).html();
var issuer = $('<div/>').text(keys[i]["issuer"]).html();
tmpldata.push({
code: code,
secret: keys[i]["secret"],
label: label,
issuer: issuer,
index: i
});
}
router.navigate("/otp", {
context: {
otpcodes: tmpldata
},
reloadCurrent: (reload == true ? true : false)
});
setInterval(function () {
refreshCountdown();
refreshCodes();
}, 1000);
refreshCountdown();
}
}
function setProgressBar(percent) {
if (mainView.router.currentRoute.name == "otp") {
app.progressbar.show(percent, app.theme === 'md' ? 'yellow' : 'blue');
} else {
app.progressbar.hide();
}
}
function loadOTPPage(reload) {
var ls_text = localStorage.getItem("otp");
if (ls_text === null || ls_text == "") {
// Recover from NativeStorage
NativeStorage.getItem("otp", function (data) {
localStorage.setItem("otp");
parseOTP(data, reload);
}, function (error) {
parseOTP("[]", reload);
});
} else {
parseOTP(ls_text, reload);
}
}
function refreshCountdown() {
var percent = ((30 - ((new Date).getSeconds() % 30)) / 30) * 100;
setProgressBar(percent);
}
function refreshCodes() {
$(".otpcard").each(function () {
var code = totp.getOtp($(this).data("secret"));
$(".otpcode", this).text(code);
});
}
function deleteOTPCode(index) {
var label = $(".otpcard[data-index=" + index + "] .otplabel").text();
navigator.notification.confirm("Delete auth key? This cannot be undone, so make sure you don't need this key to login anymore!", function (result) {
if (result != 1) {
return;
}
var keys = JSON.parse(localStorage.getItem("otp"));
keys.splice(index, 1);
localStorage.setItem("otp", JSON.stringify(keys));
NativeStorage.setItem("otp", JSON.stringify(keys));
loadOTPPage(true);
}, "Delete " + label + "?");
}
function addOTPCode(key, label, issuer) {
if (key == "") {
navigator.notification.alert("Missing secret key.", null, "Error", 'Dismiss');
return;
}
key = key.toUpperCase();
/* Thanks to https://stackoverflow.com/a/27362880 for the regex */
if (!key.match(/^(?:[A-Z2-7]{8})*(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=)?$/)) {
navigator.notification.alert("Secret key is not valid base32.", null, "Error", 'Dismiss');
return;
}
if (label == "") {
navigator.notification.alert("Missing label.", null, "Error", 'Dismiss');
return;
}
var ls_text = localStorage.getItem("otp");
var keys = [];
if (ls_text != null && ls_text != "") {
keys = JSON.parse(ls_text || "[]");
}
keys.push({"secret": key, "label": label, "issuer": issuer});
localStorage.setItem("otp", JSON.stringify(keys));
NativeStorage.setItem("otp", JSON.stringify(keys));
app.toast.create({
text: '2-factor key saved.',
closeButton: true,
}).open();
loadOTPPage(true);
}
function scanOTPCode() {
try {
cordova.plugins.barcodeScanner.scan(
function (result) {
if (!result.cancelled) {
try {
var url = decodeURI(result.text);
} catch (e) {
navigator.notification.alert("Could not decode OTP URI.", null, "Error", 'Dismiss');
return;
}
if (!url.startsWith("otpauth://")) {
navigator.notification.alert("Invalid OTP code. Try again.", null, "Error", 'Dismiss');
return;
}
if (!url.startsWith("otpauth://totp/")) {
navigator.notification.alert("Unsupported key type.", null, "Error", 'Dismiss');
return;
}
var stripped = url.replace("otpauth://totp/", "");
var params = stripped.split("?")[1].split("&");
var label = stripped.split("?")[0];
var secret = "";
var issuer = "";
for (var i = 0; i < params.length; i++) {
var param = params[i].split("=");
if (param[0] == "secret") {
secret = param[1].toUpperCase();
} else if (param[0] == "issuer") {
issuer = param[1];
} else if (param[0] == "algorithm" && param[1].toLowerCase() != "sha1") {
navigator.notification.alert("Unsupported hash algorithm.", null, "Error", 'Dismiss');
return;
} else if (param[0] == "digits" && param[1] != "6") {
navigator.notification.alert("Unsupported digit count.", null, "Error", 'Dismiss');
return;
} else if (param[0] == "period" && param[1] != "30") {
navigator.notification.alert("Unsupported period.", null, "Error", 'Dismiss');
return;
}
}
try {
secret = decodeURIComponent(secret);
issuer = decodeURIComponent(issuer);
label = decodeURIComponent(label);
} catch (e) {
navigator.notification.alert("Could not decode OTP URI.", null, "Error", 'Dismiss');
return;
}
addOTPCode(secret, label, issuer);
}
},
function (error) {
navigator.notification.alert("Scanning failed: " + error, null, "Error", 'Dismiss');
},
{
"showFlipCameraButton": false,
"prompt": "Scan OTP QR code."
}
);
} catch (ex) {
navigator.notification.alert(ex.message, null, "Error", 'Dismiss');
}
}
function addManualOTP() {
var label = $("#addotp_sheetmodal #label").val();
var secret = $("#addotp_sheetmodal #secret").val().replace(/\s+/g, '');
app.sheet.close("#addotp_sheetmodal");
addOTPCode(secret, label, "");
}

@ -0,0 +1,138 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
function deleteAllSettings() {
navigator.notification.confirm("Really wipe user data? You will need to resync the app with AccountHub to use it again. This will not delete 2-factor auth keys.", function (result) {
if (result != 1) {
return;
}
// Wipe localStorage
localStorage.removeItem("username");
localStorage.removeItem("password");
localStorage.removeItem("syncurl");
localStorage.removeItem("key");
localStorage.removeItem("accounts");
NativeStorage.remove("accounts", function () {
// force-reload app
navigator.notification.alert("All connection data and credentials erased.", function () {
restartApplication();
}, "App Reset", 'Continue');
});
}, "Are you sure?");
}
/**
* Prompts the user to enter their password, then checks the password and
* saves or displays an error.
* @returns {undefined}
*/
function updatePassword() {
navigator.notification.prompt("Re-enter your password.", function (results) {
if (results.buttonIndex == 1) {
$.post(localStorage.getItem("syncurl"), {
username: localStorage.getItem("username"),
key: localStorage.getItem("key"),
password: results.input1,
action: "check_password"
}, function (data) {
if (data.status === 'OK') {
localStorage.setItem("password", results.input1);
passwd(results.input1);
navigator.notification.alert("Saved password updated.", function () {
// Reload app just to be safe
restartApplication();
}, "Success", 'Continue');
} else {
navigator.notification.alert(data.msg, null, "Error", 'Dismiss');
}
}, "json").fail(function () {
navigator.notification.alert("Could not connect to the server. Try again later.", null, "Error", 'Dismiss');
});
}
}, "Update Password", ["Save", "Cancel"]);
}
function updateSettingsData() {
cordova.getAppVersion.getVersionNumber(function (version) {
$('#app_version').text(version);
});
cordova.getAppVersion.getPackageName(function (package) {
$('#app_package').text(package);
});
cordova.getAppVersion.getVersionCode(function (version) {
$('#app_version_code').text(version);
});
if (localStorage.getItem("username")) {
$("#username").text(localStorage.getItem("username"));
}
if (localStorage.getItem("key")) {
var key = localStorage.getItem("key");
var stars = "";
for (var i = 0; i < key.length - 6; i++) {
stars += "*";
}
$("#pairingkey").text(key.slice(0, 3) + stars + key.slice(-3));
}
if (localStorage.getItem("syncurl")) {
$("#syncurl").text(localStorage.getItem("syncurl").replace("/mobile/index.php", ""));
}
}
function getSettingsTemplateData() {
return [
{
setting: "userinfo",
title: '<i class="fa fa-user"></i> <span id="username">Not logged in</span>',
text: '<i class="fa fa-key"></i> Pairing Code: <span id="pairingkey">None</span><br /><i class="fa fa-server"></i> Server: <span id="syncurl">None</span>',
onclick: ""
},
{
setting: "accounts",
title: "Manage and switch accounts",
onclick: "openAccountSwitcher(false)"
},
{
setting: "updatepassword",
title: "Update Password",
text: "Enter your new password if you changed it from AccountHub.",
onclick: "updatePassword()"
},
{
setting: "deleteall",
title: "Disconnect All Accounts",
text: "Forget all account data for all connected accounts and open the setup tool.",
onclick: "deleteAllSettings()"
},
{
setting: "versions",
title: "Netsyms Apps for Mobile</span> v<span id=\"app_version\">2.x</span>",
text: "Copyright &copy; 2018 Netsyms Technologies. License: <span style=\"text-decoration: underline;\" onclick=\"window.open('https://source.netsyms.com/Business/MobileApp?pk_campaign=NetsymsMobile-SystemBrowser', '_system', '');\">Mozilla Public License 2.0</span>.",
onclick: ""
},
{
setting: "opensource",
title: "Open Source Information",
text: "",
onclick: "router.navigate('/credits')"
},
{
setting: "privacy",
title: "Privacy Policy",
text: "",
onclick: "cordova.InAppBrowser.open('https://netsyms.com/legal?pk_campaign=NetsymsMobile-SystemBrowser', '_blank', 'location=yes')"
}
];
}
function loadSettingsPage() {
router.navigate("/settings", {
context: {
settings: getSettingsTemplateData()
},
});
updateSettingsData();
}

@ -0,0 +1,196 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
setupusername = "";
setuppassword = "";
setupsynckey = "";
setupsyncurl = "";
netsymscomurl = "https://apps.netsyms.com/account/mobile/index.php";
netsymsbizurl = "https://BIZID.netsyms.biz/accounthub/mobile/index.php";
if (localStorage.getItem("firstrun") === null) {
$("#setuptitle").text("Setup");
$(".firstrun-only").css("display", "");
}
$('#use-security-checkbox-li').click(function () {
// Event fires before the checkbox is changed, so we need to do the opposite
if ($("#use-security").prop("checked")) {
$('#protocol-select').text("http://");
} else {
$('#protocol-select').text("https://");
}
});
/* Detect if the user typed "http[s]://" into the URL box and correct for it */
$("#syncurl").blur(function () {
if ($('#syncurl').val().toLowerCase().startsWith("https://")) {
$('#syncurl').val($('#syncurl').val().replace(/https\:\/\//ig, ""));
$('#protocol-select').text("https://");
$('#use-security').prop('checked', true);
} else if ($('#syncurl').val().toLowerCase().startsWith("http://")) {
$('#syncurl').val($('#syncurl').val().replace(/http\:\/\//ig, ""));
$('#protocol-select').text("http://");
$('#use-security').prop('checked', false);
}
});
$("#key").on("keyup", function () {
if (window.getSelection().toString() !== '') {
return;
}
var text = $('#key').val().replace(/\s+/g, '');
var formatted = "";
for (var i = 1; i <= text.length; i++) {
formatted = formatted + text[i - 1];
if (i % 5 == 0 && i > 1 && i < text.length) {
// add a space every 5 characters,
// unless it's the first character
// or the last character
formatted = formatted + " ";
}
}
$('#key').val(formatted.toUpperCase());
});
$('#username').on("keyup", function () {
$('#username').val($('#username').val().toLowerCase());
});
function manualsetup() {
if ($('#syncurl').val().toLowerCase().startsWith("http")) {
var syncurl = $('#syncurl').val();
} else {
var syncurl = $('#protocol-select').text() + $('#syncurl').val();
}
var username = $('#username').val();
var key = $('#key').val().replace(/\s+/g, '');
checkAndSave(syncurl, username, key);
}
function manualshow() {
$('#manual_setup').css('display', 'block');
}
function checkAndSave(syncurl, username, key) {
app.preloader.show();
$.post(syncurl, {
username: username,
key: key,
action: "check_key"
}, function (data) {
app.preloader.hide();
if (data.status === 'OK') {
setupusername = username;
setupsyncurl = syncurl;
setupsynckey = key;
router.navigate({
name: 'setup2'
});
} else {
navigator.notification.alert(data.msg, null, "Error", 'Dismiss');
}
}, "json").fail(function () {
app.preloader.hide();
navigator.notification.alert("Could not connect to the server. Try again.", null, "Error", 'Dismiss');
});
}
function personalsetup() {
app.preloader.show();
var username = $("#personal_username").val();
var password = $("#personal_password").val();
$.post(netsymscomurl, {
username: username,
password: password,
key: "NOKEY",
desc: device.platform + " " + device.model + " " + device.serial,
action: "generatesynccode"
}, function (result) {
app.preloader.hide();
if (result.status == "OK") {
var code = result.code;
var accid = addaccount(username, password, netsymscomurl, code);
switchaccount(accid, false);
localStorage.setItem("firstrun", "1");
navigator.notification.alert("Account connected!", null, "Success", 'Continue');
restartApplication();
} else if (result.status == "ERROR") {
navigator.notification.alert(result.msg, null, "Error", 'Dismiss');
} else {
navigator.notification.alert("Something went wrong, please try again.", null, "Error", 'Dismiss');
}
}, "json").fail(function () {
app.preloader.hide();
navigator.notification.alert("Something went wrong, please try again.", null, "Error", 'Dismiss');
});
}
function businesssetup() {
app.preloader.show();
var username = $("#personal_username").val();
var password = $("#personal_password").val();
var url = netsymsbizurl.replace("BIZID", $("#bizid").val());
$.post(url, {
username: username,
password: password,
key: "NOKEY",
desc: device.platform + " " + device.model + " " + device.serial,
action: "generatesynccode"
}, function (result) {
app.preloader.hide();
if (result.status == "OK") {
var code = result.code;
var accid = addaccount(username, password, url, code);
switchaccount(accid, false);
localStorage.setItem("firstrun", "1");
navigator.notification.alert("Account connected!", null, "Success", 'Continue');
restartApplication();
} else if (result.status == "ERROR") {
navigator.notification.alert(result.msg, null, "Error", 'Dismiss');
} else {
navigator.notification.alert("Something went wrong, please try again.", null, "Error", 'Dismiss');
}
}, "json").fail(function () {
app.preloader.hide();
navigator.notification.alert("Something went wrong, please try again.", null, "Error", 'Dismiss');
});
}
function scanCode() {
try {
cordova.plugins.barcodeScanner.scan(
function (result) {
if (!result.cancelled) {
if (!result.text.startsWith("bizsync://")) {
navigator.notification.alert("Invalid sync code. Try again.", null, "Error", 'Dismiss');
return;
}
var url = result.text.replace("bizsync://", "");
var parts = url.split("/");
var syncurl = parts[0].replace(/\\/g, "/");
var username = parts[1];
var key = parts[2];
checkAndSave(syncurl, username, key);
}
},
function (error) {
navigator.notification.alert("Scanning failed: " + error, null, "Error", 'Dismiss');
},
{
"showFlipCameraButton": false,
"prompt": "Scan mobile sync QR code."
}
);
} catch (ex) {
navigator.notification.alert(ex.message, null, "Error", 'Dismiss');
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save