summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamir Merdan <44159556+dado-ca@users.noreply.github.com>2018-11-14 11:17:18 +0100
committerGitHub <noreply@github.com>2018-11-14 11:17:18 +0100
commitbb78ec417458347887a0668223dc7fd7bad377ea (patch)
tree494a609118c85467702061a743e9fd0b7dba1860
parentb2cccc52c08f8195a1ddbb747c949915134940b4 (diff)
parentdbee219a9674daadd05aa1a27b36e76d91a35b5f (diff)
Merge branch 'master' into master
-rw-r--r--.github/stale.yml11
-rw-r--r--CHANGELOG.md740
-rw-r--r--GoogleService-Info.plist4
-rw-r--r--bower.json4
-rwxr-xr-xbuild_android.sh22
-rwxr-xr-xbuild_ios.sh3
-rw-r--r--config.xml8
-rw-r--r--package.json13
-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.css2
-rw-r--r--www/index.html2
-rw-r--r--www/js/DataModel.js190
-rw-r--r--www/js/DevOptionsCtrl.js14
-rw-r--r--www/js/EventCtrl.js283
-rw-r--r--www/js/EventModalCtrl.js88
-rw-r--r--www/js/EventServer.js38
-rw-r--r--www/js/EventsModalGraphCtrl.js2
-rw-r--r--www/js/LogCtrl.js193
-rw-r--r--www/js/LoginCtrl.js20
-rw-r--r--www/js/MomentCtrl.js21
-rw-r--r--www/js/MonitorCtrl.js136
-rw-r--r--www/js/MontageCtrl.js29
-rw-r--r--www/js/MontageHistoryCtrl.js15
-rw-r--r--www/js/NewsCtrl.js18
-rw-r--r--www/js/PortalLoginCtrl.js175
-rw-r--r--www/js/StateCtrl.js136
-rw-r--r--www/js/TimelineCtrl.js34
-rw-r--r--www/js/TimelineModalCtrl.js76
-rw-r--r--www/js/WizardCtrl.js22
-rwxr-xr-xwww/js/app.js194
-rw-r--r--www/lang/locale-ar.json1
-rw-r--r--www/lang/locale-ba.json1
-rw-r--r--www/lang/locale-de.json27
-rw-r--r--www/lang/locale-en.json34
-rw-r--r--www/lang/locale-es.json2
-rw-r--r--www/lang/locale-fr.json2
-rw-r--r--www/lang/locale-hu.json2
-rw-r--r--www/lang/locale-it.json1
-rwxr-xr-xwww/lang/locale-nl.json2
-rw-r--r--www/lang/locale-pl.json24
-rw-r--r--www/lang/locale-pt.json2
-rw-r--r--www/lang/locale-ru.json2
-rw-r--r--www/templates/events-modal.html5
-rw-r--r--www/templates/events-popover.html5
-rw-r--r--www/templates/events.html4
-rw-r--r--www/templates/log.html16
-rw-r--r--www/templates/moment.html2
-rw-r--r--www/templates/monitors-modal.html1
-rw-r--r--www/templates/monitors.html9
-rw-r--r--www/templates/state.html105
-rw-r--r--www/templates/timeline-modal.html2
82 files changed, 1446 insertions, 1296 deletions
diff --git a/.github/stale.yml b/.github/stale.yml
index 7d6713d6..7444ec02 100644
--- a/.github/stale.yml
+++ b/.github/stale.yml
@@ -4,13 +4,10 @@ daysUntilStale: 45
daysUntilClose: 4
# Issues with these labels will never be considered stale
exemptLabels:
- - pinned
- - security
- - enhancement
- - bug
- - long term
- - informational
- - help wanted
+ - keep alive
+ - :tipping_hand_man: informational
+ - :sparkles: enhancement
+ - :beetle: bug
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f46e0ef5..c7e6a1bf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,27 +1,67 @@
# Change Log
-## [v1.3.018](https://github.com/pliablepixels/zmNinja/tree/v1.3.018) (2018-09-14)
-[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.3.016...v1.3.018)
+## [v1.3.029](https://github.com/pliablepixels/zmNinja/tree/v1.3.029) (2018-11-07)
+[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.3.018...v1.3.029)
-**Implemented enhancements:**
+**Closed issues:**
-- Allow easier switching between profiles [\#704](https://github.com/pliablepixels/zmNinja/issues/704)
+- Windows client issues [\#739](https://github.com/pliablepixels/zmNinja/issues/739)
+- Add support to display storage information [\#733](https://github.com/pliablepixels/zmNinja/issues/733)
+- IOS Notifications not clearing [\#727](https://github.com/pliablepixels/zmNinja/issues/727)
+- \(Android only\) Notifications don't arrive when a cellphone is locked [\#726](https://github.com/pliablepixels/zmNinja/issues/726)
+- push onTap doesn't always work [\#725](https://github.com/pliablepixels/zmNinja/issues/725)
+- multi server multi storage event playback doesn't work [\#724](https://github.com/pliablepixels/zmNinja/issues/724)
+- migrate zmN to WKWebView [\#723](https://github.com/pliablepixels/zmNinja/issues/723)
+- How to view continuous events? [\#715](https://github.com/pliablepixels/zmNinja/issues/715)
+- Is the android version still available from Google Play? [\#713](https://github.com/pliablepixels/zmNinja/issues/713)
+- Recording playback fails after upgrade to ZM 1.32.0 [\#711](https://github.com/pliablepixels/zmNinja/issues/711)
+- Allow full video downloads [\#710](https://github.com/pliablepixels/zmNinja/issues/710)
+- Is it possible to run zm ninja with dual screen? Two instances? [\#706](https://github.com/pliablepixels/zmNinja/issues/706)
+- Google Play store states app not compatible with Nvidia Shield Android TV [\#705](https://github.com/pliablepixels/zmNinja/issues/705)
-**Fixed bugs:**
+**Merged pull requests:**
-- If multi-server recording server name doesn't have a protocol, zmN doesn't show feeds [\#702](https://github.com/pliablepixels/zmNinja/issues/702)
-- Authentification with new iOs app version [\#690](https://github.com/pliablepixels/zmNinja/issues/690)
-- Authentication broken with API Access Error [\#689](https://github.com/pliablepixels/zmNinja/issues/689)
+- Fixes double definition in www/js/app.js [\#740](https://github.com/pliablepixels/zmNinja/pull/740) ([ArsenyZorin](https://github.com/ArsenyZorin))
+- kStateMultiServer missing [\#738](https://github.com/pliablepixels/zmNinja/pull/738) ([maymaymay](https://github.com/maymaymay))
+- desktop logs rework [\#736](https://github.com/pliablepixels/zmNinja/pull/736) ([maymaymay](https://github.com/maymaymay))
+- \#733 initial rough in [\#735](https://github.com/pliablepixels/zmNinja/pull/735) ([maymaymay](https://github.com/maymaymay))
+- \#733 initial rough in [\#734](https://github.com/pliablepixels/zmNinja/pull/734) ([florie1706](https://github.com/florie1706))
+- desktop logs rework [\#732](https://github.com/pliablepixels/zmNinja/pull/732) ([florie1706](https://github.com/florie1706))
+- typo [\#731](https://github.com/pliablepixels/zmNinja/pull/731) ([maymaymay](https://github.com/maymaymay))
+- modified sensitive info warning, removed old text from language files… [\#730](https://github.com/pliablepixels/zmNinja/pull/730) ([florie1706](https://github.com/florie1706))
+- new keys for monitor status [\#728](https://github.com/pliablepixels/zmNinja/pull/728) ([maymaymay](https://github.com/maymaymay))
+- menu option to toggle event summary \(iPhoneX ui interference\) [\#722](https://github.com/pliablepixels/zmNinja/pull/722) ([florie1706](https://github.com/florie1706))
+- menu option to toggle event summary \(iPhoneX ui interference\) [\#721](https://github.com/pliablepixels/zmNinja/pull/721) ([maymaymay](https://github.com/maymaymay))
+- added missing keys [\#720](https://github.com/pliablepixels/zmNinja/pull/720) ([dado-ca](https://github.com/dado-ca))
+- Bosnian Line 404 corrected [\#719](https://github.com/pliablepixels/zmNinja/pull/719) ([dado-ca](https://github.com/dado-ca))
+- master keys:420, locale-pl.json keys:420 [\#718](https://github.com/pliablepixels/zmNinja/pull/718) ([maymaymay](https://github.com/maymaymay))
+- Bosnian translation [\#717](https://github.com/pliablepixels/zmNinja/pull/717) ([dado-ca](https://github.com/dado-ca))
+- various fixes for XCode 10 build process and iCloud [\#714](https://github.com/pliablepixels/zmNinja/pull/714) ([florie1706](https://github.com/florie1706))
+- use corrent icon path [\#712](https://github.com/pliablepixels/zmNinja/pull/712) ([CorySanin](https://github.com/CorySanin))
+- WKWebView fixes [\#709](https://github.com/pliablepixels/zmNinja/pull/709) ([pliablepixels](https://github.com/pliablepixels))
+- various fixes for XCode 10 build process and iCloud [\#708](https://github.com/pliablepixels/zmNinja/pull/708) ([maymaymay](https://github.com/maymaymay))
+- spanish trans update [\#707](https://github.com/pliablepixels/zmNinja/pull/707) ([fxrnando](https://github.com/fxrnando))
+
+## [v1.3.018](https://github.com/pliablepixels/zmNinja/tree/v1.3.018) (2018-09-14)
+[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.3.016...v1.3.018)
**Closed issues:**
+- Allow easier switching between profiles [\#704](https://github.com/pliablepixels/zmNinja/issues/704)
+- If multi-server recording server name doesn't have a protocol, zmN doesn't show feeds [\#702](https://github.com/pliablepixels/zmNinja/issues/702)
- Allow better desktop packaging schemes [\#701](https://github.com/pliablepixels/zmNinja/issues/701)
- Thumbnails not appearing in Events list [\#700](https://github.com/pliablepixels/zmNinja/issues/700)
- switch between different Zoneminder servers [\#699](https://github.com/pliablepixels/zmNinja/issues/699)
- Enable cloud sync [\#697](https://github.com/pliablepixels/zmNinja/issues/697)
+- iOS issues with Auth and zmNinja 1.3.017, with ZM 1.30.4 \(exploratory\) [\#696](https://github.com/pliablepixels/zmNinja/issues/696)
- Live Streaming Does Not Work for iOS 11.4.1 [\#694](https://github.com/pliablepixels/zmNinja/issues/694)
- Check for privacy disclaimer accept/reject status in ZM 1.31.47 and beyond [\#692](https://github.com/pliablepixels/zmNinja/issues/692)
+- Frozen, message displayed "cleaning up" and app freezes. [\#691](https://github.com/pliablepixels/zmNinja/issues/691)
+- Authentification with new iOs app version [\#690](https://github.com/pliablepixels/zmNinja/issues/690)
+- Authentication broken with API Access Error [\#689](https://github.com/pliablepixels/zmNinja/issues/689)
+- Row spacing on event list when using "portrait" monitors [\#688](https://github.com/pliablepixels/zmNinja/issues/688)
- Desktop - Clicking the event notify icon when an event is being viewed results in a "No events to display message" [\#674](https://github.com/pliablepixels/zmNinja/issues/674)
+- Allow navigation to detailed event playback from event montage [\#347](https://github.com/pliablepixels/zmNinja/issues/347)
- Desktop: Window Title is Inconsistent [\#170](https://github.com/pliablepixels/zmNinja/issues/170)
**Merged pull requests:**
@@ -34,20 +74,16 @@
## [v1.3.016](https://github.com/pliablepixels/zmNinja/tree/v1.3.016) (2018-08-24)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.3.013...v1.3.016)
-**Implemented enhancements:**
+**Closed issues:**
- Support multi-window view on Android [\#682](https://github.com/pliablepixels/zmNinja/issues/682)
-- Add zmNinja keybindings for desktop [\#675](https://github.com/pliablepixels/zmNinja/issues/675)
-
-**Fixed bugs:**
-
- Not auto switching to fallback server [\#681](https://github.com/pliablepixels/zmNinja/issues/681)
- Settings keep disappearing [\#680](https://github.com/pliablepixels/zmNinja/issues/680)
- Authentication issues between zm 1.30.4 and zmNinja 1.3.013 [\#679](https://github.com/pliablepixels/zmNinja/issues/679)
+- IOS: buttons not visible in event list when camera rotated 90 degrees [\#678](https://github.com/pliablepixels/zmNinja/issues/678)
+- Add zmNinja keybindings for desktop [\#675](https://github.com/pliablepixels/zmNinja/issues/675)
- Desktop - Event list thumbnails knock buttons out of view [\#673](https://github.com/pliablepixels/zmNinja/issues/673)
-
-**Closed issues:**
-
+- Desktop app, no notifications. Works with ios app. [\#650](https://github.com/pliablepixels/zmNinja/issues/650)
- Push Notification issue [\#639](https://github.com/pliablepixels/zmNinja/issues/639)
**Merged pull requests:**
@@ -61,31 +97,27 @@
## [v1.3.013](https://github.com/pliablepixels/zmNinja/tree/v1.3.013) (2018-07-31)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.3.011...v1.3.013)
-**Fixed bugs:**
+**Closed issues:**
- Android App sucked all my high speed data plan [\#647](https://github.com/pliablepixels/zmNinja/issues/647)
## [v1.3.011](https://github.com/pliablepixels/zmNinja/tree/v1.3.011) (2018-07-25)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.3.008...v1.3.011)
-**Implemented enhancements:**
-
-- Allow montage resize to work with finer grained control [\#669](https://github.com/pliablepixels/zmNinja/issues/669)
-- support new API login mechanism [\#668](https://github.com/pliablepixels/zmNinja/issues/668)
-- Enhancement: For desktop instances, would be cool to control cams motion \(PTZ\) using keyboard arrow keys [\#648](https://github.com/pliablepixels/zmNinja/issues/648)
-
-**Fixed bugs:**
-
-- Fix FreeNAS 1.30.4 API issues + other stuff related to 1.32.0 login process vs 1.30.4 [\#676](https://github.com/pliablepixels/zmNinja/issues/676)
-
**Closed issues:**
+- Fix FreeNAS 1.30.4 API issues + other stuff related to 1.32.0 login process vs 1.30.4 [\#676](https://github.com/pliablepixels/zmNinja/issues/676)
- Updating EventsController.php [\#672](https://github.com/pliablepixels/zmNinja/issues/672)
+- Allow montage resize to work with finer grained control [\#669](https://github.com/pliablepixels/zmNinja/issues/669)
+- support new API login mechanism [\#668](https://github.com/pliablepixels/zmNinja/issues/668)
+- Window Title incorrect on PC [\#667](https://github.com/pliablepixels/zmNinja/issues/667)
- Montage frame rate [\#666](https://github.com/pliablepixels/zmNinja/issues/666)
- Zmeventnotification.pl Working but no push notifications [\#664](https://github.com/pliablepixels/zmNinja/issues/664)
- Montage cannot load images and monitor streams will not load, but API calls succeed [\#658](https://github.com/pliablepixels/zmNinja/issues/658)
+- Enhancement: For desktop instances, would be cool to control cams motion \(PTZ\) using keyboard arrow keys [\#648](https://github.com/pliablepixels/zmNinja/issues/648)
- ZmNinjaDesktop on Linux64 \( ubuntu 16.04 \) touchscreen scrolling [\#642](https://github.com/pliablepixels/zmNinja/issues/642)
- Enhancement: Change between running states from main menu big buttons or widget [\#633](https://github.com/pliablepixels/zmNinja/issues/633)
+- Apple TV Support [\#632](https://github.com/pliablepixels/zmNinja/issues/632)
**Merged pull requests:**
@@ -97,12 +129,6 @@
## [v1.3.008](https://github.com/pliablepixels/zmNinja/tree/v1.3.008) (2018-06-30)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.3.004...v1.3.008)
-**Fixed bugs:**
-
-- Event list incorrect after deleting first event in the list [\#651](https://github.com/pliablepixels/zmNinja/issues/651)
-- Time not properly displayed in the event modal when selecting 'next event' [\#649](https://github.com/pliablepixels/zmNinja/issues/649)
-- zmNinja - montage view - monitors don't show on first run, but show after login saved [\#641](https://github.com/pliablepixels/zmNinja/issues/641)
-
**Closed issues:**
- Don't delete logs on coldstart. Android now that that every time [\#661](https://github.com/pliablepixels/zmNinja/issues/661)
@@ -110,6 +136,11 @@
- Cameras Slow [\#656](https://github.com/pliablepixels/zmNinja/issues/656)
- Add privacy/transparency link [\#653](https://github.com/pliablepixels/zmNinja/issues/653)
- Add hook before sending notification [\#652](https://github.com/pliablepixels/zmNinja/issues/652)
+- Event list incorrect after deleting first event in the list [\#651](https://github.com/pliablepixels/zmNinja/issues/651)
+- Time not properly displayed in the event modal when selecting 'next event' [\#649](https://github.com/pliablepixels/zmNinja/issues/649)
+- zmNinja - montage view - monitors don't show on first run, but show after login saved [\#641](https://github.com/pliablepixels/zmNinja/issues/641)
+- api update needed [\#610](https://github.com/pliablepixels/zmNinja/issues/610)
+- Can't build in IOS [\#609](https://github.com/pliablepixels/zmNinja/issues/609)
**Merged pull requests:**
@@ -124,14 +155,11 @@
## [v1.3.004](https://github.com/pliablepixels/zmNinja/tree/v1.3.004) (2018-06-03)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.3.002...v1.3.004)
-**Fixed bugs:**
+**Closed issues:**
- Certain android phones cannot store data [\#636](https://github.com/pliablepixels/zmNinja/issues/636)
- Login succeeded but API failed [\#635](https://github.com/pliablepixels/zmNinja/issues/635)
- 1.3.0 - live view not working if no auth is used [\#634](https://github.com/pliablepixels/zmNinja/issues/634)
-
-**Closed issues:**
-
- Desktop, at certain windows sizes the 24hr Preview frames will jiggle. [\#600](https://github.com/pliablepixels/zmNinja/issues/600)
- Missing events if logged in zmNinja with non admin user [\#568](https://github.com/pliablepixels/zmNinja/issues/568)
- Enhance System Status to show disk space details [\#430](https://github.com/pliablepixels/zmNinja/issues/430)
@@ -150,46 +178,42 @@
## [v1.3.0](https://github.com/pliablepixels/zmNinja/tree/v1.3.0) (2018-05-18)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.515...v1.3.0)
-**Implemented enhancements:**
+**Closed issues:**
- Allow alarm image browsing inside events modal view [\#624](https://github.com/pliablepixels/zmNinja/issues/624)
- Add ability to copy/paste text [\#623](https://github.com/pliablepixels/zmNinja/issues/623)
-- Support storageareas multi-port [\#602](https://github.com/pliablepixels/zmNinja/issues/602)
-- event banner display motion zone [\#593](https://github.com/pliablepixels/zmNinja/issues/593)
-- Feature: delete events by swiping from the left and clicking a delete button. In events list view [\#547](https://github.com/pliablepixels/zmNinja/issues/547)
-- Feature: ability to delete an event from footage view [\#546](https://github.com/pliablepixels/zmNinja/issues/546)
-- Add watch app extensions for live camera streams [\#221](https://github.com/pliablepixels/zmNinja/issues/221)
-- evaluate what it takes to implement client certificates [\#3](https://github.com/pliablepixels/zmNinja/issues/3)
-
-**Fixed bugs:**
-
- downloading MP4s on android don't work [\#621](https://github.com/pliablepixels/zmNinja/issues/621)
-- clean up event handlers \(memory leaks\) [\#611](https://github.com/pliablepixels/zmNinja/issues/611)
-- On resume, we often get "Event server connection error" [\#604](https://github.com/pliablepixels/zmNinja/issues/604)
-- Sometimes on start, authentication fails [\#603](https://github.com/pliablepixels/zmNinja/issues/603)
-- The resolution of \#553 breaks on some phones - window reload [\#598](https://github.com/pliablepixels/zmNinja/issues/598)
-- Wizard transforms basic auth credentials to lowercase when entered as part of portal URL [\#591](https://github.com/pliablepixels/zmNinja/issues/591)
-- increased CPU and/or memory usage over time [\#553](https://github.com/pliablepixels/zmNinja/issues/553)
-- 'camera disconnected' graphic changes thumbnail resolution in 'Montage' view, causing overlap. [\#528](https://github.com/pliablepixels/zmNinja/issues/528)
-
-**Closed issues:**
-
- Add basic auth token for apache mod\_header foo [\#618](https://github.com/pliablepixels/zmNinja/issues/618)
- clean up neighbor event navigation and add video support for navigation [\#614](https://github.com/pliablepixels/zmNinja/issues/614)
- remove basic auth user:password in URLs and convert to Authorization header [\#613](https://github.com/pliablepixels/zmNinja/issues/613)
+- clean up event handlers \(memory leaks\) [\#611](https://github.com/pliablepixels/zmNinja/issues/611)
- cleanup streaming - big time [\#606](https://github.com/pliablepixels/zmNinja/issues/606)
+- On resume, we often get "Event server connection error" [\#604](https://github.com/pliablepixels/zmNinja/issues/604)
+- Sometimes on start, authentication fails [\#603](https://github.com/pliablepixels/zmNinja/issues/603)
+- Support storageareas multi-port [\#602](https://github.com/pliablepixels/zmNinja/issues/602)
- New thumbnails don't load in Events List and 24hr Preview [\#599](https://github.com/pliablepixels/zmNinja/issues/599)
+- The resolution of \#553 breaks on some phones - window reload [\#598](https://github.com/pliablepixels/zmNinja/issues/598)
- jesus christ [\#597](https://github.com/pliablepixels/zmNinja/issues/597)
- testing probotsentiment [\#596](https://github.com/pliablepixels/zmNinja/issues/596)
- bullshit issue - testing request info bot [\#595](https://github.com/pliablepixels/zmNinja/issues/595)
- Live view not working in zmNinja Pro but is working in web browser and another APP [\#594](https://github.com/pliablepixels/zmNinja/issues/594)
+- event banner display motion zone [\#593](https://github.com/pliablepixels/zmNinja/issues/593)
- Event listing time is incorrect [\#592](https://github.com/pliablepixels/zmNinja/issues/592)
+- Wizard transforms basic auth credentials to lowercase when entered as part of portal URL [\#591](https://github.com/pliablepixels/zmNinja/issues/591)
- PTZ issues ... was working but doesn't seem to be now [\#590](https://github.com/pliablepixels/zmNinja/issues/590)
- take out explicit SSL toggle switch in settings [\#589](https://github.com/pliablepixels/zmNinja/issues/589)
- Allow playing recorded feed for in progress events from events view \(if possible\) [\#587](https://github.com/pliablepixels/zmNinja/issues/587)
+- increased CPU and/or memory usage over time [\#553](https://github.com/pliablepixels/zmNinja/issues/553)
+- Feature: delete events by swiping from the left and clicking a delete button. In events list view [\#547](https://github.com/pliablepixels/zmNinja/issues/547)
+- Feature: ability to delete an event from footage view [\#546](https://github.com/pliablepixels/zmNinja/issues/546)
+- 'camera disconnected' graphic changes thumbnail resolution in 'Montage' view, causing overlap. [\#528](https://github.com/pliablepixels/zmNinja/issues/528)
- Req: Android Wear [\#516](https://github.com/pliablepixels/zmNinja/issues/516)
+- Req: Picture-in-Picture [\#515](https://github.com/pliablepixels/zmNinja/issues/515)
- zmNinja for Apple tvOS [\#449](https://github.com/pliablepixels/zmNinja/issues/449)
+- NFR: Persistent timeline view scale and zoom level [\#361](https://github.com/pliablepixels/zmNinja/issues/361)
+- Add watch app extensions for live camera streams [\#221](https://github.com/pliablepixels/zmNinja/issues/221)
- Improve event montage view [\#186](https://github.com/pliablepixels/zmNinja/issues/186)
+- evaluate what it takes to implement client certificates [\#3](https://github.com/pliablepixels/zmNinja/issues/3)
**Merged pull requests:**
@@ -217,25 +241,19 @@
## [v1.2.515](https://github.com/pliablepixels/zmNinja/tree/v1.2.515) (2018-01-11)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.513...v1.2.515)
-**Implemented enhancements:**
-
-- Introduce a new feature to give a 24 hr image only preview [\#570](https://github.com/pliablepixels/zmNinja/issues/570)
-- external app launch for monitor live view or event ID view [\#569](https://github.com/pliablepixels/zmNinja/issues/569)
-- play event on tap after new alarm notification received [\#563](https://github.com/pliablepixels/zmNinja/issues/563)
-
-**Fixed bugs:**
+**Closed issues:**
+- Visibility icon is too close to Menu icon [\#582](https://github.com/pliablepixels/zmNinja/issues/582)
- if event server goes down, zmNinja keeps spawning new connections in "pending auth" state [\#579](https://github.com/pliablepixels/zmNinja/issues/579)
- timeline tap/double-tap doesn't work well on mobile devices [\#577](https://github.com/pliablepixels/zmNinja/issues/577)
- cleanup events page - avoid reloading view for filters & pullup footer often shows no entries [\#576](https://github.com/pliablepixels/zmNinja/issues/576)
-- Saving event server settings is erratic + push received for monitors that are unchecked [\#499](https://github.com/pliablepixels/zmNinja/issues/499)
-
-**Closed issues:**
-
-- Visibility icon is too close to Menu icon [\#582](https://github.com/pliablepixels/zmNinja/issues/582)
- undefined Push notification error - Cannot save event server settings [\#572](https://github.com/pliablepixels/zmNinja/issues/572)
+- Introduce a new feature to give a 24 hr image only preview [\#570](https://github.com/pliablepixels/zmNinja/issues/570)
+- external app launch for monitor live view or event ID view [\#569](https://github.com/pliablepixels/zmNinja/issues/569)
- migrate from ng-websocket to angular-websocket [\#565](https://github.com/pliablepixels/zmNinja/issues/565)
+- play event on tap after new alarm notification received [\#563](https://github.com/pliablepixels/zmNinja/issues/563)
- UWP app in the works? [\#521](https://github.com/pliablepixels/zmNinja/issues/521)
+- Saving event server settings is erratic + push received for monitors that are unchecked [\#499](https://github.com/pliablepixels/zmNinja/issues/499)
**Merged pull requests:**
@@ -263,15 +281,12 @@
## [v1.2.510](https://github.com/pliablepixels/zmNinja/tree/v1.2.510) (2017-12-10)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.507...v1.2.510)
-**Implemented enhancements:**
+**Closed issues:**
- migrate push to firebase for a server less APNS/FCM solution [\#562](https://github.com/pliablepixels/zmNinja/issues/562)
- Support new zms multiport feature \(isaac fork only, for now\) [\#561](https://github.com/pliablepixels/zmNinja/issues/561)
-- Thumbs in event page \(needs API update\) [\#91](https://github.com/pliablepixels/zmNinja/issues/91)
-
-**Closed issues:**
-
- locale-hu.json help-hu.html update [\#558](https://github.com/pliablepixels/zmNinja/issues/558)
+- Thumbs in event page \(needs API update\) [\#91](https://github.com/pliablepixels/zmNinja/issues/91)
**Merged pull requests:**
@@ -283,21 +298,15 @@
## [v1.2.507](https://github.com/pliablepixels/zmNinja/tree/v1.2.507) (2017-11-06)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.504...v1.2.507)
-**Implemented enhancements:**
+**Closed issues:**
- Add finger print auth for android \(already exists for iOS\) [\#555](https://github.com/pliablepixels/zmNinja/issues/555)
- Re-orient the PTZ UI for limited space orientations [\#554](https://github.com/pliablepixels/zmNinja/issues/554)
-
-**Fixed bugs:**
-
+- Login Auth Sucess but api failed Issue [\#552](https://github.com/pliablepixels/zmNinja/issues/552)
- Selecting Timeline in zmNinja IOS app causes application freeze [\#551](https://github.com/pliablepixels/zmNinja/issues/551)
- "the connection to the server was unsuccessful file ///android\_asset/www/index.html" [\#550](https://github.com/pliablepixels/zmNinja/issues/550)
-- zmninja 1.2.35D \(desktop\) for macos hangs with white screen [\#441](https://github.com/pliablepixels/zmNinja/issues/441)
-
-**Closed issues:**
-
-- Login Auth Sucess but api failed Issue [\#552](https://github.com/pliablepixels/zmNinja/issues/552)
- Lag when left in Full Screen Montage [\#526](https://github.com/pliablepixels/zmNinja/issues/526)
+- zmninja 1.2.35D \(desktop\) for macos hangs with white screen [\#441](https://github.com/pliablepixels/zmNinja/issues/441)
**Merged pull requests:**
@@ -306,32 +315,23 @@
## [v1.2.504](https://github.com/pliablepixels/zmNinja/tree/v1.2.504) (2017-10-09)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.503...v1.2.504)
-**Fixed bugs:**
-
-- 1.2.503 broke timeline in Android & Desktop [\#549](https://github.com/pliablepixels/zmNinja/issues/549)
-
**Closed issues:**
+- 1.2.503 broke timeline in Android & Desktop [\#549](https://github.com/pliablepixels/zmNinja/issues/549)
- System edit privileges required to permit non-admin to change camera mode [\#548](https://github.com/pliablepixels/zmNinja/issues/548)
- Support for multiple screens \(desktop\) [\#543](https://github.com/pliablepixels/zmNinja/issues/543)
## [v1.2.503](https://github.com/pliablepixels/zmNinja/tree/v1.2.503) (2017-10-01)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.44...v1.2.503)
-**Implemented enhancements:**
-
-- Allow running multiple, different instances of zmNinja \(desktop\) [\#542](https://github.com/pliablepixels/zmNinja/issues/542)
-- Abstract zmNinja out from ZM specifics [\#318](https://github.com/pliablepixels/zmNinja/issues/318)
-
-**Fixed bugs:**
-
-- German language - JSON corrupted -affects 1.2.500 [\#545](https://github.com/pliablepixels/zmNinja/issues/545)
-
**Closed issues:**
+- German language - JSON corrupted -affects 1.2.500 [\#545](https://github.com/pliablepixels/zmNinja/issues/545)
+- Allow running multiple, different instances of zmNinja \(desktop\) [\#542](https://github.com/pliablepixels/zmNinja/issues/542)
- make it easier to make desktop builds [\#541](https://github.com/pliablepixels/zmNinja/issues/541)
- Explore upgrading electron wrapper to solve white screen issues [\#539](https://github.com/pliablepixels/zmNinja/issues/539)
- All monitors view refresh rate 0 or very low on my PC/Windows installation of ZMNinja [\#527](https://github.com/pliablepixels/zmNinja/issues/527)
+- Abstract zmNinja out from ZM specifics [\#318](https://github.com/pliablepixels/zmNinja/issues/318)
**Merged pull requests:**
@@ -341,27 +341,21 @@
## [v1.2.44](https://github.com/pliablepixels/zmNinja/tree/v1.2.44) (2017-09-25)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.41...v1.2.44)
-**Implemented enhancements:**
-
-- Montage Cycle - customize timer [\#530](https://github.com/pliablepixels/zmNinja/issues/530)
-- New language: Hungarian/Magyar [\#529](https://github.com/pliablepixels/zmNinja/issues/529)
-
-**Fixed bugs:**
-
-- zmNinja incorrectly reports invalid API [\#537](https://github.com/pliablepixels/zmNinja/issues/537)
-- Crosswalk build no longer works on newer android phones [\#536](https://github.com/pliablepixels/zmNinja/issues/536)
-- Fixes for IOS11 and iPhone X [\#534](https://github.com/pliablepixels/zmNinja/issues/534)
-- Many presets in live view results in the screen overflowing [\#517](https://github.com/pliablepixels/zmNinja/issues/517)
-
**Closed issues:**
- Mac screen sleep issue [\#538](https://github.com/pliablepixels/zmNinja/issues/538)
+- zmNinja incorrectly reports invalid API [\#537](https://github.com/pliablepixels/zmNinja/issues/537)
+- Crosswalk build no longer works on newer android phones [\#536](https://github.com/pliablepixels/zmNinja/issues/536)
- Update code base to work with new ionic dev env [\#535](https://github.com/pliablepixels/zmNinja/issues/535)
+- Fixes for IOS11 and iPhone X [\#534](https://github.com/pliablepixels/zmNinja/issues/534)
- zmNinja fails against ZM 1.31.1 [\#533](https://github.com/pliablepixels/zmNinja/issues/533)
+- Montage Cycle - customize timer [\#530](https://github.com/pliablepixels/zmNinja/issues/530)
+- New language: Hungarian/Magyar [\#529](https://github.com/pliablepixels/zmNinja/issues/529)
- 1.30.4 API not connecting [\#523](https://github.com/pliablepixels/zmNinja/issues/523)
- Does 1.3 work with zmninja [\#522](https://github.com/pliablepixels/zmNinja/issues/522)
- Feature request: possibility to select a run state from zmNinja [\#520](https://github.com/pliablepixels/zmNinja/issues/520)
- Stability problem on zmNinja on Windows 10 x64 after adding a fourth monitor [\#519](https://github.com/pliablepixels/zmNinja/issues/519)
+- Many presets in live view results in the screen overflowing [\#517](https://github.com/pliablepixels/zmNinja/issues/517)
- fit/fill screen option issue [\#514](https://github.com/pliablepixels/zmNinja/issues/514)
- Any chance of A10 Allwinder cpu suport? [\#513](https://github.com/pliablepixels/zmNinja/issues/513)
@@ -377,22 +371,17 @@
## [v1.2.41](https://github.com/pliablepixels/zmNinja/tree/v1.2.41) (2017-04-11)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v/1.2.40...v1.2.41)
-**Implemented enhancements:**
+**Closed issues:**
- Implement concept of 'default profile' & 'workspace' in Montage [\#509](https://github.com/pliablepixels/zmNinja/issues/509)
- Support Amcrest PTZ in zmNinja [\#508](https://github.com/pliablepixels/zmNinja/issues/508)
+- Add support for manual disable/enable alarms [\#507](https://github.com/pliablepixels/zmNinja/issues/507)
+- Menu bar retaining previous title [\#506](https://github.com/pliablepixels/zmNinja/issues/506)
- Allow for montage scaling at increments of 5% \(currently 10%\) [\#505](https://github.com/pliablepixels/zmNinja/issues/505)
-- In monitor list \(Montage screen\) make the color of disabled monitors more prominent [\#503](https://github.com/pliablepixels/zmNinja/issues/503)
-
-**Fixed bugs:**
-
- Montage profile showing new monitors automatically [\#504](https://github.com/pliablepixels/zmNinja/issues/504)
-- Video playback \(h264\) breaks on iOS with a config.xml setting [\#501](https://github.com/pliablepixels/zmNinja/issues/501)
-
-**Closed issues:**
-
-- Add support for manual disable/enable alarms [\#507](https://github.com/pliablepixels/zmNinja/issues/507)
+- In monitor list \(Montage screen\) make the color of disabled monitors more prominent [\#503](https://github.com/pliablepixels/zmNinja/issues/503)
- When zoneminder is in contineous record mode zmNinja shows no events [\#502](https://github.com/pliablepixels/zmNinja/issues/502)
+- Video playback \(h264\) breaks on iOS with a config.xml setting [\#501](https://github.com/pliablepixels/zmNinja/issues/501)
- 2 Monitors - But only only one show up in "Event List" [\#500](https://github.com/pliablepixels/zmNinja/issues/500)
- Google independent zmNinja via F-Droid or downloadable packages \(apk\) [\#498](https://github.com/pliablepixels/zmNinja/issues/498)
- iOS app frozen after being in background [\#482](https://github.com/pliablepixels/zmNinja/issues/482)
@@ -408,14 +397,12 @@
## [v1.2.40](https://github.com/pliablepixels/zmNinja/tree/v1.2.40) (2017-03-19)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.39...v1.2.40)
-**Fixed bugs:**
-
-- Problem with notifications. [\#468](https://github.com/pliablepixels/zmNinja/issues/468)
-- Login denied for user "" when not using ZM authentication [\#459](https://github.com/pliablepixels/zmNinja/issues/459)
-
**Closed issues:**
+- Windows zmNinja authenticates without "use zm authentication" checked [\#496](https://github.com/pliablepixels/zmNinja/issues/496)
- Timezone incorrect [\#492](https://github.com/pliablepixels/zmNinja/issues/492)
+- Problem with notifications. [\#468](https://github.com/pliablepixels/zmNinja/issues/468)
+- Login denied for user "" when not using ZM authentication [\#459](https://github.com/pliablepixels/zmNinja/issues/459)
**Merged pull requests:**
@@ -427,24 +414,19 @@
## [v1.2.39](https://github.com/pliablepixels/zmNinja/tree/v1.2.39) (2017-03-04)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.38...v1.2.39)
-**Implemented enhancements:**
-
-- French Translation [\#469](https://github.com/pliablepixels/zmNinja/issues/469)
-- New language: German [\#466](https://github.com/pliablepixels/zmNinja/issues/466)
-
-**Fixed bugs:**
-
-- \(timeout\) "Zoneminder Authentication Failed" even though Zoneminder's logs says authentication was successful [\#487](https://github.com/pliablepixels/zmNinja/issues/487)
-- Can't get out of fullscreen mode \(confirmed on win64\) [\#473](https://github.com/pliablepixels/zmNinja/issues/473)
-
**Closed issues:**
- Update source build to use new versions of Cordova/Ionic [\#491](https://github.com/pliablepixels/zmNinja/issues/491)
+- \(timeout\) "Zoneminder Authentication Failed" even though Zoneminder's logs says authentication was successful [\#487](https://github.com/pliablepixels/zmNinja/issues/487)
+- Can't get out of fullscreen mode \(confirmed on win64\) [\#473](https://github.com/pliablepixels/zmNinja/issues/473)
+- French Translation [\#469](https://github.com/pliablepixels/zmNinja/issues/469)
- Launch zmNinja via iOS app URL scheme [\#467](https://github.com/pliablepixels/zmNinja/issues/467)
+- New language: German [\#466](https://github.com/pliablepixels/zmNinja/issues/466)
- zmNinja complied from sources for Android and push notification [\#464](https://github.com/pliablepixels/zmNinja/issues/464)
- \[Desktop/Windows\]Window placement and size is not preserved across multiple sessions. [\#462](https://github.com/pliablepixels/zmNinja/issues/462)
- Cycle Montage [\#460](https://github.com/pliablepixels/zmNinja/issues/460)
- view streaming video inside ionic with iOS 10.2.1? [\#458](https://github.com/pliablepixels/zmNinja/issues/458)
+- \[Desktop\] Resize cameras in full screen freely? [\#457](https://github.com/pliablepixels/zmNinja/issues/457)
- missing event only shown with Filters [\#445](https://github.com/pliablepixels/zmNinja/issues/445)
- FAB action buttons are confusing [\#204](https://github.com/pliablepixels/zmNinja/issues/204)
@@ -470,7 +452,7 @@
## [v1.2.38](https://github.com/pliablepixels/zmNinja/tree/v1.2.38) (2017-02-17)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.37...v1.2.38)
-**Implemented enhancements:**
+**Closed issues:**
- SSL - add an option that either requires self signed certs installed on phones or will only work with real certs [\#455](https://github.com/pliablepixels/zmNinja/issues/455)
- Allow users to hide MP4/GIF buttons [\#454](https://github.com/pliablepixels/zmNinja/issues/454)
@@ -483,18 +465,12 @@
## [v1.2.37](https://github.com/pliablepixels/zmNinja/tree/v1.2.37) (2017-02-11)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.36...v1.2.37)
-**Implemented enhancements:**
+**Closed issues:**
- Add ability to view server logs [\#452](https://github.com/pliablepixels/zmNinja/issues/452)
-- Add ability to reflow montage without resetting size [\#448](https://github.com/pliablepixels/zmNinja/issues/448)
-
-**Fixed bugs:**
-
- wizard often does not detect cgi-bin [\#451](https://github.com/pliablepixels/zmNinja/issues/451)
- fs command line option not working [\#450](https://github.com/pliablepixels/zmNinja/issues/450)
-
-**Closed issues:**
-
+- Add ability to reflow montage without resetting size [\#448](https://github.com/pliablepixels/zmNinja/issues/448)
- Montage Image Scale not Saving on Win x64 [\#447](https://github.com/pliablepixels/zmNinja/issues/447)
- Side menu scroll feature locks after switching servers OR displaying liveview in landscape [\#337](https://github.com/pliablepixels/zmNinja/issues/337)
@@ -505,34 +481,29 @@
## [v1.2.36](https://github.com/pliablepixels/zmNinja/tree/v1.2.36) (2017-02-06)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.35...v1.2.36)
-**Implemented enhancements:**
+**Closed issues:**
- Add ability to hide grey buttons in single monitor view [\#443](https://github.com/pliablepixels/zmNinja/issues/443)
+- Hard coded text found [\#440](https://github.com/pliablepixels/zmNinja/issues/440)
+- Hard coded text alert found [\#437](https://github.com/pliablepixels/zmNinja/issues/437)
- Desktop app opening maximized, in full screen montage view [\#436](https://github.com/pliablepixels/zmNinja/issues/436)
- Adding Dutch Language Files [\#433](https://github.com/pliablepixels/zmNinja/issues/433)
- Allow for archived events to be displayed or hidden \(based on toggle switch\) [\#432](https://github.com/pliablepixels/zmNinja/issues/432)
- Enhancement: Add event names to Event list view [\#431](https://github.com/pliablepixels/zmNinja/issues/431)
-- server settings - confirm deletion [\#423](https://github.com/pliablepixels/zmNinja/issues/423)
-- Add ability to view zones as overlays on live monitor feed [\#420](https://github.com/pliablepixels/zmNinja/issues/420)
-- Add ability to cycle between montage profiles [\#419](https://github.com/pliablepixels/zmNinja/issues/419)
-- Adding Dutch language [\#387](https://github.com/pliablepixels/zmNinja/issues/387)
-- Hide credentials of simple auth in display [\#363](https://github.com/pliablepixels/zmNinja/issues/363)
-
-**Fixed bugs:**
-
- switching from full screen to regular causes header alignment issues\(iOS only\) [\#429](https://github.com/pliablepixels/zmNinja/issues/429)
- when bulk frames are present, frame view while viewing footage goes wrong [\#428](https://github.com/pliablepixels/zmNinja/issues/428)
- display cgi-bin error if a wrong cgi path is set in login even if you don't tap save [\#427](https://github.com/pliablepixels/zmNinja/issues/427)
+- invalid api [\#426](https://github.com/pliablepixels/zmNinja/issues/426)
- Fallback Server Hangup [\#424](https://github.com/pliablepixels/zmNinja/issues/424)
+- server settings - confirm deletion [\#423](https://github.com/pliablepixels/zmNinja/issues/423)
- Cannot delete events [\#422](https://github.com/pliablepixels/zmNinja/issues/422)
-- restricted users for event notification not working [\#391](https://github.com/pliablepixels/zmNinja/issues/391)
-
-**Closed issues:**
-
-- Hard coded text found [\#440](https://github.com/pliablepixels/zmNinja/issues/440)
-- Hard coded text alert found [\#437](https://github.com/pliablepixels/zmNinja/issues/437)
- Typo in Validating-if-APIs-work-on-ZM page \(events instead of events.json\): [\#421](https://github.com/pliablepixels/zmNinja/issues/421)
+- Add ability to view zones as overlays on live monitor feed [\#420](https://github.com/pliablepixels/zmNinja/issues/420)
+- Add ability to cycle between montage profiles [\#419](https://github.com/pliablepixels/zmNinja/issues/419)
- event server settings - Strange Behaviour [\#414](https://github.com/pliablepixels/zmNinja/issues/414)
+- restricted users for event notification not working [\#391](https://github.com/pliablepixels/zmNinja/issues/391)
+- Adding Dutch language [\#387](https://github.com/pliablepixels/zmNinja/issues/387)
+- Hide credentials of simple auth in display [\#363](https://github.com/pliablepixels/zmNinja/issues/363)
**Merged pull requests:**
@@ -546,7 +517,7 @@
## [v1.2.35](https://github.com/pliablepixels/zmNinja/tree/v1.2.35) (2016-12-31)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.34...v1.2.35)
-**Implemented enhancements:**
+**Closed issues:**
- Add ability to show motion outlines in alarm frames \(if enabled in ZM\) [\#417](https://github.com/pliablepixels/zmNinja/issues/417)
- Archive selected events [\#388](https://github.com/pliablepixels/zmNinja/issues/388)
@@ -559,19 +530,13 @@
## [v1.2.34](https://github.com/pliablepixels/zmNinja/tree/v1.2.34) (2016-12-24)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.33...v1.2.34)
-**Implemented enhancements:**
-
-- Add ability to launch app via URL for external integration [\#411](https://github.com/pliablepixels/zmNinja/issues/411)
-- Allow for pinning and hiding monitors during rearranging in montage [\#409](https://github.com/pliablepixels/zmNinja/issues/409)
-
-**Fixed bugs:**
-
-- First time users - app gets locked if APIs are not configured \[Mostly Android\] [\#415](https://github.com/pliablepixels/zmNinja/issues/415)
-
**Closed issues:**
+- First time users - app gets locked if APIs are not configured \[Mostly Android\] [\#415](https://github.com/pliablepixels/zmNinja/issues/415)
- Missing translations Russian [\#412](https://github.com/pliablepixels/zmNinja/issues/412)
+- Add ability to launch app via URL for external integration [\#411](https://github.com/pliablepixels/zmNinja/issues/411)
- Missing translations for popup buttons [\#410](https://github.com/pliablepixels/zmNinja/issues/410)
+- Allow for pinning and hiding monitors during rearranging in montage [\#409](https://github.com/pliablepixels/zmNinja/issues/409)
- Mobile unable to connect to the event server [\#403](https://github.com/pliablepixels/zmNinja/issues/403)
- Download events as avi,mov, even mp4 videos [\#334](https://github.com/pliablepixels/zmNinja/issues/334)
@@ -585,18 +550,12 @@
## [v1.2.32](https://github.com/pliablepixels/zmNinja/tree/v1.2.32) (2016-12-09)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.31...v1.2.32)
-**Implemented enhancements:**
-
-- Montage Camera Groups [\#397](https://github.com/pliablepixels/zmNinja/issues/397)
-- Multiple selectable/saveable 'Montage' views within a server profile [\#390](https://github.com/pliablepixels/zmNinja/issues/390)
-
-**Fixed bugs:**
-
-- In some cases, events screen shows no events - even though there are events [\#408](https://github.com/pliablepixels/zmNinja/issues/408)
-
**Closed issues:**
+- In some cases, events screen shows no events - even though there are events [\#408](https://github.com/pliablepixels/zmNinja/issues/408)
- Translation issue [\#400](https://github.com/pliablepixels/zmNinja/issues/400)
+- Montage Camera Groups [\#397](https://github.com/pliablepixels/zmNinja/issues/397)
+- Multiple selectable/saveable 'Montage' views within a server profile [\#390](https://github.com/pliablepixels/zmNinja/issues/390)
**Merged pull requests:**
@@ -612,29 +571,23 @@
## [v1.2.31](https://github.com/pliablepixels/zmNinja/tree/v1.2.31) (2016-12-02)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.30...v1.2.31)
-**Fixed bugs:**
-
-- \[H.264\] Cue position: player reports incorrect length [\#395](https://github.com/pliablepixels/zmNinja/issues/395)
-- hardcoded phrases in code \(not using translation files\) [\#394](https://github.com/pliablepixels/zmNinja/issues/394)
-
**Closed issues:**
- rewrite GIFcreation to be able to handle much larger images [\#398](https://github.com/pliablepixels/zmNinja/issues/398)
+- \[H.264\] Cue position: player reports incorrect length [\#395](https://github.com/pliablepixels/zmNinja/issues/395)
+- hardcoded phrases in code \(not using translation files\) [\#394](https://github.com/pliablepixels/zmNinja/issues/394)
## [v1.2.30](https://github.com/pliablepixels/zmNinja/tree/v1.2.30) (2016-11-26)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.29...v1.2.30)
-**Implemented enhancements:**
+**Closed issues:**
+- \[BUG\] Window title does not change to 'Events' when in events view [\#389](https://github.com/pliablepixels/zmNinja/issues/389)
+- adding spanish language [\#384](https://github.com/pliablepixels/zmNinja/issues/384)
- Add ability to download mp4 files: if using feature-264 [\#383](https://github.com/pliablepixels/zmNinja/issues/383)
- \[H264\] Playback speed in event player [\#382](https://github.com/pliablepixels/zmNinja/issues/382)
- \[h264\] add cue points in video player for alarmed frames [\#381](https://github.com/pliablepixels/zmNinja/issues/381)
- Add ability to save animated gif version of event \(alarm frames only\) [\#379](https://github.com/pliablepixels/zmNinja/issues/379)
-
-**Closed issues:**
-
-- \[BUG\] Window title does not change to 'Events' when in events view [\#389](https://github.com/pliablepixels/zmNinja/issues/389)
-- adding spanish language [\#384](https://github.com/pliablepixels/zmNinja/issues/384)
- Monitor configuration change hangs on FreeBSD-11 [\#373](https://github.com/pliablepixels/zmNinja/issues/373)
**Merged pull requests:**
@@ -648,23 +601,17 @@
## [v1.2.29](https://github.com/pliablepixels/zmNinja/tree/v1.2.29) (2016-11-16)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v/1.2.28...v1.2.29)
-**Implemented enhancements:**
+**Closed issues:**
- New language: Polish \(credit @maymaymay\) [\#372](https://github.com/pliablepixels/zmNinja/issues/372)
- \[NFR\] Add button 'Now' to timeline screen [\#371](https://github.com/pliablepixels/zmNinja/issues/371)
+- Timeline dynamic updates issue [\#369](https://github.com/pliablepixels/zmNinja/issues/369)
+- On certain samsung phones, autocorrect makes it hard to enter text in input configuration [\#367](https://github.com/pliablepixels/zmNinja/issues/367)
- Add Russian language \(credit @BoskSpb\) [\#366](https://github.com/pliablepixels/zmNinja/issues/366)
- \[H264\] Time overlay during playback [\#362](https://github.com/pliablepixels/zmNinja/issues/362)
- Option to fit to screen on H264 event playback [\#358](https://github.com/pliablepixels/zmNinja/issues/358)
-
-**Fixed bugs:**
-
-- On certain samsung phones, autocorrect makes it hard to enter text in input configuration [\#367](https://github.com/pliablepixels/zmNinja/issues/367)
- When navigating events using prev/next or gapless, it shows all events including ones with 0 alarms [\#113](https://github.com/pliablepixels/zmNinja/issues/113)
-**Closed issues:**
-
-- Timeline dynamic updates issue [\#369](https://github.com/pliablepixels/zmNinja/issues/369)
-
**Merged pull requests:**
- Polish language name modyfication [\#375](https://github.com/pliablepixels/zmNinja/pull/375) ([maymaymay](https://github.com/maymaymay))
@@ -679,46 +626,36 @@
## [v1.2.28](https://github.com/pliablepixels/zmNinja/tree/v1.2.28) (2016-11-08)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.26...v1.2.28)
-**Implemented enhancements:**
+**Closed issues:**
+- view=view\_video mode is not working \(requires ZM patch\) [\#364](https://github.com/pliablepixels/zmNinja/issues/364)
+- Cancel timeline custom range settings leads to indefinitely 'working on graph data' [\#360](https://github.com/pliablepixels/zmNinja/issues/360)
- \[DESKTOP\] \(H264\) Automatic playback? [\#359](https://github.com/pliablepixels/zmNinja/issues/359)
- Remember last state of application \(desktops\) [\#357](https://github.com/pliablepixels/zmNinja/issues/357)
- Allow option for timeline view to get dynamically updated as new events occur [\#356](https://github.com/pliablepixels/zmNinja/issues/356)
-- Differentiate between server timezone and local timezone \(needs ZM API Update \#1655\) [\#353](https://github.com/pliablepixels/zmNinja/issues/353)
-
-**Fixed bugs:**
-
-- Cancel timeline custom range settings leads to indefinitely 'working on graph data' [\#360](https://github.com/pliablepixels/zmNinja/issues/360)
+- Can't load as a web page on Android since d76cf1c commit [\#355](https://github.com/pliablepixels/zmNinja/issues/355)
- alarm frame navigation while watching event footage shows incorrect frames [\#354](https://github.com/pliablepixels/zmNinja/issues/354)
+- Differentiate between server timezone and local timezone \(needs ZM API Update \#1655\) [\#353](https://github.com/pliablepixels/zmNinja/issues/353)
- iOS Websockets stopped working with latest updates [\#352](https://github.com/pliablepixels/zmNinja/issues/352)
- Android \< 5.0 has SSL cert issues [\#351](https://github.com/pliablepixels/zmNinja/issues/351)
- Try and solve the montage overlapping when the image doesn't fully load [\#350](https://github.com/pliablepixels/zmNinja/issues/350)
-**Closed issues:**
-
-- view=view\_video mode is not working \(requires ZM patch\) [\#364](https://github.com/pliablepixels/zmNinja/issues/364)
-- Can't load as a web page on Android since d76cf1c commit [\#355](https://github.com/pliablepixels/zmNinja/issues/355)
-
## [v1.2.26](https://github.com/pliablepixels/zmNinja/tree/v1.2.26) (2016-10-13)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.24...v1.2.26)
-**Implemented enhancements:**
+**Closed issues:**
- simplify event montage UX [\#348](https://github.com/pliablepixels/zmNinja/issues/348)
- Show actual \(server\) time in visible in full screen \(desktop\) [\#346](https://github.com/pliablepixels/zmNinja/issues/346)
+- Video broken when viewed through non-standard port [\#345](https://github.com/pliablepixels/zmNinja/issues/345)
+- Montage Not working [\#343](https://github.com/pliablepixels/zmNinja/issues/343)
- Implement "shrinking headers" as you scroll to get more real estate [\#342](https://github.com/pliablepixels/zmNinja/issues/342)
-- Add Montage Awesomeness to Event Montage [\#201](https://github.com/pliablepixels/zmNinja/issues/201)
-
-**Fixed bugs:**
-
+- Show an error message if event server connection fail [\#341](https://github.com/pliablepixels/zmNinja/issues/341)
- Make events list work with system font size [\#339](https://github.com/pliablepixels/zmNinja/issues/339)
- IOS 10 - crash on image save to photo albums [\#338](https://github.com/pliablepixels/zmNinja/issues/338)
-
-**Closed issues:**
-
-- Montage Not working [\#343](https://github.com/pliablepixels/zmNinja/issues/343)
-- Show an error message if event server connection fail [\#341](https://github.com/pliablepixels/zmNinja/issues/341)
+- Android - show notifications in system tray [\#279](https://github.com/pliablepixels/zmNinja/issues/279)
- adding download button for video events [\#235](https://github.com/pliablepixels/zmNinja/issues/235)
+- Add Montage Awesomeness to Event Montage [\#201](https://github.com/pliablepixels/zmNinja/issues/201)
**Merged pull requests:**
@@ -729,24 +666,18 @@
## [v1.2.24](https://github.com/pliablepixels/zmNinja/tree/v1.2.24) (2016-09-24)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.19...v1.2.24)
-**Implemented enhancements:**
-
-- Arabic language implementation \(credit @aljabr\) [\#336](https://github.com/pliablepixels/zmNinja/issues/336)
-- enable low bandwidth mode for zmN [\#321](https://github.com/pliablepixels/zmNinja/issues/321)
-
-**Fixed bugs:**
-
-- Yellow Event Summary Window \(Ionic pullup footer\) displays no data when dragged up. [\#333](https://github.com/pliablepixels/zmNinja/issues/333)
-- No live view \(via monitor, not montage\) after switching between servers. [\#329](https://github.com/pliablepixels/zmNinja/issues/329)
-- languages with non-english numbers break events/timeline feeds [\#325](https://github.com/pliablepixels/zmNinja/issues/325)
-- "Error - unable to save snapshot" on Android V6 [\#322](https://github.com/pliablepixels/zmNinja/issues/322)
-
**Closed issues:**
+- Arabic language implementation \(credit @aljabr\) [\#336](https://github.com/pliablepixels/zmNinja/issues/336)
- Syntax error: newline unexpected [\#335](https://github.com/pliablepixels/zmNinja/issues/335)
+- Yellow Event Summary Window \(Ionic pullup footer\) displays no data when dragged up. [\#333](https://github.com/pliablepixels/zmNinja/issues/333)
- v [\#332](https://github.com/pliablepixels/zmNinja/issues/332)
- Validate From/To date in Event Filter [\#330](https://github.com/pliablepixels/zmNinja/issues/330)
+- No live view \(via monitor, not montage\) after switching between servers. [\#329](https://github.com/pliablepixels/zmNinja/issues/329)
+- languages with non-english numbers break events/timeline feeds [\#325](https://github.com/pliablepixels/zmNinja/issues/325)
- IOS status bar [\#324](https://github.com/pliablepixels/zmNinja/issues/324)
+- "Error - unable to save snapshot" on Android V6 [\#322](https://github.com/pliablepixels/zmNinja/issues/322)
+- enable low bandwidth mode for zmN [\#321](https://github.com/pliablepixels/zmNinja/issues/321)
- ZMNinja for Kodi [\#311](https://github.com/pliablepixels/zmNinja/issues/311)
- zmNinja for Windows Mobile [\#299](https://github.com/pliablepixels/zmNinja/issues/299)
@@ -759,44 +690,35 @@
## [v1.2.19](https://github.com/pliablepixels/zmNinja/tree/v1.2.19) (2016-09-04)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.18...v1.2.19)
-**Implemented enhancements:**
-
-- Cycle monitors [\#319](https://github.com/pliablepixels/zmNinja/issues/319)
-
-**Fixed bugs:**
+**Closed issues:**
- Switching servers without saving first causes the app to freeze \(android/ios\) [\#320](https://github.com/pliablepixels/zmNinja/issues/320)
+- Cycle monitors [\#319](https://github.com/pliablepixels/zmNinja/issues/319)
## [v1.2.18](https://github.com/pliablepixels/zmNinja/tree/v1.2.18) (2016-09-02)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.17...v1.2.18)
-**Implemented enhancements:**
+**Closed issues:**
- for all event related views \(event list, footage, analyze\) show "relative time from now" like "1 day ago" or "2 hours ago" [\#317](https://github.com/pliablepixels/zmNinja/issues/317)
## [v1.2.17](https://github.com/pliablepixels/zmNinja/tree/v1.2.17) (2016-09-01)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.2.13...v1.2.17)
-**Implemented enhancements:**
+**Closed issues:**
- Add ability to perform monitor config changes for all monitors \(credit @sctt\) [\#316](https://github.com/pliablepixels/zmNinja/issues/316)
- enable/disable sound and vibration push notifications [\#314](https://github.com/pliablepixels/zmNinja/issues/314)
-- Add Wake/Sleep/Reset to PTZ functions \(credit: @sctt\) [\#306](https://github.com/pliablepixels/zmNinja/issues/306)
-
-**Fixed bugs:**
-
- clean up event server flow - its been a bloody mess for a while [\#312](https://github.com/pliablepixels/zmNinja/issues/312)
- Add option to disable nativeTransitions [\#310](https://github.com/pliablepixels/zmNinja/issues/310)
+- Add Wake/Sleep/Reset to PTZ functions \(credit: @sctt\) [\#306](https://github.com/pliablepixels/zmNinja/issues/306)
- app freezes when adding more than 2 profiles [\#304](https://github.com/pliablepixels/zmNinja/issues/304)
- saving a server profile removes the "Add" button while in the same view [\#303](https://github.com/pliablepixels/zmNinja/issues/303)
- 1.2.0 seems to have routing issues and xwalk issues [\#302](https://github.com/pliablepixels/zmNinja/issues/302)
+- ZMninja API issue with zoneminder 1.30 [\#300](https://github.com/pliablepixels/zmNinja/issues/300)
- zmNinja fails to log in over open internet on first invocation [\#126](https://github.com/pliablepixels/zmNinja/issues/126)
- it seems in some cases monitor intervals don't get transmitted to zmeventserver [\#112](https://github.com/pliablepixels/zmNinja/issues/112)
-**Closed issues:**
-
-- ZMninja API issue with zoneminder 1.30 [\#300](https://github.com/pliablepixels/zmNinja/issues/300)
-
**Merged pull requests:**
- tweaks to \#313 [\#315](https://github.com/pliablepixels/zmNinja/pull/315) ([pliablepixels](https://github.com/pliablepixels))
@@ -818,29 +740,23 @@
## [vv1.2.0](https://github.com/pliablepixels/zmNinja/tree/vv1.2.0) (2016-08-10)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.1.96...vv1.2.0)
-**Implemented enhancements:**
+**Closed issues:**
- Allow frame navigation when you tap on alarms view within the modal [\#301](https://github.com/pliablepixels/zmNinja/issues/301)
+- license doc typos [\#297](https://github.com/pliablepixels/zmNinja/issues/297)
- When viewing alarmed frames in events view, allow option to only show frames that differ in time [\#296](https://github.com/pliablepixels/zmNinja/issues/296)
+- Having issues setting up Real Time Notifications with ZM ninja and ZM server [\#295](https://github.com/pliablepixels/zmNinja/issues/295)
- Encrypt user profile for more security [\#294](https://github.com/pliablepixels/zmNinja/issues/294)
-- Portuguese language support [\#290](https://github.com/pliablepixels/zmNinja/issues/290)
-- Allow frame navigation when you tap on a thumbnail image [\#288](https://github.com/pliablepixels/zmNinja/issues/288)
-- tapping on graphs should show a nice event list - current doesn't do anything useful [\#18](https://github.com/pliablepixels/zmNinja/issues/18)
-
-**Fixed bugs:**
-
- Password appears in log as plain text [\#293](https://github.com/pliablepixels/zmNinja/issues/293)
- server settings get deleted, especially on iOS [\#292](https://github.com/pliablepixels/zmNinja/issues/292)
+- Portuguese language support [\#290](https://github.com/pliablepixels/zmNinja/issues/290)
+- Allow frame navigation when you tap on a thumbnail image [\#288](https://github.com/pliablepixels/zmNinja/issues/288)
- Tweak montage layout to avoid overlaps and gaps [\#286](https://github.com/pliablepixels/zmNinja/issues/286)
-- Focus! Solve that damn "go to login screen" issue that some users are facing [\#193](https://github.com/pliablepixels/zmNinja/issues/193)
-
-**Closed issues:**
-
-- license doc typos [\#297](https://github.com/pliablepixels/zmNinja/issues/297)
-- Having issues setting up Real Time Notifications with ZM ninja and ZM server [\#295](https://github.com/pliablepixels/zmNinja/issues/295)
- zmNinja via VPN on iOS [\#265](https://github.com/pliablepixels/zmNinja/issues/265)
- rework event graphs in event page, make event navigation easier [\#233](https://github.com/pliablepixels/zmNinja/issues/233)
- PTZ support could be improved [\#207](https://github.com/pliablepixels/zmNinja/issues/207)
+- Focus! Solve that damn "go to login screen" issue that some users are facing [\#193](https://github.com/pliablepixels/zmNinja/issues/193)
+- tapping on graphs should show a nice event list - current doesn't do anything useful [\#18](https://github.com/pliablepixels/zmNinja/issues/18)
**Merged pull requests:**
@@ -852,61 +768,43 @@
## [v1.1.96](https://github.com/pliablepixels/zmNinja/tree/v1.1.96) (2016-07-13)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.1.94...v1.1.96)
-**Implemented enhancements:**
-
-- Make sure zmNinja plays ball with new user roles in APIs [\#93](https://github.com/pliablepixels/zmNinja/issues/93)
-
-**Fixed bugs:**
+**Closed issues:**
- Slash screen PIN entry text error on zmN 1.1.94b [\#284](https://github.com/pliablepixels/zmNinja/issues/284)
+- Multi-server not video from cameras [\#283](https://github.com/pliablepixels/zmNinja/issues/283)
- build for android broke - uglify is messing up release builds [\#282](https://github.com/pliablepixels/zmNinja/issues/282)
- ZMNinja back button issue [\#281](https://github.com/pliablepixels/zmNinja/issues/281)
- Modify montage filtering to make sure maxLimit does not include disabled monitors [\#277](https://github.com/pliablepixels/zmNinja/issues/277)
- Some Android phones seem to have SSL issues with self-signed certs [\#273](https://github.com/pliablepixels/zmNinja/issues/273)
-
-**Closed issues:**
-
-- Multi-server not video from cameras [\#283](https://github.com/pliablepixels/zmNinja/issues/283)
+- Make sure zmNinja plays ball with new user roles in APIs [\#93](https://github.com/pliablepixels/zmNinja/issues/93)
## [v1.1.94](https://github.com/pliablepixels/zmNinja/tree/v1.1.94) (2016-07-09)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.1.93...v1.1.94)
-**Implemented enhancements:**
+**Closed issues:**
+- zmNinja-I can only see one camera in the app in montage view, but I can see my 2 cameras in browser [\#280](https://github.com/pliablepixels/zmNinja/issues/280)
- Allow to navigate to live stream on notification tap [\#278](https://github.com/pliablepixels/zmNinja/issues/278)
- Allow upto 10 monitors to be arranged per row in montage [\#276](https://github.com/pliablepixels/zmNinja/issues/276)
-
-**Fixed bugs:**
-
- Playback of events fails using view=video mode [\#275](https://github.com/pliablepixels/zmNinja/issues/275)
-- zmNinja does not launch on iOS 10 [\#271](https://github.com/pliablepixels/zmNinja/issues/271)
-
-**Closed issues:**
-
-- zmNinja-I can only see one camera in the app in montage view, but I can see my 2 cameras in browser [\#280](https://github.com/pliablepixels/zmNinja/issues/280)
- Swipe to next event for the same monitor id not working [\#274](https://github.com/pliablepixels/zmNinja/issues/274)
+- zmNinja does not launch on iOS 10 [\#271](https://github.com/pliablepixels/zmNinja/issues/271)
## [v1.1.93](https://github.com/pliablepixels/zmNinja/tree/v1.1.93) (2016-06-16)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.1.92...v1.1.93)
-**Implemented enhancements:**
+**Closed issues:**
+- Fix android permissions [\#268](https://github.com/pliablepixels/zmNinja/issues/268)
+- Validate language coverage [\#267](https://github.com/pliablepixels/zmNinja/issues/267)
+- Allow special characters in password to work in wizard [\#264](https://github.com/pliablepixels/zmNinja/issues/264)
- Implement language translations [\#261](https://github.com/pliablepixels/zmNinja/issues/261)
- Italian Language [\#260](https://github.com/pliablepixels/zmNinja/issues/260)
+- Update project to work with ionic@2 tools [\#259](https://github.com/pliablepixels/zmNinja/issues/259)
- Improve desktop mouse-wheel scrolling in the event view [\#258](https://github.com/pliablepixels/zmNinja/issues/258)
-
-**Fixed bugs:**
-
-- Allow special characters in password to work in wizard [\#264](https://github.com/pliablepixels/zmNinja/issues/264)
- if you open a footage modal and exit before 5 seconds, the app keeps checking for event status [\#257](https://github.com/pliablepixels/zmNinja/issues/257)
- Montage and Live View no longer working [\#256](https://github.com/pliablepixels/zmNinja/issues/256)
- 1.1.9 for Android broke pinch and zoom [\#255](https://github.com/pliablepixels/zmNinja/issues/255)
-
-**Closed issues:**
-
-- Fix android permissions [\#268](https://github.com/pliablepixels/zmNinja/issues/268)
-- Validate language coverage [\#267](https://github.com/pliablepixels/zmNinja/issues/267)
-- Update project to work with ionic@2 tools [\#259](https://github.com/pliablepixels/zmNinja/issues/259)
- switch to non parsed zms for montage - see if it helps packery [\#254](https://github.com/pliablepixels/zmNinja/issues/254)
**Merged pull requests:**
@@ -921,35 +819,30 @@
## [v1.1.9](https://github.com/pliablepixels/zmNinja/tree/v1.1.9) (2016-05-20)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.1.7...v1.1.9)
-**Implemented enhancements:**
+**Closed issues:**
+- . [\#253](https://github.com/pliablepixels/zmNinja/issues/253)
- Add ability to jump to specific timeframe during event playback [\#252](https://github.com/pliablepixels/zmNinja/issues/252)
+- Fix keyboard jump on certain fields/iOS [\#251](https://github.com/pliablepixels/zmNinja/issues/251)
- Allow users to specify a minimum alarm frame count for the events page [\#250](https://github.com/pliablepixels/zmNinja/issues/250)
- Implement new color scheme [\#249](https://github.com/pliablepixels/zmNinja/issues/249)
- Show recording state in monitors \(alert/alarm/recording/idle\) [\#248](https://github.com/pliablepixels/zmNinja/issues/248)
-- add ability to force trigger alarms \(needs API upgrade\) [\#245](https://github.com/pliablepixels/zmNinja/issues/245)
-- support multi-server feeds and the new server API [\#241](https://github.com/pliablepixels/zmNinja/issues/241)
-- Write a configuration wizard [\#234](https://github.com/pliablepixels/zmNinja/issues/234)
-
-**Fixed bugs:**
-
-- Fix keyboard jump on certain fields/iOS [\#251](https://github.com/pliablepixels/zmNinja/issues/251)
+- clean up monitorCtrl - remove Event crap - we now have different controllers [\#247](https://github.com/pliablepixels/zmNinja/issues/247)
- clean up buttons so they don't overlap in many views [\#246](https://github.com/pliablepixels/zmNinja/issues/246)
+- add ability to force trigger alarms \(needs API upgrade\) [\#245](https://github.com/pliablepixels/zmNinja/issues/245)
- Switching between profiles fails to discover monitors [\#244](https://github.com/pliablepixels/zmNinja/issues/244)
+- switching between fid mode playback \(api 1.30+\) and path mode causes issues if I don't restart app [\#243](https://github.com/pliablepixels/zmNinja/issues/243)
+- video .mp4 event issue [\#242](https://github.com/pliablepixels/zmNinja/issues/242)
+- support multi-server feeds and the new server API [\#241](https://github.com/pliablepixels/zmNinja/issues/241)
+- check if android is exiting on background [\#240](https://github.com/pliablepixels/zmNinja/issues/240)
- Event Graphs issue [\#239](https://github.com/pliablepixels/zmNinja/issues/239)
- Event server customization [\#238](https://github.com/pliablepixels/zmNinja/issues/238)
- Push notification issue [\#237](https://github.com/pliablepixels/zmNinja/issues/237)
+- Enhancement: zmNinja as surveillance solution [\#236](https://github.com/pliablepixels/zmNinja/issues/236)
+- Write a configuration wizard [\#234](https://github.com/pliablepixels/zmNinja/issues/234)
- Fix the monitor orientation code for rotated cameras [\#232](https://github.com/pliablepixels/zmNinja/issues/232)
- protocol bug - cgi-bin discover [\#231](https://github.com/pliablepixels/zmNinja/issues/231)
-
-**Closed issues:**
-
-- . [\#253](https://github.com/pliablepixels/zmNinja/issues/253)
-- clean up monitorCtrl - remove Event crap - we now have different controllers [\#247](https://github.com/pliablepixels/zmNinja/issues/247)
-- switching between fid mode playback \(api 1.30+\) and path mode causes issues if I don't restart app [\#243](https://github.com/pliablepixels/zmNinja/issues/243)
-- video .mp4 event issue [\#242](https://github.com/pliablepixels/zmNinja/issues/242)
-- check if android is exiting on background [\#240](https://github.com/pliablepixels/zmNinja/issues/240)
-- Enhancement: zmNinja as surveillance solution [\#236](https://github.com/pliablepixels/zmNinja/issues/236)
+- Does not support ssl client certification [\#227](https://github.com/pliablepixels/zmNinja/issues/227)
- Application not recorvering from connection errors [\#199](https://github.com/pliablepixels/zmNinja/issues/199)
- Event Montage unstable [\#183](https://github.com/pliablepixels/zmNinja/issues/183)
- \[DESKTOP\] Playback control bar lost some features in 1.0.9 [\#176](https://github.com/pliablepixels/zmNinja/issues/176)
@@ -957,27 +850,21 @@
## [v1.1.7](https://github.com/pliablepixels/zmNinja/tree/v1.1.7) (2016-04-23)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.1.4...v1.1.7)
-**Implemented enhancements:**
+**Closed issues:**
+- improve timeline taps - make a closest guess [\#230](https://github.com/pliablepixels/zmNinja/issues/230)
- Add option to tap on alarm events in events view to see a larger version [\#229](https://github.com/pliablepixels/zmNinja/issues/229)
- Add a helper function to automatically detect cgi-bin [\#228](https://github.com/pliablepixels/zmNinja/issues/228)
+- iOS and Android: introduce native transitions and scrolling \[performance\] [\#226](https://github.com/pliablepixels/zmNinja/issues/226)
+- Email notifications with animated GIF attachements [\#225](https://github.com/pliablepixels/zmNinja/issues/225)
- PTZ zoom support [\#224](https://github.com/pliablepixels/zmNinja/issues/224)
-
-**Fixed bugs:**
-
- Not possible to control PTZ after swipe from non-PTZ camera [\#223](https://github.com/pliablepixels/zmNinja/issues/223)
- PTZ with moveRel \(Axis PTZ as an example\) does not work when navigated from Montage view [\#222](https://github.com/pliablepixels/zmNinja/issues/222)
+- Add version number to help page [\#220](https://github.com/pliablepixels/zmNinja/issues/220)
+- Upgrade code-base to new plugins, ionic 1.2.4, etc. [\#219](https://github.com/pliablepixels/zmNinja/issues/219)
- montage natural scrolling does not work [\#218](https://github.com/pliablepixels/zmNinja/issues/218)
- when dragging around in analyze graph, don't scroll the screen [\#217](https://github.com/pliablepixels/zmNinja/issues/217)
- full screen in montage does not work [\#216](https://github.com/pliablepixels/zmNinja/issues/216)
-
-**Closed issues:**
-
-- improve timeline taps - make a closest guess [\#230](https://github.com/pliablepixels/zmNinja/issues/230)
-- iOS and Android: introduce native transitions and scrolling \[performance\] [\#226](https://github.com/pliablepixels/zmNinja/issues/226)
-- Email notifications with animated GIF attachements [\#225](https://github.com/pliablepixels/zmNinja/issues/225)
-- Add version number to help page [\#220](https://github.com/pliablepixels/zmNinja/issues/220)
-- Upgrade code-base to new plugins, ionic 1.2.4, etc. [\#219](https://github.com/pliablepixels/zmNinja/issues/219)
- Error: Hook failed with error code ENOENT: [\#210](https://github.com/pliablepixels/zmNinja/issues/210)
## [v1.1.4](https://github.com/pliablepixels/zmNinja/tree/v1.1.4) (2016-04-05)
@@ -986,52 +873,38 @@
## [v1.1.3](https://github.com/pliablepixels/zmNinja/tree/v1.1.3) (2016-04-02)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.1.2...v1.1.3)
-**Implemented enhancements:**
+**Closed issues:**
- new feature to analyze frames quickly from event list [\#215](https://github.com/pliablepixels/zmNinja/issues/215)
+- zmNinja 1.1.3 build from source - Push registration failed [\#214](https://github.com/pliablepixels/zmNinja/issues/214)
- re-introduce ability to hide monitors with new drag/drop montage [\#213](https://github.com/pliablepixels/zmNinja/issues/213)
-- Enhance timeline graph to allow for event frame scrubbing [\#209](https://github.com/pliablepixels/zmNinja/issues/209)
-- Allow ability to only browse alarm frames while in full screen footage view [\#206](https://github.com/pliablepixels/zmNinja/issues/206)
-
-**Fixed bugs:**
-
- zmNinja build from source does not load on iOS 9.x - hangs on splashscreen [\#212](https://github.com/pliablepixels/zmNinja/issues/212)
-- Some SSL users are facing issues with reachability returning no servers reachable [\#208](https://github.com/pliablepixels/zmNinja/issues/208)
-
-**Closed issues:**
-
-- zmNinja 1.1.3 build from source - Push registration failed [\#214](https://github.com/pliablepixels/zmNinja/issues/214)
- No live view video playback, cgi path is set. [\#211](https://github.com/pliablepixels/zmNinja/issues/211)
+- Enhance timeline graph to allow for event frame scrubbing [\#209](https://github.com/pliablepixels/zmNinja/issues/209)
+- Some SSL users are facing issues with reachability returning no servers reachable [\#208](https://github.com/pliablepixels/zmNinja/issues/208)
+- Allow ability to only browse alarm frames while in full screen footage view [\#206](https://github.com/pliablepixels/zmNinja/issues/206)
- Fix layout for first run when no layout config exists - check demo acct [\#205](https://github.com/pliablepixels/zmNinja/issues/205)
## [v1.1.2](https://github.com/pliablepixels/zmNinja/tree/v1.1.2) (2016-03-19)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.1.1...v1.1.2)
-**Implemented enhancements:**
-
-- Left drawer should open with swipe gesture in any view not just fullscreen [\#202](https://github.com/pliablepixels/zmNinja/issues/202)
-- Local and External Server configuration \[$5\] [\#133](https://github.com/pliablepixels/zmNinja/issues/133)
-
-**Fixed bugs:**
-
-- quick scrub drag slider stopped working [\#196](https://github.com/pliablepixels/zmNinja/issues/196)
-
**Closed issues:**
- Add gesture to exit any fullscreen [\#203](https://github.com/pliablepixels/zmNinja/issues/203)
+- Left drawer should open with swipe gesture in any view not just fullscreen [\#202](https://github.com/pliablepixels/zmNinja/issues/202)
- Demo Account Autocreating itself [\#200](https://github.com/pliablepixels/zmNinja/issues/200)
- ionic state restore not creating platforms/android directory [\#198](https://github.com/pliablepixels/zmNinja/issues/198)
+- Compile for Windows 10 mobile [\#197](https://github.com/pliablepixels/zmNinja/issues/197)
+- quick scrub drag slider stopped working [\#196](https://github.com/pliablepixels/zmNinja/issues/196)
- Authentication Failed [\#195](https://github.com/pliablepixels/zmNinja/issues/195)
+- Local and External Server configuration \[$5\] [\#133](https://github.com/pliablepixels/zmNinja/issues/133)
## [v1.1.1](https://github.com/pliablepixels/zmNinja/tree/v1.1.1) (2016-03-14)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.1.0...v1.1.1)
-**Fixed bugs:**
-
-- The new montage function resets montage layout if there are hidden or disabled monitors [\#194](https://github.com/pliablepixels/zmNinja/issues/194)
-
**Closed issues:**
+- The new montage function resets montage layout if there are hidden or disabled monitors [\#194](https://github.com/pliablepixels/zmNinja/issues/194)
- Testing issue template \(dummy issue\) [\#192](https://github.com/pliablepixels/zmNinja/issues/192)
- testing issue template [\#191](https://github.com/pliablepixels/zmNinja/issues/191)
- decrease splash screen delay \(reduce startup delay\) [\#190](https://github.com/pliablepixels/zmNinja/issues/190)
@@ -1040,128 +913,98 @@
## [v1.1.0](https://github.com/pliablepixels/zmNinja/tree/v1.1.0) (2016-03-12)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.0.9...v1.1.0)
-**Implemented enhancements:**
+**Closed issues:**
+- switching server profiles causes inconsistency if you go to developer options [\#189](https://github.com/pliablepixels/zmNinja/issues/189)
+- changing timeline limit does not go into effect until app restart [\#188](https://github.com/pliablepixels/zmNinja/issues/188)
- Add a pre-configured demo account for people to test around with [\#187](https://github.com/pliablepixels/zmNinja/issues/187)
- Add gesture to open left menu while in full screen live view [\#185](https://github.com/pliablepixels/zmNinja/issues/185)
- Add touch gesture to exit live view [\#182](https://github.com/pliablepixels/zmNinja/issues/182)
+- No image for monitors nor events [\#181](https://github.com/pliablepixels/zmNinja/issues/181)
+- Android build fails [\#180](https://github.com/pliablepixels/zmNinja/issues/180)
- add dynamic drag and drop and multiple size options to montage - make it awesome and more consistent [\#179](https://github.com/pliablepixels/zmNinja/issues/179)
+- iPhone stopped working [\#178](https://github.com/pliablepixels/zmNinja/issues/178)
- Prev day/next day for timeline [\#177](https://github.com/pliablepixels/zmNinja/issues/177)
- 12/24 hours scheme settings [\#175](https://github.com/pliablepixels/zmNinja/issues/175)
-
-**Fixed bugs:**
-
-- switching server profiles causes inconsistency if you go to developer options [\#189](https://github.com/pliablepixels/zmNinja/issues/189)
-- changing timeline limit does not go into effect until app restart [\#188](https://github.com/pliablepixels/zmNinja/issues/188)
- Desktop \(possibly others\): Inescapable UI pattern [\#174](https://github.com/pliablepixels/zmNinja/issues/174)
-
-**Closed issues:**
-
-- No image for monitors nor events [\#181](https://github.com/pliablepixels/zmNinja/issues/181)
-- Android build fails [\#180](https://github.com/pliablepixels/zmNinja/issues/180)
-- iPhone stopped working [\#178](https://github.com/pliablepixels/zmNinja/issues/178)
- non-free license [\#173](https://github.com/pliablepixels/zmNinja/issues/173)
- iOS: Montage View arrange views \(third icon from top-right\) does not function [\#172](https://github.com/pliablepixels/zmNinja/issues/172)
## [v1.0.9](https://github.com/pliablepixels/zmNinja/tree/v1.0.9) (2016-02-25)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.0.7...v1.0.9)
-**Implemented enhancements:**
-
-- Route event playback via ZMS [\#164](https://github.com/pliablepixels/zmNinja/issues/164)
-- Montage view zoom slider, ergonomy [\#163](https://github.com/pliablepixels/zmNinja/issues/163)
-- \[DESKTOP\] Zooming for non touch screen displays. [\#162](https://github.com/pliablepixels/zmNinja/issues/162)
-- Fix playback speed for long events [\#161](https://github.com/pliablepixels/zmNinja/issues/161)
-
-**Fixed bugs:**
-
-- Desktop: Monitors Freeze when Exiting Full Screen [\#169](https://github.com/pliablepixels/zmNinja/issues/169)
-- changing to invalid credentials after valid credentials continues to work [\#167](https://github.com/pliablepixels/zmNinja/issues/167)
-
**Closed issues:**
- iOS: Events--\>Filter by Date/Time does not work [\#171](https://github.com/pliablepixels/zmNinja/issues/171)
+- Desktop: Monitors Freeze when Exiting Full Screen [\#169](https://github.com/pliablepixels/zmNinja/issues/169)
- Desktop: Event Footage extremely low resolution [\#168](https://github.com/pliablepixels/zmNinja/issues/168)
+- changing to invalid credentials after valid credentials continues to work [\#167](https://github.com/pliablepixels/zmNinja/issues/167)
- ionic state restore failed [\#166](https://github.com/pliablepixels/zmNinja/issues/166)
- Desktop: Montage places last image below rather than alongside previous [\#165](https://github.com/pliablepixels/zmNinja/issues/165)
+- Route event playback via ZMS [\#164](https://github.com/pliablepixels/zmNinja/issues/164)
+- Montage view zoom slider, ergonomy [\#163](https://github.com/pliablepixels/zmNinja/issues/163)
+- \[DESKTOP\] Zooming for non touch screen displays. [\#162](https://github.com/pliablepixels/zmNinja/issues/162)
+- Fix playback speed for long events [\#161](https://github.com/pliablepixels/zmNinja/issues/161)
- \[DESKTOP\] Playback issue on windows platform [\#151](https://github.com/pliablepixels/zmNinja/issues/151)
## [v1.0.7](https://github.com/pliablepixels/zmNinja/tree/v1.0.7) (2016-02-09)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.0.6...v1.0.7)
-**Implemented enhancements:**
-
-- Refine montage history to accept from/to dates [\#160](https://github.com/pliablepixels/zmNinja/issues/160)
-
**Closed issues:**
+- Refine montage history to accept from/to dates [\#160](https://github.com/pliablepixels/zmNinja/issues/160)
- Build is failing [\#156](https://github.com/pliablepixels/zmNinja/issues/156)
## [v1.0.6](https://github.com/pliablepixels/zmNinja/tree/v1.0.6) (2016-02-05)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.0.5...v1.0.6)
-**Implemented enhancements:**
-
-- Allow event server to work without SSL - requires zmeventserver upgrade [\#159](https://github.com/pliablepixels/zmNinja/issues/159)
-- Introduce a montage timeline function [\#154](https://github.com/pliablepixels/zmNinja/issues/154)
-- Addition Next frame/prev frame buttons when viewing event - for fine grained snapshot control. [\#150](https://github.com/pliablepixels/zmNinja/issues/150)
-- Notification icon and sound - add ability to play default sounds [\#135](https://github.com/pliablepixels/zmNinja/issues/135)
-
**Closed issues:**
+- Allow event server to work without SSL - requires zmeventserver upgrade [\#159](https://github.com/pliablepixels/zmNinja/issues/159)
- Make exit buttons of live view and events view consistent [\#158](https://github.com/pliablepixels/zmNinja/issues/158)
- Remove SSL cert requirement [\#157](https://github.com/pliablepixels/zmNinja/issues/157)
- Closing data leaks - trying to bottle up areas which may result in chrome keeping TCP connections open in background [\#155](https://github.com/pliablepixels/zmNinja/issues/155)
+- Introduce a montage timeline function [\#154](https://github.com/pliablepixels/zmNinja/issues/154)
- xcode fails on linking [\#153](https://github.com/pliablepixels/zmNinja/issues/153)
- installing ios-deploy ends with an error [\#152](https://github.com/pliablepixels/zmNinja/issues/152)
+- Addition Next frame/prev frame buttons when viewing event - for fine grained snapshot control. [\#150](https://github.com/pliablepixels/zmNinja/issues/150)
- Progress bar is ignored in Event View when playback is paused. [\#149](https://github.com/pliablepixels/zmNinja/issues/149)
+- Notification icon and sound - add ability to play default sounds [\#135](https://github.com/pliablepixels/zmNinja/issues/135)
## [v1.0.5](https://github.com/pliablepixels/zmNinja/tree/v1.0.5) (2016-01-23)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.0.3...v1.0.5)
-**Implemented enhancements:**
+**Closed issues:**
- Add ability to save a snapshot of an event playback to disk [\#148](https://github.com/pliablepixels/zmNinja/issues/148)
-
-**Fixed bugs:**
-
- 1.0.4 Broke basic auth [\#147](https://github.com/pliablepixels/zmNinja/issues/147)
-- Basic auth only - no zm auth - app goes to login on restart and says auth fails - app works [\#140](https://github.com/pliablepixels/zmNinja/issues/140)
-
-**Closed issues:**
-
- montage display wrap got messed up in newer versions of Chrome [\#146](https://github.com/pliablepixels/zmNinja/issues/146)
- Viewing events on slow connection basically doesn't work [\#145](https://github.com/pliablepixels/zmNinja/issues/145)
+- Basic auth only - no zm auth - app goes to login on restart and says auth fails - app works [\#140](https://github.com/pliablepixels/zmNinja/issues/140)
## [v1.0.3](https://github.com/pliablepixels/zmNinja/tree/v1.0.3) (2016-01-19)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.0.2...v1.0.3)
-**Implemented enhancements:**
+**Closed issues:**
- Allow montage to flow as columns \(packed\) or rows \(not packed\) [\#144](https://github.com/pliablepixels/zmNinja/issues/144)
-- Reduce android apk size [\#142](https://github.com/pliablepixels/zmNinja/issues/142)
-- Improve timeline performance [\#129](https://github.com/pliablepixels/zmNinja/issues/129)
-- For Android only: Allow an exit option in menu [\#128](https://github.com/pliablepixels/zmNinja/issues/128)
-- Implement a mechanism to detect when network is on/off [\#127](https://github.com/pliablepixels/zmNinja/issues/127)
-- Add support for Pan/Tilt/Zoom Presets [\#116](https://github.com/pliablepixels/zmNinja/issues/116)
-
-**Fixed bugs:**
-
- Monitor order is different one can observe in ZM montage [\#143](https://github.com/pliablepixels/zmNinja/issues/143)
-- You can swipe to dead monitor [\#138](https://github.com/pliablepixels/zmNinja/issues/138)
-- switching networks should trigger authentication [\#134](https://github.com/pliablepixels/zmNinja/issues/134)
-- Excessive background data usage [\#131](https://github.com/pliablepixels/zmNinja/issues/131)
-
-**Closed issues:**
-
+- Reduce android apk size [\#142](https://github.com/pliablepixels/zmNinja/issues/142)
- \[Log in Failed\] Checking if reCaptcha is enabled in zm.. [\#141](https://github.com/pliablepixels/zmNinja/issues/141)
- Swiping with ZMS is slower than swiping without zms [\#139](https://github.com/pliablepixels/zmNinja/issues/139)
+- You can swipe to dead monitor [\#138](https://github.com/pliablepixels/zmNinja/issues/138)
- Exit button on Android build [\#137](https://github.com/pliablepixels/zmNinja/issues/137)
- zmninja cannot talk to zmeventserver [\#136](https://github.com/pliablepixels/zmNinja/issues/136)
+- switching networks should trigger authentication [\#134](https://github.com/pliablepixels/zmNinja/issues/134)
- HTTP basic auth credentials not stored [\#132](https://github.com/pliablepixels/zmNinja/issues/132)
+- Excessive background data usage [\#131](https://github.com/pliablepixels/zmNinja/issues/131)
- Android build fails [\#130](https://github.com/pliablepixels/zmNinja/issues/130)
+- Improve timeline performance [\#129](https://github.com/pliablepixels/zmNinja/issues/129)
+- For Android only: Allow an exit option in menu [\#128](https://github.com/pliablepixels/zmNinja/issues/128)
+- Implement a mechanism to detect when network is on/off [\#127](https://github.com/pliablepixels/zmNinja/issues/127)
- \[DESKTOP\]\[QUESTION\] gconf [\#125](https://github.com/pliablepixels/zmNinja/issues/125)
- CSS montage - implement a better reflow algorithm [\#124](https://github.com/pliablepixels/zmNinja/issues/124)
+- Add support for Pan/Tilt/Zoom Presets [\#116](https://github.com/pliablepixels/zmNinja/issues/116)
- Auto upload successful build to testfairy [\#75](https://github.com/pliablepixels/zmNinja/issues/75)
- Integrate with Travis [\#72](https://github.com/pliablepixels/zmNinja/issues/72)
- When moving montage monitors around, remember to move the size [\#16](https://github.com/pliablepixels/zmNinja/issues/16)
@@ -1169,93 +1012,71 @@
## [v1.0.2](https://github.com/pliablepixels/zmNinja/tree/v1.0.2) (2015-12-28)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v1.0.1...v1.0.2)
-**Implemented enhancements:**
+**Closed issues:**
- Implement a way to only play alarmed frames [\#118](https://github.com/pliablepixels/zmNinja/issues/118)
## [v1.0.1](https://github.com/pliablepixels/zmNinja/tree/v1.0.1) (2015-12-27)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v0.87.3...v1.0.1)
-**Implemented enhancements:**
+**Closed issues:**
- Add an option to play at real FPS in single monitor view [\#123](https://github.com/pliablepixels/zmNinja/issues/123)
- Offer a server selection menu on app launch [\#122](https://github.com/pliablepixels/zmNinja/issues/122)
- Add a stop button to PTZ [\#121](https://github.com/pliablepixels/zmNinja/issues/121)
+- HTTP Basic authentication [\#120](https://github.com/pliablepixels/zmNinja/issues/120)
- Pack in the montage view better [\#119](https://github.com/pliablepixels/zmNinja/issues/119)
- Truncate monitor name in montage if size of image is less [\#117](https://github.com/pliablepixels/zmNinja/issues/117)
-
-**Fixed bugs:**
-
-- Developer setting for Frame Update allows decimals [\#114](https://github.com/pliablepixels/zmNinja/issues/114)
-
-**Closed issues:**
-
-- HTTP Basic authentication [\#120](https://github.com/pliablepixels/zmNinja/issues/120)
- Cannot get video [\#115](https://github.com/pliablepixels/zmNinja/issues/115)
+- Developer setting for Frame Update allows decimals [\#114](https://github.com/pliablepixels/zmNinja/issues/114)
## [v0.87.3](https://github.com/pliablepixels/zmNinja/tree/v0.87.3) (2015-12-15)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v0.87.2...v0.87.3)
-**Implemented enhancements:**
+**Closed issues:**
- Add ability to detect cgi-bin configuration issues \(experimental\) [\#110](https://github.com/pliablepixels/zmNinja/issues/110)
-- Allow 'show all/show alarmed' events to persist and show menu option in both Events and Timeline Views [\#108](https://github.com/pliablepixels/zmNinja/issues/108)
-- Make timeline items configurable instead of forcing 200 [\#104](https://github.com/pliablepixels/zmNinja/issues/104)
-
-**Fixed bugs:**
-
- popover "..." menu in event and timeline does not show in certain scenarios - so no menu [\#109](https://github.com/pliablepixels/zmNinja/issues/109)
+- Allow 'show all/show alarmed' events to persist and show menu option in both Events and Timeline Views [\#108](https://github.com/pliablepixels/zmNinja/issues/108)
- Disabling event server does not disable push notifications via APNS/GCM [\#107](https://github.com/pliablepixels/zmNinja/issues/107)
- Quick scrub on devices \(atleast iOS\) does not stop if you tap [\#106](https://github.com/pliablepixels/zmNinja/issues/106)
+- Timeline on v0.87.2 shows only motion events [\#105](https://github.com/pliablepixels/zmNinja/issues/105)
+- Make timeline items configurable instead of forcing 200 [\#104](https://github.com/pliablepixels/zmNinja/issues/104)
- Bulk frames are causing problems with the scrub bar positioning of alarmed frames [\#102](https://github.com/pliablepixels/zmNinja/issues/102)
- Gapless playback showing events from non-persisted monitors [\#86](https://github.com/pliablepixels/zmNinja/issues/86)
-**Closed issues:**
-
-- Timeline on v0.87.2 shows only motion events [\#105](https://github.com/pliablepixels/zmNinja/issues/105)
-
## [v0.87.2](https://github.com/pliablepixels/zmNinja/tree/v0.87.2) (2015-11-20)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v0.87...v0.87.2)
## [v0.87](https://github.com/pliablepixels/zmNinja/tree/v0.87) (2015-11-20)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v0.87.1...v0.87)
-**Fixed bugs:**
+**Closed issues:**
- Tap to load events on push notification is broken [\#103](https://github.com/pliablepixels/zmNinja/issues/103)
+- \[DESKTOP\] Timeline is UTC [\#101](https://github.com/pliablepixels/zmNinja/issues/101)
- Monitors in zmNinja should respect sequence of monitors in Zoneminder [\#100](https://github.com/pliablepixels/zmNinja/issues/100)
- SavetoPhone not working [\#99](https://github.com/pliablepixels/zmNinja/issues/99)
- 0.87.1 broke quick scrub thumbnail [\#98](https://github.com/pliablepixels/zmNinja/issues/98)
- \[DESKTOP\] Image scaling issues [\#90](https://github.com/pliablepixels/zmNinja/issues/90)
-
-**Closed issues:**
-
-- \[DESKTOP\] Timeline is UTC [\#101](https://github.com/pliablepixels/zmNinja/issues/101)
- \[DESKTOP\] Lift 200 last entries limit for timeline [\#88](https://github.com/pliablepixels/zmNinja/issues/88)
## [v0.87.1](https://github.com/pliablepixels/zmNinja/tree/v0.87.1) (2015-11-18)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v0.86...v0.87.1)
-**Implemented enhancements:**
-
-- Event page is overcrowded for mocord users - add option to show only alarmed frames [\#89](https://github.com/pliablepixels/zmNinja/issues/89)
-- Ability to specify multiple ZM servers and switch between them [\#83](https://github.com/pliablepixels/zmNinja/issues/83)
-- add per monitor 'alarmed' status indicator to montage view [\#82](https://github.com/pliablepixels/zmNinja/issues/82)
-
-**Fixed bugs:**
-
-- zmNinja adds cgi-bin on its own to cgi path. This is a problem for Centos [\#92](https://github.com/pliablepixels/zmNinja/issues/92)
-- Can't toggle gapless playback when viewing timeline events [\#85](https://github.com/pliablepixels/zmNinja/issues/85)
-- desktop app no video from timeline [\#70](https://github.com/pliablepixels/zmNinja/issues/70)
-
**Closed issues:**
- Breaking changes for this release: [\#97](https://github.com/pliablepixels/zmNinja/issues/97)
- Zoneminder specific notes for this release [\#96](https://github.com/pliablepixels/zmNinja/issues/96)
- Increase desktop limit of timeline to 2000 events instead of 200 [\#95](https://github.com/pliablepixels/zmNinja/issues/95)
- Implement daily version check for Desktop versions [\#94](https://github.com/pliablepixels/zmNinja/issues/94)
+- zmNinja adds cgi-bin on its own to cgi path. This is a problem for Centos [\#92](https://github.com/pliablepixels/zmNinja/issues/92)
+- Event page is overcrowded for mocord users - add option to show only alarmed frames [\#89](https://github.com/pliablepixels/zmNinja/issues/89)
- eliminate duplicate code between timeline and event control for footage mode [\#87](https://github.com/pliablepixels/zmNinja/issues/87)
+- Can't toggle gapless playback when viewing timeline events [\#85](https://github.com/pliablepixels/zmNinja/issues/85)
- Non-persisted monitors showing in timeline, events views [\#84](https://github.com/pliablepixels/zmNinja/issues/84)
+- Ability to specify multiple ZM servers and switch between them [\#83](https://github.com/pliablepixels/zmNinja/issues/83)
+- add per monitor 'alarmed' status indicator to montage view [\#82](https://github.com/pliablepixels/zmNinja/issues/82)
- Clean up persistent data storage mechanism [\#81](https://github.com/pliablepixels/zmNinja/issues/81)
- Remove external deps from codebase [\#80](https://github.com/pliablepixels/zmNinja/issues/80)
- Update .gitignore to support osx [\#78](https://github.com/pliablepixels/zmNinja/issues/78)
@@ -1263,6 +1084,7 @@
- add contributing guidelines [\#74](https://github.com/pliablepixels/zmNinja/issues/74)
- Add License [\#73](https://github.com/pliablepixels/zmNinja/issues/73)
- desktop app, can't export logs [\#71](https://github.com/pliablepixels/zmNinja/issues/71)
+- desktop app no video from timeline [\#70](https://github.com/pliablepixels/zmNinja/issues/70)
- make email logs work in desktop mode by opening default client [\#69](https://github.com/pliablepixels/zmNinja/issues/69)
- in quick scrub/footage mode - start playing without waiting for a tap [\#68](https://github.com/pliablepixels/zmNinja/issues/68)
- make mouse wheel work in desktop mode [\#67](https://github.com/pliablepixels/zmNinja/issues/67)
@@ -1275,87 +1097,64 @@
## [v0.86](https://github.com/pliablepixels/zmNinja/tree/v0.86) (2015-11-06)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v0.85...v0.86)
-**Implemented enhancements:**
+**Closed issues:**
+- If swiping is enabled, don't swipe if image is zoomed in -- causes pan/zoom conflicts [\#66](https://github.com/pliablepixels/zmNinja/issues/66)
+- getDiskStatus seems to be a performance bottleneck - disable for now in System State screen [\#65](https://github.com/pliablepixels/zmNinja/issues/65)
+- clean up non-reachable code during portal check [\#64](https://github.com/pliablepixels/zmNinja/issues/64)
+- Allow saving event videos to device. [\#63](https://github.com/pliablepixels/zmNinja/issues/63)
- Make Back button to exit from live view [\#61](https://github.com/pliablepixels/zmNinja/issues/61)
- ability to run all screens of zmNinja on a desktop without console errors [\#59](https://github.com/pliablepixels/zmNinja/issues/59)
- In playback mode, add the ability to swipe to the next event of whichever monitor has the next event and/or initiate gapless playback of same. [\#49](https://github.com/pliablepixels/zmNinja/issues/49)
- In playback mode, add the ability to swipe to the next event of the same monitor and/or initiate gapless playback. [\#48](https://github.com/pliablepixels/zmNinja/issues/48)
-
-**Fixed bugs:**
-
- tapping on events before they complete causes issues [\#44](https://github.com/pliablepixels/zmNinja/issues/44)
-**Closed issues:**
-
-- If swiping is enabled, don't swipe if image is zoomed in -- causes pan/zoom conflicts [\#66](https://github.com/pliablepixels/zmNinja/issues/66)
-- getDiskStatus seems to be a performance bottleneck - disable for now in System State screen [\#65](https://github.com/pliablepixels/zmNinja/issues/65)
-- clean up non-reachable code during portal check [\#64](https://github.com/pliablepixels/zmNinja/issues/64)
-
## [v0.85](https://github.com/pliablepixels/zmNinja/tree/v0.85) (2015-11-01)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v0.84...v0.85)
-**Implemented enhancements:**
+**Closed issues:**
- video branch support for zmNinja [\#60](https://github.com/pliablepixels/zmNinja/issues/60)
- changing servers requires reload of monitors - should be automatically done [\#58](https://github.com/pliablepixels/zmNinja/issues/58)
-
-**Fixed bugs:**
-
- fix version check - in one part of the code, I'm not doing a \>= check resulting in new ZM versions failing [\#57](https://github.com/pliablepixels/zmNinja/issues/57)
+- permissions on Android [\#56](https://github.com/pliablepixels/zmNinja/issues/56)
- notifications delivered while the app is running should also produce the same sound [\#55](https://github.com/pliablepixels/zmNinja/issues/55)
- iOS notifications are not showing style and sound options [\#54](https://github.com/pliablepixels/zmNinja/issues/54)
-**Closed issues:**
-
-- permissions on Android [\#56](https://github.com/pliablepixels/zmNinja/issues/56)
-
## [v0.84](https://github.com/pliablepixels/zmNinja/tree/v0.84) (2015-10-28)
[Full Changelog](https://github.com/pliablepixels/zmNinja/compare/v0.83...v0.84)
-**Implemented enhancements:**
+**Closed issues:**
- offer an option to force web sockets even if push is supported [\#53](https://github.com/pliablepixels/zmNinja/issues/53)
-- customize screen to load on push notification tap [\#47](https://github.com/pliablepixels/zmNinja/issues/47)
-
-**Fixed bugs:**
-
- Ssl toggle and https in login [\#52](https://github.com/pliablepixels/zmNinja/issues/52)
- Swiping to the left should reveal next monitor, not prev monitor \(seen on iOS 9\) [\#51](https://github.com/pliablepixels/zmNinja/issues/51)
- rev 0.83, event icon is a solid block [\#50](https://github.com/pliablepixels/zmNinja/issues/50)
+- customize screen to load on push notification tap [\#47](https://github.com/pliablepixels/zmNinja/issues/47)
- Monitor view: events not showing for deselected monitors \(and should since the goal in monitor view is to see all monitors which would include their events\). [\#46](https://github.com/pliablepixels/zmNinja/issues/46)
- Montage view: swipe shows deselected monitors \(and should not\). [\#45](https://github.com/pliablepixels/zmNinja/issues/45)
- Timeline more menu bonked again [\#43](https://github.com/pliablepixels/zmNinja/issues/43)
-
-**Closed issues:**
-
- custom range dates shown even if pullup overwrites them [\#37](https://github.com/pliablepixels/zmNinja/issues/37)
- Latest Events panel doesn't initialize correctly on first use. [\#36](https://github.com/pliablepixels/zmNinja/issues/36)
- Android client: System Status view returns HTTP error [\#32](https://github.com/pliablepixels/zmNinja/issues/32)
- app causes ZM crash/bad behavior after it's been asleep for a while [\#30](https://github.com/pliablepixels/zmNinja/issues/30)
## [v0.83](https://github.com/pliablepixels/zmNinja/tree/v0.83) (2015-10-24)
-**Implemented enhancements:**
+**Closed issues:**
- ability to restrict monitors in all views - depending on some global selection [\#42](https://github.com/pliablepixels/zmNinja/issues/42)
- make it optional to swipe between live view of monitors [\#41](https://github.com/pliablepixels/zmNinja/issues/41)
-- review security approach - switch to auth token instead of passing u+p in url [\#2](https://github.com/pliablepixels/zmNinja/issues/2)
-
-**Fixed bugs:**
-
- if apis can't be reached the app assumes version is 0.0.0 and moves app to low version screen [\#40](https://github.com/pliablepixels/zmNinja/issues/40)
- Check multiple web sockets created in android -- seems old web sockets don't get deleted [\#39](https://github.com/pliablepixels/zmNinja/issues/39)
-- Background mode: Popover menus stick around [\#33](https://github.com/pliablepixels/zmNinja/issues/33)
-
-**Closed issues:**
-
- Monitor change makes enabled 0 [\#38](https://github.com/pliablepixels/zmNinja/issues/38)
- Restarting ZM in state control results in client freezing [\#35](https://github.com/pliablepixels/zmNinja/issues/35)
- radial menu is broken [\#34](https://github.com/pliablepixels/zmNinja/issues/34)
+- Background mode: Popover menus stick around [\#33](https://github.com/pliablepixels/zmNinja/issues/33)
- monitor buttons to navigate can overlap exit,zoom,refresh buttons [\#31](https://github.com/pliablepixels/zmNinja/issues/31)
- pinch zoom on monitor too sensitive, detects false swipes [\#29](https://github.com/pliablepixels/zmNinja/issues/29)
- Montage re-order does not work with large list of monitors [\#28](https://github.com/pliablepixels/zmNinja/issues/28)
- investigate when timeline barfs with a "no parent" error [\#27](https://github.com/pliablepixels/zmNinja/issues/27)
+- app gets into weird state that prevents timeline from populating and syslog goes nuts from montage [\#26](https://github.com/pliablepixels/zmNinja/issues/26)
- zmNinja should give a useful warning when the API is non-functional [\#25](https://github.com/pliablepixels/zmNinja/issues/25)
- apk Download of zmNinja [\#22](https://github.com/pliablepixels/zmNinja/issues/22)
- Add destroy to each view and cancel all view timers again there just to make sure [\#21](https://github.com/pliablepixels/zmNinja/issues/21)
@@ -1374,6 +1173,7 @@
- When images are loaded over a slow connection, there is a white screen till it loads [\#6](https://github.com/pliablepixels/zmNinja/issues/6)
- handle situations when zms does not respond to your commands for a while [\#5](https://github.com/pliablepixels/zmNinja/issues/5)
- test product on Android - make sure all plugins work etc. [\#4](https://github.com/pliablepixels/zmNinja/issues/4)
+- review security approach - switch to auth token instead of passing u+p in url [\#2](https://github.com/pliablepixels/zmNinja/issues/2)
- we are only retrieving the first page of events - need to fix it to get all [\#1](https://github.com/pliablepixels/zmNinja/issues/1)
**Merged pull requests:**
@@ -1383,4 +1183,4 @@
-\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
+\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file
diff --git a/GoogleService-Info.plist b/GoogleService-Info.plist
index eb3a19e2..bbdb0546 100644
--- a/GoogleService-Info.plist
+++ b/GoogleService-Info.plist
@@ -23,7 +23,7 @@
<key>STORAGE_BUCKET</key>
<string>ninja-1105.appspot.com</string>
<key>IS_ADS_ENABLED</key>
- <true></true>
+ <false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
@@ -37,4 +37,4 @@
<key>DATABASE_URL</key>
<string>https://ninja-1105.firebaseio.com</string>
</dict>
-</plist> \ No newline at end of file
+</plist>
diff --git a/bower.json b/bower.json
index 8079f1af..db6aad91 100644
--- a/bower.json
+++ b/bower.json
@@ -32,7 +32,6 @@
"angular-ui-router": "0.2.13",
"angular-wizard": "~0.6.1",
"crypto-js": "~3.1.6",
- "filelogger": "~1.3.0",
"font-awesome": "~4.3.0",
"ion-datetime-picker": "~0.1.1",
"ionic-native-transitions": "shprink/ionic-native-transitions#~1.0.2",
@@ -48,7 +47,8 @@
"videogular-themes-default": "~1.4.4",
"vis": "~4.20.0",
"holderjs": "^2.9.4",
- "localforage": "^1.7.1"
+ "localforage": "^1.7.1",
+ "filelogger": "^1.3.2"
},
"resolutions": {
"angular-sanitize": "1.5.3",
diff --git a/build_android.sh b/build_android.sh
index 0eb723c5..65d14676 100755
--- a/build_android.sh
+++ b/build_android.sh
@@ -1,10 +1,14 @@
#!/bin/bash
+ ./electron_js/sync_versions.sh
+
APPVER=`cat config.xml | grep "widget " | sed 's/.* version=\"\([^\"]*\)\" xmlns.*/\1/'`
# multipleApk adds 2 and 4 in Xwalk builds for arm and x86 respectively
ver_pre5=${APPVER//.}
ver=${APPVER//.}9
+ echo "About to build version: $APPVER"
+ read -p "Press any key..."
# App signining credentials in this file
NINJAKEYSTORE=~/Desktop/zmNinja.keystore
@@ -13,23 +17,9 @@ if [ ! -f "$NINJAKEYSTORE" ]; then
exit
fi
-rm -f release_files 2>/dev/null
+rm -rf release_files 2>/dev/null
mkdir release_files
-# no arguments - build both
-# 1 == build crosswalk only
-# 2 == build native only
-BUILD_MODE="all"
-if [ "$1" = "1" ]; then
- BUILD_MODE="xwalk"
- echo "only building crosswalk"
-fi
-
-if [ "$1" = "2" ]; then
- BUILD_MODE="native"
- echo "only building native view (5+)"
-fi
-
echo "----------> Only building native. Not building crosswalk anymore due to compatibility issues <----------------------"
BUILD_MODE="native"
@@ -39,7 +29,7 @@ if [ "$BUILD_MODE" = "native" ] || [ "$BUILD_MODE" = "all" ]; then
echo "${ver}: Building Release mode for android 5+..."
echo "--------------------------------------------"
-# No longger needed as we are not supporting Xwalk
+# No longer needed as we are not supporting Xwalk
# echo "Removing android and re-adding..."
# cordova platform remove android
# cordova platform add android@6.4.0
diff --git a/build_ios.sh b/build_ios.sh
index cbd66b34..f9042358 100755
--- a/build_ios.sh
+++ b/build_ios.sh
@@ -9,3 +9,6 @@ echo "see https://forum.ionicframework.com/t/how-to-build-ionic-cordova-with-xco
echo "-- building --"
ionic cordova build ios --release --buildConfig="./build-auto.json"
+
+echo "********* Done *************"
+echo "Make sure you are using Legacy build in XCode (File->Workspace) or push/etc may stop working"
diff --git a/config.xml b/config.xml
index ab9eb243..a119d5ea 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.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">
+<widget android-packageName="com.pliablepixels.zmninja_pro" id="com.pliablepixels.zmninja_pro" ios-CFBundleIdentifier="com.pliablepixels.zmninja-pro" version="1.3.029" 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
@@ -143,11 +143,8 @@
<plugin name="phonegap-plugin-mobile-accessibility" spec="^1.0.5" />
<plugin name="cordova-plugin-touch-id" spec="^3.2.0" />
<plugin name="cordova-plugin-android-fingerprint-auth" spec="^1.4.0" />
- <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-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" />
@@ -167,6 +164,9 @@
<variable name="ANDROID_SUPPORT_ANNOTATIONS_VERSION" value="27.+" />
</plugin>
<plugin name="cordova-plugin-advanced-websocket" spec="^1.1.3" />
+ <plugin name="cordova-plugin-network-information" spec="^2.0.1" />
+ <plugin name="cordova-plugin-x-socialsharing" spec="^5.4.1" />
+ <plugin name="cordova-plugin-media-pp-fork" spec="^1.0.2-dev" />
<engine name="android" spec="^6.4.0" />
<engine name="ios" spec="~4.5.5" />
</widget>
diff --git a/package.json b/package.json
index 95216464..1dd678a8 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "zmninjapro",
"description": "Home security mobile app for ZoneMinder",
- "version": "1.3.026",
+ "version": "1.3.029",
"displayName": "zmNinja",
"author": "Pliable Pixels",
"license": "custom see LICENSE.md",
@@ -33,8 +33,6 @@
"cordova-plugin-network-information": {},
"cordova-plugin-device": {},
"cordova-plugin-file": {},
- "cordova-plugin-media-pp-fork": {},
- "cordova-plugin-email": {},
"cordova-plugin-statusbar": {},
"cordova-library-helper-pp-fork": {},
"cordova-plugin-multi-window": {},
@@ -53,7 +51,9 @@
"cordova-plugin-ionic-webview": {
"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
},
- "cordova-plugin-advanced-websocket": {}
+ "cordova-plugin-advanced-websocket": {},
+ "cordova-plugin-x-socialsharing": {},
+ "cordova-plugin-media-pp-fork": {}
}
},
"dependencies": {
@@ -70,7 +70,6 @@
"cordova-plugin-cloud-settings": "^1.0.4",
"cordova-plugin-customurlscheme": "^4.3.0",
"cordova-plugin-device": "^2.0.1",
- "cordova-plugin-email": "^1.2.7",
"cordova-plugin-file": "^6.0.1",
"cordova-plugin-file-transfer": "^1.7.1",
"cordova-plugin-globalization": "^1.0.7",
@@ -90,9 +89,11 @@
"cordova-plugin-touch-id": "^3.2.0",
"cordova-plugin-websocket": "^0.12.2",
"cordova-plugin-whitelist": "^1.3.2",
+ "cordova-plugin-x-socialsharing": "^5.4.1",
"cordova-sqlite-storage": "^1.5.3",
"deep-equal": "^1.0.1",
"electron-window-state": "^4.1.1",
+ "es6-promise-plugin": "^4.2.2",
"jsonfile": "^4.0.0",
"keypress": "^0.2.1",
"menu": "^0.2.5",
@@ -175,4 +176,4 @@
]
}
}
-}
+} \ No newline at end of file
diff --git a/resources/ios/icon/icon-1024.png b/resources/ios/icon/icon-1024.png
index 8ce1f586..aa50eac9 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 992e4347..9e97d84f 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 88e9093f..02894e98 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 0eb2d14f..788fe95d 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 cb772e83..8a91b961 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 03ee7ed4..8e6364c2 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 74f726ca..a174521c 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 0eb2d14f..788fe95d 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 7574996d..0826397a 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 a2d820df..2901e9c5 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 3338ca7f..85e03aba 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 133f22f2..48108537 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 cc8edd0a..c24a1fb8 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 fb75f8f9..cefa818d 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 79cd46a1..646dfc2e 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 8251efd0..19e512ba 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 46c34cc5..a0f103b8 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 742116e2..19520dae 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 6eb4742d..b861fb45 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 b987bfaa..adde94a5 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 ba037c77..07cb296d 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 456327ee..5711fb71 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 ba79a715..44400b52 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 9000638f..f74ec44a 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 5ed46f67..25fd38a3 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 bc6d1502..2c638236 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 39f7f9de..edb3790f 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 e0685076..8b84094c 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 df205911..92cc0a9e 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 5fde545a..4256914f 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 77108330..14f10bd9 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 0a72e96b..0ae96272 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 2d8650d7..3c12a932 100644
--- a/www/css/style.css
+++ b/www/css/style.css
@@ -810,7 +810,7 @@ progress[aria-valuenow]:before {
}
.list .item.item-accordion {
- line-height: 200px;
+ line-height: 100%;
padding-top: 0;
padding-bottom: 0;
transition: 3s all linear;
diff --git a/www/index.html b/www/index.html
index 7aa77593..97db02aa 100644
--- a/www/index.html
+++ b/www/index.html
@@ -66,6 +66,8 @@
<script src="lib/ng-mfb/src/mfb-directive.js"></script>
<script src="lib/angular-touch/angular-touch.min.js"></script>
<script src="lib/holderjs/holder.min.js"></script>
+ <script src="lib/angular-cookies/angular-cookies.min.js"></script>
+
diff --git a/www/js/DataModel.js b/www/js/DataModel.js
index 6dbd5958..3e5f41c1 100644
--- a/www/js/DataModel.js
+++ b/www/js/DataModel.js
@@ -20,7 +20,7 @@ angular.module('zmApp.controllers')
DO NOT TOUCH zmAppVersion
It is changed by sync_version.sh
*/
- var zmAppVersion = "1.3.026";
+ var zmAppVersion = "1.3.029";
var isBackground = false;
var justResumed = false;
var timeSinceResumed = -1;
@@ -408,7 +408,7 @@ angular.module('zmApp.controllers')
var as = 'undefined';
- if (!mid && monitors.length > 0) {
+ if (!mid && monitors && monitors.length > 0) {
mid = monitors[0].Monitor.Id;
}
@@ -675,6 +675,67 @@ angular.module('zmApp.controllers')
debug(val);
},
+ evaluateTappedNotification: function() {
+
+ var state = "";
+ var stateParams1 = {};
+ var stateParams2 = {};
+
+ debug ("Inside evaluateNotifications");
+
+ if ($rootScope.tappedNotification == 2) { // url launch
+ debug("Came via app url launch with mid=" + $rootScope.tappedMid);
+ debug("Came via app url launch with eid=" + $rootScope.tappedEid);
+
+
+ if (parseInt($rootScope.tappedMid) > 0) {
+ debug("Going to live view ");
+ state = "app.monitors";
+
+ } else if (parseInt($rootScope.tappedEid) > 0) {
+ debug("Going to events with EID=" + $rootScope.tappedEid);
+ state = "app.events";
+ stateParams1 = {
+ "id": 0,
+ "playEvent": true
+ };
+ stateParams2 = {
+ reload: true
+ };
+
+ }
+
+
+ } // 2
+ else if ($rootScope.tappedNotification == 1) // push
+ {
+
+
+ debug("Came via push tap. onTapScreen=" + loginData.onTapScreen);
+ if (loginData.onTapScreen == $translate.instant('kTapMontage')) {
+ debug("Going to montage");
+ state = "app.montage";
+
+
+ } else if (loginData.onTapScreen == $translate.instant('kTapEvents')) {
+ debug("Going to events");
+ state = "app.events";
+ stateParams1 = {
+ "id": 0,
+ "playEvent": true
+ };
+
+ } else // we go to live
+ {
+ debug("Going to live view ");
+ state = "app.monitors";
+
+ }
+ }
+ $rootScope.tappedNotification = 0;
+ return [state, stateParams1, stateParams2];
+ },
+
setLastUpdateCheck: function (val) {
lastUpdateCheck = val;
localforage.setItem("lastUpdateCheck", lastUpdateCheck);
@@ -703,13 +764,7 @@ angular.module('zmApp.controllers')
// the ZM authors fix this and streamline the access of images
// from APIs, I don't have an option
- zmStateGo: function (state, p1, p2) {
- if ($rootScope.platformOS == 'desktop')
- $state.go(state, p1, p2);
- else
- $state.go(state, p1, p2);
- // $ionicNativeTransitions.stateGo(state, p1, p2);
- },
+
// used when an empty server profile is created
getDefaultLoginObject: function () {
@@ -912,8 +967,8 @@ angular.module('zmApp.controllers')
if (exists) {
log("A cloud configuration has been found");
window.cordova.plugin.cloudsettings.load(function (cloudData) {
- console.log("CLOUD DATA FOUND" + JSON.stringify(cloudData));
- debug("Cloud data retrieved is:" + JSON.stringify(cloudData));
+ //console.log("CLOUD DATA FOUND" + JSON.stringify(cloudData));
+ // debug("Cloud data retrieved is:" + JSON.stringify(cloudData));
if (cloudData && cloudData.defaultServerName && cloudData.serverGroupList) {
log("retrieved a valid cloud config with a defaultServerName of:" + cloudData.defaultServerName);
log("replacing local DB with cloud...");
@@ -1148,7 +1203,7 @@ angular.module('zmApp.controllers')
if (typeof loginData.disableSimulStreaming == 'undefined') {
- loginData.disableSimulStreaming = ($rootScope.platformOS == 'ios') ? true : false;
+ loginData.disableSimulStreaming = false;
//console.log("INIT DISABLING SIMUL:" + loginData.disableSimulStreaming);
}
@@ -1364,7 +1419,7 @@ angular.module('zmApp.controllers')
loginData.enableSlowLoading = false;
}
- log("SlowDelay is: " + loginData.enableSlowLoading);
+
if (typeof loginData.enableStrictSSL == 'undefined') {
@@ -1830,7 +1885,7 @@ angular.module('zmApp.controllers')
if (forceReload == 1 || configParams.ZM_EVENT_IMAGE_DIGITS == '-1') {
var apiurl = loginData.apiurl;
var myurl = apiurl + '/configs/viewByName/ZM_EVENT_IMAGE_DIGITS.json';
- debug("Config URL for digits is:" + myurl);
+ //debug("Config URL for digits is:" + myurl);
$http.get(myurl)
.then(function (data) {
data = data.data;
@@ -1848,8 +1903,8 @@ angular.module('zmApp.controllers')
return (d.promise);
});
} else {
- log("ZM_EVENT_IMAGE_DIGITS is already configured for " +
- configParams.ZM_EVENT_IMAGE_DIGITS);
+ // log("ZM_EVENT_IMAGE_DIGITS is already configured for " +
+ // configParams.ZM_EVENT_IMAGE_DIGITS);
d.resolve(configParams.ZM_EVENT_IMAGE_DIGITS);
return (d.promise);
}
@@ -1925,11 +1980,11 @@ angular.module('zmApp.controllers')
return $http.get(req + "&command=1")
.then(
function (s) {
- debug("pause success for ck:" + ck + " with:" + JSON.stringify(s));
+ // debug("pause success for ck:" + ck );
},
function (e) {
- debug("pause success for ck:" + ck + " with:" + JSON.stringify(e));
+ // debug("pause error for ck:" + ck + " with:" + JSON.stringify(e));
}
);
@@ -1949,11 +2004,11 @@ angular.module('zmApp.controllers')
return $http.get(req + "&command=2")
.then(
function (s) {
- debug("play success for ck:" + ck + " with:" + JSON.stringify(s));
+ // debug("play success for ck:" + ck + " with:" + JSON.stringify(s));
},
function (e) {
- debug("play success for ck:" + ck + " with:" + JSON.stringify(e));
+ // debug("play error for ck:" + ck + " with:" + JSON.stringify(e));
}
);
@@ -2026,6 +2081,29 @@ angular.module('zmApp.controllers')
},*/
+ getMultiServersCached: function () {
+ return multiservers;
+ },
+
+ // use non cached for daemon status
+ getMultiServers: function () {
+ return $http.get (loginData.apiurl+'/servers.json');
+
+ },
+
+ getMultiServer: function (id) {
+
+ var ndx = -1;
+ for (var i=0; i < multiservers.length; i++) {
+ if (multiservers[i].Server.Id == id) {
+ ndx = i;
+ break;
+ }
+ }
+ return ndx == -1 ? {}:multiservers[ndx];
+
+ },
+
regenConnKeys: function () {
debug("DataModel: Regenerating connkeys...");
@@ -2067,7 +2145,7 @@ angular.module('zmApp.controllers')
.then(function (data) {
// console.log("HTTP success got " + JSON.stringify(data.monitors));
data = data.data;
- monitors = data.monitors;
+ if (data.monitors) monitors = data.monitors;
if ($rootScope.authSession == 'undefined') {
@@ -2089,7 +2167,7 @@ angular.module('zmApp.controllers')
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));
+ log("multi server list loaded:" + JSON.stringify(data));
multiservers = data.servers;
var multiserver_scheme = "http://";
@@ -2103,6 +2181,8 @@ angular.module('zmApp.controllers')
for (var i = 0; i < monitors.length; i++) {
// make them all show for now
+
+
monitors[i].Monitor.listDisplay = 'show';
monitors[i].Monitor.isAlarmed = false;
monitors[i].Monitor.connKey = (Math.floor((Math.random() * 999999) + 1)).toString();
@@ -2123,15 +2203,16 @@ angular.module('zmApp.controllers')
multiservers[j].Server.Hostname = multiserver_scheme + multiservers[j].Server.Hostname;
}
- debug("Monitor " + monitors[i].Monitor.Id + " has a recording server hostname of " + multiservers[j].Server.Hostname);
+ // debug("Monitor " + monitors[i].Monitor.Id + " has a recording server hostname of " + multiservers[j].Server.Hostname);
// Now here is the logic, I need to retrieve serverhostname,
// and slap on the host protocol and path. Meh.
- var p = URI.parse(loginData.streamingurl);
- var s = URI.parse(multiservers[j].Server.Hostname);
+ var s = URI.parse(loginData.streamingurl);
+ var m = URI.parse(multiservers[j].Server.Hostname);
+ var p = URI.parse(loginData.url);
/* if (!p.port && !isNaN(p.path)) {
debug ("Portal: port path reversed?");
@@ -2148,31 +2229,33 @@ angular.module('zmApp.controllers')
}
*/
- debug("recording server parsed is " + JSON.stringify(s));
+ debug("recording server reported is " + JSON.stringify(m));
debug("portal parsed is " + JSON.stringify(p));
+ debug("streaming url parsed is " + JSON.stringify(s));
+ debug ("multi-port is:"+zmsPort);
var st = "";
var baseurl = "";
var streamingurl = "";
- st += (s.scheme ? s.scheme : p.scheme) + "://"; // server scheme overrides
+ st += (m.scheme ? m.scheme : p.scheme) + "://"; // server scheme overrides
// if server doesn't have a protocol, what we want is in path
- if (!s.host) {
- s.host = s.path;
- s.path = undefined;
+ if (!m.host) {
+ m.host = m.path;
+ m.path = undefined;
}
- st += s.host;
+ st += m.host;
//console.log ("STEP 1: ST="+st);
if (zmsPort <= 0 || loginData.disableSimulStreaming) {
- if (p.port || s.port) {
- st += (s.port ? ":" + s.port : ":" + p.port);
+ if (p.port || m.port) {
+ st += (m.port ? ":" + m.port : ":" + p.port);
streamingurl = st;
//console.log ("STEP 2 no ZMS: ST="+st);
@@ -2180,17 +2263,19 @@ angular.module('zmApp.controllers')
} else {
var sport = parseInt(zmsPort) + parseInt(monitors[i].Monitor.Id);
- streamingurl = st + ':' + sport;
+ st = st + ':' + sport;
- if (p.port || s.port)
- st += (s.port ? ":" + s.port : ":" + p.port);
+ if (p.port || m.port)
+ st += (m.port ? ":" + m.port : ":" + p.port);
//console.log ("STEP 2: ST="+st);
}
baseurl = st;
+
controlURL = st;
+ controlURL += (p.path ? p.path:'');
st += (s.path ? s.path : p.path);
streamingurl += (s.path ? s.path : p.path);
@@ -2203,6 +2288,9 @@ angular.module('zmApp.controllers')
monitors[i].Monitor.streamingURL = st;
monitors[i].Monitor.baseURL = baseurl;
monitors[i].Monitor.controlURL = controlURL;
+
+
+ debug ("Storing baseurl="+baseurl+" streamingURL="+st+" recordingURL="+controlURL);
//console.log ("** Streaming="+st+" **base="+baseurl);
// starting 1.30 we have fid=xxx mode to return images
monitors[i].Monitor.imageMode = (versionCompare($rootScope.apiVersion, "1.30") == -1) ? "path" : "fid";
@@ -2213,11 +2301,13 @@ angular.module('zmApp.controllers')
} else {
//monitors[i].Monitor.listDisplay = 'show';
+ debug ("No servers matched, filling defaults...");
monitors[i].Monitor.isAlarmed = false;
monitors[i].Monitor.connKey = (Math.floor((Math.random() * 999999) + 1)).toString();
monitors[i].Monitor.rndKey = (Math.floor((Math.random() * 999999) + 1)).toString();
var st2 = loginData.streamingurl;
+ controlURL = loginData.url;
if (zmsPort > 0 && !loginData.disableSimulStreaming) {
// we need to insert minport
@@ -2239,6 +2329,8 @@ angular.module('zmApp.controllers')
if (p3.path) controlURL += p3.path;
}
+ debug ("Storing streaming="+st2+" recording="+controlURL);
+
monitors[i].Monitor.streamingURL = st2;
monitors[i].Monitor.controlURL = controlURL;
//debug ("Streaming URL for Monitor " + monitors[i].Monitor.Id + " is " + monitors[i].Monitor.streamingURL );
@@ -2246,13 +2338,7 @@ angular.module('zmApp.controllers')
monitors[i].Monitor.baseURL = loginData.url;
monitors[i].Monitor.imageMode = (versionCompare($rootScope.apiVersion, "1.30") == -1) ? "path" : "fid";
- // but now check if forced path
- if (loginData.forceImageModePath) {
- debug("Overriding, setting image mode to true as you have requested force enable");
- monitors[i].Monitor.imageMode = 'path';
- }
-
- // debug("API " + $rootScope.apiVersion + ": Monitor " + monitors[i].Monitor.Id + " will use " + monitors[i].Monitor.imageMode + " for direct image access");
+
}
}
// now get packery hide if applicable
@@ -2347,7 +2433,7 @@ angular.module('zmApp.controllers')
var succ;
try {
- console.log(textsucc);
+ //console.log(textsucc);
succ = JSON.parse(textsucc.data);
if (succ.data) succ = succ.data;
if (succ.config) {
@@ -2849,6 +2935,20 @@ angular.module('zmApp.controllers')
},
+
+ getRecordingURL: function (id) {
+ var idnum = parseInt(id);
+ for (var i = 0; i < monitors.length; i++) {
+ if (parseInt(monitors[i].Monitor.Id) == idnum) {
+ // console.log ("Matched, exiting getMonitorname");
+ //console.log ("!!!"+monitors[i].Monitor.controlURL);
+ return monitors[i].Monitor.controlURL;
+ }
+
+ }
+ return "(Unknown)";
+ },
+
getBaseURL: function (id) {
var idnum = parseInt(id);
for (var i = 0; i < monitors.length; i++) {
@@ -2876,7 +2976,7 @@ angular.module('zmApp.controllers')
$rootScope.authSession = "undefined";
- console.log("CURRENT SERVER: " + loginData.currentServerVersion);
+ // console.log("CURRENT SERVER: " + loginData.currentServerVersion);
if (loginData.currentServerVersion && (versionCompare(loginData.currentServerVersion, zm.versionWithLoginAPI) != -1 || loginData.loginAPISupported)) {
diff --git a/www/js/DevOptionsCtrl.js b/www/js/DevOptionsCtrl.js
index dab4570b..1e194fab 100644
--- a/www/js/DevOptionsCtrl.js
+++ b/www/js/DevOptionsCtrl.js
@@ -10,6 +10,7 @@ angular.module('zmApp.controllers').controller('zmApp.DevOptionsCtrl', ['$scope'
};
+
//----------------------------------------------------------------
// Alarm notification handling
//----------------------------------------------------------------
@@ -47,6 +48,19 @@ angular.module('zmApp.controllers').controller('zmApp.DevOptionsCtrl', ['$scope'
// state, that effectively overwrites current view power management needs
//------------------------------------------------------------------------
$scope.$on('$ionicView.beforeEnter', function () {
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> DevOptionsCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+
+
//console.log("**VIEW ** DevOptions Ctrl Entered");
$scope.loginData = NVRDataModel.getLogin();
console.log("DEV LOGS=" + $scope.loginData.enableLogs);
diff --git a/www/js/EventCtrl.js b/www/js/EventCtrl.js
index 90b615a2..66ff6463 100644
--- a/www/js/EventCtrl.js
+++ b/www/js/EventCtrl.js
@@ -32,7 +32,7 @@ angular.module('zmApp.controllers')
})
- .controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'carouselUtils', '$translate', '$cordovaFileTransfer', '$cordovaFile', '$ionicListDelegate', 'ionPullUpFooterState', function ($scope, $rootScope, zm, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, carouselUtils, $translate, $cordovaFileTransfer, $cordovaFile, $ionicListDelegate, ionPullUpFooterState) {
+ .controller('zmApp.EventCtrl', ['$scope', '$rootScope', 'zm', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', '$ionicSlideBoxDelegate', '$ionicPosition', '$ionicPopover', '$ionicPopup', 'EventServer', '$sce', '$cordovaBadge', '$cordovaLocalNotification', '$q', 'carouselUtils', '$translate', '$cordovaFileTransfer', '$cordovaFile', '$ionicListDelegate', 'ionPullUpFooterState', 'SecuredPopups', function ($scope, $rootScope, zm, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, $ionicSlideBoxDelegate, $ionicPosition, $ionicPopover, $ionicPopup, EventServer, $sce, $cordovaBadge, $cordovaLocalNotification, $q, carouselUtils, $translate, $cordovaFileTransfer, $cordovaFile, $ionicListDelegate, ionPullUpFooterState,SecuredPopups) {
// events in last 5 minutes
// TODO https://server/zm/api/events/consoleEvents/5%20minute.json
@@ -71,6 +71,9 @@ angular.module('zmApp.controllers')
// initial code
//---------------------------------------------------
+
+
+
//we come here is TZ is updated after the view loads
var tzu = $scope.$on('tz-updated', function () {
$scope.tzAbbr = NVRDataModel.getTimeZoneNow();
@@ -90,7 +93,7 @@ angular.module('zmApp.controllers')
//
window.addEventListener("resize", recomputeThumbSize, false);
$ionicListDelegate.canSwipeItems(true);
- NVRDataModel.debug("enabling options swipe");
+ // NVRDataModel.debug("enabling options swipe");
// see if we come from monitors, if so, don't filter events
if ($ionicHistory.backTitle() == 'Monitors') {
@@ -115,8 +118,8 @@ angular.module('zmApp.controllers')
footerExpand();
// now do event playback if asked
- if (parseInt($rootScope.tappedEid) > 0) {
- NVRDataModel.debug(" Trying ot live play " + $rootScope.tappedEid);
+ if (parseInt($rootScope.tappedEid) > 0 && $stateParams.playEvent == 'true') {
+ NVRDataModel.debug(" Trying to play event due to push:" + $rootScope.tappedEid);
playSpecificEvent($rootScope.tappedEid);
}
@@ -137,7 +140,7 @@ angular.module('zmApp.controllers')
};
$scope.event = event;
$scope.currentEvent = event;
- openModal(event);
+ openModal(event, 'enabled');
}
@@ -146,9 +149,9 @@ angular.module('zmApp.controllers')
NVRDataModel.debug("EventCtrl: Deregistering resize listener");
window.removeEventListener("resize", recomputeThumbSize, false);
- NVRDataModel.debug("EventCtrl: Deregistering broadcast handles");
+ //NVRDataModel.debug("EventCtrl: Deregistering broadcast handles");
for (var i = 0; i < broadcastHandles.length; i++) {
- // broadcastHandles[i]();
+ // broadcastHandles[i]();
}
broadcastHandles = [];
});
@@ -158,6 +161,21 @@ angular.module('zmApp.controllers')
//console.log ("********* BEFORE ENTER");
//
+ $scope.mid = '';
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> EventCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $scope.mid = $rootScope.tappedMid;
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+
+
$scope.modalData = {
"doRefresh": false
};
@@ -192,7 +210,7 @@ angular.module('zmApp.controllers')
if (NVRDataModel.getLogin().enableThumbs) {
- NVRDataModel.debug("--> thumbnail means increasing row size");
+ // NVRDataModel.debug("--> thumbnail means increasing row size");
eventsListScrubHeight = 370;
eventsListDetailsHeight = 330;
@@ -427,19 +445,18 @@ angular.module('zmApp.controllers')
myevents[i].Event.humanizeTime = humanizeTime(myevents[i].Event.StartTime);
myevents[i].Event.streamingURL = NVRDataModel.getStreamingURL(myevents[i].Event.MonitorId);
- myevents[i].Event.baseURL = NVRDataModel.getBaseURL(myevents[i].Event.MonitorId);
+ myevents[i].Event.recordingURL = NVRDataModel.getRecordingURL(myevents[i].Event.MonitorId);
myevents[i].Event.imageMode = NVRDataModel.getImageMode(myevents[i].Event.MonitorId);
//console.log ("***** MULTISERVER STREAMING URL FOR EVENTS " + myevents[i].Event.streamingURL);
- // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.baseURL);
+ // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.recordingURL);
myevents[i].Event.MonitorName = NVRDataModel.getMonitorName(myevents[i].Event.MonitorId);
myevents[i].Event.ShowScrub = false;
myevents[i].Event.height = eventsListDetailsHeight;
// now construct base path
- myevents[i].Event.BasePath = computeBasePath(myevents[i]);
- myevents[i].Event.relativePath = computeRelativePath(myevents[i]);
+
// get thumbW/H
@@ -459,18 +476,11 @@ angular.module('zmApp.controllers')
// in multiserver BasePath is login url for frames
// http://login.url/index.php?view=frame&eid=19696772&fid=21
- // console.log ("COMPARING "+NVRDataModel.getLogin().url+ " TO " +myevents[i].Event.baseURL);
- if (NVRDataModel.getLogin().url != myevents[i].Event.baseURL) {
- //NVRDataModel.debug ("Multi server, changing base");
- myevents[i].Event.baseURL = NVRDataModel.getLogin().url;
-
- }
+ // console.log ("COMPARING "+NVRDataModel.getLogin().url+ " TO " +myevents[i].Event.recordingURL);
+
- if (myevents[i].Event.imageMode == 'path')
- //if (1)
- myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/events/" + myevents[i].Event.relativePath + myevents[i].Event.DefaultVideo;
- else
- myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/index.php?view=view_video&eid=" + myevents[i].Event.Id;
+
+ myevents[i].Event.videoPath = myevents[i].Event.recordingURL + "/index.php?view=view_video&eid=" + myevents[i].Event.Id;
// if (idfound)
if (idfound) {
@@ -525,7 +535,7 @@ angular.module('zmApp.controllers')
}
- function saveNow(imgsrc, r, f) {
+ function saveNow(imgsrc) {
var fname = "zmninja.jpg";
var fn = "cordova.plugins.photoLibrary.saveImage";
@@ -874,9 +884,11 @@ angular.module('zmApp.controllers')
});
};
- $scope.showImage = function (p, r, f, fid, e, imode, id, parray, ndx) {
+ $scope.showImage = function (p, f, fid, e, imode, id, parray, ndx) {
var img;
+// console.log ("P="+p+" F="+f+" E="+e+" imode="+imode+" id="+id+" parray="+JSON.stringify(parray)+" ndx="+ndx);
+
//console.log ("HERE");
$scope.kFrame = $translate.instant('kFrame');
$scope.kEvent = $translate.instant('kEvent');
@@ -903,20 +915,11 @@ angular.module('zmApp.controllers')
NVRDataModel.debug("No index adjustment necessary as we are using all frames");
}
- // console.log ("Image Mode " + imode);
- // console.log ("parray : " + JSON.stringify(parray));
- // console.log ("index: " + ndx);
- if ($scope.imode == 'path') {
- if ($scope.outlineMotion)
- $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].aname;
- else
- $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname;
- $scope.fallbackImgSrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname;
- } else {
+
$scope.imgsrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id + $scope.outlineMotionParam;
$scope.fallbackImgSrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id;
- }
+
//$rootScope.zmPopup = $ionicPopup.alert({title: kFrame+':'+fid+'/'+kEvent+':'+e,template:img, cssClass:'popup80'});
@@ -944,7 +947,7 @@ angular.module('zmApp.controllers')
type: 'button-assertive button-small ion-camera',
onTap: function (e) {
e.preventDefault();
- saveNow($scope.imgsrc, r, parray[$scope.ndx].fname);
+ saveNow($scope.imgsrc);
}
},
@@ -969,17 +972,11 @@ angular.module('zmApp.controllers')
if (nndx == null) nndx = $scope.ndx;
$scope.ndx = nndx;
- if ($scope.imode == 'path') {
- if ($scope.outlineMotion)
- $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].aname;
- else
- $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname;
- $scope.fallbackImgSrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname;
- } else {
+
$scope.imgsrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id + $scope.outlineMotionParam;
$scope.fallbackImgSrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id;
- }
+
e.preventDefault();
@@ -1008,17 +1005,11 @@ angular.module('zmApp.controllers')
if (nndx == null) nndx = $scope.ndx;
$scope.ndx = nndx;
- if ($scope.imode == 'path') {
- if ($scope.outlineMotion)
- $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].aname;
- else
- $scope.imgsrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname;
- $scope.fallbackImgSrc = p + "/index.php?view=image&path=" + r + $scope.parray[$scope.ndx].fname;
- } else {
+
$scope.imgsrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id + $scope.outlineMotionParam;
$scope.fallbackImgSrc = p + "/index.php?view=image&fid=" + $scope.parray[$scope.ndx].id;
- }
+
e.preventDefault();
@@ -1193,14 +1184,9 @@ angular.module('zmApp.controllers')
{
var fname;
//console.log ("PATH="+e.Event.imageMode);
- if (e.Event.imageMode == 'path')
- //if (1)
- {
- var rfp = padToN(data.event.Frame[i].FrameId, eventImageDigits) + "-capture.jpg";
- fname = e.Event.baseURL + "/index.php?view=image&width=" + zm.maxGifWidth + "&path=" + e.Event.relativePath + rfp;
- } else {
- fname = e.Event.baseURL + "/index.php?view=image&width=" + zm.maxGifWidth + "&fid=" + data.event.Frame[i].Id;
- }
+
+ fname = e.Event.recordingURL + "/index.php?view=image&width=" + zm.maxGifWidth + "&fid=" + data.event.Frame[i].Id;
+
if (data.event.Frame[i].TimeStamp != lastTime /*|| fps < 2*/ )
@@ -1814,11 +1800,25 @@ angular.module('zmApp.controllers')
// data for events ranges summaries using the consolveEvents facility of ZM
//--------------------------------------------------------------------------
+
+ $scope.footerToggle = function() {
+
+ if ($scope.footerState == ionPullUpFooterState.EXPANDED)
+ $scope.footerCollapse();
+ else
+ $scope.footerExpand();
+ };
+
$scope.footerExpand = function () {
+ $scope.footerState = ionPullUpFooterState.EXPANDED;
footerExpand();
};
+ $scope.footerCollapse = function() {
+ $scope.footerState = ionPullUpFooterState.MINIMIZED;
+ };
+
function footerExpand() {
//https://server/zm/api/events/consoleEvents/5%20minute.json
var ld = NVRDataModel.getLogin();
@@ -1826,12 +1826,12 @@ angular.module('zmApp.controllers')
var af = "/AlarmFrames >=:" + (ld.enableAlarmCount ? ld.minAlarmCount : 0);
var apiurl = ld.apiurl + "/events/consoleEvents/1 hour" + af + ".json";
- NVRDataModel.debug("consoleEvents API:" + apiurl);
+ //NVRDataModel.debug("consoleEvents API:" + apiurl);
$http.get(apiurl)
.then(function (data) {
data = data.data;
- NVRDataModel.debug(JSON.stringify(data));
+ // NVRDataModel.debug(JSON.stringify(data));
$scope.hours = [];
var p = data.results;
for (var key in data.results) {
@@ -1863,11 +1863,11 @@ angular.module('zmApp.controllers')
});
apiurl = ld.apiurl + "/events/consoleEvents/1 day" + af + ".json";
- NVRDataModel.debug("consoleEvents API:" + apiurl);
+ //NVRDataModel.debug("consoleEvents API:" + apiurl);
$http.get(apiurl)
.then(function (data) {
data = data.data;
- NVRDataModel.debug(JSON.stringify(data));
+ //NVRDataModel.debug(JSON.stringify(data));
$scope.days = [];
var p = data.results;
for (var key in data.results) {
@@ -1896,11 +1896,11 @@ angular.module('zmApp.controllers')
});
apiurl = ld.apiurl + "/events/consoleEvents/1 week" + af + ".json";
- NVRDataModel.debug("consoleEvents API:" + apiurl);
+ //NVRDataModel.debug("consoleEvents API:" + apiurl);
$http.get(apiurl)
.then(function (data) {
data = data.data;
- NVRDataModel.debug(JSON.stringify(data));
+ // NVRDataModel.debug(JSON.stringify(data));
$scope.weeks = [];
var p = data.results;
for (var key in data.results) {
@@ -1930,11 +1930,11 @@ angular.module('zmApp.controllers')
});
apiurl = ld.apiurl + "/events/consoleEvents/1 month" + af + ".json";
- NVRDataModel.debug("consoleEvents API:" + apiurl);
+ //NVRDataModel.debug("consoleEvents API:" + apiurl);
$http.get(apiurl)
.then(function (data) {
data = data.data;
- NVRDataModel.debug(JSON.stringify(data));
+ //NVRDataModel.debug(JSON.stringify(data));
$scope.months = [];
var p = data.results;
for (var key in data.results) {
@@ -2033,7 +2033,7 @@ angular.module('zmApp.controllers')
NVRDataModel.debug("disabling options swipe");
} else {
$ionicListDelegate.canSwipeItems(true);
- NVRDataModel.debug("enabling options swipe");
+ //NVRDataModel.debug("enabling options swipe");
}
};
@@ -2075,11 +2075,11 @@ angular.module('zmApp.controllers')
if (event.Event.ShowScrub == false) {
$ionicListDelegate.canSwipeItems(true);
- NVRDataModel.debug("enabling options swipe due to toggle");
+ //NVRDataModel.debug("enabling options swipe due to toggle");
} else {
$ionicListDelegate.canSwipeItems(false);
$ionicListDelegate.closeOptionButtons();
- NVRDataModel.debug("disabling options swipe due to toggle");
+ // NVRDataModel.debug("disabling options swipe due to toggle");
}
@@ -2105,7 +2105,17 @@ angular.module('zmApp.controllers')
NVRDataModel.log("API for event details" + myurl);
$http.get(myurl)
.then(function (data) {
+
+
data = data.data;
+
+
+ // var ndata = data.replace(/<pre class="cake-error">/,'');
+
+ // console.log ("NDATA:"+ndata);
+ //<pre class="cake-error">
+
+
$scope.FrameArray = data.event.Frame;
// $scope.slider_options.scale=[];
@@ -2143,7 +2153,7 @@ angular.module('zmApp.controllers')
},
function (err) {
NVRDataModel.log("Error retrieving detailed frame API " + JSON.stringify(err));
- NVRDataModel.displayBanner('error', ['could not retrieve frame details', 'please try again']);
+ // NVRDataModel.displayBanner('error', ['could not retrieve frame details', 'please try again']);
});
} // end of groupType == alarms
@@ -2200,20 +2210,7 @@ angular.module('zmApp.controllers')
$scope.slides = [];
var i;
- if (event.Event.imageMode == 'path') {
- NVRDataModel.debug("EventCtrl: found " + frames + " frames to scrub");
-
- for (i = 1; i <= frames; i++) {
- var fname = padToN(i, eventImageDigits) + "-capture.jpg";
-
- $scope.slides.push({
- id: i,
- img: fname
- });
-
- }
- } else // we need fids
- {
+
var myurl_frames = loginData.apiurl + '/events/' + event.Event.Id + ".json";
NVRDataModel.log("API for event details" + myurl_frames);
$http.get(myurl_frames)
@@ -2243,7 +2240,7 @@ angular.module('zmApp.controllers')
NVRDataModel.displayBanner('error', [$translate.instant('kErrorFrameBanner'), $translate.instant('kErrorPleaseTryAgain')]);
});
- }
+
// now get event details to show alarm frames
loginData = NVRDataModel.getLogin();
@@ -2254,10 +2251,8 @@ angular.module('zmApp.controllers')
event.Event.video = {};
var videoURL;
- //if (event.Event.imageMode == 'path')
-
- /* videoURL = event.Event.baseURL + "/events/" + event.Event.relativePath + event.Event.DefaultVideo;*/
- videoURL = event.Event.baseURL + "/index.php?view=view_video&eid=" + event.Event.Id;
+
+ videoURL = event.Event.recordingURL + "/index.php?view=view_video&eid=" + event.Event.Id;
if ($rootScope.authSession != 'undefined') videoURL += $rootScope.authSession;
videoURL += NVRDataModel.insertBasicAuthToken();
@@ -2480,56 +2475,8 @@ angular.module('zmApp.controllers')
}
};
- //--------------------------------------------------------
- // utility function
- //--------------------------------------------------------
-
- function computeRelativePath(event) {
- var relativePath = "";
- var loginData = NVRDataModel.getLogin();
- var str = event.Event.StartTime;
- var yy = moment(str).locale('en').format('YY');
- var mm = moment(str).locale('en').format('MM');
- var dd = moment(str).locale('en').format('DD');
- var hh = moment(str).locale('en').format('HH');
- var min = moment(str).locale('en').format('mm');
- var sec = moment(str).locale('en').format('ss');
- relativePath = event.Event.MonitorId + "/" +
- yy + "/" +
- mm + "/" +
- dd + "/" +
- hh + "/" +
- min + "/" +
- sec + "/";
- return relativePath;
-
- }
-
- //--------------------------------------------------------
- // utility function
- //--------------------------------------------------------
-
- function computeBasePath(event) {
- var basePath = "";
- var loginData = NVRDataModel.getLogin();
- var str = event.Event.StartTime;
- var yy = moment(str).locale('en').format('YY');
- var mm = moment(str).locale('en').format('MM');
- var dd = moment(str).locale('en').format('DD');
- var hh = moment(str).locale('en').format('HH');
- var min = moment(str).locale('en').format('mm');
- var sec = moment(str).locale('en').format('ss');
-
- basePath = event.Event.baseURL + "/events/" +
- event.Event.MonitorId + "/" +
- yy + "/" +
- mm + "/" +
- dd + "/" +
- hh + "/" +
- min + "/" +
- sec + "/";
- return basePath;
- }
+
+
$scope.modalGraph = function () {
$ionicModal.fromTemplateUrl('templates/events-modalgraph.html', {
@@ -2745,11 +2692,13 @@ angular.module('zmApp.controllers')
NVRDataModel.debug("No more - We have a total of " + maxEventsPage + " and are at page=" + currEventsPage);
console.log("*** At Page " + currEventsPage + " of " + maxEventsPage + ", not proceeding");
+ $ionicLoading.hide();
return;
}
currEventsPage++;
if (!enableLoadMore) {
+ $ionicLoading.hide();
moreEvents = false; // Don't ion-scroll till enableLoadMore is true;
$scope.$broadcast('scroll.infiniteScrollComplete');
@@ -2759,11 +2708,15 @@ angular.module('zmApp.controllers')
var loadingStr = "";
if ($scope.search.text != "") {
- var toastStr = $translate.instant('kToastSearchingPage') + currEventsPage;
+
+ var toastStr = $translate.instant('kPleaseWait') +'...'+ currEventsPage;
+ console.log ("SHOW " + toastStr );
$ionicLoading.show({
maxwidth: 100,
+ noBackdrop:true,
scope: $scope,
- template: '<button class="button button-clear icon-left ion-close-circled button-text-wrap" ng-click="cancelSearch()" >' + toastStr + '</button>'
+ template: toastStr,
+ // template: '<button class="button button-clear icon-left ion-close-circled button-text-wrap" ng-click="cancelSearch()" >' + toastStr + '</button>'
});
loadingStr = "none";
@@ -2806,15 +2759,13 @@ angular.module('zmApp.controllers')
// now construct base path
myevents[i].Event.streamingURL = NVRDataModel.getStreamingURL(myevents[i].Event.MonitorId);
- myevents[i].Event.baseURL = NVRDataModel.getBaseURL(myevents[i].Event.MonitorId);
+ myevents[i].Event.recordingURL = NVRDataModel.getRecordingURL(myevents[i].Event.MonitorId);
myevents[i].Event.imageMode = NVRDataModel.getImageMode(myevents[i].Event.MonitorId);
// console.log ("***** MULTISERVER STREAMING URL FOR EVENTS " + myevents[i].Event.streamingURL);
- // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.baseURL);
+ // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.recordingURL);
myevents[i].Event.ShowScrub = false;
- myevents[i].Event.BasePath = computeBasePath(myevents[i]);
- myevents[i].Event.relativePath = computeRelativePath(myevents[i]);
myevents[i].Event.height = eventsListDetailsHeight;
// get thumbW/H
@@ -2837,11 +2788,8 @@ angular.module('zmApp.controllers')
}
- if (myevents[i].Event.imageMode == 'path')
- //if (1)
- myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/events/" + myevents[i].Event.relativePath + myevents[i].Event.DefaultVideo;
- else
- myevents[i].Event.videoPath = myevents[i].Event.baseURL + "/index.php?view=view_video&eid=" + myevents[i].Event.Id;
+
+ myevents[i].Event.videoPath = myevents[i].Event.recordingURL + "/index.php?view=view_video&eid=" + myevents[i].Event.Id;
if (idfound) $scope.events.push(myevents[i]);
}
@@ -2854,6 +2802,7 @@ angular.module('zmApp.controllers')
function (error) {
// console.log("*** No More Events to Load, Stop Infinite Scroll ****");
moreEvents = false;
+ $ionicLoading.hide();
$scope.$broadcast('scroll.infiniteScrollComplete');
});
@@ -2866,7 +2815,7 @@ angular.module('zmApp.controllers')
function recomputeThumbSize() {
- NVRDataModel.debug("EventCtrl: recompute thumbnails");
+ // NVRDataModel.debug("EventCtrl: recompute thumbnails");
for (var i = 0; i < $scope.events.length; i++) {
var tempMon = NVRDataModel.getMonitorObject($scope.events[i].Event.MonitorId);
@@ -2930,7 +2879,7 @@ angular.module('zmApp.controllers')
$scope.constructThumbnail = function (event) {
var stream = "";
- stream = event.Event.baseURL +
+ stream = event.Event.recordingURL +
"/index.php?view=image&show=capture&fid=" +
(event.Event.MaxScoreFrameId ? event.Event.MaxScoreFrameId : "1&eid=" + event.Event.Id) +
"&width=" + event.Event.thumbWidth * 2 +
@@ -2945,14 +2894,10 @@ angular.module('zmApp.controllers')
$scope.constructScrubFrame = function (event, slide) {
var stream = "";
- if (event.Event.imageMode == 'path') {
- stream = event.Event.baseURL + "/index.php?view=image" +
- "&path=" + event.Event.relativePath + slide.img + "&height=380";
-
- } else if (event.Event.imageMode == 'fid') {
- stream = event.Event.baseURL + "/index.php?view=image" +
+
+ stream = event.Event.recordingURL + "/index.php?view=image" +
"&fid=" + slide.id + $scope.outlineMotionParam;
- }
+
if ($rootScope.authSession != 'undefined') stream += $rootScope.authSession;
stream += NVRDataModel.insertBasicAuthToken();
@@ -2964,22 +2909,14 @@ angular.module('zmApp.controllers')
$scope.constructAlarmFrame = function (event, alarm, motion) {
var stream = "";
- if (event.Event.imageMode == 'fid') {
- stream = event.Event.baseURL +
+
+ stream = event.Event.recordingURL +
"/index.php?view=image&fid=" + alarm.id;
if (motion) stream += $scope.outlineMotionParam;
-
- } else if (event.Event.imageMode == 'path') {
- stream = event.Event.baseURL +
- "/index.php?view=image&path=" + event.Event.relativePath +
- motion ? alarm.aname : alarm.fname +
- "&height=380";
-
-
- }
if ($rootScope.authSession != 'undefined') stream += $rootScope.authSession;
stream += NVRDataModel.insertBasicAuthToken();
+// console.log ("alarm:"+stream);
return stream;
};
diff --git a/www/js/EventModalCtrl.js b/www/js/EventModalCtrl.js
index b992017c..11a7434a 100644
--- a/www/js/EventModalCtrl.js
+++ b/www/js/EventModalCtrl.js
@@ -261,7 +261,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
NVRDataModel.debug("player reported a video error:" + JSON.stringify(event));
$rootScope.zmPopup = SecuredPopups.show('alert', {
title: $translate.instant('kError'),
- template: $rootScope.platformOS == 'desktop' ? $translate.instant('kVideoError') : $translate.instant('kVideoErrorMobile'),
+ template: $translate.instant('kVideoError'),
okText: $translate.instant('kButtonOk'),
cancelText: $translate.instant('kButtonCancel'),
});
@@ -349,7 +349,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
}
})
.then(function (resp) {
- NVRDataModel.debug("sendCmd response:" + JSON.stringify(resp));
+ // NVRDataModel.debug("sendCmd response:" + JSON.stringify(resp));
d.resolve(resp);
return (d.promise);
@@ -762,9 +762,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$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));
@@ -772,7 +770,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
url = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand +
"&eid=" + $scope.eventId +
"&fid=" + $scope.slides[$scope.mycarousel.index - 1].id;
- }
+
if ($rootScope.authSession != 'undefined') {
url += $rootScope.authSession;
@@ -803,11 +801,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
onTap: function (e) {
if ($scope.slideIndex > 0) $scope.slideIndex--;
- if ($scope.event.Event.imageMode == 'path') {
- $scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&path=" + $scope.relativePath + $scope.slides[$scope.slideIndex].img;
- } else {
+
$scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&eid=" + $scope.eventId + "&fid=" + $scope.slides[$scope.slideIndex].id;
- }
+
if ($rootScope.authSession != 'undefined') {
$scope.selectEventUrl += $rootScope.authSession;
@@ -831,11 +827,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
onTap: function (e) {
if ($scope.slideIndex < $scope.slideLastIndex) $scope.slideIndex++;
- if ($scope.event.Event.imageMode == 'path') {
- $scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&path=" + $scope.relativePath + $scope.slides[$scope.slideIndex].img;
- } else {
+
$scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&eid=" + $scope.eventId + "&fid=" + $scope.slides[$scope.slideIndex].id;
- }
+
if ($rootScope.authSession != 'undefined') {
$scope.selectEventUrl += $rootScope.authSession;
@@ -860,11 +854,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
if (tempVar < 0) tempVar = 0;
$scope.slideIndex = tempVar;
- if ($scope.event.Event.imageMode == 'path') {
- $scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&path=" + $scope.relativePath + $scope.slides[$scope.slideIndex].img;
- } else {
+
$scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&eid=" + $scope.eventId + "&fid=" + $scope.slides[$scope.slideIndex].id;
- }
+
if ($rootScope.authSession != 'undefined') {
$scope.selectEventUrl += $rootScope.authSession;
@@ -889,11 +881,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$scope.slideIndex = tempVar;
if ($scope.slideIndex < $scope.slideLastIndex) $scope.slideIndex++;
- if ($scope.event.Event.imageMode == 'path') {
- $scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&path=" + $scope.relativePath + $scope.slides[$scope.slideIndex].img;
- } else {
+
$scope.selectEventUrl = $scope.playbackURL + '/index.php?view=image&rand=' + $rootScope.rand + "&eid=" + $scope.eventId + "&fid=" + $scope.slides[$scope.slideIndex].id;
- }
+
if ($rootScope.authSession != 'undefined') {
$scope.selectEventUrl += $rootScope.authSession;
@@ -1074,14 +1064,14 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
if (currentStreamState == streamState.STOPPED || !$scope.eventId) {
stream = "";
} else if (currentStreamState == streamState.SNAPSHOT) {
- stream = $scope.loginData.url +
+ stream = currentEvent.Event.recordingURL +
"/index.php?view=image" +
"&fid=" + $scope.snapshotFrameId +
(!isGlobalFid ? "&eid=" + $scope.eventId : "") +
"&scale=" + $scope.singleImageQuality +
$rootScope.authSession;
} else if (currentStreamState == streamState.ACTIVE) {
- stream = $scope.loginData.streamingurl +
+ stream = currentEvent.Event.streamingURL +
"/nph-zms?source=event&mode=jpeg" +
"&event=" + $scope.eventId + "&frame=1" +
"&replay=" + $scope.currentStreamMode +
@@ -1092,9 +1082,11 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
}
//console.log ($scope.connKey );
- //console.log ("STREAM="+stream);
+
//console.log ("EID="+$scope.eventId);
if ($rootScope.basicAuthToken && stream) stream += "&basicauth=" + $rootScope.basicAuthToken;
+
+ //console.log ("STREAM="+stream);
return stream;
};
@@ -1141,6 +1133,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
isSnapShotEnabled = true;
currentStreamState = streamState.SNAPSHOT;
if (m.snapshotId) {
+
+ $scope.snapshotFrameId = m.snapshotId;
+
$scope.snapshotFrameId = m.snapshotId;
isGlobalFid = true;
} else {
@@ -1170,10 +1165,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$scope.singleImageQuality = (NVRDataModel.getBandwidth() == "lowbw") ? zm.eventSingleImageQualityLowBW : ld.singleImageQuality;
$scope.blockSlider = false;
$scope.checkEventOn = false;
- //$scope.singleImageQuality = 100;
-
- //$scope.commandURL = $scope.currentEvent.Event.baseURL+"/index.php";
- // NVRDataModel.log (">>>>>>>>>>>>>>>>>>ZMS url command is " + $scope.commandURL);
+
currentEvent = $scope.currentEvent;
@@ -1311,7 +1303,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
}
- NVRDataModel.debug("Deregistering broadcast handles");
+ // NVRDataModel.debug("Deregistering broadcast handles");
for (var i = 0; i < broadcastHandles.length; i++) {
// broadcastHandles[i]();
}
@@ -1924,7 +1916,10 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
function computeAlarmFrames(data) {
$scope.alarm_images = [];
tempAlarms = [];
- $scope.FrameArray = data.event.Frame;
+ $scope.FrameArray = [];
+
+ //console.log ("FRAME ARRAY: "+JSON.stringify(data));
+ if (data.event && data.event.Frame) $scope.FrameArray = data.event.Frame;
var ts = 0;
for (i = 0; i < data.event.Frame.length; i++) {
@@ -1953,14 +1948,14 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
$scope.constructFrame = function (fid) {
var frame = "";
- frame = currentEvent.Event.baseURL + "/index.php?view=image" +
+ frame = currentEvent.Event.recordingURL + "/index.php?view=image" +
"&eid=" + currentEvent.Event.Id +
"&fid=" + fid +
"&height=" + 200;
if ($rootScope.authSession != 'undefined') frame += $rootScope.authSession;
frame += NVRDataModel.insertBasicAuthToken();
- // console.log (frame);
+ //console.log ("alarm:"+frame);
return frame;
};
@@ -1983,8 +1978,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
NVRDataModel.log("*** Constructed API for detailed events: " + myurl);
$scope.humanizeTime = "...";
$scope.mName = "...";
- $scope.liveFeedMid = '';
-
+ $scope.liveFeedMid = $scope.mid;
$http.get(myurl)
.then(function (success) {
@@ -1992,8 +1986,9 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
var event = success.data.event;
currentEvent = event;
$scope.event = event;
+ $scope.currentEvent = event;
-
+ // console.log ("prepareModal DATA:"+JSON.stringify(success.data));
computeAlarmFrames(success.data);
$scope.eventWarning = '';
@@ -2008,8 +2003,8 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
event.Event.relativePath = computeRelativePath(event);
event.Event.streamingURL = NVRDataModel.getStreamingURL(event.Event.MonitorId);
- // event.Event.baseURL = NVRDataModel.getBaseURL (event.Event.MonitorId);
- event.Event.baseURL = loginData.url;
+
+ event.Event.recordingURL = NVRDataModel.getRecordingURL(event.Event.MonitorId);
event.Event.imageMode = NVRDataModel.getImageMode(event.Event.MonitorId);
//console.log (JSON.stringify( success));
@@ -2056,10 +2051,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
event.Event.video = {};
var videoURL;
- if ((event.Event.imageMode == 'path') || NVRDataModel.getLogin().forceImageModePath)
- videoURL = event.Event.baseURL + "/events/" + event.Event.relativePath + event.Event.DefaultVideo;
- else
- videoURL = event.Event.baseURL + "/index.php?view=view_video&eid=" + event.Event.Id;
+ videoURL = event.Event.recordingURL + "/index.php?view=view_video&eid=" + event.Event.Id;
if ($rootScope.authSession != 'undefined') videoURL += $rootScope.authSession;
if ($rootScope.basicAuthToken) videoURL = videoURL + "&basicauth=" + $rootScope.basicAuthToken;
@@ -2073,10 +2065,7 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
NVRDataModel.debug("Video url passed to player is: " + videoURL);
- // console.log (">>>>>>>>>>>>>"+loginData.url+"-VS-"+event.Event.baseURL);
-
- //console.log("************** VIDEO IS " + videoURL);
-
+
$scope.videoObject = {
config: {
autoPlay: true,
@@ -2204,7 +2193,12 @@ angular.module('zmApp.controllers').controller('EventModalCtrl', ['$scope', '$ro
},
function (err) {
NVRDataModel.log("Error retrieving detailed frame API " + JSON.stringify(err));
- NVRDataModel.displayBanner('error', ['could not retrieve frame details', 'please try again']);
+ // NVRDataModel.displayBanner('error', ['could not retrieve frame details']);
+ $scope.eventWarning = $translate.instant('kLiveView');
+ // if this happens we get to live feed
+ $scope.liveFeedMid = $scope.mid;
+
+
});
}
diff --git a/www/js/EventServer.js b/www/js/EventServer.js
index 1340b88d..5ef0a260 100644
--- a/www/js/EventServer.js
+++ b/www/js/EventServer.js
@@ -17,6 +17,7 @@ angular.module('zmApp.controllers')
var pushInited = false;
var isTimerOn = false;
var nativeWebSocketId = -1;
+ var iClosed = false;
@@ -31,7 +32,10 @@ angular.module('zmApp.controllers')
NVRDataModel.log("openHandshake: Websocket open, sending Auth");
sendMessage("auth", {
user: loginData.username,
- password: loginData.password
+ password: loginData.password,
+ monlist: loginData.eventServerMonitors,
+ intlist: loginData.eventServerInterval
+
});
@@ -63,6 +67,13 @@ angular.module('zmApp.controllers')
function handleClose(event) {
+
+ if (iClosed) {
+ NVRDataModel.debug ("App closed socket, not reconnecting");
+ iClosed = false;
+ return;
+ }
+
console.log("*********** WEBSOCKET CLOSE CALLED");
if (!NVRDataModel.getLogin().isUseEventServer) return;
@@ -99,6 +110,7 @@ angular.module('zmApp.controllers')
if (str.reason == 'APNSDISABLED') {
console.log("FORCE CLOSING");
+ iClosed=true;
ws.close();
NVRDataModel.displayBanner('error', ['Event Server: APNS disabled'], 2000, 6000);
$rootScope.apnsToken = "";
@@ -319,7 +331,7 @@ angular.module('zmApp.controllers')
NVRDataModel.log("Clearing error/close cbk, disconnecting and deleting Event Server socket...");
- if ($rootScope.platforOS == 'desktop') {
+ if ($rootScope.platformOS == 'desktop') {
if (typeof ws === 'undefined') {
NVRDataModel.log("Event server socket is empty, nothing to disconnect");
return;
@@ -327,10 +339,12 @@ angular.module('zmApp.controllers')
ws.onmessage = null;
+ iClosed = true;
ws.close();
ws = undefined;
} else {
if (nativeWebSocketId != -1) //native;
+ iClosed = true;
CordovaWebsocketPlugin.wsClose(nativeWebSocketId, 1000, "Connection closed");
nativeWebSocketId = -1;
@@ -478,6 +492,7 @@ angular.module('zmApp.controllers')
// console.log("*********** MEDIA BLOG IS " + mediasrc);
media = $cordovaMedia.newMedia(mediasrc);
+
push.on('registration', function (data) {
pushInited = true;
NVRDataModel.debug("Push Notification registration ID received: " + JSON.stringify(data));
@@ -522,10 +537,6 @@ angular.module('zmApp.controllers')
}
-
-
- //console.log ("WUTPUT SENDING REG WITH "+monstring);
-
$rootScope.monstring = monstring;
$rootScope.intstring = intstring;
@@ -548,6 +559,7 @@ angular.module('zmApp.controllers')
push.on('notification', function (data) {
$ionicPlatform.ready(function () {
+ NVRDataModel.log("******* notification handler device ready");
NVRDataModel.debug("received push notification");
var ld = NVRDataModel.getLogin();
@@ -598,13 +610,13 @@ angular.module('zmApp.controllers')
$rootScope.tappedMid = mid;
$rootScope.tappedEid = eid;
- NVRDataModel.log("Push notification: Tapped Monitor taken as:" + $rootScope.tappedMid);
+ NVRDataModel.log("ES:Push notification: Tapped Monitor taken as:" + $rootScope.tappedMid);
if ($rootScope.platformOS == 'ios') {
- NVRDataModel.debug("iOS only: clearing background push");
+ NVRDataModel.debug("ES:iOS only: clearing background push");
push.finish(function () {
- NVRDataModel.debug("processing of push data is finished");
+ NVRDataModel.debug("ES:processing of push data is finished");
});
}
@@ -616,7 +628,13 @@ angular.module('zmApp.controllers')
}
// keep this emit not broadcast
// see Portal latch for reason
- $rootScope.$emit('process-push');
+
+ //https://stackoverflow.com/a/22651128/1361529
+ $timeout ( function () {
+ NVRDataModel.debug ("EventServer: broadcasting process-push");
+ $rootScope.$broadcast('process-push');
+ },100);
+
} else // app is foreground
{
diff --git a/www/js/EventsModalGraphCtrl.js b/www/js/EventsModalGraphCtrl.js
index b4e82ee2..0cfacb68 100644
--- a/www/js/EventsModalGraphCtrl.js
+++ b/www/js/EventsModalGraphCtrl.js
@@ -23,7 +23,7 @@ angular.module('zmApp.controllers').controller('EventsModalGraphCtrl', ['$scope'
$scope.$on('modal.removed', function (e, m) {
- NVRDataModel.debug("Deregistering broadcast handles");
+ //NVRDataModel.debug("Deregistering broadcast handles");
for (var i = 0; i < broadcastHandles.length; i++) {
// broadcastHandles[i]();
}
diff --git a/www/js/LogCtrl.js b/www/js/LogCtrl.js
index 78a02992..01566750 100644
--- a/www/js/LogCtrl.js
+++ b/www/js/LogCtrl.js
@@ -2,7 +2,7 @@
/* jslint browser: true*/
/* global saveAs, cordova,StatusBar,angular,console,moment */
-angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$rootScope', 'zm', '$ionicModal', 'NVRDataModel', '$ionicSideMenuDelegate', '$fileLogger', '$cordovaEmailComposer', '$ionicPopup', '$timeout', '$ionicHistory', '$state', '$interval', '$ionicLoading', '$translate', '$http', function ($scope, $rootScope, zm, $ionicModal, NVRDataModel, $ionicSideMenuDelegate, $fileLogger, $cordovaEmailComposer, $ionicPopup, $timeout, $ionicHistory, $state, $interval, $ionicLoading, $translate, $http) {
+angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$rootScope', 'zm', '$ionicModal', 'NVRDataModel', '$ionicSideMenuDelegate', '$fileLogger', '$cordovaEmailComposer', '$ionicPopup', '$timeout', '$ionicHistory', '$state', '$interval', '$ionicLoading', '$translate', '$http', 'SecuredPopups', function ($scope, $rootScope, zm, $ionicModal, NVRDataModel, $ionicSideMenuDelegate, $fileLogger, $cordovaEmailComposer, $ionicPopup, $timeout, $ionicHistory, $state, $interval, $ionicLoading, $translate, $http, SecuredPopups) {
$scope.openMenu = function () {
$ionicSideMenuDelegate.toggleLeft();
};
@@ -11,20 +11,9 @@ angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$roo
// Controller main
//---------------------------------------------------------------
- var intervalLogUpdateHandle;
- document.addEventListener("pause", onPause, false);
- document.addEventListener("resume", onResume, false);
- function onPause() {
- NVRDataModel.debug("LogCtrl: pause called, killing log timer");
- // $interval.cancel(intervalLogUpdateHandle);
- }
- function onResume() {
- // NVRDataModel.debug("LogCtrl: resume called, starting log timer");
- loadLogs();
- }
$scope.flipLogs = function () {
if ($scope.logEntity == 'ZoneMinder')
@@ -76,115 +65,84 @@ angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$roo
}
};
- //--------------------------------------------------------------------------
- // Make sure user knows information masking is best effort
- //--------------------------------------------------------------------------
-
- $scope.sendEmail = function (logstring) {
- logstring = logstring.substring(0, 20000);
- $ionicPopup.confirm({
- title: $translate.instant('kSensitiveTitle'),
- template: $rootScope.appName + ' ' + $translate.instant('kSensitiveBody'),
- okText: $translate.instant('kButtonOk'),
- cancelText: $translate.instant('kButtonCancel'),
- })
- .then(function (res) {
- if (res) {
-
- logstring = "zmNinja version:" + $scope.zmAppVersion +
- " (" + $rootScope.platformOS + ")\n" +
- "ZoneMinder version:" + NVRDataModel.getCurrentServerVersion() + "\n" +
- logstring;
- sendEmailReally(logstring);
- }
- });
- };
+ // desktop download
+ $scope.downloadLogs = function () {
+ var body = "zmNinja version:" + $scope.zmAppVersion +
+ " (" + $rootScope.platformOS + ")\n" +
+ "ZoneMinder version:" + NVRDataModel.getCurrentServerVersion()+"\n\n";
- //--------------------------------------------------------------------------
- // Convenience function to send logs via email
- //--------------------------------------------------------------------------
- function sendEmailReally(logstring) {
-
- //console.log ("LOGSTRING:"+logstring);
- if (window.cordova) {
-
- // do my best to replace sensitive information
- var loginData = NVRDataModel.getLogin();
-
- // We don't need this anymore as log and debug now strip passwords
- /*if (loginData.password !="")
- {
- var re1 = new RegExp(loginData.password, "g");
- logstring = logstring.replace(re1, "<deleted>");
- }*/
- // keep the protocol, helps to debug
- var urlNoProtocol = loginData.url.replace(/.*?:\/\//, "");
- if (urlNoProtocol != "") {
- var re2 = new RegExp(urlNoProtocol, "g");
- // just replacing baseurl - that will take care of
- // masking api but may not be cgi
- logstring = logstring.replace(re2, "<server>");
- }
- urlNoProtocol = loginData.streamingurl.replace(/.*?:\/\//, "");
- if (urlNoProtocol != "") {
- var re3 = new RegExp(urlNoProtocol, "g");
- logstring = logstring.replace(re3, "<server>");
- }
+ body = $translate.instant('kSensitiveBody') + '\n\n\n' + body;
+ var fname = $rootScope.appName + "-logs-" +
+ moment().format('MMM-DD-YY_HH-mm-ss') + ".txt";
- urlNoProtocol = loginData.eventServer.replace(/.*?:\/\//, "");
- if (urlNoProtocol != "") {
- var re4 = new RegExp(urlNoProtocol, "g");
- logstring = logstring.replace(re4, "<server>");
- }
+ $fileLogger.checkFile()
+ .then(function (d) {
- //console.log ("NEW LOGSTRING:"+logstring);
- /* window.plugins.emailComposer.showEmailComposerWithCallback(callback, $rootScope.appName + ' logs', logstring, [zm.authoremail]);*/
-
-
- cordova.plugins.email.isAvailable(
- function (isAvailable) {
-
- if (isAvailable) {
- // body encapsulation requires br :^
- // see https://github.com/katzer/cordova-plugin-email-composer/issues/150
- logstring = logstring.split('\n').join('<br/>');
- cordova.plugins.email.open({
- to: zm.authoremail,
- subject: $rootScope.appName + ' logs',
- body: logstring
- });
- } else {
- // kEmailNotConfigured
- $rootScope.zmPopup = SecuredPopups.show('alert', {
- title: $translate.instant('kError'),
- template: $translate.instant('kEmailNotConfigured'),
- okText: $translate.instant('kButtonOk'),
- cancelText: $translate.instant('kButtonCancel'),
- });
+ body = body + window.localStorage[d.name];
+ var file = new Blob([body], {
+ type: 'text/plain'
+ });
+ var url = URL.createObjectURL(file);
+
+ $rootScope.zmPopup = SecuredPopups.show('alert', {
+ title: $translate.instant('kNote'),
+ template: $translate.instant('kTapDownloadLogs') + "<br/><br/><center><a href='" + url + "' class='button button-assertive icon ion-android-download' download='" + fname + "'>" + " " + $translate.instant('kDownload') + "</a></center>",
+ okText: $translate.instant('kDismiss'),
+ okType: 'button-stable'
+ },
+ function (e) {
+ NVRDataModel.debug("Error getting log file:" + JSON.stringify(e));
}
- });
+ );
+ });
- } else {
- // console.log("Using default email client to send data");
- var fname = $rootScope.appName + "-logs-" +
- moment().format('MMM-DD-YY_HH-mm-ss') + ".txt";
+ };
- var blob = new Blob([logstring], {
- type: "text/plain;charset=utf-8"
- });
- saveAs(blob, fname);
- }
+ // mobile - picks up applogs on the FS and sends an email with it
+
+ $scope.attachLogs = function () {
+ var body = "zmNinja version:" + $scope.zmAppVersion +
+ " (" + $rootScope.platformOS + ")<br/>" +
+ "ZoneMinder version:" + NVRDataModel.getCurrentServerVersion() + "<br/>";
+ body = '<b>' + $translate.instant('kSensitiveBody') + '</b><br/><br/>' + body;
+
+ $fileLogger.checkFile()
+ .then(function (d) {
+ var fileWithPath = cordova.file.dataDirectory + d.name;
+ NVRDataModel.log("file location:" + fileWithPath);
+
+ var onSuccess = function (result) {
+ NVRDataModel.log("Share completed? " + result.completed);
+ NVRDataModel.log("Shared to app: " + result.app);
+ };
+
+ var onError = function (msg) {
+ NVRDataModel.log("Sharing failed with message: " + msg);
+ };
+
+ window.plugins.socialsharing.shareViaEmail(
+ body, //body
+ 'zmNinja Logs attached', // subject
+ [zm.authoremail], //to
+ null, // cc
+ null, //bcc
+ [fileWithPath],
+ onSuccess,
+ onError
+ );
- }
+ },
+ function (e) {
+ NVRDataModel.debug("Error attaching log file:" + JSON.stringify(e));
+ });
+
+
+ };
- function callback() {
- // console.log ("EMAIL SENT");
- NVRDataModel.debug("Email sent callback called");
- }
function loadZMlogs() {
var ld = NVRDataModel.getLogin();
@@ -257,6 +215,22 @@ angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$roo
// reset power state on exit as if it is called after we enter another
// state, that effectively overwrites current view power management needs
//------------------------------------------------------------------------
+
+
+ $scope.$on('$ionic.beforeEnter', function () {
+
+ $scope.$on("process-push", function () {
+ NVRDataModel.debug(">> LogCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:" + JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate: true,
+ disableBack: true
+ });
+ $state.go(s[0], s[1], s[2]);
+ });
+ });
+
$scope.$on('$ionicView.enter', function () {
//console.log("**VIEW ** Log Ctrl Entered");
@@ -280,6 +254,7 @@ angular.module('zmApp.controllers').controller('zmApp.LogCtrl', ['$scope', '$roo
};
$scope.zmAppVersion = NVRDataModel.getAppVersion();
+ $scope.zmVersion = NVRDataModel.getCurrentServerVersion();
/* intervalLogUpdateHandle = $interval(function ()
{
diff --git a/www/js/LoginCtrl.js b/www/js/LoginCtrl.js
index ca6b9df9..09a48ac2 100644
--- a/www/js/LoginCtrl.js
+++ b/www/js/LoginCtrl.js
@@ -33,6 +33,7 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
}
+
//----------------------------------------------------------------
// Alarm notification handling
//----------------------------------------------------------------
@@ -233,6 +234,20 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
// state, that effectively overwrites current view power management needs
//------------------------------------------------------------------------
$scope.$on('$ionicView.beforeEnter', function () {
+
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> LoginCtrl: push handler. Not processing push, because you might be here due to login failure");
+ /*var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);*/
+ });
+
+
oldLoginData = '';
$scope.loginData = NVRDataModel.getLogin();
@@ -262,11 +277,6 @@ angular.module('zmApp.controllers').controller('zmApp.LoginCtrl', ['$scope', '$r
NVRDataModel.log("Creating new login entry for wizard");
$scope.loginData = angular.copy(NVRDataModel.getDefaultLoginObject());
- // default object has this as false
- if ($rootScope.platformOS == 'ios') {
- $scope.loginData.disableSimulStreaming = true;
- }
-
$scope.loginData.serverName = $rootScope.wizard.serverName;
$scope.loginData.url = $rootScope.wizard.loginURL;
$scope.loginData.apiurl = $rootScope.wizard.apiURL;
diff --git a/www/js/MomentCtrl.js b/www/js/MomentCtrl.js
index 6a56158e..44f653df 100644
--- a/www/js/MomentCtrl.js
+++ b/www/js/MomentCtrl.js
@@ -23,6 +23,8 @@ angular.module('zmApp.controllers').controller('zmApp.MomentCtrl', ['$scope', '$
$ionicSideMenuDelegate.toggleLeft();
};
+
+
//----------------------------------------------------------------
// Alarm notification handling
//----------------------------------------------------------------
@@ -134,9 +136,8 @@ angular.module('zmApp.controllers').controller('zmApp.MomentCtrl', ['$scope', '$
data.events[i].Event.hide = false;
data.events[i].Event.icon = "ion-code-working";
- //data.events[i].Event.baseURL = NVRDataModel.getBaseURL(data.events[i].Event.MonitorId);
- // huh? why did I need the above? eventCtrl reverses it with below...
- data.events[i].Event.baseURL = NVRDataModel.getLogin().url;
+
+ data.events[i].Event.recordingURL = NVRDataModel.getLogin().url;
data.events[i].Event.monitorName = NVRDataModel.getMonitorName(data.events[i].Event.MonitorId);
data.events[i].Event.dateObject = new Date(data.events[i].Event.StartTime);
@@ -267,7 +268,7 @@ angular.module('zmApp.controllers').controller('zmApp.MomentCtrl', ['$scope', '$
$scope.constructFrame = function (moment) {
var stream = "";
// console.log ($scope.isMaxScoreFramePresent);
- stream = moment.Event.baseURL + "/index.php?view=image" +
+ stream = moment.Event.recordingURL + "/index.php?view=image" +
($scope.isMaxScoreFramePresent ? "&fid=" + moment.Event.MaxScoreFrameId : "&eid=" + moment.Event.Id + "&fid=1") +
"&width=" + moment.Event.thumbWidth * 2 +
"&height=" + moment.Event.thumbHeight * 2;
@@ -834,6 +835,18 @@ angular.module('zmApp.controllers').controller('zmApp.MomentCtrl', ['$scope', '$
$scope.$on('$ionicView.beforeEnter', function () {
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> MomentCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+
//console.log ("HERE>>>>>>>>>>>>>>>>>>>>>>>>>>>");
monitors = angular.copy(message); // don't mess up the main monitors list
diff --git a/www/js/MonitorCtrl.js b/www/js/MonitorCtrl.js
index 9edb1e36..7241db53 100644
--- a/www/js/MonitorCtrl.js
+++ b/www/js/MonitorCtrl.js
@@ -6,18 +6,12 @@
// refer to comments in EventCtrl for the modal stuff. They are almost the same
angular.module('zmApp.controllers')
- .controller('zmApp.MonitorCtrl', ['$ionicPopup', 'zm', '$scope', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$ionicLoading', '$ionicModal', '$state', '$http', '$rootScope', '$timeout', '$ionicHistory', '$ionicPlatform', '$translate', '$q',
- function ($ionicPopup, zm, $scope, NVRDataModel, message, $ionicSideMenuDelegate, $ionicLoading, $ionicModal, $state, $http, $rootScope, $timeout, $ionicHistory, $ionicPlatform, $translate, $q) {
+ .controller('zmApp.MonitorCtrl', ['$ionicPopup', 'zm', '$scope', 'NVRDataModel', '$ionicSideMenuDelegate', '$ionicLoading', '$ionicModal', '$state', '$http', '$rootScope', '$timeout', '$ionicHistory', '$ionicPlatform', '$translate', '$q',
+ function ($ionicPopup, zm, $scope, NVRDataModel, $ionicSideMenuDelegate, $ionicLoading, $ionicModal, $state, $http, $rootScope, $timeout, $ionicHistory, $ionicPlatform, $translate, $q) {
- //-----------------------------------------------------------------------
- // Controller Main
- //-----------------------------------------------------------------------
-
- // var isModalOpen = false;
-
- // console.log("***EVENTS: Waiting for Monitors to load before I proceed");
var loginData;
+ $scope.monitorLoadStatus = "...";
// --------------------------------------------------------
// Handling of back button in case modal is open should
@@ -48,6 +42,8 @@ angular.module('zmApp.controllers')
$ionicSideMenuDelegate.toggleLeft();
};
+
+
//----------------------------------------------------------------
// Alarm notification handling
//----------------------------------------------------------------
@@ -251,6 +247,20 @@ angular.module('zmApp.controllers')
// reset power state on exit as if it is called after we enter another
// state, that effectively overwrites current view power management needs
//------------------------------------------------------------------------
+
+ $scope.$on('$ionicView.beforeEnter', function() {
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> MonitorCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+ });
$scope.$on('$ionicView.enter', function () {
// console.log("**VIEW ** Monitor Ctrl Entered");
NVRDataModel.setAwake(false);
@@ -260,24 +270,15 @@ angular.module('zmApp.controllers')
$scope.$on('$ionicView.afterEnter', function () {
// console.log("**VIEW ** Monitor Ctrl Entered");
+
+ NVRDataModel.debug ("Monitor Control afterEnter");
$scope.monitors = [];
- $scope.monitors = message;
+ $scope.monitorLoadStatus = $translate.instant ('kPleaseWait')+'...';
+
//console.log (">>>>>>>>>>>> MONITOR CTRL " + JSON.stringify($scope.monitors));
- if ($scope.monitors.length == 0) {
- $rootScope.zmPopup = $ionicPopup.alert({
- title: $translate.instant('kNoMonitors'),
- template: $translate.instant('kPleaseCheckCredentials')
- });
- $ionicHistory.nextViewOptions({
- disableBack: true
- });
- $state.go("app.login", {
- "wizard": false
- });
- return;
- }
+
loginData = NVRDataModel.getLogin();
monitorStateCheck();
@@ -292,15 +293,21 @@ angular.module('zmApp.controllers')
var tm = $rootScope.tappedMid;
$rootScope.tappedMid = 0;
var monitem;
- for (var m = 0; m < $scope.monitors.length; m++) {
- if ($scope.monitors[m].Monitor.Id == tm) {
- monitem = $scope.monitors[m];
- break;
- }
- }
+ NVRDataModel.getMonitors(0)
+ .then ( function (data) {
+ $scope.monitors = data;
+ for (var m = 0; m < $scope.monitors.length; m++) {
+ if ($scope.monitors[m].Monitor.Id == tm) {
+ monitem = $scope.monitors[m];
+ break;
+ }
+ }
+ openModal(monitem.Monitor.Id, monitem.Monitor.Controllable, monitem.Monitor.ControlId, monitem.Monitor.connKey, monitem);
+ });
+
- openModal(monitem.Monitor.Id, monitem.Monitor.Controllable, monitem.Monitor.ControlId, monitem.Monitor.connKey, monitem);
+
}
});
@@ -399,8 +406,67 @@ angular.module('zmApp.controllers')
//-----------------------------------------------------------------------
function monitorStateCheck() {
+
+ // console.log ("Checking monitors");
+ var ld = NVRDataModel.getLogin();
+ // force get for latest status of monitors if av.
+ NVRDataModel.getMonitors(1)
+ .then (function (data) {
+
+ $scope.monitors = data;
+
+ if (!$scope.monitors.length) {
+ $scope.monitorLoadStatus = $translate.instant ('kNoMonitors');
+ }
+
+ if (!$scope.monitors[0].Monitor_Status ) {
+ NVRDataModel.debug ("no Monitor_Status found reverting to daemonCheck...");
+ forceDaemonCheck();
+ }
+ else {
+ NVRDataModel.debug ("reporting status of monitors from multi-server API");
+ processMonitorStatus();
+ }
+
+ },
+ function (err) {
+ NVRDataModel.debug ("Monitor fetch error, reverting to daemonCheck...");
+ $scope.monitorLoadStatus = $translate.instant ('kNoMonitors');
+ forceDaemonCheck();
+ });
+
+ }
+
+ function processMonitorStatus () {
+
+ //array('Unknown','NotRunning','Running','NoSignal','Signal'),
+
+
+ // console.log (JSON.stringify($scope.monitors));
+ for (var j=0; j < $scope.monitors.length; j++) {
+
+ if ($scope.monitors[j].Monitor_Status.Status == 'Connected') {
+ $scope.monitors[j].Monitor.isRunning = "true";
+ $scope.monitors[j].Monitor.color = zm.monitorRunningColor;
+ $scope.monitors[j].Monitor.char = "ion-checkmark-circled";
+ $scope.monitors[j].Monitor.isRunningText = $scope.monitors[j].Monitor_Status.Status;
+ }
+ else {
+ $scope.monitors[j].Monitor.isRunning = "false";
+ $scope.monitors[j].Monitor.color = zm.monitorNotRunningColor;
+ $scope.monitors[j].Monitor.char = "ion-close-circled";
+ $scope.monitors[j].Monitor.isRunningText = $scope.monitors[j].Monitor_Status.Status;
+ }
+
+ }
+
+ }
+
+ function forceDaemonCheck() {
var apiMonCheck;
+ $scope.loginData = NVRDataModel.getLogin();
+
// The status is provided by zmdc.pl
// "not running", "pending", "running since", "Unable to connect"
var i;
@@ -409,13 +475,10 @@ angular.module('zmApp.controllers')
$scope.monitors[j].Monitor.isRunningText = "...";
$scope.monitors[j].Monitor.isRunning = "...";
$scope.monitors[j].Monitor.color = zm.monitorCheckingColor;
- $scope.monitors[j].Monitor.char = "ion-checkmark-circled";
- apiMonCheck = loginData.apiurl + "/monitors/daemonStatus/id:" + $scope.monitors[j].Monitor.Id + "/daemon:zmc.json";
-
- //apiMonCheck = apiMonCheck.replace(loginData.url, $scope.monitors[j].Monitor.baseURL);
-
- // in multiserver replace apiurl with baseurl
+ $scope.monitors[j].Monitor.char = "ion-help-circled";
+ apiMonCheck = $scope.loginData.apiurl + "/monitors/daemonStatus/id:" + $scope.monitors[j].Monitor.Id + "/daemon:zmc.json";
+
NVRDataModel.debug("MonitorCtrl:monitorStateCheck: " + apiMonCheck);
//console.log("**** ZMC CHECK " + apiMonCheck);
$http.get(apiMonCheck)
@@ -432,6 +495,7 @@ angular.module('zmApp.controllers')
} else if (data.statustext.indexOf("running since") > -1) {
$scope.monitors[j].Monitor.isRunning = "true";
$scope.monitors[j].Monitor.color = zm.monitorRunningColor;
+ $scope.monitors[j].Monitor.char = "ion-checkmark-circled";
} else if (data.statustext.indexOf("Unable to connect") > -1) {
$scope.monitors[j].Monitor.isRunning = "false";
$scope.monitors[j].Monitor.color = zm.monitorNotRunningColor;
diff --git a/www/js/MontageCtrl.js b/www/js/MontageCtrl.js
index 161a1025..0e3d34d0 100644
--- a/www/js/MontageCtrl.js
+++ b/www/js/MontageCtrl.js
@@ -47,6 +47,10 @@ angular.module('zmApp.controllers')
var broadcastHandles = [];
+
+
+
+
var as = $scope.$on("auth-success", function () {
/* var tnow = new Date();
@@ -218,13 +222,6 @@ angular.module('zmApp.controllers')
"view": 'app.montage'
});
-
- /* $state.transitionTo($state.current, $stateParams, {
- reload: true,
- inherit: false,
- notify: true
- });*/
-
});
@@ -1823,6 +1820,19 @@ angular.module('zmApp.controllers')
// minimal has to be beforeEnter or header won't hide
$scope.$on('$ionicView.beforeEnter', function () {
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> MontageCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+
+
timeInMontage = new Date();
broadcastHandles = [];
randToAvoidCacheMem = new Date().getTime();
@@ -2019,6 +2029,11 @@ angular.module('zmApp.controllers')
currentStreamState = streamState.STOPPED;
viewCleanup();
viewCleaned = true;
+ //NVRDataModel.debug("Deregistering broadcast handles");
+ for (var i = 0; i < broadcastHandles.length; i++) {
+ broadcastHandles[i]();
+ }
+ broadcastHandles = [];
});
diff --git a/www/js/MontageHistoryCtrl.js b/www/js/MontageHistoryCtrl.js
index e2782387..0373adcd 100644
--- a/www/js/MontageHistoryCtrl.js
+++ b/www/js/MontageHistoryCtrl.js
@@ -11,6 +11,9 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc
var viewCleaned = false;
$scope.isScreenReady = false;
+
+
+
//--------------------------------------------------------------------------------------
// Handles bandwidth change, if required
//
@@ -1064,6 +1067,18 @@ angular.module('zmApp.controllers').controller('zmApp.MontageHistoryCtrl', ['$sc
}
}
$scope.$on('$ionicView.beforeEnter', function () {
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> MontageHistoryCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+
// This rand is really used to reload the monitor image in img-src so it is not cached
// I am making sure the image in montage view is always fresh
// I don't think I am using this anymore FIXME: check and delete if needed
diff --git a/www/js/NewsCtrl.js b/www/js/NewsCtrl.js
index ba45fb0e..180f70d7 100644
--- a/www/js/NewsCtrl.js
+++ b/www/js/NewsCtrl.js
@@ -27,6 +27,8 @@ angular.module('zmApp.controllers').controller('zmApp.NewsCtrl', ['$scope', '$ro
}
};
+
+
//-------------------------------------------------------------------------
// Lets make sure we set screen dim properly as we enter
// The problem is we enter other states before we leave previous states
@@ -34,6 +36,22 @@ angular.module('zmApp.controllers').controller('zmApp.NewsCtrl', ['$scope', '$ro
// reset power state on exit as if it is called after we enter another
// state, that effectively overwrites current view power management needs
//------------------------------------------------------------------------
+
+
+ $scope.$on ('$ionicView.beforeEnter', function () {
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> NewsCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+ });
+
$scope.$on('$ionicView.enter', function () {
// console.log("**VIEW ** News Ctrl Entered");
NVRDataModel.setAwake(false);
diff --git a/www/js/PortalLoginCtrl.js b/www/js/PortalLoginCtrl.js
index 7fb4cc50..22bb46f8 100644
--- a/www/js/PortalLoginCtrl.js
+++ b/www/js/PortalLoginCtrl.js
@@ -5,33 +5,74 @@
/* global vis,cordova,StatusBar,angular,console,moment */
angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionicPlatform', '$scope', 'zm', 'NVRDataModel', '$ionicSideMenuDelegate', '$rootScope', '$http', '$q', '$state', '$ionicLoading', '$ionicPopover', '$ionicScrollDelegate', '$ionicModal', '$timeout', 'zmAutoLogin', '$ionicHistory', 'EventServer', '$translate', '$ionicPopup', function ($ionicPlatform, $scope, zm, NVRDataModel, $ionicSideMenuDelegate, $rootScope, $http, $q, $state, $ionicLoading, $ionicPopover, $ionicScrollDelegate, $ionicModal, $timeout, zmAutoLogin, $ionicHistory, EventServer, $translate, $ionicPopup) {
- var processPush = false;
+
var broadcastHandles = [];
+ var processPush = false;
+ var alreadyTransitioned = false;
$scope.$on('$ionicView.beforeLeave', function () {
- //processPush = false;
- // NVRDataModel.debug ("BeforeEnter in Portal: setting ProcessPush to false");
+ processPush = false;
+
});
+
+
$scope.$on('$ionicView.beforeLeave', function () {
- NVRDataModel.debug("Portal: Deregistering broadcast handles");
+ //NVRDataModel.debug("Portal: Deregistering broadcast handles");
for (var i = 0; i < broadcastHandles.length; i++) {
//broadcastHandles[i]();
}
broadcastHandles = [];
});
+
+ $scope.$on('$ionicView.beforeEnter',
+ function () {
+ alreadyTransitioned = false;
+
+ });
+
+
$scope.$on('$ionicView.enter',
function () {
+
+
+ $scope.$on ( "process-push", function () {
+ processPush = true;
+
+ if (!alreadyTransitioned) {
+ NVRDataModel.debug (">> PortalLogin: push handler, marking to resolve later");
+
+ }
+ else {
+ NVRDataModel.debug (">> PortalLoginCtrl: push handler");
+ processPush = false;
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ return;
+
+ }
+
+ });
+
+
NVRDataModel.setJustResumed(false);
NVRDataModel.debug("Inside Portal login Enter handler");
loginData = NVRDataModel.getLogin();
$ionicHistory.nextViewOptions({
+ disableAnimate:true,
disableBack: true
});
+
+
$scope.pindata = {};
if ($ionicSideMenuDelegate.isOpen()) {
$ionicSideMenuDelegate.toggleLeft();
@@ -153,6 +194,7 @@ angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionic
disableAnimate: true,
disableBack: true
});
+
$state.go("app.login", {
"wizard": false
});
@@ -244,6 +286,8 @@ angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionic
//NVRDataModel.debug ("logging state transition");
NVRDataModel.debug("2nd Auth: Transitioning state to: " +
statetoGo + " with param " + JSON.stringify($rootScope.lastStateParam));
+
+ alreadyTransitioned = true;
$state.go(statetoGo, $rootScope.lastStateParam);
return;
@@ -266,100 +310,8 @@ angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionic
}
- //this needs to be rootScope so it lives even when we are out of view
- var pp = $rootScope.$on("process-push", function () {
- NVRDataModel.debug("*** PROCESS PUSH HANDLER CALLED INSIDE PORTAL LOGIN, setting ProcessPush to true");
- processPush = true;
- evaluateTappedNotification();
-
-
- });
- broadcastHandles.push(pp);
-
- function evaluateTappedNotification() {
- var ld = NVRDataModel.getLogin();
-
- // give enough time for state conflicts to work out
- // that way PortalLogin doesn't override this
- // and I thought I was eliminating hacks....
- $timeout(function () {
- processPush = false;
- }, 1000);
-
-
- if ($rootScope.tappedNotification == 2) { // url launch
- NVRDataModel.debug("Came via app url launch with mid=" + $rootScope.tappedMid);
- NVRDataModel.debug("Came via app url launch with eid=" + $rootScope.tappedEid);
- $rootScope.tappedNotification = 0;
- $ionicHistory.nextViewOptions({
- disableBack: true
- });
-
- if (parseInt($rootScope.tappedMid) > 0) {
- NVRDataModel.debug("Going to live view ");
- $state.go("app.monitors");
- return;
-
- } else if (parseInt($rootScope.tappedEid) > 0) {
- NVRDataModel.debug("Going to events with EID=" + $rootScope.tappedEid);
- $state.go("app.events", {
- //"id": $rootScope.tappedEid,
- "id": 0,
- "playEvent": true
- }, {
- reload: true
- });
- return;
- }
- // go with monitor first, then event - just because I feel like ;)
-
-
- } else if ($rootScope.tappedNotification == 1) // push
- {
-
-
- NVRDataModel.log("Came via push tap. onTapScreen=" + ld.onTapScreen);
- $rootScope.pushOverride = true;
- //console.log ("***** NOTIFICATION TAPPED ");
- $rootScope.tappedNotification = 0;
- $ionicHistory.nextViewOptions({
- disableBack: true
- });
-
- if (ld.onTapScreen == $translate.instant('kTapMontage')) {
- NVRDataModel.debug("Going to montage");
- $state.go("app.montage");
-
- return;
- } else if (ld.onTapScreen == $translate.instant('kTapEvents')) {
- NVRDataModel.debug("Going to events");
- $state.go("app.events", {
- "id": 0,
- "playEvent": false
- });
- return;
- } else // we go to live
- {
- NVRDataModel.debug("Going to live view ");
- $state.go("app.monitors");
- return;
- }
- } else {
- /* NVRDataModel.debug ("Inside evaluateTapped, but no tap occured.");
- NVRDataModel.debug ("This can happen if timing mismatch and holy foo happens");
- $state.go("app.montage",
- {},
- {
- reload: true
- });
- return;*/
-
- }
-
- }
-
-
+ //broadcastHandles.push(pp);
function unlock(idVerified) {
/*
@@ -438,7 +390,7 @@ angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionic
NVRDataModel.zmPrivacyProcessed()
.then(function (val) {
- console.log(">>>>>>>>>>>>>>>>>>> PRIVACY PROCEESSED:" + val);
+ // console.log(">>>>>>>>>>>>>>>>>>> PRIVACY PROCESSED:" + val);
if (!val) {
var alertPopup = $ionicPopup.alert({
title: $translate.instant('kNote'),
@@ -456,21 +408,34 @@ angular.module('zmApp.controllers').controller('zmApp.PortalLoginCtrl', ['$ionic
// if push happens AFTER this, then while going to
// lastState, it will interrupt and go to onTap
// (I HOPE...)
- if (!processPush) {
+
//console.log ("NOTIFICATION TAPPED INSIDE CHECK IS "+$rootScope.tappedNotification);
var statetoGo = $rootScope.lastState ? $rootScope.lastState : 'app.montage';
// NVRDataModel.debug("logging state transition");
- NVRDataModel.debug("Transitioning state to: " +
+
+ if (!processPush) {
+ alreadyTransitioned = true;
+ NVRDataModel.debug("Transitioning state to: " +
statetoGo + " with param " + JSON.stringify($rootScope.lastStateParam));
$state.go(statetoGo, $rootScope.lastStateParam);
return;
+ }
+ else {
+ NVRDataModel.debug ("Deferred handling of push:");
+ processPush = false;
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ return;
+ }
+
- }
- // else
- // evaluateTappedNotification();
-
-
+
},
function (error) { // API Error
NVRDataModel.log("API Error handler: going to login getAPI returned error: " + JSON.stringify(error));
diff --git a/www/js/StateCtrl.js b/www/js/StateCtrl.js
index 62bffb81..34255287 100644
--- a/www/js/StateCtrl.js
+++ b/www/js/StateCtrl.js
@@ -26,27 +26,59 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
var apiRun = loginData.apiurl + "/host/daemonCheck.json";
var apiLoad = loginData.apiurl + "/host/getLoad.json";
- var apiDisk = loginData.apiurl + "/host/getDiskPercent.json";
+ var apiStorage = loginData.apiurl + "/storage.json";
+ var apiServer = loginData.apiurl + "/servers.json";
var apiCurrentState = loginData.apiurl + "/States.json";
var apiExec = loginData.apiurl + "/states/change/";
var inProgress = 0; // prevents user from another op if one is in progress
getRunStatus();
+ getLoadStatus();
+ getCurrentState();
+ getStorageStatus();
+ getServerStatus();
+
+
+// credit https://stackoverflow.com/a/14919494/1361529
+ $scope.humanFileSize = function(bytes, si) {
+ var thresh = si ? 1000 : 1024;
+ bytes = parseFloat(bytes);
+ if (isNaN(bytes)) bytes=0;
+ if(Math.abs(bytes) < thresh) {
+ return bytes + ' B';
+ }
+ var units = si? ['kB','MB','GB','TB','PB','EB','ZB','YB']:['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
+ var u = -1;
+ do {
+ bytes /= thresh;
+ ++u;
+ } while(Math.abs(bytes) >= thresh && u < units.length - 1);
+ return bytes.toFixed(1)+' '+units[u];
+};
+
+$scope.matchServer = function (id) {
+ var str = id;
+ var name = "";
+ for (var i=0; i< $scope.servers.length; i++) {
+ if ($scope.servers[i].Server.Id == id) {
+ name = $scope.servers[i].Server.Name;
+ break;
+ }
+ }
+ if (name) {
+ str = name + " ("+id+")";
+ }
+ return str;
+};
- // Let's stagger this by 500ms each to see if Chrome lets these through
- // This may also help if your Apache is not configured to let multiple connections through
-
- $timeout(function () {
- NVRDataModel.debug("invoking LoadStatus...");
- getLoadStatus();
- }, 2000);
-
- $timeout(function () {
- NVRDataModel.debug("invoking CurrentState...");
- getCurrentState();
- }, 4000);
+$scope.toggleStorage = function() {
+ $scope.showStorage = !$scope.showStorage;
+};
+$scope.toggleServer = function() {
+ $scope.showServer = !$scope.showServer;
+};
/*
$timeout(function () {
NVRDataModel.debug("invoking DiskStatus...");
@@ -60,6 +92,25 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
// reset power state on exit as if it is called after we enter another
// state, that effectively overwrites current view power management needs
//------------------------------------------------------------------------
+
+
+ $scope.$on ('$ionicView.beforeEnter', function () {
+
+ $scope.showStorage = true;
+ $scope.showServer = true;
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> StateCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+ });
+
$scope.$on('$ionicView.enter', function () {
// console.log("**VIEW ** Montage Ctrl Entered");
NVRDataModel.setAwake(false);
@@ -175,22 +226,46 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
}
//----------------------------------------------------------------------
- // returns disk space in gigs taken up by events
+ // returns Storage data
//----------------------------------------------------------------------
- function getDiskStatus() {
- NVRDataModel.debug("StateCtrl/getDiskStatus: " + apiDisk);
- $http.get(apiDisk)
+ function getStorageStatus() {
+
+ $scope.storage = [];
+ NVRDataModel.debug("StorageStatus: " + apiStorage);
+ $http.get(apiStorage)
.then(
function (success) {
- NVRDataModel.debug("StateCtrl/getDiskStatus: success");
- NVRDataModel.debug("Disk results: " + JSON.stringify(success));
- var obj = success.data.usage;
- if (obj.Total.space != undefined) {
- $scope.zmDisk = parseFloat(obj.Total.space).toFixed(1).toString() + "G";
- } else {
- $scope.zmDisk = "unknown";
- NVRDataModel.log("Error retrieving disk space, API returned null for obj.Total.space");
+
+ $scope.storage = success.data.storage;
+ //console.log (JSON.stringify($scope.storage));
+
+ },
+ function (error) {
+ $scope.zmDisk = "unknown";
+ // console.log("ERROR:" + JSON.stringify(error));
+ NVRDataModel.log("Error retrieving DiskStatus: " + JSON.stringify(error), "error");
+ }
+ );
+ }
+
+
+ //----------------------------------------------------------------------
+ // returns Storage data
+ //----------------------------------------------------------------------
+ function getServerStatus() {
+
+ $scope.servers = [];
+ NVRDataModel.debug("ServerStatus: " + apiStorage);
+ $http.get(apiServer)
+ .then(
+ function (success) {
+
+ $scope.servers = success.data.servers;
+ if ($scope.servers.length > 0) {
+ $scope.zmRun =$translate.instant('kStateMultiServer');
+ $scope.color = 'grey';
}
+ // console.log (JSON.stringify($scope.storage));
},
function (error) {
@@ -205,6 +280,10 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
// returns ZM running status
//----------------------------------------------------------------------
function getRunStatus() {
+
+
+
+
NVRDataModel.debug("StateCtrl/getRunStatus: " + apiRun);
$http.get(apiRun)
.then(
@@ -367,9 +446,10 @@ angular.module('zmApp.controllers').controller('zmApp.StateCtrl', ['$ionicPopup'
//console.log("***Pull to Refresh");
NVRDataModel.debug("StateCtrl/refresh: calling getRun/Load/Disk/CurrentState");
getRunStatus();
- $timeout(getLoadStatus, 2000);
- $timeout(getCurrentState, 4000);
- //$timeout (getDiskStatus,6000);
+ getLoadStatus();
+ getCurrentState();
+ getStorageStatus();
+ getServerStatus();
$scope.$broadcast('scroll.refreshComplete');
};
diff --git a/www/js/TimelineCtrl.js b/www/js/TimelineCtrl.js
index e1fbc4ef..bfcb34da 100644
--- a/www/js/TimelineCtrl.js
+++ b/www/js/TimelineCtrl.js
@@ -20,6 +20,7 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
$ionicSideMenuDelegate.toggleLeft();
};
+
//---------------------------------------f-------------------------
// Alarm notification handling
//----------------------------------------------------------------
@@ -283,9 +284,9 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
}
- NVRDataModel.debug("Timeline: Deregistering broadcast handles");
+ //NVRDataModel.debug("Timeline: Deregistering broadcast handles");
for (var i = 0; i < broadcastHandles.length; i++) {
- // broadcastHandles[i]();
+ broadcastHandles[i]();
}
broadcastHandles = [];
@@ -306,6 +307,19 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
$scope.$on('$ionicView.beforeEnter', function () {
+
+
+ $scope.$on ( "process-push", function () {
+ NVRDataModel.debug (">> TimelineCtrl: push handler");
+ var s = NVRDataModel.evaluateTappedNotification();
+ NVRDataModel.debug("tapped Notification evaluation:"+ JSON.stringify(s));
+ $ionicHistory.nextViewOptions({
+ disableAnimate:true,
+ disableBack: true
+ });
+ $state.go(s[0],s[1],s[2]);
+ });
+
//$ionicHistory.clearCache();
//$ionicHistory.clearHistory();
timeline = '';
@@ -864,11 +878,11 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
myevents[j].Event.MonitorName = NVRDataModel.getMonitorName(myevents[j].Event.MonitorId);
myevents[j].Event.streamingURL = NVRDataModel.getStreamingURL(myevents[j].Event.MonitorId);
- myevents[j].Event.baseURL = NVRDataModel.getBaseURL(myevents[j].Event.MonitorId);
+ myevents[j].Event.recordingURL = NVRDataModel.getRecordingURL(myevents[j].Event.MonitorId);
myevents[j].Event.imageMode = NVRDataModel.getImageMode(myevents[j].Event.MonitorId);
- if (NVRDataModel.getLogin().url != myevents[j].Event.baseURL) {
+ if (NVRDataModel.getLogin().url != myevents[j].Event.recordingURL) {
- myevents[j].Event.baseURL = NVRDataModel.getLogin().url;
+ myevents[j].Event.recordingURL = NVRDataModel.getLogin().url;
}
if (typeof myevents[j].Event.DefaultVideo === 'undefined')
@@ -1168,16 +1182,14 @@ angular.module('zmApp.controllers').controller('zmApp.TimelineCtrl', ['$ionicPla
// now construct base path
myevents[i].Event.streamingURL = NVRDataModel.getStreamingURL(myevents[i].Event.MonitorId);
- myevents[i].Event.baseURL = NVRDataModel.getBaseURL(myevents[i].Event.MonitorId);
+ myevents[i].Event.recordingURL = NVRDataModel.getRecordingURL(myevents[i].Event.MonitorId);
myevents[i].Event.imageMode = NVRDataModel.getImageMode(myevents[i].Event.MonitorId);
- if (NVRDataModel.getLogin().url != myevents[i].Event.baseURL) {
+ if (NVRDataModel.getLogin().url != myevents[i].Event.recordingURL) {
//NVRDataModel.debug ("Multi server, changing base");
- myevents[i].Event.baseURL = NVRDataModel.getLogin().url;
+ myevents[i].Event.recordingURL = NVRDataModel.getLogin().url;
}
- // console.log ("***** MULTISERVER STREAMING URL FOR EVENTS " + myevents[i].Event.streamingURL);
-
- // console.log ("***** MULTISERVER BASE URL FOR EVENTS " + myevents[i].Event.baseURL);
+
if (idfound) {
diff --git a/www/js/TimelineModalCtrl.js b/www/js/TimelineModalCtrl.js
index 238d271a..11c604f1 100644
--- a/www/js/TimelineModalCtrl.js
+++ b/www/js/TimelineModalCtrl.js
@@ -47,15 +47,11 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', '
$scope.constructFrames = function (event, alarm) {
var stream = "";
- if (event.Event.imageMode == 'path') {
- stream = event.Event.baseURL + "/index.php?view=image" +
- "&path=" + event.Event.relativePath + alarm.fname +
- "&height=380";
- } else if (event.Event.imageMode == 'fid') {
- stream = event.Event.baseURL + "/index.php?view=image" +
+
+ stream = event.Event.recordingURL + "/index.php?view=image" +
"&fid=" + alarm.id;
- }
+
if ($rootScope.authSession != 'undefined') stream += $rootScope.authSession;
stream += NVRDataModel.insertBasicAuthToken();
@@ -125,13 +121,10 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', '
$scope.showImage = function (p, r, f, fid, e, imode, id) {
var img;
//console.log("Image Mode " + imode);
- if (imode == 'path')
-
- img = "<img width='100%' ng-src='" + p + "/index.php?view=image&path=" + r + f + "'>";
- else {
+
img = "<img width='100%' ng-src='" + p + "/index.php?view=image&fid=" + id + "'>";
// console.log ("IS MULTISERVER SO IMAGE IS " + img);
- }
+
$rootScope.zmPopup = $ionicPopup.alert({
title: 'frame:' + fid + '/Event:' + e,
template: img,
@@ -300,7 +293,7 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', '
fid: event.event.Frame[i].FrameId,
id: event.event.Frame[i].Id,
//group:i,
- relativePath: computeRelativePath(event.event),
+
score: event.event.Frame[i].Score,
fname: padToN(event.event.Frame[i].FrameId, eventImageDigits) + "-capture.jpg",
@@ -317,7 +310,7 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', '
eid: event.event.Event.Id,
fid: event.event.Frame[i].FrameId,
//group:i,
- relativePath: computeRelativePath(event.event),
+
score: event.event.Frame[i].Score,
fname: padToN(event.event.Frame[i].FrameId, eventImageDigits) + "-capture.jpg",
id: event.event.Frame[i].Id,
@@ -361,10 +354,10 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', '
//console.log ("You tapped " + ndx);
$scope.alarm_images = [];
- $scope.playbackURL = $scope.event.Event.baseURL;
+ $scope.playbackURL = $scope.event.Event.recordingURL;
var items = current_data.datasets[0].frames[ndx];
$scope.alarm_images.push({
- relativePath: items.relativePath,
+
fid: items.fid,
id: items.id,
fname: items.fname,
@@ -376,56 +369,7 @@ angular.module('zmApp.controllers').controller('TimelineModalCtrl', ['$scope', '
}
- //--------------------------------------------------------
- // utility function
- //--------------------------------------------------------
-
- function computeRelativePath(event) {
- var relativePath = "";
- var loginData = NVRDataModel.getLogin();
- var str = event.Event.StartTime;
- var yy = moment(str).locale('en').format('YY');
- var mm = moment(str).locale('en').format('MM');
- var dd = moment(str).locale('en').format('DD');
- var hh = moment(str).locale('en').format('HH');
- var min = moment(str).locale('en').format('mm');
- var sec = moment(str).locale('en').format('ss');
- relativePath = event.Event.MonitorId + "/" +
- yy + "/" +
- mm + "/" +
- dd + "/" +
- hh + "/" +
- min + "/" +
- sec + "/";
- return relativePath;
-
- }
-
- //--------------------------------------------------------
- // utility function
- //--------------------------------------------------------
-
- function computeBasePath(event) {
- var basePath = "";
- var loginData = NVRDataModel.getLogin();
- var str = event.Event.StartTime;
- var yy = moment(str).locale('en').format('YY');
- var mm = moment(str).locale('en').format('MM');
- var dd = moment(str).locale('en').format('DD');
- var hh = moment(str).locale('en').format('HH');
- var min = moment(str).locale('en').format('mm');
- var sec = moment(str).locale('en').format('ss');
-
- basePath = loginData.url + "/events/" +
- event.Event.MonitorId + "/" +
- yy + "/" +
- mm + "/" +
- dd + "/" +
- hh + "/" +
- min + "/" +
- sec + "/";
- return basePath;
- }
+
function humanizeTime(str) {
return moment.tz(str, NVRDataModel.getTimeZoneNow()).fromNow();
diff --git a/www/js/WizardCtrl.js b/www/js/WizardCtrl.js
index f4b3d456..8a5f1ac4 100644
--- a/www/js/WizardCtrl.js
+++ b/www/js/WizardCtrl.js
@@ -2,7 +2,7 @@
/* jslint browser: true*/
/* global cordova,StatusBar,angular,console, Masonry, URI */
-angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$rootScope', '$ionicModal', 'NVRDataModel', '$ionicSideMenuDelegate', '$ionicHistory', '$state', '$ionicPopup', 'SecuredPopups', '$http', '$q', 'zm', '$ionicLoading', 'WizardHandler', '$translate', function ($scope, $rootScope, $ionicModal, NVRDataModel, $ionicSideMenuDelegate, $ionicHistory, $state, $ionicPopup, SecuredPopups, $http, $q, zm, $ionicLoading, WizardHandler, $translate) {
+angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$rootScope', '$ionicModal', 'NVRDataModel', '$ionicSideMenuDelegate', '$ionicHistory', '$state', '$ionicPopup', 'SecuredPopups', '$http', '$q', 'zm', '$ionicLoading', 'WizardHandler', '$translate', '$cookies', function ($scope, $rootScope, $ionicModal, NVRDataModel, $ionicSideMenuDelegate, $ionicHistory, $state, $ionicPopup, SecuredPopups, $http, $q, zm, $ionicLoading, WizardHandler, $translate, $cookies) {
$scope.openMenu = function () {
$ionicSideMenuDelegate.toggleLeft();
};
@@ -342,6 +342,26 @@ angular.module('zmApp.controllers').controller('zmApp.WizardCtrl', ['$scope', '$
function logout(u) {
var d = $q.defer();
+ NVRDataModel.debug ("Clearing cookies");
+ if (window.cordova) {
+ // we need to do this or ZM will send same auth hash
+ // this was fixed in a PR dated Oct 18
+
+ cordova.plugin.http.clearCookies();
+ }
+ else {
+ angular.forEach($cookies, function (v, k) {
+ $cookies.remove(k);
+ });
+ }
+
+ if ($scope.wizard.useauth && $scope.wizard.usebasicauth) {
+ NVRDataModel.debug ("setting basic auth with "+$scope.wizard.basicuser+":"+$scope.wizard.basicpassword);
+ cordova.plugin.http.useBasicAuth($scope.wizard.basicuser, $scope.wizard.basicpassword);
+
+ }
+
+
$http({
method: 'POST',
diff --git a/www/js/app.js b/www/js/app.js
index fef31358..cf64c31b 100755
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -28,7 +28,8 @@ angular.module('zmApp', [
'uk.ac.soton.ecs.videogular.plugins.cuepoints',
'dcbImgFallback',
'ngImageAppear',
- 'angular-websocket'
+ 'angular-websocket',
+ 'ngCookies'
])
@@ -41,7 +42,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: '2.0',
+ minEventServerVersion: '2.4',
castAppId: 'BA30FB4C',
alarmFlashTimer: 20000, // time to flash alarm
gcmSenderId: '710936220256',
@@ -49,7 +50,7 @@ angular.module('zmApp', [
largeHttpTimeout: 30000,
logFile: 'zmNinjaLog.txt',
authoremail: 'pliablepixels+zmNinja@gmail.com',
- logFileMaxSize: 30000, // after this limit log gets reset
+ logFileMaxSize: 100000, // after this limit log gets reset
updateCheckInterval: 86400000, // 24 hrs
loadingTimeout: 15000,
@@ -714,6 +715,14 @@ angular.module('zmApp', [
}
//console.log ("HTTP response");
+
+
+ if (response.data && typeof(response.data) == 'string' && response.data.startsWith("<pre class=\"cake-error\">")) {
+ console.log ("cake error detected, attempting fix...");
+ response.data = JSON.parse(response.data.replace(/<pre class=\"cake-error\">[\s\S]*<\/pre>/,''));
+ //console.log ("FIXED="+response.data);
+ }
+ //"data":"<pre class=\"cake-error\">
return response;
}
@@ -852,7 +861,7 @@ angular.module('zmApp', [
// This service automatically logs into ZM at periodic intervals
//------------------------------------------------------------------
- .factory('zmAutoLogin', function ($interval, NVRDataModel, $http, zm, $browser, $timeout, $q, $rootScope, $ionicLoading, $ionicPopup, $state, $ionicContentBanner, EventServer, $ionicHistory, $translate) {
+ .factory('zmAutoLogin', ['$interval', 'NVRDataModel', '$http', 'zm', '$timeout', '$q', '$rootScope', '$ionicLoading', '$ionicPopup', '$state', '$ionicContentBanner', 'EventServer', '$ionicHistory', '$translate', '$cookies',function ($interval, NVRDataModel, $http, zm, $timeout, $q, $rootScope, $ionicLoading, $ionicPopup, $state, $ionicContentBanner, EventServer, $ionicHistory, $translate, $cookies) {
var zmAutoLoginHandle;
//------------------------------------------------------------------
@@ -956,17 +965,34 @@ angular.module('zmApp', [
// which actually means auth failed, but ZM treats it as a success
//------------------------------------------------------------------
+ function _doLoginNoLogout (str) {
+
+ return _doLogin(str);
+ }
+
+ function _doLogoutAndLogin(str) {
+ NVRDataModel.debug ("Clearing cookies");
- function doLogoutAndLogin(str) {
+ if (window.cordova) {
+ // we need to do this or ZM will send same auth hash
+ // this was fixed in a PR dated Oct 18
+
+ cordova.plugin.http.clearCookies();
+ }
+ /* else {
+ angular.forEach($cookies, function (v, k) {
+ $cookies.remove(k);
+ });
+ }*/
return NVRDataModel.logout()
.then(function (ans) {
- return doLogin(str);
+ return _doLogin(str);
});
}
- function doLogin(str) {
+ function _doLogin(str) {
var d = $q.defer();
var ld = NVRDataModel.getLogin();
@@ -979,13 +1005,6 @@ angular.module('zmApp', [
return d.promise;
}
-
- if ($rootScope.isDownloading) {
- NVRDataModel.log("Skipping login process as we are downloading...");
- d.resolve("success");
- return d.promise;
- }
-
NVRDataModel.debug("Resetting zmCookie...");
$rootScope.zmCookie = '';
// first try to login, if it works, good
@@ -995,7 +1014,7 @@ angular.module('zmApp', [
proceedWithLogin()
.then(function (success) {
- NVRDataModel.debug("Storing login time as " + moment().toString());
+ //NVRDataModel.debug("Storing login time as " + moment().toString());
localforage.setItem("lastLogin", moment().toString());
d.resolve(success);
return d.promise;
@@ -1115,7 +1134,7 @@ angular.module('zmApp', [
if (!succ.version) {
NVRDataModel.debug("API login returned fake success, going back to webscrape");
- var ld = NVRDataModel.getLogin();
+ ld = NVRDataModel.getLogin();
ld.loginAPISupported = false;
NVRDataModel.setLogin(ld);
@@ -1132,6 +1151,7 @@ angular.module('zmApp', [
return d.promise;
}
NVRDataModel.debug("API based login returned... ");
+ console.log (JSON.stringify(succ));
NVRDataModel.setCurrentServerVersion(succ.version);
$ionicLoading.hide();
//$rootScope.loggedIntoZm = 1;
@@ -1157,11 +1177,12 @@ angular.module('zmApp', [
d.resolve("Login Success");
-
$rootScope.$broadcast('auth-success', succ);
+ return d.promise;
+
} catch (e) {
NVRDataModel.debug("Login API approach did not work...");
- var ld = NVRDataModel.getLogin();
+ ld = NVRDataModel.getLogin();
ld.loginAPISupported = false;
NVRDataModel.setLogin(ld);
loginWebScrape()
@@ -1217,7 +1238,7 @@ angular.module('zmApp', [
}
- );
+ ); // post
@@ -1380,7 +1401,7 @@ angular.module('zmApp', [
$interval.cancel(zmAutoLoginHandle);
//doLogin();
zmAutoLoginHandle = $interval(function () {
- doLogin("");
+ _doLogin("");
}, zm.loginInterval); // Auto login every 5 minutes
// PHP timeout is around 10 minutes
@@ -1400,9 +1421,11 @@ angular.module('zmApp', [
return {
start: start,
stop: stop,
- doLogin: doLogoutAndLogin
+ doLogin: _doLogoutAndLogin,
+ doLoginNoLogout: _doLoginNoLogout
+
};
- })
+ }])
//====================================================================
// First run in ionic
@@ -1414,6 +1437,7 @@ angular.module('zmApp', [
$ionicPlatform.ready(function () {
//console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>INSIDE RUN");
+ NVRDataModel.log("******* app .run device ready");
$fileLogger.setStorageFilename(zm.logFile);
$fileLogger.setTimestampFormat('MMM d, y ' + NVRDataModel.getTimeFormatSec());
@@ -1452,26 +1476,6 @@ angular.module('zmApp', [
NVRDataModel.log("You are running on " + $rootScope.platformOS);
- /*if (window.cordova && $rootScope.platformOS == 'android') {
-
- cordova.plugins.diagnostic.isExternalStorageAuthorized(function (authorized) {
- if (!authorized) cordova.plugins.diagnostic.requestExternalStorageAuthorization(okperm, nopermerr);
- }, function (err) {
- console.log("diagnostic external storage error " + err);
- });
-
-
- }*/
-
-
- function nopermerr() {
- NVRDataModel.displayBanner('error', ['Storage permission must be allowed'], "", 4000);
- }
-
- function okperm() {
- //console.log("cool");
- NVRDataModel.displayBanner('success', ['Storage permission acquired'], "", 4000);
- }
$rootScope.appName = "zmNinja";
$rootScope.zmGlobalCookie = "";
@@ -1508,12 +1512,16 @@ angular.module('zmApp', [
//navigator.app.exitApp();
};
-
+
// This is a global exception interceptor
$rootScope.exceptionMessage = function (error) {
NVRDataModel.debug("**EXCEPTION**" + error.reason + " caused by " + error.cause);
};
+ // for .config block
+ $rootScope.debug = function (msg) {
+ NVRDataModel.debug(msg);
+ };
if ($rootScope.platformOS == 'desktop' && 0) {
@@ -1656,29 +1664,37 @@ angular.module('zmApp', [
// lets see if it really works
$rootScope.online = navigator.onLine;
- document.addEventListener("offline", function () {
- //console.log ("OFFLINE------------------------------------");
+ // set up network state handlers after 3secs
+ // android seems to howl about this at app start?
+ $timeout (function() {
+
+ NVRDataModel.log ("--------->Setting up network state handlers....");
+ document.addEventListener("offline", onOffline, false);
+ document.addEventListener("online", onOnline, false);
+
+ },3000);
+
+
+ function onOffline() {
$timeout(function () {
$rootScope.online = false;
- NVRDataModel.log("Your network went offline");
+ NVRDataModel.log("************** Your network went offline");
//$rootScope.$emit('network-change', "offline");
});
- }, false);
+ }
- document.addEventListener("online", function () {
- //console.log ("ONLINE------------------------------------");
+ function onOnline() {
$timeout(function () {
-
-
- NVRDataModel.log("Your network came back online");
+ if ($rootScope.online == true) {
+ NVRDataModel.log ("**** network online, but looks like it was not offline, not doing anything");
+ return;
+ }
+ NVRDataModel.log("************ Your network came back online");
$rootScope.online = true;
-
- $timeout(function () {
- // NVRDataModel.debug ("Ignoring - Alex R. Hack");
- if (0) {
+
var networkState = "browser not supported";
if (navigator.connection) networkState = navigator.connection.type;
NVRDataModel.debug("Detected network type as: " + networkState);
@@ -1693,15 +1709,13 @@ angular.module('zmApp', [
NVRDataModel.debug("Not changing bandwidth state, as auto change is not on");
}
NVRDataModel.log("Your network is online, re-authenticating");
- zmAutoLogin.doLogin($translate.instant('kReAuthenticating'));
- }
-
- }, 1000); // need a time gap, seems network type registers late
-
-
+ zmAutoLogin.doLoginNoLogout($translate.instant('kReAuthenticating'));
+
});
- }, false);
+
+ }
+
// This code takes care of trapping the Android back button
// and takes it to the menu.
@@ -1787,7 +1801,7 @@ angular.module('zmApp', [
toState.name != "app.zm-portal-login"
) {
- NVRDataModel.debug("Setting last-desktop-state to:" + JSON.stringify(toState));
+ // NVRDataModel.debug("Setting last-desktop-state to:" + JSON.stringify(toState));
localforage.setItem('last-desktop-state', {
'name': toState.name,
'params': toState.params
@@ -1826,7 +1840,7 @@ angular.module('zmApp', [
// to work in Windows
- NVRDataModel.debug("Setting last-desktop-state to:" + JSON.stringify(toState) + " with params:" + JSON.stringify(toParams));
+ //NVRDataModel.debug("Setting last-desktop-state to:" + JSON.stringify(toState) + " with params:" + JSON.stringify(toParams));
localforage.setItem('last-desktop-state', {
'name': toState,
'params': toParams
@@ -1998,7 +2012,7 @@ angular.module('zmApp', [
$rootScope.$stateParams = $stateParams;
if (window.cordova) {
- console.log("------------->Keyboard foonone");
+
//window.cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
@@ -2082,7 +2096,7 @@ angular.module('zmApp', [
localforage.getItem('last-desktop-state')
.then(function (succ) {
- console.log("FOUND STATE" + JSON.stringify(succ) + ":" + succ);
+// console.log("FOUND STATE" + JSON.stringify(succ) + ":" + succ);
// sanitize this
if (!succ.name || typeof succ.name !== 'string') {
@@ -2157,10 +2171,19 @@ angular.module('zmApp', [
function resumeHandler() {
+
NVRDataModel.setBackground(false);
NVRDataModel.setJustResumed(true);
$ionicPlatform.ready(function () {
+
+ NVRDataModel.log("******* resumeHandler device ready");
NVRDataModel.log("App is resuming from background");
+
+ NVRDataModel.log ("-->Re-registering online/offine");
+ document.addEventListener("offline", onOffline, false);
+ document.addEventListener("online", onOnline, false);
+
+
$rootScope.isDownloading = false;
var ld = NVRDataModel.getLogin();
@@ -2178,8 +2201,8 @@ angular.module('zmApp', [
$rootScope.lastState = $ionicHistory.currentView().stateName;
$rootScope.lastStateParam =
$ionicHistory.currentView().stateParams;
- NVRDataModel.debug("Last State recorded:" +
- JSON.stringify($ionicHistory.currentView()));
+ //NVRDataModel.debug("Last State recorded:" +
+ //JSON.stringify($ionicHistory.currentView()));
if ($rootScope.lastState == "app.zm-portal-login") {
NVRDataModel.debug("Last state was portal-login, so forcing montage");
@@ -2208,6 +2231,11 @@ angular.module('zmApp', [
}
function pauseHandler() {
+
+ NVRDataModel.log ("-->Clearing online/offine");
+ document.removeEventListener("offline", onOffline, false);
+ document.removeEventListener("online", onOnline, false);
+
NVRDataModel.setBackground(true);
NVRDataModel.setJustResumed(false);
// NVRDataModel.setJustResumed(true); // used for window stop
@@ -2255,7 +2283,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, $injector) {
//$logProvider.debugEnabled(false);
//$compileProvider.debugInfoEnabled(false);
@@ -2286,9 +2314,10 @@ angular.module('zmApp', [
// 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) {
+ $provide.decorator('$http', ['$delegate', '$q', '$injector', function ($delegate, $q, $injector) {
// create function which overrides $http function
var $http = $delegate;
+ var logger = $injector.get("$rootScope");
var wrapper = function () {
var url;
@@ -2300,19 +2329,31 @@ angular.module('zmApp', [
if (window.cordova && isOutgoingRequest) {
+
var d = $q.defer();
var options = {
method: method,
data: arguments[0].data,
headers: arguments[0].headers,
- timeout: arguments[0].timeout,
+ // timeout: arguments[0].timeout,
responseType: arguments[0].responseType
};
+
+ if (arguments[0].timeout) options.timeout = arguments[0].timeout;
// 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
+
+ // work around for cake-error leak
+
+ // console.log ("HTTP RESPONSE:" + JSON.stringify(succ.data));
+ if (succ.data && succ.data.startsWith("<pre class=\"cake-error\">") ) {
+ logger.debug ("**** Native: cake-error in message, trying fix...");
+ succ.data = JSON.parse(succ.data.replace(/<pre class=\"cake-error\">[\s\S]*<\/pre>/,''));
+ }
+
if (options.responseType == 'text') {
// don't parse into JSON
d.resolve({
@@ -2320,6 +2361,9 @@ angular.module('zmApp', [
});
return d.promise;
} else {
+
+
+
try {
d.resolve({
"data": JSON.parse(succ.data)
@@ -2337,7 +2381,7 @@ angular.module('zmApp', [
}
},
function (err) {
- console.log("*** Inside native HTTP error: " + JSON.stringify(err));
+ logger.debug("*** Inside native HTTP error: " + JSON.stringify(err));
d.reject(err);
return d.promise;
@@ -2495,12 +2539,12 @@ angular.module('zmApp', [
data: {
requireLogin: true
},
- resolve: {
+ /*resolve: {
message: function (NVRDataModel) {
// console.log("Inside app.montage resolve");
return NVRDataModel.getMonitors(0);
}
- },
+ },*/
url: "/monitors",
cache: false,
templateUrl: "templates/monitors.html",
diff --git a/www/lang/locale-ar.json b/www/lang/locale-ar.json
index 662bbc41..fc190a8c 100644
--- a/www/lang/locale-ar.json
+++ b/www/lang/locale-ar.json
@@ -250,7 +250,6 @@
"kSelectLanguage" :"اختيار اللغة",
"kSelectRunState" :"إختار وضع التشغيل",
"kSendingPTZ" :"Sending PTZ",
- "kSensitiveBody" :"will modify the logs when creating the final output to remove sensitive data like urls and passwords. However it is eventually your responsibility to make sure there is no sensitive data in the logs. Please make sure you review and edit the logs before you send it out",
"kSensitiveTitle" :"معلومات حساسة",
"kServerAdd" :"إضافة",
"kServerEmptyError" :"اسم الخادم لايمكن ان يكون فارغاً",
diff --git a/www/lang/locale-ba.json b/www/lang/locale-ba.json
index 6b0bef08..9ba1aa05 100644
--- a/www/lang/locale-ba.json
+++ b/www/lang/locale-ba.json
@@ -419,4 +419,3 @@
"kZMStopped" :"zaustavljeno",
"kZMUndetermined" :"neodređeno",
"kZMUpgradeNeeded" :"Potrebno ažurirati ZoneMinder"
-} \ No newline at end of file
diff --git a/www/lang/locale-de.json b/www/lang/locale-de.json
index 3292a558..b2cf65ed 100644
--- a/www/lang/locale-de.json
+++ b/www/lang/locale-de.json
@@ -15,6 +15,7 @@
"kApplyingChanges" :"Wende Änderungen an. Bitte warten",
"kArrangingImages" :"Ordne Kameras",
"kAt" :"um",
+ "kAuthHashDisabled" :"AUTH_HASH_LOGINS muss aktiviert werden, damit Bilder angezeigt werden. Starte bitte nach dem Aktivieren ZM neu.",
"kAuthSuccess" :"Authentifizierung erfolgreich",
"kAuthenticating" :"verbinde ",
"kAuthenticatingWebScrape" :"verbinde über Web Scrape",
@@ -73,7 +74,10 @@
"kDiscoveringAPI" :"Suche API",
"kDiscoveringCGI" :"Suche CGI",
"kDiscoveringPortal" :"Suche Portal",
+ "kDismiss" :"verwerfen",
"kDone" :"Erledigt",
+ "kDownload" :"Herunterladen",
+ "kDownloadVideoImage" :"Drücke den Knopf um das Video herunterzuladen. Bitte achte auf die Dateigröße, da es kein Fortschrittsbalken während des Downloads gibt.",
"kEmailNotConfigured" :"Email nicht eingerichtet",
"kEnable24hr" :"24-Stunden Zeitformat aktivieren",
"kEnableDebug" :"Aktiviere Debug Logs",
@@ -216,8 +220,11 @@
"kMonMonitor" :"Monitor",
"kMonNodect" :"Nodect",
"kMonNone" :"None",
+ "kMonPortalURL" :"Portal URL",
"kMonPreAlarm" :"pre-alarm",
"kMonRecord" :"Record",
+ "kMonRecordingURL" :"Aufnahme URL",
+ "kMonStreamingURL" :"Streaming URL",
"kMonitorSingleImageScale" :"Livebild Einzelbildgröße",
"kMonitors" :"Kameras",
"kMontage" :"Übersicht",
@@ -293,8 +300,8 @@
"kProfileChangeNotification" :"Du hast von {{oldName}} zu {{newName}} gewechselt. Bitte zuerst dieses Profil speichern",
"kProtect" :"Schutz",
"kPullToReload" :"Ziehen um Daten neu zu laden",
- "kReachabilityFailed" :"Anmeldung am Hauptserver fehlgeschlagen,versuche Reservesystem",
"kReAuthenticating" :"Erneute Authentifizierung",
+ "kReachabilityFailed" :"Anmeldung am Hauptserver fehlgeschlagen,versuche Reservesystem",
"kRecaptcha" :"Scheint so, dass Du reCaptcha aktiviert hast. Bitte schalte es aus, damit diese App funktioniert",
"kReconfirmPin" :"PIN bestätigen",
"kRecordingProgress" :"Aufnahme im Gange",
@@ -308,10 +315,11 @@
"kResumeDelay" :"Verzögerung resumen",
"kRetrievingProfileData" :"empfange Profildaten",
"kSave" :"Speichern",
- "kSavingSnapshot" :"Sichere Einzelbild ",
"kSaveToCloud" :"mit der Cloud synchronisieren",
- "kSaveToCloudIOS" :"sichere Einstellungen in Dein iCloud-Konto. Der Synchronisationsvorgang kann einige Stunden dauern",
"kSaveToCloudANDROID" :"sichere Einstellungen über den Backup Service von Android. Der Synchronisationsvorgang kann einige Stunden dauern",
+ "kSaveToCloudIOS" :"sichere Einstellungen in Dein iCloud-Konto. Der Synchronisationsvorgang kann einige Stunden dauern",
+ "kSavingSnapshot" :"Sichere Einzelbild ",
+ "kScheme" :"Schema",
"kScore" :"Punktzahl",
"kScrub" :"Analyse",
"kSearch" :"Suche",
@@ -324,7 +332,7 @@
"kSelectRunState" :"Status auswählen",
"kSelectSwitch" :"Ausgewähltes Profil wird geladen",
"kSendingPTZ" :"Sende PTZ",
- "kSensitiveBody" :"In der Log-Datei, welche nun zum verschicken erstellt wird, werden sensible Daten, wie URLs und Passwörter, entfernt. Überprüfe trotzdem, dass keine sensiblen Daten in dem Log sind, bevor Du die Datei verschickst.",
+ "kSensitiveBody" :"*** Bitte mache vor dem Versenden der Logdatei alle vertraulichen Daten unkenntlich. zmNinja versucht bereits Passwörter herauszufiltern, allerdings kann es sein, dass Passwörter erhalten bleiben, wenn Sie z.B. im URL enthalten sind. ***",
"kSensitiveTitle" :"Vertrauliche Daten",
"kServerAdd" :"Hinzufügen",
"kServerEmptyError" :"Servername darf nicht leer sein",
@@ -342,13 +350,22 @@
"kSpeed" :"Geschwindigkeit",
"kStart" :"Start",
"kStateAreYouSure" :"Bist Du sicher, dass Du folgendes tun möchtest ",
+ "kStateCpuLoad" :"CPU Auslastung",
+ "kStateDiskUsed" :"Festplatte benutzt",
+ "kStateFreeMem" :"Arbeitsspeicher frei",
"kStateHideControls" :"Verstecke ZoneMinder Bedienelemente",
+ "kStateHost" :"Host",
+ "kStatePath" :"Pfad",
+ "kStateServer" :"Server",
"kStateShowControls" :"Zeige ZoneMinder Bedienelemente",
+ "kStateStorage" :"Speicherplatz",
+ "kStateTotalMem" :"Arbeitsspeicher gesamt",
"kStatus" :"Status",
"kStop" :"Stop",
"kSuccess" :"erledigt",
"kSwitchingEvents" :"wechsle Ereignisse",
"kSystemStatus" :"Systemstatus",
+ "kTapDownloadLogs" :"Klicke auf den Button um die Logdateien herunterzuladen.",
"kTapEvents" :"Ereignisse",
"kTapLiveMonitor" :"Livebild",
"kTapMontage" :"Livebild",
@@ -366,6 +383,7 @@
"kToDate" :"Datum bis",
"kToTime" :"Zeit bis",
"kToastSearchingPage" :"Suchseite",
+ "kToggleSummary" :"Ergebnis durchschalten",
"kTrue" :"an",
"kTrying" :"versuche",
"kType" :"Typ",
@@ -384,7 +402,6 @@
"kVibrateOnPush" :"Bei Push vibrieren",
"kVideo" :"Video",
"kVideoError" :"Video nicht abspielbar.",
- "kVideoErrorMobile" :"Video nicht abspielbar. Versuche 'force image path for events' in den Entwicklereinstellungen zu aktivieren. Der Format kann auch inkompatibel mit einem mobilen Systenview sein",
"kVideoLoading" :"Lade Video",
"kVideoMp4Warning" :"Es ist aktuell nicht erkennbar, wann das Video komplett heruntergeladen ist. Bitte Downloadgröße verfolgen.",
"kWarningBasicAuth" :"Basisauthentifizierung kann das Abspielen des Livebilds stören. Bitte FAQ lesen",
diff --git a/www/lang/locale-en.json b/www/lang/locale-en.json
index b30f2d23..123a3445 100644
--- a/www/lang/locale-en.json
+++ b/www/lang/locale-en.json
@@ -18,7 +18,7 @@
"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",
+ "kAuthenticatingWebScrape" :"authenticating via web scrape",
"kAutoSwitchBW" :"auto switch bandwidth",
"kAwake1" :"Keep display on",
"kAwake2" :"(when viewing footage)",
@@ -52,7 +52,7 @@
"kCycleMonitorsInterval" :"monitor cycle interval",
"kCycleMontageInterval" :"montage cycle interval",
"kDataPrivacy" :"Data Privacy",
- "kDataPrivacyZM" : "zmNinja will not function properly till your process ZoneMinder's Privacy Policy. Please open ZoneMinder web console and accept or reject it.",
+ "kDataPrivacyZM" :"zmNinja will not function properly till your process ZoneMinder's Privacy Policy. Please open ZoneMinder web console and accept or reject it.",
"kDay" :"Day",
"kDecreaseSize" :"decrease size",
"kDelete" :"Delete",
@@ -74,10 +74,10 @@
"kDiscoveringAPI" :"discovering api",
"kDiscoveringCGI" :"discovering cgi",
"kDiscoveringPortal" :"discovering portal",
- "kDismiss" : "Dismiss",
+ "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",
+ "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",
@@ -220,8 +220,11 @@
"kMonMonitor" :"Monitor",
"kMonNodect" :"Nodect",
"kMonNone" :"None",
+ "kMonPortalURL" :"Portal url",
"kMonPreAlarm" :"pre-alarm",
"kMonRecord" :"record",
+ "kMonRecordingURL" :"Recording url",
+ "kMonStreamingURL" :"Streaming url",
"kMonitorSingleImageScale" :"Live view single image scale",
"kMonitors" :"Monitors",
"kMontage" :"Montage",
@@ -297,8 +300,8 @@
"kProfileChangeNotification" :"You have changed from {{oldName}} to {{newName}}. Please save this profile first",
"kProtect" :"protect",
"kPullToReload" :"pull to reload data",
- "kReachabilityFailed" : "primary login failed, trying fallbacks",
"kReAuthenticating" :"re-authenticating",
+ "kReachabilityFailed" :"primary login failed, trying fallbacks",
"kRecaptcha" :"Looks like you have enabled reCaptcha. It needs to be turned off for the app to work",
"kReconfirmPin" :"Reconfirm PIN",
"kRecordingProgress" :"recording in progress",
@@ -312,10 +315,11 @@
"kResumeDelay" :"resume delay",
"kRetrievingProfileData" :"retrieving profile data",
"kSave" :"Save",
- "kSavingSnapshot" :"saving snapshot",
"kSaveToCloud" :"sync with cloud",
- "kSaveToCloudIOS" :"saves settings to your personal iCloud account. May take several hours to sync",
"kSaveToCloudANDROID" :"saves settings via Android's Backup Service. May take several hours to sync",
+ "kSaveToCloudIOS" :"saves settings to your personal iCloud account. May take several hours to sync",
+ "kSavingSnapshot" :"saving snapshot",
+ "kScheme" :"Scheme",
"kScore" :"score",
"kScrub" :"Scrub",
"kSearch" :"search",
@@ -328,7 +332,7 @@
"kSelectRunState" :"Select run state",
"kSelectSwitch" :"Selected profile will be loaded",
"kSendingPTZ" :"Sending PTZ",
- "kSensitiveBody" :"will modify the logs when creating the final output to remove sensitive data like urls and passwords. However it is eventually your responsibility to make sure there is no sensitive data in the logs. Please make sure you review and edit the logs before you send it out",
+ "kSensitiveBody" :"*** Before you send the logs, please make sure you remove any sensitive information. zmNinja tries to filter out passwords, but it is possible that passwords will be included if you include them in URLs, for example ***",
"kSensitiveTitle" :"Sensitive Information",
"kServerAdd" :"Add",
"kServerEmptyError" :"Server Name cannot be empty",
@@ -346,13 +350,23 @@
"kSpeed" :"speed",
"kStart" :"Start",
"kStateAreYouSure" :"Are you sure you want to ",
+ "kStateCpuLoad" :"CPU Load",
+ "kStateDiskUsed" :"Disk Used",
+ "kStateFreeMem" :"Free Memory",
"kStateHideControls" :"Hide ZoneMinder Controls",
+ "kStateHost" :"Host",
+ "kStateMultiServer" :"multi server",
+ "kStatePath" :"Path",
+ "kStateServer" :"Server",
"kStateShowControls" :"Show ZoneMinder Controls",
+ "kStateStorage" :"Storage",
+ "kStateTotalMem" :"Total Memory",
"kStatus" :"Status",
"kStop" :"Stop",
"kSuccess" :"Success",
"kSwitchingEvents" :"switching events",
"kSystemStatus" :"System Status",
+ "kTapDownloadLogs" :"Tap the button to download logs",
"kTapEvents" :"Events",
"kTapLiveMonitor" :"Live Monitor",
"kTapMontage" :"Montage",
@@ -370,6 +384,7 @@
"kToDate" :"To Date",
"kToTime" :"To Time",
"kToastSearchingPage" :"searching page ",
+ "kToggleSummary" :"toggle summary",
"kTrue" :"true",
"kTrying" :"trying",
"kType" :"type",
@@ -387,8 +402,7 @@
"kVersionIncompatible" :"I am incompatible with your ZoneMinder version",
"kVibrateOnPush" :"Vibrate on push",
"kVideo" :"Video",
- "kVideoError" :"Video not playable.",
- "kVideoErrorMobile" :"Video not playable. Try enabling 'force image path for events' in Dev Settings. The format may also be incompatible with a mobile system view",
+ "kVideoError" :"Video not playable",
"kVideoLoading" :"Loading Video",
"kVideoMp4Warning" :"It is currently not possible to know when video is fully downloaded. Please track file size of download.",
"kWarningBasicAuth" :"Basic auth may interfere with live streaming. Please read FAQ",
diff --git a/www/lang/locale-es.json b/www/lang/locale-es.json
index 95375571..d4fb53a6 100644
--- a/www/lang/locale-es.json
+++ b/www/lang/locale-es.json
@@ -324,7 +324,6 @@
"kSelectRunState" :"Seleccionar estado de funcionamiento",
"kSelectSwitch" :"El perfil seleccionado será cargado",
"kSendingPTZ" :"Enviando PTZ",
- "kSensitiveBody" :"Se modificarán los registros cuando se cree la salida final para remover información sensible como urls y contraseñas. Sin embargo eventualmente es su responsabilidad el asegurarse que no haya información sensible en los registros. Por favor asegúrese de haber revisado y editado los registros antes de enviarlos.",
"kSensitiveTitle" :"Información Sensible",
"kServerAdd" :"Añadir",
"kServerEmptyError" :"El servidor debe tener un nombre válido.",
@@ -384,7 +383,6 @@
"kVibrateOnPush" :"Vibrar en notificaciones push",
"kVideo" :"Vídeo",
"kVideoError" :"El vídeo no se puede reproducir.",
- "kVideoErrorMobile" :"El vídeo no se puede reproducir. Trata de habilitar 'forzar el directorio para los eventos' en Opc de Desarrollador. El formato también podría ser incompatible con la vista en sistemas móviles",
"kVideoLoading" :"Cargando Vídeo",
"kVideoMp4Warning" :"Actualmente no es posible saber cuando el vídeo se ha descargado completamente. Por favor fíjese en el tamaño del archivo para tener un estimado.",
"kWarningBasicAuth" :"La autenticación básica puede interferir con stremings en vivo. Por favor lea las preguntas frecuentes.",
diff --git a/www/lang/locale-fr.json b/www/lang/locale-fr.json
index 8d507b0d..0b5dd537 100644
--- a/www/lang/locale-fr.json
+++ b/www/lang/locale-fr.json
@@ -287,7 +287,6 @@
"kSelectRunState" :"Choix du mode de fonctionnement",
"kSelectSwitch" :"Profil à charger",
"kSendingPTZ" :"Envoi PTZ",
- "kSensitiveBody" :"modifiera les logs lors de la création du rapport afin de supprimer les informations sensibles (mots de passe, URLs, etc.). Cependant il est de votre responsabilité de vérifier que les logs ne contiennent aucun information sensible. Merci de le faire avant l'envoi.",
"kSensitiveTitle" :"Informations sensibles",
"kServerAdd" :"Ajouter",
"kServerEmptyError" :"Le nom du serveur ne peut être vide",
@@ -341,7 +340,6 @@
"kVibrateOnPush" :"Vibrer en cas de notification",
"kVideo" :"Vidéo",
"kVideoError" :"Impossible de lire la vidéo.",
- "kVideoErrorMobile" :"Impossible de lire la vidéo. Essayez d'activer l'option 'Forcer le chemin des événements' dans les options développeur. Il se peut que le format soit incompatible avec les appareils mobiles",
"kVideoLoading" :"Chargement de la vidéo",
"kVideoMp4Warning" :"Impossible de déterminer l'avancement du téléchargement de la vidéo. Veuillez suivre la taille du fichier.",
"kWarningLargeTimeline" :"Une valeur élevée peut réduire les performances. Si vous trouvez le calendrier lent, essayez de réduire à la valeur 200 puis augmentez progressivement.",
diff --git a/www/lang/locale-hu.json b/www/lang/locale-hu.json
index 77a09b46..4f4db929 100644
--- a/www/lang/locale-hu.json
+++ b/www/lang/locale-hu.json
@@ -290,7 +290,6 @@
"kSelectRunState" :"Válassza ki a futási állapotot",
"kSelectSwitch" :"A kiválasztott profil betöltődik",
"kSendingPTZ" :"PTZ küldése",
- "kSensitiveBody" :"Módosítja a naplókat, amikor létrehozza a végső kimenetet az érzékeny adatok - például urls és jelszavak - eltávolításához. Végül azonban az Ön felelőssége, hogy győződjön meg arról, hogy nincsenek érzékeny adatok a naplókban. Kérjük, győződjön meg róla, hogy a naplófájlokat ellenőrizze és szerkesztette, mielőtt elküldené",
"kSensitiveTitle" :"Érzékeny információ",
"kServerAdd" :"Hozzáad",
"kServerEmptyError" :"A kiszolgáló neve nem lehet üres",
@@ -344,7 +343,6 @@
"kVibrateOnPush" :"Rezgés érintéskor",
"kVideo" :"Videó",
"kVideoError" :"A videó nem játszható le.",
- "kVideoErrorMobile" :"A videó nem játszható. Próbálja engedélyezni a 'Elérési út az eseményekhez' lehetőséget az eszköz beállításaiban. A formátum is összeegyeztethetetlen a mobil rendszer nézettel",
"kVideoLoading" :"Videó betöltése",
"kVideoMp4Warning" :"Jelenleg nem lehet tudni, hogy a videó teljesen letöltődik-e. Kérjük, kövesse nyomon a letöltés fájlméretét.",
"kWarningLargeTimeline" :"Nagy érték befolyásolhatja az idővonal teljesítményét. Ha az idővonal teljesítményét lassunak találja, próbálja csökkenteni a 200-as értéket, és folytassa tovább.",
diff --git a/www/lang/locale-it.json b/www/lang/locale-it.json
index a0e2ca06..930792c1 100644
--- a/www/lang/locale-it.json
+++ b/www/lang/locale-it.json
@@ -249,7 +249,6 @@
"kSelectLanguage" :"Seleziona Lingua",
"kSelectRunState" :"Seleziona modo operativo",
"kSendingPTZ" :"Invio PTZ",
- "kSensitiveBody" :"Dovrai modificare il log,quando lo vorrai inviare, dovrai togliere i tuoi dati sensibili. In ogni caso sarà tua responsabilità assicurarti che non ci siano dati sensibili. Fai attenzione a rimuovere i dati sensibili quando invii il log",
"kSensitiveTitle" :"Informazioni sensibili",
"kServerAdd" :"Aggiungi",
"kServerEmptyError" :"Il nome del server non può rimanere vuoto",
diff --git a/www/lang/locale-nl.json b/www/lang/locale-nl.json
index ab09023e..a6367952 100755
--- a/www/lang/locale-nl.json
+++ b/www/lang/locale-nl.json
@@ -282,7 +282,6 @@
"kSelectRunState" :"Uitvoerings modus selecteren",
"kSelectSwitch" :"Geselecteerde profiel wordt geladen",
"kSendingPTZ" :"PTZ zenden",
- "kSensitiveBody" :"in de opgeslagen log bestanden worden gevoelige gegevens zoals urls en wachtwoorden verwijderd. Het is echter uw verantwoordelijkheid om er zeker van te zijn dat er geen gevoelige gegevens achterblijven. Voordat u de bestanden verzendt verzeker u hiervan door deze na te kijken en indien nodig te bewerken.",
"kSensitiveTitle" :"Gevoelige informatie",
"kServerAdd" :"Toevoegen",
"kServerEmptyError" :"Server naam mag niet leeg zijn",
@@ -336,7 +335,6 @@
"kVibrateOnPush" :"Trillen bij push",
"kVideo" :"Video",
"kVideoError" :"Kan video niet afspelen.",
- "kVideoErrorMobile" :"Kan video niet afspelen. Probeer 'Dwing gebeurtenissen bestands map te gebruiken' te activeren in ontwikkelaars instellingen. Het formaat is wellicht ook niet compatible met mobiel systeem beeld",
"kVideoLoading" :"Video laden",
"kVideoMp4Warning" :"Het is niet mogelijk te detecteren wanneer video volledig is gedownload. Vergelijk grootte van de download.",
"kWarningLargeTimeline" :"Een hoge waarde kan de tijdlijn prestatie beïnvloeden. Bij slechte prestaties van de tijdlijn start met een waarde van 200 en verhoog deze langzaam.",
diff --git a/www/lang/locale-pl.json b/www/lang/locale-pl.json
index 486d0e0d..6a24dfcd 100644
--- a/www/lang/locale-pl.json
+++ b/www/lang/locale-pl.json
@@ -220,8 +220,11 @@
"kMonMonitor" :"Monitor",
"kMonNodect" :"Nodect",
"kMonNone" :"Żaden",
+ "kMonPortalURL" :"url Portalu",
"kMonPreAlarm" :"pre-alarm",
"kMonRecord" :"Record",
+ "kMonRecordingURL" :"url Nagrywania",
+ "kMonStreamingURL" :"url Streamingu",
"kMonitorSingleImageScale" :"Skalowanie pojedynczego obrazy Podglądu na żywo",
"kMonitors" :"Monitory",
"kMontage" :"Podgląd",
@@ -297,8 +300,8 @@
"kProfileChangeNotification" :"Zmieniłeś z {{oldName}} na {{newName}}. Zapisz wcześniej ten profil.",
"kProtect" :"zabezpiecz",
"kPullToReload" :"przeciągnij by przeładować dane",
- "kReachabilityFailed" :"podstawowe logowanie nie powiodło się, próbuję zapasowego",
"kReAuthenticating" :"ponowne uwierzytelnianie",
+ "kReachabilityFailed" :"podstawowe logowanie nie powiodło się, próbuję zapasowego",
"kRecaptcha" :"Wygląda na to, że właczyłeś reCaptcha. Powinna być wyłączona, żeby aplikacja działała.",
"kReconfirmPin" :"Potwierdź PIN",
"kRecordingProgress" :"trwa nagrywanie",
@@ -313,9 +316,10 @@
"kRetrievingProfileData" :"pobieranie danych profilu",
"kSave" :"Zapisz",
"kSaveToCloud" :"synchronizuj z chmurą",
- "kSaveToCloudIOS" :"zapisuje ustawienia na twoim koncie iCloud. Synchronizacja może zająć kilka godzin",
"kSaveToCloudANDROID" :"zapisuje ustawienia przez Serwis Backup Android'a. Synchronizacja może zająć kilka godzin",
+ "kSaveToCloudIOS" :"zapisuje ustawienia na twoim koncie iCloud. Synchronizacja może zająć kilka godzin",
"kSavingSnapshot" :"zapisuję obraz",
+ "kScheme" :"Schemat",
"kScore" :"punkty",
"kScrub" :"Podgląd",
"kSearch" :"szukaj",
@@ -328,7 +332,7 @@
"kSelectRunState" :"Wybierz stan działania",
"kSelectSwitch" :"Wybrany profil zostanie załadowany",
"kSendingPTZ" :"Wysyła PTZ",
- "kSensitiveBody" :"tworząc finalny log zmodyfikuje jego zawartość, aby usunąć wrażliwe dane takie jak linki czy hasła. Jednak na Tobie spoczywa odpowiedzialność upewnienia się, że wszystkie dane wrażliwe zostały usunięte. Upewnij się, że przeglądnąłeś i edytowałeś log przed jego wysłaniem",
+ "kSensitiveBody" :"*** Zanim wyślesz log, upewnij się, że usunąłeś wszystkie wrażliwe dane. zmNinja spróbuje usunąć hasła, jednak możliwe, że część z nich pozostanie, np. te umieszczone w adresach URL ***",
"kSensitiveTitle" :"Dane Wrażliwe",
"kServerAdd" :"Dodaj",
"kServerEmptyError" :"Nazwa serwera nie może być pusta",
@@ -346,13 +350,23 @@
"kSpeed" :"prędkość",
"kStart" :"Start",
"kStateAreYouSure" :"Jesteś pewien, że chcesz ",
+ "kStateCpuLoad" :"Obciążenie CPU",
+ "kStateDiskUsed" :"Dysku w użyciu",
+ "kStateFreeMem" :"Wolnej pamięci",
"kStateHideControls" :"Ukryj Przyciski ZoneMinder",
+ "kStateHost" :"Host",
+ "kStateMultiServer" :"wiele serwerów",
+ "kStatePath" :"Ścieżka",
+ "kStateServer" :"Serwer",
"kStateShowControls" :"Pokaż Przyciski ZoneMinder",
+ "kStateStorage" :"Pamięć",
+ "kStateTotalMem" :"Całość pamięci",
"kStatus" :"Stan",
"kStop" :"Stop",
"kSuccess" :"Sukces",
"kSwitchingEvents" :"przełączam zdarzenia",
"kSystemStatus" :"Stan Systemu",
+ "kTapDownloadLogs" :"Wciśnij przycisk by pobrać logi",
"kTapEvents" :"Zdarzenia",
"kTapLiveMonitor" :"Podgląd na żywo",
"kTapMontage" :"Podgląd",
@@ -370,6 +384,7 @@
"kToDate" :"Do Daty",
"kToTime" :"Do Czasu",
"kToastSearchingPage" :"szuka strony ",
+ "kToggleSummary" :"przełącz Zdarzenia na podsumowanie",
"kTrue" :"prawda",
"kTrying" :"próbuję",
"kType" :"typ",
@@ -387,8 +402,7 @@
"kVersionIncompatible" :"Jestem niekompatybilny z wersją Twojego ZoneMinder'a",
"kVibrateOnPush" :"Wibruj przy dotknięciu",
"kVideo" :"Wideo",
- "kVideoError" :"Wideo nie odtwarzalne.",
- "kVideoErrorMobile" :"Wideo nie odtwarzalne. Spróbuj włączyć 'wymuś ścieżkę obrazu dla zdarzenia' w Ustawieniach Zaawansowanych. Format może być też niekompatybilny z przeglądarką systemu mobilnego",
+ "kVideoError" :"Wideo nie odtwarzalne",
"kVideoLoading" :"Ładuję Wideo",
"kVideoMp4Warning" :"Obecnie nie ma możliwości stwierdzenia, czy wideo zostało w pełni ściągnięte. Sprawdź wielkość pliku do ściągnięcia.",
"kWarningBasicAuth" :"Prosta autoryzacja może powodować konflikt ze streamingiem na żywo. Proszę, przeczytaj FAQ",
diff --git a/www/lang/locale-pt.json b/www/lang/locale-pt.json
index 703f9048..276ff573 100644
--- a/www/lang/locale-pt.json
+++ b/www/lang/locale-pt.json
@@ -261,7 +261,6 @@
"kSelectLanguage" :"Escolher Linguagem",
"kSelectRunState" :"Escolher estado de execução",
"kSendingPTZ" :"Enviando PTZ",
- "kSensitiveBody" :"modificará os logs ao criar o resultado final para remover os dados sensíveis, como URLs e senhas. No entanto, é, eventualmente, da sua responsabilidade certificar-se de que não há dados sensíveis nos logs. Por favor, certifique-se de rever e editar os registos antes de enviá-lo para fora",
"kSensitiveTitle" :"Informação Sensivel",
"kServerAdd" :"Adicionar",
"kServerEmptyError" :"O Nome do Servidor tem de estar preenchido",
@@ -313,7 +312,6 @@
"kVibrateOnPush" :"Vibrar ao premir",
"kVideo" :"Vídeo",
"kVideoError" :"Vídeo não reproduzível.",
- "kVideoErrorMobile" :"Vídeo não reproduzível. Experimente ativar 'forçar o caminho da imagem para eventos' em Configurações Dev. O formato também pode ser incompatível com o sistema de visualização do equipamento móvel",
"kVideoLoading" :"Carregando Vídeo",
"kVideoMp4Warning" :"Não é possível de momento saber quando o vídeo está totalmente carregado. Por favor, verifique o tamnho do arquivo de download.",
"kWarningLargeTimeline" :"Um valor elevado pode afetar o desempenho da timeline. Se você achar o desempenho da timeline lento, tente reduzir o valor para 200 e trabalhe a partir daí.",
diff --git a/www/lang/locale-ru.json b/www/lang/locale-ru.json
index a359eb58..b79de803 100644
--- a/www/lang/locale-ru.json
+++ b/www/lang/locale-ru.json
@@ -266,7 +266,6 @@
"kSelectRunState" :"Выбрать состояние запуска",
"kSelectSwitch" :"Выбранный профиль будет загружен",
"kSendingPTZ" :"Отправка PTZ",
- "kSensitiveBody" :"пытается модифицировать логи когда создает отчет для обезличивания персональной информации например ссылок и паролей. Однако это ваша ответственность быть уверенным что логи не содержат конфиденциальную информацию. Перед тем как отправлять емейл, пожалуйста проверьте логи и подкорректируйте их если потребуется",
"kSensitiveTitle" :"Персональная Информация",
"kServerAdd" :"Добавить",
"kServerEmptyError" :"Имя сервера не может быть пустым",
@@ -318,7 +317,6 @@
"kVibrateOnPush" :"Вибрировать при нажатии",
"kVideo" :"Видео",
"kVideoError" :"Не возможно проиграть видео.",
- "kVideoErrorMobile" :"Не возможно проиграть видео. Попробуйте включить 'принудительный путь к картинкам для событий' в Настройках Разработчика. Формат может быть также не совместим с плеером мобильной системой",
"kVideoLoading" :"Загрузка Видео",
"kVideoMp4Warning" :"Сейчас не возможно определить когда видео будет полностью загружено. Пожалуйста следите за размером скачиваемого файла.",
"kWarningLargeTimeline" :"Большое значение может повлиять на производительность временной шкалы. Если производительность временной шкалы медленна, попробуйте уменьшить значение до 200.",
diff --git a/www/templates/events-modal.html b/www/templates/events-modal.html
index 164c3f62..319f8366 100644
--- a/www/templates/events-modal.html
+++ b/www/templates/events-modal.html
@@ -33,14 +33,15 @@
</div>
-
+
<img ng-if="!liveFeedMid" image-spinner-src="{{constructStream()}}" ng-class="{'object-fit_cover':imageFit==false, 'object-fit_contain':imageFit==true}"
on-double-tap="closeModal();" img-spinner-w="1024" img-spinner-h="768" image-spinner-loader="lines"
imageonload="modalImageLoaded()" on-swipe-left="onSwipeEvent(nextId,1)" on-swipe-right="onSwipeEvent(prevId,-1)" />
<div ng-if="liveFeedMid">
- <img image-spinner-src="{{loginData.streamingurl}}/nph-zms?mode=jpeg&monitor={{liveFeedMid}}&connkey={{connKey}}{{$root.authSession}}"
+
+ <img image-spinner-src="{{currentEvent.Event.streamingURL}}/nph-zms?mode=jpeg&monitor={{liveFeedMid}}&connkey={{connKey}}{{$root.authSession}}"
ng-class="{'object-fit_cover':imageFit==false, 'object-fit_contain':imageFit==true}" on-double-tap="closeModal();"
img-spinner-w="1024" img-spinner-h="768" image-spinner-loader="lines" imageonload="modalImageLoaded()"
on-swipe-left="onSwipeEvent(nextId,1)" on-swipe-right="onSwipeEvent(prevId,-1)" />
diff --git a/www/templates/events-popover.html b/www/templates/events-popover.html
index d61f8f5b..2620c9b3 100644
--- a/www/templates/events-popover.html
+++ b/www/templates/events-popover.html
@@ -11,8 +11,13 @@
</a>
<a class="item" ng-href="" ng-click="popover.hide();toggleMinAlarmFrameCount();" ng-if="loginData.enableAlarmCount">{{'kShowAllEvents'
| translate}}</a>
+
<a class="item" ng-href="" ng-click="popover.hide();toggleMinAlarmFrameCount();" ng-if="!loginData.enableAlarmCount">
{{'kShowAlarmedEvents' | translate}}</a>
+
+ <a class="item" ng-href="" ng-click="popover.hide();footerToggle();" >
+ {{ 'kToggleSummary' | translate}}</a>
+
</div>
</ion-content>
</ion-popover-view>
diff --git a/www/templates/events.html b/www/templates/events.html
index b312a79c..71522fa0 100644
--- a/www/templates/events.html
+++ b/www/templates/events.html
@@ -152,13 +152,13 @@
<span ng-repeat="alarm in alarm_images | selectFrames: typeOfFrames">
<figure class="animated slideInLeft" style="display:inline-block">
- <!--{{event.Event.baseURL}} p:{{event.Event.imageMode}}-->
+ <!--{{event.Event.recordingURL}} p:{{event.Event.imageMode}}-->
<figcaption class="smallnote">
<span translate="kFrame"></span>:{{alarm.frameid}},
<span translate="kScore"></span>:{{alarm.score}},
<span translate="kTime"></span>: {{prettifyTimeSec(alarm.time)}}</figcaption>
<img ng-src="{{constructAlarmFrame(event,alarm,true)}}" fallback-src="{{constructAlarmFrame(event,alarm,false)}}"
- style="width: auto; height: auto;max-width: 100%;max-height: 170px" on-tap="showImage(event.Event.baseURL,event.Event.relativePath,alarm.fname, alarm.frameid, event.Event.Id, event.Event.imageMode, alarm.id, alarm_images, $index)" />
+ style="width: auto; height: auto;max-width: 100%;max-height: 170px" on-tap="showImage(event.Event.recordingURL, alarm.fname, alarm.frameid, event.Event.Id, event.Event.imageMode, alarm.id, alarm_images, $index)" />
</figure>
diff --git a/www/templates/log.html b/www/templates/log.html
index 0ad840d8..2884c4bb 100644
--- a/www/templates/log.html
+++ b/www/templates/log.html
@@ -4,7 +4,10 @@
&nbsp;
<button ng-class="selectOn? 'button button-icon button-clear ion-ios-copy':'button button-icon button-clear ion-ios-copy-outline'"
- ng-click="selectToggle()"></button>
+ ng-click="selectToggle()"></button> &nbsp;
+
+
+
<button data-badge="{{$root.alarmCount}}" class="animated infinite tada button button-icon button-clear ion-ios-bell notification-badge"
ng-click="handleAlarms();" ng-if="$root.isAlarm"></button>
@@ -13,10 +16,10 @@
<a class="button button-icon icon ion-arrow-swap" ng-href="" ng-click="flipLogs()"></a>
<a ng-if="logEntity == $root.appName" class="button button-icon icon ion-trash-a" ng-href="" ng-click="deleteLogs()"></a>
<div ng-if="$root.platformOS!='desktop'">
- <a class="button button-icon icon ion-email" ng-href="" ng-click="sendEmail(log.logString)"> </a>
+ <a class="button button-icon icon ion-email" ng-href="" ng-click="attachLogs()"> </a>
</div>
<div ng-if="$root.platformOS=='desktop'">
- <a class="button button-icon icon ion-android-download" ng-href="" ng-click="sendEmail(log.logString)"> </a>
+ <a class="button button-icon icon ion-android-download" ng-href="" ng-click="downloadLogs()"> </a>
</div>
</ion-nav-buttons>
<ion-content delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
@@ -31,11 +34,14 @@
<button class="button button-small button-stable icon ion-chevron-left" ng-click="changePage(1)">
</button>
<button class="button button-small button-stable icon ion-chevron-right" ng-click="changePage(-1)">
- </button>
+ </button><br/>
+ <b>ZoneMinder {{'kVersion'|translate}}: {{zmVersion}} </b><br/>
+
</div>
<div ng-if="logEntity==$root.appName">
- <b>{{$root.appName}} {{'kVersion'|translate}}: {{zmAppVersion}} ({{$root.platformOS}})</b>
+ <b>{{$root.appName}} {{'kVersion'|translate}}: {{zmAppVersion}} ({{$root.platformOS}})</b><br/>
+ <b>ZoneMinder {{'kVersion'|translate}}: {{zmVersion}} </b>
</div>
<div ng-if="selectOn" class="aside-1">{{'kLogsCopyPaste' | translate }}</div>
diff --git a/www/templates/moment.html b/www/templates/moment.html
index 45cdbd13..0f0f55c4 100644
--- a/www/templates/moment.html
+++ b/www/templates/moment.html
@@ -113,7 +113,7 @@
ng-click="togglePin(moment.Event.Id)"></button>
</div>
- <!--on-tap="showThumbnail(moment.Event.baseURL,moment.Event.MaxScoreFrameId)"-->
+
<figcaption ng-if="showIcons" class="normal-figcaption">&nbsp;{{moment.Event.humanizeTime}}
<span style="float:right">{{hourmin(moment.Event.StartTime)}}&nbsp;</span>
</figcaption>
diff --git a/www/templates/monitors-modal.html b/www/templates/monitors-modal.html
index f039780a..72ed2baa 100644
--- a/www/templates/monitors-modal.html
+++ b/www/templates/monitors-modal.html
@@ -7,6 +7,7 @@
zooming="true" direction="xy" style="width: 100%;" overflow-scroll="false">
<!-- android needs this 100vh - otherwise max- does not work -->
<!-- -->
+
<div id="monitorimage" style="height: 100vh;" class="main">
<div ng-if="$root.authSession!='undefined'">
<div ng-if="!animationInProgress">
diff --git a/www/templates/monitors.html b/www/templates/monitors.html
index fbd1ce26..5da6b8db 100644
--- a/www/templates/monitors.html
+++ b/www/templates/monitors.html
@@ -48,8 +48,11 @@
<br /> {{'kStatus' | translate}}: {{monitor.Monitor.isRunningText}}
<br /> {{'kId' | translate}}: {{monitor.Monitor.Id}}
<br /> {{'kEventRecording' | translate}}: {{(monitor.Monitor.VideoWriter>0?'kVideo':'kImages') | translate}}
- <br />
- <br />
+ <br />{{'kMonStreamingURL' | translate}}: {{monitor.Monitor.streamingURL}}
+ <br />{{'kMonPortalURL' | translate}}: {{monitor.Monitor.baseURL}}
+ <br />{{'kMonRecordingURL' | translate}}: {{monitor.Monitor.controlURL}}
+ <br /> <br/>
+
</p>
<div style="float:right;">
<a class="button button-small icon icon-left icon ion-gear-a" href="" ng-click="changeConfig(monitor.Monitor.Name, monitor.Monitor.Id,monitor.Monitor.Enabled,monitor.Monitor.Function);">{{'kConfiguration'
@@ -61,7 +64,7 @@
</div>
</div>
<ion-item ng-show="!monitors.length">
- {{'kNoMonitors' | translate}}
+ {{monitorLoadStatus}}
</ion-item>
</ion-content>
</ion-view>
diff --git a/www/templates/state.html b/www/templates/state.html
index f5bff536..b534b693 100644
--- a/www/templates/state.html
+++ b/www/templates/state.html
@@ -4,8 +4,27 @@
<button data-badge="{{$root.alarmCount}}" class="animated infinite tada button button-icon button-clear ion-ios-bell notification-badge"
ng-click="handleAlarms();" ng-if="$root.isAlarm"></button>
</ion-nav-buttons>
- <ion-content delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+ <ion-content delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll >
<ion-refresher pulling-text="{{'kPullToReload' | translate}}..." spinner="bubbles" on-refresh="doRefresh()"></ion-refresher>
+
+ <ion-item>
+
+ <div>
+ <div class="row">
+ <div class="col text-center">
+ <a class="button button-small button-outline button-dark " ng-click="selectCustomState();" href="">{{'kChangeState'|translate}}</a>
+ <a class="button button-small button-outline button-dark " ng-click="controlZM('restart');" href="">{{'kRestart'
+ | translate}}</a>
+ <a class="button button-small button-outline button-dark" href="" ng-click="controlZM('stop');">{{'kStop'
+ | translate}}</a>
+ <a class="button button-small button-outline button-dark" ng-click="controlZM('start');" href="">{{'kStart'
+ | translate}}</a>
+ </div>
+ </div>
+ </div>
+ </ion-item>
+
+
<ion-list>
<ion-item>
<div class="row">
@@ -35,23 +54,77 @@
</div>
</div>
</ion-item>
+ </ion-list>
- <ion-item>
+
+
+ <div class="list" >
- <div>
- <div class="row">
- <div class="col text-center">
- <a class="button button-small button-outline button-dark " ng-click="selectCustomState();" href="">{{'kChangeState'|translate}}</a>
- <a class="button button-small button-outline button-dark " ng-click="controlZM('restart');" href="">{{'kRestart'
- | translate}}</a>
- <a class="button button-small button-outline button-dark" href="" ng-click="controlZM('stop');">{{'kStop'
- | translate}}</a>
- <a class="button button-small button-outline button-dark" ng-click="controlZM('start');" href="">{{'kStart'
- | translate}}</a>
- </div>
- </div>
+ <!-- Storage -->
+ <div class="item item-divider item-icon-left item-icon-right" ng-click="toggleStorage()">
+ <i class="icon" ng-class="showStorage? 'ion-minus':'ion-plus'"></i>
+ <i class="icon ion-social-buffer"></i>
+ {{'kStateStorage' | translate}}
</div>
- </ion-item>
- </ion-list>
+ <div ng-repeat = "store in storage">
+ <div class="item item-accordion item-divider" ng-show="showStorage">
+
+ {{store.Storage.Name}} ({{store.Storage.Id}})
+ </div> <!-- divider -->
+ <div class="item item-accordion" ng-show="showStorage">
+
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStatePath' | translate }}: {{store.Storage.Path}}
+ </div>
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStateDiskUsed' | translate }}: {{ humanFileSize(store.Storage.DiskSpace,true)}}
+ </div>
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kScheme' | translate }}: {{ store.Storage.Scheme}}
+ </div>
+ <div ng-if="store.Storage.ServerId" class="row" style="font-size:80%;line-height:140%;">
+ {{'kStateServer' | translate }}: {{ matchServer(store.Storage.ServerId)}}
+ </div>
+
+ </div> <!-- item -->
+ </div> <!-- repeat -->
+
+ <!-- server -->
+ <div class="item item-divider item-icon-left item-icon-right" ng-click="toggleServer()">
+ <i class="icon" ng-class="showServer? 'ion-minus':'ion-plus'"></i>
+ <i class="icon ion-monitor"></i>
+ {{'kStateServer' | translate}}
+ </div>
+ <div ng-repeat = "server in servers">
+ <div class="item item-accordion item-divider" ng-show="showServer">
+
+ {{server.Server.Name}} ({{server.Server.Id}})
+ </div> <!-- divider -->
+ <div class="item item-accordion" ng-show="showServer">
+
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStateHost' | translate }}: {{server.Server.Hostname}}
+ </div>
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStatus' | translate }}: {{ server.Server.Status}}
+ </div>
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStateCpuLoad' | translate }}: {{ server.Server.CpuLoad}}
+ </div>
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStateTotalMem' | translate }}: {{ humanFileSize(server.Server.TotalMem, true)}}
+ </div>
+ <div class="row" style="font-size:80%;line-height:140%;">
+ {{'kStateFreeMem' | translate }}: {{ humanFileSize(server.Server.FreeMem, true)}}
+ </div>
+
+ </div> <!-- item -->
+ </div> <!-- repeat -->
+ </div> <!-- list ---->
+
+
+
+
+
</ion-content>
</ion-view>
diff --git a/www/templates/timeline-modal.html b/www/templates/timeline-modal.html
index 3ae0aba7..5b6c8694 100644
--- a/www/templates/timeline-modal.html
+++ b/www/templates/timeline-modal.html
@@ -27,7 +27,7 @@
<figure style="display:inline-block">
<figcaption class="smallnote">f:{{alarm.fid}} scr:{{alarm.score}} @ {{alarm.time}}</figcaption>
<img image-spinner-src="{{constructFrames(event,alarm)}}" style="width: auto; height: auto;max-width: 100%;max-height: 170px"
- on-tap="showImage(event.Event.baseURL,event.Event.relativePath,alarm.fname, alarm.fid, event.Event.Id, event.Event.imageMode, alarm.id)"
+ on-tap="showImage(event.Event.recordingURL,event.Event.relativePath,alarm.fname, alarm.fid, event.Event.Id, event.Event.imageMode, alarm.id)"
image-spinner-loader="lines" />