Skip to content

Commit a3905da

Browse files
committed
Some more modal changes (look at those doc comments :o)
How did this work the first time i tested it???
1 parent db4a6c9 commit a3905da

8 files changed

+334
-120
lines changed

src/api/apis/BoardGameGeekAPI.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import MediaDbPlugin from '../../main';
44
import {BoardGameModel} from 'src/models/BoardGameModel';
55
import {debugLog} from '../../utils/Utils';
66
import {requestUrl} from 'obsidian';
7-
import {MediaType} from '../../utils/MediaType';
87

98
export class BoardGameGeekAPI extends APIModel {
109
plugin: MediaDbPlugin;

src/main.ts

Lines changed: 42 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ import {MarkdownView, Notice, parseYaml, Plugin, stringifyYaml, TFile, TFolder}
22
import {getDefaultSettings, MediaDbPluginSettings, MediaDbSettingTab} from './settings/Settings';
33
import {APIManager} from './api/APIManager';
44
import {MediaTypeModel} from './models/MediaTypeModel';
5-
import {dateTimeToString, markdownTable, replaceIllegalFileNameCharactersInString, UserCancelError, UserSkipError} from './utils/Utils';
5+
import {dateTimeToString, markdownTable, replaceIllegalFileNameCharactersInString} from './utils/Utils';
66
import {OMDbAPI} from './api/apis/OMDbAPI';
7-
import {MediaDbSearchResultModal} from './modals/MediaDbSearchResultModal';
87
import {MALAPI} from './api/apis/MALAPI';
98
import {WikipediaAPI} from './api/apis/WikipediaAPI';
109
import {MusicBrainzAPI} from './api/apis/MusicBrainzAPI';
@@ -15,7 +14,7 @@ import {PropertyMapper} from './settings/PropertyMapper';
1514
import {YAMLConverter} from './utils/YAMLConverter';
1615
import {MediaDbFolderImportModal} from './modals/MediaDbFolderImportModal';
1716
import {PropertyMapping, PropertyMappingModel} from './settings/PropertyMapping';
18-
import {ModalHelper} from './utils/ModalHelper';
17+
import {ModalHelper, ModalResultCode} from './utils/ModalHelper';
1918

2019
export default class MediaDbPlugin extends Plugin {
2120
settings: MediaDbPluginSettings;
@@ -126,23 +125,23 @@ export default class MediaDbPlugin extends Plugin {
126125
*/
127126
async createLinkWithSearchModal() {
128127

129-
let apiSearchResults: MediaTypeModel[] = await this.modalHelper.openAdvancedSearchModal(async (advancedSearchOptions) => {
130-
return await this.apiManager.query(advancedSearchOptions.query, advancedSearchOptions.apis);
128+
let apiSearchResults: MediaTypeModel[] = await this.modalHelper.openAdvancedSearchModal({}, async (advancedSearchModalData) => {
129+
return await this.apiManager.query(advancedSearchModalData.query, advancedSearchModalData.apis);
131130
});
132131

133132
if (!apiSearchResults) {
134133
return;
135134
}
136135

137-
const selectResults: MediaTypeModel[] = await this.modalHelper.openSelectModal(apiSearchResults, async (selectedMediaTypeModels) => {
138-
return await this.queryDetails(selectedMediaTypeModels);
136+
const selectResults: MediaTypeModel[] = await this.modalHelper.openSelectModal({elements: apiSearchResults, multiSelect: false}, async (selectModalData) => {
137+
return await this.queryDetails(selectModalData.selected);
139138
});
140139

141140
if (!selectResults || selectResults.length < 1) {
142141
return;
143142
}
144143

145-
const link = `[${selectResults[0].title}](${selectResults[0].url})`
144+
const link = `[${selectResults[0].title}](${selectResults[0].url})`;
146145

147146
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
148147

@@ -160,16 +159,16 @@ export default class MediaDbPlugin extends Plugin {
160159
* TODO: further refactor: extract it into own method, pass the action (api query) as lambda as well as an options object
161160
*/
162161
async createEntryWithAdvancedSearchModal() {
163-
const apiSearchResults: MediaTypeModel[] = await this.modalHelper.openAdvancedSearchModal(async (advancedSearchOptions) => {
164-
return await this.apiManager.query(advancedSearchOptions.query, advancedSearchOptions.apis);
162+
let apiSearchResults: MediaTypeModel[] = await this.modalHelper.openAdvancedSearchModal({}, async (advancedSearchModalData) => {
163+
return await this.apiManager.query(advancedSearchModalData.query, advancedSearchModalData.apis);
165164
});
166165

167166
if (!apiSearchResults) {
168167
return;
169168
}
170169

171-
const selectResults: MediaTypeModel[] = await this.modalHelper.openSelectModal(apiSearchResults, async (selectedMediaTypeModels) => {
172-
return await this.queryDetails(selectedMediaTypeModels);
170+
const selectResults: MediaTypeModel[] = await this.modalHelper.openSelectModal({elements: apiSearchResults}, async (selectModalData) => {
171+
return await this.queryDetails(selectModalData.selected);
173172
});
174173

175174
if (!selectResults) {
@@ -180,9 +179,9 @@ export default class MediaDbPlugin extends Plugin {
180179
}
181180

182181
async createEntryWithIdSearchModal() {
183-
const idSearchResult: MediaTypeModel = await this.modalHelper.openIdSearchModal(async (idSearchOptions) => {
184-
return await this.apiManager.queryDetailedInfoById(idSearchOptions.query, idSearchOptions.api);
185-
})
182+
const idSearchResult: MediaTypeModel = await this.modalHelper.openIdSearchModal({}, async (idSearchModalData) => {
183+
return await this.apiManager.queryDetailedInfoById(idSearchModalData.query, idSearchModalData.api);
184+
});
186185

187186
if (!idSearchResult) {
188187
return;
@@ -210,7 +209,7 @@ export default class MediaDbPlugin extends Plugin {
210209
return detailModels;
211210
}
212211

213-
async createMediaDbNoteFromModel(mediaTypeModel: MediaTypeModel, options: {attachTemplate?: boolean, attachFile?: TFile, openNote?: boolean}): Promise<void> {
212+
async createMediaDbNoteFromModel(mediaTypeModel: MediaTypeModel, options: { attachTemplate?: boolean, attachFile?: TFile, openNote?: boolean }): Promise<void> {
214213
try {
215214
console.debug('MDB | creating new note');
216215

@@ -223,12 +222,15 @@ export default class MediaDbPlugin extends Plugin {
223222
}
224223
}
225224

226-
private async generateMediaDbNoteContents(mediaTypeModel: MediaTypeModel, options: {attachTemplate?: boolean, attachFile?: TFile}) {
225+
private async generateMediaDbNoteContents(mediaTypeModel: MediaTypeModel, options: { attachTemplate?: boolean, attachFile?: TFile }) {
227226
let fileMetadata = this.modelPropertyMapper.convertObject(mediaTypeModel.toMetaDataObject());
228227
let fileContent = '';
229228

230229
({fileMetadata, fileContent} = await this.attachFile(fileMetadata, fileContent, options.attachFile));
231-
({fileMetadata, fileContent} = await this.attachTemplate(fileMetadata, fileContent, options.attachTemplate ? await this.mediaTypeManager.getTemplate(mediaTypeModel, this.app) : ''));
230+
({
231+
fileMetadata,
232+
fileContent,
233+
} = await this.attachTemplate(fileMetadata, fileContent, options.attachTemplate ? await this.mediaTypeManager.getTemplate(mediaTypeModel, this.app) : ''));
232234

233235
fileContent = `---\n${this.settings.useCustomYamlStringifier ? YAMLConverter.toYaml(fileMetadata) : stringifyYaml(fileMetadata)}---\n` + fileContent;
234236
return fileContent;
@@ -417,46 +419,36 @@ export default class MediaDbPlugin extends Plugin {
417419
continue;
418420
}
419421

420-
let selectedResults: MediaTypeModel[] = [];
421-
const modal = new MediaDbSearchResultModal(this, results, true);
422-
try {
423-
selectedResults = await new Promise((resolve, reject) => {
424-
modal.title = `Results for \'${title}\'`;
425-
modal.setSubmitCallback(res => resolve(res));
426-
modal.setSkipCallback(() => reject(new UserCancelError('user skipped')));
427-
modal.setCloseCallback(err => {
428-
if (err) {
429-
reject(err);
430-
}
431-
reject(new UserCancelError('user canceled'));
432-
});
433-
434-
modal.open();
435-
});
436-
} catch (e) {
437-
modal.close();
438-
if (e instanceof UserCancelError) {
439-
erroredFiles.push({filePath: file.path, error: e.message});
440-
canceled = true;
441-
continue;
442-
} else if (e instanceof UserSkipError) {
443-
erroredFiles.push({filePath: file.path, error: e.message});
444-
continue;
445-
} else {
446-
erroredFiles.push({filePath: file.path, error: e.message});
447-
continue;
448-
}
422+
let {selectModalResult, selectModal} = await this.modalHelper.createSelectModal({elements: results, skipButton: true, modalTitle: `Results for \'${title}\'`});
423+
424+
if (selectModalResult.code === ModalResultCode.ERROR) {
425+
erroredFiles.push({filePath: file.path, error: selectModalResult.error.message});
426+
selectModal.close();
427+
continue;
428+
}
429+
430+
if (selectModalResult.code === ModalResultCode.CLOSE) {
431+
erroredFiles.push({filePath: file.path, error: 'user canceled'});
432+
selectModal.close();
433+
canceled = true;
434+
continue;
435+
}
436+
437+
if (selectModalResult.code === ModalResultCode.SKIP) {
438+
erroredFiles.push({filePath: file.path, error: 'user skipped'});
439+
selectModal.close();
440+
continue;
449441
}
450442

451-
if (selectedResults.length === 0) {
443+
if (selectModalResult.data.selected.length === 0) {
452444
erroredFiles.push({filePath: file.path, error: `no search results selected`});
453445
continue;
454446
}
455447

456-
const detailedResults = await this.queryDetails(selectedResults);
448+
const detailedResults = await this.queryDetails(selectModalResult.data.selected);
457449
await this.createMediaDbNotes(detailedResults, appendContent ? file : null);
458450

459-
modal.close();
451+
selectModal.close();
460452
}
461453
}
462454

src/modals/MediaDbAdvancedSearchModal.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
11
import {ButtonComponent, Modal, Notice, Setting, TextComponent, ToggleComponent} from 'obsidian';
22
import {MediaTypeModel} from '../models/MediaTypeModel';
33
import MediaDbPlugin from '../main';
4+
import {ADVANCED_SEARCH_MODAL_DEFAULT_OPTIONS, AdvancedSearchModalData, AdvancedSearchModalOptions} from '../utils/ModalHelper';
45

56
export class MediaDbAdvancedSearchModal extends Modal {
7+
plugin: MediaDbPlugin;
8+
69
query: string;
710
isBusy: boolean;
8-
plugin: MediaDbPlugin;
9-
searchBtn: ButtonComponent;
11+
title: string;
1012
selectedApis: { name: string, selected: boolean }[];
11-
submitCallback?: (res: { query: string, apis: string[] }) => void;
13+
14+
searchBtn: ButtonComponent;
15+
16+
submitCallback?: (res: AdvancedSearchModalData) => void;
1217
closeCallback?: (err?: Error) => void;
1318

14-
constructor(plugin: MediaDbPlugin) {
19+
20+
constructor(plugin: MediaDbPlugin, advancedSearchModalOptions: AdvancedSearchModalOptions) {
21+
advancedSearchModalOptions = Object.assign({}, ADVANCED_SEARCH_MODAL_DEFAULT_OPTIONS, advancedSearchModalOptions);
1522
super(plugin.app);
23+
1624
this.plugin = plugin;
1725
this.selectedApis = [];
26+
this.title = advancedSearchModalOptions.modalTitle;
27+
this.query = advancedSearchModalOptions.prefilledSearchString;
28+
1829
for (const api of this.plugin.apiManager.apis) {
19-
this.selectedApis.push({name: api.apiName, selected: false});
30+
this.selectedApis.push({name: api.apiName, selected: advancedSearchModalOptions.preselectedAPIs.contains(api.apiName)});
2031
}
2132
}
2233

23-
setSubmitCallback(submitCallback: (res: { query: string, apis: string[] }) => void): void {
34+
setSubmitCallback(submitCallback: (res: AdvancedSearchModalData) => void): void {
2435
this.submitCallback = submitCallback;
2536
}
2637

@@ -59,12 +70,13 @@ export class MediaDbAdvancedSearchModal extends Modal {
5970
onOpen() {
6071
const {contentEl} = this;
6172

62-
contentEl.createEl('h2', {text: 'Search media db'});
73+
contentEl.createEl('h2', {text: this.title});
6374

6475
const placeholder = 'Search by title';
6576
const searchComponent = new TextComponent(contentEl);
6677
searchComponent.inputEl.style.width = '100%';
6778
searchComponent.setPlaceholder(placeholder);
79+
searchComponent.setValue(this.query);
6880
searchComponent.onChange(value => (this.query = value));
6981
searchComponent.inputEl.addEventListener('keydown', this.keyPressCallback.bind(this));
7082

src/modals/MediaDbIdSearchModal.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
11
import {ButtonComponent, DropdownComponent, Modal, Notice, Setting, TextComponent} from 'obsidian';
22
import {MediaTypeModel} from '../models/MediaTypeModel';
33
import MediaDbPlugin from '../main';
4+
import {ID_SEARCH_MODAL_DEFAULT_OPTIONS, IdSearchModalData, IdSearchModalOptions} from '../utils/ModalHelper';
45

56
export class MediaDbIdSearchModal extends Modal {
7+
plugin: MediaDbPlugin;
8+
69
query: string;
710
isBusy: boolean;
8-
plugin: MediaDbPlugin;
9-
searchBtn: ButtonComponent;
11+
title: string;
1012
selectedApi: string;
11-
submitCallback?: (res: { query: string, api: string }, err?: Error) => void;
13+
14+
searchBtn: ButtonComponent;
15+
16+
submitCallback?: (res: IdSearchModalData, err?: Error) => void;
1217
closeCallback?: (err?: Error) => void;
1318

14-
constructor(plugin: MediaDbPlugin) {
19+
20+
constructor(plugin: MediaDbPlugin, idSearchModalOptions: IdSearchModalOptions) {
21+
idSearchModalOptions = Object.assign({}, ID_SEARCH_MODAL_DEFAULT_OPTIONS, idSearchModalOptions);
1522
super(plugin.app);
23+
1624
this.plugin = plugin;
17-
this.selectedApi = plugin.apiManager.apis[0].apiName;
25+
this.title = idSearchModalOptions.modalTitle;
26+
this.selectedApi = idSearchModalOptions.preselectedAPI || plugin.apiManager.apis[0].apiName;
1827
}
1928

20-
setSubmitCallback(submitCallback: (res: { query: string, api: string }, err?: Error) => void): void {
29+
setSubmitCallback(submitCallback: (res: IdSearchModalData, err?: Error) => void): void {
2130
this.submitCallback = submitCallback;
2231
}
2332

@@ -54,7 +63,7 @@ export class MediaDbIdSearchModal extends Modal {
5463
onOpen() {
5564
const {contentEl} = this;
5665

57-
contentEl.createEl('h2', {text: 'Search media db by id'});
66+
contentEl.createEl('h2', {text: this.title});
5867

5968
const placeholder = 'Search by id';
6069
const searchComponent = new TextComponent(contentEl);

src/modals/MediaDbSearchResultModal.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
11
import {MediaTypeModel} from '../models/MediaTypeModel';
22
import MediaDbPlugin from '../main';
33
import {SelectModal} from './SelectModal';
4+
import {SELECT_MODAL_OPTIONS_DEFAULT, SelectModalData, SelectModalOptions} from '../utils/ModalHelper';
45

56
export class MediaDbSearchResultModal extends SelectModal<MediaTypeModel> {
67
plugin: MediaDbPlugin;
7-
heading: string;
8+
89
busy: boolean;
9-
submitCallback: (res: MediaTypeModel[]) => void;
10+
sendCallback: boolean;
11+
12+
submitCallback: (res: SelectModalData) => void;
1013
closeCallback: (err?: Error) => void;
1114
skipCallback: () => void;
1215

13-
sendCallback: boolean;
1416

15-
constructor(plugin: MediaDbPlugin, elements: MediaTypeModel[], skipButton: boolean, allowMultiSelect: boolean = true) {
16-
super(plugin.app, elements, allowMultiSelect);
17+
constructor(plugin: MediaDbPlugin, selectModalOptions: SelectModalOptions) {
18+
selectModalOptions = Object.assign({}, SELECT_MODAL_OPTIONS_DEFAULT, selectModalOptions);
19+
super(plugin.app, selectModalOptions.elements, selectModalOptions.multiSelect);
1720
this.plugin = plugin;
1821

19-
this.title = 'Search Results';
22+
this.title = selectModalOptions.modalTitle;
2023
this.description = 'Select one or multiple search results.';
21-
this.addSkipButton = skipButton;
24+
this.addSkipButton = selectModalOptions.skipButton;
2225

2326
this.busy = false;
2427

2528
this.sendCallback = false;
2629
}
2730

28-
setSubmitCallback(submitCallback: (res: MediaTypeModel[]) => void): void {
31+
setSubmitCallback(submitCallback: (res: SelectModalData) => void): void {
2932
this.submitCallback = submitCallback;
3033
}
3134

@@ -49,7 +52,7 @@ export class MediaDbSearchResultModal extends SelectModal<MediaTypeModel> {
4952
if (!this.busy) {
5053
this.busy = true;
5154
this.submitButton.setButtonText('Creating entry...');
52-
this.submitCallback(this.selectModalElements.filter(x => x.isActive()).map(x => x.value));
55+
this.submitCallback({selected: this.selectModalElements.filter(x => x.isActive()).map(x => x.value)});
5356
}
5457
}
5558

src/settings/PropertyMappingModelComponent.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,16 @@
4646
<div class="media-db-plugin-property-mapping-to">
4747
<input type="text" spellcheck="false" bind:value="{property.newProperty}">
4848
</div>
49-
{ /if }
50-
{ /if }
49+
{ /if }
50+
{ /if }
5151
</div>
52-
{ /each }
52+
{ /each }
5353
</div>
5454
{ #if !validationResult?.res }
5555
<div class="media-db-plugin-property-mapping-validation">
5656
{validationResult?.err?.message}
5757
</div>
58-
{ /if }
58+
{ /if }
5959
<button
6060
class="media-db-plugin-property-mappings-save-button {validationResult?.res ? 'mod-cta' : 'mod-muted'}"
6161
on:click={() => { if(model.validate().res) save(model) }}>Save

src/settings/PropertyMappingModelsComponent.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<div class="setting-item" style="display: flex; gap: 10px; flex-direction: column; align-items: stretch;">
1717
{ #each models as model }
1818
<PropertyMappingModelComponent model={model} save={save}></PropertyMappingModelComponent>
19-
{ /each }
19+
{ /each }
2020

2121
<!--
2222
<pre>{JSON.stringify(models, null, 4)}</pre>

0 commit comments

Comments
 (0)