69 karma · joined July 16, 2016
I couldn't believe it myself but by basically force closing the settings menu the drawer animation will be gone until you reboot :)
Long Story short, i just programmed my own App now for that. Works with all garmin watches and let's use define a fixed Workout and allows to analyze your individual performances across exercises:
https://multisports.creatness.studio - i'm still waiting for Garmin to approve my App Store Submission (another long story with garmin) but it can already be downloaded and sideloaded on a garmin watch. using it for a few weeks now myself.
(function() { 'use strict';
const SITE = "https://www.youtube.com";
const LINK_TO_TIMESTAMP = true;
const SHOW_PREVIEW_IMAGE = true;
const createPreviewElement = (videoId, newURL, frame) => {
const container = document.createElement("div");
container.setAttribute('data-yt-preview', 'true');
container.style.position = "relative";
container.style.width = frame.width + "px";
container.style.height = frame.height + "px";
container.style.cursor = "pointer";
const img = document.createElement("img");
img.src = `https://i.ytimg.com/vi/${videoId}/mqdefault.jpg`;
img.alt = "Preview image of Youtube video";
img.style.width = "100%";
img.style.height = "100%";
img.style.objectFit = "cover";
const playButton = document.createElement("div");
playButton.innerHTML = "▶";
playButton.style.position = "absolute";
playButton.style.top = "50%";
playButton.style.left = "50%";
playButton.style.transform = "translate(-50%, -50%)";
playButton.style.fontSize = "48px";
playButton.style.color = "white";
playButton.style.backgroundColor = "rgba(0, 0, 0, 0.7)";
playButton.style.borderRadius = "50%";
playButton.style.width = "80px";
playButton.style.height = "80px";
playButton.style.display = "flex";
playButton.style.justifyContent = "center";
playButton.style.alignItems = "center";
container.appendChild(img);
container.appendChild(playButton);
container.addEventListener("click", () => {
const iframe = document.createElement("iframe");
iframe.src = frame.src + (frame.src.includes('?') ? '&' : '?') + 'autoplay=1';
iframe.width = frame.width;
iframe.height = frame.height;
iframe.frameBorder = "0";
iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture";
iframe.allowFullscreen = true;
iframe.setAttribute('data-yt-processed', 'true');
container.parentNode.replaceChild(iframe, container);
});
return container;
};
const replaceEmbed = (frame) => {
const frameURL = frame.src || frame.dataset?.src;
if (!frameURL) return;
const match = frameURL.match(/(^https?:)?\/\/(www\.)?youtube(-nocookie)?\.com\/embed\/([a-zA-Z0-9\-_]{11}).*?(\?.*((t|start)=([\dsmh]*)))?/i);
if (match?.length == 9) {
const videoId = match[4];
const newURL = SITE + "/watch?" + ((LINK_TO_TIMESTAMP && match[8]) ? "t=" + match[8] + "&" : "") + "v=" + videoId;
const previewElement = createPreviewElement(videoId, newURL, frame);
frame.parentNode.replaceChild(previewElement, frame);
// common lazyload hiding methods
previewElement.style.display = "block !important";
previewElement.style.opacity = "100% !important";
previewElement.style.background = "transparent !important";
const parent = previewElement.parentElement;
if (parent) {
parent.style.display = "block !important";
parent.style.opacity = "100% !important";
parent.style.background = "transparent !important";
}
}
};
const observeDOM = () => {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
if (node.tagName === 'IFRAME' && !node.hasAttribute('data-yt-processed')) {
replaceEmbed(node);
} else {
node.querySelectorAll('iframe:not([data-yt-processed])').forEach(replaceEmbed);
}
}
});
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
};
// Initial replacement
document.querySelectorAll('iframe:not([data-yt-processed])').forEach(replaceEmbed);
// Start observing DOM changes
observeDOM();
})();The biggest problem currently are people spreading those types of misinformation see https://www.reddit.com/r/uBlockOrigin/comments/17j6ygs/youtu...
https://app.foodolyst.creatness.studio [Web]
https://play.google.com/store/apps/details?id=studio.creatne... [Android]
Currently trying to release it on IOS, but Apple is very strict with these types of apps.
[1] https://blog.nativescript.org/perf-metrics-universal-javascr...
If anyone is interested, it is currently available in the google app store. Apple coming soon. Foodolyst: https://play.google.com/store/apps/details?id=studio.creatne...
Also available as a webapp: https://app.foodolyst.creatness.studio
The app works in German&English. I haven't proof read every English entry however, so feedback is very much welcomed. I can return lifetime premium access in return :)
Okay enough advertising, sorry but the topic is quite interesting and everyone with food problems can just benefit from this.
41% OPTION 1: No changes. Telegram may continue to share IP addresses and phone numbers of terror suspects only based on a court decision
21% OPTION 2: Upon request by German police authorities, Telegram may disclose IP addresses and phone numbers of suspects of serious crimes, even if not supported by a court decision.
34% OPTION 3: Under no circumstances may Telegram share user information, including IP addresses and phone numbers of terror suspects.
4% No opinion / I am not from Germany
There are gateways who are more complicated and more for developers, but of course i don't want to offer these.
1) Directus (in my view the best offering of features)
2) Supabase (if you want more performance. the admin ui however can only be used for internal access)
3) Appwrite (works good and has its own advantages. however in my case i would rather go with 1&2)
-Strapi is out since v4 (too many really big showstopers. i was a fanboy since v3 but directus just brings more to the table and is way mature)
-feathers.js (more lightweight, but unfortunately lost its momentum. better alternatives are nowadays available)