Some more modal changes (look at those doc comments :o)
How did this work the first time i tested it???
This commit is contained in:
parent
db4a6c98a3
commit
a3905daf5b
8 changed files with 374 additions and 160 deletions
|
|
@ -5,16 +5,135 @@ import {MediaDbSearchResultModal} from '../modals/MediaDbSearchResultModal';
|
|||
import {Notice} from 'obsidian';
|
||||
import MediaDbPlugin from '../main';
|
||||
|
||||
interface AdvancedSearchOptions {
|
||||
|
||||
export enum ModalResultCode {
|
||||
SUCCESS,
|
||||
SKIP,
|
||||
CLOSE,
|
||||
ERROR,
|
||||
}
|
||||
|
||||
/**
|
||||
* Object containing the data {@link ModalHelper.createAdvancedSearchModal} returns.
|
||||
* On {@link ModalResultCode.SUCCESS} this contains {@link AdvancedSearchModalData}.
|
||||
* On {@link ModalResultCode.ERROR} this contains a reference to that error.
|
||||
*/
|
||||
export interface AdvancedSearchModalResult {
|
||||
code: ModalResultCode.SUCCESS | ModalResultCode.CLOSE | ModalResultCode.ERROR,
|
||||
data?: AdvancedSearchModalData,
|
||||
error?: Error,
|
||||
}
|
||||
|
||||
/**
|
||||
* Object containing the data {@link ModalHelper.createIdSearchModal} returns.
|
||||
* On {@link ModalResultCode.SUCCESS} this contains {@link IdSearchModalData}.
|
||||
* On {@link ModalResultCode.ERROR} this contains a reference to that error.
|
||||
*/
|
||||
export interface IdSearchModalResult {
|
||||
code: ModalResultCode.SUCCESS | ModalResultCode.CLOSE | ModalResultCode.ERROR,
|
||||
data?: IdSearchModalData,
|
||||
error?: Error,
|
||||
}
|
||||
|
||||
/**
|
||||
* Object containing the data {@link ModalHelper.createSelectModal} returns.
|
||||
* On {@link ModalResultCode.SUCCESS} this contains {@link SelectModalData}.
|
||||
* On {@link ModalResultCode.ERROR} this contains a reference to that error.
|
||||
*/
|
||||
export interface SelectModalResult {
|
||||
code: ModalResultCode.SUCCESS | ModalResultCode.CLOSE | ModalResultCode.SKIP | ModalResultCode.ERROR,
|
||||
data?: SelectModalData,
|
||||
error?: Error,
|
||||
}
|
||||
|
||||
/**
|
||||
* The data the advanced search modal returns.
|
||||
* query: the query string
|
||||
* apis: the selected APIs
|
||||
*/
|
||||
export interface AdvancedSearchModalData {
|
||||
query: string,
|
||||
apis: string[],
|
||||
}
|
||||
|
||||
interface IdSearchOptions {
|
||||
/**
|
||||
* The data the id search modal returns.
|
||||
* query: the query string
|
||||
* apis: the selected APIs
|
||||
*/
|
||||
export interface IdSearchModalData {
|
||||
query: string,
|
||||
api: string,
|
||||
}
|
||||
|
||||
/**
|
||||
* The data the select modal returns.
|
||||
* selected: the selected items
|
||||
*/
|
||||
export interface SelectModalData {
|
||||
selected: MediaTypeModel[],
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for the advanced search modal.
|
||||
* modalTitle: the title of the modal
|
||||
* preselectedAPIs: a list of preselected APIs
|
||||
* prefilledSearchString: prefilled query
|
||||
*/
|
||||
export interface AdvancedSearchModalOptions {
|
||||
modalTitle?: string,
|
||||
preselectedAPIs?: string[],
|
||||
prefilledSearchString?: string,
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for the id search modal.
|
||||
* modalTitle: the title of the modal
|
||||
* preselectedAPIs: a list of preselected APIs
|
||||
* prefilledSearchString: prefilled query
|
||||
*/
|
||||
export interface IdSearchModalOptions {
|
||||
modalTitle?: string,
|
||||
preselectedAPI?: string,
|
||||
prefilledSearchString?: string,
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for the select modal.
|
||||
* modalTitle: the title of the modal
|
||||
* elements: the elements the user can select from
|
||||
* multiSelect: whether to allow multiselect
|
||||
* skipButton: whether to add a skip button to the modal
|
||||
*/
|
||||
export interface SelectModalOptions {
|
||||
modalTitle?: string,
|
||||
elements?: MediaTypeModel[],
|
||||
multiSelect?: boolean,
|
||||
skipButton?: boolean,
|
||||
}
|
||||
|
||||
export const ADVANCED_SEARCH_MODAL_DEFAULT_OPTIONS: AdvancedSearchModalOptions = {
|
||||
modalTitle: 'Media DB Advanced Search',
|
||||
preselectedAPIs: [],
|
||||
prefilledSearchString: '',
|
||||
};
|
||||
|
||||
export const ID_SEARCH_MODAL_DEFAULT_OPTIONS: IdSearchModalOptions = {
|
||||
modalTitle: 'Media DB Id Search',
|
||||
preselectedAPI: '',
|
||||
prefilledSearchString: '',
|
||||
};
|
||||
|
||||
export const SELECT_MODAL_OPTIONS_DEFAULT: SelectModalOptions = {
|
||||
modalTitle: 'Media DB Search Results',
|
||||
elements: [],
|
||||
multiSelect: true,
|
||||
skipButton: false,
|
||||
};
|
||||
|
||||
/**
|
||||
* A class providing multiple usefull functions for dealing with the plugins modals.
|
||||
*/
|
||||
export class ModalHelper {
|
||||
plugin: MediaDbPlugin;
|
||||
|
||||
|
|
@ -23,105 +142,185 @@ export class ModalHelper {
|
|||
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));
|
||||
/**
|
||||
* Creates an {@link MediaDbAdvancedSearchModal}, then sets callbacks and awaits them,
|
||||
* returning either the user input once submitted or nothing once closed.
|
||||
* The modal needs ot be manually closed by calling `close()` on the modal reference.
|
||||
*
|
||||
* @param advancedSearchModalOptions the options for the modal, see {@link ADVANCED_SEARCH_MODAL_DEFAULT_OPTIONS}
|
||||
* @returns the user input or nothing and a reference to the modal.
|
||||
*/
|
||||
async createAdvancedSearchModal(advancedSearchModalOptions: AdvancedSearchModalOptions): Promise<{ advancedSearchModalResult: AdvancedSearchModalResult, advancedSearchModal: MediaDbAdvancedSearchModal }> {
|
||||
const modal = new MediaDbAdvancedSearchModal(this.plugin, advancedSearchModalOptions);
|
||||
const res: AdvancedSearchModalResult = await new Promise((resolve, reject) => {
|
||||
modal.setSubmitCallback(res => resolve({code: ModalResultCode.SUCCESS, data: res}));
|
||||
modal.setCloseCallback(err => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
resolve({code: ModalResultCode.ERROR, error: err});
|
||||
}
|
||||
resolve(undefined);
|
||||
resolve({code: ModalResultCode.CLOSE});
|
||||
});
|
||||
|
||||
modal.open();
|
||||
});
|
||||
return {advancedSearchOptions: res, advancedSearchModal: modal};
|
||||
return {advancedSearchModalResult: res, advancedSearchModal: modal};
|
||||
}
|
||||
|
||||
async openAdvancedSearchModal<T>(submitCallback: (advancedSearchOptions: AdvancedSearchOptions) => Promise<T>): Promise<T> {
|
||||
const {advancedSearchOptions, advancedSearchModal} = await this.createAdvancedSearchModal();
|
||||
if (!advancedSearchOptions) {
|
||||
advancedSearchModal.close();
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Opens an {@link MediaDbAdvancedSearchModal} and awaits its result,
|
||||
* then executes the `submitCallback` returning the callbacks result and closing the modal.
|
||||
*
|
||||
* @param advancedSearchModalOptions the options for the modal, see {@link ADVANCED_SEARCH_MODAL_DEFAULT_OPTIONS}
|
||||
* @param submitCallback the callback that gets executed after the modal has been submitted, but after it has been closed
|
||||
* @returns the user input or nothing and a reference to the modal.
|
||||
*/
|
||||
async openAdvancedSearchModal(advancedSearchModalOptions: AdvancedSearchModalOptions, submitCallback: (advancedSearchModalData: AdvancedSearchModalData) => Promise<MediaTypeModel[]>): Promise<MediaTypeModel[]> {
|
||||
const {advancedSearchModalResult, advancedSearchModal} = await this.createAdvancedSearchModal(advancedSearchModalOptions);
|
||||
|
||||
try {
|
||||
let callbackRes: T;
|
||||
callbackRes = await submitCallback(advancedSearchOptions);
|
||||
advancedSearchModal.close();
|
||||
return callbackRes;
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
new Notice(e.toString());
|
||||
if (advancedSearchModalResult.code === ModalResultCode.ERROR) {
|
||||
// there was an error in the modal itself
|
||||
console.warn(advancedSearchModalResult.error);
|
||||
new Notice(advancedSearchModalResult.error.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();
|
||||
if (advancedSearchModalResult.code === ModalResultCode.CLOSE) {
|
||||
// modal is already being closed
|
||||
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);
|
||||
callbackRes = await submitCallback(advancedSearchModalResult.data);
|
||||
advancedSearchModal.close();
|
||||
return callbackRes;
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
new Notice(e.toString());
|
||||
advancedSearchModal.close();
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link MediaDbIdSearchModal}, then sets callbacks and awaits them,
|
||||
* returning either the user input once submitted or nothing once closed.
|
||||
* The modal needs ot be manually closed by calling `close()` on the modal reference.
|
||||
*
|
||||
* @param idSearchModalOptions the options for the modal, see {@link ID_SEARCH_MODAL_DEFAULT_OPTIONS}
|
||||
* @returns the user input or nothing and a reference to the modal.
|
||||
*/
|
||||
async createIdSearchModal(idSearchModalOptions: IdSearchModalOptions): Promise<{ idSearchModalResult: IdSearchModalResult, idSearchModal: MediaDbIdSearchModal }> {
|
||||
const modal = new MediaDbIdSearchModal(this.plugin, idSearchModalOptions);
|
||||
const res: IdSearchModalResult = await new Promise((resolve, reject) => {
|
||||
modal.setSubmitCallback(res => resolve({code: ModalResultCode.SUCCESS, data: res}));
|
||||
modal.setCloseCallback(err => {
|
||||
if (err) {
|
||||
resolve({code: ModalResultCode.ERROR, error: err});
|
||||
}
|
||||
resolve({code: ModalResultCode.CLOSE});
|
||||
});
|
||||
|
||||
modal.open();
|
||||
});
|
||||
return {idSearchModalResult: res, idSearchModal: modal};
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens an {@link MediaDbIdSearchModal} and awaits its result,
|
||||
* then executes the `submitCallback` returning the callbacks result and closing the modal.
|
||||
*
|
||||
* @param idSearchModalOptions the options for the modal, see {@link ID_SEARCH_MODAL_DEFAULT_OPTIONS}
|
||||
* @param submitCallback the callback that gets executed after the modal has been submitted, but after it has been closed
|
||||
* @returns the user input or nothing and a reference to the modal.
|
||||
*/
|
||||
async openIdSearchModal(idSearchModalOptions: IdSearchModalOptions, submitCallback: (idSearchModalData: IdSearchModalData) => Promise<MediaTypeModel>): Promise<MediaTypeModel> {
|
||||
const {idSearchModalResult, idSearchModal} = await this.createIdSearchModal(idSearchModalOptions);
|
||||
|
||||
if (idSearchModalResult.code === ModalResultCode.ERROR) {
|
||||
// there was an error in the modal itself
|
||||
console.warn(idSearchModalResult.error);
|
||||
new Notice(idSearchModalResult.error.toString());
|
||||
idSearchModal.close();
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (idSearchModalResult.code === ModalResultCode.CLOSE) {
|
||||
// modal is already being closed
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
let callbackRes: MediaTypeModel;
|
||||
callbackRes = await submitCallback(idSearchModalResult.data);
|
||||
idSearchModal.close();
|
||||
return callbackRes;
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
new Notice(e.toString());
|
||||
idSearchModal.close();
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link MediaDbSearchResultModal}, then sets callbacks and awaits them,
|
||||
* returning either the user input once submitted or nothing once closed.
|
||||
* The modal needs ot be manually closed by calling `close()` on the modal reference.
|
||||
*
|
||||
* @param selectModalOptions the options for the modal, see {@link SELECT_MODAL_OPTIONS_DEFAULT}
|
||||
* @returns the user input or nothing and a reference to the modal.
|
||||
*/
|
||||
async createSelectModal(selectModalOptions: SelectModalOptions): Promise<{ selectModalResult: SelectModalResult, selectModal: MediaDbSearchResultModal }> {
|
||||
const modal = new MediaDbSearchResultModal(this.plugin, selectModalOptions);
|
||||
const res: SelectModalResult = await new Promise((resolve, reject) => {
|
||||
modal.setSubmitCallback(res => resolve({code: ModalResultCode.SUCCESS, data: res}));
|
||||
modal.setSkipCallback(() => resolve({code: ModalResultCode.SKIP}));
|
||||
modal.setCloseCallback(err => {
|
||||
if (err) {
|
||||
resolve({code: ModalResultCode.ERROR, error: err});
|
||||
}
|
||||
resolve({code: ModalResultCode.CLOSE});
|
||||
});
|
||||
|
||||
modal.open();
|
||||
});
|
||||
return {selectModalResult: res, selectModal: modal};
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens an {@link MediaDbSearchResultModal} and awaits its result,
|
||||
* then executes the `submitCallback` returning the callbacks result and closing the modal.
|
||||
*
|
||||
* @param selectModalOptions the options for the modal, see {@link SELECT_MODAL_OPTIONS_DEFAULT}
|
||||
* @param submitCallback the callback that gets executed after the modal has been submitted, but after it has been closed
|
||||
* @returns the user input or nothing and a reference to the modal.
|
||||
*/
|
||||
async openSelectModal(selectModalOptions: SelectModalOptions, submitCallback: (selectModalData: SelectModalData) => Promise<MediaTypeModel[]>): Promise<MediaTypeModel[]> {
|
||||
const {selectModalResult, selectModal} = await this.createSelectModal(selectModalOptions);
|
||||
|
||||
if (selectModalResult.code === ModalResultCode.ERROR) {
|
||||
// there was an error in the modal itself
|
||||
console.warn(selectModalResult.error);
|
||||
new Notice(selectModalResult.error.toString());
|
||||
selectModal.close();
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (selectModalResult.code === ModalResultCode.CLOSE) {
|
||||
// modal is already being closed
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (selectModalResult.code === ModalResultCode.SKIP) {
|
||||
// selection was skipped
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
let callbackRes: MediaTypeModel[];
|
||||
callbackRes = await submitCallback(selectModalResult.data);
|
||||
selectModal.close();
|
||||
return callbackRes;
|
||||
} catch (e) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue