872 lines
27 KiB
TypeScript
872 lines
27 KiB
TypeScript
import type { App } from 'obsidian';
|
|
import { Notice, PluginSettingTab, SecretComponent, SettingGroup } from 'obsidian';
|
|
import type MediaDbPlugin from 'packages/obsidian/src/main';
|
|
import type { MediaTypeModel } from 'packages/obsidian/src/models/MediaTypeModel';
|
|
import type { PropertyMappingModelData } from 'packages/obsidian/src/settings/PropertyMapping';
|
|
import { PropertyMapping, PropertyMappingModel, PropertyMappingOption } from 'packages/obsidian/src/settings/PropertyMapping';
|
|
import PropertyMappingModelsComponent from 'packages/obsidian/src/settings/PropertyMappingModelsComponent';
|
|
import { FileSuggest } from 'packages/obsidian/src/settings/suggesters/FileSuggest';
|
|
import { FolderSuggest } from 'packages/obsidian/src/settings/suggesters/FolderSuggest';
|
|
import { MediaType } from 'packages/obsidian/src/utils/MediaType';
|
|
import { MEDIA_TYPES } from 'packages/obsidian/src/utils/MediaTypeManager';
|
|
import { unCamelCase } from 'packages/obsidian/src/utils/Utils';
|
|
|
|
function createDateFormatDescription(preview: string): DocumentFragment {
|
|
return createFragment(frag => {
|
|
const container = frag.createDiv();
|
|
container.appendText('Your custom date format. Use ');
|
|
container.createEl('em', { text: "'YYYY-MM-DD'" });
|
|
container.appendText(' for example.');
|
|
container.createEl('br');
|
|
container.appendText('For more syntax, refer to ');
|
|
container.createEl('a', {
|
|
href: 'https://momentjs.com/docs/#/displaying/format/',
|
|
text: 'format reference',
|
|
});
|
|
container.appendText('.');
|
|
container.createEl('br');
|
|
container.appendText('Your current syntax looks like this: ');
|
|
container.createEl('em', { text: preview });
|
|
});
|
|
}
|
|
|
|
function createPropertyMappingsDescription(): DocumentFragment {
|
|
return createFragment(frag => {
|
|
const container = frag.createDiv();
|
|
container.createEl('p', {
|
|
text: 'Here you can customize how metadata fields are mapped to property names in the front matter of the created notes.',
|
|
});
|
|
container.createEl('p', {
|
|
text: 'You can choose to keep the original name, rename the property, or remove it entirely.',
|
|
});
|
|
const paragraph = container.createEl('p');
|
|
paragraph.createEl('strong', {
|
|
text: 'Remember to save your changes using the save button for each individual category.',
|
|
});
|
|
});
|
|
}
|
|
|
|
// MARK: Settings
|
|
export interface MediaDbPluginSettings {
|
|
OMDbKeyId: string;
|
|
TMDBKeyId: string;
|
|
//MobyGamesKeyId: string;
|
|
//GiantBombKeyId: string;
|
|
IGDBClientId: string;
|
|
IGDBClientSecret: string;
|
|
RAWGAPIKeyId: string;
|
|
ComicVineKeyId: string;
|
|
BoardgameGeekKeyId: string;
|
|
|
|
LegacyApiKeys: readonly ['OMDbKey', 'TMDBKey', 'MobyGamesKey', 'GiantBombKey', 'ComicVineKey', 'BoardgameGeekKey'];
|
|
|
|
sfwFilter: boolean;
|
|
templates: boolean;
|
|
customDateFormat: string;
|
|
openNoteInNewTab: boolean;
|
|
useDefaultFrontMatter: boolean;
|
|
enableTemplaterIntegration: boolean;
|
|
imageDownload: boolean;
|
|
imageFolder: string;
|
|
|
|
BoardgameGeekAPI_disabledMediaTypes: MediaType[];
|
|
ComicVineAPI_disabledMediaTypes: MediaType[];
|
|
//GiantBombAPI_disabledMediaTypes: MediaType[];
|
|
IGDBAPI_disabledMediaTypes: MediaType[];
|
|
RAWGAPI_disabledMediaTypes: MediaType[];
|
|
MALAPI_disabledMediaTypes: MediaType[];
|
|
MALAPIManga_disabledMediaTypes: MediaType[];
|
|
//MobyGamesAPI_disabledMediaTypes: MediaType[];
|
|
MusicBrainzAPI_disabledMediaTypes: MediaType[];
|
|
OMDbAPI_disabledMediaTypes: MediaType[];
|
|
OpenLibraryAPI_disabledMediaTypes: MediaType[];
|
|
SteamAPI_disabledMediaTypes: MediaType[];
|
|
TMDBMovieAPI_disabledMediaTypes: MediaType[];
|
|
TMDBSeasonAPI_disabledMediaTypes: MediaType[];
|
|
TMDBSeriesAPI_disabledMediaTypes: MediaType[];
|
|
VNDBAPI_disabledMediaTypes: MediaType[];
|
|
WikipediaAPI_disabledMediaTypes: MediaType[];
|
|
|
|
movieTemplate: string;
|
|
seriesTemplate: string;
|
|
seasonTemplate: string;
|
|
mangaTemplate: string;
|
|
gameTemplate: string;
|
|
wikiTemplate: string;
|
|
musicReleaseTemplate: string;
|
|
boardgameTemplate: string;
|
|
bookTemplate: string;
|
|
|
|
movieFileNameTemplate: string;
|
|
seriesFileNameTemplate: string;
|
|
seasonFileNameTemplate: string;
|
|
mangaFileNameTemplate: string;
|
|
gameFileNameTemplate: string;
|
|
wikiFileNameTemplate: string;
|
|
musicReleaseFileNameTemplate: string;
|
|
boardgameFileNameTemplate: string;
|
|
bookFileNameTemplate: string;
|
|
|
|
movieFolder: string;
|
|
seriesFolder: string;
|
|
seasonFolder: string;
|
|
mangaFolder: string;
|
|
gameFolder: string;
|
|
wikiFolder: string;
|
|
musicReleaseFolder: string;
|
|
boardgameFolder: string;
|
|
bookFolder: string;
|
|
|
|
propertyMappingModels: PropertyMappingModelData[];
|
|
|
|
// DEPRECATED: Use propertyMappingModels instead
|
|
moviePropertyConversionRules: string;
|
|
seriesPropertyConversionRules: string;
|
|
seasonPropertyConversionRules: string;
|
|
mangaPropertyConversionRules: string;
|
|
gamePropertyConversionRules: string;
|
|
wikiPropertyConversionRules: string;
|
|
musicReleasePropertyConversionRules: string;
|
|
boardgamePropertyConversionRules: string;
|
|
bookPropertyConversionRules: string;
|
|
}
|
|
|
|
/**
|
|
* Helper class to get/set settings for a specific media type.
|
|
*/
|
|
class MediaTypeMappedSettings {
|
|
mediaType: MediaType;
|
|
|
|
constructor(mediaType: MediaType) {
|
|
this.mediaType = mediaType;
|
|
}
|
|
|
|
getTemplate(settings: MediaDbPluginSettings): string {
|
|
switch (this.mediaType) {
|
|
case MediaType.Movie:
|
|
return settings.movieTemplate;
|
|
case MediaType.Series:
|
|
return settings.seriesTemplate;
|
|
case MediaType.Season:
|
|
return settings.seasonTemplate;
|
|
case MediaType.ComicManga:
|
|
return settings.mangaTemplate;
|
|
case MediaType.Game:
|
|
return settings.gameTemplate;
|
|
case MediaType.Wiki:
|
|
return settings.wikiTemplate;
|
|
case MediaType.MusicRelease:
|
|
return settings.musicReleaseTemplate;
|
|
case MediaType.BoardGame:
|
|
return settings.boardgameTemplate;
|
|
case MediaType.Book:
|
|
return settings.bookTemplate;
|
|
}
|
|
}
|
|
|
|
setTemplate(settings: MediaDbPluginSettings, template: string): void {
|
|
switch (this.mediaType) {
|
|
case MediaType.Movie:
|
|
settings.movieTemplate = template;
|
|
break;
|
|
case MediaType.Series:
|
|
settings.seriesTemplate = template;
|
|
break;
|
|
case MediaType.Season:
|
|
settings.seasonTemplate = template;
|
|
break;
|
|
case MediaType.ComicManga:
|
|
settings.mangaTemplate = template;
|
|
break;
|
|
case MediaType.Game:
|
|
settings.gameTemplate = template;
|
|
break;
|
|
case MediaType.Wiki:
|
|
settings.wikiTemplate = template;
|
|
break;
|
|
case MediaType.MusicRelease:
|
|
settings.musicReleaseTemplate = template;
|
|
break;
|
|
case MediaType.BoardGame:
|
|
settings.boardgameTemplate = template;
|
|
break;
|
|
case MediaType.Book:
|
|
settings.bookTemplate = template;
|
|
break;
|
|
}
|
|
}
|
|
|
|
getFileNameTemplate(settings: MediaDbPluginSettings): string {
|
|
switch (this.mediaType) {
|
|
case MediaType.Movie:
|
|
return settings.movieFileNameTemplate;
|
|
case MediaType.Series:
|
|
return settings.seriesFileNameTemplate;
|
|
case MediaType.Season:
|
|
return settings.seasonFileNameTemplate;
|
|
case MediaType.ComicManga:
|
|
return settings.mangaFileNameTemplate;
|
|
case MediaType.Game:
|
|
return settings.gameFileNameTemplate;
|
|
case MediaType.Wiki:
|
|
return settings.wikiFileNameTemplate;
|
|
case MediaType.MusicRelease:
|
|
return settings.musicReleaseFileNameTemplate;
|
|
case MediaType.BoardGame:
|
|
return settings.boardgameFileNameTemplate;
|
|
case MediaType.Book:
|
|
return settings.bookFileNameTemplate;
|
|
}
|
|
}
|
|
|
|
setFileNameTemplate(settings: MediaDbPluginSettings, template: string): void {
|
|
switch (this.mediaType) {
|
|
case MediaType.Movie:
|
|
settings.movieFileNameTemplate = template;
|
|
break;
|
|
case MediaType.Series:
|
|
settings.seriesFileNameTemplate = template;
|
|
break;
|
|
case MediaType.Season:
|
|
settings.seasonFileNameTemplate = template;
|
|
break;
|
|
case MediaType.ComicManga:
|
|
settings.mangaFileNameTemplate = template;
|
|
break;
|
|
case MediaType.Game:
|
|
settings.gameFileNameTemplate = template;
|
|
break;
|
|
case MediaType.Wiki:
|
|
settings.wikiFileNameTemplate = template;
|
|
break;
|
|
case MediaType.MusicRelease:
|
|
settings.musicReleaseFileNameTemplate = template;
|
|
break;
|
|
case MediaType.BoardGame:
|
|
settings.boardgameFileNameTemplate = template;
|
|
break;
|
|
case MediaType.Book:
|
|
settings.bookFileNameTemplate = template;
|
|
break;
|
|
}
|
|
}
|
|
|
|
getFolder(settings: MediaDbPluginSettings): string {
|
|
switch (this.mediaType) {
|
|
case MediaType.Movie:
|
|
return settings.movieFolder;
|
|
case MediaType.Series:
|
|
return settings.seriesFolder;
|
|
case MediaType.Season:
|
|
return settings.seasonFolder;
|
|
case MediaType.ComicManga:
|
|
return settings.mangaFolder;
|
|
case MediaType.Game:
|
|
return settings.gameFolder;
|
|
case MediaType.Wiki:
|
|
return settings.wikiFolder;
|
|
case MediaType.MusicRelease:
|
|
return settings.musicReleaseFolder;
|
|
case MediaType.BoardGame:
|
|
return settings.boardgameFolder;
|
|
case MediaType.Book:
|
|
return settings.bookFolder;
|
|
}
|
|
}
|
|
|
|
setFolder(settings: MediaDbPluginSettings, folder: string): void {
|
|
switch (this.mediaType) {
|
|
case MediaType.Movie:
|
|
settings.movieFolder = folder;
|
|
break;
|
|
case MediaType.Series:
|
|
settings.seriesFolder = folder;
|
|
break;
|
|
case MediaType.Season:
|
|
settings.seasonFolder = folder;
|
|
break;
|
|
case MediaType.ComicManga:
|
|
settings.mangaFolder = folder;
|
|
break;
|
|
case MediaType.Game:
|
|
settings.gameFolder = folder;
|
|
break;
|
|
case MediaType.Wiki:
|
|
settings.wikiFolder = folder;
|
|
break;
|
|
case MediaType.MusicRelease:
|
|
settings.musicReleaseFolder = folder;
|
|
break;
|
|
case MediaType.BoardGame:
|
|
settings.boardgameFolder = folder;
|
|
break;
|
|
case MediaType.Book:
|
|
settings.bookFolder = folder;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: Defaults
|
|
const DEFAULT_SETTINGS: MediaDbPluginSettings = {
|
|
OMDbKeyId: '',
|
|
TMDBKeyId: '',
|
|
//MobyGamesKeyId: '',
|
|
//GiantBombKeyId: '',
|
|
IGDBClientId: '',
|
|
IGDBClientSecret: '',
|
|
RAWGAPIKeyId: '',
|
|
ComicVineKeyId: '',
|
|
BoardgameGeekKeyId: '',
|
|
|
|
LegacyApiKeys: ['OMDbKey', 'TMDBKey', 'MobyGamesKey', 'GiantBombKey', 'ComicVineKey', 'BoardgameGeekKey'],
|
|
|
|
sfwFilter: true,
|
|
templates: true,
|
|
customDateFormat: 'L',
|
|
openNoteInNewTab: true,
|
|
useDefaultFrontMatter: true,
|
|
enableTemplaterIntegration: false,
|
|
imageDownload: false,
|
|
imageFolder: 'Media DB/images',
|
|
|
|
BoardgameGeekAPI_disabledMediaTypes: [],
|
|
ComicVineAPI_disabledMediaTypes: [],
|
|
//GiantBombAPI_disabledMediaTypes: [],
|
|
IGDBAPI_disabledMediaTypes: [],
|
|
RAWGAPI_disabledMediaTypes: [],
|
|
MALAPI_disabledMediaTypes: [],
|
|
MALAPIManga_disabledMediaTypes: [],
|
|
//MobyGamesAPI_disabledMediaTypes: [],
|
|
MusicBrainzAPI_disabledMediaTypes: [],
|
|
OMDbAPI_disabledMediaTypes: [],
|
|
OpenLibraryAPI_disabledMediaTypes: [],
|
|
SteamAPI_disabledMediaTypes: [],
|
|
TMDBMovieAPI_disabledMediaTypes: [],
|
|
TMDBSeasonAPI_disabledMediaTypes: [],
|
|
TMDBSeriesAPI_disabledMediaTypes: [],
|
|
VNDBAPI_disabledMediaTypes: [],
|
|
WikipediaAPI_disabledMediaTypes: [],
|
|
|
|
movieTemplate: '',
|
|
seriesTemplate: '',
|
|
seasonTemplate: '',
|
|
mangaTemplate: '',
|
|
gameTemplate: '',
|
|
wikiTemplate: '',
|
|
musicReleaseTemplate: '',
|
|
boardgameTemplate: '',
|
|
bookTemplate: '',
|
|
|
|
movieFileNameTemplate: '{{ title }} ({{ year }})',
|
|
seriesFileNameTemplate: '{{ title }} ({{ year }})',
|
|
seasonFileNameTemplate: '{{ title }} ({{ year }})',
|
|
mangaFileNameTemplate: '{{ title }} ({{ year }})',
|
|
gameFileNameTemplate: '{{ title }} ({{ year }})',
|
|
wikiFileNameTemplate: '{{ title }}',
|
|
musicReleaseFileNameTemplate: '{{ title }} (by {{ ENUM:artists }} - {{ year }})',
|
|
boardgameFileNameTemplate: '{{ title }} ({{ year }})',
|
|
bookFileNameTemplate: '{{ title }} ({{ year }})',
|
|
|
|
movieFolder: 'Media DB/movies',
|
|
seriesFolder: 'Media DB/series',
|
|
seasonFolder: 'Media DB/series',
|
|
mangaFolder: 'Media DB/comics',
|
|
gameFolder: 'Media DB/games',
|
|
wikiFolder: 'Media DB/wiki',
|
|
musicReleaseFolder: 'Media DB/music',
|
|
boardgameFolder: 'Media DB/boardgames',
|
|
bookFolder: 'Media DB/books',
|
|
|
|
propertyMappingModels: [],
|
|
|
|
// DEPRECATED
|
|
moviePropertyConversionRules: '',
|
|
seriesPropertyConversionRules: '',
|
|
seasonPropertyConversionRules: '',
|
|
mangaPropertyConversionRules: '',
|
|
gamePropertyConversionRules: '',
|
|
wikiPropertyConversionRules: '',
|
|
musicReleasePropertyConversionRules: '',
|
|
boardgamePropertyConversionRules: '',
|
|
bookPropertyConversionRules: '',
|
|
};
|
|
|
|
export const lockedPropertyMappings: string[] = ['type', 'id', 'dataSource'];
|
|
|
|
export function getDefaultSettings(plugin: MediaDbPlugin): MediaDbPluginSettings {
|
|
const defaultSettings = DEFAULT_SETTINGS;
|
|
|
|
// construct property mapping defaults
|
|
const propertyMappingModels: PropertyMappingModelData[] = [];
|
|
for (const mediaType of MEDIA_TYPES) {
|
|
const model: MediaTypeModel = plugin.mediaTypeManager.createMediaTypeModelFromMediaType({}, mediaType);
|
|
const metadataObj = model.toMetaDataObject();
|
|
|
|
const propertyMappingModel: PropertyMappingModel = new PropertyMappingModel(mediaType);
|
|
|
|
for (const key of Object.keys(metadataObj)) {
|
|
propertyMappingModel.properties.push(
|
|
new PropertyMapping(
|
|
key,
|
|
'',
|
|
PropertyMappingOption.Default,
|
|
lockedPropertyMappings.includes(key),
|
|
false, // wikilink default
|
|
),
|
|
);
|
|
}
|
|
|
|
// Convert to plain data for serialization
|
|
propertyMappingModels.push(propertyMappingModel.toJSON());
|
|
}
|
|
|
|
defaultSettings.propertyMappingModels = propertyMappingModels;
|
|
return defaultSettings;
|
|
}
|
|
|
|
// MARK: Settings Tab
|
|
export class MediaDbSettingTab extends PluginSettingTab {
|
|
plugin: MediaDbPlugin;
|
|
private propertyMappingModelsComponent?: PropertyMappingModelsComponent;
|
|
|
|
constructor(app: App, plugin: MediaDbPlugin) {
|
|
super(app, plugin);
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
override hide(): void {
|
|
this.propertyMappingModelsComponent?.unload();
|
|
this.propertyMappingModelsComponent = undefined;
|
|
super.hide();
|
|
}
|
|
|
|
display(): void {
|
|
const { containerEl } = this;
|
|
if (this.propertyMappingModelsComponent) {
|
|
this.propertyMappingModelsComponent.unload();
|
|
this.propertyMappingModelsComponent = undefined;
|
|
}
|
|
containerEl.empty();
|
|
|
|
const mediaTypeSettings = MEDIA_TYPES.map(mt => new MediaTypeMappedSettings(mt));
|
|
|
|
// MARK: General settings
|
|
const generalGroup = new SettingGroup(containerEl);
|
|
|
|
generalGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('SFW filter')
|
|
.setDesc('Only shows SFW results for APIs that offer filtering.')
|
|
.addToggle(cb => {
|
|
cb.setValue(this.plugin.settings.sfwFilter).onChange(data => {
|
|
this.plugin.settings.sfwFilter = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
}),
|
|
);
|
|
|
|
generalGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('Resolve {{ tags }} in templates')
|
|
.setDesc('Whether to resolve {{ tags }} in templates. The spaces inside the curly braces are important.')
|
|
.addToggle(cb => {
|
|
cb.setValue(this.plugin.settings.templates).onChange(data => {
|
|
this.plugin.settings.templates = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
}),
|
|
);
|
|
|
|
generalGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('Date format')
|
|
.setDesc(createDateFormatDescription(this.plugin.dateFormatter.getPreview()))
|
|
.addText(cb => {
|
|
cb.setPlaceholder(DEFAULT_SETTINGS.customDateFormat)
|
|
.setValue(this.plugin.settings.customDateFormat === DEFAULT_SETTINGS.customDateFormat ? '' : this.plugin.settings.customDateFormat)
|
|
.onChange(data => {
|
|
const newDateFormat = data ? data : DEFAULT_SETTINGS.customDateFormat;
|
|
this.plugin.settings.customDateFormat = newDateFormat;
|
|
const previewEl = activeDocument.getElementById('media-db-dateformat-preview');
|
|
if (previewEl) {
|
|
previewEl.textContent = this.plugin.dateFormatter.getPreview(newDateFormat); // update preview
|
|
}
|
|
void this.plugin.saveSettings();
|
|
});
|
|
}),
|
|
);
|
|
|
|
generalGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('Open note in new tab')
|
|
.setDesc('Open the newly created note in a new tab.')
|
|
.addToggle(cb => {
|
|
cb.setValue(this.plugin.settings.openNoteInNewTab).onChange(data => {
|
|
this.plugin.settings.openNoteInNewTab = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
}),
|
|
);
|
|
|
|
generalGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('Use default front matter')
|
|
.setDesc('Whether to use the default front matter. If disabled, the front matter from the template will be used. Same as mapping everything to remove.')
|
|
.addToggle(cb => {
|
|
cb.setValue(this.plugin.settings.useDefaultFrontMatter).onChange(data => {
|
|
this.plugin.settings.useDefaultFrontMatter = data;
|
|
void this.plugin.saveSettings();
|
|
// Redraw settings to display/remove the property mappings
|
|
this.display();
|
|
});
|
|
}),
|
|
);
|
|
|
|
generalGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('Enable Templater integration')
|
|
.setDesc(
|
|
'Enable integration with the templater plugin, this also needs templater to be installed. Warning: Templater allows you to execute arbitrary JavaScript code and system commands.',
|
|
)
|
|
.addToggle(cb => {
|
|
cb.setValue(this.plugin.settings.enableTemplaterIntegration).onChange(data => {
|
|
this.plugin.settings.enableTemplaterIntegration = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
}),
|
|
);
|
|
|
|
generalGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('Download images')
|
|
.setDesc('Downloads images for new notes in the folder below')
|
|
.addToggle(cb => {
|
|
cb.setValue(this.plugin.settings.imageDownload).onChange(data => {
|
|
this.plugin.settings.imageDownload = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
}),
|
|
);
|
|
|
|
generalGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('Image folder')
|
|
.setDesc('Where downloaded images should be stored.')
|
|
.addSearch(cb => {
|
|
const suggester = new FolderSuggest(this.app, cb.inputEl);
|
|
suggester.onSelect(folder => {
|
|
cb.setValue(folder.path);
|
|
this.plugin.settings.imageFolder = folder.path;
|
|
void this.plugin.saveSettings();
|
|
suggester.close();
|
|
});
|
|
cb.setPlaceholder(DEFAULT_SETTINGS.imageFolder)
|
|
.setValue(this.plugin.settings.imageFolder)
|
|
.onChange(data => {
|
|
this.plugin.settings.imageFolder = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
}),
|
|
);
|
|
|
|
// MARK: API keys
|
|
const apiKeyGroup = new SettingGroup(containerEl);
|
|
apiKeyGroup.setHeading('API Keys');
|
|
|
|
apiKeyGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('OMDb API key')
|
|
.setDesc('API key for "www.omdbapi.com".')
|
|
.addComponent(el => {
|
|
const component = new SecretComponent(this.app, el);
|
|
|
|
component.setValue(this.plugin.settings.OMDbKeyId).onChange(data => {
|
|
this.plugin.settings.OMDbKeyId = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
|
|
return component;
|
|
}),
|
|
);
|
|
apiKeyGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('TMDB API key')
|
|
.setDesc('API Read Access Token for "https://www.themoviedb.org".')
|
|
.addComponent(el => {
|
|
const component = new SecretComponent(this.app, el);
|
|
|
|
component.setValue(this.plugin.settings.TMDBKeyId).onChange(data => {
|
|
this.plugin.settings.TMDBKeyId = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
|
|
return component;
|
|
}),
|
|
);
|
|
// apiKeyGroup.addSetting(
|
|
// setting =>
|
|
// void setting
|
|
// .setName('Moby Games key')
|
|
// .setDesc('API key for "www.mobygames.com".')
|
|
// .addComponent(el => {
|
|
// const component = new SecretComponent(this.app, el);
|
|
|
|
// component.setValue(this.plugin.settings.MobyGamesKeyId).onChange(data => {
|
|
// this.plugin.settings.MobyGamesKeyId = data;
|
|
// void this.plugin.saveSettings();
|
|
// });
|
|
|
|
// return component;
|
|
// }),
|
|
// );
|
|
// apiKeyGroup.addSetting(
|
|
// setting =>
|
|
// void setting
|
|
// .setName('Giant Bomb Key')
|
|
// .setDesc('API key for "www.giantbomb.com".')
|
|
// .addComponent(el => {
|
|
// const component = new SecretComponent(this.app, el);
|
|
|
|
// component.setValue(this.plugin.settings.GiantBombKeyId).onChange(data => {
|
|
// this.plugin.settings.GiantBombKeyId = data;
|
|
// void this.plugin.saveSettings();
|
|
// });
|
|
|
|
// return component;
|
|
// }),
|
|
// );
|
|
apiKeyGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('IGDB Client ID')
|
|
.setDesc('Client ID for IGDB API (Required for Twitch OAuth).')
|
|
.addComponent(el => {
|
|
const component = new SecretComponent(this.app, el);
|
|
|
|
component.setValue(this.plugin.settings.IGDBClientId).onChange(data => {
|
|
this.plugin.settings.IGDBClientId = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
|
|
return component;
|
|
}),
|
|
);
|
|
apiKeyGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('IGDB Client Secret')
|
|
.setDesc('Client Secret for IGDB API.')
|
|
.addComponent(el => {
|
|
const component = new SecretComponent(this.app, el);
|
|
|
|
component.setValue(this.plugin.settings.IGDBClientSecret).onChange(data => {
|
|
this.plugin.settings.IGDBClientSecret = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
|
|
return component;
|
|
}),
|
|
);
|
|
apiKeyGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('RAWG API Key')
|
|
.setDesc('API key for "rawg.io".')
|
|
.addComponent(el => {
|
|
const component = new SecretComponent(this.app, el);
|
|
|
|
component.setValue(this.plugin.settings.RAWGAPIKeyId).onChange(data => {
|
|
this.plugin.settings.RAWGAPIKeyId = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
|
|
return component;
|
|
}),
|
|
);
|
|
apiKeyGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('Comic Vine Key')
|
|
.setDesc('API key for "www.comicvine.gamespot.com".')
|
|
.addComponent(el => {
|
|
const component = new SecretComponent(this.app, el);
|
|
|
|
component.setValue(this.plugin.settings.ComicVineKeyId).onChange(data => {
|
|
this.plugin.settings.ComicVineKeyId = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
|
|
return component;
|
|
}),
|
|
);
|
|
apiKeyGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName('Boardgame Geek Key')
|
|
.setDesc('API key for "www.boardgamegeek.com".')
|
|
.addComponent(el => {
|
|
const component = new SecretComponent(this.app, el);
|
|
|
|
component.setValue(this.plugin.settings.BoardgameGeekKeyId).onChange(data => {
|
|
this.plugin.settings.BoardgameGeekKeyId = data;
|
|
void this.plugin.saveSettings();
|
|
});
|
|
|
|
return component;
|
|
}),
|
|
);
|
|
|
|
// MARK: Media type settings
|
|
|
|
// Create a map to store APIs for each media type
|
|
const mediaTypeApiMap = new Map<MediaType, string[]>();
|
|
|
|
// Populate the map with APIs for each media type dynamically
|
|
for (const api of this.plugin.apiManager.apis) {
|
|
for (const mediaType of api.types) {
|
|
if (!mediaTypeApiMap.has(mediaType)) {
|
|
mediaTypeApiMap.set(mediaType, []);
|
|
}
|
|
mediaTypeApiMap.get(mediaType)!.push(api.apiName);
|
|
}
|
|
}
|
|
|
|
for (const mediaTypeSetting of mediaTypeSettings) {
|
|
const mediaTypeGroup = new SettingGroup(containerEl);
|
|
const mediaType = mediaTypeSetting.mediaType;
|
|
const mediaTypeName = unCamelCase(mediaTypeSetting.mediaType);
|
|
const mediaTypeNameLower = mediaTypeName.toLowerCase();
|
|
|
|
mediaTypeGroup.setHeading(`${mediaTypeName} settings`);
|
|
|
|
// Folder
|
|
mediaTypeGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName(`Import Folder`)
|
|
.setDesc(`Where newly imported ${mediaTypeNameLower} should be placed.`)
|
|
.addSearch(cb => {
|
|
const suggester = new FolderSuggest(this.app, cb.inputEl);
|
|
suggester.onSelect(folder => {
|
|
cb.setValue(folder.path);
|
|
mediaTypeSetting.setFolder(this.plugin.settings, folder.path);
|
|
void this.plugin.saveSettings();
|
|
suggester.close();
|
|
});
|
|
cb.setPlaceholder(mediaTypeSetting.getFolder(DEFAULT_SETTINGS))
|
|
.setValue(mediaTypeSetting.getFolder(this.plugin.settings))
|
|
.onChange(data => {
|
|
mediaTypeSetting.setFolder(this.plugin.settings, data);
|
|
void this.plugin.saveSettings();
|
|
});
|
|
}),
|
|
);
|
|
|
|
// Template
|
|
mediaTypeGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName(`Template`)
|
|
.setDesc(`Template file to be used when creating a new note for a ${mediaTypeNameLower}.`)
|
|
.addSearch(cb => {
|
|
const suggester = new FileSuggest(this.app, cb.inputEl);
|
|
suggester.onSelect(file => {
|
|
cb.setValue(file.path);
|
|
mediaTypeSetting.setTemplate(this.plugin.settings, file.path);
|
|
void this.plugin.saveSettings();
|
|
suggester.close();
|
|
});
|
|
cb.setPlaceholder(`Example: ${mediaTypeNameLower}Template.md`)
|
|
.setValue(mediaTypeSetting.getTemplate(this.plugin.settings))
|
|
.onChange(data => {
|
|
mediaTypeSetting.setTemplate(this.plugin.settings, data);
|
|
void this.plugin.saveSettings();
|
|
});
|
|
}),
|
|
);
|
|
|
|
// File name template
|
|
mediaTypeGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName(`File name template`)
|
|
.setDesc(`Template for the file name used when creating a new note for a ${mediaTypeNameLower}.`)
|
|
.addText(cb => {
|
|
cb.setPlaceholder(`Example: ${mediaTypeSetting.getFileNameTemplate(DEFAULT_SETTINGS)}`)
|
|
.setValue(mediaTypeSetting.getFileNameTemplate(this.plugin.settings))
|
|
.onChange(data => {
|
|
mediaTypeSetting.setFileNameTemplate(this.plugin.settings, data);
|
|
void this.plugin.saveSettings();
|
|
});
|
|
}),
|
|
);
|
|
|
|
// APIs
|
|
const apis = mediaTypeApiMap.get(mediaType) ?? [];
|
|
if (apis.length > 1) {
|
|
for (const apiName of apis) {
|
|
const api = this.plugin.apiManager.apis.find(api => api.apiName === apiName);
|
|
if (api) {
|
|
const disabledMediaTypes = api.getDisabledMediaTypes();
|
|
|
|
mediaTypeGroup.addSetting(
|
|
setting =>
|
|
void setting
|
|
.setName(apiName)
|
|
.setDesc(`Use ${apiName} API for ${unCamelCase(mediaType)}.`)
|
|
.addToggle(cb => {
|
|
cb.setValue(!disabledMediaTypes.includes(mediaType)).onChange(data => {
|
|
if (data) {
|
|
const index = disabledMediaTypes.indexOf(mediaType);
|
|
if (index != -1) {
|
|
disabledMediaTypes.splice(index, 1);
|
|
}
|
|
} else {
|
|
disabledMediaTypes.push(mediaType);
|
|
}
|
|
void this.plugin.saveSettings();
|
|
});
|
|
}),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: Property mappings
|
|
|
|
if (this.plugin.settings.useDefaultFrontMatter) {
|
|
const mappingGroup = new SettingGroup(containerEl);
|
|
mappingGroup.setHeading('Property mappings');
|
|
mappingGroup.addSetting(setting => {
|
|
setting.setName('Property mappings explanation').setDesc(createPropertyMappingsDescription());
|
|
const propertyMappingsEl = setting.descEl.createDiv();
|
|
this.propertyMappingModelsComponent = new PropertyMappingModelsComponent(propertyMappingsEl, {
|
|
models: structuredClone(this.plugin.settings.propertyMappingModels),
|
|
save: (model: PropertyMappingModelData): void => {
|
|
// Update the matching model in settings (stored as plain data)
|
|
const index = this.plugin.settings.propertyMappingModels.findIndex(m => m.type === model.type);
|
|
if (index !== -1) {
|
|
this.plugin.settings.propertyMappingModels[index] = model;
|
|
}
|
|
|
|
new Notice(`MDB: Property mappings for ${model.type} saved successfully.`);
|
|
void this.plugin.saveSettings();
|
|
},
|
|
});
|
|
this.propertyMappingModelsComponent.load();
|
|
});
|
|
}
|
|
}
|
|
}
|