mirror of
https://github.com/broekema41/obsidian-vcf-contacts.git
synced 2026-07-22 05:42:58 +00:00
more code refactoring for maintainabillity
This commit is contained in:
parent
78b258b6da
commit
67f1eca272
22 changed files with 3068 additions and 74 deletions
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
3014
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -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
3
src/contacts/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from './contactDataKeys';
|
||||
export * from './contactFrontmatter';
|
||||
export * from './contactMdTemplate';
|
||||
3
src/contacts/vcard/index.ts
Normal file
3
src/contacts/vcard/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from './vcardDefinitions';
|
||||
export * from './vcardParse';
|
||||
export * from './vcardToString';
|
||||
|
|
@ -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";
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -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.')
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
import { TFile } from "obsidian";
|
||||
|
||||
export type Contact = {
|
||||
data: Record<string, any>;
|
||||
file: TFile;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Menu, Notice } from "obsidian";
|
||||
import * as React from "react";
|
||||
import {Menu, Notice} from "obsidian";
|
||||
|
||||
interface CopyableItemProps {
|
||||
value: string;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
|
|
|||
|
|
@ -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 => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue