wowtoken.app

git clone https://git.emily.sh/wowtoken-app/wowtoken.app.git
Log | Files | Refs | README | LICENSE

index.js (10738B)


      1 import 'chartjs-adapter-dayjs-4';
      2 import "./style.css"
      3 
      4 import fetchCurrent from "./fetchCurrent";
      5 import fetchData from "./fetchData";
      6 import {updateHighTime} from "./highTime";
      7 import {updateLowTime} from "./lowTime";
      8 import {addLoader, removeLoader} from "./loader";
      9 import {allowOverlay, forceOverlayOff, forceOverlayOn, isOverlayAllowed, isOverlaySelected} from "./overlay";
     10 import TokenChart from "./tokenChart";
     11 import Datum from "./datum";
     12 
     13 // TODO: This file should be seperated into multiple with better ownership
     14 
     15 let currentRegionSelection = '';
     16 let currentTimeSelection = '';
     17 let currentAggregateSelection = '';
     18 let startYAtZero = false;
     19 let datum;
     20 let chart;
     21 const currentPriceHash = {
     22     us: 0,
     23     eu: 0,
     24     kr: 0,
     25     tw: 0
     26 };
     27 const chartData = {
     28     us: [],
     29     eu: [],
     30     kr: [],
     31     tw: []
     32 }
     33 
     34 async function callUpdateURL() {
     35     await updateTokens(await fetchCurrent());
     36 }
     37 
     38 async function updateTokens(data) {
     39     await Promise.all([
     40         updateRegionalToken('us', data),
     41         updateRegionalToken('eu', data),
     42         updateRegionalToken('kr', data),
     43         updateRegionalToken('tw', data)
     44     ]);
     45 }
     46 
     47 async function updateRegionalToken(region, data) {
     48     if (currentPriceHash[region] !== data[region][1]) {
     49         currentPriceHash[region] = data[region][1];
     50         if (region === currentRegionSelection) {
     51             formatToken();
     52             datum = new Datum(Date.parse(data[region][0]), data[region][1]);
     53             if (currentAggregateSelection === 'none' && chart.active()) {
     54                 await chart.addDataToChart(datum);
     55             }
     56             else if (currentAggregateSelection === 'none' && !chart.active()) {
     57                 await chart.lateUpdate(datum);
     58             }
     59         }
     60     }
     61 }
     62 
     63 async function updateRegionPreference(newRegion) {
     64     if (newRegion !== currentRegionSelection) {
     65         await chart.destroyChart();
     66         addLoader();
     67         currentRegionSelection = newRegion;
     68     }
     69     formatToken();
     70     await pullChartData();
     71 }
     72 
     73 async function updateTimePreference(newTime) {
     74     if (newTime !== currentTimeSelection) {
     75         await chart.destroyChart();
     76         addLoader();
     77         currentTimeSelection = newTime;
     78     }
     79     if (newTime === "all") {
     80         forceOverlayOff();
     81     }
     82     else {
     83         allowOverlay();
     84     }
     85     await pullChartData();
     86     updateHighTime();
     87     updateLowTime();
     88 }
     89 
     90 async function updateAggregatePreference(newAggregate) {
     91     if (newAggregate !== currentAggregateSelection) {
     92         await chart.destroyChart();
     93         addLoader();
     94         currentAggregateSelection = newAggregate;
     95     }
     96     await pullChartData();
     97 }
     98 
     99 function toggleAdvancedSetting() {
    100     let element = document.getElementById('advanced-options')
    101     if (document.getElementById('enable-advanced').checked)
    102     {
    103         element.style.display = 'flex';
    104     }
    105     else
    106     {
    107         element.style.display = 'none';
    108     }
    109 }
    110 
    111 function toggleStartYAtZero(){
    112     startYAtZero = document.getElementById('y-start').checked;
    113     chart.toggleYStart(startYAtZero);
    114 }
    115 
    116 async function toggleOverlay() {
    117     await chart.destroyChart();
    118     addLoader();
    119     await pullChartData();
    120 }
    121 
    122 async function pullChartData() {
    123     let timeSelection = currentTimeSelection;
    124     if (isOverlaySelected()) {
    125         let timeDigits = parseInt(timeSelection.slice(0, timeSelection.length - 1)) * 2;
    126         let timeUnit = timeSelection.slice(timeSelection.length - 1);
    127         timeSelection = `${timeDigits}${timeUnit}`;
    128     }
    129     chartData[currentRegionSelection] = await fetchData(currentRegionSelection, timeSelection, currentAggregateSelection);
    130     if (!chart.active()) {
    131         await chart.createChart(currentRegionSelection, currentTimeSelection, startYAtZero, chartData[currentRegionSelection]);
    132     }
    133     else {
    134         for (let i = 0; i < chartData[currentRegionSelection].length; i++) {
    135             await chart.addDataToChart(chartData[currentRegionSelection][i]);
    136         }
    137         console.warn("This should never hit, and should be okay to remove");
    138     }
    139     removeLoader();
    140 }
    141 
    142 function formatToken() {
    143     document.getElementById("token").innerText = currentPriceHash[currentRegionSelection].toLocaleString();
    144 }
    145 
    146 // TODO: These maybe able to be collapsed into a single function with params or a lambda
    147 
    148 function detectRegionQuery(urlSearchParams) {
    149     const validRegions = ['us', 'eu', 'tw', 'kr'];
    150     if (validRegions.includes(urlSearchParams.get('region').toLowerCase())) {
    151         currentRegionSelection = urlSearchParams.get('region').toLowerCase();
    152         let regionDDL = document.getElementById('region');
    153         for (let i = 0; i < regionDDL.options.length; i++) {
    154             if (regionDDL.options[i].value === currentRegionSelection) {
    155                 regionDDL.options[i].selected = true;
    156             }
    157         }
    158     } else {
    159         console.warn("An incorrect or malformed region selection was made in the query string");
    160     }
    161 }
    162 
    163 function detectTimeQuery(urlSearchParams) {
    164     // In the future, we will allow all the times to be selected,
    165     // once I come up with a good reduction algorithm.
    166     // For larger time selections, it's currently hardcoded into the backend
    167     const validTimes = ['72h', '168h', '336h', '720h', '30d', '2190h', '90d', '1y', '2y', '6m', 'all'];
    168     if (validTimes.includes(urlSearchParams.get('time').toLowerCase())) {
    169         currentTimeSelection = urlSearchParams.get('time').toLowerCase();
    170         if (currentTimeSelection === 'all') {
    171             forceOverlayOff();
    172         }
    173         let timeDDL = document.getElementById('time');
    174         for (let i = 0; i < timeDDL.options.length; i++) {
    175             if (timeDDL.options[i].value === currentTimeSelection) {
    176                 timeDDL.options[i].selected = true;
    177             }
    178         }
    179         updateHighTime();
    180         updateLowTime();
    181     } else {
    182         console.warn("An incorrect or malformed time selection was made in the query string");
    183     }
    184 }
    185 
    186 function detectAggregateQuery(urlSearchParams) {
    187     const validOperations = ['none', 'daily_mean', 'avg'];
    188     if (validOperations.includes(urlSearchParams.get('aggregate').toLowerCase())) {
    189         currentAggregateSelection = urlSearchParams.get('aggregate').toLowerCase();
    190         // For backwards compatibility
    191         if (currentAggregateSelection === 'daily_mean') {
    192             currentAggregateSelection = 'avg';
    193         }
    194         let aggregateDDL = document.getElementById('aggregate');
    195         for (let i = 0; i < aggregateDDL.options.length; i++) {
    196             if (aggregateDDL.options[i].value === currentAggregateSelection) {
    197                 aggregateDDL.options[i].selected = true;
    198             }
    199         }
    200     } else {
    201         console.warn("An incorrect or malformed aggregate selection was made in the query string");
    202     }
    203 }
    204 
    205 function detectZeroQuery(urlSearchParams) {
    206     startYAtZero = urlSearchParams.get('startAtZero') === 'true';
    207     let advOptions = document.getElementById('enable-advanced');
    208     let startAtZeroOption = document.getElementById('y-start');
    209     advOptions.checked = startYAtZero;
    210     startAtZeroOption.checked = startYAtZero;
    211     toggleAdvancedSetting();
    212     toggleStartYAtZero();
    213 }
    214 
    215 function detectOverlayQuery(urlSearchParams) {
    216     const enableOverlay = urlSearchParams.get('overlay') === 'previous_time';
    217     if (enableOverlay) {
    218         forceOverlayOn();
    219     } else {
    220         forceOverlayOff();
    221     }
    222 }
    223 
    224 function detectURLQuery() {
    225     const urlSearchParams = new URLSearchParams(window.location.search);
    226     if (urlSearchParams.has('region')) {
    227         detectRegionQuery(urlSearchParams);
    228     }
    229     if (urlSearchParams.has('time')) {
    230         detectTimeQuery(urlSearchParams);
    231     }
    232     if (urlSearchParams.has('aggregate')) {
    233         detectAggregateQuery(urlSearchParams);
    234     }
    235     if (urlSearchParams.has('startAtZero')) {
    236         detectZeroQuery(urlSearchParams)
    237     }
    238     if (urlSearchParams.has('overlay')) {
    239         detectOverlayQuery(urlSearchParams);
    240     }
    241 }
    242 
    243 function buildDeepLinksURL() {
    244     let url = "https://wowtoken.app/?"
    245     if (currentTimeSelection !== '72h'){
    246         url += `time=${currentTimeSelection}&`
    247     }
    248     if (currentRegionSelection !== 'us'){
    249         url += `region=${currentRegionSelection}&`
    250     }
    251     if (currentAggregateSelection !== '' && currentAggregateSelection !== 'none'){
    252         url += `aggregate=${currentAggregateSelection}&`
    253     }
    254     if (startYAtZero !== false){
    255         url += `startAtZero=${startYAtZero}&`
    256     }
    257     if (isOverlaySelected()){
    258         url += `overlay=previous_time&`
    259     }
    260     return url
    261 }
    262 
    263 function copyURL() {
    264     let toolTip = document.getElementById('urlTooltip');
    265     navigator.clipboard.writeText(buildDeepLinksURL()).then(
    266         () => {
    267             toolTip.innerHTML= "Copied the URL";
    268         },
    269         () => {
    270             toolTip.innerHTML = "Unable to copy URL to clipboard";
    271         }
    272     );
    273 }
    274 
    275 function toolTipMouseOut() {
    276     let tooltip = document.getElementById("urlTooltip");
    277     tooltip.innerHTML = "Copy to clipboard";
    278 }
    279 
    280 function registerEventHandles() {
    281     registerCopyHandlers();
    282     registerOptionHandlers();
    283     registerAdvancedHandlers();
    284 }
    285 
    286 // TODO: These need to be moved out into probably tokenChart if not other files
    287 
    288 function registerAdvancedHandlers() {
    289     document.getElementById('enable-advanced').addEventListener('change', () => {
    290         toggleAdvancedSetting();
    291     })
    292     document.getElementById('y-start').addEventListener('change', () => {
    293         toggleStartYAtZero();
    294     })
    295     document.getElementById('period-overlay').addEventListener('change', () => {
    296         toggleOverlay();
    297     })
    298 }
    299 
    300 function registerCopyHandlers() {
    301     document.getElementById('copyURLButton').addEventListener('click', function () {
    302         copyURL();
    303     })
    304     document.getElementById('copyURLButton').addEventListener('mouseout', function () {
    305         toolTipMouseOut();
    306     })
    307 }
    308 
    309 function registerOptionHandlers() {
    310     document.getElementById('region').addEventListener('change', function() {
    311         updateRegionPreference(this.value);
    312     });
    313     currentRegionSelection = document.getElementById('region').value;
    314     document.getElementById('time').addEventListener('change', function() {
    315         updateTimePreference(this.value);
    316     });
    317     currentTimeSelection = document.getElementById('time').value;
    318     document.getElementById('aggregate').addEventListener('change', function () {
    319         updateAggregatePreference(this.value);
    320     })
    321     currentAggregateSelection = document.getElementById('aggregate').value;
    322 }
    323 
    324 document.addEventListener('DOMContentLoaded', function () {
    325     registerEventHandles();
    326     detectURLQuery();
    327     chart = new TokenChart();
    328     Promise.all([
    329         callUpdateURL(),
    330     ]).then(pullChartData);
    331 
    332     setInterval(callUpdateURL, 60*1000);
    333 }, false);
    334