Twitter 图片查看增强

让推特图片浏览更加人性化

当前为 2022-09-30 提交的版本,查看 最新版本

  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.2.4
  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. // @include https://mobile.twitter.com/*
  14. // @license MIT
  15. // @grant GM_addStyle
  16. // @grant GM_getValue
  17. // @grant GM_setValue
  18. // @grant GM_registerMenuCommand
  19. // @run-at document-end
  20. // ==/UserScript==
  21.  
  22. // 注意 NOTICE
  23. // v1.0.0 是一次重大更新,你将不再需要设置 aria-label,并且支持所有语言。如果某一天脚本突然无法正常工作,请于脚本页面反馈,或退回至 v0.6.3。
  24. // 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.
  25.  
  26. (() => {
  27. 'use strict';
  28.  
  29. // 滑动切换图片
  30. let enableDragToSwitch = GM_getValue('enableDragToSwitch', false);
  31. GM_registerMenuCommand('Drag to swtich images', () => {
  32. enableDragToSwitch = confirm(`Do you want to enable drag to swtich images?
  33. Current: ${enableDragToSwitch ? 'Enabled' : 'Disabled'}
  34.  
  35. Please refresh to take effect after modification.`);
  36. GM_setValue('enableDragToSwitch', enableDragToSwitch);
  37. });
  38.  
  39. if (enableDragToSwitch) GM_addStyle('img{-webkit-user-drag:none}');
  40.  
  41. const labels = {};
  42. try {
  43. const kv = {
  44. af8fa2ad: 'close',
  45. af8fa2ae: 'close',
  46. c4d53ba2: 'prev',
  47. d70740d9: 'next',
  48. d70740da: 'next',
  49. };
  50. const i18nModule = webpackChunk_twitter_responsive_web.find(([[name]]) =>
  51. name.startsWith('i18n')
  52. );
  53. Object.values(i18nModule[1]).forEach(fn => {
  54. if (fn.length < 3) return;
  55. try {
  56. fn(undefined, undefined, () => ({
  57. _register: () => (k, v) => {
  58. if (k in kv) labels[kv[k]] = v;
  59. },
  60. }));
  61. } catch (e) {}
  62. });
  63. } catch (error) {
  64. console.error(error);
  65. }
  66.  
  67. const getBtnByLabel = label =>
  68. document.querySelector(`div[aria-labelledby="modal-header"] div[aria-label="${label}"]`);
  69. const clickBtn = name => {
  70. const $btn = getBtnByLabel(labels[name]);
  71. if ($btn) {
  72. $btn.click();
  73. return true;
  74. }
  75. return false;
  76. };
  77.  
  78. const closeImgView = () => clickBtn('close');
  79. const prevImg = () => clickBtn('prev');
  80. const nextImg = () => clickBtn('next');
  81.  
  82. window.addEventListener('wheel', ({ deltaY, target: { tagName, baseURI } }) => {
  83. if (tagName == 'IMG' && /\/photo\//.test(baseURI)) {
  84. if (deltaY < 0) prevImg();
  85. else if (deltaY > 0) nextImg();
  86. }
  87. });
  88.  
  89. if (enableDragToSwitch) {
  90. let x = 0;
  91. let y = 0;
  92. window.addEventListener('mousedown', ({ clientX, clientY }) => {
  93. x = clientX;
  94. y = clientY;
  95. });
  96. window.addEventListener(
  97. 'mouseup',
  98. ({ button, clientX, clientY, target: { tagName, baseURI } }) => {
  99. if (button !== 0 || !(tagName == 'IMG' && /\/photo\//.test(baseURI))) return;
  100. const [sx, sy] = [clientX - x, clientY - y].map(Math.abs);
  101. const mx = clientX - x;
  102. if (sx <= 10 && sy <= 10) closeImgView();
  103. if (sy <= sx) {
  104. if (mx > 0) prevImg();
  105. else if (mx < 0) nextImg();
  106. }
  107. }
  108. );
  109. } else {
  110. document.addEventListener(
  111. 'click',
  112. e => {
  113. const {
  114. target: { tagName, baseURI },
  115. } = e;
  116. if (!(tagName == 'IMG' && /\/photo\//.test(baseURI))) return;
  117. closeImgView();
  118. e.stopPropagation();
  119. },
  120. { capture: true }
  121. );
  122. }
  123. })();