Skip to content

Commit

Permalink
fix: add extra logic to keep track of time accurately when in the bac…
Browse files Browse the repository at this point in the history
…kground

Fixes #608
  • Loading branch information
sekwah41 committed Aug 30, 2024
1 parent 2c3d11d commit 6351580
Show file tree
Hide file tree
Showing 4 changed files with 17,805 additions and 25,480 deletions.
63 changes: 48 additions & 15 deletions app/renderer/src/contexts/CounterContext.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useState, useEffect, useCallback } from "react";
import React, { useCallback, useEffect, useState } from "react";
import useStayAwake from "use-stay-awake";
import { setRound, setTimerType, setPlay } from "store";
import { setPlay, setRound, setTimerType } from "store";
import { useNotification } from "hooks";
import { padNum, isEqualToOne } from "utils";
import { isEqualToOne, padNum } from "utils";

import notificationIcon from "assets/logos/notification-dark.png";

Expand Down Expand Up @@ -51,12 +51,24 @@ const CounterProvider: React.FC = ({ children }) => {
const [shouldFullscreen, setShouldFullscreen] = useState(false);

const [count, setCount] = useState(config.stayFocus * 60);
const [lastCountTime, setLastCountTime] = useState(Date.now());
const [hasNotified30Seconds, setHasNotified30Seconds] =
useState(false);
const [hasNotified60Seconds, setHasNotified60Seconds] =
useState(false);
const [hasNotifiedBreak, setHasNotifiedBreak] = useState(false);

const [duration, setDuration] = useState(config.stayFocus * 60);

const setTimerDuration = useCallback((time: number) => {
setDuration(time * 60);
setCount(time * 60);
setLastCountTime(Date.now());
setHasNotified30Seconds(false);
if (time > 1) {
setHasNotified60Seconds(false);
}
setHasNotifiedBreak(false);
}, []);

const resetTimerAction = useCallback(() => {
Expand All @@ -71,8 +83,7 @@ const CounterProvider: React.FC = ({ children }) => {
setTimerDuration(config.longBreak);
break;
case TimerStatus.SPECIAL_BREAK:
setDuration(duration);
setCount(duration);
setTimerDuration(duration / 60);
break;
}
}, [
Expand All @@ -81,10 +92,15 @@ const CounterProvider: React.FC = ({ children }) => {
config.shortBreak,
timer.timerType,
duration,
setDuration,
setTimerDuration,
]);

useEffect(() => {
if (timer.playing) {
setLastCountTime(Date.now());
}
}, [timer.playing]);

useEffect(() => {
if (timer.playing && timer.timerType !== TimerStatus.STAY_FOCUS) {
preventSleeping();
Expand Down Expand Up @@ -212,21 +228,28 @@ const CounterProvider: React.FC = ({ children }) => {
useEffect(() => {
let timerInterval: NodeJS.Timeout;

// calculate how far off a full second the countdown timer is and adjust the countdown timer accordingly
const offset = count % 1;
if (timer.playing) {
timerInterval = setInterval(() => {
setCount((prevState) => {
let remaining = prevState - 1;
return remaining;
// Calculate time passed since last count
const now = Date.now();
const timePassed = now - lastCountTime;

setLastCountTime(Date.now());
return prevState - timePassed / 1000;
});
}, 1000);
}, offset * 1000);
}

return () => clearInterval(timerInterval);
}, [timer.playing]);
}, [timer.playing, lastCountTime, count]);

useEffect(() => {
if (settings.notificationType === "extra") {
if (count === 61) {
if (count <= 60 && count > 0 && !hasNotified60Seconds) {
setHasNotified60Seconds(true);
if (timer.timerType === TimerStatus.SHORT_BREAK) {
notification(
"60 seconds left.",
Expand All @@ -247,9 +270,12 @@ const CounterProvider: React.FC = ({ children }) => {
);
}
} else if (
count === 31 &&
timer.timerType === TimerStatus.STAY_FOCUS
count <= 30 &&
count > 0 &&
timer.timerType === TimerStatus.STAY_FOCUS &&
!hasNotified30Seconds
) {
setHasNotified30Seconds(true);
notification(
"30 seconds left.",
{ body: "Pause all media playing if there's one." },
Expand All @@ -258,7 +284,8 @@ const CounterProvider: React.FC = ({ children }) => {
}
}

if (count === 0) {
if (count <= 0 && !hasNotifiedBreak) {
setHasNotifiedBreak(true);
switch (timer.timerType) {
case TimerStatus.STAY_FOCUS:
if (timer.round < config.sessionRounds) {
Expand Down Expand Up @@ -379,6 +406,12 @@ const CounterProvider: React.FC = ({ children }) => {
settings.notificationType,
settings.autoStartWorkTime,
settings.enableVoiceAssistance,
hasNotified60Seconds,
hasNotified60Seconds,
hasNotifiedBreak,
setHasNotified30Seconds,
setHasNotified60Seconds,
setHasNotifiedBreak,
]);

useEffect(() => {
Expand All @@ -394,7 +427,7 @@ const CounterProvider: React.FC = ({ children }) => {
return (
<CounterContext.Provider
value={{
count,
count: Math.ceil(count),
duration,
resetTimerAction,
shouldFullscreen,
Expand Down
2 changes: 1 addition & 1 deletion app/tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "pomatez"
# In the current version of release please, unless the toml file is in the root of the project it cannot be updated.
# https://github.com/googleapis/release-please/issues/1724
# util/cargo-version-updater.js will run to keep this value up to date before rust builds.
version = "1.6.4"
version = "1.7.0"
description = "Attractive pomodoro timer for Windows, Mac, and Linux."
authors = ["Roldan Montilla Jr"]
license = "MIT"
Expand Down
Loading

0 comments on commit 6351580

Please sign in to comment.