Add Wall View API Endpoint
parent
21c44fcc27
commit
5e37b8b3b9
|
@ -54,6 +54,8 @@ module.exports = function(s,config,lang,io){
|
|||
if(config.renderPaths.grid === undefined){config.renderPaths.grid='pages/grid'}
|
||||
//slick.js (cycle) page
|
||||
if(config.renderPaths.cycle === undefined){config.renderPaths.cycle='pages/cycle'}
|
||||
//WallView page
|
||||
if(config.renderPaths.wallview === undefined){config.renderPaths.wallview='pages/wallview'}
|
||||
// Use uws/cws
|
||||
if(config.useUWebsocketJs === undefined){config.useUWebsocketJs=true}
|
||||
if(config.webBlocksPreloaded === undefined){
|
||||
|
|
|
@ -415,4 +415,34 @@ module.exports = function(s,config,lang,app){
|
|||
},res,req);
|
||||
},res,req);
|
||||
});
|
||||
/**
|
||||
* Page : Get WallView
|
||||
*/
|
||||
app.get(config.webPaths.apiPrefix+':auth/wallview/:ke', function (req,res){
|
||||
s.auth(req.params,function(user){
|
||||
const authKey = req.params.auth
|
||||
const groupKey = req.params.ke
|
||||
if(
|
||||
user.permissions.watch_stream === "0"
|
||||
|| user.details.sub
|
||||
&& user.details.allmonitors !== '1'
|
||||
){
|
||||
res.end(user.lang['Not Permitted'])
|
||||
return
|
||||
}
|
||||
s.renderPage(req,res,config.renderPaths.wallview,{
|
||||
forceUrlPrefix: req.query.host || '',
|
||||
data: req.params,
|
||||
protocol: req.protocol,
|
||||
baseUrl: req.protocol + '://' + req.hostname,
|
||||
config: s.getConfigWithBranding(req.hostname),
|
||||
define: s.getDefinitonFile(user.details ? user.details.lang : config.lang),
|
||||
lang: lang,
|
||||
$user: user,
|
||||
authKey: authKey,
|
||||
groupKey: groupKey,
|
||||
originalURL: s.getOriginalUrl(req)
|
||||
});
|
||||
},res,req);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
#wallview-container {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
#wallview-canvas {
|
||||
position: relative;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#wallview-controls{
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
opacity: 0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
#wallview-controls:hover{
|
||||
opacity: 100%;
|
||||
}
|
||||
|
||||
#wallview-monitorList i{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#wallview-monitorList .active i{
|
||||
display: inlin-block;
|
||||
}
|
||||
|
||||
#wallview-canvas .wallview-video {
|
||||
position: absolute;
|
||||
}
|
||||
#wallview-canvas .wallview-video .overlay {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border: 0;
|
||||
}
|
||||
#wallview-canvas .wallview-video iframe {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#wallview-canvas .wallview-video.col-md-4 {
|
||||
height:30vh;
|
||||
}
|
||||
#wallview-canvas .wallview-video.col-md-6 {
|
||||
height: 40vh;
|
||||
}
|
||||
#wallview-canvas .wallview-video.col-md-12 {
|
||||
height: 80vh;
|
||||
margin-bottom: 0.5rem !important;
|
||||
}
|
||||
#wallview-canvas .wallview-video:not(.no-video){
|
||||
background-color: #000!important;
|
||||
}
|
||||
#wallview-canvas .wallview-video.no-video{
|
||||
display: none;
|
||||
}
|
||||
#wallview-canvas.show-non-playing .wallview-video.no-video{
|
||||
display: flex;
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
var loadedMonitors = {}
|
||||
var selectedMonitors = {}
|
||||
$(document).ready(function(){
|
||||
var wallViewMonitorList = $('#wallview-monitorList')
|
||||
var wallViewControls = $('#wallview-controls')
|
||||
var wallViewCanvas = $('#wallview-canvas')
|
||||
function getApiPrefix(innerPart){
|
||||
return `${urlPrefix}${authKey}${innerPart ? `/${innerPart}/${groupKey}` : ''}`
|
||||
}
|
||||
function getWindowName(){
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const theWindow = urlParams.get('window');
|
||||
return theWindow || '1'
|
||||
}
|
||||
function drawMonitorListItem(monitor){
|
||||
wallViewMonitorList.append(`<li><a class="dropdown-item" select-monitor="${monitor.mid}" href="#"><i class="fa fa-check"></i> ${monitor.name}</a></li>`)
|
||||
}
|
||||
function drawMonitorList(){
|
||||
return new Promise((resolve) => {
|
||||
$.get(getApiPrefix('monitor'),function(monitors){
|
||||
$.each(monitors, function(n,monitor){
|
||||
if(monitor.mode !== 'stop' && monitor.mode !== 'idle'){
|
||||
loadedMonitors[monitor.mid] = monitor;
|
||||
drawMonitorListItem(monitor)
|
||||
}
|
||||
})
|
||||
resolve(monitors)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function getMonitorListItem(monitorId){
|
||||
return wallViewMonitorList.find(`[select-monitor="${monitorId}"]`)
|
||||
}
|
||||
|
||||
function selectMonitor(monitorId, css){
|
||||
css = css || {};
|
||||
selectedMonitors[monitorId] = Object.assign({}, loadedMonitors[monitorId]);
|
||||
wallViewCanvas.append(`<div class="wallview-video p-0 m-0" live-stream="${monitorId}" style="left:${css.left || 0}px;top:${css.top || 0}px;width:${css.width ? css.width + 'px' : '50vw'};height:${css.height ? css.height + 'px' : '40vh'};"><div class="overlay"></div><iframe src="${getApiPrefix('embed')}/${monitorId}/fullscreen%7Cjquery%7Crelative?host=/"></iframe></div>`)
|
||||
wallViewCanvas.find(`[live-stream="${monitorId}"]`)
|
||||
.draggable({
|
||||
grid: [10, 10],
|
||||
snap: '#wallview-canvas',
|
||||
containment: "window",
|
||||
stop: function(){
|
||||
saveLayout()
|
||||
}
|
||||
})
|
||||
.resizable({
|
||||
grid: [10, 10],
|
||||
snap: '#wallview-canvas',
|
||||
containment: "window",
|
||||
stop: function(){
|
||||
saveLayout()
|
||||
}
|
||||
})
|
||||
getMonitorListItem(monitorId).addClass('active')
|
||||
}
|
||||
function deselectMonitor(monitorId){
|
||||
delete(selectedMonitors[monitorId])
|
||||
var monitorItem = wallViewCanvas.find(`[live-stream="${monitorId}"]`);
|
||||
monitorItem.find('iframe').attr('src','about:blank')
|
||||
monitorItem.remove()
|
||||
getMonitorListItem(monitorId).removeClass('active')
|
||||
}
|
||||
|
||||
function getCurrentLayout(){
|
||||
var layout = []
|
||||
wallViewCanvas.find('.wallview-video').each(function(n,v){
|
||||
var el = $(v)
|
||||
var monitorId = el.attr('live-stream')
|
||||
var position = el.position()
|
||||
console.log(monitorId,position)
|
||||
layout.push({
|
||||
monitorId,
|
||||
css: {
|
||||
left: position.left,
|
||||
top: position.top,
|
||||
width: el.width(),
|
||||
height: el.height(),
|
||||
}
|
||||
})
|
||||
})
|
||||
return layout
|
||||
}
|
||||
|
||||
function saveLayout(){
|
||||
var windowName = getWindowName();
|
||||
var layout = getCurrentLayout();
|
||||
localStorage.setItem(`windowLayout_${windowName}`, JSON.stringify(layout))
|
||||
}
|
||||
|
||||
function getLayout(){
|
||||
var windowName = getWindowName();
|
||||
var layout = JSON.parse(localStorage.getItem(`windowLayout_${windowName}`) || '[]')
|
||||
return layout;
|
||||
}
|
||||
|
||||
function loadSavedLayout(){
|
||||
var layout = getLayout()
|
||||
layout.forEach(function({ monitorId, css }, n){
|
||||
selectMonitor(monitorId, css)
|
||||
})
|
||||
}
|
||||
|
||||
drawMonitorList().then(loadSavedLayout)
|
||||
$('body').on('click', '[select-monitor]', function(e){
|
||||
e.preventDefault()
|
||||
var el = $(this);
|
||||
var monitorId = el.attr('select-monitor')
|
||||
var isSelected = selectedMonitors[monitorId]
|
||||
if(isSelected){
|
||||
deselectMonitor(monitorId)
|
||||
}else{
|
||||
selectMonitor(monitorId)
|
||||
}
|
||||
saveLayout()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,65 @@
|
|||
<title><%- lang.Shinobi %></title>
|
||||
<%
|
||||
var forceUrlPrefix
|
||||
var urlPrefix = ``
|
||||
var targetPort = config.ssl && config.ssl.port && protocol === 'https' ? config.ssl.port : config.port
|
||||
var addonsEnabled = {}
|
||||
var rawAddonList = decodeURI(data.addon || '').split('|');
|
||||
rawAddonList.forEach(function(piece){
|
||||
var pieceParts = piece.split('=');
|
||||
var key = pieceParts[0];
|
||||
var value = pieceParts[1] || true;
|
||||
addonsEnabled[key] = value;
|
||||
});
|
||||
function getAddon(addonTag){
|
||||
return addonsEnabled[addonTag];
|
||||
}
|
||||
var streamWidth = parseInt(getAddon('width')) || 640
|
||||
var streamHeight = parseInt(getAddon('height')) || 480
|
||||
var hasGUI = getAddon('gui')
|
||||
var isFullscreen = getAddon('fullscreen')
|
||||
var isRelativeUrl = getAddon('relative')
|
||||
if(forceUrlPrefix){
|
||||
urlPrefix = forceUrlPrefix
|
||||
}else if(isRelativeUrl){
|
||||
urlPrefix = ''
|
||||
}else if(config.baseURL){
|
||||
urlPrefix = config.baseURL
|
||||
}else if(!targetPort || targetPort === '' || targetPort == 80 || targetPort == 443){
|
||||
urlPrefix = baseUrl
|
||||
}else{
|
||||
urlPrefix = `${baseUrl}:${targetPort}`
|
||||
}
|
||||
if(urlPrefix.endsWith('/') === false){
|
||||
urlPrefix += '/'
|
||||
}
|
||||
var originalURL = `${urlPrefix}`
|
||||
%>
|
||||
<%- include('blocks/header-favicon') %>
|
||||
<script>window.$user=<%- JSON.stringify($user) %>;</script>
|
||||
<script>window.urlPrefix = "<%- urlPrefix || '' %>";</script>
|
||||
<script>window.groupKey = "<%- groupKey || '' %>";</script>
|
||||
<script>window.authKey = "<%- authKey || '' %>";</script>
|
||||
<script src="<%- urlPrefix %>assets/vendor/js/socket.io.min.js"></script>
|
||||
<script src="<%- urlPrefix %>assets/vendor/js/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="<%- urlPrefix %>assets/vendor/font-awesome/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="<%- urlPrefix %>assets/vendor/bootstrap5/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="<%- urlPrefix %>assets/css/bs5.wallview.css">
|
||||
<link rel="stylesheet" href="<%- urlPrefix %>assets/vendor/jquery-ui.min.css">
|
||||
<div id="wallview-container">
|
||||
<div id="wallview-canvas">
|
||||
|
||||
</div>
|
||||
<div id="wallview-controls">
|
||||
<div class="dropdown">
|
||||
<a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="monitorListButton" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<%- lang.Monitors %>
|
||||
</a>
|
||||
<ul id="wallview-monitorList" class="dropdown-menu" aria-labelledby="monitorListButton"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <script src="<%- urlPrefix %>assets/js/bs5.embed.utils.js"></script> -->
|
||||
<script src="<%- urlPrefix %>assets/vendor/bootstrap5/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="<%- urlPrefix %>assets/vendor/js/jquery-ui.min.js"></script>
|
||||
<script src="<%- urlPrefix %>assets/js/bs5.wallview.js"></script>
|
Loading…
Reference in New Issue