big changes; we have a good TS config now
This commit is contained in:
parent
cbbaf54b33
commit
4497991344
54 changed files with 750 additions and 671 deletions
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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> = {};
|
||||
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;">
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
|
|
|
|||
|
|
@ -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[] {
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue