cleaning custom icons
This commit is contained in:
parent
d821344ade
commit
46a5d3d114
|
@ -1,8 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { setIcon, TFile } from 'obsidian'
|
||||
import { showExcerpt } from 'src/settings/utils'
|
||||
import { onMount } from 'svelte'
|
||||
import type { ResultNote } from '../globals'
|
||||
import type LocatorPlugin from '../main'
|
||||
import { getDefaultIconSVG } from '../tools/icon-utils'
|
||||
import {
|
||||
getExtension,
|
||||
isFileCanvas,
|
||||
|
@ -12,15 +14,6 @@
|
|||
pathWithoutFilename,
|
||||
} from '../tools/utils'
|
||||
import ResultItemContainer from './ResultItemContainer.svelte'
|
||||
// Import icon utility functions
|
||||
import { showExcerpt } from 'src/settings/utils'
|
||||
import {
|
||||
getDefaultIconSVG,
|
||||
getIconNameForPath,
|
||||
initializeIconPacks,
|
||||
loadIconData,
|
||||
loadIconSVG,
|
||||
} from '../tools/icon-utils'
|
||||
|
||||
export let selected = false
|
||||
export let note: ResultNote
|
||||
|
@ -29,19 +22,12 @@
|
|||
let imagePath: string | null = null
|
||||
let title = ''
|
||||
let notePath = ''
|
||||
let iconData = {}
|
||||
let folderIconSVG: string | null = null
|
||||
let fileIconSVG: string | null = null
|
||||
let prefixToIconPack: { [prefix: string]: string } = {}
|
||||
let iconsPath: string
|
||||
const folderIconSVG = getDefaultIconSVG('folder')
|
||||
const fileIconSVG = getDefaultIconSVG(note.path)
|
||||
let iconDataLoaded = false // Flag to indicate iconData is loaded
|
||||
|
||||
// Initialize icon data and icon packs once when the component mounts
|
||||
onMount(async () => {
|
||||
iconData = await loadIconData(plugin)
|
||||
const iconPacks = await initializeIconPacks(plugin)
|
||||
prefixToIconPack = iconPacks.prefixToIconPack
|
||||
iconsPath = iconPacks.iconsPath
|
||||
iconDataLoaded = true // Set the flag after iconData is loaded
|
||||
})
|
||||
|
||||
|
@ -51,40 +37,9 @@
|
|||
// Update title and notePath before loading icons
|
||||
title = note.displayTitle || note.basename
|
||||
notePath = pathWithoutFilename(note.path)
|
||||
await loadIcons()
|
||||
})()
|
||||
}
|
||||
|
||||
async function loadIcons() {
|
||||
// Load folder icon
|
||||
const folderIconName = getIconNameForPath(notePath, iconData)
|
||||
if (folderIconName) {
|
||||
folderIconSVG = await loadIconSVG(
|
||||
folderIconName,
|
||||
plugin,
|
||||
iconsPath,
|
||||
prefixToIconPack
|
||||
)
|
||||
} else {
|
||||
// Fallback to default folder icon
|
||||
folderIconSVG = getDefaultIconSVG('folder', plugin)
|
||||
}
|
||||
|
||||
// Load file icon
|
||||
const fileIconName = getIconNameForPath(note.path, iconData)
|
||||
if (fileIconName) {
|
||||
fileIconSVG = await loadIconSVG(
|
||||
fileIconName,
|
||||
plugin,
|
||||
iconsPath,
|
||||
prefixToIconPack
|
||||
)
|
||||
} else {
|
||||
// Fallback to default icons based on file type
|
||||
fileIconSVG = getDefaultIconSVG(note.path, plugin)
|
||||
}
|
||||
}
|
||||
|
||||
// Svelte action to render SVG content with dynamic updates
|
||||
function renderSVG(node: HTMLElement, svgContent: string) {
|
||||
node.innerHTML = svgContent
|
||||
|
@ -163,10 +118,8 @@
|
|||
title="The document above is embedded in this note" />
|
||||
{:else}
|
||||
<!-- File Icon -->
|
||||
{#if fileIconSVG}
|
||||
<span class="omnisearch-result__icon" use:renderSVG={fileIconSVG} />
|
||||
{/if}
|
||||
{/if}
|
||||
<span>
|
||||
{@html plugin.textProcessor.highlightText(title, matchesTitle)}
|
||||
</span>
|
||||
|
@ -191,9 +144,8 @@
|
|||
{#if notePath}
|
||||
<div class="omnisearch-result__folder-path">
|
||||
<!-- Folder Icon -->
|
||||
{#if folderIconSVG}
|
||||
<span class="omnisearch-result__icon" use:renderSVG={folderIconSVG} />
|
||||
{/if}
|
||||
|
||||
<span>
|
||||
{@html plugin.textProcessor.highlightText(notePath, matchesNotePath)}
|
||||
</span>
|
||||
|
|
|
@ -1,181 +1,12 @@
|
|||
import { getIcon, normalizePath } from 'obsidian'
|
||||
import type LocatorPlugin from '../main'
|
||||
import { getIcon } from 'obsidian'
|
||||
import {
|
||||
isFileImage,
|
||||
isFilePDF,
|
||||
isFileCanvas,
|
||||
isFileExcalidraw,
|
||||
warnVerbose,
|
||||
isFileImage,
|
||||
isFilePDF
|
||||
} from './utils'
|
||||
import { escapeHTML } from './text-processing'
|
||||
|
||||
export interface IconPacks {
|
||||
prefixToIconPack: { [prefix: string]: string }
|
||||
iconsPath: string
|
||||
}
|
||||
|
||||
export async function loadIconData(plugin: LocatorPlugin): Promise<any> {
|
||||
const app = plugin.app
|
||||
|
||||
// Check if the 'obsidian-icon-folder' plugin is installed and enabled
|
||||
// Casting 'app' to 'any' here to avoid TypeScript errors since 'plugins' might not be defined on 'App'
|
||||
const iconFolderPlugin = (app as any).plugins.getPlugin(
|
||||
'obsidian-icon-folder'
|
||||
)
|
||||
if (!iconFolderPlugin) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const dataJsonPath = `${app.vault.configDir}/plugins/obsidian-icon-folder/data.json`
|
||||
try {
|
||||
const dataJsonContent = await app.vault.adapter.read(dataJsonPath)
|
||||
const rawIconData = JSON.parse(dataJsonContent)
|
||||
// Normalize keys
|
||||
const iconData: any = {}
|
||||
for (const key in rawIconData) {
|
||||
const normalizedKey = normalizePath(key)
|
||||
iconData[normalizedKey] = rawIconData[key]
|
||||
}
|
||||
return iconData
|
||||
} catch (e) {
|
||||
warnVerbose('Failed to read data.json:', e)
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
export async function initializeIconPacks(
|
||||
plugin: LocatorPlugin
|
||||
): Promise<IconPacks> {
|
||||
// Add 'Li' prefix for Lucide icons
|
||||
const prefixToIconPack: { [prefix: string]: string } = { Li: 'lucide-icons' }
|
||||
let iconsPath = 'icons'
|
||||
|
||||
const app = plugin.app
|
||||
|
||||
// Access the obsidian-icon-folder plugin
|
||||
const iconFolderPlugin = (app as any).plugins.getPlugin(
|
||||
'obsidian-icon-folder'
|
||||
)
|
||||
|
||||
if (iconFolderPlugin) {
|
||||
// Get the icons path from the plugin's settings
|
||||
const iconFolderSettings = iconFolderPlugin.settings
|
||||
iconsPath = iconFolderSettings?.iconPacksPath || 'icons'
|
||||
const iconsDir = `${app.vault.configDir}/${iconsPath}`
|
||||
|
||||
try {
|
||||
const iconPackDirs = await app.vault.adapter.list(iconsDir)
|
||||
if (iconPackDirs.folders && iconPackDirs.folders.length > 0) {
|
||||
for (const folderPath of iconPackDirs.folders) {
|
||||
const pathParts = folderPath.split('/')
|
||||
const iconPackName = pathParts[pathParts.length - 1]
|
||||
const prefix = createIconPackPrefix(iconPackName)
|
||||
prefixToIconPack[prefix] = iconPackName
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
warnVerbose('Failed to list icon packs:', e)
|
||||
}
|
||||
}
|
||||
|
||||
return { prefixToIconPack, iconsPath }
|
||||
}
|
||||
|
||||
function createIconPackPrefix(iconPackName: string): string {
|
||||
if (iconPackName.includes('-')) {
|
||||
const splitted = iconPackName.split('-')
|
||||
let result = splitted[0].charAt(0).toUpperCase()
|
||||
for (let i = 1; i < splitted.length; i++) {
|
||||
result += splitted[i].charAt(0).toLowerCase()
|
||||
}
|
||||
return result
|
||||
}
|
||||
return (
|
||||
iconPackName.charAt(0).toUpperCase() + iconPackName.charAt(1).toLowerCase()
|
||||
)
|
||||
}
|
||||
|
||||
export function getIconNameForPath(path: string, iconData: any): string | null {
|
||||
const normalizedPath = normalizePath(path)
|
||||
const iconEntry = iconData[normalizedPath]
|
||||
if (iconEntry) {
|
||||
if (typeof iconEntry === 'string') {
|
||||
return iconEntry
|
||||
} else if (typeof iconEntry === 'object' && iconEntry.iconName) {
|
||||
return iconEntry.iconName
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function parseIconName(iconName: string): {
|
||||
prefix: string
|
||||
name: string
|
||||
} {
|
||||
const prefixMatch = iconName.match(/^[A-Z][a-z]*/)
|
||||
if (prefixMatch) {
|
||||
const prefix = prefixMatch[0]
|
||||
const name = iconName.substring(prefix.length)
|
||||
return { prefix, name }
|
||||
} else {
|
||||
// No prefix, treat the entire iconName as the name
|
||||
return { prefix: '', name: iconName }
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadIconSVG(
|
||||
iconName: string,
|
||||
plugin: LocatorPlugin,
|
||||
iconsPath: string,
|
||||
prefixToIconPack: { [prefix: string]: string }
|
||||
): Promise<string | null> {
|
||||
const parsed = parseIconName(iconName)
|
||||
const { prefix, name } = parsed
|
||||
|
||||
if (!prefix) {
|
||||
// No prefix, assume it's an emoji or text
|
||||
return `<span class="locator-result__icon--emoji">${escapeHTML(
|
||||
name
|
||||
)}</span>`
|
||||
}
|
||||
|
||||
const iconPackName = prefixToIconPack[prefix]
|
||||
|
||||
if (!iconPackName) {
|
||||
warnVerbose(`No icon pack found for prefix: ${prefix}`)
|
||||
return null
|
||||
}
|
||||
|
||||
if (iconPackName === 'lucide-icons') {
|
||||
// Convert CamelCase to dash-case for Lucide icons
|
||||
const dashedName = name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
|
||||
const iconEl = getIcon(dashedName)
|
||||
if (iconEl) {
|
||||
return iconEl.outerHTML
|
||||
} else {
|
||||
warnVerbose(`Lucide icon not found: ${dashedName}`)
|
||||
return null
|
||||
}
|
||||
} else {
|
||||
if (!iconsPath) {
|
||||
warnVerbose('Icons path is not set. Cannot load icon SVG.')
|
||||
return null
|
||||
}
|
||||
const iconPath = `${plugin.app.vault.configDir}/${iconsPath}/${iconPackName}/${name}.svg`
|
||||
try {
|
||||
const svgContent = await plugin.app.vault.adapter.read(iconPath)
|
||||
return svgContent
|
||||
} catch (e) {
|
||||
warnVerbose(`Failed to load icon SVG for ${iconName} at ${iconPath}:`, e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getDefaultIconSVG(
|
||||
notePath: string,
|
||||
plugin: LocatorPlugin
|
||||
): string {
|
||||
export function getDefaultIconSVG(notePath: string): string {
|
||||
// Return SVG content for default icons based on file type
|
||||
let iconName = 'file'
|
||||
if (isFileImage(notePath)) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user