Fixes Connect bug where activity chart order is not saved for devices that don't have step speed loss
// ==UserScript==
// @name Garmin Connect: save activity chart order
// @namespace http://tampermonkey.net/
// @description Fixes Connect bug where activity chart order is not saved for devices that don't have step speed loss
// @author You
// @match https://connect.garmin.com/modern/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=garmin.com
// @grant window.onurlchange
// @license MIT
// @version 0.4
// ==/UserScript==
(function () {
'use strict';
const urlPrefix = 'https://connect.garmin.com/modern/activity/'
let currentPageMatchesUrl = false;
const chartListQuery = '.customize-charts-list .sortable-checkboxes';
let tasks = []
waitForUrl()
function waitForUrl() {
// if (window.onurlchange == null) {
// feature is supported
window.addEventListener('urlchange', onUrlChange);
// }
onUrlChange();
}
function onUrlChange() {
const urlMatches = window.location.href.startsWith(urlPrefix);
if (!currentPageMatchesUrl) {
if (urlMatches) {
currentPageMatchesUrl = true;
init();
}
} else {
if (!urlMatches) {
currentPageMatchesUrl = false;
deinit();
}
}
}
function init() {
tasks = [];
tasks.push(runWhenReady(chartListQuery, fixSaveOrder));
}
function deinit() {
tasks.forEach(task => task.stop());
tasks = [];
}
function runWhenReady(readySelector, callback) {
let numAttempts = 0;
let timer = undefined
const tryNow = function () {
const elem = document.querySelector(readySelector);
if (elem) {
callback(elem);
} else {
numAttempts++;
if (numAttempts >= 34) {
console.warn('Giving up after 34 attempts. Could not find: ' + readySelector);
} else {
timer = setTimeout(tryNow, 250 * Math.pow(1.1, numAttempts));
}
}
};
const stop = function () {
clearTimeout(timer);
timer = undefined
}
tryNow();
return {
stop
}
}
function fixSaveOrder(elem) {
const runningActivityTypeElement = document.querySelector("[data-activity-type='running']");
if (runningActivityTypeElement) {
const children = Array.from(elem.children)
if (children.some(child => child.getAttribute('data-which') === 'directStepSpeedLoss')) {
console.log("step speed loss chart exists, nothing to do")
} else {
console.log("step speed loss chart doesn't exist")
}
const newNode = elem.lastElementChild.cloneNode();
newNode.setAttribute('data-which', 'directStepSpeedLoss');
newNode.setAttribute('style', 'display:none'); //not strictly necessary but doesn't hurt
elem.appendChild(newNode);
console.log("successfully added invisible entry for step speed loss chart. chart order should be savable now")
}
}
})();