Ticket #9939: meta-web.diff
File meta-web.diff, 32.0 KB (added by , 13 years ago) |
---|
-
new file js/dialog/dialog.css
diff --git a/js/dialog/dialog.css b/js/dialog/dialog.css new file mode 100644 index 0000000..7b73405
- + 1 /** 2 * Dialog 3 * 4 * @author Roland Franssen <franssen.roland@gmail.com> 5 * @license MIT 6 * @version 2.1 7 **/ 8 9 /* DONT CHANGE */ 10 * html .fixed { position:absolute } 11 .fixed { position:fixed } 12 13 /* DIALOG CORE */ 14 #dialog-overlay { top:0;left:0;width:100%;height:100%;z-index:900 } 15 #dialog-container { overflow:hidden;z-index:901;text-align:left } 16 17 /* DIALOG TOP */ 18 #dialog-top{background:#999;border:1px solid #fff;padding:5px;font-weight:bold} 19 #dialog-title{color:#333} 20 #dialog-close{color:#fff;padding-left:5px} 21 #dialog-close:hover{color:#ccc} 22 23 /* DIALOG BOTTOM */ 24 #dialog-bottom{background:#eee;border-top:1px solid #ccc;color:#666;padding:5px;text-align:center;font-size:12px} 25 #dialog-bottom .next, 26 #dialog-bottom .prev{color:#ccc;font-weight:bold;color:#333} 27 #dialog-bottom .next:hover, 28 #dialog-bottom .prev:hover{color:#f90} 29 #dialog-bottom .next{padding-left:10px} 30 #dialog-bottom .prev{padding-right:10px} 31 #dialog-bottom .curr{} 32 33 /* DIALOG MISC */ 34 #dialog-loading{color:#ccc;font-weight:bold;text-align:center;padding:20px} 35 36 /* DIALOG PREDEFINED */ 37 #dialog-container .alert, 38 #dialog-container .confirm { text-align:center;color:#999 } 39 #dialog-container .alert input, 40 #dialog-container .confirm input { font-weight:bold;width:75px } 41 42 /* DIALOG PERSONAL */ 43 #dialog-container .myFirstDialog { color:orange;font-size:20px } -
new file js/dialog/dialog.js
diff --git a/js/dialog/dialog.js b/js/dialog/dialog.js new file mode 100644 index 0000000..3b227ff
- + 1 /** 2 * Dialog 3 * 4 * @author Roland Franssen <franssen.roland@gmail.com> 5 * @license MIT 6 * @version 2.1 7 **/ 8 9 var Dialogs = { 10 Lang:{ 11 close: ' × ', 12 prev: '« Previous', 13 next: 'Next »', 14 loading: 'Loading...', 15 ok: 'OK', 16 yes: 'Yes', 17 no: 'No' 18 }, 19 Default:{ 20 handle: null, // css rule | element | null 21 autoOpen: false, // true | false 22 background: ['#000', '#fff'], // array 23 width: 'auto', // auto | max | integer 24 height: 'auto', // auto | max | integer 25 minWidth: null, // null | pixel value 26 minHeight: null, // null | pixel value 27 innerScroll: true, // true | false 28 opacity: .75, // float | false 29 margin: 10, // integer 30 padding: 10, // integer 31 title: null, // string | null 32 className: null, // string | null 33 content: null, // string | element | array | object | function 34 iframe: null, // string | null 35 target:{ 36 id: null, // string | null 37 auto: true // true | false 38 }, 39 ajax:{ 40 url: null, // string | null 41 jsonTemplate: null, // interpolation template string | null 42 options: {} // default ajax options 43 }, 44 close:{ 45 link: true, // true | false 46 esc: true, // true | false 47 overlay: true // true | false 48 }, 49 afterOpen: Prototype.emptyFunction, // function 50 afterClose: Prototype.emptyFunction, // function 51 afterClick: Prototype.emptyFunction, // function 52 afterIframeLoad:Prototype.emptyFunction // function 53 }, 54 Browser:{ 55 IE6:(Prototype.Browser.IE && parseInt(navigator.appVersion) == 4 && navigator.userAgent.toLowerCase().indexOf('msie 6.') != -1) 56 } 57 }; 58 59 Object.extend(Dialogs, { 60 _exec:false, 61 _open:false, 62 _elements:{ 63 overlay:['div', 'dialog-overlay', 'fixed'], 64 container:['div', 'dialog-container', 'fixed'], 65 content:['div', 'dialog-content'], 66 loading:['div', 'dialog-loading'], 67 top:['div', 'dialog-top'], 68 bottom:['div', 'dialog-bottom'], 69 title:['span', 'dialog-title'], 70 close:['a', 'dialog-close'], 71 next:['a', null, 'next'], 72 prev:['a', null, 'prev'], 73 curr:['span', null, 'curr'] 74 }, 75 fix:{ 76 scroll:Dialogs.Browser.IE6, 77 select:Dialogs.Browser.IE6 78 }, 79 view:function(){ 80 var view = document.viewport, 81 dim = view.getDimensions(), 82 data = {width:dim.width, height:dim.height}; 83 if(Dialogs.fix.scroll){ 84 var scroll = view.getScrollOffsets(); 85 data.top = scroll.top; 86 data.left = scroll.left; 87 } 88 return data; 89 }, 90 elm:function(elm){ 91 return Dialogs._elements[elm]; 92 }, 93 load:function(domready){ 94 if(!!Dialogs._exec) return; 95 Dialogs._exec = true; 96 var e = Dialogs._elements; 97 for(var x in e){ 98 var d = e[x], 99 a = {style:'display:none'}; 100 if(d[1]) a['id'] = d[1]; 101 if(d[2]) a['className'] = d[2]; 102 switch(d[0]){ 103 case 'a': a['href'] = 'javascript:;'; break; 104 } 105 var el = new Element(d[0], a); 106 if(Dialogs.Lang[x]) el.update(Dialogs.Lang[x]); 107 Dialogs._elements[x] = el; 108 } 109 var load = function(){ 110 var e = Dialogs._elements; 111 $(document.body) 112 .insert(e['overlay']) 113 .insert(e['container'] 114 .insert(e['top'] 115 .insert(e['title']) 116 .insert(e['close']) 117 ) 118 .insert(e['content']) 119 .insert(e['bottom'] 120 .insert(e['prev']) 121 .insert(e['curr']) 122 .insert(e['next']) 123 ) 124 ); 125 if(Dialogs.Browser.IE6) e['top'].insert(new Element('div', {style:'clear:both'})); 126 }; 127 if(!!domready) document.observe('dom:loaded', load); 128 else load.call(); 129 }, 130 close:function(){ 131 [Dialogs.elm('title'), Dialogs.elm('content'), Dialogs.elm('curr')].invoke('update', ''); 132 for(var x in Dialogs._elements) Dialogs._elements[x].writeAttribute('style', 'display:none'); 133 Dialogs.elm('container').setStyle('left:-99999px;top:-99999px'); 134 if(Dialogs.fix.select) 135 $$('select.dialog-hideselect').invoke('show').invoke('removeClassName', 'dialog-hideselect'); 136 Dialogs._open = false; 137 }, 138 alert:function(s){ 139 var o = new Element('input', {value:Dialogs.Lang.ok, type:'button'}), 140 a = new Dialog({ 141 className:'alert', 142 close:{link:false, esc:true}, 143 padding:20, 144 content:function(){ 145 o.observe('click', Dialogs.close); 146 return [s, '<br /><br />', o]; 147 }, 148 afterOpen:function(){ 149 o.focus(); 150 } 151 }); 152 a.open(); 153 }, 154 confirm:function(s, y_call, n_call){ 155 var y = new Element('input', {value:Dialogs.Lang.yes, type:'button'}), 156 n = new Element('input', {value:Dialogs.Lang.no, type:'button'}), 157 c = new Dialog({ 158 className:'confirm', 159 close:{link:false}, 160 padding:20, 161 content:function(){ 162 y.observe('click', function(){ 163 if(Object.isFunction(y_call)) y_call(); 164 else Dialogs.close(); 165 }); 166 n.observe('click', function(){ 167 if(Object.isFunction(n_call)) n_call(); 168 else Dialogs.close(); 169 }); 170 return [s, '<br /><br />', y, n]; 171 }, 172 afterOpen:function(){ 173 y.focus(); 174 } 175 }); 176 c.open(); 177 } 178 }); 179 var Dialog = Class.create(); 180 Dialog.prototype = { 181 initialize:function(opt){ 182 this.opt = Object.extend(Object.clone(Dialogs.Default), opt || {}); 183 var c = this.opt.content; 184 if(Object.isFunction(c)) 185 Object.extend(this.opt, {content:c()}); 186 c = this.opt.content; 187 if(Object.isString(this.opt.target.id) || Object.isElement(this.opt.target.id)){ 188 var b = $(this.opt.target.id); 189 Object.extend(this.opt, {content:b.innerHTML}); 190 if(this.opt.target.auto){ 191 var a = /#(.+)$/.exec(window.location); 192 if(Object.isArray(a) && Object.isString(a[1])){ 193 a = a[1].split(',').last(); 194 if(a == b.identify()) this.open.bind(this).delay(1); 195 } 196 } 197 }else if(Object.isHash(c)) 198 this.steps = { 199 i:0, 200 k:c.keys(), 201 v:c.values(), 202 m:c.size() 203 }; 204 this.attachEvents(); 205 if(this.opt.autoOpen) this.open(); 206 }, 207 exec:function(bool){ 208 return Dialogs._open == this._open && Dialogs.elm('overlay').visible() && bool; 209 }, 210 attachEvents:function(){ 211 Event.observe(window, 'resize', this.setDimensions.bindAsEventListener(this)); 212 if(Dialogs.fix.scroll) 213 Event.observe(window, 'scroll', this.setScroll.bindAsEventListener(this)); 214 var handles = []; 215 if(Object.isElement(this.opt.handle)) handles.push($(this.opt.handle)); 216 else if(Object.isArray(this.opt.handle)) this.opt.handle.each(function(handle){ handles.push($(handle)); }); 217 else if(Object.isString(this.opt.handle)) handles = $$(this.opt.handle); 218 handles.invoke('show').invoke('observe', 'click', function(e){ 219 e.stop(); 220 if(Object.isFunction(this.opt.afterClick)) this.opt.afterClick(e); 221 this.open(); 222 }.bindAsEventListener(this)); 223 Dialogs.elm('close').observe('click', function(){ 224 if(this.exec(this.opt.close.link)) this.close(); 225 }.bindAsEventListener(this)); 226 Dialogs.elm('overlay').observe('click', function(){ 227 if(this.exec(this.opt.close.overlay)) this.close(); 228 }.bindAsEventListener(this)); 229 document.observe('keyup', function(e){ 230 if(this.exec(this.opt.close.esc && (e.which || e.keyCode) == Event.KEY_ESC)) this.close(); 231 }.bindAsEventListener(this)); 232 if(this.steps){ 233 [Dialogs.elm('prev'), Dialogs.elm('next')].invoke('observe', 'click', this.setSteps.bindAsEventListener(this)); 234 document.observe('keydown', function(e){ 235 var c = e.which || e.keyCode; 236 if(this.exec((c == Event.KEY_LEFT) || (c == Event.KEY_RIGHT))) this.setSteps(e); 237 }.bindAsEventListener(this)); 238 } 239 }, 240 setAuto:function(){ 241 this.auto = {max:0}; 242 var t = Dialogs.elm('title'), c = Dialogs.elm('close'); 243 [t,c].invoke('setStyle', 'float:none'); 244 $w('top content bottom').each(function(b){ 245 var e = Dialogs.elm(b); 246 if(!e.visible()) this.auto[b] = {width:0,height:0}; 247 else{ 248 e.writeAttribute('style', 'display:inline;float:left;overflow:visible;white-space:nowrap'); 249 this.auto[b] = e.getDimensions(); 250 e.writeAttribute('style', 'overflow:hidden'); 251 if(b == 'content') this.auto[b].width += (parseInt(this.opt.padding) || 0) * 2; 252 if(this.auto[b].width > this.auto.max) this.auto.max = this.auto[b].width; 253 } 254 }.bind(this)); 255 t.setStyle('float:left'); 256 c.setStyle('float:right'); 257 }, 258 setDimensions:function(){ 259 if(!this.exec(true)) return; 260 this.setAuto(); 261 var a = this.auto, 262 d = Dialogs.view(), 263 t = Dialogs.elm('content'), 264 c = Dialogs.elm('container'), 265 o = { 266 m:((parseInt(this.opt.margin) || 0) * 2), 267 p:((parseInt(this.opt.padding) || 0) * 2), 268 t:a.top.height, 269 b:a.bottom.height 270 }, 271 m = {width:(d.width-o.m), height:(d.height-o.m-o.t-o.b)}, 272 h = this.opt.height, 273 w = this.opt.width, 274 x = y = false; 275 if(Object.isNumber(w)) w += o.p; 276 if(w == 'max') w = m.width; 277 if(!Object.isNumber(w)) w = a.max; 278 if(w < (this.opt.minWidth || 0)) w = this.opt.minWidth || 0; 279 if(w > m.width){ w = m.width; x = true } 280 t.setStyle('width:'+(w-o.p)+'px;height:auto'); 281 if(Object.isNumber(h)) h += o.p; 282 if(h == 'max') h = m.height; 283 if(!Object.isNumber(h)) h = t.getHeight()+o.p; 284 if(h < (this.opt.minHeight || 0)) w = this.opt.minHeight || 0; 285 if(h > m.height){ h = m.height; y = true; } 286 t.setStyle('height:'+(h-o.p)+'px;padding:'+(o.p/2)+'px'); 287 // dh: commented out to seperate overflow-x and overflow-y 288 // if(this.opt.innerScroll && (x || y)) t.setStyle('overflow:scroll'); 289 if(this.opt.innerScroll && x) t.setStyle('overflow-x:scroll'); 290 if(this.opt.innerScroll && y) t.setStyle('overflow-y:scroll'); 291 var s = {w:w,h:(h+o.t+o.b)}; 292 c.setStyle('width:'+s.w+'px;height:'+s.h+'px;top:50%;left:50%;margin:-'+parseInt(s.h/2)+'px 0 0 -'+parseInt(s.w/2)+'px'); 293 if(Dialogs.fix.scroll){ 294 Dialogs.elm('overlay').setStyle('width:'+d.width+'px;height:'+d.height+'px'); 295 this.setScroll(); 296 } 297 }, 298 setScroll:function(){ 299 if(!this.exec(true)) return; 300 var v = Dialogs.view(), 301 c = Dialogs.elm('container'), 302 d = c.getDimensions(), 303 t = v.top + parseInt((v.height - d.height) / 2), 304 l = v.left + parseInt((v.width - d.width) / 2); 305 c.setStyle('margin:0;top:'+t+'px;left:'+l+'px'); 306 Dialogs.elm('overlay').setStyle('margin:'+v.top+'px 0 0 '+v.left+'px'); 307 }, 308 setLoad:function(){ 309 var l = Dialogs.elm('loading').show(), 310 t = Dialogs.elm('content'), 311 b = t.down('#'+l.identify()); 312 if(!Object.isElement(b)) t.insert(l); 313 }, 314 setAjax:function(){ 315 this.setLoad(); 316 var o = this.opt.ajax.options || {}, 317 c = (o.onComplete && Object.isFunction(o.onComplete) ? o.onComplete : null), 318 a = function(t){ 319 var tpl = this.opt.ajax.jsonTemplate; 320 if(t.responseJSON && Object.isString(tpl)) Dialogs.elm('content').update(tpl.interpolate(t.responseJSON)); 321 else Dialogs.elm('content').update(t.responseText || ''); 322 this.setImages(); 323 this.setDimensions(); 324 if(Object.isFunction(c)) c(t); 325 }.bind(this); 326 Object.extend(o, {onComplete:a}); 327 new Ajax.Request(this.opt.ajax.url, o); 328 }, 329 setIframe:function(){ 330 this.setLoad(); 331 var f = new Element('iframe', {src:this.opt.iframe, frameborder:0, id:'dialog-iframe'}); 332 Dialogs.elm('content').insert(f); 333 f.observe('load', function(){ 334 Dialogs.elm('loading').hide(); 335 f.setStyle('width:100%;height:100%'); 336 this.setDimensions(); 337 if(Object.isFunction(this.opt.afterIframeLoad)) this.opt.afterIframeLoad(); 338 }.bindAsEventListener(this)); 339 }, 340 setSteps:function(ev){ 341 if(!this.exec(true)) return; 342 var m = this.steps.m, 343 s = false, 344 n = Dialogs.elm('next'), 345 p = Dialogs.elm('prev'); 346 if((ev.which || ev.keyCode) == Event.KEY_RIGHT || ev.element().hasClassName('next')){ 347 if(this.steps.i < (m - 1)) s = true; 348 if(s) ++this.steps.i; 349 if(((this.steps.i + 1) >= m) && n.visible()) n.hide(); 350 if(((this.steps.i - 1) >= 0) && !p.visible()) p.show(); 351 }else{ 352 if(this.steps.i > 0) s = true; 353 if(s) --this.steps.i; 354 if(((this.steps.i - 1) < 0) && p.visible()) p.hide(); 355 if(((this.steps.i + 1) <= m) && !n.visible()) n.show(); 356 } 357 if(s) this.setContent(); 358 }, 359 setContent:function(){ 360 var c = this.opt.content, 361 t = Dialogs.elm('content'); 362 t.update(''); 363 if(Object.isString(c) || Object.isElement(c)) t.insert(c); 364 else if(Object.isArray(c)) c.each(function(b){ t.insert(b); }); 365 else if(Object.isHash(c)){ 366 var b = Dialogs.elm('bottom'); 367 t.update('').insert(this.steps.v[this.steps.i]); 368 Dialogs.elm('curr').update(this.steps.k[this.steps.i]); 369 if(!b.visible()) b.show().childElements().invoke('show'); 370 if(this.steps.i <= 0) Dialogs.elm('prev').hide(); 371 if(this.steps.i >= (this.steps.m - 1)) Dialogs.elm('next').hide(); 372 }else if(Object.isString(this.opt.ajax.url)) this.setAjax(); 373 else if(Object.isString(this.opt.iframe)) this.setIframe(); 374 this.setImages(); 375 this.setDimensions.bind(this).defer(); 376 }, 377 setImages:function(){ 378 Dialogs.elm('content').select('img').each(function(el){ 379 el.onload = function(){ 380 this.setDimensions(); 381 }.bind(this); 382 }.bind(this)); 383 }, 384 open:function(){ 385 if(Dialogs.fix.select) 386 $$('select').select(function(el){ return el.visible(); }).invoke('hide').invoke('addClassName', 'dialog-hideselect'); 387 if(Object.isString(this.opt.title) || this.opt.close.link){ 388 if(Object.isString(this.opt.title)) Dialogs.elm('title').show().update(this.opt.title); 389 if(this.opt.close.link) Dialogs.elm('close').show(); 390 else Dialogs.elm('close').hide(); 391 Dialogs.elm('top').show(); 392 }else Dialogs.elm('top').hide(); 393 var o = Dialogs.elm('overlay'), c = Dialogs.elm('container'), t = Dialogs.elm('content'); 394 [o, c, t].invoke('show'); 395 // dh: commented out background so it can be set via class 396 // o.setOpacity(this.opt.opacity || 1).setStyle({background:this.opt.background[0] || '#000'}); 397 o.setOpacity(this.opt.opacity || 1); 398 // dh: commented out background so it can be set via class 399 // c.writeAttribute('style', 'left:-99999px;top:-99999px;background:'+(this.opt.background[1] || '#fff')); 400 c.writeAttribute('style', 'left:-99999px;top:-99999px;'); 401 t.writeAttribute('class', this.opt.className || ''); 402 Dialogs._open = new Date().getTime(); 403 this._open = Dialogs._open; 404 this.setContent(); 405 if(Object.isFunction(this.opt.afterOpen)) this.opt.afterOpen(); 406 }, 407 close:function(){ 408 Dialogs.close(); 409 if(Object.isFunction(this.opt.afterClose)) this.opt.afterClose(); 410 } 411 }; -
modules/_shared/tmpl/default/header.php
diff --git a/modules/_shared/tmpl/default/header.php b/modules/_shared/tmpl/default/header.php index 691d059..2d16bc0 100644
a b EOF; 70 70 </script> 71 71 72 72 <link rel="stylesheet" type="text/css" href="js/prototip/prototip.css"> 73 <link rel="stylesheet" type="text/css" href="js/dialog/dialog.css"> 73 74 <link rel="stylesheet" type="text/css" href="<?php echo skin_url ?>/style.css"> 74 75 <link rel="stylesheet" type="text/css" href="<?php echo skin_url ?>/header.css"> 75 76 <link rel="stylesheet" type="text/css" href="<?php echo skin_url ?>/menus.css"> … … EOF; 84 85 85 86 <script type="text/javascript" src="js/prototype.js"></script> 86 87 <script type="text/javascript" src="js/prototip/prototip.js"></script> 88 <script type="text/javascript" src="js/dialog/dialog.js"></script> 87 89 88 90 <script type="text/javascript" src="js/utils.js"></script> 89 91 <script type="text/javascript" src="js/AC_OETags.js"></script> -
new file modules/tv/lookup_metadata.php
diff --git a/modules/tv/lookup_metadata.php b/modules/tv/lookup_metadata.php new file mode 100644 index 0000000..ca9cfbf
- + 1 <?php 2 /** 3 * Does a query against the backend to look up metadata for a show 4 * returns the result as JSON 5 * 6 * @license GPL 7 * 8 * @package MythWeb 9 * @subpackage TV 10 * 11 /**/ 12 13 header('Content-Type: application/json'); 14 15 $url = "Video/LookupVideo"; 16 $args = array( 17 'Title' => $_REQUEST['title'], 18 'Subtitle' => $_REQUEST['subtitle'], 19 'Inetref' => $_REQUEST['inetref'], 20 'Season' => $_REQUEST['season'], 21 'Episode' => $_REQUEST['episode'], 22 'GrabberType' => $_REQUEST['grabbertype']); 23 24 echo MythBackend::find()->httpRequestAsJson($url, $args); -
modules/tv/tmpl/default/_advanced_options.php
diff --git a/modules/tv/tmpl/default/_advanced_options.php b/modules/tv/tmpl/default/_advanced_options.php index 421e9ae..69083e1 100644
a b 24 24 ); 25 25 } 26 26 27 // Tries to populate the inetref, season and episode fields 28 // by doing a metadata lookup against the backend. If multiple 29 // results are return displays a dialog to let the user choose 30 // the appropriate show 31 function lookupMetadata() { 32 ajax_add_request(); 33 34 new Ajax.Request('<?php echo root_url ?>tv/lookup_metadata', 35 { 36 parameters: { 37 'title' : "<?php echo $schedule->title ?>", 38 'subtitle' : "<?php echo $schedule->subtitle ?>", 39 'inetref' : $("inetref").value, 40 'season' : $("season").value, 41 'episode' : $("episode").value 42 }, 43 asynchronous: true, 44 method: 'get', 45 onSuccess: onMetadata, 46 onFailure: onMetadataFailure 47 } 48 ); 49 } 50 51 // callback for when metadata is returned for this show 52 function onMetadata(transport) { 53 ajax_remove_request(); 54 55 // make sure we got valid date 56 if (!transport || !transport.responseJSON || !transport.responseJSON.VideoLookupList) { 57 messageDialog("<?php echo t("Metadata Lookup Error")?>", 58 "<?php echo t("Server returned invalid data when attempting to retrieve metadata.")?>"); 59 } 60 61 var list = transport.responseJSON.VideoLookupList; 62 63 // display an error if there's no data 64 if (list.Count == 0) { 65 messageDialog("<?php echo t("Metadata Lookup")?>", "<?php echo t("No metadata results found.")?>"); 66 67 // populate the data immediately if there is one result 68 } else if (list.Count == 1) { 69 updateMetadata(list.VideoLookups[0]); 70 71 // otherwise display a dialog for the user to choose which result 72 } else { 73 multipleResultDialog(list); 74 } 75 } 76 77 // updates the inetref, season & episode values on the page 78 // optionally creates or updates a "metdata home page" link 79 // in the "More" section of the page 80 function updateMetadata(item) { 81 $("inetref").value = item.InetRef; 82 $("season").value = item.Season; 83 $("episode").value = item.Episode; 84 85 var homePage = $("home-page"); 86 87 // if this item doesn't have a home page link then 88 // remove the existing link or ignore 89 if (!item.HomePage) { 90 homePage && Element.remove(homePage); 91 return; 92 } 93 94 // update the link or create it if this item does have a home page 95 if (homePage) { 96 homePage.href = item.HomePage; 97 } else { 98 $$(".x-links")[0].children[1].insert({top: 99 new Element("a", {href: item.HomePage, target: "_new", id: "home-page"}).update("<?php echo t("Metadata Home Page") ?>")}); 100 } 101 } 102 103 // displays a dialog with an image and title of each possible show 104 // if the user clicks on one of them then populates the metadata in the page 105 function multipleResultDialog(list) { 106 // parent div for the result 107 var parent = new Element("div", {"class": "multiple-metadata"}); 108 109 // add all of the results 110 parent.insert(generateResults(list)); 111 112 // add a cancel "button" to exit without choosing an option 113 var a = new Element("a", {}).update("<?php echo t("Cancel") ?>"); 114 Event.observe(a, "click", function() { Dialogs.close(); }); 115 var d = new Element("div", {"class": "commands"}); 116 d.insert(a); 117 parent.insert(d); 118 119 // display the dialog 120 new Dialog({ 121 opacity: 0.9, 122 title: "<?php echo t("Select the correct show")?>", 123 content: parent 124 }).open(); 125 } 126 127 // returns a div with a list of all of the items neatly formatted 128 function generateResults(list) { 129 var div = new Element("div", {"class": "metadata-list"}); 130 131 for (var i=0; i < list.VideoLookups.length; i++) { 132 div.insert(generateResultsItem(list.VideoLookups[i])); 133 } 134 135 return div; 136 } 137 138 // returns a div for a single result 139 // includes hover and click event handlers 140 function generateResultsItem(item) { 141 var div = new Element("div", {"class": "metadata-item"}); 142 Event.observe(div, "mouseover", function(e) { this.addClassName("hover");}); 143 Event.observe(div, "mouseout", function(e) { this.removeClassName("hover");}); 144 Event.observe(div, "click", function(e) { updateMetadata(item); Dialogs.close();}); 145 var img = generateItemImg(item); 146 div.insert(img); 147 var title = new Element("div", {"class": "title"}); 148 title.update(item.Title); 149 div.insert(title); 150 return div; 151 } 152 153 // generates an image or empty div based on if there is 154 // any thumbnail art work for this item 155 function generateItemImg(item) { 156 if (item.Artwork && item.Artwork.length) { 157 var art = item.Artwork[0]; 158 var thumbUrl = art.Thumbnail; 159 return new Element("img", {src: thumbUrl, "class": art.Type}); 160 } 161 return new Element("div", {"class": "no-art"}); 162 } 163 164 // callback for failure contacting the server 165 function onMetadataFailure(response) { 166 ajax_remove_request(); 167 messageDialog("<?php echo t("Metadata Lookup Error")?>", "<?php echo t("Error contacting server to retrieve metadata.")?>"); 168 } 169 170 // displays a dialog with a message in it and an OK button 171 function messageDialog(title, msg) { 172 $("metadata-message").update(msg); 173 new Dialog({ 174 opacity: 0.9, 175 title: title, 176 target:{ 177 id:'message-dialog', 178 auto:true 179 } 180 }).open(); 181 182 } 183 184 // Hook to start up the Dialog JS 185 Dialogs.load(); 186 27 187 // --> 28 188 </script> 29 30 189 <h3><?php echo t('Advanced Options') ?>:</h3> 31 190 (<?php 32 echo '<a href="#"onclick="toggle_advanced(false); return false;" id="hide_advanced"';191 echo '<a onclick="toggle_advanced(false); return false;" id="hide_advanced"'; 33 192 if (!$_SESSION['tv']['show_advanced_schedule']) 34 193 echo ' style="display: none"'; 35 194 echo '>', t('Hide'), '</a>', … … 133 292 <dt><?php echo t('Preferred Input') ?>:</dt> 134 293 <dd><?php input_select($schedule->prefinput, 'prefinput') ?></dd> 135 294 <dt><?php echo t('Internet Reference #') ?>:</dt> 136 <dd ><input type="text" name="inetref" value="<?php echo html_entities($schedule->inetref) ?>"></dd>295 <dd class="commands"><input id="inetref" class="inetref" type="text" name="inetref" value="<?php echo html_entities($schedule->inetref) ?>"><a onclick="lookupMetadata(); return false;"><?php echo t("Look up Metadata")?></a></dd> 137 296 <dt><?php echo t('Season') ?>:</dt> 138 <dd><input type="text" class="quantity" name="season" value="<?php echo html_entities($schedule->season) ?>"></dd>297 <dd><input type="text" id="season" class="quantity" name="season" value="<?php echo html_entities($schedule->season) ?>"></dd> 139 298 <dt><?php echo t('Episode') ?>:</dt> 140 <dd><input type="text" class="quantity" name="episode" value="<?php echo html_entities($schedule->episode) ?>"></dd>299 <dd><input type="text" id="episode" class="quantity" name="episode" value="<?php echo html_entities($schedule->episode) ?>"></dd> 141 300 <dt><label for="autometadata"><?php echo t('Look up Metadata') ?>:</label></dt> 142 301 <dd><input type="checkbox" class="radio" id="autometadata" name="autometadata"<?php if ($schedule->autometadata) echo ' CHECKED' ?> value="1"></dd> 143 302 <dt><label for="autocommflag"><?php echo t('Auto-flag commercials') ?>:</label></dt> … … 167 326 <dd><input type="text" class="quantity" name="endoffset" value="<?php echo html_entities($schedule->endoffset) ?>"> 168 327 <?php echo t('minutes') ?></dd> 169 328 </dl> 329 330 <div style="display: none;" id="message-dialog"> 331 <div id="metadata-message"></div> 332 <div class="commands"> 333 <a onclick="Dialogs.close(); return false;"><?php echo t('OK') ?></a> 334 </div> 335 </div> -
modules/tv/tmpl/default/detail.php
diff --git a/modules/tv/tmpl/default/detail.php b/modules/tv/tmpl/default/detail.php index 71ed1ea..4c0526a 100644
a b 94 94 parameters: {exit: 1, 95 95 host: host, 96 96 chanid: chanid, 97 starttime: starttime ,97 starttime: starttime 98 98 } 99 99 } 100 100 ); 101 101 } 102 102 103 // Tries to find metadata for the current item 104 // If found adds a "Home Page" link to the page 105 function lookupMetadata() { 106 new Ajax.Request('<?php echo root_url ?>tv/lookup_metadata', 107 { 108 parameters: { 109 'title' : "<?php echo $program->title ?>", 110 'subtitle' : "<?php echo $program->subtitle ?>", 111 'inetref' : "<?php echo $program->inetref ?>", 112 'season' : "<?php echo $program->season ?>", 113 'episode' : "<?php echo $program->episode ?>" 114 }, 115 asynchronous: true, 116 method: 'get', 117 onSuccess: onMetadata, 118 onFailure: onMetadataFailure 119 } 120 ); 121 122 } 123 124 // if metadata is found inserts a home page link behind the inetref value 125 function onMetadata(transport) { 126 var list = transport.responseJSON.VideoLookupList; 127 128 // if there are 0 or > 1 entry then we just ignore it 129 if (list.Count == 1) { 130 $("metadata-home-page").insert( 131 new Element("a", {href: list.VideoLookups[0].HomePage, target: "_new"}).update("<?php echo t("(Metdata Home Page)")?>")); 132 } 133 134 } 135 136 // silently fail (no need to disrupt the page) 137 function onMetadataFailure(transport) { 138 } 139 140 // hook to look up data once the page has started 141 lookupMetadata(); 103 142 // --> 104 143 </script> 105 144 … … 214 250 if (strlen($program->inetref) > 0) { 215 251 ?><tr class="x-extras"> 216 252 <th><?php echo t('Internet Reference #') ?>:</th> 217 <td><?php echo $program->inetref ?> </td>253 <td><?php echo $program->inetref ?> <span id="metadata-home-page"></span></td> 218 254 </tr><?php 219 255 } 220 256 if ($program->season > 0) { -
skins/default/style.css
diff --git a/skins/default/style.css b/skins/default/style.css index 2fbb26e..7353351 100644
a b 235 235 #feed_buttons a { 236 236 padding-right: 1em; 237 237 } 238 239 #dialog-overlay { 240 background-color: #506090; 241 } 242 243 #dialog-top { 244 background-color: #203670; 245 border: 1px solid #203670; 246 } 247 248 #dialog-title { 249 color: white; 250 251 } 252 253 #dialog-content { 254 background-color: #265990; 255 text-align: center; 256 } -
skins/default/tv_schedule.css
diff --git a/skins/default/tv_schedule.css b/skins/default/tv_schedule.css index b1a7ed9..3ae3388 100644
a b 56 56 width: 18em; 57 57 } 58 58 59 #schedule input.inetref { 60 width: 5em !important; 61 margin-right: 20px; 62 } 63 59 64 /* A special subclass for options with extra-long input fields */ 60 65 #schedule .x-options dl.x-long input, .x-options dl.x-long textarea { 61 66 width: 32em; … … 73 78 padding: .5em 0 1em 0; 74 79 } 75 80 81 /* Metadata specific classes */ 82 83 #metadata-message { 84 margin-bottom: 10px; 85 } 86 87 .multiple-metadata { 88 } 89 90 .metadata-item { 91 width: 500px; 92 min-height: 150px; 93 margin: 0px 15px 10px 0px; 94 border: 1px solid white; 95 } 96 97 .metadata-item.hover { 98 background-color: white; 99 cursor: pointer; 100 color: #265990; 101 } 102 103 .metadata-item img { 104 float: left; 105 } 106 107 .metadata-item img.coverart { 108 height: 150px; 109 width: 100px; 110 } 111 112 .metadata-item img.fanart { 113 height: 150px; 114 width: 100px; 115 } 116 117 .metadata-item img.banner { 118 height: 55px; 119 width: 300px; 120 margin: 5px auto 0px; 121 float: none; 122 } 123 124 .metadata-item .no-art { 125 height: 2em; 126 } 127 128 129 .metadata-item .title { 130 font-size: 3em; 131 font-weight: bold; 132 padding-top: .5em; 133 } 134