more code refactoring for maintainabillity

This commit is contained in:
Roland Broekema 2025-04-15 22:43:09 +02:00
parent 78b258b6da
commit 67f1eca272
22 changed files with 3068 additions and 74 deletions

View file

@ -5,6 +5,8 @@ root = true
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = tab
indent_style = space
indent_size = 2
tab_width = 2

View file

@ -5,7 +5,8 @@
"node": true
},
"plugins": [
"@typescript-eslint"
"@typescript-eslint",
"simple-import-sort"
],
"extends": [
"eslint:recommended",
@ -17,6 +18,8 @@
},
"rules": {
"no-unused-vars": 1,
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
"@typescript-eslint/no-unused-vars": [
"error",
{
@ -27,4 +30,4 @@
"no-prototype-builtins": "off",
"@typescript-eslint/no-empty-function": "off"
}
}
}

3014
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,11 @@
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
"version": "node version-bump.mjs && git add manifest.json versions.json"
},
"keywords": ["obsidian", "contacts", "vcard"],
"keywords": [
"obsidian",
"contacts",
"vcard"
],
"author": "",
"license": "MIT",
"devDependencies": {
@ -20,6 +24,8 @@
"@typescript-eslint/parser": "5.29.0",
"builtin-modules": "3.3.0",
"esbuild": "0.14.47",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-simple-import-sort": "^12.1.1",
"obsidian": "latest",
"tslib": "2.4.0",
"typescript": "4.7.4"

View file

@ -1,9 +1,13 @@
import {TFile} from "obsidian";
import * as yaml from 'js-yaml';
import { Contact } from "./contact";
import { TFile } from "obsidian";
import { getApp } from "src/context/sharedAppContext";
export async function parseContactFiles(files: TFile[]) {
export type Contact = {
data: Record<string, any>;
file: TFile;
}
export async function getFrontmatterFromFiles(files: TFile[]) {
const { metadataCache } = getApp();
const contactsData: Contact[] = [];
for (const file of files) {
@ -34,7 +38,7 @@ export async function updateFrontMatterValue(file: TFile, key: string, value: st
yamlObj[key] = value;
const newFrontMatter = '---\n' + yaml.dump(yamlObj) + '---\n';
const newFrontMatter = '---\n' + yaml.dump(yamlObj, { lineWidth: -1 }) + '---\n';
const newContent = newFrontMatter + body;
await app.vault.modify(file, newContent);

View file

@ -9,7 +9,7 @@ export function mdRender(record: Record<string, any>, hashtags: string): string
const tempTags= recordWithoutNote.CATEGORIES.split(',')
additionalTags = `#${tempTags.join(' #')}`
}
const yamlString = yaml.dump(recordWithoutNote);
const yamlString = yaml.dump(recordWithoutNote, { lineWidth: -1 });
return `---
${yamlString}

3
src/contacts/index.ts Normal file
View file

@ -0,0 +1,3 @@
export * from './contactDataKeys';
export * from './contactFrontmatter';
export * from './contactMdTemplate';

View file

@ -0,0 +1,3 @@
export * from './vcardDefinitions';
export * from './vcardParse';
export * from './vcardToString';

View file

@ -1,4 +1,4 @@
import {VCardForObsidianRecord, VCardStructuredFields} from "./vcardDefinitions";
import { VCardForObsidianRecord, VCardStructuredFields } from "src/contacts/vcard";
import { ContactNameModal } from "src/ui/modals/contactNameModal";
import { convertToLatestVCFPhotoFormat } from "src/util/avatarActions";

View file

@ -1,7 +1,7 @@
import {Notice, TFile} from "obsidian";
import {parseKey} from "./vcardKey";
import {VCardStructuredFields} from "./vcardDefinitions";
import {getApp} from "src/context/sharedAppContext";
import { Notice, TFile } from "obsidian";
import { parseKey } from "src/contacts";
import { VCardStructuredFields } from "src/contacts/vcard";
import { getApp } from "src/context/sharedAppContext";
function filterNonNull<T>(array: (T | null | undefined)[]): T[] {
return array.filter((item): item is T => item !== null && item !== undefined);

View file

@ -6,7 +6,6 @@ export function setApp(app: App) {
_app = app
}
// Safe accessor, runtime-enforced, TS knows it's not undefined
export function getApp(): App {
if (!_app) {
throw new Error('App context has not been set.')

View file

@ -1,4 +1,4 @@
import {App, Modal, normalizePath, Notice, TAbstractFile, TFile, TFolder, Vault, Workspace} from "obsidian";
import {App, normalizePath, Notice, TAbstractFile, TFile, TFolder, Vault, Workspace} from "obsidian";
import { join } from "path";
import { FileExistsModal } from "src/ui/modals/fileExistsModal";

View file

@ -1,6 +0,0 @@
import { TFile } from "obsidian";
export type Contact = {
data: Record<string, any>;
file: TFile;
}

View file

@ -1,11 +1,10 @@
import { setIcon, TFile } from "obsidian";
import * as React from "react";
import {getApp} from "src/context/sharedAppContext";
import {fileId, openFile} from "src/file/file";
import {Contact} from "src/parse/contact";
import {setIcon, TFile} from "obsidian";
import Avatar from "./Avatar";
import { parseKey } from "src/parse/vcard/vcardKey";
import { CopyableItem } from "./CopyableItem";
import { Contact, parseKey } from "src/contacts";
import { getApp } from "src/context/sharedAppContext";
import { fileId, openFile } from "src/file/file";
import Avatar from "src/ui/sidebar/components/Avatar";
import { CopyableItem } from "src/ui/sidebar/components/CopyableItem";
type ContactProps = {
contact: Contact;

View file

@ -1,10 +1,10 @@
import { randomUUID } from "crypto";
import { TFile } from "obsidian";
import * as React from "react";
import { Contact } from "src/parse/contact";
import { Contact } from "src/contacts";
import { ContactView } from "src/ui/sidebar/components/ContactView";
import { Sort } from "src/util/constants";
import { ContactView } from "./ContactView";
import myScrollTo from "src/util/myScrollTo";
import {TFile} from "obsidian";
type ContactsListProps = {

View file

@ -1,5 +1,5 @@
import { Menu, Notice } from "obsidian";
import * as React from "react";
import {Menu, Notice} from "obsidian";
interface CopyableItemProps {
value: string;

View file

@ -1,18 +1,21 @@
import {normalizePath, Notice, TAbstractFile, TFile, TFolder} from "obsidian";
import { normalizePath, Notice, TAbstractFile, TFile, TFolder, WorkspaceLeaf } from "obsidian";
import * as React from "react";
import { Contact, getFrontmatterFromFiles, mdRender } from "src/contacts";
import { createEmptyVcard, parseToSingles, parseVcard, vcardToString } from "src/contacts/vcard";
import { getApp } from "src/context/sharedAppContext";
import {createContactFile, createFileName, findContactFiles, openFilePicker, saveVcardFilePicker} from "src/file/file";
import {
createContactFile,
createFileName,
findContactFiles,
openFilePicker,
saveVcardFilePicker
} from "src/file/file";
import ContactsPlugin from "src/main";
import { Contact } from "src/parse/contact";
import { parseContactFiles } from "src/parse/parse";
import { Sort } from "src/util/constants";
import { ContactsListView } from "./ContactsListView";
import { HeaderView } from "./HeaderView";
import { createEmptyVcard, parseToSingles, parseVcard } from "src/parse/vcard/vcardParse";
import { mdRender } from "src/parse/vcard/vcardMdTemplate";
import myScrollTo from "src/util/myScrollTo";
import { vcardToString } from "src/parse/vcard/vcardToString";
import { ContactsListView } from "src/ui/sidebar/components/ContactsListView";
import { HeaderView } from "src/ui/sidebar/components/HeaderView";
import { processAvatar } from "src/util/avatarActions";
import { Sort } from "src/util/constants";
import myScrollTo from "src/util/myScrollTo";
type RootProps = {
@ -39,7 +42,7 @@ export const SidebarRootView = (props: RootProps) => {
return;
}
parseContactFiles(findContactFiles(contactsFolder)).then((contactsData) =>{
getFrontmatterFromFiles(findContactFiles(contactsFolder)).then((contactsData) =>{
setContacts(contactsData);
});
};
@ -52,6 +55,7 @@ export const SidebarRootView = (props: RootProps) => {
const updateFiles = (file: TAbstractFile) => {
setTimeout(() => {
console.log('updatingFiles');
if (isFileInFolder(file)) {
parseContacts();
}
@ -71,9 +75,11 @@ export const SidebarRootView = (props: RootProps) => {
};
}, [vault, folder]);
React.useEffect(() => {
app.workspace.on("active-leaf-change", myScrollTo.scrollToLeaf);
app.workspace.on("active-leaf-change", (leaf: WorkspaceLeaf):void => {
console.log('leafchange', leaf);
myScrollTo.scrollToLeaf(leaf);
});
return () => {
myScrollTo.clearDebounceTimer()

View file

@ -1,10 +1,10 @@
import { ItemView, WorkspaceLeaf } from "obsidian";
import * as React from "react";
import { createRoot } from "react-dom/client";
import {setApp, clearApp} from "src/context/sharedAppContext";
import { clearApp, setApp } from "src/context/sharedAppContext";
import ContactsPlugin from "src/main";
import { SidebarRootView } from "src/ui/sidebar/components/SidebarRootView";
import { CONTACTS_VIEW_CONFIG } from "src/util/constants";
import { SidebarRootView } from "./components/SidebarRootView";
export class ContactsView extends ItemView {
root = createRoot(this.containerEl.children[1]);

View file

@ -1,7 +1,6 @@
import {Contact} from "src/parse/contact";
import {openFilePicker} from "src/file/file";
import {updateFrontMatterValue} from "src/parse/parse";
import {App, Notice} from "obsidian";
import { Notice } from "obsidian";
import { Contact, updateFrontMatterValue } from "src/contacts";
import { openFilePicker } from "src/file/file";
const resizeAndCropImage = (img: HTMLImageElement, outputSize: number): HTMLCanvasElement => {
const canvas = document.createElement('canvas');

View file

@ -1,4 +1,4 @@
import {MarkdownView, WorkspaceLeaf} from "obsidian";
import { MarkdownView, WorkspaceLeaf } from "obsidian";
import { fileId } from "src/file/file";
let debounceTimer: NodeJS.Timeout;
@ -28,7 +28,7 @@ const scrollToLeaf = (leaf: WorkspaceLeaf):void => {
behavior: "smooth",
});
});
}, 250);
}, 50);
};
const scrollToTop = ():void => {