Greasy Fork is available in English.

Twitter (X): Скрыть Текстовые Публикации

Сделайте ленту публикаций чище

// ==UserScript==
// @name           Twitter (X): Скрыть Текстовые Публикации
// @name:en        Twitter (X): Hide Text Posts
// @name:ru        Twitter (X): Скрыть Текстовые Публикации
// @name:zh        Twitter (X): 隐藏文本出版物
// @namespace      http://tampermonkey.net/
// @version        3.3
// @description    Сделайте ленту публикаций чище
// @description:en Make your feed cleaner
// @description:ru Сделайте ленту публикаций чище
// @description:zh 使出版物提要更清洁
// @author         Grihail
// @match          https://twitter.com/*
// @icon           https://www.google.com/s2/favicons?sz=64&domain=twitter.com
// @grant          GM_setValue
// @grant          GM_getValue
// @license        CC-BY
// ==/UserScript==
 
//Локализация
const pageLanguage = document.documentElement.lang.toLowerCase();
const currentLanguage = pageLanguage.startsWith('ru') ? 'ru' : (pageLanguage.startsWith('zh') ? 'zh' : 'en'); // Добавлено определение для китайского языка
const translations = {
    en: {title: 'Hide:', textPost: 'Text post', textReply: 'Text reply:', textRepost: 'Text repost', textQuote: 'Text quote', selfRepost: 'Self repost',
    },
    ru: {title: 'Скрыть:', textPost: 'Текстовый пост', textReply: 'Текстовый ответ:', textRepost: 'Репост текста', textQuote: 'Цитата текста', selfRepost: 'Само-репост',
    },
    zh: {title: '隐藏:', textPost: '文本帖子', textReply: '文本回复:', textRepost: '文本转发', textQuote: '文本引用', selfRepost: '自我转发',
    }
};

// Интеграция интерфейса и функционал
function insertPostSettings() {
  const postSettingsHTML = `
    <div class="postSettings" style="border-radius: 16px; width: 90%; border-color: rgb(47, 51, 54); overflow: hidden; border-width: 1px; border-style: solid; display: flex; box-sizing: border-box; flex-direction: column; padding: 0 12px 12px 12px; margin-top: 16px;">
	<h2 style="margin-block: unset; display: flex; align-items: center; padding-left: 12px;" class="r-1h3ijdo r-1nao33i r-37j5jr r-adyw6z r-b88u0q r-135wba7 r-bcqeeo">
		<span>${translations[currentLanguage].title}</span></h2>
    <div class="textCheck" style="width: 90%;display: flex;justify-content: space-between;align-items: center;padding: 12px;">
    	<svg viewBox="0 0 24 24" style="margin-right: 12px;height: 1.25em;flex-shrink: 0;">
    	<g style="fill: #e7e9ea;">
        	<path d="M1.751 10c0-4.42 3.584-8 8.005-8h4.366c4.49 0 8.129 3.64 8.129 8.13 0 2.96-1.607 5.68-4.196 7.11l-8.054 4.46v-3.69h-.067c-4.49.1-8.183-3.51-8.183-8.01zm8.005-6c-3.317 0-6.005 2.69-6.005 6 0 3.37 2.77 6.08 6.138 6.01l.351-.01h1.761v2.3l5.087-2.81c1.951-1.08 3.163-3.13 3.163-5.36 0-3.39-2.744-6.13-6.129-6.13H9.756z"></path></g></svg>
    	<span class="r-1nao33i r-37j5jr r-a023e6 r-rjixqe" style="width: 100%;">${translations[currentLanguage].textPost}</span>
      <input type="checkbox" class="textPost" data-target-class="textPostHide" ${getCheckboxValue('textPost')}></input></div>
    <div class="replytextCheck" style="width: 90%;display: flex;justify-content: space-between;align-items: center;padding: 12px;">
    	<svg viewBox="0 0 24 24" style="margin-right: 12px;height: 1.25em;flex-shrink: 0;">
    	<g style="fill: #e7e9ea;"><path d="M1.751 10c0-4.42 3.584-8 8.005-8h4.366c4.49 0 8.129 3.64 8.129 8.13 0 2.96-1.607 5.68-4.196 7.11l-8.054 4.46v-3.69h-.067c-4.49.1-8.183-3.51-8.183-8.01zm8.005-6c-3.317 0-6.005 2.69-6.005 6 0 3.37 2.77 6.08 6.138 6.01l.351-.01h1.761v2.3l5.087-2.81c1.951-1.08 3.163-3.13 3.163-5.36 0-3.39-2.744-6.13-6.129-6.13H9.756z"></path></g></svg>
    	<span class="r-1nao33i r-37j5jr r-a023e6 r-rjixqe" style="width: 100%;">${translations[currentLanguage].textReply}</span>
    	<input type="checkbox" class="textReply" data-target-class="textReplyHide"${getCheckboxValue('textReply')}></input></div>
    <div class="repostCheck" style="width: 90%;display: flex;justify-content: space-between;align-items: center;padding: 12px;">
    	<svg viewBox="0 0 24 24" style="margin-right: 12px;height: 1.25em;flex-shrink: 0;">
    	<g style="fill: #e7e9ea;">
        	<path d="M4.5 3.88l4.432 4.14-1.364 1.46L5.5 7.55V16c0 1.1.896 2 2 2H13v2H7.5c-2.209 0-4-1.79-4-4V7.55L1.432 9.48.068 8.02 4.5 3.88zM16.5 6H11V4h5.5c2.209 0 4 1.79 4 4v8.45l2.068-1.93 1.364 1.46-4.432 4.14-4.432-4.14 1.364-1.46 2.068 1.93V8c0-1.1-.896-2-2-2z"></path></g></svg>
    	<span class="r-1nao33i r-37j5jr r-a023e6 r-rjixqe" style="width: 100%;">${translations[currentLanguage].textRepost}</span>
      <input type="checkbox" class="textRepost" data-target-class="textRepostHide"${getCheckboxValue('textRepost')}></input></div>
    <div class="selfrepostCheck" style="width: 90%;display: flex;justify-content: space-between;align-items: center;padding: 12px;">
        <svg viewBox="0 0 24 24" style="margin-right: 12px;height: 1.25em;flex-shrink: 0;">
	    <g style="fill: #e7e9ea;">
        	<path d="M14.23 2.854c.98-.977 2.56-.977 3.54 0l3.38 3.378c.97.977.97 2.559 0 3.536L9.91 21H3v-6.914L14.23 2.854zm2.12 1.414c-.19-.195-.51-.195-.7 0L5 14.914V19h4.09L19.73 8.354c.2-.196.2-.512 0-.708l-3.38-3.378zM14.75 19l-2 2H21v-2h-6.25z"></path></g></svg>
	    <span class="r-1nao33i r-37j5jr r-a023e6 r-rjixqe" style="width: 100%;">${translations[currentLanguage].textQuote}</span>
      <input type="checkbox" class="textQuote" data-target-class="textQuoteHide"${getCheckboxValue('textQuote')}></input></div>
    <div class="replyCheck" style="width: 90%;display: flex;justify-content: space-between;align-items: center;padding: 12px;">
    	<svg viewBox="0 0 24 24" style="margin-right: 12px;height: 1.25em;flex-shrink: 0;">
    	<g style="fill: #e7e9ea;">
        	<path d="M4.5 3.88l4.432 4.14-1.364 1.46L5.5 7.55V16c0 1.1.896 2 2 2H13v2H7.5c-2.209 0-4-1.79-4-4V7.55L1.432 9.48.068 8.02 4.5 3.88zM16.5 6H11V4h5.5c2.209 0 4 1.79 4 4v8.45l2.068-1.93 1.364 1.46-4.432 4.14-4.432-4.14 1.364-1.46 2.068 1.93V8c0-1.1-.896-2-2-2z"></path></g></svg>
    	<span class="r-1nao33i r-37j5jr r-a023e6 r-rjixqe" style="width: 100%;">${translations[currentLanguage].selfRepost}</span>
       <input type="checkbox" class="selfRepost" data-target-class="selfRepostHide"${getCheckboxValue('selfRepost')}></input></div></div>
  `;
   const targetSelector = "body > #react-root > div > div > div[data-at-shortcutkeys] > header > div > div > div > div:nth-child(1)";
  const targetElement = document.querySelector(targetSelector);

  if (!document.querySelector('.postSettings')) {
    targetElement.insertAdjacentHTML('beforeend', postSettingsHTML);

    const checkboxes = document.querySelectorAll('.postSettings input[type="checkbox"]');

    function updateVisibility() {
      if (window.location.href !== 'https://twitter.com/home') {
        // Если не на домашней странице Twitter, не обновляем видимость элементов
        return;
      }

      checkboxes.forEach(checkbox => {
        const dataAttribute = checkbox.getAttribute('data-target-class');
        const elementsToToggle = document.querySelectorAll(`.${dataAttribute}`);

        elementsToToggle.forEach(element => {
          element.style.display = checkbox.checked ? 'none' : 'block';
        });
      });

      // Сохраняем значения checkbox в localStorage
      setCheckboxValue('textPost', checkboxes[0].checked);
      setCheckboxValue('textReply', checkboxes[1].checked);
      setCheckboxValue('textRepost', checkboxes[2].checked);
      setCheckboxValue('textQuote', checkboxes[3].checked);
      setCheckboxValue('selfRepost', checkboxes[4].checked);
    }

    checkboxes.forEach(checkbox => {
      checkbox.addEventListener('change', updateVisibility);
    });

    setInterval(updateVisibility, 100);

    // Дополнительный код для управления видимостью интерфейса в зависимости от URL
    setInterval(() => {
      const currentURL = window.location.href;
      const postSettings = document.querySelector('.postSettings');
      if (currentURL === "https://twitter.com/home") {
        postSettings.style.opacity = '100%';
      } else {
        postSettings.style.opacity = '0%';
      }
    }, 700);
  }
}
// Функция для получения значения checkbox из localStorage
function getCheckboxValue(key) {
  const screenName = getCurrentUserScreenName();
  return localStorage.getItem(`${screenName}_${key}`) === 'false' ? '' : 'checked';
}
 
// Функция для сохранения значения checkbox в localStorage
function setCheckboxValue(key, value) {
  const screenName = getCurrentUserScreenName();
  localStorage.setItem(`${screenName}_${key}`, value);
}
 
// Функция для извлечения screenName из HTML кода
function extractScreenName(html) {
  var regex = /"screen_name":"([^"]+)"/;
  var match = html.match(regex);
 
  if (match && match[1]) {
    return match[1];
  } else {
    return null;
  }
}
 // Функция для получения screenName текущего пользователя
function getCurrentUserScreenName() {
  var htmlCode = document.documentElement.outerHTML;
  var screenName = extractScreenName(htmlCode);
  return screenName ? screenName : 'unknown';
}
 
setInterval(function() {
  document.querySelectorAll('div:nth-child(1) > section > div:nth-child(2) > div > [data-testid="cellInnerDiv"]').forEach(function(element) {
    const media = element.querySelector('article > div > div > div:nth-child(2) > div:nth-child(2) > div[id] > div:not([id])');
    const reply = element.querySelector('article > div > div > div:nth-child(2) > div:nth-child(1) > div:nth-child(2)');
    const lastReply = element.querySelector('article > div > div > div:nth-child(1) > div > div > div');
    const repost = element.querySelector('article > div > div > div:nth-child(1) > div > div > div > div');
    const quote = element.querySelector('article > div > div > div:nth-child(2) > div:nth-child(2) > div[id] > div[id]');
    const mediaQuote = element.querySelector('article > div > div > div:nth-child(2) > div:nth-child(2) > div[id] > div[id] > div[role] > div > div:nth-child(3)');

    const repostAuthor = element.querySelector('article > div > div > div:nth-child(1) > div > div > div > div > div:nth-child(2) > div > div > div > a[href]');
    const postAuthor = element.querySelector('article > div > div > div:nth-child(2) > div:nth-child(1) > div > div > div > div:nth-child(2) > div > div:nth-child(2) > div > a[href]');

    if (!media && !repost && !lastReply && !quote) {
      element.classList.add('textPostHide');
    }
    if (!media && (reply || lastReply)) {
      element.classList.add('textReplyHide');
    }
    if ((!media && repost) && (!reply || !lastReply)) {
      element.classList.add('textRepostHide');
    }
    if (!media && quote) {
      element.classList.add('textQuoteHide');
    }
    if (postAuthor && repostAuthor && postAuthor.href === repostAuthor.href) {
      element.classList.add('selfRepostHide');
    }})}, 1000);
 
// Основной код скрипта
setInterval(() => {
  const currentURL = window.location.href;
  if (currentURL === 'https://twitter.com/home') {
    insertPostSettings();
    addClassesToElements();
  }
}, 1000);