Piazza - Archive with Delete Key

bind the delete key to quickly archive posts

当前为 2021-06-27 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Piazza - Archive with Delete Key
// @namespace    https://openuserjs.org/users/zachhardesty7
// @author       Zach Hardesty <[email protected]> (https://github.com/zachhardesty7)
// @description  bind the delete key to quickly archive posts
// @copyright    2019, Zach Hardesty (https://zachhardesty.com/)
// @license      GPL-3.0-only; http://www.gnu.org/licenses/gpl-3.0.txt
// @version      2.3.2

// @homepageURL  https://github.com/zachhardesty7/tamper-monkey-scripts-collection/raw/master/piazza-archive-with-delete-key.user.js
// @homepageURL  https://openuserjs.org/scripts/zachhardesty7/Piazza_-_Archive_with_Delete_Key
// @supportURL   https://openuserjs.org/scripts/zachhardesty7/Piazza_-_Archive_with_Delete_Key/issues


// @include      https://piazza.com/class/*
// ==/UserScript==
/* global P */

// TODO: add undo shortcut

// let lastDeletedItemId
let lastMovement = "down" // or 'up'

/**
 * ret prev item in cur week if exists or back up and move to prev week to get last item
 *
 * @see {getNextItem}
 * @param {Element} el - target
 * @returns {?HTMLElement} result
 */
const getPrevItem = (el) => {
  if (el.previousElementSibling) return el.previousElementSibling

  let parent = el.parentElement.parentElement.previousElementSibling
  while (parent) {
    if (parent.lastElementChild && parent.lastElementChild.lastElementChild) {
      return parent.lastElementChild.lastElementChild
    }
    parent = parent.previousElementSibling
  }

  // must be at start of posts so force get next
  const item = getNextItem(el)
  if (!item) throw new Error("cannot find any other posts") // prevent inf loop
  return item
}

/**
 * ret next item in cur week if exists or back up and move to next week to get first item
 *
 * @param {Element} el - target
 * @returns {?HTMLElement} result
 */
const getNextItem = (el) => {
  // sibling from same week
  if (el.nextElementSibling) return el.nextElementSibling

  // back up element to week div and select next week
  let parent = el.parentElement.parentElement.nextElementSibling
  // return first proceeding week with a post in it
  while (parent) {
    if (parent.lastElementChild && parent.lastElementChild.firstElementChild) {
      return parent.lastElementChild.firstElementChild
    }
    parent = parent.nextElementSibling // update to next week
  }

  // must be at end of posts so force get prev
  const item = getPrevItem(el)
  if (!item) throw new Error("cannot find any other posts") // prevent inf loop
  return item
}

/**
 * navigate posts on key press
 *
 * @param {KeyboardEvent} e - keydown event
 */
const onKeydownHandler = (e) => {
  // move to prev feed item
  if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
    const prevItem = getPrevItem(document.querySelector(".feed_item.selected"))
    prevItem && prevItem.click()
    lastMovement = "up"
  }

  // move to next feed item
  if (e.key === "ArrowRight" || e.key === "ArrowDown") {
    const nextItem = getNextItem(document.querySelector(".feed_item.selected"))
    nextItem && nextItem.click()
    lastMovement = "down"
  }

  // del & move to next feed item
  if (e.key === "Delete") {
    const item = document.querySelector(".feed_item.selected")
    const newItem =
      lastMovement === "up" // change view
        ? getPrevItem(item)
        : getNextItem(item)
    newItem && newItem.click()
    // lastDeletedItemId = (item.id)
    P.feed.delFeedItem(item.id)
  }

  // FIXME: cannot read property 'remove' of null
  // if (e.key === 'z' && e.ctrlKey) {
  //   if (lastDeletedItemId) {
  //     P.feed.addFeedItem(lastDeletedItemId)
  //   }
  // }
}

// update direction of last movement direction for each click
document.addEventListener("click", (e) => {
  let clickedPost = /** @type {HTMLElement} */ (e.target)

  // traverse up html until the post item is found or `null`
  while (clickedPost && !clickedPost.className.includes("feed_item")) {
    clickedPost = clickedPost.parentElement
  }

  if (clickedPost) {
    const selected = document.querySelector(".feed_item.selected")

    // id of week the post is in
    const bucketClicked = clickedPost.parentElement.id
    const bucketSelected = selected.parentElement.id

    if (bucketClicked > bucketSelected) lastMovement = "down"
    else if (bucketClicked < bucketSelected) lastMovement = "up"
    else {
      // posts in the same week
      // get position within the week
      const positionClicked = [...clickedPost.parentElement.children].indexOf(
        clickedPost
      )
      const positionSelected = [...selected.parentElement.children].indexOf(
        selected
      )

      if (positionClicked < positionSelected) lastMovement = "up"
      else if (positionClicked > positionSelected) lastMovement = "down"
      else {
        /* don't update lastMovement if already selected item is clicked */
      }
    }
  }
})

document.addEventListener("keydown", onKeydownHandler)