diff --git a/.env.example b/.env.example index 16e7ec1..778e40f 100644 --- a/.env.example +++ b/.env.example @@ -3,3 +3,4 @@ PORT= # The port to run the server at TMDB_ACCESS_TOKEN= # Your TMDB API access token TIVO_API_URL= # The TiVo API URL DATABASE_URL= # Your PostgreSQL URL +JWT= # Your JWT secret \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 76a3ffd..2d522f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "express": "^4.21.2", "jsonwebtoken": "^9.0.2", "mysql2": "^3.11.5", + "node-cache": "^5.1.2", "node-fetch": "^3.3.2", "pg": "^8.13.1", "reflect-metadata": "^0.2.2", @@ -1220,6 +1221,15 @@ "node": ">=10" } }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, "node_modules/color": { "version": "4.2.3", "license": "MIT", @@ -2915,6 +2925,18 @@ "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", "license": "MIT" }, + "node_modules/node-cache": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", + "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", + "license": "MIT", + "dependencies": { + "clone": "2.x" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/node-domexception": { "version": "1.0.0", "funding": [ diff --git a/package.json b/package.json index e47307a..e236166 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "lint": "eslint .", "start": "npm install && npm run build && node dist/index.js", "dev": "tsx watch src/index.ts", - "drzzle:studio": "drizzle-kit studio" + "db:push": "drizzle-kit push", + "db:studio": "drizzle-kit studio" }, "engines": { "node": "v23.5.0", @@ -64,6 +65,7 @@ "express": "^4.21.2", "jsonwebtoken": "^9.0.2", "mysql2": "^3.11.5", + "node-cache": "^5.1.2", "node-fetch": "^3.3.2", "pg": "^8.13.1", "reflect-metadata": "^0.2.2", diff --git a/src/public/js/vino_US.js b/src/public/js/vino_US.js index 9e29673..6a1ea2c 100644 --- a/src/public/js/vino_US.js +++ b/src/public/js/vino_US.js @@ -1,10 +1,11 @@ +/* eslint-disable no-undef */ +/* eslint-disable no-prototype-builtins */ // TODO: Finish JSDocing code -/* eslint-disable */ -if (typeof vino === 'undefined') { // If not on a WiiU, emulate the Vino and WiiU Gamepad APIs. - console.log('Initialize API emulation'); - if (typeof wiiu === 'undefined') { window.wiiu = {}, window.wiiu.gamepad = { update: function () { } }; } +if (typeof vino === "undefined") { // If not on a WiiU, emulate the Vino and WiiU Gamepad APIs. + console.log("Initialize API emulation"); + if (typeof wiiu === "undefined") { window.wiiu = {}, window.wiiu.gamepad = { update: function () { } }; } - $(document).on('keyup', function (event) { + $(document).on("keyup", function (event) { wiiu.gamepad.hold = 0; }); @@ -17,7 +18,7 @@ if (typeof vino === 'undefined') { // If not on a WiiU, emulate the Vino and Wii country: "US", language: "EN", - fl: "1236925795,1166356730,1409518437,1088392656,1090934832,1573645812,1672254576,1746347141,1112166243,1773702389,1541552688,1679086960,1609011959,1371173300,1426703823,1381149235,1338603408,1122156854,1309239659,1427220684,1498872945,1468960081,1029645862,1092713399,1413957266,1106036020,1637587789,1391350154,1672305136,1098860494" + fl: "1236925795,1166356730,1409518437,1088392656,1090934832,1573645812,1672254576,1746347141,1112166243,1773702389,1541552688,1679086960,1609011959,1371173300,1426703823,1381149235,1338603408,1122156854,1309239659,1427220684,1498872945,1468960081,1029645862,1092713399,1413957266,1106036020,1637587789,1391350154,1672305136,1098860494", }; window.vino = { @@ -25,7 +26,7 @@ if (typeof vino === 'undefined') { // If not on a WiiU, emulate the Vino and Wii console.log("Focus keyboard to: " + document.activeElement); }, requestGarbageCollect: function () { - console.log('Requested Garbage collection'); + console.log("Requested Garbage collection"); }, acr_setHostName: function (hostname) { }, @@ -55,7 +56,7 @@ if (typeof vino === 'undefined') { // If not on a WiiU, emulate the Vino and Wii return true; }, soundStopAll: function () { - console.log("Stop all sounds") + console.log("Stop all sounds"); }, ls_getItem: function (key) { return localStorage.getItem(key); @@ -77,53 +78,53 @@ if (typeof vino === 'undefined') { // If not on a WiiU, emulate the Vino and Wii return localStorage.length; }, lyt_setIsEnableClientLoadingIcon: function (show) { - console.log((show ? 'Show' : 'Hide') + ' blue loading icon'); + console.log((show ? "Show" : "Hide") + " blue loading icon"); }, lyt_setIsEnableWhiteMask: function (withmask) { - console.log((withmask ? 'With' : 'Without') + ' white mask'); + console.log((withmask ? "With" : "Without") + " white mask"); }, lyt_startTouchEffect: function () { - console.log('Show touch effect'); + console.log("Show touch effect"); }, lyt_reset: function () { - console.log('Reset lyt'); + console.log("Reset lyt"); }, lyt_decideFixedFrame: function () { - console.log('Decide lyt'); + console.log("Decide lyt"); }, lyt_drawFixedFrame: function (one, two, three, four) { - console.log('Drew frame at ' + one, two, three, four); + console.log("Drew frame at " + one, two, three, four); }, lyt_startTouchNodeEffect: function (one, two, three, four) { - console.log('Show touch mouse effect at ' + one, two, three, four); + console.log("Show touch mouse effect at " + one, two, three, four); }, video_enableOnTV: function (bool) { - console.log('Enable video on TV is ' + bool); + console.log("Enable video on TV is " + bool); }, emulate_touch: function (one, two, three) { - console.log('Emulate touch at ' + one, two, three); + console.log("Emulate touch at " + one, two, three); }, emulate_inputDelay: function (one) { - console.log('Emulate input delay in ' + one + ' seconds'); + console.log("Emulate input delay in " + one + " seconds"); }, exit: function () { - console.log('Exit app'); + console.log("Exit app"); }, exitForce: function () { - console.log('Forcing exit app'); + console.log("Forcing exit app"); }, isReturnedFromOtherApplication: function () { - console.log('App was not returned from other application'); + console.log("App was not returned from other application"); return false; }, runOliveErrorDialog: function (errorCode) { - alert('115-' + errorCode + '\n\n' + 'An Miiverse error occurred.'); + alert("115-" + errorCode + "\n\n" + "An Miiverse error occurred."); }, runErrorDialog: function (errorCode) { - alert('119-9' + errorCode + '\n\n' + 'An Vino error occurred.'); + alert("119-9" + errorCode + "\n\n" + "An Vino error occurred."); }, olv_getErrorCodeOnInitialize: function () { - alert('115-5004' + '\n\n' + 'The Miiverse service has ended.'); + alert("115-5004" + "\n\n" + "The Miiverse service has ended."); }, runSingleButtonDialog: function (msg, btnStr) { alert(msg + "\n\n[ " + btnStr + " ]"); @@ -140,25 +141,25 @@ if (typeof vino === 'undefined') { // If not on a WiiU, emulate the Vino and Wii return debugConsole.language; }, loading_setIconRect: function (one, two, three, four) { - console.log('Set loading icon position at ' + one, two, three, four); + console.log("Set loading icon position at " + one, two, three, four); }, loading_setIconAppear: function (show) { - console.log((show ? 'Show' : 'Hide') + ' loading icon.'); + console.log((show ? "Show" : "Hide") + " loading icon."); }, loading_setIconVisibility: function (show) { - console.log((show ? 'Instantly show' : 'Instantly hide') + ' loading icon.'); + console.log((show ? "Instantly show" : "Instantly hide") + " loading icon."); }, soundPlay: function (soundLabel) { - console.log('Played sound effect ' + soundLabel); + console.log("Played sound effect " + soundLabel); }, soundPlayEx: function (soundLabel, delay) { - console.log('Played sound effect ' + soundLabel + " with delay " + delay); + console.log("Played sound effect " + soundLabel + " with delay " + delay); }, soundPlayVolume: function (soundLabel, vol) { - console.log('Played sound effect ' + soundLabel + ' with volume ' + vol); + console.log("Played sound effect " + soundLabel + " with volume " + vol); }, ir_enableCodeset: function (one) { - console.log('Enabled IR codeset ' + one); + console.log("Enabled IR codeset " + one); }, ir_existsTvCodeset: function () { return true; @@ -167,10 +168,10 @@ if (typeof vino === 'undefined') { // If not on a WiiU, emulate the Vino and Wii return false; }, ir_send: function (one, two) { - console.log('Sent IR code ' + one); + console.log("Sent IR code " + one); }, ir_muteOneShotSound: function (bool) { - console.log('IR sound is enabled?: ' + bool); + console.log("IR sound is enabled?: " + bool); }, navi_reset: function () { }, @@ -178,29 +179,29 @@ if (typeof vino === 'undefined') { // If not on a WiiU, emulate the Vino and Wii return; }, navi_setMoveMethod: function (one) { - console.log('Set move method ' + one); + console.log("Set move method " + one); }, navi_setBaseVisibilityOnKeyEvent: function (bool) { - console.log('Base visibility is ' + bool); + console.log("Base visibility is " + bool); }, navi_setBaseVisibility: function (bool) { - console.log('Base visibility is ' + bool); + console.log("Base visibility is " + bool); }, navi_set: function (one, two, three, four) { - console.log('Navi set at ' + one, two, three, four); + console.log("Navi set at " + one, two, three, four); }, navi_decide: function () { }, act_getCurrentSlotNo: function () { - console.log('Returned account slot "1"'); + console.log("Returned account slot \"1\""); return 1; }, act_getMiiImage: function (slot) { - console.log('Returned Mii image from ' + slot); + console.log("Returned Mii image from " + slot); return "https://pretendo-cdn.b-cdn.net/mii/" + debugConsole.pid + "/normal_face.png"; }, act_getMiiImageEx: function (slot, expression) { - console.log('Returned Mii image from ' + slot + ' with expression ' + expression); + console.log("Returned Mii image from " + slot + " with expression " + expression); var imageUrl; switch (expression) { case 7: @@ -228,184 +229,184 @@ if (typeof vino === 'undefined') { // If not on a WiiU, emulate the Vino and Wii return imageUrl; }, act_getMiiData: function (slot) { - console.log('Returned Mii data from ' + slot); + console.log("Returned Mii data from " + slot); return debugConsole.mii; }, act_getNum: function () { - console.log('Returned number of accounts'); + console.log("Returned number of accounts"); return 1; }, act_getName: function (slot) { - console.log('Returned Mii name from ' + slot); + console.log("Returned Mii name from " + slot); return debugConsole.name; }, act_getPid: function (slot) { - console.log('Returned account PID from ' + slot); + console.log("Returned account PID from " + slot); return debugConsole.pid; }, act_getAgeDivision: function (slot) { - console.log('Returned account age division from ' + slot); + console.log("Returned account age division from " + slot); return 1; }, apd_isEnabled: function () { - console.log('APD is enabled on console'); + console.log("APD is enabled on console"); return true; }, apd_getPeriod: function () { - console.log('Return APD period'); + console.log("Return APD period"); return 6200; }, apd_enable: function () { - console.log('APD has been enabled'); + console.log("APD has been enabled"); return true; }, apd_disable: function () { - console.log('APD has been disabled'); + console.log("APD has been disabled"); return false; }, memo_open: function (state) { - console.log((state ? 'Open with reset' : 'Open without reset') + ' memo UI'); + console.log((state ? "Open with reset" : "Open without reset") + " memo UI"); return true; }, memo_reset: function () { - console.log('Memo UI was reset'); + console.log("Memo UI was reset"); return true; }, memo_isFinish: function () { - console.log('Memo UI finished'); + console.log("Memo UI finished"); return true; }, memo_getImagePng: function () { - console.log('Return memo UI image'); - return 'https://i.ibb.co/rwr9J38/descarga.png'; + console.log("Return memo UI image"); + return "https://i.ibb.co/rwr9J38/descarga.png"; }, memo_getImageTgaRaw: function () { - console.log('Return memo UI raw image'); - return 'DARA'; + console.log("Return memo UI raw image"); + return "DARA"; }, memo_getImageTgaCompressed: function () { - console.log('Return memo UI compressed image'); - return 'DARA'; + console.log("Return memo UI compressed image"); + return "DARA"; }, fp_getFriendList: function () { - console.log('Return friend list'); + console.log("Return friend list"); return debugConsole.fl; }, fp_getFriendName: function (PID) { - console.log('Get friend name of ' + PID); - return 'David Joaq'; + console.log("Get friend name of " + PID); + return "David Joaq"; }, jumpToTitle: function (TID, bool) { - console.log('Jump to app ' + TID); + console.log("Jump to app " + TID); }, checkTitleExist: function (TID) { - console.log("TID " + TID + " does exist.") + console.log("TID " + TID + " does exist."); return true; }, jumpToMiiverse: function (bool) { - console.log('Jump to Miiverse is ' + bool); + console.log("Jump to Miiverse is " + bool); }, jumpToMiiversePostId: function (postid, bool) { - console.log('Jump to post ' + postid + ' on Miiverse is ' + bool); + console.log("Jump to post " + postid + " on Miiverse is " + bool); }, jumpToEShop: function (TID, bool) { - console.log('Jump to eShop page of TID ' + TID + ' is ' + bool); + console.log("Jump to eShop page of TID " + TID + " is " + bool); }, jumpToVod: function (url, TID, bool) { - console.log('Jump to VOD app of TID ' + TID + ' with URL ' + url + ' is ' + bool); + console.log("Jump to VOD app of TID " + TID + " with URL " + url + " is " + bool); window.location.href = url; }, jumpToBrowser: function (url, bool) { - console.log((bool ? 'Jump' : 'Did not jump') + ' to URL ' + url); + console.log((bool ? "Jump" : "Did not jump") + " to URL " + url); window.location.href = url; }, jumpToSettingsTvRemote: function (bool) { - console.log((bool ? 'Jump' : 'Did not jump') + ' to TV Remote Settings'); + console.log((bool ? "Jump" : "Did not jump") + " to TV Remote Settings"); }, olv_isEnabled: function () { - console.log('Miiverse is enabled'); + console.log("Miiverse is enabled"); return true; }, olv_getPostingResult: function () { - console.log('Post was successful'); + console.log("Post was successful"); return 1; }, olv_getHostName: function () { - console.log('Miiverse host name ' + 'https://api.olv.pretendo.cc'); - return 'https://api.olv.pretendo.cc'; + console.log("Miiverse host name " + "https://api.olv.pretendo.cc"); + return "https://api.olv.pretendo.cc"; }, olv_getUserAgent: function () { - console.log('Miiverse user agent ' + 'WiiU/POLV-5.0.3/353'); - return 'WiiU/POLV-5.0.3/305'; + console.log("Miiverse user agent " + "WiiU/POLV-5.0.3/353"); + return "WiiU/POLV-5.0.3/305"; }, olv_getServiceToken: function () { - console.log('Return service token'); - return '837vCg+l8rgFmGSHhZXRH22xr7YUxPhQ95FvhWr3JmoYBsWxUfIYZHFF+J6NYy9eUVnEhv8y3YFw2BrZZ3UEunQfHf7omFk0t4kWywIZYQcaZUDx367u7uSwW+34xF4+/IPQFGLtCh6moWe97yHcOMR374iAmzb1uTDM2cRgDco='; + console.log("Return service token"); + return "837vCg+l8rgFmGSHhZXRH22xr7YUxPhQ95FvhWr3JmoYBsWxUfIYZHFF+J6NYy9eUVnEhv8y3YFw2BrZZ3UEunQfHf7omFk0t4kWywIZYQcaZUDx367u7uSwW+34xF4+/IPQFGLtCh6moWe97yHcOMR374iAmzb1uTDM2cRgDco="; }, olv_getParameterPack: function () { - console.log('Return param pack'); - return 'XHRpdGxlX2lkXDE0MDc1ODEzMTA0OTcwMzRcYWNjZXNzX2tleVwzNDczXHBsYXRmb3JtX2lkXDFc cmVnaW9uX2lkXDJcbGFuZ3VhZ2VfaWRcMVxjb3VudHJ5X2lkXDQ5XGFyZWFfaWRcMzZcbmV0d29y a19yZXN0cmljdGlvblwwXGZyaWVuZF9yZXN0cmljdGlvblwwXHJhdGluZ19yZXN0cmljdGlvblwx N1xyYXRpbmdfb3JnYW5pemF0aW9uXDFcdHJhbnNmZXJhYmxlX2lkXDExMDU5OTY0MDc3OTU4MjI1 MzQ3XHR6X25hbWVcQW1lcmljYS9OZXdfWW9ya1x1dGNfb2Zmc2V0XC0xNDQwMFw='; + console.log("Return param pack"); + return "XHRpdGxlX2lkXDE0MDc1ODEzMTA0OTcwMzRcYWNjZXNzX2tleVwzNDczXHBsYXRmb3JtX2lkXDFc cmVnaW9uX2lkXDJcbGFuZ3VhZ2VfaWRcMVxjb3VudHJ5X2lkXDQ5XGFyZWFfaWRcMzZcbmV0d29y a19yZXN0cmljdGlvblwwXGZyaWVuZF9yZXN0cmljdGlvblwwXHJhdGluZ19yZXN0cmljdGlvblwx N1xyYXRpbmdfb3JnYW5pemF0aW9uXDFcdHJhbnNmZXJhYmxlX2lkXDExMDU5OTY0MDc3OTU4MjI1 MzQ3XHR6X25hbWVcQW1lcmljYS9OZXdfWW9ya1x1dGNfb2Zmc2V0XC0xNDQwMFw="; }, olv_postText: function (body, topicTag, feelingID, spoiler, searchkey1, searchkey2, searchkey3, searchkey4, searchkey5) { - console.log('Post to Miiverse with message ' + '"' + body + '"' + ' with topic ' + topicTag + ' with feeling ID ' + feelingID + ' with spoilers ' + spoiler + ' with search key ' + searchkey1 + ' with search key ' + searchkey2 + ' with search key ' + searchkey3 + ' with search key ' + searchkey4 + ' with search key ' + searchkey5); + console.log("Post to Miiverse with message " + "\"" + body + "\"" + " with topic " + topicTag + " with feeling ID " + feelingID + " with spoilers " + spoiler + " with search key " + searchkey1 + " with search key " + searchkey2 + " with search key " + searchkey3 + " with search key " + searchkey4 + " with search key " + searchkey5); }, olv_postTextFixedPhrase: function (body, topicTag, feelingID, spoiler, searchkey1, searchkey2, searchkey3, searchkey4, searchkey5) { - console.log('Post to Miiverse fixed phrase with message ' + '"' + body + '"' + ' with topic ' + topicTag + ' with feeling ID ' + feelingID + ' with spoilers ' + spoiler + ' with search key ' + searchkey1 + ' with search key ' + searchkey2 + ' with search key ' + searchkey3 + ' with search key ' + searchkey4 + ' with search key ' + searchkey5); + console.log("Post to Miiverse fixed phrase with message " + "\"" + body + "\"" + " with topic " + topicTag + " with feeling ID " + feelingID + " with spoilers " + spoiler + " with search key " + searchkey1 + " with search key " + searchkey2 + " with search key " + searchkey3 + " with search key " + searchkey4 + " with search key " + searchkey5); }, olv_postImage: function (painting, topicTag, feelingID, spoiler, searchkey1, searchkey2, searchkey3, searchkey4, searchkey5) { - console.log('Post to Miiverse with drawing ' + '"' + painting + '"' + ' with topic ' + topicTag + ' with feeling ID ' + feelingID + ' with spoilers ' + spoiler + ' with search key ' + searchkey1 + ' with search key ' + searchkey2 + ' with search key ' + searchkey3 + ' with search key ' + searchkey4 + ' with search key ' + searchkey5); + console.log("Post to Miiverse with drawing " + "\"" + painting + "\"" + " with topic " + topicTag + " with feeling ID " + feelingID + " with spoilers " + spoiler + " with search key " + searchkey1 + " with search key " + searchkey2 + " with search key " + searchkey3 + " with search key " + searchkey4 + " with search key " + searchkey5); }, olv_postImageFixedPhrase: function (painting, topicTag, feelingID, spoiler, searchkey1, searchkey2, searchkey3, searchkey4, searchkey5) { - console.log('Post to Miiverse fixed phrase with drawing ' + '"' + painting + '"' + ' with topic ' + topicTag + ' with feeling ID ' + feelingID + ' with spoilers ' + spoiler + ' with search key ' + searchkey1 + ' with search key ' + searchkey2 + ' with search key ' + searchkey3 + ' with search key ' + searchkey4 + ' with search key ' + searchkey5); + console.log("Post to Miiverse fixed phrase with drawing " + "\"" + painting + "\"" + " with topic " + topicTag + " with feeling ID " + feelingID + " with spoilers " + spoiler + " with search key " + searchkey1 + " with search key " + searchkey2 + " with search key " + searchkey3 + " with search key " + searchkey4 + " with search key " + searchkey5); }, suggest_isOpening: function () { }, suggest_set: function (sug1, sug2, sug3, sug4, sug5, sug6, sug7, sug8, sug9, sug10) { - console.log('Set suggestion strings ' + '"' + sug1 + '", ' + '"' + sug2 + '", ' + '"' + sug3 + '", ' + '"' + sug4 + '", ' + '"' + sug5 + '", ' + '"' + sug6 + '", ' + '"' + sug7 + '", ' + '"' + sug8 + '", ' + '"' + sug9 + '", ' + '"' + sug10 + '"'); + console.log("Set suggestion strings " + "\"" + sug1 + "\", " + "\"" + sug2 + "\", " + "\"" + sug3 + "\", " + "\"" + sug4 + "\", " + "\"" + sug5 + "\", " + "\"" + sug6 + "\", " + "\"" + sug7 + "\", " + "\"" + sug8 + "\", " + "\"" + sug9 + "\", " + "\"" + sug10 + "\""); return true; }, suggest_reset: function () { - console.log('Reset suggestion strings'); + console.log("Reset suggestion strings"); return true; }, suggest_getString: function () { }, pc_checkPIN: function () { - console.log('PIN is true, perentl conrol allowed'); + console.log("PIN is true, perentl conrol allowed"); return true; }, pc_runPINInput: function () { - console.log('PIN is correcto, perentl conrol allowed'); + console.log("PIN is correcto, perentl conrol allowed"); return 1; }, pc_isControlled: function () { - console.log('Parental Controls are disabled'); + console.log("Parental Controls are disabled"); return false; }, pc_getMiiverseControlLevel: function () { - console.log('No Miiverse Control Settings'); + console.log("No Miiverse Control Settings"); return 0; }, pc_isControlledNetworkCommunication: function () { - console.log('No Network Communication Settings'); + console.log("No Network Communication Settings"); return false; }, pc_isControlledFriendReg: function () { - console.log('No Friend Settings'); + console.log("No Friend Settings"); return false; }, pc_isControlledBrowser: function () { - console.log('No Browser Settings'); + console.log("No Browser Settings"); return false; }, ng_checkText: function (message) { - console.log(message + ' does not contain any blacklisted words.'); + console.log(message + " does not contain any blacklisted words."); return true; }, ng_checkWord: function (message) { - console.log(message + ' is not a blacklisted word.'); + console.log(message + " is not a blacklisted word."); return true; - } + }, }; } @@ -421,22 +422,22 @@ var Jamiroquai = function () { */ this.travelWithoutMoving = function () { return vino.requestGarbageCollect(); - } + }; /** * Returns "25fps" (literally never used) * @returns { string } Returns a string "25fps" */ this.getFrameRate = function () { return "25fps"; - } + }; /** * The return of the Space Cowboy (true) * @returns { boolean } always true */ this.isReturnOfTheSpaceCowboy = function () { return true; - } -} + }; +}; var tvii = tvii || { clientUrl: location.origin, @@ -559,68 +560,99 @@ var tvii = tvii || { RATINGS: function (isTV, programID) { return "https://api.themoviedb.org/3/" + (isTV ? "tv" : "movie") + "/" + programID + "/content_ratings?language=" + tvii.utils.getLang(); }, + MII: function (slot, expression, isBody, refresh) { + var principalId = vino.act_getPid(slot); + var baseUrl = tvii.clientUrl + "/api/v1/miis/" + principalId + "/"; + var url = baseUrl + (isBody ? "body_" : "portrait_"); + + switch (expression) { + case 0: + url+= "normal_face.webp"; + break; + case 1: + url+= "happy_face.webp"; + break; + case 2: + url+= "like_face.webp"; + break; + case 3: + url+= "surprised_face.webp"; + break; + case 4: + url+= "frustrated_face.webp"; + break; + case 5: + url+= "puzzled_face.webp"; + break; + default: + url+= "normal_face.webp"; + break; + } + + return url + (refresh ? "?refresh=1" : "?refresh=0"); + }, generateTMDBImageUrl: function (backdrop_path, width) { - return tvii.clientUrl + "/api/v1/data/image?url=https://image.tmdb.org/t/p/w500" + backdrop_path + "&width=" + String(width); + return tvii.clientUrl + "/api/v1/data/image.webp?url=https://image.tmdb.org/t/p/w500" + backdrop_path + "&w=" + String(width); }, generateImageUrl: function (url, width) { - return tvii.clientUrl + "/api/v1/data/image?url=" + url + "&width=" + String(width); - } + return tvii.clientUrl + "/api/v1/data/image.webp?url=" + url + "&w=" + String(width); + }, }, templates: { // list templates for the spa router templateList: [ { template_query: "tv", // the query (?page=) - template_file: "tv.html" // the html file to load (/templates/) + template_file: "tv.html", // the html file to load (/templates/) }, { template_query: "settings", - template_file: "settings.html" + template_file: "settings.html", }, { template_query: "home", - template_file: "home.html" + template_file: "home.html", }, { template_query: "remote", - template_file: "remote.html" + template_file: "remote.html", }, { template_query: "setup", - template_file: "setup.html" + template_file: "setup.html", }, { template_query: "program_view", - template_file: "program.html" + template_file: "program.html", }, { template_query: "tvtags", - template_file: "tvtag.html" + template_file: "tvtag.html", }, { template_query: "tvtag_tagline", - template_file: "tvtag_tagline.html" + template_file: "tvtag_tagline.html", }, { template_query: "tvtag_moment", - template_file: "tvtag_moment.html" + template_file: "tvtag_moment.html", }, { template_query: "favorites", - template_file: "favorites.html" + template_file: "favorites.html", }, { template_query: "sports", - template_file: "sports.html" + template_file: "sports.html", }, { template_query: "movies", - template_file: "movies.html" + template_file: "movies.html", }, { template_query: "manual", - template_file: "manual.html" - } + template_file: "manual.html", + }, ], requestAll: function () { var templateLoadCount = 0; @@ -634,10 +666,10 @@ var tvii = tvii || { if (xhr.status == 200) { var tem = { template_name: temToLoad.template_query, - template_html: xhr.responseText - } + template_html: xhr.responseText, + }; - sessionStorage.setItem("template_" + tem.template_name, JSON.stringify(tem)) + sessionStorage.setItem("template_" + tem.template_name, JSON.stringify(tem)); templateLoadCount++; if (templateLoadCount >= tvii.templates.templateList.length) { @@ -654,7 +686,7 @@ var tvii = tvii || { }, get: function (templateName) { //Always include remote HTML - var remoteHTML = JSON.parse(sessionStorage.getItem("template_remote")).template_html + var remoteHTML = JSON.parse(sessionStorage.getItem("template_remote")).template_html; var getHTML = JSON.parse(sessionStorage.getItem("template_" + templateName)).template_html; return getHTML.trim() + remoteHTML.trim(); }, @@ -721,7 +753,7 @@ var tvii = tvii || { } - var locFile = tvii.utils.getLang().split('-')[0] + "_" + region + ".json"; + locFile = tvii.utils.getLang().split("-")[0] + "_" + region + ".json"; var sendRequest = function (locFile) { var xhr = new XMLHttpRequest(); @@ -746,10 +778,10 @@ var tvii = tvii || { getLoc: function (locID, arrayReplace) { var localizedString = tvii.locFile[locID]; - if (arrayReplace && typeof arrayReplace === 'object') { + if (arrayReplace && typeof arrayReplace === "object") { for (var key in arrayReplace) { if (arrayReplace.hasOwnProperty(key)) { - var placeholder = new RegExp(key, 'g'); + var placeholder = new RegExp(key, "g"); localizedString = localizedString.replace(placeholder, arrayReplace[key]); } } @@ -767,11 +799,11 @@ var tvii = tvii || { for (var key in a) { var value = a[key]; - $(el).attr(key, tvii.templates.getLoc(value)) + $(el).attr(key, tvii.templates.getLoc(value)); } }); - } + }, }, router: { routes: [], @@ -789,7 +821,7 @@ var tvii = tvii || { break; } } - } + }, }, utils: { buttonType: { @@ -802,7 +834,7 @@ var tvii = tvii || { 128: "zl", 64: "zr", 8: "plus", - 4: "minus" + 4: "minus", }, getDateInTMDBFormat: function (date) { var year = date.getFullYear(); @@ -810,10 +842,10 @@ var tvii = tvii || { var day = date.getDate(); function twoDigits(value) { - return value < 10 ? '0' + value : value; + return value < 10 ? "0" + value : value; } - return year + '-' + twoDigits(month) + '-' + twoDigits(day); + return year + "-" + twoDigits(month) + "-" + twoDigits(day); }, startInitialLoading: function () { vino.loading_setIconRect(360, 160, 120, 120); @@ -826,12 +858,12 @@ var tvii = tvii || { $(document).on("tvii:templates:loaded", function () { $(document).off("tvii:templates:loaded"); tvii.templates.requestJSONLoc(); - }) + }); $(document).on("tvii:templates:jsonloc:loaded", function () { $(document).off("tvii:templates:jsonloc:loaded"); $(document).trigger("tvii:initialized"); - }) + }); tvii.templates.requestAll(); }, @@ -841,7 +873,7 @@ var tvii = tvii || { if (!$.data(this, "hoverLSTNR")) { $(this).on("mousedown", function () { sel = $(this); - vino.soundPlay('SE_CMN_TOUCH_ON'); + vino.soundPlay("SE_CMN_TOUCH_ON"); $(this).data("soundPlayed", true); $(this).addClass("hover"); @@ -849,7 +881,7 @@ var tvii = tvii || { $(this).on("mouseout", function (evt) { if (sel && sel.length && !sel.is($(this))) { return; - }; + } if (sel == null) { $(this).removeClass("hover"); @@ -859,7 +891,7 @@ var tvii = tvii || { $(this).removeClass("hover"); $(this).data("soundPlayed", false); - vino.soundPlay('SE_CMN_TOUCH_CANCEL'); + vino.soundPlay("SE_CMN_TOUCH_CANCEL"); sel = null; }); $(this).on("mouseup", function () { @@ -905,13 +937,13 @@ var tvii = tvii || { queryString = window.location.search.substring(1); } else { queryString = param; - param = param.split('?')[1]; + param = param.split("?")[1]; } - var params = queryString.split('&'); + var params = queryString.split("&"); for (var i = 0; i < params.length; i++) { - var pair = params[i].split('='); + var pair = params[i].split("="); if (pair[0] === param) { return decodeURIComponent(pair[1]); } @@ -922,13 +954,13 @@ var tvii = tvii || { changePage: function (pageQuery, replace) { //If is returned from app? if (pageQuery == 1) { - pageQuery = location.search + pageQuery = location.search; } if (replace) { - window.history.replaceState({}, '', pageQuery); + window.history.replaceState({}, "", pageQuery); } else { - window.history.pushState({}, '', pageQuery); - console.log("pushed state") + window.history.pushState({}, "", pageQuery); + console.log("pushed state"); } tvii.utils.showWrapper(false); tvii.utils.clearWrapper(); @@ -948,16 +980,16 @@ var tvii = tvii || { if (currentQuery == null) { if (queryString) { - queryString += '&' + encodeURIComponent(queryName) + '=' + encodeURIComponent(queryValue); + queryString += "&" + encodeURIComponent(queryName) + "=" + encodeURIComponent(queryValue); } else { - queryString = '?' + encodeURIComponent(queryName) + '=' + encodeURIComponent(queryValue); + queryString = "?" + encodeURIComponent(queryName) + "=" + encodeURIComponent(queryValue); } } else { - var regex = new RegExp('([?&])' + encodeURIComponent(queryName) + '=.*?(&|$)', 'i'); - queryString = queryString.replace(regex, '$1' + encodeURIComponent(queryName) + '=' + encodeURIComponent(queryValue) + '$2'); + var regex = new RegExp("([?&])" + encodeURIComponent(queryName) + "=.*?(&|$)", "i"); + queryString = queryString.replace(regex, "$1" + encodeURIComponent(queryName) + "=" + encodeURIComponent(queryValue) + "$2"); } - window.history.replaceState({}, '', tvii.clientUrl + queryString); + window.history.replaceState({}, "", tvii.clientUrl + queryString); }, initTouchEffect: function () { //Check if click was real @@ -990,7 +1022,7 @@ var tvii = tvii || { $(".wrapper").html(""); }, replaceWrapper: function (html) { - $(".wrapper").html(html) + $(".wrapper").html(html); }, getWrapper: function () { return $(".wrapper").html(); @@ -1017,8 +1049,8 @@ var tvii = tvii || { $(".container").off("mousedown"); $(".container").off("mousemove"); $(".container").off("mouseup"); - clearInterval(tvii.naviResetInterval) - clearInterval(tvii.tvTagProgramLeftInterval) + clearInterval(tvii.naviResetInterval); + clearInterval(tvii.tvTagProgramLeftInterval); }, handleImageLoading: function (imgs, transition) { @@ -1033,7 +1065,7 @@ var tvii = tvii || { $(img).off("error"); // Handle image load success - $(img).on('load', function () { + $(img).on("load", function () { var g = $(this); if (transition) { g.addClass("fadein"); @@ -1045,7 +1077,7 @@ var tvii = tvii || { }); // Handle image load error - $(img).on('error', function () { + $(img).on("error", function () { var g = $(this); if (transition) { g.removeClass("fadein"); @@ -1056,9 +1088,9 @@ var tvii = tvii || { // Trigger load event manually if image is already complete if (img.complete) { if (img.naturalWidth > 0 && img.naturalHeight > 0) { - $(img).trigger('load'); + $(img).trigger("load"); } else { - $(img).trigger('error'); + $(img).trigger("error"); } } } @@ -1086,7 +1118,7 @@ var tvii = tvii || { var self = this; // Initialize event listeners - this.scrCont.on('mousedown', function (e) { + this.scrCont.on("mousedown", function (e) { self.isMouseDown = true; self.startPosX = e.pageX; self.startPosY = e.pageY; @@ -1096,14 +1128,14 @@ var tvii = tvii || { self.lastScrollPosY = self.scrollStartY; self.scrollVelocityX = 0; // Reset scroll velocity on mousedown self.scrollVelocityY = 0; - self.scrCont.css('cursor', 'grabbing'); + self.scrCont.css("cursor", "grabbing"); clearInterval(self.inertiaInterval); // Stop any previous inertia interval }); - $(document).on('mouseup', function () { + $(document).on("mouseup", function () { if (self.isMouseDown) { self.isMouseDown = false; - self.scrCont.css('cursor', 'grab'); + self.scrCont.css("cursor", "grab"); self.hasStartedScrolling = false; // Reset scroll start flag // Smooth scrolling inertia @@ -1122,32 +1154,32 @@ var tvii = tvii || { } // Trigger scrolling event on the container element - self.scrCont.trigger('scrolling', { + self.scrCont.trigger("scrolling", { scrollX: self.getScrollX(), - scrollY: self.getScrollY() + scrollY: self.getScrollY(), }); } else { clearInterval(self.inertiaInterval); // Stop inertia when velocity is low // Trigger scrollEnd event on the container element - self.scrCont.trigger('scrollEnd', { + self.scrCont.trigger("scrollEnd", { scrollX: self.getScrollX(), - scrollY: self.getScrollY() + scrollY: self.getScrollY(), }); } }, 20); // Update every 20ms for smooth scrolling } }); - this.scrCont.on('mousemove', function (e) { + this.scrCont.on("mousemove", function (e) { if (self.isMouseDown) { if (!self.hasStartedScrolling) { self.hasStartedScrolling = true; // Trigger scrollStart event on the container element - self.scrCont.trigger('scrollStart', { + self.scrCont.trigger("scrollStart", { scrollX: self.getScrollX(), - scrollY: self.getScrollY() + scrollY: self.getScrollY(), }); } @@ -1177,8 +1209,8 @@ var tvii = tvii || { } } else { // Normal behavior (not forced to one direction) - var walkX = (currentPosX - self.startPosX) * 2; // Scroll speed - var walkY = (currentPosY - self.startPosY) * 2; + walkX = (currentPosX - self.startPosX) * 2; // Scroll speed + walkY = (currentPosY - self.startPosY) * 2; if (self.isHorizontal === true || self.isHorizontal === 3) { self.scrCont.scrollLeft(self.scrollStartX - walkX); @@ -1193,9 +1225,9 @@ var tvii = tvii || { } // Trigger scrolling event on the container element - self.scrCont.trigger('scrolling', { + self.scrCont.trigger("scrolling", { scrollX: self.getScrollX(), - scrollY: self.getScrollY() + scrollY: self.getScrollY(), }); } }); @@ -1223,7 +1255,7 @@ var tvii = tvii || { lab.on("click", function (evt) { vino.soundPlay("SE_A_TAB_TOUCH_OFF"); var $this = $(this); - var $dropdownMenu = $this.closest('.dropdown-container').find('.dropdown-menu'); + var $dropdownMenu = $this.closest(".dropdown-container").find(".dropdown-menu"); if ($dropdownMenu.length === 0) { if (tvii.currentToggle != null) { tvii.currentToggle.addClass("none"); @@ -1257,7 +1289,7 @@ var tvii = tvii || { } }); - $('[data-toggle]').each(function () { + $("[data-toggle]").each(function () { if (!$.data(this, "toggleL")) { $(this).on("click", function (evt) { var toggler = $(this); @@ -1282,17 +1314,17 @@ var tvii = tvii || { } }); - $('.dropdown-menu .tab-label').each(function () { + $(".dropdown-menu .tab-label").each(function () { if (!$.data(this, "labelTogL")) { $(this).on("click", function (evt) { var option = $(this); option.parent().find(".tab-label").removeClass("selected"); - $('[data-toggle]').removeClass("selected"); - $('[data-toggle]').find(".current").addClass("none"); + $("[data-toggle]").removeClass("selected"); + $("[data-toggle]").find(".current").addClass("none"); if (!option.parent().parent().parent().find("[data-toggle]").hasClass("selected")) { - $('.dropdown-menu .tab-label').removeClass("selected") + $(".dropdown-menu .tab-label").removeClass("selected"); option.parent().parent().parent().find("[data-toggle]").addClass("selected"); option.addClass("selected"); option.parent().parent().parent().find("[data-toggle]").find(".current").removeClass("none").text(option.text()); @@ -1372,8 +1404,8 @@ var tvii = tvii || { "8": 18, "9": 19, "0": 20, - "INPUT": 52 - } + "INPUT": 52, + }; //Set up codeset? if (vino.ir_existsTvCodeset()) { @@ -1418,17 +1450,17 @@ var tvii = tvii || { vino.ir_send(irCodes[code], 1); } - tvii.utils.setUpHoverToEls($(".remote-control a:not(.channel):not(.exit-modal)")) - var chBtns = $('.remote-control .remote-content .channel-scroll .channel'); + tvii.utils.setUpHoverToEls($(".remote-control a:not(.channel):not(.exit-modal)")); + var chBtns = $(".remote-control .remote-content .channel-scroll .channel"); chBtns.on("click", function () { if (!$(this).attr("data-ir-code")) { return; } - var chCode = $(this).attr("data-ir-code").split(''); + var chCode = $(this).attr("data-ir-code").split(""); changeChannel.apply(null, chCode); }); - var favChScroll = new tvii.utils.ScrollingContainer($('.remote-control .remote-content .channel-scroll'), true); + var favChScroll = new tvii.utils.ScrollingContainer($(".remote-control .remote-content .channel-scroll"), true); favChScroll.scrCont.on("scroll", function (e) { var $this = $(this); var scrollLeft = $this.scrollLeft(); @@ -1451,19 +1483,19 @@ var tvii = tvii || { } // Play sound when scrolling - vino.soundPlayEx('SE_A_DIAL_SCROLL', 20); - }) + vino.soundPlayEx("SE_A_DIAL_SCROLL", 20); + }); $(".remote-button, .exit-remote-control").on("click", function () { $(".remote-control").toggleClass("none"); $(".remote-control").toggleClass("modal-window-open"); - }) + }); $(".remote-button").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); - }) + }); $(".exit-remote-control").on("click", function () { vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); - }) + }); $(".remote-control").on("click", function (e) { if (e.target === this) { @@ -1473,12 +1505,12 @@ var tvii = tvii || { }); }, initPageLinks: function () { - $('a').on("click", function () { + $("a").on("click", function () { var link = $(this); if (link.attr("data-url") != null) { - tvii.utils.changePage(link.attr("data-url"), false) + tvii.utils.changePage(link.attr("data-url"), false); } - }) + }); }, sendXHR: function (type, url, callbackSuccess, callbackError, headers, formData) { tvii.utils.abortOngoingXHR(); @@ -1506,7 +1538,7 @@ var tvii = tvii || { } tvii.currentXHR = null; } - } + }; if (type === "POST") { tvii.currentXHR.setRequestHeader("Content-Type", "application/json"); @@ -1523,8 +1555,8 @@ var tvii = tvii || { } }, focusElement: function (el) { - $('[navi_target]').removeClass('focus'); - el.addClass('focus').focus(); + $("[navi_target]").removeClass("focus"); + el.addClass("focus").focus(); }, initButton: function () { var buttonType = { @@ -1542,11 +1574,11 @@ var tvii = tvii || { 40: "d-down", 37: "d-left", 39: "d-right", - } + }; var lockW = null; function lerp(a, b, alpha) { - return a + alpha * (b - a) + return a + alpha * (b - a); } vino.navi_setMoveMethod(-1); @@ -1568,30 +1600,30 @@ var tvii = tvii || { function doButtonAction(r) { if (r == 65) { - if ($('.focus').length > 0) { - if (!$('.focus').is(':visible')) { - $('.focus').removeClass('focus').blur(); + if ($(".focus").length > 0) { + if (!$(".focus").is(":visible")) { + $(".focus").removeClass("focus").blur(); } - else if ($('.focus').find('input:not([type="radio"])').length) { - $('.focus').find('input:not([type="radio"])').first().focus(); + else if ($(".focus").find("input:not([type=\"radio\"])").length) { + $(".focus").find("input:not([type=\"radio\"])").first().focus(); vino.wakeKeyboard(); - } else if ($('.focus').is('label')) { - $('.focus').find('input').first().focus(); - $('.focus').find('input').first().trigger('click'); - if ($('.focus').find('input').first().is('input:not([type="radio"]')) { + } else if ($(".focus").is("label")) { + $(".focus").find("input").first().focus(); + $(".focus").find("input").first().trigger("click"); + if ($(".focus").find("input").first().is("input:not([type=\"radio\"]")) { vino.wakeKeyboard(); } - } else if ($('.focus').is('input[type="text"]')) { - $('.focus').focus(); + } else if ($(".focus").is("input[type=\"text\"]")) { + $(".focus").focus(); vino.wakeKeyboard(); - } else if ($('.focus').is('input[type="number"]')) { - $('.focus').focus(); + } else if ($(".focus").is("input[type=\"number\"]")) { + $(".focus").focus(); vino.wakeKeyboard(); - } else if ($('.focus').is('input[type="radio"]')) { - $('.focus').focus(); - $('.focus').trigger('click'); + } else if ($(".focus").is("input[type=\"radio\"]")) { + $(".focus").focus(); + $(".focus").trigger("click"); } else { - $('.focus').trigger('click'); + $(".focus").trigger("click"); } } } @@ -1601,18 +1633,18 @@ var tvii = tvii || { var f; if ($(".modal-window-open").length) { - all = $('.modal-window-open [navi_target]:visible'); // Get all visible elements with the navi_target attribute - f = $('.modal-window-open [navi_target].focus:visible'); // Get the currently focused visible element + all = $(".modal-window-open [navi_target]:visible"); // Get all visible elements with the navi_target attribute + f = $(".modal-window-open [navi_target].focus:visible"); // Get the currently focused visible element } else { - all = $('[navi_target]:visible'); // Get all visible elements with the navi_target attribute - f = $('[navi_target].focus:visible'); // Get the currently focused visible element + all = $("[navi_target]:visible"); // Get all visible elements with the navi_target attribute + f = $("[navi_target].focus:visible"); // Get the currently focused visible element } if (f.length === 0) { - $('[navi_target]').removeClass('focus'); + $("[navi_target]").removeClass("focus"); // If no element has the .focus class, focus the first visible element in document order - all.first().addClass('focus').focus(); + all.first().addClass("focus").focus(); } else { // If a focused element exists, move focus based on the arrow key var currentIndex = all.index(f); // Get the index of the currently focused element @@ -1629,16 +1661,16 @@ var tvii = tvii || { // Ensure new index is within bounds if (newIndex >= 0 && newIndex < all.length) { // Remove .focus from current and add it to the new visible element - f.removeClass('focus'); - all.eq(newIndex).addClass('focus').focus(); // Focus the element at the new index + f.removeClass("focus"); + all.eq(newIndex).addClass("focus").focus(); // Focus the element at the new index } } } - var openModal2 = $('.modal-window-open-2'); - var openModal = $('.modal-window-open'); + var openModal2 = $(".modal-window-open-2"); + var openModal = $(".modal-window-open"); if (openModal.length) { - var i = openModal.find('.accesskey-' + buttonType[r] + ':visible'); + var i = openModal.find(".accesskey-" + buttonType[r] + ":visible"); if (i.length) { if (i.is("input")) { i.focus(); @@ -1649,7 +1681,7 @@ var tvii = tvii || { } return; } else if (openModal2.length) { - var i = openModal2.find('.accesskey-' + buttonType[r] + ':visible'); + i = openModal2.find(".accesskey-" + buttonType[r] + ":visible"); if (i.length) { if (i.is("input")) { i.focus(); @@ -1660,7 +1692,7 @@ var tvii = tvii || { } return; } else { - var i = $('.accesskey-' + buttonType[r] + ':visible'); + i = $(".accesskey-" + buttonType[r] + ":visible"); if (i.length) { if (i.is("input")) { i.focus(); @@ -1675,8 +1707,8 @@ var tvii = tvii || { var inputCheck = setInterval(function () { wiiu.gamepad.update(); if (wiiu.gamepad.tpTouch == 1) { - if ($('.focus').length > 0) { - $('.focus').removeClass('focus').blur(); + if ($(".focus").length > 0) { + $(".focus").removeClass("focus").blur(); } } @@ -1688,7 +1720,7 @@ var tvii = tvii || { return; } - var c = $('.l-stick-scroll:visible').first(); + var c = $(".l-stick-scroll:visible").first(); switch (wiiu.gamepad.hold) { case 1073741824: c.scrollLeft(function (i, v) { return v + lerp(-25, -25, wiiu.gamepad.lStickX); }); @@ -1705,14 +1737,14 @@ var tvii = tvii || { } }, 0); - } - } + }, + }, }; $(window).on("load", function () { tvii.utils.startInitialLoading(); $(window).off("load"); -}) +}); $(document).on("tvii:initialized", function () { tvii.utils.endInitialLoading(); @@ -1723,7 +1755,7 @@ $(document).on("tvii:initialized", function () { $(document).on("tvii:pageclear", function () { tvii.utils.abortOngoingXHR(); tvii.utils.clearEvents(); -}) +}); $(document).on("tvii:pagechange", function () { var j = new Jamiroquai(); @@ -1731,7 +1763,7 @@ $(document).on("tvii:pagechange", function () { tvii.utils.initRemote(); tvii.utils.initPageLinks(); -}) +}); $(window).on("popstate", function () { tvii.utils.changePage(location.search, true); @@ -1744,7 +1776,7 @@ tvii.router.connect("^[?&]page=manual(?:&|$)", function () { $(document).trigger("modalchange:manual", [$(show)]); history.pushState(null, "", location.search + "&manual=" + id); - }; + } $("[data-show]").on("click", function () { changeScreen($(this).attr("data-hide"), $(this).attr("data-show"), $(this).attr("data-id")); @@ -1773,7 +1805,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { function changeScreen(hide, show) { $(hide).addClass("none"); - $(show).removeClass("none") + $(show).removeClass("none"); $(document).trigger("modalchange:setup", [$(show)]); } @@ -1784,7 +1816,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { var favSocial; var favStr; var favChn; - var aboutPageInfo = new tvii.utils.ScrollingContainer($(".setup-modal.zipcode-info .about-text"), false) + var aboutPageInfo = new tvii.utils.ScrollingContainer($(".setup-modal.zipcode-info .about-text"), false); var providerScroll = new tvii.utils.ScrollingContainer($(".provider-container"), true); var favoriteTVAddScroll = new tvii.utils.ScrollingContainer($(".program-container.favorites-tv-container"), true); var favoriteMovieAddScroll = new tvii.utils.ScrollingContainer($(".movie-container.favorites-movie-container"), true); @@ -1801,53 +1833,53 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { var MovieRating; providerScroll.scrCont.on("scrolling", function (e, data) { - provX = data.scrollX - }) + provX = data.scrollX; + }); favoriteTVAddScroll.scrCont.on("scrolling", function (e, data) { - favTVX = data.scrollX - }) + favTVX = data.scrollX; + }); favoriteMovieAddScroll.scrCont.on("scrolling", function (e, data) { - favMX = data.scrollX - }) + favMX = data.scrollX; + }); favoriteSocialScroll.scrCont.on("scrolling", function (e, data) { - favSocial = data.scrollX - }) + favSocial = data.scrollX; + }); favoriteStreamingScroll.scrCont.on("scrolling", function (e, data) { - favStr = data.scrollX - }) + favStr = data.scrollX; + }); favoriteChannelsScroll.scrCont.on("scrolling", function (e, data) { - favChn = data.scrollX - }) + favChn = data.scrollX; + }); $("[data-show]").on("click", function () { changeScreen($(this).attr("data-hide"), $(this).attr("data-show")); - }) + }); $(".back-button, .exit-modal").on("click", function () { vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); - }) + }); $(".next-button").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); - }) + }); $(".setup-modal.zipcode a:not(.mii):not(.exit-button)").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); - }) + }); $(".setup-modal.zipcode a:not(.mii):not(.exit-button)").on("mousedown mouseup mousemove mouseout", function () { - }) + }); $(".setup-modal.zipcode a:not(.mii):not(.exit-button)").on("mousedown", function () { vino.soundPlay("SE_CMN_TOUCH_ON"); - }) + }); - $(".setup-modal.zipcode .mii img").attr("src", vino.act_getMiiImage(tvii.userSlot)); + $(".setup-modal.zipcode .mii img").attr("src", tvii.url.MII(vino.act_getCurrentSlotNo(), 0, false, false)); $(".exit-button").on("click", function () { vino.soundPlay("SE_COMMON_FINISH_TOUCH_OFF"); @@ -1930,7 +1962,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { case 0: pcAlertTimeout = setTimeout(function () { alert(tvii.templates.getLoc("vino.setup.screen.pc.alert1")); - }, 95) + }, 95); break; case 1: $(".setup-modal-page-pc").addClass("none"); @@ -1939,7 +1971,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { default: break; } - }) + }); } function requestProviders() { @@ -1962,8 +1994,8 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { newZip.val().length || !newZip.val().length) { - console.log(zipCode) - console.log(newZip.val()) + console.log(zipCode); + console.log(newZip.val()); //Checks only for US Zip code if (newZip.hasClass("zipnum") && @@ -2068,9 +2100,9 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".setup-modal p.notice .provider-chamount").html( tvii.templates.getLoc("vino.setup.screen1.p5", { - "%s": chAm - }) - ) + "%s": chAm, + }), + ); $(".setup-modal p.notice .provider-chpreview").html( tvii.templates.getLoc("vino.setup.screen1.p6", { @@ -2079,14 +2111,14 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { "%g": ch2Nu, "%h": ch2Na, "%j": ch3Nu, - "%k": ch3Na - }) - ) + "%k": ch3Na, + }), + ); $(".setup-modal p.notice").css("display", "none"); setTimeout(function () { $(".setup-modal p.notice").css("display", ""); - }, 0) + }, 0); } if (!$(".setup-modal-page-2").data("providerTVTypeListener")) { @@ -2102,30 +2134,30 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { switch ($(this).attr("data-type")) { case "cab": $(".provider-container a").css("display", "none"); - if ($('.provider-container [data-provider-type="CABLE"], .provider-container [data-provider-type="OVD"]').length < 1) { + if ($(".provider-container [data-provider-type=\"CABLE\"], .provider-container [data-provider-type=\"OVD\"]").length < 1) { $(".provider-container").find("h3.no-providers").addClass("fadein"); $(".provider-container").find("h3.no-providers").css("display", ""); break; } - $('.provider-container [data-provider-type="CABLE"], .provider-container [data-provider-type="OVD"]').css("display", ""); + $(".provider-container [data-provider-type=\"CABLE\"], .provider-container [data-provider-type=\"OVD\"]").css("display", ""); break; case "sat": $(".provider-container a").css("display", "none"); - if ($('.provider-container [data-provider-type="SATELLITE"]').length < 1) { + if ($(".provider-container [data-provider-type=\"SATELLITE\"]").length < 1) { $(".provider-container").find("h3.no-providers").addClass("fadein"); $(".provider-container").find("h3.no-providers").css("display", ""); break; } - $('.provider-container [data-provider-type="SATELLITE"]').css("display", ""); + $(".provider-container [data-provider-type=\"SATELLITE\"]").css("display", ""); break; case "ant": $(".provider-container a").css("display", "none"); - if ($('.provider-container [data-provider-type="OTA"]').length < 1) { + if ($(".provider-container [data-provider-type=\"OTA\"]").length < 1) { $(".provider-container").find("h3.no-providers").addClass("fadein"); $(".provider-container").find("h3.no-providers").css("display", ""); break; } - $('.provider-container [data-provider-type="OTA"]').css("display", ""); + $(".provider-container [data-provider-type=\"OTA\"]").css("display", ""); break; default: break; @@ -2140,7 +2172,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { } providerScroll.scrCont.scrollLeft(provX); - }) + }); $(".setup-modal-page-2").data("providerTVTypeListener", true); } @@ -2153,7 +2185,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".setup-modal p.notice").css("display", ""); provX = 0; var providers = JSON.parse(responseText).result.hits; - var providerHTML = ''; + var providerHTML = ""; for (var i = 0; i < providers.length; i++) { var headendId = providers[i].headendId; @@ -2169,24 +2201,24 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { var chName = channelsPreview[g].name.en; var chNum = channelsPreview[g].channels[0].channel; - attrsCh += 'data-channel-preview-' + g + '-name="' + chName + '" ' + - 'data-channel-preview-' + g + '-num="' + chNum + '" ' + attrsCh += "data-channel-preview-" + g + "-name=\"" + chName + "\" " + + "data-channel-preview-" + g + "-num=\"" + chNum + "\" "; } - var anchor = '' + - '' + name + '' + - ''; + "data-provider-channel-amount=\"" + channelAmount + "\" " + + "data-provider-type=\"" + lineupType + "\">" + + "" + name + "" + + ""; - providerHTML += anchor + '\n'; + providerHTML += anchor + "\n"; } - providerHTML += '

' + tvii.templates.getLoc("vino.setup.screen2.h7") + '

\n'; + providerHTML += "

" + tvii.templates.getLoc("vino.setup.screen2.h7") + "

\n"; $(".provider-container").html(providerHTML); $(".provider-container a").addClass("fadein"); @@ -2198,8 +2230,8 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(this).addClass("selected"); - console.log($(this).attr("data-provider-headend-id")) - }) + console.log($(this).attr("data-provider-headend-id")); + }); $(".provider-type-container").addClass("fadein"); $(".provider-type-container").css("display", ""); }, 450); @@ -2211,14 +2243,14 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".loading-provider.error").css("display", ""); $(".loading-provider.error").addClass("fadein"); }, 450); - }) + }); } function requestStreamingProviders() { if ($(".streaming-container .provider").length) { - favoriteStreamingScroll.scrCont.scrollLeft(favStr) + favoriteStreamingScroll.scrCont.scrollLeft(favStr); } function setStrProvListeners() { @@ -2245,14 +2277,14 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { function requestDiscoverTVFavorites() { if (sessionStorage.getItem("not_responsible_content_shown_flag") != "shown") { - alert(tvii.templates.getLoc("vino.setup.screen3.alert1")) + alert(tvii.templates.getLoc("vino.setup.screen3.alert1")); alert(tvii.templates.getLoc("vino.setup.screen3.alert2")); alert(tvii.templates.getLoc("vino.setup.screen3.alert3")); sessionStorage.setItem("not_responsible_content_shown_flag", "shown"); } if ($(".program-container .program").length) { - favoriteTVAddScroll.scrCont.scrollLeft(favTVX) + favoriteTVAddScroll.scrCont.scrollLeft(favTVX); return; } @@ -2267,7 +2299,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { } }); - tvii.utils.handleImageLoading($('.program-container.favorites-tv-container .program img'), true); + tvii.utils.handleImageLoading($(".program-container.favorites-tv-container .program img"), true); } $(".program-container.favorites-tv-container").html(""); @@ -2286,7 +2318,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { tvii.utils.sendXHR("GET", tvii.url.DISCOVER(true, discoverTVQuery, ""), function (responseText) { var results = JSON.parse(responseText).result.tv; if (!results.length) { return; } - var resultHTML = ''; + var resultHTML = ""; var halfwayIndex = Math.floor(results.length / 2); for (var i = 0; i < results.length; i++) { @@ -2294,27 +2326,27 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { var name = results[i].name; var id = results[i].id; - var anchor = '' + - '' + - '
' + - '' + name + '' + - '' + - '' + - '
' + - '' + - '
'; + var anchor = "" + + "" + + "
" + + "" + name + "" + + "" + + "" + + "
" + + "" + + "
"; - resultHTML += anchor + '\n'; + resultHTML += anchor + "\n"; if (i === halfwayIndex - 1) { // Add
after the first half - resultHTML += '
\n'; + resultHTML += "
\n"; } } - resultHTML += '' + - '' + - ''; + resultHTML += "" + + "" + + ""; $(".program-container.favorites-tv-container").html(resultHTML); tvii.utils.initTouchEffect(); @@ -2322,19 +2354,19 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".program-container.favorites-tv-container .program-favorite-search").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); - }) + }); $(".program-container.favorites-tv-container .program-favorite-search input").on("change", function () { tvii.utils.sendXHR("GET", tvii.url.SEARCH(1, $(this).val(), ""), function (searchResults) { var searchRes = JSON.parse(searchResults).results; if (!searchRes.length) { return; } - var firstHalfHTML = ''; - var secondHalfHTML = ''; + var firstHalfHTML = ""; + var secondHalfHTML = ""; var $container = $(".program-container.favorites-tv-container"); - var $br = $container.find('br'); - var $searchElement = $('.program-container .program-favorite-search'); + var $br = $container.find("br"); + var $searchElement = $(".program-container .program-favorite-search"); var $beforeBr = $br.prevAll("a"); // Find all elements before
var $afterBr = $br.nextAll("a"); // Find all
elements after
@@ -2349,26 +2381,26 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { var id = searchRes[x].id; // Check if the program with the same id already exists - if ($('.program-container.favorites-tv-container').find('[data-program-id="' + id + '"]').length > 0) { + if ($(".program-container.favorites-tv-container").find("[data-program-id=\"" + id + "\"]").length > 0) { continue; // Skip if the anchor already exists } - var anchor = '
' + - '' + - '
' + - '' + name + '' + - '' + - '' + - '
' + - '' + - '
'; + var anchor = "" + + "" + + "
" + + "" + name + "" + + "" + + "" + + "
" + + "" + + "
"; if (elementsBeforeBr <= elementsAfterBr) { - firstHalfHTML += anchor + '\n'; + firstHalfHTML += anchor + "\n"; elementsBeforeBr++; } else { - secondHalfHTML += anchor + '\n' + secondHalfHTML += anchor + "\n"; elementsAfterBr++; } } @@ -2408,7 +2440,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".program-container.favorites-tv-container").css("display", ""); }, function (xhr) { - }) + }); } function requestDiscoverMovieFavorites() { @@ -2424,11 +2456,11 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { } }); - tvii.utils.handleImageLoading($('.movie-container.favorites-movie-container .movie img'), true); + tvii.utils.handleImageLoading($(".movie-container.favorites-movie-container .movie img"), true); } if ($(".movie-container.favorites-movie-container .movie").length) { - favoriteMovieAddScroll.scrCont.scrollLeft(favMX) + favoriteMovieAddScroll.scrCont.scrollLeft(favMX); return; } @@ -2449,28 +2481,28 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { tvii.utils.sendXHR("GET", tvii.url.DISCOVER(false, discoverMovieQuery, ""), function (responseText) { var results = JSON.parse(responseText).result.movies; if (!results.length) { return; } - var resultHTML = ''; + var resultHTML = ""; for (var i = 0; i < results.length; i++) { var image = tvii.url.generateTMDBImageUrl(results[i].poster_path, 224); var name = results[i].title; var id = results[i].id; - var anchor = '' + - '' + - '
' + - '' + name + '' + - '
' + - '' + - '
'; + var anchor = "" + + "" + + "
" + + "" + name + "" + + "
" + + "" + + "
"; - resultHTML += anchor + '\n'; + resultHTML += anchor + "\n"; } - resultHTML += '' + - '' + - ''; + resultHTML += "" + + "" + + ""; $(".movie-container.favorites-movie-container").html(resultHTML); tvii.utils.initTouchEffect(); @@ -2478,14 +2510,14 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".movie-container.favorites-movie-container .movie-favorite-search").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); - }) + }); $(".movie-container.favorites-movie-container .movie-favorite-search input").on("change", function () { tvii.utils.sendXHR("GET", tvii.url.SEARCH(2, $(this).val(), ""), function (searchResults) { var searchRes = JSON.parse(searchResults).results; if (!searchRes.length) { return; } - var resultHTML = ''; + var resultHTML = ""; // Generate HTML for each program for (var x = 0; x < searchRes.length; x++) { @@ -2494,20 +2526,20 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { var id = searchRes[x].id; // Check if the program with the same id already exists - if ($('.movie-container.favorites-movie-container').find('[data-movie-id="' + id + '"]').length > 0) { + if ($(".movie-container.favorites-movie-container").find("[data-movie-id=\"" + id + "\"]").length > 0) { continue; // Skip if the anchor already exists } - var anchor = '' + - '' + - '
' + - '' + name + '' + - '
' + - '' + - '
'; + var anchor = "" + + "" + + "
" + + "" + name + "" + + "
" + + "" + + "
"; - resultHTML += anchor + '\n'; + resultHTML += anchor + "\n"; } $(".movie-container.favorites-movie-container .movie-favorite-search").before(resultHTML); @@ -2524,7 +2556,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".movie-container.favorites-movie-container").css("display", ""); }, function (xhr) { - }) + }); } @@ -2534,7 +2566,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".search-channel.search-callsign, .search-channel.search-number").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); - }) + }); $(".search-channel.search-number input").on("change", function () { if (!channelList || !channelList.length) { @@ -2543,7 +2575,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { favoriteChannelsScroll.stop(); var searchValue = $(this).val().trim().toUpperCase(); - var regex = new RegExp(searchValue, 'i'); + var regex = new RegExp(searchValue, "i"); var matches = channelList.filter(function (channel) { return regex.test(channel.channelNo); @@ -2551,11 +2583,11 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { matches = matches.slice(0, 25); - var firstHalfHTML = ''; - var secondHalfHTML = ''; + var firstHalfHTML = ""; + var secondHalfHTML = ""; var $container = $(".fav-tv-channels"); - var $br = $container.find('br'); + var $br = $container.find("br"); var $beforeBr = $br.prevAll("a"); // Find all elements before
var $afterBr = $br.nextAll("a"); // Find all
elements after
@@ -2581,20 +2613,20 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { continue; } - var anchor = '
' + - '' + cs + ' ' + number + '' + - '' + - ''; + var anchor = "" + + "" + cs + " " + number + "" + + "" + + ""; // Distribute matches based on the current length of each section if (elementsBeforeBr <= elementsAfterBr) { - firstHalfHTML += anchor + '\n'; // Add to first half (before
) if it has fewer or equal items + firstHalfHTML += anchor + "\n"; // Add to first half (before
) if it has fewer or equal items elementsBeforeBr++; } else { - secondHalfHTML += anchor + '\n'; // Add to second half (after
) if it has fewer items + secondHalfHTML += anchor + "\n"; // Add to second half (after
) if it has fewer items elementsAfterBr++; } } @@ -2613,7 +2645,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { setFavChnListeners(); favoriteChannelsScroll.stop(); $container.animate({ - scrollLeft: $container[0].scrollWidth + scrollLeft: $container[0].scrollWidth, }, 1000, "swing", function () { favoriteChannelsScroll.stop(); }); @@ -2627,7 +2659,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { favoriteChannelsScroll.stop(); var searchValue = $(this).val().trim().toUpperCase(); - var regex = new RegExp(searchValue, 'i'); + var regex = new RegExp(searchValue, "i"); var matches = channelList.filter(function (channel) { return regex.test(channel.callSign); @@ -2635,11 +2667,11 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { matches = matches.slice(0, 25); - var firstHalfHTML = ''; - var secondHalfHTML = ''; + var firstHalfHTML = ""; + var secondHalfHTML = ""; var $container = $(".fav-tv-channels"); - var $br = $container.find('br'); + var $br = $container.find("br"); var $beforeBr = $br.prevAll("a"); // Find all elements before
var $afterBr = $br.nextAll("a"); // Find all
elements after
@@ -2648,7 +2680,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { for (var i = 0; i < matches.length; i++) { var image = matches[i].thumbnail; - var g = image.indexOf('?w='); + var g = image.indexOf("?w="); if (g !== -1) { var updatedStr = image.substring(0, g); @@ -2667,22 +2699,22 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { continue; } - var anchor = '
' + - '' + - '' + cs + ' ' + number + '' + - '' + - ''; + var anchor = "" + + "" + + "" + cs + " " + number + "" + + "" + + ""; // Distribute matches based on the current length of each section if (elementsBeforeBr <= elementsAfterBr) { - firstHalfHTML += anchor + '\n'; // Add to first half (before
) if it has fewer or equal items + firstHalfHTML += anchor + "\n"; // Add to first half (before
) if it has fewer or equal items elementsBeforeBr++; } else { - secondHalfHTML += anchor + '\n'; // Add to second half (after
) if it has fewer items + secondHalfHTML += anchor + "\n"; // Add to second half (after
) if it has fewer items elementsAfterBr++; } } @@ -2701,7 +2733,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { setFavChnListeners(); favoriteChannelsScroll.stop(); $container.animate({ - scrollLeft: $container[0].scrollWidth + scrollLeft: $container[0].scrollWidth, }, 1000, "swing", function () { favoriteChannelsScroll.stop(); }); @@ -2732,15 +2764,15 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { if (vino.info_getCountry() == "US" && $(".setup-modal.zipcode input.zipnum").val()) { zipcode = $(".setup-modal.zipcode input.zipnum").val(); } else if (vino.info_getCountry() == "CA" && $(".setup-modal.zipcode input.zipkey").val()) { - zipcode = $(".setup-modal.zipcode input.zipkey").val().replace(/\s/g, '').toUpperCase(); + zipcode = $(".setup-modal.zipcode input.zipkey").val().replace(/\s/g, "").toUpperCase(); } else { zipcode = null; } if (selectedProvider.length) { - lineup = selectedProvider.attr("data-provider-id") - headend = selectedProvider.attr("data-provider-headend-id") - device = selectedProvider.attr("data-provider-device") ? selectedProvider.attr("data-provider-device") : "-" + lineup = selectedProvider.attr("data-provider-id"); + headend = selectedProvider.attr("data-provider-headend-id"); + device = selectedProvider.attr("data-provider-device") ? selectedProvider.attr("data-provider-device") : "-"; } var time = new Date().toISOString(); @@ -2759,7 +2791,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".fav-tv-channels").attr("data-channel-container-headend") === headend && $(".fav-tv-channels").attr("data-channel-container-device") === device && $(".fav-tv-channels .channel").length) { - favoriteChannelsScroll.scrCont.scrollLeft(favChn) + favoriteChannelsScroll.scrCont.scrollLeft(favChn); return; } @@ -2792,7 +2824,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".fav-tv-channels").attr("data-channel-container-device", device); console.log(responseText); // Check what the API response is returning channelList = JSON.parse(responseText).result.hits; - console.log(channelList) + console.log(channelList); //Load 50 channels initally var initialCh; if (channelList.length > 40) { @@ -2800,11 +2832,11 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { } else { initialCh = channelList.length; } - var resultHTML = ''; + var resultHTML = ""; var halfwayIndex = Math.floor(initialCh / 2); for (var i = 0; i < initialCh; i++) { - var image = ''; + var image = ""; // Sometimes the image is not available? // TODO: use zap2it for images @@ -2820,18 +2852,18 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { var chid = channelList[i].id; var cs = channelList[i].callSign; - var anchor = '' + - '' + - '' + cs + ' ' + number + '' + - '' + - ''; + var anchor = "" + + "" + + "" + cs + " " + number + "" + + "" + + ""; - resultHTML += anchor + '\n'; + resultHTML += anchor + "\n"; if (i === halfwayIndex - 1) { // Add
after the first half - resultHTML += '
\n'; + resultHTML += "
\n"; } } @@ -2841,7 +2873,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { setFavChnListeners(); }, function (xhr) { - }) + }); } @@ -2852,14 +2884,14 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { xhr.open("POST", tvii.clientUrl + "/api/v1/account/BSLinkAttempt"); xhr.send(JSON.stringify({ identifier: bskyUser, - password: bskyPass - })) + password: bskyPass, + })); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { vino.loading_setIconAppear(false); if (xhr.status == 200) { - if (!xhr.responseText) { return } + if (!xhr.responseText) { return; } var r = JSON.parse(xhr.responseText); callbackSuccess( JSON.parse(xhr.responseText), @@ -2870,15 +2902,15 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { active: r.active, accessJwt: r.accessJwt, refreshJwt: r.refreshJwt, - displayName: r.displayName - } + displayName: r.displayName, + }, ); } else { - if (!xhr.responseText) { return } + if (!xhr.responseText) { return; } callbackError(JSON.parse(xhr.responseText)); } } - } + }; } function requestTwitterCodeActivated(code, callbackSuccess, callbackError) { @@ -2888,17 +2920,17 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status == 200) { - if (!xhr.responseText) { return } + if (!xhr.responseText) { return; } var r = JSON.parse(xhr.responseText); if (r.status == "verified") { callbackSuccess(r); } } else { - if (!xhr.responseText) { return } + if (!xhr.responseText) { return; } callbackError(JSON.parse(xhr.responseText)); } } - } + }; } function requestTwitterLoginCode(callbackSuccess, callbackError) { @@ -2910,15 +2942,15 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { if (xhr.readyState == 4) { vino.loading_setIconAppear(false); if (xhr.status == 200) { - if (!xhr.responseText) { return } + if (!xhr.responseText) { return; } var r = JSON.parse(xhr.responseText); callbackSuccess(r); } else { - if (!xhr.responseText) { return } + if (!xhr.responseText) { return; } callbackError(JSON.parse(xhr.responseText)); } } - } + }; } if (!$(".setup-modal-page-6").data("socialSetupListeners")) { // Check if the event is already bound @@ -2961,9 +2993,9 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { twttrSuccessInterval = setInterval(function () { requestTwitterCodeActivated($(".twttr-login .code").text(), function (response) { clearInterval(twttrSuccessInterval); - $(".social-media-container .twtt-button").attr("data-twitter-user-id", response.twttr_user_id) - $(".social-media-container .twtt-button").attr("data-twitter-oauth-token", response.twttr_oauth_token) - $(".social-media-container .twtt-button").attr("data-twitter-oauth-verifier", response.twttr_oauth_verifier) + $(".social-media-container .twtt-button").attr("data-twitter-user-id", response.twttr_user_id); + $(".social-media-container .twtt-button").attr("data-twitter-oauth-token", response.twttr_oauth_token); + $(".social-media-container .twtt-button").attr("data-twitter-oauth-verifier", response.twttr_oauth_verifier); $(".twttr-login .username").text("@" + response.twttr_screen_name); $(".twttr-login form").addClass("none"); $(".twttr-login .logged").removeClass("none"); @@ -2996,7 +3028,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { if (!$(".twttr-login .code").text().length) { requestTwitterLoginCode(function (codeResponse) { - $(".twttr-login .code").text(codeResponse.code) + $(".twttr-login .code").text(codeResponse.code); setTwitterInterval(); }, function () { }); @@ -3014,24 +3046,24 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".tumblr-login-container").toggleClass("modal-window-open"); $(".tumblr-login-container").css("display", "block"); } - }) + }); $(".bsky-login-container .exit-modal").on("click", function () { $(".bsky-login-container").toggleClass("modal-window-open"); $(".bsky-login-container").css("display", ""); - }) + }); $(".tumblr-login-container .exit-modal").on("click", function () { clearInterval(tumblrSuccessInterval); $(".tumblr-login-container").toggleClass("modal-window-open"); $(".tumblr-login-container").css("display", ""); - }) + }); $(".twttr-login-container .exit-modal").on("click", function () { clearInterval(twttrSuccessInterval); $(".twttr-login-container").toggleClass("modal-window-open"); $(".twttr-login-container").css("display", ""); - }) + }); $(".bsky-login input").on("input change", function () { if ($(".bsky-login .username").val().length < 1) { @@ -3071,7 +3103,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".twttr-login-container").removeClass("modal-window-open"); $(".twttr-login-container").css("display", ""); } - }) + }); $(".bsky-login form>.submit").on("click", function () { var btn = $(this); @@ -3082,7 +3114,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { var bskyUser = $(".bsky-login .username"); var bskyPass = $(".bsky-login .pass"); btn.addClass("disabled"); - requestBlueSkyLogin(bskyUser.val().replace(/@/g, ''), bskyPass.val(), function (response, data) { + requestBlueSkyLogin(bskyUser.val().replace(/@/g, ""), bskyPass.val(), function (response, data) { $(".social-media-container .bsky-button").attr("data-bsky-password", data.password); $(".social-media-container .bsky-button").attr("data-bsky-username", data.username); @@ -3099,8 +3131,8 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { }, function () { alert(tvii.templates.getLoc("vino.setup.bsky.error1")); btn.removeClass("disabled"); - }) - }) + }); + }); $(".bsky-login .logged>.submit").on("click", function () { if ($(this).hasClass("disabled")) { @@ -3122,7 +3154,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { $(".bsky-login .pass").val(""); $(".bsky-login-container").find(".bsky-login form").removeClass("none"); } - }) + }); $(".setup-modal-page-6").data("socialSetupListeners", true); // Mark the event as bound } @@ -3169,7 +3201,7 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { // TODO: Be specific about the error alert("An error occurred while creating the account. Please try again."); }, function () {}, formData); - }) + }); $(document).on("modalchange:setup", function (evt, show) { if (!BGMisPlaying && show.hasClass("setup-modal-page-2")) { @@ -3208,7 +3240,23 @@ tvii.router.connect("^[?&]page=setup(?:&|$)", function () { } else if (show.hasClass("setup-modal-page-1")) { changeStatusbar(0); } - }) + }); + + var touchMii = 0; + $(".setup-modal.zipcode .mii").on("click", function () { + var mii = $(this).find("img"); + touchMii++; + vino.soundPlay("SE_WORD_MII"); + + if (touchMii >= 10) { + mii.css("transform", "rotate(180deg)"); + setTimeout(function () { + mii.css("transform", "rotate(0deg)"); + }, 200); + } + + console.log("Mii clicked"); + }); }); @@ -3216,43 +3264,43 @@ tvii.router.connect("^[?&]page=home(?:&|$)", function () { //Main page, clear previous cache from other pages that may have not been used tvii.utils.clearStorage(); - var helpContainer = new tvii.utils.ScrollingContainer($('.help-modal .help-container'), true); + var helpContainer = new tvii.utils.ScrollingContainer($(".help-modal .help-container"), true); - $(".mii-icon img").attr("src", vino.act_getMiiImage(tvii.userSlot)); + $(".mii-icon img").attr("src", tvii.url.MII(vino.act_getCurrentSlotNo(), 0, false, false)); $(".mii-icon").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); - }) + }); $(".home-buttons a").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); - }) + }); $(".exit-button").on("click", function () { vino.soundPlay("SE_COMMON_FINISH_TOUCH_OFF"); vino.exit(); - }) + }); $(".help-button").on("click", function () { vino.soundPlay("SE_A_HELP_TOUCH_OFF"); - }) + }); $(".exit-help").on("click", function () { vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); - }) + }); $(".help-button, .exit-help").on("click", function () { $(".help-modal").toggleClass("none"); $(".help-modal").toggleClass("modal-window-open"); - }) + }); }); tvii.router.connect("^[?&]page=settings(?:&|$)", function () { tvii.utils.initTabs(); - var settingScroll = new tvii.utils.ScrollingContainer($('.settings-container'), true); - var toolsScroll = new tvii.utils.ScrollingContainer($('.tools-container'), true); - var creditScroll = new tvii.utils.ScrollingContainer($('.credits-container'), true); + var settingScroll = new tvii.utils.ScrollingContainer($(".settings-container"), true); + var toolsScroll = new tvii.utils.ScrollingContainer($(".tools-container"), true); + var creditScroll = new tvii.utils.ScrollingContainer($(".credits-container"), true); var sX; var tX; @@ -3261,15 +3309,15 @@ tvii.router.connect("^[?&]page=settings(?:&|$)", function () { settingScroll.scrCont.on("scrolling", function (e, data) { sX = data.scrollX; - }) + }); toolsScroll.scrCont.on("scrolling", function (e, data) { tX = data.scrollX; - }) + }); creditScroll.scrCont.on("scrolling", function (e, data) { cX = data.scrollX; - }) + }); $(document).on("tvii:tabchange", function (event, tab) { settingScroll.stop(); @@ -3278,7 +3326,7 @@ tvii.router.connect("^[?&]page=settings(?:&|$)", function () { if (touchMii > 0) { touchMii = 0; - $(".mii-body img").attr("src", vino.act_getMiiImageEx(tvii.userSlot, 7)); + $(".mii-body img").attr("src", tvii.url.MII(vino.act_getCurrentSlotNo(), 0, true, false)); } if (tab.attr("data-section") == "about") { @@ -3300,25 +3348,25 @@ tvii.router.connect("^[?&]page=settings(?:&|$)", function () { toolsScroll.scrCont.scrollLeft(tX); } - }) + }); //If did go back, then tab query should already exist if (tvii.utils.getQuery("scene", true) != null) { var query = tvii.utils.getQuery("scene", true); } else { - tvii.utils.triggerTab($('[data-section="settings"]')); + tvii.utils.triggerTab($("[data-section=\"settings\"]")); } $(".back-button").on("click", function () { vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); history.back(); - }) + }); $(".home-top").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); tvii.utils.changePage("?page=home", true); - }) + }); $(".settings-container .mii-body").on("click", function () { var mii = $(this).find("img"); @@ -3328,7 +3376,7 @@ tvii.router.connect("^[?&]page=settings(?:&|$)", function () { if (touchMii >= 100) { var randomIndex = Math.floor(Math.random() * numImages) + 1; - var newImageSrc = vino.act_getMiiImageEx(randomIndex, 7); + var newImageSrc = tvii.url.MII(randomIndex, 0, true, false); mii.attr("src", newImageSrc); } mii.css("bottom", "10px"); @@ -3344,13 +3392,13 @@ tvii.router.connect("^[?&]page=settings(?:&|$)", function () { setTimeout(function () { mii.css("bottom", "0px"); }, 50); - }) + }); $(".settings-buttons a, .tools-buttons a").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); - }) + }); - $(".mii-body img").attr("src", vino.act_getMiiImageEx(tvii.userSlot, 7)); + $(".mii-body img").attr("src", tvii.url.MII(vino.act_getCurrentSlotNo(), 0, true, false)); $(".mii-body span").text(vino.act_getName(tvii.userSlot)); }); @@ -3358,10 +3406,10 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { tvii.utils.initTabs(); tvii.utils.initToggle(); - var episodesScroll = new tvii.utils.ScrollingContainer($('.program-view-episodes'), true); - var actorsScroll = new tvii.utils.ScrollingContainer($('.program-view-actors'), true); - var infoDescScroll = new tvii.utils.ScrollingContainer($('.program-view-info .info>p1'), false); - var seasonDropScroll = new tvii.utils.ScrollingContainer($('#season-dropdown .dropdown-menu'), true); + var episodesScroll = new tvii.utils.ScrollingContainer($(".program-view-episodes"), true); + var actorsScroll = new tvii.utils.ScrollingContainer($(".program-view-actors"), true); + var infoDescScroll = new tvii.utils.ScrollingContainer($(".program-view-info .info>p1"), false); + var seasonDropScroll = new tvii.utils.ScrollingContainer($("#season-dropdown .dropdown-menu"), true); var query; @@ -3380,29 +3428,29 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { seasonDropScroll.scrCont.prev().on("click", function () { seasonDropScroll.scrCont.scrollLeft(dropX); - }) + }); $(".back-button").on("click", function () { vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); history.back(); - }) + }); $(".home-top").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); tvii.utils.changePage("?page=home", true); - }) + }); episodesScroll.scrCont.on("scrolling", function (e, data) { - epiX = data.scrollX - }) + epiX = data.scrollX; + }); actorsScroll.scrCont.on("scrolling", function (e, data) { - actiX = data.scrollX - }) + actiX = data.scrollX; + }); seasonDropScroll.scrCont.on("scrolling", function (e, data) { - dropX = data.scrollX - }) + dropX = data.scrollX; + }); actorsScroll.scrCont.on("scroll", function () { var c = $(this); @@ -3461,7 +3509,7 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { episodesScroll.scrCont.scrollLeft(epiX); switch (tab.attr("data-season")) { case "schedule": - console.log("schedule") + console.log("schedule"); break; case "upcoming": var curS = program.next_ep_season; @@ -3474,7 +3522,7 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { } break; } - }) + }); function getProgramDetailsById(id) { tvii.utils.disableElements($(".tab-label"), true); @@ -3485,33 +3533,33 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { name: details.name, id: details.id, backdrop_path: details.backdrop_path, - next_ep_season: details.next_episode_to_air ? details.next_episode_to_air.season_number : null - } + next_ep_season: details.next_episode_to_air ? details.next_episode_to_air.season_number : null, + }; - var seasonHTML = ''; + var seasonHTML = ""; for (var i = 0; i < seasons; i++) { console.log(details.seasons); console.log(details.seasons[i]); - var anchor = '
  • ' + - '' + - 'Season ' + details.seasons[i].season_number + - '' + - '
  • '; - - seasonHTML += anchor + '\n'; + var anchor = "
  • " + + "" + + "Season " + details.seasons[i].season_number + + "" + + "
  • "; + + seasonHTML += anchor + "\n"; } $("#season-dropdown .dropdown-menu").html($("#season-dropdown .dropdown-menu").html() + seasonHTML); $(".program-title-big").text(details.name); - $(".program-title-big").css("display", "block") + $(".program-title-big").css("display", "block"); $(".program-poster>img").attr("src", tvii.url.generateTMDBImageUrl(details.poster_path, 200)); tvii.utils.handleImageLoading($(".program-poster>img"), false); - $(".program-view-info .info>h1").text(details.name) + $(".program-view-info .info>h1").text(details.name); $(".program-view-info .info>p1").text(details.overview); $(".program-view-info .info>.metadata>.score").text(String(Math.round(details.vote_average * 10)) + "%"); @@ -3521,24 +3569,24 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { var video = details.videos.results[0]; if (video.site == "YouTube") { $(".program-view-trailer").html($(".program-view-trailer").html() + - '' + "", ); - $(".program-view-trailer>marquee").text(details.name + " : " + video.name) - $('.program-view-trailer>video').on('load', function () { + $(".program-view-trailer>marquee").text(details.name + " : " + video.name); + $(".program-view-trailer>video").on("load", function () { }); - $('.program-view-trailer>video').on('error', function () { + $(".program-view-trailer>video").on("error", function () { }); $(".program-view-info .info>.metadata>.trailer").removeClass("none"); $(".program-view-info .info>.metadata>.trailer").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); - }) + }); $(".program-view-trailer>.exit-modal").on("click", function () { - vino.soundPlay("SE_A_CLOSE_TOUCH_OFF") - }) + vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); + }); $(".program-view-info .info>.metadata>.trailer, .program-view-trailer>.exit-modal").on("click", function () { $(".program-view-trailer").toggleClass("none"); $(".program-view-trailer").toggleClass("modal-window-open-2"); - }) + }); } } @@ -3554,7 +3602,7 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { vino.jumpToBrowser(url, false); } } - }) + }); } tvii.utils.initTouchEffect(); @@ -3563,10 +3611,10 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { setTimeout(function () { if (tvii.utils.getQuery("season", true) != "") { - console.log("Query exists") + console.log("Query exists"); var queryS = tvii.utils.getQuery("season", true); - var tab = $('[data-season="' + queryS + '"]'); + var tab = $("[data-season=\"" + queryS + "\"]"); var dropdown = tab.parent().parent().parent(); tvii.utils.triggerToggleByOption(dropdown, tab); @@ -3574,14 +3622,14 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { } else if (tvii.utils.getQuery("tab", true) != "") { var queryT = tvii.utils.getQuery("tab", true); if (queryT == "info") { - tvii.utils.triggerTab($('[data-season="' + queryT + '"]')) + tvii.utils.triggerTab($("[data-season=\"" + queryT + "\"]")); } else { - console.log(queryT) - var dropdown = $('[data-season="' + queryT + '"]').parent().parent().parent(); - tvii.utils.triggerToggleByOption(dropdown, $('[data-season="' + queryT + '"]')) + console.log(queryT); + dropdown = $("[data-season=\"" + queryT + "\"]").parent().parent().parent(); + tvii.utils.triggerToggleByOption(dropdown, $("[data-season=\"" + queryT + "\"]")); } } else { - tvii.utils.triggerToggleByOption($("#season-dropdown"), $('[data-season="upcoming"]')); + tvii.utils.triggerToggleByOption($("#season-dropdown"), $("[data-season=\"upcoming\"]")); } tvii.utils.disableElements($(".tab-label"), false); @@ -3598,24 +3646,24 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { if (offset && jsonActorCache != null) { var offsetL = $(".program-view-actors .actor").length; if (offsetL < jsonActorCache.length) { - var castHTML = ''; + var castHTML = ""; var limit = offsetL + 10; limit = Math.min(limit, jsonActorCache.length); for (var y = offsetL; y < limit; y++) { var actor = jsonActorCache[y]; var anchor = - '' + - (actor.profile_path ? '' : '') + - '
    ' + - (type == "latest" ? '' + actor.character + '' : '' + actor.roles[0].character + '') + - '' + actor.name + '' + - '(c)TheMovieDB.org' + - '
    ' + - '
    '; - - castHTML += anchor + '\n'; + "" + + (actor.profile_path ? "" : "") + + "
    " + + (type == "latest" ? "" + actor.character + "" : "" + actor.roles[0].character + "") + + "" + actor.name + "" + + "(c)TheMovieDB.org" + + "
    " + + "
    "; + + castHTML += anchor + "\n"; } // Append the new batch of actors @@ -3634,7 +3682,7 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { } jsonActorCache = null; - $(".program-view-actors").html(''); + $(".program-view-actors").html(""); $(".program-view-actors").attr("data-actor-selected", type); var url; @@ -3648,28 +3696,28 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { actiX = 0; var details = JSON.parse(responseText); if (!details.cast || details.cast.length < 1) { - $(".program-view-actors").html('

    No cast information is available.

    '); + $(".program-view-actors").html("

    No cast information is available.

    "); return; } var cast = details.cast; jsonActorCache = cast; - var castHTML = ''; + var castHTML = ""; for (var b = 0; b < Math.min(10, cast.length); b++) { var actor = cast[b]; var anchor = - '' + - (actor.profile_path ? '' : '') + - '
    ' + - (type == "latest" ? '' + actor.character + '' : '' + actor.roles[0].character + '') + - '' + actor.name + '' + - '(c)TheMovieDB.org' + - '
    ' + - '
    '; - - castHTML += anchor + '\n'; + "" + + (actor.profile_path ? "" : "") + + "
    " + + (type == "latest" ? "" + actor.character + "" : "" + actor.roles[0].character + "") + + "" + actor.name + "" + + "(c)TheMovieDB.org" + + "
    " + + "
    "; + + castHTML += anchor + "\n"; } //When changing screen, not implemented yet @@ -3682,7 +3730,7 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { }, function () { actiX = 0; - }) + }); } function formatReleaseDate(air_date) { @@ -3732,10 +3780,10 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { var episodes = seasonData.episodes; if (!episodes.length && isUpcoming) { - $(".program-view-episodes>.episodes").html('No episodes are set to release on
    Streaming Video
    Check Schedule for upcoming TV airings.
    '); + $(".program-view-episodes>.episodes").html("No episodes are set to release on
    Streaming Video
    Check Schedule for upcoming TV airings.
    "); return; } else if (!episodes.length) { - $(".program-view-episodes>.episodes").html('No episodes are available in this
    season on either Streaming Video or live TV.
    '); + $(".program-view-episodes>.episodes").html("No episodes are available in this
    season on either Streaming Video or live TV.
    "); return; } @@ -3761,7 +3809,7 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { filteredEpisodes.push(episode); } - var seasonHTML = ''; + var seasonHTML = ""; var halfwayIndex = Math.floor(filteredEpisodes.length / 2); //Currently only handle 400 episodes @@ -3772,42 +3820,42 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { } for (var i = 0; i < filteredEpisodes.length; i++) { - var episode = filteredEpisodes[i]; - var parts = episode.air_date.split("-"); - var episodeDate = new Date(parts[0], parts[1] - 1, parts[2]); + episode = filteredEpisodes[i]; + parts = episode.air_date.split("-"); + episodeDate = new Date(parts[0], parts[1] - 1, parts[2]); episodeDate.setHours(0, 0, 0, 0); var timeString = formatReleaseDate(episode.air_date); var programName = program.name; - var anchor = '' + + var anchor = "" + (isUpcoming ? - '
    ' + - '' + timeString + '' + - '
    ' - : '') + - - (episode.still_path ? '' : '') + - '
    ' + - '' + programName + '' + - '' + episode.name + '' + - '' + "S" + episode.season_number + ":E" + episode.episode_number + - '' + - '
    ' + - '
    '; - - seasonHTML += anchor + '\n'; + "
    " + + "" + timeString + "" + + "
    " + : "") + + + (episode.still_path ? "" : "") + + "
    " + + "" + programName + "" + + "" + episode.name + "" + + "" + "S" + episode.season_number + ":E" + episode.episode_number + + "" + + "
    " + + ""; + + seasonHTML += anchor + "\n"; if (i === halfwayIndex - 1) { // Add
    after the first half - seasonHTML += '
    \n'; + seasonHTML += "
    \n"; } } - if (seasonHTML.trim() === '' && isUpcoming) { - $(".program-view-episodes>.episodes").html('No episodes are set to release on
    Streaming Video
    Check Schedule for upcoming TV airings.
    '); + if (seasonHTML.trim() === "" && isUpcoming) { + $(".program-view-episodes>.episodes").html("No episodes are set to release on
    Streaming Video
    Check Schedule for upcoming TV airings.
    "); return; } else { $(".program-view-episodes .episodes").html(seasonHTML); @@ -3816,20 +3864,19 @@ tvii.router.connect("^[?&]page=program_view(?:&|$)", function () { }, function (xhr) { epiX = 0; if (isUpcoming) { - $(".program-view-episodes>.episodes").html('This season does not have upcoming episodes on
    either Streaming Video or Live TV.
    '); + $(".program-view-episodes>.episodes").html("This season does not have upcoming episodes on
    either Streaming Video or Live TV.
    "); return; } else { - $(".program-view-episodes>.episodes").html('This season does not have available episodes on
    either Streaming Video or Live TV.
    '); + $(".program-view-episodes>.episodes").html("This season does not have available episodes on
    either Streaming Video or Live TV.
    "); return; } - return; }); } function setProgramEpisodesListeners() { tvii.utils.initTouchEffect(); - tvii.utils.initNaviConfirm($('.program-container .program.episode')); + tvii.utils.initNaviConfirm($(".program-container .program.episode")); $(".program-container .program.episode").each(function () { if (!$.data(this, "prgeCL")) { @@ -3853,36 +3900,36 @@ tvii.router.connect("^[?&]page=tvtags(?:&|$)", function () { $(".back-button").on("click", function () { vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); history.back(); - }) + }); $(".home-top").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); tvii.utils.changePage("?page=home", true); - }) + }); }); tvii.router.connect("^[?&]page=favorites(?:&|$)", function () { $(".back-button").on("click", function () { vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); history.back(); - }) + }); $(".home-top").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); tvii.utils.changePage("?page=home", true); - }) + }); }); tvii.router.connect("^[?&]page=movies(?:&|$)", function () { $(".back-button").on("click", function () { vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); history.back(); - }) + }); $(".home-top").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); tvii.utils.changePage("?page=home", true); - }) + }); }); @@ -3890,17 +3937,17 @@ tvii.router.connect("^[?&]page=tvtag_moment(?:&|$)", function () { $(".back-button").on("click", function () { vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); history.back(); - }) + }); $(".home-top").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); tvii.utils.changePage("?page=home", true); - }) + }); - tvii.utils.setUpHoverToEls($(".tvtag-container.moment-view .comments>.comment .meta>.yeah, .tvtag-container.moment-view .comments>.comment .meta>.reply")) + tvii.utils.setUpHoverToEls($(".tvtag-container.moment-view .comments>.comment .meta>.yeah, .tvtag-container.moment-view .comments>.comment .meta>.reply")); - var chatScroll = new tvii.utils.ScrollingContainer($('.tvtag-container.moment-view .container'), false); - var colorsScroll = new tvii.utils.ScrollingContainer($('.doodle-modal ul.colors'), false); + var chatScroll = new tvii.utils.ScrollingContainer($(".tvtag-container.moment-view .container"), false); + var colorsScroll = new tvii.utils.ScrollingContainer($(".doodle-modal ul.colors"), false); function setUpDoodleCanvas() { //canvas is drawing to canvas, canvaso is the final, and canvasx is the transparent canvas @@ -3913,33 +3960,33 @@ tvii.router.connect("^[?&]page=tvtag_moment(?:&|$)", function () { doodleImg, latestCanvas; var tool; - var latestCanvas = null; + latestCanvas = null; var previousCanvas = null; var undoStack = []; var redoStack = []; function init() { - finalBGCanvas = document.querySelector('canvas#final'); + finalBGCanvas = document.querySelector("canvas#final"); - finalBGCanvasContext = finalBGCanvas.getContext('2d'); + finalBGCanvasContext = finalBGCanvas.getContext("2d"); //canvas with all drawings var container = finalBGCanvas.parentNode; - finalDrawingCanvas = document.createElement('canvas'); - finalDrawingCanvas.id = 'doodle-final-canvas'; + finalDrawingCanvas = document.createElement("canvas"); + finalDrawingCanvas.id = "doodle-final-canvas"; finalDrawingCanvas.width = finalBGCanvas.width; finalDrawingCanvas.height = finalBGCanvas.height; - finalDrawingCanvasContext = finalDrawingCanvas.getContext('2d'); + finalDrawingCanvasContext = finalDrawingCanvas.getContext("2d"); finalDrawingCanvasContext.lineWidth = 3.0; finalDrawingCanvasContext.strokeStyle = "rgba(0,0,0,1)"; //canvas with temp drawings - initialTempCanvas = document.createElement('canvas'); - initialTempCanvas.id = 'doodle-temp-canvas'; + initialTempCanvas = document.createElement("canvas"); + initialTempCanvas.id = "doodle-temp-canvas"; initialTempCanvas.width = finalBGCanvas.width; initialTempCanvas.height = finalBGCanvas.height; @@ -3948,14 +3995,14 @@ tvii.router.connect("^[?&]page=tvtag_moment(?:&|$)", function () { container.appendChild(initialTempCanvas); //Make all drawings happen on inital canvas, we later copy the drawing to the final drawing canvas - initialTempCanvasContext = initialTempCanvas.getContext('2d'); + initialTempCanvasContext = initialTempCanvas.getContext("2d"); initialTempCanvasContext.strokeStyle = "#af0000"; initialTempCanvasContext.lineWidth = 3.0; - initialTempCanvas.addEventListener('mousedown', ev_canvas, false); - initialTempCanvas.addEventListener('mousemove', ev_canvas, false); - initialTempCanvas.addEventListener('mouseup', ev_canvas, false); - initialTempCanvas.addEventListener('mousedown', untoggle, false); + initialTempCanvas.addEventListener("mousedown", ev_canvas, false); + initialTempCanvas.addEventListener("mousemove", ev_canvas, false); + initialTempCanvas.addEventListener("mouseup", ev_canvas, false); + initialTempCanvas.addEventListener("mousedown", untoggle, false); } var tools = {}; @@ -3967,7 +4014,7 @@ tvii.router.connect("^[?&]page=tvtag_moment(?:&|$)", function () { this.mousedown = function (ev) { initialTempCanvasContext.beginPath(); initialTempCanvasContext.lineJoin = "round"; - finalDrawingCanvasContext.globalCompositeOperation = 'source-over'; + finalDrawingCanvasContext.globalCompositeOperation = "source-over"; initialTempCanvasContext.moveTo(ev._x, ev._y); tool.started = true; }; @@ -3993,7 +4040,7 @@ tvii.router.connect("^[?&]page=tvtag_moment(?:&|$)", function () { this.mousedown = function (ev) { finalDrawingCanvasContext.beginPath(); finalDrawingCanvasContext.lineJoin = "round"; - finalDrawingCanvasContext.globalCompositeOperation = 'destination-out'; + finalDrawingCanvasContext.globalCompositeOperation = "destination-out"; finalDrawingCanvasContext.moveTo(ev._x, ev._y); tool.started = true; }; @@ -4086,7 +4133,7 @@ tvii.router.connect("^[?&]page=tvtag_moment(?:&|$)", function () { $(".back-button").addClass("none"); $(".remote-button").addClass("none"); $(".doodle-modal").removeClass("none"); - }) + }); $(".exit-doodle").on("click", function () { vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); @@ -4107,16 +4154,16 @@ tvii.router.connect("^[?&]page=tvtag_moment(?:&|$)", function () { vino.soundPlay("SE_A_CHECK_TOUCH_OFF"); $(".doodle-modal ul.colors li a").removeClass("selected"); $(this).addClass("selected"); - changeColor("#" + $(this).attr('id')); - }) + changeColor("#" + $(this).attr("id")); + }); $(".doodle-modal ul:not(.colors) li a:not(.dropdown-menu a)").on("click", function () { vino.soundPlay("SE_A_TAB_TOUCH_OFF"); - }) + }); $(".doodle-modal ul.colors").on("scroll", function () { untoggle(); - }) + }); $(".doodle-modal ul li a.clear").on("click", function () { var c = $(this); @@ -4124,8 +4171,8 @@ tvii.router.connect("^[?&]page=tvtag_moment(?:&|$)", function () { setTimeout(function () { cleanMomentDrawAndRedraw(); c.removeClass("selected"); - }, 300) - }) + }, 300); + }); /*$(".doodle-modal ul li a.undo").on("click", function () { restoreLatestCanvas(); @@ -4146,7 +4193,7 @@ tvii.router.connect("^[?&]page=tvtag_moment(?:&|$)", function () { $(this).addClass("selected"); changeStrokeSize(parseInt($(this).attr("data-stroke")), 10); untoggle(); - }) + }); $(".doodle-modal .dropdown-menu.eraser-size a").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); @@ -4159,7 +4206,7 @@ tvii.router.connect("^[?&]page=tvtag_moment(?:&|$)", function () { $(this).addClass("selected"); changeEraserStrokeSize(parseInt($(this).attr("data-stroke")), 10); untoggle(); - }) + }); $(".doodle-modal ul.colors li a.input-hex input").on("change", function () { if (!$(".doodle-modal ul li a.pencil").hasClass("selected")) { @@ -4173,7 +4220,7 @@ tvii.router.connect("^[?&]page=tvtag_moment(?:&|$)", function () { changeColor($(this).val()); untoggle(); vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); - }) + }); //Set up $(".doodle-modal ul.colors li a").first().addClass("selected"); @@ -4194,14 +4241,14 @@ tvii.router.connect("^[?&]page=tvtag_moment(?:&|$)", function () { $(".tvtag-container.moment-view .comments>.comment .meta>.reply").on("click", function () { $(this).focus(); vino.wakeKeyboard(); - }) + }); var fc = $(".tvtag-container.moment-view .comments>.comment:first-child"); var fch = fc.outerHeight(true); - $('.tvtag-container.moment-view .container').animate({ - scrollTop: fch + $(".tvtag-container.moment-view .container").animate({ + scrollTop: fch, }, 500); } @@ -4214,43 +4261,44 @@ tvii.router.connect("^[?&]page=tvtag_tagline(?:&|$)", function () { $(".back-button").on("click", function () { vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); history.back(); - }) + }); $(".home-top").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); tvii.utils.changePage("?page=home", true); - }) + }); - var taglineScroll = new tvii.utils.ScrollingContainer($('.tvtag-container .container'), false); - var stationsScroll = new tvii.utils.ScrollingContainer($('.tvtag-container .tvtag-menu #tune-stations .dropdown-menu'), false); + var taglineScroll = new tvii.utils.ScrollingContainer($(".tvtag-container .container"), false); + var stationsScroll = new tvii.utils.ScrollingContainer($(".tvtag-container .tvtag-menu #tune-stations .dropdown-menu"), false); tvii.utils.initToggle(); var episode; var program; if (tvii.utils.getQuery("episode_id", true) != null && tvii.utils.getQuery("program_id", true) != null) { - console.log("Query exists") + console.log("Query exists"); episode = tvii.utils.getQuery("episode_id", true); program = tvii.utils.getQuery("program_id", true); requestTagline(); } else { + return; } function requestTagline() { tvii.utils.sendXHR("GET", tvii.url.TV_TAG_TAGLINE(program, episode), function (text) { var response = JSON.parse(text); - console.log(response) + console.log(response); }, function (err) { - }) + }); } //Canvas test function initProgramLeftToEnd(startTime, duration, callbackOnEnd) { - var canvas = document.getElementById('time-left-endtime'); - var ctx = canvas.getContext('2d'); + var canvas = document.getElementById("time-left-endtime"); + var ctx = canvas.getContext("2d"); var canvasSize = 34; var totalDuration = duration * 1000; // Convert duration to milliseconds var fps = 60; // Frames per second @@ -4280,19 +4328,19 @@ tvii.router.connect("^[?&]page=tvtag_tagline(?:&|$)", function () { if (hours > 0) { // Return h:m:s format - return hours + ':' + - (minutes < 10 ? '0' + minutes : minutes) + ':' + - (seconds < 10 ? '0' + seconds : seconds); + return hours + ":" + + (minutes < 10 ? "0" + minutes : minutes) + ":" + + (seconds < 10 ? "0" + seconds : seconds); } else { // Return m:s format - return minutes + ':' + - (seconds < 10 ? '0' + seconds : seconds); + return minutes + ":" + + (seconds < 10 ? "0" + seconds : seconds); } } // Update the span element with the remaining time function updateTimeSpan() { - var timeSpanElement = document.getElementById('time-left-span'); + var timeSpanElement = document.getElementById("time-left-span"); if (isStarted) { var elapsedTime = getElapsedTime(); @@ -4306,10 +4354,10 @@ tvii.router.connect("^[?&]page=tvtag_tagline(?:&|$)", function () { var formattedTime = formatTime(remainingTime); timeSpanElement.textContent = formattedTime; } else { - var remainingTime = getTimeUntilStart(); - var formattedTime = formatTime(remainingTime); + remainingTime = getTimeUntilStart(); + formattedTime = formatTime(remainingTime); if (timeSpanElement != null) { - timeSpanElement.textContent = '-' + formattedTime; // Prepend "-" when before start time + timeSpanElement.textContent = "-" + formattedTime; // Prepend "-" when before start time } } } @@ -4321,7 +4369,7 @@ tvii.router.connect("^[?&]page=tvtag_tagline(?:&|$)", function () { ctx.beginPath(); ctx.moveTo(canvasSize / 2, canvasSize / 2); // Move to the center of the canvas ctx.arc(canvasSize / 2, canvasSize / 2, canvasSize / 2, startAngle, endAngle); // Draw arc - ctx.fillStyle = 'white'; + ctx.fillStyle = "white"; ctx.fill(); ctx.closePath(); } @@ -4340,7 +4388,7 @@ tvii.router.connect("^[?&]page=tvtag_tagline(?:&|$)", function () { if (isStarted && progress >= 1) { clearInterval(tvii.tvTagProgramLeftInterval); - document.getElementById('time-left-span').textContent = '00:00'; + document.getElementById("time-left-span").textContent = "00:00"; callbackOnEnd(); } } @@ -4383,15 +4431,15 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { tvii.utils.initTabs(); tvii.utils.initToggle(); - var showScroll = new tvii.utils.ScrollingContainer($('.program-container'), true); - var guideScroll = new tvii.utils.ScrollingContainer($('.tv-guide-container .guide-content'), 4); + var showScroll = new tvii.utils.ScrollingContainer($(".program-container"), true); + var guideScroll = new tvii.utils.ScrollingContainer($(".tv-guide-container .guide-content"), 4); var strCount = 1; var isRequesting = false; var pstateScrollX = 0; $(document).on("tvii:tabchange", function (event, tab) { checkTab(tab.attr("data-section")); - }) + }); guideScroll.scrCont.on("scrolling", function () { var y = guideScroll.scrCont.scrollTop(); @@ -4424,16 +4472,16 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { //If did go back, then tab query should already exist if (tvii.utils.getQuery("tab", true) != null) { - console.log("Query exists") - var query = tvii.utils.getQuery("tab", true); + console.log("Query exists"); + query = tvii.utils.getQuery("tab", true); - var tab = $('[data-section="' + query + '"]'); + var tab = $("[data-section=\"" + query + "\"]"); var dropdown = tab.parent().parent().parent(); tvii.utils.triggerToggleByOption(dropdown, tab); } else { - tvii.utils.triggerToggleByOption($("#live-tv-dropdown"), $('[data-section="now"]')); + tvii.utils.triggerToggleByOption($("#live-tv-dropdown"), $("[data-section=\"now\"]")); } @@ -4441,13 +4489,13 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { vino.soundPlay("SE_A_CLOSE_TOUCH_OFF"); clearProgramContainerCache(); history.back(); - }) + }); $(".home-top").on("click", function () { vino.soundPlay("SE_A_DECIDE_TOUCH_OFF"); clearProgramContainerCache(); tvii.utils.changePage("?page=home", true); - }) + }); function getTodayDate() { var today = new Date(); @@ -4457,10 +4505,10 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { // Function to ensure two digits function twoDigits(value) { - return value < 10 ? '0' + value : value; + return value < 10 ? "0" + value : value; } - return year + '-' + twoDigits(month) + '-' + twoDigits(day); + return year + "-" + twoDigits(month) + "-" + twoDigits(day); } function getYesterdayDate() { @@ -4475,10 +4523,10 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { // Function to ensure two digits function twoDigits(value) { - return value < 10 ? '0' + value : value; + return value < 10 ? "0" + value : value; } - return year + '-' + twoDigits(month) + '-' + twoDigits(day); + return year + "-" + twoDigits(month) + "-" + twoDigits(day); } function getDate30DaysBeforeToday() { @@ -4490,10 +4538,10 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { // Function to ensure two digits function twoDigits(value) { - return value < 10 ? '0' + value : value; + return value < 10 ? "0" + value : value; } - return year + '-' + twoDigits(month) + '-' + twoDigits(day); + return year + "-" + twoDigits(month) + "-" + twoDigits(day); } function getDate30DaysFromToday() { @@ -4508,10 +4556,10 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { // Function to ensure two digits function twoDigits(value) { - return value < 10 ? '0' + value : value; + return value < 10 ? "0" + value : value; } - return year + '-' + twoDigits(month) + '-' + twoDigits(day); + return year + "-" + twoDigits(month) + "-" + twoDigits(day); } function setProgramContainerCache() { @@ -4523,11 +4571,11 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { var cache = { html: $(".program-container").html(), - scrollmore_query: $('.program-container').attr("data-scrollmore-query"), - scrollmore_type: $('.program-container').attr("data-scrollmore-type"), - scrollmore_finish: $('.program-container').attr("data-scrollmore-finish"), - page: strCount - } + scrollmore_query: $(".program-container").attr("data-scrollmore-query"), + scrollmore_type: $(".program-container").attr("data-scrollmore-type"), + scrollmore_finish: $(".program-container").attr("data-scrollmore-finish"), + page: strCount, + }; sessionStorage.setItem("program-container", JSON.stringify(cache)); } @@ -4557,7 +4605,7 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { var c = sessionStorage.getItem("program-container"); if (c != null) { var j = new Jamiroquai; - return j.isReturnOfTheSpaceCowboy() + return j.isReturnOfTheSpaceCowboy(); } return false; } @@ -4571,7 +4619,7 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { function setProgramListeners() { tvii.utils.initTouchEffect(); - tvii.utils.initNaviConfirm($('.program-container .program')); + tvii.utils.initNaviConfirm($(".program-container .program")); $(".program-container .program").each(function () { if (!$.data(this, "prgcL")) { @@ -4594,9 +4642,9 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { tvii.utils.replacePageQuery("tab", tab); strCount = 1; - $('.program-container').removeAttr("data-scrollmore-query"); - $('.program-container').removeAttr("data-scrollmore-type"); - $('.program-container').removeAttr("data-scrollmore-finish"); + $(".program-container").removeAttr("data-scrollmore-query"); + $(".program-container").removeAttr("data-scrollmore-type"); + $(".program-container").removeAttr("data-scrollmore-finish"); if (isProgramContainerCacheAvailable()) { restoreProgramContainerCache(); @@ -4604,20 +4652,20 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { } switch (tab) { case "now": - console.log("hi") + console.log("hi"); requestLivePrograms("?date=" + ""); break; case "30min": requestLivePrograms("?date=" + ""); break; case "1hr": - requestLivePrograms() + requestLivePrograms(); break; case "grid": requestTVGrid(); break; case "friends-live": - requestLivePrograms() + requestLivePrograms(); break; case "trending-next": requestStreamingPrograms("&watch_region=" + vino.info_getCountry() + "&air_date.gte=" + getTodayDate() + "&air_date.lte=" + getDate30DaysFromToday() + "&screened_theatrically=false&with_watch_providers=8|9|390|2&sort_by=popularity.asc"); @@ -4629,7 +4677,7 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { requestStreamingPrograms("&watch_region=" + vino.info_getCountry() + "&screened_theatrically=false&with_watch_providers=8|9|390|2&sort_by=vote_average.desc&vote_count.gte=200"); break; case "friends-streaming": - requestLivePrograms() + requestLivePrograms(); break; default: break; @@ -4637,7 +4685,7 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { } function requestTVGrid() { - $('.program-container').addClass("none"); + $(".program-container").addClass("none"); $(".tv-guide-container").removeClass("none"); //Placeholder data until we implement login @@ -4716,7 +4764,7 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { finishGridRequest(); } } - } + }; //Checks if we are in DST to use Zap2Its time offset per zip code (their guides are in a hardcoded timezone, we need this.) function getTimezoneOffset() { @@ -4735,8 +4783,8 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { currentDate.getUTCDate(), currentDate.getUTCHours(), currentDate.getUTCMinutes(), - currentDate.getUTCSeconds() - ) + currentDate.getUTCSeconds(), + ), ); // Check if the current UTC date is within the DST period @@ -4827,14 +4875,14 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { var minutes = date.getMinutes(); // Determine AM/PM and convert to 12-hour format - var period = (hours >= 12) ? 'PM' : 'AM'; + var period = (hours >= 12) ? "PM" : "AM"; hours = hours % 12; hours = (hours === 0) ? 12 : hours; // Convert 0 hours to 12 for AM/PM format // Format minutes to always be 2 digits - var formattedMinutes = (minutes < 10) ? '0' + minutes : minutes; + var formattedMinutes = (minutes < 10) ? "0" + minutes : minutes; - return hours + ':' + formattedMinutes + ' ' + period; + return hours + ":" + formattedMinutes + " " + period; } //Clear guide before re-requesting @@ -4853,101 +4901,101 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { getUnixStartDateForGuide(hourToStartGuide), userProvider.pref), - function (responseText) { - var guide = JSON.parse(responseText); - var channels = guide.channels; + function (responseText) { + var guide = JSON.parse(responseText); + var channels = guide.channels; - var mins = timespan * 2; - var initialTime = formatGuideStartTime(hourToStartGuide); + var mins = timespan * 2; + var initialTime = formatGuideStartTime(hourToStartGuide); - var todayDiv = $('').text("Today"); - $(".tv-guide-container .hours").append(todayDiv); + var todayDiv = $("").text("Today"); + $(".tv-guide-container .hours").append(todayDiv); - for (var r = 0; r < mins; r++) { - var formattedTime = formatTimeForGuideStart(initialTime); - var timeDiv = $('').text(formattedTime); + for (var r = 0; r < mins; r++) { + var formattedTime = formatTimeForGuideStart(initialTime); + var timeDiv = $("").text(formattedTime); - // Append the time div to the container - $(".tv-guide-container .hours").append(timeDiv); + // Append the time div to the container + $(".tv-guide-container .hours").append(timeDiv); - // Increment the time by 30 minutes for the next iteration - initialTime.setMinutes(initialTime.getMinutes() + 30); - } + // Increment the time by 30 minutes for the next iteration + initialTime.setMinutes(initialTime.getMinutes() + 30); + } - // Loop through channels and append to the guide - //Handle 50 channels for now - for (var i = 0; i < 50; i++) { - var chaA = $(""); - chaA.text(channels[i].callSign + " " + channels[i].channelNo); - $(".tv-guide-container .channels").append(chaA); + // Loop through channels and append to the guide + //Handle 50 channels for now + for (var i = 0; i < 50; i++) { + var chaA = $(""); + chaA.text(channels[i].callSign + " " + channels[i].channelNo); + $(".tv-guide-container .channels").append(chaA); - var chAList = $("
    "); - var programs = channels[i].events; + var chAList = $("
    "); + var programs = channels[i].events; - for (var y = 0; y < programs.length; y++) { - var pA = $(""); - var pASh = $("

    "); - var pAEn = $(""); + for (var y = 0; y < programs.length; y++) { + var pA = $(""); + var pASh = $("

    "); + var pAEn = $(""); - var duration = parseInt(programs[y].duration, 10); - var startTime = programs[y].startTime; - var endTime = programs[y].endTime; + var duration = parseInt(programs[y].duration, 10); + var startTime = programs[y].startTime; + var endTime = programs[y].endTime; - var adjustedStartTime = adjustProgramDateByOffset(startTime); - var adjustedEndTime = adjustProgramDateByOffset(endTime); + var adjustedStartTime = adjustProgramDateByOffset(startTime); + var adjustedEndTime = adjustProgramDateByOffset(endTime); - var adjustedGuideStartTime = formatGuideStartTimeUTC(hourToStartGuide); + var adjustedGuideStartTime = formatGuideStartTimeUTC(hourToStartGuide); - var startDifference = adjustedStartTime.getTime() - adjustedGuideStartTime.getTime(); + var startDifference = adjustedStartTime.getTime() - adjustedGuideStartTime.getTime(); - // Convert the difference to minutes - var differenceInMinutes = Math.floor(startDifference / (1000 * 60)); + // Convert the difference to minutes + var differenceInMinutes = Math.floor(startDifference / (1000 * 60)); - if (differenceInMinutes < 0) { // Change this condition to check for negative difference - // Program starts before the guide starts - duration = Math.max(0, duration + differenceInMinutes); // Adjust duration correctly - } + if (differenceInMinutes < 0) { // Change this condition to check for negative difference + // Program starts before the guide starts + duration = Math.max(0, duration + differenceInMinutes); // Adjust duration correctly + } - if (y === 0) { - console.log("Adjusted Program:", programs[y].program.title); - console.log("Duration:", duration) - console.log("Adjusted OG Start Time:", startTime); - console.log("Adjusted Start Time:", adjustedStartTime); - console.log("Guide Start Date:", adjustedGuideStartTime) - console.log("Adjusted Difference:", differenceInMinutes) - } + if (y === 0) { + console.log("Adjusted Program:", programs[y].program.title); + console.log("Duration:", duration); + console.log("Adjusted OG Start Time:", startTime); + console.log("Adjusted Start Time:", adjustedStartTime); + console.log("Guide Start Date:", adjustedGuideStartTime); + console.log("Adjusted Difference:", differenceInMinutes); + } - /*console.log(adjustProgramDateByOffset(startTime))*/ + /*console.log(adjustProgramDateByOffset(startTime))*/ - pASh.text(programs[y].program.title); - if (programs[y].program.episodeTitle != null) { - pAEn.text(programs[y].program.episodeTitle); - } else { - pAEn.text(""); - pA.addClass("noep"); - } + pASh.text(programs[y].program.title); + if (programs[y].program.episodeTitle != null) { + pAEn.text(programs[y].program.episodeTitle); + } else { + pAEn.text(""); + pA.addClass("noep"); + } - if (programs[y].flag.length) { - if (programs[y].flag.indexOf("New") !== -1) { - pA.addClass("new"); - } + if (programs[y].flag.length) { + if (programs[y].flag.indexOf("New") !== -1) { + pA.addClass("new"); } - - var pixelsPerMinute = 180 / 30; // 6 pixels per minute - var programWidth = duration * pixelsPerMinute; - pA.css("width", programWidth + "px"); - - pA.append(pASh); - pA.append(pAEn); - chAList.append(pA); } - $(".tv-guide-container .guide-content").append(chAList); + var pixelsPerMinute = 180 / 30; // 6 pixels per minute + var programWidth = duration * pixelsPerMinute; + pA.css("width", programWidth + "px"); + + pA.append(pASh); + pA.append(pAEn); + chAList.append(pA); } + $(".tv-guide-container .guide-content").append(chAList); + } + - }, function (xhr) { - }) + }, function (xhr) { + }); } } @@ -4955,19 +5003,19 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { $(".tv-guide-container").addClass("none"); $(".program-container").removeClass("none"); - if (isRequesting || $('.program-container').attr("data-scrollmore-finish") && $('.program-container').attr("data-scrollmore-finish") == "1") { + if (isRequesting || $(".program-container").attr("data-scrollmore-finish") && $(".program-container").attr("data-scrollmore-finish") == "1") { return; } isRequesting = true; if (!isOffset) { - $('.program-container').html(""); + $(".program-container").html(""); } if (isOffset) { - var firstHalfHTML = ''; - var secondHalfHTML = ''; + var firstHalfHTML = ""; + var secondHalfHTML = ""; } tvii.utils.sendXHR("GET", tvii.url.DISCOVER(true, query), function (responseText) { @@ -4983,11 +5031,11 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { if (!results.length || page > pages_length) { isRequesting = false; if (page > pages_length) { - $('.program-container').attr("data-scrollmore-finish", "1"); + $(".program-container").attr("data-scrollmore-finish", "1"); } return; } - var resultHTML = ''; + var resultHTML = ""; var halfwayIndex = Math.floor(results.length / 2); for (var i = 0; i < results.length; i++) { @@ -4996,50 +5044,50 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { var name = results[i].name; var id = results[i].id; - var anchor = '' + - (backdrop_path ? '' : '') + - '
    ' + - '' + name + '' + - '' + - '' + - '
    ' + - '
    '; + var anchor = "" + + (backdrop_path ? "" : "") + + "
    " + + "" + name + "" + + "" + + "" + + "
    " + + "
    "; if (isOffset) { if (i < halfwayIndex) { - firstHalfHTML += anchor + '\n'; + firstHalfHTML += anchor + "\n"; } else { - secondHalfHTML += anchor + '\n'; + secondHalfHTML += anchor + "\n"; } } else { - resultHTML += anchor + '\n'; + resultHTML += anchor + "\n"; if (i === halfwayIndex - 1) { - resultHTML += '
    \n'; + resultHTML += "
    \n"; } } } - if (!$('.program-container').attr("data-scrollmore-query")) { - $('.program-container').attr("data-scrollmore-query", query + "&page=" + strCount); + if (!$(".program-container").attr("data-scrollmore-query")) { + $(".program-container").attr("data-scrollmore-query", query + "&page=" + strCount); } else { var regex = /(&page=)[^&]*/; - if (regex.test($('.program-container').attr("data-scrollmore-query"))) { - var at = $('.program-container').attr("data-scrollmore-query").replace(regex, '$1' + strCount); - $('.program-container').attr("data-scrollmore-query", at); + if (regex.test($(".program-container").attr("data-scrollmore-query"))) { + var at = $(".program-container").attr("data-scrollmore-query").replace(regex, "$1" + strCount); + $(".program-container").attr("data-scrollmore-query", at); } } - $('.program-container').attr("data-scrollmore-type", "streaming"); - $('.program-container').attr("data-scrollmore-finish", "0"); + $(".program-container").attr("data-scrollmore-type", "streaming"); + $(".program-container").attr("data-scrollmore-finish", "0"); if (isOffset) { var $container = $(".program-container"); - var $br = $container.find('br'); - var $searchBefore = $(".program-container a:last-child") + var $br = $container.find("br"); + var $searchBefore = $(".program-container a:last-child"); var elementsBeforeBr = $br.prevAll().length; var elementsAfterBr = $br.nextAll().length; @@ -5050,7 +5098,7 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { $searchBefore.after(secondHalfHTML); } else { - $('.program-container').html(resultHTML); + $(".program-container").html(resultHTML); } if (pstateScrollX) { @@ -5063,7 +5111,7 @@ tvii.router.connect("^[?&]page=tv(?:&|$)", function () { isRequesting = false; }, function (xhr) { isRequesting = false; - }) + }); } function requestLivePrograms(query, isOffset) { diff --git a/src/routes/api/data.ts b/src/routes/api/data.ts index 2f3927e..1ee0412 100644 --- a/src/routes/api/data.ts +++ b/src/routes/api/data.ts @@ -1,61 +1,112 @@ import express, { Request, Response } from "express"; +import NodeCache from "node-cache"; //cache import fetch from "node-fetch"; // fetch polyfill for node import sharp from "sharp"; import dayjs from "dayjs"; import { createWhitePixel, fixCountryCode, handleTMDBProvider, handleApiResponse, getDGRegion } from "../../utils/getData.js"; import { logger } from "../../utils/logger.js"; import { env } from "../../env.js"; +import { URL, URLSearchParams } from "url"; const router = express.Router(); const tmdbApiKey = `Bearer ${env.TMDB_ACCESS_TOKEN}`; // Get this from TheMovieDB developers page (https://developers.themoviedb.org/) const mainApiUrl = env.TIVO_API_URL; // Secret value 🤫 (for this dm @ItzSwirlz or @SkyeDoesThings on Discord) +const imageCache = new NodeCache({ stdTTL: 1209600 }); /** - * [GET] /api/v1/data/image - Image proxy + * [GET] /api/v1/data/image.webp - Image proxy * * Proxies and resizes images under our domain + * TODO: Test if TVii supports webp images */ -router.get("/image", async (req: Request, res: Response) => { - const imageUrl = req.query.url as string; // The image to proxy - const width = parseInt(req.query.width as string, 10) || 1; // The width you want to resize the image to +router.get("/image.webp", async (req: Request, res: Response) => { + const query = req.query as Record; + const width = parseInt(query.w as string, 10) || 1; // The width to resize the image to - // sends a white pixel + // Sends a white pixel const sendWhitePixel = async () => { try { const buffer = await createWhitePixel(); - res.status(400).contentType("image/png").send(buffer); + res.status(400) + .set("Cache-Control", "no-store") // Prevent caching for error responses + .contentType("image/webp") + .send(buffer); } catch (e) { logger.error(`Error generating white pixel: ${e}`); res.status(500).send("Invalid image provided."); } }; - if (!imageUrl) { + if (!query.url) { await sendWhitePixel(); return; } try { - if (width > 10000) throw new Error("Width too large"); // Somewhere around here I was getting a segfault error (also it just takes for ever to load past like 9k) + const cacheKey = `${query.url}|w=${width}`; + const cachedImage = imageCache.get(cacheKey); + + if (cachedImage) { + res.set({ + "Content-Type": "image/webp", + "Cache-Control": "public, max-age=1209600", // Inform client it's cacheable + }).send(cachedImage); + return; + } + + const baseUrl = new URL(query.url); + const newQueryParams = new URLSearchParams(baseUrl.search); + + for (const [key, value] of Object.entries(query)) { + if (key !== "w" && key !== "url") { + newQueryParams.set(key, value); + } + } + + baseUrl.search = newQueryParams.toString(); + + query.url = baseUrl.toString(); - const imgRes = await fetch(imageUrl); + if (width > 10000) throw new Error("Width too large"); + + const imgRes = await fetch(query.url); if (!imgRes.ok || !imgRes.headers.get("content-type")?.startsWith("image/")) { throw new Error(`Invalid image URL or content type: ${imgRes.statusText}`); } - const contentType = imgRes.headers.get("content-type") || "image/png"; + const contentType = imgRes.headers.get("content-type") || "image/webp"; const imageBuffer = Buffer.from(await imgRes.arrayBuffer()); let processedBuffer = imageBuffer; if (width > 0) { processedBuffer = await sharp(imageBuffer) - .resize(width) - .toFormat("png") + .resize(width, null, { + withoutEnlargement: true, + fit: "inside", + }) + .toFormat("webp") + .webp({ + quality: 75, + effort: 6, + lossless: false, + nearLossless: false, + smartSubsample: true, + alphaQuality: 80, + mixed: true, + }) .toBuffer(); + // debug + //logger.info(`Original size: ${imageBuffer.length / 1024}KB, Processed size: ${processedBuffer.length / 1024}KB`); } - res.set("Content-Type", contentType).send(processedBuffer); + // Cache the processed image + imageCache.set(cacheKey, processedBuffer); + + res.set({ + "Content-Type": contentType, + "Cache-Control": "public, max-age=1209600", // Inform client it's cacheable + }).send(processedBuffer); } catch (e) { logger.error(`Error fetching or processing image: ${e}`); await sendWhitePixel(); diff --git a/src/routes/api/miis.ts b/src/routes/api/miis.ts new file mode 100644 index 0000000..4661fbc --- /dev/null +++ b/src/routes/api/miis.ts @@ -0,0 +1,139 @@ +import express, { type Request, type Response } from "express"; +import fetch from "node-fetch"; +import NodeCache from "node-cache"; +import sharp from "sharp"; +import { logger } from "../../utils/logger.js"; +import { createWhitePixel } from "../../utils/getData.js"; + +interface MiiDataResponse { + data: string; +} + +const router = express.Router(); +const imageCache = new NodeCache({ stdTTL: 1209600 }); +const arianMiiUrl = "https://mii-unsecure.ariankordi.net"; + +router.get("/:principalId/:image", async (req: Request, res: Response) => { + const sendWhitePixel = async () => { + try { + const buffer = await createWhitePixel(); + res.status(400) + .set("Cache-Control", "no-store") + .contentType("image/webp") + .send(buffer); + } catch (e) { + logger.error(`Error generating white pixel: ${e}`); + res.status(500).send("Invalid image provided."); + } + }; + + try { + const { principalId, image } = req.params; + const refresh = req.query.refresh || "0"; + const width = parseInt(req.query.w as string, 10) || 600; + + const cacheKey = `${principalId}/${image}`; + if (refresh !== "1") { + const cachedImage = imageCache.get(cacheKey); + if (cachedImage) { + res.set({ + "Content-Type": "image/webp", + "Cache-Control": "public, max-age=1209600", // Cacheable for clients + }).send(cachedImage); + return; + } + } + + const miiDataResponse = await fetch( + `${arianMiiUrl}/mii_data/?pid=${principalId}&api_id=1`, + ); + if (!miiDataResponse.ok) { + res.status(500).json({ error: "Failed to fetch Mii data" }); + return; + } + + const miiDataJson = await miiDataResponse.json() as MiiDataResponse; + const miiData = miiDataJson.data; + + let url: string | undefined; + + switch (image) { + case "body_happy_face.webp": + url = `${arianMiiUrl}/miis/image.png?api_id=1&data=${encodeURIComponent(miiData)}&force_refresh=${refresh}&shaderType=wiiu_blinn&type=all_body_sugar&expression=smile_open_mouth&width=600&bodyType=wiiu`; + break; + case "portrait_happy_face.webp": + url = `${arianMiiUrl}/miis/image.png?api_id=1&data=${encodeURIComponent(miiData)}&force_refresh=${refresh}&shaderType=wiiu_blinn&type=face&expression=smile_open_mouth&width=600&bodyType=wiiu`; + break; + case "body_like_face.webp": + url = `${arianMiiUrl}/miis/image.png?api_id=1&data=${encodeURIComponent(miiData)}&force_refresh=${refresh}&shaderType=wiiu_blinn&type=all_body_sugar&expression=like_wink_left&width=600&bodyType=wiiu`; + break; + case "portrait_like_face.webp": + url = `${arianMiiUrl}/miis/image.png?api_id=1&data=${encodeURIComponent(miiData)}&force_refresh=${refresh}&shaderType=wiiu_blinn&type=face&expression=like_wink_left&width=600&bodyType=wiiu`; + break; + case "body_surprised_face.webp": + url = `${arianMiiUrl}/miis/image.png?api_id=1&data=${encodeURIComponent(miiData)}&force_refresh=${refresh}&shaderType=wiiu_blinn&type=all_body_sugar&expression=surprise_open_mouth&width=600&bodyType=wiiu`; + break; + case "portrait_surprised_face.webp": + url = `${arianMiiUrl}/miis/image.png?api_id=1&data=${encodeURIComponent(miiData)}&force_refresh=${refresh}&shaderType=wiiu_blinn&type=face&expression=surprise_open_mouth&width=600&bodyType=wiiu`; + break; + case "body_frustrated_face.webp": + url = `${arianMiiUrl}/miis/image.png?api_id=1&data=${encodeURIComponent(miiData)}&force_refresh=${refresh}&shaderType=wiiu_blinn&type=all_body_sugar&expression=frustrated&width=600&bodyType=wiiu`; + break; + case "portrait_frustrated_face.webp": + url = `${arianMiiUrl}/miis/image.png?api_id=1&data=${encodeURIComponent(miiData)}&force_refresh=${refresh}&shaderType=wiiu_blinn&type=face&expression=frustrated&width=600&bodyType=wiiu`; + break; + case "body_puzzled_face.webp": + url = `${arianMiiUrl}/miis/image.png?api_id=1&data=${encodeURIComponent(miiData)}&force_refresh=${refresh}&shaderType=wiiu_blinn&type=all_body_sugar&expression=sorrow&width=600&bodyType=wiiu`; + break; + case "portrait_puzzled_face.webp": + url = `${arianMiiUrl}/miis/image.png?api_id=1&data=${encodeURIComponent(miiData)}&force_refresh=${refresh}&shaderType=wiiu_blinn&type=face&expression=sorrow&width=600&bodyType=wiiu`; + break; + case "body_normal_face.webp": + url = `${arianMiiUrl}/miis/image.png?api_id=1&data=${encodeURIComponent(miiData)}&force_refresh=${refresh}&shaderType=wiiu_blinn&type=all_body_sugar&expression=normal&width=600&bodyType=wiiu`; + break; + case "portrait_normal_face.webp": + url = `${arianMiiUrl}/miis/image.png?api_id=1&data=${encodeURIComponent(miiData)}&force_refresh=${refresh}&shaderType=wiiu_blinn&type=face&expression=normal&width=600&bodyType=wiiu`; + break; + default: + await sendWhitePixel(); + return; + } + + const miiImageResponse = await fetch(url); + if (!miiImageResponse.ok) { + await sendWhitePixel(); + return; + } + + const imageBuffer = Buffer.from(await miiImageResponse.arrayBuffer()); + let processedBuffer = await sharp(imageBuffer) + .resize(width, null, { + withoutEnlargement: true, + fit: "inside", + }) + .toFormat("webp") + .webp({ + quality: 75, + effort: 6, + lossless: false, + nearLossless: false, + smartSubsample: true, + alphaQuality: 80, + mixed: true, + }) + .toBuffer(); + + imageCache.set(cacheKey, processedBuffer); + + res.set({ + "Content-Type": "image/webp", + "Cache-Control": "public, max-age=1209600", + }).send(processedBuffer); + } catch (e) { + logger.error(String(e)); + await sendWhitePixel(); + } +}); + + +export { router as miis }; diff --git a/src/routes/exports.ts b/src/routes/exports.ts index de91831..0ebf68a 100644 --- a/src/routes/exports.ts +++ b/src/routes/exports.ts @@ -3,6 +3,7 @@ import { vino } from "./ui/vino.js"; // TVii itself import { tvtag } from "./api/fakeTVTag.js"; // Fake TVTag route import { act } from "./api/act.js"; // Account import { data } from "./api/data.js"; // API stuff +import { miis } from "./api/miis.js"; // Mii images interface Route { name: string; @@ -32,6 +33,11 @@ const routes: Route[] = [ path: "/api/v1/data", route: data, }, + { + name: "Miis", + path: "/api/v1/miis", + route: miis, + }, ]; export { routes as exports }; \ No newline at end of file diff --git a/src/utils/getData.ts b/src/utils/getData.ts index 4234240..f4c24ae 100644 --- a/src/utils/getData.ts +++ b/src/utils/getData.ts @@ -179,6 +179,7 @@ export const createWhitePixel = async () => { background: { r: 255, g: 255, b: 255 }, }, }) - .png() + .webp() + .toFormat("webp") .toBuffer(); }; \ No newline at end of file