ibn_rushd / LingQ

// ==UserScript==
// @name         LingQ
// @namespace    http://tampermonkey.net/
// @version      0.3.8
// @description  same site better UX
// @author       ibn_rushd
// @match        https://www.lingq.com/*
// @license GPL-3.0-or-later; https://www.gnu.org/licenses/gpl-3.0.txt
// @grant        GM_addStyle
// ==/UserScript==

/* jshint esversion: 8 */

var version = "0.3.8";

GM_addStyle(`
.bg-dark {
    background: #091a2f !important;
}

.dashboard-wrap-section  {
    width: 1440px;
    margin: 0 auto;
}

.dashboard-wrap-section p {
    font-family: 'Roboto',sans-serif;
    font-size: 1em;
    line-height: 1.5rem;
    letter-spacing: 0.00625rem;
    font-weight: 400;
    overflow-wrap: break-word;
    color: white;
    margin-bottom: 40px;
}


.dashboard-wrap-section h1 {
    color: white
}

.languages tr:nth-child(even) {
    background: rgba(255,255,255,0.03);
}

table.languages {
    width: 100%;
    font-family: monospace;
    text-align: left;
    color: white;
    font-size: 20px;
    margin-top: 85px;
}

table.languages th {
    color: white;
}

.hero-head .navbar {
    background: #091a2f;
}

table.languages tr th:hover {
    cursor: pointer;
}

table.languages tr th:hover span {
    border-bottom: 2px solid white;
}

table.languages .tr .number {
    width:  90px;
}

table.languages .tr .name {
    width:  150px;
}

table.languages .tr .known {
    width:  130px;
}

table.languages .tr .streak {
    width:  140px;
}

table.languages .tr .mastery {
    width:  140px;
}


table.languages tr th, table.languages tr td {
    vertical-align: bottom;
    font-size: 1em;
    padding: 1.1rem .75rem;
}

.popup.achievement-popup .modal-dialog{
    position: absolute;
    top: 0;
    display: inline-block;
    min-width: 100%;
}

.popup.achievement-popup .modal-dialog .modal-content {
    height: 100vh;
    top: -30px;
    margin: 0;
    padding: 0;
    border-radius: 0;
}

.achievement-popup .close {
    display: none;
}
ul.languages > li > a {
    width: 110px;
    display: inline-block;
}
.autopage-button {
    background: transparent;
    width: 32px;
    height: 32px;
    display: inline-block;
    outline: 0;
    border-radius: 50%;
    padding: 0;
    border: 1px solid #3184de;
    color: #3184de;
    font-size: 50px;
    line-height: 60px;
    margin-top: -1px;
    margin-left: 5px;
}

.autopage-button:hover, .autopage-button:focus, .autopage-button:active {
    background: #3184de;
    color: white;
}

.total-pages {
    margin-right: 20px;
    width: 70px;
    text-align: center;
    background: #2b60a3;
    color: white;
    font-size: 16px;
}

.lesson-card .widget-area {
    box-shadow: none;
}

.rc-slider {
    height: 10px !important;
    border-radius: 0;
    background: #64a9ff!important;
    top: 80px !important;
}

.rc-slider .rc-slider-track{
    height: 10px !important;
    background: #fac138 !important;
}

.rc-slider .rc-slider-handle {
    border-color: #fac138 !important;
    background: #fac138 !important;
    height: 20px !important;
    width: 20px !important;
}

.lingq-audio-player.activated .play-button {
    top: 14px !important;
    left: 34px !important;
}

.lesson-completed {
    background: white !important;
}

.lesson-completed .lesson-head {
    top: 80px;
}

.lesson-card {
    background: transparent;
    box-shadow: none !important;
}

section.lesson-topbar {
    min-height: 84px !important;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,.15);
    margin-bottom: 25px !important;;
    border-radius: 4px !important;
}

.app-nav-wrapper .app-nav .navbar-collapse .navbar-nav.import-menu-item {
    background: transparent;
}

.lingq-audio-player .time {
    top: 55px !important;
    font-size: 14px !important;
    left: 87px!important;
}

.lesson-card .lesson-content {
    border-radius: 4px; !important;
    padding-top: 15px;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,.15);
    background: white;
}

.body-progress {
    background: white;
    height: 4px;
    position: absolute;
    z-index: 1;
    transition-duration: 2000ms;
}
.version {
    text-align: center;
    background: #7eb9ff;
}

.app-nav-wrapper .app-nav .container {
    width: 1200px !important;
}

.streak-in-top-nav:after {
    content: "\\E013";
    order: 1;
    font-family: Glyphicons Halflings;
    border-radius: 50%;
    width: 21px;
    height: 21px;
    display: block;
    float: right;
    margin-left: 9px;
    font-size: 10px;
    padding: 0px 5px;
    background: #444444;
}

body #app {
    overflow-y: hidden !important;
}

#app, .app-nav {
    background: linear-gradient(120deg, #2b60a3 550px, #3584de 550px) !important;
}

.dashboard-top-stats {
    height: 100px;
    margin-bottom: 20px;
    color: white;
    margin-left: -60px;
    margin-right: -30px
}

.dashboard-top-stats li {
    height: 100px;
    display: block;
    width: calc(33% - 40px);
    float: left;
    margin: 20px;
    padding: 20px;
    background: #1f1f30;
}

.status-bar .status-0 {
    background: white !important;
    color: #444 !important;
    font-size: 16px !important;
    height: 42px;
}

.btn:focus.status-0, .status-0.active, .status-0:hover{
    background: #e2de40 !important;
}

.btn:focus.status-5, .btn.status-5.active, .btn.status-5:hover{
    background: #e24040 !important;
}

.display-total-words .label-bullet {
    border: 1px solid black;
}

.display-percentage-unknown .label-bullet {
    background: #ff5959;
}

.lessons-wrap .current-lesson {
    background: #f6f6f6;
    padding: 30px 10px !important;
    box-shadow: 0 5px 5px 0 #c3bfbf;
    margin: 0 0px 5px 0px;
}

.today-counter span {
    color: white;
    position: relative;
    height: 55px;
    line-height: 55px;
    z-index: 1;
}

.today-counter .btn_update {
    color: black;
    padding: 0 10px 0 10px;
    cursor: pointer;
    font-size: 25px;
    color: white;
    transform: rotate(154deg);
    transition: transform 800ms ease;
}

.btn_update:hover {
    transform: rotate(0deg);
    padding: 0 10px 0 10px;
    top: -1px;
}

.lessons-wrap {
    padding: 0px !important;
}

.lessons-wrap .lesson-item k
    padding: 10px !important;
}`
);

//BEFORE LOAD HAPPENS
//11b (beta) show loading bar for webpage
showLoadingBar(10);

var base_url = "https://lingq.com";
var data = [];
var topbar = document.querySelector('.counters.nav');
var lang = window.location.pathname.split('/')[3];
var api_url = "https://www.lingq.com/api/v2/";
var span_lingq;
var span_mastery;
var current_lesson_link;
var total_linq_of_lesson;
var supported_languages = [
    "ar",
    "da",
    "de",
    "en",
    "es",
    "fr",
    "id",
    "ru",
    "tr"
];
var mastery_lessons = {
    ar: 690829,
    da: 836059,
    de: 836064,
    en: 854377,
    es: 836067,
    fr: 689806,
    id: 835925,
    ru: 690605,
    tr: 836056
};

var unique_words = {
    ar: 5001,
    da: 4999,
    de: 4988,
    en: 5329,
    es: 4994,
    fr: 4998,
    id: 4919,
    ru: 4963,
    tr: 4950
};


function setTotalLingqOfLesson() {
    console.log("setTotalLingqOfLesson()");
    if (window.location.href.indexOf("lesson/") != -1) {
        var l = document.querySelector(".words-index").innerText.split("(")[1].split(")")[0];
        total_linq_of_lesson = Number(l);
    }
}
function setContinueButtonInCourse() {
    console.log("setContinueButtonInCourse");
    if (window.location.href.indexOf("course") != -1) {
        waitForElement(".action-list", function() {
            var action_list = document.querySelector(".action-list");
            var li = document.createElement("li");
            var a = document.createElement("a");
            li.setAttribute('class','action-item continue');
            a.innerHTML = "Continue with Lesson;";
            a.addEventListener('click', function() { goToCurrentLesson();});
            li.appendChild(a);
            action_list.appendChild(li);
        });
    }
}

function showLoadingBar(number) {
    if (window.location.pathname !== "/en/") {
        console.log("showLoadingBar()");

        if (!number) {
            setTimeout(function () {
                let progress  = document.querySelector(".body-progress");
                progress.remove();
            }, 2000);
            return;
        }

        if (number === 10) {
            waitForElement("header nav", function () {
                var nav = document.querySelector("header nav");
                var progress_loading = document.createElement("div");
                progress_loading.classList.add("body-progress");

                var nav_container = document.querySelector("#main-nav");
                nav_container.insertBefore(progress_loading, nav);
            });
        }

        waitForElement(".body-progress", function () {
            document.querySelector(".body-progress").style.width = number + "%";
        });
    }
}

function goToCurrentLesson() {
    window.location = base_url + current_lesson_link;
}

function setLingqDailies() {
    if (window.location.href.indexOf("learn") != -1) {
        var today_counter = document.createElement("li");
        today_counter.setAttribute('class','today-counter counter-item');
        var lingq_text = document.createElement("span");
        lingq_text.setAttribute('class','lingq_text');
        var btn_update = document.createElement("span");
        btn_update.setAttribute('class','btn_update');
        btn_update.innerHTML = "↺";
        today_counter.appendChild(lingq_text);
        today_counter.appendChild(btn_update);
        topbar.appendChild(today_counter);
        span_lingq = document.querySelector('.today-counter.counter-item .lingq_text');
        span_mastery = document.querySelector('.navbar-nav.counters .coin-counter .count');
        btn_update = document.querySelector('.today-counter.counter-item .btn_update');
        btn_update.addEventListener('click', function() { updateDailyLingq(); }, false);
        span_lingq.innerText = "?? Lingq's";
    }
}

async function updateDailyLingq() {
    if (window.location.href.indexOf("learn") != -1) {
        showStreakInTopNav(); 
        console.log("updateDailyLingq");

        span_lingq.innerText = "Loading...";
        var response = await fetch(api_url + lang + "/milestones/").then(response => response.json());
        span_lingq.innerText = response.stats.lingqs_daily + "/" + LINGQ_SETTINGS.dailyLingqsGoal + " Lingq's";
    }
}

function continueWithLastLessonInCourse() {
    console.log("connectTriggersToBlueWords");

    if (window.location.href.indexOf("course") != -1) {
        waitForElement(".lessons-wrap .lesson-list", function() {
            var lessons = document.querySelector('.lessons-wrap .lesson-list');
            var lessons_items = document.querySelector('.lessons-wrap .lesson-list .lesson-item');
            var total_completed = document.querySelectorAll('.completed').length;
            var current_lesson = lessons.childNodes[total_completed];
            lessons.insertBefore(current_lesson, lessons.firstChild);
            lessons.firstChild.classList.add("current-lesson");
            current_lesson_link = document.querySelector(".current-lesson a").getAttribute("href");
        });
    }
}

function logoLinksToDashboard() {
    if (window.location.href.indexOf("learn") != -1) {
        document.querySelector(".navbar-brand").setAttribute("href", "/en");
    }
}

async function getLanguages(filter, lang) {
    response = await fetch(api_url + "languages/").then(response => response.json());
    if (filter === "active") {
        var result = [];
        response.forEach(function (item) {
            if (item.knownWords > 0) {
                result.push([item.title, item.knownWords, item.code]);
            }
        });

        return result.sort();
    }

    if (filter === "last_week") {
        response = await fetch(api_url + lang + "/progress/?interval=last_week").then(response => response.json());
        document.querySelector(".languages ." + lang + " .today").innerHTML= "(" + response.knownWords + ")";
    }

    return response;
}

async function getRecentLesson(lang) {
    let response = await fetch(api_url + lang + "/lessons/recent/?page_size=1");
    let result = await response.json();
    result = result.results[0];

    let id = result.contentId;
    let lesson_url = base_url + "/en/learn/" + lang + "/web/lesson/" + id;
    let title = result.collectionTitle;

    ret = [title, lesson_url];

    return ret;
}


function sortTable(n) {
    var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
    table = document.getElementById("languages");
    switching = true;
    // Set the sorting direction to ascending:
    dir = "asc";
    /* Make a loop that will continue until
    no switching has been done: */
    while (switching) {
      // Start by saying: no switching is done:
      switching = false;
      rows = table.rows;
      /* Loop through all table rows (except the
      first, which contains table headers): */
      for (i = 1; i < (rows.length - 1); i++) {
        // Start by saying there should be no switching:
        shouldSwitch = false;
        /* Get the two elements you want to compare,
        one from current row and one from the next: */
        x = rows[i].getElementsByTagName("TD")[n];
        y = rows[i + 1].getElementsByTagName("TD")[n];

        var x_value;
        var y_value;

        if(isNaN(parseFloat(x.innerHTML))){
            x_value  =  x.innerHTML.toLowerCase();
        } else {
            x_value = parseFloat(x.innerHTML);
        }

        if(isNaN(parseFloat(y.innerHTML))){
            y_value  =  y.innerHTML.toLowerCase();
        } else {
            y_value = parseFloat(y.innerHTML);
        }

        if (dir == "asc") {
          if (x_value > y_value) {
            // If so, mark as a switch and break the loop:
            shouldSwitch = true;
            break;
          }
        } else if (dir == "desc") {
          if (x_value < y_value) {
            // If so, mark as a switch and break the loop:
            shouldSwitch = true;
            break;
          }
        }
      }
      if (shouldSwitch) {
        /* If a switch has been marked, make the switch
        and mark that a switch has been done: */
        rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
        switching = true;
        // Each time a switch is done, increase this count by 1:
        switchcount ++;
      } else {
        /* If no switching has been done AND the direction is "asc",
        set the direction to "desc" and run the while loop again. */
        if (switchcount == 0 && dir == "asc") {
          dir = "desc";
          switching = true;
        }
      }
    }
  }

function setUpDashboard() {
    console.log("setUpDashboard");
    if (window.location.pathname === "/en/") {
        document.querySelector(".hero-body").remove();
        document.querySelector(".hero-foot").remove();
        document.querySelector(".section-library").remove();
        document.querySelector(".section-providers").remove();
        document.querySelector(".section-features").remove();
        document.querySelector(".section-cta").remove();
        document.querySelector(".section-steve").remove();
        document.querySelector(".section-community").remove();
        document.querySelector(".section-testimonials").remove();
        document.querySelector(".section-featured").remove();
        document.querySelector(".section-devices").remove();

        document.querySelector("section").classList.remove("hero");
        document.querySelector("section").classList.remove("is-black");
        document.querySelector("section").classList.add("dashboard-wrap-section");
        document.querySelector("section").classList.add("bg-dark");
        document.querySelector("body").classList.add("bg-dark");
        document.querySelector("head title").innerText = "Dashboard - LingQ Learning Languages Simply";

        //active languages
        getLanguages("active").then( languages => {
            var list = document.createElement("table");
            list.classList.add("languages");
            list.setAttribute("id", "languages");
            var tr = document.createElement("tr");
            var th = document.createElement("th");
            th.innerHTML = "<span>#</span>"
            th.addEventListener("click", () => sortTable(0));
            tr.appendChild(th);
            var th = document.createElement("th");
            th.innerHTML = "<span>Language</span>"
            th.addEventListener("click", () => sortTable(1));
            tr.appendChild(th);
            var th = document.createElement("th");
            th.innerHTML = "<span>Known</span>"
            th.addEventListener("click", () => sortTable(2));
            tr.appendChild(th);
            var th = document.createElement("th");
            th.innerHTML = "<span>Streak</span>"
            th.addEventListener("click", () => sortTable(3));
            tr.appendChild(th);
            var th = document.createElement("th");
            th.innerHTML = "<span>Mastery</span>"
            th.addEventListener("click", () => sortTable(4));
            tr.appendChild(th);
            var th = document.createElement("th");
            th.innerHTML = "<span>Lesson</span>"
            th.addEventListener("click", () => sortTable(5));
            tr.appendChild(th);
            list.appendChild(tr);

            console.log(languages);
            languages.forEach(function (item, index) {
                var tr = document.createElement("tr");
                tr.classList.add(item[2]);

                var td = document.createElement("td");
                td.classList.add("rank");
                td.innerText = index + 1;
                tr.appendChild(td);

                var td = document.createElement("td");
                td.innerHTML = "<a href='/en/learn/" + item[2] + "/web/'>" + item[0] + "</a>" ;
                td.classList.add("name");
                tr.appendChild(td);

                td = document.createElement("td");
                td.classList.add("known");
                td.innerText = item[1];
                tr.appendChild(td);

                td = document.createElement("td");
                td.classList.add("streak");
                tr.appendChild(td);

                td = document.createElement("td");
                td.classList.add("mastery");
                tr.appendChild(td);

                td = document.createElement("td");
                td.classList.add("lesson");
                tr.appendChild(td);

                list.appendChild(tr);
            });
            document.querySelector("section").appendChild(list);
        });

        //streak
        getLanguages("active").then( languages => {
            languages.forEach(function (item) {
                langIsOnStreak(item[2]).then(function(result) {
                    td = document.querySelector(".languages ." + item[2] + " .streak");
                    console.log("streak" + result + item[2])
                    if (result) {
                        td.innerHTML = "streak";
                    } else {
                        td.innerHTML = "no";
                    }
                });
            });
        });

        //mastery
        getLanguages("active").then( languages => {
            languages.forEach((item) => {
                console.log("dave");
                getPercentageOfMastery(item[2]).then( percent => {
                    document.querySelector(".languages ." + item[2] + " .mastery").innerHTML = percent.toFixed(2) + "%";
                });
            });
        });

        //recent lesson
        getLanguages("active").then( languages => {
            languages.forEach(function (item) {
                getRecentLesson(item[2]).then( recent => {
                    a = document.createElement("a");
                    a.innerText = recent[0];
                    a.setAttribute('href', recent[1]);
                    document.querySelector(".languages ." + item[2] + " .lesson").appendChild(a);
                });
            });
        });
    }
}

function disableReviewPage() {
    if (window.location.href.indexOf("review") != -1) {
        window.location = base_url + "/learn/" + lang + "/web";
    }
}

function waitForElement(id, callback){
    var poops = setInterval(function(){
        if(document.querySelector(id)){
            clearInterval(poops);
            callback();
        }
    }, 100);
}

function waitForValue(callback){
    var poops = setInterval(function(){
        if(document.querySelectorAll(".display-lingqs")[1].getAttribute("title").split(" ")[0] !== "0"){
            clearInterval(poops);
            callback();
        }
    }, 100);
}

function addGlyph() {
    var dislike = document.querySelector(".status-bar .status-0");
    if (document.querySelector(".status-4").classList.contains("active") || document.querySelector(".status-5").classList.contains("active")) {
        dislike.className = "status-0 btn btn-default glyphicon glyphicon-link";
    } else {
        dislike.className = "status-0 btn btn-default active glyphicon glyphicon-link";
    }
    dislike.innerHTML = "";
}

function likeDislikeLingq() {
    if (window.location.href.indexOf("lesson/") != -1) {
        console.log("likeDislikeLingq()");
        waitForElement(".status-1", function() {
            if (document.querySelector(".status-bar .status-1")) {
                document.querySelector(".status-bar .status-1").remove();
                document.querySelector(".status-bar .status-2").remove();
                document.querySelector(".status-bar .status-3").remove();
            }
            //TODO: this should be coded in a better way
            addGlyph();
            document.querySelector(".status-bar .status-0")
                .addEventListener('click', function () { addGlyph(); });
            document.querySelector(".status-bar .status-4")
                .addEventListener('click', function () { addGlyph(); });
        });
    }
}

function checkIfLingqTotalChanged() {
    console.log("checkIfLingqTotalChanged()");
    let current_total_lingq_of_lesson = Number(document.querySelector(".words-index").innerText.split("(")[1].split(")")[0]);

    if (Number(total_linq_of_lesson) != current_total_lingq_of_lesson) {
        total_linq_of_lesson = current_total_lingq_of_lesson; 
        updateDailyLingq();
    }
}

function whenWordIsClikedDo() {
    if (window.location.href.indexOf("lesson/") != -1) {
        console.log("whenWordIsClikedDo()");
        waitForElement(".card-widget", function () {
            if(document.querySelectorAll(".yellow-wrap").length === 1) {
                likeDislikeLingq();
            }
            var card_widget = document.querySelector(".widget-area");
            var observer = new MutationObserver(function() {
                console.log("something got clicked");
                likeDislikeLingq();
                checkIfLingqTotalChanged();
                refreshPageNumber();
                cleanUpSentences();
            });
            observer.observe(card_widget, {subtree: true, childList: true});
        });
    }
}

function addProfileLinkInTopNav() {
    if (window.location.href.indexOf("learn") != -1) {
        var li = document.createElement("li");
        li.innerHTML = '<a class="profile" href="/en/learn/' + lang + '/web/profile">Profile</a>';

        var left_nav = document.querySelector(".left-nav");
        left_nav.appendChild(li);
    }

    if (window.location.href.indexOf("profile") != -1) {
        document.querySelector(".left-nav").classList.remove("community");
        document.querySelector(".left-nav .profile").style.border = "1px solid";
    }
}

async function langIsOnStreak(lang) {
    response = await fetch(api_url + lang + "/progress/?interval=today").then(response => response.json());
    goal = Number.parseInt(response.cardsCreatedGoal, 10);
    created = Number.parseInt(response.cardsCreated, 10);
    if (goal <= created) {
        return true;
    }
    return false;
}

async function showStreakInTopNav() {
    console.log("showStreakInTopNav()");
    if (window.location.href.indexOf("learn") != -1) {
        if (await langIsOnStreak(lang)) {
            document.querySelector(".streak-counter .count").classList.add("streak-in-top-nav");
        }
    }
}

function removeRightPane() {
    var known_words = document.querySelector('.known-words.counter');
    if (known_words) {
        known_words.remove();
        document.querySelector('.header-title').remove();
        document.querySelector('.dailygoal-section').remove();
        document.querySelector('.challenges-tab').remove();
    }
}

function addFooter() {
    console.log("addFooter");
}

function addSortByInCourses() {
    if (window.location.href.indexOf("course") != -1) {
        waitForElement(".footer .extra-info", function() {
            var list = document.querySelector(".footer .extra-info");
            var article = document.createElement("article"); 
            var select = document.createElement("select"); 
            select.addEventListener("change", () => sortCourse());
            var p = document.createElement("p"); 

            var option = document.createElement("option"); 
            option.innerText = "Default";
            option.setAttribute("value", "Default");
            option.setAttribute("selected", "selected");

            var option2 = document.createElement("option"); 
            option2.innerText = "Alphabetical";
            option2.setAttribute("value", "Alphabetical");

            var option3 = document.createElement("option"); 
            option3.innerText = "Lingq";
            option3.setAttribute("value", "Lingq");

            var option4 = document.createElement("option"); 
            option4.innerText = "Likes";
            option4.setAttribute("value", "Likes");

            var option5 = document.createElement("option"); 
            option5.innerText = "Unknown words";
            option5.setAttribute("value", "Unknown words");

            var option6 = document.createElement("option"); 
            option6.innerText = "Duration";
            option6.setAttribute("value", "Duration");

            var option7 = document.createElement("option"); 
            option7.innerText = "Total words";
            option7.setAttribute("value", "Total words");

            select.appendChild(option);
            select.appendChild(option2);
            select.appendChild(option3);
            select.appendChild(option4);
            select.appendChild(option5);
            select.appendChild(option6);
            select.appendChild(option7);

            article.classList.add("extra-info-item"); 
            article.innerHTML = "<p>Sort by: </p>"; 
            article.firstChild.appendChild(select); 
            list.insertBefore(article, list.firstChild);
        });
    }
}
  
function addMoreCourseInfo() {
    if (window.location.href.indexOf("course") != -1) {
        console.log("addMoreCourseInfo");
        var show_duration = false;

        waitForElement(".lesson-item .quick-stats", function () {
            waitForValue(function (){
                document.querySelectorAll(".lesson-item .quick-stats").forEach(function (item) {
                    if (item.parentNode.parentNode.querySelector(".lesson-length").children.length === 3) {
                        //var duration = item.parentNode.parentNode.querySelector(".lesson-length span").children[1].innerText;
                        //var stat_duration = document.createElement("span"); 
                        //stat_duration.classList.add("quick-stat-item");
                        //stat_duration.classList.add("display-duration");
                        //stat_duration.innerHTML = '<img class="label-bullet" src="/static/webapp/images/icons/head-set-icon.svg">' + duration;
    
                        var length = item.parentNode.parentNode.querySelectorAll(".lesson-length span")[3].innerText;
                        length = length.split(": ")[1];
                        var stat_total_words = document.createElement("span"); 
                        stat_total_words.classList.add("quick-stat-item");
                        stat_total_words.classList.add("display-total-words");
                        stat_total_words.innerHTML = '<span class="label-bullet"></span>' + length;
                    } else {
                        var length = item.parentNode.parentNode.querySelector(".lesson-length").innerText.split(":")[2]
                        var stat_total_words = document.createElement("span"); 
                        stat_total_words.classList.add("quick-stat-item");
                        stat_total_words.classList.add("display-total-words");
                        stat_total_words.innerHTML = '<span class="label-bullet"></span>' + length;
    
                    }
    
                    var blue_words = item.querySelector(".display-bluewords").innerText.split("(")[0];
                    var yellow_words = item.querySelector(".display-lingqs").getAttribute("title").split(" ")[0];
    
                    if (yellow_words === "0") {
    
                    }
                    var percentage_unknown = (Number(blue_words) + Number(yellow_words)) / length * 100;
    
                    console.log(yellow_words)
                    console.log(blue_words)
    
                    console.log("length:" + length);
                    console.log("percentage:" + percentage_unknown)
    
                    var stat_percentage_unknown = document.createElement("span"); 
                    stat_percentage_unknown.classList.add("quick-stat-item");
                    stat_percentage_unknown.classList.add("display-percentage-unknown");
                    stat_percentage_unknown.innerHTML = '<span class="label-bullet"></span><b>' + percentage_unknown.toFixed(2) + "%</b>";
                                  
                    if (show_duration) {
                        item.append(stat_duration);
                    }
    
                    item.append(stat_total_words);
                    item.append(stat_percentage_unknown);
                });
            });
        });

    }
}

function sortCourse() {
    var list = [];
    var counter = 0;
    var schedule = [];
    var flip = false;

    let select = document.querySelector(".footer .extra-info select");
    if (select.value === "Default") {
        // QUICK FIX
        window.location.reload(false);
    }

    if (select.value === "Alphabetical") {
        flip = true;
        console.log("sort by: Alphabetical");
        list = [];
        counter = 0;
        document.querySelectorAll("section .lesson-title h3.title").forEach(function (item) {
            var temp = [counter, item.innerText];
            list.push(temp);
            counter++;
        });
        console.log("list");
        console.log(list);
        schedule = [];
        schedule = list.sort(function (a, b) {
            return (a[1].toLowerCase() < b[1].toLowerCase()) ? -1 : 1;

        });
        console.log("alpha_list");
        console.log(schedule);

    }

    if (select.value === "Lingq") {
        flip = true;
        console.log("sort by: Lingq");
        list = [];
        counter = 0;
        document.querySelectorAll("section .lesson-item .display-lingqs").forEach(function (item) {
            var temp = [counter, item.innerText];
            list.push(temp);
            counter++;
        });
        console.log("list");
        console.log(list);
        schedule = [];
        schedule = list.sort(function (a, b) {
            return (parseInt(a[1]) < parseInt(b[1])) ? -1 : 1;
        });
        scedule = schedule.reverse();
        console.log("lingq_list");
        console.log(schedule);
    }

    if (select.value === "Likes") {
        flip = false;
        console.log("sort by: Likes");
        list = [];
        counter = 0;
        document.querySelectorAll("section .lesson-item .display-rose").forEach(function (item) {
            var temp = [counter, item.innerText];
            list.push(temp);
            counter++;
        });
        console.log("list");
        console.log(list);
        schedule = [];
        schedule = list.sort(function (a, b) {
            return (parseInt(a[1]) < parseInt(b[1])) ? -1 : 1;

        });
        console.log("likes_list");
        console.log(schedule);
    }

    if (select.value === "Unknown words") {
        console.log("sort by: Unknown words");
        flip = false;
        list = [];
        counter = 0;
        document.querySelectorAll("section .lesson-item .display-bluewords").forEach(function (item) {
            var temp = [counter, item.innerText.split("(")[0]];
            list.push(temp);
            counter++;
        });
        console.log("list");
        console.log(list);
        schedule = [];
        schedule = list.sort(function (a, b) {
            return (parseInt(a[1]) < parseInt(b[1])) ? -1 : 1;

        });
        console.log("unknown_words_list");
        console.log(schedule);
    }

    if (select.value === "Duration") {
        console.log("sort by: Duration");
        flip = false;
        list = [];
        counter = 0;
        document.querySelectorAll(".display-duration").forEach(function (item) {
            var minutes = parseInt(item.innerText.split(":")[0], 10);
            console.log(counter + "minutes: " + minutes);
            var seconds = parseInt(item.innerText.split(":")[1].split("m")[0], 10);
            console.log(counter + "seconds: " + seconds);
            var time = parseInt((parseInt(minutes, 10)*60) + parseInt(seconds, 10), 10);
            console.log(counter + "time: " + time);

            var temp = [counter, time];
            list.push(temp);
            counter++;
        });
        console.log("list");
        console.log(list);
        schedule = [];
        schedule = list.sort(function (a, b) {
            return (parseInt(a[1]) < parseInt(b[1])) ? -1 : 1;

        });
        console.log("duration_list");
        console.log(schedule);
    }


    if (select.value === "Total words") {
        flip = false;
        console.log("sort by: Total words");
        list = [];
        counter = 0;
        document.querySelectorAll(".display-total-words").forEach(function (item) {
            var temp = [counter, item.innerText];
            list.push(temp);
            counter++;
        });
        console.log("list");
        console.log(list);
        schedule = [];
        schedule = list.sort(function (a, b) {
            return (parseInt(a[1]) < parseInt(b[1])) ? -1 : 1;

        });
        console.log("total_words_list");
        console.log(schedule);
    }

    hussle(getScheduleFrom(schedule), flip);
}

function getScheduleFrom(list) {
    let result = [];
    list.forEach(function (item) {
        result.push(item[0]);
    });
    return result;
}

function hussle(schedule, flip) {
    var lessons = document.querySelector('.lessons-wrap .lesson-list');
    var list = [];

    schedule.forEach(function (position) {
        list.push(lessons.childNodes[position]);
    });

    if (flip) {
        list.reverse();
    }

    list.forEach(function (item) {
        lessons.insertBefore(item, lessons.firstChild);
    });
}

function recentlyTab() {
    var correct_page = false;
    var urls = ["feed", "my-lessons", "vocabulary", "playlist"];
    urls.forEach(function(item) {
        if (window.location.href.indexOf(item) != -1) {
            correct_page = true;
        }
    });

    if (correct_page) {
        var global_tabs = document.querySelector(".main-section .nav-tabs");
        var li = document.createElement("li"); 
        li.innerHTML = "<a>Recently</a>"; 
        global_tabs.insertBefore(li, global_tabs.firstChild);
    }
}

function addVersionInPage() {
    var div_version = document.createElement("div");
    div_version.classList.add("version");
    div_version.innerText = version;
    if (window.location.pathname ===  "/en/") {
        waitForElement("#languages", function() {
            document.querySelector("#languages").append(div_version);
        })
    } else {
        document.querySelector("#app").append(div_version);
    }

}

function getCurrentSegment(segments) {
    for (var i = 0; i < segments.length; i++) {
        if(segments[i].classList.contains("current")) {
            return i + 1;
        }
    }
}

function addPageNumber() {
    console.log("addPageNumber()");
    if (window.location.href.indexOf("lesson/") != -1) {
        var div_total_pages = document.createElement("div");
        div_total_pages.classList.add("total-pages");
        text_mode_toggle = document.querySelector(".text-mode-toggle"); 

        waitForElement(".text-mode-toggle", function() {
            waitForElement(".current", function() {
                div_total_pages.innerText = "Page: ?/?";
                text_mode_toggle.parentElement.insertBefore(div_total_pages, text_mode_toggle);
                refreshPageNumber();
            });
        });
    }
}

function getSentenceMode(button) {
    console.log("getSentenceMode()");
    if (button) {
        var sentece_mode = button.path[0].classList[0];
        if (sentece_mode === "sentence-size") {
            return true;
        }
    }
    return false;
}

function refreshPageNumber(button) {
    console.log("refreshPageNumber()");
    var sentence_mode = getSentenceMode(button);
    console.log("sentence_mode" + sentence_mode);

    waitForElement(".total-pages", function () {
        var segments = document.querySelectorAll(".segment");
        var position = getCurrentSegment(segments);
        var total_pages = document.querySelector(".total-pages");
        total_pages.innerText = position + " of " + segments.length;
    });

}

function eventListenerForTextMode() {
    waitForElement(".text-mode-toggle", function () {
        text_mode_toggle = document.querySelector(".text-mode-toggle"); 
        text_mode_toggle.addEventListener('click', function(item) { 
            refreshPageNumber(item);
        }
        );
    });
}

function nextLesson() {
    console.log("nextLesson()");
    waitForElement(".sentence-item", function () {
        location.reload();
    });
}

function eventListenerForNextLesson() {
    waitForElement(".next-lesson .btn", function () {
        next_lesson = document.querySelector(".next-lesson .btn"); 
        next_lesson.addEventListener('click', function() { 
            nextLesson();
        }
        );
    });
}

function eventListenerForUpArrow() {
    if (window.location.href.indexOf("lesson/") != -1) {
        console.log("eventListenerForUpArrow()");
        document.onkeydown = function(e) {
            switch (e.key) {
                case 'ArrowUp':
                    console.log('translate');
                    document.querySelector(".loadedContent > .btn").click();
                    if (document.querySelectorAll(".lingq-word").length > 0) {
                        document.querySelectorAll(".lingq-word")[0].click()
                    } else {
                        if (document.querySelectorAll(".blue-word").length > 0) {
                            document.querySelectorAll(".blue-word")[0].click()
                        }
                    }
                    break;

                case '/':
                    console.log('known word');
                    //TODO: when clicking a dot in all 3 situations it makes the word known
            }
        };
    }
}

function cleanUpSentences() {
    if (window.location.href.indexOf("lesson/") != -1) {

        console.log("cleanUpSentences()");

        var clean_up = true;
        var final_punctuation = [];
        var span;
        waitForElement(".sentence-text .loadedContent", function() {
            var max_sections = document.querySelector(".sentence-text .loadedContent .sentence-tts-wrap p").childElementCount;

            for (let i = 0; i < max_sections; i++) {  
                var max_sentences = document.querySelector(".sentence-text .loadedContent .sentence-tts-wrap p").childNodes[i].childElementCount;
                var punctuation = [];
                for (let j = 0; j < max_sentences; j++) {
                    //find a punctuation
                    span = document.querySelector(".sentence-text .loadedContent .sentence-tts-wrap p").childNodes[i].childNodes[j];

                    if (span.getAttribute("class") === "sentence-item punctuation") {
                        punctuation.push(j);
                    }
                }

                if (clean_up) {
                    console.log("cleanUpSentences()");
                    document.querySelector(".sentence-text .loadedContent .sentence-tts-wrap p").childNodes[i].style.visibility = "visible";
                }

                final_punctuation.push(punctuation);
                punctuation = [];
            }

            for (let i = 0; i < final_punctuation; i++) {
                document.querySelector(".sentence-text .loadedContent .sentence-tts-wrap p").childNodes[i].childNodes[j]
            }
        });
    }
}

async function showPercentageOfMastery() {
    console.log("showPercentageOfMaster");

    if (supported_languages.includes(lang)) {
        mastery_id = mastery_lessons[lang];
        var response = await fetch("https://www.lingq.com/api/v3/" + lang + "/collections/counters/?collection=" + mastery_id).then(response => response.json());
        var response = Object.entries(response);
        var newWordsCount = Number(response[0][1]["newWordsCount"]);
        var uniqueWordCount = unique_words[lang];
        var yellowCount = Number(response[0][1]["cardsCount"])

        var total = (1 - (newWordsCount + yellowCount) / uniqueWordCount) * 100;
        span_mastery.innerText = total.toFixed(2) + "%";

    } else {
        span_mastery.innerText = "lang unknown %";
    }
}

async function getPercentageOfMastery(lang) {
    mastery_id = mastery_lessons[lang];

    var response = await fetch("https://www.lingq.com/api/v3/" + lang + "/collections/counters/?collection=" + mastery_id).then(response => response.json());
    console.log(response);
    var response = Object.entries(response);
    var newWordsCount = Number(response[0][1]["newWordsCount"]);
    var uniqueWordCount = unique_words[lang];
    var yellowCount = Number(response[0][1]["cardsCount"])


    console.log("newWordsCount: " + newWordsCount)
    console.log("uniqueWordCount: " + uniqueWordCount)
    console.log("yellowCount: " + yellowCount)

    return total = (1 - (newWordsCount + yellowCount) / uniqueWordCount) * 100;
}

function open_links() {
    supported_languages.forEach(function(item) {
        getRecentLesson(item).then((result) => {
            console.log(result);
            var lesson = result[1]
            window.open(lesson);
        });
    })
}

function setUpOpenAllLanguagesLinkInDashboard() {
    if (window.location.pathname === "/en/") {
        var a = document.createElement("a");   // Create a <button> element
        a.innerHTML = "Open All"; 
        a.style.top = "79px";
        a.style.fontSize = "30px";
        a.style.position = "relative";
        a.addEventListener ("click", open_links, false);
        document.querySelector("section").appendChild(a); 
    }
}

function removeWhiteSentences()  {
    if (window.location.href.indexOf("lesson") !== -1) {
        waitForElement(".sentence-tts-wrap p", function() {
            document.querySelectorAll(".sentence-tts-wrap p").forEach((item) => {
                console.log(item);
                if (item.innerHTML.search("lingq-word")  !== -1 && item.innerHTML.search("blue-word")  !== -1 ) {
                    item.style.display = "none";
                }
            });
        });
    }

}

//01. (alpha) never allow the review page redirect to lessons
disableReviewPage();

//05b. (beta) page /dashboard has some info about all languages you are learning
setUpDashboard();
showLoadingBar(20);

addEventListener('load', function () {
    //02a. (beta) add total lingq in top bar
    //02b. (beta) update btn for daily lingq
    //02c. (beta) update daily lingq when loaded.
    //02d. (beta) total lingq of lesson.
    setLingqDailies();
    updateDailyLingq();
    setTotalLingqOfLesson();
    showLoadingBar(30);

    //03. (beta) make sure the last course you did before completing is the first one in the course list.
    continueWithLastLessonInCourse();
    showLoadingBar(40);

    //04. (beta) continue button in course
    setContinueButtonInCourse();

    //05a. (beta) lingq logo links to /dashboard
    logoLinksToDashboard();

    //06 (alpha) like dislike instead of 5 points
    whenWordIsClikedDo();

    //07 (beta) add profile links
    addProfileLinkInTopNav();
    showLoadingBar(50);

    //08 (beta) show streak in topnav
    showStreakInTopNav(); 
    showLoadingBar(60);

    //09 (beta) add duration and listening length
    addMoreCourseInfo();

    //10. (beta) sort by in courses
    addSortByInCourses();
    showLoadingBar(70);

    //11 (alpha) add version to page
    addVersionInPage();

    //12 (alpha) add which page you are on in numbers
    addPageNumber();
    eventListenerForTextMode();
    eventListenerForNextLesson();
    showLoadingBar(80);

    //13 (alpha) go to one pane parallex style
    removeRightPane();

    //14 (alpha) up arrow is translate
    eventListenerForUpArrow();

    //15 (beta) show loading bar for webpage
    showLoadingBar(90);
    
    //16 (alpha) show percentage of top 5000 words.
    if (window.location.pathname !== "/en/") {
        showPercentageOfMastery();
    }

    //17 (alpha) clean up sentences without lingqs
    cleanUpSentences();

    showLoadingBar(100);
    showLoadingBar(false);

    // 18 (alpha) button to open all languages in new tabs
    setUpOpenAllLanguagesLinkInDashboard();

    //??. (delayed) having a footer (with social media buttons)
    //addFooter();

    // 19 (alpha) remove sentences that are white
    //removeWhiteSentences();
});