Better-Devinci

A better leonard-de-vinci portal

目前為 2023-10-11 提交的版本,檢視 最新版本

// ==UserScript==
// @name        Better-Devinci
// @name:cpf    Better-Devinci
// @namespace   Violentmonkey Scripts
// @match       https://www.leonard-de-vinci.net/*
// @match       https://learning.devinci.fr/*
// @license     GNU GPLv3
// @version     2.5
// @author      loliprane
// @description A better leonard-de-vinci portal
// ==/UserScript==

//localstorage setup

// @match       https://www.leonard-de-vinci.net/*
let CheckLocalStorage= function(Item,Base_value){
  if(localStorage.getItem(Item)==null){
    localStorage.setItem(Item,Base_value)
  }
}

let IsLocalStorageTrue= function(Item){
  return localStorage.getItem(Item)=='True'
}

CheckLocalStorage("Version_Better_Devinci","2.2")

CheckLocalStorage("Hide_Slider","False")
CheckLocalStorage("Number_Message_read",0)

CheckLocalStorage("Footer&Scrollbar","True")
CheckLocalStorage("Notification","True")
CheckLocalStorage("SideBar_Diminish","False")
CheckLocalStorage("Hide_news","True")
CheckLocalStorage("Better_Marks","True")
CheckLocalStorage("Finished_Sport_Inscription","False")
//end of localstorage setup

//every page setup
let StudentLanguageFR
let Page_Setup_Portal= function(){
  StudentLanguageFR = document.querySelector('img[src*="/images/flags/"]').currentSrc.includes("fr.png")
  if(IsLocalStorageTrue("Footer&Scrollbar")){
    document.querySelector('html').style.height="0px" //remove the scrollbar when not necessary
    document.querySelector('#footer').remove() // remove the unecessary footer
  }
  if (IsLocalStorageTrue("Notification")) {
    if(document.querySelector('.UD_messages_new'+'.badge').innerText==localStorage.getItem("Number_Message_read")){
      document.querySelector('.UD_messages_new'+'.badge').remove()
      document.querySelector(".UD_messages_new"+".strong").innerText=0
    }
    else {
      let MessageRead_Button = document.createElement("button");
      MessageRead_Button.id = "Message_Read_Button";
      MessageRead_Button.textContent = "Show Messages as read";
      MessageRead_Button.style.color= 'red'
      document.querySelector(".nav-messages-header").append(MessageRead_Button)
      document.querySelector('.UD_messages_new'+'.badge').innerText-=localStorage.getItem("Number_Message_read")
      document.querySelector(".UD_messages_new"+".strong").innerText-=localStorage.getItem("Number_Message_read")


      MessageRead_Button.addEventListener("click", function() {
        localStorage.setItem("Number_Message_read",parseInt(localStorage.getItem("Number_Message_read"))+parseInt(document.querySelector('.UD_messages_new').innerText))
        document.querySelector('.UD_messages_new').remove()
        document.querySelector(".UD_messages_new"+".strong").innerText=0
        MessageRead_Button.remove()
      })
    }
  }

  const BetterDevinci_link = document.createElement("a");
  BetterDevinci_link.id = "BetterDevinci_link"
  BetterDevinci_link.setAttribute("href", "/?Better-Devinci");
  BetterDevinci_link.textContent = "+";
  BetterDevinci_link.style.color = 'red'
  BetterDevinci_link.style.fontWeight='bold'
  BetterDevinci_link.style.fontSize='20px'
  document.querySelector(".navbar-inner-title").append(BetterDevinci_link)

  if(document.querySelector(".social-sidebar"+".sidebar-full")!=null && IsLocalStorageTrue("SideBar_Diminish")){
    document.querySelector(".switch-sidebar-icon"+".icon-align-justify").click()
  }
}
  //end of every page setup

  let Sports= function(){
    if(document.querySelector(".text-center"+".alert"+".alert-success") !=null){
      localStorage.setItem("Finished_Sport_Inscription","True")
    }
  }


let BetterDevinci_Page = function(){
  document.querySelector("#main").querySelectorAll(".container-fluid")[1].remove()
  let Rewrite_Container = document.createElement("div");
  Rewrite_Container.id = "OwO";
  Rewrite_Container.style.margin='10px'
  Rewrite_Container.style.paddingLeft='10px'
  document.querySelector("#main").append(Rewrite_Container)

  const TextPresentation=document.createElement("div");
  TextPresentation.textContent = "This page is still in beta, it lists everything Better-Devinci does and you can activate or deactivate it";
  TextPresentation.style.color= 'red'
  TextPresentation.style.marginBottom='20px'
  Rewrite_Container.append(TextPresentation)

  const data = [
    { name: 'Footer&Scrollbar', description: 'Removes the footer. The scrollbar when useful' },
    { name: 'Notification', description: "Adds a button to mark all messages as read since it's bugged..."},
    { name: 'Hide_news', description: 'Adds the ability to hide & unhide the news panel with a button' },
    { name: 'Better_Marks', description: 'Adds the ability to diminish by semester and module the marks' },
    { name: 'SideBar_Diminish', description: 'Diminish the sidebar when useful to have more place on the page' },
]

  const table = document.createElement('table');
  const headerRow = document.createElement('tr');

  const nameHeaderCell = document.createElement('th');
  nameHeaderCell.textContent = 'Name';
  nameHeaderCell.style.height='50px'
  nameHeaderCell.style.width='200px'
  //headerRow.appendChild(nameHeaderCell);
  const descriptionHeaderCell = document.createElement('th');
  descriptionHeaderCell.textContent = 'Description';
  headerRow.appendChild(descriptionHeaderCell);
  const checkboxHeaderCell = document.createElement('th');
  checkboxHeaderCell.textContent = 'Checkbox';
  headerRow.appendChild(checkboxHeaderCell);

  table.appendChild(headerRow);

  data.forEach(item => {
    const row = document.createElement('tr');

    const nameCell = document.createElement('td');
    nameCell.textContent = item.name;
    nameCell.style.textAlign = 'center';
    //nameCell.style.paddingRight='70px'
    row.appendChild(nameCell);

    const descriptionCell = document.createElement('td');
    descriptionCell.textContent = item.description;
    descriptionCell.style.textAlign = 'center';
    row.appendChild(descriptionCell);

    const checkboxCell = document.createElement('td');
    checkboxCell.style.display = 'flex'
    checkboxCell.style.justifyContent = 'center';
    const checkbox = document.createElement('input');
    checkbox.type = 'checkbox';
    checkboxCell.appendChild(checkbox);
    row.appendChild(checkboxCell);

    if(localStorage.getItem(item.name) === 'True') {
      checkbox.checked = true;
    }

    checkbox.addEventListener('change', function() {
      if (localStorage.getItem(item.name) === 'True') {
        localStorage.setItem(item.name,"False")
      }
      else{
        localStorage.setItem(item.name,"True")
      }
    });

    table.appendChild(row);
  });

  Rewrite_Container.append(table);
}

let Marks= function() {
  if(IsLocalStorageTrue("Better_Marks")){
    const Semestre = document.querySelectorAll(".dd-item");

    const SemestreFiltered = Array.from(Semestre).filter(element => {
      return element.classList.contains("dd-item") && element.classList.length === 1;
    });
    SemestreFiltered.forEach((Parent) =>{
      let Pullright_class=Parent.children[0].children[0]
      Pullright_class.style.fontSize='20px'
      Pullright_class.style.color='red'
      Pullright_class.innerText= "-"
      Pullright_class.style.fontWeight='bold'
      Pullright_class.style.marginRight='3px'
      Parent.children[0].addEventListener("click", function() {
        if(Pullright_class.innerText== "-"){
          Pullright_class.innerText= "+"
          Pullright_class.style.marginRight='0px'

        }
        else{
          Pullright_class.innerText= "-"
          Pullright_class.style.marginRight='3px'
        }

        Array.from(Parent.children).forEach((Child) => {
          if(Child.classList.value.includes('dd-list hide')){
            Child.classList.value = 'dd-list'
          }
          else if (Child.classList.value=='dd-list'){
            Child.classList.value = 'dd-list hide'
          }
        })
      })
    })

    const Module = document.querySelectorAll(".dd-unite-student");

    Module.forEach((Parent) =>{
      let span = document.createElement("span");
      span.className = "UwU";
      span.textContent = "ㅤㅤㅤㅤ-";
      span.style.fontSize='20px'
      span.style.color='purple'
      span.style.fontWeight='bold'
      span.style.paddingRight='3px'
      Parent.children[0].querySelector(".pull-right").appendChild(span)

      Parent.children[0].addEventListener("click", function() {
        let Span_Selector=Parent.children[0].querySelector(".UwU")
        if(Span_Selector.innerText== "ㅤㅤㅤㅤ-"){
          Span_Selector.innerText= "ㅤㅤㅤㅤ+"
          Span_Selector.style.paddingRight='0px'
        }
        else{
          Span_Selector.innerText= "ㅤㅤㅤㅤ-"
          Span_Selector.style.paddingRight='3px'
        }

        Array.from(Parent.children).forEach((Child) => {
          if(Child.classList.value.includes('dd-list hide')){
            Child.classList.value = 'dd-list'
          }
          else if (Child.classList.value=='dd-list'){
            Child.classList.value = 'dd-list hide'
          }
        })
      })
    })
  }
}

let Message= function(){
  const MessageContainer = document.querySelector("#main").children[2]
  if(MessageContainer.children.length==0){
    if(StudentLanguageFR){
      MessageContainer.innerHTML += "<div>Toujours pas réparé... (Regardez vos mail pour les infos ici)</div>"
    }
    else{
      MessageContainer.innerHTML += "<div>They still didn't fix this... (Check your mail for info here)</div>"
    }
  }
}


let MainPage= function(){
  if(IsLocalStorageTrue("Hide_news")){
    const Body = document.querySelector(".body")

    let SliderButton = document.createElement("button");
    SliderButton.id = "Slider_Button";
    SliderButton.textContent = "Hide News";
    Body.parentElement.parentElement.prepend(SliderButton);

    let SliderContainer=Body.parentElement

    if(localStorage.getItem("Hide_Slider")=="True"){
      SliderButton.innerHTML="Show News"
      SliderContainer.className+=' hide'
    }

    SliderButton.addEventListener("click", function() {
      if(localStorage.getItem("Hide_Slider")=="False"){
        SliderButton.innerHTML="Show News"
        SliderContainer.className+=' hide'
        localStorage.setItem("Hide_Slider","True")
      }
        else{
        SliderButton.innerHTML="Hide News"
        SliderContainer.className=SliderContainer.className.replace(" hide","")
        localStorage.setItem("Hide_Slider","False")
      }
    })
  }
  if(document.querySelector(".social-box"+".social-blue").childNodes[1].innerText == "Réinscription"){
    if(document.querySelector(".social-box"+".social-blue").childNodes[3].innerText.includes("Vous êtes maintenant réinscrit(e)")){
      document.querySelector(".social-box"+".social-blue").className+=' hide'
    }
  }
  if(document.querySelector(".alert"+".alert-info") && document.querySelector(".alert"+".alert-info").childNodes[1].innerText == 'Inscription Sports 2023-2024'){
    if(IsLocalStorageTrue("Finished_Sport_Inscription")){
      document.querySelector(".alert"+".alert-info").className+=' hide'
    }
  }
}

function Presence(){
  document.querySelector(".icon-question-sign").parentElement.remove()
}

function CheckPage(){
  if(location.href.includes("www.leonard-de-vinci.net/")){
    Page_Setup_Portal()
    if(location.href == "https://www.leonard-de-vinci.net/"){
      MainPage()
    }
    else if(location.href == "https://www.leonard-de-vinci.net/?Better-Devinci"){
      BetterDevinci_Page()
    }
    else if(location.href == "https://www.leonard-de-vinci.net/?my=marks"){
      Marks()
    }
    else if(location.href.includes("https://www.leonard-de-vinci.net/?my=msg")){
      Message()
    }
    else if(location.href == "https://www.leonard-de-vinci.net/student/presences/"){
      Presence()
    }
    else if(location.href == "https://www.leonard-de-vinci.net/student/sport/"){
      Sports()
    }
  }
  else if(location.href.includes("https://learning.devinci.fr")){
    Page_learning_devinci()
    if(location.href.includes("https://learning.devinci.fr/course/view.php?id=")||location.href.includes("https://learning.devinci.fr/mod") && !location.href.includes("https://learning.devinci.fr/mod/forum")){
      Courses()
    }
    else if(location.href == "https://learning.devinci.fr/my/"){
      Learning_Main_Page()
    }
  }
}

CheckPage()



function Learning_Main_Page(){

  document.querySelector("#inst3124").parentElement.appendChild(document.querySelector("#inst3124"))
  document.querySelector("#page-header").remove()
  document.querySelector("#inst174").remove()
  document.querySelector("#instance-2524-header").remove()
  document.querySelector("#topofscroll").style.setProperty("margin", "0px", "important");
  document.querySelector("#inst2524").children[0].style.setProperty("padding-top", "0px", "important");

  document.querySelector(".mt-0").remove()

  let intervalLearning_Main_Page=setInterval(function(){
    //document.querySelector('[data-region="course-content"]').parentElement.style.gap='5px' // maybe important later
    if(document.querySelectorAll(".dashboard-card-footer").length!=0){
      document.querySelectorAll(".dashboard-card-footer").forEach(function(UwU){UwU.remove()})
      document.querySelectorAll(".muted").forEach(function(UwU){UwU.remove()})
      document.querySelectorAll('[data-region="course-content"]').forEach(function(UwU){
        UwU.style.margin='0px'
        UwU.style.paddingBottom='0px'
      })
      document.querySelectorAll(".multiline").forEach(function(UwU){
          UwU.innerText=UwU.innerText.replace(UwU.innerText.match(/\s\([a-zA-Z0-9-]+\)/g)[0],"")
      })
      document.getElementsByClassName(" block_courses_discover block  card mb-3")[0].remove()
      clearInterval(intervalLearning_Main_Page)
    }
  }, 20)
  /*let observer_Courses = new MutationObserver(function (mutationsList, observer) {
    console.log("observer")
    for (let mutation of mutationsList) {
      if (mutation.type === 'childList' ||true) {
        console.log("passed childlist")
        // Check if added nodes match the criteria
        for (let node of mutation.addedNodes) {
          if(node.nodeType === Node.ELEMENT_NODE && (node.matches(".dashboard-card-footer") || node.matches(".muted"))){
            console.log("test")
            node.remove()
          }
          else if(node.nodeType === Node.ELEMENT_NODE && (node.matches('[data-region="course-content"]'))){
            console.log("test")
            node.style.margin='0px'
            node.style.paddingBottom='0px'
          }
          else if(node.nodeType === Node.ELEMENT_NODE && (node.matches(".multiline"))){
            console.log("test")
            node.innerText=node.innerText.replace(node.innerText.match(/\s\([a-zA-Z0-9-]+\)/g)[0],"")
          }
          else if(node.nodeType === Node.ELEMENT_NODE && (node.matches(".block_courses_discover"))){
            console.log("test")
            node.remove()
          }
        }
      }
    }
  });
  observer_Courses.observe(document, { childList: true, subtree: true });*/
}

function Page_learning_devinci(){
  if(Math.random()>0.90){
      var imgElement = document.createElement("img");
    var imageUrl = "https://i.scdn.co/image/7f0f6e141da13a24d758157c8fcfdd84c48c51d0";
    imgElement.src = imageUrl;
    imgElement.width = 35;
    imgElement.height = 35;
    let replace_img=setInterval(function(){
      if(document.querySelector(".avatar"+".current")){
       document.querySelector(".avatar"+".current").childNodes[1].replaceWith(imgElement)
        clearInterval(replace_img)
      }
    }, 20)
  }
}

function Courses(){
  console.log("in courses")

  if(document.querySelector('#resourceobject'+'[type="application/pdf"]')){
    let OpenPdf = document.createElement("button");
    OpenPdf.id = "OpenPdf"
    OpenPdf.textContent = "Open Pdf";
    OpenPdf.className="btn"
    OpenPdf.style.color='red'
    let interval_Pdf=setInterval(function(){
      if(document.querySelector("#focus-navigation-buttons-start")){
        document.querySelector("#focus-navigation-buttons-start").prepend(OpenPdf)
        clearInterval(interval_Pdf)
      }
    }, 20)
    OpenPdf.addEventListener("click", function() {
      window.open(document.querySelector('#resourceobject'+'[type="application/pdf"]').data)
    })
  }

  else if(document.querySelector('.btn'+'.btn-secondary'+'[type="submit"]')){
    let interval_Folder=setInterval(function(){
      if(document.querySelector('#ygtvc1')){
        if(document.querySelector('#ygtv2') && document.querySelector('#ygtv2').querySelector("[href]").href.includes(".PNG?forcedownload=1")){

          for(let i=0;i<document.querySelector('#ygtvc1').childElementCount;i++){
            //
            let imgsource = document.querySelector('#ygtv'+(i+2))
            let img = document.createElement("img")
            img.classList+="resourceimage"
            img.title = imgsource.querySelector(".fp-filename").innerText
            img.loading="lazy"
            img.src = imgsource.querySelector("[href]").href
            img.style.display = "none";

            imgsource.appendChild(img)
            //
            let Hide_IMG = document.createElement("button");
            Hide_IMG.id = "Hide_IMG"+i;
            Hide_IMG.style.border = "none"
            Hide_IMG.style.borderRadius = "5px"
            if(img.style.display != "none"){
              Hide_IMG.textContent = "Hide Img";
            }
            else{
              Hide_IMG.textContent = "Show Img";
            }


            document.querySelector('#ygtv'+(i+2)).querySelector('.fp-filename-icon').appendChild(Hide_IMG)

            Hide_IMG.addEventListener("click", function() {
              if(img.style.display != "none"){
                img.style.display = "none";
                Hide_IMG.textContent = "Show Img"

              }
              else{
                img.style.display = "block";
                Hide_IMG.textContent = "Hide Img"
              }
            })
          }
        }
        else if(document.querySelector('#ygtv2') && document.querySelector('#ygtv2').querySelector("[href]").href.includes(".pdf?forcedownload=1")){
          for(let i=0;i<document.querySelector('#ygtvc1').childElementCount;i++){
            let link=document.querySelector('#ygtv'+(i+2)).querySelector('a')
            link.href=link.href.replace('?forcedownload=1',"")
            link.target='_blank'
          }
        }
        clearInterval(interval_Folder)
      }
    },20)
  }


  if(location.href.includes("https://learning.devinci.fr/course/view.php")){
    if( document.querySelector("#collapsable_announces") && (document.querySelector("#collapsable_announces").innerText="Vous n'avez pas d'annonce disponible")){
      document.querySelector("#collapsable_announces").previousElementSibling.remove()
      document.querySelector("#collapsable_announces").remove()
    }
    if(document.querySelector(".focus-completion"+".container")){
      document.querySelector(".focus-completion"+".container").remove()
    }
  }
  let counter_HideLocked=0
  let interval_HideLocked=setInterval(function(){
      if(document.querySelector("#theme_boost-drawers-courseindex").querySelectorAll(".restrictions").length!=0){
        console.log("button should be there")

        let HideLockedButton = document.createElement("button");
        HideLockedButton.id = "Slider_Button";
        HideLockedButton.textContent = "Hide Locked";
        document.querySelector("#theme_boost-drawers-courseindex").childNodes[1].append(HideLockedButton);

        HideLockedButton.addEventListener("click", function() {
          let all_Locked = document.querySelector("#theme_boost-drawers-courseindex").querySelectorAll(".restrictions")
          all_Locked.forEach((Locked_Module)=>{
            Locked_Module.style.setProperty("display", "none", "important");
          })
          HideLockedButton.textContent = "Locked are hidden";
          HideLockedButton.disabled = true;
        })
        clearInterval(interval_HideLocked)
      }
      else{
        counter_HideLocked++
        if(counter_HideLocked>50){
          clearInterval(interval_HideLocked)
        }
      }
    }, 50)

  if(document.querySelector("#theme_boost-drawers-courseindex").querySelectorAll(".restrictions").length!=0){

    let HideLockedButton = document.createElement("button");
    HideLockedButton.id = "Slider_Button";
    HideLockedButton.textContent = "Hide Locked";
    document.querySelector("#theme_boost-drawers-courseindex").childNodes[1].append(HideLockedButton);

    HideLockedButton.addEventListener("click", function() {
      let all_Locked = document.querySelector("#theme_boost-drawers-courseindex").querySelectorAll(".restrictions")
      all_Locked.forEach((Locked_Module)=>{
        Locked_Module.style.setProperty("display", "none", "important");
      })
      HideLockedButton.textContent = "Locked are hidden";
      HideLockedButton.disabled = true;
    })
  }
}