summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPliable Pixels <pliablepixels@users.noreply.github.com>2018-10-14 15:00:02 -0400
committerGitHub <noreply@github.com>2018-10-14 15:00:02 -0400
commit3cd1ff34c0cd8412ebe07d4ba5614ec938b72456 (patch)
treeb256e275147ee495721bedeaaafb1a65f8aef98c
parentffbacb34a6a654eb1124c627320bc75131636ff7 (diff)
parent863e507613e33cc66022ba3639f7e1a5b8eb7c96 (diff)
Merge pull request #709 from pliablepixels/webview
WKWebView migration resolutions and other stuff
-rwxr-xr-xbuild_android.sh60
-rwxr-xr-xbuild_ios.sh7
-rw-r--r--config.xml45
-rw-r--r--jsconfig.json15
-rw-r--r--package.json32
-rwxr-xr-xprepare_desktop.sh76
-rw-r--r--resources/ios/icon/icon-1024.pngbin32775 -> 32775 bytes
-rw-r--r--resources/ios/icon/icon-40.pngbin1526 -> 1526 bytes
-rw-r--r--resources/ios/icon/icon-40@2x.pngbin3486 -> 3486 bytes
-rw-r--r--resources/ios/icon/icon-40@3x.pngbin5265 -> 5265 bytes
-rw-r--r--resources/ios/icon/icon-50.pngbin2181 -> 2181 bytes
-rw-r--r--resources/ios/icon/icon-50@2x.pngbin4386 -> 4386 bytes
-rw-r--r--resources/ios/icon/icon-60.pngbin2647 -> 2647 bytes
-rw-r--r--resources/ios/icon/icon-60@2x.pngbin5265 -> 5265 bytes
-rw-r--r--resources/ios/icon/icon-60@3x.pngbin7814 -> 7814 bytes
-rw-r--r--resources/ios/icon/icon-72.pngbin3161 -> 3161 bytes
-rw-r--r--resources/ios/icon/icon-72@2x.pngbin6195 -> 6195 bytes
-rw-r--r--resources/ios/icon/icon-76.pngbin3352 -> 3352 bytes
-rw-r--r--resources/ios/icon/icon-76@2x.pngbin6643 -> 6643 bytes
-rw-r--r--resources/ios/icon/icon-83.5@2x.pngbin7168 -> 7168 bytes
-rw-r--r--resources/ios/icon/icon-small.pngbin1205 -> 1205 bytes
-rw-r--r--resources/ios/icon/icon-small@2x.pngbin2520 -> 2520 bytes
-rw-r--r--resources/ios/icon/icon-small@3x.pngbin3803 -> 3803 bytes
-rw-r--r--resources/ios/icon/icon.pngbin2451 -> 2451 bytes
-rw-r--r--resources/ios/icon/icon@2x.pngbin4988 -> 4988 bytes
-rw-r--r--resources/ios/splash/Default-568h@2x~iphone.pngbin26982 -> 26982 bytes
-rw-r--r--resources/ios/splash/Default-667h.pngbin32395 -> 32395 bytes
-rw-r--r--resources/ios/splash/Default-736h.pngbin62886 -> 62886 bytes
-rw-r--r--resources/ios/splash/Default-Landscape-736h.pngbin62629 -> 62629 bytes
-rw-r--r--resources/ios/splash/Default-Landscape@2x~ipad.pngbin59305 -> 59305 bytes
-rw-r--r--resources/ios/splash/Default-Landscape@~ipadpro.pngbin87979 -> 87979 bytes
-rw-r--r--resources/ios/splash/Default-Landscape~ipad.pngbin25129 -> 25129 bytes
-rw-r--r--resources/ios/splash/Default-Portrait@2x~ipad.pngbin59374 -> 59374 bytes
-rw-r--r--resources/ios/splash/Default-Portrait@~ipadpro.pngbin88671 -> 88671 bytes
-rw-r--r--resources/ios/splash/Default-Portrait~ipad.pngbin25496 -> 25496 bytes
-rw-r--r--resources/ios/splash/Default@2x~iphone.pngbin22993 -> 22993 bytes
-rw-r--r--resources/ios/splash/Default@2x~universal~anyany.pngbin97293 -> 97293 bytes
-rw-r--r--resources/ios/splash/Default~iphone.pngbin10366 -> 10366 bytes
-rw-r--r--www/css/style.css13
-rw-r--r--www/index.html3
-rw-r--r--www/js/DataModel.js147
-rw-r--r--www/js/EventCtrl.js250
-rw-r--r--www/js/EventModalCtrl.js323
-rw-r--r--www/js/EventServer.js498
-rw-r--r--www/js/EventServerSettingsCtrl.js10
-rw-r--r--www/js/EventsGraphsCtrl.js7
-rw-r--r--www/js/FirstUseCtrl.js7
-rw-r--r--www/js/LoginCtrl.js70
-rw-r--r--www/js/MenuController.js72
-rw-r--r--www/js/MonitorCtrl.js13
-rw-r--r--www/js/MonitorModalCtrl.js178
-rw-r--r--www/js/MontageCtrl.js4
-rw-r--r--www/js/NewsCtrl.js13
-rw-r--r--www/js/TimelineCtrl.js29
-rw-r--r--www/js/WizardCtrl.js23
-rwxr-xr-xwww/js/app.js187
-rw-r--r--www/lang/locale-en.json4
-rw-r--r--www/templates/events-modal.html16
-rw-r--r--www/templates/events.html15
-rw-r--r--www/templates/monitors-modal.html4
60 files changed, 1351 insertions, 770 deletions
diff --git a/build_android.sh b/build_android.sh
index d084d8c4..0eb723c5 100755
--- a/build_android.sh
+++ b/build_android.sh
@@ -13,8 +13,8 @@ if [ ! -f "$NINJAKEYSTORE" ]; then
exit
fi
+rm -f release_files 2>/dev/null
mkdir release_files
-rm -f release_files/*
# no arguments - build both
# 1 == build crosswalk only
@@ -30,45 +30,8 @@ if [ "$1" = "2" ]; then
echo "only building native view (5+)"
fi
-############ Crosswalk build ####################################
-if [ "$BUILD_MODE" = "xwalk" ] || [ "$BUILD_MODE" = "all" ]; then
-
- echo "${ver_pre5}: Building Release mode for Xwalk android..."
- echo "--------------------------------------------"
- echo "Removing android and re-adding..."
- cordova platform remove android
- cordova platform add android@6.3.0
- cordova plugin remove cordova-plugin-crosswalk-webview --nosave
- echo "Adding crosswalk..."
- #cordova plugin add cordova-plugin-crosswalk-webview
- cordova plugin add cordova-plugin-crosswalk-webview@2.2.0 --variable XWALK_MODE="lite" --variable "XWALK_VERSION"="17.46.459.1" --nosave
- #cordova plugin add cordova-plugin-crosswalk-webview --variable XWALK_VERSION="22+"
- #ionic plugin add cordova-plugin-crosswalk-webview
- # crosswalk handles SSL certificate handling in a different way
- # need to switch plugins
- echo "Adding crosswalk cert plugin..."
- cordova plugin remove cordova-plugin-certificates --nosave
- cordova plugin add cordova-plugin-crosswalk-certificate-pp-fork --nosave
- cp "$NINJAKEYSTORE" platforms/android/
- echo "Building XWALK ..."
- #cordova build android --release -- --targetSdkVersion=23
- cordova build android --release -- --gradleArg=-PcdvVersionCode=${ver_pre5}
-
- # copy builds to my release directory
- cp platforms/android/build/outputs/apk/android-x86-release-unsigned.apk release_files/
- cp platforms/android/build/outputs/apk/android-armv7-release-unsigned.apk release_files/
- echo "Copied files to release_files"
-
- # sign them
- cd release_files/
- jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ../platforms/android/zmNinja.keystore android-armv7-release-unsigned.apk zmNinja
- jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ../platforms/android/zmNinja.keystore android-x86-release-unsigned.apk zmNinja
- ~/Library/Android/sdk/build-tools/25.0.2/zipalign -v 4 android-x86-release-unsigned.apk zmNinja-x86-pre5.apk
- ~/Library/Android/sdk/build-tools/25.0.2/zipalign -v 4 android-armv7-release-unsigned.apk zmNinja-arm-pre5.apk
- rm -f android-x86-release-unsigned.apk android-armv7-release-unsigned.apk
- cd ..
-fi
-
+echo "----------> Only building native. Not building crosswalk anymore due to compatibility issues <----------------------"
+BUILD_MODE="native"
############ Native web view build ###############################
if [ "$BUILD_MODE" = "native" ] || [ "$BUILD_MODE" = "all" ]; then
@@ -76,24 +39,25 @@ if [ "$BUILD_MODE" = "native" ] || [ "$BUILD_MODE" = "all" ]; then
echo "${ver}: Building Release mode for android 5+..."
echo "--------------------------------------------"
- echo "Removing android and re-adding..."
- cordova platform remove android
- cordova platform add android@6.3.0
+# No longger needed as we are not supporting Xwalk
+# echo "Removing android and re-adding..."
+# cordova platform remove android
+# cordova platform add android@6.4.0
#clean up past build stuff
- echo "Adding default browser..."
- cordova plugin remove cordova-plugin-crosswalk-webview
+# echo "Adding default browser..."
+# cordova plugin remove cordova-plugin-crosswalk-webview
# use the right plugin for SSL certificate mgmt
- cordova plugin remove cordova-plugin-crosswalk-certificate-pp-fork
- cordova plugin add cordova-plugin-certificates
+# cordova plugin remove cordova-plugin-crosswalk-certificate-pp-fork
+# cordova plugin add cordova-plugin-certificates
cp "$NINJAKEYSTORE" platforms/android/
# Make sure native builds are only deployed in devices >= Android 5
cordova build android --release -- --minSdkVersion=21 --versionCode=${ver}
# copy build to release folder and sign
- cp platforms/android/build/outputs/apk/android-release-unsigned.apk release_files/
+ cp platforms/android/build/outputs/apk/release/android-release-unsigned.apk release_files/
echo "Copied files to release_files"
cd release_files/
diff --git a/build_ios.sh b/build_ios.sh
index 0e87eca7..cbd66b34 100755
--- a/build_ios.sh
+++ b/build_ios.sh
@@ -1,4 +1,11 @@
echo "*** Using old build system due to XCode 10 issues ** "
echo "see https://forum.ionicframework.com/t/how-to-build-ionic-cordova-with-xcode-10/142044"
+#ionic cordova plugin add cordova-plugin-ionic-webview@latest
+
+#echo "--- readding certificate plugin to make sure... ---"
+#ionic cordova plugin remove cordova-plugin-certificates
+#ionic cordova plugin add cordova-plugin-certificates
+
+echo "-- building --"
ionic cordova build ios --release --buildConfig="./build-auto.json"
diff --git a/config.xml b/config.xml
index 9866dea0..ab9eb243 100644
--- a/config.xml
+++ b/config.xml
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
-<widget android-packageName="com.pliablepixels.zmninja_pro" id="com.pliablepixels.zmninja_pro" ios-CFBundleIdentifier="com.pliablepixels.zmninja-pro" version="1.3.025" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
+<widget android-packageName="com.pliablepixels.zmninja_pro" id="com.pliablepixels.zmninja_pro" ios-CFBundleIdentifier="com.pliablepixels.zmninja-pro" version="1.3.026" 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>zmNinja</name>
<description>
High performance ZoneMinder client
@@ -8,10 +8,14 @@
Pliable Pixels
</author>
<content src="index.html" />
+ <allow-navigation href="localhost:8080/*" />
+ <allow-navigation href="gap://ready" />
<access launch-external="yes" origin="mailto:*" />
<access allows-arbitrary-loads-for-media="true" allows-arbitrary-loads-in-web-content="true" allows-local-networking="true" origin="*" />
<allow-intent href="mailto:*" />
- <allow-navigation href="*" />
+ <allow-intent href="http://*/*" />
+ <allow-intent href="https://*/*" />
+ <preference name="KeyboardResizeMode" value="native" />
<preference name="xwalkMultipleApk" value="true" />
<preference name="AndroidPersistentFileLocation" value="Compatibility" />
<preference name="iosPersistentFileLocation" value="Library" />
@@ -25,7 +29,7 @@
<preference name="AutoHideSplashScreen" value="false" />
<preference name="ShowSplashScreenSpinner" value="false" />
<preference name="SplashScreen" value="screen" />
- <preference name="deployment-target" value="8.0" />
+ <preference name="deployment-target" value="10.0" />
<preference name="SplashScreenDelay" value="300" />
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="FadeSplashScreen" value="false" />
@@ -36,7 +40,17 @@
<param name="ios-package" onload="true" value="CDVStatusBar" />
</feature>
<platform name="ios">
+ <feature name="CDVWKWebViewEngine">
+ <param name="ios-package" value="CDVWKWebViewEngine" />
+ </feature>
+ <preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine" />
<resource-file src="GoogleService-Info.plist" />
+ <config-file parent="NSAppTransportSecurity" target="*-Info.plist">
+ <dict>
+ <key>NSAllowsArbitraryLoads</key>
+ <true />
+ </dict>
+ </config-file>
<config-file parent="NSPhotoLibraryAddUsageDescription" platform="ios" target="*-Info.plist">
<string>Store photos of events and live feeds</string>
</config-file>
@@ -82,6 +96,9 @@
<icon height="1024" src="resources/ios/icon/icon-1024.png" width="1024" />
</platform>
<platform name="android">
+ <config-file parent="/*" target="AndroidManifest.xml">
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ </config-file>
<resource-file src="build-extras.gradle" target="build-extras.gradle" />
<resource-file src="google-services.json" target="google-services.json" />
<preference name="android-manifest/@android:installLocation" value="auto" />
@@ -108,7 +125,6 @@
<icon src="resources/android/icon/drawable-xhdpi-icon.png" />
<preference name="SplashShowOnlyFirstTime" value="false" />
<plugin name="cordova-plugin-add-swift-support" spec="^1.7.2" />
- <plugin name="com.telerik.plugins.nativepagetransitions" spec="^0.6.5" />
<plugin name="cordova-plugin-android-permissions" spec="^1.0.0" />
<plugin name="cordova-plugin-app-version" spec="^0.1.9" />
<plugin name="cordova-plugin-customurlscheme" spec="^4.3.0">
@@ -118,9 +134,6 @@
<plugin name="cordova-plugin-globalization" spec="^1.0.7" />
<plugin name="cordova-plugin-inappbrowser" spec="^1.7.1" />
<plugin name="cordova-plugin-insomnia" spec="^4.3.0" />
- <plugin name="cordova-plugin-photo-library" spec="^1.2.2">
- <variable name="PHOTO_LIBRARY_USAGE_DESCRIPTION" value="images to gallery" />
- </plugin>
<plugin name="cordova-plugin-pin-dialog" spec="^0.1.3" />
<plugin name="cordova-plugin-settings-hook" spec="^0.2.7" />
<plugin name="cordova-plugin-splashscreen" spec="^4.0.3" />
@@ -133,23 +146,27 @@
<plugin name="cordova-plugin-network-information" spec="^2.0.1" />
<plugin name="cordova-plugin-device" spec="^2.0.1" />
<plugin name="cordova-plugin-file" spec="^6.0.1" />
- <plugin name="cordova-plugin-canvas2image-pp-fork" spec="^0.6.0">
- <variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value=" " />
- </plugin>
<plugin name="cordova-plugin-media-pp-fork" spec="^1.0.2-dev" />
<plugin name="cordova-plugin-email" spec="^1.2.7" />
<plugin name="cordova-plugin-statusbar" spec="^2.4.2" />
<plugin name="cordova-library-helper-pp-fork" spec="^1.0.1" />
<plugin name="cordova-plugin-multi-window" spec="0.0.3" />
<plugin name="cordova-plugin-ignore-lint-translation" spec="0.0.1" />
- <plugin name="cordova-plugin-ionic-keyboard" spec="^2.1.2" />
<plugin name="cordova-plugin-cloud-settings" spec="^1.0.4">
<variable name="ANDROID_BACKUP_SERVICE_KEY" value="AEdPqrEAAAAIqF-OaHdwIzZhx2L1WOfAGTagBxm5a1R4wBW_Uw" />
</plugin>
- <plugin name="phonegap-plugin-push" spec="^2.1.3">
+ <plugin name="cordova-plugin-ionic-keyboard" spec="^2.1.2" />
+ <plugin name="cordova-plugin-photo-library" spec="git+https://github.com/pliablepixels/cordova-plugin-photo-library.git">
+ <variable name="PHOTO_LIBRARY_USAGE_DESCRIPTION" value="Save image alarms todisk" />
+ </plugin>
+ <plugin name="cordova-plugin-advanced-http" spec="^2.0.1" />
+ <plugin name="phonegap-plugin-push" spec="~2.1.3">
<variable name="FCM_VERSION" value="11.6.2" />
</plugin>
- <plugin name="cordova-plugin-certificates" spec="^0.6.4" />
- <engine name="android" spec="^6.3.0" />
+ <plugin name="cordova-plugin-ionic-webview" spec="https://github.com/pliablepixels/cordova-plugin-ionic-webview.git">
+ <variable name="ANDROID_SUPPORT_ANNOTATIONS_VERSION" value="27.+" />
+ </plugin>
+ <plugin name="cordova-plugin-advanced-websocket" spec="^1.1.3" />
+ <engine name="android" spec="^6.4.0" />
<engine name="ios" spec="~4.5.5" />
</widget>
diff --git a/jsconfig.json b/jsconfig.json
index bccb75f0..fb1eda40 100644
--- a/jsconfig.json
+++ b/jsconfig.json
@@ -1,11 +1,18 @@
{
+
+
"include": [
- "www/**/*"
+ "www/js/**/*",
+ "www/css/**/*",
+ "www/templates/**/*"
],
"exclude": [
- "node_modules/**/*",
- "dist/**/*",
- "platforms/**/*"
+ "node_modules",
+ "**/node_modules/*",
+ "dist",
+ "platforms",
+ ".vscode",
+
]
} \ No newline at end of file
diff --git a/package.json b/package.json
index 0a31483d..95216464 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "zmninjapro",
"description": "Home security mobile app for ZoneMinder",
- "version":"1.3.022",
+ "version": "1.3.026",
"displayName": "zmNinja",
"author": "Pliable Pixels",
"license": "custom see LICENSE.md",
@@ -12,7 +12,6 @@
],
"plugins": {
"cordova-plugin-add-swift-support": {},
- "com.telerik.plugins.nativepagetransitions": {},
"cordova-plugin-android-permissions": {},
"cordova-plugin-app-version": {},
"cordova-plugin-customurlscheme": {
@@ -22,9 +21,6 @@
"cordova-plugin-globalization": {},
"cordova-plugin-inappbrowser": {},
"cordova-plugin-insomnia": {},
- "cordova-plugin-photo-library": {
- "PHOTO_LIBRARY_USAGE_DESCRIPTION": "images to gallery"
- },
"cordova-plugin-pin-dialog": {},
"cordova-plugin-settings-hook": {},
"cordova-plugin-splashscreen": {},
@@ -37,37 +33,40 @@
"cordova-plugin-network-information": {},
"cordova-plugin-device": {},
"cordova-plugin-file": {},
- "cordova-plugin-canvas2image-pp-fork": {
- "PHOTOLIBRARY_USAGE_DESCRIPTION": " "
- },
"cordova-plugin-media-pp-fork": {},
"cordova-plugin-email": {},
"cordova-plugin-statusbar": {},
"cordova-library-helper-pp-fork": {},
"cordova-plugin-multi-window": {},
"cordova-plugin-ignore-lint-translation": {},
- "cordova-plugin-ionic-keyboard": {},
"cordova-plugin-cloud-settings": {
"ANDROID_BACKUP_SERVICE_KEY": "AEdPqrEAAAAIqF-OaHdwIzZhx2L1WOfAGTagBxm5a1R4wBW_Uw"
},
+ "cordova-plugin-ionic-keyboard": {},
+ "cordova-plugin-photo-library": {
+ "PHOTO_LIBRARY_USAGE_DESCRIPTION": "Save image alarms todisk"
+ },
+ "cordova-plugin-advanced-http": {},
"phonegap-plugin-push": {
"FCM_VERSION": "11.6.2"
},
- "cordova-plugin-certificates": {}
+ "cordova-plugin-ionic-webview": {
+ "ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
+ },
+ "cordova-plugin-advanced-websocket": {}
}
},
"dependencies": {
"clivas": "^0.2.0",
- "com.telerik.plugins.nativepagetransitions": "^0.6.5",
- "cordova-android": "^6.3.0",
+ "cordova-android": "^6.4.0",
"cordova-ios": "~4.5.5",
"cordova-library-helper-pp-fork": "^1.0.1",
"cordova-plugin-add-swift-support": "^1.7.2",
+ "cordova-plugin-advanced-http": "^2.0.1",
+ "cordova-plugin-advanced-websocket": "^1.1.3",
"cordova-plugin-android-fingerprint-auth": "^1.4.0",
"cordova-plugin-android-permissions": "^1.0.0",
"cordova-plugin-app-version": "^0.1.9",
- "cordova-plugin-canvas2image-pp-fork": "^0.6.0",
- "cordova-plugin-certificates": "^0.6.4",
"cordova-plugin-cloud-settings": "^1.0.4",
"cordova-plugin-customurlscheme": "^4.3.0",
"cordova-plugin-device": "^2.0.1",
@@ -79,10 +78,11 @@
"cordova-plugin-inappbrowser": "^1.7.1",
"cordova-plugin-insomnia": "^4.3.0",
"cordova-plugin-ionic-keyboard": "^2.1.2",
+ "cordova-plugin-ionic-webview": "git+https://github.com/pliablepixels/cordova-plugin-ionic-webview.git",
"cordova-plugin-media-pp-fork": "^1.0.2-dev",
"cordova-plugin-multi-window": "0.0.3",
"cordova-plugin-network-information": "^2.0.1",
- "cordova-plugin-photo-library": "^1.2.2",
+ "cordova-plugin-photo-library": "git+https://github.com/pliablepixels/cordova-plugin-photo-library.git",
"cordova-plugin-pin-dialog": "^0.1.3",
"cordova-plugin-settings-hook": "^0.2.7",
"cordova-plugin-splashscreen": "^4.0.3",
@@ -99,7 +99,7 @@
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"phonegap-plugin-mobile-accessibility": "^1.0.5",
- "phonegap-plugin-push": "^2.1.3"
+ "phonegap-plugin-push": "~2.1.3"
},
"devDependencies": {
"bower": "^1.8.4",
diff --git a/prepare_desktop.sh b/prepare_desktop.sh
new file mode 100755
index 00000000..86d28945
--- /dev/null
+++ b/prepare_desktop.sh
@@ -0,0 +1,76 @@
+#!/bin/bash
+
+REL="v2.0.3"
+#REL="v1.4.3"
+WGET='wget'
+WGET_ARGS='-q --show-progress'
+UNZIP='unzip'
+UNZIP_ARGS='-d'
+
+exe() { echo "\$ $@" ; "$@" ; }
+
+echo ----------------------------------------------------
+echo Pliable Pixels Desktop preparation process
+echo Use this to download electron images
+echo You really need to do this one time
+echo ----------------------------------------------------
+echo
+echo This will delete all files in desktop/ and also remove icon associations
+read -p "Press a key to continue or Ctrl-C to break..."
+
+
+iswget=`which ${WGET}`
+if [ $? -ne 0 ]; then
+ echo "**ERROR** You need ${WGET} installed in your path to use this tool."
+ exit
+fi
+rm -rf desktop
+mkdir -p desktop 2>/dev/null
+cd desktop
+
+
+declare -a release_names=("darwin-x64" "win32-x64" "win32-ia32" "linux-arm" "linux-x64" "linux-ia32")
+declare -a release_renames=("zmNinja-mac.app" "zmNinja-win64bit" "zmNinja-win32bit" "zmNinja-linuxarm" "zmNinja-linux64bit" "zmNinja-linux32bit")
+
+for i in "${!release_names[@]}"
+do
+ RELEASE="https://github.com/electron/electron/releases/download/${REL}/electron-${REL}-${release_names[$i]}.zip"
+ echo
+ echo "Working on ${RELEASE}..."
+ #echo "Rename to ${release_renames[$i]}"
+ echo "---------------------------------------------"
+
+ echo "Downloading ${release_names[i]} ..."
+ exe ${WGET} ${RELEASE} ${WGET_ARGS}
+
+
+ echo "Decompressing image..."
+ if [ "${release_names[$i]}" != "darwin-x64" ]; then
+ exe mkdir electron-${REL}-${release_names[$i]} >/dev/null 2>&1
+ exe rm -fr electron-${REL}-${release_names[$i]}/* >/dev/null 2>&1
+ exe ${UNZIP} electron-${REL}-${release_names[$i]}.zip ${UNZIP_ARGS} electron-${REL}-${release_names[$i]} 2>/dev/null
+ exe mv electron-${REL}-${release_names[$i]} ${release_renames[$i]} >/dev/null 2>&1
+ mv ${release_renames[$i]}/electron.exe ${release_renames[$i]}/zmNinja.exe >/dev/null 2>&1
+ mv ${release_renames[$i]}/electron ${release_renames[$i]}/zmNinja >/dev/null 2>&1
+
+ else # OSX
+ exe ${UNZIP} electron-${REL}-${release_names[$i]}.zip 2>/dev/null
+ exe mv Electron.app ${release_renames[$i]}
+
+ fi
+
+ rm LICENSE* >/dev/null 2>&1
+ rm version >/dev/null 2>&1
+done
+
+rm *.zip >/dev/null 2>&1
+
+echo
+echo =========================================================
+echo All done. Use ./make_desktop now
+echo You need to associate icons for OSX and windows
+echo for OSX
+echo =========================================================
+echo
+
+
diff --git a/resources/ios/icon/icon-1024.png b/resources/ios/icon/icon-1024.png
index a8863a65..8ce1f586 100644
--- a/resources/ios/icon/icon-1024.png
+++ b/resources/ios/icon/icon-1024.png
Binary files differ
diff --git a/resources/ios/icon/icon-40.png b/resources/ios/icon/icon-40.png
index e7f34dfe..992e4347 100644
--- a/resources/ios/icon/icon-40.png
+++ b/resources/ios/icon/icon-40.png
Binary files differ
diff --git a/resources/ios/icon/icon-40@2x.png b/resources/ios/icon/icon-40@2x.png
index 86427b97..88e9093f 100644
--- a/resources/ios/icon/icon-40@2x.png
+++ b/resources/ios/icon/icon-40@2x.png
Binary files differ
diff --git a/resources/ios/icon/icon-40@3x.png b/resources/ios/icon/icon-40@3x.png
index f374d227..0eb2d14f 100644
--- a/resources/ios/icon/icon-40@3x.png
+++ b/resources/ios/icon/icon-40@3x.png
Binary files differ
diff --git a/resources/ios/icon/icon-50.png b/resources/ios/icon/icon-50.png
index 28625a52..cb772e83 100644
--- a/resources/ios/icon/icon-50.png
+++ b/resources/ios/icon/icon-50.png
Binary files differ
diff --git a/resources/ios/icon/icon-50@2x.png b/resources/ios/icon/icon-50@2x.png
index 89dbcbe9..03ee7ed4 100644
--- a/resources/ios/icon/icon-50@2x.png
+++ b/resources/ios/icon/icon-50@2x.png
Binary files differ
diff --git a/resources/ios/icon/icon-60.png b/resources/ios/icon/icon-60.png
index 1b43dde7..74f726ca 100644
--- a/resources/ios/icon/icon-60.png
+++ b/resources/ios/icon/icon-60.png
Binary files differ
diff --git a/resources/ios/icon/icon-60@2x.png b/resources/ios/icon/icon-60@2x.png
index f374d227..0eb2d14f 100644
--- a/resources/ios/icon/icon-60@2x.png
+++ b/resources/ios/icon/icon-60@2x.png
Binary files differ
diff --git a/resources/ios/icon/icon-60@3x.png b/resources/ios/icon/icon-60@3x.png
index 0ea98f88..7574996d 100644
--- a/resources/ios/icon/icon-60@3x.png
+++ b/resources/ios/icon/icon-60@3x.png
Binary files differ
diff --git a/resources/ios/icon/icon-72.png b/resources/ios/icon/icon-72.png
index 6dbbc4cf..a2d820df 100644
--- a/resources/ios/icon/icon-72.png
+++ b/resources/ios/icon/icon-72.png
Binary files differ
diff --git a/resources/ios/icon/icon-72@2x.png b/resources/ios/icon/icon-72@2x.png
index aebe82bc..3338ca7f 100644
--- a/resources/ios/icon/icon-72@2x.png
+++ b/resources/ios/icon/icon-72@2x.png
Binary files differ
diff --git a/resources/ios/icon/icon-76.png b/resources/ios/icon/icon-76.png
index 9b7b13ca..133f22f2 100644
--- a/resources/ios/icon/icon-76.png
+++ b/resources/ios/icon/icon-76.png
Binary files differ
diff --git a/resources/ios/icon/icon-76@2x.png b/resources/ios/icon/icon-76@2x.png
index e31278cc..cc8edd0a 100644
--- a/resources/ios/icon/icon-76@2x.png
+++ b/resources/ios/icon/icon-76@2x.png
Binary files differ
diff --git a/resources/ios/icon/icon-83.5@2x.png b/resources/ios/icon/icon-83.5@2x.png
index 923975fd..fb75f8f9 100644
--- a/resources/ios/icon/icon-83.5@2x.png
+++ b/resources/ios/icon/icon-83.5@2x.png
Binary files differ
diff --git a/resources/ios/icon/icon-small.png b/resources/ios/icon/icon-small.png
index eb650703..79cd46a1 100644
--- a/resources/ios/icon/icon-small.png
+++ b/resources/ios/icon/icon-small.png
Binary files differ
diff --git a/resources/ios/icon/icon-small@2x.png b/resources/ios/icon/icon-small@2x.png
index 6800f2b6..8251efd0 100644
--- a/resources/ios/icon/icon-small@2x.png
+++ b/resources/ios/icon/icon-small@2x.png
Binary files differ
diff --git a/resources/ios/icon/icon-small@3x.png b/resources/ios/icon/icon-small@3x.png
index a5edb37f..46c34cc5 100644
--- a/resources/ios/icon/icon-small@3x.png
+++ b/resources/ios/icon/icon-small@3x.png
Binary files differ
diff --git a/resources/ios/icon/icon.png b/resources/ios/icon/icon.png
index 1430cc4c..742116e2 100644
--- a/resources/ios/icon/icon.png
+++ b/resources/ios/icon/icon.png
Binary files differ
diff --git a/resources/ios/icon/icon@2x.png b/resources/ios/icon/icon@2x.png
index e326f4ca..6eb4742d 100644
--- a/resources/ios/icon/icon@2x.png
+++ b/resources/ios/icon/icon@2x.png
Binary files differ
diff --git a/resources/ios/splash/Default-568h@2x~iphone.png b/resources/ios/splash/Default-568h@2x~iphone.png
index 6294c251..b987bfaa 100644
--- a/resources/ios/splash/Default-568h@2x~iphone.png
+++ b/resources/ios/splash/Default-568h@2x~iphone.png
Binary files differ
diff --git a/resources/ios/splash/Default-667h.png b/resources/ios/splash/Default-667h.png
index dcf6739c..ba037c77 100644
--- a/resources/ios/splash/Default-667h.png
+++ b/resources/ios/splash/Default-667h.png
Binary files differ
diff --git a/resources/ios/splash/Default-736h.png b/resources/ios/splash/Default-736h.png
index b74244b2..456327ee 100644
--- a/resources/ios/splash/Default-736h.png
+++ b/resources/ios/splash/Default-736h.png
Binary files differ
diff --git a/resources/ios/splash/Default-Landscape-736h.png b/resources/ios/splash/Default-Landscape-736h.png
index e24c2e99..ba79a715 100644
--- a/resources/ios/splash/Default-Landscape-736h.png
+++ b/resources/ios/splash/Default-Landscape-736h.png
Binary files differ
diff --git a/resources/ios/splash/Default-Landscape@2x~ipad.png b/resources/ios/splash/Default-Landscape@2x~ipad.png
index 263d27d8..9000638f 100644
--- a/resources/ios/splash/Default-Landscape@2x~ipad.png
+++ b/resources/ios/splash/Default-Landscape@2x~ipad.png
Binary files differ
diff --git a/resources/ios/splash/Default-Landscape@~ipadpro.png b/resources/ios/splash/Default-Landscape@~ipadpro.png
index 9ba935ac..5ed46f67 100644
--- a/resources/ios/splash/Default-Landscape@~ipadpro.png
+++ b/resources/ios/splash/Default-Landscape@~ipadpro.png
Binary files differ
diff --git a/resources/ios/splash/Default-Landscape~ipad.png b/resources/ios/splash/Default-Landscape~ipad.png
index f31bd7b7..bc6d1502 100644
--- a/resources/ios/splash/Default-Landscape~ipad.png
+++ b/resources/ios/splash/Default-Landscape~ipad.png
Binary files differ
diff --git a/resources/ios/splash/Default-Portrait@2x~ipad.png b/resources/ios/splash/Default-Portrait@2x~ipad.png
index 9932c9c2..39f7f9de 100644
--- a/resources/ios/splash/Default-Portrait@2x~ipad.png
+++ b/resources/ios/splash/Default-Portrait@2x~ipad.png
Binary files differ
diff --git a/resources/ios/splash/Default-Portrait@~ipadpro.png b/resources/ios/splash/Default-Portrait@~ipadpro.png
index 4b850386..e0685076 100644
--- a/resources/ios/splash/Default-Portrait@~ipadpro.png
+++ b/resources/ios/splash/Default-Portrait@~ipadpro.png
Binary files differ
diff --git a/resources/ios/splash/Default-Portrait~ipad.png b/resources/ios/splash/Default-Portrait~ipad.png
index cf6d37ef..df205911 100644
--- a/resources/ios/splash/Default-Portrait~ipad.png
+++ b/resources/ios/splash/Default-Portrait~ipad.png
Binary files differ
diff --git a/resources/ios/splash/Default@2x~iphone.png b/resources/ios/splash/Default@2x~iphone.png
index 63aa416c..5fde545a 100644
--- a/resources/ios/splash/Default@2x~iphone.png
+++ b/resources/ios/splash/Default@2x~iphone.png
Binary files differ
diff --git a/resources/ios/splash/Default@2x~universal~anyany.png b/resources/ios/splash/Default@2x~universal~anyany.png
index cee7a645..77108330 100644
--- a/resources/ios/splash/Default@2x~universal~anyany.png
+++ b/resources/ios/splash/Default@2x~universal~anyany.png
Binary files differ
diff --git a/resources/ios/splash/Default~iphone.png b/resources/ios/splash/Default~iphone.png
index 41c5fed8..0a72e96b 100644
--- a/resources/ios/splash/Default~iphone.png
+++ b/resources/ios/splash/Default~iphone.png
Binary files differ
diff --git a/www/css/style.css b/www/css/style.css
index 175a8748..2d8650d7 100644
--- a/www/css/style.css
+++ b/www/css/style.css
@@ -1843,4 +1843,15 @@ body {
.platform-ios.platform-cordova:not(.fullscreen) .has-subheader {
top: 88px !important;
-} \ No newline at end of file
+}
+
+
+
+ /* @media screen and (-webkit-min-device-pixel-ratio:0) {
+ select,
+ textarea,
+ input {
+ font-size: 16px;
+ }
+ }*/
+ \ No newline at end of file
diff --git a/www/index.html b/www/index.html
index 4d8d2332..7aa77593 100644
--- a/www/index.html
+++ b/www/index.html
@@ -5,7 +5,7 @@
<meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=0, viewport-fit=cover">
<meta http-equiv="Content-Security-Policy" content="img-src * blob: android-webview-video-poster: cdvphotolibrary: 'self' data: ws: wss://*; default-src * blob: 'self' gap: wss: ws: data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; connect-src * http: https: ws: wss:;">
@@ -13,6 +13,7 @@
<!--<meta http-equiv="Content-Security-Policy" content="img-src * blob: android-webview-video-poster: cdvphotolibrary: 'self' data:; default-src * blob: 'self' gap: wss: ws: ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval';connect-src * http: https: ws: wss:;">-->
+
<title></title>
<meta name="format-detection" content="telephone=no">
<link rel="stylesheet" href="css/animate.min.css">
diff --git a/www/js/DataModel.js b/www/js/DataModel.js
index 575f369c..3b465400 100644
--- a/www/js/DataModel.js
+++ b/www/js/DataModel.js
@@ -9,10 +9,10 @@
angular.module('zmApp.controllers')
- .service('NVRDataModel', ['$ionicPlatform', '$http', '$q', '$ionicLoading', '$ionicBackdrop', '$fileLogger', 'zm', '$rootScope', '$ionicContentBanner', '$timeout', '$cordovaPinDialog', '$ionicPopup', '$localstorage', '$state', '$ionicNativeTransitions', '$translate', '$cordovaSQLite',
+ .service('NVRDataModel', ['$ionicPlatform', '$http', '$q', '$ionicLoading', '$ionicBackdrop', '$fileLogger', 'zm', '$rootScope', '$ionicContentBanner', '$timeout', '$cordovaPinDialog', '$ionicPopup', '$localstorage', '$state', '$translate', '$cordovaSQLite',
function ($ionicPlatform, $http, $q, $ionicLoading, $ionicBackdrop, $fileLogger,
zm, $rootScope, $ionicContentBanner, $timeout, $cordovaPinDialog,
- $ionicPopup, $localstorage, $state, $ionicNativeTransitions, $translate) {
+ $ionicPopup, $localstorage, $state, $translate) {
var currentServerMultiPortSupported = false;
@@ -20,7 +20,7 @@ angular.module('zmApp.controllers')
DO NOT TOUCH zmAppVersion
It is changed by sync_version.sh
*/
- var zmAppVersion = "1.3.022";
+ var zmAppVersion = "1.3.026";
var isBackground = false;
var justResumed = false;
var timeSinceResumed = -1;
@@ -28,7 +28,7 @@ angular.module('zmApp.controllers')
var monitors = [];
var multiservers = [];
- var oldevents = [];
+
var migrationComplete = false;
var tz = "";
@@ -202,18 +202,27 @@ angular.module('zmApp.controllers')
*
* @returns
*/
- function setSSLCerts() {
- if (!window.cordova) return;
+ function setCordovaHttpOptions() {
+
+ if (loginData.isUseBasicAuth) {
+ debug ("Cordova HTTP: configuring basic auth");
+ cordova.plugin.http.useBasicAuth(loginData.basicAuthUser, loginData.basicAuthPassword);
+ }
+
if (!loginData.enableStrictSSL) {
//alert("Enabling insecure SSL");
log(">>>> Disabling strict SSL checking (turn off in Dev Options if you can't connect)");
- cordova.plugins.certificates.trustUnsecureCerts(true);
+ cordova.plugin.http.setSSLCertMode('nocheck', function() {
+ debug('--> SSL is permissive, will allow any certs. Use at your own risk.');
+ }, function() {
+ console.log('-->Error setting SSL permissive');
+ });
} else {
log(">>>> Enabling strict SSL checking (turn off in Dev Options if you can't connect)");
- cordova.plugins.certificates.trustUnsecureCerts(false);
+
}
}
@@ -301,6 +310,7 @@ angular.module('zmApp.controllers')
+
function getZmsMultiPortSupport(forceReload) {
var d = $q.defer();
if (configParams.ZM_MIN_STREAMING_PORT == -1 || forceReload) {
@@ -308,7 +318,8 @@ angular.module('zmApp.controllers')
var apiurl = loginData.apiurl;
var myurl = apiurl + '/configs/viewByName/ZM_MIN_STREAMING_PORT.json';
$http.get(myurl)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
//console.log ("GOT " + JSON.stringify(data));
if (data.config && data.config.Value) {
@@ -324,8 +335,8 @@ angular.module('zmApp.controllers')
d.resolve(configParams.ZM_MIN_STREAMING_PORT);
return (d.promise);
- })
- .error(function (err) {
+ },
+ function (err) {
configParams.ZM_MIN_STREAMING_PORT = 0;
log("ZM_MIN_STREAMING_PORT not supported");
setCurrentServerMultiPortSupported(false);
@@ -694,7 +705,8 @@ angular.module('zmApp.controllers')
if ($rootScope.platformOS == 'desktop')
$state.go(state, p1, p2);
else
- $ionicNativeTransitions.stateGo(state, p1, p2);
+ $state.go(state, p1, p2);
+ // $ionicNativeTransitions.stateGo(state, p1, p2);
},
// used when an empty server profile is created
@@ -1130,13 +1142,13 @@ angular.module('zmApp.controllers')
}
- console.log("INIT SIMUL=" + loginData.disableSimulStreaming);
- console.log("INIT PLATFORM IS=" + $rootScope.platformOS);
+ //console.log("INIT SIMUL=" + loginData.disableSimulStreaming);
+ //console.log("INIT PLATFORM IS=" + $rootScope.platformOS);
if (typeof loginData.disableSimulStreaming == 'undefined') {
loginData.disableSimulStreaming = ($rootScope.platformOS == 'ios') ? true : false;
- console.log("INIT DISABLING SIMUL:" + loginData.disableSimulStreaming);
+ //console.log("INIT DISABLING SIMUL:" + loginData.disableSimulStreaming);
}
@@ -1442,10 +1454,9 @@ angular.module('zmApp.controllers')
log("defaultServer configuration NOT found. Keeping login at defaults");
}
- //console.log ("LOGS="+JSON.stringify(loginData.enableLogs));
- // now set up SSL - need to do it after data return
+
// from local forage
- setSSLCerts();
+ if (window.cordova) setCordovaHttpOptions();
// FIXME: HACK: This is the latest entry point into dataModel init, so start portal login after this
@@ -1812,6 +1823,13 @@ angular.module('zmApp.controllers')
// This function returns the numdigits for padding capture images
//-----------------------------------------------------------------------------
+
+ getAuthHashLogin: function () {
+
+ return $http.get(loginData.apiurl + '/configs/viewByName/ZM_AUTH_HASH_LOGINS.json');
+
+ },
+
getKeyConfigParams: function (forceReload) {
var d = $q.defer();
@@ -1821,14 +1839,14 @@ angular.module('zmApp.controllers')
var myurl = apiurl + '/configs/viewByName/ZM_EVENT_IMAGE_DIGITS.json';
debug("Config URL for digits is:" + myurl);
$http.get(myurl)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
log("ZM_EVENT_IMAGE_DIGITS is " + data.config.Value);
configParams.ZM_EVENT_IMAGE_DIGITS = data.config.Value;
d.resolve(configParams.ZM_EVENT_IMAGE_DIGITS);
return (d.promise);
- })
- .error(function (err) {
+ },function (err) {
log("Error retrieving ZM_EVENT_IMAGE_DIGITS" + JSON.stringify(err), "error");
log("Taking a guess, setting ZM_EVENT_IMAGE_DIGITS to 5");
// FIXME: take a plunge and keep it at 5?
@@ -1852,16 +1870,21 @@ angular.module('zmApp.controllers')
//--------------------------------------------------------------------------
getPathZms: function () {
var d = $q.defer();
+
+
var apiurl = loginData.apiurl;
var myurl = apiurl + '/configs/viewByName/ZM_PATH_ZMS.json';
debug("Config URL for ZMS PATH is:" + myurl);
$http.get(myurl)
- .success(function (data) {
+ .then(function (data) {
+
+ data = data.data;
+ //console.log (">>>> GOT: "+JSON.stringify(data));
configParams.ZM_PATH_ZMS = data.config.Value;
d.resolve(configParams.ZM_PATH_ZMS);
return (d.promise);
- })
- .error(function (error) {
+ },
+ function (error) {
log("Can't retrieving ZM_PATH_ZMS: " + JSON.stringify(error));
d.resolve("");
return (d.promise);
@@ -2025,7 +2048,7 @@ angular.module('zmApp.controllers')
$ionicLoading.show({
template: $translate.instant('kLoadingMonitors'),
animation: 'fade-in',
- showBackdrop: true,
+ showBackdrop: false,
duration: zm.loadingTimeout,
maxWidth: 200,
showDelay: 0
@@ -2048,8 +2071,9 @@ angular.module('zmApp.controllers')
debug("ZMS Multiport reported: " + zmsPort);
debug("Monitor URL to fetch is:" + myurl);
$http.get(myurl /*,{timeout:15000}*/ )
- .success(function (data) {
+ .then(function (data) {
// console.log("HTTP success got " + JSON.stringify(data.monitors));
+ data = data.data;
monitors = data.monitors;
@@ -2068,7 +2092,8 @@ angular.module('zmApp.controllers')
debug("Inside getMonitors, will also regen connkeys");
debug("Now trying to get multi-server data, if present");
$http.get(apiurl + "/servers.json")
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
// We found a server list API, so lets make sure
// we get the hostname as it will be needed for playback
log("multi server list loaded" + JSON.stringify(data));
@@ -2240,8 +2265,8 @@ angular.module('zmApp.controllers')
// now get packery hide if applicable
reloadMonitorDisplayStatus();
d.resolve(monitors);
- })
- .error(function (err) {
+ },
+ function (err) {
log("multi server list loading error");
multiservers = [];
@@ -2284,8 +2309,8 @@ angular.module('zmApp.controllers')
$ionicLoading.hide();
log("Monitor load was successful, loaded " + monitors.length + " monitors");
- })
- .error(function (err) {
+ },
+ function (err) {
//console.log("HTTP Error " + err);
log("Monitor load failed " + JSON.stringify(err), "error");
// To keep it simple for now, I'm translating an error
@@ -2321,7 +2346,8 @@ angular.module('zmApp.controllers')
$http({
url: myurl,
method: 'GET',
- transformResponse: undefined
+ transformResponse: undefined,
+ responseType:'text',
})
// $http.get(myurl)
.then(function (textsucc) {
@@ -2493,6 +2519,11 @@ angular.module('zmApp.controllers')
getEventsPages: function (monitorId, startTime, endTime) {
//console.log("********** INSIDE EVENTS PAGES ");
+
+ var d = $q.defer();
+
+
+
var apiurl = loginData.apiurl;
var myurl = apiurl + "/events/index";
@@ -2511,23 +2542,24 @@ angular.module('zmApp.controllers')
$ionicLoading.show({
template: $translate.instant('kCalcEventSize') + '...',
animation: 'fade-in',
- showBackdrop: true,
+ showBackdrop: false,
duration: zm.loadingTimeout,
maxWidth: 200,
showDelay: 0
});
//var myurl = (monitorId == 0) ? apiurl + "/events.json?page=1" : apiurl + "/events/index/MonitorId:" + monitorId + ".json?page=1";
- var d = $q.defer();
+
$http.get(myurl)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
$ionicLoading.hide();
//console.log ("**** EVENTS PAGES I GOT "+JSON.stringify(data));
//console.log("**** PAGE COUNT IS " + data.pagination.pageCount);
d.resolve(data.pagination);
return d.promise;
- })
- .error(function (error) {
+ },
+ function (error) {
$ionicLoading.hide();
// console.log("*** ERROR GETTING TOTAL PAGES ***");
log("Error retrieving page count of events " + JSON.stringify(error), "error");
@@ -2548,9 +2580,13 @@ angular.module('zmApp.controllers')
//-----------------------------------------------------------------------------
// new reminder
- // https://zm/api/events.json?&sort=StartTime&direction=desc
+ //
+ //https:///zm/api/events.json?&sort=StartTime&direction=desc&page=1
getEvents: function (monitorId, pageId, loadingStr, startTime, endTime) {
+
+
+ if (!pageId) pageId = 1;
//console.log("ZMData getEvents called with ID=" + monitorId + "and Page=" + pageId);
if (!loadingStr) {
@@ -2562,7 +2598,7 @@ angular.module('zmApp.controllers')
$ionicLoading.show({
template: loadingStr,
animation: 'fade-in',
- showBackdrop: true,
+ showBackdrop: false,
maxWidth: 200,
showDelay: 0,
duration: zm.loadingTimeout, //specifically for Android - http seems to get stuck at times
@@ -2582,14 +2618,11 @@ angular.module('zmApp.controllers')
myurl = myurl + "/EndTime <=:" + endTime;
myurl = myurl + "/AlarmFrames >=:" + (loginData.enableAlarmCount ? loginData.minAlarmCount : 0);
- myurl = myurl + ".json";
- if (pageId) {
- myurl = myurl + "?page=" + pageId;
- } else {
- //console.log("**** PAGE WAS " + pageId);
- }
+ myurl = myurl + ".json?&sort=StartTime&direction=desc&page="+pageId;
+
+ debug ("getEvents:"+myurl);
// Simulated data
// myurl = "https://api.myjson.com/bins/4jx44.json";
@@ -2597,20 +2630,18 @@ angular.module('zmApp.controllers')
//console.log (">>>>>Constructed URL " + myurl);
$http.get(myurl /*,{timeout:15000}*/ )
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
if (loadingStr != 'none') $ionicLoading.hide();
//myevents = data.events;
- myevents = data.events.reverse();
- if (monitorId == 0) {
- oldevents = myevents;
- }
- //console.log (JSON.stringify(data));
- // console.log("DataModel Returning " + myevents.length + "events for page" + pageId);
+ myevents = data;
+
+
d.resolve(myevents);
return d.promise;
- })
- .error(function (err) {
+ },
+ function (err) {
if (loadingStr != 'none') $ionicLoading.hide();
displayBanner('error', ['error retrieving event list', 'please try again']);
//console.log("HTTP Events error " + err);
@@ -2622,10 +2653,7 @@ angular.module('zmApp.controllers')
d.reject(myevents);
- // FIXME: Check what pagination does to this logic
- if (monitorId == 0) {
- oldevents = [];
- }
+
return d.promise;
});
return d.promise;
@@ -2862,7 +2890,8 @@ angular.module('zmApp.controllers')
debug("Logging out using API method");
$http.get(loginData.apiurl + '/host/logout.json', {
timeout: 7000,
- transformResponse: undefined
+ transformResponse: undefined,
+ // responseType:'text',
})
.then(function (s) {
debug("Logout returned... ");
diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js
index 0d825eb4..32367682 100644
--- a/www/js/EventCtrl.js
+++ b/www/js/EventCtrl.js
@@ -45,7 +45,8 @@ angular.module('zmApp.controllers')
var oldEvent;
var scrollbynumber;
var eventImageDigits = 5; // failsafe
- var eventsPage;
+ var currEventsPage = 1;
+ var maxEventsPage = 1;
var moreEvents;
var pageLoaded;
var enableLoadMore;
@@ -236,7 +237,7 @@ angular.module('zmApp.controllers')
});
$scope.showSearch = false;
- eventsPage = 1;
+
moreEvents = true;
$scope.viewTitle = {
title: ""
@@ -257,8 +258,8 @@ angular.module('zmApp.controllers')
var apiurl = NVRDataModel.getLogin().apiurl + '/events/' + eid + '.json';
$http.get(apiurl)
- .success(function (data) {})
- .error(function (err) {});
+ .then(function (data) {},
+ function (err) {});
}
@@ -342,6 +343,8 @@ angular.module('zmApp.controllers')
$scope.monitors = NVRDataModel.applyMontageMonitorPrefs(tempMon, 2)[0];
} else*/
$scope.monitors = message;
+ currEventsPage = 1;
+ maxEventsPage = 1;
if ($scope.monitors.length == 0) {
var pTitle = $translate.instant('kNoMonitors');
@@ -374,14 +377,8 @@ angular.module('zmApp.controllers')
nolangTo = moment($rootScope.toString).locale('en').format("YYYY-MM-DD HH:mm:ss");
//NVRDataModel.debug ("GETTING EVENTS USING "+$scope.id+" "+nolangFrom+" "+ nolangTo);
- NVRDataModel.getEventsPages($scope.id, nolangFrom, nolangTo)
- .then(function (data) {
- // console.log ("WE GOT PAGES="+JSON.stringify(data));
- eventsPage = data.pageCount || 1;
- NVRDataModel.debug("EventCtrl: found " + eventsPage + " pages of events");
- pageLoaded = true;
- $scope.viewTitle.title = data.count;
+
NVRDataModel.debug("EventCtrl: grabbing events for: id=" + $scope.id + " Date/Time:" + $rootScope.fromString +
"-" + $rootScope.toString);
nolangFrom = "";
@@ -391,11 +388,20 @@ angular.module('zmApp.controllers')
if ($rootScope.toString)
nolangTo = moment($rootScope.toString).locale('en').format("YYYY-MM-DD HH:mm:ss");
- NVRDataModel.getEvents($scope.id, eventsPage, "", nolangFrom, nolangTo)
+ NVRDataModel.getEvents($scope.id, currEventsPage, "", nolangFrom, nolangTo)
.then(function (data) {
+ pageLoaded = true;
+ //$scope.viewTitle.title = data.pagination.count;
+
+ console.log (JSON.stringify(data.pagination));
+ if (data.pagination && data.pagination.pageCount)
+ maxEventsPage = data.pagination.pageCount;
+
+ NVRDataModel.debug ("We have a total of "+maxEventsPage+" and are at page="+currEventsPage);
+
// console.log ("WE GOT EVENTS="+JSON.stringify(data));
- var myevents = data;
+ var myevents = data.events;
NVRDataModel.debug("EventCtrl: success, got " + myevents.length + " events");
var loginData = NVRDataModel.getLogin();
@@ -493,7 +499,6 @@ angular.module('zmApp.controllers')
}
});
- });
}
//-------------------------------------------------------
@@ -522,6 +527,11 @@ angular.module('zmApp.controllers')
function saveNow(imgsrc, r, f) {
+ var fname = "zmninja.jpg";
+ var fn = "cordova.plugins.photoLibrary.saveImage";
+ var loginData = NVRDataModel.getLogin();
+
+
$ionicLoading.show({
template: $translate.instant('kSavingSnapshot') + "...",
noBackdrop: true,
@@ -530,52 +540,106 @@ angular.module('zmApp.controllers')
var url = imgsrc;
NVRDataModel.log("saveNow: File path to grab is " + url);
- var img = new Image();
- img.onload = function () {
- // console.log("********* ONLOAD");
- var canvas = document.createElement('canvas');
- canvas.width = img.width;
- canvas.height = img.height;
- var context = canvas.getContext('2d');
- context.drawImage(img, 0, 0);
-
- var imageDataUrl = canvas.toDataURL('image/jpeg', 1.0);
- var imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, '');
-
- if ($rootScope.platformOS != "desktop") {
- try {
-
- cordova.exec(
- SaveSuccess,
- SaveError,
- 'Canvas2ImagePlugin',
- 'saveImageDataToLibrary', [imageData]
- );
- // carouselUtils.setStop(curState);
- } catch (e) {
-
- SaveError(e.message);
- // carouselUtils.setStop(curState);
+ if ($rootScope.platformOS != 'desktop') {
+
+ var album = 'zmNinja';
+ NVRDataModel.debug("Trying to save image to album: " + album);
+ cordova.plugins.photoLibrary.requestAuthorization(
+ function () {
+ //url = "https://picsum.photos/200/300/?random";
+
+ var fileTransfer = new FileTransfer();
+ var urle = encodeURI(url);
+
+
+ fileTransfer.onprogress = function (progressEvent) {
+ if (progressEvent.lengthComputable) {
+
+ $timeout(function () {
+ var perc = Math.floor(progressEvent.loaded / progressEvent.total * 100);
+ $ionicLoading.show({
+ template: $translate.instant('kPleaseWait') + "... (" + perc + "%)",
+ noBackdrop: true,
+ //duration: zm.httpTimeout
+ });
+ });
+
+
+ }
+ };
+
+ fileTransfer.download(urle, cordova.file.dataDirectory + fname,
+ function (entry) {
+ NVRDataModel.debug("local download complete: " + entry.toURL());
+ NVRDataModel.debug("Now trying to move it to album");
+ var pluginName = (fname == "zmNinja.mp4" ? "saveVideo" : "saveImage");
+
+
+ cordova.plugins.photoLibrary[pluginName](entry.toURL(), album,
+ function (cameraRollAssetId) {
+ SaveSuccess();
+ $cordovaFile.removeFile(cordova.file.dataDirectory, fname)
+ .then(
+ function () {
+ NVRDataModel.debug("file removed from data directory");
+ },
+ function (e) {
+ NVRDataModel.debug("could not delete temp file: " + JSON.stringify(e));
+ }
+ );
+
+
+ },
+ function (err) {
+ NVRDataModel.debug("Saving error:" + JSON.stringify(err));
+ SaveError();
+
+ });
+
+
+
+
+ },
+ function (err) {
+ NVRDataModel.log("error downloading:" + JSON.stringify(err));
+ SaveError();
+ }, !loginData.enableStrictSSL, {});
+
+
+
+
+ // User gave us permission to his library, retry reading it!
+ },
+ function (err) {
+ // User denied the access
+ NVRDataModel.debug("Permission not granted");
+ SaveError();
+ }, // if options not provided, defaults to {read: true}.
+
+ {
+ read: true,
+ write: true
}
- } else {
-
- var fname = r + f + ".png";
- fname = fname.replace(/\//, "-");
- fname = fname.replace(/\.jpg/, '');
-
- canvas.toBlob(function (blob) {
- saveAs(blob, fname);
- SaveSuccess();
- });
- }
- };
- try {
- img.src = url;
- // console.log ("SAVING IMAGE SOURCE");
- } catch (e) {
- SaveError(e.message);
+ );
+
+ } else {
+ //desktop
+
+ $ionicLoading.hide();
+
+ $rootScope.zmPopup = SecuredPopups.show('alert', {
+ title: $translate.instant('kNote'),
+ template: $translate.instant('kDownloadVideoImage')+"<br/><br/><center><a href='" + url + "' class='button button-assertive icon ion-android-download' download>"+" "+$translate.instant('kDownload')+"</a></center>",
+ okText: $translate.instant('kDismiss'),
+ okType:'button-stable'
+ });
+
+
+
}
+
+
}
@@ -1655,7 +1719,8 @@ angular.module('zmApp.controllers')
return $http.delete(apiDelete)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
$ionicLoading.hide();
NVRDataModel.debug("delete output: " + JSON.stringify(data));
@@ -1685,8 +1750,8 @@ angular.module('zmApp.controllers')
//doRefresh();
- })
- .error(function (data) {
+ },
+ function (data) {
$ionicLoading.hide();
NVRDataModel.debug("delete error: " + JSON.stringify(data));
NVRDataModel.displayBanner('error', [$translate.instant('kDeleteEventError1'), $translate.instant('kDeleteEventError2')]);
@@ -1760,11 +1825,12 @@ angular.module('zmApp.controllers')
var af = "/AlarmFrames >=:" + (ld.enableAlarmCount ? ld.minAlarmCount : 0);
- var apiurl = ld.apiurl + "/events/consoleEvents/1%20hour" + af + ".json";
+ var apiurl = ld.apiurl + "/events/consoleEvents/1 hour" + af + ".json";
NVRDataModel.debug("consoleEvents API:" + apiurl);
$http.get(apiurl)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
NVRDataModel.debug(JSON.stringify(data));
$scope.hours = [];
var p = data.results;
@@ -1796,10 +1862,11 @@ angular.module('zmApp.controllers')
}
});
- apiurl = ld.apiurl + "/events/consoleEvents/1%20day" + af + ".json";
+ apiurl = ld.apiurl + "/events/consoleEvents/1 day" + af + ".json";
NVRDataModel.debug("consoleEvents API:" + apiurl);
$http.get(apiurl)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
NVRDataModel.debug(JSON.stringify(data));
$scope.days = [];
var p = data.results;
@@ -1828,10 +1895,11 @@ angular.module('zmApp.controllers')
}
});
- apiurl = ld.apiurl + "/events/consoleEvents/1%20week" + af + ".json";
+ apiurl = ld.apiurl + "/events/consoleEvents/1 week" + af + ".json";
NVRDataModel.debug("consoleEvents API:" + apiurl);
$http.get(apiurl)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
NVRDataModel.debug(JSON.stringify(data));
$scope.weeks = [];
var p = data.results;
@@ -1861,10 +1929,11 @@ angular.module('zmApp.controllers')
}
});
- apiurl = ld.apiurl + "/events/consoleEvents/1%20month" + af + ".json";
+ apiurl = ld.apiurl + "/events/consoleEvents/1 month" + af + ".json";
NVRDataModel.debug("consoleEvents API:" + apiurl);
$http.get(apiurl)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
NVRDataModel.debug(JSON.stringify(data));
$scope.months = [];
var p = data.results;
@@ -2035,7 +2104,8 @@ angular.module('zmApp.controllers')
var myurl = loginData.apiurl + '/events/' + event.Event.Id + ".json";
NVRDataModel.log("API for event details" + myurl);
$http.get(myurl)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
$scope.FrameArray = data.event.Frame;
// $scope.slider_options.scale=[];
@@ -2070,8 +2140,8 @@ angular.module('zmApp.controllers')
oldEvent = event;
//console.log (JSON.stringify(data));
- })
- .error(function (err) {
+ },
+ function (err) {
NVRDataModel.log("Error retrieving detailed frame API " + JSON.stringify(err));
NVRDataModel.displayBanner('error', ['could not retrieve frame details', 'please try again']);
});
@@ -2147,7 +2217,8 @@ angular.module('zmApp.controllers')
var myurl_frames = loginData.apiurl + '/events/' + event.Event.Id + ".json";
NVRDataModel.log("API for event details" + myurl_frames);
$http.get(myurl_frames)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
$scope.FrameArray = data.event.Frame;
// $scope.slider_options.scale=[];
@@ -2166,8 +2237,8 @@ angular.module('zmApp.controllers')
}
//console.log (JSON.stringify(data));
- })
- .error(function (err) {
+ },
+ function (err) {
NVRDataModel.log("Error retrieving detailed frame API " + JSON.stringify(err));
NVRDataModel.displayBanner('error', [$translate.instant('kErrorFrameBanner'), $translate.instant('kErrorPleaseTryAgain')]);
});
@@ -2208,7 +2279,8 @@ angular.module('zmApp.controllers')
var myurl2 = loginData.apiurl + '/events/' + event.Event.Id + ".json";
NVRDataModel.log("API for event details" + myurl2);
$http.get(myurl2)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
$scope.FrameArray = data.event.Frame;
// $scope.slider_options.scale=[];
$scope.slider_options.scale = [];
@@ -2229,8 +2301,8 @@ angular.module('zmApp.controllers')
}
//console.log (JSON.stringify(data));
- })
- .error(function (err) {
+ },
+ function (err) {
NVRDataModel.log("Error retrieving detailed frame API " + JSON.stringify(err));
NVRDataModel.displayBanner('error', [$translate.instant('kErrorFrameBanner'), $translate.instant('kErrorPleaseTryAgain')]);
});
@@ -2650,7 +2722,7 @@ angular.module('zmApp.controllers')
$ionicLoading.show({
template: $translate.instant('kSearchCancelled'),
animation: 'fade-in',
- showBackdrop: true,
+ showBackdrop: false,
duration: 2000,
maxWidth: 200,
showDelay: 0
@@ -2666,14 +2738,17 @@ angular.module('zmApp.controllers')
// the events API does not return an error for anything
// except greater page limits than reported
- // console.log("***** LOADING MORE INFINITE SCROLL ****");
- eventsPage--;
- if ((eventsPage <= 0) && (pageLoaded)) {
+ console.log("***** LOADING MORE INFINITE SCROLL ****");
+
+ if ((currEventsPage >= maxEventsPage) && (pageLoaded)) {
moreEvents = false;
- //console.log("*** At Page " + eventsPage + ", not proceeding");
+ NVRDataModel.debug ("No more - We have a total of "+maxEventsPage+" and are at page="+currEventsPage);
+
+ console.log("*** At Page " + currEventsPage + " of "+maxEventsPage+", not proceeding");
return;
}
+ currEventsPage++;
if (!enableLoadMore) {
moreEvents = false; // Don't ion-scroll till enableLoadMore is true;
$scope.$broadcast('scroll.infiniteScrollComplete');
@@ -2684,7 +2759,7 @@ angular.module('zmApp.controllers')
var loadingStr = "";
if ($scope.search.text != "") {
- var toastStr = $translate.instant('kToastSearchingPage') + eventsPage;
+ var toastStr = $translate.instant('kToastSearchingPage') + currEventsPage;
$ionicLoading.show({
maxwidth: 100,
scope: $scope,
@@ -2701,11 +2776,12 @@ angular.module('zmApp.controllers')
if ($rootScope.toString)
nolangTo = moment($rootScope.toString).locale('en').format("YYYY-MM-DD HH:mm:ss");
- NVRDataModel.getEvents($scope.id, eventsPage, loadingStr, nolangFrom, nolangTo)
+ NVRDataModel.getEvents($scope.id, currEventsPage, loadingStr, nolangFrom, nolangTo)
.then(function (data) {
var loginData = NVRDataModel.getLogin();
// console.log("Got new page of events with Page=" + eventsPage);
- var myevents = data;
+ var myevents = data.events;
+
for (var i = 0; i < myevents.length; i++) {
@@ -2855,7 +2931,7 @@ angular.module('zmApp.controllers')
$scope.constructThumbnail = function (event) {
var stream = "";
stream = event.Event.baseURL +
- "/index.php?view=image&show=capture&fid=" +
+ "/index.php?view=image&show=capture&fid=" +
(event.Event.MaxScoreFrameId ? event.Event.MaxScoreFrameId : "1&eid=" + event.Event.Id) +
"&width=" + event.Event.thumbWidth * 2 +
"&height=" + event.Event.thumbHeight * 2;
@@ -2997,6 +3073,8 @@ angular.module('zmApp.controllers')
// console.log("***Pull to Refresh");
NVRDataModel.debug("Reloading monitors");
+ maxEventsPage = 1;
+ currEventsPage = 1;
var refresh = NVRDataModel.getMonitors(1);
refresh.then(function (data) {
$scope.monitors = data;
diff --git a/www/js/EventModalCtrl.js b/www/js/EventModalCtrl.js
index cf77aa3d..0e6d6be7 100644
--- a/www/js/EventModalCtrl.js
+++ b/www/js/EventModalCtrl.js
@@ -3,7 +3,7 @@
/* jslint browser: true*/
/* global saveAs, cordova,StatusBar,angular,console,ionic, moment, Chart */
-angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$q', '$sce', 'carouselUtils', '$ionicPopup', '$translate', '$filter', 'SecuredPopups', function ($scope, $rootScope, zm, NVRDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $q, $sce, carouselUtils, $ionicPopup, $translate, $filter, SecuredPopups) {
+angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$q', '$sce', 'carouselUtils', '$ionicPopup', '$translate', '$filter', 'SecuredPopups', '$cordovaFile', function ($scope, $rootScope, zm, NVRDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $q, $sce, carouselUtils, $ionicPopup, $translate, $filter, SecuredPopups, $cordovaFile) {
var playerReady = false;
@@ -86,13 +86,13 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
NVRDataModel.debug("Setting playback to " + $scope.streamMode);
- if ($rootScope.platformOS == 'desktop') {
+ if ($rootScope.platformOS == 'desktop') {
window.addEventListener('keydown', keyboardHandler, true);
}
- // Keyboard handler for desktop versions
- function keyboardHandler(evt) {
+ // Keyboard handler for desktop versions
+ function keyboardHandler(evt) {
var handled = false;
var keyCodes = {
@@ -103,36 +103,31 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
ESC: 27,
FITFILL_F: 70,
- PLAY_SELECT:13
-
+ PLAY_SELECT: 13
+
};
- $timeout (function () {
+ $timeout(function () {
var keyCode = evt.keyCode;
-
- console.log (keyCode + " PRESSED");
+
+ console.log(keyCode + " PRESSED");
if (keyCode == keyCodes.ESC) {
$scope.closeModal();
- }
- else if (keyCode == keyCodes.LEFT) {
-
- $scope.jumpToEvent($scope.prevId, -1);
- }
- else if (keyCode == keyCodes.RIGHT) {
+ } else if (keyCode == keyCodes.LEFT) {
+
+ $scope.jumpToEvent($scope.prevId, -1);
+ } else if (keyCode == keyCodes.RIGHT) {
$scope.jumpToEvent($scope.nextId, 1);
- }
- else if (keyCode == keyCodes.FITFILL_F) {
+ } else if (keyCode == keyCodes.FITFILL_F) {
$scope.scaleImage();
- }
- else if (keyCode == keyCodes.PLAY_SELECT) {
+ } else if (keyCode == keyCodes.PLAY_SELECT) {
if ($scope.isSnapShot() && !$scope.liveFeedMid) {
$scope.convertSnapShotToStream();
- }
- else {
- NVRDataModel.debug ("Not in snapshot mode, ignoring");
+ } else {
+ NVRDataModel.debug("Not in snapshot mode, ignoring");
}
}
@@ -407,13 +402,14 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
// pass: loginData.password
}
})
- .success(function (resp) {
- // NVRDataModel.debug ("processEvent success:"+JSON.stringify(resp));
+ .then(function (resp) {
+ //NVRDataModel.debug ("processEvent success:"+JSON.stringify(resp));
+ resp = resp.data;
if (resp.result == "Ok") {
if (resp.status) $scope.currentProgress.progress = resp.status.progress;
- if (resp.status) $scope.eventId = resp.status.event;
+ if (resp.status && resp.status.event) $scope.eventId = resp.status.event;
$scope.d_eventId = $scope.eventId;
if (resp.status) $scope.currentRate = resp.status.rate;
@@ -444,8 +440,8 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
NVRDataModel.debug("so I'm regenerating Connkey to " + $scope.connKey);*/
}
- })
- .error(function (resp) {
+ },
+ function (resp) {
NVRDataModel.debug("processEvent error:" + JSON.stringify(resp));
//eventQueryHandle = $timeout (function(){checkEvent();}, zm.eventPlaybackQuery);
@@ -509,7 +505,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$ionicLoading.show({
template: $translate.instant('kDone'),
noBackdrop: true,
- duration: 1000
+ duration: 2000
});
NVRDataModel.debug("ModalCtrl:Photo saved successfuly");
}
@@ -518,9 +514,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$ionicLoading.show({
template: $translate.instant('kErrorSave'),
noBackdrop: true,
- duration: 2000
+ duration: 3000
});
- NVRDataModel.log("Error saving image: " + e.message);
+ //NVRDataModel.log("Error saving image: " + e.message);
//console.log("***ERROR");
}
@@ -528,6 +524,36 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
// streamReq.send( streamParms+"&command="+CMD_SEEK+"&offset="+offset );
};
+
+ $scope.saveEventVideoToPhoneWithPerms = function () {
+
+ if ($rootScope.platformOS != 'android') {
+ saveNow();
+ return;
+ }
+
+ NVRDataModel.debug("EventModalCtrl: Permission checking for write");
+ var permissions = cordova.plugins.permissions;
+ permissions.hasPermission(permissions.WRITE_EXTERNAL_STORAGE, checkPermissionCallback, null);
+
+ function checkPermissionCallback(status) {
+ if (!status.hasPermission) {
+ SaveError("No permission to write to external storage");
+ }
+ permissions.requestPermission(permissions.WRITE_EXTERNAL_STORAGE, succ, err);
+ }
+
+ function succ(s) {
+ saveNow();
+ }
+
+ function err(e) {
+ SaveError("Error in requestPermission");
+ }
+
+ };
+
+
//-----------------------------------------------------------------------
// Saves a snapshot of the monitor image to phone storage
//-----------------------------------------------------------------------
@@ -562,8 +588,21 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
function processSaveEventImageToPhone(onlyAlarms) {
+
+
+ if ($scope.isSnapShot()) {
+
+
+ $scope.selectEventUrl = $scope.constructStream();
+ NVRDataModel.debug("just saving current snapshot:" + $scope.selectEventUrl);
+ saveNow("image");
+ return;
+
+ }
+
if ($scope.loginData.useNphZmsForEvents) {
NVRDataModel.log("Use ZMS stream to save to phone");
+
saveEventImageToPhoneZms(onlyAlarms);
} else {
@@ -587,13 +626,13 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
sendCommand('1', $scope.connKey).
then(function (resp) {
- console.log ("PAUSE ANSWER IS " + JSON.stringify(resp));
+ console.log("PAUSE ANSWER IS " + JSON.stringify(resp));
if (resp && resp.data && resp.data.status)
$scope.currentProgress.progress = resp.data.status.progress;
- else
- $scope.currentProgress.progress = 100;
-
+ else
+ $scope.currentProgress.progress = 100;
+
// console.log ("STEP 0 progress is " + $scope.currentProgress.progress);
$scope.slides = [];
@@ -706,24 +745,33 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
// console.log ("________________UNUSED?_______________________");
var curState = carouselUtils.getStop();
carouselUtils.setStop(true);
+ var url;
//console.log("Your index is " + $scope.mycarousel.index);
//console.log("Associated image is " + $scope.slides[$scope.mycarousel.index].img);
+
+
+
NVRDataModel.debug("ModalCtrl: SaveEventImageToPhone called");
var canvas, context, imageDataUrl, imageData;
var loginData = NVRDataModel.getLogin();
// for alarms only
- if (onlyAlarms) $scope.mycarousel.index = 0;
- var url;
+ if (onlyAlarms || ($scope.defaultVideo !== undefined && $scope.defaultVideo != ''))
+ $scope.mycarousel.index = 1;
+
if ($scope.event.Event.imageMode == 'path') {
url = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&path=" + $scope.relativePath + $scope.slides[$scope.mycarousel.index].img;
} else {
+
+ console.log("SLIDES " + JSON.stringify($scope.slides));
+ console.log("CAROUSEL " + JSON.stringify($scope.mycarousel));
+
url = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand +
"&eid=" + $scope.eventId +
- "&fid=" + $scope.slides[$scope.mycarousel.index].id;
+ "&fid=" + $scope.slides[$scope.mycarousel.index - 1].id;
}
if ($rootScope.authSession != 'undefined') {
@@ -867,68 +915,141 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
text: '',
type: 'button-positive button-small ion-checkmark-round',
onTap: function (e) {
- saveNow();
+ saveNow("image");
}
}
]
});
- function saveNow() {
- $ionicLoading.show({
- template: $translate.instant('kSavingSnapshot') + "...",
- noBackdrop: true,
- duration: zm.httpTimeout
- });
- var url = $scope.selectEventUrl;
- NVRDataModel.log("saveNow: File path to grab is " + url);
-
- var img = new Image();
- img.onload = function () {
- // console.log("********* ONLOAD");
- canvas = document.createElement('canvas');
- canvas.width = img.width;
- canvas.height = img.height;
- context = canvas.getContext('2d');
- context.drawImage(img, 0, 0);
-
- imageDataUrl = canvas.toDataURL('image/jpeg', 1.0);
- imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, '');
-
- if ($rootScope.platformOS != "desktop") {
- try {
-
- cordova.exec(
- SaveSuccess,
- SaveError,
- 'Canvas2ImagePlugin',
- 'saveImageDataToLibrary', [imageData]
- );
- // carouselUtils.setStop(curState);
- } catch (e) {
-
- SaveError(e.message);
- // carouselUtils.setStop(curState);
- }
- } else {
- var fname = $scope.relativePath + $scope.slides[$scope.slideIndex].img + ".png";
- fname = fname.replace(/\//, "-");
- fname = fname.replace(/\.jpg/, '');
- canvas.toBlob(function (blob) {
- saveAs(blob, fname);
- SaveSuccess();
- });
+ }
+
+ function saveNow(t) {
+
+ var fname = "zmninja.jpg";
+ var fn = "cordova.plugins.photoLibrary.saveImage";
+ var loginData = NVRDataModel.getLogin();
+
+ $ionicLoading.show({
+ template: $translate.instant('kPleaseWait') + "...",
+ noBackdrop: true,
+ duration: zm.httpTimeout
+ });
+
+ if ($scope.defaultVideo !== undefined && $scope.defaultVideo != '' && t != "image") {
+ $scope.selectEventUrl = $scope.video_url;
+ fname = "zmNinja.mp4";
+ fn = "cordova.plugins.photoLibrary.saveVideo";
+
+
+ }
+
+ NVRDataModel.debug("-->Going to try and download " + $scope.selectEventUrl);
+ var url = $scope.selectEventUrl;
+
+
+ NVRDataModel.log(">>saveNow: File path to grab is " + url);
+
+ if ($rootScope.platformOS != 'desktop') {
+
+ var album = 'zmNinja';
+ NVRDataModel.debug("Trying to save image to album: " + album);
+ cordova.plugins.photoLibrary.requestAuthorization(
+ function () {
+ //url = "https://picsum.photos/200/300/?random";
+
+ var fileTransfer = new FileTransfer();
+ var urle = encodeURI(url);
+
+
+ fileTransfer.onprogress = function (progressEvent) {
+ if (progressEvent.lengthComputable) {
+
+ $timeout(function () {
+ var perc = Math.floor(progressEvent.loaded / progressEvent.total * 100);
+ $ionicLoading.show({
+ template: $translate.instant('kPleaseWait') + "... (" + perc + "%)",
+ noBackdrop: true,
+ //duration: zm.httpTimeout
+ });
+ });
+
+
+ }
+ };
+
+ fileTransfer.download(urle, cordova.file.dataDirectory + fname,
+ function (entry) {
+ NVRDataModel.debug("local download complete: " + entry.toURL());
+ NVRDataModel.debug("Now trying to move it to album");
+ var pluginName = (fname == "zmNinja.mp4" ? "saveVideo" : "saveImage");
+
+
+ cordova.plugins.photoLibrary[pluginName](entry.toURL(), album,
+ function (cameraRollAssetId) {
+ SaveSuccess();
+ $cordovaFile.removeFile(cordova.file.dataDirectory, fname)
+ .then(
+ function () {
+ NVRDataModel.debug("file removed from data directory");
+ },
+ function (e) {
+ NVRDataModel.debug("could not delete temp file: " + JSON.stringify(e));
+ }
+ );
+
+
+ },
+ function (err) {
+ NVRDataModel.debug("Saving error:" + JSON.stringify(err));
+ SaveError();
+
+ });
+
+
+
+
+ },
+ function (err) {
+ NVRDataModel.log("error downloading:" + JSON.stringify(err));
+ SaveError();
+ }, !loginData.enableStrictSSL, {});
+
+
+
+
+ // User gave us permission to his library, retry reading it!
+ },
+ function (err) {
+ // User denied the access
+ NVRDataModel.debug("Permission not granted");
+ SaveError();
+ }, // if options not provided, defaults to {read: true}.
+
+ {
+ read: true,
+ write: true
}
- };
- try {
- img.src = url;
- // console.log ("SAVING IMAGE SOURCE");
- } catch (e) {
- SaveError(e.message);
- }
+ );
+
+ } else {
+ //desktop
+
+ $ionicLoading.hide();
+
+ $rootScope.zmPopup = SecuredPopups.show('alert', {
+ title: $translate.instant('kNote'),
+ template: $translate.instant('kDownloadVideoImage')+"<br/><br/><center><a href='" + url + "' class='button button-assertive icon ion-android-download' download>"+" "+$translate.instant('kDownload')+"</a></center>",
+ okText: $translate.instant('kDismiss'),
+ okType:'button-stable'
+ });
+
+
+
}
+
}
$scope.reloadView = function () {
@@ -946,8 +1067,8 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$scope.constructStream = function (monitor) {
+ //console.log ("STREAMSTATE ="+currentStreamState);
if ($scope.animationInProgress) return "";
-
var stream = "";
// eventId gets populated when prepareModal completes
if (currentStreamState == streamState.STOPPED || !$scope.eventId) {
@@ -971,7 +1092,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
}
//console.log ($scope.connKey );
- // console.log ("STREAM="+stream);
+ //console.log ("STREAM="+stream);
//console.log ("EID="+$scope.eventId);
if ($rootScope.basicAuthToken && stream) stream += "&basicauth=" + $rootScope.basicAuthToken;
return stream;
@@ -1166,7 +1287,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$scope.videoTime = function (s, c) {
- // console.log ("VIDEO TIME WITH "+s+ " and "+c);
+ // console.log ("VIDEO TIME WITH "+s+ " and "+c);
var a, o;
if (NVRDataModel.getLogin().useLocalTimeZone) {
a = moment.tz(s, NVRDataModel.getTimeZoneNow()).tz(moment.tz.guess());
@@ -1184,10 +1305,10 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$scope.$on('modal.removed', function (e, m) {
- if ($rootScope.platformOS == 'desktop') {
- NVRDataModel.debug ("Removing keyboard handler");
+ if ($rootScope.platformOS == 'desktop') {
+ NVRDataModel.debug("Removing keyboard handler");
window.removeEventListener('keydown', keyboardHandler, true);
-
+
}
NVRDataModel.debug("Deregistering broadcast handles");
@@ -1429,7 +1550,8 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
});
return $http.delete(apiDelete)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
$ionicLoading.hide();
// NVRDataModel.debug("delete output: " + JSON.stringify(data));
@@ -1459,8 +1581,8 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
//doRefresh();
- })
- .error(function (data) {
+ },
+ function (data) {
$ionicLoading.hide();
NVRDataModel.debug("delete error: " + JSON.stringify(data));
NVRDataModel.displayBanner('error', [$translate.instant('kDeleteEventError1'), $translate.instant('kDeleteEventError2')]);
@@ -1810,8 +1932,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
// console.log ("**ONLY ALARM AT " + i + "of " + data.event.Frame.length);
- if (ts != data.event.Frame[i].TimeStamp)
- {
+ if (ts != data.event.Frame[i].TimeStamp) {
tempAlarms.push({
id: data.event.Frame[i].Id,
@@ -1819,7 +1940,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
});
ts = data.event.Frame[i].TimeStamp;
}
-
+
}
diff --git a/www/js/EventServer.js b/www/js/EventServer.js
index fae8b307..a460795c 100644
--- a/www/js/EventServer.js
+++ b/www/js/EventServer.js
@@ -16,39 +16,25 @@ angular.module('zmApp.controllers')
var localNotificationId = 0;
var pushInited = false;
var isTimerOn = false;
+ var nativeWebSocketId = -1;
+
//--------------------------------------------------------------------------
// called when the websocket is opened
//--------------------------------------------------------------------------
- function openHandshake() {
- NVRDataModel.log("Inside openHandshake");
- var loginData = NVRDataModel.getLogin();
- if (loginData.isUseEventServer == false || loginData.eventServer == "") {
- NVRDataModel.log("openHandShake: no event server");
- return;
- }
-
- if (typeof ws == 'undefined') {
- NVRDataModel.debug("websocket is undefined, need to create ws before I can sent auth");
- ws = $websocket(loginData.eventServer, {
- reconnectIfNotNormalClose: false
- });
- // ws.onOpen(openHandshake);
- // return;
- }
+ function handleOpen(data) {
+ NVRDataModel.debug("WebSocket open called with:" + JSON.stringify(data));
+ var loginData = NVRDataModel.getLogin();
NVRDataModel.log("openHandshake: Websocket open, sending Auth");
- ws.send({
- event: 'auth',
- data: {
- user: loginData.username,
- password: loginData.password
- }
-
+ sendMessage("auth", {
+ user: loginData.username,
+ password: loginData.password
});
+
if ($rootScope.apnsToken != '') {
var plat = $ionicPlatform.is('ios') ? 'ios' : 'android';
var ld = NVRDataModel.getLogin();
@@ -60,276 +46,296 @@ angular.module('zmApp.controllers')
// let's do this only if disabled. If enabled, I suppose registration
// will be called?
//if (ld.disablePush)
- if (1) {
- //console.log ("HANDSHAKE MESSAGE WITH "+$rootScope.monstring);
- ws.send({
- event: 'push',
- data: {
- type: 'token',
- platform: plat,
- token: $rootScope.apnsToken,
- monlist: $rootScope.monstring,
- intlist: $rootScope.intstring,
- state: pushstate
- }
- });
- }
+ //console.log ("HANDSHAKE MESSAGE WITH "+$rootScope.monstring);
+
+ sendMessage("push", {
+ type: 'token',
+ platform: plat,
+ token: $rootScope.apnsToken,
+ monlist: $rootScope.monstring,
+ intlist: $rootScope.intstring,
+ state: pushstate
+
+ });
}
}
- //--------------------------------------------------------------------------
- // Called once at app start. Does a lazy definition of websockets open
- //--------------------------------------------------------------------------
- function init() {
+ function handleClose(event) {
+ console.log("*********** WEBSOCKET CLOSE CALLED");
+ if (!NVRDataModel.getLogin().isUseEventServer) return;
- $rootScope.isAlarm = 0;
- $rootScope.alarmCount = "0";
+ if (!isTimerOn) {
+ NVRDataModel.log("Will try to reconnect in 10 sec..");
+ $timeout(init, 10000);
+ isTimerOn = true;
+ }
+ }
- isTimerOn = false;
+ function handleError(event) {
+ console.log("*********** WEBSOCKET ERROR CALLED");
+ if (!NVRDataModel.getLogin().isUseEventServer) return;
- var d = $q.defer();
+ if (!isTimerOn) {
+ NVRDataModel.log("Will try to reconnect in 10 sec..");
+ $timeout(init, 10000);
+ isTimerOn = true;
+ }
+ }
- var loginData = NVRDataModel.getLogin();
+ function handleMessage(smsg) {
+ //NVRDataModel.debug ("Websocket received message:"+smsg);
+ str = JSON.parse(smsg);
+ NVRDataModel.debug("Real-time event: " + JSON.stringify(str));
- //console.log ("INIT GOT " + JSON.stringify(loginData));
- if (loginData.isUseEventServer == false || !loginData.eventServer) {
- NVRDataModel.log("No Event Server present. Not initializing");
- d.reject("false");
- return d.promise;
- }
- //if (!$rootScope.apnsToken)
- if (!pushInited) pushInit();
+ // Error messages
+ if (str.status != 'Success') {
+ NVRDataModel.log("Event Error: " + JSON.stringify(str));
- // console.log ("WS TYPEOF="+ typeof ws);
- // console.log ("WS="+JSON.stringify(ws));
- /*if (typeof ws !== 'undefined')
- {
- NVRDataModel.debug("websocket already initialized --Forcing close");
- ws.close(true);
- ws=undefined;
-
- }*/
+ if (str.reason == 'APNSDISABLED') {
+ console.log("FORCE CLOSING");
+ ws.close();
+ NVRDataModel.displayBanner('error', ['Event Server: APNS disabled'], 2000, 6000);
+ $rootScope.apnsToken = "";
+ }
- NVRDataModel.log("Initializing Websocket with URL " +
- loginData.eventServer);
- /* ws = $websocket.$new(
- {
- url: loginData.eventServer,
- reconnect: true,
- reconnectInterval: 60000,
- lazy: true
- });*/
-
- ws = $websocket(loginData.eventServer, {
- reconnectIfNotNormalClose: false
- });
- ws.onOpen(openHandshake);
+ }
- initCalled = true;
- // Transmit auth information to server
- // ws.$on('$open', openHandshake);
+ if (str.status == 'Success' && (str.event == 'auth')) {
+ if (str.version == undefined)
+ str.version = "0.1";
+ if (NVRDataModel.versionCompare(str.version, zm.minEventServerVersion) == -1) {
+ $rootScope.zmPopup = $ionicPopup.alert({
+ title: $translate.instant('kEventServerVersionTitle'),
+ template: $translate.instant('kEventServerVersionBody1') + " " + str.version + ". " + $translate.instant('kEventServerVersionBody2') + " " +
+ zm.minEventServerVersion,
+ okText: $translate.instant('kButtonOk'),
+ cancelText: $translate.instant('kButtonCancel'),
+ });
+ }
- if (ws) {
- ws.onErrorCallbacks = [];
- NVRDataModel.debug("Removing error handlers for websocket");
}
- NVRDataModel.debug("Setting up websocket error handler");
- //ws.$on('$error', function(e)
- ws.onError(function (e) {
+ if (str.status == 'Success' && str.event == 'alarm') // new events
+ {
- NVRDataModel.debug("Websocket Errorhandler called");
+ var localNotText;
+ // ZMN specific hack for Event Server
+ if (str.supplementary != 'true') {
+ new Audio('sounds/blop.mp3').play();
+ localNotText = "";
+ $rootScope.isAlarm = 1;
+
+ // Show upto a max of 99 when it comes to display
+ // so aesthetics are maintained
+ if ($rootScope.alarmCount == "99") {
+ $rootScope.alarmCount = "99+";
+ }
+ if ($rootScope.alarmCount != "99+") {
+ $rootScope.alarmCount = (parseInt($rootScope.alarmCount) + 1).toString();
+ }
- var timeElapsedSinceResume = NVRDataModel.getTimeSinceResumed();
+ } else {
+ NVRDataModel.debug("received supplementary event information over websockets");
+ }
+ var eventsToDisplay = [];
+ var listOfMonitors = [];
+ for (var iter = 0; iter < str.events.length; iter++) {
+ // lets stack the display so they don't overwrite
+ //eventsToDisplay.push(str.events[iter].Name + ": latest new alarm (" + str.events[iter].EventId + ")");
+ var txt = str.events[iter].EventId;
+ if (str.events[iter].Cause) {
+ txt = str.events[iter].Cause;
+ }
+ eventsToDisplay.push(str.events[iter].Name + ": " + txt);
+ localNotText = localNotText + str.events[iter].Name + ": " + txt + ",";
+ listOfMonitors.push(str.events[iter].MonitorId);
- if (timeElapsedSinceResume == -1) {
- // so we display error
- timeElapsedSinceResume = moment().subtract('1', hour);
}
+ localNotText = localNotText.substring(0, localNotText.length - 1);
- var duration = moment.duration(moment().diff(timeElapsedSinceResume)).asSeconds().toFixed(1);
+ // if we are in background, do a local notification, else do an in app display
+ if (!NVRDataModel.isBackground()) {
- NVRDataModel.debug(">> time since resumed is " + duration + " seconds");
+ //emit alarm details - this is when received over websockets
+ $rootScope.$broadcast('alarm', {
+ message: listOfMonitors
+ });
- if (duration > zm.waitTimeTillResume) {
+ if (str.supplementary != 'true') {
- $timeout(function () {
- var eserr = $translate.instant('kEventServerConnErr');
- NVRDataModel.displayBanner('error', [eserr]);
- }, 1000); // leave time for transitions
+ NVRDataModel.debug("App is in foreground, displaying banner");
+ if (eventsToDisplay.length > 0) {
- } else {
- NVRDataModel.debug("ES error happened " + timeElapsedSinceResume + " secs after resume, maybe fake, lets wait...");
+ if (eventsToDisplay.length == 1) {
+ //console.log("Single Display: " + eventsToDisplay[0]);
+ NVRDataModel.displayBanner('alarm', [eventsToDisplay[0]], 5000, 5000);
+ } else {
+ NVRDataModel.displayBanner('alarm', eventsToDisplay,
+ 5000, 5000 * eventsToDisplay.length);
+ }
+
+ }
+ }
}
+ }
+ }
- /*if (typeof ws !== 'undefined'){
- NVRDataModel.debug ("-->Forcing socket close");
- ws.close(true);
+ //--------------------------------------------------------------------------
+ // Called once at app start. Does a lazy definition of websockets open
+ //--------------------------------------------------------------------------
+ function init() {
- }*/
+ $rootScope.isAlarm = 0;
+ $rootScope.alarmCount = "0";
+ isTimerOn = false;
- ws = undefined;
+ var d = $q.defer();
+ var loginData = NVRDataModel.getLogin();
- NVRDataModel.log("Will try to reconnect in 10 sec..");
- if (!isTimerOn) {
- $timeout(init, 10000);
- isTimerOn = true;
- }
+ if (loginData.isUseEventServer == false || !loginData.eventServer) {
+ NVRDataModel.log("No Event Server present. Not initializing");
+ d.reject("false");
+ return d.promise;
+ }
+ NVRDataModel.log("Initializing Websocket with URL " +
+ loginData.eventServer);
- //console.log ("VALUE TIME " + lastEventServerCheck);
- //console.log ("NOW TIME " + Date.now());
- });
+ if ($rootScope.platforOS == 'desktop') {
+ NVRDataModel.debug("Using browser websockets...");
+ return setupDesktopSocket();
+ } else {
+ NVRDataModel.debug("Using native websockets...");
+ return setupMobileSocket();
- ws.onClose(function ()
- // ws.$on('$close', function()
- {
- NVRDataModel.log("Websocket closed");
- ws = undefined;
+ }
- var ld = NVRDataModel.getLogin();
- /* if (ld.isUseEventServer && !isTimerOn) {
- // this means remote error, because zmN still
- // wants it on
- $timeout ( init, 10000 );
- isTimerOn = true;
- }*/
+ }
- });
- // Handles responses back from ZM ES
+ function setupMobileSocket() {
- ws.onMessage(function (str)
- // ws.$on('$message', function(str)
+ var loginData = NVRDataModel.getLogin();
+ var d = $q.defer();
- {
- str = JSON.parse(str.data);
- //console.log ("FULL MESSAGE="+JSON.stringify(str.data));
- NVRDataModel.debug("Real-time event: " + JSON.stringify(str));
+ var wsOptions = {
+ url: loginData.eventServer,
+ acceptAllCerts: !loginData.enableStrictSSL
+ };
+
+ CordovaWebsocketPlugin.wsConnect(wsOptions,
+ function (recvEvent) {
+ console.log("Received callback from WebSocket: " + recvEvent.callbackMethod);
+ if (recvEvent.callbackMethod == 'onMessage') {
+ handleMessage(recvEvent.message);
+ } else if (recvEvent.callbackMethod == 'onClose') {
+ handleClose();
+ } else if (recvEvent.callbackMethod == 'onFail') {
+ handleError();
+ }
- // Error messages
- if (str.status != 'Success') {
- NVRDataModel.log("Event Error: " + JSON.stringify(str));
+ },
+ function (success) {
+ console.log("Connected to WebSocket with id: " + success.webSocketId);
+ nativeWebSocketId = success.webSocketId;
+ handleOpen(success);
+ if (!pushInited) {
+ NVRDataModel.debug("Initializing FCM push");
+ pushInit();
+ }
+ d.resolve(true);
+ return d.promise;
+ },
+ function (error) {
+ console.log("Failed to connect to WebSocket: " +
+ "code: " + error.code +
+ ", reason: " + error.reason +
+ ", exception: " + error.exception);
+ d.resolve(false);
+ return d.promise;
+ }
+ );
+ return d.promise;
+ }
- if (str.reason == 'APNSDISABLED') {
- ws.close();
- NVRDataModel.displayBanner('error', ['Event Server: APNS disabled'], 2000, 6000);
- $rootScope.apnsToken = "";
- }
+ function setupDesktopSocket() {
- }
+ var d = $q.defer();
+ ws = new WebSocket(loginData.eventServer);
- if (str.status == 'Success' && (str.event == 'auth')) {
- if (str.version == undefined)
- str.version = "0.1";
- if (NVRDataModel.versionCompare(str.version, zm.minEventServerVersion) == -1) {
- $rootScope.zmPopup = $ionicPopup.alert({
- title: $translate.instant('kEventServerVersionTitle'),
- template: $translate.instant('kEventServerVersionBody1') + " " + str.version + ". " + $translate.instant('kEventServerVersionBody2') + " " +
- zm.minEventServerVersion,
- okText: $translate.instant('kButtonOk'),
- cancelText: $translate.instant('kButtonCancel'),
- });
- }
+ ws.onopen = function (event) {
+ handleOpen(event.data);
+ if (!pushInited) {
+ NVRDataModel.debug("Initializing FCM push");
+ pushInit();
+ }
+ d.resolve("true");
+ return d.promise;
+ };
- }
- if (str.status == 'Success' && str.event == 'alarm') // new events
- {
+ ws.onclose = function (event) {
+ handleClose(event);
+ d.reject("error");
+ return d.promise;
- var localNotText;
- // ZMN specific hack for Event Server
- if (str.supplementary != 'true') {
- new Audio('sounds/blop.mp3').play();
- localNotText = "";
- $rootScope.isAlarm = 1;
-
- // Show upto a max of 99 when it comes to display
- // so aesthetics are maintained
- if ($rootScope.alarmCount == "99") {
- $rootScope.alarmCount = "99+";
- }
- if ($rootScope.alarmCount != "99+") {
- $rootScope.alarmCount = (parseInt($rootScope.alarmCount) + 1).toString();
- }
+ };
- } else {
- NVRDataModel.debug("received supplementary event information over websockets");
- }
- var eventsToDisplay = [];
- var listOfMonitors = [];
- for (var iter = 0; iter < str.events.length; iter++) {
- // lets stack the display so they don't overwrite
- //eventsToDisplay.push(str.events[iter].Name + ": latest new alarm (" + str.events[iter].EventId + ")");
- var txt = str.events[iter].EventId;
- if (str.events[iter].Cause) {
- txt = str.events[iter].Cause;
- }
- eventsToDisplay.push(str.events[iter].Name + ": " + txt);
- localNotText = localNotText + str.events[iter].Name + ": " + txt + ",";
- listOfMonitors.push(str.events[iter].MonitorId);
+ ws.onerror = function (event) {
+ handleError(event);
+ d.reject("error");
+ return d.promise;
- }
- localNotText = localNotText.substring(0, localNotText.length - 1);
+ };
- // if we are in background, do a local notification, else do an in app display
- if (!NVRDataModel.isBackground()) {
- //emit alarm details - this is when received over websockets
- $rootScope.$broadcast('alarm', {
- message: listOfMonitors
- });
+ ws.onmessage = function (event) {
- if (str.supplementary != 'true') {
+ var smsg = event.data;
+ handleMessage(smsg);
- NVRDataModel.debug("App is in foreground, displaying banner");
- if (eventsToDisplay.length > 0) {
- if (eventsToDisplay.length == 1) {
- //console.log("Single Display: " + eventsToDisplay[0]);
- NVRDataModel.displayBanner('alarm', [eventsToDisplay[0]], 5000, 5000);
- } else {
- NVRDataModel.displayBanner('alarm', eventsToDisplay,
- 5000, 5000 * eventsToDisplay.length);
- }
+ };
+
+ return d.promise;
+ }
- }
- }
- }
- } //end of success handler
- });
- d.resolve("true");
- return (d.promise);
- }
function disconnect() {
- if (typeof ws === 'undefined') {
- NVRDataModel.log("Event server socket is empty, nothing to disconnect");
- return;
- }
NVRDataModel.log("Clearing error/close cbk, disconnecting and deleting Event Server socket...");
- // ws.$close();
- ws.onErrorCallbacks = [];
- ws.onCloseCallbacks = [];
- ws.close(true); // force close
- // ws.$un('open');
- // ws.$un('close');
- // ws.$un('message');
- ws = undefined;
+
+ if ($rootScope.platforOS == 'desktop'){
+ if (typeof ws === 'undefined') {
+ NVRDataModel.log("Event server socket is empty, nothing to disconnect");
+ return;
+ }
+
+
+ ws.onmessage = null;
+ ws.close();
+ ws = undefined;
+ }
+ else {
+ if (nativeWebSocketId != -1) //native;
+ CordovaWebsocketPlugin.wsClose(nativeWebSocketId, 1000, "Connection closed");
+ nativeWebSocketId = -1;
+
+ }
+
}
@@ -348,43 +354,31 @@ angular.module('zmApp.controllers')
return;
}
- if (typeof ws === 'undefined') {
+ if (typeof ws === 'undefined' && nativeWebSocketId == -1) {
NVRDataModel.debug("Event server not initalized, not sending message");
return;
}
// console.log (">>>>>>>>>>>>>>>>>EVENT SERVER SENDING: type="+type+" DATA="+JSON.stringify(obj));
- ws.send({
+
+ var msg = {
'event': type,
'data': obj
- });
-
- /*if (ws.$status() == ws.$CLOSED)
- {
- NVRDataModel.log("Websocket was closed, trying to re-open");
- ws.$un('$open');
- //ws.$on ('$open', openHandshake);
- ws.$open();
-
- ws.$on('$open', openHandshake, function()
- {
+ };
- //console.log(" sending " + type + " " +
- // JSON.stringify(obj));
- //console.log("sending " + type + " " + JSON.stringify(obj));
- ws.$emit(type, obj);
-
- ws.$un('$open');
- ws.$on('$open', openHandshake);
-
- });
+ var jmsg = JSON.stringify(msg);
+ NVRDataModel.debug("~~~~ sendMessage: Sending->" + jmsg);
+ if ($rootScope.platformOS == 'desktop') {
+ ws.send(jmsg);
}
- else*
- {
- ws.send(type, obj);
- // console.log("sending " + type + " " + JSON.stringify(obj));
- }*/
+ else {
+ if (nativeWebSocketId != -1)
+ CordovaWebsocketPlugin.wsSend(nativeWebSocketId, jmsg);
+ else
+ NVRDataModel.debug ("ERROR:native websocket not initialized, can't send "+jmsg);
+ }
+
}
diff --git a/www/js/EventServerSettingsCtrl.js b/www/js/EventServerSettingsCtrl.js
index 24928007..c5857369 100644
--- a/www/js/EventServerSettingsCtrl.js
+++ b/www/js/EventServerSettingsCtrl.js
@@ -212,7 +212,8 @@
EventServer.sendMessage("control", {
type: 'filter',
monlist: monstring,
- intlist: intervalstring
+ intlist: intervalstring,
+ token: $rootScope.apnsToken
}, 1);
if ($rootScope.apnsToken != "")
@@ -231,7 +232,12 @@
}
- });
+ },
+ function (err) {
+ NVRDataModel.debug("Event Server init failed");
+ }
+
+ );
} // no event server configured/enabled
else {
diff --git a/www/js/EventsGraphsCtrl.js b/www/js/EventsGraphsCtrl.js
index bfffb351..cad2cc0b 100644
--- a/www/js/EventsGraphsCtrl.js
+++ b/www/js/EventsGraphsCtrl.js
@@ -190,12 +190,13 @@ angular.module('zmApp.controllers').controller('zmApp.EventsGraphsCtrl', ['$ioni
// console.log("Monitor event URL:" + url);
NVRDataModel.log("EventGraph: composed url is " + url);
$http.get(url /*,{timeout:15000}*/ )
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
NVRDataModel.debug("Event count for monitor" +
monitors[j].Monitor.Id + " is " + data.pagination.count);
$scope.chart.data.datasets[0].data[j] = data.pagination.count;
- })
- .error(function (data) {
+ },
+ function (data) {
// ideally I should be treating it as an error
// but what I am really doing now is treating it like no events
// works but TBD: make this into a proper error handler
diff --git a/www/js/FirstUseCtrl.js b/www/js/FirstUseCtrl.js
index 89f45e96..1ad42e9c 100644
--- a/www/js/FirstUseCtrl.js
+++ b/www/js/FirstUseCtrl.js
@@ -18,8 +18,11 @@ angular.module('zmApp.controllers').controller('zmApp.FirstUseCtrl', ['$scope',
//
if (window.cordova) {
- cordova.plugins.certificates.trustUnsecureCerts(true);
- NVRDataModel.log(">>>>>Accepting all certificates, since its first use");
+ cordova.plugin.http.setSSLCertMode('nocheck', function() {
+ NVRDataModel.debug('--> First use -> SSL is permissive, will allow any certs for now. You can change it later.');
+ }, function() {
+ console.log('-->First Use -> Error setting SSL permissive');
+ });
}
diff --git a/www/js/LoginCtrl.js b/www/js/LoginCtrl.js
index 9410b276..d2dfe899 100644
--- a/www/js/LoginCtrl.js
+++ b/www/js/LoginCtrl.js
@@ -582,6 +582,27 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
if ($rootScope.platformOS != 'desktop') {
+ if ($scope.loginData.isUseBasicAuth) {
+ NVRDataModel.debug ("Cordova HTTP: configuring basic auth");
+ cordova.plugin.http.useBasicAuth($scope.loginData.basicAuthUser, $scope.loginData.basicAuthPassword);
+ }
+
+ if (!$scope.loginData.enableStrictSSL) {
+
+ //alert("Enabling insecure SSL");
+ NVRDataModel.log(">>>> Disabling strict SSL checking (turn off in Dev Options if you can't connect)");
+ cordova.plugin.http.setSSLCertMode('nocheck', function() {
+ NVRDataModel.debug('--> SSL is permissive, will allow any certs. Use at your own risk.');
+ }, function() {
+ console.log('-->Error setting SSL permissive');
+ });
+
+ } else {
+
+ NVRDataModel.log(">>>> Enabling strict SSL checking (turn off in Dev Options if you can't connect)");
+
+ }
+
if ($scope.loginData.saveToCloud) {
NVRDataModel.debug ("writing data to cloud");
@@ -628,21 +649,28 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
oldName = $scope.loginData.serverName;
if ($scope.loginData.isUseEventServer) {
- EventServer.init();
- if ($rootScope.apnsToken && $scope.loginData.disablePush != true) {
- NVRDataModel.log("Making sure we get push notifications");
- EventServer.sendMessage('push', {
- type: 'token',
- platform: $rootScope.platformOS,
- token: $rootScope.apnsToken,
- state: "enabled"
- }, 1);
- }
- EventServer.sendMessage("control", {
- type: 'filter',
- monlist: $scope.loginData.eventServerMonitors,
- intlist: $scope.loginData.eventServerInterval
+ EventServer.init()
+ .then (function (succ) {
+ if ($rootScope.apnsToken && $scope.loginData.disablePush != true) {
+ NVRDataModel.log("Making sure we get push notifications");
+ EventServer.sendMessage('push', {
+ type: 'token',
+ platform: $rootScope.platformOS,
+ token: $rootScope.apnsToken,
+ state: "enabled"
+ }, 1);
+ }
+ EventServer.sendMessage("control", {
+ type: 'filter',
+ monlist: $scope.loginData.eventServerMonitors,
+ intlist: $scope.loginData.eventServerInterval,
+ token: $rootScope.apnsToken
+ });
+ },
+ function (err) {
+ NVRDataModel.log ("Event server init failed");
});
+
}
@@ -672,8 +700,9 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
NVRDataModel.log("Validating APIs at " + apiurl);
$http.get(apiurl)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
NVRDataModel.getTimeZone(true);
var loginStatus = $translate.instant('kExploreEnjoy') + " " + $rootScope.appName + "!";
EventServer.refresh();
@@ -688,7 +717,8 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
NVRDataModel.log("ZM relative cgi-path: " + zm_cgi + ", you entered: " + user_cgi);
$http.get(ld.streamingurl + "/zms")
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
NVRDataModel.debug("Urk! cgi-path returned success, but it should not have come here");
loginStatus = $translate.instant('kLoginStatusNoCgi');
@@ -717,8 +747,8 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
});
}
- })
- .error(function (error, status) {
+ },
+ function (error, status) {
// If its 5xx, then the cgi-bin path is valid
// if its 4xx then the cgi-bin path is not valid
@@ -757,8 +787,8 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
});
});
- })
- .error(function (error) {
+ },
+ function (error) {
NVRDataModel.displayBanner('error', [$translate.instant('kBannerAPICheckFailed'), $translate.instant('kBannerPleaseCheck')]);
NVRDataModel.log("API login error " + JSON.stringify(error));
diff --git a/www/js/MenuController.js b/www/js/MenuController.js
index 995abba3..d9d4d114 100644
--- a/www/js/MenuController.js
+++ b/www/js/MenuController.js
@@ -2,14 +2,14 @@
/* jslint browser: true*/
/* global cordova,StatusBar,angular,console */
-angular.module('zmApp.controllers').controller('MenuController', ['$scope', '$ionicSideMenuDelegate', 'zm', '$stateParams', '$ionicHistory', '$state', 'NVRDataModel', '$rootScope', '$ionicPopup', '$translate', '$timeout', '$location','EventServer', 'zmAutoLogin','$http',function ($scope, $ionicSideMenuDelegate, zm, $stateParams, $ionicHistory, $state, NVRDataModel, $rootScope, $ionicPopup, $translate, $timeout, $location, EventServer, zmAutoLogin, $http) {
+angular.module('zmApp.controllers').controller('MenuController', ['$scope', '$ionicSideMenuDelegate', 'zm', '$stateParams', '$ionicHistory', '$state', 'NVRDataModel', '$rootScope', '$ionicPopup', '$translate', '$timeout', '$location','EventServer', 'zmAutoLogin','$http','SecuredPopups',function ($scope, $ionicSideMenuDelegate, zm, $stateParams, $ionicHistory, $state, NVRDataModel, $rootScope, $ionicPopup, $translate, $timeout, $location, EventServer, zmAutoLogin, $http, SecuredPopups) {
$scope.openMenu = function () {
$ionicSideMenuDelegate.toggleLeft();
};
//----------------------------------------------------------------
// This controller sits along with the main app to bring up
- // the language menu from the main menu
+ // the language menu from the main
//----------------------------------------------------------------
@@ -83,22 +83,48 @@ angular.module('zmApp.controllers').controller('MenuController', ['$scope', '$io
}
- if (loginData.isUseEventServer) {
- EventServer.init();
- if ($rootScope.apnsToken && loginData.disablePush != true) {
- NVRDataModel.log("Making sure we get push notifications");
- EventServer.sendMessage('push', {
- type: 'token',
- platform: $rootScope.platformOS,
- token: $rootScope.apnsToken,
- state: "enabled"
- }, 1);
+
+ if (window.cordova) {
+
+ if (loginData.isUseBasicAuth) {
+ NVRDataModel.debug ("Cordova HTTP: configuring basic auth");
+ cordova.plugin.http.useBasicAuth(loginData.basicAuthUser, loginData.basicAuthPassword);
+ }
+
+ if (!loginData.enableStrictSSL) {
+
+ //alert("Enabling insecure SSL");
+ NVRDataModel.log(">>>> Disabling strict SSL checking (turn off in Dev Options if you can't connect)");
+ cordova.plugin.http.setSSLCertMode('nocheck', function() {
+ NVRDataModel.debug('--> SSL is permissive, will allow any certs. Use at your own risk.');
+ }, function() {
+ console.log('-->Error setting SSL permissive');
+ });
+
+ } else {
+
+ NVRDataModel.log(">>>> Enabling strict SSL checking (turn off in Dev Options if you can't connect)");
+
}
- EventServer.sendMessage("control", {
- type: 'filter',
- monlist: loginData.eventServerMonitors,
- intlist: loginData.eventServerInterval
+
+ }
+
+
+ if (loginData.isUseEventServer) {
+ EventServer.init()
+ .then (function (succ) {
+ EventServer.sendMessage("control", {
+ type: 'filter',
+ monlist: loginData.eventServerMonitors,
+ intlist: loginData.eventServerInterval,
+ token: $rootScope.apnsToken
+ });
+ },
+ function (err) {
+ NVRDataModel.debug ("EventServer init failed");
});
+
+
}
@@ -119,8 +145,9 @@ angular.module('zmApp.controllers').controller('MenuController', ['$scope', '$io
NVRDataModel.log("Validating APIs at " + apiurl);
$http.get(apiurl)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
NVRDataModel.getTimeZone(true);
var loginStatus = $translate.instant('kExploreEnjoy') + " " + $rootScope.appName + "!";
EventServer.refresh();
@@ -135,7 +162,8 @@ angular.module('zmApp.controllers').controller('MenuController', ['$scope', '$io
NVRDataModel.log("ZM relative cgi-path: " + zm_cgi + ", you entered: " + user_cgi);
$http.get(ld.streamingurl + "/zms")
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
NVRDataModel.debug("Urk! cgi-path returned success, but it should not have come here");
loginStatus = $translate.instant('kLoginStatusNoCgi');
@@ -183,8 +211,8 @@ angular.module('zmApp.controllers').controller('MenuController', ['$scope', '$io
});
- })
- .error(function (error, status) {
+ },
+ function (error, status) {
// If its 5xx, then the cgi-bin path is valid
// if its 4xx then the cgi-bin path is not valid
@@ -233,8 +261,8 @@ angular.module('zmApp.controllers').controller('MenuController', ['$scope', '$io
});
});
- })
- .error(function (error) {
+ },
+ function (error) {
NVRDataModel.displayBanner('error', [$translate.instant('kBannerAPICheckFailed'), $translate.instant('kBannerPleaseCheck')]);
NVRDataModel.log("API login error " + JSON.stringify(error));
diff --git a/www/js/MonitorCtrl.js b/www/js/MonitorCtrl.js
index 38bdf765..881d6a2c 100644
--- a/www/js/MonitorCtrl.js
+++ b/www/js/MonitorCtrl.js
@@ -181,10 +181,10 @@ angular.module('zmApp.controllers')
}
})
- .success(function () {
+ .then(function () {
NVRDataModel.debug("MonitorCtrl: Not restarting ZM - Make sure you have the patch installed in MonitorsController.php or this won't work");
- })
- .error(function (data, status, headers, config) {
+ },
+ function (data, status, headers, config) {
NVRDataModel.debug("MonitorCtrl: Error changing monitor " + JSON.stringify(data));
$scope.monfunc.myfailedIds.push(item);
});
@@ -419,7 +419,8 @@ angular.module('zmApp.controllers')
NVRDataModel.debug("MonitorCtrl:monitorStateCheck: " + apiMonCheck);
//console.log("**** ZMC CHECK " + apiMonCheck);
$http.get(apiMonCheck)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
NVRDataModel.debug("MonitorCtrl: monitor check state returned: " + JSON.stringify(data));
if (data.statustext.indexOf("not running") > -1) {
$scope.monitors[j].Monitor.isRunning = "false";
@@ -438,8 +439,8 @@ angular.module('zmApp.controllers')
}
$scope.monitors[j].Monitor.isRunningText = data.statustext;
- })
- .error(function (data) {
+ },
+ function (data) {
NVRDataModel.debug("MonitorCtrl: Error->monitor check state returned: " +
JSON.stringify(data));
NVRDataModel.displayBanner('error', [$translate.instant('kErrorRetrievingState'), $translate.instant('kPleaseTryAgain')]);
diff --git a/www/js/MonitorModalCtrl.js b/www/js/MonitorModalCtrl.js
index 3d765aed..cc110197 100644
--- a/www/js/MonitorModalCtrl.js
+++ b/www/js/MonitorModalCtrl.js
@@ -3,7 +3,7 @@
/* jslint browser: true*/
/* global saveAs, cordova,StatusBar,angular,console,ionic, moment, imagesLoaded, chrome */
-angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$q', '$sce', 'carouselUtils', '$ionicPopup', 'SecuredPopups', '$translate', function ($scope, $rootScope, zm, NVRDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $q, $sce, carouselUtils, $ionicPopup, SecuredPopups, $translate) {
+angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$q', '$sce', 'carouselUtils', '$ionicPopup', 'SecuredPopups', '$translate', '$cordovaFile', function ($scope, $rootScope, zm, NVRDataModel, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $q, $sce, carouselUtils, $ionicPopup, SecuredPopups, $translate, $cordovaFile) {
$scope.animationInProgress = false;
$scope.imageFit = true;
@@ -37,7 +37,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
/* $ionicLoading.show({
template: $translate.instant('kNegotiatingStreamAuth') + '...',
animation: 'fade-in',
- showBackdrop: true,
+ showBackdrop: false,
duration: zm.loadingTimeout,
maxWidth: 300,
showDelay: 0
@@ -853,17 +853,18 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
});
- req.success(function (resp) {
+ req.then(function (resp) {
//console.log("SUCCESS: " + JSON.stringify(resp));
$ionicLoading.hide();
- });
-
- req.error(function (resp) {
+ },
+ function (resp) {
$ionicLoading.hide();
//console.log("ERROR: " + JSON.stringify(resp));
NVRDataModel.log("Error sending PTZ:" + JSON.stringify(resp), "error");
});
+
+
}
$scope.getZoomLevel = function () {
@@ -896,10 +897,20 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
function moveToMonitor(m, d) {
- $scope.animationInProgress = true;
+
if ($scope.isZoneEdit) {
NVRDataModel.log("Not cycling, as you are editing zones");
+ return;
}
+
+ if ($scope.monitors.length <= 1) {
+ NVRDataModel.log("Not cycling, as you only have at most 1 monitors");
+ return;
+ }
+
+
+
+ $scope.animationInProgress = true;
var curstate = $ionicHistory.currentStateName();
var found = 0;
var mid;
@@ -1036,9 +1047,9 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
//-------------------------------------------------------------
// Turns on or off an alarm forcibly (mode true = on, false = off)
//-------------------------------------------------------------
- $scope.enableAlarm = function (mid, mode) {
+ $scope.triggerAlarm = function (mid, mode) {
- if (mode) // trigger alarm
+ if (mode == 'on') // trigger alarm
{
$rootScope.zmPopup = SecuredPopups.show('show', {
title: 'Confirm',
@@ -1046,7 +1057,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
buttons: [{
text: $translate.instant('kButtonYes'),
onTap: function (e) {
- enableAlarm(mid, mode);
+ triggerAlarm(mid, mode);
}
},
{
@@ -1059,11 +1070,11 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
});
} else
- enableAlarm(mid, mode);
+ triggerAlarm(mid, mode);
- function enableAlarm(mid, mode) {
+ function triggerAlarm(mid, mode) {
var apiurl = NVRDataModel.getLogin().apiurl;
- var c = mode ? "on" : "off";
+ var c = mode=='on' ? 'on' : 'off';
var alarmurl = apiurl + "/monitors/alarm/id:" + mid + "/command:" + c + ".json";
NVRDataModel.log("Invoking " + alarmurl);
@@ -1081,6 +1092,8 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
noBackdrop: true,
duration: 2000,
});
+
+
},
function (error) {
@@ -1089,7 +1102,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
noBackdrop: true,
duration: 3000,
});
- NVRDataModel.debug("Error in enableAlarm " + JSON.stringify(error));
+ NVRDataModel.debug("Error in triggerAlarm " + JSON.stringify(error));
});
}
@@ -1183,49 +1196,75 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
NVRDataModel.log("SavetoPhone:Trying to save image from " + url);
- var img = new Image();
- img.onload = function () {
- // console.log("********* ONLOAD");
- canvas = document.createElement('canvas');
- canvas.width = img.width;
- canvas.height = img.height;
- context = canvas.getContext('2d');
- context.drawImage(img, 0, 0);
-
- imageDataUrl = canvas.toDataURL('image/jpeg', 1.0);
- imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, '');
-
- if ($rootScope.platformOS != "desktop") {
- try {
-
- cordova.exec(
- SaveSuccess,
- SaveError,
- 'Canvas2ImagePlugin',
- 'saveImageDataToLibrary', [imageData]
- );
- } catch (e) {
-
- SaveError(e.message);
- }
- } else {
+ if ($rootScope.platformOS != 'desktop') {
+ var album = 'zmNinja';
+ NVRDataModel.debug ("Trying to save image to album: "+album);
+ cordova.plugins.photoLibrary.requestAuthorization(
+ function () {
+ //url = "https://picsum.photos/200/300/?random";
+
+ var fileTransfer = new FileTransfer();
+ var urle = encodeURI(url);
+ var fname = "zmninja.jpg";
+
+ fileTransfer.download(urle, cordova.file.dataDirectory + fname,
+ function(entry){
+ NVRDataModel.debug("local download complete: " + entry.toURL());
+ NVRDataModel.debug("Now trying to move it to album");
+ cordova.plugins.photoLibrary.saveImage(entry.toURL(), album,
+ function (cameraRollAssetId) {
+ SaveSuccess();
+ $cordovaFile.removeFile(cordova.file.dataDirectory, fname)
+ .then (
+ function () {
+ NVRDataModel.debug ("file removed from data directory");
+ },
+ function (e) {
+ NVRDataModel.debug ("could not delete temp file: "+JSON.stringify(e));
+ }
+ );
+
+
+ }, function (err) {
+ NVRDataModel.debug ("Saving error:" + JSON.stringify(err));
+ SaveError();
+
+ });
+
+ },
+ function(err) { NVRDataModel.debug ("error downloading:"+JSON.stringify(err));SaveError();}, !loginData.enableStrictSSL, {});
- var fname = $scope.monitorName + "-" +
- moment().format('MMM-DD-YY_HH-mm-ss') + ".png";
- canvas.toBlob(function (blob) {
- saveAs(blob, fname);
- SaveSuccess();
- });
- }
- };
- try {
- img.src = url;
- // console.log ("SAVING IMAGE SOURCE");
- } catch (e) {
- SaveError(e.message);
+
+
+ // User gave us permission to his library, retry reading it!
+ },
+ function (err) {
+ // User denied the access
+ NVRDataModel.debug ("Permission not granted");
+ SaveError();
+ }, // if options not provided, defaults to {read: true}.
+
+ {
+ read: true,
+ write: true
+ }
+ );
+ }
- }
+ else {
+
+ $ionicLoading.hide();
+
+ $rootScope.zmPopup = SecuredPopups.show('alert', {
+ title: $translate.instant('kNote'),
+ template: $translate.instant('kDownloadVideoImage')+"<br/><br/><center><a href='" + url + "' class='button button-assertive icon ion-android-download' download=\"balls.jpg\">"+" "+$translate.instant('kDownload')+"</a></center>",
+ okText: $translate.instant('kDismiss'),
+ okType:'button-stable'
+ });
+
+ }
+
}
@@ -1420,14 +1459,16 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
}
});
- req.success(function (resp) {
+ req.then(function (resp) {
+ resp = resp.data;
if (resp.result == "Ok" && ndx != -1) {
var ld = NVRDataModel.getLogin();
var apiurl = ld.apiurl + "/events/" + resp.status.event + ".json";
//console.log ("API " + apiurl);
$http.get(apiurl)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
if ($scope.MontageMonitors[ndx].eventUrlTime != data.event.Event.StartTime) {
var element = angular.element(document.getElementById($scope.MontageMonitors[ndx].Monitor.Id + "-timeline"));
@@ -1441,19 +1482,21 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
}
- })
- .error(function (data) {
+ },
+ function (data) {
$scope.MontageMonitors[ndx].eventUrlTime = "-";
});
}
- });
+ },
- req.error(function (resp) {
+ function (resp) {
//console.log("ERROR: " + JSON.stringify(resp));
NVRDataModel.log("Error sending event command " + JSON.stringify(resp), "error");
});
+
+
}
$scope.toggleListMenu = function () {
@@ -1518,7 +1561,8 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
var ld = NVRDataModel.getLogin();
var url = ld.apiurl + "/monitors/" + mid + ".json";
$http.get(url)
- .success(function (data) {
+ .then(function (data) {
+ data = data.data;
$scope.isControllable = data.monitor.Monitor.Controllable;
// *** Only for testing - comment out //
@@ -1533,8 +1577,8 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
NVRDataModel.debug("configurePTZ : getting controllable data " + myurl);
$http.get(myurl)
- .success(function (data) {
-
+ .then(function (data) {
+ data = data.data;
// *** Only for testing - comment out - start//
/*data.Control.Control.CanSleep = '1';
data.Control.Control.CanWake = '1';
@@ -1696,8 +1740,8 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
}
NVRDataModel.log("ConfigurePTZ Modal: ControlDB reports PTZ command to be " + $scope.ptzMoveCommand);
- })
- .error(function (data) {
+ },
+ function (data) {
// console.log("** Error retrieving move PTZ command");
NVRDataModel.log("ConfigurePTZ : Error retrieving PTZ command " + JSON.stringify(data), "error");
});
@@ -1705,8 +1749,8 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$
} else {
NVRDataModel.log("configurePTZ " + mid + " is not PTZ controllable");
}
- })
- .error(function (data) {
+ },
+ function (data) {
// console.log("** Error retrieving move PTZ command");
NVRDataModel.log("configurePTZ : Error retrieving PTZ command " + JSON.stringify(data), "error");
});
diff --git a/www/js/MontageCtrl.js b/www/js/MontageCtrl.js
index fefe2ddc..f4c77a80 100644
--- a/www/js/MontageCtrl.js
+++ b/www/js/MontageCtrl.js
@@ -334,7 +334,7 @@ angular.module('zmApp.controllers')
progressCalled = true;
loadCount++;
- console.log ("loaded "+loadCount+" of "+positions.length);
+ // console.log ("loaded "+loadCount+" of "+positions.length);
// if (layouttype) $timeout (function(){layout(pckry);},100);
});
@@ -1828,7 +1828,7 @@ angular.module('zmApp.controllers')
// NVRDataModel.regenConnKeys();
$scope.monitors = NVRDataModel.getMonitorsNow();
- console.log ("MONITORS:"+JSON.stringify($scope.monitors));
+ //console.log ("MONITORS:"+JSON.stringify($scope.monitors));
$scope.MontageMonitors = angular.copy($scope.monitors);
diff --git a/www/js/NewsCtrl.js b/www/js/NewsCtrl.js
index 6be6aa0e..55712753 100644
--- a/www/js/NewsCtrl.js
+++ b/www/js/NewsCtrl.js
@@ -88,15 +88,12 @@ angular.module('zmApp.controllers').controller('zmApp.NewsCtrl', ['$scope', '$ro
$http.get(zm.blogUrl, {
- transformResponse: function (d, h) {
- var trunc = "])}while(1);</x>";
- d = d.substr(trunc.length);
- return d;
- }
+ responseType:'text'
})
- .success(function (datastr) {
-
-
+ .then(function (datastr) {
+ datastr = datastr.data;
+ var trunc = "])}while(1);</x>";
+ datastr= datastr.substr(trunc.length);
// console.log ("DATA:"+data);
//
var data = JSON.parse(datastr);
diff --git a/www/js/TimelineCtrl.js b/www/js/TimelineCtrl.js
index 250fda9e..a5c7f818 100644
--- a/www/js/TimelineCtrl.js
+++ b/www/js/TimelineCtrl.js
@@ -1026,7 +1026,7 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
$ionicLoading.show({
template: $translate.instant('kLoadingGraph') + "...",
animation: 'fade-in',
- showBackdrop: true,
+ showBackdrop: false,
maxWidth: 200,
showDelay: 0,
duration: zm.loadingTimeout, //specifically for Android - http seems to get stuck at times
@@ -1103,9 +1103,9 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
//console.log ("**NOLANG" + fromDateNoLang + " " + toDateNoLang);
NVRDataModel.getEventsPages(0, fromDateNoLang, toDateNoLang)
- .then(function (data) {
- var pages = data.pageCount || 1;
- var itemsPerPage = parseInt(data.limit);
+ .then(function (epData) {
+ var pages = 1;
+ var itemsPerPage = parseInt(epData.limit);
var iterCount;
// So iterCount is the # of HTTP calls I need to make
@@ -1117,17 +1117,18 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
// for dynamic binding which was easier, but due to performance reasons
// I am waiting for the full data to load before I draw
var promises = [];
- while ((pages > 0) && (iterCount > 0)) {
+ while ((pages <= epData.pageCount) && (iterCount > 0)) {
var promise = NVRDataModel.getEvents(0, pages, "none", fromDateNoLang, toDateNoLang);
promises.push(promise);
- pages--;
+
+ pages++;
iterCount--;
}
$q.all(promises)
.then(function (data) {
- NVRDataModel.debug("TimelineCtrl/drawgraph: all pages of graph data received");
+ NVRDataModel.debug("TimelineCtrl/drawgraph: all pages of graph data received " );
graphIndex = 0;
NVRDataModel.log("Creating " + $scope.monitors.length + " groups for the graph");
// create groups
@@ -1143,8 +1144,10 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
}
for (var j = 0; j < data.length; j++) {
- var myevents = data[j];
+ var myevents = data[j].events;
+ // console.log ("****************DATA ="+JSON.stringify(data[j]));
+ // console.log ("**********************************");
if (graphIndex > count) {
NVRDataModel.log("Exiting page count graph - reached limit of " + count);
break;
@@ -1203,10 +1206,12 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
}
//console.log ("ADDED "+tzs+" " +tze);
+
+ if (!graphData.get(myevents[i].Event.Id)) {
graphData.add({
//id: graphIndex,
id: myevents[i].Event.Id,
- content: "<span class='my-vis-font'>" + "( <i class='ion-android-notifications'></i>" + myevents[i].Event.AlarmFrames + ") " + "(" + myevents[j].Event.Id + ") " + myevents[i].Event.Notes + "</span>",
+ content: "<span class='my-vis-font'>" + "( <i class='ion-android-notifications'></i>" + myevents[i].Event.AlarmFrames + ") " + "(" + myevents[i].Event.Id + ") " + myevents[i].Event.Notes + "</span>",
start: tzs,
//start: myevents[i].Event.StartTime,
@@ -1224,7 +1229,9 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
myevent: myevents[i]
});
+ //console.log ("IED="+myevents[i].Event.Id);
graphIndex++;
+ }
} else {
//console.log ("SKIPPED GRAPH ID " + graphIndex);
}
@@ -1375,7 +1382,7 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
var _item;
for (var x = 0; x < visible.length; x++) {
_item = timeline.itemSet.items[x];
- if (_item.data.group == prop.group) {
+ if (_item && _item.data && _item.data.group == prop.group) {
if (Math.abs(_item.left - prop.x) < minDist) {
closestItem = _item;
minDist = Math.abs(_item.left - prop.x);
@@ -1398,7 +1405,7 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
/*$ionicLoading.show({
template: "",
animation: 'fade-in',
- showBackdrop: true,
+ showBackdrop: false,
maxWidth: 200,
showDelay: 0,
duration: 1500,
diff --git a/www/js/WizardCtrl.js b/www/js/WizardCtrl.js
index 6ce8ea1b..a152f537 100644
--- a/www/js/WizardCtrl.js
+++ b/www/js/WizardCtrl.js
@@ -13,12 +13,8 @@ angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$
function login(u, zmu, zmp) {
var d = $q.defer();
-
-
-
-
$http({
- method: 'POST',
+ method: 'post',
//withCredentials: true,
url: u,
headers: {
@@ -31,6 +27,7 @@ angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$
str.push(encodeURIComponent(p) + "=" +
encodeURIComponent(obj[p]));
var params = str.join("&");
+ //console.log ("PARAMS in login:"+params);
return params;
},
@@ -41,7 +38,8 @@ angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$
view: "console"
}
})
- .success(function (data, status, headers) {
+ .then(function (data, status, headers) {
+ data = data.data;
//console.log("LOOKING FOR " + zm.loginScreenString);
//console.log("DATA RECEIVED " + JSON.stringify(data));
if (data.indexOf(zm.loginScreenString) == -1) {
@@ -58,9 +56,9 @@ angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$
d.reject(false);
return d.promise;
}
- })
- .error(function (error) {
- //console.log("************ERROR");
+ },
+ function (error) {
+ // console.log("************ERROR:"+ JSON.stringify(error));
$scope.wizard.portalValidText = $translate.instant('kPortalDetectionFailed');
$scope.wizard.portalColor = "#e74c3c";
d.reject(false);
@@ -197,10 +195,13 @@ angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$
var urls = [a1, a2, a3, a4, a5];
- NVRDataModel.getPathZms() // what does ZM have stored in PATH_ZMS?
+ // can't use getPathZms as loginData is not inited yet
+ $http.get ($scope.wizard.apiURL+"/configs/viewByName/ZM_PATH_ZMS.json")
+ //NVRDataModel.getPathZms() // what does ZM have stored in PATH_ZMS?
.then(function (data) {
// remove zms or nph-zms
- var path = data.trim();
+ var str = data.data.config.Value;
+ var path = str.trim();
path = path.replace("/nph-zms", "");
path = path.replace("/zms", "");
urls.push(baseUri.trim() + path);
diff --git a/www/js/app.js b/www/js/app.js
index 6287e09b..5935ee0d 100755
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -25,7 +25,7 @@ angular.module('zmApp', [
'com.2fdevs.videogular',
'com.2fdevs.videogular.plugins.controls',
'com.2fdevs.videogular.plugins.overlayplay',
- 'ionic-native-transitions',
+ //'ionic-native-transitions',
'mgo-angular-wizard',
'pascalprecht.translate',
'uk.ac.soton.ecs.videogular.plugins.cuepoints',
@@ -44,7 +44,7 @@ angular.module('zmApp', [
.constant('zm', {
minAppVersion: '1.28.107', // if ZM is less than this, the app won't work
recommendedAppVersion: '1.32.0',
- minEventServerVersion: '1.0',
+ minEventServerVersion: '2.0',
castAppId: 'BA30FB4C',
alarmFlashTimer: 20000, // time to flash alarm
gcmSenderId: '710936220256',
@@ -264,7 +264,6 @@ angular.module('zmApp', [
})
-
// credit https://gist.github.com/Zren/beaafd64f395e23f4604
.directive('mouseWheelScroll', function ($timeout) {
@@ -322,7 +321,7 @@ angular.module('zmApp', [
//console.log ("requestConfig is " + JSON.stringify(requestConfig));
imageLoadingDataShare.set(1);
$http(requestConfig)
- .success(function (data) {
+ .then(function (data) {
//console.log ("Inside HTTP after Calling " + requestConfig.url);
//console.log ("data got " + JSON.stringify(data));
@@ -763,6 +762,9 @@ angular.module('zmApp', [
NVRDataModel.setLastUpdateCheck(moment().toISOString());
// $localstorage.set("lastUpdateCheck", moment().toISOString());
//console.log ("FULL STRING " + success.data.tag_name);
+
+ // console.log ("^^^^^^^^^^^^^ GOT: " + JSON.stringify(success));
+
var res = success.data.tag_name.match("v(.*)");
zmUpdateVersion = res[1];
var currentVersion = NVRDataModel.getAppVersion();
@@ -783,16 +785,16 @@ angular.module('zmApp', [
NVRDataModel.log("Checking for news updates");
$http.get(zm.blogUrl, {
- transformResponse: function (d, h) {
- var trunc = "])}while(1);</x>";
- if (d) {
- d = d.substr(trunc.length);
- }
- return d;
- }
+ responseType:'text',
+ transformResponse:undefined
})
- .success(function (datastr) {
+ .then(function (datastr) {
+ // again, for cordova-http
+
+ datastr = datastr.data;
+ var trunc = "])}while(1);</x>";
+ datastr = datastr.substr(trunc.length);
var data = JSON.parse(datastr);
$rootScope.newBlogPost = "";
@@ -906,6 +908,30 @@ angular.module('zmApp', [
contentBannerInstance();
}, 2000);
NVRDataModel.debug("auth-success broadcast:Successful");
+
+
+ var ld = NVRDataModel.getLogin();
+
+ // we need AUTH_HASH_LOGIN to be on for WKWebView /mobile
+ if (ld.isUseAuth && $rootScope.platformOS != 'desktop') {
+ NVRDataModel.getAuthHashLogin()
+ .then (function (data) {
+
+ if (data.data && data.data.config.Value != '1') {
+ $ionicPopup.alert({
+ title: $translate.instant('kError'),
+ template: $translate.instant('kAuthHashDisabled')
+ });
+ }
+
+ },
+ function (err) {
+ console.log ("AUTH HASH ERROR: "+JSON.stringify(conf));
+ });
+ }
+
+
+
});
$rootScope.getProfileName = function () {
@@ -1059,10 +1085,11 @@ angular.module('zmApp', [
$http({
- method:'POST',
+ method:'post',
url: loginAPI,
timeout:httpDelay,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
+ responseType:'text',
transformResponse: undefined,
transformRequest: function(obj) {
var str = [];
@@ -1242,7 +1269,7 @@ angular.module('zmApp', [
//NVRDataModel.debug ("*** AUTH LOGIN URL IS " + loginData.url);
$http({
- method: 'POST',
+ method: 'post',
timeout: httpDelay,
//withCredentials: true,
url: loginData.url + '/index.php',
@@ -1266,8 +1293,9 @@ angular.module('zmApp', [
view: "console"
}
})
- .success(function (data, status, headers) {
+ .then(function (data, status, headers) {
// console.log(">>>>>>>>>>>>>> PARALLEL POST SUCCESS");
+ data = data.data;
$ionicLoading.hide();
// Coming here does not mean success
@@ -1324,8 +1352,8 @@ angular.module('zmApp', [
return (d.promise);
- })
- .error(function (error, status) {
+ },
+ function (error, status) {
// console.log(">>>>>>>>>>>>>> PARALLEL POST ERROR");
$ionicLoading.hide();
@@ -1380,7 +1408,7 @@ angular.module('zmApp', [
// First run in ionic
//====================================================================
- .run(function ($ionicPlatform, $ionicPopup, $rootScope, zm, $state, $stateParams, NVRDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, zmCheckUpdates, $fileLogger, $timeout, $ionicHistory, $window, $ionicSideMenuDelegate, EventServer, $ionicContentBanner, $ionicLoading, $ionicNativeTransitions, $translate, $localstorage) {
+ .run(function ($ionicPlatform, $ionicPopup, $rootScope, zm, $state, $stateParams, NVRDataModel, $cordovaSplashscreen, $http, $interval, zmAutoLogin, zmCheckUpdates, $fileLogger, $timeout, $ionicHistory, $window, $ionicSideMenuDelegate, EventServer, $ionicContentBanner, $ionicLoading, /* $ionicNativeTransitions,*/ $translate, $localstorage) {
$ionicPlatform.ready(function () {
@@ -1967,9 +1995,9 @@ angular.module('zmApp', [
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
- if (window.cordova && window.cordova.plugins.Keyboard) {
- // console.log("no keyboard");
- // cordova.plugins.Keyboard.disableScroll(true);
+ if (window.cordova ) {
+ console.log("------------->Keyboard foonone");
+ //window.cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
@@ -2000,13 +2028,14 @@ angular.module('zmApp', [
// console.log("file logger");
- if (NVRDataModel.getLogin().disableNative) {
+ /*if (NVRDataModel.getLogin().disableNative) {
NVRDataModel.log("Disabling native transitions...");
$ionicNativeTransitions.enable(false);
} else {
NVRDataModel.log("Enabling native transitions...");
$ionicNativeTransitions.enable(true);
- }
+ }*/
+
// At this stage, DataModel.init is not called yet
// but I do need to know the language
@@ -2230,7 +2259,7 @@ angular.module('zmApp', [
//------------------------------------------------------------------
// My route map connecting menu options to their respective templates and controllers
- .config(function ($stateProvider, $urlRouterProvider, $httpProvider, $ionicConfigProvider, $provide, $compileProvider, $ionicNativeTransitionsProvider, $logProvider, $translateProvider) {
+ .config(function ($stateProvider, $urlRouterProvider, $httpProvider, $ionicConfigProvider, $provide, $compileProvider, /*$ionicNativeTransitionsProvider,*/ $logProvider, $translateProvider) {
//$logProvider.debugEnabled(false);
//$compileProvider.debugInfoEnabled(false);
@@ -2254,8 +2283,111 @@ angular.module('zmApp', [
};
}]);
+
+ // Wraps around $http that switches between browser XHR
+ // or cordova-advanced-http based on if cordova is available
+ // credits:
+ // a) https://www.exratione.com/2013/08/angularjs-wrapping-http-for-fun-and-profit/
+ // b) https://gist.github.com/adamreisnz/354364e2a58786e2be71
+
+ $provide.decorator('$http', ['$delegate', '$q', function($delegate, $q) {
+ // create function which overrides $http function
+ var $http = $delegate;
+
+ var wrapper = function () {
+ var url;
+ var method;
+
+ url = arguments[0].url;
+ method = arguments[0].method;
+ var isOutgoingRequest = /^(http|https):\/\//.test(url);
+ if (window.cordova && isOutgoingRequest) {
+
+
+ var d = $q.defer();
+ var options = {
+ method: method,
+ data: arguments[0].data,
+ headers: arguments[0].headers,
+ timeout: arguments[0].timeout,
+ responseType: arguments[0].responseType
+ };
+ // console.log ("**** -->"+method+"<-- using native HTTP with:"+encodeURI(url)+" payload:"+JSON.stringify(options));
+ cordova.plugin.http.sendRequest(encodeURI(url),options,
+ function (succ) {
+ // automatic JSON parse if no responseType: text
+ // fall back to text if JSON parse fails too
+ if (options.responseType =='text') {
+ // don't parse into JSON
+ d.resolve({"data":succ.data});
+ return d.promise;
+ }
+ else {
+ try {
+ d.resolve({"data":JSON.parse(succ.data)});
+ return d.promise;
+ }
+ catch (e) {
+
+ //console.log ("*** Native HTTP response: JSON parsing failed for "+url+", returning text");
+ d.resolve({"data":succ.data});
+ return d.promise;
+ }
+
+ }
+ },
+ function (err) {
+ console.log ("*** Inside native HTTP error: "+JSON.stringify(err));
+
+ d.reject(err);
+ return d.promise;
+ });
+ return d.promise;
+
+ }
+ else { // not cordova, so lets go back to default http
+ // console.log ("**** "+method+" using XHR HTTP for "+url);
+ return $http.apply($http, arguments);
+ }
+
+ };
+
+ // wrap around all HTTP methods
+ Object.keys($http).filter(function (key) {
+ return (typeof $http[key] === 'function');
+ }).forEach(function (key) {
+ wrapper[key] = function () {
+ return $http[key].apply($http, arguments);
+ };
+ });
+ // wrap convenience functions
+ $delegate.get = function (url,config) {
+ return wrapper(angular.extend(config || {}, {
+ method: 'get',
+ url: url
+ }));
+ };
+
+ $delegate.post = function (url,data,config) {
+ return wrapper(angular.extend(config || {}, {
+ method: 'post',
+ url: url,
+ data:data
+ }));
+ };
+
+ $delegate.delete = function (url,config) {
+ return wrapper(angular.extend(config || {}, {
+ method: 'delete',
+ url: url
+ }));
+ };
+
+ return wrapper;
+ }]);
+
// If you do this, Allow Origin can't be *
- //$httpProvider.defaults.withCredentials = true;
+ $httpProvider.defaults.withCredentials = true;
$httpProvider.interceptors.push('timeoutHttpIntercept');
$ionicConfigProvider.navBar.alignTitle('center');
//$ionicConfigProvider.backButton.text('').icon('ion-chevron-left');
@@ -2265,10 +2397,11 @@ angular.module('zmApp', [
// so it messes up scrolldelegate zoom and possibly others
//$ionicConfigProvider.scrolling.jsScrolling(false);
$compileProvider.debugInfoEnabled(false);
+ $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|cdvphotolibrary):/);
- $ionicNativeTransitionsProvider.setDefaultOptions({
+ /*$ionicNativeTransitionsProvider.setDefaultOptions({
duration: 250,
- });
+ }); */
$translateProvider.useStaticFilesLoader({
prefix: 'lang/locale-',
diff --git a/www/lang/locale-en.json b/www/lang/locale-en.json
index fcdd8ecc..2950c0dd 100644
--- a/www/lang/locale-en.json
+++ b/www/lang/locale-en.json
@@ -15,6 +15,7 @@
"kApplyingChanges" :"Applying changes. Please wait",
"kArrangingImages" :"arranging images",
"kAt" :"at",
+ "kAuthHashDisabled" :" AUTH_HASH_LOGINS needs to be enabled to display images. Please restart ZM afer enabling it.",
"kAuthSuccess" :"authentication success",
"kAuthenticating" :"authenticating",
"kAuthenticatingWebScrape" : "authenticating via web scrape",
@@ -75,7 +76,10 @@
"kDiscoveringAPI" :"discovering api",
"kDiscoveringCGI" :"discovering cgi",
"kDiscoveringPortal" :"discovering portal",
+ "kDismiss" : "Dismiss",
"kDone" :"done",
+ "kDownload" :"Download",
+ "kDownloadVideoImage" : "Tap the button below to download. If you are downloading a video, there is no progress indication, so please monitor file size",
"kEmailNotConfigured" :"Email not configured",
"kEnable24hr" :"enable 24hr time format",
"kEnableDebug" :"Enable debug logs",
diff --git a/www/templates/events-modal.html b/www/templates/events-modal.html
index 598bde23..1f168b69 100644
--- a/www/templates/events-modal.html
+++ b/www/templates/events-modal.html
@@ -155,11 +155,21 @@
<a href="" ng-click="toggleGapless()">
<i class="ion-ios-loop-strong"></i>-{{loginData.gapless? ('kOn' | translate): ('kOff' | translate)}}</a>
</li>
- <li ng-if="defaultVideo=='' && isToggleListMenu && (!isSnapShot() || liveFeedMid) ">
- <a href="" ng-click="saveEventImageToPhoneWithPerms(false)">
- <i class="ion-ios-camera"></i>
+ <li ng-if="isToggleListMenu">
+ <a href="" ng-click="saveEventImageToPhoneWithPerms(false, 'any')">
+ <i class="ion-camera"></i>
</a>
</li>
+
+
+
+ <li ng-if="isToggleListMenu && defaultVideo !='' && defaultVideo != undefined">
+ <a href="" ng-click="saveEventVideoToPhoneWithPerms()">
+ <i class="ion-android-download"></i>
+ </a>
+ </li>
+
+
<li ng-if="defaultVideo=='' && isToggleListMenu">
<a href="" ng-click="saveEventImageToPhoneWithPerms(true)">
<i class="ion-android-notifications"></i>
diff --git a/www/templates/events.html b/www/templates/events.html
index c517966f..79c0ef8f 100644
--- a/www/templates/events.html
+++ b/www/templates/events.html
@@ -78,12 +78,17 @@
{{humanize(event.Event.Length)}}
</span>
<br/>
+
+ <!-- No longer needed - direct video download supported now
+
<button ng-if="gifshotSupported && loginData.enableGIFMP4 " class="button button-small button-clear icon gif-icon" ng-click="permissionsDownload(event)">
</button>
<a ng-if="(event.Event.DefaultVideo!='' && event.Event.DefaultVideo!==undefined) && $root.platformOS=='desktop' && loginData.enableGIFMP4 "
class="button button-clear button-small icon mp4-icon" href="{{event.Event.videoPath}}" download="{{event.Event.Id}}-video.mp4"
ng-click="mp4warning()"></a>
+ -->
+
<button ng-if="event.Event.DefaultVideo!='' && event.Event.DefaultVideo!=undefined && $root.platformOS!='desktop' && loginData.enableGIFMP4 "
class="button button-small button-clear icon mp4-icon" ng-click="downloadFileToDevice(event.Event.videoPath, event.Event.Id)">
@@ -95,8 +100,14 @@
<div align="right" class="col col-40" ng-if="loginData.enableThumbs" >
- <img ng-image-appear no-loader transition-duration="0.3s" animation="fillIn" bg-color="#6C7A89" ng-src="{{constructThumbnail(event)}}"
- on-tap="closeIfOpen(event);openModalWithSnapshot(event)" width="{{event.Event.thumbWidth}}px" height="{{event.Event.thumbHeight}}px" />
+
+ <img bg-color="#6C7A89" src="{{constructThumbnail(event)}}"
+ on-tap="closeIfOpen(event);openModalWithSnapshot(event)" width="{{event.Event.thumbWidth}}px" height="{{event.Event.thumbHeight}}px" />
+ <!--
+ <img ng-image-appear no-loader transition-duration="0.3s" animation="fillIn" bg-color="#6C7A89" ng-src="{{constructThumbnail(event)}}"
+ on-tap="closeIfOpen(event);openModalWithSnapshot(event)" width="{{event.Event.thumbWidth}}px" height="{{event.Event.thumbHeight}}px" />
+ -->
+
<!--<p>{{event.Event.thumbWidth}}px*{{event.Event.thumbHeight}}px</p>-->
diff --git a/www/templates/monitors-modal.html b/www/templates/monitors-modal.html
index 980e2384..0b6ec69c 100644
--- a/www/templates/monitors-modal.html
+++ b/www/templates/monitors-modal.html
@@ -148,12 +148,12 @@
</a>
</li>
<li ng-if="isToggleListMenu">
- <a href="" ng-click="enableAlarm(monitorId,true)">
+ <a href="" ng-click="triggerAlarm(monitorId,'on')">
<i class="icon ion-flash"></i>
</a>
</li>
<li ng-if="isToggleListMenu">
- <a href="" ng-click="enableAlarm(monitorId,false)">
+ <a href="" ng-click="triggerAlarm(monitorId,'off')">
<i class="icon ion-flash-off"></i>
</a>
</li>