NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Kiwiphttps://openuserjs.org/scripts/outerspace/Kiwipost.ge_parcel_infoost.ge parcel info // @namespace http://dev-exp.io/ // @version 0.3 // @description Display the comment, price and the website info for each parcel on the dashboard // @author You // @match https://kiwipost.ge/dashboard* // @match https://dashboard.kiwipost.ge/* // @match https://api.kiwipost.ge/* // @icon https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_xmlhttpRequest // @copyright 2023, outerspace (https://openuserjs.org/users/outerspace) // @license MIT // @updateURL https://openuserjs.org/meta/outerspace/Kiwipost.ge_parcel_info.meta.js // @downloadURL https://openuserjs.org/install/outerspace/Kiwipost.ge_parcel_info.user.js // ==/UserScript== function lerp(amt, start, end) { return (1 - amt) * start + amt * end } const debounce = (fn, delay = 100) => { let timer = null; return () => (new Promise((resolve, reject) => { if (timer) return; timer = setTimeout(() => { fn.apply(this, arguments); timer = null; resolve(); }, delay); })); }; let ranOnce = false; const once = (fn) => { if (!ranOnce) fn(); ranOnce = true; }; const cyrb53 = (str, seed = 0) => { let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed; for (let i = 0, ch; i < str.length; i++) { ch = str.charCodeAt(i); h1 = Math.imul(h1 ^ ch, 2654435761); h2 = Math.imul(h2 ^ ch, 1597334677); } h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507); h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909); h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507); h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909); return 4294967296 * (2097151 & h2) + (h1 >>> 0); }; const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent; let watchDOMChanges = true; function groupColor(number) { number = (number % 0xFFFFFF / 0xFFFFFF) var h = ~~lerp(number, 0, 360); var s = 80; //~~lerp(number, 42, 98); var l = 95; //~~lerp(number, 40, 90); return `hsl(${h},${s}%,${l}%)`; }; const observeDOM = (function () { const MutationObserver = window.MutationObserver || window.WebKitMutationObserver; return function (obj, callback) { if (!obj || obj.nodeType !== 1) return; if (MutationObserver) { // define a new observer const mutationObserver = new MutationObserver(callback) // have the observer observe for changes in children mutationObserver.observe(obj, { childList: true, subtree: true, attributes: true, characterData: true }) return mutationObserver } // browser support fallback else if (window.addEventListener) { obj.addEventListener('DOMNodeInserted', callback, false) obj.addEventListener('DOMNodeRemoved', callback, false) } } })(); (function () { 'use strict'; const dataMap = {}; const getParcelInfo = async (tracking_number) => { let res = GM_getValue(tracking_number); if (res) { if (!res.comment) GM_deleteValue(tracking_number) else return res;; } try { GM_xmlhttpRequest({ method: "GET", url: `https://api.kiwipost.ge/json/orders/single/${dataMap[tracking_number].id}`, headers: { "Content-Type": "application/json" }, onload: function (response) { const res = JSON.parse(response.responseText); if (res && res.comment) { GM_setValue(tracking_number, res) } }, }); } catch (e) {} } const comparer = (a, b) => { const v1 = a.getAttribute('data-sort'); const v2 = b.getAttribute('data-sort'); return v1 && v2 && v1.localeCompare(v2); }; const updated = debounce(() => { const cells = document.querySelectorAll('.tab-pane.show .table-item tr td:first-child'); cells.forEach(c => { let tr = c.closest('tr'); let tracking_number = c.getAttribute('data-tracking'); if (!tracking_number) { tracking_number = c.textContent.trim(); c.setAttribute('data-tracking', tracking_number) } getParcelInfo(tracking_number).then((parcelInfo) => { if (!parcelInfo) return; let color = ""; if (dataMap[tracking_number]) { const flight = dataMap[tracking_number].transfer.number; const arrive = dataMap[tracking_number].transfer.arrive; color = groupColor(cyrb53(`${parcelInfo.obtain_webstore}-${flight}-${arrive}`)); c.closest('tr').setAttribute('style', `background-color: ${color};`); const isoDate = arrive.split('.').reverse().join('.'); const sortString = `${isoDate}-${flight}-${parcelInfo.obtain_webstore}`; tr.setAttribute('data-sort', sortString); } c.innerHTML = `${tracking_number}<br/> <span style="font-size: 12px; line-height: 13px;color: gray;font-weight: normal; font-family: helv;">${parcelInfo.comment}<br/> ${parcelInfo.obtain_webstore} ${parcelInfo.obtain_cost}${parcelInfo.obtain_currency}</span> `; }); }); console.log('updated'); }, 100); GM_xmlhttpRequest({ method: "GET", url: "https://api.kiwipost.ge/json/all-orders", headers: { "Content-Type": "application/json" }, onload: function (response) { const res = JSON.parse(response.responseText); res.forEach(r => { dataMap[r.tracking_number] = r; }); observeDOM(document.querySelector('#app'), async function (m) { if (watchDOMChanges) { await updated(); } }); updated(); document.addEventListener('click', () => { document.querySelectorAll('.table-item table tbody').forEach(table => { Array.from(table.querySelectorAll('tr:nth-child(n)')) .sort(comparer) .forEach(tr => table.appendChild(tr)); }); }); }, }); })();