Times are randomised across morning, afternoon, evening and night.
iPhone: add app to home screen first. Requires iOS 16.4+.
Preferences
👤
Your name
Not set
›
🗑
Clear all data
Deletes all check-ins and settings
About
ℹ️
Better Minute
Version 6.0 • Not a medical service
🔒
Privacy
All data stored locally on your device only
✨
Done.
Small steps still count.
/* ── NOTIFICATIONS ── */
var DEFAULT_TIMES=['08:30','13:00','18:30','21:00'];
var NOTIF_MSGS=[
{title:'Time for a check-in',body:'How are you feeling right now? It takes 60 seconds.'},
{title:'Better Minute',body:'A quick pause can shift everything. How are you doing?'},
{title:'Check in with yourself',body:'Your mood matters. Take one minute for you.'},
{title:'How are you feeling?',body:'Morning, afternoon or night - you deserve a moment.'},
{title:'One minute for you',body:'Whatever is happening, Better Minute is here.'},
{title:'Your daily check-in',body:'Small habit, big difference. How are you right now?'},
{title:'Pause for a second',body:'How has your day been treating you so far?'},
{title:'Better Minute reminder',body:'Check in, breathe, get a personalised suggestion.'},
{title:'Quick question',body:'On a scale of terrible to great - where are you today?'},
{title:'You have got a moment',body:'Use it to check in. It takes less than a minute.'}
];
function initNotifications(){
if(!('Notification' in window)){updateNotifStatus();return;}
if(Notification.permission==='granted'){scheduleAllNotifications();updateNotifStatus();hideBanner();return;}
if(Notification.permission==='denied'){showBannerIfDue('denied');updateNotifStatus();return;}
showBannerIfDue('default');updateNotifStatus();
}
function showBannerIfDue(state){
try{var last=parseInt(localStorage.getItem('bm_notif_last_prompt')||'0');if(Date.now()-last<24*60*60*1000)return;}catch(e){}
setTimeout(function(){
var banner=document.getElementById('notif-banner');if(!banner)return;
if(state==='denied'){
var t=document.getElementById('notif-banner-title');
var b=document.getElementById('notif-banner-body');
var btn=document.getElementById('notif-enable-btn');
if(t)t.innerHTML='🔔 Reminders are off';
if(b)b.textContent='Notifications are blocked. Fix it: Settings > '+getBrowserName()+' > Notifications > Allow.';
if(btn){btn.textContent='Got it';btn.onclick=function(){hideBanner();recordPromptShown();};}
}
banner.style.display='block';recordPromptShown();
},3000);
}
function recordPromptShown(){try{localStorage.setItem('bm_notif_last_prompt',Date.now().toString());}catch(e){}}
function hideBanner(){var b=document.getElementById('notif-banner');if(b)b.style.display='none';}
function getBrowserName(){var ua=navigator.userAgent;if(/safari/i.test(ua)&&!/chrome/i.test(ua))return 'Safari';if(/chrome/i.test(ua))return 'Chrome';if(/firefox/i.test(ua))return 'Firefox';return 'your browser';}
function updateNotifStatus(){
var txt=document.getElementById('notif-status-text');
var arr=document.getElementById('notif-toggle-arr');
if(!txt)return;
if(!('Notification' in window)){txt.textContent='Not available on this browser';return;}
if(Notification.permission==='granted'){
var c=4;try{c=parseInt(localStorage.getItem('bm_notif_count')||'4');}catch(e){}
txt.textContent='On - '+c+' random reminder'+(c>1?'s':'')+' per day';
if(arr)arr.innerHTML='✓';
} else if(Notification.permission==='denied'){
txt.textContent='Blocked - enable in your phone Settings';
if(arr)arr.innerHTML='!';
} else {
txt.textContent='Off - tap to turn on';
if(arr)arr.innerHTML='›';
}
}
function requestNotifPermission(){
if(!('Notification' in window)){var m=document.getElementById('notif-msg');if(m)m.textContent='Not supported on this browser';return;}
if(Notification.permission==='denied'){
var m=document.getElementById('notif-msg');
if(m)m.textContent='Blocked. Go to Settings > '+getBrowserName()+' > Notifications > Allow.';
hideBanner();return;
}
Notification.requestPermission().then(function(perm){
hideBanner();
if(perm==='granted'){
scheduleAllNotifications();updateNotifStatus();renderNotifTimeUI();
var w=document.getElementById('notif-time-wrap');if(w)w.style.display='block';
var m=document.getElementById('notif-msg');
if(m){var c=4;try{c=parseInt(localStorage.getItem('bm_notif_count')||'4');}catch(e){}
m.textContent='Reminders on! You will get '+c+' random nudges per day.';
setTimeout(function(){if(m)m.textContent='';},4000);}
} else {updateNotifStatus();}
});
}
function pad2(n){return n<10?'0'+n:String(n);}
function getRandomTimes(count){
var windows=[[7*60,10*60],[11*60,14*60],[16*60,19*60],[20*60,22*60]];
var times=[];
windows.slice(0,count).forEach(function(w){
var mins=w[0]+Math.floor(Math.random()*(w[1]-w[0]));
times.push(pad2(Math.floor(mins/60))+':'+pad2(mins%60));
});
return times.sort();
}
function scheduleAllNotifications(){
if(Notification.permission!=='granted')return;
if(window._notifTimers)window._notifTimers.forEach(function(t){clearTimeout(t);});
window._notifTimers=[];
var count=4;try{count=parseInt(localStorage.getItem('bm_notif_count')||'4');}catch(e){}
var today=new Date().toDateString();
var lastDay='';try{lastDay=localStorage.getItem('bm_notif_day')||'';}catch(e){}
var times;
if(lastDay===today){try{times=JSON.parse(localStorage.getItem('bm_notif_times'));}catch(e){times=getRandomTimes(count);}}
else{times=getRandomTimes(count);try{localStorage.setItem('bm_notif_times',JSON.stringify(times));localStorage.setItem('bm_notif_day',today);}catch(e){}}
var now=new Date();
times.forEach(function(timeStr){
var p=timeStr.split(':');
var next=new Date();next.setHours(parseInt(p[0])||9,parseInt(p[1])||0,0,0);
if(next<=now)next.setDate(next.getDate()+1);
var t=setTimeout(function(){
fireNotification();
var daily=setInterval(function(){
var c2=4;try{c2=parseInt(localStorage.getItem('bm_notif_count')||'4');}catch(e){}
var nt=getRandomTimes(c2);
try{localStorage.setItem('bm_notif_times',JSON.stringify(nt));localStorage.setItem('bm_notif_day',new Date().toDateString());}catch(e){}
fireNotification();
},24*60*60*1000);
window._notifTimers.push(daily);
},next-now);
window._notifTimers.push(t);
});
}
function fireNotification(){
if(Notification.permission!=='granted')return;
var today=new Date().toDateString();
var checked=S.log.length>0&&new Date(S.log[0].time).toDateString()===today;
var msg=checked?{title:'Great work today',body:'You already checked in. Keep the streak going tomorrow!'}:NOTIF_MSGS[Math.floor(Math.random()*NOTIF_MSGS.length)];
if('serviceWorker' in navigator){
navigator.serviceWorker.ready.then(function(reg){
reg.showNotification(msg.title,{body:msg.body,icon:'/icon-192.png',badge:'/icon-192.png',tag:'bm-checkin',renotify:true,vibrate:[200,100,200],data:{url:'/'}});
}).catch(function(){try{new Notification(msg.title,{body:msg.body,icon:'/icon-192.png'});}catch(e){}});
} else {try{new Notification(msg.title,{body:msg.body,icon:'/icon-192.png'});}catch(e){}}
}
function renderNotifTimeUI(){
var wrap=document.getElementById('notif-time-wrap');if(!wrap)return;
var count=4;try{count=parseInt(localStorage.getItem('bm_notif_count')||'4');}catch(e){}
wrap.innerHTML=
'
Times are randomised daily across morning, afternoon, evening and night windows.
'+
''+
'
iPhone: add app to home screen first. Requires iOS 16.4+.
'+
'';
wrap.querySelectorAll('.notif-count-btn').forEach(function(btn){
btn.addEventListener('click',function(){
wrap.querySelectorAll('.notif-count-btn').forEach(function(b){b.style.borderColor='var(--bdr2)';b.style.background='var(--surf)';b.style.color='var(--ink2)';});
btn.style.borderColor='var(--ink)';btn.style.background='var(--ink)';btn.style.color='#fff';
try{localStorage.setItem('bm_notif_count',btn.dataset.count);}catch(e){}
});
});
var sb=document.getElementById('notif-save-count-btn');
if(sb)sb.addEventListener('click',function(){
var c=4;try{c=parseInt(localStorage.getItem('bm_notif_count')||'4');}catch(e){}
try{localStorage.removeItem('bm_notif_day');}catch(e){}
scheduleAllNotifications();updateNotifStatus();
var m=document.getElementById('notif-msg');
if(m){m.textContent='Saved! '+c+' random reminder'+(c>1?'s':'')+' per day.';setTimeout(function(){if(m)m.textContent='';},3000);}
});
}
var _enBtn=document.getElementById('notif-enable-btn');
if(_enBtn)_enBtn.addEventListener('click',requestNotifPermission);
var _disBtn=document.getElementById('notif-dismiss-btn');
if(_disBtn)_disBtn.addEventListener('click',function(){hideBanner();recordPromptShown();});
var _nRow=document.getElementById('notif-row');
if(_nRow)_nRow.addEventListener('click',function(){
if(Notification.permission==='granted'){
var w=document.getElementById('notif-time-wrap');
if(w){w.style.display=(w.style.display==='none'||!w.style.display)?'block':'none';if(w.style.display==='block')renderNotifTimeUI();}
} else {requestNotifPermission();}
});
setTimeout(initNotifications,600);