Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions src/IconicPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ interface IconicSettings {
uncolorSelect: boolean;
uncolorQuick: boolean;
rememberDeletedItems: boolean;
useFrontmatterIcon: boolean;
frontmatterIconProperty: string;
frontmatterIconColorProperty: string;
dialogState: {
iconMode: boolean;
emojiMode: boolean;
Expand Down Expand Up @@ -139,6 +142,9 @@ const DEFAULT_SETTINGS: IconicSettings = {
uncolorDrag: false,
uncolorSelect: false,
uncolorQuick: false,
useFrontmatterIcon: false,
frontmatterIconProperty: 'icon',
frontmatterIconColorProperty: 'iconColor',
rememberDeletedItems: false,
dialogState: {
iconMode: true,
Expand Down Expand Up @@ -355,6 +361,12 @@ export default class IconicPlugin extends Plugin {
this.ruleManager.updateRulings(page);
}
}));

this.registerEvent(this.app.metadataCache.on('changed', (_file, _data, cache) => {
if (this.settings.useFrontmatterIcon && (cache.frontmatter?.[this.settings.frontmatterIconProperty] || cache.frontmatter?.[this.settings.frontmatterIconColorProperty])) {
this.fileIconManager?.refreshIcons();
}
}))
});

this.registerEvent(this.app.workspace.on('css-change', () => {
Expand Down Expand Up @@ -964,6 +976,79 @@ export default class IconicPlugin extends Plugin {
}, unloading) : null;
}

/**
* Get icon from frontmatter
*/
getIconAndColorFromFrontmatter = (
item: Item | Icon
): Promise<{
icon?: string;
iconColor?: string;
} | undefined> => {
return new Promise((resolve) => {
if (!("category" in item) || item.category !== "file") {
return resolve(undefined);
}
const file = this.app.vault.getFileByPath(item.id);
if (!file){
return resolve(undefined);
}
try{
this.app.fileManager.processFrontMatter(
file,
(frontmatter) => {
if (!(this.settings.frontmatterIconProperty in frontmatter) && !(this.settings.frontmatterIconColorProperty in frontmatter)) {
return resolve(undefined);
}
return resolve({
icon: frontmatter[this.settings.frontmatterIconProperty],
iconColor: frontmatter[this.settings.frontmatterIconColorProperty],
});
}
)} catch (e) {
return resolve(undefined);
}
});
};

/**
* Set icon in frontmatter
*/
setIconAndColorInFrontmatter = (
item: Item | Icon,
icon: string | null,
color: string | null
): Promise<void> => {
return new Promise((resolve) => {
if (!("category" in item) || item.category !== "file") {
return resolve();
}
const file = this.app.vault.getFileByPath(item.id);
if (!file) {
return resolve();
}
try {
this.app.fileManager.processFrontMatter(
file,
(frontmatter) => {
if (icon === null) {
delete frontmatter[this.settings.frontmatterIconProperty];
} else {
frontmatter[this.settings.frontmatterIconProperty] = icon;
}
if (color === null) {
delete frontmatter[this.settings.frontmatterIconColorProperty]
} else {
frontmatter[this.settings.frontmatterIconColorProperty] = color;
}
return resolve();
}
)} catch (e) {
return resolve();
}
});
}

/**
* Create tag definition.
*/
Expand Down Expand Up @@ -1087,6 +1172,9 @@ export default class IconicPlugin extends Plugin {
const fileBase = this.settings.fileIcons[file.id];
if (icon !== fileBase?.icon) triggers.add('icon');
if (color !== fileBase?.color) triggers.add('color');
if(this.settings.useFrontmatterIcon) {
this.setIconAndColorInFrontmatter(file, icon, color)
}
this.updateIconSetting(this.settings.fileIcons, file.id, icon, color);
this.saveSettings();
this.ruleManager.triggerRulings('file', ...triggers);
Expand Down
44 changes: 44 additions & 0 deletions src/IconicSettingTab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,50 @@ export default class IconicSettingTab extends PluginSettingTab {
this.plugin.saveSettings();
})
);

// Icon in frontmatter
new Setting(this.containerEl)
.setName(STRINGS.settings.useFrontmatterIcon.name)
.setDesc(STRINGS.settings.useFrontmatterIcon.desc)
.addToggle(toggle => toggle
.setValue(this.plugin.settings.useFrontmatterIcon)
.onChange(value => {
this.plugin.settings.useFrontmatterIcon = value;
this.plugin.saveSettings();
this.plugin.fileIconManager?.refreshIcons();
this.display()
})
);

if(this.plugin.settings.useFrontmatterIcon){
// Frontmatter icon property name
new Setting(this.containerEl)
.setName(STRINGS.settings.frontmatterIconProperty.name)
.setDesc(STRINGS.settings.frontmatterIconProperty.desc)
.addText(text => text
.setPlaceholder(STRINGS.settings.frontmatterIconProperty.placeholder)
.setValue(this.plugin.settings.frontmatterIconProperty)
.onChange(value => {
this.plugin.settings.frontmatterIconProperty = value;
this.plugin.saveSettings();
this.plugin.fileIconManager?.refreshIcons();
})
);

// Frontmatter color property name
new Setting(this.containerEl)
.setName(STRINGS.settings.frontmatterIconColorProperty.name)
.setDesc(STRINGS.settings.frontmatterIconColorProperty.desc)
.addText(text => text
.setPlaceholder(STRINGS.settings.frontmatterIconColorProperty.placeholder)
.setValue(this.plugin.settings.frontmatterIconColorProperty)
.onChange(value => {
this.plugin.settings.frontmatterIconColorProperty = value;
this.plugin.saveSettings();
this.plugin.fileIconManager?.refreshIcons();
})
);
}
}

/**
Expand Down
14 changes: 14 additions & 0 deletions src/Strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,20 @@ export default class Strings {
name: 'Remember icons of deleted items',
desc: 'Any custom icons will reappear when their item exists again.',
},
useFrontmatterIcon: {
name: 'Frontmatter icon',
desc: 'Use a frontmatter property to set/read the icon of a file.',
},
frontmatterIconProperty: {
name: 'Frontmatter icon property',
desc: 'Name of the frontmatter property to set/read the icon.',
placeholder: 'icon',
},
frontmatterIconColorProperty: {
name: 'Frontmatter icon color property',
desc: 'Name of the frontmatter property to set/read the icon color.',
placeholder: 'iconColor',
}
};

static {
Expand Down
11 changes: 10 additions & 1 deletion src/managers/FileIconManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default class FileIconManager extends IconManager {
/**
* Refresh an array of file icons, including any subitems.
*/
private refreshChildIcons(files: FileItem[], itemEls: HTMLElement[], unloading?: boolean): void {
private async refreshChildIcons(files: FileItem[], itemEls: HTMLElement[], unloading?: boolean): Promise<void> {
for (const itemEl of itemEls) {
itemEl.addClass('iconic-item');

Expand Down Expand Up @@ -138,6 +138,15 @@ export default class FileIconManager extends IconManager {
}
}

if(this.plugin.settings.useFrontmatterIcon && !unloading) {
const frontmatterIcon = (await this.plugin.getIconAndColorFromFrontmatter(rule));
if (frontmatterIcon?.icon) {
rule.icon = frontmatterIcon.icon;
}
if (frontmatterIcon?.iconColor) {
rule.color = frontmatterIcon.iconColor;
}
}
if (iconEl.hasClass('collapse-icon') && !rule.icon && !rule.iconDefault) {
this.refreshIcon(rule, iconEl); // Skip click listener if icon will be a collapse arrow
} else if (this.plugin.isSettingEnabled('clickableIcons')) {
Expand Down