Greasy Fork 还支持 简体中文。

X (Twitter) - own tweets

Adds a link to users' pages to search for tweets only from them (no retweets without comment).

  1. // ==UserScript==
  2. // @name X (Twitter) - own tweets
  3. // @version 5
  4. // @grant none
  5. // @require https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js
  6. // @match https://x.com/*
  7. // @author monnef
  8. // @description Adds a link to users' pages to search for tweets only from them (no retweets without comment).
  9. // @namespace monnef.eu
  10. // ==/UserScript==
  11.  
  12. // config
  13. const debug = false;
  14. const numberOfAttempts = 5;
  15. const workInterval = 1000;
  16. // end of config
  17.  
  18. const linkMarker = 'monnef--no-retweets';
  19. const dLog = (...xs) => debug && console.log('[OwnTweets]', ...xs);
  20. const state = { lastUrl: null, attempts: 0 };
  21.  
  22. const insertLink = (nameEl) => {
  23. if (nameEl.parent().parent().parent().parent().find(`.${linkMarker}`).length) return;
  24. const handle = nameEl.text();
  25. const linkEl = $("<a/>")
  26. .attr('href', `/search?q=from%3A%40${handle.slice(1)}&src=typed_query`)
  27. .text('[Own Tweets]')
  28. .addClass(linkMarker)
  29. .css({
  30. color: 'rgb(29, 161, 242)',
  31. marginLeft: '5px'
  32. })
  33. ;
  34. nameEl.parent().parent().after(linkEl);
  35. };
  36.  
  37. const isHandleEl = (el) => el.length && el.text().startsWith('@');
  38.  
  39. const tryGetAndProcessNameEl = (x, y) => {
  40. const nameEl = $(document.elementFromPoint(x, y));
  41. const handle = nameEl.text();
  42. dLog('tryGetAndProcessNameEl', x, y, ';nameEl', nameEl, ';handle', handle);
  43. if (isHandleEl(nameEl)) {
  44. state.attempts = numberOfAttempts;
  45. insertLink(nameEl);
  46. return true;
  47. } else {
  48. return false;
  49. }
  50. }
  51.  
  52. const work = () => {
  53. const curUrl = window.location.href;
  54. if (state.lastUrl === curUrl) {
  55. state.attempts++;
  56. if (state.attempts >= numberOfAttempts) {
  57. dLog('work - url didn\'t change, skipping');
  58. return;
  59. }
  60. } else {
  61. state.attempts = 0;
  62. }
  63. dLog('work', curUrl, state.lastUrl, state.attempts);
  64. state.lastUrl = curUrl;
  65. const handleEl = $('div[data-testid="UserName"]')
  66. .find('span')
  67. .filter((_, el) => $(el).text().trim().startsWith('@'));
  68.  
  69. dLog('handleEl', handleEl);
  70. if (handleEl.length) {
  71. insertLink(handleEl);
  72. } else {
  73. dLog('failed to locate handleEl');
  74. }
  75. }
  76.  
  77. $(() => setInterval(work, workInterval))