PlexEXT

Enhances Plex

  1. // ==UserScript==
  2. // @name PlexEXT
  3. // @icon https://www.macupdate.com/images/icons256/27302.png
  4. // @namespace skoshy.com
  5. // @version 0.1.3
  6. // @description Enhances Plex
  7. // @author Stefan Koshy
  8. // @match http*://localhost:32400/*
  9. // @match http*://app.plex.tv/web/*
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. var scriptid = 'plex-supreme';
  14.  
  15. var newElements = {};
  16. var timers = {};
  17.  
  18. var css = `
  19. /* Makes video controls a little lighter */
  20. .video-controls-overlay {background-color: rgba(0,0,0,.2);}
  21. .video-controls-overlay:hover {background-color: rgba(0,0,0,.8);}
  22.  
  23. /* CUSTOM TOOLTIP */
  24. .`+scriptid+`-tooltip {
  25. position: fixed;
  26. bottom: 5px;
  27. left: 5px;
  28. background: rgba(255, 255, 255, .8);
  29. padding: 3px;
  30. border-radius: 20px;
  31. color: black;
  32. z-index: 10000000;
  33. }
  34. `;
  35.  
  36. function brightnessChangeCheck(event) {
  37. if (!isFocusOnInputBox(event.target)) {
  38. if (event.shiftKey) {
  39. var video = document.querySelector('video');
  40.  
  41. var brightness = parseFloat(parseFromFilter('brightness', video.style.filter));
  42. if (!brightness || isNaN(brightness)) { // no brightness has been specified yet
  43. video.style.filter = 'brightness(1.0)';
  44. brightness = parseFloat(parseFromFilter('brightness', video.style.filter));
  45. }
  46.  
  47. if (event.keyCode === 33) { // shift+pgup
  48. var newBrightness = brightness+.1;
  49. video.style.filter = 'brightness('+newBrightness+')';
  50. showTooltip('Brightness: '+newBrightness.toFixed(2));
  51. } else if (event.keyCode === 34) { // shift+pgdn
  52. var newBrightness = brightness-.1;
  53. video.style.filter = 'brightness('+newBrightness+')';
  54. showTooltip('Brightness: '+newBrightness.toFixed(2));
  55. }
  56. }
  57. }
  58. }
  59.  
  60. // will parse attribute from a filter string
  61. // ex: parseFromFilter('brightness', 'brightness(1.5)') => 1.5
  62. // will return false if it can't parse it
  63. function parseFromFilter(name, string) {
  64. if (string == undefined)
  65. return false;
  66. var startLength = name.length+1;
  67. var startPos = string.indexOf(name+'(');
  68. if (startPos == -1)
  69. return false;
  70. var endPos = string.indexOf(')', startLength+startPos);
  71. if (endPos == -1)
  72. return false;
  73. return string.substring(startLength+startPos, startLength+startPos+endPos);
  74. }
  75.  
  76. function showTooltip(text) {
  77. newElements.tooltip.innerHTML = text;
  78. newElements.tooltip.style.display = 'block';
  79. clearTimeout(timers.tooltip);
  80. timers.tooltip = setTimeout(function() {newElements.tooltip.style.display = 'none';}, 1000);
  81. }
  82.  
  83. function addGlobalStyle(css, id) {
  84. var head, style;
  85. head = document.getElementsByTagName('head')[0];
  86. if (!head) { return; }
  87. style = document.createElement('style');
  88. style.type = 'text/css';
  89. style.innerHTML = css;
  90. style.id = id;
  91. head.appendChild(style);
  92. }
  93.  
  94. function initialize() {
  95. if (location.hostname == 'localhost' && location.port != '32400')
  96. return;
  97. // create the tooltip
  98. newElements.tooltip = document.createElement('div');
  99. newElements.tooltip.className = scriptid+'-tooltip';
  100. newElements.tooltip.style.display = 'none';
  101. insertAfter(newElements.tooltip, document.querySelector('#plex'));
  102.  
  103. // initialize check for increasing/decreasing brightness
  104. document.body.addEventListener('keydown', brightnessChangeCheck);
  105.  
  106. addGlobalStyle(css, scriptid);
  107. }
  108.  
  109. initialize();
  110.  
  111. // passed a target element, will check if it's an input box
  112. function isFocusOnInputBox(target) {
  113. if (target.getAttribute('role') == 'textbox' || target.tagName == 'INPUT' || target.tagName == 'TEXTAREA')
  114. return true;
  115. else
  116. return false;
  117. }
  118.  
  119. function insertAfter(newNode, referenceNode) {
  120. referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
  121. }