Closed dryezl closed 1 month ago
在侧边栏上这样显示确实不方便,可以借用dataview直接在markdown视图中进行显示,你觉得如何?
不过,目前保存的数据中,只有一级标签,具体如何做,还要再考虑下。 我下版先把数据接口开放出来,也许通过dv-js的方式就能完全达成效果了。
在侧边栏上这样显示确实不方便,可以借用dataview直接在markdown视图中进行显示,你觉得如何?
我有点没有跟上,没有想好效果会是怎么样的?可能有示意图,会更清晰一些的。
示意图没做出来,就是dataview查询的那种。 这里有dataview的一些教程,可以先了解下 https://obsidian.vip/zh/dataview/
做出来了一版,不用更新插件,目前的就可以使用。
这是效果: 这是md文件及dataviewjs代码 240815-22.48-srs-dvjs.md
并不是最佳实践,只能算是抛砖引玉吧,欢迎讨论分享
```dataviewjs
// 配置项
const showList = false; // true: 显示为列表, false: 显示为表格,表格会更丰富复杂些
const tableTitle = ["tags", "fileLink", "复习次数", "难度", "上次", "间隔", "复习效果"]; // 表头, 与下边tableDataPro返回值保持一致
const tableDataPro = (tags, p, item)=> {
// tags 即该笔记含有的全部标签
// p 即dataview中的文件,使用格式p.file.xx, 其中xx为文件属性,具体可参考:
// 中文翻译版(较旧,有些属性没有更新) https://obsidian.vip/zh/dataview/dataview-advanced-a.html#_3-2-file-%E6%96%87%E4%BB%B6%E9%9A%90%E5%BC%8F%E5%AD%97%E6%AE%B5
// 官方版: https://blacksmithgu.github.io/obsidian-dataview/annotation/metadata-pages/
// item 即trackefiles.json中的数据结构
// 如 {"nextReview":1694649162045,"ID":6,"fileIndex":4,"itemType":"note","deckName":"#incrmwrt","timesReviewed":3,"timesCorrect":3,"errorStreak":0,"data":{"due":"2023-09-13T23:52:42.039Z","stability":2.6,"difficulty":5.86999,"elapsed_days":0,"scheduled_days":0,"reps":3,"lapses":0,"state":1,"last_review":"2023-09-13T23:47:42.039Z"}}
return [tags, p.file.link, item.timesReviewed, item.data.difficulty, item.data.last_review?.toDateString(), item.data.scheduled_days, item.data.state]; // 可根据需要修改为想显示的数据, 注意同步更新上面表头tableTitle 变量
}
// 插件
const srplugin = app.plugins.plugins["obsidian-spaced-repetition-recall"];
const store = srplugin.store;
console.debug("store:", store);
const decks = srplugin.reviewDecks; // 侧边栏显示的数据组
const tags = Object.keys(decks); //要显示的一级标签
let deckfilepathes = []; // 要显示的笔记路径
// 读取笔记路径
Object.values(decks).forEach(deck => {
deck.newNotes.forEach(file=> deckfilepathes.push(file.note.path));
deck.scheduledNotes.forEach(file => deckfilepathes.push(file.note.path));
})
//console.debug(decks);
// 主逻辑处理
Object.values(decks).forEach(deck => {
const gpnew = {};
const folderEl = summaryEl(deck.deckName); // 创建一级标签css
// 新笔记进行子标签分组
const newNotes = dv.array(deck.newNotes).groupBy(file =>{
const pf = dv.page(file.note.path);
return getMultiTag(pf,deck.deckName);
})
console.debug("gpnew: ", newNotes);
newNotes.forEach((gp) => {
gpnew[gp.key]=gp.rows;
//_render_file(gp,gp.rows);
//const links = dv.fileLink(gp.rows.note.path);
//console.debug("links: ",links);
//dv.list("[["+links.path+"]]");
});
// 复习过的笔记进行子标签分组
const schedGroups = dv.array(deck.scheduledNotes);
const dvGroups = schedGroups
.groupBy((file) =>{
return getMultiTag(dv.page(file.note.path),deck.deckName);
});
// console.debug("schedGroups: ", schedGroups, dvGroups);
// 复习过的笔记根据复习日期分组
dvGroups.forEach(gp =>{
const schednotes = gp.rows.groupBy((file) =>{
return new Date(file.item.nextReview).toDateString();
})
.sort(gp => new Date(gp.key).valueOf());
// console.debug("schednotes: ", schednotes);
// 创建子标签css
let subTagEl = folderEl;
if(newNotes.length <= 1 && dvGroups.length <=1) {
subTagEl = folderEl;
}else {
subTagEl = summaryEl(gp.key,true, folderEl);
}
// 显示新笔记
if(gpnew[gp.key]){
_render_file(subTagEl, gp.key,gpnew[gp.key], " - new");
gpnew[gp.key]=undefined;
}
// 显示复习过的笔记
schednotes.forEach(sns =>{
// console.debug("sns: ", sns);
_render_file(subTagEl, sns.key,sns.rows);
});
});
// 显示只有新笔记的标签及笔记
for(const key in gpnew) {
if(gpnew[key]) {
const subTagEl = summaryEl(key,true, folderEl);
_render_file(subTagEl, key,gpnew[key], " - new");
gpnew[key]=undefined;
}
}
console.debug("schedGroups: ", schedGroups, dvGroups);
});
// 获取多级标签
function getMultiTag(p,key=undefined) {
let gt = "default";
tags.some(t => {
for(const ft of p.file.tags) {
if(ft.includes(t)) {
gt=ft ;
return true;
}
}
});
if(gt==="default" && key) {
gt = key+"/"+gt;
}
return gt;
};
// 创建大纲风格的css 元素
function summaryEl(key,child=false, folderEl=undefined) {
key=key.startsWith("#")?key.substring(1):key;
if(child) {
return folderEl = dv.el("details", dv.el("summary", `${key}`), {container:folderEl,cls:"tree-item-children"});
}
return folderEl = dv.el("details", dv.el("summary", `** ${key}**`));
}
// 渲染笔记
function _render_file(folderEl, key, notes, title="") {
if(notes.values.length<1) return;
let tv = notes.map(file => {
// console.debug("file", p)
const p=dv.page(file.note.path);
let tag="default";
if(p.file.tags) {
tag = p.file.tags;
}
if(showList) {
return p.file.link; // 返回值,以方便使用列表markdownList 进行渲染
}else {
return tableDataPro(tag,p, file.item); // 返回数组,以方便使用表格markdownTable 进行渲染
}
});
// console.debug("tv:", tv);
let dtlEl = summaryEl(key+title, true, folderEl);
let data_render;
if(showList) {
data_render= dv.markdownList(tv);
}else {
data_render= dv.markdownTable(tableTitle,tv);
}
dv.el("div", data_render, {container:dtlEl});
}
谢谢,可以实现的。
请问笔记复习(note review)的悬浮栏是否可以更新为当前笔记的状态呢?
我激活笔记复习的悬浮栏之后,通过上述dataviewjs跳转到对应笔记之后,发现悬浮栏上的状态没有对应更新的。
这个真没办法🤣,dataview渲染的,已经不在插件控制范围内了
---原始邮件--- 发件人: "James @.> 发送时间: 2024年8月21日(周三) 中午1:02 收件人: @.>; 抄送: @.**@.>; 主题: Re: [open-spaced-repetition/obsidian-spaced-repetition-recall] [Share]: 与dataview插件联动-自定义数据显示-笔记(note)复习支持层级tags分类 (Issue #62)
谢谢,可以实现的。
请问笔记复习(note review)的悬浮栏是否可以更新为当前笔记的状态呢?
我激活笔记复习的悬浮栏之后,通过上述dataviewjs跳转到对应笔记之后,发现悬浮栏上的状态没有对应更新的。
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
不过,如果悬浮栏有显示,你点击记忆程度后的评分还是会对应到当前显示的笔记上的。
---原始邮件--- 发件人: @.> 发送时间: 2024年8月21日(周三) 晚上7:25 收件人: @*.**@*.>; 抄送: @*.**@*.***>; 主题: 回复:[open-spaced-repetition/obsidian-spaced-repetition-recall] [Share]: 与dataview插件联动-自定义数据显示-笔记(note)复习支持层级tags分类 (Issue #62)
这个真没办法🤣,dataview渲染的,已经不在插件控制范围内了
---原始邮件--- 发件人: "James @.> 发送时间: 2024年8月21日(周三) 中午1:02 收件人: @.>; 抄送: @.**@.>; 主题: Re: [open-spaced-repetition/obsidian-spaced-repetition-recall] [Share]: 与dataview插件联动-自定义数据显示-笔记(note)复习支持层级tags分类 (Issue #62)
谢谢,可以实现的。
请问笔记复习(note review)的悬浮栏是否可以更新为当前笔记的状态呢?
我激活笔记复习的悬浮栏之后,通过上述dataviewjs跳转到对应笔记之后,发现悬浮栏上的状态没有对应更新的。
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
不好意思,我没有表达清楚。 我目前流程是,点击obsidian右下角 (图片中标号1),激活悬浮栏(图片中标号2)。然后通过dataviewjs对笔记情况汇总,通过其链接跳转到目标笔记。 我的困惑是,我通过链接跳转到笔记之后,悬浮栏的内容没有更新的。 这个悬浮栏的内容,应该是当前插件控制的吧 另外有一个问题,如果一个笔记标记了多个标签(tag),请问它是有一个记忆状态还是每个标签有一个记忆状态呢?
悬浮栏显示的内容是插件控的,但在你点击侧边栏或底栏或插件时,它才会更新显示的内容。而点击双链打开的笔记,不在插件的逻辑内,自然就没法更新内容了。
---原始邮件--- 发件人: "James @.> 发送时间: 2024年8月21日(周三) 晚上7:44 收件人: @.>; 抄送: @.**@.>; 主题: Re: [open-spaced-repetition/obsidian-spaced-repetition-recall] [Share]: 与dataview插件联动-自定义数据显示-笔记(note)复习支持层级tags分类 (Issue #62)
不好意思,我没有表达清楚。 我目前流程尝试流程是,点击obsidian右下角 (图片中标号1),激活悬浮栏(图片中标号2)。然后通过dataviewjs对笔记情况汇总,通过其链接跳转到目标笔记。 我的困惑是,我通过链接跳转到笔记之后,悬浮栏的内容没有更新的。 这个悬浮栏的内容,应该是当前插件控制的吧 1724240310030.jpg (view on web) 另外有一个问题,如果一个笔记标记了多个标签(tag),请问它是有一个记忆状态还是每个标签有一个记忆状态呢?
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
请问有没有可能让悬浮栏和当前打开笔记挂钩呢?即悬浮栏的信息体现为当前打开笔记(active-session)的信息的
应该是可以的,但会有一点点降低Ob性能(这样实现后,会在每次打开笔记时都会进行判断操作)。 我会考虑下这个需求,看还有没别的更好的方法。
在侧边栏上这样显示确实不方便,可以借用dataview直接在markdown视图中进行显示,你觉得如何?
不过,目前保存的数据中,只有一级标签,具体如何做,还要再考虑下。 我下版先把数据接口开放出来,也许通过dv-js的方式就能完全达成效果了。
大佬,对于他所提到的优先级问题,我在想插件是否增加一个基于标签顺序的推送机制。例如依据这个设置里填入标签的先后顺序:
在开启「直接复习笔记?」功能后,插件优先推送带有review标签的待复习笔记,然后再推送带有undone标签的笔记。
直接复习是随机选一标签,然后直到该标签复习完。 你说的这个标签顺序,没有必要,可以关闭“直接复习”设置,在复习开始时根据需要选对应标签即可。
另外有一个问题,如果一个笔记标记了多个标签(tag),请问它是有一个记忆状态还是每个标签有一个记忆状态呢?
请问目前插件是怎么设定这个呢?
就是两个循环(笔记中出现的标签、设置中的标签)查找匹配,具体顺序记不清楚了,你试下就知道了。
---原始邮件--- 发件人: "James @.> 发送时间: 2024年9月10日(周二) 晚上9:12 收件人: @.>; 抄送: @.**@.>; 主题: Re: [open-spaced-repetition/obsidian-spaced-repetition-recall] [Share]: 与dataview插件联动-自定义数据显示-笔记(note)复习支持层级tags分类 (Issue #62)
另外有一个问题,如果一个笔记标记了多个标签(tag),请问它是有一个记忆状态还是每个标签有一个记忆状态呢?
请问目前插件是怎么设定这个呢?
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
const srplugin = app.plugins.plugins["obsidian-spaced-repetition-recall"]; 请问我在哪里可以看到 srplugin 这个对象的介绍呢?比如卡片数据存储在哪里的。我想查看单独笔记的卡片数量,但现在搞不懂怎么使用这个的。
srplugin就是本插件的实例
可以加入调试代码, ctrl+shift+i在调试窗口中看到,然后展开摸索吧,如果不熟悉,建议只修改上面示例代码配置项部分
console.debug("sr插件实例:", srplugin);
谢谢。我先试一下的。
Is your feature request related to a problem? Please describe.
因为个人笔记较多,因此每天进行复习的时候,其实不可能全部复习完的,所以想利用层级tags来对笔记的重要性进行分类的。这样,最起码能把重要性较高先复习完的。
Describe the solution you'd like
目前的笔记复习只能考虑一级标签的,没有二级标签的
Additional context
目前的插件转折实现的,新定义一级标签作为重要性的。好像这个想法也可以的。因为加上二级标签之后,如何展示也是一个问题的。卡片复习那边可以展示二级标签,因为它不用展示卡片列表内容的。 暂时提个想法的