electron 托盘图标闪烁_用 Electron 开发桌面效率工具

用 Electron 开发桌面效率工具

Electron 已经不算新技术,最早是 github 从 Atom 编辑器衍生出来的框架。通过编写 Javascript, HTML, CSS 能快速编译出跨系统的桌面 app。Electron 的出现使得作为前端开发工程师的我们输出范围更广。

分享最近用 Electron 做的一个基于番茄工作法的小应用,由于实现难度不大,市面上已经有非常多类似的app。我们尝试用 Electron 来实现一个。

最终效果预览:

e493de46-e318-eb11-8da9-e4434bdf6706.png

工作法

番茄工作法的核心是将任务颗粒拆分到单位时间内(25分钟)可以完成,在这25分钟内专注在这个任务三,不允许做任何与任务无关的事,在任务任务完成之后可以短暂休息一会,再继续工作。

所以这个 app 的重点是让你创建任务,⏳ 25分钟,帮让 focus on 当前在做的任务。

站在巨人的肩膀上开发

尝试新技术的时候,不要从零开始学习如何搭建技术栈,先做出来,遇到问题再查。 Electron 社区有很多优秀的沉淀,工具,模板,组件,教程等等。

搜索 react 关键字,找到了 electron-react-boilerplate 这个样板库, 这个库已经集成了 react, redux, sass, flow, hmr webpack 等工具,同时准备好 electron-builder 打包工具,作为 electron 新手,我们优先选择开箱即用的工具,快速开启业务开发。

SVG 和 React Component

大概画了一下草图,准备进入开发阶段。考虑后面会用到 svg icon,先在 FlatIcon 上找些免费的图标,下载 SVG 文件。

通过 SVGR 在线工具导入 svg 内容生成 React Component 代码。(svgr 也有 cli 等工具)

用 SVG Component 的好处是可以在代码上更灵活地控制样式,相比 png 图标可交互性强,复用率高。

e693de46-e318-eb11-8da9-e4434bdf6706.png

托盘和托盘弹窗

这个 app 启动的时候就隐藏在托盘菜单的一角,点击的时候显示 BrowserWindow,通过 Electron 提供的方法,可以获得托盘和托盘弹窗的 Bounds 信息,设置坐标位置。

// main.jsconst tray = new Tray(path.join(__dirname, '../static', 'tray.png'));const mainWindow = new BrowserWindow({ // ...others frame: false, resizable: true, transparent: true});const showWindow = () => { const { x, y } = getPositionFromActiveDisplay(); mainWindow.setPosition(x, y, true); mainWindow.show();};const getPositionFromActiveDisplay = () => { const trayBounds = tray.getBounds(); const windowBounds = mainWindow.getBounds(); const x = Math.round(trayBounds.x + trayBounds.width / 2 - windowBounds.width / 2); const y = Math.round(trayBounds.y + trayBounds.height); return { x, y };}; 
e893de46-e318-eb11-8da9-e4434bdf6706.png

图的三角是由前端代码绘制的,加上 frame 和 electron 背景色,应该长这样。

e993de46-e318-eb11-8da9-e4434bdf6706.png

渲染线程和主线程

app 需要倒计时功能,告诉用户距离任务完成时间还有多久。Electron 有渲染进程和主线程,BrowserWindow 不可见的时候,渲染进程会尽量减少消耗,所以如果 Tick 在渲染进程的话,当 app 处于后台时会出现非常大的时间偏差。这里使用 Electron 提供的 ipcMain 和 ipcRenderer 做进程通信。

在主线程每秒发送 Tick 事件

// main.jsipcMain.once('store-ready', event => { const run = () => { setTimeout(() => { run(); event.sender.send('tick'); }, 1000); }; run();});复制代码

渲染进程就收事件并将 dispatch TICK action。

// app/index.jsconst store = configureStore({ tasks: electronStore.getTasks()});ipcRenderer.send('store-ready');ipcRenderer.on('tick', () => { store.dispatch({ type: TICK });});复制代码

redux store 里面判断当前执行的任务计算倒计时时间。

switch (action.type) { case TICK: return { ...state, rows: state.rows.map(task => task.id === state.currentId ? { ...task, remain: Math.max(task.remain - 1, 0) } : task ) };复制代码

数据持久存储

数据持久化有很多种方案,因为是前端浏览器,我们可以选择 localStorage, Cookie,indexDB 等等。考虑可靠性,持久化以及存储空间,还可以通过 Electron 写文件的方式,把数据写入到应用路径下。这样即使 app 被卸载了,只要数据没被清空,用户数据还在。

通过 Electron app getPath 可以获得应用存储路径

import { app } from 'electron';app.getPath('userData');复制代码

mac 下应用 app 的路径是 /Users/user/Library/Application Support/focus。更简单的方式可以直接用开源库 electron-store,以 key-value 的格式存储 json 文件。

{ "tasks": { "rows": [ { "name": "任务名称
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值