Quantcast
Channel: Active questions tagged svelte - Stack Overflow
Viewing all articles
Browse latest Browse all 1541

Certain parts of extension only update when refreshing the extension

$
0
0

I hope this is the right place to ask, if it's not, please tell me where I should post it.

I'm making a pomodoro timer browser extension using WXT and Svelte.js with Typescript. My extension works quite as it should, the problem is that certain things only really update when I close and reopen the extension. It might be that I'm misusing background.ts a bit. I tried lots of different stuff, placing some events on different places, tried normal functions and async on some places but it all didn't help... Could someone give me a few tips how I make this extension dynamic and make it work properly? I'm already stuck for quite some time now...

Here's my code for Start.svelte (element for start/pause button), TimerType.svelte (to change timers, the timer count does not update dynamically) and background.ts.

<!-- Start.svelte --><script lang="ts">  import {    POMODORO as pomodoro,    SHORT_BREAK as shortBreak,    LONG_BREAK as longBreak,  } from "@/utils/constants";  import pauseIcon from "~/assets/icon/pause.png";  import playIcon from "~/assets/icon/play.png";  import timeUp from "~/assets/sound/time-up.wav";  import toDoubleDigit from "@/utils/toDoubleDigit";  import { onMount } from "svelte";  const timeUpSound = new Audio(timeUp);  export let buttonState: "START" | "PAUSE" = "START";  export let timer: HTMLElement | null = document.getElementById("timer");  export let timerType: "POMODORO" | "SHORT_BREAK" | "LONG_BREAK" = "POMODORO";  export let completedSessions = {    completedPomodoros: 0,    completedShortBreaks: 0,    completedLongBreaks: 0,  };  let timeBetween: number = 0;  let shouldUpdateTimer = true;  onMount(async () => {    const state = await browser.runtime.sendMessage({ type: "GET_STATE" });    if (state) {      timerType = state.timerType;      completedSessions = state.completedSessions;    }    initializeTimer(timerType);  });  const initializeTimer = (timerType: "POMODORO" | "SHORT_BREAK" | "LONG_BREAK") => {    switch (timerType) {      case "POMODORO":        timeBetween = Number(pomodoro);        break;      case "SHORT_BREAK":        timeBetween = Number(shortBreak);        break;      case "LONG_BREAK":        timeBetween = Number(longBreak);        break;    }    if (timer) {      const { minutes, seconds } = getMinutesSeconds(timeBetween);      timer.innerHTML = `${minutes}:${seconds}`;    }    console.log(`debug> initializeTimer called with timerType: ${timerType}, timeBetween: ${timeBetween}`);  };  const resetTimer = () => {    switch (timerType) {      case "POMODORO":        timeBetween = Number(pomodoro);        buttonState = "START";        break;      case "SHORT_BREAK":        timeBetween = Number(shortBreak);        buttonState = "START";        break;      case "LONG_BREAK":        timeBetween = Number(longBreak);        buttonState = "START";        break;    }    if (timer) {      const { minutes, seconds } = getMinutesSeconds(timeBetween);      timer.innerHTML = `${minutes}:${seconds}`;    }  };  initializeTimer(timerType);  console.log(`debug> timeBetween: ${timeBetween}`);  $: {    browser.runtime.onMessage.addListener((message, sender, onResponse) => {      console.log(`debug> received message inside Start.svelte: ${message.type}`);      if (message.type === "RESET_TIMER") {        timeUpSound.play();        completedSessions = message.completedSessions;        resetTimer();      } else if (message.type === "INIT_TIMER") {        initializeTimer(message.timerType);      } else if (message.type === "UPDATE_TIMER") {        if (timer) {          timer.innerText = message.time;          timeBetween = message.time            .split(":")            .reduce((acc: number, time: number, index: number) => {              if (index === 0) {                return acc + Number(time) * 60000;              } else {                return acc + Number(time) * 1000;              }            }, 0);        }      }    });  }  const getMinutesSeconds = (time: number) => ({    minutes: toDoubleDigit(Math.floor((time / 60000) % 60)),    seconds: toDoubleDigit(Math.floor((time / 1000) % 60)),  });  $: ({ minutes, seconds } = getMinutesSeconds(timeBetween));  const changeButtonState = () => {    buttonState = buttonState === "START" ? "PAUSE" : "START";  };  $: {    if (shouldUpdateTimer && timer) {      timer.innerHTML = `${minutes}:${seconds}`;      shouldUpdateTimer = false;    }  }  const handleClick = async () => {    if (buttonState === "START") {      await browser.runtime.sendMessage({        type: "START_TIMER",        time: timeBetween,      });    } else {      const response = await browser.runtime.sendMessage({        type: "PAUSE_TIMER",        time: timeBetween,      });      if (timer && response) {        const time = Number(response.time);        if (!isNaN(time)) {          const { minutes, seconds } = getMinutesSeconds(time);          timer.innerText = `${minutes}:${seconds}`;        }      }    }    changeButtonState();  };</script><button id="timerButton" on:click={handleClick}> // by the way, these buttons work correctly when you click on them, just usually don't show up correctly in the extension  {#if buttonState === "START"}<img src={playIcon} width="12" alt="Play" />  {:else}<img src={pauseIcon} width="12" alt="Pause" />  {/if}</button>
<!-- TimerType.svelte --><script lang="ts">    import './timertype.css';    import './Start.svelte';    export let timerType: "POMODORO" | "SHORT_BREAK" | "LONG_BREAK" = "POMODORO";    export let buttonState: "START" | "PAUSE" = "START";    export let completedSessions = {      completedPomodoros: 0,      completedShortBreaks: 0,      completedLongBreaks: 0    };    const handleClick = () => {        const pomodoro = document.getElementById('pomodoro') as HTMLInputElement;        const shortBreak = document.getElementById('shortBreak') as HTMLInputElement;        const longBreak = document.getElementById('longBreak') as HTMLInputElement;        if (pomodoro.checked) {            timerType = "POMODORO";        } else if (shortBreak.checked) {            timerType = "SHORT_BREAK";        } else if (longBreak.checked) {            timerType = "LONG_BREAK";        }        browser.runtime.sendMessage({ type: "INIT_TIMER", timerType });        console.log(`debug> completedSessions: ${JSON.stringify(completedSessions)}`);        console.log(`debug> timer changed to: ${timerType}`);    }</script><div class="timer-type" data-is="multiswitch"><form><label><input type="radio" id="pomodoro" data-id="1" name="timerType" checked on:click={handleClick} disabled={buttonState === "PAUSE"}><span>Pomodoro {#if completedSessions.completedPomodoros > 0}<strong style="font-family: 'Manrope'; line-height: 1;">({completedSessions.completedPomodoros})</strong>{/if}</span></label><label><input type="radio" id="shortBreak" data-id="2" name="timerType" on:click={handleClick} disabled={buttonState === "PAUSE"}><span>Short Break {#if completedSessions.completedShortBreaks > 0}<strong style="font-family: 'Manrope'; line-height: 1;">({completedSessions.completedShortBreaks})</strong>{/if}</span></label><label><input type="radio" id="longBreak" name="timerType" data-id="3" on:click={handleClick} disabled={buttonState === "PAUSE"}><span>Long Break {#if completedSessions.completedLongBreaks > 0}<strong style="font-family: 'Manrope'; line-height: 1;">({completedSessions.completedLongBreaks})</strong>{/if}</span></label><div id="indicator"></div></form></div>
// background.tsimport { countdown } from "@/utils/countdown";import toDoubleDigit from "@/utils/toDoubleDigit";export let timerType: "POMODORO" | "SHORT_BREAK" | "LONG_BREAK" = "POMODORO";export let completedSessions = {  completedPomodoros: 0,  completedShortBreaks: 0,  completedLongBreaks: 0,};let interval: NodeJS.Timeout | null = null;let timeBetween: number;export default defineBackground(() => {  console.log("info> started StudyMate", { id: browser.runtime.id });  const getMinutesSeconds = (time: number) => {    const minutes = toDoubleDigit(Math.floor(time / 60000) % 60);    const seconds = toDoubleDigit(Math.floor(time / 1000) % 60);    return { minutes, seconds };  };  const updateTimer = (time: number) => {    let { minutes, seconds } = getMinutesSeconds(time);    return `${minutes}:${seconds}`;  };  const playTimer = (time: number) => {    interval = countdown(      time,      (remainingTime) => {        timeBetween = remainingTime;        browser.runtime.sendMessage({          type: "UPDATE_TIMER",          time: updateTimer(timeBetween),        });      },      () => {        if (timerType === "POMODORO") {          completedSessions.completedPomodoros += 1;        } else if (timerType === "SHORT_BREAK") {          completedSessions.completedShortBreaks += 1;        } else if (timerType === "LONG_BREAK") {          completedSessions.completedLongBreaks += 1;        }        browser.runtime.sendMessage({ type: "RESET_TIMER" });      }    );  };  const pauseTimer = () => {    if (interval !== null) clearInterval(interval);  };  browser.runtime.onMessage.addListener((message, sender, sendResponse) => {    if (message.type === "GET_STATE") {      sendResponse({ timerType, completedSessions });    } else if (message.type === "START_TIMER") {      playTimer(message.time);      sendResponse({ status: "timerStarted", time: updateTimer(message.time) });    } else if (message.type === "PAUSE_TIMER") {      pauseTimer();      console.log(        `debug> background.ts sent response w/ ${updateTimer(message.time)}`      );      sendResponse({ status: "timerPaused", time: updateTimer(message.time) });    } else if (message.type === "INIT_TIMER") {      browser.runtime.sendMessage({ type: "INIT_TIMER", timerType: message.timerType });    }    console.log(      `debug> received message inside background.ts: ${        message.type      } with additional data: ${JSON.stringify(message)}`    );    return true;  });});

If you need more code to reproduce, it's on GitHub: https://github.com/ThatFrogDev/StudyMate.

Also to reproduce, a quick example:


Viewing all articles
Browse latest Browse all 1541

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>