· 6 years ago · Jan 15, 2020, 02:22 PM
1// ==UserScript==
2// @name Faction Last Active
3// @namespace namespace
4// @version 0.9
5// @description description
6// @author tos
7// @match *.torn.com/factions.php*
8// @run-at document-end
9// @grant GM_addStyle
10// @grant GM_xmlhttpRequest
11// ==/UserScript==
12
13const api_key = 'API KEY In Here'
14
15GM_addStyle(`
16 .last_action_icon {
17 cursor: pointer;
18 vertical-align: middle;
19 display: inline-block;
20 background-image: url(/images/v2/sidebar_icons_desktop_2017.png);
21 background-repeat: no-repeat;
22 background-position-y: -785px;
23 width: 34px;
24 height: 30px;
25 }
26
27 .member_active {
28 color: green;
29 }
30 .member_idle {
31 color: #ff7c23;
32 }
33 .member_away {
34 color: red;
35 font-weight: bold;
36 }
37`)
38
39let faction = ''
40const info_wrap = document.querySelector('.faction-info')
41if (info_wrap) faction = info_wrap.getAttribute('data-faction')
42
43const torn_api = async (args) => {
44 const a = args.split('.')
45 if (a.length!==3) throw(`Bad argument in torn_api(args, key): ${args}`)
46 return new Promise((resolve, reject) => {
47 GM_xmlhttpRequest ( {
48 method: "POST",
49 url: `https://api.torn.com/${a[0]}/${a[1]}?selections=${a[2]}&key=${api_key}`,
50 headers: {
51 "Content-Type": "application/json"
52 },
53 onload: (response) => {
54 try {
55 const resjson = JSON.parse(response.responseText)
56 resolve(resjson)
57 } catch(err) {
58 reject(err)
59 }
60 },
61 onerror: (err) => {
62 reject(err)
63 }
64 })
65 })
66}
67
68
69const toggleLastAction = (iconsTitle, memberUL) => {
70 if (iconsTitle.innerText === 'Icons') {
71 iconsTitle.childNodes[0].nodeValue = 'Last Action'
72 torn_api(`faction.${faction}.basic`).then((res) => {
73 console.log(res)
74 if (res.error && res.error.code === 2) alert('Invalid API key in Faction Last Action script. Please update in line 11.')
75 for (const li of memberUL.children) {
76 const lastActionDIV = li.querySelector('.last-action')
77 const memberID = lastActionDIV.getAttribute('data-member-ID')
78 const lastAction = res.members[memberID].last_action.relative
79 li.querySelector('.member-icons #iconTray').classList.toggle('hide')
80 lastActionDIV.innerText = lastAction
81 if (lastAction.includes('minute') && parseInt(lastAction.split(' ')[0]) <= 10) lastActionDIV.classList.add('member_active')
82 if (lastAction.includes('day') && parseInt(lastAction.split(' ')[0]) < 7) lastActionDIV.classList.add('member_idle')
83 if (lastAction.includes('day') && parseInt(lastAction.split(' ')[0]) >= 7) lastActionDIV.classList.add('member_away')
84 lastActionDIV.classList.toggle('hide')
85 }
86 })
87 }
88 else {
89 iconsTitle.childNodes[0].nodeValue = 'Icons'
90 for (const li of memberUL.children) {
91 li.querySelector('.member-icons #iconTray').classList.toggle('hide')
92 li.querySelector('.last-action').classList.toggle('hide')
93 }
94 }
95}
96
97const add_toggle = (node) => {
98 const iconsTitle = node.querySelector('.title .member-icons')
99 const memberUL = node.querySelector('.member-list')
100 iconsTitle.insertAdjacentHTML('beforeend', `<i class="last_action_icon right"></i>`)
101 node.querySelector('.last_action_icon').addEventListener('click', () => { toggleLastAction(iconsTitle, memberUL) })
102 for (const li of memberUL.children) {
103 const memberID = li.querySelector('.user.name').getAttribute('href').split('XID=')[1]
104 li.querySelector('.member-icons #iconTray').insertAdjacentHTML('afterend', `<div class="last-action hide" data-member-id="${memberID}"></div>`)
105 }
106}
107
108const observer = new MutationObserver((mutations) => {
109 for (const mutation of mutations) {
110 for (const node of mutation.addedNodes) {
111 if (node.className && node.querySelector('.f-war-list')) {
112 add_toggle(node)
113 }
114 }
115 }
116})
117
118const otherFactionUL = document.querySelector('.f-war-list')
119if (otherFactionUL) {
120 add_toggle(otherFactionUL)
121}
122else {
123 const wrapper = document.querySelector('#factions')
124 observer.observe(wrapper, { subtree: true, childList: true })
125}