mirror of
https://gitlab.com/Shinobi-Systems/ShinobiCE.git
synced 2025-03-09 15:40:15 +00:00
Support Shinobi at https://licenses.shinobi.video/subscribe
This commit is contained in:
parent
ef40f3f231
commit
167603dfb0
118 changed files with 16152 additions and 5441 deletions
3
web/libs/.gitignore
vendored
3
web/libs/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
demo
|
||||
demo
|
||||
impervious
|
||||
|
|
41
web/libs/css/bootstrap-slider.min.css
vendored
Normal file
41
web/libs/css/bootstrap-slider.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -460,4 +460,4 @@
|
|||
opacity: 1;
|
||||
transform: rotate(360deg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,3 +87,361 @@ img{max-width:100%}
|
|||
.video_grid .thumb .title-strip{top:0;opacity:0.5}
|
||||
.video_grid .thumb .button-strip{bottom:0;opacity:0}
|
||||
.video_grid .thumb:hover .title-strip, .video_grid .thumb:hover .button-strip{opacity:1}
|
||||
|
||||
|
||||
|
||||
/* */
|
||||
.canvas_holder canvas{z-index:11}
|
||||
|
||||
.demo-blog .mdl-card__media ~ .mdl-card__supporting-text{position:relative;overflow:initial;cursor:move}
|
||||
.demo-blog .mdl-card__media ~ .mdl-card__supporting-text .btn-group{cursor: default}
|
||||
|
||||
.demo-blog .demo-blog__posts.montage{max-width:100%}
|
||||
|
||||
.hide-side .mdl-layout__drawer{overflow-y: hidden}
|
||||
.mdl-layout__header-row{padding-left:10!important}
|
||||
.mdl-layout__header-row .nav>li>a{border-radius:50%;}
|
||||
.mdl-layout__drawer-button i{position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;height:1em;color:#fff}
|
||||
|
||||
|
||||
.video_video{margin:auto;max-width:100%;max-height:600px;}
|
||||
#confirm_window .video_video{margin-top:15px}
|
||||
#confirm_window .info-table{margin-top:15px}
|
||||
@media (max-width: 768px){
|
||||
.full.modal .modal-body,.medium.modal .modal-body{max-height:400px;overflow:auto}
|
||||
}
|
||||
@media (min-width: 768px){
|
||||
.modal.full,.modal.medium{padding-left:0!important;}
|
||||
.modal.full .modal-dialog{width:calc(100% - 10px)!important;margin: 30px auto;max-width: none;}
|
||||
.modal.medium .modal-dialog{width:calc(70% - 10px)!important;margin: 30px auto;}
|
||||
.full.modal .modal-body,.medium.modal .modal-body{height:calc(100% - 200px);overflow:auto}
|
||||
}
|
||||
|
||||
.flex-container-modal-body{overflow: auto}
|
||||
.flex-container-modal-body .flex-block>div{flex:1;float:none}
|
||||
|
||||
.modal{overflow:auto!important}
|
||||
|
||||
.videos_list .title{font-size:12pt;padding:0 10px}
|
||||
|
||||
.demo-drawer{background:#2b2a2a;color:#fff;}
|
||||
.demo-drawer.mdl-layout__drawer .mdl-navigation{padding-top:0;}
|
||||
.demo-drawer::-webkit-scrollbar{display:none;}
|
||||
.small-square-img{height:40px;width:40px;border-radius:5px}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#side_menu_right.nav-xs{width:0!important;overflow:hidden}
|
||||
.side-menu table{color:#fff;}
|
||||
#main_canvas{background:#333;color:#fff;padding-top:0}
|
||||
#main_header{background:#222;color:#fff;}
|
||||
#logs_modal table tr td:first-child{width:10%}
|
||||
[class_toggle]{cursor:pointer}
|
||||
|
||||
.form-group label{width:100%}
|
||||
|
||||
.table-striped>tbody>tr>td{vertical-align:middle}
|
||||
.table-striped .thumbnail{width:100px;height:80px;border-radius:5px;margin:0;display:inline-block;}
|
||||
|
||||
|
||||
|
||||
|
||||
.follow-list ul{padding:0;margin:0;font-family:"Roboto","Helvetica","Arial",sans-serif;}
|
||||
.follow-list ul a:not(.btn){color:#fff}
|
||||
.os_bars{width:600px;display:inline-block;padding:5px 0 0 10px}
|
||||
@media screen and (max-width: 600px){
|
||||
.os_bars{width:200px;}
|
||||
.os_bars label{padding:2.5px 0;margin:0;font-size:8pt}
|
||||
}
|
||||
.os_bars .display-table .display-table-cell{padding:5px;vertical-align:center;width:33%}
|
||||
.progress{height:5px;margin:0;}
|
||||
.os_bars label,.os_bars .percent{padding:2.5px 0;margin:0;font-size:7.5pt}
|
||||
.ui-pnotify-hide .ui-pnotify{display:none!important}
|
||||
/*cool dropdown thing*/
|
||||
ul.msg_list li {
|
||||
background: #f7f7f7;color:#333;
|
||||
padding: 5px;
|
||||
display: list-item;
|
||||
margin: 6px 6px 0;
|
||||
width: 96% !important
|
||||
}
|
||||
|
||||
ul.msg_list li div{display:block}
|
||||
|
||||
ul.msg_list li:last-child {
|
||||
margin-bottom: 6px;
|
||||
padding: 10px
|
||||
}
|
||||
|
||||
ul.msg_list li a {
|
||||
padding: 3px 5px !important
|
||||
}
|
||||
ul.msg_list li .progress {
|
||||
height:5px;margin:10px 0 0 0;
|
||||
}
|
||||
|
||||
ul.msg_list li .image img {
|
||||
border-radius: 2px 2px 2px 2px;
|
||||
-webkit-border-radius: 2px 2px 2px 2px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
width: 11%
|
||||
}
|
||||
|
||||
ul.msg_list li .time {
|
||||
font-size: 11px;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
ul.msg_list li .message {
|
||||
display: block !important;
|
||||
font-size: 11px
|
||||
}
|
||||
|
||||
.dropdown-menu.msg_list span {
|
||||
white-space: normal
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
border: medium none;
|
||||
box-shadow: none;
|
||||
display: none;
|
||||
float: left;
|
||||
font-size: 12px;
|
||||
left: 0;
|
||||
list-style: none outside none;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
text-shadow: none;
|
||||
top: 100%;
|
||||
z-index: 9998;
|
||||
border: 1px solid #D9DEE4;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0
|
||||
}
|
||||
|
||||
.dropdown-menu>li>a {
|
||||
color: #5A738E
|
||||
}
|
||||
|
||||
.navbar-nav .open .dropdown-menu {
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
margin-top: 0;
|
||||
border: 1px solid #D9DEE4;
|
||||
-webkit-box-shadow: none;
|
||||
right: 0;
|
||||
left: auto;
|
||||
width: 220px
|
||||
}
|
||||
.is-small-screen .nav>li{display:inline-block}
|
||||
.navbar-nav .open .dropdown-menu li a{padding:7px 15px}
|
||||
.navbar-nav .open .dropdown-menu.msg_list {
|
||||
width: 300px
|
||||
}
|
||||
.nav>li>a{color:#fff}
|
||||
.nav>li>a:focus, .nav>li>a:hover,.nav .open>a, .nav .open>a:focus, .nav .open>a:hover{background:#867560}
|
||||
|
||||
.mdl-js-layout.hide-side:not(.is-small-screen){
|
||||
|
||||
}
|
||||
@media screen and (min-width: 1025px){
|
||||
.mdl-js-layout.hide-side:not(.is-small-screen)>.mdl-layout__drawer {
|
||||
width: 0px;transition:0.2s;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
.mdl-js-layout.hide-side:not(.is-small-screen) .mdl-layout__header .mdl-layout__drawer-button{
|
||||
display:none;
|
||||
}
|
||||
.mdl-js-layout.hide-side:not(.is-small-screen)>.mdl-layout__content{
|
||||
margin-left: 0px;transition:0.2s
|
||||
}
|
||||
.mdl-js-layout.hide-side:not(.is-small-screen)>.mdl-layout__header{
|
||||
margin-left: 0px;width:100%;transition:0.2s
|
||||
}
|
||||
.mdl-menu__item>div{display:flex;align-items: center;width:100%}
|
||||
.mdl-menu__item>div>i{margin-right:5px}
|
||||
|
||||
|
||||
/*Digital Zoom*/
|
||||
.stream-block{
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
}
|
||||
.zoomGlass {
|
||||
overflow: hidden;
|
||||
transition: none;
|
||||
width: 175px; height: 175px;
|
||||
position: absolute;
|
||||
border-radius: 15px;
|
||||
border: 3px solid #ddd;
|
||||
z-index:9999;
|
||||
}
|
||||
.zoomGlass iframe,
|
||||
.zoomGlass video,
|
||||
.zoomGlass canvas{
|
||||
padding: 0!important;
|
||||
max-width: none!important;
|
||||
position: absolute;
|
||||
transition: none;
|
||||
}
|
||||
.zoomGlass .hoverShade{position:absolute;width:100%;height:100%}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*** custom checkboxes ***/
|
||||
|
||||
.checkbox input[type=checkbox] { display:none; } /* to hide the checkbox itself */
|
||||
.checkbox input[type=checkbox] + label:before {
|
||||
font-family: FontAwesome;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.checkbox input[type=checkbox] + label:before { content: "\f096"; } /* unchecked icon */
|
||||
.checkbox input[type=checkbox] + label:before { letter-spacing: 10px; } /* space between checkbox and label */
|
||||
|
||||
.checkbox input[type=checkbox]:checked + label:before { content: "\f046"; } /* checked icon */
|
||||
.checkbox input[type=checkbox]:checked + label:before { letter-spacing: 5px; } /* allow space for check mark */
|
||||
|
||||
/*Clock*/
|
||||
#time-date {font-size:12px; text-align:center;}
|
||||
@media screen and (min-width:1025px){
|
||||
#clock {padding-right:35px}
|
||||
}
|
||||
#clock ul { width:150px; margin:0 auto; padding:0px; list-style:none; text-align:center; }
|
||||
#clock ul li { display:inline; font-size:1.6em; text-align:center;font-family:monospace;}
|
||||
|
||||
#clock .point { position:relative; -moz-animation:mymove 1s ease infinite; -webkit-animation:mymove 1s ease infinite; }
|
||||
|
||||
/*custom vis.js css*/
|
||||
.vis-timeline{background:#212121;color:#fff;border-color:#444}
|
||||
.vis-time-axis .vis-text{color: #dedede}
|
||||
.vis-item.vis-range .vis-item-content{background:#333;color:#fff}
|
||||
.vis-time-axis .vis-grid.vis-minor{border-color:#444}
|
||||
|
||||
|
||||
@-moz-document url-prefix() {
|
||||
.full.modal .modal-body, .medium.modal .modal-body {
|
||||
height:70%
|
||||
}
|
||||
}
|
||||
|
||||
/*animations*/
|
||||
@keyframes blink {
|
||||
0% { opacity:1 }
|
||||
50% { opacity:0 }
|
||||
100% { opacity:1 }
|
||||
}
|
||||
@-webkit-keyframes blink {
|
||||
0% { opacity:1 }
|
||||
50% { opacity:0 }
|
||||
100% { opacity:1 }
|
||||
}
|
||||
.blink,[mode="Record"] .lamp {
|
||||
-webkit-animation: blink 1s linear infinite;
|
||||
-moz-animation: blink 1s linear infinite;
|
||||
animation: blink 1s linear infinite;
|
||||
}
|
||||
|
||||
/* All-CSS Toggle Switch (Checkbox Hack) by Marcus Burnette - https://codepen.io/mburnette/pen/LxNxNg */
|
||||
.marc-toggle {
|
||||
width: 50px;
|
||||
height: 25px;
|
||||
}
|
||||
.marc-toggle.abs-bot-left {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
.marc-toggle.abs-bot-right {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
.marc-toggle input[type=checkbox]{
|
||||
height: 0;
|
||||
width: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.marc-toggle label {
|
||||
cursor: pointer;
|
||||
text-indent: -9999px;
|
||||
width: 100px;
|
||||
height: 20px;
|
||||
background: grey;
|
||||
display: block;
|
||||
border-radius: 100px;
|
||||
margin-bottom: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.marc-toggle label:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: #fff;
|
||||
border-radius: 90px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.marc-toggle input:checked + label {
|
||||
background: #00118c;
|
||||
}
|
||||
|
||||
.marc-toggle input:checked + label:after {
|
||||
left: calc(100% - 5px);
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.marc-toggle label:active:after {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
/*hexagon pattern*/
|
||||
.bg-hexagon {
|
||||
background-color: #054e9f;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='49' viewBox='0 0 28 49'%3E%3Cg fill-rule='evenodd'%3E%3Cg id='hexagons' fill='%23fdfdfd' fill-opacity='0.4' fill-rule='nonzero'%3E%3Cpath d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.demo-drawer .mdl-menu__container{
|
||||
max-height: 500px!important;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
/* */
|
||||
.slider.slider-horizontal {
|
||||
width:100%!important
|
||||
}
|
||||
/* */
|
||||
.epic-text {
|
||||
margin:15px 0 0 0;
|
||||
text-align:center;
|
||||
color:#777;
|
||||
font-family: sans-serif;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 3pt;
|
||||
font-size: 8pt;
|
||||
}
|
||||
/* Start of custom table sorter */
|
||||
.table .table-header-sorter {
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.table th.table-header-sorter i.fa-sort {
|
||||
color: #ccc;
|
||||
}
|
||||
.table th.table-header-sorter i {
|
||||
margin-left: 10px;
|
||||
}
|
||||
/* End of custom table sorter */
|
||||
|
|
45
web/libs/css/dash2.darktheme.css
Normal file
45
web/libs/css/dash2.darktheme.css
Normal file
|
@ -0,0 +1,45 @@
|
|||
.dark .list-group-item{border-color: #444;background:#222}
|
||||
.dark .list-group-item.active{background:#c49a68;border-color:#a7865f}
|
||||
.novideos{text-transform: uppercase;text-align: center;border-bottom:0!important;padding-top: 55%!important;letter-spacing:2px}
|
||||
|
||||
.btn-warning {
|
||||
color: #fff;
|
||||
background-color: #c49a68;
|
||||
border-color: #c49a68;
|
||||
}
|
||||
.dark .table-striped>tbody>tr:nth-of-type(even){background:#616161}
|
||||
.dark .table-striped>tbody>tr>td{border-color:#222;color:#fff}
|
||||
.dark .table-striped>thead>tr>th{border-color:#222;color:#fff;background:#616161;vertical-align:middle;}
|
||||
.dark .table-striped>tbody>tr:nth-of-type(odd){background-color: #4c4747;}
|
||||
.dark .table>tbody>tr.active>td{background:inherit;border:0}
|
||||
.dark code{color: #c49a68;background-color: #36333d;}
|
||||
.dark a:not(.btn){color: #c49a68;}
|
||||
|
||||
|
||||
|
||||
|
||||
.dark.form-control,.dark .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
padding: 6px 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
color: #eee;
|
||||
background-color: #36333d;
|
||||
background-image: none;
|
||||
border: 1px solid #444;
|
||||
border-radius: 4px;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
}
|
||||
|
||||
.dark.form-control:focus,.dark .form-control:focus {
|
||||
color: #ddd;
|
||||
background-color: #333;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.dark .slider-selection {
|
||||
background:#555;
|
||||
}
|
|
@ -22,23 +22,25 @@ form.modal-body{margin:0}
|
|||
.form-group-group .mdl-list__item:hover{background:#e6e6e6;border-radius:4px;}
|
||||
.dark .form-group-group .mdl-list__item{color:#fff;border-bottom:1px solid #444;}
|
||||
.dark .form-group-group .mdl-list__item:hover{background:#555;}
|
||||
.form-group-group:last-child,.form-group-group > .form-group:last-child{margin-bottom:0}
|
||||
.form-group-group h4{margin:0 -10px 15px -10px;padding:15px;background:#ddd;}
|
||||
.form-group-group h4 small{color:#fff;}
|
||||
.form-group-group:visible:last-child,.form-group-group > .form-group:last-child{margin-bottom:0}
|
||||
.form-group-group > h4{margin:0 -10px 15px -10px;padding:15px;background:#ddd;}
|
||||
.form-group-group > h4:empty{padding:2px}
|
||||
.form-group-group > h4 small{color:#fff;}
|
||||
.form-group-group.red{border-color:#d9534f}
|
||||
.form-group-group.red h4{background:#d9534f;color:#fff}
|
||||
.form-group-group.red > h4{background:#d9534f;color:#fff}
|
||||
.form-group-group.purple{border-color:#3f51b5}
|
||||
.form-group-group.purple h4{background:#3f51b5;color:#fff}
|
||||
.form-group-group.purple > h4{background:#3f51b5;color:#fff}
|
||||
.form-group-group.blue{border-color:#337ab7}
|
||||
.form-group-group.blue h4{background:#337ab7;color:#fff}
|
||||
.form-group-group.blue > h4{background:#337ab7;color:#fff}
|
||||
.form-group-group.navy{border-color:#31708f}
|
||||
.form-group-group.navy h4{background:#31708f;color:#fff}
|
||||
.form-group-group.navy > h4{background:#31708f;color:#fff}
|
||||
.form-group-group.green{border-color:#449d44}
|
||||
.form-group-group.green h4{background:#449d44;color:#fff}
|
||||
.form-group-group.green > h4{background:#449d44;color:#fff}
|
||||
.form-group-group.forestgreen{border-color:#1e4046}
|
||||
.form-group-group.forestgreen h4{background:#1e4046;color:#fff}
|
||||
.form-group-group.forestgreen > h4{background:#1e4046;color:#fff}
|
||||
.form-group-group.orange{border-color:#c49a68}
|
||||
.form-group-group.orange h4{background:#c49a68;color:#fff}
|
||||
.form-group-group.orange > h4{background:#c49a68;color:#fff}
|
||||
.form-group-group.grey{border-color:#777}
|
||||
.form-group-group.grey h4{background:#777;color:#fff}
|
||||
.form-group-group.grey > h4{background:#777;color:#fff}
|
||||
.dark .form-group-group{background:#222}
|
||||
.form-group-group:last-child {margin-bottom: 0}
|
||||
|
|
17
web/libs/css/dash2.misc.css
Normal file
17
web/libs/css/dash2.misc.css
Normal file
|
@ -0,0 +1,17 @@
|
|||
#diskUsedList .title {
|
||||
letter-spacing: 2px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
font-size: 7pt;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
#diskUsedList .value {
|
||||
letter-spacing:2px;
|
||||
font-weight:100;
|
||||
}
|
||||
#diskUsedList .log-item {
|
||||
line-height: 1
|
||||
}
|
||||
#diskUsedList .log-item .progress {
|
||||
margin: 2px 0 0 0;
|
||||
}
|
|
@ -4,3 +4,4 @@
|
|||
.dark.modal .modal-body{background:#333;}
|
||||
.dark.modal .close{color:#fff;}
|
||||
.dark.modal{color:#fff;}
|
||||
#confirm_window {z-index: 11111}
|
||||
|
|
26
web/libs/css/dash2.monitorStates.css
Normal file
26
web/libs/css/dash2.monitorStates.css
Normal file
|
@ -0,0 +1,26 @@
|
|||
.state-monitor-row-fields{
|
||||
border-bottom: 1px solid #444;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.state-monitor-row-fields .list-group{
|
||||
height: 300px
|
||||
}
|
||||
.state-monitor-row .list-group .list-group-item:first-child{
|
||||
border-top:0;
|
||||
}
|
||||
.state-monitor-row .list-group .list-group-item:last-child{
|
||||
border-bottom:0;
|
||||
}
|
||||
|
||||
.state-monitor-row-select-container {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.state-monitor-row-fields-container {
|
||||
border: 1px solid #444;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.state-monitor-row-fields-field {
|
||||
margin-top: 5px;
|
||||
}
|
|
@ -84,3 +84,20 @@ img.circle-img,div.circle-img{border-radius:50%;height:50px;width:50px}
|
|||
[status="1"] .btn[video="launch"],[data-status="1"] .btn[video="launch"]{background:#337ab7;border-color:#337ab7}
|
||||
[status="2"] .btn[launch="video"],[status="2"] .btn[video="launch"],[data-status="2"] .btn[video="launch"]{background:#a59100;border-color:#a59100}
|
||||
.signal.red{background:#c9302c}
|
||||
|
||||
|
||||
|
||||
#monSectionStreamChannels,#monSectionInputMaps{margin-bottom: 15px;}
|
||||
#monSectionStreamChannels:empty,#monSectionInputMaps:empty{display:none}
|
||||
|
||||
|
||||
#monitors_list .monitor_block{transition:none}
|
||||
.dropdown-menu.scrollable{max-height:300px}
|
||||
.upload_file input{display:none}
|
||||
#video_preview .stream-objects{right:0;margin:auto;display:inline-block;position:relative;width:auto}
|
||||
.stream-block,.stream-objects{overflow: hidden!important}
|
||||
.stream-objects{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10}
|
||||
.stream-objects .tag{position:absolute;bottom:100%;left:0;background:red;color:#fff;font-family:monospace;font-size:80%;border-radius:5px 5px 0 0 ;padding:3px 5px;}
|
||||
.stream-objects .stream-detected-object{position:absolute;top:0;left:0;border:3px solid red;background:transparent;border-radius:5px}
|
||||
.stream-objects .stream-detected-point{position:absolute;top:0;left:0;border:3px solid yellow;background:transparent;border-radius:5px}
|
||||
.stream-objects .point{position:absolute;top:0;left:0;border:3px solid red;border-radius:50%}
|
||||
|
|
176
web/libs/css/dash2.powerVideo2.css
Normal file
176
web/libs/css/dash2.powerVideo2.css
Normal file
|
@ -0,0 +1,176 @@
|
|||
#powerVideo .videoPlayer {
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
#powerVideo .videoPlayer video{
|
||||
max-width: 100%;
|
||||
height: 300px;
|
||||
object-fit: fill;
|
||||
}
|
||||
|
||||
#powerVideo .videoPlayer:fullscreen video{
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
#powerVideoMonitorControls{
|
||||
border-radius: 0 0 5px 5px;
|
||||
padding: 5px;
|
||||
background: #222;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#powerVideoMonitorsList{
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#powerVideoMonitorsList .list-item{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#powerVideoMonitorViews {
|
||||
text-align: center;
|
||||
min-height: 300px;
|
||||
background: #444;
|
||||
border-radius: 5px 5px 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#powerVideo .videoPlayer .videoPlayer-detection-info {
|
||||
position: absolute;
|
||||
padding: 20px 10px 20px 10px;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: auto;
|
||||
z-index: 11;
|
||||
opacity: 0;
|
||||
background: rgba(0,0,0,0.7);
|
||||
color: #fff;
|
||||
font-family: monospace;
|
||||
overflow: auto;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#powerVideo .videoPlayer:hover .videoPlayer-detection-info,
|
||||
#powerVideo .videoPlayer.show-detection-info .videoPlayer-detection-info {
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
#powerVideo .videoPlayer .videoPlayer-stream-objects {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
#powerVideo .videoPlayer .videoPlayer-detection-info-object div {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#powerVideo .videoPlayer .videoPlayer-detection-info-object {
|
||||
text-align: left
|
||||
}
|
||||
|
||||
.videoPlayer-stream-objects .tag {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 0;
|
||||
background: red;
|
||||
color: #fff;
|
||||
font-family: monospace;
|
||||
font-size: 80%;
|
||||
border-radius: 5px 5px 0 0;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
|
||||
.videoPlayer-stream-objects .stream-detected-object {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border: 3px solid red;
|
||||
background: transparent;
|
||||
border-radius: 5px
|
||||
}
|
||||
|
||||
.videoPlayer-stream-objects .stream-detected-point {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border: 3px solid yellow;
|
||||
background: transparent;
|
||||
border-radius: 5px
|
||||
}
|
||||
|
||||
.videoPlayer-stream-objects .point {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border: 3px solid red;
|
||||
border-radius: 50%
|
||||
}
|
||||
|
||||
/* loading */
|
||||
#powerVideo .loading {
|
||||
font-size: 20pt;
|
||||
text-align: center;
|
||||
}
|
||||
#powerVideo .loading > div {
|
||||
margin-top: 5px
|
||||
}
|
||||
|
||||
/* VIS.js */
|
||||
|
||||
#powerVideo video {
|
||||
width: 100%;
|
||||
padding: 6px 0 0 0
|
||||
}
|
||||
|
||||
#powerVideo .videoAfter,
|
||||
#powerVideo .videoBefore {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#powerVideo .vis-timeline {
|
||||
font-family: monospace;
|
||||
border-radius: 5px;
|
||||
border-color: #172b4d;
|
||||
}
|
||||
#powerVideo .vis-item {
|
||||
border-color: #347af1;
|
||||
background-color: #4d87d0;
|
||||
color: #fff;
|
||||
}
|
||||
#powerVideo .vis-item.vis-selected {
|
||||
border-color: #f5365c;
|
||||
background-color: #f5365c;
|
||||
color: #fff;
|
||||
}
|
||||
#powerVideo .vis-panel.vis-bottom {
|
||||
border: 1px #17294b;
|
||||
}
|
||||
#powerVideo .vis-time-axis .vis-grid.vis-minor{
|
||||
border-color: #1a539a;
|
||||
}
|
||||
#powerVideo .vis-time-axis .vis-grid.vis-major {
|
||||
border-color: #4d87d0;
|
||||
}
|
||||
#powerVideo .vis-time-axis .vis-text {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
[timeline-video-file] .progress{
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
opacity: 0;
|
||||
}
|
||||
.vis-selected [timeline-video-file] .progress{
|
||||
opacity: 1;
|
||||
}
|
|
@ -6,3 +6,13 @@
|
|||
#pvideo_viewer .bufferBar{position:absolute;left:0;top:0;opacity:0.4}
|
||||
#pvideo_viewer .timeBar{position:relative;z-index: 222;background:transparent}
|
||||
#pvideo_viewer h3{font-family:monospace}
|
||||
|
||||
|
||||
#vis_pwrvideo{height:250px}
|
||||
|
||||
|
||||
#vis_monitors{overflow:auto;max-height:400px}
|
||||
#vis_monitors .btn-group-vertical{width:100%}
|
||||
|
||||
|
||||
#motion_list{height:155px;overflow:auto;border-radius:5px;border:1px solid #444;position:relative;background: #222;margin:0}
|
||||
|
|
|
@ -3,3 +3,7 @@
|
|||
#region_editor .cord_element{position:absolute;background:rgba(221, 221, 221, 0.8);z-index:11;padding:5px;}
|
||||
#region_editor .cord_element.selected{z-index:12;}
|
||||
#region_editor .cord_element .controls{margin-bottom:5px;}
|
||||
|
||||
|
||||
|
||||
#region_editor_live iframe,.canvas_holder canvas{border:0;position:absolute;left:0;top:0}
|
||||
|
|
34
web/libs/css/dash2.sidemenu.css
Normal file
34
web/libs/css/dash2.sidemenu.css
Normal file
|
@ -0,0 +1,34 @@
|
|||
#accbtn{
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.side-menu .monitor_block{padding:0;position:relative}
|
||||
.side-menu .monitor_block img{width:100%;height:75px;cursor:pointer;border: 0.5px inset #263238;}
|
||||
@media screen and (max-width:1025px){
|
||||
.side-menu .monitor_block img{height:175px;}
|
||||
}
|
||||
.side-menu .monitor_block:hover .icons{opacity:1}
|
||||
.side-menu .monitor_block:hover .title{opacity:1}
|
||||
.side-menu .monitor_block .icons,.side-menu .monitor_block .title{opacity:0;width:100%;bottom:0;left:0;background:rgba(0,0,0,0.6);position:absolute;padding:2.5px;z-index:11;cursor:move}
|
||||
.side-menu .monitor_block .title{bottom:auto;top:0;color:#fff}
|
||||
.nav-xs.side-menu .monitor_block{width:100%}
|
||||
.side-menu .monitor_block .list-data{display:none}
|
||||
.output_data:empty{display:none}
|
||||
.output_data{max-height:500px;font-family:monospace;padding:10px;border-radius:5px;background:#f3f3f3;overflow:auto}
|
||||
.dark .output_data{background:#222;}
|
||||
#probe .output_data div>div{margin-left:10px}
|
||||
.side-menu.list-blocks .monitor_block .icons,.side-menu.list-blocks .monitor_block .title{position:inherit;opacity:1;background:none}
|
||||
.side-menu.list-blocks .monitor_block .title{padding:5px;border-radius:5px;background:#222;}
|
||||
.side-menu.list-blocks .monitor_block:not(:last-child){border-bottom: 1px solid #54502d;}
|
||||
.side-menu.list-blocks .monitor_block:first-child{border-top: 1px solid #54502d;}
|
||||
.side-menu.list-blocks .monitor_block{float:none;width:100%;padding: 10px}
|
||||
.side-menu.list-blocks .monitor_block.ui-sortable-helper{background:rgba(0,0,0,0.6);border-radius:5px;padding:5px;border:0}
|
||||
.side-menu.list-blocks .monitor_block .list-data{display:block}
|
||||
.side-menu.list-blocks .monitor_block img{width:60px;height:60px;cursor:pointer;display:inline-block;margin-right:10px;border-radius:50%;vertical-align:top;border:0}
|
||||
.nav-xs.side-menu.list-blocks .monitor_block img{width:40px;height:40px;}
|
||||
.side-menu.list-blocks .monitor_block .box{width:calc(100% - 70px);display:inline-block}
|
||||
.nav-xs.side-menu.list-blocks .monitor_block .list-data{display:none}
|
||||
.side-menu .mdl-menu{z-index: 12}
|
110
web/libs/css/dash2.timelapse.jpeg.css
Normal file
110
web/libs/css/dash2.timelapse.jpeg.css
Normal file
|
@ -0,0 +1,110 @@
|
|||
#timelapsejpeg .frames .frame{
|
||||
height: 100px;
|
||||
}
|
||||
#timelapsejpeg .frames .frame img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#timelapsejpeg .frameStrip img{
|
||||
position:absolute;
|
||||
width:100%;
|
||||
height:100%;
|
||||
top:0;
|
||||
left:0;
|
||||
}
|
||||
#timelapsejpeg .modal-body > .row,
|
||||
#timelapsejpeg .modal-body > .row > div {
|
||||
position:relative;
|
||||
height: 100%;
|
||||
}
|
||||
#timelapsejpeg .frameIcons .frame{
|
||||
border-radius: 15px;
|
||||
overflow: hidden;
|
||||
}
|
||||
#timelapsejpeg .frameIcons .frame.selected{
|
||||
border: 3px solid #ffc96b;
|
||||
}
|
||||
#timelapsejpeg .frameIcons > div:not(:last-child){
|
||||
margin-bottom: 15px
|
||||
}
|
||||
#timelapsejpeg .frameIcons{
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
#timelapsejpeg .frameIcons .frame{
|
||||
background-size: cover;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
#timelapsejpeg .frameIcons .frame .shade{
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding: 5px 10px;
|
||||
font-family: monospace;
|
||||
background: rgba(0,0,0,0.6);
|
||||
color: #fff
|
||||
}
|
||||
#timelapsejpeg .playBackView{
|
||||
position:absolute;
|
||||
height: 50%;
|
||||
width:100%;
|
||||
top:0;
|
||||
left:0;
|
||||
background:#333;
|
||||
}
|
||||
#timelapsejpeg .playBackView img{
|
||||
height:100%;
|
||||
}
|
||||
#timelapsejpeg .liveStreamView{
|
||||
position:absolute;
|
||||
text-align: center;
|
||||
height: 50%;
|
||||
width:100%;
|
||||
top:50%;
|
||||
left:0;
|
||||
background:#333;
|
||||
}
|
||||
#timelapsejpeg .liveStreamView iframe{
|
||||
width:100%;
|
||||
height:100%;
|
||||
display: inline-block;
|
||||
margin: auto;
|
||||
border: 0;
|
||||
}
|
||||
/* stand alone */
|
||||
#timelapsejpeg.standalone {
|
||||
background: #2f2f2f;
|
||||
color:#fff;
|
||||
}
|
||||
#timelapsejpeg.standalone .fieldHolder{
|
||||
padding-top: 20px;
|
||||
}
|
||||
.scroll-style-6::-webkit-scrollbar-track
|
||||
{
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||
background-color: #333;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.scroll-style-6::-webkit-scrollbar
|
||||
{
|
||||
width: 10px;
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.scroll-style-6::-webkit-scrollbar-thumb
|
||||
{
|
||||
background-color: #555;
|
||||
background-image: -webkit-linear-gradient(45deg,
|
||||
rgba(255, 255, 255, .2) 25%,
|
||||
transparent 25%,
|
||||
transparent 50%,
|
||||
rgba(255, 255, 255, .2) 50%,
|
||||
rgba(255, 255, 255, .2) 75%,
|
||||
transparent 75%,
|
||||
transparent)
|
||||
}
|
|
@ -1,400 +0,0 @@
|
|||
#accbtn{
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#vis_pwrvideo{height:250px}
|
||||
#monSectionStreamChannels,#monSectionInputMaps{margin-bottom: 15px;}
|
||||
#monSectionStreamChannels:empty,#monSectionInputMaps:empty{display:none}
|
||||
#region_editor_live iframe,.canvas_holder canvas{border:0;position:absolute;left:0;top:0}
|
||||
.canvas_holder canvas{z-index:11}
|
||||
|
||||
.demo-blog .mdl-card__media ~ .mdl-card__supporting-text{position:relative;overflow:initial;cursor:move}
|
||||
.demo-blog .mdl-card__media ~ .mdl-card__supporting-text .btn-group{cursor: default}
|
||||
|
||||
.demo-blog .demo-blog__posts.montage{max-width:100%}
|
||||
|
||||
.mdl-layout__drawer{overflow-y: visible!important}
|
||||
.hide-side .mdl-layout__drawer{overflow-y: hidden}
|
||||
.mdl-layout__header-row{padding-left:10!important}
|
||||
.mdl-layout__header-row .nav>li>a{border-radius:50%;}
|
||||
.mdl-layout__drawer-button i{position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;height:1em;color:#fff}
|
||||
|
||||
|
||||
.video_video{margin:auto;max-width:100%;max-height:600px;}
|
||||
#confirm_window .video_video{margin-top:15px}
|
||||
#confirm_window .info-table{margin-top:15px}
|
||||
@media (max-width: 768px){
|
||||
.full.modal .modal-body,.medium.modal .modal-body{max-height:400px;overflow:auto}
|
||||
}
|
||||
@media (min-width: 768px){
|
||||
.modal.full,.modal.medium{padding-left:0!important;}
|
||||
.modal.full .modal-dialog{width:calc(100% - 10px)!important;margin: 30px auto;}
|
||||
.modal.medium .modal-dialog{width:calc(70% - 10px)!important;margin: 30px auto;}
|
||||
.full.modal .modal-body,.medium.modal .modal-body{height:calc(100% - 200px);overflow:auto}
|
||||
}
|
||||
|
||||
.flex-container-modal-body{overflow: auto}
|
||||
.flex-container-modal-body .flex-block>div{flex:1;float:none}
|
||||
|
||||
.modal{overflow:auto!important}
|
||||
|
||||
.videos_list .title{font-size:12pt;padding:0 10px}
|
||||
|
||||
.demo-drawer{background:#2b2a2a;color:#fff;}
|
||||
.demo-drawer.mdl-layout__drawer .mdl-navigation{padding-top:0;}
|
||||
.demo-drawer::-webkit-scrollbar{display:none;}
|
||||
.small-square-img{height:40px;width:40px;border-radius:5px}
|
||||
|
||||
.side-menu .monitor_block{padding:0;position:relative}
|
||||
.side-menu .monitor_block img{width:100%;height:75px;cursor:pointer;border: 0.5px inset #263238;}
|
||||
@media screen and (max-width:1025px){
|
||||
.side-menu .monitor_block img{height:175px;}
|
||||
}
|
||||
.side-menu .monitor_block:hover .icons{opacity:1}
|
||||
.side-menu .monitor_block:hover .title{opacity:1}
|
||||
.side-menu .monitor_block .icons,.side-menu .monitor_block .title{opacity:0;width:100%;bottom:0;left:0;background:rgba(0,0,0,0.6);position:absolute;padding:2.5px;z-index:11;cursor:move}
|
||||
.side-menu .monitor_block .title{bottom:auto;top:0;color:#fff}
|
||||
.nav-xs.side-menu .monitor_block{width:100%}
|
||||
.side-menu .monitor_block .list-data{display:none}
|
||||
.output_data:empty{display:none}
|
||||
.output_data{max-height:500px;font-family:monospace;padding:10px;border-radius:5px;background:#f3f3f3;overflow:auto}
|
||||
.dark .output_data{background:#222;}
|
||||
#probe .output_data div>div{margin-left:10px}
|
||||
.side-menu.list-blocks .monitor_block .icons,.side-menu.list-blocks .monitor_block .title{position:inherit;opacity:1;background:none}
|
||||
.side-menu.list-blocks .monitor_block .title{padding:5px;border-radius:5px;background:#222;}
|
||||
.side-menu.list-blocks .monitor_block:not(:last-child){border-bottom: 1px solid #54502d;}
|
||||
.side-menu.list-blocks .monitor_block:first-child{border-top: 1px solid #54502d;}
|
||||
.side-menu.list-blocks .monitor_block{float:none;width:100%;padding: 10px}
|
||||
.side-menu.list-blocks .monitor_block.ui-sortable-helper{background:rgba(0,0,0,0.6);border-radius:5px;padding:5px;border:0}
|
||||
.side-menu.list-blocks .monitor_block .list-data{display:block}
|
||||
.side-menu.list-blocks .monitor_block img{width:60px;height:60px;cursor:pointer;display:inline-block;margin-right:10px;border-radius:50%;vertical-align:top;border:0}
|
||||
.nav-xs.side-menu.list-blocks .monitor_block img{width:40px;height:40px;}
|
||||
.side-menu.list-blocks .monitor_block .box{width:calc(100% - 70px);display:inline-block}
|
||||
.nav-xs.side-menu.list-blocks .monitor_block .list-data{display:none}
|
||||
.side-menu .mdl-menu{z-index: 12}
|
||||
|
||||
#monitors_list .monitor_block{transition:none}
|
||||
.dropdown-menu.scrollable{max-height:300px}
|
||||
.upload_file input{display:none}
|
||||
#video_preview .stream-objects{right:0;margin:auto;display:inline-block;position:relative;width:auto}
|
||||
.stream-block,.stream-objects{overflow: hidden!important}
|
||||
.stream-objects{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10}
|
||||
.stream-objects .tag{position:absolute;bottom:100%;left:0;background:red;color:#fff;font-family:monospace;font-size:80%;border-radius:5px 5px 0 0 ;padding:3px 5px;}
|
||||
.stream-objects .stream-detected-object{position:absolute;top:0;left:0;border:3px solid red;background:transparent;border-radius:5px}
|
||||
.stream-objects .stream-detected-point{position:absolute;top:0;left:0;border:3px solid yellow;background:transparent;border-radius:5px}
|
||||
.stream-objects .point{position:absolute;top:0;left:0;border:3px solid red;border-radius:50%}
|
||||
|
||||
|
||||
#side_menu_right.nav-xs{width:0!important;overflow:hidden}
|
||||
.side-menu table{color:#fff;}
|
||||
#main_canvas{background:#333;color:#fff;padding-top:0}
|
||||
#main_header{background:#222;color:#fff;}
|
||||
#logs_modal table tr td:first-child{width:10%}
|
||||
[class_toggle]{cursor:pointer}
|
||||
|
||||
.form-group label{width:100%}
|
||||
|
||||
|
||||
|
||||
#vis_monitors{overflow:auto;max-height:400px}
|
||||
#vis_monitors .btn-group-vertical{width:100%}
|
||||
|
||||
|
||||
.table-striped>tbody>tr>td{vertical-align:middle}
|
||||
.table-striped .thumbnail{width:100px;height:80px;border-radius:5px;margin:0;display:inline-block;}
|
||||
#motion_list{height:155px;overflow:auto;border-radius:5px;border:1px solid #444;position:relative;background: #222;margin:0}
|
||||
.dark .list-group-item{border-color: #444;background:#222}
|
||||
.dark .list-group-item.active{background:#c49a68;border-color:#a7865f}
|
||||
.novideos{text-transform: uppercase;text-align: center;border-bottom:0!important;padding-top: 55%!important;letter-spacing:2px}
|
||||
|
||||
.btn-warning {
|
||||
color: #fff;
|
||||
background-color: #c49a68;
|
||||
border-color: #c49a68;
|
||||
}
|
||||
.dark .table-striped>tbody>tr:nth-of-type(even){background:#616161}
|
||||
.dark .table-striped>tbody>tr>td{border-color:#222;color:#fff}
|
||||
.dark .table-striped>thead>tr>th{border-color:#222;color:#fff;background:#616161;vertical-align:middle;}
|
||||
.dark .table-striped>tbody>tr:nth-of-type(odd){background-color: #4c4747;}
|
||||
.dark .table>tbody>tr.active>td{background:inherit;border:0}
|
||||
.dark code{color: #c49a68;background-color: #36333d;}
|
||||
.dark a:not(.btn){color: #c49a68;}
|
||||
.follow-list ul{padding:0;margin:0;font-family:"Roboto","Helvetica","Arial",sans-serif;}
|
||||
.follow-list ul a:not(.btn){color:#fff}
|
||||
.os_bars{width:600px;display:inline-block;padding:5px 0 0 10px}
|
||||
@media screen and (max-width: 600px){
|
||||
.os_bars{width:200px;}
|
||||
.os_bars label{padding:2.5px 0;margin:0;font-size:8pt}
|
||||
}
|
||||
.os_bars .display-table .display-table-cell{padding:5px;vertical-align:center;width:33%}
|
||||
.progress{height:5px;margin:0;}
|
||||
.os_bars label,.os_bars .percent{padding:2.5px 0;margin:0;font-size:7.5pt}
|
||||
.ui-pnotify-hide .ui-pnotify{display:none!important}
|
||||
/*cool dropdown thing*/
|
||||
ul.msg_list li {
|
||||
background: #f7f7f7;color:#333;
|
||||
padding: 5px;
|
||||
display: list-item;
|
||||
margin: 6px 6px 0;
|
||||
width: 96% !important
|
||||
}
|
||||
|
||||
ul.msg_list li div{display:block}
|
||||
|
||||
ul.msg_list li:last-child {
|
||||
margin-bottom: 6px;
|
||||
padding: 10px
|
||||
}
|
||||
|
||||
ul.msg_list li a {
|
||||
padding: 3px 5px !important
|
||||
}
|
||||
ul.msg_list li .progress {
|
||||
height:5px;margin:10px 0 0 0;
|
||||
}
|
||||
|
||||
ul.msg_list li .image img {
|
||||
border-radius: 2px 2px 2px 2px;
|
||||
-webkit-border-radius: 2px 2px 2px 2px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
width: 11%
|
||||
}
|
||||
|
||||
ul.msg_list li .time {
|
||||
font-size: 11px;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
ul.msg_list li .message {
|
||||
display: block !important;
|
||||
font-size: 11px
|
||||
}
|
||||
|
||||
.dropdown-menu.msg_list span {
|
||||
white-space: normal
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
border: medium none;
|
||||
box-shadow: none;
|
||||
display: none;
|
||||
float: left;
|
||||
font-size: 12px;
|
||||
left: 0;
|
||||
list-style: none outside none;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
text-shadow: none;
|
||||
top: 100%;
|
||||
z-index: 9998;
|
||||
border: 1px solid #D9DEE4;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0
|
||||
}
|
||||
|
||||
.dropdown-menu>li>a {
|
||||
color: #5A738E
|
||||
}
|
||||
|
||||
.navbar-nav .open .dropdown-menu {
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
margin-top: 0;
|
||||
border: 1px solid #D9DEE4;
|
||||
-webkit-box-shadow: none;
|
||||
right: 0;
|
||||
left: auto;
|
||||
width: 220px
|
||||
}
|
||||
.is-small-screen .nav>li{display:inline-block}
|
||||
.navbar-nav .open .dropdown-menu li a{padding:7px 15px}
|
||||
.navbar-nav .open .dropdown-menu.msg_list {
|
||||
width: 300px
|
||||
}
|
||||
.nav>li>a{color:#fff}
|
||||
.nav>li>a:focus, .nav>li>a:hover,.nav .open>a, .nav .open>a:focus, .nav .open>a:hover{background:#867560}
|
||||
|
||||
.mdl-js-layout.hide-side:not(.is-small-screen){
|
||||
|
||||
}
|
||||
@media screen and (min-width: 1025px){
|
||||
.mdl-js-layout.hide-side:not(.is-small-screen)>.mdl-layout__drawer {
|
||||
width: 0px;transition:0.2s
|
||||
}
|
||||
}
|
||||
.mdl-js-layout.hide-side:not(.is-small-screen) .mdl-layout__header .mdl-layout__drawer-button{
|
||||
display:none;
|
||||
}
|
||||
.mdl-js-layout.hide-side:not(.is-small-screen)>.mdl-layout__content{
|
||||
margin-left: 0px;transition:0.2s
|
||||
}
|
||||
.mdl-js-layout.hide-side:not(.is-small-screen)>.mdl-layout__header{
|
||||
margin-left: 0px;width:100%;transition:0.2s
|
||||
}
|
||||
.mdl-menu__item>div{display:flex;align-items: center;width:100%}
|
||||
.mdl-menu__item>div>i{margin-right:5px}
|
||||
|
||||
|
||||
/*Digital Zoom*/
|
||||
.stream-block{
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
}
|
||||
.zoomGlass {
|
||||
overflow: hidden;
|
||||
transition: none;
|
||||
width: 175px; height: 175px;
|
||||
position: absolute;
|
||||
border-radius: 15px;
|
||||
border: 3px solid #ddd;
|
||||
z-index:9999;
|
||||
}
|
||||
.zoomGlass iframe,.zoomGlass canvas{position:absolute;transition: none;}
|
||||
.zoomGlass .hoverShade{position:absolute;width:100%;height:100%}
|
||||
|
||||
.dark.form-control,.dark .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
padding: 6px 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
color: #eee;
|
||||
background-color: #36333d;
|
||||
background-image: none;
|
||||
border: 1px solid #444;
|
||||
border-radius: 4px;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
}
|
||||
|
||||
.dark.form-control:focus,.dark .form-control:focus {
|
||||
color: #ddd;
|
||||
background-color: #333;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
/*** custom checkboxes ***/
|
||||
|
||||
.checkbox input[type=checkbox] { display:none; } /* to hide the checkbox itself */
|
||||
.checkbox input[type=checkbox] + label:before {
|
||||
font-family: FontAwesome;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.checkbox input[type=checkbox] + label:before { content: "\f096"; } /* unchecked icon */
|
||||
.checkbox input[type=checkbox] + label:before { letter-spacing: 10px; } /* space between checkbox and label */
|
||||
|
||||
.checkbox input[type=checkbox]:checked + label:before { content: "\f046"; } /* checked icon */
|
||||
.checkbox input[type=checkbox]:checked + label:before { letter-spacing: 5px; } /* allow space for check mark */
|
||||
|
||||
/*Clock*/
|
||||
#time-date {font-size:12px; text-align:center;}
|
||||
@media screen and (min-width:1025px){
|
||||
#clock {padding-right:35px}
|
||||
}
|
||||
#clock ul { width:150px; margin:0 auto; padding:0px; list-style:none; text-align:center; }
|
||||
#clock ul li { display:inline; font-size:1.6em; text-align:center;font-family:monospace;}
|
||||
|
||||
#clock .point { position:relative; -moz-animation:mymove 1s ease infinite; -webkit-animation:mymove 1s ease infinite; }
|
||||
|
||||
/*custom vis.js css*/
|
||||
.vis-timeline{background:#212121;color:#fff;border-color:#444}
|
||||
.vis-time-axis .vis-text{color: #dedede}
|
||||
.vis-item.vis-range .vis-item-content{background:#333;color:#fff}
|
||||
.vis-time-axis .vis-grid.vis-minor{border-color:#444}
|
||||
|
||||
|
||||
@-moz-document url-prefix() {
|
||||
.full.modal .modal-body, .medium.modal .modal-body {
|
||||
height:70%
|
||||
}
|
||||
}
|
||||
|
||||
/*animations*/
|
||||
@keyframes blink {
|
||||
0% { opacity:1 }
|
||||
50% { opacity:0 }
|
||||
100% { opacity:1 }
|
||||
}
|
||||
@-webkit-keyframes blink {
|
||||
0% { opacity:1 }
|
||||
50% { opacity:0 }
|
||||
100% { opacity:1 }
|
||||
}
|
||||
.blink,[mode="Record"] .lamp {
|
||||
-webkit-animation: blink 1s linear infinite;
|
||||
-moz-animation: blink 1s linear infinite;
|
||||
animation: blink 1s linear infinite;
|
||||
}
|
||||
|
||||
/* All-CSS Toggle Switch (Checkbox Hack) by Marcus Burnette - https://codepen.io/mburnette/pen/LxNxNg */
|
||||
.marc-toggle {
|
||||
width: 50px;
|
||||
height: 25px;
|
||||
}
|
||||
.marc-toggle.abs-bot-left {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
.marc-toggle.abs-bot-right {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
.marc-toggle input[type=checkbox]{
|
||||
height: 0;
|
||||
width: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.marc-toggle label {
|
||||
cursor: pointer;
|
||||
text-indent: -9999px;
|
||||
width: 100px;
|
||||
height: 20px;
|
||||
background: grey;
|
||||
display: block;
|
||||
border-radius: 100px;
|
||||
margin-bottom: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.marc-toggle label:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: #fff;
|
||||
border-radius: 90px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.marc-toggle input:checked + label {
|
||||
background: #00118c;
|
||||
}
|
||||
|
||||
.marc-toggle input:checked + label:after {
|
||||
left: calc(100% - 5px);
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.marc-toggle label:active:after {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
/*hexagon pattern*/
|
||||
.bg-hexagon {
|
||||
background-color: #054e9f;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='49' viewBox='0 0 28 49'%3E%3Cg fill-rule='evenodd'%3E%3Cg id='hexagons' fill='%23fdfdfd' fill-opacity='0.4' fill-rule='nonzero'%3E%3Cpath d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
|
||||
}
|
1
web/libs/css/vis.min.css
vendored
Normal file
1
web/libs/css/vis.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 223 KiB |
Binary file not shown.
Before Width: | Height: | Size: 217 KiB After Width: | Height: | Size: 218 KiB |
5
web/libs/js/bootstrap-slider.min.js
vendored
Normal file
5
web/libs/js/bootstrap-slider.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
|||
$(document).ready(function() {
|
||||
var monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
|
||||
var dayNames= ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]
|
||||
var monthNames = [ lang.January, lang.February, lang.March, lang.April, lang.May, lang.June, lang.July, lang.August, lang.September, lang.October, lang.November, lang.December ];
|
||||
var dayNames= [lang.Sunday, lang.Monday, lang.Tuesday, lang.Wednesday, lang.Thursday, lang.Friday, lang.Saturday]
|
||||
|
||||
var newDate = new Date();
|
||||
newDate.setDate(newDate.getDate());
|
||||
|
|
|
@ -12,6 +12,16 @@ $.ccio.permissionCheck = function(toCheck,monitorId){
|
|||
}
|
||||
return false
|
||||
}
|
||||
$.parseJSON = function(string){
|
||||
var parsed
|
||||
try{
|
||||
parsed = JSON.parse(string)
|
||||
}catch(err){
|
||||
|
||||
}
|
||||
if(!parsed)parsed = string
|
||||
return parsed
|
||||
}
|
||||
$.ccio.op = function(r,rr,rrr){
|
||||
if(!rrr){rrr={};};if(typeof rrr === 'string'){rrr={n:rrr}};if(!rrr.n){rrr.n='ShinobiOptions_'+location.host}
|
||||
ii={o:localStorage.getItem(rrr.n)};try{ii.o=JSON.parse(ii.o)}catch(e){ii.o={}}
|
||||
|
@ -113,25 +123,27 @@ $.ccio.base64ArrayBuffer = function(arrayBuffer) {
|
|||
|
||||
return base64
|
||||
}
|
||||
$.ccio.snapshot=function(e,cb){
|
||||
var image_data,url;
|
||||
e.details=JSON.parse(e.mon.details);
|
||||
$.ccio.snapshot = function(options,cb){
|
||||
var image_data
|
||||
var url
|
||||
var monitor = options.mon || options.monitor || options
|
||||
var details = $.parseJSON(monitor.details)
|
||||
if($.ccio.op().jpeg_on!==true){
|
||||
var extend=function(image_data,width,height){
|
||||
var len = image_data.length
|
||||
var arraybuffer = new Uint8Array( len );
|
||||
var arraybuffer = new Uint8Array( len )
|
||||
for (var i = 0; i < len; i++) {
|
||||
arraybuffer[i] = image_data.charCodeAt(i);
|
||||
arraybuffer[i] = image_data.charCodeAt(i)
|
||||
}
|
||||
try {
|
||||
var blob = new Blob([arraybuffer], {type: 'application/octet-stream'});
|
||||
var blob = new Blob([arraybuffer], {type: 'application/octet-stream'})
|
||||
} catch (e) {
|
||||
var bb = new (window.WebKitBlobBuilder || window.MozBlobBuilder);
|
||||
var bb = new (window.WebKitBlobBuilder || window.MozBlobBuilder)
|
||||
bb.append(arraybuffer);
|
||||
var blob = bb.getBlob('application/octet-stream');
|
||||
}
|
||||
url = (window.URL || window.webkitURL).createObjectURL(blob);
|
||||
finish(url,image_data,width,height);
|
||||
url = (window.URL || window.webkitURL).createObjectURL(blob)
|
||||
finish(url,image_data,width,height)
|
||||
try{
|
||||
setTimeout(function(){
|
||||
URL.revokeObjectURL(url)
|
||||
|
@ -139,142 +151,191 @@ $.ccio.snapshot=function(e,cb){
|
|||
}catch(er){}
|
||||
}
|
||||
var finish = function(url,image_data,width,height){
|
||||
cb(url,image_data,width,height);
|
||||
cb(url,image_data,width,height)
|
||||
}
|
||||
switch(JSON.parse(e.mon.details).stream_type){
|
||||
switch(details.stream_type){
|
||||
case'hls':case'flv':case'mp4':
|
||||
$.ccio.snapshotVideo($('[mid='+e.mon.mid+'].monitor_item video')[0],function(base64,video_data,width,height){
|
||||
$.ccio.snapshotVideo($('[mid='+monitor.mid+'][ke='+monitor.ke+'][auth='+monitor.user.auth_token+'].monitor_item video')[0],function(base64,video_data,width,height){
|
||||
extend(video_data,width,height)
|
||||
})
|
||||
break;
|
||||
case'mjpeg':
|
||||
$('#temp').html('<canvas></canvas>')
|
||||
var c = $('#temp canvas')[0];
|
||||
var img = $('img',$('[mid='+e.mon.mid+'].monitor_item .stream-element').contents())[0];
|
||||
c.width = img.width;
|
||||
c.height = img.height;
|
||||
var ctx = c.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0,c.width,c.height);
|
||||
var c = $('#temp canvas')[0]
|
||||
var img = $('img',$('[mid='+monitor.mid+'][ke='+monitor.ke+'][auth='+monitor.user.auth_token+'].monitor_item .stream-element').contents())[0]
|
||||
c.width = img.width
|
||||
c.height = img.height
|
||||
var ctx = c.getContext('2d')
|
||||
ctx.drawImage(img, 0, 0,c.width,c.height)
|
||||
extend(atob(c.toDataURL('image/jpeg').split(',')[1]),c.width,c.height)
|
||||
break;
|
||||
case'h265':
|
||||
var c = $('[mid='+e.mon.mid+'].monitor_item canvas')[0];
|
||||
var ctx = c.getContext('2d');
|
||||
var c = $('[mid='+monitor.mid+'][ke='+monitor.ke+'][auth='+monitor.user.auth_token+'].monitor_item canvas')[0]
|
||||
var ctx = c.getContext('2d')
|
||||
extend(atob(c.toDataURL('image/jpeg').split(',')[1]),c.width,c.height)
|
||||
break;
|
||||
case'b64':
|
||||
base64 = e.mon.last_frame.split(',')[1];
|
||||
var image_data = new Image();
|
||||
image_data.src = base64;
|
||||
base64 = monitor.last_frame.split(',')[1]
|
||||
var image_data = new Image()
|
||||
image_data.src = base64
|
||||
extend(atob(base64),image_data.width,image_data.height)
|
||||
break;
|
||||
case'jpeg':case'h265':
|
||||
url=e.p.find('.stream-element').attr('src');
|
||||
image_data = new Image();
|
||||
image_data.src = url;
|
||||
finish(url,image_data,image_data.width,image_data.height);
|
||||
case'jpeg':
|
||||
url=e.p.find('.stream-element').attr('src')
|
||||
image_data = new Image()
|
||||
image_data.src = url
|
||||
finish(url,image_data,image_data.width,image_data.height)
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
url=e.p.find('.stream-element').attr('src');
|
||||
image_data = new Image();
|
||||
image_data.src = url;
|
||||
cb(url,image_data,image_data.width,image_data.height);
|
||||
url = e.p.find('.stream-element').attr('src')
|
||||
image_data = new Image()
|
||||
image_data.src = url
|
||||
cb(url,image_data,image_data.width,image_data.height)
|
||||
}
|
||||
}
|
||||
$.ccio.snapshotVideo=function(videoElement,cb){
|
||||
var image_data;
|
||||
$.ccio.snapshotVideo = function(videoElement,cb){
|
||||
var image_data
|
||||
var base64
|
||||
$('#temp').html('<canvas></canvas>')
|
||||
var c = $('#temp canvas')[0];
|
||||
var img = videoElement;
|
||||
c.width = img.videoWidth;
|
||||
c.height = img.videoHeight;
|
||||
var ctx = c.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0,c.width,c.height);
|
||||
var c = $('#temp canvas')[0]
|
||||
var img = videoElement
|
||||
c.width = img.videoWidth
|
||||
c.height = img.videoHeight
|
||||
var ctx = c.getContext('2d')
|
||||
ctx.drawImage(img, 0, 0,c.width,c.height)
|
||||
base64=c.toDataURL('image/jpeg')
|
||||
image_data=atob(base64.split(',')[1]);
|
||||
var arraybuffer = new ArrayBuffer(image_data.length);
|
||||
var view = new Uint8Array(arraybuffer);
|
||||
image_data=atob(base64.split(',')[1])
|
||||
var arraybuffer = new ArrayBuffer(image_data.length)
|
||||
var view = new Uint8Array(arraybuffer)
|
||||
for (var i=0; i<image_data.length; i++) {
|
||||
view[i] = image_data.charCodeAt(i) & 0xff;
|
||||
view[i] = image_data.charCodeAt(i) & 0xff
|
||||
}
|
||||
try {
|
||||
var blob = new Blob([arraybuffer], {type: 'application/octet-stream'});
|
||||
var blob = new Blob([arraybuffer], {type: 'application/octet-stream'})
|
||||
} catch (e) {
|
||||
var bb = new (window.WebKitBlobBuilder || window.MozBlobBuilder);
|
||||
bb.append(arraybuffer);
|
||||
var blob = bb.getBlob('application/octet-stream');
|
||||
var bb = new (window.WebKitBlobBuilder || window.MozBlobBuilder)
|
||||
bb.append(arraybuffer)
|
||||
var blob = bb.getBlob('application/octet-stream')
|
||||
}
|
||||
cb(base64,image_data,c.width,c.height);
|
||||
cb(base64,image_data,c.width,c.height)
|
||||
}
|
||||
$.ccio.magnifyStream = function(e){
|
||||
if(!e.p){
|
||||
e.e=$(this),
|
||||
e.p=e.e.parents('[mid]')
|
||||
$.ccio.magnifyStream = function(options,user){
|
||||
if(!user)user = $user
|
||||
if(!options.p && !options.parent){
|
||||
var el = $(this),
|
||||
parent = el.parents('[mid]')
|
||||
}else{
|
||||
parent = options.p || options.parent
|
||||
}
|
||||
if(e.animate === true){
|
||||
if(!options.attribute){
|
||||
options.attribute = ''
|
||||
}
|
||||
if(options.animate === true){
|
||||
var zoomGlassAnimate = 'animate'
|
||||
}else{
|
||||
var zoomGlassAnimate = 'css'
|
||||
}
|
||||
if(e.auto === true){
|
||||
if(!options.magnifyOffsetElement){
|
||||
options.magnifyOffsetElement = '.stream-block'
|
||||
}
|
||||
if(!options.targetForZoom){
|
||||
options.targetForZoom = '.stream-element'
|
||||
}
|
||||
if(options.auto === true){
|
||||
var streamBlockOperator = 'position'
|
||||
}else{
|
||||
var streamBlockOperator = 'offset'
|
||||
}
|
||||
if(e.useCanvas === true){
|
||||
var magnifiedElement = 'canvas'
|
||||
var magnifiedElement
|
||||
if(!options.videoUrl){
|
||||
if(options.useCanvas === true){
|
||||
magnifiedElement = 'canvas'
|
||||
}else{
|
||||
magnifiedElement = 'iframe'
|
||||
}
|
||||
}else{
|
||||
var magnifiedElement = 'iframe'
|
||||
magnifiedElement = 'video'
|
||||
}
|
||||
e.ke=e.p.attr('ke'),//group key
|
||||
e.mid=e.p.attr('mid'),//monitor id
|
||||
e.auth=e.p.attr('auth'),//authkey
|
||||
e.mon=$.ccio.mon[e.ke+e.mid+e.auth]//monitor configuration
|
||||
if(e.zoomAmount)e.mon.zoomAmount=3;
|
||||
if(!e.mon.zoomAmount)e.mon.zoomAmount=3;
|
||||
e.height=parseFloat(e.p.attr('realHeight')) * e.mon.zoomAmount//height of stream
|
||||
e.width=parseFloat(e.p.attr('realWidth')) * e.mon.zoomAmount;//width of stream
|
||||
var targetForZoom = e.p.find('.stream-element');
|
||||
zoomGlass = e.p.find(".zoomGlass");
|
||||
if(!options.mon && !options.monitor){
|
||||
var groupKey = parent.attr('ke')//group key
|
||||
var monitorId = parent.attr('mid')//monitor id
|
||||
var sessionKey = parent.attr('auth')//authkey
|
||||
var monitor = $.ccio.mon[groupKey + monitorId + sessionKey]//monitor configuration
|
||||
}else{
|
||||
var monitor = options.mon || options.monitor
|
||||
var groupKey = monitor.ke//group key
|
||||
var monitorId = monitor.mid//monitor id
|
||||
var sessionKey = monitor.auth//authkey
|
||||
}
|
||||
if(options.zoomAmount)zoomAmount = 3
|
||||
if(!zoomAmount)zoomAmount = 3
|
||||
var realHeight = parent.attr('realHeight')
|
||||
var realWidth = parent.attr('realWidth')
|
||||
var height = parseFloat(realHeight) * zoomAmount//height of stream
|
||||
var width = parseFloat(realWidth) * zoomAmount//width of stream
|
||||
var targetForZoom = parent.find(options.targetForZoom)
|
||||
zoomGlass = parent.find(".zoomGlass")
|
||||
var zoomFrame = function(){
|
||||
var magnify_offset = e.p.find('.stream-block')[streamBlockOperator]();
|
||||
var mx = e.pageX - magnify_offset.left;
|
||||
var my = e.pageY - magnify_offset.top;
|
||||
var rx = Math.round(mx/targetForZoom.width()*e.width - zoomGlass.width()/2)*-1;
|
||||
var ry = Math.round(my/targetForZoom.height()*e.height - zoomGlass.height()/2)*-1;
|
||||
var px = mx - zoomGlass.width()/2;
|
||||
var py = my - zoomGlass.height()/2;
|
||||
zoomGlass[zoomGlassAnimate]({left: px, top: py}).find(magnifiedElement)[zoomGlassAnimate]({left: rx, top: ry});
|
||||
var magnify_offset = parent.find(options.magnifyOffsetElement)[streamBlockOperator]()
|
||||
var mx = options.pageX - magnify_offset.left
|
||||
var my = options.pageY - magnify_offset.top
|
||||
var rx = Math.round(mx/targetForZoom.width()*width - zoomGlass.width()/2)*-1
|
||||
var ry = Math.round(my/targetForZoom.height()*height - zoomGlass.height()/2)*-1
|
||||
var px = mx - zoomGlass.width()/2
|
||||
var py = my - zoomGlass.height()/2
|
||||
zoomGlass[zoomGlassAnimate]({left: px, top: py}).find(magnifiedElement)[zoomGlassAnimate]({left: rx, top: ry})
|
||||
}
|
||||
if(!e.height||!e.width||zoomGlass.length===0){
|
||||
$.ccio.snapshot(e,function(url,buffer,width,height){
|
||||
e.width = width * e.mon.zoomAmount;
|
||||
e.height = height * e.mon.zoomAmount;
|
||||
e.p.attr('realWidth',width)
|
||||
e.p.attr('realHeight',height)
|
||||
zoomGlass = e.p.find(".zoomGlass");
|
||||
if(zoomGlass.length===0){
|
||||
if(e.useCanvas === true){
|
||||
e.p.append('<div class="zoomGlass"><canvas class="blenderCanvas"></canvas></div>');
|
||||
}else{
|
||||
e.p.append('<div class="zoomGlass"><iframe src="'+e.auth+'/embed/'+e.ke+'/'+e.mid+'/fullscreen|jquery|relative"/><div class="hoverShade"></div></div>');
|
||||
}
|
||||
zoomGlass = e.p.find(".zoomGlass");
|
||||
}
|
||||
zoomGlass.find(magnifiedElement).css({height:e.height,width:e.width});
|
||||
zoomFrame()
|
||||
var commit = function(height,width){
|
||||
zoomGlass.find(magnifiedElement).css({
|
||||
height: height,
|
||||
width: width
|
||||
})
|
||||
}else{
|
||||
zoomGlass.find(magnifiedElement).css({height:e.height,width:e.width});
|
||||
zoomFrame()
|
||||
}
|
||||
if(!height || !width || zoomGlass.length === 0){
|
||||
zoomGlass = parent.find(".zoomGlass")
|
||||
var zoomGlassShell = function(contents){return `<div ${options.attribute} class="zoomGlass">${contents}</div>`}
|
||||
if(!options.videoUrl){
|
||||
$.ccio.snapshot(monitor,function(url,buffer,w,h){
|
||||
parent.attr('realWidth',w)
|
||||
parent.attr('realHeight',h)
|
||||
if(zoomGlass.length === 0){
|
||||
if(options.useCanvas === true){
|
||||
parent.append(zoomGlassShell('<canvas class="blenderCanvas"></canvas>'))
|
||||
}else{
|
||||
parent.append(zoomGlassShell('<iframe src="'+$.ccio.init('location',user)+sessionKey+'/embed/'+groupKey+'/'+monitorId+'/fullscreen|jquery|relative"/><div class="hoverShade"></div>'))
|
||||
}
|
||||
zoomGlass = parent.find(".zoomGlass")
|
||||
}
|
||||
commit(h,w)
|
||||
})
|
||||
}else{
|
||||
if(zoomGlass.length === 0){
|
||||
parent.append(zoomGlassShell(`<video src="${options.videoUrl}" preload></video>`))
|
||||
}
|
||||
if(options.setTime){
|
||||
var video = zoomGlass.find('video')[0]
|
||||
video.currentTime = options.setTime
|
||||
height = video.videoHeight
|
||||
width = video.videoWidth
|
||||
parent.attr('realWidth',width)
|
||||
parent.attr('realHeight',height)
|
||||
}
|
||||
commit(height,width)
|
||||
}
|
||||
}else{
|
||||
if(options.setTime){
|
||||
var video = zoomGlass.find('video')
|
||||
var src = video.attr('src')
|
||||
video[0].currentTime = options.setTime
|
||||
if(options.videoUrl !== src)zoomGlass.html(`<video src="${options.videoUrl}" preload></video>`)
|
||||
}
|
||||
commit(height,width)
|
||||
}
|
||||
}
|
||||
$.ccio.destroyStream = function(d,user,killElement){
|
||||
if(d.mid && !d.id)d.id = d.mid
|
||||
console.log(d.ke+d.id+user.auth_token)
|
||||
console.log($.ccio.mon[d.ke+d.id+user.auth_token])
|
||||
if($.ccio.mon[d.ke+d.id+user.auth_token]){
|
||||
console.log('destroy')
|
||||
$.ccio.init('closeVideo',{mid:d.id,ke:d.ke},user);
|
||||
|
@ -297,3 +358,59 @@ $.ccio.destroyStream = function(d,user,killElement){
|
|||
}
|
||||
}
|
||||
}
|
||||
$(document).ready(function(){
|
||||
$('body')
|
||||
.on('click', '.table-header-sorter', function () {
|
||||
var $sort = jQuery(this).find('i');
|
||||
var currentSort = undefined;
|
||||
if ($sort.hasClass('fa-sort-asc')) {
|
||||
currentSort = 'asc';
|
||||
} else if ($sort.hasClass('fa-sort-desc')) {
|
||||
currentSort = 'desc';
|
||||
}
|
||||
|
||||
jQuery(this)
|
||||
.parent()
|
||||
.find('i.fa')
|
||||
.removeClass('fa-sort-asc')
|
||||
.removeClass('fa-sort-desc')
|
||||
.addClass('fa-sort');
|
||||
|
||||
jQuery(this)
|
||||
.find('i.fa')
|
||||
.toggleClass('fa-sort', currentSort === 'desc')
|
||||
.toggleClass('fa-sort-asc', currentSort === undefined)
|
||||
.toggleClass('fa-sort-desc', currentSort === 'asc');
|
||||
|
||||
const field = jQuery(this).data('field');
|
||||
const $body = jQuery(this)
|
||||
.closest('.table')
|
||||
.find('tbody');
|
||||
|
||||
const sortedRows = $body
|
||||
.find('tr')
|
||||
.detach()
|
||||
.sort(function(a,b) {
|
||||
const data1 = jQuery(a).data('sort');
|
||||
const data2 = jQuery(b).data('sort');
|
||||
if (currentSort === undefined)
|
||||
return data1[field] > data2[field] ? 1 : data1[field] < data2[field] ? -1 : 0;
|
||||
else if (currentSort === 'asc')
|
||||
return data1[field] > data2[field] ? -1 : data1[field] < data2[field] ? 1 : 0;
|
||||
else
|
||||
return data1._no > data2._no ? 1 : data1._no < data2._no ? -1 : 0;
|
||||
});
|
||||
$body.append(sortedRows);
|
||||
})
|
||||
.on('click','[tab-chooser]',function(){
|
||||
var el = $(this)
|
||||
var parent = el.parents('[tab-chooser-parent]')
|
||||
var tabName = el.attr('tab-chooser')
|
||||
var allTabsInParent = parent.find('[tab-section]')
|
||||
var allTabChoosersInParent = parent.find('[tab-chooser]')
|
||||
allTabsInParent.hide()
|
||||
allTabChoosersInParent.removeClass('active')
|
||||
el.addClass('active')
|
||||
parent.find(`[tab-section="${tabName}"]`).show()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -3,8 +3,7 @@ $.ccio={
|
|||
mon:{},
|
||||
useUTC: <%- config.useUTC || false %>,
|
||||
definitions: <%-JSON.stringify(define)%>,
|
||||
libURL: '<%-window.libURL%>',
|
||||
logMemory: []
|
||||
libURL: '<%-window.libURL%>'
|
||||
};
|
||||
<% if(config.DropboxAppKey){ %>
|
||||
$.ccio.DropboxAppKey = '<%-window.DropboxAppKey%>'
|
||||
|
@ -118,7 +117,6 @@ $(document).ready(function(e){
|
|||
}
|
||||
})
|
||||
}
|
||||
//on window resize
|
||||
document.addEventListener("fullscreenchange", onFullScreenChange, false);
|
||||
document.addEventListener("webkitfullscreenchange", onFullScreenChange, false);
|
||||
document.addEventListener("mozfullscreenchange", onFullScreenChange, false);
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
$(document).ready(function(){
|
||||
$.confirm={e:$('#confirm_window')};
|
||||
$.confirm.title=$.confirm.e.find('.modal-title span')
|
||||
$.confirm.body=$.confirm.e.find('.modal-body')
|
||||
$.confirm.footer=$.confirm.e.find('.modal-footer')
|
||||
$.confirm.click=function(x,e){
|
||||
$.confirm.footer.find('.confirmaction').remove()
|
||||
var createButton = function(x,place,callback){
|
||||
$.confirm.footer.prepend('<button type="button" class="btn '+x.class+' confirmaction confirmaction'+place+'">'+x.title+'</button>')
|
||||
if(!x.class){x.class='btn-success'}
|
||||
if(!x.title){x.title='Save changes'}
|
||||
$.confirm.footer.find('.confirmaction'+place).click(function(){
|
||||
$.confirm.e.modal('hide')
|
||||
callback();
|
||||
})
|
||||
}
|
||||
if(x instanceof Array){
|
||||
$.each(x,function(place,x){
|
||||
createButton(x,place,x.callback)
|
||||
})
|
||||
}else{
|
||||
createButton(x,0,e)
|
||||
}
|
||||
}
|
||||
$.confirm.create = function(options){
|
||||
if(options.title && options.body){
|
||||
$.confirm.e.modal('show')
|
||||
$.confirm.title.text(options.title)
|
||||
$.confirm.body.html(options.body)
|
||||
}
|
||||
if(options.clickOptions && options.clickCallback)$.confirm.click(options.clickOptions,options.clickCallback)
|
||||
}
|
||||
$.confirm.e.on('hidden.bs.modal', function () {
|
||||
$.confirm.footer.find('.confirmaction').remove()
|
||||
})
|
||||
})
|
129
web/libs/js/dash2.downloadAndZip.js
Normal file
129
web/libs/js/dash2.downloadAndZip.js
Normal file
|
@ -0,0 +1,129 @@
|
|||
$(document).ready(function(){
|
||||
var downloadFile = function(remoteLink,onProgress,onSuccess){
|
||||
if(!onProgress)onProgress = function(){}
|
||||
if(!onSuccess)onSuccess = function(){}
|
||||
var xhr = new window.XMLHttpRequest();
|
||||
xhr.addEventListener("progress", function(evt) {
|
||||
if (evt.lengthComputable) {
|
||||
var percentComplete = (evt.loaded / evt.total * 100).toFixed(2);
|
||||
onProgress(percentComplete)
|
||||
}
|
||||
}, false)
|
||||
xhr.addEventListener('readystatechange', function(e) {
|
||||
if(xhr.readyState == 2 && xhr.status == 200) {
|
||||
// Download is being started
|
||||
}
|
||||
else if(xhr.readyState == 3) {
|
||||
// Download is under progress
|
||||
}
|
||||
else if(xhr.readyState == 4) {
|
||||
onSuccess(xhr.response)
|
||||
// Downloaing has finished
|
||||
|
||||
// request.response holds the file data
|
||||
}
|
||||
})
|
||||
xhr.responseType = 'blob'
|
||||
|
||||
// Downloading a JPEG file
|
||||
xhr.open('get', remoteLink)
|
||||
|
||||
xhr.send()
|
||||
}
|
||||
var downloadBulkVideos = function(videos,onProgress,onSuccess){
|
||||
var fileBuffers = {}
|
||||
var numberOfCompletedDownloads = 0
|
||||
var getVideo = function(video){
|
||||
var url = video.href
|
||||
downloadFile(url,function(percent){
|
||||
if(onProgress)onProgress(video,percent)
|
||||
},function(buffer){
|
||||
++numberOfCompletedDownloads
|
||||
fileBuffers[url] = Object.assign(video,{buffer: buffer})
|
||||
console.log(fileBuffers[url] )
|
||||
console.log(videos.length, numberOfCompletedDownloads)
|
||||
if(videos.length === numberOfCompletedDownloads){
|
||||
if(onSuccess)onSuccess(fileBuffers)
|
||||
}else{
|
||||
getVideo(videos[numberOfCompletedDownloads])
|
||||
}
|
||||
})
|
||||
}
|
||||
getVideo(videos[numberOfCompletedDownloads])
|
||||
}
|
||||
var saveFile = function(blob, filename) {
|
||||
console.log(blob,filename)
|
||||
if (window.navigator.msSaveOrOpenBlob) {
|
||||
window.navigator.msSaveOrOpenBlob(blob, filename);
|
||||
} else {
|
||||
const a = document.createElement('a');
|
||||
document.body.appendChild(a);
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
setTimeout(() => {
|
||||
window.URL.revokeObjectURL(url);
|
||||
document.body.removeChild(a);
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
var zipVideosAndDownload = function(videos,onSuccess){
|
||||
var zip = new JSZip();
|
||||
var zipFileName = `ShinobiVideos_${$.ccio.timeObject(new Date()).format('YYYY-MM-DDTHH-mm-ss')}.zip`
|
||||
var foldersCreated = {}
|
||||
var downloadBars = {}
|
||||
var progressBarHtml = []
|
||||
var videosCopy = Object.assign(videos,{})
|
||||
$.each(videosCopy,function(n,video){
|
||||
var fileZipName = `${$.ccio.timeObject(video.time).format('YYYY-MM-DDTHH-mm-ss')}.${video.ext}`
|
||||
var fileId = video.ke + video.mid + moment(video.time).format('YYYY-MM-DDTHH-mm-ss')
|
||||
video.fileId = fileId
|
||||
video.fileZipName = fileZipName
|
||||
if(!foldersCreated[video.ke]){
|
||||
foldersCreated[video.ke] = {}
|
||||
foldersCreated[video.ke]._zipFolder = zip.folder(video.ke)
|
||||
}
|
||||
if(!foldersCreated[video.ke][video.mid]){
|
||||
foldersCreated[video.ke][video.mid] = {}
|
||||
foldersCreated[video.ke][video.mid]._zipFolder = foldersCreated[video.ke]._zipFolder.folder(video.mid)
|
||||
}
|
||||
progressBarHtml.push(`<br><small></small><div id="download-${fileId}" class="progress"><div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%"></div></div>`)
|
||||
})
|
||||
new PNotify({
|
||||
type:'notice',
|
||||
title: lang['Downloading Videos'],
|
||||
text: lang['Please Wait for Completion'] + progressBarHtml.join(''),
|
||||
hide: false,
|
||||
modules: {
|
||||
Buttons: {
|
||||
closer: true,
|
||||
sticker: false
|
||||
},
|
||||
Mobile: {
|
||||
swipeDismiss: false
|
||||
}
|
||||
},
|
||||
})
|
||||
$.each(videosCopy,function(n,video){
|
||||
downloadBars[video.fileId] = $(`#download-${video.fileId} .progress-bar`)
|
||||
})
|
||||
downloadBulkVideos(videosCopy,function(video,percent){
|
||||
downloadBars[video.fileId].width(percent + '%').attr('aria-valuenow', percent)
|
||||
},function(videosWithBuffers){
|
||||
new PNotify({
|
||||
type:'success',
|
||||
title: lang['Zipping Videos'],
|
||||
text: lang['Please Wait for Completion']
|
||||
})
|
||||
$.each(videosWithBuffers,function(n,video){
|
||||
foldersCreated[video.ke][video.mid]._zipFolder.file(video.fileZipName, video.buffer)
|
||||
})
|
||||
zip.generateAsync({type:"blob"}).then(function(content) {
|
||||
saveFile(content, zipFileName)
|
||||
if(onSuccess)onSuccess(content)
|
||||
});
|
||||
})
|
||||
}
|
||||
$.zipVideosAndDownload = zipVideosAndDownload
|
||||
})
|
|
@ -20,8 +20,13 @@ $.ccio.tm=function(x,d,z,user){
|
|||
d.per=parseInt(d.hr/24*100);
|
||||
d.circle='<div title="at '+d.hr+' hours of '+d.startMoment.format('MMMM DD')+'" '+href+' video="launch" class="progress-circle progress-'+d.per+'"><span>'+d.hr+'</span></div>'
|
||||
tmp+='<li class="video-item glM'+d.mid+user.auth_token+'" auth="'+user.auth_token+'" mid="'+d.mid+'" ke="'+d.ke+'" status="'+d.status+'" status="'+d.status+'" file="'+d.filename+'">'+d.circle+'<div><span title="'+d.endMoment.format()+'" class="livestamp"></span></div><div><div class="small"><b>'+lang.Start+'</b> : '+d.startMoment.format('h:mm:ss , MMMM Do YYYY')+'</div><div class="small"><b>'+lang.End+'</b> : '+d.endMoment.format('h:mm:ss , MMMM Do YYYY')+'</div></div><div><span class="pull-right">'+(parseInt(d.size)/1000000).toFixed(2)+'mb</span><div class="controls btn-group"><a class="btn btn-sm btn-primary" video="launch" '+href+'><i class="fa fa-play-circle"></i></a> <a download="'+d.dlname+'" '+href+' class="btn btn-sm btn-default"><i class="fa fa-download"></i></a>'
|
||||
if($.ccio.DropboxAppKey){ tmp+='<a video="download" host="dropbox" download="'+d.dlname+'" '+href+' class="btn btn-sm btn-default"><i class="fa fa-dropbox"></i></a>' }
|
||||
tmp+='<a title="'+lang['Delete Video']+'" video="delete" href="'+$.ccio.init('videoHrefToDelete',url)+'" class="btn btn-sm btn-danger permission_video_delete"><i class="fa fa-trash"></i></a></div></div></li>';
|
||||
if($.ccio.DropboxAppKey){
|
||||
tmp+='<a video="download" host="dropbox" download="'+d.dlname+'" '+href+' class="btn btn-sm btn-default"><i class="fa fa-dropbox"></i></a>'
|
||||
}
|
||||
if($.ccio.permissionCheck('video_delete',d.mid)){
|
||||
tmp += '<a title="'+lang['Delete Video']+'" video="delete" href="'+$.ccio.init('videoHrefToDelete',url)+'" class="btn btn-sm btn-danger"><i class="fa fa-trash"></i></a>'
|
||||
}
|
||||
tmp += '</div></div></li>';
|
||||
$(z).each(function(n,v){
|
||||
v=$(v);
|
||||
if(v.find('.video-item').length>10){v.find('.video-item:last').remove()}
|
||||
|
@ -33,25 +38,25 @@ $.ccio.tm=function(x,d,z,user){
|
|||
tmp+='<div class="btn-group btn-group-xs">'
|
||||
var buttons = {
|
||||
"Pop": {
|
||||
"label": "Pop",
|
||||
"label": lang['Pop'],
|
||||
"attr": "monitor=\"pop\"",
|
||||
"class": "default",
|
||||
"icon": "external-link"
|
||||
},
|
||||
"Power Viewer": {
|
||||
"label": "Power Viewer",
|
||||
"attr": "monitor=\"powerview\"",
|
||||
"class": "default",
|
||||
"icon": "map-marker"
|
||||
},
|
||||
// "Power Viewer": {
|
||||
// "label": lang['Power Viewer'],
|
||||
// "attr": "monitor=\"powerview\"",
|
||||
// "class": "default",
|
||||
// "icon": "map-marker"
|
||||
// },
|
||||
"Videos List": {
|
||||
"label": "Videos List",
|
||||
"label": lang['Videos List'],
|
||||
"attr": "monitor=\"videos_table\"",
|
||||
"class": "default",
|
||||
"icon": "film"
|
||||
},
|
||||
"Monitor Settings": {
|
||||
"label": "Monitor Settings",
|
||||
"label": lang['Monitor Settings'],
|
||||
"attr": "monitor=\"edit\"",
|
||||
"class": "default",
|
||||
"icon": "wrench"
|
||||
|
@ -89,50 +94,56 @@ $.ccio.tm=function(x,d,z,user){
|
|||
tmp+='<div class="btn-group btn-group-sm">'//start of btn list
|
||||
var buttons = {
|
||||
"Snapshot": {
|
||||
"label": "Snapshot",
|
||||
"label": lang['Snapshot'],
|
||||
"attr": "monitor=\"snapshot\"",
|
||||
"class": "primary",
|
||||
"icon": "camera"
|
||||
},
|
||||
"Show Logs": {
|
||||
"label": "Show Logs",
|
||||
"label": lang['Show Logs'],
|
||||
"attr": "monitor=\"show_data\"",
|
||||
"class": "warning",
|
||||
"icon": "exclamation-triangle"
|
||||
},
|
||||
"Control": {
|
||||
"label": "Control",
|
||||
"label": lang['Control'],
|
||||
"attr": "monitor=\"control_toggle\"",
|
||||
"class": "default arrows",
|
||||
"icon": "arrows"
|
||||
},
|
||||
"Status Indicator": {
|
||||
"label": "Status Indicator",
|
||||
"Reconnect Stream": {
|
||||
"label": lang['Reconnect Stream'],
|
||||
"attr": "monitor=\"watch_on\"",
|
||||
"class": "success signal",
|
||||
"icon": "plug"
|
||||
},
|
||||
"Pop": {
|
||||
"label": "Pop",
|
||||
"label": lang['Pop'],
|
||||
"attr": "monitor=\"pop\"",
|
||||
"class": "default",
|
||||
"icon": "external-link"
|
||||
},
|
||||
"Pop": {
|
||||
"label": lang['Zoom In'],
|
||||
"attr": "monitor=\"zoomStreamWithMouse\"",
|
||||
"class": "default",
|
||||
"icon": "search-plus"
|
||||
},
|
||||
"Calendar": {
|
||||
"label": "Calendar",
|
||||
"label": lang['Calendar'],
|
||||
"attr": "monitor=\"calendar\"",
|
||||
"class": "default ",
|
||||
"icon": "calendar"
|
||||
},
|
||||
"Power Viewer": {
|
||||
"label": "Power Viewer",
|
||||
"attr": "monitor=\"powerview\"",
|
||||
"class": "default",
|
||||
"icon": "map-marker"
|
||||
},
|
||||
// "Power Viewer": {
|
||||
// "label": lang['Power Viewer'],
|
||||
// "attr": "monitor=\"powerview\"",
|
||||
// "class": "default",
|
||||
// "icon": "map-marker"
|
||||
// },
|
||||
"Time-lapse": {
|
||||
"label": "Time-lapse",
|
||||
"attr": "monitor=\"timelapse\"",
|
||||
"label": lang['Time-lapse'],
|
||||
"attr": "monitor=\"timelapseJpeg\"",
|
||||
"class": "default",
|
||||
"icon": "angle-double-right"
|
||||
},
|
||||
|
@ -143,25 +154,25 @@ $.ccio.tm=function(x,d,z,user){
|
|||
"icon": "th"
|
||||
},
|
||||
"Videos List": {
|
||||
"label": "Videos List",
|
||||
"label": lang['Videos List'],
|
||||
"attr": "monitor=\"videos_table\"",
|
||||
"class": "default",
|
||||
"icon": "film"
|
||||
},
|
||||
"Monitor Settings": {
|
||||
"label": "Monitor Settings",
|
||||
"label": lang['Monitor Settings'],
|
||||
"attr": "monitor=\"edit\"",
|
||||
"class": "default",
|
||||
"icon": "wrench"
|
||||
},
|
||||
"Fullscreen": {
|
||||
"label": "Fullscreen",
|
||||
"label": lang['Fullscreen'],
|
||||
"attr": "monitor=\"fullscreen\"",
|
||||
"class": "default",
|
||||
"icon": "arrows-alt"
|
||||
},
|
||||
"Close": {
|
||||
"label": "Close",
|
||||
"label": lang['Close'],
|
||||
"attr": "monitor=\"watch_off\"",
|
||||
"class": "danger",
|
||||
"icon": "times"
|
||||
|
|
|
@ -75,7 +75,7 @@ $(document).ready(function(e){
|
|||
$.logWriter.floodTimeout = setTimeout(function(){
|
||||
delete($.logWriter.floodTimeout)
|
||||
$.logWriter.floodCounter = 0
|
||||
},1000)
|
||||
},2000)
|
||||
$.ccio.tm(4,d,'#logs,'+id+'.monitor_item .logs:visible,'+id+'#add_monitor:visible .logs',user)
|
||||
}
|
||||
//open all monitors
|
||||
|
@ -320,6 +320,32 @@ $(document).ready(function(e){
|
|||
user=$user
|
||||
}
|
||||
switch(e.a){
|
||||
case'zoomStreamWithMouse':
|
||||
var streamWindow = $('.monitor_item[mid="'+e.mid+'"][ke="'+e.ke+'"][auth="'+e.auth+'"]')
|
||||
if(e.mon.magnifyStreamEnabled){
|
||||
e.mon.magnifyStreamEnabled = false
|
||||
streamWindow
|
||||
.off('mousemove')
|
||||
.off('touchmove')
|
||||
.find('.zoomGlass').remove()
|
||||
}else{
|
||||
e.mon.magnifyStreamEnabled = true
|
||||
const magnifyStream = function(e){
|
||||
$.ccio.magnifyStream({
|
||||
p: streamWindow,
|
||||
zoomAmount: 1,
|
||||
auto: false,
|
||||
animate: false,
|
||||
pageX: e.pageX,
|
||||
pageY: e.pageY,
|
||||
attribute: 'monitor="zoomStreamWithMouse"'
|
||||
},user)
|
||||
}
|
||||
streamWindow
|
||||
.on('mousemove', magnifyStream)
|
||||
.on('touchmove', magnifyStream)
|
||||
}
|
||||
break;
|
||||
case'show_data':
|
||||
e.p.toggleClass('show_data')
|
||||
var dataBlocks = e.p.find('.stream-block,.mdl-data_window')
|
||||
|
@ -365,31 +391,17 @@ $(document).ready(function(e){
|
|||
})
|
||||
}
|
||||
break;
|
||||
case'timelapse':
|
||||
$.timelapse.e.modal('show')
|
||||
$.timelapse.monitors.find('.monitor').remove()
|
||||
case'timelapseJpeg':
|
||||
$.timelapseJpeg.e.modal('show')
|
||||
$.timelapseJpeg.monitors.find('.monitor').remove()
|
||||
$.each($.ccio.mon,function(n,v){
|
||||
$.timelapse.monitors.append('<option class="monitor" value="'+v.mid+'">'+v.name+'</option>')
|
||||
$.timelapseJpeg.monitors.append('<option class="monitor" value="'+v.mid+'">'+v.name+'</option>')
|
||||
})
|
||||
e.e=$.timelapse.monitors.find('.monitor').prop('selected',false)
|
||||
e.e=$.timelapseJpeg.monitors.find('.monitor').prop('selected',false)
|
||||
if(e.mid!==''){
|
||||
e.e=$.timelapse.monitors.find('.monitor[value="'+e.mid+'"]')
|
||||
e.e=$.timelapseJpeg.monitors.find('.monitor[value="'+e.mid+'"]')
|
||||
}
|
||||
e.e.first().prop('selected',true)
|
||||
$.timelapse.f.submit()
|
||||
break;
|
||||
case'powerview':
|
||||
$.pwrvid.e.modal('show')
|
||||
$.pwrvid.m.empty()
|
||||
$.each($.ccio.mon,function(n,v){
|
||||
$.pwrvid.m.append('<option value="'+v.mid+'">'+v.name+'</option>')
|
||||
})
|
||||
e.e=$.pwrvid.m.find('option').prop('selected',false)
|
||||
if(e.mid!==''){
|
||||
e.e=$.pwrvid.m.find('[value="'+e.mid+'"]')
|
||||
}
|
||||
e.e.first().prop('selected',true)
|
||||
$.pwrvid.f.submit()
|
||||
break;
|
||||
case'region':
|
||||
if(!e.mon){
|
||||
|
@ -508,6 +520,7 @@ $(document).ready(function(e){
|
|||
right: 'month,agendaWeek,agendaDay,listWeek'
|
||||
},
|
||||
defaultDate: $.ccio.timeObject(d.videos[0].time).format('YYYY-MM-DD'),
|
||||
locale: user.details.lang.substring(0, 2),
|
||||
navLinks: true,
|
||||
eventLimit: true,
|
||||
events:e.ar,
|
||||
|
@ -562,21 +575,21 @@ $(document).ready(function(e){
|
|||
var showThumbnail = $.ccio.op().showThumbnail === '1'
|
||||
$.vidview.e.removeClass('dark')
|
||||
e.t.attr('class','fa fa-film')
|
||||
var tmp = '<table class="table table-striped" style="max-height:500px">';
|
||||
var tmp = '<table class="table table-striped table-bordered">';
|
||||
tmp+='<thead>';
|
||||
tmp+='<tr>';
|
||||
tmp+='<th><div class="checkbox"><input id="videos_select_all" type="checkbox"><label for="videos_select_all"></label></div></th>';
|
||||
if(showThumbnail)tmp+='<th data-field="Thumbnail" data-sortable="true">'+lang.Thumbnail+'</th>';
|
||||
tmp+='<th data-field="Closed" data-sortable="true">'+lang.Closed+'</th>';
|
||||
tmp+='<th data-field="Ended" data-sortable="true">'+lang.Ended+'</th>';
|
||||
tmp+='<th data-field="Started" data-sortable="true">'+lang.Started+'</th>';
|
||||
tmp+='<th data-field="Monitor" data-sortable="true">'+lang.Monitor+'</th>';
|
||||
tmp+='<th data-field="Filename" data-sortable="true">'+lang.Filename+'</th>';
|
||||
tmp+='<th data-field="Size" data-sortable="true">'+lang['Size (mb)']+'</th>';
|
||||
tmp+='<th data-field="Preview" data-sortable="true">'+lang.Preview+'</th>';
|
||||
tmp+='<th data-field="Watch" data-sortable="true">'+lang.Watch+'</th>';
|
||||
tmp+='<th data-field="Download" data-sortable="true">'+lang.Download+'</th>';
|
||||
tmp+='<th class="permission_video_delete" data-field="Delete" data-sortable="true">'+lang.Delete+'</th>';
|
||||
if(showThumbnail)tmp+='<th>'+lang.Thumbnail+'</th>';
|
||||
tmp+='<th class="table-header-sorter" data-field="Closed">'+lang.Closed+'<i class="fa fa-sort"></i></th>';
|
||||
tmp+='<th class="table-header-sorter" data-field="Ended">'+lang.Ended+'<i class="fa fa-sort"></i></th>';
|
||||
tmp+='<th class="table-header-sorter" data-field="Started">'+lang.Started+'<i class="fa fa-sort"></i></th>';
|
||||
tmp+='<th class="table-header-sorter" data-field="Monitor">'+lang.Monitor+'<i class="fa fa-sort"></i></th>';
|
||||
tmp+='<th class="table-header-sorter" data-field="Filename">'+lang.Filename+'<i class="fa fa-sort"></i></th>';
|
||||
tmp+='<th class="table-header-sorter" data-field="Size">'+lang['Size (mb)']+'<i class="fa fa-sort"></i></th>';
|
||||
tmp+='<th>'+lang.Preview+'</th>';
|
||||
tmp+='<th>'+lang.Watch+'</th>';
|
||||
tmp+='<th>'+lang.Download+'</th>';
|
||||
tmp+='<th class="permission_video_delete">'+lang.Delete+'</th>';
|
||||
// tmp+='<th class="permission_video_delete" data-field="Fix" data-sortable="true">'+lang.Fix+'</th>';
|
||||
tmp+='</tr>';
|
||||
tmp+='</thead>';
|
||||
|
@ -588,10 +601,19 @@ $(document).ready(function(e){
|
|||
v.mon=$.ccio.mon[v.ke+v.mid+user.auth_token];
|
||||
v.start=v.time;
|
||||
// v.filename=$.ccio.init('tf',v.time)+'.'+v.ext;
|
||||
tmp+='<tr data-ke="'+v.ke+'" data-status="'+v.status+'" data-mid="'+v.mid+'" data-file="'+v.filename+'" data-auth="'+v.mon.user.auth_token+'">';
|
||||
const sortData = {
|
||||
_no: n,
|
||||
Closed: $.ccio.timeObject(v.end).unix(),
|
||||
Ended: $.ccio.timeObject(v.end).unix(),
|
||||
Started: $.ccio.timeObject(v.time).unix(),
|
||||
Monitor: v.mon.name,
|
||||
Filename: v.filename,
|
||||
Size: v.size,
|
||||
};
|
||||
tmp+='<tr data-sort="' + JSON.stringify(sortData).replace(/"/g, """) + '" data-ke="'+v.ke+'" data-status="'+v.status+'" data-mid="'+v.mid+'" data-file="'+v.filename+'" data-auth="'+v.mon.user.auth_token+'">';
|
||||
tmp+='<td><div class="checkbox"><input id="'+v.ke+'_'+v.filename+'" name="'+v.filename+'" value="'+v.mid+'" type="checkbox"><label for="'+v.ke+'_'+v.filename+'"></label></div></td>';
|
||||
if(showThumbnail)tmp+='<td class="text-center"><img class="thumbnail"></td>';
|
||||
tmp+='<td><span class="livestamp" title="'+$.ccio.timeObject(v.end).format('YYYY-MM-DD HH:mm:ss')+'"></span></td>';
|
||||
tmp+='<td>'+$.ccio.timeObject(v.end).fromNow()+'</td>';
|
||||
tmp+='<td title="'+v.end+'">'+$.ccio.timeObject(v.end).format('h:mm:ss A, MMMM Do YYYY')+'</td>';
|
||||
tmp+='<td title="'+v.time+'">'+$.ccio.timeObject(v.time).format('h:mm:ss A, MMMM Do YYYY')+'</td>';
|
||||
tmp+='<td>'+v.mon.name+'</td>';
|
||||
|
@ -608,6 +630,10 @@ $(document).ready(function(e){
|
|||
tmp+='</tbody>';
|
||||
tmp+='</table>';
|
||||
e.b.html(tmp)
|
||||
e.b.css({
|
||||
overflow: 'auto',
|
||||
height: '100%',
|
||||
}).scrollTop(0);
|
||||
if(showThumbnail){
|
||||
var i = 0
|
||||
var getThumbnail = function(){
|
||||
|
@ -624,8 +650,6 @@ $(document).ready(function(e){
|
|||
}
|
||||
getThumbnail()
|
||||
}
|
||||
$.ccio.init('ls');
|
||||
$.vidview.e.find('table').bootstrapTable();
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
@ -796,6 +820,4 @@ $(document).ready(function(e){
|
|||
.on('dblclick','.stream-hud',function(){
|
||||
$(this).parents('[mid]').find('[monitor="fullscreen"]').click();
|
||||
})
|
||||
//.on('mousemove',".magnifyStream",$.ccio.magnifyStream)
|
||||
//.on('touchmove',".magnifyStream",$.ccio.magnifyStream);
|
||||
})
|
||||
|
|
|
@ -336,11 +336,11 @@ $.ccio.init=function(x,d,user,k){
|
|||
case'drawMatrices':
|
||||
d.height=d.stream.height()
|
||||
d.width=d.stream.width()
|
||||
if(d.monitorDetails.detector_scale_x===''){d.monitorDetails.detector_scale_x=320}
|
||||
if(d.monitorDetails.detector_scale_y===''){d.monitorDetails.detector_scale_y=240}
|
||||
if(!d.details.imgWidth && d.monitorDetails.detector_scale_x===''){d.monitorDetails.detector_scale_x=320}
|
||||
if(!d.details.imgHeight && d.monitorDetails.detector_scale_y===''){d.monitorDetails.detector_scale_y=240}
|
||||
|
||||
d.widthRatio=d.width/d.monitorDetails.detector_scale_x
|
||||
d.heightRatio=d.height/d.monitorDetails.detector_scale_y
|
||||
d.widthRatio=d.width/d.details.imgWidth || d.monitorDetails.detector_scale_x
|
||||
d.heightRatio=d.height/d.details.imgHeight || d.monitorDetails.detector_scale_y
|
||||
|
||||
d.streamObjects.find('.stream-detected-object[name="'+d.details.name+'"]').remove()
|
||||
d.tmp=''
|
||||
|
|
320
web/libs/js/dash2.monitorStates.js
Normal file
320
web/libs/js/dash2.monitorStates.js
Normal file
|
@ -0,0 +1,320 @@
|
|||
$(document).ready(function(){
|
||||
$.monitorStates = {
|
||||
e: $('#monitorStates'),
|
||||
selector: $('#monitorStatesSelector'),
|
||||
monitors: $('#monitorStatesMonitors'),
|
||||
loaded: {}
|
||||
}
|
||||
$.monitorStates.f = $.monitorStates.e.find('form')
|
||||
$.monitorStates.loadPresets = function(callback){
|
||||
$.get($.ccio.init('location',$user) + $user.auth_token + '/monitorStates/' + $user.ke,function(d){
|
||||
var html = ''
|
||||
$.each(d.presets,function(n,v){
|
||||
$.monitorStates.loaded[v.name] = v
|
||||
html += '<option value="' + v.name + '">' + v.name + '</option>'
|
||||
})
|
||||
$.monitorStates.selector.find('optgroup').html(html)
|
||||
if(callback)callback()
|
||||
})
|
||||
}
|
||||
$.monitorStates.e.on('shown.bs.modal', function (e) {
|
||||
if($.monitorStates.selector.val() === '')$.monitorStates.loadPresets()
|
||||
})
|
||||
var buildOptions = function(field,possiblities,fieldData){
|
||||
if(!field)console.error('field',field)
|
||||
var fieldElement = ''
|
||||
possiblities.forEach(function(option){
|
||||
if(option.optgroup){
|
||||
fieldElement += '<optgroup label="' + option.name + '">'
|
||||
fieldElement += buildOptions(field,option.optgroup,fieldData)
|
||||
fieldElement += '</optgroup>'
|
||||
}else{
|
||||
var selected = ''
|
||||
if(option.value === fieldData || option.value === field.default){
|
||||
selected = 'selected'
|
||||
}
|
||||
fieldElement += '<option value="' + option.value + '" ' + selected + '>' + option.name + '</option>'
|
||||
}
|
||||
})
|
||||
return fieldElement
|
||||
}
|
||||
var drawBlock = function(monitorSettings,preloadedData){
|
||||
var html = ''
|
||||
var headerTitle = lang[monitorSettings.name]
|
||||
// if(monitorSettings.evaluation && !eval(monitorSettings.evaluation)){
|
||||
// return
|
||||
// }
|
||||
if(monitorSettings.blocks){
|
||||
monitorSettings.blocks.forEach(function(settingsBlock){
|
||||
html += drawBlock(settingsBlock)
|
||||
})
|
||||
}
|
||||
if(monitorSettings.info){
|
||||
monitorSettings.info.forEach(function(field){
|
||||
if(field.isFormGroupGroup === true){
|
||||
html += drawBlock(field)
|
||||
}else{
|
||||
if(field.notForSubAccount === true){
|
||||
var notForSubAccount = '!details.sub'
|
||||
if(!field.evaluation){
|
||||
field.evaluation = notForSubAccount
|
||||
}else{
|
||||
field.evaluation += ' && ' + notForSubAccount
|
||||
}
|
||||
}
|
||||
if(!field.name || field.evaluation && !eval(field.evaluation)){
|
||||
return
|
||||
}
|
||||
var attributes = []
|
||||
var listGroupClass = []
|
||||
var monitorRowFieldClass = []
|
||||
if(preloadedData){
|
||||
var isDetail = false
|
||||
var name = field.name
|
||||
var fieldData
|
||||
if(name.indexOf('detail=') > -1){
|
||||
isDetail = true
|
||||
name = name.replace('detail=','')
|
||||
if(preloadedData.details)fieldData = preloadedData.details[name]
|
||||
}else{
|
||||
fieldData = preloadedData[name]
|
||||
}
|
||||
if(fieldData){
|
||||
listGroupClass.push('active')
|
||||
if(fieldType !== 'select'){
|
||||
attributes.push(`value="${fieldData}"`)
|
||||
}
|
||||
}else{
|
||||
monitorRowFieldClass.push('display:none')
|
||||
}
|
||||
}else{
|
||||
monitorRowFieldClass.push('display:none')
|
||||
}
|
||||
if(field.placeholder || field.default){
|
||||
attributes.push(`placeholder="${field.placeholder || field.default}"`)
|
||||
}else if(field.example){
|
||||
attributes.push(`placeholder="Example : ${field.example}"`)
|
||||
}
|
||||
var possiblities = field.possible || []
|
||||
var fieldType = field.fieldType || 'text'
|
||||
var fieldElement = ''
|
||||
switch(fieldType){
|
||||
case'number':
|
||||
if(field.numberMin){
|
||||
attributes.push(`min="${field.numberMin}"`)
|
||||
}
|
||||
if(field.numberMax){
|
||||
attributes.push(`max="${field.numberMax}"`)
|
||||
}
|
||||
fieldElement = '<div><input type="number" class="form-control" ' + attributes.join(' ') + '></div>'
|
||||
break;
|
||||
case'password':
|
||||
fieldElement = '<div><input type="password" class="form-control" ' + attributes.join(' ') + '></div>'
|
||||
break;
|
||||
case'text':
|
||||
fieldElement = `<div><input class="form-control" ${attributes.join(' ')}></div>`
|
||||
break;
|
||||
case'textarea':
|
||||
fieldElement = '<div><textarea class="form-control" ' + attributes.join(' ') + '></textarea></div>'
|
||||
break;
|
||||
case'select':
|
||||
fieldElement = '<div><select class="form-control" ' + attributes.join(' ') + '>'
|
||||
fieldElement += buildOptions(field,possiblities,fieldData)
|
||||
fieldElement += '</select></div>'
|
||||
break;
|
||||
}
|
||||
if(fieldType === 'ul' || fieldType === 'div' || fieldType === 'btn' || field.name === 'mid'){
|
||||
|
||||
}else{
|
||||
if(headerTitle){
|
||||
html += `<div class="list-group-item ${listGroupClass.join(' ')}" data-name="${field.name}" data-value="${field.value || ""}">
|
||||
<h4>${headerTitle} : ${field.field}</h4>
|
||||
<div><small>${field.description}</small></div>
|
||||
<div class="state-monitor-row-fields-field mt-4" style="${monitorRowFieldClass.join(' ')}">${fieldElement}</div>
|
||||
</div>`
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return html
|
||||
}
|
||||
$.monitorStates.drawMonitor = function(preloadedData){
|
||||
var MonitorSettings = $.ccio.definitions['Monitor Settings']
|
||||
var html = ''
|
||||
console.log(preloadedData)
|
||||
Object.keys(MonitorSettings.blocks).forEach(function(blockKey){
|
||||
var block = MonitorSettings.blocks[blockKey]
|
||||
html += drawBlock(block,preloadedData)
|
||||
})
|
||||
var monitorSelect = `<select class="state-monitor-row-select form-control">`
|
||||
$.each($.ccio.mon,function(n,monitor){
|
||||
monitorSelect += `<option value="${monitor.mid}">${monitor.name} (${monitor.mid})</option>`
|
||||
})
|
||||
monitorSelect += `</select>`
|
||||
var fullHtml = `<div class="form-group state-monitor-row">
|
||||
<div class="input-group state-monitor-row-select-container">
|
||||
${monitorSelect}
|
||||
<div class="input-group-btn">
|
||||
<a class="btn btn-danger delete-monitor">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-group state-monitor-row-fields-container" style="height:300px;overflow: auto">
|
||||
${html}
|
||||
</div>
|
||||
</div>`
|
||||
return fullHtml
|
||||
}
|
||||
$.monitorStates.e.on('click','.add-monitor',function(e){
|
||||
var el = $(this)
|
||||
var html = $.monitorStates.drawMonitor()
|
||||
$.monitorStates.monitors.append(html)
|
||||
})
|
||||
$.monitorStates.e.on('click','.state-monitor-row-fields-container .list-group-item',function(e){
|
||||
var el = $(this)
|
||||
var listGroupParent = el.parents('.list-group')
|
||||
var fieldContainer = el.find('.state-monitor-row-fields-field')
|
||||
var name = el.attr('data-name')
|
||||
var value = el.attr('data-value')
|
||||
if(el.hasClass('active')){
|
||||
el.removeClass('active')
|
||||
fieldContainer.hide()
|
||||
}else{
|
||||
el.addClass('active')
|
||||
fieldContainer.show()
|
||||
}
|
||||
})
|
||||
$.monitorStates.e.on('click','.state-monitor-row-fields-container .form-control',function(e){
|
||||
e.preventDefault()
|
||||
return false
|
||||
})
|
||||
$.monitorStates.e.on('change','.json',function(e){
|
||||
var el = $(this)
|
||||
var val = el.val()
|
||||
try{
|
||||
el.css('border-color','green')
|
||||
var parsed = JSON.parse(val)
|
||||
el.val(JSON.stringify(parsed,null,3))
|
||||
}catch(err){
|
||||
el.css('border-color','red')
|
||||
return $.ccio.init('note',{title:lang['Invalid JSON'],text:lang.InvalidJSONText,type:'error'})
|
||||
}
|
||||
})
|
||||
$.monitorStates.e.on('click','.delete',function(e){
|
||||
$.confirm.e.modal('show');
|
||||
$.confirm.title.text(lang['Delete Monitor States Preset']);
|
||||
$.confirm.body.html(lang.deleteMonitorStateText1);
|
||||
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||
var form = $.monitorStates.f.serializeObject()
|
||||
$.post($.ccio.init('location',$user) + $user.auth_token + '/monitorStates/' + $user.ke + '/' + form.name + '/delete',function(d){
|
||||
$.ccio.log(d)
|
||||
if(d.ok === true){
|
||||
$.monitorStates.loadPresets()
|
||||
$.ccio.init('note',{title:lang.Success,text:d.msg,type:'success'})
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
$.monitorStates.e.on('click','.delete-monitor',function(e){
|
||||
var el = $(this).parents('.state-monitor-row')
|
||||
$.confirm.e.modal('show');
|
||||
$.confirm.title.text(lang['Delete Monitor State']);
|
||||
$.confirm.body.html(lang.deleteMonitorStateText2)
|
||||
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||
el.remove()
|
||||
})
|
||||
})
|
||||
$.monitorStates.selector.change(function(e){
|
||||
var selected = $(this).val()
|
||||
var loaded = $.monitorStates.loaded[selected]
|
||||
var namespace = $.monitorStates.e.find('[name="name"]')
|
||||
var deleteButton = $.monitorStates.e.find('.delete')
|
||||
if(loaded){
|
||||
namespace.val(loaded.name)
|
||||
var html = ''
|
||||
$.each(loaded.details.monitors,function(n,v){
|
||||
console.log(v)
|
||||
html += $.monitorStates.drawMonitor(v)
|
||||
})
|
||||
$.monitorStates.monitors.html(html)
|
||||
deleteButton.show()
|
||||
}else{
|
||||
namespace.val('')
|
||||
$.monitorStates.monitors.empty()
|
||||
deleteButton.hide()
|
||||
}
|
||||
})
|
||||
$.monitorStates.getFormValuesFromJson = function(){
|
||||
var rows = $.monitorStates.monitors.find('.state-monitor-row')
|
||||
var monitors = []
|
||||
rows.each(function(n,v){
|
||||
var el = $(v)
|
||||
var textarea = el.find('textarea')
|
||||
try{
|
||||
var json = JSON.parse(el.find('.json').val())
|
||||
textarea.css('border-color','green')
|
||||
if(json.mid)monitors.push(json)
|
||||
}catch(err){
|
||||
textarea.css('border-color','red')
|
||||
$.ccio.init('note',{title:lang['Invalid JSON'],text:lang.InvalidJSONText,type:'error'})
|
||||
}
|
||||
})
|
||||
return monitors
|
||||
}
|
||||
$.monitorStates.getFormValues = function(){
|
||||
var rows = $.monitorStates.monitors.find('.state-monitor-row')
|
||||
var monitors = []
|
||||
rows.each(function(n,v){
|
||||
var monitorJson = {
|
||||
details: {}
|
||||
}
|
||||
var el = $(v)
|
||||
var fieldsSelcted = el.find('.list-group-item.active')
|
||||
monitorJson.mid = el.find('.state-monitor-row-select').val()
|
||||
fieldsSelcted.each(function(nn,element){
|
||||
var field = $(element)
|
||||
var name = field.attr('data-name')
|
||||
var value = field.find('.form-control').val()
|
||||
var isDetail = false
|
||||
if(name.indexOf('detail=') > -1){
|
||||
isDetail = true
|
||||
name = name.replace('detail=','')
|
||||
monitorJson.details[name] = value
|
||||
}else{
|
||||
monitorJson[name] = value
|
||||
}
|
||||
})
|
||||
if(Object.keys(monitorJson).length > 2 || Object.keys(monitorJson.details).length > 2){
|
||||
monitors.push(monitorJson)
|
||||
}
|
||||
})
|
||||
return monitors
|
||||
}
|
||||
$.monitorStates.f.submit(function(e){
|
||||
e.preventDefault()
|
||||
var el = $(this)
|
||||
var form = el.serializeObject()
|
||||
var monitors = $.monitorStates.getFormValues()
|
||||
if(form.name === ''){
|
||||
return $.ccio.init('note',{title:lang['Invalid Data'],text:lang['Name cannot be empty.'],type:'error'})
|
||||
}
|
||||
if(monitors.length === 0){
|
||||
return $.ccio.init('note',{title:lang['Invalid Data'],text:lang['Must be atleast one row'],type:'error'})
|
||||
}
|
||||
var data = {
|
||||
monitors: monitors
|
||||
}
|
||||
$.post($.ccio.init('location',$user) + $user.auth_token + '/monitorStates/' + $user.ke + '/' + form.name + '/insert',{data:data},function(d){
|
||||
$.ccio.log(d)
|
||||
if(d.ok === true){
|
||||
$.monitorStates.loadPresets(function(){
|
||||
$.monitorStates.selector.val(form.name)
|
||||
})
|
||||
$.ccio.init('note',{title:lang.Success,text:d.msg,type:'success'})
|
||||
}
|
||||
})
|
||||
return false;
|
||||
})
|
||||
})
|
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,17 @@
|
|||
$(document).ready(function(e){
|
||||
var getUrlPieces = function(url){
|
||||
var el = document.createElement('a');
|
||||
el.href = url
|
||||
return el
|
||||
// el.host // www.somedomain.com (includes port if there is one[1])
|
||||
// el.hostname // www.somedomain.com
|
||||
// el.hash // #top
|
||||
// el.href // http://www.somedomain.com/account/search?filter=a#top
|
||||
// el.pathname // /account/search
|
||||
// el.port // (port if there is one[1])
|
||||
// el.protocol // http:
|
||||
// el.search // ?filter=a
|
||||
}
|
||||
//multi monitor manager
|
||||
$.multimon={e:$('#multi_mon')};
|
||||
$.multimon.table=$.multimon.e.find('.tableData tbody');
|
||||
|
@ -17,7 +30,7 @@ $.multimon.e.find('.import_config').click(function(){
|
|||
var e={};e.e=$(this);e.mid=e.e.parents('[mid]').attr('mid');
|
||||
$.confirm.e.modal('show');
|
||||
$.confirm.title.text(lang['Import Monitor Configuration'])
|
||||
e.html=lang.ImportMultiMonitorConfigurationText+'<div style="margin-top:15px"><div class="form-group"><textarea placeholder="'+lang['Paste JSON here.']+'" class="form-control"></textarea></div><label class="upload_file btn btn-primary btn-block"> Upload File <input class="upload" type=file name="files[]"></label></div>';
|
||||
e.html=lang.ImportMultiMonitorConfigurationText+'<div style="margin-top:15px"><div class="form-group"><textarea placeholder="'+lang['Paste JSON here.']+'" class="form-control"></textarea></div><label class="upload_file btn btn-primary btn-block">'+lang['Upload File']+'<input class="upload" type=file name="files[]"></label></div>';
|
||||
$.confirm.body.html(e.html)
|
||||
$.confirm.e.find('.upload').change(function(e){
|
||||
var files = e.target.files; // FileList object
|
||||
|
@ -28,7 +41,7 @@ $.multimon.e.find('.import_config').click(function(){
|
|||
}
|
||||
reader.readAsText(f);
|
||||
});
|
||||
$.confirm.click({title:'Import',class:'btn-primary'},function(){
|
||||
$.confirm.click({title:lang['Import'],class:'btn-primary'},function(){
|
||||
// setTimeout(function(){
|
||||
// $.confirm.e.modal('show');
|
||||
// },1000)
|
||||
|
@ -67,7 +80,8 @@ $.multimon.e.find('.import_config').click(function(){
|
|||
console.log(newMon)
|
||||
return newMon
|
||||
}
|
||||
parsedData=JSON.parse($.confirm.e.find('textarea').val());
|
||||
var textFieldData = $.confirm.e.find('textarea').val()
|
||||
var parsedData = JSON.parse(textFieldData)
|
||||
//zoneminder one monitor
|
||||
if(parsedData.monitor){
|
||||
$.aM.import({
|
||||
|
@ -95,8 +109,45 @@ $.multimon.e.find('.import_config').click(function(){
|
|||
})
|
||||
}
|
||||
}catch(err){
|
||||
$.ccio.log(err)
|
||||
$.ccio.init('note',{title:lang['Invalid JSON'],text:lang.InvalidJSONText,type:'error'})
|
||||
//#EXTM3U
|
||||
if(textFieldData.indexOf('#EXTM3U') > -1 && textFieldData.indexOf('{"') === -1){
|
||||
var m3u8List = textFieldData.replace('#EXTM3U','').trim().split('\n')
|
||||
var parsedList = {}
|
||||
var currentName
|
||||
m3u8List.forEach(function(line){
|
||||
if(line.indexOf('#EXTINF:-1,') > -1){
|
||||
currentName = line.replace('#EXTINF:-1,','').trim()
|
||||
}else{
|
||||
parsedList[currentName] = line.trim()
|
||||
}
|
||||
})
|
||||
$.each(parsedList,function(name,url){
|
||||
var link = getUrlPieces(url)
|
||||
var newMon = $.aM.generateDefaultMonitorSettings()
|
||||
newMon.details = JSON.parse(newMon.details)
|
||||
newMon.mid = 'HLS' + name.toLowerCase()
|
||||
newMon.name = name
|
||||
newMon.port = link.port
|
||||
newMon.host = link.hostname
|
||||
newMon.path = link.pathname
|
||||
newMon.details.tv_channel = '1'
|
||||
newMon.details.tv_channel_id = name
|
||||
newMon.details.auto_host_enable = '1'
|
||||
newMon.details.auto_host = url
|
||||
newMon.details.stream_quality = '1'
|
||||
newMon.details.stream_fps = ''
|
||||
newMon.details.stream_vcodec = 'libx264'
|
||||
newMon.details.stream_acodec = 'aac'
|
||||
newMon.details.stream_type = 'hls'
|
||||
newMon.details.hls_time = '10'
|
||||
newMon.type = 'mp4'
|
||||
newMon.details = JSON.stringify(newMon.details)
|
||||
postMonitor(newMon)
|
||||
})
|
||||
}else{
|
||||
$.ccio.log(err)
|
||||
$.ccio.init('note',{title:lang['Invalid JSON'],text:lang.InvalidJSONText,type:'error'})
|
||||
}
|
||||
}
|
||||
// });
|
||||
});
|
||||
|
@ -116,7 +167,7 @@ $.multimon.getSelectedMonitors = function(unclean){
|
|||
$.multimon.e.find('.delete').click(function(){
|
||||
var arr=$.multimon.getSelectedMonitors(true);
|
||||
if(arr.length===0){
|
||||
$.ccio.init('note',{title:'No Monitors Selected',text:'Select atleast one monitor to delete.',type:'error'});
|
||||
$.ccio.init('note',{title:lang['No Monitors Selected'],text:lang['Select atleast one monitor to delete'],type:'error'});
|
||||
return
|
||||
}
|
||||
$.confirm.e.modal('show');
|
||||
|
@ -125,7 +176,7 @@ $.multimon.e.find('.delete').click(function(){
|
|||
$.confirm.body.html(e.html)
|
||||
$.confirm.click([
|
||||
{
|
||||
title:'Delete Monitors',
|
||||
title:lang['Delete']+' '+lang['Monitors'],
|
||||
class:'btn-danger',
|
||||
callback:function(){
|
||||
$.each(arr,function(n,v){
|
||||
|
@ -136,7 +187,7 @@ $.multimon.e.find('.delete').click(function(){
|
|||
}
|
||||
},
|
||||
{
|
||||
title:'Delete Monitors and Files',
|
||||
title:lang['Delete Monitors and Files'],
|
||||
class:'btn-danger',
|
||||
callback:function(){
|
||||
$.each(arr,function(n,v){
|
||||
|
@ -152,7 +203,7 @@ $.multimon.e.find('.delete').click(function(){
|
|||
// var arr=$.multimon.getSelectedMonitors();
|
||||
// var arrObject={}
|
||||
// if(arr.length===0){
|
||||
// $.ccio.init('note',{title:'No Monitors Selected',text:'Select atleast one monitor to delete.',type:'error'});
|
||||
// $.ccio.init('note',{title:lang['No Monitors Selected'],text:lang['Select atleast one monitor to delete'],type:'error'});
|
||||
// return
|
||||
// }
|
||||
// $.multimonedit.selectedList = arr;
|
||||
|
@ -162,7 +213,7 @@ $.multimon.e.find('.save_config').click(function(){
|
|||
var e={};e.e=$(this);
|
||||
var arr=$.multimon.getSelectedMonitors();
|
||||
if(arr.length===0){
|
||||
$.ccio.init('note',{title:'No Monitors Selected',text:'Select atleast one monitor to delete.',type:'error'});
|
||||
$.ccio.init('note',{title:lang['No Monitors Selected'],text:lang['Select atleast one monitor to delete'],type:'error'});
|
||||
return
|
||||
}
|
||||
e.dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(arr));
|
||||
|
|
616
web/libs/js/dash2.powerVideo2.js
Normal file
616
web/libs/js/dash2.powerVideo2.js
Normal file
|
@ -0,0 +1,616 @@
|
|||
$(document).ready(function(e){
|
||||
var powerVideoWindow = $('#powerVideo')
|
||||
var powerVideoMonitorsListElement = $('#powerVideoMonitorsList')
|
||||
var powerVideoMonitorViewsElement = $('#powerVideoMonitorViews')
|
||||
var powerVideoTimelineStripsContainer = $('#powerVideoTimelineStrips')
|
||||
var powerVideoDateRangeElement = $('#powerVideoDateRange')
|
||||
var powerVideoVideoLimitElement = $('#powerVideoVideoLimit')
|
||||
var powerVideoEventLimitElement = $('#powerVideoEventLimit')
|
||||
var powerVideoLoadedVideos = {}
|
||||
var powerVideoLoadedEvents = {}
|
||||
var powerVideoLoadedChartData = {}
|
||||
var loadedTableGroupIds = {}
|
||||
var eventsLabeledByTime = {}
|
||||
var monitorSlotPlaySpeeds = {}
|
||||
var currentlyPlayingVideos = {}
|
||||
var extenders = {
|
||||
onVideoPlayerTimeUpdateExtensions: [],
|
||||
onVideoPlayerTimeUpdate: function(extender){
|
||||
extenders.onVideoPlayerTimeUpdateExtensions.push(extender)
|
||||
},
|
||||
onVideoPlayerCreateExtensions: [],
|
||||
onVideoPlayerCreate: function(extender){
|
||||
extenders.onVideoPlayerCreateExtensions.push(extender)
|
||||
},
|
||||
}
|
||||
var activeTimeline = null
|
||||
// fix utc/localtime translation (use timelapseJpeg as guide, it works as expected) >
|
||||
powerVideoDateRangeElement.daterangepicker({
|
||||
startDate:$.ccio.timeObject().subtract(moment.duration("24:00:00")),
|
||||
endDate:$.ccio.timeObject().add(moment.duration("24:00:00")),
|
||||
timePicker: true,
|
||||
timePicker24Hour: true,
|
||||
timePickerSeconds: true,
|
||||
timePickerIncrement: 30,
|
||||
locale: {
|
||||
format: 'MM/DD/YYYY h:mm A'
|
||||
}
|
||||
},function(start, end, label){
|
||||
// $.pwrvid.drawTimeline()
|
||||
powerVideoDateRangeElement.focus()
|
||||
getSelectedMonitors().each(function(n,activeElement){
|
||||
var monitorId = $(activeElement).attr('data-monitor')
|
||||
requestTableData(monitorId)
|
||||
})
|
||||
});
|
||||
// fix utc/localtime translation (use timelapseJpeg as guide, it works as expected) />
|
||||
var loadVideosToTimeLineMemory = function(monitorId,videos,events){
|
||||
powerVideoLoadedVideos[monitorId] = videos
|
||||
powerVideoLoadedEvents[monitorId] = events
|
||||
}
|
||||
var drawMonitorsList = function(){
|
||||
var html = ''
|
||||
$.each($.ccio.mon,function(n,monitor){
|
||||
html += `<div class="list-group-item" data-monitor="${monitor.mid}">${monitor.name}</div>`
|
||||
})
|
||||
powerVideoMonitorsListElement.html(html)
|
||||
}
|
||||
var requestTableData = function(monitorId,user){
|
||||
if(!user)user = $user
|
||||
var dateData = powerVideoDateRangeElement.data('daterangepicker')
|
||||
$.ccio.cx({
|
||||
f: 'monitor',
|
||||
ff: 'get',
|
||||
fff: 'videos&events',
|
||||
videoLimit: parseInt(powerVideoVideoLimitElement.val()) || 0,
|
||||
eventLimit: parseInt(powerVideoEventLimitElement.val()) || 500,
|
||||
startDate: dateData.startDate.utc().format('YYYY-MM-DDTHH:mm:ss'),
|
||||
endDate: dateData.endDate.utc().format('YYYY-MM-DDTHH:mm:ss'),
|
||||
ke: user.ke,
|
||||
mid: monitorId
|
||||
})
|
||||
}
|
||||
var unloadTableData = function(monitorId,user){
|
||||
if(!user)user = $user
|
||||
delete(powerVideoLoadedVideos[monitorId])
|
||||
delete(powerVideoLoadedEvents[monitorId])
|
||||
delete(loadedTableGroupIds[monitorId])
|
||||
delete(loadedTableGroupIds[monitorId + '_events'])
|
||||
powerVideoMonitorViewsElement.find(`.videoPlayer[data-mid="${monitorId}"]`).remove()
|
||||
drawLoadedTableData()
|
||||
}
|
||||
var checkEventsAgainstVideo = function(video,events){
|
||||
var videoStartTime = new Date(video.time)
|
||||
var videoEndTime = new Date(video.end)
|
||||
var eventsToCheck = events
|
||||
video.detections = {}
|
||||
var newSetOfEventsWithoutChecked = {}
|
||||
$.each(eventsToCheck,function(n,event){
|
||||
var eventTime = new Date(event.time)
|
||||
var seekPosition = (eventTime - videoStartTime) / 1000
|
||||
if (videoStartTime <= eventTime && eventTime <= videoEndTime) {
|
||||
if(!video.details.confidence)video.details.confidence = 0
|
||||
video.detections[seekPosition] = event
|
||||
eventsLabeledByTime[video.mid][video.time][seekPosition] = event
|
||||
}else{
|
||||
newSetOfEventsWithoutChecked[n] = video
|
||||
}
|
||||
})
|
||||
eventsToCheck = newSetOfEventsWithoutChecked
|
||||
}
|
||||
var prepareVideosAndEventsForTable = function(monitorId,videos,events){
|
||||
var chartData = []
|
||||
eventsLabeledByTime[monitorId] = {}
|
||||
$.each(videos,function(n,video){
|
||||
eventsLabeledByTime[monitorId][video.time] = {}
|
||||
if(videos[n - 1])video.videoAfter = videos[n - 1]
|
||||
if(videos[n + 1])video.videoBefore = videos[n + 1]
|
||||
checkEventsAgainstVideo(video,events)
|
||||
chartData.push({
|
||||
group: loadedTableGroupIds[monitorId],
|
||||
content: `<div timeline-video-file="${video.mid}${video.time}">
|
||||
${video.time}
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-danger" role="progressbar" style="width:0%;"><span></span></div>
|
||||
</div>
|
||||
</div>`,
|
||||
start: video.time,
|
||||
end: video.end,
|
||||
videoInfo: video
|
||||
})
|
||||
})
|
||||
$.each(events,function(n,event){
|
||||
var eventReason = event.details.reason.toUpperCase()
|
||||
var eventSlotTag = eventReason
|
||||
if(eventReason === 'OBJECT' && event.details.matrices[0]){
|
||||
eventSlotTag = []
|
||||
event.details.matrices.forEach(function(matrix){
|
||||
eventSlotTag.push(matrix.tag)
|
||||
})
|
||||
eventSlotTag = eventSlotTag.join(', ')
|
||||
}
|
||||
chartData.push({
|
||||
group: loadedTableGroupIds[monitorId + '_events'],
|
||||
content: `<div timeline-event="${event.time}">${eventSlotTag}</div>`,
|
||||
start: event.time,
|
||||
eventInfo: event
|
||||
})
|
||||
})
|
||||
return chartData
|
||||
}
|
||||
var getAllChartDataForLoadedVideos = function(){
|
||||
var chartData = []
|
||||
Object.keys(powerVideoLoadedVideos).forEach(function(monitorId,n){
|
||||
var videos = powerVideoLoadedVideos[monitorId]
|
||||
var events = powerVideoLoadedEvents[monitorId]
|
||||
var parsedVideos = prepareVideosAndEventsForTable(monitorId,videos,events)
|
||||
powerVideoLoadedChartData[monitorId] = parsedVideos
|
||||
chartData = chartData.concat(parsedVideos)
|
||||
})
|
||||
return chartData
|
||||
}
|
||||
var visuallySelectItemInRow = function(video){
|
||||
powerVideoTimelineStripsContainer.find(`[timeline-video-file="${video.mid}${video.time}"]`).parents('.vis-item').addClass('vis-selected')
|
||||
}
|
||||
var visuallyDeselectItemInRow = function(video){
|
||||
powerVideoTimelineStripsContainer.find(`[timeline-video-file="${video.mid}${video.time}"]`).parents('.vis-item').removeClass('vis-selected')
|
||||
}
|
||||
var drawTableTimeout = null
|
||||
var drawLoadedTableData = function(){
|
||||
// destroy old
|
||||
try{
|
||||
if(activeTimeline && activeTimeline.destroy){
|
||||
activeTimeline.destroy()
|
||||
}
|
||||
}catch(err){
|
||||
|
||||
}
|
||||
//
|
||||
powerVideoTimelineStripsContainer.html(`<div class="loading"><i class="fa fa-spinner fa-pulse"></i><div class="epic-text">${lang['Please Wait...']}</div></div>`)
|
||||
clearTimeout(drawTableTimeout)
|
||||
drawTableTimeout = setTimeout(function(){
|
||||
var container = powerVideoTimelineStripsContainer[0]
|
||||
var groupsDataSet = new vis.DataSet()
|
||||
var groups = []
|
||||
var groupId = 1
|
||||
Object.keys(powerVideoLoadedVideos).forEach(function(monitorId,n){
|
||||
groups.push({
|
||||
id: groupId,
|
||||
content: monitorId
|
||||
})
|
||||
groupId += 1
|
||||
groups.push({
|
||||
id: groupId,
|
||||
content: lang.Events
|
||||
})
|
||||
groupId += 1
|
||||
loadedTableGroupIds[monitorId] = groupId - 2
|
||||
loadedTableGroupIds[monitorId + '_events'] = groupId - 1
|
||||
})
|
||||
groupsDataSet.add(groups)
|
||||
var chartData = getAllChartDataForLoadedVideos()
|
||||
if(chartData.length > 0){
|
||||
var items = new vis.DataSet(chartData)
|
||||
var options = {
|
||||
selectable: false,
|
||||
stack: false,
|
||||
showCurrentTime: false,
|
||||
}
|
||||
// Create a Timeline
|
||||
var timeline = new vis.Timeline(container, items, groupsDataSet, options)
|
||||
powerVideoTimelineStripsContainer.find('.loading').remove()
|
||||
var timeChanging = false
|
||||
timeline.on('rangechange', function(properties){
|
||||
timeChanging = true
|
||||
})
|
||||
timeline.on('rangechanged', function(properties){
|
||||
setTimeout(function(){
|
||||
timeChanging = false
|
||||
},300)
|
||||
})
|
||||
timeline.on('click', function(properties){
|
||||
if(!timeChanging){
|
||||
var selectedTime = properties.time
|
||||
var videosAtSameTime = findAllVideosAtTime(selectedTime)
|
||||
powerVideoTimelineStripsContainer.find('.vis-item').removeClass('vis-selected')
|
||||
$.each(videosAtSameTime,function(monitorId,videos){
|
||||
var selectedVideo = videos[0]
|
||||
if(selectedVideo){
|
||||
loadVideoIntoMonitorSlot(selectedVideo,selectedTime)
|
||||
visuallySelectItemInRow(selectedVideo)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
activeTimeline = timeline
|
||||
}else{
|
||||
powerVideoTimelineStripsContainer.html(`<div class="loading"><i class="fa fa-exclamation-circle"></i><div class="epic-text">${lang['No Data']}</div></div>`)
|
||||
}
|
||||
},1000)
|
||||
}
|
||||
var drawMatrices = function(event,options){
|
||||
var streamObjectsContainer = options.streamObjectsContainer
|
||||
var height = options.height
|
||||
var width = options.width
|
||||
var monitorId = options.mid
|
||||
var widthRatio = width / event.details.imgWidth
|
||||
var heightRatio = height / event.details.imgHeight
|
||||
|
||||
streamObjectsContainer.find('.stream-detected-object[name="'+event.details.name+'"]').remove()
|
||||
var html = ''
|
||||
$.each(event.details.matrices,function(n,matrix){
|
||||
html += `<div class="stream-detected-object" name="${event.details.name}" style="height:${heightRatio * matrix.height}px;width:${widthRatio * matrix.width}px;top:${heightRatio * matrix.y}px;left:${widthRatio * matrix.x}px;">`
|
||||
if(matrix.tag)html += `<span class="tag">${matrix.tag}</span>`
|
||||
html += '</div>'
|
||||
})
|
||||
streamObjectsContainer.append(html)
|
||||
}
|
||||
var attachEventsToVideoActiveElement = function(video){
|
||||
var monitorId = video.mid
|
||||
var videoPlayerContainer = powerVideoMonitorViewsElement.find(`.videoPlayer[data-mid=${monitorId}]`)
|
||||
var videoElement = videoPlayerContainer.find(`video.videoNow`)
|
||||
var streamObjectsContainer = videoPlayerContainer.find(`.videoPlayer-stream-objects`)
|
||||
var detectionInfoContainerMotion = videoPlayerContainer.find(`.videoPlayer-detection-info-motion`)
|
||||
var detectionInfoContainerObject = videoPlayerContainer.find(`.videoPlayer-detection-info-object`)
|
||||
var detectionInfoContainerRaw = videoPlayerContainer.find(`.videoPlayer-detection-info-raw`)
|
||||
var motionMeterProgressBar = videoPlayerContainer.find(`.videoPlayer-motion-meter .progress-bar`)
|
||||
var motionMeterProgressBarTextBox = videoPlayerContainer.find(`.videoPlayer-motion-meter .progress-bar span`)
|
||||
var videoCurrentTimeProgressBar = powerVideoTimelineStripsContainer.find(`[timeline-video-file="${video.mid}${video.time}"] .progress-bar`)[0]
|
||||
var preloadedNext = false
|
||||
var reinitializeStreamObjectsContainer = function(){
|
||||
height = videoElement.height()
|
||||
width = videoElement.width()
|
||||
}
|
||||
reinitializeStreamObjectsContainer()
|
||||
$(videoElement)
|
||||
.resize(reinitializeStreamObjectsContainer)
|
||||
// .off('loadeddata').on('loadeddata', function() {
|
||||
// reinitializeStreamObjectsContainer()
|
||||
// var allLoaded = true
|
||||
// getAllActiveVideosInSlots().each(function(n,videoElement){
|
||||
// if(!videoElement.readyState === 4)allLoaded = false
|
||||
// })
|
||||
// setTimeout(function(){
|
||||
// if(allLoaded){
|
||||
// playAllSlots()
|
||||
// }
|
||||
// },1500)
|
||||
// })
|
||||
// .off("pause").on("pause",function(){
|
||||
// console.log(monitorId,'pause')
|
||||
// })
|
||||
// .off("play").on("play",function(){
|
||||
// console.log(monitorId,'play')
|
||||
// })
|
||||
.off("timeupdate").on("timeupdate",function(){
|
||||
var event = eventsLabeledByTime[monitorId][video.time][parseInt(this.currentTime)]
|
||||
if(event){
|
||||
if(event.details.matrices){
|
||||
drawMatrices(event,{
|
||||
streamObjectsContainer: streamObjectsContainer,
|
||||
monitorId: monitorId,
|
||||
height: height,
|
||||
width: width,
|
||||
})
|
||||
detectionInfoContainerObject.html($.ccio.init('jsontoblock',event.details.matrices))
|
||||
}
|
||||
if(event.details.confidence){
|
||||
motionMeterProgressBar.css('width',event.details.confidence+'px')
|
||||
motionMeterProgressBarTextBox.text(event.details.confidence)
|
||||
var html = `<div>${lang['Region']} : ${event.details.name}</div>
|
||||
<div>${lang['Confidence']} : ${event.details.confidence}</div>
|
||||
<div>${lang['Plugin']} : ${event.details.plug}</div>`
|
||||
detectionInfoContainerMotion.html(html)
|
||||
// detectionInfoContainerRaw.html($.ccio.init('jsontoblock',{`${lang['Plug']}`:event.details.plug}))
|
||||
}
|
||||
}
|
||||
var currentTime = this.currentTime;
|
||||
var watchPoint = Math.floor((currentTime/this.duration) * 100)
|
||||
if(!preloadedNext && watchPoint >= 75){
|
||||
preloadedNext = true
|
||||
var videoAfter = videoPlayerContainer.find(`video.videoAfter`)[0]
|
||||
videoAfter.setAttribute('preload',true)
|
||||
}
|
||||
if(videoCurrentTimeProgressBar)videoCurrentTimeProgressBar.style.width = `${watchPoint}px`
|
||||
extenders.onVideoPlayerTimeUpdateExtensions.forEach(function(extender){
|
||||
extender(videoElement,watchPoint)
|
||||
})
|
||||
})
|
||||
var onEnded = function() {
|
||||
visuallyDeselectItemInRow(video)
|
||||
if(video.videoAfter){
|
||||
visuallySelectItemInRow(video.videoAfter)
|
||||
loadVideoIntoMonitorSlot(video.videoAfter)
|
||||
}
|
||||
}
|
||||
videoElement[0].onended = onEnded
|
||||
videoElement[0].onerror = onEnded
|
||||
}
|
||||
var dettachEventsToVideoActiveElement = function(monitorId){
|
||||
var videoElement = powerVideoMonitorViewsElement.find(`.videoPlayer[data-mid=${monitorId}] video.videoNow`)
|
||||
$(videoElement)
|
||||
// .off('loadeddata')
|
||||
.off("pause")
|
||||
.off("play")
|
||||
.off("timeupdate")
|
||||
}
|
||||
var findAllVideosAtTime = function(selectedTime){
|
||||
var time = new Date(selectedTime)
|
||||
var parsedVideos = {}
|
||||
$.each(powerVideoLoadedVideos,function(monitorId,videos){
|
||||
var videosFilteredByTime = videos.filter(function(video){
|
||||
return (
|
||||
(new Date(video.time)) <= time && time < (new Date(video.end))
|
||||
)
|
||||
});
|
||||
parsedVideos[monitorId] = videosFilteredByTime
|
||||
})
|
||||
return parsedVideos
|
||||
}
|
||||
var resetVisualDetectionDataForMonitorSlot = function(monitorId){
|
||||
var videoPlayerContainer = powerVideoMonitorViewsElement.find(`.videoPlayer[data-mid=${monitorId}]`)
|
||||
var streamObjectsContainer = videoPlayerContainer.find(`.videoPlayer-stream-objects`)
|
||||
var detectionInfoContainerObject = videoPlayerContainer.find(`.videoPlayer-detection-info-object`)
|
||||
var detectionInfoContainerMotion = videoPlayerContainer.find(`.videoPlayer-detection-info-motion`)
|
||||
var motionMeterProgressBar = videoPlayerContainer.find(`.videoPlayer-motion-meter .progress-bar`)
|
||||
var motionMeterProgressBarTextBox = videoPlayerContainer.find(`.videoPlayer-motion-meter .progress-bar span`)
|
||||
detectionInfoContainerObject.empty()
|
||||
detectionInfoContainerMotion.empty()
|
||||
streamObjectsContainer.empty()
|
||||
motionMeterProgressBar.css('width','0')
|
||||
motionMeterProgressBarTextBox.text('0')
|
||||
}
|
||||
var loadVideoIntoMonitorSlot = function(video,selectedTime){
|
||||
if(!video)return
|
||||
resetVisualDetectionDataForMonitorSlot(video.mid)
|
||||
currentlyPlayingVideos[video.mid] = video
|
||||
var timeToStartAt = selectedTime - new Date(video.time)
|
||||
var numberOfMonitors = Object.keys(powerVideoLoadedVideos).length
|
||||
// if(numberOfMonitors > 3)numberOfMonitors = 3 //start new row after 3
|
||||
if(numberOfMonitors == 1)numberOfMonitors = 2 //make single monitor not look like a doofus
|
||||
if(timeToStartAt < 0)timeToStartAt = 0
|
||||
var widthOfBlock = 100 / numberOfMonitors
|
||||
var videoContainer = powerVideoMonitorViewsElement.find(`.videoPlayer[data-mid=${video.mid}] .videoPlayer-buffers`)
|
||||
if(videoContainer.length === 0){
|
||||
if(!monitorSlotPlaySpeeds)monitorSlotPlaySpeeds[video.mid] = {}
|
||||
powerVideoMonitorViewsElement.append(`<div class="videoPlayer" style="width:${widthOfBlock}%" data-mid="${video.mid}">
|
||||
<div class="videoPlayer-detection-info">
|
||||
<div class="videoPlayer-detection-info-raw"></div>
|
||||
<h5 class="epic-text">${lang.Motion}</h5>
|
||||
<div class="videoPlayer-detection-info-motion"></div>
|
||||
<h5 class="epic-text">${lang.Matrices}</h5>
|
||||
<div class="videoPlayer-detection-info-object"></div>
|
||||
</div>
|
||||
<div class="videoPlayer-stream-objects"></div>
|
||||
<div class="videoPlayer-buffers"></div>
|
||||
<div class="videoPlayer-motion-meter progress" title="${lang['Motion Meter']}">
|
||||
<div class="progress-bar progress-bar-danger" role="progressbar" style="width:0%;"><span></span></div>
|
||||
</div>
|
||||
</div>`)
|
||||
videoContainer = powerVideoMonitorViewsElement.find(`.videoPlayer[data-mid=${video.mid}] .videoPlayer-buffers`)
|
||||
}else{
|
||||
powerVideoMonitorViewsElement.find('.videoPlayer').css('width',`${widthOfBlock}%`)
|
||||
}
|
||||
var videoCurrentNow = videoContainer.find('.videoNow')
|
||||
var videoCurrentAfter = videoContainer.find('.videoAfter')
|
||||
// var videoCurrentBefore = videoContainer.find('.videoBefore')
|
||||
dettachEventsToVideoActiveElement(video.mid)
|
||||
videoContainer.find('video').each(function(n,v){
|
||||
v.pause()
|
||||
})
|
||||
var videoIsSame = (video.href == videoCurrentNow.attr('video'))
|
||||
var videoIsAfter = (video.href == videoCurrentAfter.attr('video'))
|
||||
// var videoIsBefore = (video.href == videoCurrentBefore.attr('video'))
|
||||
var drawVideoHTML = function(position){
|
||||
var videoData
|
||||
var exisitingElement = videoContainer.find('.' + position)
|
||||
if(position){
|
||||
videoData = video[position]
|
||||
}else{
|
||||
position = 'videoNow'
|
||||
videoData = video
|
||||
}
|
||||
if(videoData){
|
||||
videoContainer.append('<video class="video_video '+position+'" video="'+videoData.href+'" playsinline><source src="'+videoData.href+'" type="video/'+videoData.ext+'"></video>')
|
||||
}
|
||||
}
|
||||
if(
|
||||
videoIsSame ||
|
||||
videoIsAfter
|
||||
// || videoIsBefore
|
||||
){
|
||||
switch(true){
|
||||
case videoIsSame:
|
||||
var videoNow = videoContainer.find('video.videoNow')[0]
|
||||
if(!videoNow.paused)videoNow.pause()
|
||||
videoNow.currentTime = timeToStartAt / 1000
|
||||
if(videoNow.paused)videoNow.play()
|
||||
return
|
||||
break;
|
||||
case videoIsAfter:
|
||||
// videoCurrentBefore.remove()
|
||||
videoCurrentNow.remove()
|
||||
videoCurrentAfter.removeClass('videoAfter').addClass('videoNow')
|
||||
// videoCurrentNow.removeClass('videoNow').addClass('videoBefore')
|
||||
drawVideoHTML('videoAfter')
|
||||
break;
|
||||
// case videoIsBefore:
|
||||
// videoCurrentAfter.remove()
|
||||
// videoCurrentBefore.removeClass('videoBefore').addClass('videoNow')
|
||||
// videoCurrentNow.removeClass('videoNow').addClass('videoAfter')
|
||||
// drawVideoHTML('videoBefore')
|
||||
// break;
|
||||
}
|
||||
}else{
|
||||
videoContainer.empty()
|
||||
drawVideoHTML()//videoNow
|
||||
// drawVideoHTML('videoBefore')
|
||||
drawVideoHTML('videoAfter')
|
||||
}
|
||||
var videoNow = videoContainer.find('video.videoNow')[0]
|
||||
attachEventsToVideoActiveElement(video)
|
||||
//
|
||||
videoNow.setAttribute('preload',true)
|
||||
videoNow.muted = true
|
||||
videoNow.playbackRate = monitorSlotPlaySpeeds[video.mid] || 1
|
||||
videoNow.currentTime = timeToStartAt / 1000
|
||||
videoNow.play()
|
||||
extenders.onVideoPlayerCreateExtensions.forEach(function(extender){
|
||||
extender(videoElement,watchPoint)
|
||||
})
|
||||
}
|
||||
var getSelectedMonitors = function(){
|
||||
return powerVideoMonitorsListElement.find('.active')
|
||||
}
|
||||
var getAllActiveVideosInSlots = function(){
|
||||
return powerVideoMonitorViewsElement.find('video.videoNow')
|
||||
}
|
||||
var pauseAllSlots = function(){
|
||||
getAllActiveVideosInSlots().each(function(n,video){
|
||||
if(!video.paused)video.pause()
|
||||
})
|
||||
}
|
||||
var toggleZoomAllSlots = function(){
|
||||
powerVideoMonitorViewsElement.find(`.videoPlayer`).each(function(n,videoContainer){
|
||||
var streamWindow = $(videoContainer)
|
||||
var monitorId = streamWindow.attr('data-mid')
|
||||
var enabled = streamWindow.attr('zoomEnabled')
|
||||
if(enabled === '1'){
|
||||
streamWindow
|
||||
.attr('zoomEnabled','0')
|
||||
.off('mouseover')
|
||||
.off('mouseout')
|
||||
.off('mousemove')
|
||||
.off('touchmove')
|
||||
.find('.zoomGlass').remove()
|
||||
}else{
|
||||
const magnifyStream = function(e){
|
||||
var videoElement = streamWindow.find('video.videoNow')
|
||||
console.log(videoElement[0].currentTime)
|
||||
$.ccio.magnifyStream({
|
||||
p: streamWindow,
|
||||
videoUrl: streamWindow.find('video.videoNow').find('source').attr('src'),
|
||||
setTime: videoElement[0].currentTime,
|
||||
monitor: $.ccio.mon[$user.ke + monitorId + $user.auth_token],
|
||||
targetForZoom: 'video.videoNow',
|
||||
magnifyOffsetElement: '.videoPlayer-buffers',
|
||||
zoomAmount: 1,
|
||||
auto: false,
|
||||
animate: false,
|
||||
pageX: e.pageX,
|
||||
pageY: e.pageY
|
||||
},$user)
|
||||
}
|
||||
streamWindow
|
||||
.attr('zoomEnabled','1')
|
||||
.on('mouseover', function(){
|
||||
streamWindow.find(".zoomGlass").show()
|
||||
})
|
||||
.on('mouseout', function(){
|
||||
streamWindow.find(".zoomGlass").hide()
|
||||
})
|
||||
.on('mousemove', magnifyStream)
|
||||
.on('touchmove', magnifyStream)
|
||||
}
|
||||
})
|
||||
}
|
||||
var playAllSlots = function(){
|
||||
getAllActiveVideosInSlots().each(function(n,video){
|
||||
if(video.paused)video.play()
|
||||
})
|
||||
}
|
||||
var setPlaySpeedOnAllSlots = function(playSpeed){
|
||||
Object.keys(powerVideoLoadedVideos).forEach(function(monitorId){
|
||||
monitorSlotPlaySpeeds[monitorId] = playSpeed
|
||||
})
|
||||
getAllActiveVideosInSlots().each(function(n,video){
|
||||
video.playbackRate = playSpeed
|
||||
})
|
||||
}
|
||||
var nextVideoAllSlots = function(){
|
||||
Object.keys(currentlyPlayingVideos).forEach(function(monitorId){
|
||||
var video = currentlyPlayingVideos[monitorId]
|
||||
visuallyDeselectItemInRow(video)
|
||||
visuallySelectItemInRow(video.videoAfter)
|
||||
loadVideoIntoMonitorSlot(video.videoAfter,0)
|
||||
})
|
||||
}
|
||||
var previousVideoAllSlots = function(){
|
||||
Object.keys(currentlyPlayingVideos).forEach(function(monitorId){
|
||||
var video = currentlyPlayingVideos[monitorId]
|
||||
visuallyDeselectItemInRow(video)
|
||||
visuallySelectItemInRow(video.videoBefore)
|
||||
loadVideoIntoMonitorSlot(video.videoBefore,0)
|
||||
})
|
||||
}
|
||||
$user.ws.on('f',function (d){
|
||||
switch(d.f){
|
||||
case'videos&events':
|
||||
var videos = d.videos.videos
|
||||
var events = d.events
|
||||
loadVideosToTimeLineMemory(d.id,videos,events)
|
||||
drawLoadedTableData()
|
||||
break;
|
||||
}
|
||||
})
|
||||
$('body')
|
||||
.on('dblclick','.videoPlayer',function(){
|
||||
var el = $(this)
|
||||
$.ccio.init('fullscreen',this)
|
||||
})
|
||||
.on('click','[data-monitor]',function(){
|
||||
var el = $(this)
|
||||
var monitorId = el.attr('data-monitor')
|
||||
el.toggleClass('active')
|
||||
if(el.hasClass('active')){
|
||||
requestTableData(monitorId)
|
||||
}else{
|
||||
unloadTableData(monitorId)
|
||||
}
|
||||
})
|
||||
.on('click','[powerVideo-control]',function(){
|
||||
var el = $(this)
|
||||
var controlType = el.attr('powerVideo-control')
|
||||
switch(controlType){
|
||||
case'toggleZoom':
|
||||
toggleZoomAllSlots()
|
||||
break;
|
||||
case'playAll':
|
||||
playAllSlots()
|
||||
break;
|
||||
case'pauseAll':
|
||||
pauseAllSlots()
|
||||
break;
|
||||
case'playSpeedAll':
|
||||
var playSpeed = el.attr('data-speed')
|
||||
setPlaySpeedOnAllSlots(playSpeed)
|
||||
break;
|
||||
case'previousVideoAll':
|
||||
playAllSlots()
|
||||
previousVideoAllSlots()
|
||||
break;
|
||||
case'nextVideoAll':
|
||||
playAllSlots()
|
||||
nextVideoAllSlots()
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
powerVideoWindow.on('shown.bs.modal',function(){
|
||||
drawMonitorsList()
|
||||
})
|
||||
$.powerVideoViewer = {
|
||||
window: powerVideoWindow,
|
||||
drawMonitorsList: drawMonitorsList,
|
||||
activeTimeline: activeTimeline,
|
||||
monitorListElement: powerVideoMonitorsListElement,
|
||||
monitorViewsElement: powerVideoMonitorViewsElement,
|
||||
timelineStripsElement: powerVideoTimelineStripsContainer,
|
||||
dateRangeElement: powerVideoDateRangeElement,
|
||||
loadedVideos: powerVideoLoadedVideos,
|
||||
loadedEvents: powerVideoLoadedEvents,
|
||||
loadedChartData: powerVideoLoadedChartData,
|
||||
loadedTableGroupIds: loadedTableGroupIds,
|
||||
extenders: extenders
|
||||
}
|
||||
})
|
128
web/libs/js/dash2.schedules.js
Normal file
128
web/libs/js/dash2.schedules.js
Normal file
|
@ -0,0 +1,128 @@
|
|||
$(document).ready(function(){
|
||||
$.schedules = {
|
||||
e: $('#schedules'),
|
||||
selector: $('#schedulesSelector'),
|
||||
loadedMonitorStates: {},
|
||||
loadedSchedules: {}
|
||||
}
|
||||
$.schedules.f = $.schedules.e.find('form')
|
||||
$.schedules.selectedStates = $.schedules.e.find('[name="monitorStates"]')
|
||||
$.schedules.selectedDays = $.schedules.e.find('[name="days"]')
|
||||
$.schedules.loadSchedules = function(callback){
|
||||
$.get($.ccio.init('location',$user) + $user.auth_token + '/schedule/' + $user.ke,function(d){
|
||||
console.log(d)
|
||||
var html = ''
|
||||
$.each(d.schedules,function(n,v){
|
||||
$.schedules.loadedSchedules[v.name] = v
|
||||
html += $.ccio.tm('option',{
|
||||
id: v.name,
|
||||
name: v.name
|
||||
})
|
||||
})
|
||||
$.schedules.selector.find('optgroup').html(html)
|
||||
if(callback)callback()
|
||||
})
|
||||
}
|
||||
$.schedules.loadMonitorStates = function(){
|
||||
$.get($.ccio.init('location',$user) + $user.auth_token + '/monitorStates/' + $user.ke,function(d){
|
||||
var html = ''
|
||||
$.each(d.presets,function(n,v){
|
||||
$.schedules.loadedMonitorStates[v.name] = v
|
||||
html += $.ccio.tm('option',{
|
||||
id: v.name,
|
||||
name: v.name
|
||||
})
|
||||
})
|
||||
$.schedules.selectedStates.html(html)
|
||||
})
|
||||
}
|
||||
$.schedules.e.on('shown.bs.modal', function (e) {
|
||||
$.schedules.loadMonitorStates()
|
||||
$.schedules.loadSchedules()
|
||||
})
|
||||
$.schedules.e.on('click','.delete',function(e){
|
||||
$.confirm.e.modal('show');
|
||||
$.confirm.title.text(lang['Delete Monitor States Preset']);
|
||||
$.confirm.body.html(lang.deleteMonitorStateText1);
|
||||
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||
var form = $.schedules.f.serializeObject()
|
||||
$.post($.ccio.init('location',$user) + $user.auth_token + '/schedule/' + $user.ke + '/' + form.name + '/delete',function(d){
|
||||
$.ccio.log(d)
|
||||
if(d.ok === true){
|
||||
$.schedules.loadSchedules()
|
||||
$.ccio.init('note',{title:lang.Success,text:d.msg,type:'success'})
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
$.schedules.selector.change(function(e){
|
||||
var selected = $(this).val()
|
||||
var loaded = $.schedules.loadedSchedules[selected]
|
||||
var namespace = $.schedules.e.find('[name="name"]')
|
||||
var deleteButton = $.schedules.e.find('.delete')
|
||||
var tzEl = $.schedules.e.find('[name="timezone"]')
|
||||
$.schedules.selectedStates.find('option:selected').removeAttr('selected')
|
||||
$.schedules.selectedDays.find('option:selected').removeAttr('selected')
|
||||
if(loaded){
|
||||
namespace.val(loaded.name)
|
||||
var html = ''
|
||||
$.each(loaded,function(n,v){
|
||||
$.schedules.f.find('[name="' + n + '"]').val(v)
|
||||
})
|
||||
$.each(loaded.details.monitorStates,function(n,v){
|
||||
$.schedules.selectedStates.find('option[value="' + v + '"]').prop('selected',true)
|
||||
})
|
||||
$.each(loaded.details.days,function(n,v){
|
||||
$.schedules.selectedDays.find('option[value="' + v + '"]').prop('selected',true)
|
||||
})
|
||||
tzEl.val(loaded.details.timezone || '+0')
|
||||
deleteButton.show()
|
||||
}else{
|
||||
tzEl.val('+0')
|
||||
namespace.val('')
|
||||
deleteButton.hide()
|
||||
}
|
||||
})
|
||||
$.schedules.f.submit(function(e){
|
||||
e.preventDefault()
|
||||
var el = $(this)
|
||||
var form = el.serializeObject()
|
||||
var monitors = []
|
||||
var failedToParseAJson = false
|
||||
var rows = $.monitorStates.monitors.find('.state-monitor-row')
|
||||
if(form.name === ''){
|
||||
return $.ccio.init('note',{title:lang['Invalid Data'],text:lang['Name cannot be empty.'],type:'error'})
|
||||
}
|
||||
if(form.start === ''){
|
||||
return $.ccio.init('note',{title:lang['Invalid Data'],text:lang['Start Time cannot be empty.'],type:'error'})
|
||||
}
|
||||
if(form.monitorStates instanceof Array === false){
|
||||
form.monitorStates = [form.monitorStates]
|
||||
}
|
||||
if(!form.days || form.days === ''){
|
||||
form.days = null
|
||||
}else if(form.days instanceof Array === false){
|
||||
form.days = [form.days]
|
||||
}
|
||||
var data = {
|
||||
start: form.start,
|
||||
end: form.end,
|
||||
enabled: form.enabled,
|
||||
details: {
|
||||
monitorStates: form.monitorStates,
|
||||
days: form.days,
|
||||
timezone: form.timezone,
|
||||
}
|
||||
}
|
||||
$.post($.ccio.init('location',$user) + $user.auth_token + '/schedule/' + $user.ke + '/' + form.name + '/insert',{data:data},function(d){
|
||||
$.ccio.log(d)
|
||||
if(d.ok === true){
|
||||
$.schedules.loadSchedules(function(){
|
||||
$.schedules.selector.val(form.name)
|
||||
})
|
||||
$.ccio.init('note',{title:lang.Success,text:d.msg,type:'success'})
|
||||
}
|
||||
})
|
||||
return false;
|
||||
})
|
||||
})
|
|
@ -7,6 +7,13 @@ $.ccio.cx=function(x,user){
|
|||
if(!x.uid){x.uid=user.uid;};
|
||||
return user.ws.emit('f',x)
|
||||
}
|
||||
$.diskUsed = {
|
||||
main: $('.diskUsed'),
|
||||
list: {},
|
||||
}
|
||||
$.each(addStorage,function(n,storage){
|
||||
$.diskUsed.list[storage.name] = $(`#diskUsedList [storage="${storage.name}"]`)
|
||||
})
|
||||
$.ccio.globalWebsocket=function(d,user){
|
||||
if(d.f!=='monitor_frame'&&d.f!=='os'&&d.f!=='video_delete'&&d.f!=='detector_trigger'&&d.f!=='detector_record_timeout_start'&&d.f!=='log'){$.ccio.log(d);}
|
||||
if(!user){
|
||||
|
@ -151,12 +158,26 @@ $.ccio.globalWebsocket=function(d,user){
|
|||
break;
|
||||
case'diskUsed':
|
||||
if(!d.limit||d.limit===''){d.limit=10000}
|
||||
d.percent=parseInt((d.size/d.limit)*100)+'%';
|
||||
d.human=parseFloat(d.size)
|
||||
d.percent = parseInt((d.size/d.limit)*100)+'%';
|
||||
d.human = parseFloat(d.size)
|
||||
if(d.human>1000){d.human=(d.human/1000).toFixed(2)+' GB'}else{d.human=d.human.toFixed(2)+' MB'}
|
||||
$('.diskUsed .value').html(d.human)
|
||||
$('.diskUsed .percent').html(d.percent)
|
||||
$('.diskUsed .progress-bar').css('width',d.percent)
|
||||
$.diskUsed.main.find('.value').html(d.human)
|
||||
$.diskUsed.main.find('.percent').html(d.percent)
|
||||
$.diskUsed.main.find('.progress-bar').css('width',d.percent)
|
||||
if(d.addStorage){
|
||||
$.each(d.addStorage,function(n,storage){
|
||||
var percent = parseInt((storage.usedSpace/storage.sizeLimit)*100)+'%'
|
||||
var humanValue = parseFloat(storage.usedSpace)
|
||||
if(humanValue > 1000){
|
||||
humanValue = (humanValue/1000).toFixed(2)+' GB'
|
||||
}else{
|
||||
humanValue = humanValue.toFixed(2)+' MB'
|
||||
}
|
||||
$.diskUsed.list[storage.name].find('.value').html(humanValue)
|
||||
$.diskUsed.list[storage.name].find('.percent').html(percent)
|
||||
$.diskUsed.list[storage.name].find('.progress-bar').css('width',percent)
|
||||
})
|
||||
}
|
||||
break;
|
||||
case'video_fix_success':case'video_fix_start':
|
||||
switch(d.f){
|
||||
|
@ -723,9 +744,14 @@ $.ccio.globalWebsocket=function(d,user){
|
|||
type: "time",
|
||||
display: true,
|
||||
time: {
|
||||
format: timeFormat,
|
||||
// round: 'day'
|
||||
}
|
||||
// format: timeFormat,
|
||||
unit: 'minute',
|
||||
displayFormats: {
|
||||
minute: 'h:mm a',
|
||||
},
|
||||
},
|
||||
categoryPercentage: 0.6,
|
||||
barPercentage: .5,
|
||||
}],
|
||||
},
|
||||
}
|
||||
|
|
14
web/libs/js/dash2.tabs.js
Normal file
14
web/libs/js/dash2.tabs.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
$(document).ready(function(){
|
||||
$('body')
|
||||
.on('click','[tab-chooser]',function(){
|
||||
var el = $(this)
|
||||
var parent = el.parents('[tab-chooser-parent]')
|
||||
var tabName = el.attr('[tab-chooser]')
|
||||
var allTabChoosersInParent = parent.find('[tab-chooser]')
|
||||
var allTabsInParent = parent.find('[tab-section]')
|
||||
allTabsInParent.hide()
|
||||
allTabChoosersInParent.removeClass('active')
|
||||
el.addClass('active')
|
||||
parent.find(`[tab-section="${tabName}"]`).show()
|
||||
})
|
||||
})
|
174
web/libs/js/dash2.timelapse.jpeg.js
Normal file
174
web/libs/js/dash2.timelapse.jpeg.js
Normal file
|
@ -0,0 +1,174 @@
|
|||
$(document).ready(function(e){
|
||||
//Timelapse JPEG Window
|
||||
$.timelapseJpeg = {e:$('#timelapsejpeg')}
|
||||
$.timelapseJpeg.datepicker = $('#timelapsejpeg_date')
|
||||
$.timelapseJpeg.timelapseJpegFps = $('#timelapseJpegFps')
|
||||
$.timelapseJpeg.framesContainer = $.timelapseJpeg.e.find('.frames')
|
||||
$.timelapseJpeg.frameStrip = $.timelapseJpeg.e.find('.frameStrip')
|
||||
$.timelapseJpeg.frameIcons = $.timelapseJpeg.e.find('.frameIcons')
|
||||
$.timelapseJpeg.fieldHolder = $.timelapseJpeg.e.find('.fieldHolder')
|
||||
$.timelapseJpeg.frameStripPreview = $.timelapseJpeg.e.find('.frameStripPreview')
|
||||
$.timelapseJpeg.frameStripContainer = $.timelapseJpeg.e.find('.frameStripContainer')
|
||||
$.timelapseJpeg.playBackViewImg = $.timelapseJpeg.e.find('.playBackView img')
|
||||
$.timelapseJpeg.liveStreamView = $.timelapseJpeg.e.find('.liveStreamView')
|
||||
$.timelapseJpeg.monitors=$.timelapseJpeg.e.find('.monitors_list')
|
||||
$.timelapseJpeg.pointer = $.ccio.init('location',$user)
|
||||
$.timelapseJpeg.downloadRecheckTimers = {}
|
||||
$.timelapseJpeg.selectedStartDate = moment().utc().subtract(2, 'days').format('YYYY-MM-DDTHH:mm:ss')
|
||||
$.timelapseJpeg.selectedEndDate = moment().utc().format('YYYY-MM-DDTHH:mm:ss')
|
||||
$.timelapseJpeg.datepicker.daterangepicker({
|
||||
startDate: moment().utc().subtract(2, 'days'),
|
||||
endDate: moment().utc(),
|
||||
timePicker: true,
|
||||
locale: {
|
||||
format: 'YYYY/MM/DD hh:mm:ss A'
|
||||
}
|
||||
}, function(start, end, label) {
|
||||
console.log(start,end)
|
||||
var selectedStartDate = moment(start).utc().format('YYYY-MM-DDTHH:mm:ss')
|
||||
var selectedEndDate = moment(end).utc().format('YYYY-MM-DDTHH:mm:ss')
|
||||
$.timelapseJpeg.draw(selectedStartDate,selectedEndDate)
|
||||
$.timelapseJpeg.selectedStartDate = selectedStartDate
|
||||
$.timelapseJpeg.selectedEndDate = selectedEndDate
|
||||
})
|
||||
$.timelapseJpeg.monitors.change(function(){
|
||||
$.timelapseJpeg.draw()
|
||||
$.timelapseJpeg.getLiveStream()
|
||||
})
|
||||
$.timelapseJpeg.getLiveStream = function(){
|
||||
var selectedMonitor = $.timelapseJpeg.monitors.val()
|
||||
$.timelapseJpeg.liveStreamView.html(`<iframe src="${$.timelapseJpeg.pointer+$user.auth_token+'/embed/'+$user.ke+'/'+selectedMonitor+'/jquery|fullscreen'}"></iframe>`)
|
||||
$.timelapseJpeg.liveStreamView.find('iframe').width($.timelapseJpeg.playBackViewImg.width())
|
||||
|
||||
}
|
||||
$.timelapseJpeg.draw = function(startDate,endDate){
|
||||
if(!startDate)startDate = $.timelapseJpeg.selectedStartDate
|
||||
if(!endDate)endDate = $.timelapseJpeg.selectedEndDate
|
||||
$.timelapseJpeg.frameStripContainerOffset = $.timelapseJpeg.frameStripContainer.offset()
|
||||
var queryString = ['start=' + startDate,'end=' + endDate]
|
||||
var frameIconsHtml = ''
|
||||
var selectedMonitor = $.timelapseJpeg.monitors.val()
|
||||
var apiURL = $.timelapseJpeg.pointer+$user.auth_token+'/timelapse/'+$user.ke+'/'+selectedMonitor
|
||||
console.log(apiURL + '?' + queryString.join('&'))
|
||||
$.getJSON(apiURL + '?' + queryString.join('&'),function(data){
|
||||
if(data && data[0]){
|
||||
var firstFilename = data[0].filename
|
||||
$.timelapseJpeg.frameSelected = firstFilename
|
||||
$.timelapseJpeg.playlist = {}
|
||||
$.timelapseJpeg.playlistArray = []
|
||||
$.each(data.reverse(),function(n,fileInfo){
|
||||
fileInfo.href = apiURL + '/' + fileInfo.filename.split('T')[0] + '/' + fileInfo.filename
|
||||
fileInfo.number = n
|
||||
frameIconsHtml += '<div class="col-md-4"><div class="frame" data-filename="' + fileInfo.filename + '" style="background-image:url(\'' + fileInfo.href + '\')"><div class="shade">' + moment(fileInfo.time).format('YYYY-MM-DD HH:mm:ss') + '</div></div></div>'
|
||||
$.timelapseJpeg.playlist[fileInfo.filename] = fileInfo
|
||||
})
|
||||
$.timelapseJpeg.playlistArray = data
|
||||
$.timelapseJpeg.frameIcons.html(frameIconsHtml)
|
||||
$.timelapseJpeg.frameIcons.find(`.frame:first`).click()
|
||||
$.timelapseJpeg.getLiveStream()
|
||||
$.timelapseJpeg.resetFilmStripPositions()
|
||||
}else{
|
||||
frameIconsHtml = lang['No Data']
|
||||
$.timelapseJpeg.frameIcons.html(frameIconsHtml)
|
||||
}
|
||||
})
|
||||
}
|
||||
$.timelapseJpeg.fieldHolderCssHeightModifier = 0
|
||||
$.timelapseJpeg.resetFilmStripPositions = function(){
|
||||
var numberOfFrames = Object.keys($.timelapseJpeg.playlist).length
|
||||
var fieldHolderHeight = $.timelapseJpeg.fieldHolder.height() + $.timelapseJpeg.fieldHolderCssHeightModifier
|
||||
console.log("calc(100% - " + fieldHolderHeight + "px)")
|
||||
$.timelapseJpeg.frameIcons.css({height:"calc(100% - " + fieldHolderHeight + "px)"})
|
||||
}
|
||||
$.timelapseJpeg.setPlayBackFrame = function(href){
|
||||
$.timelapseJpeg.playBackViewImg[0].src = href
|
||||
}
|
||||
$.timelapseJpeg.playInterval = 1000 / 30
|
||||
$.timelapseJpeg.play = function(){
|
||||
var selectedFrame = $.timelapseJpeg.playlist[$.timelapseJpeg.frameSelected]
|
||||
var selectedFrameNumber = $.timelapseJpeg.playlist[$.timelapseJpeg.frameSelected].number
|
||||
$.timelapseJpeg.setPlayBackFrame(selectedFrame.href)
|
||||
$.timelapseJpeg.frameIcons.find(`.frame.selected`).removeClass('selected')
|
||||
$.timelapseJpeg.frameIcons.find(`.frame[data-filename="${selectedFrame.filename}"]`).addClass('selected')
|
||||
clearTimeout($.timelapseJpeg.playIntervalTimer)
|
||||
$.timelapseJpeg.playIntervalTimer = setTimeout(function(){
|
||||
++selectedFrameNumber
|
||||
var newSelectedFrame = $.timelapseJpeg.playlistArray[selectedFrameNumber]
|
||||
if(!newSelectedFrame)return
|
||||
$.timelapseJpeg.frameSelected = newSelectedFrame.filename
|
||||
$.timelapseJpeg.play()
|
||||
},$.timelapseJpeg.playInterval)
|
||||
}
|
||||
$.timelapseJpeg.destroy = function(){
|
||||
$.timelapseJpeg.pause()
|
||||
$.timelapseJpeg.frameIcons.empty()
|
||||
$.timelapseJpeg.setPlayBackFrame(null)
|
||||
}
|
||||
$.timelapseJpeg.pause = function(){
|
||||
clearTimeout($.timelapseJpeg.playIntervalTimer)
|
||||
delete($.timelapseJpeg.playIntervalTimer)
|
||||
}
|
||||
$.timelapseJpeg.togglePlayPause = function(){
|
||||
if($.timelapseJpeg.playIntervalTimer){
|
||||
$.timelapseJpeg.pause()
|
||||
}else{
|
||||
$.timelapseJpeg.play()
|
||||
}
|
||||
}
|
||||
$.timelapseJpeg.e.on('click','.frame',function(){
|
||||
$.timelapseJpeg.pause()
|
||||
var selectedFrame = $(this).attr('data-filename')
|
||||
if(selectedFrame === $.timelapseJpeg.frameSelected){
|
||||
return $.timelapseJpeg.togglePlayPause()
|
||||
}
|
||||
$.timelapseJpeg.frameSelected = selectedFrame
|
||||
$.timelapseJpeg.frameIcons.find(`.frame.selected`).removeClass('selected')
|
||||
$.timelapseJpeg.frameIcons.find(`.frame[data-filename="${selectedFrame}"]`).addClass('selected')
|
||||
var href = $.timelapseJpeg.playlist[selectedFrame].href
|
||||
$.timelapseJpeg.setPlayBackFrame(href)
|
||||
})
|
||||
$.timelapseJpeg.e.on('click','.download_mp4',function(){
|
||||
var _this = $(this)
|
||||
var runDownloader = function(){
|
||||
var startDate = $.timelapseJpeg.selectedStartDate
|
||||
var endDate = $.timelapseJpeg.selectedEndDate
|
||||
var queryString = ['fps=' + $.timelapseJpeg.timelapseJpegFps.val(),'start=' + startDate,'end=' + endDate,'mp4=1']
|
||||
var timerId = queryString.join('&')
|
||||
var selectedMonitor = $.timelapseJpeg.monitors.val()
|
||||
var generatorUrl = $.timelapseJpeg.pointer + $user.auth_token + '/timelapse/' + $user.ke + '/' + selectedMonitor
|
||||
$.getJSON(generatorUrl + '?' + queryString.join('&'),function(response){
|
||||
if(response.fileExists){
|
||||
_this.text(lang['Download'])
|
||||
var downloadName = startDate + '_' + endDate + '_' + selectedMonitor + '.mp4'
|
||||
var a = document.createElement('a')
|
||||
a.href = generatorUrl + '?' + queryString.concat(['download="1"']).join('&')
|
||||
a.download = downloadName
|
||||
a.click()
|
||||
}else{
|
||||
_this.html(' <i class="fa fa-spinner fa-pulse"></i> ')
|
||||
clearTimeout($.timelapseJpeg.downloadRecheckTimers[timerId])
|
||||
$.timelapseJpeg.downloadRecheckTimers[timerId] = setTimeout(function(){
|
||||
runDownloader()
|
||||
},5000)
|
||||
}
|
||||
})
|
||||
}
|
||||
runDownloader()
|
||||
})
|
||||
$.timelapseJpeg.e.on('shown.bs.modal', function (e) {
|
||||
// $.timelapseJpeg.datepicker.val($.timelapseJpeg.baseDate)
|
||||
// $.timelapseJpeg.draw($.timelapseJpeg.baseDate)
|
||||
})
|
||||
$.timelapseJpeg.e.on('hidden.bs.modal', function (e) {
|
||||
$.timelapseJpeg.destroy()
|
||||
})
|
||||
$.timelapseJpeg.timelapseJpegFps
|
||||
.on('slide',function(ev){
|
||||
$.timelapseJpeg.playInterval = 1000 / ev.value
|
||||
})
|
||||
.slider({
|
||||
formatter: function(value) {
|
||||
return 'FPS : ' + value;
|
||||
}
|
||||
})
|
||||
})
|
|
@ -3,9 +3,80 @@ $(document).ready(function(e){
|
|||
$.sM={e:$('#settings')};
|
||||
$.sM.f=$.sM.e.find('form');
|
||||
$.sM.links=$('#linkShinobi');
|
||||
$.sM.addStorageMaxAmounts=$('#add_storage_max_amounts')
|
||||
$.sM.addStorageMaxAmountsField=$.sM.e.find('[detail="addStorage"]')
|
||||
$.sM.g=$('#settings_mon_groups');
|
||||
$.sM.md=$.sM.f.find('[detail]');
|
||||
$.sM.md.change($.ccio.form.details);
|
||||
$.sM.e.find('.follow-list ul').affix();
|
||||
$.sM.sections = {}
|
||||
var addSection = function(section){
|
||||
if(!section.id){
|
||||
var userSettingsId = section.name.replace(/[^a-zA-Z ]/g, '').replace(/[^a-zA-Z ]/g, '').replace(/ /g, '')
|
||||
section.id = userSettingsId
|
||||
}
|
||||
$.sM.sections[section.name] = section.id
|
||||
if(section.info){
|
||||
$.each(section.info,function(m,block){
|
||||
if(block.isFormGroupGroup === true){
|
||||
addSection(block)
|
||||
}
|
||||
})
|
||||
}
|
||||
if(section.blocks){
|
||||
$.each(section.blocks,function(m,block){
|
||||
addSection(block)
|
||||
})
|
||||
}
|
||||
}
|
||||
$.each($.ccio.definitions['Account Settings'].blocks,function(n,section){
|
||||
addSection(section)
|
||||
})
|
||||
$.sM.drawList = function(){
|
||||
var list = $.sM.e.find('.follow-list ul')
|
||||
var html = ''
|
||||
$.each($.sM.sections,function(sectionName,sectionId){
|
||||
var el = $('#' + sectionId)
|
||||
if(el.length > 0){
|
||||
html += '<li><a class="scrollTo" href="#' + sectionId + '" scrollToParent="#settings .modal-body">' + sectionName + '</a></li>'
|
||||
}
|
||||
})
|
||||
list.html(html)
|
||||
}
|
||||
try{
|
||||
var addStorageData = JSON.parse($user.details.addStorage || '{}')
|
||||
var html = ''
|
||||
$.each(addStorage,function(n,storage){
|
||||
var limit = ""
|
||||
if(addStorageData[storage.path] && addStorageData[storage.path].limit){
|
||||
limit = addStorageData[storage.path].limit
|
||||
}
|
||||
html += `<div class="form-group">\
|
||||
<label><div><span>${lang['Max Storage Amount']} : ${storage.name}</span></div>\
|
||||
<div><input class="form-control" addStorageLimit="${storage.path}" value="${limit}"></div>\
|
||||
</label>\
|
||||
</div>`
|
||||
})
|
||||
$.sM.addStorageMaxAmounts.html(html)
|
||||
$.sM.addStorageMaxAmounts.on('change','[addStorageLimit]',function(){
|
||||
var json = {}
|
||||
$.each(addStorage,function(n,storage){
|
||||
var storageId = storage.path
|
||||
var el = $.sM.addStorageMaxAmounts.find('[addStorageLimit="' + storageId + '"]')
|
||||
var value = el.val()
|
||||
json[storageId] = {
|
||||
name: storage.name,
|
||||
path: storage.path,
|
||||
limit: value
|
||||
}
|
||||
})
|
||||
$.sM.addStorageMaxAmountsField.val(JSON.stringify(json))
|
||||
})
|
||||
}catch(err){
|
||||
console.log(err)
|
||||
}
|
||||
|
||||
$.sM.drawList()
|
||||
$.sM.f.find('[selector]').change(function(e){
|
||||
e.v=$(this).val();e.a=$(this).attr('selector')
|
||||
$.sM.f.find('.'+e.a+'_input').hide()
|
||||
|
|
|
@ -109,19 +109,15 @@ $.vidview.e.find('.export_selected').click(function(){
|
|||
$.confirm.e.modal('show');
|
||||
$.confirm.title.text(lang['Export Selected Videos'])
|
||||
var html = lang.ExportSelectedVideosMsg+'<div style="margin-bottom:15px"></div>'
|
||||
var selectedVideos = []
|
||||
$.each(videos,function(n,v){
|
||||
html+=v.filename+'<br>';
|
||||
selectedVideos.push($.vidview.loadedVideos[v.filename])
|
||||
})
|
||||
$.confirm.body.html(html)
|
||||
$.confirm.click({title:'Export Video',class:'btn-danger'},function(){
|
||||
var queryVariables = []
|
||||
queryVariables.push('videos='+JSON.stringify(videos))
|
||||
if($.ccio.useUTC === true){
|
||||
queryVariables.push('isUTC=true')
|
||||
}
|
||||
var downloadZip = $.ccio.init('location',$user)+$user.auth_token+'/zipVideos/'+$user.ke+'?'+queryVariables.join('&')
|
||||
$('#temp').html('<iframe>a</iframe>').find('iframe').attr('src',downloadZip);
|
||||
});
|
||||
$.zipVideosAndDownload(selectedVideos)
|
||||
})
|
||||
})
|
||||
$.vidview.e.find('.merge_selected').click(function(){
|
||||
e = {}
|
||||
|
|
13
web/libs/js/jszip.min.js
vendored
Normal file
13
web/libs/js/jszip.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
web/libs/js/moment-with-locales.min.js
vendored
Normal file
1
web/libs/js/moment-with-locales.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
47
web/libs/js/vis.min.js
vendored
Normal file
47
web/libs/js/vis.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -15,34 +15,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
//confirmwindow
|
||||
$.confirm={e:$('#confirm_window')};
|
||||
$.confirm.title=$.confirm.e.find('.modal-title span')
|
||||
$.confirm.body=$.confirm.e.find('.modal-body')
|
||||
$.confirm.footer=$.confirm.e.find('.modal-footer')
|
||||
$.confirm.click=function(x,e){
|
||||
$.confirm.footer.find('.confirmaction').remove()
|
||||
var createButton = function(x,place,callback){
|
||||
$.confirm.footer.prepend('<button type="button" class="btn '+x.class+' confirmaction confirmaction'+place+'">'+x.title+'</button>')
|
||||
if(!x.class){x.class='btn-success'}
|
||||
if(!x.title){x.title='Save changes'}
|
||||
$.confirm.footer.find('.confirmaction'+place).click(function(){
|
||||
$.confirm.e.modal('hide')
|
||||
callback();
|
||||
})
|
||||
}
|
||||
if(x instanceof Array){
|
||||
$.each(x,function(place,x){
|
||||
createButton(x,place,x.callback)
|
||||
})
|
||||
}else{
|
||||
createButton(x,0,e)
|
||||
}
|
||||
}
|
||||
$(document).ready(function(){
|
||||
$.confirm.e.on('hidden.bs.modal', function () {
|
||||
$.confirm.footer.find('.confirmaction').remove()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<script src="<%-window.libURL%>libs/js/dash2.confirm.js"></script>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<%
|
||||
if(!window.libURL)window.libURL = originalURL
|
||||
%>
|
||||
<link rel="icon" href="<%-window.libURL%>libs/img/icon/favicon.ico" type="image/x-icon" />
|
||||
<link rel="shortcut icon" href="<%-window.libURL%>libs/img/icon/favicon.ico" type="image/x-icon" />
|
||||
<link rel="icon" href="<%-window.libURL%><%-config.webFavicon%>" type="image/x-icon" />
|
||||
<link rel="shortcut icon" href="<%-window.libURL%><%-config.webFavicon%>" type="image/x-icon" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="Shinobi">
|
||||
<meta name="apple-mobile-web-app-title" content="<%-config.webPageTitle%>">
|
||||
<link rel="apple-touch-icon" href="<%-window.libURL%>libs/img/icon/apple-touch-icon.png" />
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="<%-window.libURL%>libs/img/icon/apple-touch-icon-57x57.png" />
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="<%-window.libURL%>libs/img/icon/apple-touch-icon-72x72.png" />
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
|
||||
<meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" />
|
||||
<meta name="description" content="Shinobi, Open Source CCTV Technology">
|
||||
<meta name="author" content="Moe Alam, moeiscool on GitHub">
|
||||
<meta name="author" content="Moe Alam of Shinobi Systems">
|
||||
|
|
1
web/pages/blocks/header-title.ejs
Normal file
1
web/pages/blocks/header-title.ejs
Normal file
|
@ -0,0 +1 @@
|
|||
<title><%- config.webPageTitle %></title>
|
|
@ -1,5 +1,6 @@
|
|||
<head>
|
||||
<title><%-lang.Shinobi%></title>
|
||||
<!-- Powered by Shinobi, http://shinobi.video -->
|
||||
<% include header-title.ejs %>
|
||||
<% if(!window.libURL)window.libURL = originalURL + global.s.checkCorrectPathEnding(config.webPaths.home) %>
|
||||
<% include header-meta.ejs %>
|
||||
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
|
||||
|
@ -8,6 +9,7 @@
|
|||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/login.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/material.min.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/material.style.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/roboto.css" type="text/css" />
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
||||
<% include header-favicon.ejs %>
|
||||
|
|
|
@ -1,45 +1,64 @@
|
|||
<!--Help Window-->
|
||||
<!--
|
||||
<div class="modal fade" id="help_window" tabindex="-1" role="dialog" aria-labelledby="help_windowLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title" id="help_windowLabel"><i class="fa fa-question-circle"></i> <span><%-lang.Help%></span></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<a href="http://shinobi.video/docs/donate"><img src="<%-window.libURL%>libs/img/icon/apple-touch-icon-152x152.png" class="pull-right" style="border-radius:50%;margin-left:20px;border: 1px solid #c3996b;"></a>
|
||||
<p>For information about how to use Shinobi you can check out the <a target="_blank" href="http://shinobi.video/docs">Docs</a>.</p>
|
||||
<p>If you would like to get professional support please consider ordering a <a href="http://shinobi.video/support">support package</a>. You can find <b>Moe Alam, The Author</b>, on the <a target="_blank" href="https://discord.gg/ehRd8Zz">Discord</a> Community Chat. For general questions and community support you can also try <a href="https://www.reddit.com/r/ShinobiCCTV">Reddit</a>.</p>
|
||||
<p><strong>Support </strong> <a href="http://shinobi.video/support">from @moeiscool</a></p>
|
||||
<p><b>Like Shinobi?</b> Please consider donating!</p>
|
||||
<div><p><strong>Paypal Address :</strong> <a href="https://www.paypal.me/ShinobiCCTV" target="_blank">paypal@m03.ca</a></p>
|
||||
<% if(!config.userHasSubscribed){ %>
|
||||
<div class="modal fade" id="help_window" tabindex="-1" role="dialog" aria-labelledby="help_windowLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title" id="help_windowLabel"><i class="fa fa-question-circle"></i> <span><%-lang.Help%></span></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<blockquote class="blockquoteInHelp">
|
||||
<a href="https://licenses.shinobi.video/subscribe" target="_blank"><img src="<%-window.libURL%>libs/img/icon/apple-touch-icon-152x152.png" class="pull-right" style="border-radius:50%;margin-left:20px;border: 1px solid #c3996b;"></a>
|
||||
<p>For information about how to use Shinobi you can check out the <a target="_blank" href="http://shinobi.video/docs">Docs</a>.</p>
|
||||
<p><a target="_blank" href="https://discord.gg/ehRd8Zz">Discord</a> Community Chat is great for meeting people and asking questions. For general questions and community support you can also try the <a href="https://www.reddit.com/r/ShinobiCCTV">Reddit forum</a>.</p>
|
||||
</blockquote>
|
||||
<blockquote class="blockquoteInHelp" style="margin-bottom:10px">
|
||||
<b>Support the development by subscribing</b> to any of the following and put your subscription key in the configuration file (conf.json), then restart Shinobi and this annoying popup window won't appear anymore, thanks! <i class="fa fa-smile-o"></i>
|
||||
<br><br>
|
||||
<code>"subscriptionId":"sub_XXXXXXXXXXXX",</code>
|
||||
<br><br>
|
||||
<p>If you already are supporting the development in a different way, please contact us and we can get this popup to go away for you :) Cheers!</p>
|
||||
</blockquote>
|
||||
<div style="margin-bottom:10px;text-align:center">
|
||||
<a href="https://licenses.shinobi.video/subscribe?planSubscribe=plan_G31AZ9mknNCa6z" target="_blank" class="btn btn-default"><i class="fa fa-share-square-o" aria-hidden="true"></i> Shinobi Mobile License ($5/m)</a>
|
||||
<a href="https://licenses.shinobi.video/subscribe?planSubscribe=plan_G3LGdNwA8lSmQy" target="_blank" class="btn btn-default"><i class="fa fa-share-square-o" aria-hidden="true"></i> Shinobi Pro License ($75/m)</a>
|
||||
</div>
|
||||
<div style="margin-bottom:5px;text-align:center">
|
||||
<a href="https://licenses.shinobi.video/subscribe?planSubscribe=plan_G42jNgIqXaWmIC" target="_blank" class="btn btn-default"><i class="fa fa-share-square-o" aria-hidden="true"></i> Tiny Support Subscription ($10/m)</a>
|
||||
</div>
|
||||
<div>
|
||||
<!-- <iframe src="https://shinobi.video/ads" style="width:100%;height:250px;border:none;"></iframe> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger pull-left hide_donate"><%-lang['Close']%></button>
|
||||
<a target="_blank" href="http://discordapp.com/invite/mdhmvuH/" class="btn btn-primary"><%-lang['Chat on Discord']%></a>
|
||||
<a target="_blank" href="http://shinobi.video/docs" class="btn btn-success"><%-lang.Documentation%></a>
|
||||
</div>
|
||||
</div>
|
||||
<p><strong>Bitcoin Address :</strong> 1FvC7M8P9wVT1hXwHj8ugxpZj8JGfGyUDu</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger pull-left hide_donate"><%-lang['Don\'t show this anymore']%></button>
|
||||
<a target="_blank" href="http://discordapp.com/invite/mdhmvuH/" class="btn btn-primary"><%-lang['Chat on Discord']%></a>
|
||||
<a target="_blank" href="http://shinobi.video/docs" class="btn btn-success"><%-lang.Documentation%></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$.help={hide:$('#help_window .hide_donate'),e:$('#help_window')}
|
||||
if($.ccio.op().hide_donate!==1){
|
||||
setTimeout(function(){
|
||||
$.help.e.modal('show')
|
||||
},1000*60*5)
|
||||
$.help.hide.click(function(){
|
||||
$.ccio.op('hide_donate',1);
|
||||
$.help.e.modal('hide');
|
||||
})
|
||||
}else{
|
||||
$.help.hide.hide()
|
||||
}
|
||||
})
|
||||
</script>-->
|
||||
<style>
|
||||
.blockquoteInHelp:before,.blockquoteInHelp:after{
|
||||
display:none;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$.help={hide:$('#help_window .hide_donate'),e:$('#help_window')}
|
||||
// if($.ccio.op().hide_donate !== 1){
|
||||
setTimeout(function(){
|
||||
$.help.e.modal('show')
|
||||
},1000*60*0.2)
|
||||
$.help.hide.click(function(){
|
||||
// $.ccio.op('hide_donate',1);
|
||||
$.help.e.modal('hide');
|
||||
})
|
||||
// }else{
|
||||
// $.help.hide.hide()
|
||||
// }
|
||||
})
|
||||
</script>
|
||||
<% } %>
|
||||
|
|
|
@ -31,11 +31,10 @@
|
|||
<div class="form-group-group blue">
|
||||
<h4><%- lang['Monitors'] %>
|
||||
<div class="pull-right">
|
||||
<a class="btn btn-default btn-xs add"> <i class="fa fa-plus"></i> </a>
|
||||
<a class="btn btn-success btn-xs add-monitor"> <i class="fa fa-plus"></i> </a>
|
||||
</div>
|
||||
</h4>
|
||||
<div id="monitorStatesMonitors">
|
||||
</div>
|
||||
<div id="monitorStatesMonitors"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -46,137 +45,4 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$.monitorStates = {
|
||||
e: $('#monitorStates'),
|
||||
selector: $('#monitorStatesSelector'),
|
||||
monitors: $('#monitorStatesMonitors'),
|
||||
loaded: {}
|
||||
}
|
||||
$.monitorStates.f = $.monitorStates.e.find('form')
|
||||
$.monitorStates.loadPresets = function(callback){
|
||||
$.get($.ccio.init('location',$user) + $user.auth_token + '/monitorStates/' + $user.ke,function(d){
|
||||
var html = ''
|
||||
$.each(d.presets,function(n,v){
|
||||
$.monitorStates.loaded[v.name] = v
|
||||
html += '<option value="' + v.name + '">' + v.name + '</option>'
|
||||
})
|
||||
$.monitorStates.selector.find('optgroup').html(html)
|
||||
if(callback)callback()
|
||||
})
|
||||
}
|
||||
$.monitorStates.e.on('shown.bs.modal', function (e) {
|
||||
if($.monitorStates.selector.val() === '')$.monitorStates.loadPresets()
|
||||
})
|
||||
$.monitorStates.add = function(loaded,doAppend){
|
||||
if(!loaded){
|
||||
json = ''
|
||||
}else{
|
||||
json = JSON.stringify(loaded,null,3)
|
||||
}
|
||||
var html = '<div class="state-monitor-row"><h4 style="margin-top:7.5px;margin-bottom:7.5px"><small> </small><div class="pull-right"><a class="btn btn-danger btn-xs delete-monitor"><i class="fa fa-trash-o"></i></a></div></h4><textarea class="json form-control" style="width:100%;height:300px">' + json +'</textarea></div>'
|
||||
if(doAppend)$.monitorStates.monitors.append(html)
|
||||
return html
|
||||
}
|
||||
$.monitorStates.e.find('.add').click(function(e){
|
||||
$.monitorStates.add(null,true)
|
||||
})
|
||||
$.monitorStates.e.on('change','.json',function(e){
|
||||
var el = $(this)
|
||||
var val = el.val()
|
||||
try{
|
||||
el.css('border-color','green')
|
||||
var parsed = JSON.parse(val)
|
||||
el.val(JSON.stringify(parsed,null,3))
|
||||
}catch(err){
|
||||
el.css('border-color','red')
|
||||
return $.ccio.init('note',{title:lang['Invalid JSON'],text:lang.InvalidJSONText,type:'error'})
|
||||
}
|
||||
})
|
||||
$.monitorStates.e.on('click','.delete',function(e){
|
||||
$.confirm.e.modal('show');
|
||||
$.confirm.title.text(lang['Delete Monitor States Preset']);
|
||||
$.confirm.body.html(lang.deleteMonitorStateText1);
|
||||
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||
var form = $.monitorStates.f.serializeObject()
|
||||
$.post($.ccio.init('location',$user) + $user.auth_token + '/monitorStates/' + $user.ke + '/' + form.name + '/delete',function(d){
|
||||
$.ccio.log(d)
|
||||
if(d.ok === true){
|
||||
$.monitorStates.loadPresets()
|
||||
$.ccio.init('note',{title:lang.Success,text:d.msg,type:'success'})
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
$.monitorStates.e.on('click','.delete-monitor',function(e){
|
||||
var el = $(this).parents('.state-monitor-row')
|
||||
$.confirm.e.modal('show');
|
||||
$.confirm.title.text(lang['Delete Monitor State']);
|
||||
$.confirm.body.html(lang.deleteMonitorStateText2)
|
||||
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||
el.remove()
|
||||
})
|
||||
})
|
||||
$.monitorStates.selector.change(function(e){
|
||||
var selected = $(this).val()
|
||||
var loaded = $.monitorStates.loaded[selected]
|
||||
var namespace = $.monitorStates.e.find('[name="name"]')
|
||||
var deleteButton = $.monitorStates.e.find('.delete')
|
||||
if(loaded){
|
||||
namespace.val(loaded.name)
|
||||
var html = ''
|
||||
$.each(loaded.details.monitors,function(n,v){
|
||||
html += $.monitorStates.add(v)
|
||||
})
|
||||
$.monitorStates.monitors.html(html)
|
||||
deleteButton.show()
|
||||
}else{
|
||||
namespace.val('')
|
||||
$.monitorStates.monitors.empty()
|
||||
deleteButton.hide()
|
||||
}
|
||||
})
|
||||
$.monitorStates.f.submit(function(e){
|
||||
e.preventDefault()
|
||||
var el = $(this)
|
||||
var form = el.serializeObject()
|
||||
var monitors = []
|
||||
var failedToParseAJson = false
|
||||
var rows = $.monitorStates.monitors.find('.state-monitor-row')
|
||||
if(form.name === ''){
|
||||
return $.ccio.init('note',{title:lang['Invalid Data'],text:lang['Name cannot be empty.'],type:'error'})
|
||||
}
|
||||
if(rows.length === 0){
|
||||
return $.ccio.init('note',{title:lang['Invalid Data'],text:lang['Must be atleast one row'],type:'error'})
|
||||
}
|
||||
rows.each(function(n,v){
|
||||
var el = $(v)
|
||||
try{
|
||||
console.log(el.find('.json').val())
|
||||
var json = JSON.parse(el.find('.json').val())
|
||||
if(json.mid)monitors.push(json)
|
||||
}catch(err){
|
||||
console.log(err)
|
||||
failedToParseAJson = true
|
||||
}
|
||||
})
|
||||
if(failedToParseAJson === true){
|
||||
return $.ccio.init('note',{title:lang['Invalid JSON'],text:lang.InvalidJSONText,type:'error'})
|
||||
}
|
||||
var data = {
|
||||
monitors: monitors
|
||||
}
|
||||
$.post($.ccio.init('location',$user) + $user.auth_token + '/monitorStates/' + $user.ke + '/' + form.name + '/insert',{data:data},function(d){
|
||||
$.ccio.log(d)
|
||||
if(d.ok === true){
|
||||
$.monitorStates.loadPresets(function(){
|
||||
$.monitorStates.selector.val(form.name)
|
||||
})
|
||||
$.ccio.init('note',{title:lang.Success,text:d.msg,type:'success'})
|
||||
}
|
||||
})
|
||||
return false;
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<script src="<%-window.libURL%>libs/js/dash2.monitorStates.js"></script>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,10 +13,10 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th><div class="checkbox"><input id="multimon_select_all" type="checkbox"><label for="multimon_select_all"></label></div></th>
|
||||
<th> </th>
|
||||
<th><%-lang['Name']%></th>
|
||||
<th><%-lang['Mode']%></th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th><%-lang['Stream']%></th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -25,7 +25,7 @@
|
|||
</table>
|
||||
</form>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default pull-left" data-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-default pull-left" data-dismiss="modal"><%-lang.Close%></button>
|
||||
<div>
|
||||
<a class="btn btn-danger delete"><%-lang['Delete']%></a>
|
||||
<a class="btn btn-primary save_config"><%-lang['Export']%></a>
|
||||
|
|
85
web/pages/blocks/powerVideo2.ejs
Normal file
85
web/pages/blocks/powerVideo2.ejs
Normal file
|
@ -0,0 +1,85 @@
|
|||
<!--Video File Window-->
|
||||
<div class="modal full fade dark" id="powerVideo" role="dialog" aria-labelledby="powerVideoLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title" id="powerVideoLabel"><i class="fa fa-map-marker"></i> <%-lang['Power Video Viewer']%><span style="display:none" class="_loading"> <i class="fa fa-pulse fa-spinner"></i></span></h4>
|
||||
</div>
|
||||
<div class="modal-body" style="overflow:inherit">
|
||||
<div class="row">
|
||||
<div class="col-md-4" id="powerVideoTabs" tab-chooser-parent>
|
||||
<div class="form-group-group grey text-center">
|
||||
<h4></h4>
|
||||
<div class="btn-group" id="powerVideoTabButtons">
|
||||
<button type="button" class="btn btn-primary btn-sm" tab-chooser="monitors"><%- lang.Monitors %></button>
|
||||
<button type="button" class="btn btn-primary btn-sm" tab-chooser="settings"><%- lang['Search Settings'] %></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group-group grey" tab-section="monitors" style="max-height:265px;overflow:auto;">
|
||||
<h4><%-lang.Monitors%></h4>
|
||||
<div id="powerVideoMonitorsList" class="list-group"></div>
|
||||
</div>
|
||||
<div class="form-group-group grey" tab-section="settings" style="display:none">
|
||||
<h4><%- lang['Search Settings'] %></h4>
|
||||
<div class="form-group">
|
||||
<label><%- lang['Date Range'] %></label>
|
||||
<input id="powerVideoDateRange" class="form-control"></input>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label><%- lang['Video Limit'] %> <small>(<%- lang['Per Monitor'] %>)</small></label>
|
||||
<input id="powerVideoVideoLimit" class="form-control" placeholder="0"></input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label><%- lang['Event Limit'] %> <small>(<%- lang['Per Monitor'] %>)</small></label>
|
||||
<input id="powerVideoEventLimit" class="form-control" placeholder="500"></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div id="powerVideoMonitorViews"></div>
|
||||
<div id="powerVideoMonitorControls" class="text-center">
|
||||
<div class="btn-group">
|
||||
<button type="button" powerVideo-control="toggleZoom" class="btn btn-sm btn-default" title="<%- lang['Zoom In'] %>"> <i class="fa fa-search-plus"></i> </button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" powerVideo-control="previousVideoAll" class="btn btn-sm btn-default" title="<%- lang['Previous Video'] %>"> <i class="fa fa-arrow-circle-left"></i> </button>
|
||||
<button type="button" powerVideo-control="playAll" class="btn btn-sm btn-danger" title="<%- lang.Play %>"> <i class="fa fa-play"></i> </button>
|
||||
<button type="button" powerVideo-control="pauseAll" class="btn btn-sm btn-default" title="<%- lang.Pause %>"> <i class="fa fa-pause"></i> </button>
|
||||
<button type="button" powerVideo-control="nextVideoAll" class="btn btn-sm btn-default" title="<%- lang['Next Video'] %>"> <i class="fa fa-arrow-circle-right"></i> </button>
|
||||
</div>
|
||||
<div class="btn-group" style="font-family: monospace;">
|
||||
<button type="button" powerVideo-control="playSpeedAll" data-speed="1" class="btn btn-sm btn-default">1</button>
|
||||
<button type="button" powerVideo-control="playSpeedAll" data-speed="5" class="btn btn-sm btn-default">5</button>
|
||||
<button type="button" powerVideo-control="playSpeedAll" data-speed="10" class="btn btn-sm btn-default">10</button>
|
||||
<button type="button" powerVideo-control="playSpeedAll" data-speed="15" class="btn btn-sm btn-default">15</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12" style="margin-top:10px;">
|
||||
<div id="powerVideoTimelineStrips">
|
||||
<div class="loading"><i class="fa fa-hand-pointer-o"></i><div class="epic-text"><%- lang['Select a Monitor'] %></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal"><%-lang['Close']%></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/vis.min.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.powerVideo2.css">
|
||||
<script src="<%-window.libURL%>libs/js/vis.min.js" async></script>
|
||||
<script src="<%-window.libURL%>libs/js/dash2.powerVideo2.js" async></script>
|
|
@ -69,7 +69,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Camera Password']%></span></div>
|
||||
<div><input class="form-control" name="pass"></div>
|
||||
<div><input class="form-control" type="password" name="pass"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group text-right">
|
||||
|
|
|
@ -35,16 +35,195 @@
|
|||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Timezone Offset']%></span></div>
|
||||
<div><select class="form-control" name="timezone">
|
||||
<% [
|
||||
{
|
||||
"text": "UTC−12:00, Y",
|
||||
"value": -720
|
||||
},
|
||||
{
|
||||
"text": "UTC−11:00, X",
|
||||
"value": -660
|
||||
},
|
||||
{
|
||||
"text": "UTC−10:00, W",
|
||||
"value": -600
|
||||
},
|
||||
{
|
||||
"text": "UTC−09:30, V†",
|
||||
"value": -570
|
||||
},
|
||||
{
|
||||
"text": "UTC−09:00, V",
|
||||
"value": -540
|
||||
},
|
||||
{
|
||||
"text": "UTC−08:00, U",
|
||||
"value": -480
|
||||
},
|
||||
{
|
||||
"text": "UTC−07:00, T",
|
||||
"value": -420
|
||||
},
|
||||
{
|
||||
"text": "UTC−06:00, S",
|
||||
"value": -360
|
||||
},
|
||||
{
|
||||
"text": "UTC−05:00, R",
|
||||
"value": -300
|
||||
},
|
||||
{
|
||||
"text": "UTC−04:00, Q",
|
||||
"value": -240
|
||||
},
|
||||
{
|
||||
"text": "UTC−03:30, P†",
|
||||
"value": -210
|
||||
},
|
||||
{
|
||||
"text": "UTC−03:00, P",
|
||||
"value": -180
|
||||
},
|
||||
{
|
||||
"text": "UTC−02:00, O",
|
||||
"value": -120
|
||||
},
|
||||
{
|
||||
"text": "UTC−01:00, N",
|
||||
"value": -60
|
||||
},
|
||||
{
|
||||
"text": "UTC±00:00, Z",
|
||||
"value": 0,
|
||||
"selected": true
|
||||
},
|
||||
{
|
||||
"text": "UTC+01:00, A",
|
||||
"value": 60
|
||||
},
|
||||
{
|
||||
"text": "UTC+02:00, B",
|
||||
"value": 120
|
||||
},
|
||||
{
|
||||
"text": "UTC+03:00, C",
|
||||
"value": 180
|
||||
},
|
||||
{
|
||||
"text": "UTC+03:30, C†",
|
||||
"value": 210
|
||||
},
|
||||
{
|
||||
"text": "UTC+04:00, D",
|
||||
"value": 240
|
||||
},
|
||||
{
|
||||
"text": "UTC+04:30, D†",
|
||||
"value": 270
|
||||
},
|
||||
{
|
||||
"text": "UTC+05:00, E",
|
||||
"value": 300
|
||||
},
|
||||
{
|
||||
"text": "UTC+05:30, E†",
|
||||
"value": 330
|
||||
},
|
||||
{
|
||||
"text": "UTC+05:45, E*",
|
||||
"value": 345
|
||||
},
|
||||
{
|
||||
"text": "UTC+06:00, F",
|
||||
"value": 360
|
||||
},
|
||||
{
|
||||
"text": "UTC+06:30, F†",
|
||||
"value": 390
|
||||
},
|
||||
{
|
||||
"text": "UTC+07:00, G",
|
||||
"value": 420
|
||||
},
|
||||
{
|
||||
"text": "UTC+08:00, H",
|
||||
"value": 480
|
||||
},
|
||||
{
|
||||
"text": "UTC+08:45, H*",
|
||||
"value": 525
|
||||
},
|
||||
{
|
||||
"text": "UTC+09:00, I",
|
||||
"value": 540
|
||||
},
|
||||
{
|
||||
"text": "UTC+09:30, I†",
|
||||
"value": 570
|
||||
},
|
||||
{
|
||||
"text": "UTC+10:00, K",
|
||||
"value": 600
|
||||
},
|
||||
{
|
||||
"text": "UTC+10:30, K†",
|
||||
"value": 630
|
||||
},
|
||||
{
|
||||
"text": "UTC+11:00, L",
|
||||
"value": 660
|
||||
},
|
||||
{
|
||||
"text": "UTC+12:00, M",
|
||||
"value": 720
|
||||
},
|
||||
{
|
||||
"text": "UTC+12:45, M*",
|
||||
"value": 765
|
||||
},
|
||||
{
|
||||
"text": "UTC+13:00, M†",
|
||||
"value": 780
|
||||
},
|
||||
{
|
||||
"text": "UTC+14:00, M†",
|
||||
"value": 840
|
||||
}
|
||||
].forEach(function(option){
|
||||
var selected = ''
|
||||
if(option.selected)selected = 'selected'
|
||||
%>
|
||||
<option value="<%- option.value %>" <%- selected %>><%- option.text %></option>
|
||||
<% }) %>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Start']%></span></div>
|
||||
<div><input class="form-control" name="start" placeholder="HH:ss"></div>
|
||||
<div><input class="form-control" name="start" placeholder="HH:mm"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['End']%></span></div>
|
||||
<div><input class="form-control" name="end" placeholder="HH:ss"></div>
|
||||
<div><input class="form-control" name="end" placeholder="HH:mm"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Days']%></span></div>
|
||||
<div><select class="form-control" style="min-height:100px" multiple name="days">
|
||||
<option value="0"><%- lang.Sunday %></option>
|
||||
<option value="1"><%- lang.Monday %></option>
|
||||
<option value="2"><%- lang.Tuesday %></option>
|
||||
<option value="3"><%- lang.Wednesday %></option>
|
||||
<option value="4"><%- lang.Thursday %></option>
|
||||
<option value="5"><%- lang.Friday %></option>
|
||||
<option value="6"><%- lang.Saturday %></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Monitor States']%></span></div>
|
||||
<div><select class="form-control" style="min-height:100px" multiple name="monitorStates">
|
||||
|
@ -60,120 +239,4 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$.schedules = {
|
||||
e: $('#schedules'),
|
||||
selector: $('#schedulesSelector'),
|
||||
loadedMonitorStates: {},
|
||||
loadedSchedules: {}
|
||||
}
|
||||
$.schedules.f = $.schedules.e.find('form')
|
||||
$.schedules.selectedStates = $.schedules.e.find('[name="monitorStates"]')
|
||||
$.schedules.loadSchedules = function(callback){
|
||||
$.get($.ccio.init('location',$user) + $user.auth_token + '/schedule/' + $user.ke,function(d){
|
||||
console.log(d)
|
||||
var html = ''
|
||||
$.each(d.schedules,function(n,v){
|
||||
$.schedules.loadedSchedules[v.name] = v
|
||||
html += $.ccio.tm('option',{
|
||||
id: v.name,
|
||||
name: v.name
|
||||
})
|
||||
})
|
||||
$.schedules.selector.find('optgroup').html(html)
|
||||
if(callback)callback()
|
||||
})
|
||||
}
|
||||
$.schedules.loadMonitorStates = function(){
|
||||
$.get($.ccio.init('location',$user) + $user.auth_token + '/monitorStates/' + $user.ke,function(d){
|
||||
var html = ''
|
||||
$.each(d.presets,function(n,v){
|
||||
$.schedules.loadedMonitorStates[v.name] = v
|
||||
html += $.ccio.tm('option',{
|
||||
id: v.name,
|
||||
name: v.name
|
||||
})
|
||||
})
|
||||
$.schedules.selectedStates.html(html)
|
||||
})
|
||||
}
|
||||
$.schedules.e.on('shown.bs.modal', function (e) {
|
||||
$.schedules.loadMonitorStates()
|
||||
$.schedules.loadSchedules()
|
||||
})
|
||||
$.schedules.e.on('click','.delete',function(e){
|
||||
$.confirm.e.modal('show');
|
||||
$.confirm.title.text(lang['Delete Monitor States Preset']);
|
||||
$.confirm.body.html(lang.deleteMonitorStateText1);
|
||||
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||
var form = $.schedules.f.serializeObject()
|
||||
$.post($.ccio.init('location',$user) + $user.auth_token + '/schedule/' + $user.ke + '/' + form.name + '/delete',function(d){
|
||||
$.ccio.log(d)
|
||||
if(d.ok === true){
|
||||
$.schedules.loadSchedules()
|
||||
$.ccio.init('note',{title:lang.Success,text:d.msg,type:'success'})
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
$.schedules.selector.change(function(e){
|
||||
var selected = $(this).val()
|
||||
var loaded = $.schedules.loadedSchedules[selected]
|
||||
var namespace = $.schedules.e.find('[name="name"]')
|
||||
var deleteButton = $.schedules.e.find('.delete')
|
||||
$.schedules.selectedStates.find('option:selected').removeAttr('selected')
|
||||
if(loaded){
|
||||
namespace.val(loaded.name)
|
||||
var html = ''
|
||||
$.each(loaded,function(n,v){
|
||||
$.schedules.f.find('[name="' + n + '"]').val(v)
|
||||
})
|
||||
$.each(loaded.details.monitorStates,function(n,v){
|
||||
$.schedules.selectedStates.find('option[value="' + v + '"]').prop('selected',true)
|
||||
})
|
||||
deleteButton.show()
|
||||
}else{
|
||||
namespace.val('')
|
||||
deleteButton.hide()
|
||||
}
|
||||
})
|
||||
$.schedules.f.submit(function(e){
|
||||
e.preventDefault()
|
||||
var el = $(this)
|
||||
var form = el.serializeObject()
|
||||
var monitors = []
|
||||
var failedToParseAJson = false
|
||||
var rows = $.monitorStates.monitors.find('.state-monitor-row')
|
||||
if(form.name === ''){
|
||||
return $.ccio.init('note',{title:lang['Invalid Data'],text:lang['Name cannot be empty.'],type:'error'})
|
||||
}
|
||||
if(form.start === ''){
|
||||
return $.ccio.init('note',{title:lang['Invalid Data'],text:lang['Start Time cannot be empty.'],type:'error'})
|
||||
}
|
||||
if(form.monitorStates instanceof Array === false){
|
||||
form.monitorStates = [form.monitorStates]
|
||||
}
|
||||
console.log(form.monitorStates)
|
||||
|
||||
var data = {
|
||||
start: form.start,
|
||||
end: form.end,
|
||||
enabled: form.enabled,
|
||||
details:{
|
||||
monitorStates: form.monitorStates
|
||||
}
|
||||
}
|
||||
$.post($.ccio.init('location',$user) + $user.auth_token + '/schedule/' + $user.ke + '/' + form.name + '/insert',{data:data},function(d){
|
||||
$.ccio.log(d)
|
||||
if(d.ok === true){
|
||||
$.schedules.loadSchedules(function(){
|
||||
$.schedules.selector.val(form.name)
|
||||
})
|
||||
$.ccio.init('note',{title:lang.Success,text:d.msg,type:'success'})
|
||||
}
|
||||
})
|
||||
return false;
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<script src="<%-window.libURL%>libs/js/dash2.schedules.js"></script>
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
<h4 class="modal-title" id="settingsLabel"><i class="fa fa-gears"></i> <%-lang.Settings%></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-2 hidden-xs follow-list">
|
||||
<ul class="affix"></ul>
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
<div class="text-center msg"></div>
|
||||
<div class="form-group-group green">
|
||||
<h4><%-lang['Account Info']%></h4>
|
||||
|
@ -24,597 +29,251 @@
|
|||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group-group grey">
|
||||
<h4><%-lang['2-Factor Authentication']%></h4>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Enabled']%></span></div>
|
||||
<div><select class="form-control" detail="factorAuth">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Email%></span></div>
|
||||
<div><select class="form-control" detail="factor_mail">
|
||||
<option value="1" selected><%-lang.Yes%></option>
|
||||
<option value="0"><%-lang.No%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group u_discord_bot_input u_discord_bot_1">
|
||||
<label><div><span><%-lang.Discord%></span></div>
|
||||
<div><select class="form-control" detail="factor_discord">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group-group grey">
|
||||
<h4><%-lang.Profile%></h4>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Email%></span></div>
|
||||
<div><input class="form-control" type="email" name="mail"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Password%> <small><%-lang.blankPassword%></small></span></div>
|
||||
<div><input class="form-control" type="password" name="pass"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Password%> <%-lang.Again%></span></div>
|
||||
<div><input class="form-control" type="password" name="password_again"></div>
|
||||
</label>
|
||||
</div>
|
||||
<% if(!details.sub){ %>
|
||||
<% if(details.edit_size!=='0'){ %>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Max Storage Amount']%></span></div>
|
||||
<div><input class="form-control" detail="size" placeholder="10000"></div>
|
||||
</label>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if(details.edit_days!=='0'){ %>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Number of Days to keep']%> <%-lang.Videos%></span></div>
|
||||
<div><input class="form-control" detail="days" placeholder="5"></div>
|
||||
</label>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if(details.edit_event_days!=='0'){ %>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Number of Days to keep']%> <%-lang.Events%></span></div>
|
||||
<div><input class="form-control" detail="event_days" placeholder="10"></div>
|
||||
</label>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if(details.edit_log_days!=='0'){ %>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Number of Days to keep']%> <%-lang.Logs%></span></div>
|
||||
<div><input class="form-control" detail="log_days" placeholder="10"></div>
|
||||
</label>
|
||||
</div>
|
||||
<% } %>
|
||||
<% } %>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Dashboard Language']%></span></div>
|
||||
<div>
|
||||
<select class="form-control" detail="lang">
|
||||
<option value="" selected>Default</option>
|
||||
<% fs.readdirSync('./languages').forEach(function(v,n){
|
||||
v=v.replace('.json','') %>
|
||||
<option value="<%-v%>"><%-v%></option>
|
||||
<% }) %>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Notification Sound']%></span></div>
|
||||
<div>
|
||||
<select class="form-control" detail="audio_note">
|
||||
<option value="" selected>No Sound</option>
|
||||
<% audioFiles.forEach(function(v,n){ %>
|
||||
<option value="<%-v%>"><%-v%></option>
|
||||
<%
|
||||
var buildOptions = function(field,possiblities){
|
||||
if(!field)console.error('field',field)
|
||||
var fieldElement = ''
|
||||
possiblities.forEach(function(option){
|
||||
if(option.optgroup){
|
||||
fieldElement += '<optgroup label="' + option.name + '">'
|
||||
fieldElement += buildOptions(field,option.optgroup)
|
||||
fieldElement += '</optgroup>'
|
||||
}else{
|
||||
var selected = ''
|
||||
if(option.value === field.default){
|
||||
selected = 'selected'
|
||||
}
|
||||
fieldElement += '<option value="' + option.value + '" ' + selected + '>' + option.name + '</option>'
|
||||
}
|
||||
})
|
||||
return fieldElement
|
||||
}
|
||||
var drawBlock = function(userSettings){
|
||||
if(userSettings.evaluation && !eval(userSettings.evaluation)){
|
||||
return
|
||||
}
|
||||
var attributes = []
|
||||
var styles = []
|
||||
var sectionClass = []
|
||||
var headerTitle = userSettings.headerTitle || lang[userSettings.name] || userSettings.name
|
||||
if(userSettings.hidden === true){
|
||||
styles.push('display:none')
|
||||
}
|
||||
if(userSettings.style){
|
||||
styles.push(userSettings.style)
|
||||
}
|
||||
if(userSettings.isSection === true){
|
||||
attributes.push('section')
|
||||
}
|
||||
if(userSettings.attribute){
|
||||
attributes.push(userSettings.attribute)
|
||||
}
|
||||
if(userSettings.id){
|
||||
attributes.push(`id="${userSettings.id}"`)
|
||||
}else{
|
||||
var userSettingsId
|
||||
if(userSettings.name){
|
||||
userSettingsId = userSettings.name.replace(/[^a-zA-Z ]/g, '').replace(/[^a-zA-Z ]/g, '').replace(/ /g, '')
|
||||
}else{
|
||||
userSettingsId = "NO NAME"
|
||||
}
|
||||
userSettings.id = userSettingsId
|
||||
attributes.push(`id="${userSettingsId}"`)
|
||||
}
|
||||
if(userSettings.color){
|
||||
sectionClass.push(userSettings.color)
|
||||
}
|
||||
if(userSettings['section-class']){
|
||||
sectionClass.push(userSettings['section-class'])
|
||||
}
|
||||
if(userSettings.isAdvanced){ %>
|
||||
<div class="h_us_input h_us_advanced">
|
||||
<% }
|
||||
if(userSettings['section-pre-pre-class']){ %>
|
||||
<div class="<%- userSettings['section-pre-pre-class'] %>">
|
||||
<% }
|
||||
if(userSettings['section-pre-class']){ %>
|
||||
<div class="<%- userSettings['section-pre-class'] %>">
|
||||
<% }
|
||||
%>
|
||||
<div <%- attributes.join(' ') %> style="<%- styles.join(';') %>" class="form-group-group <%- sectionClass.join(' ') %>">
|
||||
<h4 class="<%- userSettings.headerClass %>"><%- headerTitle %>
|
||||
<% if(userSettings.headerButtons){ %>
|
||||
<div class="pull-right">
|
||||
<% userSettings.headerButtons.forEach(function(button){ %>
|
||||
<a class="btn btn-success btn-xs <%- button.class %>">
|
||||
<% if(button.icon){ %><i class="fa fa-<%- button.icon %>"></i><% } %>
|
||||
<% if(button.text){ %><%- button.text %><% } %>
|
||||
</a>
|
||||
<% }) %>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Alert Sound']%></span></div>
|
||||
<div>
|
||||
<select class="form-control" detail="audio_alert">
|
||||
<option value="" selected>No Sound</option>
|
||||
<% audioFiles.forEach(function(v,n){ %>
|
||||
<option value="<%-v%>"><%-v%></option>
|
||||
<% }) %>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Alert Sound Delay']%></span></div>
|
||||
<div><input class="form-control" detail="audio_delay" placeholder="1"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Popout Monitor on Event']%></span></div>
|
||||
<div><select class="form-control" detail="event_mon_pop">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</h4>
|
||||
<% if(userSettings['input-mapping']){ %>
|
||||
<div class="form-group-group forestgreen" style="display:none" input-mapping="<%- userSettings['input-mapping'] %>">
|
||||
<h4><%-lang['Input Feed']%>
|
||||
<div class="pull-right">
|
||||
<a class="btn btn-success btn-xs add_map_row"><i class="fa fa-plus-square-o"></i></a>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="choices"></div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if(userSettings.blockquote){ %>
|
||||
<blockquote class="<%- userSettings.blockquoteClass || '' %>">
|
||||
<%- userSettings.blockquote %>
|
||||
</blockquote>
|
||||
<% } %>
|
||||
|
||||
<%
|
||||
if(userSettings.blocks){
|
||||
userSettings.blocks.forEach(function(settingsBlock){
|
||||
drawBlock(settingsBlock)
|
||||
})
|
||||
}
|
||||
if(userSettings.info){
|
||||
userSettings.info.forEach(function(field){
|
||||
if(field.isFormGroupGroup === true){
|
||||
drawBlock(field)
|
||||
}else{
|
||||
if(field.notForSubAccount === true){
|
||||
var notForSubAccount = '!details.sub'
|
||||
if(!field.evaluation){
|
||||
field.evaluation = notForSubAccount
|
||||
}else{
|
||||
field.evaluation += ' && ' + notForSubAccount
|
||||
}
|
||||
}
|
||||
if(field.evaluation && !eval(field.evaluation)){
|
||||
return
|
||||
}
|
||||
var hidden = ''
|
||||
if(field.hidden === true){
|
||||
hidden = 'style="display:none"'
|
||||
}
|
||||
var fieldClass = []
|
||||
var attributes = []
|
||||
if(field.name && field.name.indexOf('detail=') > -1){
|
||||
attributes.push(field.name)
|
||||
}else if(field.name){
|
||||
attributes.push("name=" + field.name)
|
||||
}
|
||||
if(field.placeholder || field.default){
|
||||
attributes.push(`placeholder="${field.placeholder || field.default}"`)
|
||||
}else if(field.example){
|
||||
attributes.push(`placeholder="Example : ${field.example}"`)
|
||||
}
|
||||
if(field.attribute){
|
||||
attributes.push(field.attribute)
|
||||
}
|
||||
if(field.selector){
|
||||
attributes.push(`selector="${field.selector}"`)
|
||||
}
|
||||
if(field.id){
|
||||
attributes.push(`id="${field.id}"`)
|
||||
}
|
||||
if(field.class){
|
||||
fieldClass.push(`${field.class}`)
|
||||
}
|
||||
var possiblities = field.possible || []
|
||||
var fieldType = field.fieldType || 'text'
|
||||
var fieldElement = ''
|
||||
var preFill = field.preFill || ''
|
||||
switch(fieldType){
|
||||
case'btn':
|
||||
|
||||
fieldElement = `<a class="btn btn-block ${fieldClass.join(' ')}" ${attributes.join(' ')}>${field.btnContent}</a>`
|
||||
break;
|
||||
case'ul':
|
||||
fieldElement = `<ul ${attributes.join(' ')} class="${fieldClass.join(' ')}" ></ul>`
|
||||
break;
|
||||
case'div':
|
||||
fieldElement = `<div ${attributes.join(' ')} class="${fieldClass.join(' ')}" ></div>`
|
||||
break;
|
||||
case'number':
|
||||
if(field.numberMin){
|
||||
attributes.push(`min="${field.numberMin}"`)
|
||||
}
|
||||
if(field.numberMax){
|
||||
attributes.push(`max="${field.numberMax}"`)
|
||||
}
|
||||
fieldElement = '<div><input type="number" class="form-control" ' + attributes.join(' ') + '></div>'
|
||||
break;
|
||||
case'password':
|
||||
fieldElement = '<div><input type="password" class="form-control" ' + attributes.join(' ') + '></div>'
|
||||
break;
|
||||
case'text':
|
||||
fieldElement = `<div><input class="form-control" ${attributes.join(' ')} value="${preFill}"></div>`
|
||||
break;
|
||||
case'textarea':
|
||||
fieldElement = '<div><textarea class="form-control" ' + attributes.join(' ') + '></textarea></div>'
|
||||
break;
|
||||
case'select':
|
||||
fieldElement = '<div><select class="form-control" ' + attributes.join(' ') + '>'
|
||||
fieldElement += buildOptions(field,possiblities)
|
||||
fieldElement += '</select></div>'
|
||||
break;
|
||||
}
|
||||
if(field.isAdvanced){ %>
|
||||
<div class="h_us_input h_us_advanced">
|
||||
<% }
|
||||
if(field['form-group-class-pre-pre-layer']){ %>
|
||||
<div class="<%- field['form-group-class-pre-pre-layer'] %>">
|
||||
<% }
|
||||
if(field['form-group-class-pre-layer']){ %>
|
||||
<div class="<%- field['form-group-class-pre-layer'] %>">
|
||||
<% }
|
||||
if(fieldType === 'ul' || fieldType === 'div' || fieldType === 'btn'){ %>
|
||||
<%- fieldElement %>
|
||||
<% }else{ %>
|
||||
<div <%- hidden %> class="form-group <%- field['form-group-class'] %>">
|
||||
<label><div><span><%- field.field %>
|
||||
<% if(field.description){ %>
|
||||
<small><%- field.description %></small>
|
||||
<% } %>
|
||||
</span></div>
|
||||
<%- fieldElement %>
|
||||
</label>
|
||||
</div>
|
||||
<% }
|
||||
}
|
||||
if(field['form-group-class-pre-layer']){ %>
|
||||
</div>
|
||||
<% }
|
||||
if(field['form-group-class-pre-pre-layer']){ %>
|
||||
</div>
|
||||
<% }
|
||||
if(field.isAdvanced){ %>
|
||||
</div>
|
||||
<% }
|
||||
})
|
||||
}
|
||||
%>
|
||||
</div>
|
||||
<% if(!details.sub){ %>
|
||||
<div class="form-group-group blue">
|
||||
<h4 class="mon_groups">
|
||||
<%-lang['Monitor Groups']%>
|
||||
<div class="pull-right">
|
||||
<a class="btn btn-success btn-xs add"><i class="fa fa-plus"></i></a>
|
||||
<a class="btn btn-danger btn-xs delete"><i class="fa fa-trash-o"></i></a>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Monitor Groups']%></span></div>
|
||||
<div><select class="form-control" id="settings_mon_groups"></select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Group Name']%></span></div>
|
||||
<div><input type="hidden" group="id">
|
||||
<input class="form-control" group="name"></div>
|
||||
</label>
|
||||
</div>
|
||||
<input type="hidden" detail="mon_groups">
|
||||
<%
|
||||
if(userSettings['section-pre-class']){ %>
|
||||
</div>
|
||||
<% if(details.use_webdav!=='0'){ %>
|
||||
<div class="form-group-group forestgreen">
|
||||
<h4><%-lang.WebDAV%></h4>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Autosave%></span></div>
|
||||
<div><select class="form-control" detail="webdav_save" selector="autosave_webdav">
|
||||
<option value="0"><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="autosave_webdav_input autosave_webdav_1">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.URL%></span></div>
|
||||
<div><input class="form-control" detail="webdav_url"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-12">
|
||||
<label><div><span><%-lang.Username%></span></div>
|
||||
<div><input class="form-control" detail="webdav_user"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group col-md-12">
|
||||
<label><div><span><%-lang.Password%></span></div>
|
||||
<div><input class="form-control" type="password" detail="webdav_pass"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Save Links to Database']%></span></div>
|
||||
<div><select class="form-control" detail="webdav_log" selector="h_webdavsld">
|
||||
<option value="0"><%-lang.No%></option>
|
||||
<option value="1" selected><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="h_webdavsld_input h_webdavsld_1">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Use Max Storage Amount']%></span></div>
|
||||
<div><select class="form-control" detail="use_webdav_size_limit" selector="h_webdavzl">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group h_webdavzl_input h_webdavzl_1">
|
||||
<label><div><span><%-lang['Max Storage Amount']%></span></div>
|
||||
<div><input class="form-control" placeholder="10000" detail="webdav_size_limit"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Save Directory']%></span></div>
|
||||
<div><input class="form-control" placeholder="/" detail="webdav_dir"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if(details.use_aws_s3!=='0'){ %>
|
||||
<div class="form-group-group forestgreen">
|
||||
<h4><%-lang['Amazon S3']%></h4>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Autosave%></span></div>
|
||||
<div><select class="form-control" detail="aws_s3_save" selector="autosave_aws_s3">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="autosave_aws_s3_input autosave_aws_s3_1">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Bucket%></span></div>
|
||||
<div><input class="form-control" detail="aws_s3_bucket" placeholder="Example : slippery-seal"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-12">
|
||||
<label><div><span><%-lang.aws_accessKeyId%></span></div>
|
||||
<div><input class="form-control" detail="aws_accessKeyId"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group col-md-12">
|
||||
<label><div><span><%-lang.aws_secretAccessKey%></span></div>
|
||||
<div><input class="form-control" type="password" detail="aws_secretAccessKey"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Region%></span></div>
|
||||
<div><select class="form-control" detail="aws_region">
|
||||
<option value="us-west-1" selected>US West (N. California)</option>
|
||||
<option value="us-west-2">US West (Oregon)</option>
|
||||
<option value="us-east-2">US East (Ohio)</option>
|
||||
<option value="us-east-1">US East (N. Virginia)</option>
|
||||
<option value="ap-south-1">Asia Pacific (Mumbai)</option>
|
||||
<option value="ap-northeast-2">Asia Pacific (Seoul)</option>
|
||||
<option value="ap-northeast-3">Asia Pacific (Osaka-Local)**</option>
|
||||
<option value="ap-southeast-1">Asia Pacific (Singapore)</option>
|
||||
<option value="ap-southeast-2">Asia Pacific (Sydney)</option>
|
||||
<option value="ap-northeast-1">Asia Pacific (Tokyo)</option>
|
||||
<option value="ca-central-1">Canada (Central)</option>
|
||||
<option value="cn-north-1">China (Beijing)</option>
|
||||
<option value="cn-northwest-1">China (Ningxia)</option>
|
||||
<option value="eu-central-1">EU (Frankfurt)</option>
|
||||
<option value="eu-west-1">EU (Ireland)</option>
|
||||
<option value="eu-west-2">EU (London)</option>
|
||||
<option value="eu-west-3">EU (Paris)</option>
|
||||
<option value="sa-east-1">South America (São Paulo)</option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Save Links to Database']%></span></div>
|
||||
<div><select class="form-control" detail="aws_s3_log" selector="h_s3sld">
|
||||
<option value="0"><%-lang.No%></option>
|
||||
<option value="1" selected><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="h_s3sld_input h_s3sld_1">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Use Max Storage Amount']%></span></div>
|
||||
<div><select class="form-control" detail="use_aws_s3_size_limit" selector="h_s3zl">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group h_s3zl_input h_s3zl_1">
|
||||
<label><div><span><%-lang['Max Storage Amount']%></span></div>
|
||||
<div><input class="form-control" placeholder="10000" detail="aws_s3_size_limit"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Save Directory']%></span></div>
|
||||
<div><input class="form-control" placeholder="" detail="aws_s3_dir"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if(details.use_bb_b2!=='0'){ %>
|
||||
<div class="form-group-group forestgreen">
|
||||
<h4><%-lang['Backblaze B2']%></h4>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Autosave%></span></div>
|
||||
<div><select class="form-control" detail="bb_b2_save" selector="autosave_bb_b2">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="autosave_bb_b2_input autosave_bb_b2_1">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Bucket%></span></div>
|
||||
<div><input class="form-control" detail="bb_b2_bucket" placeholder="Example : slippery-seal"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-12">
|
||||
<label><div><span><%-lang.accountId%></span></div>
|
||||
<div><input class="form-control" detail="bb_b2_accountId"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group col-md-12">
|
||||
<label><div><span><%-lang.applicationKey%></span></div>
|
||||
<div><input class="form-control" type="password" detail="bb_b2_applicationKey"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Save Links to Database']%></span></div>
|
||||
<div><select class="form-control" detail="bb_b2_log" selector="h_b2sld">
|
||||
<option value="0"><%-lang.No%></option>
|
||||
<option value="1" selected><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="h_b2sld_input h_b2sld_1">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Use Max Storage Amount']%></span></div>
|
||||
<div><select class="form-control" detail="use_bb_b2_size_limit" selector="h_b2zl">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group h_b2zl_input h_b2zl_1">
|
||||
<label><div><span><%-lang['Max Storage Amount']%></span></div>
|
||||
<div><input class="form-control" placeholder="10000" detail="bb_b2_size_limit"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Save Directory']%></span></div>
|
||||
<div><input class="form-control" placeholder="" detail="bb_b2_dir"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if(details.use_whcs!=='0'){ %>
|
||||
<div class="form-group-group forestgreen">
|
||||
<h4><%-lang['Wasabi Hot Cloud Storage']%></h4>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Autosave%></span></div>
|
||||
<div><select class="form-control" detail="whcs_save" selector="autosave_whcs">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="autosave_whcs_input autosave_whcs_1">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Bucket%></span></div>
|
||||
<div><input class="form-control" detail="whcs_bucket" placeholder="Example : slippery-seal"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-12">
|
||||
<label><div><span><%-lang.aws_accessKeyId%></span></div>
|
||||
<div><input class="form-control" detail="whcs_accessKeyId"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group col-md-12">
|
||||
<label><div><span><%-lang.aws_secretAccessKey%></span></div>
|
||||
<div><input class="form-control" type="password" detail="whcs_secretAccessKey"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Region%></span></div>
|
||||
<div><select class="form-control" detail="whcs_region">
|
||||
<option value="us-west-1" selected>US West</option>
|
||||
<option value="us-east-1">US East</option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Save Links to Database']%></span></div>
|
||||
<div><select class="form-control" detail="whcs_log" selector="h_whcssld">
|
||||
<option value="0"><%-lang.No%></option>
|
||||
<option value="1" selected><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="h_whcssld_input h_whcssld_1">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Use Max Storage Amount']%></span></div>
|
||||
<div><select class="form-control" detail="use_whcs_size_limit" selector="h_whcszl">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group h_whcszl_input h_whcszl_1">
|
||||
<label><div><span><%-lang['Max Storage Amount']%></span></div>
|
||||
<div><input class="form-control" placeholder="10000" detail="whcs_size_limit"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Save Directory']%></span></div>
|
||||
<div><input class="form-control" placeholder="" detail="whcs_dir"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if(details.use_sftp!=='0'){ %>
|
||||
<div class="form-group-group forestgreen">
|
||||
<h4><%-lang['SFTP (SSH File Transfer)']%></h4>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Autosave%></span></div>
|
||||
<div><select class="form-control" detail="sftp_save" selector="autosave_sftp">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="autosave_sftp_input autosave_sftp_1">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Host%></span></div>
|
||||
<div><input class="form-control" detail="sftp_host"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Port%></span></div>
|
||||
<div><input class="form-control" type="text" detail="sftp_port"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Username%></span></div>
|
||||
<div><input class="form-control" type="text" detail="sftp_username"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Password%></span></div>
|
||||
<div><input class="form-control" type="password" detail="sftp_password"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.privateKey%></span></div>
|
||||
<div><textarea class="form-control" type="password" detail="sftp_privateKey"></textarea></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Save Directory']%></span></div>
|
||||
<div><input class="form-control" placeholder="" detail="sftp_dir"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if(details.use_discordbot!=='0'){ %>
|
||||
<div class="form-group-group forestgreen">
|
||||
<h4><%-lang['Discord Bot']%></h4>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Enabled%></span></div>
|
||||
<div><select class="form-control" detail="discordbot" selector="u_discord_bot">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="u_discord_bot_input u_discord_bot_1">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Token%></span></div>
|
||||
<div><input type="password" class="form-control" placeholder="XXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXX" detail="discordbot_token"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Channel ID']%></span></div>
|
||||
<div><input class="form-control" placeholder="xxxxxxxxxxxxxxxxxx" detail="discordbot_channel"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if(details.use_ldap!=='0'){ %>
|
||||
<div class="form-group-group forestgreen">
|
||||
<h4><%-lang.LDAP%></h4>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Enable%></span></div>
|
||||
<div><select class="form-control" detail="ldap_enable" selector="ldap_i">
|
||||
<option value="0"><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="ldap_i_input ldap_i_1" style="display:none">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.URL%></span></div>
|
||||
<div><input class="form-control" detail="ldap_url"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['bindDN']%></span></div>
|
||||
<div><input class="form-control" detail="ldap_bindDN" placeholder="<%-lang.Example%> : cn=admin,dc=test,dc=com"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Bind Credentials']%></span></div>
|
||||
<div><input class="form-control" detail="ldap_bindCredentials"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Search Filter']%></span></div>
|
||||
<div><input class="form-control" detail="ldap_searchFilter" placeholder="cn={{username}}"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Search Base']%></span></div>
|
||||
<div><input class="form-control" detail="ldap_searchBase" placeholder="dc=test,dc=com"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% } %>
|
||||
<div class="form-group-group navy">
|
||||
<h4><%-lang.Preferences%></h4>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.CSS%></span></div>
|
||||
<div><textarea class="form-control" placeholder="#main_header{background:#b59f00}" detail="css"></textarea></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Force Monitors Per Row']%></span></div>
|
||||
<div><select class="form-control" localStorage="montage_use" selector="st_force_mon_rows">
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group st_force_mon_rows_input st_force_mon_rows_1">
|
||||
<label><div><span><%-lang['Monitors per row']%></span></div>
|
||||
<div><input class="form-control" placeholder="3" localStorage="montage"></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Browser Console Log']%></span></div>
|
||||
<div><select class="form-control" localStorage="browserLog">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Get Logs to Client']%></span></div>
|
||||
<div><select class="form-control" detail="get_server_log">
|
||||
<option value="1" selected><%-lang.Yes%></option>
|
||||
<option value="0"><%-lang.No%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Show Thumbnails in Video List']%></span></div>
|
||||
<div><select class="form-control" localStorage="showThumbnail">
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Themes']%></span></div>
|
||||
<div><select class="form-control" detail="theme">
|
||||
<option value="" selected>Default</option>
|
||||
<% fs.readdirSync(__dirname+'/web/libs/themes').forEach(function(v){ %>
|
||||
<option value="<%-v%>"><%-v%></option>
|
||||
<% }) %>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<% }
|
||||
if(userSettings['section-pre-pre-class']){ %>
|
||||
</div>
|
||||
<% }
|
||||
if(userSettings.isAdvanced){ %>
|
||||
</div>
|
||||
<% }
|
||||
}
|
||||
%>
|
||||
<% Object.keys(define['Account Settings'].blocks).forEach(function(blockKey){
|
||||
var accountSettings = define['Account Settings'].blocks[blockKey]
|
||||
drawBlock(accountSettings)
|
||||
}) %>
|
||||
<div class="form-group-group green linkShinobi">
|
||||
<h4><%-lang['Link Shinobi']%><div class="pull-right"><a class="btn btn-success btn-xs add"><i class="fa fa-plus"></i></a></div></h4>
|
||||
<div id="linkShinobi"></div>
|
||||
</div>
|
||||
<input type="hidden" name="details">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default pull-left" data-dismiss="modal"><i class="fa fa-times"></i> <%-lang.Close%></button>
|
||||
<button type="submit" class="btn btn-success"><i class="fa fa-check"></i> <%-lang.Save%></button>
|
||||
|
|
|
@ -15,32 +15,40 @@
|
|||
<div class="form-group">
|
||||
<label><div><span><%-lang['All Monitors and Privileges']%></span></div>
|
||||
<div><select class="form-control" detail="allmonitors">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group permission-view">
|
||||
<label><div><span><%-lang['Can Create and Delete Monitors']%></span></div>
|
||||
<div><select class="form-control" detail="monitor_create">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group permission-view">
|
||||
<label><div><span><%-lang['Can Change User Settings']%></span></div>
|
||||
<div><select class="form-control" detail="user_change">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Can View Logs']%></span></div>
|
||||
<div><select class="form-control" detail="view_logs">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Landing Page']%></span></div>
|
||||
<div><select class="form-control" detail="landing_page">
|
||||
<option value="" selected><%-lang.Default%></option>
|
||||
<option value="timelapse"><%-lang.Timelapse %></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -57,8 +65,8 @@
|
|||
<div class="form-group">
|
||||
<label><div><span><%- v.name %></span></div>
|
||||
<div><select class="form-control" monitor="monitors" mid="<%- v.mid %>">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -76,8 +84,8 @@
|
|||
<div class="form-group">
|
||||
<label><div><span><%- v.name %></span></div>
|
||||
<div><select class="form-control" monitor="monitor_edit" mid="<%- v.mid %>">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -95,8 +103,8 @@
|
|||
<div class="form-group">
|
||||
<label><div><span><%- v.name %></span></div>
|
||||
<div><select class="form-control" monitor="video_view" mid="<%- v.mid %>">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -114,8 +122,8 @@
|
|||
<div class="form-group">
|
||||
<label><div><span><%- v.name %></span></div>
|
||||
<div><select class="form-control" monitor="video_delete" mid="<%- v.mid %>">
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
<option value="0" selected><%-lang.No%></option>
|
||||
<option value="1"><%-lang.Yes%></option>
|
||||
</select></div>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -129,4 +137,4 @@
|
|||
<input type="hidden" name="details">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,81 +1,66 @@
|
|||
<!--Timelapse Window-->
|
||||
<div class="modal full fade dark" id="timelapse" role="dialog" aria-labelledby="timelapseLabel" aria-hidden="true">
|
||||
<div class="modal full fade dark" id="timelapsejpeg" role="dialog" aria-labelledby="timelapsejpegLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title" id="timelapseLabel"><i class="fa fa-angle-double-right"></i> <span><%-lang['Time-lapse Tool']%></span></h4>
|
||||
</div>
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title" id="timelapsejpegLabel"><i class="fa fa-angle-double-right"></i> <span><%-lang['Timelapse']%></span></h4>
|
||||
</div>
|
||||
<div class="modal-body text-center">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="timelapse_hud">
|
||||
<div class="timelapse_playRate hover-hide"></div>
|
||||
<div class="controlBar hover-hide">
|
||||
<div class="form-group">
|
||||
<div class="progress" id="timelapse_seekBar">
|
||||
<div class="progress-bar progress-bar-warning" role="progressbar" style="width:0%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="form-group monospace">
|
||||
<div class="btn-group timelapseSpeedUseBasicSwitch">
|
||||
<a timelapse="stepBackBack" class="active btn btn-primary"> <i class="fa fa-backward"></i> </a>
|
||||
<a timelapse="stepBack" class="btn btn-primary"> <i class="fa fa-arrow-circle-o-left"></i> </a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<a timelapse="play" class="btn btn-default"> <i class="fa fa-play"></i> </a>
|
||||
<a timelapse="mute" class="btn btn-default"> <i class="fa fa-volume-up"></i> </a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<a timelapse="stepFront" class="btn btn-primary"> <i class="fa fa-arrow-circle-o-right"></i> </a>
|
||||
<a timelapse="stepFrontFront" class="active btn btn-primary"> <i class="fa fa-forward"></i> </a>
|
||||
</div>
|
||||
<a timelapse="download" class="btn btn-info"> <i class="fa fa-download"></i> </a>
|
||||
<div class="btn-group">
|
||||
<a timelapse="setPlayBackRate" playRate="1" class="btn btn-default">1</a>
|
||||
<a timelapse="setPlayBackRate" playRate="5" class="btn btn-default">5</a>
|
||||
<a timelapse="setPlayBackRate" playRate="15" class="btn btn-default">15</a>
|
||||
</div>
|
||||
<div class="btn-group timelapseSpeedUseBasicSwitch">
|
||||
<a timelapse="setPlayBackRate" playRate="30" class="btn btn-default">30</a>
|
||||
<a timelapse="setPlayBackRate" playRate="60" class="btn btn-default">60</a>
|
||||
<a timelapse="setPlayBackRate" playRate="120" class="btn btn-default">120</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="marc-toggle abs-bot-left">
|
||||
<input title="<%-lang['Use HTML5 Play Method']%>" type="checkbox" id="timelapseSpeedUseBasic"/><label for="timelapseSpeedUseBasic"><%-lang['Use HTML5 Play Method']%></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="fieldHolder text-left">
|
||||
<div class="form-group text-center">
|
||||
<%
|
||||
var logoImageLink
|
||||
if(config.logoLocation76x76.indexOf('//') === -1){
|
||||
logoImageLink = window.libURL + config.logoLocation76x76
|
||||
}else{
|
||||
logoImageLink = config.logoLocation76x76
|
||||
}
|
||||
%>
|
||||
<img src="<%- logoImageLink %>" style="<%- config.logoLocation76x76Style %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Monitor']%></span></div>
|
||||
<div><select class="form-control dark monitors_list"></select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Date']%></span></div>
|
||||
<div><input type="text" id="timelapsejpeg_date" class="form-control" value="" /></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input id="timelapseJpegFps" data-slider-id='timelapseJpegFps' type="text"
|
||||
data-slider-min="1" data-slider-max="30" data-slider-step="1" data-slider-value="30" value="30"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<!-- <div class="btn-group"> -->
|
||||
<!-- <a class="btn btn-primary download_mp4"><%-lang['Build']%></a> -->
|
||||
<a class="btn btn-danger btn-block download_mp4"><%-lang['Download']%></a>
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
<div id="timelapse_video_display"></div>
|
||||
</div>
|
||||
<div class="">
|
||||
</div>
|
||||
<div class="frameIcons row scroll-style-6"></div>
|
||||
</div>
|
||||
<div class="col-md-8 frameStripContainer contained">
|
||||
<div class="playBackView"><img></div>
|
||||
<div class="liveStreamView"></div>
|
||||
</div>
|
||||
<form class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang.Monitor%></span></div>
|
||||
<div><select class="form-control monitors_list"></select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Date Range']%></span></div>
|
||||
<div><input type="text" id="timelapse_daterange" class="form-control" value="" /></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<ul id="timelapse_video_line" class="list-group"></ul>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal"><%-lang.Close%></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal"><%-lang.Close%></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="<%-window.libURL%>libs/js/dash2.timelapse.js"></script>
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.timelapse.jpeg.css">
|
||||
<script src="<%-window.libURL%>libs/js/dash2.timelapse.jpeg.js"></script>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<% include blocks/header %>
|
||||
<script>var $user = <%- JSON.stringify($user) %>;</script>
|
||||
<script>var lang = <%- JSON.stringify(lang) %>;</script>
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/roboto.css" type="text/css" />
|
||||
<script>var addStorage = <%- JSON.stringify(addStorage) %>;</script>
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/material-design-iconic-font.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/pnotify.custom.min.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/vbox.css">
|
||||
|
@ -16,19 +16,19 @@
|
|||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/gridstack.min.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/gridstack-extra.min.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/bootstrap-table.min.css">
|
||||
<!--
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/bootstrap-slider.min.css">
|
||||
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.basic.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.misc.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.monitors.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.monitorStates.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.forms.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.modal.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.monitors.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.powervideo.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.ptzcontrols.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.regioneditor.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.rightotleft.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.timelapse.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.css">
|
||||
-->
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.old.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.righttoleft.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.sidemenu.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.darktheme.css">
|
||||
<% customAutoLoad.LibsCss.forEach(function(lib){ %>
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/<%-lib%>">
|
||||
<% }) %>
|
||||
|
@ -56,7 +56,7 @@
|
|||
<ul class="nav navbar-nav">
|
||||
<li title="<%-lang['Toggle Sidebar']%>" class_toggle="hide-side" data-target=".mdl-js-layout"><a> <i class="fa fa-bars"></i> </a></li>
|
||||
<li title="<%-lang['Add Monitor']%>" mid="" ke="" class="hidden-xs permission_monitor_create"><a monitor="edit"> <i class="fa fa-plus"></i> </a></li>
|
||||
<li title="<%-lang['Power Video Viewer']%>" class="hidden-xs" mid="" ke=""><a monitor="powerview"> <i class="fa fa-map-marker"></i> </a></li>
|
||||
<li title="<%-lang['Power Video Viewer']%>" class="hidden-xs" data-toggle="modal" data-target="#powerVideo"><a> <i class="fa fa-map-marker"></i> </a></li>
|
||||
<li>
|
||||
<a title="<%-lang['Monitor Groups']%>" id="group_list_button" class="mdl-js-button"> <i class="fa fa-video-camera"></i> </a>
|
||||
<ul class="mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="group_list_button" id="group_list"></ul>
|
||||
|
@ -101,16 +101,31 @@
|
|||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li role="presentation" class="dropdown">
|
||||
<li role="presentation" class="dropdown hidden-xs">
|
||||
<a href="javascript:;" class="dropdown-toggle info-number" data-toggle="dropdown" aria-expanded="true"> <i class="fa fa-group"></i> </a>
|
||||
<ul id="users_online" class="dropdown-menu list-unstyled msg_list scrollable" role="menu"></ul>
|
||||
</li>
|
||||
<!--
|
||||
|
||||
<li role="presentation" class="dropdown">
|
||||
<a href="javascript:;" class="dropdown-toggle info-number" data-toggle="dropdown" aria-expanded="true"> <i class="fa fa-info-circle"></i> </a>
|
||||
<ul id="notifications" class="dropdown-menu list-unstyled msg_list scrollable" role="menu"></ul>
|
||||
<a href="javascript:;" class="dropdown-toggle info-number" data-toggle="dropdown" aria-expanded="true"> <i class="fa fa-hdd-o"></i> </a>
|
||||
<ul id="diskUsedList" class="dropdown-menu list-unstyled msg_list scrollable" role="menu">
|
||||
<% addStorage.forEach(function(storage){ %>
|
||||
<li class="log-item" storage="<%- storage.name %>">
|
||||
<span>
|
||||
<div class="title"><%- storage.name %></div>
|
||||
<span class="pull-right percent"></span>
|
||||
<label><span class="value"></span></label>
|
||||
</span>
|
||||
<div class="message">
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-warning" role="progressbar"></div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<% }) %>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
|
||||
<li role="presentation" class="dropdown">
|
||||
<a href="javascript:;" class="dropdown-toggle info-number" data-toggle="dropdown" aria-expanded="true"> <i class="fa fa-exclamation-triangle"></i> </a>
|
||||
<ul id="logs" class="dropdown-menu list-unstyled msg_list scrollable" role="menu">
|
||||
|
@ -125,8 +140,8 @@
|
|||
<button id="accbtn" style="color:#fff" class="mdl-button mdl-js-button mdl-js-ripple-effect"><i class="fa fa-caret-down"></i> <span class="usermail"></span></button>
|
||||
<ul class="mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="accbtn">
|
||||
<li class="mdl-menu__item" data-toggle="modal" data-target="#multi_mon"><div><i class="fa fa-clone"></i><div><%- lang['Monitors'] %></div></div></li>
|
||||
<li class="mdl-menu__item" mid="" ke=""><div class="flex" monitor="powerview"><i class="fa fa-map-marker"></i><div><%- lang['Power Viewer'] %></div></div></li>
|
||||
<li class="mdl-menu__item" mid="" ke=""><div class="flex" monitor="timelapse"><i class="fa fa-angle-double-right"></i><div><%- lang['Time-lapse'] %></div></div></li>
|
||||
<li class="mdl-menu__item" data-toggle="modal" data-target="#powerVideo"><div><i class="fa fa-map-marker"></i><div><%- lang['Power Viewer'] %></div></div></li>
|
||||
<li class="mdl-menu__item" mid="" ke=""><div class="flex" monitor="timelapseJpeg"><i class="fa fa-angle-double-right"></i><div><%- lang['Timelapse'] %></div></div></li>
|
||||
<li class="mdl-menu__item permission_user_change" data-toggle="modal" data-target="#settings"><div><i class="fa fa-gears"></i><div><%- lang.Settings %></div></div></li>
|
||||
<li class="mdl-menu__item" data-toggle="modal" data-target="#apis"><div><i class="fa fa-code"></i><div><%- lang.API %></div></div></li>
|
||||
<% if(!details.sub){ %>
|
||||
|
@ -154,7 +169,7 @@
|
|||
</header>
|
||||
<nav class="demo-navigation mdl-navigation side-menu" id="left_menu">
|
||||
<div class="form-group col-md-12">
|
||||
<input class="form-control dark" placeholder="Search Monitors" id="monitors_list_search">
|
||||
<input class="form-control dark" placeholder="<%- lang.Search %> <%- lang.Monitors %>" id="monitors_list_search">
|
||||
</div>
|
||||
<div id="monitors_list" class="display-table"></div>
|
||||
<div class="mdl-layout-spacer"></div>
|
||||
|
@ -173,7 +188,6 @@
|
|||
<% include blocks/logs.ejs %>
|
||||
<% include blocks/settings.ejs %>
|
||||
<% include blocks/filters.ejs %>
|
||||
<% include blocks/powervideo.ejs %>
|
||||
<% include blocks/timelapse.ejs %>
|
||||
<% include blocks/videoview.ejs %>
|
||||
<% include blocks/monitoredit.ejs %>
|
||||
|
@ -183,6 +197,7 @@
|
|||
<% include blocks/monitorStates.ejs %>
|
||||
<% include blocks/schedules.ejs %>
|
||||
<% include blocks/confirm.ejs %>
|
||||
<% include blocks/help.ejs %>
|
||||
<% customAutoLoad.PageBlocks.forEach(function(block){ %>
|
||||
<%- include(block) %>
|
||||
<% }) %>
|
||||
|
@ -200,13 +215,16 @@
|
|||
<script src="<%-window.libURL%>libs/js/bootstrap-table.min.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/socket.io.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/fullcalendar.min.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/locale-all.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/hls.min.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/libde265.min.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/bootstrap-slider.min.js"></script>
|
||||
<script type="text/javascript" src="<%-window.libURL%>libs/js/flv.shinobi.js">;</script>
|
||||
<script src="<%-window.libURL%>libs/js/jszip.min.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/dash2.downloadAndZip.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/menu.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/clock.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/poseidon.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/Chart.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/clusterPoints.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/daterangepicker.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/jquery.canvasAreaDraw.js"></script>
|
||||
|
@ -228,3 +246,4 @@
|
|||
<script src="<%-window.libURL%>libs/js/<%-lib%>"></script>
|
||||
<% }) %>
|
||||
<% include blocks/help.ejs %>
|
||||
<% include blocks/powerVideo2.ejs %>
|
||||
|
|
|
@ -6,21 +6,30 @@
|
|||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<div class="panel panel-login">
|
||||
<div class="panel-heading">
|
||||
<div class="panel-heading-shade">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<a href="http://shinobi.video" target="_blank">
|
||||
<img src="<%-window.libURL%>libs/img/icon/apple-touch-icon-76x76.png" style="border-radius:50%">
|
||||
</a>
|
||||
<% if(config.showLoginCardHeader === true){
|
||||
var logoImageLink
|
||||
if(config.logoLocation76x76.indexOf('//') === -1){
|
||||
logoImageLink = window.libURL + config.logoLocation76x76
|
||||
}else{
|
||||
logoImageLink = config.logoLocation76x76
|
||||
}
|
||||
%>
|
||||
<div class="panel-heading">
|
||||
<div class="panel-heading-shade">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<a href="<%- config.logoLocation76x76Link %>" target="_blank">
|
||||
<img src="<%- logoImageLink %>" style="<%- config.logoLocation76x76Style %>">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<form id="login-form" method="post" style="display: block;">
|
||||
<form id="login-form" method="post" style="display: block;margin:0">
|
||||
<input type="hidden" name="machineID" id="machineID" value="">
|
||||
<% var message,timeLeft;if(message){ %>
|
||||
<div class="form-group text-center monospace">
|
||||
|
@ -28,48 +37,68 @@
|
|||
</div>
|
||||
<% } %>
|
||||
<div class="form-group">
|
||||
<input type="text" name="mail" id="email" tabindex="1" class="monospace form-control" placeholder="Email" value="">
|
||||
<input type="text" name="mail" id="email" tabindex="1" class="monospace form-control" placeholder="<%- lang.Email %>" value="">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="password" name="pass" id="pass" tabindex="2" class="monospace form-control" placeholder="Password">
|
||||
<input type="password" name="pass" id="pass" tabindex="2" class="monospace form-control" placeholder="<%- lang.Password %>">
|
||||
</div>
|
||||
<div class="form-group f_i_input f_i_ldap" style="display:none">
|
||||
<input name="key" id="key" tabindex="2" class="monospace form-control" placeholder="Group Key">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-md-12 monospace" style="width:calc(100% - 48px)">
|
||||
<select class="form-control" name="function" selector="f_i">
|
||||
<% switch(screen){
|
||||
case'super': %>
|
||||
<option value="super"><%- lang.Superuser %></option>
|
||||
<% break;
|
||||
case'admin': %>
|
||||
<option value="admin"><%- lang.Admin %></option>
|
||||
<% break;
|
||||
default: %>
|
||||
<option value="dash" selected><%- lang.Dashboard %></option>
|
||||
<% if(config.productType==='Pro'){ %>
|
||||
<option value="ldap"><%- lang.LDAP %></option>
|
||||
<% } %>
|
||||
<option value="streamer"><%- lang.Streamer %></option>
|
||||
<option value="cam"><%- lang.Dashcam %> (<%- lang.Streamer %> v2)</option>
|
||||
<% break;
|
||||
} %>
|
||||
</select>
|
||||
</div>
|
||||
<div class="text-right" title="<%- lang['Remember Me'] %>" style="display:inline-block">
|
||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" for="remember_me">
|
||||
<input type="checkbox" id="remember_me" value="1" name="remember" class="mdl-switch__input">
|
||||
<span class="monospace mdl-switch__label"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" style="margin:20px"></div>
|
||||
<div class="form-group">
|
||||
<% if(config.showLoginSelector === true){ %>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-md-12 monospace" style="width:calc(100% - 48px)">
|
||||
<select class="form-control" name="function" selector="f_i">
|
||||
<% switch(screen){
|
||||
case'super': %>
|
||||
<option value="super"><%- lang.Superuser %></option>
|
||||
<% break;
|
||||
case'admin': %>
|
||||
<option value="admin"><%- lang.Admin %></option>
|
||||
<% break;
|
||||
default: %>
|
||||
<option value="dash" selected><%- lang.Dashboard %></option>
|
||||
<% if(config.productType==='Pro'){ %>
|
||||
<option value="ldap"><%- lang.LDAP %></option>
|
||||
<% } %>
|
||||
<option value="streamer"><%- lang.Streamer %></option>
|
||||
<option value="cam"><%- lang.Dashcam %> (<%- lang.Streamer %> v2)</option>
|
||||
<% break;
|
||||
} %>
|
||||
</select>
|
||||
</div>
|
||||
<div class="text-right" title="<%- lang['Remember Me'] %>" style="display:inline-block">
|
||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" for="remember_me">
|
||||
<input type="checkbox" id="remember_me" value="1" name="remember" class="mdl-switch__input">
|
||||
<span class="monospace mdl-switch__label"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% }else{ %>
|
||||
<select class="form-control" name="function" style="display:none">
|
||||
<% switch(screen){
|
||||
case'super': %>
|
||||
<option value="super"><%- lang.Superuser %></option>
|
||||
<% break;
|
||||
case'admin': %>
|
||||
<option value="admin"><%- lang.Admin %></option>
|
||||
<% break;
|
||||
default: %>
|
||||
<option value="dash" selected><%- lang.Dashboard %></option>
|
||||
<% break;
|
||||
} %>
|
||||
</select>
|
||||
<% } %>
|
||||
<div class="form-group" style="margin:0">
|
||||
<button type="submit" name="login-submit" id="login-submit" tabindex="4" class="btn btn-success btn-block"><%- lang.Login %></button>
|
||||
</div>
|
||||
<% if(config.showPoweredByShinobi){ %>
|
||||
<p style="<%- config.poweredByShinobiClass %>"><small><%- config.poweredByShinobi %></small></p>
|
||||
<% }else{ %>
|
||||
<!-- <%- config.poweredByShinobi %> -->
|
||||
<% } %>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -11,17 +11,22 @@
|
|||
<link href="<%-window.libURL%>libs/css/montserrat.css" rel="stylesheet" />
|
||||
<link href="<%-window.libURL%>libs/css/font-awesome.min.css" rel="stylesheet" />
|
||||
<!-- CSS Files -->
|
||||
<link href="<%-window.libURL%>libs/css/bootstrap4.min.css" rel="stylesheet" />
|
||||
<link href="<%-window.libURL%>libs/css/main.dash2.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/bootstrap4.min.css" />
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.css" />
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/pnotify.custom.min.css">
|
||||
<link href="<%-window.libURL%>libs/css/now-ui-kit.css?v=1.1.0" rel="stylesheet" />
|
||||
<link href="<%-window.libURL%>libs/css/super-page.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/now-ui-kit.css?v=1.1.0" />
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.basic.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.modal.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.forms.css">
|
||||
<link rel="stylesheet" href="<%-window.libURL%>libs/css/super-page.css" />
|
||||
<script src="<%-window.libURL%>libs/js/jquery.min.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/jquery-ui.min.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/basic.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/jquery.serialize.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/pnotify.custom.min.js"></script>
|
||||
<script src="<%-window.libURL%>libs/js/popper.min.js" type="text/javascript"></script>
|
||||
<script src="<%-window.libURL%>libs/js/bootstrap4.min.js" type="text/javascript"></script>
|
||||
<script src="<%-window.libURL%>libs/js/dash2.confirm.js" type="text/javascript"></script>
|
||||
<style>
|
||||
.form-group label>div:first-child{width:40%}
|
||||
.list-group li .form-group {margin:0}
|
||||
|
@ -67,16 +72,16 @@
|
|||
<div id="main-card" class="card">
|
||||
<ul class="nav nav-tabs nav-tabs-neutral justify-content-center bg-primary" id="tablist" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="tab" href="#accounts" role="tab">Accounts</a>
|
||||
<a class="nav-link active" data-toggle="tab" href="#accounts" role="tab"><%-lang['Accounts']%></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#config" role="tab">Configuration</a>
|
||||
<a class="nav-link" data-toggle="tab" href="#config" role="tab"><%-lang['Configuration']%></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#system" role="tab">Controls and Logs</a>
|
||||
<a class="nav-link" data-toggle="tab" href="#system" role="tab"><%-lang['Controls and Logs']%></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#changeSuperPreferences" role="tab">Preferences</a>
|
||||
<a class="nav-link" data-toggle="tab" href="#changeSuperPreferences" role="tab"><%-lang['Preferences']%></a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="card-body">
|
||||
|
@ -89,7 +94,7 @@
|
|||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link add">
|
||||
<p><i class="fa fa-plus-square-o"></i> Add Account</p>
|
||||
<p><i class="fa fa-plus-square-o"></i> <%-lang['Add']%> <%-lang['Accounts']%></p>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -128,7 +133,7 @@
|
|||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" system="deleteLogs">
|
||||
<p><i class="fa fa-trash-o"></i> Clear Logs</p>
|
||||
<p><i class="fa fa-trash-o"></i> <%-lang['Delete']%> <%-lang['Logs']%></p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
|
@ -146,13 +151,7 @@
|
|||
<p><i class="fa fa-retweet"></i> <%-lang['Flush PM2 Logs']%></p>
|
||||
</a>
|
||||
</li>
|
||||
<!--
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" system="update">
|
||||
<p><i class="fa fa-arrow-up"></i> <%-lang['Update']%></p>
|
||||
</a>
|
||||
</li>
|
||||
-->
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -169,6 +168,15 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row text-center">
|
||||
<div class="col">
|
||||
<a href="https://gitlab.com/Shinobi-Systems/Shinobi/commit/<%- currentVersion %>" target="_blank">
|
||||
<small class="epic-text" style="font-weight: 700;color: #fff;letter-spacing: 2pt;">
|
||||
Current Version : <%- currentVersion %>
|
||||
</small>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -221,10 +229,12 @@ switch($user.lang){
|
|||
})
|
||||
break;
|
||||
}
|
||||
$.ccio.ws=io(location.origin,{
|
||||
$.ccio.ws = io(location.origin,{
|
||||
path : tool.checkCorrectPathEnding(location.pathname)+'socket.io'
|
||||
});
|
||||
$.ccio.cx=function(x){return $.ccio.ws.emit('super',x)}
|
||||
})
|
||||
$.ccio.cx = function(x){
|
||||
return $.ccio.ws.emit('super',x)
|
||||
}
|
||||
$.ccio.ws.on('connect',function(d){
|
||||
$.ccio.cx({f:'init',mail:$user.mail,pass:$user.pass})
|
||||
})
|
||||
|
@ -393,7 +403,7 @@ $.conf.f.submit(function(e){
|
|||
e.html='<p>This is a change being applied to the configuration file (conf.json). Are you sure you want to do this? You must restart Shinobi for these changes to take effect. <b>The JSON below is what you are about to save.</b></p>'
|
||||
e.html+='<pre>'+JSON.stringify($.parseJSON($.conf.draw.val()),null,3)+'</pre>'
|
||||
$.confirm.body.html(e.html)
|
||||
$.confirm.click({title:'Save',class:'btn-success'},function(){
|
||||
$.confirm.click({title:lang.Save,class:'btn-success'},function(){
|
||||
$.post('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/system/configure',{
|
||||
data: $.conf.draw.val()
|
||||
},function(data){
|
||||
|
@ -459,10 +469,10 @@ $.system.e.find('[system]').click(function(e){
|
|||
switch($(this).attr('system')){
|
||||
case'deleteLogs':
|
||||
$.confirm.e.modal('show');
|
||||
$.confirm.title.html('Delete Logs <small>'+e.u+'</small>')
|
||||
$.confirm.title.html('<%=lang['Delete Logs']%> <small>'+e.u+'</small>')
|
||||
e.html='Do you want to delete these logs? User logs will <b>not</b> be deleted.'
|
||||
$.confirm.body.html(e.html)
|
||||
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||
$.confirm.click({title:lang.Delete,class:'btn-danger'},function(){
|
||||
// $.ccio.cx({f:'logs',ff:'delete',ke:'$'})
|
||||
$.get('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/logs/delete',function(data){
|
||||
console.log(data)
|
||||
|
@ -472,9 +482,9 @@ $.system.e.find('[system]').click(function(e){
|
|||
break;
|
||||
case'update':
|
||||
$.confirm.e.modal('show')
|
||||
$.confirm.title.html('Update Shinobi?')
|
||||
$.confirm.title.html('<%=lang.Update%> Shinobi?')
|
||||
$.confirm.body.html('Updating Shinobi means overwriting files. If you have modified any files yourself you should update Shinobi manually.')
|
||||
$.confirm.click({title:'Update',class:'btn-danger'},function(){
|
||||
$.confirm.click({title:lang.Update,class:'btn-danger'},function(){
|
||||
// $.ccio.cx({f:'system',ff:'update'})
|
||||
$.get('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/system/update',function(data){
|
||||
console.log(data)
|
||||
|
@ -501,9 +511,9 @@ $.system.e.find('[restart]').click(function(e){
|
|||
break;
|
||||
}
|
||||
})
|
||||
$.confirm.title.html('Restart?')
|
||||
$.confirm.title.html('<%=lang.Restart%>?')
|
||||
$.confirm.body.html(e.html)
|
||||
$.confirm.click({title:'Restart',class:'btn-danger'},function(){
|
||||
$.confirm.click({title:lang.Restart,class:'btn-danger'},function(){
|
||||
// $.ccio.cx({f:'system',ff:'restart',target:e.target})
|
||||
$.get('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/system/restart/'+encodeURIComponent(e.target),function(data){
|
||||
console.log(data)
|
||||
|
|
118
web/pages/timelapse.ejs
Normal file
118
web/pages/timelapse.ejs
Normal file
|
@ -0,0 +1,118 @@
|
|||
<%
|
||||
if(config.ssl&&config.ssl.port&&data.protocol==='https'){
|
||||
data.port=config.ssl.port
|
||||
}else{
|
||||
data.port=config.port
|
||||
}
|
||||
data.url = baseUrl
|
||||
if(data.addon && data.addon.indexOf('relative')>-1){
|
||||
data.url=''
|
||||
}
|
||||
%>
|
||||
<% include blocks/header-title.ejs %>
|
||||
<% include blocks/header-meta.ejs %>
|
||||
<% include blocks/header-favicon.ejs %>
|
||||
<link rel="stylesheet" href="<%=data.url%>/libs/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="<%=data.url%>/libs/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="<%-data.url%>/libs/css/daterangepicker.css">
|
||||
<link rel="stylesheet" href="<%-data.url%>/libs/css/dash2.basic.css">
|
||||
<link rel="stylesheet" href="<%-data.url%>/libs/css/dash2.forms.css">
|
||||
<link rel="stylesheet" href="<%-data.url%>/libs/css/dash2.darktheme.css">
|
||||
<link rel="stylesheet" href="<%-data.url%>/libs/css/bootstrap-slider.min.css">
|
||||
|
||||
|
||||
<div id="timelapsejpeg" class="standalone dark">
|
||||
<div class="modal-body text-center" style="padding-top:0;padding-bottom:0;">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="fieldHolder text-left">
|
||||
<div class="form-group text-center">
|
||||
<%
|
||||
var logoImageLink
|
||||
if(config.logoLocation76x76.indexOf('//') === -1){
|
||||
logoImageLink = window.libURL + config.logoLocation76x76
|
||||
}else{
|
||||
logoImageLink = config.logoLocation76x76
|
||||
}
|
||||
%>
|
||||
<img src="<%- logoImageLink %>" style="<%- config.logoLocation76x76Style %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Monitor']%></span></div>
|
||||
<div><select class="form-control dark monitors_list"></select></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><div><span><%-lang['Date']%></span></div>
|
||||
<div><input type="text" id="timelapsejpeg_date" class="form-control" value="" /></div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input id="timelapseJpegFps" data-slider-id='timelapseJpegFps' type="text"
|
||||
data-slider-min="1" data-slider-max="30" data-slider-step="1" data-slider-value="30" value="30"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<!-- <div class="btn-group"> -->
|
||||
<!-- <a class="btn btn-primary download_mp4"><%-lang['Build']%></a> -->
|
||||
<a class="btn btn-danger btn-block download_mp4"><%-lang['Download']%></a>
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="">
|
||||
</div>
|
||||
<div class="frameIcons row scroll-style-6"></div>
|
||||
</div>
|
||||
<div class="col-md-8 frameStripContainer contained">
|
||||
<div class="playBackView"><img></div>
|
||||
<div class="liveStreamView"></div>
|
||||
<!-- <div class="frames"></div>
|
||||
<div class="frameStripPreview"></div>
|
||||
<div class="frameStrip"></div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="<%=data.url%>/libs/js/jquery.min.js"></script>
|
||||
<script src="<%=data.url%>/libs/js/jquery-ui.min.js"></script>
|
||||
<script>$.ccio = {mon:{}}</script>
|
||||
<script src="<%-data.url%>/libs/js/moment-with-locales.min.js"></script>
|
||||
<script src="<%-data.url%>/libs/js/daterangepicker.js"></script>
|
||||
<script src="<%-data.url%>/libs/js/bootstrap-slider.min.js"></script>
|
||||
<script src="<%-data.url%>/libs/js/dash2.init.js"></script>
|
||||
<link rel="stylesheet" href="<%-data.url%>/libs/css/dash2.timelapse.jpeg.css">
|
||||
<script src="<%-data.url%>/libs/js/dash2.timelapse.jpeg.js"></script>
|
||||
<script>
|
||||
var data = <%- JSON.stringify(data) %>
|
||||
var $user = <%- JSON.stringify($user) %>
|
||||
var lang = <%- JSON.stringify(lang) %>
|
||||
var languageChoice = "<%- config.language || 'en' %>".replace('_','-').toLowerCase()
|
||||
moment.locale(languageChoice)
|
||||
$user.auth_token = data.auth
|
||||
$(document).ready(function(){
|
||||
$.timelapseJpeg.pointer = data.url + '/'
|
||||
$.timelapseJpeg.fieldHolderCssHeightModifier = 50
|
||||
$.timelapseJpeg.monitors.find('.monitor').remove()
|
||||
$.getJSON(data.url+'/'+$user.auth_token+'/monitor/'+$user.ke,function(d){
|
||||
if(d instanceof Array){
|
||||
$.each(d,function(n,monitor){
|
||||
$.ccio.mon[monitor.ke + monitor.mid + $user.auth_token] = monitor
|
||||
})
|
||||
}else{
|
||||
$.ccio.mon[d.ke + d.mid + $user.auth_token] = d
|
||||
}
|
||||
$.each($.ccio.mon,function(n,v){
|
||||
$.timelapseJpeg.monitors.append('<option class="monitor" value="'+v.mid+'">'+v.name+'</option>')
|
||||
})
|
||||
$.timelapseJpeg.monitors.find('.monitor').prop('selected',false)
|
||||
// if(monitor.mid !== ''){
|
||||
// $.timelapseJpeg.monitors.find('.monitor[value="'+e.mid+'"]')
|
||||
// }
|
||||
// $.timelapseJpeg.datepicker.val($.timelapseJpeg.baseDate)
|
||||
$.timelapseJpeg.selectedStartDate = moment().utc().subtract(2, 'days').format('YYYY-MM-DD')
|
||||
$.timelapseJpeg.selectedEndDate = moment().utc().add(1, 'days').format('YYYY-MM-DD')
|
||||
$.timelapseJpeg.draw($.timelapseJpeg.selectedStartDate,$.timelapseJpeg.selectedEndDate)
|
||||
})
|
||||
})
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue