diff --git a/src/main.ts b/src/main.ts index c9853af..8a92528 100644 --- a/src/main.ts +++ b/src/main.ts @@ -621,9 +621,14 @@ export default class MediaDbPlugin extends Plugin { const erroredFiles: { filePath: string; error: string }[] = []; let canceled: boolean = false; - const { selectedAPI, titleFieldName, appendContent } = await new Promise<{ selectedAPI: string; titleFieldName: string; appendContent: boolean }>(resolve => { - new MediaDbFolderImportModal(this.app, this, (selectedAPI: string, titleFieldName: string, appendContent: boolean) => { - resolve({ selectedAPI, titleFieldName, appendContent }); + const { selectedAPI, titleFieldName, idFieldName, appendContent } = await new Promise<{ + selectedAPI: string; + titleFieldName: string; + idFieldName: string; + appendContent: boolean; + }>(resolve => { + new MediaDbFolderImportModal(this.app, this, (selectedAPI: string, titleFieldName: string, idFieldName: string, appendContent: boolean) => { + resolve({ selectedAPI, titleFieldName, idFieldName, appendContent }); }).open(); }); @@ -637,54 +642,75 @@ export default class MediaDbPlugin extends Plugin { const metadata = this.getMetadataFromFileCache(file); - const title = metadata[titleFieldName]; - if (!title || typeof title !== 'string') { - erroredFiles.push({ filePath: file.path, error: `metadata field '${titleFieldName}' not found, empty, or not a string` }); - continue; - } + // Querying by ID takes priority, doesn't require user to select from multiple matches + const id = metadata[idFieldName]; + if (id && typeof id === 'string') { + try { + const model = await this.apiManager.queryDetailedInfoById(id, selectedAPI); + if (model) { + await this.createMediaDbNotes([model], appendContent ? file : undefined); + } else { + erroredFiles.push({ filePath: file.path, error: `Failed to query API with id: ${id}` }); + } + } catch (e) { + erroredFiles.push({ filePath: file.path, error: `${e}` }); + continue; + } + } else { + // Query API with title instead, requires user to select best match + const title = metadata[titleFieldName]; + if (!title || typeof title !== 'string') { + erroredFiles.push({ filePath: file.path, error: `metadata field '${titleFieldName}' not found, empty, or not a string` }); + continue; + } - let results: MediaTypeModel[] = []; - try { - results = await this.apiManager.query(title, [selectedAPI]); - } catch (e) { - erroredFiles.push({ filePath: file.path, error: `${e}` }); - continue; - } - if (!results || results.length === 0) { - erroredFiles.push({ filePath: file.path, error: `no search results` }); - continue; - } + let results: MediaTypeModel[] = []; + try { + results = await this.apiManager.query(title, [selectedAPI]); + } catch (e) { + erroredFiles.push({ filePath: file.path, error: `${e}` }); + continue; + } + if (!results || results.length === 0) { + erroredFiles.push({ filePath: file.path, error: `no search results` }); + continue; + } - const { selectModalResult, selectModal } = await this.modalHelper.createSelectModal({ elements: results, skipButton: true, modalTitle: `Results for '${title}'` }); + const { selectModalResult, selectModal } = await this.modalHelper.createSelectModal({ + elements: results, + skipButton: true, + modalTitle: `Results for '${title}'`, + }); + + if (selectModalResult.code === ModalResultCode.ERROR) { + erroredFiles.push({ filePath: file.path, error: selectModalResult.error.message }); + selectModal.close(); + continue; + } + + if (selectModalResult.code === ModalResultCode.CLOSE) { + erroredFiles.push({ filePath: file.path, error: 'user canceled' }); + selectModal.close(); + canceled = true; + continue; + } + + if (selectModalResult.code === ModalResultCode.SKIP) { + erroredFiles.push({ filePath: file.path, error: 'user skipped' }); + selectModal.close(); + continue; + } + + if (selectModalResult.data.selected.length === 0) { + erroredFiles.push({ filePath: file.path, error: `no search results selected` }); + continue; + } + + const detailedResults = await this.queryDetails(selectModalResult.data.selected); + await this.createMediaDbNotes(detailedResults, appendContent ? file : undefined); - if (selectModalResult.code === ModalResultCode.ERROR) { - erroredFiles.push({ filePath: file.path, error: selectModalResult.error.message }); selectModal.close(); - continue; } - - if (selectModalResult.code === ModalResultCode.CLOSE) { - erroredFiles.push({ filePath: file.path, error: 'user canceled' }); - selectModal.close(); - canceled = true; - continue; - } - - if (selectModalResult.code === ModalResultCode.SKIP) { - erroredFiles.push({ filePath: file.path, error: 'user skipped' }); - selectModal.close(); - continue; - } - - if (selectModalResult.data.selected.length === 0) { - erroredFiles.push({ filePath: file.path, error: `no search results selected` }); - continue; - } - - const detailedResults = await this.queryDetails(selectModalResult.data.selected); - await this.createMediaDbNotes(detailedResults, appendContent ? file : undefined); - - selectModal.close(); } } diff --git a/src/modals/MediaDbFolderImportModal.ts b/src/modals/MediaDbFolderImportModal.ts index 995df1a..478fa25 100644 --- a/src/modals/MediaDbFolderImportModal.ts +++ b/src/modals/MediaDbFolderImportModal.ts @@ -4,23 +4,25 @@ import type MediaDbPlugin from '../main'; export class MediaDbFolderImportModal extends Modal { plugin: MediaDbPlugin; - onSubmit: (selectedAPI: string, titleFieldName: string, appendContent: boolean) => void; + onSubmit: (selectedAPI: string, titleFieldName: string, idFieldName: string, appendContent: boolean) => void; selectedApi: string; searchBtn?: ButtonComponent; titleFieldName: string; + idFieldName: string; appendContent: boolean; - constructor(app: App, plugin: MediaDbPlugin, onSubmit: (selectedAPI: string, titleFieldName: string, appendContent: boolean) => void) { + constructor(app: App, plugin: MediaDbPlugin, onSubmit: (selectedAPI: string, titleFieldName: string, idFieldName: string, appendContent: boolean) => void) { super(app); this.plugin = plugin; this.onSubmit = onSubmit; this.selectedApi = plugin.apiManager.apis[0].apiName; this.titleFieldName = ''; + this.idFieldName = ''; this.appendContent = false; } submit(): void { - this.onSubmit(this.selectedApi, this.titleFieldName, this.appendContent); + this.onSubmit(this.selectedApi, this.titleFieldName, this.idFieldName, this.appendContent); this.close(); } @@ -43,7 +45,7 @@ export class MediaDbFolderImportModal extends Modal { apiSelectorWrapper.appendChild(apiSelectorComponent.selectEl); contentEl.createDiv({ cls: 'media-db-plugin-spacer' }); - contentEl.createEl('h3', { text: 'Append note content to Media DB entry.' }); + contentEl.createEl('h3', { text: 'Append note content to Media DB entry?' }); const appendContentToggleElementWrapper = contentEl.createEl('div', { cls: 'media-db-plugin-list-wrapper' }); const appendContentToggleTextWrapper = appendContentToggleElementWrapper.createEl('div', { cls: 'media-db-plugin-list-text-wrapper' }); @@ -60,7 +62,7 @@ export class MediaDbFolderImportModal extends Modal { appendContentToggleComponentWrapper.appendChild(appendContentToggle.toggleEl); contentEl.createDiv({ cls: 'media-db-plugin-spacer' }); - contentEl.createEl('h3', { text: 'The name of the metadata field that should be used as the title to query.' }); + contentEl.createEl('h3', { text: "Name of 'title' metadata field to use in API query." }); const placeholder = 'title'; const titleFieldNameComponent = new TextComponent(contentEl); @@ -74,6 +76,20 @@ export class MediaDbFolderImportModal extends Modal { }); contentEl.appendChild(titleFieldNameComponent.inputEl); + contentEl.createDiv({ cls: 'media-db-plugin-spacer' }); + contentEl.createEl('h3', { text: "Name of 'id' metadata field to use in API query (if present, will be used instead of title)." }); + + const idFieldNameComponent = new TextComponent(contentEl); + idFieldNameComponent.inputEl.style.width = '100%'; + idFieldNameComponent.setPlaceholder('id'); + idFieldNameComponent.onChange(value => (this.idFieldName = value)); + idFieldNameComponent.inputEl.addEventListener('keydown', ke => { + if (ke.key === 'Enter') { + this.submit(); + } + }); + contentEl.appendChild(idFieldNameComponent.inputEl); + contentEl.createDiv({ cls: 'media-db-plugin-spacer' }); new Setting(contentEl)