邮件草稿自动保存器hooks代码实现

基于之前的自动保存草稿设计思路——邮件项目草稿存取优化实践,做了初步的代码实现,将其封装成hooks,其功能主要就是草稿自动保存器。 设计回顾 其中比较编辑邮件是否发生变化的数据来源需要依赖业务组件传递 hooks说明 入参 业务组件需要传递hooks两个参数 1.如何拿到正在编辑有的信息的方法getEditingData 2.调用保存草稿接口的方法saveDraft,该方法需要返回保存的草稿信息(即保存草稿接口入参) 返回结果 1+2.鉴于hooks需要能在正在提交草稿、取消草稿后自行关闭定时器,所以需要业务组件使用经hooks包装过的提交草稿( saveDraftMailProcess)、取消草稿方法(cancelMailDraftProcess)。 3.启动草稿自动保存器的入口initAutoSaver 4.暴露编辑邮件是否发生变化的方法isEmailContentEdited 5.暴露出缓存的草稿信息cachedEmailRef 代码实现 import React, { useEffect, useRef } from 'react'; import EmailService from 'views/mail/utils/email.service'; import { isDataEquals } from 'views/mail/utils'; export const useAutoSave = (getEditingData, saveDraft) => { const cachedEmailRef = useRef({}); const timeIdRef = useRef(null); // Read more…

华为手表(或手环)表盘主题制作

前几天把自己的小米手环升级成华为手环了,期间看了看表盘市场,这其实类似于主题市场吧,但是相比而言设计难度小不少,只是对配置能力要求稍高一点。 表盘有些是免费,其它的是3元、6元不等。 其实表盘里面的静态元素可以直接在画在背景图中,比如上图中的五角星、小黄鸭、水母、外星人,跑鞋、心跳等。 动态的数据就需要每个制作一张对应的图片,比如“1O:08”的每个数字(:也可以画在背景图里面) “星期五”也是类似的 harmonyOS会自动在星期五的时候显示你上传的“周五”的图片 里面相对复杂一点的就是“进度”类控件 我们也是先在背景图上画上进度为0的情况,或者说是弧形为“空”的轨迹。 背景图上画上默认的空的三环 再传上有进度的三环轨迹图片(以最外面的步数为例,红色) 步数进度为79.19%的时候,红色进度的比例 以前我一直觉得想换个主题、表盘的什么还需要付费,很是反感,其实细想一下,有需求就有市场,同时这也算手机厂商让开发者或是设计者一个将能力变现的机会,没什么不好的。 有能力的童鞋可以试着打磨自己的能力,配合上创新,试着将自己的能力变现,接受市场的检验吧。

邮件项目草稿存取优化实践

在之前调研了各大主流邮件平台草稿保存方案现状(具体见参考主流平台优化邮件项目的自动保存草稿机制)后,我们可以据此对自己当前项目进行改进了。 各邮件产品方案对比 产品 跳转行为保存 自动保存 独立窗口 提交草稿条件 163邮箱 提交草稿,toast提示 每5分钟执行提交草稿 不支持 若内容变化则提交服务端 QQ邮箱 二次确认提示后提交草稿 每30秒执行提交草稿 每30秒执行保存本地缓存 支持 若内容变化则提交服务端 Outlook邮箱 提交草稿,无提示 每30秒执行提交草稿 支持 若内容变化则提交服务端 Gmail邮箱 提交草稿,无提示 输入后实时提交草稿 支持 不论内容是否变化直接提交服务端 当前项目 schema唤起场景给予二次确认提示;其他场景直接提交草稿,无提示 不支持 支持 不论内容是否变化直接提交服务端 主流邮件平台保存草稿机制 自动保存草稿 1 提交流程:仅当编辑邮件内容发生变化时才会提交至服务端 2 触发时机:编辑邮件途中的跳转行为+自动执行 独立窗口 新开窗口加载的草稿内容直接由前端通过主窗口进行数据传递,不需要借助于服务端。 改进 1 能判断当前编辑邮件是否发生变化 与服务端同步草稿数据后更新草稿前端记录值。 2 自动保存草稿 每30秒执行一次保存草稿,若编辑邮件发生变化则提交服务端。 3 切换独立窗口数据传递 Read more…

屠龙勇士终成恶龙,说的就是百度统计,换51.la统计吧

曾几何时,网站统计时代主要是用51.la统计和站长统计cnzz,当时这两个我都用过,感觉有些简陋,页面看上去不太顺眼,然后百度统计出现了,我果断的换成了百度统计。当时的百度也没那么讨厌,加上大家主要是依靠百度搜索来作为入口的,直接用百度自己的站点统计,也算全家桶了。 这几年百度不复当年之名,产品和做法也时常遭人吐槽,旗下的百度统计也是其中之一了,感觉每隔一段时间就会发现有部分功能被砍掉,或者说升级到一个所谓的更强版本,然后呢,这个版本要收费了。。。 “站内来源”模块 “事件分析”模块 比如上图中的“事件分析”模块,看api能够实现一些事件埋点,比如统计资源的下载次数什么的。 但是自己实测了百度这个并不好用,统计不准,经常漏统计。跟51.la统计相比,差太远了。不知道是不是跟它出了这个公告有关,想让我是用付费的“新功能”。。。 function _zhagTrack(id) { window.LA?.track('download', {[id]: new Date().toLocaleString()}); // 51.la统计 window._hmt?.push(['_trackEvent', 'download', 'click', id]); // 百度统计 } 百度统计什么也没统计上 51.la统计倒是统计上了 目前看来51.la统计的分析渠道还挺多的,目前还不收费。 现在百度是越来越不行了,目前我也就仅剩一个百度输入法了(主要是搜狗之流广告更多,加上Mac、PC、android、IOS多平台的同步的输入法可选项就不多)

在github actions下怎么实现私有仓库授权和通信

自己最近用了github actions感觉还是不错的,之前只是简单了解过,这周抽空把官方文档大致看了一遍对这条流程有了更进一步的理解吧。 我突然有个想法,想把自己写的私有项目爬行数据数据crawl的功能部分共享出来(写的太烂了,不好意思公开),具体怎么做呢?crawl依然保留为私有项目,但是我可以另起一个repository来做几个公开的actions,暴露出入参和出参,这两个项目都是我自己的,只要这个公开仓库能实现私有仓库crawl的授权和通信,不就可以间接公开了crawl的能力吗? 通过actions开放部分功能,用私有仓库隐藏实现细节,没错,用github actions就是可以这么任性。。。。 说干就干,我就在网上找了找怎么才能在workflows的jobs里面使用到私有仓库的内容,最后经过实测后发现可以这么做,将自己的ssh key保存在在公开的actions项目的secrets里面,那样这个actions里面就可以checkout出crawl的代码内,然后就能使用里面的功能了了。具体的步骤如下: 首先自己设置ssh key,后续就可以据此来打通权限了 将ssh key公开的加入对外公开的actions项目的secrets里面,这样这个项目可以使用ssh key,也不会有公开的风险 在公开的actions的workflows里面使用crawl能力 先checkout后run 大家可以试试了,后续我会把公开的actions全部放到daoAction这个组织下面,目前公开的有 https://github.com/daoAction/notify 一个通过bark设备key来通知的actions

参考主流平台优化邮件项目的自动保存草稿机制

背景 邮件项目目前有两处支持自动保存草稿 场景一:在编辑邮件过程中切换至其它邮件,编辑内容自动保存为邮件草稿。 场景二:在主窗口编辑邮件时点击“独立窗口打开”,主窗口编辑内容自动保存草稿,独立窗口加载该草稿。 待优化点: 依赖明确的页面跳转或者点击行为触发保存草稿,没有实时保存机制 场景二中切换独立窗口过程依赖服务端来完成草稿信息存、取,容易受到网络等因素影响 主流产品保存草稿方案调研 现存方案 163邮箱 行为保存 页面跳转或主动点击保存时自动保存,在顶部给予提示 实时保存 5分钟后执行一次自动保存检查,内容有变化则提交服务端 独立窗口 打开邮件,写邮件、查看邮件默认是使用新开标签窗口来打开页面,无独立窗口。 QQ邮箱 行为保存 判断当前是否存在内容变更,有则进行二次弹框确认,否则直接跳转。 实时保存 独立窗口 在编辑邮件时支持新开浏览器窗口写信。 主窗口暂存当前邮件信息至window下全局变量,window.open新开窗口,新窗口加载主窗口全局变量信息。 Outlook 行为保存 页面切换自动保存 自动保存 每30秒执行一次自动保存检查,如果编辑器内容发生改变则提交服务器。新开窗口后自动保存检查仍由主窗口完成。 独立窗口 window.open新开窗口,新窗口通过使用主窗口共享变量的方式加载当前邮件信息。 Gmail 输入后立即保存至服务端 结论 主流邮件平台保存草稿的机制基本类似,主要有以下几点: 除主动保存点击外,其它从当前编辑页跳出的操作行为,都会保存草稿至服务端。 使用定时器实现自动保存检查,如果编辑内容较上次发生变更则提交草稿至服务端。 新开窗口加载的草稿数据直接来源于主窗口的草稿数据,不需要借助于服务端。 总结 现有邮件项目将采取以下措施改进现有自动保存机制 提供对当前编辑器内容是否发生变更的判断能力 加入对当前编辑内容的自动保存定时执行机制,检查发生内容变更则及时保存至服务端 新开窗口加载邮件草稿数据不再借助服务端完成存取,直接通过前端数据共享或通信完成即可

自学日语五十音的一点笔记

与汉语对比 首先了解下什么是日语的五十音,它就类似汉语里面的韵母、声母。 汉语里面含有里面有单韵母a、o、e、i、u、ü 声母b、p、m、f、d、t、n、l、g、k、h、j、q、x、zh、ch、sh、r、z、c、s。 但是日语里面没有专门的ü。“韵母”只有a、i、u、e、o。 声母韵母组合有k行、s行、t行、n行、h行、m行、y行、r行、w行、g行、z行 五十音图 日语五十音图当中: 清音50个音节,加上拨音 ん一共51个,因此,五十音图也叫做“清音五十音图”。; 浊音/半浊音有25个音节; 拗音有36个音节; 1、清音:当气流通过声门时,如果声道中某处面积很小,气流高速冲过此处时产生湍流,当气流速度与横截面积之比大于某个临界速度便产生摩擦音,即清音。 2、浊音:发音时声带颤动的是浊音,又叫“带音”。声带不颤动的是清音,又叫“不带音”. 练习辨别清音和浊音,可以把耳朵捂起来把清浊音连着念。 日语里が 行、ざ 行、だ 行、ば 行就是浊音,共计20个假名。.他们的声母分别为浊辅音:g、z、d、b。 世界上英、美、法、德、日、俄等国均有大量浊音,如[b]、[d]、[g]、[z]等。 3、半浊音:半浊音只有一行,5个假名,即:ぱ、ぴ、ぷ、ぺ、ぽ。 “半浊音”是日本人的习惯叫法,实际上这行假名的辅音是清音p。 4、拗音:拗音是指「い」段假名(含浊音、半浊音)(除い外)和复元音「や」、「ゆ」、「よ」拼起来的音节,共有三十六个。 在「い」段假名后面右下角加小写的「や」、「ゆ」、「よ」来表示。片假名、平假名输入时在中间加个y即可。 日语的拗音表: a u o きゃ(kya) きゅ(kyu) きょ(kyo) ぎゃ(gya) ぎゅ(gyu) ぎょ(gyo) しゃ(sya) しゅ(syu) しょ(syo) じゃ(zya) じゅ(zyu) じょ(zyo) ちゃ(tya) ちゅ(tyu) ちょ(tyo) ぢゃ(dya) ぢゅ(dyu) ぢょ(dyo) にゃ(nya) にゅ(nyu) にょ(nyo) Read more…

QQ邮箱、163邮箱自动保存草稿机制调研

背景 准备优化自己的邮箱项目中草稿的保存,目前是完全依赖调用后端接口保存,并且不支持自动保存功能,希望先调用主流邮箱的机制,并与之保持一致的用户体验。 QQ邮箱 页面切换时主体窗口内iframe会覆盖成最新的,每次仅存在一个iframe。 存储时机 页面跳转(比如点击调转至收件箱) 判断当前是否存在内容变更,有则进行二次弹框确认,否则直接跳转 自动保存 两个每30秒执行一次定时器 保存至本地:如果编辑器内容发生改变则将编辑器内容保存至本地 自动保存:如果编辑器内容发生改变则提交服务器(服务器返回成功后删除本地缓存)+ 保存至本地逻辑 存储地点 加密后存入localStorage 163邮箱 打开邮件,写邮件、查看邮件是使用新“标签”打开页面。 存储时机 页面切换(比如切换至收件箱) 直接切换,如果编辑器内容发生改变,直接自动保存草稿并给予提示 自动保存 保存至服务器:每3分钟执行一次定时器,直接保存内容至服务端 自动保存:执行一次定时器(首次是2分钟),内容有变化则提交服务端,并设置定时器为5分钟 + 执行下次定时器 总结 共同点: 能够检测内容是否发生了变更 页面跳转时自动保存草稿或者给予二次确认 两套计时器,一套是定时保存(本地或者服务端),一套定时检测

邮件项目左侧tab切换,右侧主体内容联动的技术实现思考过程

大家都使用过outlook,在outlook的左侧会有各种文件夹(比如收件箱、已发送邮件),点击文件夹,右侧会打开对应文件夹内的邮件,切换不同文件夹,会继续打开之前打开的邮件。 我们自己的邮件项目怎么实现类似的功能呢? 背景 我们的需求有以下几点: 实现上述outlook类似的功能,只是我们的不叫文件夹,叫tab,在对应的tab下未曾打开过邮件的话,就直接显示空态(NoMail);如果上次打开过邮件这重新打开该邮件;如果通过操作将邮件从当前tab转移了(比如将“待处理”的邮件删除后,该邮件进入“已删除”),因为之前打开的邮件已经不在属于此tab了,该tab需要显示空态。这个功能为了方便描述,后面我们称之为联动,也就是左边tab和右边窗口主体内容联动。 因为“已删除”里面邮件是支持“恢复邮件”的操作,恢复后的邮件会进入“待处理”tab,客服可以重新对它进行回复。为了方便客服,此时不用将右侧主体切换为空态(如果根据联动的话,该邮件已经不在属于“已删除”tab),而是直接以待处理态显示该邮件,若客服后面切换至其它tab再切回“已删除”时,才遵从联动要求,右侧主体不显示该邮件。 现状 项目中已经通过消息来实现一个移动机制了,能够将一个邮件从一个tab移动至另一个tab。 下面以删除“待处理”的邮件这一操作为例,此时目标邮件会从“待处理”tab移动至“已删除”tab。 各个tab(“待处理”,“已删除”)会监听一个“MOVE”的消息,该消息内容如下 { mailId: 'aaa', targetTabName: 'deleted', } 因为一个邮件在任何时候只会隶属于唯一一个tab,所以我们各个tab在收到上述消息后,除了“已删除”tab的tabName为“deleted”,是和消息体中的targetTabName一致,其它的都不满足,不满足的tab将列表中mailId是aaa的邮件(如果有的话)删掉;而满足条件的“已删除”列表将列表中mailId是aaa的邮件(如果有的话)更新成最新状态,如果当前tab没有这个邮件,这将该邮件插入到tab里面。 需求实现 我们可以将需求简单归纳成以下几点 切换tab时,如果有上次打开邮件的记录,则右侧继续打开该邮件 如果右侧需要打开或者已经打开的邮件,不属于当前tab了,将右侧显示为空态 右侧打开的邮件的需要进行记录,方便再次切换至该tab时重新打开 “已删除”tab的邮件需要特殊处理,刚恢复的时候,即使其不再属于“已删除”tab,暂时无视联动规则,依然能成功打开,但是切换tab再切换tab时,遵从联动规则 如果我们按照技术实现来理解需求的话,大致是这样的: 大多数情况下,当前打开的邮件需要满足其隶属于当前激活的tab这一条件,如果不满足则右侧显示空态;满足则能打开,并对其进行记录,方便下次切换到该tab时继续打开。 我们需要设计一个是否满足这一条件的检测机制,这套机制可以借助已有的移动机制,因为将邮件从一个tab移动至另一个tab的过程中,我们可以知道目标邮件已经不再属于当前tab了,可以顺便做切换至空态的操作。 用一个对象tabRouteMap来存储各个tab的上次路由即对应的mailId,然后提供一个setTabRouteMap的方法来更新这个对应关系。 const tabRouteMap = { pending: { routeName: 'NoMail', // 空态 mailId: '', }, completed: { routeName: 'ReplyMail', // 回复邮件态 mailId: 'aaa', }, deleted: Read more…

报错node-sass version 6.0.1 is incompatible with ^4.0.0

有时候容易不经意间切换了node版本,升级了node-sass, 然后在跑一些老项目就容易出现这样的报错。 查看node-sass的版本就是6.0.1依然很可能报,没问题啊,这个4.0.0是哪里来的? 百度随便搜下node-sass version 6.0.1 is incompatible with ^4.0.0.指的就是,排在前面的很多文章会说node版本和node-sass的版本不一致,一般都是会你升级node-sass版本,要么降级node版本,会提到node-sass官网给出的node-sass和node版本的对应关系 node-sass官方给的这个是没错的,只是网上的文章给的答案不全面,因为及时你的node版本是16+,node-sass的版本是6.0.1依然很可能报 node-sass version 6.0.1 is incompatible with ^4.0.0.,这是为什么了? 因为sass-loader,它的版本和node-sass不一致,报错信息的^4.0.0很可能指的就是sass-loader的版本,它们的版本也需要一致的,一般来说它们的大版本一致就可以了,我通常会在npm上看它们的版本关系。 根据node版本确定node-sass的版本 node16+版本就用node-sass6+版本最新的6.0.1就行了。 根据node-sass版本确定sass-loader的版本 node-sass6+版本就用sass-loader6+版本最新的6.0.7就行了。 现在node => node-sass => sass-loader它们三个的版本都匹配,重新npm install就好了。