homepage.php 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070
  1. <?php
  2. $data = false;
  3. ini_set("display_errors", 1);
  4. ini_set("error_reporting", E_ALL | E_STRICT);
  5. require_once("user.php");
  6. require_once("functions.php");
  7. use Kryptonit3\Sonarr\Sonarr;
  8. use Kryptonit3\SickRage\SickRage;
  9. $sonarr = new Sonarr(SONARRURL, SONARRKEY);
  10. $radarr = new Sonarr(RADARRURL, RADARRKEY);
  11. $sickrage = new SickRage(SICKRAGEURL, SICKRAGEKEY);
  12. $USER = new User("registration_callback");
  13. // Check if connection to homepage is allowed
  14. qualifyUser(HOMEPAGEAUTHNEEDED, true);
  15. // Load Colours/Appearance
  16. foreach(loadAppearance() as $key => $value) {
  17. ${$key} = $value;
  18. }
  19. $startDate = date('Y-m-d',strtotime("-".CALENDARSTARTDAY." days"));
  20. $endDate = date('Y-m-d',strtotime("+".CALENDARENDDAY." days"));
  21. ?>
  22. <!DOCTYPE html>
  23. <html lang="en" class="no-js">
  24. <head>
  25. <meta charset="UTF-8">
  26. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  27. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  28. <meta name="msapplication-tap-highlight" content="no" />
  29. <title><?=$title;?> Homepage</title>
  30. <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
  31. <link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.min.css">
  32. <link rel="stylesheet" href="bower_components/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.css">
  33. <script src="js/menu/modernizr.custom.js"></script>
  34. <link rel="stylesheet" href="bower_components/animate.css/animate.min.css">
  35. <link rel="stylesheet" href="bower_components/fullcalendar/dist/fullcalendar.css">
  36. <link rel="stylesheet" href="css/style.css?v=<?php echo INSTALLEDVERSION; ?>">
  37. <link rel="stylesheet" href="bower_components/mdi/css/materialdesignicons.min.css?v=<?php echo INSTALLEDVERSION; ?>">
  38. <link rel="stylesheet" href="bower_components/google-material-color/dist/palette.css?v=<?php echo INSTALLEDVERSION; ?>">
  39. <link rel="stylesheet" type="text/css" href="bower_components/slick/slick.css?v=<?php echo INSTALLEDVERSION; ?>">
  40. <!-- Add the slick-theme.css if you want default styling -->
  41. <!--Scripts-->
  42. <script src="bower_components/jquery/dist/jquery.min.js"></script>
  43. <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
  44. <script src="bower_components/moment/min/moment.min.js"></script>
  45. <script src="bower_components/jquery.nicescroll/jquery.nicescroll.min.js"></script>
  46. <script src="bower_components/slimScroll/jquery.slimscroll.min.js"></script>
  47. <script src="bower_components/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.js"></script>
  48. <script src="bower_components/jquery.nicescroll/jquery.nicescroll.min.js"></script>
  49. <script src="bower_components/cta/dist/cta.min.js"></script>
  50. <script src="bower_components/fullcalendar/dist/fullcalendar.js?v=<?php echo INSTALLEDVERSION; ?>"></script>
  51. <script src="bower_components/slick/slick.js?v=<?php echo INSTALLEDVERSION; ?>"></script>
  52. <script src="js/jqueri_ui_custom/jquery-ui.min.js"></script>
  53. <script src="js/jquery.mousewheel.min.js" type="text/javascript"></script>
  54. <!--Other-->
  55. <script src="js/ajax.js?v=<?php echo INSTALLEDVERSION; ?>"></script>
  56. <!--[if lt IE 9]>
  57. <script src="bower_components/html5shiv/dist/html5shiv.min.js"></script>
  58. <script src="bower_components/respondJs/dest/respond.min.js"></script>
  59. <![endif]-->
  60. <style>
  61. .fc-day-grid-event{
  62. cursor: pointer;
  63. }
  64. .recentItems {
  65. padding-top: 10px;
  66. margin: 5px 0;
  67. }
  68. .slick-image-tall{
  69. width: 125px;
  70. height: 180px;
  71. }
  72. .slick-image-short{
  73. width: 125px;
  74. height: 130px;
  75. margin-top: 50px;
  76. }
  77. .overlay{
  78. position: absolute;
  79. top: 0;
  80. left: 0;
  81. width: 100%;
  82. height: 100%;
  83. display: none;
  84. z-index: 0;
  85. opacity: .98;
  86. }
  87. sort {
  88. display: none;
  89. }
  90. table.fc-list-table {
  91. table-layout: auto;
  92. }.tabbable{
  93. margin-bottom: 0;
  94. }.fc-day-grid-event .fc-content {
  95. white-space: normal;
  96. }.fc-list-item {
  97. table-layout: auto;
  98. position: inherit;
  99. margin: 10px;
  100. border-radius: 4px;
  101. padding: 0 5px 0 5px;
  102. color: #fff !important;
  103. }.fc-calendar .fc-toolbar {
  104. background: <?=$topbar;?>;
  105. color: <?=$topbartext;?>;
  106. border-radius: 5px 5px 0 0;
  107. padding: 15px;
  108. }.fc-calendar .fc-toolbar .fc-right {
  109. bottom: 0px;
  110. right: 20px;
  111. }.fc-calendar .fc-toolbar .fc-right button {
  112. color: <?=$topbartext;?>;
  113. }.fc-calendar .fc-toolbar .fc-prev-button, .fc-calendar .fc-toolbar .fc-next-button {
  114. color: <?=$topbartext;?>;
  115. }.carousel-image{
  116. width: 100px !important;
  117. height: 150px !important;
  118. border-radius: 3px 0 0 3px;
  119. }.carousel-image.album{
  120. width: 150px !important;
  121. height: 150px !important;
  122. border-radius: 3px 0 0 3px;
  123. }.carousel-control.album {
  124. top: 5px !important;
  125. width: 4% !important;
  126. }.carousel-control {
  127. top: 5px !important;
  128. width: 4% !important;
  129. }.carousel-caption.album {
  130. position: absolute;
  131. right: 4%;
  132. top: 0px;
  133. left: 160px;
  134. z-index: 10;
  135. bottom: 0px;
  136. padding-top: 0px;
  137. color: #fff;
  138. text-align: left;
  139. }.carousel-caption {
  140. position: absolute;
  141. right: 4%;
  142. top: 0px;
  143. left: 110px;
  144. z-index: 10;
  145. bottom: 0px;
  146. padding-top: 0px;
  147. color: #fff;
  148. text-align: left;
  149. padding-bottom: 2px !important;
  150. overflow: hidden !important;
  151. } @media screen and (max-width: 576px) {
  152. .nzbtable {
  153. padding-left: 5px !important;
  154. padding-right: 2px !important;
  155. font-size: 10px !important;
  156. word-break: break-word !important;
  157. }
  158. .nzbtable-file-row {
  159. padding-left: 5px !important;
  160. padding-right: 2px !important;
  161. font-size: 10px !important;
  162. white-space: normal !important;
  163. word-break: break-all !important;
  164. width: 0% !important;
  165. }
  166. } .nzbtable-file-row {
  167. white-space: normal !important;
  168. word-break: break-all !important;
  169. width: 0% !important;
  170. }.nzbtable-row {
  171. white-space: normal !important;
  172. width: 0% !important;
  173. font-size: 12px; !important;
  174. }<?php customCSS(); ?>
  175. </style>
  176. </head>
  177. <body class="scroller-body" style="padding: 0px;">
  178. <div class="main-wrapper" style="position: initial;">
  179. <div id="content" class="container-fluid">
  180. <br/>
  181. <?php if (qualifyUser(HOMEPAGENOTICEAUTH) && HOMEPAGENOTICETITLE && HOMEPAGENOTICETYPE && HOMEPAGENOTICEMESSAGE && HOMEPAGENOTICELAYOUT) { echo buildHomepageNotice(HOMEPAGENOTICELAYOUT, HOMEPAGENOTICETYPE, HOMEPAGENOTICETITLE, HOMEPAGENOTICEMESSAGE); } ?>
  182. <?php if (qualifyUser(HOMEPAGECUSTOMHTML1AUTH) && HOMEPAGECUSTOMHTML1) { echo "<div>" . HOMEPAGECUSTOMHTML1 . "</div>"; } ?>
  183. <?php if(SPEEDTEST == "true"){ ?>
  184. <style type="text/css">
  185. .flash {
  186. animation: flash 0.6s linear infinite;
  187. }
  188. @keyframes flash {
  189. 0% { opacity: 0.6; }
  190. 50% { opacity: 1; }
  191. }
  192. </style>
  193. <script type="text/javascript">
  194. var w = null
  195. function runTest() {
  196. document.getElementById('startBtn').style.display = 'none'
  197. document.getElementById('testArea').style.display = ''
  198. document.getElementById('abortBtn').style.display = ''
  199. w = new Worker('bower_components/speed/speedtest_worker.min.js')
  200. var interval = setInterval(function () { w.postMessage('status') }, 100)
  201. w.onmessage = function (event) {
  202. var data = event.data.split(';')
  203. var status = Number(data[0])
  204. var dl = document.getElementById('download')
  205. var ul = document.getElementById('upload')
  206. var ping = document.getElementById('ping')
  207. var jitter = document.getElementById('jitter')
  208. dl.className = status === 1 ? 'w-name flash' : 'w-name'
  209. ping.className = status === 2 ? 'w-name flash' : 'w-name'
  210. jitter.className = ul.className = status === 3 ? 'w-name flash' : 'w-name'
  211. if (status >= 4) {
  212. clearInterval(interval)
  213. document.getElementById('abortBtn').style.display = 'none'
  214. document.getElementById('startBtn').style.display = ''
  215. w = null
  216. }
  217. if (status === 5) {
  218. document.getElementById('testArea').style.display = 'none'
  219. }
  220. dl.textContent = data[1] + " Mbit/s";
  221. $("#downloadpercent").attr("style", "width: " + data[1] + "%;");
  222. $("#uploadpercent").attr("style", "width: " + data[2] + "%;");
  223. $("#pingpercent").attr("style", "width: " + data[3] + "%;");
  224. $("#jitterpercent").attr("style", "width: " + data[5] + "%;");
  225. ul.textContent = data[2] + " Mbit/s";
  226. ping.textContent = data[3] + " ms";
  227. jitter.textContent = data[5] + " ms";
  228. }
  229. w.postMessage('start')
  230. }
  231. function abortTest() {
  232. if (w) w.postMessage('abort')
  233. }
  234. </script>
  235. <div class="row" id="testArea" style="display:none">
  236. <div class="test col-sm-3 col-lg-3">
  237. <div class="content-box ultra-widget green-bg" data-counter="">
  238. <div id="downloadpercent" class="progress-bar progress-bar-striped active w-used" style=""></div>
  239. <div class="w-content">
  240. <div class="w-icon right pull-right"><i class="mdi mdi-cloud-download"></i></div>
  241. <div class="w-descr left pull-left text-center">
  242. <span class="testName text-uppercase w-name">Download</span>
  243. <br>
  244. <span class="w-name counter" id="download" ></span>
  245. </div>
  246. </div>
  247. </div>
  248. </div>
  249. <div class="test col-sm-3 col-lg-3">
  250. <div class="content-box ultra-widget red-bg" data-counter="">
  251. <div id="uploadpercent" class="progress-bar progress-bar-striped active w-used" style=""></div>
  252. <div class="w-content">
  253. <div class="w-icon right pull-right"><i class="mdi mdi-cloud-upload"></i></div>
  254. <div class="w-descr left pull-left text-center">
  255. <span class="testName text-uppercase w-name">Upload</span>
  256. <br>
  257. <span class="w-name counter" id="upload" ></span>
  258. </div>
  259. </div>
  260. </div>
  261. </div>
  262. <div class="test col-sm-3 col-lg-3">
  263. <div class="content-box ultra-widget yellow-bg" data-counter="">
  264. <div id="pingpercent" class="progress-bar progress-bar-striped active w-used" style=""></div>
  265. <div class="w-content">
  266. <div class="w-icon right pull-right"><i class="mdi mdi-timer"></i></div>
  267. <div class="w-descr left pull-left text-center">
  268. <span class="testName text-uppercase w-name">Latency</span>
  269. <br>
  270. <span class="w-name counter" id="ping" ></span>
  271. </div>
  272. </div>
  273. </div>
  274. </div>
  275. <div class="test col-sm-3 col-lg-3">
  276. <div class="content-box ultra-widget blue-bg" data-counter="">
  277. <div id="jitterpercent" class="progress-bar progress-bar-striped active w-used" style=""></div>
  278. <div class="w-content">
  279. <div class="w-icon right pull-right"><i class="mdi mdi-pulse"></i></div>
  280. <div class="w-descr left pull-left text-center">
  281. <span class="testName text-uppercase w-name">Jitter</span>
  282. <br>
  283. <span class="w-name counter" id="jitter" ></span>
  284. </div>
  285. </div>
  286. </div>
  287. </div>
  288. <br/>
  289. </div>
  290. <div id="abortBtn" class="row" style="display: none" onclick="javascript:abortTest()">
  291. <div class="col-lg-12">
  292. <div class="content-box red-bg" style="cursor: pointer;">
  293. <h1 style="margin: 10px" class="text-uppercase text-center">Abort Speed Test</h1>
  294. <div class="clearfix"></div>
  295. </div>
  296. </div>
  297. </div>
  298. <div id="startBtn" class="row" onclick="javascript:runTest()">
  299. <div class="col-lg-12">
  300. <div class="content-box green-bg" style="cursor: pointer;">
  301. <h1 style="margin: 10px" class="text-uppercase text-center">Run Speed Test</h1>
  302. <div class="clearfix"></div>
  303. </div>
  304. </div>
  305. </div>
  306. <?php } ?>
  307. <?php if((PLEXSEARCH == "true" && qualifyUser(PLEXHOMEAUTH))) { ?>
  308. <div id="searchPlexRow" class="row">
  309. <div class="col-lg-12">
  310. <div class="content-box box-shadow big-box todo-list">
  311. <form id="plexSearchForm" onsubmit="return false;" autocomplete="off">
  312. <div class="">
  313. <div class="input-group">
  314. <div style="border-radius: 25px 0 0 25px; border:0" class="input-group-addon gray-bg"><i class="fa fa-search white"></i></div>
  315. <input id="searchInput" type="text" style="border-radius: 0;" autocomplete="off" name="search-title" class="form-control input-group-addon gray-bg" placeholder="Media Search">
  316. <div id="clearSearch" style="border-radius: 0 25px 25px 0;border:0; cursor: pointer;" class="input-group-addon gray-bg"><i class="fa fa-close white"></i></div>
  317. <button style="display:none" id="plexSearchForm_submit" class="btn btn-primary waves"></button>
  318. </div>
  319. </div>
  320. </form>
  321. <div id="resultshere" class="table-responsive"></div>
  322. </div>
  323. </div>
  324. </div>
  325. <?php } ?>
  326. <?php if((NZBGETURL != "" && qualifyUser(NZBGETHOMEAUTH)) || (SABNZBDURL != "" && qualifyUser(SABNZBDHOMEAUTH))) { ?>
  327. <div id="downloadClientRow" class="row">
  328. <div class="col-xs-12 col-md-12">
  329. <div class="content-box">
  330. <div class="tabbable panel with-nav-tabs panel-default">
  331. <div class="panel-heading">
  332. <div class="content-tools i-block pull-right">
  333. <a id="getDownloader" class="repeat-btn">
  334. <i class="fa fa-repeat"></i>
  335. </a>
  336. <a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
  337. <i class="fa fa-chevron-down"></i>
  338. </a>
  339. <!-- Lets Move This To Homepage Settings
  340. <ul id="downloaderSeconds" class="dropdown-menu" style="top: 32px !important">
  341. <li data-value="5000"><a>Refresh every 5 seconds</a></li>
  342. <li data-value="10000"><a>Refresh every 10 seconds</a></li>
  343. <li data-value="30000"><a>Refresh every 30 seconds</a></li>
  344. <li data-value="60000"><a>Refresh every 60 seconds</a></li>
  345. </ul>
  346. -->
  347. </div>
  348. <h3 class="pull-left"><?php if(NZBGETURL != ""){ echo "NZBGet "; } if(SABNZBDURL != ""){ echo "SABnzbd "; } ?></h3>
  349. <ul class="nav nav-tabs pull-right">
  350. <li class="active"><a href="#downloadQueue" data-toggle="tab" aria-expanded="true"><?php echo $language->translate("QUEUE");?></a></li>
  351. <li class=""><a href="#downloadHistory" data-toggle="tab" aria-expanded="false"><?php echo $language->translate("HISTORY");?></a></li>
  352. </ul>
  353. <div class="clearfix"></div>
  354. </div>
  355. <div class="panel-body">
  356. <div class="tab-content">
  357. <div class="tab-pane fade active in" id="downloadQueue">
  358. <div class="table-responsive" style="max-height: 300px">
  359. <table class="table table-striped progress-widget zero-m" style="max-height: 300px">
  360. <thead>
  361. <tr>
  362. <th class="col-xs-7 nzbtable-file-row"><?php echo $language->translate("FILE");?></th>
  363. <th class="col-xs-2 nzbtable"><?php echo $language->translate("STATUS");?></th>
  364. <th class="col-xs-1 nzbtable"><?php echo $language->translate("CATEGORY");?></th>
  365. <th class="col-xs-2 nzbtable"><?php echo $language->translate("PROGRESS");?></th>
  366. </tr>
  367. </thead>
  368. <tbody class="dl-queue sabnzbd"></tbody>
  369. <tbody class="dl-queue nzbget"></tbody>
  370. </table>
  371. </div>
  372. </div>
  373. <div class="tab-pane fade" id="downloadHistory">
  374. <div class="table-responsive" style="max-height: 300px">
  375. <table class="table table-striped progress-widget zero-m" style="max-height: 300px">
  376. <thead>
  377. <tr>
  378. <th class="col-xs-7 nzbtable-file-row"><?php echo $language->translate("FILE");?></th>
  379. <th class="col-xs-2 nzbtable"><?php echo $language->translate("STATUS");?></th>
  380. <th class="col-xs-1 nzbtable"><?php echo $language->translate("CATEGORY");?></th>
  381. <th class="col-xs-2 nzbtable"><?php echo $language->translate("PROGRESS");?></th>
  382. </tr>
  383. </thead>
  384. <tbody class="dl-history sabnzbd"></tbody>
  385. <tbody class="dl-history nzbget"></tbody>
  386. </table>
  387. </div>
  388. </div>
  389. </div>
  390. </div>
  391. </div>
  392. </div>
  393. </div>
  394. </div>
  395. <?php } ?>
  396. <?php if (qualifyUser(PLEXHOMEAUTH) && PLEXTOKEN) { ?>
  397. <div id="plexRowNowPlaying" class="row">
  398. <?php if(PLEXPLAYINGNOW == "true"){ echo getPlexStreams(12, PLEXSHOWNAMES, $USER->role); } ?>
  399. </div>
  400. <div id="plexRow" class="row">
  401. <div class="col-lg-12">
  402. <?php
  403. if(PLEXRECENTMOVIE == "true" || PLEXRECENTTV == "true" || PLEXRECENTMUSIC == "true"){
  404. $plexArray = array("movie" => PLEXRECENTMOVIE, "season" => PLEXRECENTTV, "album" => PLEXRECENTMUSIC);
  405. echo getPlexRecent($plexArray);
  406. }
  407. ?>
  408. </div>
  409. </div>
  410. <div id="plexPlaylists" class="row">
  411. <div class="col-lg-12">
  412. <?php
  413. if(PLEXPLAYLISTS == "true"){
  414. echo getPlexPlaylists($plexArray);
  415. }
  416. ?>
  417. </div>
  418. </div>
  419. <?php } ?>
  420. <?php if (qualifyUser(EMBYHOMEAUTH) && EMBYTOKEN) { ?>
  421. <div id="embyRowNowPlaying" class="row">
  422. <?php if(EMBYPLAYINGNOW == "true"){ echo getEmbyStreams(12, EMBYSHOWNAMES, $USER->role); } ?>
  423. </div>
  424. <div id="embyRow" class="row">
  425. <div class="col-lg-12">
  426. <?php
  427. if(EMBYRECENTMOVIE == "true" || EMBYRECENTTV == "true" || EMBYRECENTMUSIC == "true"){
  428. $embyArray = array("Movie" => EMBYRECENTMOVIE, "Episode" => EMBYRECENTTV, "MusicAlbum" => EMBYRECENTMUSIC, "Series" => EMBYRECENTTV);
  429. echo getEmbyRecent($embyArray);
  430. }
  431. ?>
  432. </div>
  433. </div>
  434. <?php } ?>
  435. <?php if ((SONARRURL != "" && qualifyUser(SONARRHOMEAUTH)) || (RADARRURL != "" && qualifyUser(RADARRHOMEAUTH)) || (HEADPHONESURL != "" && qualifyUser(HEADPHONESHOMEAUTH)) || (SICKRAGEURL != "" && qualifyUser(SICKRAGEHOMEAUTH))) { ?>
  436. <div id="calendarLegendRow" class="row" style="padding: 0 0 10px 0;">
  437. <div class="col-lg-12 content-form form-inline">
  438. <div class="form-group">
  439. <select class="form-control" id="imagetype_selector" style="width: auto !important; display: inline-block">
  440. <option value="all">View All</option>
  441. <?php if(RADARRURL != ""){ echo '<option value="film">Movies</option>'; }?>
  442. <?php if(SONARRURL != "" || SICKRAGEURL != ""){ echo '<option value="tv">TV Shows</option>'; }?>
  443. <?php if(HEADPHONESURL != ""){ echo '<option value="music">Music</option>'; }?>
  444. </select>
  445. <span class="label label-primary well-sm">Available</span>
  446. <span class="label label-danger well-sm">Unavailable</span>
  447. <span class="label indigo-bg well-sm">Unreleased</span>
  448. <span class="label light-blue-bg well-sm">Premier</span>
  449. </div>
  450. <!--
  451. <div class="pull-right">
  452. <div class="btn-group" role="group">
  453. <button type="button" class="btn waves btn-default btn-sm dropdown-toggle waves-effect waves-float" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">View All<span class="caret"></span></button>
  454. <ul style="right:0; left: auto" class="dropdown-menu">
  455. <li><a class="" href="javascript:void(0)">Movies</a></li>
  456. <li><a class="" href="javascript:void(0)">TV Shows</a></li>
  457. <li><a class="" href="javascript:void(0)">Music</a></li>
  458. </ul>
  459. </div>
  460. </div>-->
  461. </div>
  462. </div>
  463. <div id="calendarRow" class="row">
  464. <div class="col-lg-12">
  465. <div id="calendar" class="fc-calendar box-shadow fc fc-ltr fc-unthemed"></div>
  466. </div>
  467. </div>
  468. <?php } ?>
  469. </div>
  470. </div>
  471. <script>
  472. $('.close-btn').click(function(e){
  473. var closedBox = $(this).closest('div.content-box').remove();
  474. e.preventDefault();
  475. });
  476. $('#clearSearch').click(function(e){
  477. $('#searchInput').val("");
  478. $('#resultshere').html("");
  479. $('#searchInput').focus();
  480. e.preventDefault();
  481. });
  482. $(document).on("click", ".openTab", function(e) {
  483. if($(this).attr("openTab") === "true") {
  484. var isActive = parent.$("div[data-content-name^='<?php echo strtolower(PLEXTABNAME);?>']");
  485. var activeFrame = isActive.children('iframe');
  486. if(isActive.length === 1){
  487. activeFrame.attr("src", $(this).attr("href"));
  488. parent.$("li[name='<?php echo strtolower(PLEXTABNAME);?>']").trigger("click");
  489. }else{
  490. parent.$("li[name='<?php echo strtolower(PLEXTABNAME);?>']").trigger("click");
  491. parent.$("div[data-content-name^='<?php echo strtolower(PLEXTABNAME);?>']").children('iframe').attr("src", $(this).attr("href"));
  492. }
  493. e.preventDefault();
  494. }else{
  495. console.log("nope");
  496. }
  497. });
  498. function localStorageSupport() {
  499. return (('localStorage' in window) && window['localStorage'] !== null)
  500. }
  501. $( document ).ready(function() {
  502. $('#plexSearchForm').on('submit', function () {
  503. var refreshBox = $(this).closest('div.content-box');
  504. $("<div class='refresh-preloader'><div class='la-timer la-dark'><div></div></div></div>").appendTo(refreshBox).fadeIn(300);
  505. setTimeout(function(){
  506. var refreshPreloader = refreshBox.find('.refresh-preloader'),
  507. deletedRefreshBox = refreshPreloader.fadeOut(300, function(){
  508. refreshPreloader.remove();
  509. });
  510. },1000);
  511. ajax_request('POST', 'search-plex', {
  512. searchtitle: $('#plexSearchForm [name=search-title]').val(),
  513. }).done(function(data){ $('#resultshere').html(data);});
  514. });
  515. $('.repeat-btn').click(function(){
  516. var refreshBox = $(this).closest('div.content-box');
  517. $("<div class='refresh-preloader'><div class='la-timer la-dark'><div></div></div></div>").appendTo(refreshBox).fadeIn(300);
  518. setTimeout(function(){
  519. var refreshPreloader = refreshBox.find('.refresh-preloader'),
  520. deletedRefreshBox = refreshPreloader.fadeOut(300, function(){
  521. refreshPreloader.remove();
  522. });
  523. },1500);
  524. });
  525. $(document).on('click', '.w-refresh', function(){
  526. var id = $(this).attr("link");
  527. $("div[np^='"+id+"']").toggle();
  528. });
  529. $('div[class*=recentItems-]').each(function() {
  530. var name = $(this).attr("data-name");
  531. console.log(name);
  532. $(this).slick({
  533. slidesToShow: 13,
  534. slidesToScroll: 13,
  535. infinite: true,
  536. lazyLoad: 'ondemand',
  537. prevArrow: '<a class="zero-m pull-left prev-mail btn btn-default waves waves-button btn-sm waves-effect waves-float"><i class="fa fa-angle-left"></i></a>',
  538. nextArrow: '<a class="pull-left next-mail btn btn-default waves waves-button btn-sm waves-effect waves-float"><i class="fa fa-angle-right"></i></a>',
  539. appendArrows: $('.'+name),
  540. arrows: true,
  541. responsive: [
  542. {
  543. breakpoint: 1750,
  544. settings: {
  545. slidesToShow: 12,
  546. slidesToScroll: 12,
  547. }
  548. },
  549. {
  550. breakpoint: 1600,
  551. settings: {
  552. slidesToShow: 11,
  553. slidesToScroll: 11,
  554. }
  555. },
  556. {
  557. breakpoint: 1450,
  558. settings: {
  559. slidesToShow: 10,
  560. slidesToScroll: 10,
  561. }
  562. },
  563. {
  564. breakpoint: 1300,
  565. settings: {
  566. slidesToShow: 9,
  567. slidesToScroll: 9,
  568. }
  569. },
  570. {
  571. breakpoint: 1150,
  572. settings: {
  573. slidesToShow: 8,
  574. slidesToScroll: 8,
  575. }
  576. },
  577. {
  578. breakpoint: 1000,
  579. settings: {
  580. slidesToShow: 7,
  581. slidesToScroll: 7,
  582. }
  583. },
  584. {
  585. breakpoint: 850,
  586. settings: {
  587. slidesToShow: 6,
  588. slidesToScroll: 6,
  589. }
  590. },
  591. {
  592. breakpoint: 700,
  593. settings: {
  594. slidesToShow: 5,
  595. slidesToScroll: 5,
  596. }
  597. },
  598. {
  599. breakpoint: 675,
  600. settings: {
  601. slidesToShow: 4,
  602. slidesToScroll: 4
  603. }
  604. },
  605. {
  606. breakpoint: 480,
  607. settings: {
  608. slidesToShow: 3,
  609. slidesToScroll: 3
  610. }
  611. }
  612. // You can unslick at a given breakpoint now by adding:
  613. // settings: "unslick"
  614. // instead of a settings object
  615. ]
  616. });
  617. });
  618. //RECENT ITEMS
  619. // each filter we click on
  620. $(".filter-recent-event > li").on("click", function() {
  621. // toggle the filter on/off
  622. $(this).data( "filter-on" , !$(this).data("filter-on") );
  623. // set all the filter strings to empty
  624. var filtersOn = "";
  625. var filtersOff = "";
  626. var allFilters = "";
  627. // loop through each filter
  628. $(".filter-recent-event > li").each(function() {
  629. // set a variable to hold the value of the filter class
  630. // and also if the filter is on/off
  631. var filter = $(this).data("filter");
  632. var isOn = $(this).data("filter-on");
  633. // add the filter to the filtersOn / filtersOff collection
  634. if( isOn ) {
  635. filtersOn += "." + filter + ", ";
  636. var title=$(this).attr('data-filter').split('-')[1];
  637. if(title == "movie"){
  638. var titleOriginal = "Movies";
  639. }else if(title == "season"){
  640. var titleOriginal = "Shows";
  641. }else if(title == "album"){
  642. var titleOriginal = "Music";
  643. }
  644. $('.js-filter-'+title).text(titleOriginal+' Active');
  645. } else {
  646. filtersOff += "." + filter + ", ";
  647. var title=$(this).attr('data-filter').split('-')[1];
  648. if(title == "movie"){
  649. var titleOriginal = "Movies";
  650. }else if(title == "season"){
  651. var titleOriginal = "Shows";
  652. }else if(title == "album"){
  653. var titleOriginal = "Music";
  654. }
  655. $('.js-filter-'+title).text(titleOriginal);
  656. }
  657. });
  658. // remove the last ", " from each filter collection.
  659. filtersOn = filtersOn.replace(/, $/, "");
  660. filtersOff = filtersOff.replace(/, $/, "");
  661. // remove all filters if none are on.
  662. if( filtersOn === "" ) {
  663. filtersOn = "*";
  664. filtersOff = "";
  665. }
  666. // combine the filters together ( on + off )
  667. allFilters = filtersOn + ":not(" + filtersOff + ")";
  668. console.log( allFilters );
  669. // now filter the slides.
  670. $('.recentItems-recent')
  671. .slick('slickUnfilter')
  672. .slick('slickFilter' , allFilters );
  673. });
  674. //PLAYLIST SHIT
  675. // each filter we click on
  676. $(".filter-recent-playlist > li").on("click", function() {
  677. var name = $(this).attr('data-name');
  678. var filter = $(this).attr('data-filter');
  679. $('#playlist-title').text(name);
  680. // now filter the slides.
  681. $('.recentItems-playlists')
  682. .slick('slickUnfilter')
  683. .slick('slickFilter' , '.'+filter );
  684. });
  685. $("body").niceScroll({
  686. railpadding: {top:0,right:0,left:0,bottom:0},
  687. scrollspeed: 30,
  688. mousescrollstep: 60
  689. });
  690. $(".table-responsive").niceScroll({
  691. railpadding: {top:0,right:0,left:0,bottom:0},
  692. scrollspeed: 30,
  693. mousescrollstep: 60
  694. });
  695. <?php if((NZBGETURL != "" && qualifyUser(NZBGETHOMEAUTH)) || (SABNZBDURL != "" && qualifyUser(SABNZBDHOMEAUTH))){ ?>
  696. var queueRefresh = <?php echo DOWNLOADREFRESH; ?>;
  697. var historyRefresh = <?php echo HISTORYREFRESH; ?>; // This really doesn't need to happen that often
  698. var queueLoad = function() {
  699. <?php if(SABNZBDURL != "") { echo '$("tbody.dl-queue.sabnzbd").load("ajax.php?a=sabnzbd-update&list=queue");'; } ?>
  700. <?php if(NZBGETURL != "") { echo '$("tbody.dl-queue.nzbget").load("ajax.php?a=nzbget-update&list=listgroups");'; } ?>
  701. };
  702. var historyLoad = function() {
  703. <?php if(SABNZBDURL != "") { echo '$("tbody.dl-history.sabnzbd").load("ajax.php?a=sabnzbd-update&list=history");'; } ?>
  704. <?php if(NZBGETURL != "") { echo '$("tbody.dl-history.nzbget").load("ajax.php?a=nzbget-update&list=history");'; } ?>
  705. };
  706. // Initial Loads
  707. queueLoad();
  708. historyLoad();
  709. // Interval Loads
  710. var queueInterval = setInterval(queueLoad, queueRefresh);
  711. var historyInterval = setInterval(historyLoad, historyRefresh);
  712. // Manual Load
  713. $("#getDownloader").click(function() {
  714. queueLoad();
  715. historyLoad();
  716. });
  717. <?php } ?>
  718. });
  719. $( window ).on( "load", function() {
  720. $( "ul.filter-recent-playlist > li:first" ).trigger("click");
  721. });
  722. </script>
  723. <?php if ((SONARRURL != "" && qualifyUser(SONARRHOMEAUTH)) || (RADARRURL != "" && qualifyUser(RADARRHOMEAUTH)) || (HEADPHONESURL != "" && qualifyUser(HEADPHONESHOMEAUTH)) || (SICKRAGEURL != "" && qualifyUser(SICKRAGEHOMEAUTH))) { ?>
  724. <script>
  725. $(function () {
  726. var date = new Date();
  727. var d = date.getDate();
  728. var m = date.getMonth();
  729. var y = date.getFullYear();
  730. $('#calendar').fullCalendar({
  731. eventLimit: false,
  732. firstDay: <?php echo CALENDARSTART;?>,
  733. height: "auto",
  734. defaultView: '<?php echo CALENDARVIEW;?>',
  735. header: {
  736. left: 'prev,next,',
  737. center: 'title',
  738. right: 'today, month, basicDay,basicWeek,'
  739. },
  740. views: {
  741. basicDay: { buttonText: '<?php echo $language->translate("DAY");?>', eventLimit: false },
  742. basicWeek: { buttonText: '<?php echo $language->translate("WEEK");?>', eventLimit: false },
  743. month: { buttonText: '<?php echo $language->translate("MONTH");?>', eventLimit: false },
  744. today: { buttonText: '<?php echo $language->translate("TODAY");?>' },
  745. },
  746. events: [
  747. <?php
  748. if (SICKRAGEURL != "" && qualifyUser(SICKRAGEHOMEAUTH)){
  749. try {
  750. echo getSickrageCalendarWanted($sickrage->future());
  751. } catch (Exception $e) {
  752. writeLog("error", "SICKRAGE/BEARD ERROR: ".strip($e->getMessage()));
  753. } try {
  754. echo getSickrageCalendarHistory($sickrage->history("100","downloaded"));
  755. } catch (Exception $e) {
  756. writeLog("error", "SICKRAGE/BEARD ERROR: ".strip($e->getMessage()));
  757. }
  758. }
  759. if (SONARRURL != "" && qualifyUser(SONARRHOMEAUTH)){
  760. try {
  761. echo getSonarrCalendar($sonarr->getCalendar($startDate, $endDate));
  762. } catch (Exception $e) {
  763. writeLog("error", "SONARR ERROR: ".strip($e->getMessage()));
  764. }
  765. }
  766. if (RADARRURL != "" && qualifyUser(RADARRHOMEAUTH)){
  767. try {
  768. echo getRadarrCalendar($radarr->getCalendar($startDate, $endDate));
  769. } catch (Exception $e) {
  770. writeLog("error", "RADARR ERROR: ".strip($e->getMessage()));
  771. }
  772. }
  773. if (HEADPHONESURL != "" && qualifyUser(HEADPHONESHOMEAUTH)){
  774. echo getHeadphonesCalendar(HEADPHONESURL, HEADPHONESKEY, "getHistory");
  775. echo getHeadphonesCalendar(HEADPHONESURL, HEADPHONESKEY, "getWanted");
  776. }?>
  777. ],
  778. eventRender: function eventRender( event, element, view ) {
  779. return ['all', event.imagetype].indexOf($('#imagetype_selector').val()) >= 0
  780. },
  781. editable: false,
  782. droppable: false,
  783. timeFormat: '<?php echo CALTIMEFORMAT; ?>',
  784. });
  785. });
  786. $('#imagetype_selector').on('change',function(){
  787. $('#calendar').fullCalendar('rerenderEvents');
  788. })
  789. </script>
  790. <?php } ?>
  791. <script>
  792. function convertTime(a){
  793. if(a){
  794. var hours = Math.trunc(a/60);
  795. var minutes = a % 60;
  796. return hours+"h "+minutes+"m";
  797. }else{
  798. return "N/A";
  799. }
  800. }
  801. function convertArray(a, type){
  802. var result = "";
  803. var count = 1;
  804. var color = "";
  805. $.each( a, function( key, value ) {
  806. if (count == 1){ color = "gray"; }else{ color = "gray"; }
  807. if(type == "MOVIE"){
  808. result += '<span class="label label-'+color+'">'+value['name']+'</span>&nbsp;';
  809. }else if(type == "TV"){
  810. result += '<span class="label label-'+color+'">'+value+'</span>&nbsp;';
  811. }
  812. count++;
  813. });
  814. return result;
  815. }
  816. function convertTrailer(a){
  817. var result = "";
  818. var count = 1;
  819. $.each( a.results, function( key, value ) {
  820. if (count == 1){
  821. result += '<span id="openTrailer" style="cursor:pointer;width: 100%;display: block;" data-key="'+value['key']+'" data-name="'+value['name']+'" data-site="'+value['site']+'" class="label label-danger"><i class="fa fa-youtube-play" aria-hidden="true"></i> &nbsp;Watch Trailer</span>&nbsp;';
  822. }
  823. count++;
  824. });
  825. return result;
  826. }
  827. function convertCast(a){
  828. var result = "";
  829. var count = 1;
  830. $.each( a.cast, function( key, value ) {
  831. if( value['profile_path'] ){
  832. if (count <= 6){
  833. result += '<div class="col-lg-2 col-xs-2"><div class="zero-m"><img style="border-radius:10%;margin-left: auto;margin-right: auto;display: block;" height="50px" src="https://image.tmdb.org/t/p/w150'+value['profile_path']+'" alt="profile"><h5 class="text-center"><strong>'+value['name']+'</strong></h5><h6 class="text-center">'+value['character']+'</h6></div></div>';
  834. count++;
  835. }
  836. }
  837. });
  838. return result;
  839. }
  840. function whatIsIt(a){
  841. var what = Object.prototype.toString;
  842. if(what.call(a) == "[object Array]"){
  843. return a[0].fileName;
  844. }else if(what.call(a) == "[object Object]"){
  845. return a.fileName;
  846. }
  847. }
  848. function whatWasIt(a){
  849. var what = Object.prototype.toString;
  850. if(what.call(a) == "[object Array]"){
  851. return a[0];
  852. }else if(what.call(a) == "[object Object]"){
  853. return a;
  854. }
  855. }
  856. $(document).on('click', "#openTrailer", function(){
  857. var key = $(this).attr("data-key");
  858. $('#iFrameYT').html('<iframe id="calendarYoutube" class="embed-responsive-item" src="https://www.youtube.com/embed/'+key+'" allowfullscreen=""></iframe>');
  859. $('#calendarVideo').modal('show');
  860. });
  861. $(document).on('click', "a[class*=ID-]", function(){
  862. $('#calendarExtra').modal('show');
  863. var refreshBox = $('#calendarMainID');
  864. $("<div class='refresh-preloader'><div class='la-timer la-dark'><div></div></div></div>").appendTo(refreshBox).fadeIn(300);
  865. setTimeout(function(){
  866. var refreshPreloader = refreshBox.find('.refresh-preloader'),
  867. deletedRefreshBox = refreshPreloader.fadeOut(300, function(){
  868. refreshPreloader.remove();
  869. });
  870. },300);
  871. var check = $(this).attr("class");
  872. var ID = check.split("--")[1];
  873. if (~check.indexOf("tvID")){
  874. var type = "TV";
  875. ajax_request('POST', 'tvdb-get', {
  876. id: ID,
  877. }).done(function(data){
  878. if( data.trakt ) {
  879. $.ajax({
  880. type: 'GET',
  881. url: 'https://api.themoviedb.org/3/tv/'+data.trakt.tmdb+'?api_key=83cf4ee97bb728eeaf9d4a54e64356a1&append_to_response=videos,credits',
  882. cache: true,
  883. async: true,
  884. complete: function(xhr, status) {
  885. var result = $.parseJSON(xhr.responseText);
  886. if (xhr.statusText === "OK") {
  887. console.log(result);
  888. $('#calendarTitle').text(result.name);
  889. $('#calendarRating').html('<span class="label label-gray"><i class="fa fa-thumbs-up white"></i> '+result.vote_average+'</span>&nbsp;');
  890. $('#calendarRuntime').html('<span class="label label-gray"><i class="fa fa-clock-o white"></i> '+convertTime(whatWasIt(result.episode_run_time))+'</span>&nbsp;');
  891. $('#calendarSummary').text(result.overview);
  892. $('#calendarTagline').text("");
  893. $('#calendarTrailer').html(convertTrailer(result.videos));
  894. $('#calendarCast').html(convertCast(result.credits));
  895. $('#calendarGenres').html(convertArray(result.genres, "MOVIE"));
  896. $('#calendarLang').html(convertArray(result.languages, "TV"));
  897. $('#calendarPoster').attr("src","https://image.tmdb.org/t/p/w300"+result.poster_path);
  898. $('#calendarMain').attr("style","background-size: cover; background: linear-gradient(rgba(25,27,29,.75),rgba(25,27,29,.75)),url(https://image.tmdb.org/t/p/w1000"+result.backdrop_path+");top: 0;left: 0;width: 100%;height: 100%;position: fixed;");
  899. $('#calendarExtra').modal('show');
  900. }
  901. }
  902. });
  903. }else{
  904. $('#calendarTitle').text(data.series.seriesName);
  905. $('#calendarRating').html('<span class="label label-gray"><i class="fa fa-thumbs-up white"></i> '+data.series.siteRating+'</span>&nbsp');
  906. $('#calendarRuntime').html('<span class="label label-gray"><i class="fa fa-clock-o white"></i> '+convertTime(data.series.runtime)+'</span>&nbsp;');
  907. $('#calendarSummary').text(data.series.overview);
  908. $('#calendarTagline').text("");
  909. $('#calendarTrailer').html("");
  910. $('#calendarCast').html("");
  911. $('#calendarGenres').html(convertArray(data.series.genre, "TV"));
  912. $('#calendarLang').html("");
  913. $('#calendarPoster').attr("src","https://thetvdb.com/banners/_cache/"+whatIsIt(data.poster));
  914. $('#calendarMain').attr("style","background-size: cover; background: linear-gradient(rgba(25,27,29,.75),rgba(25,27,29,.75)),url(ajax.php?a=show-image&image=http://thetvdb.com/banners/"+whatIsIt(data.backdrop)+");top: 0;left: 0;width: 100%;height: 100%;position: fixed;");
  915. $('#calendarExtra').modal('show');
  916. }
  917. });
  918. }else if (~check.indexOf("movieID")){
  919. var type = "MOVIE";
  920. $.ajax({
  921. type: 'GET',
  922. url: 'https://api.themoviedb.org/3/movie/'+ID+'?api_key=83cf4ee97bb728eeaf9d4a54e64356a1&append_to_response=videos,credits',
  923. cache: true,
  924. async: true,
  925. complete: function(xhr, status) {
  926. var result = $.parseJSON(xhr.responseText);
  927. console.log(result);
  928. console.log(convertCast(result.credits));
  929. if (xhr.statusText === "OK") {
  930. $('#calendarTitle').text(result.title);
  931. $('#calendarRating').html('<span class="label label-gray"><i class="fa fa-thumbs-up white"></i> '+result.vote_average+'</span>&nbsp;');
  932. $('#calendarRuntime').html('<span class="label label-gray"><i class="fa fa-clock-o white"></i> '+convertTime(result.runtime)+'</span>&nbsp;');
  933. $('#calendarSummary').text(result.overview);
  934. $('#calendarTagline').text(result.tagline);
  935. $('#calendarTrailer').html(convertTrailer(result.videos));
  936. $('#calendarCast').html(convertCast(result.credits));
  937. $('#calendarGenres').html(convertArray(result.genres, "MOVIE"));
  938. $('#calendarLang').html(convertArray(result.spoken_languages, "MOVIE"));
  939. $('#calendarPoster').attr("src","https://image.tmdb.org/t/p/w300"+result.poster_path);
  940. $('#calendarMain').attr("style","background-size: cover; background: linear-gradient(rgba(25,27,29,.75),rgba(25,27,29,.75)),url(https://image.tmdb.org/t/p/w1000"+result.backdrop_path+");top: 0;left: 0;width: 100%;height: 100%;position: fixed;");
  941. $('#calendarExtra').modal('show');
  942. }
  943. }
  944. });
  945. }
  946. });
  947. </script>
  948. <div id="calendarExtra" class="modal fade in" tabindex="-1" role="dialog">
  949. <div class="modal-dialog modal-lg gray-bg" role="document">
  950. <div id="calendarMainID" class="modal-content">
  951. <div class="modal-content" id="calendarMain"></div>
  952. <div style="position: inherit; padding: 15px">
  953. <span id="calendarRuntime" class="pull-left"></span>
  954. <span id="calendarRating" class="pull-left"></span>
  955. <span id="calendarGenres" class="pull-right"></span>
  956. </div>
  957. <div class="modal-body">
  958. <div class="row">
  959. <div class="col-sm-4">
  960. <img style="width:100%;border-radius: 10px;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);" id="calendarPoster" src="">
  961. </div>
  962. <div class="col-sm-8">
  963. <h2 id="calendarTitle" class="modal-title text-center">Modal title</h2>
  964. <h6 id="calendarTagline" class="modal-title text-center"><em>Modal title</em></h6>
  965. <p id="calendarSummary">Modal Summary</p>
  966. <div class="" id="calendarCast">Modal Summary</div>
  967. </div>
  968. </div>
  969. </div>
  970. <div style="position: inherit; padding: 15px 0px 30px 0px; margin-top: -20px;">
  971. <div class="col-sm-4">
  972. <span id="calendarTrailer" class="pull-left" style="width:100%"></span>
  973. </div>
  974. <div class="col-sm-8">
  975. <span id="calendarLang" class="pull-right"></span>
  976. </div>
  977. </div>
  978. </div>
  979. </div>
  980. </div>
  981. <div id="calendarVideo" class="modal fade in palette-Grey-900 bg" tabindex="-1" role="dialog">
  982. <div class="modal-dialog modal-lg gray-bg" role="document">
  983. <div id="calendarMainVideo" class="modal-content gray-bg">
  984. <div class="">
  985. <!-- 16:9 aspect ratio -->
  986. <div id="iFrameYT" class="embed-responsive embed-responsive-16by9 gray-bg"></div>
  987. </div>
  988. </div>
  989. </div>
  990. </div>
  991. </body>
  992. </html>