update settings; fix some minor issues

This commit is contained in:
Moritz Jung 2026-01-28 21:41:06 +01:00
parent abbf10cf3d
commit 97cf350a32
24 changed files with 882 additions and 950 deletions

3
.gitignore vendored
View file

@ -36,4 +36,5 @@ exampleVault/.obsidian/plugins/obsidian-media-db-plugin/*
!exampleVault/.obsidian/plugins/obsidian-media-db-plugin/.hotreload
exampleVault/Media DB/*
meta.txt
meta.txt
main.js

BIN
bun.lockb

Binary file not shown.

View file

@ -26,26 +26,26 @@
"@happy-dom/global-registrator": "^18.0.1",
"@lemons_dev/parsinom": "^0.0.12",
"@popperjs/core": "^2.11.8",
"@types/bun": "^1.2.19",
"@types/bun": "^1.3.7",
"builtin-modules": "^5.0.0",
"esbuild": "^0.25.8",
"esbuild": "^0.25.12",
"esbuild-plugin-copy-watch": "^2.3.1",
"esbuild-svelte": "^0.9.3",
"eslint": "^9.32.0",
"esbuild-svelte": "^0.9.4",
"eslint": "^9.39.2",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-only-warn": "^1.1.0",
"iso-639-2": "^3.0.2",
"obsidian": "latest",
"openapi-fetch": "^0.14.0",
"openapi-typescript": "^7.8.0",
"prettier": "^3.6.2",
"prettier-plugin-svelte": "^3.4.0",
"openapi-fetch": "^0.14.1",
"openapi-typescript": "^7.10.1",
"prettier": "^3.8.1",
"prettier-plugin-svelte": "^3.4.1",
"string-argv": "^0.3.2",
"svelte": "^5.38.0",
"svelte-check": "^4.3.1",
"svelte": "^5.48.5",
"svelte-check": "^4.3.5",
"svelte-preprocess": "^6.0.3",
"tslib": "^2.8.1",
"typescript": "^5.9.2",
"typescript-eslint": "^8.39.0"
"typescript": "^5.9.3",
"typescript-eslint": "^8.54.0"
}
}

View file

@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call */
import createClient from 'openapi-fetch';
import type MediaDbPlugin from '../../main';
import type { MediaTypeModel } from '../../models/MediaTypeModel';

View file

@ -1,9 +1,11 @@
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call */
import createClient from 'openapi-fetch';
import type MediaDbPlugin from '../../main';
import type { MediaTypeModel } from '../../models/MediaTypeModel';
import { SeasonModel } from '../../models/SeasonModel';
import { MediaType } from '../../utils/MediaType';
import { APIModel } from '../APIModel';
import { SeasonModel } from '../../models/SeasonModel';
import type { paths } from '../schemas/TMDB';
export class TMDBSeasonAPI extends APIModel {
@ -82,7 +84,9 @@ export class TMDBSeasonAPI extends APIModel {
totalSeasons = detailsData.seasons.length;
}
}
} catch {}
} catch {
// Ignore errors and assume 0 seasons
}
ret.push(
new SeasonModel({

View file

@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call */
import createClient from 'openapi-fetch';
import type MediaDbPlugin from '../../main';
import type { MediaTypeModel } from '../../models/MediaTypeModel';

View file

@ -257,4 +257,8 @@ export class VNDBAPI extends APIModel {
},
});
}
getDisabledMediaTypes(): MediaType[] {
return this.plugin.settings.VNDBAPI_disabledMediaTypes;
}
}

View file

@ -13,15 +13,14 @@ import { MusicBrainzAPI } from './api/apis/MusicBrainzAPI';
import { OMDbAPI } from './api/apis/OMDbAPI';
import { OpenLibraryAPI } from './api/apis/OpenLibraryAPI';
import { SteamAPI } from './api/apis/SteamAPI';
import { TMDBSeriesAPI } from './api/apis/TMDBSeriesAPI';
import { TMDBSeasonAPI } from './api/apis/TMDBSeasonAPI';
import { TMDBMovieAPI } from './api/apis/TMDBMovieAPI';
import { WikipediaAPI } from './api/apis/WikipediaAPI';
import { ComicVineAPI } from './api/apis/ComicVineAPI';
import { TMDBSeasonAPI } from './api/apis/TMDBSeasonAPI';
import { TMDBSeriesAPI } from './api/apis/TMDBSeriesAPI';
import { VNDBAPI } from './api/apis/VNDBAPI';
import { MediaDbFolderImportModal } from './modals/MediaDbFolderImportModal';
import { WikipediaAPI } from './api/apis/WikipediaAPI';
import { ConfirmOverwriteModal } from './modals/ConfirmOverwriteModal';
import { MediaDbSeasonSelectModal } from './modals/MediaDbSeasonSelectModal';
import type {SeasonSelectModalElement} from './modals/MediaDbSeasonSelectModal';
import { MediaDbSeasonSelectModal } from './modals/MediaDbSeasonSelectModal';
import type { MediaTypeModel } from './models/MediaTypeModel';
import { PropertyMapper } from './settings/PropertyMapper';
import { PropertyMapping, PropertyMappingModel } from './settings/PropertyMapping';
@ -271,7 +270,7 @@ export default class MediaDbPlugin extends Plugin {
private async handleSeasonSelectModal(types: string[], selectResults: MediaTypeModel[]): Promise<boolean> {
if (types.length === 1 && types[0] === 'season' && selectResults.length === 1 && selectResults[0].dataSource === 'TMDBSeasonAPI') {
// Use static import for the modal
const tmdbSeasonAPI = this.apiManager.getApiByName('TMDBSeasonAPI') as import('./api/apis/TMDBSeasonAPI').TMDBSeasonAPI;
const tmdbSeasonAPI = this.apiManager.getApiByName('TMDBSeasonAPI') as TMDBSeasonAPI;
if (!tmdbSeasonAPI) {
new Notice('TMDBSeasonAPI not found.');
return true;
@ -296,8 +295,8 @@ export default class MediaDbPlugin extends Plugin {
true,
seriesName,
);
const selectedSeasons: any[] = await new Promise(resolve => {
modal.setSubmitCallback(resolve);
const selectedSeasons: SeasonSelectModalElement[] = await new Promise(resolve => {
modal.setSubmitCb(resolve);
modal.open();
});
if (!selectedSeasons || selectedSeasons.length === 0) {
@ -309,7 +308,7 @@ export default class MediaDbPlugin extends Plugin {
const orig = allSeasons.find(s => s.seasonNumber === season.season_number);
if (orig) {
// Fetch full metadata using getById
const tmdbSeasonAPI = this.apiManager.getApiByName('TMDBSeasonAPI') as import('./api/apis/TMDBSeasonAPI').TMDBSeasonAPI;
const tmdbSeasonAPI = this.apiManager.getApiByName('TMDBSeasonAPI') as TMDBSeasonAPI;
if (tmdbSeasonAPI) {
const fullMeta = await tmdbSeasonAPI.getById(orig.id);
await this.createMediaDbNotes([fullMeta]);

View file

@ -28,11 +28,11 @@ export class MediaDbAdvancedSearchModal extends Modal {
this.isBusy = false;
}
setSubmitCallback(submitCallback: (res: AdvancedSearchModalData) => void): void {
setSubmitCb(submitCallback: (res: AdvancedSearchModalData) => void): void {
this.submitCallback = submitCallback;
}
setCloseCallback(closeCallback: (err?: Error) => void): void {
setCloseCb(closeCallback: (err?: Error) => void): void {
this.closeCallback = closeCallback;
}

View file

@ -28,11 +28,11 @@ export class MediaDbIdSearchModal extends Modal {
this.isBusy = false;
}
setSubmitCallback(submitCallback: (res: IdSearchModalData, err?: Error) => void): void {
setSubmitCb(submitCallback: (res: IdSearchModalData, err?: Error) => void): void {
this.submitCallback = submitCallback;
}
setCloseCallback(closeCallback: (err?: Error) => void): void {
setCloseCb(closeCallback: (err?: Error) => void): void {
this.closeCallback = closeCallback;
}

View file

@ -26,11 +26,11 @@ export class MediaDbPreviewModal extends Modal {
this.markdownComponent = new Component();
}
setSubmitCallback(submitCallback: (previewModalData: PreviewModalData) => void): void {
setSubmitCb(submitCallback: (previewModalData: PreviewModalData) => void): void {
this.submitCallback = submitCallback;
}
setCloseCallback(closeCallback: (err?: Error) => void): void {
setCloseCb(closeCallback: (err?: Error) => void): void {
this.closeCallback = closeCallback;
}

View file

@ -31,11 +31,11 @@ export class MediaDbSearchModal extends Modal {
this.isBusy = false;
}
setSubmitCallback(submitCallback: (res: SearchModalData) => void): void {
setSubmitCb(submitCallback: (res: SearchModalData) => void): void {
this.submitCallback = submitCallback;
}
setCloseCallback(closeCallback: (err?: Error) => void): void {
setCloseCb(closeCallback: (err?: Error) => void): void {
this.closeCallback = closeCallback;
}

View file

@ -27,11 +27,11 @@ export class MediaDbSearchResultModal extends SelectModal<MediaTypeModel> {
this.sendCallback = false;
}
setSubmitCallback(submitCallback: (res: SelectModalData) => void): void {
setSubmitCb(submitCallback: (res: SelectModalData) => void): void {
this.submitCallback = submitCallback;
}
setCloseCallback(closeCallback: (err?: Error) => void): void {
setCloseCb(closeCallback: (err?: Error) => void): void {
this.closeCallback = closeCallback;
}

View file

@ -40,11 +40,11 @@ export class MediaDbSeasonSelectModal extends SelectModal<SeasonSelectModalEleme
this.close();
}
setSubmitCallback(cb: (selectedSeasons: SeasonSelectModalElement[]) => void): void {
setSubmitCb(cb: (selectedSeasons: SeasonSelectModalElement[]) => void): void {
this.submitCallback = cb;
}
setCloseCallback(cb: (err?: Error) => void): void {
setCloseCb(cb: (err?: Error) => void): void {
this.closeCallback = cb;
}
}

View file

@ -59,7 +59,7 @@ export class SeasonModel extends MediaTypeModel {
migrateObject(this, obj, this);
if (!obj.hasOwnProperty('userData')) {
if (!Object.hasOwn(obj, 'userData')) {
migrateObject(this.userData, obj, this.userData);
}

View file

@ -124,14 +124,16 @@ export class PropertyMapping {
if (!this.property || !containsOnlyLettersAndUnderscores(this.property)) {
return {
res: false,
err: new PropertyMappingValidationError(`Error in property mapping "${this.toString()}": property may not be empty and only contain letters and underscores.`),
err: new PropertyMappingValidationError(`Error in property mapping "${this.toString()}": property may not be empty and may only contain letters and underscores.`),
};
}
if (!this.newProperty || !containsOnlyLettersAndUnderscores(this.newProperty)) {
return {
res: false,
err: new PropertyMappingValidationError(`Error in property mapping "${this.toString()}": new property may not be empty and only contain letters and underscores.`),
err: new PropertyMappingValidationError(
`Error in property mapping "${this.toString()}": new property may not be empty and may only contain letters and underscores.`,
),
};
}

View file

@ -2,7 +2,7 @@
import { PropertyMappingModel, PropertyMappingOption, propertyMappingOptions } from './PropertyMapping';
import { capitalizeFirstLetter } from '../utils/Utils';
import Icon from './Icon.svelte';
interface Props {
model: PropertyMappingModel;
save: (model: PropertyMappingModel) => void;
@ -10,70 +10,39 @@
let { model, save }: Props = $props();
let unsavedChanges = $state(false);
// svelte-ignore state_referenced_locally
let validationResult: { res: boolean; err?: Error } | undefined = $derived(model.validate());
function onModelUpdate() {
unsavedChanges = true;
model = model.copy();
}
</script>
<div class="media-db-plugin-property-mappings-model-container">
<div class="setting-item-name">{capitalizeFirstLetter(model.type)}</div>
<div class="media-db-plugin-property-mappings-model-header">
<div class="setting-item-name">{capitalizeFirstLetter(model.type)}</div>
<table class="media-db-plugin-property-mappings-table">
<thead>
<tr>
<th class="col-property">Property</th>
<th class="col-mapping">Mapping</th>
<th class="col-new-name">New name</th>
<th class="col-wikilink">Wikilink</th>
</tr>
</thead>
<tbody>
{#each model.properties as property}
<tr>
<td class="col-property">
<code>{property.property}</code>
</td>
<div class="media-db-plugin-property-mappings-model-actions">
{#if unsavedChanges}
<div class="media-db-plugin-property-mapping-unsaved-changes">Unsaved changes</div>
{/if}
{#if property.locked}
<td class="col-locked" colspan="3">
<div class="media-db-plugin-property-binding-text">property cannot be remapped</div>
</td>
{:else}
<td class="col-mapping">
<select
class="dropdown"
bind:value={property.mapping}
onchange={() => {
model = model.copy();
}}
>
{#each propertyMappingOptions as remappingOption}
<option value={remappingOption}>
{remappingOption}
</option>
{/each}
</select>
</td>
<td class="col-new-name">
{#if property.mapping === PropertyMappingOption.Map}
<div class="media-db-plugin-property-mapping-to">
<Icon iconName="arrow-right" />
<input class="media-db-plugin-property-mapping-input" type="text" spellcheck="false" bind:value={property.newProperty} />
</div>
{:else}
<span class="media-db-plugin-property-mapping-to-disabled"></span>
{/if}
</td>
<td class="col-wikilink">
<label class="media-db-plugin-property-mapping-wikilink-label" title="Convert value to wikilink ([[value]])">
<input type="checkbox" bind:checked={property.wikilink} />
</label>
</td>
{/if}
</tr>
{/each}
</tbody>
</table>
<button
class="media-db-plugin-property-mappings-save-button {validationResult?.res ? 'mod-cta' : 'mod-muted'}"
onclick={() => {
if (model.validate().res) {
save(model);
unsavedChanges = false;
}
}}
>
Save
</button>
</div>
</div>
{#if !validationResult?.res}
<div class="media-db-plugin-property-mapping-validation">
@ -81,33 +50,169 @@
</div>
{/if}
<button
class="media-db-plugin-property-mappings-save-button {validationResult?.res ? 'mod-cta' : 'mod-muted'}"
onclick={() => {
if (model.validate().res) save(model);
}}
>
Save
</button>
<div class="media-db-plugin-property-mappings-table-container">
<table class="media-db-plugin-property-mappings-table">
<thead>
<tr>
<th class="col-property">Property</th>
<th class="col-mapping">Mapping</th>
<th class="col-new-name">New name</th>
<th class="col-wikilink">Wikilink</th>
</tr>
</thead>
<tbody>
{#each model.properties as property}
<tr>
<td class="col-property">
<code>{property.property}</code>
</td>
{#if property.locked}
<td class="col-locked" colspan="3">
<div class="media-db-plugin-property-binding-text">property cannot be remapped</div>
</td>
{:else}
<td class="col-mapping">
<select class="dropdown" bind:value={property.mapping} onchange={() => onModelUpdate()}>
{#each propertyMappingOptions as remappingOption}
<option value={remappingOption}>
{remappingOption}
</option>
{/each}
</select>
</td>
<td class="col-new-name">
{#if property.mapping === PropertyMappingOption.Map}
<div class="media-db-plugin-property-mapping-to">
<Icon iconName="arrow-right" />
<input
class="media-db-plugin-property-mapping-input"
type="text"
spellcheck="false"
bind:value={property.newProperty}
onchange={() => onModelUpdate()}
/>
</div>
{:else}
<span class="media-db-plugin-property-mapping-to-disabled"></span>
{/if}
</td>
<td class="col-wikilink">
<label class="media-db-plugin-property-mapping-wikilink-label" title="Convert value to wikilink ([[value]])">
<input type="checkbox" bind:checked={property.wikilink} onchange={() => onModelUpdate()} />
</label>
</td>
{/if}
</tr>
{/each}
</tbody>
</table>
</div>
</div>
<style>
/* Container */
.media-db-plugin-property-mappings-model-container {
margin-bottom: var(--size-4-8);
}
/* Header and actions */
.media-db-plugin-property-mappings-model-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--size-4-4);
gap: var(--size-4-3);
}
.media-db-plugin-property-mappings-model-header .setting-item-name {
font-weight: var(--font-semibold);
font-size: var(--font-ui-medium);
color: var(--text-normal);
margin: 0;
}
.media-db-plugin-property-mappings-model-actions {
display: flex;
align-items: center;
gap: var(--size-4-3);
}
.media-db-plugin-property-mapping-unsaved-changes {
color: var(--text-warning);
font-size: var(--font-ui-small);
white-space: nowrap;
}
.media-db-plugin-property-mappings-save-button {
white-space: nowrap;
cursor: pointer;
}
.media-db-plugin-property-mappings-save-button.mod-muted {
opacity: 0.5;
cursor: not-allowed;
}
/* Validation error */
.media-db-plugin-property-mapping-validation {
color: var(--text-error);
background: rgba(var(--color-red-rgb), 0.1);
padding: var(--size-4-3) var(--size-4-4);
margin-bottom: var(--size-4-4);
border-left: 3px solid var(--text-error);
font-size: var(--font-ui-small);
line-height: 1.5;
border-radius: var(--radius-s);
}
/* Table container */
.media-db-plugin-property-mappings-table-container {
overflow-x: auto;
}
.media-db-plugin-property-mappings-table {
width: 100%;
border-collapse: collapse;
border-spacing: 0;
table-layout: fixed; /* prevent overflow from wide cells */
font-size: var(--font-ui-small);
}
/* remove excessive left padding and keep within container */
.media-db-plugin-property-mappings-table th,
.media-db-plugin-property-mappings-table td {
padding: 2px 4px;
/* Table header */
.media-db-plugin-property-mappings-table thead {
border-bottom: 1px solid var(--background-modifier-border);
}
.media-db-plugin-property-mappings-table th {
padding: var(--size-4-2) var(--size-4-3);
padding-left: 0;
text-align: left;
font-weight: var(--font-semibold);
color: var(--text-muted);
font-size: var(--font-ui-smaller);
text-transform: uppercase;
letter-spacing: 0.02em;
border-bottom: none;
}
/* Table body */
.media-db-plugin-property-mappings-table tbody tr {
transition: background-color 0.1s ease;
}
.media-db-plugin-property-mappings-table td {
padding: var(--size-4-3) var(--size-4-3) var(--size-4-3) 0;
border-bottom: 1px solid var(--background-modifier-border-hover);
vertical-align: middle;
}
/* column widths */
.media-db-plugin-property-mappings-table tbody tr:last-child td {
border-bottom: none;
}
/* Column widths */
.col-property {
width: 25%;
white-space: nowrap;
@ -126,36 +231,66 @@
text-align: center;
}
/* ensure inner controls don't push table wider than container */
.media-db-plugin-property-mapping-to {
display: flex;
align-items: center;
gap: 4px;
min-width: 0;
.col-locked {
text-align: center;
font-style: italic;
}
.media-db-plugin-property-mapping-input,
/* Property name styling */
.media-db-plugin-property-mappings-table code {
padding: var(--size-4-1) var(--size-4-2);
margin: 0;
background: var(--code-background);
color: var(--code-normal);
border-radius: var(--radius-s);
font-size: var(--font-ui-smaller);
font-family: var(--font-monospace);
}
/* Locked property text */
.media-db-plugin-property-binding-text {
color: var(--text-muted);
font-size: var(--font-ui-small);
font-style: italic;
}
/* Dropdown select - use Obsidian defaults */
.media-db-plugin-property-mappings-table select.dropdown {
width: 100%;
max-width: 100%;
box-sizing: border-box;
}
.media-db-plugin-property-mapping-wikilink-label {
display: inline-flex;
/* Remap input */
.media-db-plugin-property-mapping-to {
display: flex;
align-items: center;
gap: 4px;
font-size: 0.95em;
cursor: pointer;
gap: var(--size-4-2);
min-width: 0;
}
.media-db-plugin-property-mapping-input {
flex: 1;
width: 100%;
font-family: var(--font-monospace);
}
.media-db-plugin-property-mapping-to-disabled {
color: var(--text-muted);
color: var(--text-faint);
font-size: var(--font-ui-medium);
}
/* avoid extra left indentation from <pre> */
.media-db-plugin-property-mappings-table code {
padding: 0;
margin: 0;
/* Wikilink checkbox */
.media-db-plugin-property-mapping-wikilink-label {
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: var(--size-4-1);
}
.media-db-plugin-property-mapping-wikilink-label input[type='checkbox'] {
cursor: pointer;
width: var(--checkbox-size);
height: var(--checkbox-size);
}
</style>

View file

@ -17,12 +17,6 @@
<!--
<pre>{JSON.stringify(models, null, 4)}</pre>
{ #each ICON_LIST as icon }
<p>
{icon} <Icon iconName="{icon}"/>
</p>
{/each}
-->
</div>

File diff suppressed because it is too large Load diff

View file

@ -7,24 +7,25 @@ import { GameModel } from '../models/GameModel';
import type { MediaTypeModel } from '../models/MediaTypeModel';
import { MovieModel } from '../models/MovieModel';
import { MusicReleaseModel } from '../models/MusicReleaseModel';
import { SeriesModel } from '../models/SeriesModel';
import { SeasonModel } from '../models/SeasonModel';
import { SeriesModel } from '../models/SeriesModel';
import { WikiModel } from '../models/WikiModel';
import type { MediaDbPluginSettings } from '../settings/Settings';
import { ILLEGAL_FILENAME_CHARACTERS } from './IllegalFilenameCharactersList';
import { MediaType } from './MediaType';
import { replaceTags } from './Utils';
// All media types in alphabetical order
export const MEDIA_TYPES: MediaType[] = [
MediaType.Movie,
MediaType.Series,
MediaType.Season,
MediaType.ComicManga,
MediaType.Game,
MediaType.Wiki,
MediaType.MusicRelease,
MediaType.BoardGame,
MediaType.Book,
MediaType.ComicManga,
MediaType.Game,
MediaType.Movie,
MediaType.MusicRelease,
MediaType.Series,
MediaType.Season,
MediaType.Wiki,
];
export class MediaTypeManager {

View file

@ -236,8 +236,8 @@ export class ModalHelper {
async createSearchModal(searchModalOptions: SearchModalOptions): Promise<{ searchModalResult: SearchModalResult; searchModal: MediaDbSearchModal }> {
const modal = new MediaDbSearchModal(this.plugin, searchModalOptions);
const res: SearchModalResult = await new Promise(resolve => {
modal.setSubmitCallback(res => resolve({ code: ModalResultCode.SUCCESS, data: res }));
modal.setCloseCallback(err => {
modal.setSubmitCb(res => resolve({ code: ModalResultCode.SUCCESS, data: res }));
modal.setCloseCb(err => {
if (err) {
resolve({ code: ModalResultCode.ERROR, error: err });
}
@ -302,8 +302,8 @@ export class ModalHelper {
): Promise<{ advancedSearchModalResult: AdvancedSearchModalResult; advancedSearchModal: MediaDbAdvancedSearchModal }> {
const modal = new MediaDbAdvancedSearchModal(this.plugin, advancedSearchModalOptions);
const res: AdvancedSearchModalResult = await new Promise(resolve => {
modal.setSubmitCallback(res => resolve({ code: ModalResultCode.SUCCESS, data: res }));
modal.setCloseCallback(err => {
modal.setSubmitCb(res => resolve({ code: ModalResultCode.SUCCESS, data: res }));
modal.setCloseCb(err => {
if (err) {
resolve({ code: ModalResultCode.ERROR, error: err });
}
@ -366,8 +366,8 @@ export class ModalHelper {
async createIdSearchModal(idSearchModalOptions: IdSearchModalOptions): Promise<{ idSearchModalResult: IdSearchModalResult; idSearchModal: MediaDbIdSearchModal }> {
const modal = new MediaDbIdSearchModal(this.plugin, idSearchModalOptions);
const res: IdSearchModalResult = await new Promise(resolve => {
modal.setSubmitCallback(res => resolve({ code: ModalResultCode.SUCCESS, data: res }));
modal.setCloseCallback(err => {
modal.setSubmitCb(res => resolve({ code: ModalResultCode.SUCCESS, data: res }));
modal.setCloseCb(err => {
if (err) {
resolve({ code: ModalResultCode.ERROR, error: err });
}
@ -430,9 +430,9 @@ export class ModalHelper {
async createSelectModal(selectModalOptions: SelectModalOptions): Promise<{ selectModalResult: SelectModalResult; selectModal: MediaDbSearchResultModal }> {
const modal = new MediaDbSearchResultModal(this.plugin, selectModalOptions);
const res: SelectModalResult = await new Promise(resolve => {
modal.setSubmitCallback(res => resolve({ code: ModalResultCode.SUCCESS, data: res }));
modal.setSubmitCb(res => resolve({ code: ModalResultCode.SUCCESS, data: res }));
modal.setSkipCallback(() => resolve({ code: ModalResultCode.SKIP }));
modal.setCloseCallback(err => {
modal.setCloseCb(err => {
if (err) {
resolve({ code: ModalResultCode.ERROR, error: err });
}
@ -493,8 +493,8 @@ export class ModalHelper {
//todo: handle attachFile for existing files
const modal = new MediaDbPreviewModal(this.plugin, previewModalOptions);
const res: PreviewModalResult = await new Promise(resolve => {
modal.setSubmitCallback(res => resolve({ code: ModalResultCode.SUCCESS, data: res }));
modal.setCloseCallback(err => {
modal.setSubmitCb(res => resolve({ code: ModalResultCode.SUCCESS, data: res }));
modal.setCloseCb(err => {
if (err) {
resolve({ code: ModalResultCode.ERROR, error: err });
}

View file

@ -1,16 +0,0 @@
import type { App } from 'obsidian';
import type { SeasonSelectModalElement } from '../modals/MediaDbSeasonSelectModal';
import { MediaDbSeasonSelectModal } from '../modals/MediaDbSeasonSelectModal';
export async function openSeasonSelectModal(app: App, plugin: any, seasons: SeasonSelectModalElement[]): Promise<SeasonSelectModalElement[] | undefined> {
return new Promise(resolve => {
const modal = new MediaDbSeasonSelectModal(plugin, seasons, true);
modal.setSubmitCallback(selected => {
resolve(selected);
});
modal.setCloseCallback(() => {
resolve(undefined);
});
modal.open();
});
}

View file

@ -64,55 +64,6 @@ small.media-db-plugin-list-text {
margin-bottom: 10px;
}
/* region property mappings */
.media-db-plugin-property-mappings-model-container {
border: 1px solid var(--background-modifier-border);
border-radius: 5px;
padding: 10px;
width: 100%;
}
.media-db-plugin-property-mappings-container {
margin: 10px 0;
display: flex;
flex-direction: column;
gap: 5px;
}
.media-db-plugin-property-mapping-element {
display: flex;
flex-direction: row;
gap: 10px;
}
.media-db-plugin-property-mapping-element-property-name-wrapper {
min-width: 160px;
background: var(--background-modifier-form-field);
padding: 2px 5px;
border-radius: 5px;
display: flex;
align-items: center;
}
.media-db-plugin-property-mapping-element-property-name {
margin: 0;
}
.media-db-plugin-property-mappings-save-button {
margin: 0;
}
.media-db-plugin-property-mapping-to {
display: flex;
align-items: center;
}
.media-db-plugin-property-mapping-validation {
color: var(--text-error);
margin-bottom: 5px;
}
.media-db-plugin-button:focus {
/*outline: 1px solid white;*/
}
@ -122,5 +73,3 @@ small.media-db-plugin-list-text {
border: var(--modal-border-width) solid var(--modal-border-color);
padding: var(--size-4-4);
}
/* endregion */

View file

@ -1,14 +0,0 @@
import { readFileSync, writeFileSync } from 'fs';
const targetVersion = process.env.npm_package_version;
// read minAppVersion from manifest.json and bump version to target version
let manifest = JSON.parse(readFileSync('manifest.json', 'utf8'));
const { minAppVersion } = manifest;
manifest.version = targetVersion;
writeFileSync('manifest.json', JSON.stringify(manifest, null, '\t'));
// update versions.json with target version and minAppVersion from manifest.json
let versions = JSON.parse(readFileSync('versions.json', 'utf8'));
versions[targetVersion] = minAppVersion;
writeFileSync('versions.json', JSON.stringify(versions, null, '\t'));