Skip to content

Add the custom-dailynote-yyyyMMdd attribute when creating a dailynote doc #9807

Closed
@frostime

Description

@frostime

创建日记的时候为日记文档添加 custom-dailynote-yyyymmdd 属性

背景

长久以来 daily note 有一个很大的问题:无法方便的查询指定日期对应的日记,而随着插件系统日益发展,这已经越来越桎梏大家对 daily note 做一些功能优化了。

目前的查询方案非常复杂: 首先需要获取 sprig 模板,然后将模板的 now 替换成其他模板函数,再交给后端渲染获取具体的 hpath,然后再找后端查询指定 hpath 的文档。问题很明显:1) 非常麻烦 2) 一次只能查询一个 3) 性能开销大。

最近这两个版本,alt + 5 来 create daily note 的工作流发生了变化:变成了 1) 后端创建文档 2)返回文档 ID 3)前端调用接口来打开文档。由于流程的变化,现在我们可以以非常简单的方案来解决上面提到的问题:在获取到日记的 ID 后,为文档添加一个自定义的属性。

具体方案

  • 整体思路:为 yyyy-mm-dd 创建的 dailynote 增加一个自定义属性 custom-dailynote-yyyymmdd: yyyymmdd (或者和 created 等字段保持一致 yyyymmddsshhmm 也行)

  • 实现方案:在 app/src/util/mount.ts 的 fetchNewDailyNote 函数中,增加一行代码,来添加这个属性。下面是我在自己插件里实现的

    export function formatDate(date?: Date, sep=''): string {
        date = date === undefined ? new Date() : date;
        let year = date.getFullYear();
        let month = date.getMonth() + 1;
        let day = date.getDate();
        return `${year}${sep}${month < 10 ? '0' + month : month}${sep}${day < 10 ? '0' + day : day}`;
    }
    
    export function setCustomDNAttr(doc_id: string, date?: Date) {
        let td= formatDate(date);
        let attr = `custom-dailynote-${td}`; //例如 custom-dailynote-20231203
        let attrs: { [key: string]: string } = {};
        attrs[attr] = td;
        serverApi.setBlockAttrs(doc_id, attrs);
    }
    
    /**
     * 打开指定的笔记本下今天的日记,如果不存在则创建
     * @param notebook_index 笔记本的 index
     */
    export async function openDiary(notebook: Notebook) {
        //...省略
        let dailynote = await serverApi.createDailyNote(notebook.id, appId);
        //...省略中间部分
        //设置日记日期的自定义属性
        setCustomDNAttr(dailynote.id);
    }

export const fetchNewDailyNote = (app: App, notebook: string) => {

只需要加这么几行代码,设置一下属性,就可以了。

好处

1. 方便查询

直接的好处就是,现在我们可以用非常统一的方式,来查询任意范围、任意时刻的 daily note 了。

image

2. 解决多对一的情况

而且,这个方案也能有效地解决日记多对一的情况。比如有的人可能把日记的模板设置为 /daily note/{{now | date "2006/01"}}。这样就导致了一整个月的日记全部放在一个文档里。

而有了上述方案,可以在单个文档中跟踪整个月的日记记录,只需要在查询的时候加一个 distinct 就可以应对多对一日记的查询。

image

image

3. 便于后面插件做进一步优化

有了这个属性,后面流式日记、自定义查询等各种优化实现起来就方便多、也会更加节省性能。

Q&A

这个提议之前提过一次,然后被 D 否决了,我这里预先回答一下可能会遇到的 battle。

#8474

Q: daily note 从设计上就是一个文档,不应该被特殊对待

这个观点本身自相矛盾,如果 daily note 应该和别的普通的文档完全一致的同等对待,那就连 alt + 5 都不应该实现。

软件内 daily note 事实上已经有特殊待遇了,在这种情况下非要坚持什么「daily note」就是一个文档,我觉得是掩耳盗铃。

退一步,就算认为添加了一个属性之后 daily note 就和别的文档地位不平等了——那又怎么样?

计算机里一个基本的哲学理念是合适的透明。如果你看不到、用不到,那就等于不存在。对于那些不会用到以后插件提供的高级功能的人来讲,多一个属性会带来什么奇怪的变化吗?他们思源的性能会因为一年多了 365 个文档属性而变得特别拉跨吗?如果不会的话——那加不加属性对他们而言就是无感的,在他们眼中日记和其他文档就是平等一致的。

Q:加了属性可能不准确的,比如用 Alt+5 创建的日记也可以重命名为其他文档。

软件的实现者不应该考虑这种问题 —— 因为这属于 exceptional 的行为。我们不能为了一小部分用户奇怪的操作就驻足不前。

Alt + 5 已经明确是「创建日记」功能了,那么创建日记后还重命名、移动文档的用户应该有「这是非正常使用方式」的自知之明。

我们真正要考虑的应该是怎么优化那些正常使用软件的用户的体验,而不是去关心那些不正常使用软件的用户的体验——错的是他们的使用方式,而不是软件

Q: 插件自己遵循这个规范,不改本体可不可以?

不可以,如果本体不遵守这个规范,那么插件规范了个寂寞。问题的核心在于,要建立一个官方认可的统一协议,以后所有的日记相关插件都遵守这个协议。

Q:加了属性之后,之前的文档怎么办?

社区开发者会解决,目前我在今日笔记里面已经了遍历过去的日记,并补充属性的功能。这些总会有办法的——前提是你要有这个属性。

image

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions