227 lines
5.8 KiB
PHP
227 lines
5.8 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<title>NETV MAM</title>
|
|
|
|
<style>
|
|
#app {
|
|
width: 100%;
|
|
}
|
|
|
|
#upload_target {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
width: 25vw;
|
|
height: 10vh;
|
|
border: 1px solid black;
|
|
}
|
|
|
|
.readyToDrop {
|
|
background-color: green;
|
|
}
|
|
|
|
#top_pane {
|
|
display: inline-flex;
|
|
justify-content: space-between;
|
|
width: 100vw;
|
|
height: 20vh;
|
|
}
|
|
|
|
#info_pane {
|
|
border: 1px solid black;
|
|
}
|
|
|
|
#cue_pane {
|
|
border: 1px solid black;
|
|
}
|
|
|
|
#live_pane {
|
|
border: 1px solid black;
|
|
}
|
|
|
|
#calendar_pane {
|
|
border: 1px solid black;
|
|
}
|
|
|
|
#tabs {
|
|
width: 100vw;
|
|
height: 70vh;
|
|
}
|
|
|
|
#tab_handles {
|
|
display: inline-flex;
|
|
justify-content: flex-start;
|
|
align-items: stretch;
|
|
width: 100vw;
|
|
height: 1vh;
|
|
}
|
|
|
|
.tabHandle {
|
|
border: 1px solid black;
|
|
padding: 2vh 1vw;
|
|
}
|
|
|
|
.activeTabHandle {
|
|
background-color: green;
|
|
}
|
|
|
|
.tab {
|
|
display: none;
|
|
width: 100vw;
|
|
height: 100%;
|
|
}
|
|
|
|
.activeTab {
|
|
display: block;
|
|
}
|
|
|
|
#cue_deck, #live_deck {
|
|
width: 320px;
|
|
}
|
|
</style>
|
|
|
|
</head>
|
|
<body>
|
|
<h1>NETV MAM</h1>
|
|
<div id="app">
|
|
<div id="top_pane">
|
|
<div id="info_pane">
|
|
|
|
</div>
|
|
<div id="cue_pane">
|
|
<h2>Preview</h2>
|
|
<video id="cue_deck" controls />
|
|
</div>
|
|
<div id="live_pane">
|
|
<h2>On-Air</h2>
|
|
<video id="live_deck" controls />
|
|
</div>
|
|
<div id="calendar_pane">
|
|
|
|
</div>
|
|
</div>
|
|
<div id="tabs">
|
|
<div id="tab_handles">
|
|
<div id="library_tab" class="tabHandle activeTabHandle">Library</div>
|
|
<div id="scheduler_tab" class="tabHandle">Scheduler</div>
|
|
<div id="epg_tab" class="tabHandle">EPG</div>
|
|
</div>
|
|
<div id="tab_content">
|
|
<div id="library" class="tab activeTab">
|
|
<div id="library_content">
|
|
<div id="library_left_column">
|
|
<div id="library_browser">
|
|
<div id="library_files_tab" class="active_library_tab library_tab"><a href="#">By Files</a></div>
|
|
<div id="library_tags_tab" class="library_tab"><a href="#">By Tags</a></div>
|
|
</div>
|
|
<div id="library_listing">
|
|
<?php
|
|
|
|
?>
|
|
</div>
|
|
</div>
|
|
<div id="library_details">
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="scheduler" class="tab">
|
|
Scheduler goes here
|
|
</div>
|
|
<div id="epg" class="tab">
|
|
EPG goes here
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="upload_target">Drop A Video File Here To Upload</div>
|
|
<div id="log_console"></div>
|
|
</div>
|
|
|
|
<script language="javascript">
|
|
// set up info pane
|
|
const infoPane = document.getElementById("info_pane");
|
|
function updateInfoPane() {
|
|
const now = new Date(Date.now());
|
|
infoPane.innerHTML = now.toDateString() + "<br />" +
|
|
now.toTimeString();
|
|
}
|
|
const infoTimer = setInterval(updateInfoPane, 1000);
|
|
// set up drag'n'drop file upload
|
|
const uploadTarget = document.getElementById("upload_target");
|
|
uploadTarget.addEventListener("dragenter", (event) => {
|
|
event.target.classList.add("readyToDrop");
|
|
});
|
|
uploadTarget.addEventListener("dragleave", (event) => {
|
|
event.target.classList.remove("readyToDrop");
|
|
});
|
|
uploadTarget.addEventListener("dragover", (event) => {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
});
|
|
uploadTarget.addEventListener("drop", (event) => {
|
|
console.log("Objects dropped on upload target.");
|
|
event.preventDefault();
|
|
event.target.classList.remove("readyToDrop");
|
|
|
|
if (event.dataTransfer.items) {
|
|
console.log(event.dataTransfer.items.length + " items dropped.");
|
|
[...event.dataTransfer.items].forEach((item, i) => {
|
|
// If dropped items aren't files, reject them
|
|
if (item.kind === "file") {
|
|
const file = item.getAsFile();
|
|
console.log(`… file[${i}].name = ${file.name}`);
|
|
const uploadURL = "upload.php";
|
|
let data = new FormData();
|
|
data.append('file', file);
|
|
fetch(uploadURL, {
|
|
method: "POST",
|
|
body: data
|
|
})
|
|
.then((response) => {
|
|
if (response.ok) {
|
|
response.json().then((json) => {
|
|
// TODO: add dialog to get media metadata for new upload
|
|
console.log("Upload response: ");
|
|
console.dir(json);
|
|
});
|
|
}
|
|
})
|
|
.catch(() => {});
|
|
|
|
}
|
|
});
|
|
} else {
|
|
// Use DataTransfer interface to access the file(s)
|
|
[...event.dataTransfer.files].forEach((file, i) => {
|
|
console.log(`… file[${i}].name = ${file.name}`);
|
|
});
|
|
}
|
|
});
|
|
|
|
// tab handler
|
|
const tabs = document.querySelectorAll(".tabHandle");
|
|
const tabContents = document.querySelectorAll(".tab");
|
|
tabs.forEach((tab) => {
|
|
tab.addEventListener("click", (event) => {
|
|
event.preventDefault();
|
|
console.log("Tab click: " + event.target.id);
|
|
tabs.forEach((tab) => {
|
|
if (event.target.id !== tab.id) {
|
|
tab.classList.remove("activeTabHandle");
|
|
}
|
|
});
|
|
event.target.classList.add("activeTabHandle");
|
|
tabContents.forEach((content) => {
|
|
content.classList.remove("activeTab");
|
|
});
|
|
const contentTargetId = event.target.id.replace("_tab", "");
|
|
const contentTarget = document.getElementById(contentTargetId);
|
|
contentTarget.classList.add("activeTab");
|
|
});
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|