MediaWiki:Follow.js

/* Update recent news about a favorite title $(function {

// Add link switch (mw.config.get("skin")) { case "wikia": // oasis case "oasis": $("#my-tools-menu").append('Theo dõi bộ truyện') break; case "monobook": case "vector": $("#p-tb ul").append('Theo dõi bộ truyện') break; }

// Core object var follower = { fn: { loadGlobal: function { }, saveGlobal: function { }, loadLocal: function { }, saveLocal: function { }, setData: function { }, follow: function { }, hasFollowed: function { }, target: function { }, untarget: function { }, remove: function { }, removeAll: function { }, getFeed: function { }, clearFeed: function { }, vitalizeInterface: function { }, genFilterByTitle: function { }, genInteractiveItem: function { }, genInteractiveFeed: function { } },       storage: { url: mw.config.get("wgScriptPath"), // domain keyOfTitles: "watchlistTitles", deleteIconURL: "https://i.imgur.com/toc40DW.png" },       data: { titles: [], targetTitles: [], from: null, to: null },       feeds: [], markup: { html: null, css: null }   }

// Decorate html follower.markup.html = ' \n' + '   \n' + '       \n' + '           To the light of Holy, to the glory of Dark, let us pray, the faith of Sonako. \n' + '       \n' + '       \n' + '           Hãy đăng nhập để đồng bộ hóa danh sách theo dõi trên mọi thiết bị và trình duyệt nhé! \n' + '       \n' + '        \n' + '    \n' + '   \n' + '       Bạn muốn thêm truyện nào vào danh sách theo dõi? (Nhập từng tên truyện một, không quan trọng hoa hay thường) \n' + '        \n' + '        \n' + '   \n' + '   \n' + '       Hãy tích chọn những truyện bạn muốn cập nhật tin tức. \n' + '       Những truyện bạn đang theo dõi: \n' + '       \n' + '       Trống vắng quá :( \n' +        '        \n' +        '             \n' +        '             \n' +        '        \n' +        '    \n' +        '    \n' +        '    \n' +        '        <input id="getFeed" type="button" value="Dạo này có chương mới chưa?"/> \n' +        '        Đang tải... \n' +        '        <p id="interval" class="info"> \n' +        '        \n' +        '        \n' +        '        \n' +        '            <input id="getMoreFeed" type="button" value="Còn  gì khác không?" class="inactive"/> \n' +        '            <input id="clearFeed" type="button" value="Xóa hết" class="inactive"/> \n' +        '        \n' +        '    \n' +        ' \n'

// Decorate css follower.markup.css = 'img.delete { \n' + '   margin: 0 4px; \n' + '   cursor: pointer; \n' + '} \n' + ' \n' + '.list { \n' + '   display: flex; \n' + '   flex-direction: column; \n' + '} \n' + ' \n' + '.inactive { \n' + '   display: none;\n' + '} \n'

// Define functionalities follower.fn.loadLocal = function { follower.fn.setData(JSON.parse(window.localStorage.getItem(follower.storage.keyOfTitles)) || {}) }

follower.fn.saveLocal = function { window.localStorage.setItem(follower.storage.keyOfTitles, JSON.stringify(follower.data)) }

follower.fn.setData = function (newState) { if (newState instanceof Object) { for (var key in newState) { if (newState.hasOwnProperty(key) && follower.data.hasOwnProperty(key)) { follower.data[key] = newState[key] }           }        }        follower.fn.saveLocal // Always save local after data changes }

follower.fn.genFilterByTitle = function (title) { return function (t) { return t.toLowerCase !== title.toLowerCase }   }

follower.fn.hasFollowed = function (title) { return follower.data.titles.includes(title.toLowerCase) }

follower.fn.follow = function (title) { if (!follower.fn.hasFollowed(title)) { var newTitle = title.toLowerCase; follower.fn.setData({               titles: follower.data.titles.concat(newTitle),                targetTitles: follower.data.targetTitles.concat(newTitle)            }) }   }

follower.fn.target = function (title) { follower.fn.setData({           targetTitles: follower.data.targetTitles.concat(title.toLowerCase)        }) }

follower.fn.untarget = function (title) { byTitle = follower.fn.genFilterByTitle(title) follower.fn.setData({           targetTitles: follower.data.targetTitles.filter(byTitle)        }) }

follower.fn.remove = function (title) { byTitle = follower.fn.genFilterByTitle(title) follower.fn.setData({           targetTitles: follower.data.targetTitles.filter(byTitle),            titles: follower.data.titles.filter(byTitle)        }) }

follower.fn.removeAll = function { follower.fn.setData({           targetTitles: [],            titles: []        }) }

follower.fn.genInteractiveItem = function (title, checked) { item = document.createElement("div") item.className = "interactiveFeedWrapper"

input = document.createElement("input") item.appendChild(input) input.setAttribute("type", "checkbox") input.setAttribute("id", "feed") input.setAttribute("name", title) input.setAttribute("value", title) input.setAttribute("checked", checked) input.addEventListener("click", function (e) {           if (e.target.checked) {                follower.fn.target(e.target.value)            } else {                follower.fn.untarget(e.target.value)            }        })

dlt = document.createElement("img") item.appendChild(dlt) dlt.setAttribute("src", follower.storage.deleteIconURL) dlt.className = "delete" dlt.addEventListener("click", function (e) {           follower.fn.remove(title)        })

lbl = document.createElement("label") item.appendChild(lbl) lbl.setAttribute("for", "feed") lbl.innerText = title

return item }

follower.fn.genInteractiveFeed = function (feed) { // TODO }

follower.fn.getFeed = function { // TODO }

follower.fn.clearFeed = function { // TODO }

follower.fn.vitalizeInterface = function { // TODO function info(text) { $(".subheader #status").text(text) }

// Set title $(".WikiaPage h1, h1#firstHeading").html("Theo Dõi Nâng cao"); $("head title").html("Theo Dõi Nâng cao | Sonako Light Novel Wiki")

// Load global and local data follower.fn.loadLocal follower.fn.loadGlobal

// Initial check of watchlist if (follower.data.titles.length == 0) { $(".watchlist .instruction").addClass("inactive") $(".watchlist .control").addClass("inactive") $(".watchlist #empty").removeClass("inactive") $(".feedRetriever").addClass("inactive") }

// Listener to register new title $(".chooser #follow").click(function {            var newTitle = $("#inputTitle").val            console.debug(newTitle)            if (!follower.fn.hasFollowed(newTitle)) {                $(".watchlist #empty").addClass("inactive")                $(".watchlist .instruction").removeClass("inactive")                $(".watchlist .control").removeClass("inactive")                $(".feedRetriever").removeClass("inactive")                $(".watchlist .content.list").append(follower.fn.genInteractiveItem(newTitle, true))            }        })

// Listener to clear titles $(".watchlist #clearTitles").click(function {            if (window.confirm("Bạn có chắc là muốn bỏ theo dõi những LN hấp dẫn này chứ?")) {                follower.fn.removeAll                $(".watchlist .content.list").empty                $(".watchlist .instruction").addClass("inactive")                $(".watchlist .control").addClass("inactive")                $(".watchlist #empty").removeClass("inactive")                $(".feedRetriever").addClass("inactive")                info("Đã bỏ theo dõi hết.")            }        })

// Listener to save titles $(".watchlist #saveTitles").click(function {            follower.fn.saveGlobal            // TODO            info("Chức năng này chưa được lập trình xong.")        })

// Listener to retrieve feed $(".feedRetriever #getFeed").click(function {            follower.fn.getFeed            // TODO            info("Chức năng này chưa được lập trình xong.")        })

// Listener to get more feeds $(".feedRetriever #getMoreFeed").click(function {            follower.fn.getFeed            // TODO            info("Chức năng này chưa được lập trình xong.")        })

// Listener to clear current feeds $(".feedRetriever #clearFeed").click(function {            follower.fn.clearFeed            // TODO            info("Chức năng này chưa được lập trình xong.")        }) }

// Implementation // Only show on Special:CatNav if (mw.config.get("wgNamespaceNumber") === -1 && mw.config.get("wgTitle") === "Follow") { /* css */ mw.util.addCSS(follower.markup.css)

/* markup */ $("#mw-content-text").html(follower.markup.html)

/* add listeners */ follower.fn.vitalizeInterface } })