Cook'd and Bomb'd Really Ignore Users

Really ignores ignored users

当前为 2021-05-18 提交的版本,查看 最新版本

// ==UserScript==
// @name        Cook'd and Bomb'd Really Ignore Users
// @description Really ignores ignored users
// @namespace   https://github.com/insin/greasemonkey/
// @version     1
// @match       https://www.cookdandbombd.co.uk/forums/index.php/board*
// @match       https://www.cookdandbombd.co.uk/forums/index.php/topic*
// @match       https://www.cookdandbombd.co.uk/forums/index.php?action=post*
// @match       https://www.cookdandbombd.co.uk/forums/index.php?action=profile;area=lists;sa=ignore*
// @match       https://www.cookdandbombd.co.uk/forums/index.php?action=unread*
// @grant       GM.registerMenuCommand
// ==/UserScript==

const IGNORED_USERS_STORAGE = 'cab_ignoredUsers'

let config = {
  addIgnoreUserControlToPosts: true,
  hidePostsQuotingIgnoredUsers: true,
  hideTopicsCreatedByIgnoredUsers: true,
  showIgnoredPosts: false,
}

let posts = []

function addStyle(css) {
  let $style = document.createElement('style')
  $style.appendChild(document.createTextNode(css))
  document.head.appendChild($style)
}

function addIgnoredPostsStyle() {
  addStyle(`
    .cab_ignoredPost {
      display: none;
    }
    .cab_ignoredPost.cab_show {
      display: block;
    }
    .cab_ignoredPost.cab_show {
      background-color: #fdd !important;
    }
    .cab_ignoredPost.cab_show {
      background-color: #fdd !important;
      border-radius: 0.7em;
    }
    .cab_ignoredPost.cab_show span.topslice,
		.cab_ignoredPost.cab_show span.topslice span,
    .cab_ignoredPost.cab_show span.botslice,
		.cab_ignoredPost.cab_show span.botslice span {
      background-image: none !important;
		}
  `)
}

function getIgnoredUsers() {
  return JSON.parse(localStorage[IGNORED_USERS_STORAGE] || '[]')
}

function toggleShowIgnoredPosts(showIgnoredPosts) {
  config.showIgnoredPosts = showIgnoredPosts
  posts.forEach(post => post.updateClassNames())
}

function TopicPage() {
  addIgnoredPostsStyle()

  let ignoredUsers = getIgnoredUsers()
  let ignoredUserIds = ignoredUsers.map(user => user.id)
  let ignoredUserNames = ignoredUsers.map(user => user.name)

  function Post($wrapper) {
    let $userLink = $wrapper.querySelector('div.poster h4 a')

    let userId = $userLink.href.match(/;u=(\d+)/)[1]
    let userName = $userLink.textContent
    let isUserIgnored = ignoredUserIds.includes(userId)
    let quotedUserNames = Array.from($wrapper.querySelectorAll('div.topslice_quote a')).map($a => $a.textContent.match(/Quote from: (.+) on /)[1])
    let quotesIgnoredUser = config.hidePostsQuotingIgnoredUsers && quotedUserNames.some(userName => ignoredUserNames.includes(userName))
    let isPostIgnored = isUserIgnored || quotesIgnoredUser

    let api = {
      updateClassNames() {
        $wrapper.parentElement.classList.toggle('cab_ignoredPost', isPostIgnored)
        $wrapper.parentElement.classList.toggle('cab_show', config.showIgnoredPosts && isPostIgnored)
      }
    }

    // Add an ignore/unignore link to user profiles in posts
    if (config.addIgnoreUserControlToPosts) {
      let $a = document.createElement('a')
      $a.href = `https://www.cookdandbombd.co.uk/forums/index.php?action=profile;area=lists;sa=ignore&${isUserIgnored ? `unignore=${userId}` : `ignore=${userName}`}`
      $a.title = `${isUserIgnored ? 'Remove from' : 'Add to'} ignore list`
      let $img = document.createElement('img')
      $img.alt = `${isUserIgnored ? 'Remove from' : 'Add to'} ignore list`
      $img.src = `/forums/Themes/default/images/buttons/${isUserIgnored ? 'close' : 'ignore'}.gif`
      $a.appendChild($img)
      let $li = document.createElement('li')
      $li.appendChild($a)
      $wrapper.querySelector('div.poster li.profile ul').appendChild($li)
    }

    api.updateClassNames()
    return api
  }

  posts = Array.from(document.querySelectorAll('div.post_wrapper')).map($wrapper => Post($wrapper))
  document.body.classList.add('cab_reallyIgnoreUsers')
}

function PostPage() {
  addIgnoredPostsStyle()

  let ignoredUserNames = getIgnoredUsers().map(user => user.name)

  function Post($wrapper) {
    let $userHeader = $wrapper.querySelector('h5')

    let userName = $userHeader.textContent.match(/Posted by: (.+)/)[1]
    let isUserIgnored = ignoredUserNames.includes(userName)
    let quotedUserNames = Array.from($wrapper.querySelectorAll('div.topslice_quote a')).map($a => $a.textContent.match(/Quote from: (.+) on /)[1])
    let quotesIgnoredUser = config.hidePostsQuotingIgnoredUsers && quotedUserNames.some(userName => ignoredUserNames.includes(userName))
    let isPostIgnored = isUserIgnored || quotesIgnoredUser

    let api = {
      updateClassNames() {
        $wrapper.classList.toggle('cab_ignoredPost', isPostIgnored)
        $wrapper.classList.toggle('cab_show', config.showIgnoredPosts && isPostIgnored)
      }
    }

    api.updateClassNames()
    return api
  }

  posts = Array.from(document.querySelectorAll('div.core_posts')).map($wrapper => Post($wrapper))
  document.body.classList.add('cab_reallyIgnoreUsers')
}

function IgnoreListPage() {
  let params = new URLSearchParams(location.search)

  // Automatically ignore a user if ignore=name is provided in the URL
  if (params.has('ignore')) {
    let $newIgnoreInput = document.querySelector('#new_ignore')
    $newIgnoreInput.value = params.get('ignore')
    $newIgnoreInput.form.submit()
    return
  }

  // Automatically unignore a user if unignore=id is provided in the URL
  if (params.has('unignore')) {
    let $removeLink = Array.from((document.querySelectorAll('.table_grid tr td:last-child a'))).find(a => a.href.includes(`remove=${params.get('unignore')}`))
    if ($removeLink) {
      $removeLink.click()
      return
    }
  }

  // Otherwise sync the ignore list
  let ignoredUsers = Array.from(document.querySelectorAll('.table_grid tr td:first-child a')).map($a => ({
    id: $a.href.match(/;u=(\d+)/)[1],
    name: $a.textContent,
  }))
  localStorage[IGNORED_USERS_STORAGE] = JSON.stringify(ignoredUsers)                                                                                
}

function ForumPage() {
  addStyle(`
    .cab_ignoredUser {
      display: none;
    }
  `)

  let ignoredUserIds = getIgnoredUsers().map(user => user.id)

  for (let $topicRow of document.querySelectorAll('#main_content_section .table_grid tbody tr')) {
    let $userLink = $topicRow.querySelector('td.subject p a')
    let userId = $userLink?.href.match(/;u=(\d+)/)?.[1]
    if (ignoredUserIds.includes(userId)) {
      $topicRow.classList.add('cab_ignoredUser')
    }
  }
}

if (location.search.includes('?action=profile;area=lists;sa=ignore')) {
  IgnoreListPage()
}
else if (location.search.includes('?action=unread') || location.pathname.includes('index.php/board')) {
  if (config.hideTopicsCreatedByIgnoredUsers) {
    ForumPage()
  }
}
else if (!document.body.classList.contains('cab_reallyIgnoreUsers')) {
  let page = location.search.includes('?action=post') ? PostPage : TopicPage
  if (typeof GM != 'undefined') {
    page()
    GM.registerMenuCommand('Toggle ignored post display', () => {
      toggleShowIgnoredPosts(!config.showIgnoredPosts)
    })
  }
  else {
    chrome.storage.local.get((storedConfig) => {
      Object.assign(config, storedConfig)
      page()
    })
    chrome.storage.onChanged.addListener((changes) => {
      if ('showIgnoredPosts' in changes) {
        toggleShowIgnoredPosts(changes['showIgnoredPosts'].newValue)
      }
    })
  }
}