Maybe working now???.
This commit is contained in:
@@ -1,8 +1,4 @@
|
|||||||
chrome.runtime.onInstalled.addListener(function () {
|
chrome.runtime.onInstalled.addListener(function () {
|
||||||
chrome.storage.sync.set({color: '#3aa757'}, function () {
|
|
||||||
console.log("The color is green.");
|
|
||||||
});
|
|
||||||
|
|
||||||
chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
|
chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
|
||||||
chrome.declarativeContent.onPageChanged.addRules([{
|
chrome.declarativeContent.onPageChanged.addRules([{
|
||||||
conditions: [new chrome.declarativeContent.PageStateMatcher({
|
conditions: [new chrome.declarativeContent.PageStateMatcher({
|
||||||
@@ -12,9 +8,4 @@ chrome.runtime.onInstalled.addListener(function () {
|
|||||||
actions: [new chrome.declarativeContent.ShowPageAction()]
|
actions: [new chrome.declarativeContent.ShowPageAction()]
|
||||||
}]);
|
}]);
|
||||||
});
|
});
|
||||||
|
|
||||||
let i = 0;
|
|
||||||
setInterval(() => {
|
|
||||||
console.log(`${++i}s since start`)
|
|
||||||
}, 1000);
|
|
||||||
});
|
});
|
||||||
+437
-32
@@ -1,38 +1,443 @@
|
|||||||
function applyDefaultStyle(element) {
|
if (typeof Overlay === "undefined") {
|
||||||
element.style.position = "fixed";
|
var Overlay = class {
|
||||||
element.style.zIndex = 99999999;
|
workout = null;
|
||||||
element.style.color = "#FFF";
|
workoutState = null;
|
||||||
element.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
|
workoutStatus = null;
|
||||||
element.style.padding = "0.25em 0.5ch";
|
display = false;
|
||||||
element.style.fontSize = "3vmax";
|
milestones = [];
|
||||||
|
program = null;
|
||||||
|
currentCpm = null;
|
||||||
|
bikes = [];
|
||||||
|
programs = [];
|
||||||
|
workouts = [];
|
||||||
|
bike = null;
|
||||||
|
setup = null;
|
||||||
|
|
||||||
|
colors = {
|
||||||
|
"-2": "#F44",
|
||||||
|
"-1": "#FAA",
|
||||||
|
"0": "#FFF",
|
||||||
|
"1": "#AFA",
|
||||||
|
"2": "#4F4",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTMLElement} mBody
|
||||||
|
* @param {HTMLElement} mTopLeft
|
||||||
|
* @param {HTMLElement} mCenter
|
||||||
|
* @param {HTMLElement} mBottomRight
|
||||||
|
*/
|
||||||
|
constructor(mBody, mTopLeft, mCenter, mBottomRight) {
|
||||||
|
this.mBody = mBody;
|
||||||
|
this.mTopLeft = mTopLeft;
|
||||||
|
this.mCenter = mCenter;
|
||||||
|
this.mBottomRight = mBottomRight;
|
||||||
|
|
||||||
|
this.initStyle();
|
||||||
|
this.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
initStyle() {
|
||||||
|
this.applyDefaultStyle(this.mTopLeft);
|
||||||
|
this.applyDefaultStyle(this.mCenter);
|
||||||
|
this.applyDefaultStyle(this.mBottomRight);
|
||||||
|
|
||||||
|
this.mTopLeft.id = "overlay-mTopLeft";
|
||||||
|
this.mTopLeft.style.left = 0;
|
||||||
|
this.mTopLeft.style.top = "25%";
|
||||||
|
|
||||||
|
this.mCenter.id = "overlay-mCenter";
|
||||||
|
this.mCenter.style.left = "50%";
|
||||||
|
this.mCenter.style.top = "50%";
|
||||||
|
this.mCenter.style.transform = "translate(-50%, -50%)";
|
||||||
|
|
||||||
|
this.mBottomRight.id = "overlay-mBottomRight";
|
||||||
|
this.mBottomRight.style.right = 0;
|
||||||
|
this.mBottomRight.style.bottom = 0;
|
||||||
|
this.mBottomRight.style.fontSize = "2vmax";
|
||||||
|
}
|
||||||
|
|
||||||
|
applyDefaultStyle(element) {
|
||||||
|
this.mBody.append(element);
|
||||||
|
|
||||||
|
element.style.position = "fixed";
|
||||||
|
element.style.zIndex = 99999999;
|
||||||
|
element.style.color = "#FFF";
|
||||||
|
element.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
|
||||||
|
element.style.padding = "0.25em 0.5ch";
|
||||||
|
element.style.fontSize = "3vmax";
|
||||||
|
element.style.lineHeight = "1.33em";
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() {
|
||||||
|
this.mTopLeft.style.display = "none";
|
||||||
|
this.mCenter.style.display = "none";
|
||||||
|
this.mBottomRight.style.display = "none";
|
||||||
|
|
||||||
|
this.display = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
this.mTopLeft.style.display = "block";
|
||||||
|
this.mCenter.style.display = "block";
|
||||||
|
this.mBottomRight.style.display = "block";
|
||||||
|
|
||||||
|
this.display = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async setUp() {
|
||||||
|
this.writeCenter("Loading...");
|
||||||
|
|
||||||
|
this.bikes = await get("/bike");
|
||||||
|
this.programs = await get("/program");
|
||||||
|
this.workouts = await get("/workout?active=true");
|
||||||
|
|
||||||
|
this.writeCenter(null);
|
||||||
|
this.updateCenterState();
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateCenterState() {
|
||||||
|
const state = this.getState();
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case "down":
|
||||||
|
this.writeCenter(`
|
||||||
|
(1) Ny økt<br/>
|
||||||
|
(2) Fortsett forrige økt
|
||||||
|
`);
|
||||||
|
break;
|
||||||
|
case "bike":
|
||||||
|
// TODO: Add this??
|
||||||
|
if (this.bikes.length === 1) {
|
||||||
|
this.setup = {state: "program", bike: this.bikes[0]};
|
||||||
|
this.updateCenterState();
|
||||||
|
} else {
|
||||||
|
this.writeCenter("Sykkelvalg ikke støttet");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "program":
|
||||||
|
const options = this.programs.map((p, i) => `(${i + 1}) ${p.name}`)
|
||||||
|
|
||||||
|
this.writeCenter("Velg programm:<br/>" + options.join("<br/>"));
|
||||||
|
break;
|
||||||
|
case "disconnected":
|
||||||
|
this.writeCenter("Kobler til...");
|
||||||
|
break;
|
||||||
|
case "connected":
|
||||||
|
this.writeCenter(`
|
||||||
|
(Enter) Start/Pause<br/>
|
||||||
|
(Esc) Stopp
|
||||||
|
`);
|
||||||
|
break;
|
||||||
|
case "started":
|
||||||
|
const calorieDiff = this.calorieDiff();
|
||||||
|
if (calorieDiff < 0) {
|
||||||
|
this.writeCenter(`
|
||||||
|
<big style="color: ${this.colors[-1]};"><big><b>${calorieDiff}</b></big> kcal!</big>
|
||||||
|
`);
|
||||||
|
} else {
|
||||||
|
this.writeCenter(null);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.writeCenter(`Ugyldig tilstand: ${state}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateKeyBindings();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateKeyBindings() {
|
||||||
|
const dis = this;
|
||||||
|
|
||||||
|
this.mBody.onkeyup = function (event) {
|
||||||
|
const state = dis.getState();
|
||||||
|
|
||||||
|
if (state === "program") {
|
||||||
|
const i = parseInt(event.key, 10);
|
||||||
|
if (!isNaN(i) && typeof dis.programs[i - 1] !== "undefined") {
|
||||||
|
dis.bike = {...dis.setup.bike};
|
||||||
|
dis.startWorkout(dis.bike, dis.programs[i - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let handled = false;
|
||||||
|
switch (event.key) {
|
||||||
|
case "1":
|
||||||
|
if (state === "down") {
|
||||||
|
dis.setup = {state: "bike"};
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "2":
|
||||||
|
if (state === "down") {
|
||||||
|
const last = dis.workouts[dis.workouts.length - 1];
|
||||||
|
console.log(last);
|
||||||
|
if (last !== undefined) {
|
||||||
|
dis.resumeWorkout(last);
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Enter":
|
||||||
|
if (state === "connected") {
|
||||||
|
dis.start();
|
||||||
|
handled = true;
|
||||||
|
} else if (state === "started") {
|
||||||
|
dis.pause();
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Escape":
|
||||||
|
if (state === "connected") {
|
||||||
|
dis.stop();
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handled) {
|
||||||
|
dis.updateCenterState();
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async startWorkout(bike, program) {
|
||||||
|
this.bike = bike;
|
||||||
|
this.program = program;
|
||||||
|
|
||||||
|
const bikeId = bike.id;
|
||||||
|
const programId = program.id;
|
||||||
|
|
||||||
|
this.workout = await post("/workout", {bikeId, programId});
|
||||||
|
this.updateCenterState();
|
||||||
|
|
||||||
|
this.workout = await post(`/workout/${this.workout.id}/connect`);
|
||||||
|
this.updateCenterState();
|
||||||
|
|
||||||
|
this.setup = null;
|
||||||
|
this.webSocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
async resumeWorkout(workout) {
|
||||||
|
this.bike = workout.bike;
|
||||||
|
this.program = workout.program;
|
||||||
|
this.workout = workout;
|
||||||
|
|
||||||
|
this.setup = null;
|
||||||
|
this.webSocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
async start() {
|
||||||
|
this.workout = await post(`/workout/${this.workout.id}/start`);
|
||||||
|
this.updateCenterState();
|
||||||
|
}
|
||||||
|
|
||||||
|
async pause() {
|
||||||
|
this.workout = await post(`/workout/${this.workout.id}/pause`);
|
||||||
|
this.updateCenterState();
|
||||||
|
}
|
||||||
|
|
||||||
|
async stop() {
|
||||||
|
await post(`/workout/${this.workout.id}/stop`);
|
||||||
|
|
||||||
|
this.workout = null;
|
||||||
|
this.workouts = await post(`/workout?active=true`);
|
||||||
|
this.updateCenterState();
|
||||||
|
}
|
||||||
|
|
||||||
|
async webSocket() {
|
||||||
|
let dis = this;
|
||||||
|
|
||||||
|
this.socket = new WebSocket(url(`/workout/${this.workout.id}/subscribe`, "ws"));
|
||||||
|
|
||||||
|
this.socket.onmessage = function ({data, timeStamp}) {
|
||||||
|
let body = JSON.parse(data);
|
||||||
|
|
||||||
|
if (typeof body.workout !== "undefined") {
|
||||||
|
dis.workout = {...body.workout, ...dis.workout}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof body.workoutStatusBackfill !== "undefined") {
|
||||||
|
body.workoutStatusBackfill.forEach(wsbf => dis.updateWorkoutStatus(wsbf));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof body.workoutStatus !== "undefined") {
|
||||||
|
dis.updateWorkoutStatus(body.workoutStatus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateWorkoutStatus(newState = null) {
|
||||||
|
if (newState !== null) {
|
||||||
|
this.workoutStatus = newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.workoutStatus === null) {
|
||||||
|
this.writeTopLeft("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {minutes, seconds, calories, distance, rpm} = this.workoutStatus;
|
||||||
|
|
||||||
|
const cpmState = this.checkCpm();
|
||||||
|
const color = this.colors[cpmState];
|
||||||
|
|
||||||
|
this.writeTopLeft(`
|
||||||
|
<b><big>${pad(minutes)}</big></b> : <b><big>${pad(seconds)}</big></b><br/>
|
||||||
|
<b style="color: ${color}">${calories}</b> <small>kcal</small><br/>
|
||||||
|
<b>${distance.toFixed(1)}</b> <small>km</small><br/>
|
||||||
|
<b>${rpm}</b> <small>rpm</small><br/>
|
||||||
|
KPM: <b>${this.currentCpm.toFixed(1)}</b><br/>
|
||||||
|
`);
|
||||||
|
|
||||||
|
if (seconds === 0 && minutes > 0) {
|
||||||
|
this.updateMilestones(minutes, calories);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateCenterState();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkCpm() {
|
||||||
|
const {calories, minutes, seconds} = this.workoutStatus;
|
||||||
|
|
||||||
|
this.currentCpm = calories * 60 / ((minutes * 60) + seconds);
|
||||||
|
if (this.currentCpm === Infinity) {
|
||||||
|
this.currentCpm = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const program = this.program;
|
||||||
|
if (program === null || this.currentCpm === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.calorieDiff() < 0) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMilestones(minutes, calories) {
|
||||||
|
this.milestones.push({minutes, calories});
|
||||||
|
|
||||||
|
if (minutes % 5 === 0) {
|
||||||
|
this.milestones = this.milestones.filter(m => m.minutes % 5 === 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
let lines = "";
|
||||||
|
this.milestones.sort((i, j) => j.minutes - i.minutes).forEach(({minutes, calories}) => {
|
||||||
|
lines += `<tr style="text-align: right"><td>${minutes} </td><td> ${calories}</td></tr>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (lines.length > 0) {
|
||||||
|
this.writeBottomRight(`
|
||||||
|
<table>
|
||||||
|
${lines}
|
||||||
|
</table>
|
||||||
|
`);
|
||||||
|
} else {
|
||||||
|
this.writeBottomRight(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeTopLeft(message) {
|
||||||
|
this.mTopLeft.innerHTML = message;
|
||||||
|
|
||||||
|
if (message === null || !this.display) {
|
||||||
|
this.mTopLeft.style.display = "none";
|
||||||
|
} else {
|
||||||
|
this.mTopLeft.style.display = "block";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeCenter(message) {
|
||||||
|
this.mCenter.innerHTML = message;
|
||||||
|
|
||||||
|
if (message === null || !this.display) {
|
||||||
|
this.mCenter.style.display = "none";
|
||||||
|
} else {
|
||||||
|
this.mCenter.style.display = "block";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeBottomRight(message) {
|
||||||
|
this.mBottomRight.innerHTML = message;
|
||||||
|
|
||||||
|
if (message === null || !this.display) {
|
||||||
|
this.mBottomRight.style.display = "none";
|
||||||
|
} else {
|
||||||
|
this.mBottomRight.style.display = "block";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
calorieDiff() {
|
||||||
|
const {minutes, seconds, calories} = this.workoutStatus;
|
||||||
|
|
||||||
|
const expected = this.expectedCalories(minutes, seconds);
|
||||||
|
return calories - expected;
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedCalories(minutes, seconds) {
|
||||||
|
const {warmupMin, warmupCpm, cpm} = this.program;
|
||||||
|
|
||||||
|
let preWarmup = 0;
|
||||||
|
if (warmupMin > 0) {
|
||||||
|
// Pre-warmup
|
||||||
|
const warmedUpMinutes = Math.min(minutes, warmupMin);
|
||||||
|
const warmedUpSeconds = warmedUpMinutes >= warmupMin ? 0 : seconds;
|
||||||
|
preWarmup = Math.round((warmupCpm * (warmedUpMinutes + (warmedUpSeconds / 60))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post-warmup
|
||||||
|
const trainedMinutes = minutes - warmupMin;
|
||||||
|
const postWarmup = Math.round((cpm * (trainedMinutes + (seconds / 60))));
|
||||||
|
|
||||||
|
// Sum
|
||||||
|
return Math.round(preWarmup + postWarmup);
|
||||||
|
}
|
||||||
|
|
||||||
|
getState() {
|
||||||
|
return (this.workout || this.setup || {state: "down"}).state;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mCalorieCount = document.createElement("div");
|
function pad(number) {
|
||||||
mCalorieCount.id = "ykonsole-calorie-count";
|
return number >= 10 ? `${number}` : `0${number}`;
|
||||||
applyDefaultStyle(mCalorieCount);
|
}
|
||||||
mCalorieCount.style.left = 0;
|
|
||||||
mCalorieCount.style.top = 0;
|
|
||||||
mCalorieCount.innerHTML = `
|
|
||||||
<b>25</b>:<b>23</b>
|
|
||||||
<br/>
|
|
||||||
<b>883</b> kal
|
|
||||||
`;
|
|
||||||
document.body.append(mCalorieCount);
|
|
||||||
|
|
||||||
let mResults = document.createElement("div");
|
function url(path, prefix = "http") {
|
||||||
mResults.id = "ykonsole-result";
|
return `${prefix}://127.0.0.1:9999/api${path}`;
|
||||||
applyDefaultStyle(mResults);
|
}
|
||||||
mResults.style.right = 0;
|
|
||||||
mResults.style.bottom = 0;
|
function get(path) {
|
||||||
mResults.style.textAlign = "right";
|
return fetch(url(path), {
|
||||||
mResults.innerHTML = `
|
method: "GET",
|
||||||
5 161<br/>
|
}).then(r => r.json());
|
||||||
10 332<br/>
|
}
|
||||||
15 490<br/>
|
|
||||||
20 712<br/>
|
function post(path, data = {}) {
|
||||||
25 875<br/>
|
return fetch(url(path), {
|
||||||
`;
|
method: "POST",
|
||||||
document.body.append(mResults);
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
}).then(r => r.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const overlay =
|
||||||
|
new Overlay(
|
||||||
|
document.body,
|
||||||
|
document.createElement("div"),
|
||||||
|
document.createElement("div"),
|
||||||
|
document.createElement("div"));
|
||||||
|
|
||||||
|
overlay.show();
|
||||||
|
overlay.setUp();
|
||||||
|
|
||||||
chrome.storage.sync.get('color', ({color}) => {
|
chrome.storage.sync.get('color', ({color}) => {
|
||||||
});
|
});
|
||||||
|
|||||||
+2
-1
@@ -19,6 +19,7 @@
|
|||||||
"activeTab",
|
"activeTab",
|
||||||
"declarativeContent",
|
"declarativeContent",
|
||||||
"https://www.youtube.com/",
|
"https://www.youtube.com/",
|
||||||
"https://indigo.stian-aune.com/"
|
"https://indigo.stian-aune.com/",
|
||||||
|
"http://127.0.0.1:9999/"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -4,13 +4,10 @@ chrome.storage.sync.get('color', function(data) {
|
|||||||
changeColor.setAttribute('value', data.color);
|
changeColor.setAttribute('value', data.color);
|
||||||
});
|
});
|
||||||
|
|
||||||
changeColor.onclick = function(element) {
|
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
|
||||||
// TODO: Add settings to STORAGE
|
console.log("test");
|
||||||
|
|
||||||
let color = element.target.value;
|
chrome.tabs.executeScript(
|
||||||
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
|
tabs[0].id,
|
||||||
chrome.tabs.executeScript(
|
{file: 'contentScript.js'});
|
||||||
tabs[0].id,
|
});
|
||||||
{file: 'contentScript.js'});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|||||||
Reference in New Issue
Block a user