【Dataview View】图片附件管理
图片稍微多一点,对它们的管理是个麻烦,因为没法直观地看到这些图片被哪些笔记引用了。然后就写了个视图来观察一下。这个视图很简陋,如果图片较多慎用,因为没做分页,可能卡死。
我图片少,以为用这个观察一下引用问题,结果发现一些图片因为多次倒腾位置复制粘贴什么的导致只能显示半截,这问题怕是存在几年了,我才发现,也算是意外收获了。
显示黄色边框的图片是无引用的图片。兼容 Excalidraw,但未兼容 Canvas,所以要自己注意判断一下确实未被画板等引用。
view.js
/**
* 图片附件管理
* @author: 稻米鼠
* @description: 图片附件管理
* @created: 2024-05-27
* @updated: 2024-05-27
* @version: 0.0.1
*/
dv.container.classList.add('images-manager-container')
/** @type {array} 图片附件的后缀 */
const extensions = [
'jpg',
'jpeg',
'png',
'gif',
'svg',
'webp',
'ico',
'tiff',
'bmp',
]
/** @type {object} 所有图片附件 */
const images = {}
// 遍历所有文件,过滤后缀
for(const filePath in app.vault.fileMap){
const file = app.vault.fileMap[filePath]
if(file.extension && extensions.includes(file.extension)){
images[file.path] = []
}
}
// 记录所有图片引用
dv.pages().forEach(page => {
page.file.outlinks.forEach(link => {
if(images[link.path]) images[link.path].push(page.file.path)
})
})
// 创建一个隐藏的元素,用来渲染图片
const renderContainer = document.createElement('div')
renderContainer.style.display = 'none'
dv.container.appendChild(renderContainer)
let URIPrefix = ''
const getURIPrefix = (path) => {
const tempImgRender = dv.span(`![[${path}]]`)
renderContainer.appendChild(tempImgRender)
URIPrefix = tempImgRender.querySelector('img').src.split(encodeURI(path))[0]
renderContainer.innerHTML = ''
}
Object.keys(images).map(path => {
if(!URIPrefix) getURIPrefix(path)
const code = `<div class="images-manager-image-item${images[path].length ? '' : ' uncited-image'}">
<div class="images-manager-image-cover" style="background-image:url(${URIPrefix}${encodeURI(path)}?${+new Date()})" aria-label="${path}" data-tooltip-position="top" data-tooltip-delay="100">
</div>
<ul>
${images[path].map(link => `<li><a class="internal-link" href="${link}" data-href="${link}" rel="noopener">${app.vault.fileMap[link].name.replace(/\.md/, '')}</a></li>`).join('\n')}
</ul>
</div>`
dv.container.innerHTML += code
})
view.css
.images-manager-container {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: .5rem;
}
.images-manager-image-item {
width: 18%;
min-width: 240px;
border: 2px solid rgba(0, 0, 0, .3);
flex-grow: 1;
}
.images-manager-image-item.uncited-image {
border-color: #fdb124;
}
.images-manager-image-cover {
aspect-ratio: 4 / 3;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
.images-manager-image-item ul {
font-size: .8rem;
padding: .5rem;
}
.images-manager-image-item li {
list-style: none;
text-wrap: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}