big changes; we have a good TS config now

This commit is contained in:
Moritz Jung 2025-01-14 22:30:28 +01:00
parent cbbaf54b33
commit 4497991344
54 changed files with 750 additions and 671 deletions

View file

@ -4,13 +4,16 @@
import { setIcon } from 'obsidian';
import { onMount } from 'svelte';
export let iconName: string = '';
export let iconSize: number = 20;
interface Props {
iconName?: string;
}
let iconEl: HTMLElement;
let { iconName = '' }: Props = $props();
let iconEl: HTMLElement | undefined = $state();
onMount(() => {
setIcon(iconEl, iconName, iconSize);
setIcon(iconEl!, iconName);
});
</script>

View file

@ -1,6 +1,6 @@
import { PropertyMappingOption } from './PropertyMapping';
import type MediaDbPlugin from '../main';
import { MEDIA_TYPES } from '../utils/MediaTypeManager';
import MediaDbPlugin from '../main';
import { PropertyMappingOption } from './PropertyMapping';
export class PropertyMapper {
plugin: MediaDbPlugin;
@ -66,7 +66,7 @@ export class PropertyMapper {
return obj;
}
const propertyMappings = this.plugin.settings.propertyMappingModels.find(x => x.type === obj.type).properties;
const propertyMappings = this.plugin.settings.propertyMappingModels.find(x => x.type === obj.type)?.properties ?? [];
const originalObj: Record<string, unknown> = {};

View file

@ -1,5 +1,5 @@
import type { MediaType } from '../utils/MediaType';
import { containsOnlyLettersAndUnderscores, PropertyMappingNameConflictError, PropertyMappingValidationError } from '../utils/Utils';
import { MediaType } from '../utils/MediaType';
export enum PropertyMappingOption {
Default = 'default',

View file

@ -1,18 +1,22 @@
<script lang="ts">
import { run } from 'svelte/legacy';
import { PropertyMappingModel, PropertyMappingOption, propertyMappingOptions } from './PropertyMapping';
import { capitalizeFirstLetter } from '../utils/Utils';
import Icon from './Icon.svelte';
export let model: PropertyMappingModel;
export let save: (model: PropertyMappingModel) => void;
let validationResult: { res: boolean; err?: Error };
$: modelChanged(model);
function modelChanged(model: PropertyMappingModel) {
validationResult = model.validate();
interface Props {
model: PropertyMappingModel;
save: (model: PropertyMappingModel) => void;
}
let { model, save }: Props = $props();
let validationResult: { res: boolean; err?: Error } | undefined = $state();
$effect(() => {
validationResult = model.validate();
});
</script>
<div class="media-db-plugin-property-mappings-model-container">
@ -51,7 +55,7 @@
{/if}
<button
class="media-db-plugin-property-mappings-save-button {validationResult?.res ? 'mod-cta' : 'mod-muted'}"
on:click={() => {
onclick={() => {
if (model.validate().res) save(model);
}}
>Save

View file

@ -2,8 +2,12 @@
import { PropertyMappingModel } from './PropertyMapping';
import PropertyMappingModelComponent from './PropertyMappingModelComponent.svelte';
export let models: PropertyMappingModel[] = [];
export let save: (model: PropertyMappingModel) => void;
interface Props {
models?: PropertyMappingModel[];
save: (model: PropertyMappingModel) => void;
}
let { models = [], save }: Props = $props();
</script>
<div class="setting-item" style="display: flex; gap: 10px; flex-direction: column; align-items: stretch;">

View file

@ -1,13 +1,14 @@
import { App, Notice, PluginSettingTab, Setting } from 'obsidian';
import MediaDbPlugin from '../main';
import { FolderSuggest } from './suggesters/FolderSuggest';
import { FileSuggest } from './suggesters/FileSuggest';
import PropertyMappingModelsComponent from './PropertyMappingModelsComponent.svelte';
import { PropertyMapping, PropertyMappingModel, PropertyMappingOption } from './PropertyMapping';
import type { App } from 'obsidian';
import { Notice, PluginSettingTab, Setting } from 'obsidian';
import { mount } from 'svelte';
import type MediaDbPlugin from '../main';
import type { MediaTypeModel } from '../models/MediaTypeModel';
import { MEDIA_TYPES } from '../utils/MediaTypeManager';
import { MediaTypeModel } from '../models/MediaTypeModel';
import { fragWithHTML } from '../utils/Utils';
import { PropertyMapping, PropertyMappingModel, PropertyMappingOption } from './PropertyMapping';
import PropertyMappingModelsComponent from './PropertyMappingModelsComponent.svelte';
import { FileSuggest } from './suggesters/FileSuggest';
import { FolderSuggest } from './suggesters/FolderSuggest';
export interface MediaDbPluginSettings {
OMDbKey: string;
@ -193,7 +194,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
});
});
new Setting(containerEl)
new Setting(containerEl)
.setName('Moby Games key')
.setDesc('API key for "www.mobygames.com".')
.addText(cb => {
@ -205,7 +206,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
});
});
new Setting(containerEl)
new Setting(containerEl)
.setName('Giant Bomb Key')
.setDesc('API key for "www.giantbomb.com".')
.addText(cb => {
@ -254,7 +255,10 @@ export class MediaDbSettingTab extends PluginSettingTab {
.onChange(data => {
const newDateFormat = data ? data : DEFAULT_SETTINGS.customDateFormat;
this.plugin.settings.customDateFormat = newDateFormat;
document.getElementById('media-db-dateformat-preview').textContent = this.plugin.dateFormatter.getPreview(newDateFormat); // update preview
const previewEl = document.getElementById('media-db-dateformat-preview');
if (previewEl) {
previewEl.textContent = this.plugin.dateFormatter.getPreview(newDateFormat); // update preview
}
void this.plugin.saveSettings();
});
});
@ -689,7 +693,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
Don't forget to save your changes using the save button for each individual category.
</p>`;
new PropertyMappingModelsComponent({
mount(PropertyMappingModelsComponent, {
target: this.containerEl,
props: {
models: this.plugin.settings.propertyMappingModels.map(x => x.copy()),

View file

@ -1,5 +1,6 @@
import type { TAbstractFile } from 'obsidian';
import { TFile } from 'obsidian';
import { TextInputSuggest } from './Suggest';
import { TAbstractFile, TFile } from 'obsidian';
export class FileSuggest extends TextInputSuggest<TFile> {
getSuggestions(inputStr: string): TFile[] {

View file

@ -1,6 +1,7 @@
// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes
import { TAbstractFile, TFolder } from 'obsidian';
import type { TAbstractFile } from 'obsidian';
import { TFolder } from 'obsidian';
import { TextInputSuggest } from './Suggest';
export class FolderSuggest extends TextInputSuggest<TFolder> {

View file

@ -1,28 +1,34 @@
// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes
import { App, ISuggestOwner, Scope } from 'obsidian';
import { createPopper, Instance as PopperInstance } from '@popperjs/core';
import type { Instance as PopperInstance } from '@popperjs/core';
import { createPopper } from '@popperjs/core';
import type { App, ISuggestOwner } from 'obsidian';
import { Scope } from 'obsidian';
import { wrapAround } from 'src/utils/Utils';
export class Suggest<T> {
private owner: ISuggestOwner<T>;
private values: T[];
private suggestions: HTMLDivElement[];
private suggestions: HTMLElement[];
private selectedItem: number;
private containerEl: HTMLElement;
constructor(owner: ISuggestOwner<T>, containerEl: HTMLElement, scope: Scope) {
this.owner = owner;
this.containerEl = containerEl;
this.values = [];
this.suggestions = [];
this.selectedItem = 0;
containerEl.on('click', '.suggestion-item', this.onSuggestionClick.bind(this));
containerEl.on('mousemove', '.suggestion-item', this.onSuggestionMouseover.bind(this));
containerEl.on('click', '.suggestion-item', (e, el) => this.onSuggestionClick(e, el));
containerEl.on('mousemove', '.suggestion-item', (e, el) => this.onSuggestionMouseover(e, el));
scope.register([], 'ArrowUp', event => {
if (!event.isComposing) {
this.setSelectedItem(this.selectedItem - 1, true);
return false;
}
return undefined;
});
scope.register([], 'ArrowDown', event => {
@ -30,6 +36,7 @@ export class Suggest<T> {
this.setSelectedItem(this.selectedItem + 1, true);
return false;
}
return undefined;
});
scope.register([], 'Enter', event => {
@ -37,10 +44,11 @@ export class Suggest<T> {
this.useSelectedItem(event);
return false;
}
return undefined;
});
}
onSuggestionClick(event: MouseEvent, el: HTMLDivElement): void {
onSuggestionClick(event: MouseEvent, el: HTMLElement): void {
event.preventDefault();
const item = this.suggestions.indexOf(el);
@ -48,7 +56,7 @@ export class Suggest<T> {
this.useSelectedItem(event);
}
onSuggestionMouseover(_event: MouseEvent, el: HTMLDivElement): void {
onSuggestionMouseover(_event: MouseEvent, el: HTMLElement): void {
const item = this.suggestions.indexOf(el);
this.setSelectedItem(item, false);
}
@ -95,7 +103,7 @@ export abstract class TextInputSuggest<T> implements ISuggestOwner<T> {
protected app: App;
protected inputEl: HTMLInputElement;
private popper: PopperInstance;
private popper?: PopperInstance;
private scope: Scope;
private suggestEl: HTMLElement;
private suggest: Suggest<T>;
@ -126,13 +134,13 @@ export abstract class TextInputSuggest<T> implements ISuggestOwner<T> {
if (suggestions.length > 0) {
this.suggest.setSuggestions(suggestions);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.open((<any>this.app).dom.appContainerEl, this.inputEl);
this.open((this.app as any).dom.appContainerEl, this.inputEl);
}
}
open(container: HTMLElement, inputEl: HTMLElement): void {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(<any>this.app).keymap.pushScope(this.scope);
(this.app as any).keymap.pushScope(this.scope);
container.appendChild(this.suggestEl);
this.popper = createPopper(inputEl, this.suggestEl, {
@ -162,7 +170,7 @@ export abstract class TextInputSuggest<T> implements ISuggestOwner<T> {
close(): void {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(<any>this.app).keymap.popScope(this.scope);
(this.app as any).keymap.popScope(this.scope);
this.suggest.setSuggestions([]);
this.popper?.destroy();