summaryrefslogtreecommitdiff
path: root/www/templates
diff options
context:
space:
mode:
Diffstat (limited to 'www/templates')
-rw-r--r--www/templates/devoptions.html184
-rw-r--r--www/templates/events-date-time-filter.html27
-rw-r--r--www/templates/events-graphs.html65
-rw-r--r--www/templates/events-modal.html119
-rw-r--r--www/templates/events-modalgraph.html9
-rw-r--r--www/templates/events-popover.html15
-rw-r--r--www/templates/events.html299
-rw-r--r--www/templates/eventserversettings.html57
-rw-r--r--www/templates/first-use.html38
-rw-r--r--www/templates/help.html12
-rw-r--r--www/templates/help/montage-help.html16
-rw-r--r--www/templates/important_message.html34
-rw-r--r--www/templates/invalidapi.html30
-rw-r--r--www/templates/log.html38
-rw-r--r--www/templates/login.html86
-rw-r--r--www/templates/lowversion.html25
-rw-r--r--www/templates/monitors-modal.html160
-rw-r--r--www/templates/monitors.html62
-rw-r--r--www/templates/montage-history.html139
-rw-r--r--www/templates/montage.html174
-rw-r--r--www/templates/news.html24
-rw-r--r--www/templates/reorder-modal.html27
-rw-r--r--www/templates/state.html70
-rw-r--r--www/templates/timeline-modal.html41
-rw-r--r--www/templates/timeline-popover.html18
-rw-r--r--www/templates/timeline.html56
-rw-r--r--www/templates/wizard.html85
-rw-r--r--www/templates/zm-portal-login.html26
28 files changed, 1936 insertions, 0 deletions
diff --git a/www/templates/devoptions.html b/www/templates/devoptions.html
new file mode 100644
index 00000000..db1f8887
--- /dev/null
+++ b/www/templates/devoptions.html
@@ -0,0 +1,184 @@
+<ion-view view-title="{{'kDevOptions' | translate}}">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ <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-nav-buttons side="right">
+ <button class="button button-clear" ng-click="saveDevOptions()">{{'kSave' | translate}}</button>
+ </ion-nav-buttons>
+ <ion-content scroll-sista delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+ <div class="list list-inset">
+ <span style="color:rgb(100,100,100)">
+ <i class="ion-android-settings" style="font-size:150%"></i> {{'kDeveloperOptionsFor'|translate}} {{loginData.serverName}}
+ </span>
+ <div class="item item-input-inset">
+ {{'kFrameUpdate'|translate}} ({{'kSec'|translate}}.)&nbsp;
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="min is 1s" ng-model="loginData.refreshSec">
+ </label>
+ </div>
+ <label>
+ <ion-toggle ng-model="loginData.use24hr" ng-checked="{{loginData.use24hr}}" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kEnable24hr' | translate}}</span></ion-toggle>
+ </label>
+ <label>
+ <ion-toggle ng-model="loginData.useLocalTimeZone" ng-checked="{{loginData.useLocalTimeZone}}" ng-disabled="!isTzSupported()" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kLocalTimeZone' | translate}}<span ng-if="!isTzSupported()"><p>{{'kTimeZoneNotSupported' | translate}}</p></span><span ng-if="isTzSupported()"><p>{{'kServerTimeZone' | translate}}:{{getTimeZoneNow()}}</p></span></span>
+ </ion-toggle>
+ </label>
+ <div ng-if="$root.platformOS=='android'">
+ <label>
+ <ion-toggle ng-model="loginData.exitOnSleep" ng-checked="{{loginData.exitOnSleep}}" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kExitAppBackground' | translate}}</span></ion-toggle>
+ </label>
+ </div>
+ <!--
+ <label>
+ <ion-toggle ng-model="loginData.useNphZms"
+ ng-checked="{{loginData.useNphZms}}"
+ toggle-class="toggle-calm">use ZMS for single live view</ion-toggle>
+ </label>
+
+ <label>
+ <ion-toggle ng-model="loginData.useNphZmsForEvents"
+ ng-checked="{{loginData.useNphZmsForEvents}}"
+ toggle-class="toggle-calm">use ZMS for events footage</ion-toggle>
+ </label>
+ -->
+ <div class="item item-text-wrap item-input-inset">
+ {{'kMaxMonitorsMontage' | translate }}&nbsp;
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="{{'kBeCareful' | translate}}" ng-model="loginData.maxMontage">
+ </label>
+ </div>
+ <!--
+ <div class="item item-input-inset">
+ maxfps for streaming&nbsp;
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="max is 30" ng-model="loginData.maxFPS">
+ </label>
+ </div>
+ -->
+ <div class="item item-text-wrap item-input-inset">
+ {{'kMontageImageScale' | translate}}(%)&nbsp;
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="max is 70" ng-model="loginData.montageQuality">
+ </label>
+ </div>
+ <div class="item item-text-wrap item-input-inset">
+ {{'kEventSingleImageScale' | translate}}(%)&nbsp;
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="" ng-model="loginData.singleImageQuality">
+ </label>
+ </div>
+ <div class="item item-text-wrap item-input-inset">
+ {{'kMonitorSingleImageScale' | translate}}(%)&nbsp;
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="" ng-model="loginData.monSingleImageQuality">
+ </label>
+ </div>
+ <!--<div class="item item-input-inset">
+ {{'kResumeDelay' | translate}}(ms)&nbsp;
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="" ng-model="loginData.resumeDelay">
+
+ </label>
+
+ </div>-->
+ <div class="item item-text-wrap item-input-inset">
+ {{'kEventMontageImageScale'|translate}}(%)&nbsp;
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="" ng-model="loginData.montageHistoryQuality">
+ </label>
+ </div>
+ <div class="item item-text-wrap item-input-inset">
+ {{'kMaxItemsForTimeline' | translate}}&nbsp;
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="" ng-model="loginData.graphSize">
+ <br/>
+ </label>
+ <br/>
+ </div>
+ <div class="item item-text-wrap item-input-inset">
+ {{'kMinAlarmCount' | translate}}&nbsp;
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="" ng-model="loginData.minAlarmCount">
+ <br/>
+ </label>
+ <br/>
+ </div>
+ <div class="item" style="background-color:#C8F7C5" ng-if="loginData.graphSize > 5000">
+ <label class="animated fadeInDown item-text-wrap">
+ {{'kWarningLargeTimeline' | translate}}
+ </label>
+ </div>
+
+ <label>
+ <ion-toggle ng-model="loginData.hideArchived" ng-checked="loginData.hideArchived" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kHideArchived' | translate}}
+ </span>
+ </ion-toggle>
+ </label>
+
+ <label ng-if="$root.platformOS!='desktop'">
+ <ion-toggle ng-model="loginData.enableStrictSSL" ng-checked="loginData.enableStrictSSL" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kEnableStrictSSL' | translate}}
+ </span>
+ </ion-toggle>
+ </label>
+
+ <label>
+ <ion-toggle ng-model="loginData.enableGIFMP4" ng-checked="loginData.enableGIFMP4" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kEnableGIFMP4' | translate}}
+ </span>
+ </ion-toggle>
+ </label>
+
+ <label>
+ <ion-toggle ng-model="loginData.enableSlowLoading" ng-checked="loginData.enableSlowLoading" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kEnableSlowLoading' | translate}}
+ </span>
+ </ion-toggle>
+ </label>
+
+ <label>
+ <ion-toggle ng-model="loginData.disableAlarmCheckMontage" ng-checked="loginData.disableAlarmCheckMontage" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kDisableAlarmMontage' | translate}}
+ <p>{{'kDisableAlarmMontageSub' | translate}}</p></span>
+ </ion-toggle>
+ </label>
+ <label>
+ <ion-toggle ng-model="loginData.enableLogs" ng-checked="{{loginData.enableLogs}}" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kEnableLogs' | translate}}</span></ion-toggle>
+ </label>
+ <div class="item item-text-wrap item-input-inset">
+ {{'kCycleMonitorsInterval'|translate}}({{'kSec'|translate}}.)&nbsp;
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="" ng-model="loginData.cycleMonitorsInterval">
+ </label>
+ </div>
+
+ <div class="item item-text-wrap item-input-inset">
+ {{'kCycleMontageInterval'|translate}}({{'kSec'|translate}}.)&nbsp;
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="" ng-model="loginData.cycleMontageInterval">
+ </label>
+ </div>
+
+
+ <label>
+ <ion-toggle ng-if="loginData.enableLogs" ng-model="loginData.enableDebug" ng-checked="{{loginData.enableDebug}}" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kEnableDebug' | translate}}</span></ion-toggle>
+ </label>
+ <label>
+ <ion-toggle ng-model="loginData.canSwipeMonitors" ng-checked="{{loginData.canSwipeMonitors}}" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kSwipeToChangeMon' | translate}}</span></ion-toggle>
+ </label>
+ <label>
+ <ion-toggle ng-model="loginData.forceImageModePath" ng-checked="{{loginData.forceImageModePath}}" toggle-class="toggle-calm"> <span class="item-text-wrap">{{'kForceImagePath' | translate}}</span></ion-toggle>
+ </label>
+ <!--
+ <label>
+ <ion-toggle ng-model="loginData.reachability" ng-checked="{{loginData.reachability}}" toggle-class="toggle-calm"> {{'kReachability' | translate}}</ion-toggle>
+ </label>
+ -->
+ <label>
+ <ion-toggle ng-model="loginData.enableBlog" ng-checked="{{loginData.enableBlog}}" toggle-class="toggle-calm"> <span class="item-text-wrap">{{'kEnableNewsUpdates' | translate}}</span></ion-toggle>
+ </label>
+ <label ng-if="$root.platformOS != 'desktop'">
+ <ion-toggle ng-model="loginData.disableNative" ng-checked="{{loginData.disableNative}}" toggle-class="toggle-calm"> <span class="item-text-wrap">{{'kDisableNative' | translate}}
+ <p>{{'kDisableNativeSub' | translate}}</p></span>
+ </ion-toggle>
+ </label>
+ </div>
+ </ion-content>
+</ion-view>
diff --git a/www/templates/events-date-time-filter.html b/www/templates/events-date-time-filter.html
new file mode 100644
index 00000000..33370ba8
--- /dev/null
+++ b/www/templates/events-date-time-filter.html
@@ -0,0 +1,27 @@
+<ion-view view-title="{{'kFilterEvents' | translate}}">
+ <ion-content scroll-sista delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+ <label class="item item-input">
+ <span class="input-label">{{'kFromDate'|translate}}:</span>
+ <input type="date" ng-model="$root.fromDate" max={{today}}>
+ </label>
+ <label class="item item-input">
+ <span class="input-label">{{'kFromTime'|translate}}</span>
+ <input type="time" ng-model="$root.fromTime">
+ </label>
+ <label class="item item-input">
+ <span class="input-label">{{'kToDate'|translate}}</span>
+ <input type="date" ng-model="$root.toDate" max={{today}}>
+ </label>
+ <label class="item item-input">
+ <span class="input-label">{{'kToTime'|translate}}</span>
+ <input type="time" ng-model="$root.toTime">
+ </label>
+ <br/>
+ <center>
+ <button class="button" ng-click="saveFilters();"> {{'kSave'|translate}}
+ </button>
+ <button class="button" ng-click="removeFilters();"> {{'kReset'|translate}}
+ </button>
+ </center>
+ </ion-content>
+</ion-view>
diff --git a/www/templates/events-graphs.html b/www/templates/events-graphs.html
new file mode 100644
index 00000000..0e14016f
--- /dev/null
+++ b/www/templates/events-graphs.html
@@ -0,0 +1,65 @@
+<!----- NOT USED -------->
+<ion-view view-title="Monitor Event Summary" cache-view="false">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ <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>
+ <!-- I'm calling the same controller function but with different parameters when
+ you switch between tabs -->
+ <!-- Oddly, unless I add a "div ng-controller" before each canvas
+ onClick handler does not work
+ -->
+ <!-- All Events view -->
+ <div id="visualization"></div>
+ <ion-tabs class="tabs-icon-top tabs-stable">
+ <ion-tab title="All" icon="ion-stats-bars" on-select="generateTCChart(0,'All Events',0)">
+ <ion-nav-view>
+ <ion-content class="has-header">
+ <div ng-controller="zmApp.EventsGraphsCtrl">
+ <canvas tc-chartjs-bar chart-data="chart.data" chart-options="chart.options" ng-click="handleChartClick($event)" chart="chartwithbars">
+ </canvas>
+ </div>
+ </ion-content>
+ </ion-nav-view>
+ </ion-tab>
+ <!-- All Events in the last hour -->
+ <ion-tab title="Last Hour" icon="ion-stats-bars" on-select="generateTCChart(1,'Events in the last hour',1)">
+ <ion-nav-view>
+ <ion-content>
+ <div ng-controller="zmApp.EventsGraphsCtrl">
+ <div style="overflow:scroll;">
+ <canvas tc-chartjs-bar chart-data="chart.data" chart-options="chart.options" ng-click="handleChartClick($event)" chart="chartwithbars">
+ </canvas>
+ </div>
+ </div>
+ </ion-content>
+ </ion-nav-view>
+ </ion-tab>
+ <!-- All Events in last 24 hrs-->
+ <ion-tab title="Day" icon="ion-stats-bars" on-select="generateTCChart(2,'Events in the last day',24)">
+ <ion-nav-view>
+ <ion-content>
+ <div ng-controller="zmApp.EventsGraphsCtrl">
+ <div style="overflow:scroll;">
+ <canvas tc-chartjs-bar chart-data="chart.data" chart-options="chart.options" chart="chartwithbars" ng-click="handleChartClick($event)">
+ </canvas>
+ </div>
+ </div>
+ </ion-content>
+ </ion-nav-view>
+ </ion-tab>
+ <!-- All Events in last week -->
+ <ion-tab title="Week" icon="ion-stats-bars" on-select="generateTCChart(3,'Events in the last week',168)">
+ <ion-nav-view>
+ <ion-content>
+ <div ng-controller="zmApp.EventsGraphsCtrl">
+ <div style="overflow:scroll;">
+ <canvas tc-chartjs-bar chart-data="chart.data" chart-options="chart.options" chart="chartwithbars" ng-click="handleChartClick($event)">
+ </canvas>
+ </div>
+ </div>
+ </ion-content>
+ </ion-nav-view>
+ </ion-tab>
+ </ion-tabs>
+</ion-view>
diff --git a/www/templates/events-modal.html b/www/templates/events-modal.html
new file mode 100644
index 00000000..68065e24
--- /dev/null
+++ b/www/templates/events-modal.html
@@ -0,0 +1,119 @@
+<div ng-controller="EventModalCtrl">
+ <!-- style="width: 90%; height: 90%; top: 5%; left: 5%; right: 5%; bottom: 5%;"-->
+ <ion-modal-view cache-view="false">
+ <ion-content style="background-color:#444444" ng-cloak>
+ <ion-scroll has-bouncing=false min-zoom=1 zooming="true" direction="xy" delegate-handle="imgscroll" on-swipe-left="onSwipeEvent(nextId,1)" on-swipe-right="onSwipeEvent(prevId,-1)" overflow-scroll="false">
+ <div id="full-screen-event" style="height: 100vh;">
+ <!--<div>-->
+ <!-- route via ZMS -->
+ <div ng-if="( (defaultVideo=='') || (loginData.enableh264==false)) && (loginData.useNphZmsForEvents==true)">
+ <!--<div style="color:white">connkey:{{connKey}}</div>-->
+ <div style="width:100vw; height:100vh;">
+ <img image-spinner-src="{{loginData.streamingurl}}/nph-zms?source=event&mode=jpeg&event={{eventId}}&frame=1&replay={{currentStreamMode}}&rate=100&connkey={{connKey}}&scale={{singleImageQuality}}{{$root.authSession}}" ng-class="{'object-fit_cover':imageFit==false, 'object-fit_contain':imageFit==true}" on-double-tap="closeModal();" />
+ <div ng-if="isPaused" style="position:absolute; top:50%; left:50%;white-space:nowrap;overflow:hidden;z-index:999" class="header-paused">
+ &nbsp;<i class="ion-pause"></i> {{'kPaused' | translate}}&nbsp;
+ </div>
+ </div>
+ </div>
+ <!-- no default video -->
+ <div ng-if="defaultVideo!==undefined && defaultVideo!='' && loginData.enableh264 == true">
+ <div ng-if="videoIsReady">
+
+
+
+
+ <div style="height:{{$root.devHeight}}px; width:{{$root.devWidth}}px;">
+
+ <!--
+
+ <br/><br/><br/><br/><br/><br/>
+
+ Falback testing:{{ video_url | trusted}}
+ <video controls>
+ <source ng-src="{{video_url | trusted}}" type="video/mp4" />
+ Your browser does not support the video tag.
+ </video>
+
+ -->
+ <videogular vg-can-play="onCanPlay()" vg-native-fullscreen="videoObject.config.nativeFullScreen" vg-player-ready="onPlayerReady($API)"
+ vg-update-playback="onPlaybackUpdate($playBack)"
+ vg-plays-inline="videoObject.config.playsInline" vg-theme="videoObject.config.theme" vg-complete="playbackFinished()" on-double-tap="closeModal();" vg-autoplay="videoObject.config.autoPlay" vg-responsive="videoObject.config.responsive" vg-update-time="videoTime(event.Event.StartTime,$currentTime)" vg-error="onVideoError($event)">
+ <vg-media vg-src="videoObject.config.sources" vg-native-controls="videoObject.config.nativeControls">
+ </vg-media>
+ <vg-controls>
+ <vg-playback-button></vg-playback-button>
+ <vg-play-pause-button></vg-play-pause-button>
+ <vg-time-display>{{ videoTime(event.Event.StartTime, currentTime ); }}</vg-time-display>
+ <vg-scrub-bar>
+ <vg-scrub-bar-current-time></vg-scrub-bar-current-time>
+ <vg-cuepoints vg-cuepoints-config="videoObject.config.cuepoints"
+ vg-cuepoints-theme="videoObject.config.cuepoints.theme.url">
+ </vg-cuepoints>
+ </vg-scrub-bar>
+ <vg-time-display>{{ timeLeft | date:'mm:ss':'+0000' }}</vg-time-display>
+ <vg-fullscreen-button></vg-fullscreen-button>
+ <vg-volume>
+ <vg-mute-button></vg-mute-button>
+ </vg-volume>
+ </vg-controls>
+
+ </videogular>
+ </div>
+ </div>
+ <!--<div id="event_canvas_video">
+ <canvas id="eventchart" width="100%" height="20px"></canvas>
+ </div>-->
+ </div>
+ </div>
+ <!-- 100vh -->
+ </ion-scroll>
+ <div ng-if="( (defaultVideo=='') || (loginData.enableh264==false)) && (loginData.useNphZmsForEvents==true)">
+ <div id="event_canvas">
+ <canvas style="padding-left:23px;
+ padding-right:23px;" id="eventchart" width="auto" height="20"></canvas>
+ </div>
+ <div ng-if="checkEventOn" id="event_slider" data-tap-disabled="false">
+ <div class="range">
+ <input on-drag="enableSliderBlock()" on-release="youChangedSlider()" type="range" min="0" max="{{currentEventDuration}}" ng-model="sliderProgress.progress">
+ </div>
+ </div>
+ <div id="event_rate_text">
+ @{{currentRate}}x {{'kAt' | translate}}:{{currentProgress.progress}}s
+ </div>
+ </div>
+
+ </ion-content>
+ </ion-modal-view>
+ <nav mfb-menu position="tr" effect="zoomin" label="{{'kCollapse'|translate}}" active-icon="ion-chevron-up" resting-icon="ion-chevron-down" toggling-method="click">
+ <a mfb-button icon="ion-arrow-right-c" label="{{'kNextEvent'|translate}}" ng-click="jumpToEvent(nextId,1);"></a>
+ <a mfb-button icon="ion-arrow-left-c" label="{{'kPrevEvent'|translate}}" ng-click="jumpToEvent(prevId,-1);"></a>
+ <a mfb-button icon="ion-arrow-resize" label="{{imageFit? ('kFillScreen' | translate):('kFitScreen' | translate)}}" ng-click="scaleImage();"></a>
+ <a mfb-button icon="ion-close" label="{{'kExitEventView' | translate}}" ng-click="closeModal()"> </a>
+ </nav>
+ <nav ng-if="loginData.useNphZmsForEvents && defaultVideo==''" mfb-menu position="br" effect="zoomin" label="{{'kCollapse' | translate}}" active-icon="ion-chevron-down" resting-icon="ion-chevron-up" toggling-method="click">
+ <a mfb-button icon="ion-skip-backward" label="{{'kFastRewind'|translate}}" ng-click="adjustSpeed('fr');"></a>
+ <a mfb-button icon="ion-skip-forward" label="{{'kFastForward'|translate}}" ng-click="adjustSpeed('ff');"></a>
+ <a mfb-button icon="ion-play" label="{{'kNormalPlay'|translate}}" ng-click="adjustSpeed('np');"></a>
+ <a mfb-button icon="ion-pause" label="{{'kPause'|translate}}" ng-click="adjustSpeed('p');"> </a>
+ </nav>
+ <div class="events-range-modal-text">{{mName}}&nbsp;<i class="ion-arrow-right-b"></i>&nbsp;{{videoDynamicTime}} ({{humanizeTime}}) [{{d_eventId}}] </div>
+ <div id="flyoutmenu" style="position:absolute;bottom:100px;left:10px">
+ <ul>
+ <li>
+ <a href="" ng-click="toggleListMenu()"> <i ng-class="(isToggleListMenu) ? 'icon ion-chevron-left': 'icon ion-chevron-right'"></i></a>
+ </li>
+ <li ng-if="defaultVideo=='' && isToggleListMenu">
+ <a href="" ng-click="toggleGapless()"> <i class="ion-ios-loop-strong"></i>-{{loginData.gapless? ('kOn' | translate): ('kOff' | translate)}}</a>
+ </li>
+ <li ng-if="defaultVideo=='' && isToggleListMenu">
+ <a href="" ng-click="saveEventImageToPhoneWithPerms(false)"> <i class="ion-ios-camera"></i></a>
+ </li>
+ <li ng-if="defaultVideo=='' && isToggleListMenu">
+ <a href="" ng-click="saveEventImageToPhoneWithPerms(true)"> <i class="ion-android-notifications"></i></a>
+ </li>
+ <li ng-if="$root.isAlarm">
+ <a data-badge="{{$root.alarmCount}}" class="notification-badge animated infinite tada" href="" ng-click="handleAlarms()"><i class="ion-ios-bell"></i></a>
+ </li>
+ </ul>
+ </div>
+</div>
diff --git a/www/templates/events-modalgraph.html b/www/templates/events-modalgraph.html
new file mode 100644
index 00000000..25b38543
--- /dev/null
+++ b/www/templates/events-modalgraph.html
@@ -0,0 +1,9 @@
+<div ng-controller="EventsModalGraphCtrl">
+ <ion-modal-view cache-view="false" style="width:80%;height:80%; top: 10%; left: 10%; right: 10%; bottom: 10%;">
+ <ion-content ng-cloak on-double-tap="closeModal()" delegate-handle="eventgraph-modal-delegate">
+ <div data-tap-disabled="true">
+ <canvas id="eventchart" width="auto" height="70%"></canvas>
+ </div>
+ </ion-content>
+ </ion-modal-view>
+</div>
diff --git a/www/templates/events-popover.html b/www/templates/events-popover.html
new file mode 100644
index 00000000..38dd1d2e
--- /dev/null
+++ b/www/templates/events-popover.html
@@ -0,0 +1,15 @@
+<ion-popover-view class="fit">
+ <ion-content>
+ <div class="list" ng-click="popover.hide()">
+ <a class="item" ng-href="" ng-click="popover.hide();$state.go('events-date-time-filter');">{{'kFilterByDateTime' | translate}}</a>
+ <!-- <a class="item" ng-href="" ng-click=" popover.hide();$state.go('events-graphs');" >
+ Event Graphs
+ </a>-->
+ <a class="item" ng-href="" ng-click="popover.hide();doRefresh();">
+ {{'kRefresh' | translate}}
+ </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>
+ </div>
+ </ion-content>
+</ion-popover-view>
diff --git a/www/templates/events.html b/www/templates/events.html
new file mode 100644
index 00000000..01aef4a8
--- /dev/null
+++ b/www/templates/events.html
@@ -0,0 +1,299 @@
+<ion-view cache-view="false">
+ <ion-nav-title>{{scrollPosition();}}</ion-nav-title>
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()">
+ </button>
+ <button class="button button-icon icon ion-ios-minus-outline" ng-click="eventList.showDelete = !eventList.showDelete;"></button>
+ <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-nav-buttons side="right">
+ <a style="" class="button button-icon icon ion-android-more-vertical" ng-click="popover.show($event)" ;>&nbsp;&nbsp;&nbsp;</a>
+ <a style="" class="button button-icon icon ion-search" ng-href="" ng-click="searchClicked();"> </a>
+ </ion-nav-buttons>
+ <div ng-if="showSearch">
+ <ion-header-bar class="bar bar-subheader item-input-inset">
+ <label class="item-input-wrapper">
+ <i class="icon ion-ios7-search placeholder-icon"></i>
+ <input type="search" placeholder="{{'kSearch'|translate}}" ng-model="search.text" autocorrect="off" autocomplete="off">
+ </label>
+ </ion-header-bar>
+ </div>
+ <!-- collection repeat forces js scrolling, thing to remember -->
+ <ion-content scroll-sista ng-cloak on-tap="tapped();" delegate-handle="mainScroll" mouse-wheel-scroll>
+ <!-- needed for header-shrink so first item doesn't go below header-->
+ <!-- <div style="height: 64px;"></div>-->
+ <!-- lets make sure the events list is not empty as collection repeat needs height -->
+ <div ng-if="!eventsBeingLoaded">
+ <ion-list show-delete="eventList.showDelete">
+ <ion-item collection-repeat="event in events| filter:search.text | eventListFilter
+ " item-height="event.Event.height" id="item-{{$index}}" on-swipe-left="checkSwipe($index);">
+ <span style="float:left;margin-top:-18px;background-color:#96281B;color:#fff;font-size:11px;opacity:0.7;border-radius: 0px 0px 5px 5px;">&nbsp;&nbsp;&nbsp;<i class="ion-calendar"></i>&nbsp;&nbsp;{{prettifyTime(event.Event.StartTime)}}&nbsp;{{tzAbbr}}&nbsp;</span>&nbsp;&nbsp;
+ <span style="float:left;margin-top:-18px;background-color:#fff;color:#888;font-size:11px;opacity:1;">&nbsp;&nbsp;<i class="ion-arrow-right-b"></i>&nbsp;{{event.Event.humanizeTime}} <span ng-if="!event.Event.EndTime">(<span translate="kRecordingProgress"></span>)</span>
+ </span>
+ <span style="float:right;margin-top:-18px;background-color:#444444;color:#fff;font-size:11px;opacity:0.7;border-radius: 0px 0px 5px 5px;">&nbsp;&nbsp;&nbsp;<i class="ion-clock"></i>&nbsp;&nbsp;{{prettifyDate(event.Event.StartTime)}}
+ &nbsp;{{tzAbbr}}&nbsp;</span>
+ <div class="row">
+ <div class="col col-left">
+ <!-- this ngswitch displays different icons
+ depending on the cause of the event -->
+ <div ng-switch on="event.Event.Cause">
+ <div ng-switch-when="Motion">
+ <i class="ion-android-walk" style="float:left; font-size:200%;"></i>
+ <i ng-class="(event.Event.DefaultVideo !== undefined && event.Event.DefaultVideo!='')? 'ion-ios-videocam':'ion-images'" style="float:left; padding-left:5px; font-size:100%;"></i>
+ <br/>
+ </div>
+ <div ng-switch-when="Signal">
+ <i class="ion-wifi" style="float:left; font-size:200%;"></i>
+ <i ng-class="(event.Event.DefaultVideo !== undefined && event.Event.DefaultVideo!='')? 'ion-ios-videocam':'ion-images'" style="float:left; padding-left:5px; font-size:100%;"></i>
+ <br/>
+ </div>
+ <div ng-switch-default>
+ <i class="ion-ionic" style="float:left; font-size:200%;"></i>
+ <i ng-class="(event.Event.DefaultVideo !== undefined && event.Event.DefaultVideo!='')? 'ion-ios-videocam':'ion-images'" style="float:left; padding-left:5px; font-size:100%;"></i>
+ <br/>
+ </div>
+ </div>
+ <!-- ng switch -->
+ <!-- {{event.Event.Cause}} -->
+ <br/>
+ <span style="font-size:80%; color:rgb(110,110,110)">
+ {{event.Event.Length}}s
+ </span>
+ </div>
+ <!-- col col left-->
+ <div class="col col-80">
+ <div class="item-text-wrap">
+
+ <b><i ng-if="event.Event.Archived=='1'" class="ion-ios-flag" style="color:red">&nbsp;</i>{{event.Event.MonitorName}}</b> ({{event.Event.Id}}) &nbsp;
+ <button ng-if="gifshotSupported && loginData.enableGIFMP4 " class="button button-small button-clear icon gif-icon" ng-click="permissionsDownload(event)">
+ </button>
+
+
+
+ <a ng-if="(event.Event.DefaultVideo!='' && event.Event.DefaultVideo!==undefined) && $root.platformOS=='desktop' && loginData.enableGIFMP4 " class="button button-clear button-small icon mp4-icon" href="{{event.Event.videoPath}}" download="{{event.Event.Id}}-video.mp4" ng-click="mp4warning()"></a>
+
+ <button ng-if="event.Event.DefaultVideo!='' && event.Event.DefaultVideo!=undefined && $root.platformOS!='desktop' && loginData.enableGIFMP4 " class="button button-small button-clear icon mp4-icon" ng-click="downloadFileToDevice(event.Event.videoPath, event.Event.Id)">
+ </button>
+
+
+ </div>
+
+ <i class="ion-images"></i> {{event.Event.Frames}} &nbsp;
+ <i class="ion-ios-bell-outline"></i> {{event.Event.AlarmFrames}} &nbsp;
+ <i class="ion-arrow-graph-up-right"></i> {{event.Event.TotScore}}
+
+
+ </div>
+ </div>
+ <!--row-->
+ <div class="row" style="font-size:80%; color:rgb(110,110,110)">
+ <div class="item-text-wrap">
+ <i class="ion-ios-pricetags-outline"></i>&nbsp; {{event.Event.Name}}<br/>
+ <i class="ion-calendar"></i>&nbsp; {{prettify(event.Event.StartTime)}}&nbsp;{{tzAbbr}}&nbsp;
+ <br/>
+ <i class="ion-clipboard"></i>&nbsp; {{event.Event.Notes}}
+
+ <!-- <br/> Default video:{{event.Event.relativePath}}{{event.Event.DefaultVideo}}-->
+ </div>
+ </div>
+ <span style="float:right">
+ <div ng-if="event.Event.EndTime || 1">
+ <button class="button button-small button-outline icon icon-left ion-stats-bars"
+ ng-click="closeIfOpen(event);analyzeEvent(event)" >
+ <span translate="kAnalyze"></span>
+ </button>
+ <button class="button button-outline button-small icon icon-left ion-ios-eye" ng-click="toggleGroupScrub(event,$index,event.Event.Frames)"> <span translate="kScrub"></span>
+ </button>
+ <button ng-if="event.Event.AlarmFrames > 0" class="button button-outline button-small icon icon-left ion-ios-bell" ng-click="toggleGroupAlarms(event,$index,event.Event.Frames)"> <span translate="kAlarms"></span>
+ </button>
+ <button class="button button-outline button-small icon icon-left ion-ios-eye" ng-click="closeIfOpen(event);openModal(event)"> <span translate="kFootage"></span>
+ </button>
+
+
+
+
+ </div>
+ </span>
+ <!-- this is the event scrub/alarm frames area -->
+ <div ng-if="isGroupShown(event)">
+ <div ng-if="groupType=='alarms'">
+ <br/>
+ <br/>
+ <div style="height:190px;">
+ <p>
+ <!--scroll <i class="icon ion-arrow-left-c"></i>
+ <i class="icon ion-arrow-right-c"></i>-->
+ <button ng-click="toggleTypeOfAlarms()" class="button button-small button-assertive button-outline">
+ <span translate="kType"></span>:{{typeOfFrames}}
+ </button>
+ <button
+ ng-click="toggleMotionOutline()" class="button button-small button-assertive button-outline">
+ <span translate="kOutlineMotion"></span>:{{outlineMotion}}
+ </button>
+ </p>
+
+
+ <ion-scroll direction="x" overflow-scroll="false" >
+ <span ng-repeat="alarm in alarm_images | selectFrames: typeOfFrames">
+
+ <figure class = "animated slideInLeft" style="display:inline-block">
+ <!--{{event.Event.baseURL}} 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-if="event.Event.imageMode=='path'" ng-src="{{event.Event.baseURL}}/index.php?view=image&path={{event.Event.relativePath}}{{outlineMotion? alarm.aname:alarm.fname}}&height=380" fallback-src="{{event.Event.baseURL}}/index.php?view=image&path={{event.Event.relativePath}}{{alarm.fname}}&height=380"" 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)" />
+
+ <img ng-if="event.Event.imageMode=='fid'" ng-src="{{event.Event.baseURL}}/index.php?view=image&fid={{alarm.id}}{{outlineMotionParam}}" fallback-src="{{event.Event.baseURL}}/index.php?view=image&fid={{alarm.id}}" 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)" />
+ </figure>
+ </span>
+ </ion-scroll>
+
+
+ </div>
+ </div>
+ <div ng-if="groupType=='scrub'">
+ <div ng-if="event.Event.DefaultVideo=='' || loginData.enableh264==false">
+ <br/>
+ <br/>
+ <br/>
+ <div style="width:90%">
+ <input ng-model="ionRange.index" type="text" id="mySlider1" slider options="slider_options" />
+ </div>
+ <br/>
+ <p>{{mycarousel.index+1}}/{{event.Event.Frames}} <span translate="kType"></span>: {{FrameArray[mycarousel.index].Type}}</p>
+ <div style="height:190px">
+ <ul rn-carousel rn-carousel-buffered rn-carousel-transition="none" rn-swipe-disabled="true" rn-carousel-index="mycarousel.index" rn-carousel-auto-slide="{{event.Event.Length/event.Event.Frames}}" rn-carousel-pause-on-hover rn-platform="{{$root.platformOS}}">
+ <li ng-repeat="slide in slides">
+ <img ng-if="event.Event.imageMode=='path'" imageonload="finishedLoadingImage($index)" image-spinner-src="{{event.Event.baseURL}}/index.php?view=image&path={{event.Event.relativePath}}{{slide.img}}&height=380" image-spinner-loader="lines" height="190px" ;/>
+ <img ng-if="event.Event.imageMode=='fid'" imageonload="finishedLoadingImage($index)" image-spinner-src="{{event.Event.baseURL}}/index.php?view=image&fid={{slide.id}}" image-spinner-loader="lines" height="190px" ;/>
+ <br/>
+ </li>
+ </ul>
+ </div>
+ </div>
+ <!-- no DefaultVideo -->
+ <div ng-if="event.Event.DefaultVideo!='' && loginData.enableh264 == true">
+ <br/>
+ <br/>
+ <br/>
+ <div class="videogular-container">
+ <videogular vg-theme="event.Event.video.config.theme" vg-plays-inline="'true'" vg-auto-play="'true'" vg-responsive="true">
+ <vg-overlay-play></vg-overlay-play>
+ <vg-controls>
+ <vg-play-pause-button></vg-play-pause-button>
+ <vg-scrub-bar>
+ <vg-scrub-bar-current-time></vg-scrub-bar-current-time>
+ </vg-scrub-bar>
+ <vg-time-display>{{ timeLeft | date:'mm:ss':'+0000' }}</vg-time-display>
+ <vg-fullscreen-button></vg-fullscreen-button>
+ <vg-volume>
+ <vg-mute-button></vg-mute-button>
+ </vg-volume>
+ </vg-controls>
+ <vg-media vg-src="event.Event.video.config.sources" vg-native-controls="false">
+ </vg-media>
+ </videogular>
+ </div>
+ </div>
+ <!-- DefaultVideo -->
+ </div>
+ <!-- type = scrub -->
+ </div>
+ <!-- isGroupShown -->
+ <ion-delete-button class="ion-minus-circled" ng-click="deleteEvent(event.Event.Id, $index)">
+ </ion-delete-button>
+
+
+ <ion-option-button ng-if="event.Event.Archived == 1" class="button-balanced" ng-click= "archiveUnarchiveEvent($index,event.Event.Id)">{{'kUnflag' | translate}}</ion-option-button>
+
+ <ion-option-button ng-if="event.Event.Archived == 0" class="button-assertive" ng-click="archiveUnarchiveEvent($index, event.Event.Id)" >{{'kFlag' | translate}}</ion-option-button>
+
+
+ <!-- hack to make sure swipe left displays well
+ if there is no content and our list height is set
+ to a larger height, the swipe display acts weird -->
+
+ <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+
+ </ion-item>
+ </ion-list>
+ </div>
+ <!-- !eventsBeingLoaded-->
+
+
+ <ion-item ng-show="!events.length">
+ <span translate="kNoEvents"></span>
+ </ion-item>
+ <div ng-if="!eventsBeingLoaded">
+ <ion-infinite-scroll ng-if="moreDataCanBeLoaded()" icon="ion-loading-c" on-infinite="loadMore()" distance="2%">
+ </ion-infinite-scroll>
+ </div>
+ <canvas id="canvas" class="hiddengifcanvas"></canvas>
+
+
+
+ </ion-content>
+ <div class="events-float-filter" ng-if="isEventFilterOn" on-tap="filterTapped();"><span translate="kFilterOn"></span></div>
+ <div class="bwmode" ng-if="$root.runMode=='lowbw'">
+ <span translate="kLowBWDisplay"></span>
+ </div>
+ <ion-pull-up-footer class="zmPullup" on-expand="footerExpand()" on-collapse="footerCollapse()" initial-state="minimized" default-behavior="expand">
+ <ion-pull-up-handle width="100" height="25" toggle="ion-chevron-up ion-chevron-down" style="border-radius: 25px 25px 0 0">
+ <i class="icon ion-chevron-up"></i>
+ </ion-pull-up-handle>
+ <ion-pull-up-bar>
+ <h1 class="title" ion-pull-up-trigger><span translate="kLatestEvents"></span></h1>
+ </ion-pull-up-bar>
+ <ion-pull-up-content scroll="true">
+ <div class="list list-inset">
+ <div class="item item-divider"><span translate="k1HourSummary"></span></div>
+ <div ng-repeat="hour in hours|filter:{ monitor: '!'+'(Unknown)'}" id="hour-{{$index}}">
+ <span style="color:black">
+ <a class="item item-icon-right" href=""
+ ng-click="showEvents('1', 'hour',hour.mid);">
+ <b>{{hour.monitor}}</b> {{hour.events}} <span translate="kEvents"></span>
+ <i class="icon ion-android-arrow-dropright"></i>
+ </a>
+ </span>
+ </div>
+ </div>
+ <div class="list list-inset">
+ <div class="item item-divider"><span translate="k1DaySummary"></span></div>
+ <div ng-repeat="day in days|filter:{ monitor: '!'+'(Unknown)'}" id="day-{{$index}}">
+ <span style="color:black">
+ <a class="item item-icon-right" href=""
+ ng-click="showEvents('1', 'day',day.mid);">
+ <b>{{day.monitor}}</b> {{day.events}} <span translate="kEvents"></span>
+ <i class="icon ion-android-arrow-dropright"></i>
+ </a>
+ </span>
+ </div>
+ </div>
+ <div class="list list-inset">
+ <div class="item item-divider"><span translate="k1WeekSummary"></span></div>
+ <div ng-repeat="week in weeks|filter:{ monitor: '!'+'(Unknown)'}" id="week-{{$index}}">
+ <span style="color:black">
+ <a class="item item-icon-right" href=""
+ ng-click="showEvents('1', 'week',week.mid);">
+ <b>{{week.monitor}}</b> {{week.events}} <span translate="kEvents"></span>
+ <i class="icon ion-android-arrow-dropright"></i>
+ </a>
+ </span>
+ </div>
+ </div>
+ <div class="list list-inset">
+ <div class="item item-divider"><span translate="k1MonthSummary"></span></div>
+ <div ng-repeat="month in months|filter:{ monitor: '!'+'(Unknown)'}" id="month-{{$index}}">
+ <span style="color:black">
+ <a class="item item-icon-right" href=""
+ ng-click="showEvents('1', 'months',month.mid);">
+ <b>{{month.monitor}}</b> {{month.events}} <span translate="kEvents"></span>
+ <i class="icon ion-android-arrow-dropright"></i>
+ </a>
+ </span>
+ </div>
+
+ </div>
+ <br/>
+ <br/>
+ </ion-pull-up-content>
+ </ion-pull-up-footer>
+</ion-view>
diff --git a/www/templates/eventserversettings.html b/www/templates/eventserversettings.html
new file mode 100644
index 00000000..622a0aee
--- /dev/null
+++ b/www/templates/eventserversettings.html
@@ -0,0 +1,57 @@
+<ion-view cache-view="false">
+ <ion-nav-title>{{'kEventServer' | translate}}/{{getTitle();}} </ion-nav-title>
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ <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-nav-buttons side="right">
+ <button class="button button-clear" ng-click="saveItems()">{{'kSave'|translate}}</button>
+ </ion-nav-buttons>
+ <ion-content scroll-sista delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+ <div class="list list-inset">
+ {{'kEventServerConfig1' | translate }}
+ </div>
+ <ion-checkbox ng-model="loginData.isUseEventServer" ng-checked="loginData.isUseEventServer">{{'kUseEventServer' | translate}}</ion-checkbox>
+ <ion-item ng-href="" ng-click="selectScreen()">
+ {{'kOnTapNavigate' | translate}}: {{defScreen}}
+ </ion-item>
+ <label class="item item-input item-floating-label" ng-if="loginData.isUseEventServer">
+ <span class="input-label">{{'kEventServer' | translate}}</span>
+ <input autocapitalize="none" autocomplete="off" autocorrect="off" type="text" placeholder="{{'kEventNotificationUrl' | translate}}" ng-model="loginData.eventServer">
+ </label>
+ <ion-toggle ng-if="loginData.isUseEventServer" ng-model="loginData.disablePush" ng-checked="loginData.disablePush" toggle-class="toggle-calm" class="item-text-wrap">{{'kOnlyUseWebSocket'| translate }}
+ <br/>
+ <p>{{'kDisablePush' | translate }}</p>
+ </ion-toggle>
+ <!-- vibrate app setting is not av. on iOS-->
+ <ion-toggle ng-if="loginData.isUseEventServer && $root.platformOS !='ios'" ng-model="loginData.vibrateOnPush" ng-checked="loginData.vibrateOnPush" toggle-class="toggle-calm">{{'kVibrateOnPush'| translate }}</ion-toggle>
+ <ion-toggle ng-if="loginData.isUseEventServer" ng-model="loginData.soundOnPush" ng-checked="loginData.soundOnPush" toggle-class="toggle-calm" class="item-text-wrap">{{'kSoundOnPush'| translate }}</ion-toggle>
+ <!--
+ <ion-toggle ng-model="loginData.defaultPushSound" toggle-class="toggle-calm" class="item-text-wrap" ng-checked="{{loginData.defaultPushSound}}">use system sound<p>please save and restart app</p></ion-toggle>
+ -->
+ <ion-list>
+ <div ng-repeat="monitor in monitors">
+ <ion-item class="custom-list" ng-click="toggleGroup(monitor)" ng-class="{active: isGroupShown(monitor)}">
+ <i class="icon" ng-class="isGroupShown(monitor) ? 'ion-minus' : 'ion-plus'"></i> &nbsp; {{monitor.Monitor.Name}}
+ </ion-item>
+ <ion-item class="item-accordion" ng-show="isGroupShown(monitor)">
+ <span class="item-checkbox">
+
+ {{'kReportEvents' | translate }}
+ <label class="checkbox">
+ <input type="checkbox" ng-model="monitor.Monitor.isChecked" ng-checked="monitor.Monitor.isChecked">
+ </label>
+ </span>
+ </ion-item>
+ <ion-item class="item-accordion" ng-show="isGroupShown(monitor)">
+ <div class="item-input-inset">
+ <label class="item-input-wrapper">
+ <input type="tel" placeholder="{{'kSec' | translate}}" ng-model="monitor.Monitor.reportingInterval">
+ </label>
+ &nbsp;{{'kMinimumIntervals' | translate}}
+ </div>
+ </ion-item>
+ </div>
+ </ion-list>
+ </ion-content>
+</ion-view>
diff --git a/www/templates/first-use.html b/www/templates/first-use.html
new file mode 100644
index 00000000..884fb0c9
--- /dev/null
+++ b/www/templates/first-use.html
@@ -0,0 +1,38 @@
+<ion-view view-title="{{$root.appName}}" hide-nav-bar="true" hide-back-button="true" cache-view="false">
+ <ion-content class="pin-background">
+ <div style="margin-left:20px; margin-right:20px">
+ <center>
+ <br/>
+ <br/>
+ <div id="responsive-image">
+ <img src="img/authlogo.png">
+ </div>
+ <br/>
+ <span style="color:white">
+ <h2 style="color:white" >Hi There!</h2>
+ <br/>
+ <h4 style="color:white">{{'kThanksForUsing' | translate}} {{$root.appName}}. <br/><br/>
+ {{'kNeedToKnow' | translate}}
+ </h4>
+ <br/>
+
+ </span>
+ <br/>
+ <div id="firstuse">
+ <button class="button icon icon-left ion-wand button-stable animated bounceInUp" ng-click="goToWizard()">
+ {{'kWizard' | translate}}
+ </button>
+ <button class="button icon icon-left ion-university button-stable animated bounceInUp" ng-click="goToLogin()">
+ {{'kExpert' | translate }}
+ </button>
+ <br/>
+ <center>
+ <button class="button button-clear icon icon-left ion-android-globe white-button-text animated bounceInUp" ng-click="switchLang()">
+ {{'kLanguage' | translate}}
+ </button>
+ </center>
+ </div>
+ </center>
+ </div>
+ </ion-content>
+</ion-view>
diff --git a/www/templates/help.html b/www/templates/help.html
new file mode 100644
index 00000000..c0f714cf
--- /dev/null
+++ b/www/templates/help.html
@@ -0,0 +1,12 @@
+<ion-view cache-view="false" view-title="{{'kHelp' | translate}}">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ <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 class="padding" scroll-sista delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+ <p><small>{{$root.appName}} v{{zmAppVersion}}</small></p>
+ <div class="list">
+ <div id="insertHelp"></div>
+ </div>
+ </ion-content>
+</ion-view>
diff --git a/www/templates/help/montage-help.html b/www/templates/help/montage-help.html
new file mode 100644
index 00000000..ff51a755
--- /dev/null
+++ b/www/templates/help/montage-help.html
@@ -0,0 +1,16 @@
+<!--- NOT USED -->
+<ion-popover-view style="width:90%">
+ <ion-header-bar class="item item-divider">
+ Montage Help
+ </ion-header-bar>
+ <ion-content padding="true">
+ <div class="row">
+ <div class="col col-10">
+ <i class="ion-log-in"></i>
+ </div>
+ <div class="col col-90">
+ There
+ </div>
+ </div>
+ </ion-content>
+</ion-popover-view>
diff --git a/www/templates/important_message.html b/www/templates/important_message.html
new file mode 100644
index 00000000..f0fd245e
--- /dev/null
+++ b/www/templates/important_message.html
@@ -0,0 +1,34 @@
+<ion-view view-title="{{$root.appName}}" hide-nav-bar="false" hide-back-button="false" cache-view="false">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ </ion-nav-buttons>
+ <ion-content class="pin-background">
+ <div style="margin-left:20px; margin-right:20px">
+ <center>
+ <br/>
+ <br/>
+ <div id="responsive-image">
+ <img src="img/authlogo.png">
+ </div>
+ <br/>
+ <span style="color:white">
+ <h2 style="color:white" class="animated bounce">{{'kImpMsg1' | translate}}</h2>
+ <br/>
+ <h4 style="color:white">{{'kImpMsg2' | translate}}</h4>
+ <br/>
+ {{'kImpMsg3' | translate}} v{{currentVersion}}.<br/> v{{recommendedVersion}} {{'kImpMsg4' | translate}}
+ <br/>
+ {{'kImpMsg5' | translate}}: <b>v{{currentVersion}}</b><br/>
+ {{'kImpMsg6' | translate}}:<b>v{{recommendedVersion}}</b><br/><br/>
+
+ <button class="button button-stable animated bounceInUp" ng-click="openMenu()">
+ {{'kImpMsg7' | translate}}
+ </button>
+
+
+ </span>
+ </center>
+ <br/>
+ </div>
+ </ion-content>
+</ion-view>
diff --git a/www/templates/invalidapi.html b/www/templates/invalidapi.html
new file mode 100644
index 00000000..af3a6977
--- /dev/null
+++ b/www/templates/invalidapi.html
@@ -0,0 +1,30 @@
+<ion-view view-title="{{$root.appName}}" hide-nav-bar="false" hide-back-button="false" cache-view="false">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ </ion-nav-buttons>
+ <ion-content class="pin-background">
+ <div style="margin-left:20px; margin-right:20px">
+ <center>
+ <br/>
+ <br/>
+ <div id="responsive-image">
+ <img src="img/authlogo.png">
+ </div>
+ <br/>
+ <span style="color:white">
+ <h2 style="color:white" class="animated bounce">{{'kInvalidAPIHeader' | translate}}</h2>
+ <br/>
+ <h4 style="color:white">{{'kInvalidAPIBody' | translate}}</h4>
+
+ <br/><br/>
+
+ <button class="button button-stable animated bounceInUp" ng-click="readFAQ()">
+ {{'kInvalidAPIRead' | translate}}</button>
+
+
+ </span>
+ </center>
+ <br/>
+ </div>
+ </ion-content>
+</ion-view>
diff --git a/www/templates/log.html b/www/templates/log.html
new file mode 100644
index 00000000..c664901d
--- /dev/null
+++ b/www/templates/log.html
@@ -0,0 +1,38 @@
+<ion-view view-title="{{logEntity}} {{'kLogs' | translate}}">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ <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-nav-buttons side="right">
+ <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 style="" class="button button-icon icon ion-email" ng-href="" ng-click="sendEmail(log.logString)"> </a>
+ </div>
+ <div ng-if="$root.platformOS=='desktop'">
+ <a style="" class="button button-icon icon ion-android-download" ng-href="" ng-click="sendEmail(log.logString)"> </a>
+ </div>
+ </ion-nav-buttons>
+ <ion-content scroll-sista delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+
+ <div ng-if="logEntity=='ZoneMinder'">
+
+ <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>
+ </div>
+
+ <div ng-if="logEntity==$root.appName">
+ <b>{{$root.appName}} {{'kVersion'|translate}}: {{zmAppVersion}} ({{$root.platformOS}})</b>
+ </div>
+
+ <div ng-if="logEntity!=$root.appName">
+ <b>ZoneMinder</b>
+ </div>
+
+
+ <br/>
+ <!-- don't indent here its a pre-->
+ <pre>{{log.logString}}</pre>
+ </ion-content>
diff --git a/www/templates/login.html b/www/templates/login.html
new file mode 100644
index 00000000..a6f409b2
--- /dev/null
+++ b/www/templates/login.html
@@ -0,0 +1,86 @@
+<ion-view view-title="{{'kSettings' | translate}}" cache-view="false">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ <button class="button button-icon button-clear ion-arrow-down-b" ng-click="serverActionSheet()"></button>
+ <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-nav-buttons side="right">
+ <button class="button button-clear" ng-click="saveItems()">{{'kSave' | translate}}</button>
+ </ion-nav-buttons>
+ <ion-content scroll-sista delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+ <div class="item item-text-wrap item-input-inset">
+ {{'kServerName' | translate }}:&nbsp;
+ <label class="item-input-wrapper">
+ <input autocorrect="off" type="text" placeholder="{{'kExampleServer' | translate}}" ng-model="loginData.serverName">
+ </label>
+ </div>
+ <label>
+ <ion-toggle ng-model="loginData.enableLowBandwidth" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kLowBandwidth'|translate}}</span>
+ </ion-toggle>
+ </label>
+ <label ng-if="loginData.enableLowBandwidth">
+ <ion-toggle ng-model="loginData.autoSwitchBandwidth" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kAutoSwitchBW'|translate}}</span>
+ </ion-toggle>
+ </label>
+ <div class="list list-inset">
+ <span style="color:rgb(100,100,100)">
+ <i class="ion-android-home" style="font-size:150%"></i>
+ {{'kZMSettingsFor' | translate}} {{loginData.serverName || ('kUnknown' | translate)}}
+ </span>
+ <p ng-if="$root.platformOS=='android'" style="font-size:0.8em; color:gray">{{'kDisableSamsung' | translate}}</p>
+ <div class="item item-text-wrap">
+ <ion-checkbox ng-model="check.isUseAuth">{{'kUseZmAuth' | translate }}</ion-checkbox>
+ <div ng-if="check.isUseAuth">
+ <label class="item item-input item-floating-label">
+ <span class="input-label">{{'kUserName'|translate}}</span>
+ <input autocapitalize="none" autocomplete="off" autocorrect="off" type="text"
+ placeholder="{{'kUserName' | translate}}" ng-model="loginData.username">
+ </label>
+ <label class="item item-input item-floating-label">
+ <span class="input-label">{{'kPassword' | translate}}</span>
+ <input type="password" placeholder="{{'kPassword' | translate}}" ng-model="loginData.password">
+ </label>
+ </div>
+ </div>
+ <label class="item item-input item-floating-label">
+ <span class="input-label">{{'kPortalUrl' | translate}}</span>
+ <input hidepassword autocapitalize="none" autocomplete="off" autocorrect="off" type="text" placeholder="{{'kPortalUrlExample' | translate}}" ng-model="loginData.url" ng-keyup="portalKeypress($event)">
+ </label>
+ <!--<button class="button button-small button-clear icon-left ion-wand" ng-click="detectCgi()">tap here to discover cgi-bin
+ </button>-->
+ <label class="item item-input item-floating-label">
+ <!--<span style="float:right;margin-top:-7px;background-color:#6d0909;color:#fff;font-size:14px;opacity:0.7;width:90px;border-radius: 0px 0px 5px 5px;" on-tap="detectCgi();">&nbsp;&nbsp;&nbsp;<i class="ion-wand"></i>discover</span>-->
+ <span class="input-label">{{'kPathToCgi' | translate}}</span>
+ <input hidepassword autocapitalize="none" autocomplete="off" autocorrect="off" type="text" placeholder="{{'kPathToCgiExample' | translate}}" ng-model="loginData.streamingurl">
+ </label>
+ <label class="item item-input item-floating-label">
+ <span class="input-label">{{'kApiUrl' | translate}}</span>
+ <input hidepassword autocapitalize="none" autocomplete="off" autocorrect="off" type="text" placeholder="{{'kApiUrlExample' | translate}}" ng-model="loginData.apiurl">
+ </label>
+ <a class="item item-icon-right" href="" ng-click="selectFallback()">
+ <i class="icon ion-ios-arrow-right">
+ </i> {{'kFallback' | translate}}
+ <p>{{loginData.fallbackConfiguration}}</p>
+ </a>
+ <a class="item item-icon-right" href="" ng-click="eventServerSettings()">
+ <i class="icon ion-ios-arrow-right">
+ </i> {{'kEventServer' | translate}}
+ </a>
+ <div ng-if="$root.platformOS != 'desktop'">
+ <label>
+ <ion-toggle ng-model="loginData.usePin" ng-change="pinPrompt();" ng-checked="{{loginData.usePin}}" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kPassword' | translate}} {{'kProtect'|translate}}</span></ion-toggle>
+ </label>
+ </div>
+ <label>
+ <ion-toggle ng-model="loginData.useSSL" ng-checked="{{loginData.useSSL}}" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kUseSSL' | translate}}</span></ion-toggle>
+ </label>
+ <div ng-if="$root.platformOS != 'desktop'">
+ <label>
+ <ion-toggle ng-model="loginData.keepAwake" ng-checked="{{loginData.keepAwake}}" toggle-class="toggle-calm"><span class="item-text-wrap">{{'kAwake1'|translate}}
+ <p>{{'kAwake2'| translate}}</p></span>
+ </ion-toggle>
+ </label>
+ </div>
+ </div>
+ </ion-content>
+</ion-view>
diff --git a/www/templates/lowversion.html b/www/templates/lowversion.html
new file mode 100644
index 00000000..d6b9cb7e
--- /dev/null
+++ b/www/templates/lowversion.html
@@ -0,0 +1,25 @@
+<ion-view view-title="{{$root.appName}}" hide-nav-bar="true" hide-back-button="true" cache-view="false">
+ <ion-content class="pin-background">
+ <div style="margin-left:20px; margin-right:20px">
+ <center>
+ <br/>
+ <br/>
+ <div id="responsive-image">
+ <img src="img/authlogo.png">
+ </div>
+ <br/>
+ <span style="color:white">
+ <h2 style="color:white" class="animated bounce">{{'kZMUpgradeNeeded' | translate}}</h2>
+ <br/>
+ <h4 style="color:white">{{'kVersionIncompatible' | translate }}</h4>
+ <br/>
+ {{'kReportedVersion' | translate}}: <b>{{currentVersion}}</b><br/>
+ {{'kMinVersion' | translate}}:<b>{{requiredVersion}}</b><br/>
+
+
+ </span>
+ <br/>
+ </center>
+ </div>
+ </ion-content>
+</ion-view>
diff --git a/www/templates/monitors-modal.html b/www/templates/monitors-modal.html
new file mode 100644
index 00000000..45b3a9d1
--- /dev/null
+++ b/www/templates/monitors-modal.html
@@ -0,0 +1,160 @@
+<div ng-controller="MonitorModalCtrl" ng-cloak>
+ <ion-modal-view cache-view="false" style="background-color:#444444">
+ <ion-content ng-cloak on-double-tap="closeModal();" scroll="false">
+
+ <div id="imagecontainer" >
+ <ion-scroll ng-if="!isZoneEdit" on-scroll="checkZoom()" delegate-handle="imgscroll" has-bouncing=false min-zoom=1 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 && !isBackground() && connKey">
+ <!--<span style="color:white">{{currentStreamMode}}</span>-->
+
+ <img id="singlemonitor" style="width:100vw; height:100vh;" image-spinner-loader="lines" image-spinner-src="{{monitor.Monitor.streamingURL}}/nph-zms?mode={{currentStreamMode}}&monitor={{monitorId}}&scale={{quality}}{{$root.authSession}}&rand={{$root.modalRand}}&connkey={{connKey}}" ng-class="{'object-fit_cover':imageFit==false, 'object-fit_contain':imageFit==true}" on-swipe-left="onSwipe(monitorId,1)" on-swipe-right="onSwipe(monitorId,-1)" on-double-tap="closeModal();" imageonload="imageLoaded()" />
+ </div>
+ <div ng-if="animationInProgress || isBackground()">
+ <img style="width:100vw; height:100vh" ng-src="img/pausevideo.png" class="object-fit_contain" />
+ </div>
+ </div>
+ <div ng-if="$root.authSession=='undefined'">
+ <img id="singlemonitor" ng-src="img/pausevideo.png" style="width:100vw; height:100vh; display:block;" class="object-fit_contain" width="{{((devWidth)/(7-monitorSize[$index]))}}px;" />
+ </div>
+ </div>
+ </ion-scroll>
+
+ <!-- egads, ion-scroll is a bind-on-start directive, so I have to repeat this thanks to zooming = false. Must be a better way -->
+ <ion-scroll ng-if="isZoneEdit" delegate-handle="imgscroll" has-bouncing=false min-zoom=1 zooming="false" 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 && !isBackground() && connKey">
+ <!--<span style="color:white">{{currentStreamMode}}</span>-->
+
+ <img id="singlemonitor" style="width:100vw; height:100vh;" image-spinner-loader="lines" image-spinner-src="{{monitor.Monitor.streamingURL}}/nph-zms?mode={{currentStreamMode}}&monitor={{monitorId}}&scale={{quality}}{{$root.authSession}}&rand={{$root.modalRand}}&connkey={{connKey}}" ng-class="{'object-fit_cover':imageFit==false, 'object-fit_contain':imageFit==true}" on-swipe-left="onSwipe(monitorId,1)" on-swipe-right="onSwipe(monitorId,-1)" on-double-tap="closeModal();" imageonload="imageLoaded()" />
+ </div>
+ <div ng-if="animationInProgress || isBackground()">
+ <img style="width:100vw; height:100vh" ng-src="img/pausevideo.png" class="object-fit_contain" />
+ </div>
+ </div>
+ <div ng-if="$root.authSession=='undefined'">
+ <img id="singlemonitor" ng-src="img/pausevideo.png" style="width:100vw; height:100vh; display:block;" class="object-fit_contain" width="{{((devWidth)/(7-monitorSize[$index]))}}px;" />
+ </div>
+ </div>
+ </ion-scroll>
+
+ <!-- zone overlays if enabled -->
+ <div ng-show="showZones">
+ <svg id="zsvg" width="100vw" height="100vh" class="zonelayer" ng-attr-view_box="0 0 {{cw}} {{ch}}" ng-attr-preserve_aspect_ratio="{{aspectFit}}" on-swipe-left="onSwipe(monitorId,1)" on-swipe-right="onSwipe(monitorId,-1)" on-double-tap="closeModal();">
+
+ <polygon ng-repeat="item in zoneArray track by $index" ng-class="{'object-fit_cover {{item.type}}':imageFit==false, 'object-fit_contain {{item.type}}':imageFit==true}" ng-attr-points="{{item.coords}}" /> </polygon>
+
+
+ <circle id="circle-{{$index}}" ng-show="isZoneEdit" ng-repeat="item in circlePoints track by $index" class="zonepoint" ng-class="{'object-fit_cover {{item.type}}':imageFit==false, 'object-fit_contain {{item.type}}':imageFit==true}" ng-attr-cx="{{item.x}}" ng-attr-cy="{{item.y}}" ng-attr-r="{{csize}}"/>
+
+
+ </svg>
+ </div>
+
+
+
+ </div>
+ </ion-content>
+ <div ng-show="isControllable=='1' && showPTZ">
+ <div class="ptzcentered">
+ <circular options="ptzRadialMenuOptions">
+ </circular>
+ </div>
+ <div ng-if="presetOn" class="ptzpresetbuttons animated fadeInDown" id="presetlist">
+ <ion-scroll style="height:170px">
+ <div ng-repeat="preset in ptzPresets track by $index">
+ <button class="button {{preset.icon}} button-small {{preset.style}}" style="float:left;margin-right:10px;margin-bottom:10px;" ng-click="controlPTZ(monitorId, preset.cmd);">{{preset.name}}</button>
+ </div>
+ </ion-scroll>
+ </div>
+ <div class="ptzcenteredbotbutton">
+ <div ng-if="canZoom">
+ <a class="button button-small icon ion-search button-positive" href="" ng-click="controlPTZ(monitorId, zoomInCommand);">+</a>
+ <a class="button button-small icon ion-search button-positive" href="" ng-click="controlPTZ(monitorId, zoomOutCommand);">-</a>
+ <a class="button button-small icon ion-search button-positive" href="" ng-click="controlPTZ(monitorId, zoomStopCommand);">x</a>
+ </div>
+ <br/>
+ <a class="button button-small icon ion-stop button-assertive" href="" ng-click="controlPTZ(monitorId, ptzStopCommand);"></a>
+ <a class="button button-small button-royal" href="" ng-click="togglePresets();">{{controlToggle}}</a>
+ </div>
+ </div>
+ </ion-modal-view>
+ <nav mfb-menu position="br" effect="zoomin" label="{{'kCollapse' | translate}}" active-icon="ion-chevron-down" resting-icon="ion-chevron-up" toggling-method="click">
+ <button mfb-button icon="ion-arrow-resize" label="{{imageFit? ('kFillScreen' | translate):('kFitScreen' | translate)}}" ng-click="scaleImage();">
+ </button>
+ <button mfb-button icon="ion-refresh" label="{{'kRefresh' | translate}}" ng-click="reloadView();">
+ </button>
+ <button mfb-button icon="ion-arrow-expand" label="{{'kControl'| translate}}" ng-click="togglePTZ();">
+ </button>
+ </nav>
+ <nav mfb-menu position="tr" effect="zoomin" label="{{'kCollapse' | translate}}" active-icon="ion-chevron-up" resting-icon="ion-chevron-down" toggling-method="click">
+ <button mfb-button icon="ion-android-arrow-back" label="{{'kPrevMonitor' | translate}} " ng-click="onTap(monitorId,-1);">
+ </button>
+ <button mfb-button icon="ion-android-arrow-forward" label="{{'kNextMonitor' | translate}}" ng-click="onTap(monitorId,1);">
+ </button>
+ <button mfb-button icon="ion-close" label="{{'kExitLiveView' | translate}}" ng-click="closeModal();">
+ </button>
+ </nav>
+ <div id="flyoutmenu" style="position:absolute;bottom:80px;left:10px">
+ <ul>
+
+ <li>
+ <a href="" ng-click="toggleListMenu()">&nbsp; <i ng-class="(isToggleListMenu) ? 'icon ion-chevron-left': 'icon ion-chevron-right'"></i>&nbsp;</a>
+ </li>
+
+ <li ng-if="isToggleListMenu">
+ <a href="" ng-click="saveImageToPhoneWithPerms(monitorId)"> <i class="icon ion-ios-camera"></i></a>
+ </li>
+ <li ng-if="$root.platformOS == 'desktop' && isToggleListMenu">
+ <a href="" ng-click="zoomImage(1)"><i class="ion-plus-round"></i></a>
+ </li>
+ <li ng-if="$root.platformOS == 'desktop' && isToggleListMenu">
+ <a href="" ng-click="zoomImage(-1)"><i class="ion-minus-round"></i></a>
+ </li>
+ <li ng-if="isToggleListMenu">
+ <a href="" ng-click="enableAlarm(monitorId,true)"> <i class="icon ion-flash"></i></a>
+ </li>
+ <li ng-if="isToggleListMenu">
+ <a href="" ng-click="enableAlarm(monitorId,false)"> <i class="icon ion-flash-off"></i></a>
+ </li>
+
+ <li ng-if="isToggleListMenu">
+ <a href="" ng-click="toggleZone()"> <i class="icon ion-qr-scanner"></i></a>
+ </li>
+
+ <!-- zone editing is TBD -->
+ <li ng-if="showZones && 0 && isToggleListMenu">
+ <a href="" ng-click="toggleZoneEdit()"> <i class="icon ion-edit"></i></a>
+ </li>
+
+ <li ng-if="showZones && isZoneEdit && isToggleListMenu">
+ <a href="" ng-click="saveZones()"> <i class="icon ion-android-done-all"></i></a>
+ </li>
+
+ <li ng-if="showZones && isZoneEdit && isToggleListMenu">
+ <a href="" ng-click="changeCircleSize()"> <i class="icon ion-navigate"></i></a>
+ </li>
+
+ <li ng-if="isToggleListMenu">
+ <a href="" ng-click="toggleCycle()"> <i class="icon ion-android-bicycle"></i>-{{cycleText}}</a>
+ </li>
+
+
+
+ <!--<li>
+
+ <a href="" ng-click="cast(monitorId, monitor)"> <i class="icon ion-android-funnel"></i></a>
+ </li>-->
+ <li ng-if="$root.isAlarm">
+ <a data-badge="{{$root.alarmCount}}" class="notification-badge animated infinite tada" href="" ng-click="handleAlarms()"><i class="ion-ios-bell"></i></a>
+ </li>
+ </ul>
+ </div>
+ <div class="monitor-modal-text">{{monitorName}} &nbsp;<span style="{{stateColor()}}">{{monStatus}}&nbsp;</span></div>
+</div>
diff --git a/www/templates/monitors.html b/www/templates/monitors.html
new file mode 100644
index 00000000..cd9e8e8e
--- /dev/null
+++ b/www/templates/monitors.html
@@ -0,0 +1,62 @@
+<ion-view view-title="{{'kMonitors' | translate}}" cache-view="false">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()">
+ </button>
+ <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 scroll-sista delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+ <ion-refresher pulling-text="Pull to reload Monitors..." spinner="bubbles" on-refresh="doRefresh()">
+ </ion-refresher>
+ <div style="float:right;margin-top:3px;margin-right:8px;">
+ <a class="button button-small icon icon-left icon ion-ios-world-outline" href="" ng-click="changeConfig('All', '','1','Monitor');">{{'kGlobalConfiguration' | translate}}</a>
+ </div>
+ <br/>
+ <div class="list card" ng-repeat="monitor in monitors">
+ <div class="item" ng-style="{'background-color': monitor.Monitor.Enabled=='1'?'white':'white'}">
+ <div ng-if="monitor.Monitor.Enabled == '1'">
+ <div class='item'>
+ <span class="item-icon-left">
+
+ <div class="icon">
+ <span class="ion-ios-videocam-outline"></span> &nbsp;
+ <span ng-class="{'ion-eye':monitor.Monitor.listDisplay=='show','ion-eye-disabled':monitor.Monitor.listDisplay!='show'}"> </span>
+ </div>
+ &nbsp;
+ <b>{{monitor.Monitor.Name}}</b>
+ </span>
+ <span class="item-icon-right">
+ <i class="icon {{monitor.Monitor.char}}" style="color:{{monitor.Monitor.color}};"></i>
+ </span>
+ <!-- <i ng-class="{'icon ion-eye':monitor.Monitor.listDisplay=='show','icon ion-eye-disabled':monitor.Monitor.listDisplay!='show'}"> </i>-->
+ </div>
+ </div>
+ <div ng-if="monitor.Monitor.Enabled != '1'">
+ <span class='item item-icon-left item-icon-right'>
+ <i class="icon ion-ios-videocam-outline"></i>
+ <b>{{monitor.Monitor.Name}}</b>
+ <i class="icon {{monitor.Monitor.char}}" style="color:grey;"></i>
+ </span>
+ </div>
+ <p>{{'kMode' | translate}} :{{monitor.Monitor.Function}}
+ <br/> {{'kResolution' | translate}}: {{monitor.Monitor.Width}}*{{monitor.Monitor.Height}}
+ <br/> {{'kMaxFPS' | translate}}: {{monitor.Monitor.MaxFPS}}
+ <br/> {{'kAlarmMaxFPS' | translate}}:{{monitor.Monitor.AlarmMaxFPS}}
+ <br/> {{'kAlarmFrameCount' |translate}}: {{monitor.Monitor.AlarmFrameCount}}
+ <br/> {{'kStatus' | translate}}: {{monitor.Monitor.isRunningText}}
+ <br/> {{'kId' | translate}}: {{monitor.Monitor.Id}}
+ <br/> {{'kEventRecording' | translate}}: {{(monitor.Monitor.VideoWriter>0?'kVideo':'kImages') | translate}}
+ <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' | translate}}</a>
+ <a class="button button-small icon icon-left ion-calendar" href="#/events/{{monitor.Monitor.Id}}/false">{{'kEventsCap'|translate}}</a>
+ <a class="button button-small icon icon-left ion-ios-eye" ng-click="openModal(monitor.Monitor.Id, monitor.Monitor.Controllable, monitor.Monitor.ControlId, monitor.Monitor.connKey, monitor)">{{'kLiveView' | translate}}</a>
+ </div>
+ </div>
+ </div>
+ <ion-item ng-show="!monitors.length">
+ {{'kNoMonitors' | translate}}
+ </ion-item>
+ </ion-content>
+</ion-view>
diff --git a/www/templates/montage-history.html b/www/templates/montage-history.html
new file mode 100644
index 00000000..785a348d
--- /dev/null
+++ b/www/templates/montage-history.html
@@ -0,0 +1,139 @@
+<ion-view view-title="{{'kEventMontage' | translate}}" cache-view="false" hide-nav-bar="{{minimal}}">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ <button class="button button-icon button-clear ion-arrow-move" ng-click="dragToggle();">&nbsp; </button>
+ <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-nav-buttons side="right">
+ <button class="button button-icon button-clear ion-loop" ng-click="resetSizes();">&nbsp; </button>
+ <button class="button button-icon button-clear ion-plus-round" ng-click="sliderChanged(1);">&nbsp; </button>
+ <button class="button button-icon button-clear ion-minus-round" ng-click="sliderChanged(-1);">&nbsp; </button>
+ <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 scroll-sista has-bouncing="false" style="background-color:#444444" delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+ <div class="timeline_text"> {{'kFrom' | translate}}:{{prettifyDateTimeFirst(datetimeValueFrom.value)}} ({{humanizeTime(datetimeValueFrom.value)}})
+ <div ng-if="$root.platformOS != 'ios'">({{'kChromeMax' | translate}})</div>
+ </div>
+ <div class="grid" id="mygrid">
+ <div class="grid-sizer grid-item-10"></div>
+ <!-- <span ng-repeat="monitor in MontageMonitors|limitTo: monLimit" ng- -->
+ <span ng-repeat="monitor in MontageMonitors | onlyEnabledAndEventHas |limitTo: currentLimit">
+ <div ng-if="$root.authSession!='undefined'">
+ <div ng-if = "monitor.Monitor.eventUrl == 'img/noevent.png' ">
+ <!-- make sure we don't use id here
+ or we lose the handle for cleanup forever!-->
+ <div class="grid-item grid-item-{{monitor.Monitor.gridScale}} " data-item-id="{{monitor.Monitor.Id}}" data-item-size="{{monitor.Monitor.gridScale}}" data-item-listdisplay="{{monitor.Monitor.listDisplay}}" >
+ <figure height="{{Monitor.monitor.height}}" width="{{Monitor.monitor.width}}" class="{{dragBorder}}" ng-show=" monitor.Monitor.listDisplay!='noshow'">
+ <img class="{{monitor.Monitor.selectStyle}}" image-spinner-src="{{monitor.Monitor.eventUrl}}" image-spinner-loader="lines" on-tap="!isDragabillyOn?noop():toggleSelectItem($index)" >
+ <figcaption class="normal-figcaption" >
+
+ &nbsp;
+
+ <i class="ion-ios-videocam"></i>
+ {{monitor.Monitor.Name}}&nbsp;
+
+
+
+ </figcaption>
+ </figure>
+ </div>
+ </div>
+ <div ng-if = "monitor.Monitor.eventUrl != 'img/noevent.png' && monitor.Monitor.connKey !=''">
+ <div class="grid-item grid-item-{{monitor.Monitor.gridScale}} " data-item-id="{{monitor.Monitor.Id}}" data-item-size="{{monitor.Monitor.gridScale}}" data-item-listdisplay="{{monitor.Monitor.listDisplay}}" >
+ <figure height="{{Monitor.monitor.height}}" width="{{Monitor.monitor.width}}" class="{{dragBorder}}" ng-show=" monitor.Monitor.listDisplay!='noshow'">
+ <img class="{{monitor.Monitor.selectStyle}}" image-spinner-src="{{monitor.Monitor.eventUrl}}{{$root.authSession}}" image-spinner-loader="lines" on-tap="!isDragabillyOn?togglePause(monitor.Monitor.Id):toggleSelectItem($index)" on-swipe-left="toggleControls()" on-swipe-right="toggleControls()" />
+ <figcaption class="normal-figcaption" >
+
+ &nbsp;
+
+ <i class="ion-ios-videocam"></i>
+ <span style="background-color:red;color:#fff" ng-if="monitor.Monitor.isPaused">&nbsp;
+
+ <i class="ion-pause"></i>&nbsp;
+
+ </span> {{monitor.Monitor.Name}}&nbsp;
+ <div ng-if="sliderVal.showTimeline && $root.runMode!='lowbw'" style="white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-size:9px" class="header-event-id" id="{{monitor.Monitor.Id}}-timeline">[{{monitor.Monitor.eid}}]
+ <i class="ion-clock"></i> {{prettifyDateTimeFirst(monitor.Monitor.eventUrlTime)}} ({{humanizeTime(monitor.Monitor.eventUrlTime)}})&nbsp;
+ </div>
+ </figcaption>
+ </figure>
+ <!-- wait for packery otherwise we get large ranges -->
+ <div ng-show="packeryDone">
+ <div class="range" style="position:absolute;top:5%;width:95%;z-index:999">
+ <input on-release="seek(monitor.Monitor.Id,monitor.Monitor.sliderProgress.progress )" type="range" min="0" max="{{monitor.Monitor.eventDuration}}" ng-model="monitor.Monitor.sliderProgress.progress">
+ </div>
+ <div id="history_canvas_video">
+ <canvas style="padding-left:23px;
+ padding-right:23px;z-index:998" id="eventchart-{{monitor.Monitor.Id}}" width="auto" height="20"></canvas>
+ </div>
+ </div>
+ <div ng-if="monitor.Monitor.seek" style="position:absolute;top:0px; left: 0px; width:100%;height:100%; background-color:rgba(0,0,0,0.3); z-index:99999">
+ <div style="position:relative;top:50%;text-align:center;color:white;background-color:rgba(0,0,0,0.5);">{{'kPleaseWait' | translate}}</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- valid auth session &!background -->
+ <!--<div ng-if="!$root.authSession=='undefined' || isBackground()">
+ <img image-spinner-src="img/pausevideo.png" />
+ </div>-->
+ </span>
+ </div>
+ <ion-item ng-show="!MontageMonitors.length"> {{'kNoMonitors' | translate }} </ion-item>
+ </ion-content>
+ <div class="bwmode" ng-if="$root.runMode=='lowbw'"> {{ 'kLowBWDisplay' | translate }} </div>
+ <div ng-show="minimal">
+ <nav mfb-menu position="br" effect="zoomin" label="collapse" active-icon="ion-chevron-down" resting-icon="ion-chevron-up" toggling-method="click">
+ <button mfb-button icon="ion-arrow-expand" label="increase size" ng-click="changeSize(-1)"></button>
+ <button mfb-button icon="ion-arrow-shrink" label="decrease size" ng-click="changeSize(1)"></button>
+ <button mfb-button icon="ion-refresh" label="refresh" ng-click="reloadView();"></button>
+ <button mfb-button icon="ion-close" label="exit full screen" ng-click="switchMinimal()"></button>
+ </nav>
+ <span class="modal-alarm-badge">
+ <a data-badge="{{$root.alarmCount}}" class="animated infinite tada button icon ion-ios-bell notification-badge button-assertive"
+ ng-click="handleAlarmsWhileMinimized();" ng-if="$root.isAlarm"></a>
+ </span>
+ </div>
+ <ion-pull-up-footer class="zmPullup" on-expand="footerExpand()" on-minimize="footerCollapse()" on-collapse="footerCollapse()" initial-state="minimized" default-behavior="expand">
+ <ion-pull-up-handle width="100" height="25" toggle="ion-chevron-up ion-chevron-down" style="border-radius: 25px 25px 0 0">
+ <i class="icon ion-chevron-up"></i>
+ </ion-pull-up-handle>
+ <ion-pull-up-bar>
+ <h1 class="title" ion-pull-up-trigger>{{'kEventMontage' | translate}}</h1>
+ </ion-pull-up-bar>
+ <ion-pull-up-content scroll="true">
+ <div class="list list-inset">
+ <div class="item item-divider">{{'kTimeline' | translate}} ({{getLocalTZ()}})</div>
+ <div class="item item-input-inset"> {{'kFrom'|translate}}:&nbsp;
+ <div class="row">
+ <div class="col col-50">
+ <label class="item-input-wrapper">
+ <input ng-change="hrsChanged()" type="tel" placeholder="{{'kHours' | translate}}" ng-model="datetimeValueFrom.hrs">
+ </label>
+ </div>
+ <div class="col col-50">
+ &nbsp;{{'kEventHistHrs' | translate}}
+ </div>
+ </div>
+ </div>
+ <ion-item>
+ <div ion-datetime-picker title="From" am-pm={{!loginData.use24hr}} ng-model="datetimeValueFrom.value" ng-change="dateChanged()">
+ <b>{{'kFrom' | translate }}: </b>{{datetimeValueFrom.value | date: timeFormat}}
+ </div> ({{humanizeTime(datetimeValueFrom.value)}})
+ </ion-item>
+ <div class="row">
+ <div class="col col-75">
+ <br/>
+ <div style="width:90%;color:black;">
+ <input ng-model="sliderVal.rate" type="text" id="mySlider6" slider options="slider_modal_options_rate" />
+ </div>
+ <br/>
+ </div>
+ <div class="col col-25" style="background-color:#AEA8D3;text-align:center"> {{'kSpeed' | translate }} </div>
+ </div>
+ <!--<ion-item><div ion-datetime-picker am-pm={{!loginData.use24hr}} ng-model="datetimeValueTo.value"><b>{{'kTo' | translate}}: </b>{{datetimeValueTo.value | date: timeFormat}}
+ </div></ion-item>-->
+ </div>
+ </ion-pull-up-content>
+ </ion-pull-up-footer>
+</ion-view>
diff --git a/www/templates/montage.html b/www/templates/montage.html
new file mode 100644
index 00000000..e591179f
--- /dev/null
+++ b/www/templates/montage.html
@@ -0,0 +1,174 @@
+<ion-view cache-view="false" hide-nav-bar="{{minimal}}">
+ <ion-nav-title>{{currentProfileName}}</ion-nav-title>
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ <button class="button button-icon button-clear ion-eye" ng-click="hideUnhide();">&nbsp;
+ </button>
+ <button class="button button-icon button-clear ion-android-more-vertical" ng-click="toggleSubMenuFunction();">&nbsp;
+ </button>
+ <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-nav-buttons side="right">
+ <span ng-click="toggleTimeType()" class="icon montage-time">
+ <i ng-class="(iconTimeNow=='server')?'icon-server':'ion-ios-location'"></i>
+ {{timeNow}}&nbsp;</span>
+ <button class="button button-icon button-clear ion-arrow-move" ng-click="dragToggle();">&nbsp;
+ </button>
+ <!--
+ <button class="button button-icon button-clear ion-monitor" ng-click="cast();">&nbsp;
+ </button>
+ -->
+ <button class="button button-icon button-clear ion-loop" ng-click="resetSizes();">&nbsp;
+ </button>
+ <button class="button button-icon button-clear ion-android-contract" ng-click="switchMinimal()">
+ </button>
+ </ion-nav-buttons>
+ <ion-content ng-cloak has-bouncing="false" style="background-color:#444444" delegate-handle="montage-delegate" overflow-scroll="false">
+ <!--<ion-content scroll-sista ng-cloak has-bouncing="false" style="background-color:#444444" delegate-handle="montage-delegate" overflow-scroll="false">-->
+ <div ng-if="!minimal && toggleSubMenu" >
+ <!-- this is header -->
+ <br/>
+ <div id="flyoutmenu" style="float:left">
+ <ul>
+ <li>
+ <a href="" ng-click="sliderChanged(1)"> <i class="ion-plus-circled"></i></a>
+ </li>
+ <li>
+ <a href="" ng-click="sliderChanged(-1)"> <i class="ion-minus-circled"></i></a>
+ </li>
+ <li>
+ <a href="" ng-click="squeezeMonitors()"> <i class="ion-android-apps"></i></a>
+ </li>
+
+ <li ng-if="!isDragabillyOn">
+ <a href="" ng-click="toggleCycle()"> <i class="ion-android-bicycle"></i>:{{getCycleStatus()}}</a>
+ </li>
+
+ <li ng-if="isDragabillyOn">
+ <a href="" ng-click="hideMonitor(monitor.Monitor.Id)"> <i class="ion-close-circled"></i></a>
+ </li>
+ <li ng-if="isDragabillyOn">
+ <a href="" ng-click="toggleStamp()"> <i class="ion-pin"></i></a>
+ </li>
+
+ </ul>
+ </div>
+
+ <div id="flyoutmenu" style="float:right">
+ <ul>
+ <li>
+ <a href="" ng-click="switchMontageProfile()"> <i class="ion-navicon-round"></i></a>
+ </li>
+
+ <li>
+ <a href="" ng-click="saveMontageProfile()"> <i class="ion-heart"></i></a>
+ </li>
+
+ <li>
+ <a href="" ng-click="deleteMontageProfile()"> <i class="ion-trash-a"></i></a>
+ </li>
+
+
+ </ul>
+ </div>
+ <div style="clear: both;"></div>
+
+ <!-- <span ng-click="sliderChanged(1)" style="float:right;margin-top:0px;padding-top:8px;background-color:#5c6767;color:#fff;font-size:25px;opacity:1;width:40px;height:36px;border-radius: 0px 0px 0px 5px;">&nbsp;<i class="ion-plus-circled">&nbsp;</i></span>
+
+
+ <span ng-click="sliderChanged(-1)" style="float:left;margin-top:0px;padding-top:8px;background-color:#5c6767;color:#fff;font-size:22px;opacity:1;width:40px;height:36px;border-radius: 0px 0px 5px 0px;">&nbsp;<i class="ion-minus-circled">&nbsp;</i></span>
+
+ <span ng-click="" style="left:50%;margin-top:0px;padding-top:8px;background-color:#5c6767;color:#fff;font-size:11px;opacity:1;width:40px;height:36px;border-radius: 0px 0px 0px 5px;">&nbsp;<i class="ion-plus-circled">&nbsp;hello</i></span>
+ -->
+
+ <br/>
+ </div>
+ <!-- now lets draw the montage windows -->
+ <div class="grid" id="mygrid">
+ <div class="grid-sizer grid-item-5"></div>
+ <!-- <span ng-repeat="monitor in MontageMonitors|limitTo: monLimit"
+ ng-if="monitor.Monitor.Function!='None' && monitor.Monitor.Enabled !='0' ">-->
+ <span ng-repeat="monitor in MontageMonitors | onlyEnabled |limitTo: monLimit">
+
+
+
+
+ <div class="grid-item grid-item-{{monitor.Monitor.gridScale}} " data-item-id="{{monitor.Monitor.Id}}" data-item-size="{{monitor.Monitor.gridScale}}" data-item-listdisplay="{{monitor.Monitor.listDisplay}} " >
+
+
+
+ <figure class="{{dragBorder}}" ng-show="monitor.Monitor.listDisplay!='noshow'">
+ <!--<div ng-if="!isModalActive" >-->
+ <!--<div ng-if="$root.authSession!='undefined' && !isBackground() && !areImagesLoading">-->
+ <div ng-if="$root.authSession!='undefined' && !isBackground() ">
+ <div ng-if = "!minimal">
+
+
+
+ <img class="{{monitor.Monitor.selectStyle}}" id="img-{{$index}}" image-spinner-src="{{monitor.Monitor.streamingURL}}/nph-zms?mode=single&monitor={{monitor.Monitor.Id}}&scale={{LoginData.montageQuality}}{{$root.authSession}}&rand={{randToAvoidCacheMem}}" ng-click="!isDragabillyOn?openModal(monitor.Monitor.Id, monitor.Monitor.Controllable, monitor.Monitor.ControlId, monitor.Monitor.connKey,monitor):toggleSelectItem(monitor.Monitor.Id);" image-spinner-loader="lines" />
+
+
+
+ </div>
+
+ <div ng-if = "minimal">
+ <img id="img-{{$index}}" image-spinner-src="{{monitor.Monitor.streamingURL}}/zms?mode=single&monitor={{monitor.Monitor.Id}}&scale={{LoginData.montageQuality}}{{$root.authSession}}&rand={{randToAvoidCacheMem}}" ng-click="!isDragabillyOn?openModal(monitor.Monitor.Id, monitor.Monitor.Controllable, monitor.Monitor.ControlId, monitor.Monitor.connKey,monitor):toggleSelectItem(monitor.Monitor.Id);" image-spinner-loader="lines" />
+ </div>
+ </div>
+
+ <!--<div ng-if="!$root.authSession=='undefined' || isBackground() || areImagesLoading">
+
+ <img id="img-{{$index}}" image-spinner-src="img/pausevideo.png" />
+
+ <canvas style="background:black;width:{{monitor.Monitor.Width}}; "></canvas>
+ </div>-->
+
+
+
+
+ <figcaption id="slowpulse" ng-class="monitor.Monitor.isAlarmed==true?'alarmed-figcaption animated infinite flash':'normal-figcaption'" >&nbsp;
+
+ <span ng-if="monitor.Monitor.isStamp && isDragabillyOn"><i class="animated infinite flash ion-pin"></i>&nbsp;</span><i class="ion-ios-videocam"></i>&nbsp;
+ {{monitor.Monitor.Name}}&nbsp;<i ng-if="$root.runMode!='lowbw'" style="{{monitor.Monitor.alarmState}}" class="ion-record"></i>&nbsp;
+
+ </figcaption>
+
+
+
+ <!--</div>--> <!-- modal not active-->
+ <!--
+ <div ng-if="isModalActive">
+ <img img id="{{img-$index}}" image-spinner-src="img/pausevideo.png" />
+ </div>-->
+
+ </figure>
+
+ </div>
+ </span>
+ <!-- ngrepeat -->
+ </div>
+ <ion-item style="background-color:#444444; color:#fff;border:none;" ng-show="!MontageMonitors.length">
+ {{'kNoMonitors' | translate}}
+ </ion-item>
+ </ion-content>
+ <div class="bwmode" ng-if="$root.runMode=='lowbw'">
+ {{ 'kLowBWDisplay' | translate }}
+ </div>
+ <div ng-show="minimal">
+ <nav mfb-menu position="br" effect="zoomin" label="{{'kCollapse' | translate}}" active-icon="ion-chevron-down" resting-icon="ion-chevron-up" toggling-method="click">
+ <button mfb-button icon="ion-arrow-expand" label="{{'kIncreaseSize' | translate}}" ng-click="sliderChanged(1)">
+ </button>
+ <button mfb-button icon="ion-arrow-shrink" label="{{'kDecreaseSize' | translate}}" ng-click="sliderChanged(-1)">
+ </button>
+ <button mfb-button icon="ion-refresh" label="{{'kRefresh' | translate}}" ng-click="resetSizes();">
+ </button>
+ <button mfb-button icon="ion-close" label="{{'kExitFullScreen'| translate}}" ng-click="switchMinimal()">
+ </button>
+ </nav>
+ <span class="modal-alarm-badge">
+ <a data-badge="{{$root.alarmCount}}" class="animated infinite tada button icon ion-ios-bell notification-badge button-assertive"
+ ng-click="handleAlarmsWhileMinimized();" ng-if="$root.isAlarm"></a>
+ </span>
+ </div>
+ <br/>
+</ion-view>
diff --git a/www/templates/news.html b/www/templates/news.html
new file mode 100644
index 00000000..84e3c2b3
--- /dev/null
+++ b/www/templates/news.html
@@ -0,0 +1,24 @@
+<ion-view view-title="{{'kNews' | translate}}">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ <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 scroll-sista delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+
+ <div class="list">
+
+ <span ng-repeat="post in newsItems">
+ <a class="item item-text-wrap item-icon-left" ng-click="loadPost(post.url, post.date)" href="">
+ <i ng-class="isUnread(post.date) ? 'icon ion-email-unread': 'icon ion-ios-email-outline'"></i>
+ {{post.title}}
+ <p>{{post.date}}</p>
+
+ </a>
+
+ </span>
+ <div ng-if="!newsItems.length">
+ <ion-item>{{'kLoading' | translate}}...</ion-item>
+ </div>
+ </div>
+ </ion-content>
+</ion-view>
diff --git a/www/templates/reorder-modal.html b/www/templates/reorder-modal.html
new file mode 100644
index 00000000..bc442128
--- /dev/null
+++ b/www/templates/reorder-modal.html
@@ -0,0 +1,27 @@
+<ion-modal-view cache-view="false" style="width: 90%; height: 90%; top: 5%; left: 5%; right: 5%; bottom: 5%;">
+ <ion-header-bar class="bar-stable">
+ <h1 class="title"></h1>
+ <div class="buttons">
+ <button class="button button-icon icon ion-checkmark" ng-click="saveReorder()"></button>
+ <button class="button button-icon icon ion-close" ng-click="cancelReorder()"></button>
+ </div>
+ </ion-header-bar>
+ <ion-content>
+ <div class="list">
+ <span ng-repeat="item in copyMontage">
+
+
+
+
+ <a ng-class="{ 'item item-avatar item-icon-right' : item.Monitor.listDisplay == 'show', 'item item-avatar item-icon-right eye-background-red' : item.Monitor.listDisplay!='show' }" ng-click="toggleHide($index)" href="" >
+
+ <img src="{{item.Monitor.streamingURL}}/nph-zms?mode=single&monitor={{item.Monitor.Id}}&scale=50{{$root.authSession}}" fallback-src />
+
+ <i ng-class="{'icon ion-eye':item.Monitor.listDisplay=='show','eye-red icon ion-eye-disabled':item.Monitor.listDisplay!='show'}"> </i><h2><span ng-class="{'eye-red':item.Monitor.listDisplay!='show'}">{{item.Monitor.Name}}</span></h2><p>{{'kId' | translate}}:{{item.Monitor.Id}}, {{'kMode' | translate}}:{{item.Monitor.Function}}</p>
+
+ </a>
+
+ </span>
+ </div>
+ </ion-content>
+</ion-modal-view>
diff --git a/www/templates/state.html b/www/templates/state.html
new file mode 100644
index 00000000..33df994e
--- /dev/null
+++ b/www/templates/state.html
@@ -0,0 +1,70 @@
+<ion-view view-title="{{'kSystemStatus' | translate}}" cache-view="false">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ <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 scroll-sista delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+ <ion-refresher pulling-text="{{'kPullToReload' | translate}}..." spinner="bubbles" on-refresh="doRefresh()"></ion-refresher>
+ <ion-list>
+ <ion-item>
+ <div class="row">
+ <div class="col col-10">
+ <i class="ion-home" style="font-size:150%;"></i>
+ </div>
+ <div class="col">
+ ZoneMinder:
+ </div>
+ <div class="col" style="text-align:right; {{color}}">
+ {{zmRun}}
+ <p>{{customState}}</p>
+ </div>
+ </div>
+ </ion-item>
+ <ion-item>
+ <div class="row">
+ <div class="col col-10">
+ <i class="ion-arrow-graph-up-right" style="font-size:150%;"></i>
+ </div>
+ <div class="col">
+ ZoneMinder {{'kLoad' | translate}}:
+ </div>
+ <div class="col" style="text-align:right;">
+ {{zmLoad}}
+ </div>
+ </div>
+ </ion-item>
+ <!--
+ <ion-item>
+ <div class="row">
+ <div class="col col-10">
+ <i class="ion-social-buffer" style="font-size:150%;"></i>
+ </div>
+
+ <div class="col">
+
+ Disk Usage:
+ </div>
+ <div class="col" style="text-align:right;">
+ {{zmDisk}}
+ </div>
+ </div>
+ </ion-item>
+ -->
+ <ion-item>
+ <button class="button button-full {{dangerButtonColor[showDanger?1:0]}}" ng-click="showDanger=!showDanger">
+ <i class="ion-alert-circled" "style:font-size:300%;"></i> {{dangerText[showDanger?1:0]}}
+ </button>
+ <div ng-show="showDanger">
+ <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-content>
+</ion-view>
diff --git a/www/templates/timeline-modal.html b/www/templates/timeline-modal.html
new file mode 100644
index 00000000..afed79f5
--- /dev/null
+++ b/www/templates/timeline-modal.html
@@ -0,0 +1,41 @@
+<!-- style="width: 90%; height: 90%; top: 5%; left: 5%; right: 5%; bottom: 5%;"-->
+<ion-modal-view cache-view="false">
+ <ion-content ng-cloak on-double-tap="closeModal()" delegate-handle="timeline-modal-delegate">
+ <div ng-controller="TimelineModalCtrl">
+ <br/>
+ <div class="item item-divider">{{mName}}&nbsp;<i class="ion-arrow-right-b"></i>&nbsp;{{'kEvent' | translate}}:{{eid}} ({{humanizeTime}})
+ <button class="button icon-left button-small button-positive" style="float:right; opacity:0.7" ng-click="switchType()">
+ <i class="ion-shuffle"></i>
+ </button>
+ </div>
+ <center>
+ <h5>{{'kEvent' | translate}} {{graphType}} {{'kFrames' | translate}} </h5>
+ <p>{{'kTimelineMessage' | translate}}</p>
+ {{errorDetails}}
+ <!--<p>scroll left/right if needed</p>-->
+ </center>
+ <div data-tap-disabled="true">
+ <canvas id="tcchart" width="auto" height="70%"></canvas>
+ </div>
+ <ion-spinner icon="spiral" style="position:absolute; top:50%;left:50%" ng-if="!dataReady"></ion-spinner>
+ <div style="height:190px;">
+ <!-- <ion-scroll direction="x" class="wide-as-needed">-->
+ <span ng-repeat="alarm in alarm_images">
+
+
+ <figure style="display:inline-block">
+ <figcaption class="smallnote">f:{{alarm.fid}} scr:{{alarm.score}} @ {{alarm.time}}</figcaption>
+ <img ng-if="event.Event.imageMode=='path'" image-spinner-src="{{event.Event.baseURL}}/index.php?view=image&path={{event.Event.relativePath}}{{alarm.fname}}&height=380" 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)" image-spinner-loader="lines"/>
+
+ <img ng-if="event.Event.imageMode=='fid'" image-spinner-src="{{event.Event.baseURL}}/index.php?view=image&fid={{alarm.id}}" 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)" image-spinner-loader="lines"/>
+
+
+
+ </figure>
+
+ </span>
+ <!--</ion-scroll>-->
+ </div>
+ </div>
+ </ion-content>
+</ion-modal-view>
diff --git a/www/templates/timeline-popover.html b/www/templates/timeline-popover.html
new file mode 100644
index 00000000..beeb482d
--- /dev/null
+++ b/www/templates/timeline-popover.html
@@ -0,0 +1,18 @@
+<ion-popover-view class="fit">
+ <ion-content>
+ <div class="list" ng-click="popover.hide()">
+ <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();buttonClicked(0);">{{'kMonth' | translate}}</a>
+ <a class="item" ng-href="" ng-click=" popover.hide();buttonClicked(1);">
+ {{'kWeek' | translate}}
+ </a>
+ <a class="item" ng-href="" ng-click="popover.hide();buttonClicked(2);">
+ {{'kDay' | translate}}
+ </a>
+ <a class="item" ng-href="" ng-click="popover.hide();buttonClicked(3);">
+ {{'kCustomRange' | translate}}
+ </a>
+ </div>
+ </ion-content>
+</ion-popover-view>
diff --git a/www/templates/timeline.html b/www/templates/timeline.html
new file mode 100644
index 00000000..a64edceb
--- /dev/null
+++ b/www/templates/timeline.html
@@ -0,0 +1,56 @@
+<meta name="format-detection" content="telephone=no" />
+<ion-view title="{{'kTimeline' | translate}}" cache-view="false">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ &nbsp;
+ <button class="button button-icon button-clear ion-arrow-left-c" ng-click="moveDays(-1);"></button>
+ <button class="button button-icon button-clear ion-arrow-right-c" ng-click="moveDays(1);"></button>
+ <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-nav-buttons side="right">
+ <button class="button button-icon button-clear ion-android-more-vertical" ng-click="popover.show($event); ">&nbsp;&nbsp;&nbsp;</button>
+ <button class="button button-icon button-clear ion-arrow-move" ng-click="toggleNav();"></button>
+ <!--
+ <button class="button button-icon button-clear ion-log-in" ng-click="zoom(-0.2)"></button>
+ <button class="button button-icon button-clear ion-log-out" ng-click="zoom(0.2)"></button>&nbsp;-->
+ </ion-nav-buttons>
+ <!--<ion-content data-tap-disabled="true">-->
+ <ion-content scroll-sista delegate-handle="none" overflow-scroll="false" mouse-wheel-scroll>
+ <div style="padding-left:15px; font-size:10px; color:grey">
+ {{prettify(fromDate)}} - {{prettify(toDate)}} &nbsp;{{tzAbbr}}&nbsp; ({{'kTimelineOnlyDisplaying1' | translate:translationData}})
+ <strong><br/>{{'kTimelineControlDisplay'|translate}}</strong>
+ </div>
+ <ion-spinner icon="spiral" style="position:absolute; top:50%;left:50%" ng-if="!graphLoaded"></ion-spinner>
+ <div ng-if="!graphLoaded">
+ <br/>
+ <br/>
+ <center>
+ <p>{{'kWorkingOnGraph' | translate}}...</p>
+ </center>
+ </div>
+ <div style="padding-left:15px; padding-right:15px;">
+ <div id="visualization">
+ </div>
+ </div>
+ <br/>
+ <div style="padding-left:15px; font-size:10px; color:grey">
+ <button ng-click="toggleFollowTime()" ng-class="follow.time? 'button button-small button-balanced':'button button-small button-assertive'">
+ {{'kUpdateTimeline' | translate}}:&nbsp;{{follow.time? ('kTrue' | translate) : ('kFalse' | translate)}}
+ </button>
+ <button ng-click="gotoNow()" class="button button-small button-balanced">
+ {{'kNow' | translate}}
+ </button>
+ <div ng-if="follow.time">
+ <p>{{newEvents}}</p>
+ </div>
+ </div>
+ </ion-content>
+</ion-view>
+<div ng-show="graphLoaded && navControls">
+ <div class="timelinebuttons">
+ <circular id="timeline-ctrl" options="radialMenuOptions" class="animated bounceInRight">
+ <!---->
+ </circular>
+ <!-- -->
+ </div>
+</div>
diff --git a/www/templates/wizard.html b/www/templates/wizard.html
new file mode 100644
index 00000000..60d1e1ef
--- /dev/null
+++ b/www/templates/wizard.html
@@ -0,0 +1,85 @@
+<ion-view view-title="{{'kWizard' | translate}}" ng-cloak cache-view="false">
+ <ion-nav-buttons side="left">
+ <button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
+ </ion-nav-buttons>
+ <ion-content class="padding" overflow-scroll="false">
+ <wizard on-finish="finishedWizard()">
+ <!-- portal url -->
+ <wz-step wz-title="1" canexit="exitPortal">
+ <h4><i id="transition-delay" class="animated swing ion-wand" style="font-size:2em"></i> {{'kWelcomeWizard' | translate}}</h4>
+ <img src="img/wizard.svg" width="100px" style="float:left" />
+ <p>{{'kWizConfigPain' | translate}}</p>
+ <h4>{{'kWizPortalUrl' | translate}}</h4>
+ <label class="item item-input">
+ <input autocorrect="off" autocapitalize="none" autocomplete="off" type="text" placeholder="{{'kPortalUrlExample' | translate}}" ng-model="wizard.portalurl">
+ </label>
+ <p ng-if="$root.platformOS=='android'" style="font-size:0.8em; color:gray">{{'kDisableSamsung' | translate}}</p>
+ <a class="button icon-left ion-information-circled button-clear button-dark" ng-click="toggleTip()">{{wizard.tiptext}}</a>
+ <div class="wizardtip" ng-show="wizard.tipshow">
+ <b>{{'kWizTip' | translate}}: </b>{{'kWizPortalTip' | translate}}
+ <br/>
+ <img src="img/portalurl.png" width="30%">
+ </div>
+ <br/>
+ <button class="button button-small icon icon-right ion-chevron-right" wz-next>{{'kNext' | translate}}</button>
+ </wz-step>
+ <!-- auth mode -->
+ <wz-step wz-title="2">
+ <h4>{{'kWizPortalAuth' | translate}}</h4>
+ <!--<img src="img/wizard.svg" width="100px" style="float:left"/>-->
+ <p>{{'kWizPortalText' | translate}}</p>
+ <ion-toggle ng-change="toggleAuth()" ng-model="wizard.useauth" ng-checked="wizard.useauth" toggle-class="toggle-calm">{{'kWizUseAuth' | translate}}</ion-toggle>
+ <ion-toggle ng-show="wizard.useauth" ng-model="wizard.usezmauth" ng-checked="wizard.usezmauth" toggle-class="toggle-calm">{{'kWizZMAuth' | translate}}</ion-toggle>
+ <div ng-if="wizard.usezmauth">
+ <label class="item item-input item-floating-label">
+ <span class="input-label">{{'kUserName' | translate}}</span>
+ <input autocorrect="off" autocapitalize="none" autocomplete="off" type="text" ng-model="wizard.zmuser" placeholder="{{'kPlaceHolderZMAuthUser'|translate}}">
+ </label>
+ <label class="item item-text-wrap item-input item-floating-label">
+ <span class="input-label">{{'kPassword' | translate}}</span>
+ <input type="password" ng-model="wizard.zmpassword" placeholder="{{'kPlaceHolderZMAuthPass'|translate}}">
+ <!--<p >{{'kWizPasswdNote' | translate}}</p>-->
+ </label>
+ </div>
+ <ion-toggle ng-show="wizard.useauth" ng-model="wizard.usebasicauth" ng-checked="wizard.usebasicauth" toggle-class="toggle-calm">{{'kWizBasicAuth' | translate}}</ion-toggle>
+ <label class="item item-input item-floating-label" ng-show="wizard.usebasicauth">
+ <span class="input-label">{{'kUserName' | translate}}</span>
+ <input autocorrect="off" autocapitalize="none" autocomplete="off" type="text" ng-model="wizard.basicuser" placeholder="{{'kPlaceHolderBasicAuthUser'|translate}}">
+ </label>
+ <label class="item item-input item-text-wrap item-floating-label" ng-show="wizard.usebasicauth">
+ <span class="input-label">{{'kPassword' | translate}}</span>
+ <input type="password" ng-model="wizard.basicpassword" placeholder="{{'kPlaceHolderBasicAuthPass'|translate}}">
+ <p>{{'kWizPasswdNote' | translate}}</p>
+ </label>
+ <a class="button icon-left ion-information-circled button-clear button-dark" ng-click="toggleTip()">{{wizard.tiptext}}</a>
+ <div class="wizardtip" ng-show="wizard.tipshow">
+ <b>{{'kWizTip'| translate}} </b> {{'kWizAuthText1' | translate}}
+ <br/> {{'kWizAuthText2' | translate}}
+ </div>
+ <br/>
+ <button class="button button-small icon icon-left ion-chevron-left" wz-previous>{{'kPrev' | translate}}</button>
+ <button class="button button-small icon icon-right ion-chevron-right" ng-click="exitAuth()">{{'kNext' | translate}}</button>
+ </wz-step>
+ <wz-step wz-title="3">
+ <br/>
+ <br/>
+ <h4>{{'kWizResults' | translate}}</h4>
+ <span ng-if="wizard.portalValidText" style="color:{{wizard.portalColor}};"><i ng-class="wizard.portalColor=='#16a085' ? 'ion-checkmark-circled':'ion-close-circled'"></i>&nbsp;{{wizard.portalValidText}}<br/></span>
+ <span ng-if="wizard.apiValidText" style="color:{{wizard.apiColor}};"><i ng-class=" wizard.apiColor=='#16a085' ? 'ion-checkmark-circled':'ion-close-circled'"></i>&nbsp;{{wizard.apiValidText}}<br/></span>
+ <span ng-if="wizard.streamingValidText" style="color:{{wizard.streamingColor}};"><i ng-class="wizard.streamingColor=='#16a085' ? 'ion-checkmark-circled':'ion-close-circled'"></i>&nbsp;{{wizard.streamingValidText}}<br/></span>
+ <br/>
+ <div class="wizardtip">
+ {{'kWizNextStep1' | translate}}:
+ <ul class="wiz-list">
+ <li>{{'kWizNextStep2' | translate}}</li>
+ <li>{{'kWizNextStep3' | translate}}</li>
+ </ul>
+ </div>
+ <br/>
+ <br/>
+ <button class="button button-small icon icon-left ion-chevron-left" wz-previous>{{'kPrev' | translate}}</button>
+ <button class="button button-small icon icon-right ion-chevron-right" ng-click="gotoLoginState()">{{'kWizGotoLogin' | translate}}</button>
+ </wz-step>
+ </wizard>
+ </ion-content>
+</ion-view>
diff --git a/www/templates/zm-portal-login.html b/www/templates/zm-portal-login.html
new file mode 100644
index 00000000..877dbb97
--- /dev/null
+++ b/www/templates/zm-portal-login.html
@@ -0,0 +1,26 @@
+<ion-view view-title="{{$root.appName}}" hide-nav-bar="true" hide-back-button="true" cache-view="false">
+ <ion-content class="pin-background" scroll="false">
+ <div style="margin-left:20px; margin-right:20px">
+ <center>
+ <br/>
+ <br/>
+ <div id="responsive-image">
+ <img src="img/authlogo.png">
+ </div>
+ <div ng-if="pinPrompt">
+ <span style="color:white">{{'kEnterPin' | translate}}</span>
+ <div class="pinCode">
+ <input id="pin-box" type="number" pattern="[0-9]*" ng-model="pindata.pin" ng-keyup="pinChange()" />
+ </div>
+ <br/> <span style="color:white">{{pindata.status}}</span>
+ <br/>
+ <button class="button button-dark icon ion-unlocked" ng-click="unlock()"> Unlock
+ </button>
+ </div>
+ <div id="really-your-fault" class="animated fadeIn" style="color:white">{{'kPortalNotice' | translate}}
+ <br/>
+ <br/>{{'kPortalNoticeSub' | translate}}</div>
+ </center>
+ </div>
+ </ion-content>
+</ion-view>