feat: Select parent folders of collection folders

This commit is contained in:
Samir L. Boulema 2026-07-12 21:57:35 +02:00
parent 7157869306
commit 8664b8eb3c
3 changed files with 35 additions and 37 deletions

24
main.ts
View file

@ -6,9 +6,8 @@ import {
DEFAULT_COLLECTION_FOLDER_PATH,
DEFAULT_COLLECTION_NAME_COLUMN,
hashCollectionContents,
processCollectionFiles,
mergeCollections,
syncCollections,
syncCounts,
} from "src/collection";
import { renderDecklist } from "src/renderer";
import { ObsidianPluginMtgSettings } from "src/settings";
@ -54,23 +53,22 @@ export default class ObsidianPluginMtg extends Plugin {
const collectionFolderPath = this.settings.collection?.folderPath || "";
if (file.parent?.path.startsWith(collectionFolderPath)) {
this.collections = await syncCollections(vault, this.settings);
this.cardCounts = await syncCounts(vault, this.settings);
this.cardCounts = mergeCollections(this.collections);
clearCache();
}
}
});
this.app.workspace.onLayoutReady(async () => {
const fileContents = await processCollectionFiles(vault, this.settings);
const hash = hashCollectionContents(fileContents);
this.collections = await syncCollections(vault, this.settings);
this.cardCounts = mergeCollections(this.collections);
const hash = hashCollectionContents(this.collections);
const savedData = await this.loadData();
if (savedData?.collectionHash === hash && savedData?.cardDataCache) {
loadCache(savedData.cardDataCache);
}
this.collections = await syncCollections(vault, this.settings);
this.cardCounts = await syncCounts(vault, this.settings);
});
this.addCommand({
@ -115,11 +113,7 @@ export default class ObsidianPluginMtg extends Plugin {
onunload() {
void (async () => {
const fileContents = await processCollectionFiles(
this.app.vault,
this.settings
);
const hash = hashCollectionContents(fileContents);
const hash = hashCollectionContents(this.collections);
const data = await this.loadData() ?? {};
await this.saveData({
@ -346,6 +340,10 @@ class FolderSuggestModal extends FuzzySuggestModal<TFolder> {
this.app.vault.getFiles().forEach((file) => {
if (file.extension === "csv" && file.parent) {
folders.set(file.parent.path, file.parent);
if (file.parent.parent) {
folders.set(file.parent.parent.path, file.parent.parent);
}
}
});

View file

@ -90,19 +90,6 @@ export const processCollectionFiles = async (
)).filter((c): c is CardCollection => c !== null);
};
export const syncCounts = async (
vault: Vault,
settings: ObsidianPluginMtgSettings
): Promise<CardCounts> => {
const collections = await processCollectionFiles(vault, settings);
return collections.reduce((acc, collection) => {
Object.entries(collection.counts).forEach(([name, count]) => {
acc[name] = (acc[name] ?? 0) + count;
});
return acc;
}, {} as CardCounts);
};
export const syncCollections = async (
vault: Vault,
settings: ObsidianPluginMtgSettings
@ -113,4 +100,13 @@ export const syncCollections = async (
export const hashCollectionContents = (contents: CardCollection[]): string => {
const combined = contents.map(c => Object.entries(c.counts).join("")).join("");
return `${contents.length}-${combined.length}`;
};
export const mergeCollections = (collections: CardCollection[]): CardCounts => {
return collections.reduce((acc, collection) => {
Object.entries(collection.counts).forEach(([name, count]) => {
acc[name] = (acc[name] ?? 0) + count;
});
return acc;
}, {} as CardCounts);
};

View file

@ -194,7 +194,8 @@ export const getMultipleCardData = async (
* @returns A record of card data indexed by normalized card name
*/
export const fetchCardDataFromScryfall = async (
distinctCards: CardIdentifier[]
distinctCards: CardIdentifier[],
onProgress?: (fetched: number, total: number) => void
): Promise<Record<string, CardData>> => {
const batches: CardIdentifier[][] = [];
let currentBatch: CardIdentifier[] = [];
@ -210,14 +211,14 @@ export const fetchCardDataFromScryfall = async (
batches.push(currentBatch);
const cardDataInBatches: ScryfallResponse[] = await Promise.all(
batches.map((batch) => getMultipleCardData(batch))
);
const cardDataByCardId: Record<string, CardData> = {};
let fetched = 0;
const total = distinctCards.length;
cardDataInBatches.forEach((batch) => {
batch.data.forEach((card: CardData) => {
for (const batch of batches) {
const result: ScryfallResponse = await getMultipleCardData(batch);
result.data.forEach((card: CardData) => {
if (card.name) {
cardDataByCardId[nameToId(card.name)] = card;
}
@ -225,7 +226,10 @@ export const fetchCardDataFromScryfall = async (
cardDataByCardId[nameToId(card.printed_name)] = card;
}
});
});
fetched += batch.length;
onProgress?.(fetched, total);
}
return cardDataByCardId;
};
@ -252,13 +256,13 @@ export const fetchCardDataFromScryfallCached = async (
});
if (uncachedCards.length > 0) {
const freshData = await fetchCardDataFromScryfall(uncachedCards);
const freshData = await fetchCardDataFromScryfall(uncachedCards, onProgress);
Object.entries(freshData).forEach(([key, data]) => {
setCachedCardData(key, data);
});
} else {
onProgress?.(distinctCards.length, distinctCards.length);
}
onProgress?.(distinctCards.length, distinctCards.length);
return getCachedCardData();
};