Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.

Commit a780bd6

Browse files
committed
Merge branch '17-fr-image-column-type'
2 parents b7f8d5f + a4949a6 commit a780bd6

File tree

4 files changed

+134
-6
lines changed

4 files changed

+134
-6
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ You can add a folder database y by right clicking on the folder where you want t
1313
![AddDatabase.gif](docs/resources/AddDatabase.gif)
1414

1515
### How to use?
16-
Database has its own type of view. It will search all notes into the same folder of the database and show the columns that you specify. Check our [documentation](https://rafaelgb.github.io/obsidian-db-folder/) for more information.
16+
Database has its own type of view. It will search all notes into the same folder of the database and show the columns that you specify. Check our [documentation](https://rafaelgb.github.io/obsidian-db-folder/features/rows/) for more information.
1717

1818
![TablePresentation.gif](docs/resources/TablePresentation.gif)
1919

src/components/Cell.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import { CellContext } from "components/contexts/CellContext";
99
import { c } from "helpers/StylesHelper";
1010
import CalendarPortal from "./portals/CalendarPortal";
1111
import { TableColumn } from "cdm/FolderModel";
12-
import CalendarTimePortal from "./portals/CalendarTimePortal";
12+
import CalendarTimePortal from "components/portals/CalendarTimePortal";
13+
import { renderMarkdown } from "components/markdown/MarkdownRenderer";
1314

1415
export default function DefaultCell(cellProperties: Cell) {
1516
const dataDispatch = (cellProperties as any).dataDispatch;
@@ -54,13 +55,13 @@ export default function DefaultCell(cellProperties: Cell) {
5455

5556
useEffect(() => {
5657
if (!dirtyCell && containerCellRef.current) {
58+
renderMarkdown;
5759
//TODO - this is a hack. find why is layout effect called twice
5860
containerCellRef.current.innerHTML = "";
59-
MarkdownRenderer.renderMarkdown(
61+
renderMarkdown(
62+
(cellProperties as any).initialState.view,
6063
contextValue.value,
61-
containerCellRef.current,
62-
note.getFile().path,
63-
(cellProperties as any).initialState.view
64+
containerCellRef.current
6465
);
6566
}
6667
}, [dirtyCell]);
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { NormalizedPath } from "cdm/FolderModel";
2+
import { DatabaseView } from "DatabaseView";
3+
import { MediaExtensions } from "helpers/Constants";
4+
import { getNormalizedPath } from "helpers/VaultManagement";
5+
import { MarkdownRenderer, TFile } from "obsidian";
6+
import { LOGGER } from "services/Logger";
7+
8+
export async function renderMarkdown(
9+
view: DatabaseView,
10+
markdownString: string,
11+
domElement: HTMLDivElement
12+
): Promise<HTMLDivElement> {
13+
try {
14+
await MarkdownRenderer.renderMarkdown(
15+
markdownString,
16+
domElement,
17+
view.file.path,
18+
view
19+
);
20+
21+
await handleEmbeds(domElement, view, 5);
22+
// applyCheckboxIndexes(dom);
23+
// findUnresolvedLinks(dom, view);
24+
} catch (e) {
25+
LOGGER.error(e);
26+
}
27+
28+
return domElement;
29+
}
30+
31+
function handleEmbeds(dom: HTMLDivElement, view: DatabaseView, depth: number) {
32+
return Promise.all(
33+
dom.findAll(".internal-embed").map(async (el) => {
34+
const src = el.getAttribute("src");
35+
const normalizedPath = getNormalizedPath(src);
36+
const target =
37+
typeof src === "string" &&
38+
view.app.metadataCache.getFirstLinkpathDest(
39+
normalizedPath.root,
40+
view.file.path
41+
);
42+
43+
if (!(target instanceof TFile)) {
44+
return;
45+
}
46+
47+
if (MediaExtensions.IMAGE.contains(target.extension)) {
48+
return handleImage(el, target, view);
49+
}
50+
51+
if (MediaExtensions.AUDIO.contains(target.extension)) {
52+
return handleAudio(el, target, view);
53+
}
54+
55+
if (MediaExtensions.VIDEO.contains(target.extension)) {
56+
return handleVideo(el, target, view);
57+
}
58+
59+
// if (target.extension === "md") {
60+
// return await handleMarkdown(el, target, normalizedPath, view, depth);
61+
// }
62+
63+
//return handleUnknownFile(el, target);
64+
})
65+
);
66+
}
67+
68+
function handleImage(el: HTMLElement, file: TFile, view: DatabaseView) {
69+
el.empty();
70+
71+
el.createEl(
72+
"img",
73+
{ attr: { src: view.app.vault.getResourcePath(file) } },
74+
(img) => {
75+
if (el.hasAttribute("width")) {
76+
img.setAttribute("width", el.getAttribute("width"));
77+
}
78+
79+
if (el.hasAttribute("height")) {
80+
img.setAttribute("height", el.getAttribute("height"));
81+
}
82+
83+
if (el.hasAttribute("alt")) {
84+
img.setAttribute("alt", el.getAttribute("alt"));
85+
}
86+
}
87+
);
88+
89+
el.addClasses(["image-embed", "is-loaded"]);
90+
}
91+
92+
function handleAudio(el: HTMLElement, file: TFile, view: DatabaseView) {
93+
el.empty();
94+
el.createEl("audio", {
95+
attr: { controls: "", src: view.app.vault.getResourcePath(file) },
96+
});
97+
el.addClasses(["media-embed", "is-loaded"]);
98+
}
99+
100+
function handleVideo(el: HTMLElement, file: TFile, view: DatabaseView) {
101+
el.empty();
102+
103+
el.createEl(
104+
"video",
105+
{ attr: { controls: "", src: view.app.vault.getResourcePath(file) } },
106+
(video) => {
107+
const handleLoad = () => {
108+
video.removeEventListener("loadedmetadata", handleLoad);
109+
110+
if (video.videoWidth === 0 && video.videoHeight === 0) {
111+
el.empty();
112+
handleAudio(el, file, view);
113+
}
114+
};
115+
116+
video.addEventListener("loadedmetadata", handleLoad);
117+
}
118+
);
119+
120+
el.addClasses(["media-embed", "is-loaded"]);
121+
}

src/helpers/Constants.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,10 @@ export function getOperatorFilterValue(keyToFind: string): string {
167167
return entry[1];
168168
}
169169

170+
export const MediaExtensions = Object.freeze({
171+
IMAGE: ['bmp', 'png', 'jpg', 'jpeg', 'gif', 'svg'],
172+
VIDEO: ['mp4', 'webm', 'ogv'],
173+
AUDIO: ['mp3', 'wav', 'm4a', '3gp', 'flac', 'ogg', 'oga']
174+
});
175+
170176
export const YAML_INDENT = Object.freeze(" ");

0 commit comments

Comments
 (0)