NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name WatchOnlineMenu // @namespace https://openuserjs.org/users/Pasha13666 // @version 4.1.10 // @description [shikimori.org] Добавляет ссылки на сайты просмотра аниме // @author Pasha13666 // @match http://shikimori.one/* // @match https://shikimori.one/* // @match http://shikimori.org/* // @match https://shikimori.org/* // @updateURL https://openuserjs.org/meta/Pasha13666/WatchOnlineMenu.meta.js // @homepageURL https://github.com/Pasha13666/AltWatcher4 // @run-at document-body // @license MIT // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_log // @grant GM_xmlhttpRequest // @connect raw.githubusercontent.com // @copyright 2019, Pasha13666 (https://openuserjs.org/users/Pasha13666) // ==/UserScript== /* div - $ph * div - $wo * a.aw4-dark-button.aw4-link - $link * a.aw4-dark-button.aw4-hider - $hider * div.clearfix - $clearfix * * div - $bar * a.aw4-dark-button.watch-online * ... * div.aw4-langs - $langs * a.aw4-dark-button.aw4-lang - $ru * a.aw4-dark-button.aw4-lang - $en */ function WatchOnlineMenu(services) { this.services = services; this.$ph = document.getElementsByClassName('watch-online')[0]; this.$rb = document.getElementsByClassName("c-info-right")[0]; this.$wo = document.createElement('div'); this.$link = document.createElement('a'); this.$hider = document.createElement('a'); this.$clearfix = document.createElement('div'); this.$bar = document.createElement('div'); this.$langs = document.createElement('div'); this.$ru = document.createElement('a'); this.$en = document.createElement('a'); this.$link.target = "_blank"; this.$ru.title = 'Искать по русскому названию'; this.$en.title = 'Искать по английскому названию'; this.$hider.innerText = "▼"; this.$ru.innerText = 'ru'; this.$en.innerText = 'en'; this.$link.classList = "aw4-dark-button aw4-link" this.$hider.classList = "aw4-dark-button aw4-hider"; this.$clearfix.classList = "clearfix"; this.$bar.classList = ""; this.$ru.classList = "aw4-dark-button aw4-lang"; this.$en.classList = "aw4-dark-button aw4-lang"; this.$langs.classList = "aw4-langs"; if (GM_getValue("searchLang", 'ru') === 'ru') this.$ru.classList.add('aw4-selected'); else this.$en.classList.add('aw4-selected'); this.isHentai = document.querySelector('a.b-tag[href*="genre/12"]') != null; if (this.$ph !== undefined){ this.$rb.removeChild(this.$ph); } this.$ph = document.createElement('div'); this.$rb.appendChild(this.$ph); for (var i = 0; i < this.services.length; i++) { var v = this.services[i]; if (this.isHentai? v.forRx: v.forNotRx) this.$bar.appendChild(this.createPlayerButton(v, i)); } this.redrawButton(); this.$ru.addEventListener('click', () => { this.$ru.classList.add('aw4-selected'); this.$en.classList.remove('aw4-selected'); GM_setValue("searchLang", 'ru'); this.redrawButton(); }); this.$en.addEventListener('click', () => { this.$en.classList.add('aw4-selected'); this.$ru.classList.remove('aw4-selected'); GM_setValue("searchLang", 'en'); this.redrawButton(); }); this.$hider.addEventListener('click', () => { this.$bar.style.display = this.$bar.style.display === 'none'? '': 'none'; }); this.$langs.appendChild(this.$ru); this.$langs.appendChild(this.$en); this.$bar.appendChild(this.$langs); this.$wo.appendChild(this.$link); this.$wo.appendChild(this.$hider); this.$wo.appendChild(this.$clearfix); this.$ph.appendChild(this.$wo); this.$ph.appendChild(this.$bar); } WatchOnlineMenu.prototype.createPlayerButton = function(service, id){ var a = document.createElement('a'); a.classList = "aw4-dark-button"; a.innerText = service.description || service.name; a.addEventListener('click', (ev) => { GM_setValue(this.isHentai? "currentRxServiceId": "currentServiceId", id); this.redrawButton(); }); a.addEventListener('mousedown', (ev) => { if (ev.which == 2 || ev.button == 4) { ev.preventDefault(); window.open(this.createServiceUrl(service),'_blank'); return; } }); return a; } WatchOnlineMenu.prototype.redrawButton = function(){ var service = this.services[GM_getValue(this.isHentai? "currentRxServiceId": "currentServiceId", 0)]; this.$link.innerText = 'Смотреть на ' + service.name; this.$link.href = this.createServiceUrl(service); this.$bar.style.display = 'none'; } WatchOnlineMenu.prototype.createServiceUrl = function(service){ //Поменять местами чтобы открывалась первая серия если крайняя еще не вышла //const epTotal = parseInt(this.$ph.dataset.episodes_aired); const epTotal = parseInt(this.$ph.dataset.total_episodes); const v = document.getElementsByClassName('current-episodes')[0]; const epWatched = (v? parseInt(v.innerText): 0) || 0; const epNext = epWatched === epTotal? 1: (epWatched + 1); const animeName = document.querySelector("#animes_show > section > div > header > h1").innerText.split(" / "); const isEnglish = GM_getValue("searchLang", 'ru') == 'en'; const data = { id: location.pathname.replace(/^\/animes\/[a-z]*(\d+)-.*$/, "$1"), link: location.href, nextEpisode: epNext, englishName: animeName[1], russianName: animeName[0], localezedName: animeName[+isEnglish], localizedEpisode: isEnglish? 'episode': 'серия' }; return location.protocol + "//" + service.url.replace(/\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g, (match, name) => encodeURIComponent(data[name])); } function checkUpdates(){ const servicesCache = GM_getValue("servicesCache", null); if (servicesCache && servicesCache.date > new Date()) return Promise.resolve(servicesCache.services); GM_log("[WatchOnlineMenu] Updating services list..."); return new Promise(function (res, rej){ GM_xmlhttpRequest({ "method": "GET", "url": "https://raw.githubusercontent.com/Pasha13666/AltWatcher4/version-" + GM_info.script.version.substring(0, 3) + "/services.json", "responseType": "json", "fetch": true, "onerror": function (){ if (servicesCache) res(servicesCache.services); else GM_log("[WatchOnlineMenu] Not starting WatchOnlineMenu due to network error."); }, "onload": function(obj){ if (obj.status !== 200 || !obj.response) { if (servicesCache) res(servicesCache.services); else GM_log("[WatchOnlineMenu] Not starting WatchOnlineMenu due to network error."); } else { GM_setValue("servicesCache", {services: obj.response, date: +new Date() + 1000 * 60 * 60 * 24}); res(obj.response); } } }); }); } document.head.appendChild(GM_addStyle( ".aw4-dark-button { background-color: #456; border: 1px solid #3e4d5d; color: #fff; display: block; text-align: center; cursor: pointer; padding: 4px 0; font-size: 15px; font-weight: 600; }" + ".aw4-link {float: left; width: calc(100% - 32px); margin-bottom: 15px; }\n" + ".aw4-hider {width: 32px; float: right; }\n" + ".aw4-lang { width: 50%; float: left; }\n" + ".aw4-langs { margin-top: 5px; }\n" + ".aw4-selected { border: 5px solid #00c12a; padding: 4px 0; }\n" )); checkUpdates() .then(function(services){ GM_log("[WatchOnlineMenu] Starting..."); let start = function(){ if (document.body && document.body.classList.contains("p-animes") && !document.getElementsByClassName('aw4-link').length) { new WatchOnlineMenu(services); } } document.addEventListener('ready', start); document.addEventListener('page:load', start); document.addEventListener('turbolinks:load', start); start(); });