From a01db62edead00b05e76bba8aedbbb15da652bcd Mon Sep 17 00:00:00 2001 From: Roland Broekema Date: Fri, 6 Jun 2025 17:40:34 +0200 Subject: [PATCH] Refs #32: repair the build and allowing for use the vcard module --- src/contacts/vcard/parse.ts | 4 ++-- src/file/file.ts | 4 ++-- src/insights/insightService.ts | 2 +- src/insights/processors/UidProcessor.tsx | 2 +- src/settings/settings.ts | 2 +- src/ui/sidebar/components/Avatar.tsx | 5 +++-- src/ui/sidebar/components/InsightsView.tsx | 2 +- src/util/avatarActions.ts | 13 ++----------- src/util/photoLineFromV3toV4.ts | 10 ++++++++++ tests/vcard.spec.ts | 4 ++-- 10 files changed, 25 insertions(+), 23 deletions(-) create mode 100644 src/util/photoLineFromV3toV4.ts diff --git a/src/contacts/vcard/parse.ts b/src/contacts/vcard/parse.ts index f71248f..90be528 100644 --- a/src/contacts/vcard/parse.ts +++ b/src/contacts/vcard/parse.ts @@ -2,7 +2,7 @@ import { VCardForObsidianRecord, VCardSupportedKey } from "src/contacts/vcard"; import { ensureHasName } from "src/contacts/vcard/shared/ensureHasName"; import { sortVCardOFields } from "src/contacts/vcard/shared/sortVcardFields"; import { StructuredFields } from "src/contacts/vcard/shared/structuredFields"; -import { convertToLatestVCFPhotoFormat } from "src/util/avatarActions"; +import { photoLineFromV3toV4 } from "src/util/photoLineFromV3toV4"; function unfoldVCardLines(vCardData: string): string[] { // Normalize line endings to \n first (handles \r, \r\n) @@ -112,7 +112,7 @@ function parseVCardLine(line: string): VCardForObsidianRecord { const typeValues:string = params["type"] ? `[${params["type"].join(",")}]` : ""; if (key.contains('PHOTO') && key.contains('ENCODING=BASE64')) { - parsedData['PHOTO'] = convertToLatestVCFPhotoFormat(line); + parsedData['PHOTO'] = photoLineFromV3toV4(line); } else if (key === 'VERSION') { parsedData['VERSION'] = '4.0'; } else if (propKey in StructuredFields) { diff --git a/src/file/file.ts b/src/file/file.ts index 9a6fba0..afc5aea 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -1,9 +1,9 @@ import {App, normalizePath, Notice, Platform,TAbstractFile, TFile, TFolder, Vault, Workspace} from "obsidian"; import { getFrontmatterFromFiles } from "src/contacts"; import { getSettings } from "src/context/sharedSettingsContext"; -import { RunType } from "src/insights/insight"; +import { RunType } from "src/insights/insight.d"; import { insightService } from "src/insights/insightService"; -import { FileExistsModal } from "src/ui/modals/fileExistsModal";; +import { FileExistsModal } from "src/ui/modals/fileExistsModal"; export async function openFile(file: TFile, workspace: Workspace) { const leaf = workspace.getLeaf() diff --git a/src/insights/insightService.ts b/src/insights/insightService.ts index e7456a8..5867ac7 100644 --- a/src/insights/insightService.ts +++ b/src/insights/insightService.ts @@ -1,6 +1,6 @@ import { Contact } from "src/contacts"; -import { InsighSettingProperties, InsightProcessor, InsightQueItem, RunType } from "src/insights/insight"; +import { InsighSettingProperties, InsightProcessor, InsightQueItem, RunType } from "src/insights/insight.d"; const processors = new Map(); diff --git a/src/insights/processors/UidProcessor.tsx b/src/insights/processors/UidProcessor.tsx index 5da6b9d..bc75873 100644 --- a/src/insights/processors/UidProcessor.tsx +++ b/src/insights/processors/UidProcessor.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { Contact, updateFrontMatterValue } from "src/contacts"; import { getSettings } from "src/context/sharedSettingsContext"; -import { InsightProcessor, InsightQueItem, RunType } from "src/insights/insight"; +import { InsightProcessor, InsightQueItem, RunType } from "src/insights/insight.d"; // Zero dependency uuid generator as its not used for millions of records const generateUUID = (): string => { diff --git a/src/settings/settings.ts b/src/settings/settings.ts index f2e9382..a67696c 100644 --- a/src/settings/settings.ts +++ b/src/settings/settings.ts @@ -1,6 +1,6 @@ import { App, PluginSettingTab, Setting } from "obsidian"; import { setSettings } from "src/context/sharedSettingsContext"; -import { InsighSettingProperties } from "src/insights/insight"; +import { InsighSettingProperties } from "src/insights/insight.d"; import { insightService } from "src/insights/insightService"; import ContactsPlugin from "src/main"; import { FolderSuggest } from "src/settings/FolderSuggest"; diff --git a/src/ui/sidebar/components/Avatar.tsx b/src/ui/sidebar/components/Avatar.tsx index 7987109..fc76914 100644 --- a/src/ui/sidebar/components/Avatar.tsx +++ b/src/ui/sidebar/components/Avatar.tsx @@ -1,5 +1,6 @@ import * as React from "react"; -import { convertToLatestVCFPhotoFormat } from "src/util/avatarActions"; +import { photoLineFromV3toV4 } from "src/util/photoLineFromV3toV4"; + interface AvatarProps { photoUrl?: string; @@ -19,7 +20,7 @@ export const Avatar = (props: AvatarProps) => {
{props.photoUrl && !hasImageError ? ( setHasImageError(true)} /> ) : ( diff --git a/src/ui/sidebar/components/InsightsView.tsx b/src/ui/sidebar/components/InsightsView.tsx index 8855a4b..62fc864 100644 --- a/src/ui/sidebar/components/InsightsView.tsx +++ b/src/ui/sidebar/components/InsightsView.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { useEffect, useRef, useState } from "react"; import { Contact } from "src/contacts"; -import { InsightQueItem, RunType } from "src/insights/insight"; +import { InsightQueItem, RunType } from "src/insights/insight.d"; import { insightService } from "src/insights/insightService"; type ActionProps = { diff --git a/src/util/avatarActions.ts b/src/util/avatarActions.ts index 7d865f5..76757b2 100644 --- a/src/util/avatarActions.ts +++ b/src/util/avatarActions.ts @@ -1,7 +1,7 @@ import { Notice } from "obsidian"; import { Contact, updateFrontMatterValue } from "src/contacts"; import { openFilePicker } from "src/file/file"; -import { RunType } from "src/insights/insight"; +import { RunType } from "src/insights/insight.d"; import { insightService } from "src/insights/insightService"; const resizeAndCropImage = (img: HTMLImageElement, outputSize: number): HTMLCanvasElement => { @@ -74,13 +74,4 @@ export const processAvatar = async (contact: Contact) => { } } -export const convertToLatestVCFPhotoFormat = (line:string) => { - const url = line.startsWith('PHOTO;') ? line.slice(6) : line; - const match = url.match(/^ENCODING=BASE64;(.*?):/); - if (match) { - const mimeType = match[1].toLowerCase(); // e.g., "jpeg" - const base64Data = url.split(':').slice(1).join(':'); - return `data:image/${mimeType};base64,${base64Data}`; - } - return url; -} + diff --git a/src/util/photoLineFromV3toV4.ts b/src/util/photoLineFromV3toV4.ts new file mode 100644 index 0000000..ea6fc15 --- /dev/null +++ b/src/util/photoLineFromV3toV4.ts @@ -0,0 +1,10 @@ +export const photoLineFromV3toV4 = (line:string) => { + const url = line.startsWith('PHOTO;') ? line.slice(6) : line; + const match = url.match(/^ENCODING=BASE64;(.*?):/); + if (match) { + const mimeType = match[1].toLowerCase(); // e.g., "jpeg" + const base64Data = url.split(':').slice(1).join(':'); + return `data:image/${mimeType};base64,${base64Data}`; + } + return url; +} diff --git a/tests/vcard.spec.ts b/tests/vcard.spec.ts index e57a8fa..7969a80 100644 --- a/tests/vcard.spec.ts +++ b/tests/vcard.spec.ts @@ -1,5 +1,5 @@ import { App } from "obsidian"; -import { createEmpty } from 'src/contacts/vcard/createEmpty'; +import { vcard } from "src/contacts/vcard"; import { setApp } from "src/context/sharedAppContext"; import { describe, expect, it, vi } from 'vitest'; @@ -28,7 +28,7 @@ vi.mock('src/ui/modals/contactNameModal', () => { }); describe('vcard creatEmpty', () => { it('should ask for a firstname and lastname ', async () => { - const empty = await createEmpty(); + const empty = await vcard.createEmpty(); expect(empty).toBeDefined(); expect(empty).toEqual(expect.objectContaining({