diff --git a/dist/extendedPlayerProfile.js b/dist/extendedPlayerProfile.js index e857873..742f038 100644 --- a/dist/extendedPlayerProfile.js +++ b/dist/extendedPlayerProfile.js @@ -117,7 +117,202 @@ parcelRequire = (function (modules, cache, entry, globalName) { } return newRequire; -})({"yRop":[function(require,module,exports) { +})({"Ph2E":[function(require,module,exports) { +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.API_URI = void 0; +const API_URI = 'https://api.tribalwarshelp.com/graphql'; +exports.API_URI = API_URI; + +var _default = function _default() { + let { + query, + variables = {} + } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return fetch('https://api.tribalwarshelp.com/graphql', { + method: 'POST', + body: JSON.stringify({ + query, + variables + }), + headers: { + 'Content-Type': 'application/json' + } + }).then(res => { + return res.json(); + }).then((_ref) => { + let { + data, + errors + } = _ref; + + if (errors && Array.isArray(errors) && errors.length > 0) { + throw new Error(errors[0].message); + } + + return new Promise(resolve => resolve(data)); + }); +}; + +exports.default = _default; +},{}],"tQUs":[function(require,module,exports) { +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _default = url => parseInt(new URLSearchParams(url).get('id')); + +exports.default = _default; +},{}],"dSAr":[function(require,module,exports) { +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _getIDFromURL = _interopRequireDefault(require("../utils/getIDFromURL")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class InADayParser { + constructor(html) { + let filters = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + this.dom = new DOMParser().parseFromString(html, 'text/html'); + this.filters = filters; + } + + isValidRow(row) { + if (this.filters.playerID && row.playerID !== this.filters.playerID) { + return false; + } + + return true; + } + + parseRow(row) { + let obj = {}; + obj.rank = parseInt(row.children[0].innerText.trim()); + obj.name = row.children[1].innerText.trim(); + obj.playerID = (0, _getIDFromURL.default)(row.children[1].querySelector('a').getAttribute('href')); + obj.tribe = row.children[2].innerText.trim(); + obj.tribeID = 0; + + if (obj.tribe) { + obj.tribeID = (0, _getIDFromURL.default)(row.children[2].querySelector('a').getAttribute('href')); + } + + obj.score = parseInt(row.children[3].innerText.trim().replace(/\./g, '')); + obj.date = row.children[4].innerText.trim(); + return obj; + } + + parse() { + const trs = this.dom.querySelectorAll('#in_a_day_ranking_table tbody tr'); + const result = []; + + for (let i = 1; i < trs.length; i++) { + const row = trs[i]; + const parsed = this.parseRow(row); + + if (this.isValidRow(parsed)) { + result.push(parsed); + } + } + + return result; + } + +} + +exports.default = InADayParser; +},{"../utils/getIDFromURL":"tQUs"}],"DMkL":[function(require,module,exports) { +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _default = () => window.location.host.split('.')[0]; + +exports.default = _default; +},{}],"V6Mf":[function(require,module,exports) { +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var _default = function _default(date) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return new Date(date).toLocaleDateString(window.game_data.locale.replace('_', '-'), _objectSpread({ + year: 'numeric', + month: 'numeric', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + second: 'numeric' + }, options)); +}; + +exports.default = _default; +},{}],"KWxH":[function(require,module,exports) { +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setItem = exports.getItem = void 0; + +const getItem = key => { + const json = localStorage.getItem(key); + let obj = {}; + + if (json) { + obj = JSON.parse(json); + } + + return obj; +}; + +exports.getItem = getItem; + +const setItem = (key, payload) => { + localStorage.setItem(key, JSON.stringify(payload)); +}; + +exports.setItem = setItem; +},{}],"yRop":[function(require,module,exports) { +"use strict"; + +var _requestCreator = _interopRequireDefault(require("./libs/requestCreator")); + +var _InADayParser = _interopRequireDefault(require("./libs/InADayParser")); + +var _getIDFromURL = _interopRequireDefault(require("./utils/getIDFromURL")); + +var _getCurrentServer = _interopRequireDefault(require("./utils/getCurrentServer")); + +var _formatDate = _interopRequireDefault(require("./utils/formatDate")); + +var _localStorage = require("./utils/localStorage"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + // ==UserScript== // @name Extended Player Profile // @namespace https://gist.github.com/Kichiyaki/3c273582cc6856512e22c86c375f795a @@ -128,8 +323,164 @@ parcelRequire = (function (modules, cache, entry, globalName) { // @match *://*.tribalwars.net/game.php*&screen=info_player* // @grant none // ==/UserScript== -const SERVER = window.location.host.split('.')[0]; -const PLAYER_ID = parseInt(new URLSearchParams(window.location.search).get('id')); +const SERVER = (0, _getCurrentServer.default)(); +let PLAYER_ID = (0, _getIDFromURL.default)(window.location.search); + +if (isNaN(PLAYER_ID) || !PLAYER_ID) { + PLAYER_ID = parseInt(game_data.player.id); +} + const LOCAL_STORAGE_KEY = 'kichiyaki_extended_player_profile' + PLAYER_ID; -const PLAYER_QUERY = "\n query player($server: String!, $id: Int!) {\n player(server: $server, id: $id) {\n id\n servers\n nameChanges {\n oldName\n newName\n changedOn\n }\n dailyGrowth\n }\n }\n"; -},{}]},{},["yRop"], null) \ No newline at end of file +const PLAYER_QUERY = "\n query player($server: String!, $id: Int!) {\n player(server: $server, id: $id) {\n id\n name\n servers\n joinedAt\n nameChanges {\n oldName\n newName\n changeDate\n }\n dailyGrowth\n }\n }\n"; +const dataContainer = document.querySelector('#player_info > tbody'); + +const loadPlayerDataFromCache = () => { + return (0, _localStorage.getItem)(LOCAL_STORAGE_KEY); +}; + +const cachePlayerData = function cachePlayerData() { + let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + (0, _localStorage.setItem)(LOCAL_STORAGE_KEY, data); +}; + +const loadInADayRankAndScore = async (name, playerID, type) => { + try { + const response = await fetch(TribalWars.buildURL('', { + screen: 'ranking', + mode: 'in_a_day', + type, + name + })); + const html = await response.text(); + const res = new _InADayParser.default(html, { + playerID + }).parse(); + + if (res.length === 0) { + throw new Error(); + } + + return res[0]; + } catch (error) { + console.log(error); + return { + rank: 0, + playerID: 0, + score: 0, + tribeID: 0, + date: new Date() + }; + } +}; + +const loadPlayerData = async () => { + const data = await (0, _requestCreator.default)({ + query: PLAYER_QUERY, + variables: { + server: SERVER, + id: PLAYER_ID + } + }); + + if (data.player) { + const inADay = {}; + inADay.att = await loadInADayRankAndScore(data.player.name, data.player.id, 'kill_att'); + inADay.def = await loadInADayRankAndScore(data.player.name, data.player.id, 'kill_def'); + inADay.sup = await loadInADayRankAndScore(data.player.name, data.player.id, 'kill_sup'); + inADay.lootRes = await loadInADayRankAndScore(data.player.name, data.player.id, 'loot_res'); + inADay.lootVil = await loadInADayRankAndScore(data.player.name, data.player.id, 'loot_vil'); + inADay.scavenge = await loadInADayRankAndScore(data.player.name, data.player.id, 'scavenge'); + inADay.conquer = await loadInADayRankAndScore(data.player.name, data.player.id, 'conquer'); + data.player.inADay = inADay; + } + + cachePlayerData(data); + return data; +}; + +const renderTr = (_ref) => { + let { + title, + data, + id + } = _ref; + let tr = document.querySelector('#' + id); + + if (!tr) { + tr = document.createElement('tr'); + tr.id = id; + tr.appendChild(document.createElement('td')); + tr.appendChild(document.createElement('td')); + dataContainer.append(tr); + } + + tr.children[0].innerHTML = title; + tr.children[1].innerHTML = data; +}; + +const render = player => { + [{ + title: 'Joined At', + data: (0, _formatDate.default)(player.joinedAt), + id: 'joined_at' + }, { + title: 'Daily growth', + data: player.dailyGrowth.toLocaleString(), + id: 'dg' + }, { + title: 'Units defeated while attacking', + data: "".concat(player.inADay.att.score.toLocaleString(), " (").concat(player.inADay.att.rank, ".)"), + id: 'kill_att' + }, { + title: 'Units defeated while defending', + data: "".concat(player.inADay.def.score.toLocaleString(), " (").concat(player.inADay.def.rank, ".)"), + id: 'kill_def' + }, { + title: 'Units defeated while supporting', + data: "".concat(player.inADay.sup.score.toLocaleString(), " (").concat(player.inADay.sup.rank, ".)"), + id: 'kill_sup' + }, { + title: 'Resources plundered', + data: "".concat(player.inADay.lootRes.score.toLocaleString(), " (").concat(player.inADay.lootRes.rank, ".)"), + id: 'loot_res' + }, { + title: 'Villages plundered', + data: "".concat(player.inADay.lootVil.score.toLocaleString(), " (").concat(player.inADay.lootVil.rank, ".)"), + id: 'loot_vil' + }, { + title: 'Resources gathered', + data: "".concat(player.inADay.scavenge.score.toLocaleString(), " (").concat(player.inADay.scavenge.rank, ".)"), + id: 'scavenge' + }, { + title: 'Villages conquered', + data: "".concat(player.inADay.conquer.score.toLocaleString(), " (").concat(player.inADay.conquer.rank, ".)"), + id: 'conquer' + }].forEach(data => { + renderTr(data); + }); +}; + +(async function () { + try { + const { + player: playerDataFromCache + } = loadPlayerDataFromCache(); + + if (playerDataFromCache) { + render(playerDataFromCache); + } + + const { + player + } = await loadPlayerData(); + + if (player) { + render(player); + } + + console.log(player); + } catch (error) { + console.log('extended player profile', error); + } +})(); +},{"./libs/requestCreator":"Ph2E","./libs/InADayParser":"dSAr","./utils/getIDFromURL":"tQUs","./utils/getCurrentServer":"DMkL","./utils/formatDate":"V6Mf","./utils/localStorage":"KWxH"}]},{},["yRop"], null) \ No newline at end of file diff --git a/dist/latestEnnoblements.js b/dist/latestEnnoblements.js index 449b458..aa7cacb 100644 --- a/dist/latestEnnoblements.js +++ b/dist/latestEnnoblements.js @@ -206,6 +206,33 @@ exports.default = void 0; var _default = () => window.location.host.split('.')[0]; +exports.default = _default; +},{}],"V6Mf":[function(require,module,exports) { +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var _default = function _default(date) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return new Date(date).toLocaleDateString(window.game_data.locale.replace('_', '-'), _objectSpread({ + year: 'numeric', + month: 'numeric', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + second: 'numeric' + }, options)); +}; + exports.default = _default; },{}],"KWxH":[function(require,module,exports) { "use strict"; @@ -242,6 +269,8 @@ var _renderPopup = _interopRequireDefault(require("./utils/renderPopup")); var _getCurrentServer = _interopRequireDefault(require("./utils/getCurrentServer")); +var _formatDate = _interopRequireDefault(require("./utils/formatDate")); + var _localStorage = require("./utils/localStorage"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -382,20 +411,9 @@ const formatVillageHTML = village => { }), "\">").concat(village.name, " (").concat(village.x, "|").concat(village.y, ") ").concat(continent, ""); }; -const formatDate = date => { - return new Date(date).toLocaleDateString(window.game_data.locale.replace('_', '-'), { - year: 'numeric', - month: 'numeric', - day: 'numeric', - hour: 'numeric', - minute: 'numeric', - second: 'numeric' - }); -}; - const formatEnnoblementRows = ennoblements => { return ennoblements.reverse().map(ennoblement => { - return "\n ".concat(formatVillageHTML(ennoblement.village), "\n ").concat(formatPlayerHTML(ennoblement.newOwner), "\n ").concat(formatPlayerHTML(ennoblement.oldOwner), "\n ").concat(formatDate(ennoblement.ennobledAt), "\n "); + return "\n ".concat(formatVillageHTML(ennoblement.village), "\n ").concat(formatPlayerHTML(ennoblement.newOwner), "\n ").concat(formatPlayerHTML(ennoblement.oldOwner), "\n ").concat((0, _formatDate.default)(ennoblement.ennobledAt), "\n "); }); }; @@ -453,4 +471,4 @@ const renderButton = () => { (function () { renderButton(); })(); -},{"./libs/requestCreator":"Ph2E","./utils/renderPopup":"P4rL","./utils/getCurrentServer":"DMkL","./utils/localStorage":"KWxH"}]},{},["hkfB"], null) \ No newline at end of file +},{"./libs/requestCreator":"Ph2E","./utils/renderPopup":"P4rL","./utils/getCurrentServer":"DMkL","./utils/formatDate":"V6Mf","./utils/localStorage":"KWxH"}]},{},["hkfB"], null) \ No newline at end of file diff --git a/src/extendedPlayerProfile.js b/src/extendedPlayerProfile.js index 656c2e3..2f08b77 100644 --- a/src/extendedPlayerProfile.js +++ b/src/extendedPlayerProfile.js @@ -1,3 +1,10 @@ +import requestCreator from './libs/requestCreator'; +import InADayParser from './libs/InADayParser'; +import getIDFromURL from './utils/getIDFromURL'; +import getCurrentServer from './utils/getCurrentServer'; +import formatDate from './utils/formatDate'; +import { setItem, getItem } from './utils/localStorage'; + // ==UserScript== // @name Extended Player Profile // @namespace https://gist.github.com/Kichiyaki/3c273582cc6856512e22c86c375f795a @@ -9,22 +16,208 @@ // @grant none // ==/UserScript== -const SERVER = window.location.host.split('.')[0]; -const PLAYER_ID = parseInt( - new URLSearchParams(window.location.search).get('id') -); +const SERVER = getCurrentServer(); +let PLAYER_ID = getIDFromURL(window.location.search); +if (isNaN(PLAYER_ID) || !PLAYER_ID) { + PLAYER_ID = parseInt(game_data.player.id); +} const LOCAL_STORAGE_KEY = 'kichiyaki_extended_player_profile' + PLAYER_ID; const PLAYER_QUERY = ` query player($server: String!, $id: Int!) { player(server: $server, id: $id) { id + name servers + joinedAt nameChanges { oldName newName - changedOn + changeDate } dailyGrowth } } `; +const dataContainer = document.querySelector('#player_info > tbody'); + +const loadPlayerDataFromCache = () => { + return getItem(LOCAL_STORAGE_KEY); +}; + +const cachePlayerData = (data = {}) => { + setItem(LOCAL_STORAGE_KEY, data); +}; + +const loadInADayRankAndScore = async (name, playerID, type) => { + try { + const response = await fetch( + TribalWars.buildURL('', { + screen: 'ranking', + mode: 'in_a_day', + type, + name, + }) + ); + const html = await response.text(); + const res = new InADayParser(html, { playerID }).parse(); + if (res.length === 0) { + throw new Error(); + } + return res[0]; + } catch (error) { + console.log(error); + return { + rank: 0, + playerID: 0, + score: 0, + tribeID: 0, + date: new Date(), + }; + } +}; + +const loadPlayerData = async () => { + const data = await requestCreator({ + query: PLAYER_QUERY, + variables: { + server: SERVER, + id: PLAYER_ID, + }, + }); + if (data.player) { + const inADay = {}; + inADay.att = await loadInADayRankAndScore( + data.player.name, + data.player.id, + 'kill_att' + ); + inADay.def = await loadInADayRankAndScore( + data.player.name, + data.player.id, + 'kill_def' + ); + inADay.sup = await loadInADayRankAndScore( + data.player.name, + data.player.id, + 'kill_sup' + ); + inADay.lootRes = await loadInADayRankAndScore( + data.player.name, + data.player.id, + 'loot_res' + ); + inADay.lootVil = await loadInADayRankAndScore( + data.player.name, + data.player.id, + 'loot_vil' + ); + inADay.scavenge = await loadInADayRankAndScore( + data.player.name, + data.player.id, + 'scavenge' + ); + inADay.conquer = await loadInADayRankAndScore( + data.player.name, + data.player.id, + 'conquer' + ); + data.player.inADay = inADay; + } + cachePlayerData(data); + return data; +}; + +const renderTr = ({ title, data, id }) => { + let tr = document.querySelector('#' + id); + if (!tr) { + tr = document.createElement('tr'); + tr.id = id; + tr.appendChild(document.createElement('td')); + tr.appendChild(document.createElement('td')); + dataContainer.append(tr); + } + tr.children[0].innerHTML = title; + tr.children[1].innerHTML = data; +}; + +const render = (player) => { + [ + { + title: 'Joined at:', + data: formatDate(player.joinedAt), + id: 'joined_at', + }, + { + title: 'Daily growth:', + data: player.dailyGrowth.toLocaleString(), + id: 'dg', + }, + { + title: 'Units defeated while attacking:', + data: `${player.inADay.att.score.toLocaleString()} (${ + player.inADay.att.rank + }.)`, + id: 'kill_att', + }, + { + title: 'Units defeated while defending:', + data: `${player.inADay.def.score.toLocaleString()} (${ + player.inADay.def.rank + }.)`, + id: 'kill_def', + }, + { + title: 'Units defeated while supporting:', + data: `${player.inADay.sup.score.toLocaleString()} (${ + player.inADay.sup.rank + }.)`, + id: 'kill_sup', + }, + { + title: 'Resources plundered:', + data: `${player.inADay.lootRes.score.toLocaleString()} (${ + player.inADay.lootRes.rank + }.)`, + id: 'loot_res', + }, + { + title: 'Villages plundered:', + data: `${player.inADay.lootVil.score.toLocaleString()} (${ + player.inADay.lootVil.rank + }.)`, + id: 'loot_vil', + }, + { + title: 'Resources gathered:', + data: `${player.inADay.scavenge.score.toLocaleString()} (${ + player.inADay.scavenge.rank + }.)`, + id: 'scavenge', + }, + { + title: 'Villages conquered:', + data: `${player.inADay.conquer.score.toLocaleString()} (${ + player.inADay.conquer.rank + }.)`, + id: 'conquer', + }, + ].forEach((data) => { + renderTr(data); + }); +}; + +(async function () { + try { + const { player: playerDataFromCache } = loadPlayerDataFromCache(); + if (playerDataFromCache) { + render(playerDataFromCache); + } + const { player } = await loadPlayerData(); + if (player) { + render(player); + } + console.log(player); + } catch (error) { + console.log('extended player profile', error); + } +})(); diff --git a/src/latestEnnoblements.js b/src/latestEnnoblements.js index bf56e5c..09e9f2a 100644 --- a/src/latestEnnoblements.js +++ b/src/latestEnnoblements.js @@ -1,12 +1,13 @@ import requestCreator from './libs/requestCreator'; import renderPopup from './utils/renderPopup'; import getCurrentServer from './utils/getCurrentServer'; +import formatDate from './utils/formatDate'; import { setItem, getItem } from './utils/localStorage'; // ==UserScript== // @name Latest ennoblements // @namespace https://gist.github.com/Kichiyaki/3c273582cc6856512e22c86c375f795a -// @version 0.1 +// @version 0.5 // @description Show the latest ennoblements // @author Kichiyaki http://dawid-wysokinski.pl/ | Icon author *GD* // @match *://*.plemiona.pl/game.php* @@ -178,20 +179,6 @@ const formatVillageHTML = (village) => { }">${village.name} (${village.x}|${village.y}) ${continent}`; }; -const formatDate = (date) => { - return new Date(date).toLocaleDateString( - window.game_data.locale.replace('_', '-'), - { - year: 'numeric', - month: 'numeric', - day: 'numeric', - hour: 'numeric', - minute: 'numeric', - second: 'numeric', - } - ); -}; - const formatEnnoblementRows = (ennoblements) => { return ennoblements.reverse().map((ennoblement) => { return ` diff --git a/src/libs/InADayParser.js b/src/libs/InADayParser.js new file mode 100644 index 0000000..8adc47a --- /dev/null +++ b/src/libs/InADayParser.js @@ -0,0 +1,44 @@ +import getIDFromURL from '../utils/getIDFromURL'; + +export default class InADayParser { + constructor(html, filters = {}) { + this.dom = new DOMParser().parseFromString(html, 'text/html'); + this.filters = filters; + } + isValidRow(row) { + if (this.filters.playerID && row.playerID !== this.filters.playerID) { + return false; + } + return true; + } + parseRow(row) { + let obj = {}; + obj.rank = parseInt(row.children[0].innerText.trim()); + obj.name = row.children[1].innerText.trim(); + obj.playerID = getIDFromURL( + row.children[1].querySelector('a').getAttribute('href') + ); + obj.tribe = row.children[2].innerText.trim(); + obj.tribeID = 0; + if (obj.tribe) { + obj.tribeID = getIDFromURL( + row.children[2].querySelector('a').getAttribute('href') + ); + } + obj.score = parseInt(row.children[3].innerText.trim().replace(/\./g, '')); + obj.date = row.children[4].innerText.trim(); + return obj; + } + parse() { + const trs = this.dom.querySelectorAll('#in_a_day_ranking_table tbody tr'); + const result = []; + for (let i = 1; i < trs.length; i++) { + const row = trs[i]; + const parsed = this.parseRow(row); + if (this.isValidRow(parsed)) { + result.push(parsed); + } + } + return result; + } +} diff --git a/src/utils/formatDate.js b/src/utils/formatDate.js new file mode 100644 index 0000000..96bbad4 --- /dev/null +++ b/src/utils/formatDate.js @@ -0,0 +1,14 @@ +export default (date, options = {}) => { + return new Date(date).toLocaleDateString( + window.game_data.locale.replace('_', '-'), + { + year: 'numeric', + month: 'numeric', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + ...options, + } + ); +}; diff --git a/src/utils/getIDFromURL.js b/src/utils/getIDFromURL.js new file mode 100644 index 0000000..0faf646 --- /dev/null +++ b/src/utils/getIDFromURL.js @@ -0,0 +1 @@ +export default (url) => parseInt(new URLSearchParams(url).get('id'));