diff --git a/travel-time/travel-helper.js b/travel-time/travel-helper.js new file mode 100644 index 0000000..9999aca --- /dev/null +++ b/travel-time/travel-helper.js @@ -0,0 +1,87 @@ +// ==UserScript== +// @name Torn - Arrival Time Predictor +// @namespace http://tampermonkey.net/ +// @version 1.0 +// @description Calculates and displays the exact local time you will land while traveling +// @author You +// @match https://www.torn.com/page.php?sid=travel +// @grant GM_addStyle +// ==/UserScript== + +(function() { + 'use strict'; + + // Setup CSS rule for the pulsing text. + GM_addStyle(` + @keyframes colorPulse { + 0% { color: #ff3333; } /* Start Red */ + 50% { color: #ffffff; } /* Midpoint Orange */ + 100% { color: #ff3333; } /* End Red */ + } + + .pulse-text { + animation: colorPulse 1s infinite ease-in-out; + } +`); + + //const flight_image = document.querySelector("#travel-root > div.viewport___cdEK9 > div.airspaceScene___euCKY.outboundFlight___rIvIA"); + //flight_image.remove(); + + // 1. Wait for Torn's travel container to load + const checkFlight = setInterval(() => { + // Torn uses countdown timers inside specific structural classes depending on the layout type + const timerElement = document.querySelector("#travel-root > div.viewport___cdEK9 > div.flightProgressSection___OEJoR > div.progressText___BEQ0k > span > span:nth-child(2) > time"); + + if (timerElement) { + clearInterval(checkFlight); + initClockExtension(timerElement); + } + }, 500); + + function initClockExtension(timerElement) { + // Create a custom UI box to display our text safely without breaking Torn's CSS + const ogTimer = document.querySelector("#travel-root > div.viewport___cdEK9 > div.flightProgressSection___OEJoR > div.progressText___BEQ0k > div > span"); + ogTimer.style.cssText = 'font-weight: bold;'; + const timeDisplay = document.createElement('div'); + timeDisplay.style.cssText = 'padding: 10px; margin-top: 10px; color: #fff; text-align: center; border-radius: 5px; font-weight: bold; border: 1px solid #444; transition: color 0.5s ease;'; + ogTimer.innerText = 'Calculating landing time...'; + //const info = document.querySelector("#travel-root > div.viewport___cdEK9.stage0 > div.factWrapper___LvERA > div"); + //info.remove(); + + // Insert our box right below Torn's native countdown timer + //timerElement.parentNode.insertBefore(timeDisplay, timerElement.nextSibling); + + // Update the landing time prediction every single second + setInterval(() => { + const timeString = timerElement.innerText; // Grabs 'HH:MM:SS' from the page + if (!timeString) return; + + const timeParts = timeString.split(':'); + if (timeParts.length === 3) { + const hours = parseInt(timeParts[0], 10); + const minutes = parseInt(timeParts[1], 10); + const seconds = parseInt(timeParts[2], 10); + + // Convert countdown duration entirely to total milliseconds + const msRemaining = ((hours * 60 * 60) + (minutes * 60) + seconds) * 1000; + // Blink the text if time left is < 2 minutes. + if (msRemaining <= 120000) { + //ogTimer.style.cssText += ' color: #aa0000;' + // Add the blinking class to the text. + ogTimer.classList.add('pulse-text'); + + } + + // Add the flight duration to the current system date/time + const landingTime = new Date(Date.now() + msRemaining); + + // Remove OG timer + + //ogTimer.remove(); + + // Format the output neatly (e.g., "16:24:05") + ogTimer.innerText = `Estimated Landing: ${landingTime.toLocaleTimeString()}`; + } + }, 1000); + } +})(); \ No newline at end of file