Skip to content

Commit f932dd7

Browse files
authored
Merge pull request #52 from AXeL-dev/feat/timer
Feat: Timer
2 parents a1467c1 + 2f5f27d commit f932dd7

File tree

32 files changed

+752
-189
lines changed

32 files changed

+752
-189
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Distract Me Not is a lightweight website blocker with a user friendly interface.
1818
- Display your custom message on blocked pages.
1919
- Immediate closing of blocked tabs.
2020
- Schedule blocking time.
21+
- Timer mode.
2122
- Export/Import websites lists.
2223
- Protect your settings with a password.
2324
- Unblock websites using a password.

package-lock.json

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"omgopass": "^3.2.1",
1717
"query-string": "^7.1.1",
1818
"react": "^17.0.2",
19+
"react-countdown-circle-timer": "^3.0.8",
1920
"react-dom": "^17.0.2",
2021
"react-router-dom": "^5.3.0",
2122
"react-scripts": "^4.0.3",
@@ -25,7 +26,7 @@
2526
},
2627
"scripts": {
2728
"start": "craco start",
28-
"build": "CI=false INLINE_RUNTIME_CHUNK=false GENERATE_SOURCEMAP=false craco build",
29+
"build": "INLINE_RUNTIME_CHUNK=false GENERATE_SOURCEMAP=false craco build",
2930
"build:firefox": "npm run build",
3031
"build:chrome": "npm run build",
3132
"build:edge": "npm run build",
@@ -41,6 +42,7 @@
4142
"sign": "node ./scripts/sign-addon.js",
4243
"test": "craco test --verbose",
4344
"test:all": "npm test -- --watchAll --testMatch \"**/src/**/*.test.{js,jsx}\"",
45+
"test:update": "npm run test:all -- -u",
4446
"eject": "react-scripts eject",
4547
"release:major": "release-it major",
4648
"release:minor": "release-it minor",

public/_locales/en/messages.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,5 +387,41 @@
387387
},
388388
"openLogs": {
389389
"message": "Open logs"
390+
},
391+
"timer": {
392+
"message": "Timer"
393+
},
394+
"enableTimer": {
395+
"message": "Enable timer"
396+
},
397+
"enableTimerDescription": {
398+
"message": "Displays a 'Timer' button on the main panel"
399+
},
400+
"defaultTimerValue": {
401+
"message": "Default timer value"
402+
},
403+
"allowStoppingTimer": {
404+
"message": "Allow stopping the timer before it ends"
405+
},
406+
"displayNotificationOnComplete": {
407+
"message": "Display a notification when the timer ends"
408+
},
409+
"allowUsingTimerWithoutPassword": {
410+
"message": "Allow using the timer without entering the password"
411+
},
412+
"mainPanel": {
413+
"message": "Main panel"
414+
},
415+
"start": {
416+
"message": "Start"
417+
},
418+
"stop": {
419+
"message": "Stop"
420+
},
421+
"remainingTime": {
422+
"message": "Remaining time"
423+
},
424+
"timerCompleted": {
425+
"message": "Timer completed!"
390426
}
391427
}

public/_locales/fr/messages.json

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,13 +344,13 @@
344344
"message": "Nombre de lignes à conserver dans la table des logs"
345345
},
346346
"hideReportIssueButton": {
347-
"message": "Masquer le bouton \"signaler un problème\" sur le panneau principal"
347+
"message": "Masquer le bouton 'signaler un problème' sur le panneau principal"
348348
},
349349
"showAddWebsitePrompt": {
350350
"message": "Afficher l'invite d'ajout de site web"
351351
},
352352
"showAddWebsitePromptTooltip": {
353-
"message": "Affiche une invite de confirmation lors de l'ajout d'un site web à partir du button \"+\" sur le panneau principal"
353+
"message": "Affiche une invite de confirmation lors de l'ajout d'un site web à partir du button '+' sur le panneau principal"
354354
},
355355
"urls": {
356356
"message": "Liens"
@@ -387,5 +387,41 @@
387387
},
388388
"openLogs": {
389389
"message": "Consulter les journaux"
390+
},
391+
"timer": {
392+
"message": "Minuteur"
393+
},
394+
"enableTimer": {
395+
"message": "Activer le minuteur"
396+
},
397+
"enableTimerDescription": {
398+
"message": "Affiche un bouton 'Minuteur' sur le panneau principal"
399+
},
400+
"defaultTimerValue": {
401+
"message": "Valeur par défaut du minuteur"
402+
},
403+
"allowStoppingTimer": {
404+
"message": "Permettre l'arrêt manuel du minuteur avant qu'il ne se termine"
405+
},
406+
"displayNotificationOnComplete": {
407+
"message": "Afficher une notification lorsque le minuteur se termine"
408+
},
409+
"allowUsingTimerWithoutPassword": {
410+
"message": "Permettre l'accès au minuteur sans entrer le mot de passe"
411+
},
412+
"mainPanel": {
413+
"message": "Panneau principal"
414+
},
415+
"start": {
416+
"message": "Démarrer"
417+
},
418+
"stop": {
419+
"message": "Arrêter"
420+
},
421+
"remainingTime": {
422+
"message": "Temps restant"
423+
},
424+
"timerCompleted": {
425+
"message": "Minuteur terminé!"
390426
}
391427
}

public/_locales/nl/messages.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,5 +387,41 @@
387387
},
388388
"openLogs": {
389389
"message": "Open logboek"
390+
},
391+
"timer": {
392+
"message": "Tijdklok"
393+
},
394+
"enableTimer": {
395+
"message": "Tijdklok inschakelen"
396+
},
397+
"enableTimerDescription": {
398+
"message": "Toont een 'Tijdklok' knop op het hoofdpaneel"
399+
},
400+
"defaultTimerValue": {
401+
"message": "Standaard timerwaarde"
402+
},
403+
"allowStoppingTimer": {
404+
"message": "Laat toe de timer te stoppen voor hij afloopt"
405+
},
406+
"displayNotificationOnComplete": {
407+
"message": "Geef een melding wanneer de timer afloopt"
408+
},
409+
"allowUsingTimerWithoutPassword": {
410+
"message": "Gebruik van de timer toestaan zonder het wachtwoord in te voeren"
411+
},
412+
"mainPanel": {
413+
"message": "Hoofdpaneel"
414+
},
415+
"start": {
416+
"message": "Start"
417+
},
418+
"stop": {
419+
"message": "Stop"
420+
},
421+
"remainingTime": {
422+
"message": "Resterende tijd"
423+
},
424+
"timerCompleted": {
425+
"message": "Timer voltooid!"
390426
}
391427
}

src/App.jsx

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import React, { Component } from 'react';
22
import { HashRouter as Router, Switch, Route } from 'react-router-dom';
33
import { TransitionGroup, CSSTransition } from 'react-transition-group';
44
import { storage } from './helpers/webext';
5-
import { isDevEnv } from './helpers/debug';
6-
import { Panel, Settings, Logs, Background, Blocked, PasswordPrompt, AddWebsitePrompt } from './components';
5+
import { isDevEnv, isTestEnv } from './helpers/debug';
6+
import { Main, Panel, Settings, Timer, Logs, Background, Blocked, PasswordPrompt, AddWebsitePrompt } from './components';
77
import { PasswordProtectedRoute } from './routes';
88

99
export default class App extends Component {
@@ -16,6 +16,9 @@ export default class App extends Component {
1616
}
1717

1818
componentDidMount() {
19+
if (isTestEnv) {
20+
return;
21+
}
1922
storage.get({
2023
password: {
2124
isEnabled: false
@@ -31,25 +34,30 @@ export default class App extends Component {
3134
return (
3235
<Router>
3336
<Route render={({ location }) => (
34-
<TransitionGroup className="page">
35-
<CSSTransition
36-
key={location.pathname}
37-
classNames="fade"
38-
timeout={300}
39-
>
40-
<Switch location={location}>
41-
<PasswordProtectedRoute exact path="/" component={Panel} accessAllowed={this.state.accessAllowed} showPromptHeader={true} showPromptFooter={true} />
42-
<PasswordProtectedRoute path="/settings" component={Settings} accessAllowed={this.state.accessAllowed} />
43-
<PasswordProtectedRoute path="/logs" component={Logs} accessAllowed={this.state.accessAllowed} />
44-
<Route path="/background" component={Background} />
45-
<Route path="/blocked" component={Blocked} />
46-
<Route path="/addWebsitePrompt" component={AddWebsitePrompt} />
47-
{isDevEnv || !this.state.accessAllowed ? (
48-
<Route path="/pwd" component={PasswordPrompt} />
49-
) : null}
50-
</Switch>
51-
</CSSTransition>
52-
</TransitionGroup>
37+
<>
38+
{/* Routes that only does redirecting should be outside of the transition group */}
39+
<Route exact path="/" component={Main} />
40+
<TransitionGroup className="page">
41+
<CSSTransition
42+
key={location.pathname}
43+
classNames="fade"
44+
timeout={300}
45+
>
46+
<Switch location={location}>
47+
<PasswordProtectedRoute path="/panel" component={Panel} accessAllowed={this.state.accessAllowed} showPromptHeader={true} showPromptFooter={true} />
48+
<PasswordProtectedRoute path="/timer" component={Timer} accessAllowed={this.state.accessAllowed} showPromptHeader={true} showPromptFooter={true} />
49+
<PasswordProtectedRoute path="/settings" component={Settings} accessAllowed={this.state.accessAllowed} />
50+
<PasswordProtectedRoute path="/logs" component={Logs} accessAllowed={this.state.accessAllowed} />
51+
<Route path="/background" component={Background} />
52+
<Route path="/blocked" component={Blocked} />
53+
<Route path="/addWebsitePrompt" component={AddWebsitePrompt} />
54+
{isDevEnv || !this.state.accessAllowed ? (
55+
<Route path="/pwd" component={PasswordPrompt} />
56+
) : null}
57+
</Switch>
58+
</CSSTransition>
59+
</TransitionGroup>
60+
</>
5361
)} />
5462
</Router>
5563
);

src/__tests__/App.test.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import React from 'react';
22
import { render, screen } from '@testing-library/react';
33
import App from '../App';
44

5+
it('renders nothing when accessAllowed prop is not defined', () => {
6+
const { container } = render(<App />);
7+
expect(container.firstChild).toBeEmptyDOMElement();
8+
});
9+
510
it('renders appName header when access is allowed', () => {
611
render(<App accessAllowed={true} />);
712
const headerElement = screen.getByText(/appName/i);
@@ -13,8 +18,3 @@ it('renders password prompt when access is not allowed', () => {
1318
const passwordInput = screen.getByPlaceholderText('password');
1419
expect(passwordInput).toBeInTheDocument();
1520
});
16-
17-
it('renders nothing when accessAllowed prop is not defined', () => {
18-
const { container } = render(<App />);
19-
expect(container).toBeEmptyDOMElement();
20-
});

src/__tests__/__snapshots__/AnimatedIconButton.test.js.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ exports[`renders correctly 1`] = `
99
class="ub-dspl_inline-flex ub-box-szg_border-box"
1010
>
1111
<svg
12-
class="css-c4d79v ub-w_22px ub-h_22px ub-box-szg_border-box"
12+
class="css-c4d79v ub-w_18px ub-h_18px ub-box-szg_border-box"
1313
data-icon="cross"
14-
viewBox="0 0 20 20"
14+
viewBox="0 0 16 16"
1515
>
1616
<path
17-
d="M11.41 10l4.29-4.29c.19-.18.3-.43.3-.71a1.003 1.003 0 00-1.71-.71L10 8.59l-4.29-4.3a1.003 1.003 0 00-1.42 1.42L8.59 10 4.3 14.29c-.19.18-.3.43-.3.71a1.003 1.003 0 001.71.71l4.29-4.3 4.29 4.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71L11.41 10z"
17+
d="M9.41 8l3.29-3.29c.19-.18.3-.43.3-.71a1.003 1.003 0 00-1.71-.71L8 6.59l-3.29-3.3a1.003 1.003 0 00-1.42 1.42L6.59 8 3.3 11.29c-.19.18-.3.43-.3.71a1.003 1.003 0 001.71.71L8 9.41l3.29 3.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71L9.41 8z"
1818
fill-rule="evenodd"
1919
/>
2020
</svg>

src/__tests__/__snapshots__/IconButton.test.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ exports[`renders correctly 1`] = `
99
class="ub-dspl_inline-flex ub-box-szg_border-box"
1010
>
1111
<svg
12-
class="css-c4d79v ub-w_16px ub-h_16px ub-box-szg_border-box"
12+
class="css-c4d79v ub-w_18px ub-h_18px ub-box-szg_border-box"
1313
data-icon="cross"
1414
viewBox="0 0 16 16"
1515
>

0 commit comments

Comments
 (0)