diff options
author | thlo <smarttv640@gmail.com> | 2013-01-05 16:37:48 +0100 |
---|---|---|
committer | thlo <t.lohmar@gmx.de> | 2013-01-05 16:37:48 +0100 |
commit | 0adab5a1ba140dda76e34a9347d69247c4de2263 (patch) | |
tree | ca3b209b5179ce9e87a9b4371a50e7747a54fba6 /vdr-smarttvweb/web | |
parent | 06c6db56340d4f97c9f0ef0d7634778bb65b5eb4 (diff) | |
download | vdr-plugin-smarttvweb-0adab5a1ba140dda76e34a9347d69247c4de2263.tar.gz vdr-plugin-smarttvweb-0adab5a1ba140dda76e34a9347d69247c4de2263.tar.bz2 |
New Web Front End. Various bug fixes.
Diffstat (limited to 'vdr-smarttvweb/web')
-rwxr-xr-x | vdr-smarttvweb/web/Data.js | 247 | ||||
-rwxr-xr-x | vdr-smarttvweb/web/Server.js | 120 | ||||
-rwxr-xr-x | vdr-smarttvweb/web/favicon.ico | bin | 0 -> 1502 bytes | |||
-rwxr-xr-x | vdr-smarttvweb/web/index.html | 100 |
4 files changed, 467 insertions, 0 deletions
diff --git a/vdr-smarttvweb/web/Data.js b/vdr-smarttvweb/web/Data.js new file mode 100755 index 0000000..5e480d2 --- /dev/null +++ b/vdr-smarttvweb/web/Data.js @@ -0,0 +1,247 @@ +var Data =
+{
+ assets : new Item,
+ folderList : [],
+};
+
+Data.reset = function() {
+ this.assets = null;
+ this.assets = new Item;
+
+ this.folderList = [];
+
+ this.folderList.push({item : this.assets, id: 0});
+};
+
+Data.completed= function(sort) {
+ if (sort == true)
+ this.assets.sortPayload();
+
+ this.folderList.push({item : this.assets, id: 0});
+ console.log ("Data.completed()= " +this.folderList.length);
+
+};
+
+Data.selectFolder = function (idx) {
+ this.folderList.push({item : this.getCurrentItem().childs[idx], id: idx});
+};
+
+Data.isRootFolder = function() {
+ if (this.folderList.length == 1)
+ return true;
+ else
+ return false;
+};
+
+Data.folderUp = function () {
+ itm = this.folderList.pop();
+ return itm.id;
+};
+
+Data.addItem = function(t_list, pyld) {
+ this.assets.addChild(t_list, pyld, 0);
+};
+
+Data.dumpFolderStruct = function(){
+ Main.log("---------- dumpFolderStruct ------------");
+ this.assets.print(0);
+ Main.log("---------- dumpFolderStruct Done -------");
+};
+
+Data.createDomTree = function () {
+
+ return this.assets.createDomTree(0);
+};
+
+Data.createJQMDomTree = function () {
+ return this.assets.createJQMDomTree(0);
+};
+
+Data.getCurrentItem = function () {
+ return this.folderList[this.folderList.length-1].item;
+};
+
+Data.getVideoCount = function()
+{
+ return this.folderList[this.folderList.length-1].item.childs.length;
+};
+
+Data.getNumString =function(num, fmt) {
+ var res = "";
+
+ if (num < 10) {
+ for (var i = 1; i < fmt; i ++) {
+ res += "0";
+ };
+ } else if (num < 100) {
+ for (var i = 2; i < fmt; i ++) {
+ res += "0";
+ };
+ }
+
+ res = res + num;
+
+ return res;
+};
+
+
+//-----------------------------------------
+function Item() {
+ this.title = "root";
+ this.isFolder = true;
+ this.childs = [];
+ this.payload = ""; // only set, if (isFolder == false)
+}
+
+Item.prototype.isFolder = function() {
+ return this.isFolder;
+};
+
+Item.prototype.getTitle = function () {
+ return this.title;
+};
+
+Item.prototype.getPayload = function () {
+ if (this.isFolder == true) {
+ Main.log("WARNING: getting payload on a folder title=" +this.title);
+ }
+ return this.payload;
+};
+
+Item.prototype.getItem = function (title) {
+ for (var i = 0; i < this.childs.length; i++) {
+ if (this.childs[i].title == title) {
+ return this.childs[i];
+ }
+ }
+ return 0;
+};
+
+Item.prototype.addChild = function (key, pyld, level) {
+ if (key.length == 1) {
+ var folder = new Item;
+// folder.title = pyld.startstr + " - " + key;
+ folder.title = key[0];
+ folder.payload = pyld;
+ folder.isFolder = false;
+ this.childs.push(folder);
+// this.titles.push({title: pyld.startstr + " - " + key , pyld : pyld});
+ }
+ else {
+ if (level > 10) {
+ Main.log(" too many levels");
+ return;
+ }
+ var t = key.shift();
+ var found = false;
+ for (var i = 0; i < this.childs.length; i++) {
+ if (this.childs[i].title == t) {
+ this.childs[i].addChild(key, pyld, level +1);
+ found = true;
+ break;
+ }
+ }
+ if (found == false) {
+ var folder = new Item;
+ folder.title = t;
+ folder.addChild(key, pyld, level+1);
+ this.childs.push(folder);
+ }
+ }
+};
+
+Item.prototype.print = function(level) {
+ var prefix= "";
+ for (var i = 0; i < level; i++)
+ prefix += " ";
+
+ for (var i = 0; i < this.childs.length; i++) {
+ Main.log(prefix + this.childs[i].title);
+ if (this.childs[i].isFolder == true) {
+ Main.log(prefix+"Childs:");
+ this.childs[i].print(level +1);
+ }
+ }
+};
+
+Item.prototype.createDomTree = function(level) {
+ var prefix= "";
+ for (var i = 0; i < level; i++)
+ prefix += "-";
+// var mydiv = $('<div class="folder">' +prefix+this.title+ '</div>');
+ var mydiv = $('<ul />');
+
+ for (var i = 0; i < this.childs.length; i++) {
+ if (this.childs[i].isFolder == true) {
+// mydiv.appendChild(this.childs[i].createDomTree());
+ var myli = $('<li class="folder">' +prefix +this.childs[i].title + '</li>');
+ myli.append(this.childs[i].createDomTree(level+1));
+ mydiv.append(myli);
+ }
+ else {
+// var mya = $('<a class="link">' +prefix +this.childs[i].title + '</a>');
+ var mya = $('<a>', { text: prefix +this.childs[i].title, href: this.childs[i].payload['link']} );
+ var myli = $('<li class="item"/>');
+ myli.append(mya);
+ mydiv.append(myli);
+ }
+ }
+ return mydiv;
+};
+
+Item.prototype.createJQMDomTree = function(level) {
+ var mydiv = $('<ul />');
+// if (level == 0) {
+ mydiv.attr('data-role', 'listview');
+ mydiv.attr('data-inset', 'true');
+// };
+//, id:'dyncreated'
+ for (var i = 0; i < this.childs.length; i++) {
+ if (this.childs[i].isFolder == true) {
+ var myh = $('<div>', {text: this.childs[i].title});
+ var myli = $('<li>');
+ myli.append(myh);
+ var mycount = $('<p>', {class: 'ui-li-count', text: this.childs[i].childs.length});
+ myli.append(mycount);
+ myli.append(this.childs[i].createJQMDomTree(level+1));
+ mydiv.append(myli);
+ }
+ else {
+ // Links
+ var digi = new Date(this.childs[i].payload['start'] *1000);
+ var mon = Data.getNumString ((digi.getMonth()+1), 2);
+ var day = Data.getNumString (digi.getDate(), 2);
+ var hour = Data.getNumString (digi.getHours(), 2);
+ var min = Data.getNumString (digi.getMinutes(), 2);
+
+ var d_str = mon + "/" + day + " " + hour + ":" + min;
+ var mya = $('<a>', { text: d_str + " - " + this.childs[i].title,
+ href: this.childs[i].payload['link'],
+ rel: 'external'} );
+ var myli = $('<li class="item"/>');
+ myli.attr('data-icon', 'false');
+ myli.attr('data-theme', 'c');
+
+ myli.append(mya);
+ mydiv.append(myli);
+ }
+ }
+ return mydiv;
+};
+
+Item.prototype.sortPayload = function() {
+ for (var i = 0; i < this.childs.length; i++) {
+ if (this.childs[i].isFolder == true) {
+ this.childs[i].sortPayload();
+ }
+ }
+ this.childs.sort(function(a,b) {
+ if (a.title == b.title) {
+ return (b.payload.start - a.payload.start);
+ }
+ else {
+ return ((a.title < b.title) ? -1 : 1);
+ }
+ });
+};
+
diff --git a/vdr-smarttvweb/web/Server.js b/vdr-smarttvweb/web/Server.js new file mode 100755 index 0000000..9fb39c5 --- /dev/null +++ b/vdr-smarttvweb/web/Server.js @@ -0,0 +1,120 @@ +var Server =
+{
+ dataReceivedCallback : null,
+ errorCallback : null,
+ doSort : false,
+ retries : 0,
+
+ XHRObj : null
+};
+
+Server.init = function()
+{
+ var success = true;
+
+ if (this.XHRObj) {
+ this.XHRObj.destroy();
+ this.XHRObj = null;
+ }
+
+ return success;
+};
+
+Server.setSort = function (val) {
+ this.doSort = val;
+};
+
+Server.fetchVideoList = function(url) {
+ if (this.XHRObj == null) {
+ this.XHRObj = new XMLHttpRequest();
+ }
+
+ if (this.XHRObj) {
+ this.XHRObj.onreadystatechange = function()
+ {
+ var splashElement = document.getElementById("splashStatus");
+
+ if (Server.XHRObj.readyState == 4) {
+ Server.createVideoList();
+ }
+ };
+
+ this.XHRObj.open("GET", url, true);
+ this.XHRObj.send(null);
+ }
+ else {
+ console.log("Failed to create XHR");
+
+ if (this.errorCallback != null) {
+ this.errorCallback("ServerError");
+ }
+ }
+};
+
+Server.createVideoList = function() {
+ console.log ("creating Video list now");
+
+ if (this.XHRObj.status != 200) {
+ if (this.errorCallback != null) {
+ this.errorCallback("ServerError");
+ }
+ }
+ else
+ {
+ var xmlResponse = this.XHRObj.responseXML;
+ if (xmlResponse == null) {
+ if (this.errorCallback != null) {
+ this.errorCallback("XmlError");
+ }
+ return;
+ }
+ var xmlElement = xmlResponse.documentElement;
+
+ if (!xmlElement) {
+ console.log("Failed to get valid XML");
+ return;
+ }
+ else
+ {
+ var items = xmlElement.getElementsByTagName("item");
+ if (items.length == 0) {
+ console.log("Something wrong. Response does not contain any item");
+ };
+
+ for (var index = 0; index < items.length; index++) {
+
+ var titleElement = items[index].getElementsByTagName("title")[0];
+ var progElement = items[index].getElementsByTagName("programme")[0];
+ var descriptionElement = items[index].getElementsByTagName("description")[0];
+ var linkElement = items[index].getElementsByTagName("link")[0];
+ var startVal =0;
+ var durVal =0;
+ try {
+ startVal = parseInt(items[index].getElementsByTagName("start")[0].firstChild.data);
+ durVal = parseInt(items[index].getElementsByTagName("duration")[0].firstChild.data);
+ }
+ catch (e) {
+ console.log("ERROR: "+e);
+ }
+
+ var desc = descriptionElement.firstChild.data;
+
+ if (titleElement && linkElement) {
+ var title_list = titleElement.firstChild.data.split("~");
+ Data.addItem( title_list, {link : linkElement.firstChild.data,
+ prog: progElement.firstChild.data,
+ desc: desc,
+ start: startVal,
+ dur: durVal});
+ }
+
+ }
+ Data.completed(this.doSort);
+
+ if (this.dataReceivedCallback)
+ {
+ this.dataReceivedCallback(); /* Notify all data is received and stored */
+ }
+ }
+ }
+};
diff --git a/vdr-smarttvweb/web/favicon.ico b/vdr-smarttvweb/web/favicon.ico Binary files differnew file mode 100755 index 0000000..2236569 --- /dev/null +++ b/vdr-smarttvweb/web/favicon.ico diff --git a/vdr-smarttvweb/web/index.html b/vdr-smarttvweb/web/index.html new file mode 100755 index 0000000..9e1117b --- /dev/null +++ b/vdr-smarttvweb/web/index.html @@ -0,0 +1,100 @@ +<!DOCTYPE html> +<html> +<head> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" /> +<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> +<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script> +<script language="javascript" type="text/javascript" src="Server.js"></script> +<script language="javascript" type="text/javascript" src="Data.js"></script> +<script> +$(document).ready(function(){ + var state = 'rec'; // Rec + + Server.init(); + + Server.dataReceivedCallback = function() { + console.log("Loaded"); + $("#anchor").append(Data.createJQMDomTree()).trigger('create'); + $.mobile.loading('hide'); + //http://jquerymobile.com/ + + // end of dataReceivedCallBack + }; + + $.mobile.loading('show'); + Server.setSort(true); + Server.fetchVideoList("/recordings.xml"); + + removeDomTree = function () { + // parent should not be deleted. + $("#anchor").children().remove(); + }; + + buttonHandler = function(btn) { + console.log("Click: " + btn); + if (state == btn) { + console.log("No Change"); + }; + $.mobile.loading('show'); + Data.reset(); + removeDomTree(); + switch (btn) { + case 'rec': + state = 'rec'; + $('#recbtn').addClass('ui-btn-active'); + $('#medbtn').removeClass('ui-btn-active'); + $('#chnbtn').removeClass('ui-btn-active'); + Server.setSort(true); + Server.fetchVideoList("/recordings.xml"); + break; + case 'med': + state = 'med'; + $('#medbtn').addClass('ui-btn-active'); + $('#recbtn').removeClass('ui-btn-active'); + $('#chnbtn').removeClass('ui-btn-active'); + Server.setSort(true); + Server.fetchVideoList("/media.xml"); + break; + case 'chn': + state = 'chn'; + $('#chnbtn').addClass('ui-btn-active'); + $('#medbtn').removeClass('ui-btn-active'); + $('#recbtn').removeClass('ui-btn-active'); + Server.setSort(false); + Server.fetchVideoList("/channels.xml"); + break; + }; + }; + +}); +</script> +<style type="text/css" > +h2 { margin:1.2em 0 .4em 0; } + } +</style> +</head> + +<body> + <div data-role="page" class="type-interior"> + + <div data-role="header" data-theme="b"> + <h1>Recordings</h1> + </div> <!-- /header --> + + <div data-role="content"> + <div class="content-primary" > + + <div data-role="controlgroup" data-type="horizontal" data-mini="true"> + <a href="#" id="recbtn" data-role="button" data-transition="fade" class="ui-btn-active" onclick="return buttonHandler('rec')">Recordings</a> + <a href="#" id="medbtn" data-role="button" data-transition="fade" onclick="return buttonHandler('med')">Media</a> + <a href="#" id="chnbtn" data-role="button" data-transition="fade" onclick="return buttonHandler('chn')">Channels</a> + </div> + + <div id="anchor"/> + </div> + </div> +</div> + </body> +</html> + |