diff --git a/src/main.ts b/src/main.ts index d9cfe58..5f87f9f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,7 +2,7 @@ import {MarkdownView, Notice, parseYaml, Plugin, stringifyYaml, TFile, TFolder} import {getDefaultSettings, MediaDbPluginSettings, MediaDbSettingTab} from './settings/Settings'; import {APIManager} from './api/APIManager'; import {MediaTypeModel} from './models/MediaTypeModel'; -import {dateTimeToString, markdownTable, replaceIllegalFileNameCharactersInString} from './utils/Utils'; +import {CreateNoteOptions, dateTimeToString, markdownTable, replaceIllegalFileNameCharactersInString} from './utils/Utils'; import {OMDbAPI} from './api/apis/OMDbAPI'; import {MALAPI} from './api/apis/MALAPI'; import {WikipediaAPI} from './api/apis/WikipediaAPI'; @@ -57,7 +57,7 @@ export default class MediaDbPlugin extends Plugin { menu.addItem(item => { item.setTitle('Import folder as Media DB entries') .setIcon('database') - .onClick(() => this.createEntriesFromFolder(file as TFolder)); + .onClick(() => this.createEntriesFromFolder(file)); }); } })); @@ -164,27 +164,44 @@ export default class MediaDbPlugin extends Plugin { }); if (!apiSearchResults) { + // TODO: add new notice saying no results found? return; } - const selectResults: MediaTypeModel[] = await this.modalHelper.openSelectModal({elements: apiSearchResults}, async (selectModalData) => { - return await this.queryDetails(selectModalData.selected); - }); + let selectResults: MediaTypeModel[]; + let proceed: boolean; - if (!selectResults) { - return; + while (!proceed) { + selectResults = await this.modalHelper.openSelectModal({elements: apiSearchResults}, async (selectModalData) => { + return await this.queryDetails(selectModalData.selected); + }); + if (!selectResults) { + return; + } + + proceed = await this.modalHelper.openPreviewModal({elements: selectResults}, async (previewModalData) => { + return previewModalData.confirmed; + }); } await this.createMediaDbNotes(selectResults); } - async createEntryWithIdSearchModal() { - const idSearchResult: MediaTypeModel = await this.modalHelper.openIdSearchModal({}, async (idSearchModalData) => { - return await this.apiManager.queryDetailedInfoById(idSearchModalData.query, idSearchModalData.api); - }); + async createEntryWithIdSearchModal(): Promise { + let idSearchResult: MediaTypeModel; + let proceed: boolean; - if (!idSearchResult) { - return; + while (!proceed) { + idSearchResult = await this.modalHelper.openIdSearchModal({}, async (idSearchModalData) => { + return await this.apiManager.queryDetailedInfoById(idSearchModalData.query, idSearchModalData.api); + }); + if (!idSearchResult) { + return; + } + + proceed = await this.modalHelper.openPreviewModal({elements: [idSearchResult]}, async (previewModalData) => { + return previewModalData.confirmed; + }); } await this.createMediaDbNoteFromModel(idSearchResult, {attachTemplate: true, openNote: true}); @@ -209,11 +226,11 @@ export default class MediaDbPlugin extends Plugin { return detailModels; } - async createMediaDbNoteFromModel(mediaTypeModel: MediaTypeModel, options: { attachTemplate?: boolean, attachFile?: TFile, openNote?: boolean }): Promise { + async createMediaDbNoteFromModel(mediaTypeModel: MediaTypeModel, options: CreateNoteOptions): Promise { try { console.debug('MDB | creating new note'); - let fileContent = await this.generateMediaDbNoteContents(mediaTypeModel, {attachTemplate: options.attachTemplate, attachFile: options.attachFile}); + let fileContent = await this.generateMediaDbNoteContents(mediaTypeModel, options); await this.createNote(this.mediaTypeManager.getFileName(mediaTypeModel), fileContent, options.openNote); } catch (e) { @@ -222,15 +239,13 @@ export default class MediaDbPlugin extends Plugin { } } - private async generateMediaDbNoteContents(mediaTypeModel: MediaTypeModel, options: { attachTemplate?: boolean, attachFile?: TFile }) { + async generateMediaDbNoteContents(mediaTypeModel: MediaTypeModel, options: CreateNoteOptions) { let fileMetadata = this.modelPropertyMapper.convertObject(mediaTypeModel.toMetaDataObject()); let fileContent = ''; + const template = options.attachTemplate ? await this.mediaTypeManager.getTemplate(mediaTypeModel, this.app) : ''; ({fileMetadata, fileContent} = await this.attachFile(fileMetadata, fileContent, options.attachFile)); - ({ - fileMetadata, - fileContent, - } = await this.attachTemplate(fileMetadata, fileContent, options.attachTemplate ? await this.mediaTypeManager.getTemplate(mediaTypeModel, this.app) : '')); + ({fileMetadata, fileContent} = await this.attachTemplate(fileMetadata, fileContent, template)); fileContent = `---\n${this.settings.useCustomYamlStringifier ? YAMLConverter.toYaml(fileMetadata) : stringifyYaml(fileMetadata)}---\n` + fileContent; return fileContent; diff --git a/src/modals/MediaDbAdvancedSearchModal.ts b/src/modals/MediaDbAdvancedSearchModal.ts index e25f0a2..fa7ac6b 100644 --- a/src/modals/MediaDbAdvancedSearchModal.ts +++ b/src/modals/MediaDbAdvancedSearchModal.ts @@ -47,7 +47,7 @@ export class MediaDbAdvancedSearchModal extends Modal { async search(): Promise { if (!this.query || this.query.length < 3) { - new Notice('MDB | Query to short'); + new Notice('MDB | Query too short'); return; } diff --git a/src/modals/MediaDbPreviewModal.ts b/src/modals/MediaDbPreviewModal.ts new file mode 100644 index 0000000..ec20a28 --- /dev/null +++ b/src/modals/MediaDbPreviewModal.ts @@ -0,0 +1,82 @@ +import {ButtonComponent, MarkdownRenderer, Modal, Setting} from 'obsidian'; +import MediaDbPlugin from 'src/main'; +import {MediaTypeModel} from 'src/models/MediaTypeModel'; +import {PREVIEW_MODAL_DEFAULT_OPTIONS, PreviewModalData, PreviewModalOptions} from '../utils/ModalHelper'; +import {CreateNoteOptions} from '../utils/Utils'; + +export class MediaDbPreviewModal extends Modal { + plugin: MediaDbPlugin; + + createNoteOptions: CreateNoteOptions; + elements: MediaTypeModel[]; + isBusy: boolean; + title: string; + cancelButton: ButtonComponent; + submitButton: ButtonComponent; + + submitCallback: (previewModalData: PreviewModalData) => void; + closeCallback: (err?: Error) => void; + + constructor(plugin: MediaDbPlugin, previewModalOptions: PreviewModalOptions) { + previewModalOptions = Object.assign({}, PREVIEW_MODAL_DEFAULT_OPTIONS, previewModalOptions); + + super(plugin.app); + + this.plugin = plugin; + this.title = previewModalOptions.modalTitle; + this.elements = previewModalOptions.elements; + this.createNoteOptions = previewModalOptions.createNoteOptions; + } + + setSubmitCallback(submitCallback: (previewModalData: PreviewModalData) => void): void { + this.submitCallback = submitCallback; + } + + setCloseCallback(closeCallback: (err?: Error) => void): void { + this.closeCallback = closeCallback; + } + + async preview(): Promise { + let {contentEl} = this; + contentEl.addClass('media-db-plugin-preview-modal'); + + contentEl.createEl('h2', {text: this.title}); + + const previewWrapper = contentEl.createDiv({cls: 'media-db-plugin-preview-wrapper'}); + + for (let result of this.elements) { + previewWrapper.createEl('h3', {text: result.englishTitle}); + const fileDiv = previewWrapper.createDiv(); + + let fileContent = await this.plugin.generateMediaDbNoteContents(result, this.createNoteOptions); + fileContent = `\n${fileContent}\n`; + + MarkdownRenderer.renderMarkdown(fileContent, fileDiv, null, null); + } + + contentEl.createDiv({cls: 'media-db-plugin-spacer'}); + + const bottomSettingRow = new Setting(contentEl); + bottomSettingRow.addButton(btn => { + btn.setButtonText('Cancel'); + btn.onClick(() => this.closeCallback()); + btn.buttonEl.addClass('media-db-plugin-button'); + this.cancelButton = btn; + }); + bottomSettingRow.addButton(btn => { + btn.setButtonText('Ok'); + btn.setCta(); + btn.onClick(() => this.submitCallback({confirmed: true})); + btn.buttonEl.addClass('media-db-plugin-button'); + this.submitButton = btn; + }); + } + + onOpen(): void { + this.preview(); + } + + onClose(): void { + this.closeCallback(); + } +} diff --git a/src/modals/SelectModal.ts b/src/modals/SelectModal.ts index 392d812..82bcccd 100644 --- a/src/modals/SelectModal.ts +++ b/src/modals/SelectModal.ts @@ -80,9 +80,8 @@ export abstract class SelectModal extends Modal { const {contentEl, titleEl} = this; titleEl.createEl('h2', {text: this.title}); - contentEl.createEl('p', {text: this.description}); - contentEl.addClass('media-db-plugin-select-modal'); + contentEl.createEl('p', {text: this.description}); this.elementWrapper = contentEl.createDiv({cls: 'media-db-plugin-select-wrapper'}); this.elementWrapper.tabIndex = 0; diff --git a/src/settings/PropertyMappingModelComponent.svelte b/src/settings/PropertyMappingModelComponent.svelte index a0a3b68..6fe5227 100644 --- a/src/settings/PropertyMappingModelComponent.svelte +++ b/src/settings/PropertyMappingModelComponent.svelte @@ -46,16 +46,16 @@
- { /if } - { /if } + { /if } + { /if } - { /each } + { /each } { #if !validationResult?.res }
{validationResult?.err?.message}
- { /if } + { /if }