manaba-enhanced-for-tsukuba/manaba-enhanced

View on GitHub
src/contentScript/main.ts

Summary

Maintainability
B
6 hrs
Test Coverage
"use strict"

import dayjs from "dayjs"

import checkAssignmentDeadline from "../methods/checkAssignmentDeadline"
import { checkLang } from "../methods/checkLang"
import checkPagePubDeadline from "../methods/checkPagePubDeadline"
import { colorizeDeadline } from "../methods/colorizeDeadline"
import createLinkToOptions from "../methods/createLinkToOptions"
import { dragAndDrop } from "../methods/dragAndDrop"
import { filterCourses } from "../methods/filterCourses"
import openCodeInRespon from "../methods/openCodeInRespon"
import removeLinkBalloon from "../methods/removeLinkBalloon"
import { syncReportText, clearStorage } from "../methods/syncReportText"
import { setUsermemoShortcuts } from "../methods/usermemo"
import { getBytesInUse, getStorage } from "../network/storage"
import type { StorageSync } from "../types/storage"

import colorizeDeadlineStyles from "./../style/colorizeDeadline.scss"
import originalButtonStyles from "./../style/originalButton.scss"

window.addEventListener("DOMContentLoaded", () => {
  getStorage({
    kind: "sync",
    keys: null,
    callback: main,
  })
})

const insertStyle = ({
  styleString,
  id,
}: {
  styleString: string
  id?: string
}) => {
  const style = document.createElement("style")
  style.innerHTML = styleString
  if (id) style.id = id
  document.head.appendChild(style)
}

const withDocumentHead = async (storageSync: Partial<StorageSync>) => {
  const url = window.location.href

  insertStyle({
    styleString: colorizeDeadlineStyles.toString(),
  })
  insertStyle({
    styleString: originalButtonStyles.toString(),
  })

  if (storageSync.featuresAssignmentsColoring) {
    const now = dayjs()
    const lang = checkLang()

    if (url.includes("home_library_query")) {
      colorizeDeadline({ checkStatus: false, now, lang })
    } else if (
      url.endsWith("query") ||
      url.endsWith("survey") ||
      url.endsWith("report")
    ) {
      colorizeDeadline({ checkStatus: true, now, lang })
    }
  }

  if (storageSync.featuresAutoSaveReports) {
    if (url.includes("report")) {
      const submitBtn = document.querySelector(
        "input[name='action_ReportStudent_submitdone']"
      )
      if (submitBtn) {
        syncReportText()

        const bytesInUse = await getBytesInUse({ kind: "local" })
        if (bytesInUse > 4500000) {
          clearStorage()
        }
      }
    }
  }
}

const main = (storageSync: Partial<StorageSync>) => {
  if (document.head) {
    withDocumentHead(storageSync)
  } else {
    let headFound = false
    new MutationObserver(() => {
      if (!headFound && document.head) {
        headFound = true
        withDocumentHead(storageSync)
      }
    }).observe(document.documentElement, { childList: true })
  }

  createLinkToOptions()

  if (storageSync.featuresRemoveConfirmation) {
    removeLinkBalloon()
  }

  if (storageSync.featuresFilterCourses) {
    const coursesContainer =
      document.getElementsByClassName("mycourses-body")[0]

    if (coursesContainer) {
      filterCourses()
    }
  }

  if (storageSync.featuresDeadlineHighlighting) {
    const pageLimitView = document.getElementsByClassName(
      "pagelimitview"
    )[0] as HTMLElement
    if (pageLimitView) {
      checkPagePubDeadline(pageLimitView)
    }

    const stdlist = document.getElementsByClassName("stdlist")[0]
    if (stdlist) {
      checkAssignmentDeadline()
    }
  }

  if (storageSync.featuresDragAndDrop) {
    dragAndDrop()
  }

  if (window.location.href.includes("usermemo")) {
    setUsermemoShortcuts()
  }

  chrome.runtime.onMessage.addListener((msg) => {
    switch (msg.kind) {
      case "open-in-respon": {
        const selectedText = window.getSelection()?.toString()
        if (selectedText) openCodeInRespon(selectedText)
        break
      }
    }
  })
}