Modal helper
This commit is contained in:
parent
25b899daa5
commit
5aa9108509
3 changed files with 169 additions and 144 deletions
|
|
@ -79,17 +79,16 @@ export class BoardGameGeekAPI extends APIModel {
|
||||||
const genres = Array.from(boardgame.querySelectorAll('boardgamecategory')).map(n => n!.textContent!);
|
const genres = Array.from(boardgame.querySelectorAll('boardgamecategory')).map(n => n!.textContent!);
|
||||||
|
|
||||||
const model = new BoardGameModel({
|
const model = new BoardGameModel({
|
||||||
type: MediaType.BoardGame,
|
|
||||||
title,
|
title,
|
||||||
englishTitle: title,
|
englishTitle: title,
|
||||||
year: year === '0' ? '' : year,
|
year: year === '0' ? '' : year,
|
||||||
dataSource: this.apiName,
|
dataSource: this.apiName,
|
||||||
url: `https://boardgamegeek.com/boardgame/${id}`,
|
url: `https://boardgamegeek.com/boardgame/${id}`,
|
||||||
id,
|
id: id,
|
||||||
|
|
||||||
genres,
|
genres: genres,
|
||||||
onlineRating,
|
onlineRating: onlineRating,
|
||||||
image,
|
image: image,
|
||||||
released: true,
|
released: true,
|
||||||
|
|
||||||
userData: {
|
userData: {
|
||||||
|
|
|
||||||
169
src/main.ts
169
src/main.ts
|
|
@ -4,10 +4,8 @@ import {APIManager} from './api/APIManager';
|
||||||
import {MediaTypeModel} from './models/MediaTypeModel';
|
import {MediaTypeModel} from './models/MediaTypeModel';
|
||||||
import {dateTimeToString, markdownTable, replaceIllegalFileNameCharactersInString, UserCancelError, UserSkipError} from './utils/Utils';
|
import {dateTimeToString, markdownTable, replaceIllegalFileNameCharactersInString, UserCancelError, UserSkipError} from './utils/Utils';
|
||||||
import {OMDbAPI} from './api/apis/OMDbAPI';
|
import {OMDbAPI} from './api/apis/OMDbAPI';
|
||||||
import {MediaDbAdvancedSearchModal} from './modals/MediaDbAdvancedSearchModal';
|
|
||||||
import {MediaDbSearchResultModal} from './modals/MediaDbSearchResultModal';
|
import {MediaDbSearchResultModal} from './modals/MediaDbSearchResultModal';
|
||||||
import {MALAPI} from './api/apis/MALAPI';
|
import {MALAPI} from './api/apis/MALAPI';
|
||||||
import {MediaDbIdSearchModal} from './modals/MediaDbIdSearchModal';
|
|
||||||
import {WikipediaAPI} from './api/apis/WikipediaAPI';
|
import {WikipediaAPI} from './api/apis/WikipediaAPI';
|
||||||
import {MusicBrainzAPI} from './api/apis/MusicBrainzAPI';
|
import {MusicBrainzAPI} from './api/apis/MusicBrainzAPI';
|
||||||
import {MediaTypeManager} from './utils/MediaTypeManager';
|
import {MediaTypeManager} from './utils/MediaTypeManager';
|
||||||
|
|
@ -17,12 +15,14 @@ import {PropertyMapper} from './settings/PropertyMapper';
|
||||||
import {YAMLConverter} from './utils/YAMLConverter';
|
import {YAMLConverter} from './utils/YAMLConverter';
|
||||||
import {MediaDbFolderImportModal} from './modals/MediaDbFolderImportModal';
|
import {MediaDbFolderImportModal} from './modals/MediaDbFolderImportModal';
|
||||||
import {PropertyMapping, PropertyMappingModel} from './settings/PropertyMapping';
|
import {PropertyMapping, PropertyMappingModel} from './settings/PropertyMapping';
|
||||||
|
import {ModalHelper} from './utils/ModalHelper';
|
||||||
|
|
||||||
export default class MediaDbPlugin extends Plugin {
|
export default class MediaDbPlugin extends Plugin {
|
||||||
settings: MediaDbPluginSettings;
|
settings: MediaDbPluginSettings;
|
||||||
apiManager: APIManager;
|
apiManager: APIManager;
|
||||||
mediaTypeManager: MediaTypeManager;
|
mediaTypeManager: MediaTypeManager;
|
||||||
modelPropertyMapper: PropertyMapper;
|
modelPropertyMapper: PropertyMapper;
|
||||||
|
modalHelper: ModalHelper;
|
||||||
|
|
||||||
frontMatterRexExpPattern: string = '^(---)\\n[\\s\\S]*?\\n---';
|
frontMatterRexExpPattern: string = '^(---)\\n[\\s\\S]*?\\n---';
|
||||||
|
|
||||||
|
|
@ -39,6 +39,7 @@ export default class MediaDbPlugin extends Plugin {
|
||||||
|
|
||||||
this.mediaTypeManager = new MediaTypeManager();
|
this.mediaTypeManager = new MediaTypeManager();
|
||||||
this.modelPropertyMapper = new PropertyMapper(this);
|
this.modelPropertyMapper = new PropertyMapper(this);
|
||||||
|
this.modalHelper = new ModalHelper(this);
|
||||||
|
|
||||||
await this.loadSettings();
|
await this.loadSettings();
|
||||||
// register the settings tab
|
// register the settings tab
|
||||||
|
|
@ -91,7 +92,7 @@ export default class MediaDbPlugin extends Plugin {
|
||||||
// register link insert command
|
// register link insert command
|
||||||
this.addCommand({
|
this.addCommand({
|
||||||
id: 'add-media-db-link',
|
id: 'add-media-db-link',
|
||||||
name: 'Add a link.',
|
name: 'Insert link',
|
||||||
checkCallback: (checking: boolean) => {
|
checkCallback: (checking: boolean) => {
|
||||||
if (!this.app.workspace.getActiveFile()) {
|
if (!this.app.workspace.getActiveFile()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -111,49 +112,24 @@ export default class MediaDbPlugin extends Plugin {
|
||||||
* - maybe custom link syntax
|
* - maybe custom link syntax
|
||||||
*/
|
*/
|
||||||
async createLinkWithSearchModal() {
|
async createLinkWithSearchModal() {
|
||||||
let results: MediaTypeModel[] = [];
|
|
||||||
|
|
||||||
const {advancedSearchOptions, advancedSearchModal} = await this.openMediaDbAdvancedSearchModal();
|
let apiSearchResults: MediaTypeModel[] = await this.modalHelper.openAdvancedSearchModal(async (advancedSearchOptions) => {
|
||||||
if (!advancedSearchOptions) {
|
return await this.apiManager.query(advancedSearchOptions.query, advancedSearchOptions.apis);
|
||||||
advancedSearchModal.close();
|
});
|
||||||
|
|
||||||
|
if (!apiSearchResults) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let apiSearchResults: MediaTypeModel[] = undefined;
|
const selectResults: MediaTypeModel[] = await this.modalHelper.openSelectModal(apiSearchResults, async (selectedMediaTypeModels) => {
|
||||||
try {
|
return await this.queryDetails(selectedMediaTypeModels);
|
||||||
apiSearchResults = await this.apiManager.query(advancedSearchOptions.query, advancedSearchOptions.apis);
|
});
|
||||||
} catch (e) {
|
|
||||||
console.warn(e);
|
if (!selectResults || selectResults.length < 1) {
|
||||||
new Notice(e.toString());
|
|
||||||
advancedSearchModal.close();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
advancedSearchModal.close();
|
const link = `[${selectResults[0].title}](${selectResults[0].url})`
|
||||||
|
|
||||||
const {selectRes, selectModal} = await this.openMediaDbSelectModal(apiSearchResults, false, false);
|
|
||||||
if (!selectRes) {
|
|
||||||
selectModal.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: let's try to not query details for this
|
|
||||||
try {
|
|
||||||
results = await this.queryDetails(selectRes);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn(e);
|
|
||||||
new Notice(e.toString());
|
|
||||||
selectModal.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
selectModal.close();
|
|
||||||
|
|
||||||
if (!results || results.length < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const link = `[${results[0].title}](${results[0].url})`
|
|
||||||
|
|
||||||
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
|
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||||
|
|
||||||
|
|
@ -171,71 +147,35 @@ export default class MediaDbPlugin extends Plugin {
|
||||||
* TODO: further refactor: extract it into own method, pass the action (api query) as lambda as well as an options object
|
* TODO: further refactor: extract it into own method, pass the action (api query) as lambda as well as an options object
|
||||||
*/
|
*/
|
||||||
async createEntryWithAdvancedSearchModal() {
|
async createEntryWithAdvancedSearchModal() {
|
||||||
let results: MediaTypeModel[] = [];
|
const apiSearchResults: MediaTypeModel[] = await this.modalHelper.openAdvancedSearchModal(async (advancedSearchOptions) => {
|
||||||
|
return await this.apiManager.query(advancedSearchOptions.query, advancedSearchOptions.apis);
|
||||||
|
});
|
||||||
|
|
||||||
const {advancedSearchOptions, advancedSearchModal} = await this.openMediaDbAdvancedSearchModal();
|
if (!apiSearchResults) {
|
||||||
if (!advancedSearchOptions) {
|
|
||||||
advancedSearchModal.close();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let apiSearchResults: MediaTypeModel[] = undefined;
|
const selectResults: MediaTypeModel[] = await this.modalHelper.openSelectModal(apiSearchResults, async (selectedMediaTypeModels) => {
|
||||||
try {
|
return await this.queryDetails(selectedMediaTypeModels);
|
||||||
apiSearchResults = await this.apiManager.query(advancedSearchOptions.query, advancedSearchOptions.apis);
|
});
|
||||||
} catch (e) {
|
|
||||||
console.warn(e);
|
if (!selectResults) {
|
||||||
new Notice(e.toString());
|
|
||||||
advancedSearchModal.close();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
advancedSearchModal.close();
|
await this.createMediaDbNotes(selectResults);
|
||||||
|
|
||||||
const {selectRes, selectModal} = await this.openMediaDbSelectModal(apiSearchResults, false);
|
|
||||||
if (!selectRes) {
|
|
||||||
selectModal.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
results = await this.queryDetails(selectRes);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn(e);
|
|
||||||
new Notice(e.toString());
|
|
||||||
selectModal.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
selectModal.close();
|
|
||||||
|
|
||||||
if (results) {
|
|
||||||
await this.createMediaDbNotes(results);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createEntryWithIdSearchModal() {
|
async createEntryWithIdSearchModal() {
|
||||||
let result: MediaTypeModel = undefined;
|
const idSearchResult: MediaTypeModel = await this.modalHelper.openIdSearchModal(async (idSearchOptions) => {
|
||||||
|
return await this.apiManager.queryDetailedInfoById(idSearchOptions.query, idSearchOptions.api);
|
||||||
|
})
|
||||||
|
|
||||||
const {idSearchOptions, idSearchModal} = await this.openMediaDbIdSearchModal();
|
if (!idSearchResult) {
|
||||||
if (!idSearchOptions) {
|
|
||||||
idSearchModal.close();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
await this.createMediaDbNoteFromModel(idSearchResult);
|
||||||
result = await this.apiManager.queryDetailedInfoById(idSearchOptions.query, idSearchOptions.api);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn(e);
|
|
||||||
new Notice(e.toString());
|
|
||||||
idSearchModal.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
idSearchModal.close();
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
await this.createMediaDbNoteFromModel(result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createMediaDbNotes(models: MediaTypeModel[], attachFile?: TFile): Promise<void> {
|
async createMediaDbNotes(models: MediaTypeModel[], attachFile?: TFile): Promise<void> {
|
||||||
|
|
@ -517,55 +457,6 @@ export default class MediaDbPlugin extends Plugin {
|
||||||
const targetFile = await this.app.vault.create(filePath, fileContent);
|
const targetFile = await this.app.vault.create(filePath, fileContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
async openMediaDbAdvancedSearchModal(): Promise<{ advancedSearchOptions: { query: string, apis: string[] }, advancedSearchModal: MediaDbAdvancedSearchModal }> {
|
|
||||||
const modal = new MediaDbAdvancedSearchModal(this);
|
|
||||||
const res: { query: string, apis: string[] } = await new Promise((resolve, reject) => {
|
|
||||||
modal.setSubmitCallback(res => resolve(res));
|
|
||||||
modal.setCloseCallback(err => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
resolve(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
modal.open();
|
|
||||||
});
|
|
||||||
return {advancedSearchOptions: res, advancedSearchModal: modal};
|
|
||||||
}
|
|
||||||
|
|
||||||
async openMediaDbIdSearchModal(): Promise<{ idSearchOptions: { query: string, api: string }, idSearchModal: MediaDbIdSearchModal }> {
|
|
||||||
const modal = new MediaDbIdSearchModal(this);
|
|
||||||
const res: { query: string, api: string } = await new Promise((resolve, reject) => {
|
|
||||||
modal.setSubmitCallback(res => resolve(res));
|
|
||||||
modal.setCloseCallback(err => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
resolve(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
modal.open();
|
|
||||||
});
|
|
||||||
return {idSearchOptions: res, idSearchModal: modal};
|
|
||||||
}
|
|
||||||
|
|
||||||
async openMediaDbSelectModal(resultsToDisplay: MediaTypeModel[], skipButton: boolean = false, allowMultiSelect: boolean = true): Promise<{ selectRes: MediaTypeModel[], selectModal: MediaDbSearchResultModal }> {
|
|
||||||
const modal = new MediaDbSearchResultModal(this, resultsToDisplay, skipButton, allowMultiSelect);
|
|
||||||
const res: MediaTypeModel[] = await new Promise((resolve, reject) => {
|
|
||||||
modal.setSubmitCallback(res => resolve(res));
|
|
||||||
modal.setSkipCallback(() => resolve([]));
|
|
||||||
modal.setCloseCallback(err => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
resolve(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
modal.open();
|
|
||||||
});
|
|
||||||
return {selectRes: res, selectModal: modal};
|
|
||||||
}
|
|
||||||
|
|
||||||
async loadSettings() {
|
async loadSettings() {
|
||||||
// console.log(DEFAULT_SETTINGS);
|
// console.log(DEFAULT_SETTINGS);
|
||||||
const diskSettings: MediaDbPluginSettings = await this.loadData();
|
const diskSettings: MediaDbPluginSettings = await this.loadData();
|
||||||
|
|
|
||||||
135
src/utils/ModalHelper.ts
Normal file
135
src/utils/ModalHelper.ts
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
import {MediaDbAdvancedSearchModal} from '../modals/MediaDbAdvancedSearchModal';
|
||||||
|
import {MediaDbIdSearchModal} from '../modals/MediaDbIdSearchModal';
|
||||||
|
import {MediaTypeModel} from '../models/MediaTypeModel';
|
||||||
|
import {MediaDbSearchResultModal} from '../modals/MediaDbSearchResultModal';
|
||||||
|
import {Notice} from 'obsidian';
|
||||||
|
import MediaDbPlugin from '../main';
|
||||||
|
|
||||||
|
interface AdvancedSearchOptions {
|
||||||
|
query: string,
|
||||||
|
apis: string[],
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IdSearchOptions {
|
||||||
|
query: string,
|
||||||
|
api: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ModalHelper {
|
||||||
|
plugin: MediaDbPlugin;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(plugin: MediaDbPlugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
async createAdvancedSearchModal(): Promise<{ advancedSearchOptions: AdvancedSearchOptions, advancedSearchModal: MediaDbAdvancedSearchModal }> {
|
||||||
|
const modal = new MediaDbAdvancedSearchModal(this.plugin);
|
||||||
|
const res: { query: string, apis: string[] } = await new Promise((resolve, reject) => {
|
||||||
|
modal.setSubmitCallback(res => resolve(res));
|
||||||
|
modal.setCloseCallback(err => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
resolve(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
modal.open();
|
||||||
|
});
|
||||||
|
return {advancedSearchOptions: res, advancedSearchModal: modal};
|
||||||
|
}
|
||||||
|
|
||||||
|
async openAdvancedSearchModal<T>(submitCallback: (advancedSearchOptions: AdvancedSearchOptions) => Promise<T>): Promise<T> {
|
||||||
|
const {advancedSearchOptions, advancedSearchModal} = await this.createAdvancedSearchModal();
|
||||||
|
if (!advancedSearchOptions) {
|
||||||
|
advancedSearchModal.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let callbackRes: T;
|
||||||
|
callbackRes = await submitCallback(advancedSearchOptions);
|
||||||
|
advancedSearchModal.close();
|
||||||
|
return callbackRes;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e);
|
||||||
|
new Notice(e.toString());
|
||||||
|
advancedSearchModal.close();
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async createIdSearchModal(): Promise<{ idSearchOptions: { query: string, api: string }, idSearchModal: MediaDbIdSearchModal }> {
|
||||||
|
const modal = new MediaDbIdSearchModal(this.plugin);
|
||||||
|
const res: { query: string, api: string } = await new Promise((resolve, reject) => {
|
||||||
|
modal.setSubmitCallback(res => resolve(res));
|
||||||
|
modal.setCloseCallback(err => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
resolve(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
modal.open();
|
||||||
|
});
|
||||||
|
return {idSearchOptions: res, idSearchModal: modal};
|
||||||
|
}
|
||||||
|
|
||||||
|
async openIdSearchModal<T>(submitCallback: (idSearchOptions: IdSearchOptions) => Promise<T>): Promise<T> {
|
||||||
|
const {idSearchOptions, idSearchModal} = await this.createIdSearchModal();
|
||||||
|
if (!idSearchOptions) {
|
||||||
|
idSearchModal.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let callbackRes: T;
|
||||||
|
callbackRes = await submitCallback(idSearchOptions);
|
||||||
|
idSearchModal.close();
|
||||||
|
return callbackRes;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e);
|
||||||
|
new Notice(e.toString());
|
||||||
|
idSearchModal.close();
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async createSelectModal(resultsToDisplay: MediaTypeModel[], skipButton: boolean = false, allowMultiSelect: boolean = true): Promise<{ selectRes: MediaTypeModel[], selectModal: MediaDbSearchResultModal }> {
|
||||||
|
const modal = new MediaDbSearchResultModal(this.plugin, resultsToDisplay, skipButton, allowMultiSelect);
|
||||||
|
const res: MediaTypeModel[] = await new Promise((resolve, reject) => {
|
||||||
|
modal.setSubmitCallback(res => resolve(res));
|
||||||
|
modal.setSkipCallback(() => resolve([]));
|
||||||
|
modal.setCloseCallback(err => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
resolve(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
modal.open();
|
||||||
|
});
|
||||||
|
return {selectRes: res, selectModal: modal};
|
||||||
|
}
|
||||||
|
|
||||||
|
async openSelectModal(mediaModels: MediaTypeModel[], submitCallback: (selectedMediaTypeModels: MediaTypeModel[]) => Promise<MediaTypeModel[]>): Promise<MediaTypeModel[]> {
|
||||||
|
const {selectRes, selectModal} = await this.createSelectModal(mediaModels, false);
|
||||||
|
if (!selectRes) {
|
||||||
|
selectModal.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let callbackRes: MediaTypeModel[];
|
||||||
|
callbackRes = await submitCallback(selectRes);
|
||||||
|
selectModal.close();
|
||||||
|
return callbackRes;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e);
|
||||||
|
new Notice(e.toString());
|
||||||
|
selectModal.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue