Greasy Fork is available in English.

Twitter image viewing enhancement

Make Twitter photo viewing more humane

As of 2022-05-22. See the latest version.

  1. // ==UserScript==
  2. // @name Twitter image viewing enhancement
  3. // @name:zh-CN Twitter 图片查看增强
  4. // @name:zh-TW Twitter 圖像查看增強
  5. // @icon https://twitter.com/favicon.ico
  6. // @namespace https://moe.best/
  7. // @version 1.0.5
  8. // @description Make Twitter photo viewing more humane
  9. // @description:zh-CN 让推特图片浏览更加人性化
  10. // @description:zh-TW 讓 Twitter 照片瀏覽更人性化
  11. // @author Jindai Kirin
  12. // @include https://twitter.com/*
  13. // @license MIT
  14. // @grant none
  15. // @run-at document-end
  16. // @require https://code.bdstatic.com/npm/jquery@3.6.0/dist/jquery.min.js
  17. // @require https://code.bdstatic.com/npm/jquery-mousewheel@3.1.13/jquery.mousewheel.js
  18. // ==/UserScript==
  19.  
  20. // 注意 NOTICE
  21. // v1.0.0 是一次重大更新,你将不再需要设置 aria-label,并且支持所有语言。如果某一天脚本突然无法正常工作,请于脚本页面反馈,或退回至 v0.6.3。
  22. // v1.0.0 is an major update, you will no longer need to set up aria-labels and it support all languages. If one day the script not work, please feedback on the script homepage or use v0.6.3.
  23.  
  24. (() => {
  25. 'use strict';
  26.  
  27. const labels = {};
  28. try {
  29. const kv = {
  30. af8fa2ae: 'close',
  31. c4d53ba2: 'prev',
  32. d70740da: 'next',
  33. };
  34. Object.values(webpackJsonp[2][1]).forEach(fn => {
  35. if (fn.length < 3) return;
  36. try {
  37. fn(undefined, undefined, () => ({
  38. _register: () => (k, v) => {
  39. if (k in kv) labels[kv[k]] = v;
  40. },
  41. }));
  42. } catch (e) {}
  43. });
  44. } catch (error) {
  45. console.error(error);
  46. }
  47.  
  48. const getBtnByLabel = label => $(`div[aria-labelledby="modal-header"] div[aria-label="${label}"]`);
  49. const clickBtn = name => {
  50. const $btn = getBtnByLabel(labels[name]);
  51. if ($btn.length) {
  52. $btn.click();
  53. return true;
  54. }
  55. return false;
  56. };
  57.  
  58. const closeImgView = () => clickBtn('close');
  59. const prevImg = () => clickBtn('prev');
  60. const nextImg = () => clickBtn('next');
  61.  
  62. $(document).mousewheel(({ deltaY, target: { tagName, baseURI } }) => {
  63. if (tagName == 'IMG' && /\/photo\//.test(baseURI)) {
  64. switch (deltaY) {
  65. case 1:
  66. prevImg();
  67. break;
  68. case -1:
  69. nextImg();
  70. break;
  71. }
  72. }
  73. });
  74.  
  75. (() => {
  76. let x = 0;
  77. let y = 0;
  78. $(document).mousedown(({ clientX, clientY }) => {
  79. x = clientX;
  80. y = clientY;
  81. });
  82. $(document).mouseup(({ button, clientX, clientY, target: { tagName, baseURI } }) => {
  83. if (button !== 0 || !(tagName == 'IMG' && /\/photo\//.test(baseURI))) return;
  84. const [sx, sy] = [clientX - x, clientY - y].map(Math.abs);
  85. const mx = clientX - x;
  86. if (sx <= 10 && sy <= 10) closeImgView();
  87. if (sy <= sx) {
  88. if (mx > 0) prevImg();
  89. else if (mx < 0) nextImg();
  90. }
  91. });
  92. })();
  93. })();