f-droid.org - Enlarge Screenshots

Enlarge (and then reduce) app's screenshots by single click. Browse (i.e. next/previous) screenshots by using arrow keys, both in enlarged mode and in the normal mode.

  1. // ==UserScript==
  2. // @name f-droid.org - Enlarge Screenshots
  3. // @namespace a-pav
  4. // @description Enlarge (and then reduce) app's screenshots by single click. Browse (i.e. next/previous) screenshots by using arrow keys, both in enlarged mode and in the normal mode.
  5. // @match *://f-droid.org/packages/*
  6. // @match *://f-droid.org/*/packages/*
  7. // @version 1.0
  8. // @run-at document-end
  9. // @author a-pav
  10. // @grant none
  11. // @icon https://f-droid.org/assets/favicon-32x32.png
  12. // ==/UserScript==
  13.  
  14. const bigScreenShotID = "enlarged-scrnsht";
  15. var screenshotsFrame = document.querySelector("#screenshots>div.frame.js_frame");
  16. if (!screenshotsFrame) {
  17. // no screenshots for this package
  18. return
  19. }
  20. var gallery = screenshotsFrame.querySelector("ul.gallery");
  21. var screenshotsList = screenshotsFrame.querySelectorAll("li.js_slide.screenshot");
  22.  
  23. function showSCREENSHOT(index) {
  24. gallery.style.display = "none";
  25.  
  26. var li = screenshotsList[index];
  27. var img = li.querySelector("img").cloneNode();
  28. img.setAttribute("id", bigScreenShotID);
  29. img.setAttribute("arrindex", index);
  30.  
  31. img.addEventListener('click', function() {
  32. removeSCREENSHOT(this);
  33. });
  34.  
  35. screenshotsFrame.append(img);
  36. img.scrollIntoView({behavior: "smooth"});
  37. }
  38.  
  39. function removeSCREENSHOT(img, scroll = true) {
  40. gallery.style.display = "block";
  41.  
  42. if (!img) {
  43. img = document.getElementById(bigScreenShotID);
  44. }
  45.  
  46. if (img) {
  47. img.parentElement.removeChild(img);
  48. }
  49.  
  50. if (scroll) {
  51. screenshotsFrame.scrollIntoView({behavior: "smooth"});
  52. }
  53. }
  54.  
  55. screenshotsList.forEach(function(elm , index) {
  56. elm.addEventListener('click', function() {
  57. showSCREENSHOT(index);
  58. });
  59. });
  60.  
  61. document.querySelectorAll("div#screenshots>span.slider_nav").forEach(function(elm) {
  62. elm.addEventListener('click', function() {
  63. var img = document.getElementById(bigScreenShotID);
  64. if (img === null) {
  65. // do nothing
  66. return;
  67. }
  68.  
  69. var next = this.classList.contains('next');
  70. var index = parseInt(img.getAttribute("arrindex"));
  71. if (next) {
  72. index += 1;
  73. if (index > screenshotsList.length - 1) {
  74. index = 0;
  75. }
  76. } else {
  77. index -= 1;
  78. if (index < 0) {
  79. index = screenshotsList.length - 1;
  80. }
  81. }
  82.  
  83. removeSCREENSHOT(img); // remove previously enlarged image
  84.  
  85. showSCREENSHOT(index);
  86. });
  87. });
  88.  
  89. // Keybindings
  90. var next = document.querySelector("div#screenshots>span.slider_nav.next");
  91. var prev = document.querySelector("div#screenshots>span.slider_nav.prev");
  92. var clickEvent = new Event('click');
  93.  
  94. window.addEventListener('keyup', function(e) {
  95. if (e.key === "ArrowRight") { // or e.which 39
  96. next.dispatchEvent(clickEvent);
  97. } else if (e.key === "ArrowLeft") { // or e.which 37
  98. prev.dispatchEvent(clickEvent);
  99. } else if (e.key === "Escape") { // or e.which: 27
  100. removeSCREENSHOT(null, false);
  101. }
  102. });