做个喝水提醒小工具,其实就三块逻辑
【摘要】 做一个喝水提醒小工具的三个部分——按天记录水量与目标量、页面内定时加系统通知双通道提醒、以及跨天自然清零的统计方式,附后台降频和权限被拒的兜底处理。
久坐写代码容易一上午不喝水,想起来的时候已经渴得不行。做个提醒工具听起来要定时、要通知、要记录,拆开看其实就三块:存什么、怎么提醒、什么时候清零。
1.存什么
一条记录只要两个字段:时间和水量。日期单独存,方便按天汇总:
const KEY = 'water-v1';
const GOAL = 1500;
function addDrink(records, amount) {
const ml = Number(amount);
if (!(ml > 0)) throw new Error('水量不合法');
return [...records, { ml, date: today(), at: Date.now() }];
}
function todayTotal(records) {
const d = today();
return records
.filter((r) => r.date === d)
.reduce((sum, r) => sum + r.ml, 0);
}
function today() {
return new Date().toISOString().slice(0, 10);
}
水量用毫升整数,不用小数,避免浮点那堆麻烦。目标量做成可改的配置,每个人不一样,写死 1500 只是个默认值。
2.怎么提醒
最省事的是页面内定时提示,不用申请权限:
let timer = null;
function startReminder(minutes, onTick) {
stopReminder();
timer = setInterval(() => onTick(), minutes * 60 * 1000);
}
function stopReminder() {
if (timer) clearInterval(timer);
timer = null;
}
想用系统通知的话走 Notification API,但要先申请权限,而且用户拒绝之后就完全没提示了。所以做法是两条腿:系统通知能用就用,用不了退化成页面内的横幅。
还有个细节:页面切到后台时定时器会被降频,提醒会不准。这时候 visibilitychange 回来时补一次判断,看距上次喝水过了多久,超了就提示。
3.什么时候清零
按天统计,跨天自然清零,不需要定时任务去清数据:
function recentDays(records, n) {
const days = [...new Set(records.map((r) => r.date))].sort();
return days.slice(-n).map((d) => ({
day: d,
total: records.filter((r) => r.date === d).reduce((s, r) => s + r.ml, 0),
done: records.filter((r) => r.date === d).reduce((s, r) => s + r.ml, 0) >= GOAL,
}));
}
简单总结一下:历史记录留着但不是每天都看,真正展示的是"最近几天达成情况"。数据量不大,全存本地就行。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)