mirror of
https://github.com/FranP-code/Pomodoro-Timer-with-Clockify-integration.git
synced 2025-10-12 23:52:30 +00:00
Notification permission ask added
This commit is contained in:
@@ -3,16 +3,20 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 17vh;
|
height: 14vh;
|
||||||
padding: 0vh 1vw;
|
padding: 0vh 1vw;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.header-main-page a {
|
.header-main-page a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
.header-main-page .title-link {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
.header-main-page h1 {
|
.header-main-page h1 {
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
font-size: 3vw;
|
font-size: 3vw;
|
||||||
|
display: inline;
|
||||||
font-family: "Raleway", sans-serif;
|
font-family: "Raleway", sans-serif;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -25,6 +29,41 @@
|
|||||||
color: #4c8ad5;
|
color: #4c8ad5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification-select {
|
||||||
|
background-color: #1FAB89;
|
||||||
|
height: 3vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
padding-left: 1vw;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #fff;
|
||||||
|
font-family: "Rambla", sans-serif;
|
||||||
|
}
|
||||||
|
.notification-select p {
|
||||||
|
display: inline-block;
|
||||||
|
align-self: center;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
margin-right: 1vw;
|
||||||
|
}
|
||||||
|
.notification-select button {
|
||||||
|
height: 80%;
|
||||||
|
width: 5%;
|
||||||
|
margin-right: 0.5vw;
|
||||||
|
border: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
align-self: center;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.notification-select button.yes {
|
||||||
|
background-color: #4caf50;
|
||||||
|
}
|
||||||
|
.notification-select button.no {
|
||||||
|
background-color: #d32f2f;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 991.98px) {
|
@media (max-width: 991.98px) {
|
||||||
.header-main-page {
|
.header-main-page {
|
||||||
height: auto;
|
height: auto;
|
||||||
@@ -37,12 +76,31 @@
|
|||||||
.header-main-page h3 {
|
.header-main-page h3 {
|
||||||
font-size: 13pt;
|
font-size: 13pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification-select {
|
||||||
|
height: auto;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.notification-select p {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 1vh;
|
||||||
|
margin-bottom: 1vh;
|
||||||
|
}
|
||||||
|
.notification-select button {
|
||||||
|
height: 30px;
|
||||||
|
width: 20%;
|
||||||
|
margin-bottom: 1vh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.header-main-page.dark-mode-component {
|
.header-main-page.dark-mode-component {
|
||||||
background-color: #303841;
|
background-color: #303841;
|
||||||
border-bottom: 1px solid #ffffff72;
|
border-bottom: 1px solid #ffffff72;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification-select.dark-mode-component {
|
||||||
|
background-color: #3A4750;
|
||||||
|
}
|
||||||
|
|
||||||
.banner-login {
|
.banner-login {
|
||||||
background-color: #D17262;
|
background-color: #D17262;
|
||||||
color: white;
|
color: white;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -7,7 +7,7 @@
|
|||||||
// align-items: center;
|
// align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
height: 17vh;
|
height: 14vh;
|
||||||
padding: 0vh 1vw;
|
padding: 0vh 1vw;
|
||||||
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -15,11 +15,18 @@
|
|||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.title-link {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
|
||||||
font-size: 3vw;
|
font-size: 3vw;
|
||||||
|
|
||||||
|
display: inline;
|
||||||
|
|
||||||
@include titleFont();
|
@include titleFont();
|
||||||
@include normalizeTitle();
|
@include normalizeTitle();
|
||||||
}
|
}
|
||||||
@@ -30,28 +37,98 @@
|
|||||||
color: $lightest-color-dark;
|
color: $lightest-color-dark;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.notification-select {
|
||||||
|
|
||||||
|
background-color: $second-color;
|
||||||
|
height: 3vh;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
|
||||||
|
padding-left: 1vw;
|
||||||
@media (max-width: 991.98px) {
|
|
||||||
.header-main-page {
|
|
||||||
height: auto;
|
|
||||||
padding: 3vw 0px;
|
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
h1 {
|
box-sizing: border-box;
|
||||||
font-size: 26pt;
|
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
@include bodyFont();
|
||||||
|
|
||||||
|
p {
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
align-self: center;
|
||||||
|
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
margin-right: 1vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
button {
|
||||||
font-size: 13pt;
|
height: 80%;
|
||||||
}
|
width: 5%;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-main-page.dark-mode-component {
|
margin-right: 0.5vw;
|
||||||
background-color: $main-color-dark;
|
|
||||||
border-bottom: 1px solid #ffffff72;
|
border: none;
|
||||||
}
|
border-radius: 2px;
|
||||||
|
|
||||||
|
align-self: center;
|
||||||
|
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.yes {
|
||||||
|
background-color: rgb(76, 175, 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.no {
|
||||||
|
background-color: rgb(211, 47, 47);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991.98px) {
|
||||||
|
.header-main-page {
|
||||||
|
height: auto;
|
||||||
|
padding: 3vw 0px;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 26pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 13pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-select {
|
||||||
|
height: auto;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
p {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 1vh;
|
||||||
|
margin-bottom: 1vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
height: 30px;
|
||||||
|
width: 20%;
|
||||||
|
margin-bottom: 1vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-main-page.dark-mode-component {
|
||||||
|
background-color: $main-color-dark;
|
||||||
|
border-bottom: 1px solid #ffffff72;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-select.dark-mode-component {
|
||||||
|
background-color: $second-color-dark;
|
||||||
|
}
|
||||||
15
src/App.js
15
src/App.js
@@ -28,6 +28,8 @@ function App() {
|
|||||||
|
|
||||||
const [KonamiCodeActive, setKonamiCodeActive] = useState(false)
|
const [KonamiCodeActive, setKonamiCodeActive] = useState(false)
|
||||||
|
|
||||||
|
const [notificationPermission, setNotificationPermission] = useState(undefined)
|
||||||
|
|
||||||
const auth = getAuth()
|
const auth = getAuth()
|
||||||
|
|
||||||
onAuthStateChanged(auth, (user) => {
|
onAuthStateChanged(auth, (user) => {
|
||||||
@@ -49,6 +51,14 @@ function App() {
|
|||||||
root.style.flexDirection ='column'
|
root.style.flexDirection ='column'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const permission = localStorage.getItem("notification-permission")
|
||||||
|
|
||||||
|
if (permission !== undefined && permission !== null) {
|
||||||
|
setNotificationPermission(permission === "true" ? true : false)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
@@ -60,6 +70,9 @@ function App() {
|
|||||||
setDarkmode={setDarkmode}
|
setDarkmode={setDarkmode}
|
||||||
|
|
||||||
KonamiCodeActive= {KonamiCodeActive}
|
KonamiCodeActive= {KonamiCodeActive}
|
||||||
|
|
||||||
|
notificationPermission={notificationPermission}
|
||||||
|
setNotificationPermission={setNotificationPermission}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Switch>
|
<Switch>
|
||||||
@@ -128,6 +141,8 @@ function App() {
|
|||||||
|
|
||||||
setKonamiCodeActive = {setKonamiCodeActive}
|
setKonamiCodeActive = {setKonamiCodeActive}
|
||||||
KonamiCodeActive= {KonamiCodeActive}
|
KonamiCodeActive= {KonamiCodeActive}
|
||||||
|
|
||||||
|
notificationPermission={notificationPermission}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<GoDownArrow
|
<GoDownArrow
|
||||||
|
|||||||
@@ -4,9 +4,23 @@ import GoToAccount from './Header Childrens/GoToAccount'
|
|||||||
|
|
||||||
const Header = (props) => {
|
const Header = (props) => {
|
||||||
|
|
||||||
|
const getPermisionDesktopNotification = async () => {
|
||||||
|
|
||||||
|
let permission = await Notification.requestPermission();
|
||||||
|
|
||||||
|
if (permission === 'granted') {
|
||||||
|
props.setNotificationPermission(true)
|
||||||
|
localStorage.setItem("notification-permission", true)
|
||||||
|
} else {
|
||||||
|
props.setNotificationPermission(false)
|
||||||
|
localStorage.setItem("notification-permission", false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<header className={props.darkMode ? 'header-main-page dark-mode-component' : 'header-main-page'} >
|
<header className={props.darkMode ? 'header-main-page dark-mode-component' : 'header-main-page'} >
|
||||||
<a href="/">
|
<a href="/" className='title-link'>
|
||||||
<h1>Clockify Pomodoro Timer</h1>
|
<h1>Clockify Pomodoro Timer</h1>
|
||||||
</a>
|
</a>
|
||||||
<DarkMode
|
<DarkMode
|
||||||
@@ -21,6 +35,19 @@ const Header = (props) => {
|
|||||||
{props.KonamiCodeActive ? 'Konami Code ON' : null}
|
{props.KonamiCodeActive ? 'Konami Code ON' : null}
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
{
|
||||||
|
props.notificationPermission === undefined || process.env.REACT_APP_ENVIROMENT !== "production" ?
|
||||||
|
<div className={props.darkMode ? 'notification-select dark-mode-component' : 'notification-select'}>
|
||||||
|
<p>Do you want to recibe a notification when a Pomodoro cicle ends?</p>
|
||||||
|
<button className="yes" onClick={getPermisionDesktopNotification}>YES</button>
|
||||||
|
<button className="no" onClick={() => {
|
||||||
|
props.setNotificationPermission(false)
|
||||||
|
localStorage.setItem("notification-permission", false)
|
||||||
|
}}>Nah</button>
|
||||||
|
</div>
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,26 +29,9 @@ const MainPomodoroTimer = (props) => {
|
|||||||
const [controlKonamiCode, setControlKonamiCode] = useState(true)
|
const [controlKonamiCode, setControlKonamiCode] = useState(true)
|
||||||
|
|
||||||
const [velocity, setVelocity] = useState(1)
|
const [velocity, setVelocity] = useState(1)
|
||||||
|
|
||||||
const [notificationPermission, setNotificationPermission] = useState('')
|
|
||||||
|
|
||||||
const setTimeStyle = () => setTimeStyleExternal(props, setMinutes, setSeconds, setBreakTime, setActualStyle, breakTime)
|
const setTimeStyle = () => setTimeStyleExternal(props, setMinutes, setSeconds, setBreakTime, setActualStyle, breakTime)
|
||||||
|
|
||||||
const getPermisionDesktopNotification = async () => {
|
|
||||||
|
|
||||||
let permission = await Notification.requestPermission();
|
|
||||||
|
|
||||||
if (permission === 'granted') {
|
|
||||||
|
|
||||||
await setNotificationPermission(true)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
setNotificationPermission(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
React.useEffect (() => {
|
React.useEffect (() => {
|
||||||
|
|
||||||
if (actualStyle !== props.style) {
|
if (actualStyle !== props.style) {
|
||||||
@@ -61,10 +44,7 @@ const MainPomodoroTimer = (props) => {
|
|||||||
detectKeys(props.setKonamiCodeActive)
|
detectKeys(props.setKonamiCodeActive)
|
||||||
|
|
||||||
setControlKonamiCode(false)
|
setControlKonamiCode(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
getPermisionDesktopNotification()
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const startTimer = () => {
|
const startTimer = () => {
|
||||||
@@ -188,7 +168,7 @@ const MainPomodoroTimer = (props) => {
|
|||||||
|
|
||||||
playAudio('work')
|
playAudio('work')
|
||||||
|
|
||||||
if (notificationPermission) {
|
if (props.notificationPermission) {
|
||||||
|
|
||||||
new Notification('Pomodoro ended');
|
new Notification('Pomodoro ended');
|
||||||
}
|
}
|
||||||
@@ -245,7 +225,7 @@ const MainPomodoroTimer = (props) => {
|
|||||||
|
|
||||||
playAudio('rest')
|
playAudio('rest')
|
||||||
|
|
||||||
if (notificationPermission) {
|
if (props.notificationPermission) {
|
||||||
|
|
||||||
new Notification('Rest ended');
|
new Notification('Rest ended');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ const MainPomodoro = (props) => {
|
|||||||
|
|
||||||
|
|
||||||
const showStyles = () => {
|
const showStyles = () => {
|
||||||
|
|
||||||
|
|
||||||
setDisplayHidden(!displayHidden)
|
setDisplayHidden(!displayHidden)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,9 +35,6 @@ const MainPomodoro = (props) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={props.darkMode ? 'main-pomodoro-container dark-mode-component' : 'main-pomodoro-container'}>
|
<div className={props.darkMode ? 'main-pomodoro-container dark-mode-component' : 'main-pomodoro-container'}>
|
||||||
<div className="main-pomodoro">
|
<div className="main-pomodoro">
|
||||||
@@ -86,6 +81,8 @@ const MainPomodoro = (props) => {
|
|||||||
setKonamiCodeActive={props.setKonamiCodeActive}
|
setKonamiCodeActive={props.setKonamiCodeActive}
|
||||||
KonamiCodeActive= {props.KonamiCodeActive}
|
KonamiCodeActive= {props.KonamiCodeActive}
|
||||||
|
|
||||||
|
notificationPermission={props.notificationPermission}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user