From 14719efa226078f4c5124213a89fdaf62b1e3996 Mon Sep 17 00:00:00 2001 From: mProjectsCode Date: Sat, 24 Sep 2022 20:33:06 +0200 Subject: [PATCH] more changes for #48, the UI now works \o/ --- src/main.ts | 55 ++++-- src/models/BoardGameModel.ts | 9 + src/models/GameModel.ts | 19 ++- src/models/MediaTypeModel.ts | 15 +- src/models/MovieModel.ts | 22 ++- src/models/MusicReleaseModel.ts | 7 + src/models/SeriesModel.ts | 16 ++ src/models/WikiModel.ts | 8 +- src/settings/Icon.svelte | 36 ++++ src/settings/PropertyBindingsComponent.svelte | 74 --------- src/settings/PropertyMapper.ts | 6 +- src/settings/PropertyMapping.ts | 6 +- .../PropertyMappingModelsComponent.svelte | 106 ++++++++++++ src/settings/Settings.ts | 157 ++++++++++++------ src/settings/suggesters/Suggest.ts | 2 +- src/utils/MediaTypeManager.ts | 5 +- src/utils/Utils.ts | 3 + 17 files changed, 381 insertions(+), 165 deletions(-) create mode 100644 src/settings/Icon.svelte delete mode 100644 src/settings/PropertyBindingsComponent.svelte create mode 100644 src/settings/PropertyMappingModelsComponent.svelte diff --git a/src/main.ts b/src/main.ts index cdbb942..9426507 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ import {Notice, parseYaml, Plugin, stringifyYaml, TFile, TFolder} from 'obsidian'; -import {DEFAULT_SETTINGS, MediaDbPluginSettings, MediaDbSettingTab} from './settings/Settings'; +import {getDefaultSettings, MediaDbPluginSettings, MediaDbSettingTab} from './settings/Settings'; import {APIManager} from './api/APIManager'; import {MediaTypeModel} from './models/MediaTypeModel'; import {dateTimeToString, debugLog, markdownTable, replaceIllegalFileNameCharactersInString, UserCancelError, UserSkipError} from './utils/Utils'; @@ -16,6 +16,7 @@ import {BoardGameGeekAPI} from './api/apis/BoardGameGeekAPI'; import {PropertyMapper} from './settings/PropertyMapper'; import {YAMLConverter} from './utils/YAMLConverter'; import {MediaDbFolderImportModal} from './modals/MediaDbFolderImportModal'; +import {PropertyMapping, PropertyMappingModel} from './settings/PropertyMapping'; export default class MediaDbPlugin extends Plugin { settings: MediaDbPluginSettings; @@ -26,14 +27,6 @@ export default class MediaDbPlugin extends Plugin { frontMatterRexExpPattern: string = '^(---)\\n[\\s\\S]*?\\n---'; async onload() { - await this.loadSettings(); - // register the settings tab - this.addSettingTab(new MediaDbSettingTab(this.app, this)); - - // TESTING - this.settings.propertyMappings = DEFAULT_SETTINGS.propertyMappings; - - this.apiManager = new APIManager(); // register APIs this.apiManager.registerAPI(new OMDbAPI(this)); @@ -44,9 +37,18 @@ export default class MediaDbPlugin extends Plugin { this.apiManager.registerAPI(new BoardGameGeekAPI(this)); // this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data - this.mediaTypeManager = new MediaTypeManager(this.settings); + this.mediaTypeManager = new MediaTypeManager(); this.modelPropertyMapper = new PropertyMapper(this); + await this.loadSettings(); + // register the settings tab + this.addSettingTab(new MediaDbSettingTab(this.app, this)); + + // TESTING + // this.settings.propertyMappingModels = getDefaultSettings(this).propertyMappingModels; + + this.mediaTypeManager.updateTemplates(this.settings); + // add icon to the left ribbon const ribbonIconEl = this.addRibbonIcon('database', 'Add new Media DB entry', (evt: MouseEvent) => @@ -491,8 +493,37 @@ export default class MediaDbPlugin extends Plugin { } async loadSettings() { - console.log(DEFAULT_SETTINGS); - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + // console.log(DEFAULT_SETTINGS); + const diskSettings: MediaDbPluginSettings = await this.loadData(); + const defaultSettings: MediaDbPluginSettings = getDefaultSettings(this); + const loadedSettings: MediaDbPluginSettings = Object.assign({}, defaultSettings, diskSettings); + + // migrate the settings loaded from the disk to match the structure of the default settings + let newPropertyMappings: PropertyMappingModel[] = []; + for (const defaultPropertyMappingModel of defaultSettings.propertyMappingModels) { + let newPropertyMappingModel: PropertyMappingModel = loadedSettings.propertyMappingModels.find(x => x.type === defaultPropertyMappingModel.type); + if (newPropertyMappingModel === undefined) { // if the propertyMappingModel exists in the default settings but not the loaded settings, add it + newPropertyMappings.push(defaultPropertyMappingModel); + } else { // if the propertyMappingModel also exists in the loaded settings, add it from there + let newProperties: PropertyMapping[] = []; + + for (const defaultProperty of defaultPropertyMappingModel.properties) { + let newProperty = newPropertyMappingModel.properties.find(x => x.property === defaultProperty.property); + if (newProperty === undefined) { + newProperties.push(defaultProperty); + } else { + newProperties.push(newProperty); + } + } + + newPropertyMappingModel.properties = newProperties; + + newPropertyMappings.push(newPropertyMappingModel); + } + } + loadedSettings.propertyMappingModels = newPropertyMappings; + + this.settings = loadedSettings; } async saveSettings() { diff --git a/src/models/BoardGameModel.ts b/src/models/BoardGameModel.ts index a2ffad3..bba4f17 100644 --- a/src/models/BoardGameModel.ts +++ b/src/models/BoardGameModel.ts @@ -19,6 +19,15 @@ export class BoardGameModel extends MediaTypeModel { constructor(obj: any = {}) { super(); + this.genres = undefined; + this.onlineRating = undefined; + this.image = undefined; + this.released = undefined; + this.userData = { + played: undefined, + personalRating: undefined, + }; + Object.assign(this, obj); this.type = this.getMediaType(); diff --git a/src/models/GameModel.ts b/src/models/GameModel.ts index 2d2e68c..86332f6 100644 --- a/src/models/GameModel.ts +++ b/src/models/GameModel.ts @@ -4,15 +4,6 @@ import {MediaType} from '../utils/MediaType'; export class GameModel extends MediaTypeModel { - type: string; - subType: string; - title: string; - englishTitle: string; - year: string; - dataSource: string; - url: string; - id: string; - genres: string[]; onlineRating: number; image: string; @@ -29,6 +20,16 @@ export class GameModel extends MediaTypeModel { constructor(obj: any = {}) { super(); + this.genres = undefined; + this.onlineRating = undefined; + this.image = undefined; + this.released = undefined; + this.releaseDate = undefined; + this.userData = { + played: undefined, + personalRating: undefined, + }; + Object.assign(this, obj); this.type = this.getMediaType(); diff --git a/src/models/MediaTypeModel.ts b/src/models/MediaTypeModel.ts index f1c4bd2..fc4f87a 100644 --- a/src/models/MediaTypeModel.ts +++ b/src/models/MediaTypeModel.ts @@ -12,6 +12,19 @@ export abstract class MediaTypeModel { userData: object; + + constructor() { + this.type = undefined; + this.subType = undefined; + this.title = undefined; + this.englishTitle = undefined; + this.year = undefined; + this.dataSource = undefined; + this.url = undefined; + this.id = undefined; + this.userData = {}; + } + abstract getMediaType(): MediaType; //a string that contains enough info to disambiguate from similar media @@ -24,7 +37,7 @@ export abstract class MediaTypeModel { } getWithOutUserData(): object { - const copy = JSON.parse(JSON.stringify(this)); + const copy = Object.assign({}, this); delete copy.userData; return copy; } diff --git a/src/models/MovieModel.ts b/src/models/MovieModel.ts index 4300801..242a0c4 100644 --- a/src/models/MovieModel.ts +++ b/src/models/MovieModel.ts @@ -4,15 +4,6 @@ import {MediaType} from '../utils/MediaType'; export class MovieModel extends MediaTypeModel { - type: string; - subType: string; - title: string; - englishTitle: string; - year: string; - dataSource: string; - url: string; - id: string; - genres: string[]; producer: string; duration: string; @@ -31,6 +22,19 @@ export class MovieModel extends MediaTypeModel { constructor(obj: any = {}) { super(); + this.genres = undefined; + this.producer = undefined; + this.duration = undefined; + this.onlineRating = undefined; + this.image = undefined; + this.released = undefined; + this.premiere = undefined; + this.userData = { + watched: undefined, + lastWatched: undefined, + personalRating: undefined, + }; + Object.assign(this, obj); this.type = this.getMediaType(); diff --git a/src/models/MusicReleaseModel.ts b/src/models/MusicReleaseModel.ts index 2d134b6..42e91e1 100644 --- a/src/models/MusicReleaseModel.ts +++ b/src/models/MusicReleaseModel.ts @@ -24,6 +24,13 @@ export class MusicReleaseModel extends MediaTypeModel { constructor(obj: any = {}) { super(); + this.genres = undefined; + this.artists = undefined; + this.rating = undefined; + this.userData = { + personalRating: undefined, + }; + Object.assign(this, obj); this.type = this.getMediaType(); diff --git a/src/models/SeriesModel.ts b/src/models/SeriesModel.ts index 43fcfae..4fbeaba 100644 --- a/src/models/SeriesModel.ts +++ b/src/models/SeriesModel.ts @@ -34,6 +34,22 @@ export class SeriesModel extends MediaTypeModel { constructor(obj: any = {}) { super(); + this.genres = undefined; + this.studios = undefined; + this.episodes = undefined; + this.duration = undefined; + this.onlineRating = undefined; + this.image = undefined; + this.released = undefined; + this.airing = undefined; + this.airedFrom = undefined; + this.airedTo = undefined; + this.userData = { + watched: undefined, + lastWatched: undefined, + personalRating: undefined, + }; + Object.assign(this, obj); this.type = this.getMediaType(); diff --git a/src/models/WikiModel.ts b/src/models/WikiModel.ts index 3121873..54d756d 100644 --- a/src/models/WikiModel.ts +++ b/src/models/WikiModel.ts @@ -23,6 +23,12 @@ export class WikiModel extends MediaTypeModel { constructor(obj: any = {}) { super(); + this.wikiUrl = undefined; + this.lastUpdated = undefined; + this.length = undefined; + this.article = undefined; + this.userData = {}; + Object.assign(this, obj); this.type = this.getMediaType(); @@ -37,7 +43,7 @@ export class WikiModel extends MediaTypeModel { } override getWithOutUserData(): object { - const copy = JSON.parse(JSON.stringify(this)); + const copy = Object.assign({}, this); delete copy.userData; delete copy.article; return copy; diff --git a/src/settings/Icon.svelte b/src/settings/Icon.svelte new file mode 100644 index 0000000..23f2002 --- /dev/null +++ b/src/settings/Icon.svelte @@ -0,0 +1,36 @@ + + + + + + +{#if iconName.length > 0} +
+
+
+{/if} diff --git a/src/settings/PropertyBindingsComponent.svelte b/src/settings/PropertyBindingsComponent.svelte deleted file mode 100644 index 26770e3..0000000 --- a/src/settings/PropertyBindingsComponent.svelte +++ /dev/null @@ -1,74 +0,0 @@ - - - - -
- { #each models as model } -
{capitalizeFirstLetter(model.type)}
-
- { #each model.properties as property } -
-
-
{property.property}
-
- {#if property.locked} -
- property can not be remapped -
- {:else} - - - {#if property.mapping === PropertyMappingOption.Map} -
- -> -
-
- -
- {/if} - {/if} -
- { /each } -
- { /each } - -
{JSON.stringify(models, null, 4)}
-
diff --git a/src/settings/PropertyMapper.ts b/src/settings/PropertyMapper.ts index 66da472..12aa4e2 100644 --- a/src/settings/PropertyMapper.ts +++ b/src/settings/PropertyMapper.ts @@ -26,7 +26,7 @@ export class PropertyMapper { } // @ts-ignore - const propertyMappings = this.plugin.settings.propertyMappings.find(x => x.type === obj.type).properties; + const propertyMappings = this.plugin.settings.propertyMappingModels.find(x => x.type === obj.type).properties; const newObj: object = {}; @@ -38,7 +38,7 @@ export class PropertyMapper { newObj[propertyMapping.newProperty] = value; } else if (propertyMapping.mapping === PropertyMappingOption.Remove) { - } else if (propertyMapping.mapping === PropertyMappingOption.None) { + } else if (propertyMapping.mapping === PropertyMappingOption.Default) { // @ts-ignore newObj[key] = value; } @@ -67,7 +67,7 @@ export class PropertyMapper { } // @ts-ignore - const propertyMappings = this.plugin.settings.propertyMappings.find(x => x.type === obj.type).properties; + const propertyMappings = this.plugin.settings.propertyMappingModels.find(x => x.type === obj.type).properties; const originalObj: object = {}; diff --git a/src/settings/PropertyMapping.ts b/src/settings/PropertyMapping.ts index 582718f..e68bdfc 100644 --- a/src/settings/PropertyMapping.ts +++ b/src/settings/PropertyMapping.ts @@ -2,12 +2,12 @@ import {containsOnlyLettersAndUnderscores} from '../utils/Utils'; import {MediaType} from '../utils/MediaType'; export enum PropertyMappingOption { - None = 'none', + Default = 'default', Map = 'remap', Remove = 'remove', } -export const propertyMappingOptions = [PropertyMappingOption.None, PropertyMappingOption.Map, PropertyMappingOption.Remove]; +export const propertyMappingOptions = [PropertyMappingOption.Default, PropertyMappingOption.Map, PropertyMappingOption.Remove]; export interface PropertyMappingModel { type: MediaType, @@ -62,7 +62,7 @@ export class PropertyMapping { } toString(): string { - if (this.mapping === PropertyMappingOption.None) { + if (this.mapping === PropertyMappingOption.Default) { return this.property; } else if (this.mapping === PropertyMappingOption.Map) { return `${this.property} -> ${this.newProperty}`; diff --git a/src/settings/PropertyMappingModelsComponent.svelte b/src/settings/PropertyMappingModelsComponent.svelte new file mode 100644 index 0000000..1e14b20 --- /dev/null +++ b/src/settings/PropertyMappingModelsComponent.svelte @@ -0,0 +1,106 @@ + + + + +
+ { #each models as model } +
+
{capitalizeFirstLetter(model.type)}
+
+ { #each model.properties as property } +
+
+
{property.property}
+
+ {#if property.locked} +
+ property can not be remapped +
+ {:else} + + + {#if property.mapping === PropertyMappingOption.Map} + +
+ +
+ {/if} + {/if} +
+ { /each } +
+ +
+ { /each } + +
{JSON.stringify(models, null, 4)}
+ + +
diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index b35ab04..30d31c6 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -1,11 +1,12 @@ -import {App, PluginSettingTab, Setting} from 'obsidian'; +import {App, Notice, PluginSettingTab, Setting} from 'obsidian'; import MediaDbPlugin from '../main'; import {FolderSuggest} from './suggesters/FolderSuggest'; import {FileSuggest} from './suggesters/FileSuggest'; -import PropertyBindingsComponent from './PropertyBindingsComponent.svelte'; +import PropertyMappingModelsComponent from './PropertyMappingModelsComponent.svelte'; import {PropertyMapping, PropertyMappingModel, PropertyMappingOption} from './PropertyMapping'; -import {MediaType} from '../utils/MediaType'; +import {MEDIA_TYPES} from '../utils/MediaTypeManager'; +import {MediaTypeModel} from '../models/MediaTypeModel'; export interface MediaDbPluginSettings { @@ -37,7 +38,7 @@ export interface MediaDbPluginSettings { musicReleasePropertyConversionRules: string, boardgamePropertyConversionRules: string, - propertyMappings: PropertyMappingModel[], + propertyMappingModels: PropertyMappingModel[], } @@ -69,62 +70,96 @@ export const DEFAULT_SETTINGS: MediaDbPluginSettings = { musicReleasePropertyConversionRules: '', boardgamePropertyConversionRules: '', - propertyMappings: [ + propertyMappingModels: [ + /* { type: MediaType.Movie, properties: [ - new PropertyMapping('type', '', PropertyMappingOption.None, true), - new PropertyMapping('subType', '', PropertyMappingOption.None), - new PropertyMapping('title', '', PropertyMappingOption.None), - new PropertyMapping('englishTitle', '', PropertyMappingOption.None), - new PropertyMapping('year', '', PropertyMappingOption.None), - new PropertyMapping('dataSource', '', PropertyMappingOption.None, true), - new PropertyMapping('url', '', PropertyMappingOption.None), - new PropertyMapping('id', '', PropertyMappingOption.None, true), + new PropertyMapping('type', '', PropertyMappingOption.Default, true), + new PropertyMapping('subType', '', PropertyMappingOption.Default), + new PropertyMapping('title', '', PropertyMappingOption.Default), + new PropertyMapping('englishTitle', '', PropertyMappingOption.Default), + new PropertyMapping('year', '', PropertyMappingOption.Default), + new PropertyMapping('dataSource', '', PropertyMappingOption.Default, true), + new PropertyMapping('url', '', PropertyMappingOption.Default), + new PropertyMapping('id', '', PropertyMappingOption.Default, true), - new PropertyMapping('genres', '', PropertyMappingOption.None), - new PropertyMapping('producer', '', PropertyMappingOption.None), - new PropertyMapping('duration', '', PropertyMappingOption.None), - new PropertyMapping('onlineRating', '', PropertyMappingOption.None), - new PropertyMapping('image', '', PropertyMappingOption.None), - new PropertyMapping('released', '', PropertyMappingOption.None), - new PropertyMapping('premiere', '', PropertyMappingOption.None), - new PropertyMapping('watched', '', PropertyMappingOption.None), - new PropertyMapping('lastWatched', '', PropertyMappingOption.None), - new PropertyMapping('personalRating', '', PropertyMappingOption.None), + new PropertyMapping('genres', '', PropertyMappingOption.Default), + new PropertyMapping('producer', '', PropertyMappingOption.Default), + new PropertyMapping('duration', '', PropertyMappingOption.Default), + new PropertyMapping('onlineRating', '', PropertyMappingOption.Default), + new PropertyMapping('image', '', PropertyMappingOption.Default), + new PropertyMapping('released', '', PropertyMappingOption.Default), + new PropertyMapping('premiere', '', PropertyMappingOption.Default), + new PropertyMapping('watched', '', PropertyMappingOption.Default), + new PropertyMapping('lastWatched', '', PropertyMappingOption.Default), + new PropertyMapping('personalRating', '', PropertyMappingOption.Default), ], }, { type: MediaType.Series, properties: [ - new PropertyMapping('type', '', PropertyMappingOption.None, true), - new PropertyMapping('subType', '', PropertyMappingOption.None), - new PropertyMapping('title', '', PropertyMappingOption.None), - new PropertyMapping('englishTitle', '', PropertyMappingOption.None), - new PropertyMapping('year', '', PropertyMappingOption.None), - new PropertyMapping('dataSource', '', PropertyMappingOption.None, true), - new PropertyMapping('url', '', PropertyMappingOption.None), - new PropertyMapping('id', '', PropertyMappingOption.None, true), + new PropertyMapping('type', '', PropertyMappingOption.Default, true), + new PropertyMapping('subType', '', PropertyMappingOption.Default), + new PropertyMapping('title', '', PropertyMappingOption.Default), + new PropertyMapping('englishTitle', '', PropertyMappingOption.Default), + new PropertyMapping('year', '', PropertyMappingOption.Default), + new PropertyMapping('dataSource', '', PropertyMappingOption.Default, true), + new PropertyMapping('url', '', PropertyMappingOption.Default), + new PropertyMapping('id', '', PropertyMappingOption.Default, true), - new PropertyMapping('genres', '', PropertyMappingOption.None), - new PropertyMapping('studios', '', PropertyMappingOption.None), - new PropertyMapping('episodes', '', PropertyMappingOption.None), - new PropertyMapping('duration', '', PropertyMappingOption.None), - new PropertyMapping('onlineRating', '', PropertyMappingOption.None), - new PropertyMapping('image', '', PropertyMappingOption.None), - new PropertyMapping('released', '', PropertyMappingOption.None), - new PropertyMapping('airing', '', PropertyMappingOption.None), - new PropertyMapping('airedFrom', '', PropertyMappingOption.None), - new PropertyMapping('airedTo', '', PropertyMappingOption.None), - new PropertyMapping('watched', '', PropertyMappingOption.None), - new PropertyMapping('lastWatched', '', PropertyMappingOption.None), - new PropertyMapping('personalRating', '', PropertyMappingOption.None), + new PropertyMapping('genres', '', PropertyMappingOption.Default), + new PropertyMapping('studios', '', PropertyMappingOption.Default), + new PropertyMapping('episodes', '', PropertyMappingOption.Default), + new PropertyMapping('duration', '', PropertyMappingOption.Default), + new PropertyMapping('onlineRating', '', PropertyMappingOption.Default), + new PropertyMapping('image', '', PropertyMappingOption.Default), + new PropertyMapping('released', '', PropertyMappingOption.Default), + new PropertyMapping('airing', '', PropertyMappingOption.Default), + new PropertyMapping('airedFrom', '', PropertyMappingOption.Default), + new PropertyMapping('airedTo', '', PropertyMappingOption.Default), + new PropertyMapping('watched', '', PropertyMappingOption.Default), + new PropertyMapping('lastWatched', '', PropertyMappingOption.Default), + new PropertyMapping('personalRating', '', PropertyMappingOption.Default), ], }, + + */ ], }; +export const lockedPropertyMappings: string[] = ['type', 'id', 'dataSource']; + +export function getDefaultSettings(plugin: MediaDbPlugin): MediaDbPluginSettings { + let defaultSettings = DEFAULT_SETTINGS; + + // construct property mapping defaults + const propertyMappingModels: PropertyMappingModel[] = []; + for (const mediaType of MEDIA_TYPES) { + const model: MediaTypeModel = plugin.mediaTypeManager.createMediaTypeModelFromMediaType({}, mediaType); + const metadataObj = model.toMetaDataObject(); + // console.log(metadataObj); + // console.log(model); + + const propertyMappingModel: PropertyMappingModel = { + type: mediaType, + properties: [], + }; + + for (const key of Object.keys(metadataObj)) { + propertyMappingModel.properties.push( + new PropertyMapping(key, '', PropertyMappingOption.Default, lockedPropertyMappings.contains(key)), + ); + } + + propertyMappingModels.push(propertyMappingModel); + } + + defaultSettings.propertyMappingModels = propertyMappingModels; + return defaultSettings; +} + export class MediaDbSettingTab extends PluginSettingTab { plugin: MediaDbPlugin; @@ -433,14 +468,38 @@ export class MediaDbSettingTab extends PluginSettingTab { */ // endregion - console.log(this.plugin.settings.propertyMappings); + console.log(this.plugin.settings.propertyMappingModels); + // console.log(getDefaultSettings(this.plugin)); - new PropertyBindingsComponent({ + let propertyMappingExplanation = containerEl.createEl('div'); + propertyMappingExplanation.innerHTML = `

Allow you to remap the metadata fields of newly created media db entries.

+

+ The different options are: + +

  • "default": does no remapping and keeps the metadata field as it is
  • +
  • "remap": renames the metadata field to what ever you specify
  • +
  • "remove": removes the metadata field entirely
  • + +

    `; + + + new PropertyMappingModelsComponent({ target: this.containerEl, props: { - models: this.plugin.settings.propertyMappings, - save: (models: PropertyMappingModel[]) => { - this.plugin.settings.propertyMappings = models; + models: JSON.parse(JSON.stringify(this.plugin.settings.propertyMappingModels)), + save: (model: PropertyMappingModel) => { + let propertyMappingModels: PropertyMappingModel[] = []; + + for (const model2 of this.plugin.settings.propertyMappingModels) { + if (model2.type === model.type) { + propertyMappingModels.push(model); + } else { + propertyMappingModels.push(model2); + } + } + + this.plugin.settings.propertyMappingModels = propertyMappingModels; + new Notice(`MDB: Property Mappings for ${model.type} saved successfully.`); this.plugin.saveSettings(); }, }, diff --git a/src/settings/suggesters/Suggest.ts b/src/settings/suggesters/Suggest.ts index 366da4b..cd5ce70 100644 --- a/src/settings/suggesters/Suggest.ts +++ b/src/settings/suggesters/Suggest.ts @@ -80,7 +80,7 @@ export class Suggest { } setSelectedItem(selectedIndex: number, scrollIntoView: boolean) { - const normalizedIndex = wrapAround(selectedIndex, this.suggestions.length); + const normalizedIndex = this.suggestions.length > 0 ? wrapAround(selectedIndex, this.suggestions.length) : 0; const prevSelectedSuggestion = this.suggestions[this.selectedItem]; const selectedSuggestion = this.suggestions[normalizedIndex]; diff --git a/src/utils/MediaTypeManager.ts b/src/utils/MediaTypeManager.ts index 08a4f1e..2f88d5e 100644 --- a/src/utils/MediaTypeManager.ts +++ b/src/utils/MediaTypeManager.ts @@ -10,14 +10,13 @@ import {WikiModel} from '../models/WikiModel'; import {MusicReleaseModel} from '../models/MusicReleaseModel'; import {BoardGameModel} from '../models/BoardGameModel'; -export const MEDIA_TYPES = [MediaType.Movie, MediaType.Series, MediaType.Game, MediaType.Wiki, MediaType.MusicRelease, MediaType.BoardGame]; +export const MEDIA_TYPES: MediaType[] = [MediaType.Movie, MediaType.Series, MediaType.Game, MediaType.Wiki, MediaType.MusicRelease, MediaType.BoardGame]; export class MediaTypeManager { mediaFileNameTemplateMap: Map; mediaTemplateMap: Map; - constructor(settings: MediaDbPluginSettings) { - this.updateTemplates(settings); + constructor() { } updateTemplates(settings: MediaDbPluginSettings) { diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index feb99d6..e8f67ac 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -176,3 +176,6 @@ export function capitalizeFirstLetter(string: string): string { return string.charAt(0).toUpperCase() + string.slice(1); } +// credits to phibr0 on discord +export const ICON_LIST = ['activity', 'airplay', 'alarm-check', 'alarm-clock-off', 'alarm-clock', 'alarm-minus', 'alarm-plus', 'album', 'alert-circle', 'alert-octagon', 'alert-triangle', 'align-center-horizontal', 'align-center-vertical', 'align-center', 'align-end-horizontal', 'align-end-vertical', 'align-horizontal-distribute-center', 'align-horizontal-distribute-end', 'align-horizontal-distribute-start', 'align-horizontal-justify-center', 'align-horizontal-justify-end', 'align-horizontal-justify-start', 'align-horizontal-space-around', 'align-horizontal-space-between', 'align-justify', 'align-left', 'align-right', 'align-start-horizontal', 'align-start-vertical', 'align-vertical-distribute-center', 'align-vertical-distribute-end', 'align-vertical-distribute-start', 'align-vertical-justify-center', 'align-vertical-justify-end', 'align-vertical-justify-start', 'align-vertical-space-around', 'align-vertical-space-between', 'anchor', 'aperture', 'archive', 'arrow-big-down', 'arrow-big-left', 'arrow-big-right', 'arrow-big-up', 'arrow-down-circle', 'arrow-down-left', 'arrow-down-right', 'arrow-down', 'arrow-left-circle', 'arrow-left-right', 'arrow-left', 'arrow-right-circle', 'arrow-right', 'arrow-up-circle', 'arrow-up-left', 'arrow-up-right', 'arrow-up', 'asterisk', 'at-sign', 'award', 'axe', 'banknote', 'bar-chart-2', 'bar-chart', 'baseline', 'battery-charging', 'battery-full', 'battery-low', 'battery-medium', 'battery', 'beaker', 'bell-minus', 'bell-off', 'bell-plus', 'bell-ring', 'bell', 'bike', 'binary', 'bitcoin', 'bluetooth-connected', 'bluetooth-off', 'bluetooth-searching', 'bluetooth', 'bold', 'book-open', 'book', 'bookmark-minus', 'bookmark-plus', 'bookmark', 'bot', 'box-select', 'box', 'briefcase', 'brush', 'bug', 'building-2', 'building', 'bus', 'calculator', 'calendar', 'camera-off', 'camera', 'car', 'carrot', 'cast', 'check-circle-2', 'check-circle', 'check-square', 'check', 'chevron-down', 'chevron-first', 'chevron-last', 'chevron-left', 'chevron-right', 'chevron-up', 'chevrons-down-up', 'chevrons-down', 'chevrons-left', 'chevrons-right', 'chevrons-up-down', 'chevrons-up', 'chrome', 'circle-slashed', 'circle', 'clipboard-check', 'clipboard-copy', 'clipboard-list', 'clipboard-x', 'clipboard', 'clock-1', 'clock-10', 'clock-11', 'clock-12', 'clock-2', 'clock-3', 'clock-4', 'clock-5', 'clock-6', 'clock-7', 'clock-8', 'clock-9', 'clock', 'cloud-drizzle', 'cloud-fog', 'cloud-hail', 'cloud-lightning', 'cloud-moon', 'cloud-off', 'cloud-rain-wind', 'cloud-rain', 'cloud-snow', 'cloud-sun', 'cloud', 'cloudy', 'clover', 'code-2', 'code', 'codepen', 'codesandbox', 'coffee', 'coins', 'columns', 'command', 'compass', 'contact', 'contrast', 'cookie', 'copy', 'copyleft', 'copyright', 'corner-down-left', 'corner-down-right', 'corner-left-down', 'corner-left-up', 'corner-right-down', 'corner-right-up', 'corner-up-left', 'corner-up-right', 'cpu', 'credit-card', 'crop', 'cross', 'crosshair', 'crown', 'currency', 'database', 'delete', 'dice-1', 'dice-2', 'dice-3', 'dice-4', 'dice-5', 'dice-6', 'disc', 'divide-circle', 'divide-square', 'divide', 'dollar-sign', 'download-cloud', 'download', 'dribbble', 'droplet', 'droplets', 'drumstick', 'edit-2', 'edit-3', 'edit', 'egg', 'equal-not', 'equal', 'eraser', 'euro', 'expand', 'external-link', 'eye-off', 'eye', 'facebook', 'fast-forward', 'feather', 'figma', 'file-check-2', 'file-check', 'file-code', 'file-digit', 'file-input', 'file-minus-2', 'file-minus', 'file-output', 'file-plus-2', 'file-plus', 'file-search', 'file-text', 'file-x-2', 'file-x', 'file', 'files', 'film', 'filter', 'flag-off', 'flag-triangle-left', 'flag-triangle-right', 'flag', 'flame', 'flashlight-off', 'flashlight', 'flask-conical', 'flask-round', 'folder-minus', 'folder-open', 'folder-plus', 'folder', 'form-input', 'forward', 'frame', 'framer', 'frown', 'function-square', 'gamepad-2', 'gamepad', 'gauge', 'gavel', 'gem', 'ghost', 'gift', 'git-branch-plus', 'git-branch', 'git-commit', 'git-fork', 'git-merge', 'git-pull-request', 'github', 'gitlab', 'glasses', 'globe-2', 'globe', 'grab', 'graduation-cap', 'grid', 'grip-horizontal', 'grip-vertical', 'hammer', 'hand-metal', 'hand', 'hard-drive', 'hard-hat', 'hash', 'haze', 'headphones', 'heart', 'help-circle', 'hexagon', 'highlighter', 'history', 'home', 'image-minus', 'image-off', 'image-plus', 'image', 'import', 'inbox', 'indent', 'indian-rupee', 'infinity', 'info', 'inspect', 'instagram', 'italic', 'japanese-yen', 'key', 'keyboard', 'landmark', 'languages', 'laptop-2', 'laptop', 'lasso-select', 'lasso', 'layers', 'layout-dashboard', 'layout-grid', 'layout-list', 'layout-template', 'layout', 'library', 'life-buoy', 'lightbulb-off', 'lightbulb', 'link-2-off', 'link-2', 'link', 'linkedin', 'list-checks', 'list-minus', 'list-ordered', 'list-plus', 'list-x', 'list', 'loader-2', 'loader', 'locate-fixed', 'locate-off', 'locate', 'lock', 'log-in', 'log-out', 'mail', 'map-pin', 'map', 'maximize-2', 'maximize', 'megaphone', 'meh', 'menu', 'message-circle', 'message-square', 'mic-off', 'mic', 'minimize-2', 'minimize', 'minus-circle', 'minus-square', 'minus', 'monitor-off', 'monitor-speaker', 'monitor', 'moon', 'more-horizontal', 'more-vertical', 'mountain-snow', 'mountain', 'mouse-pointer-2', 'mouse-pointer-click', 'mouse-pointer', 'mouse', 'move-diagonal-2', 'move-diagonal', 'move-horizontal', 'move-vertical', 'move', 'music', 'navigation-2', 'navigation', 'network', 'octagon', 'option', 'outdent', 'package-check', 'package-minus', 'package-plus', 'package-search', 'package-x', 'package', 'palette', 'palmtree', 'paperclip', 'pause-circle', 'pause-octagon', 'pause', 'pen-tool', 'pencil', 'percent', 'person-standing', 'phone-call', 'phone-forwarded', 'phone-incoming', 'phone-missed', 'phone-off', 'phone-outgoing', 'phone', 'pie-chart', 'piggy-bank', 'pin', 'pipette', 'plane', 'play-circle', 'play', 'plug-zap', 'plus-circle', 'plus-square', 'plus', 'pocket', 'podcast', 'pointer', 'pound-sterling', 'power-off', 'power', 'printer', 'qr-code', 'quote', 'radio-receiver', 'radio', 'redo', 'refresh-ccw', 'refresh-cw', 'regex', 'repeat-1', 'repeat', 'reply-all', 'reply', 'rewind', 'rocket', 'rocking-chair', 'rotate-ccw', 'rotate-cw', 'rss', 'ruler', 'russian-ruble', 'save', 'scale', 'scan-line', 'scan', 'scissors', 'screen-share-off', 'screen-share', 'search', 'send', 'separator-horizontal', 'separator-vertical', 'server-crash', 'server-off', 'server', 'settings-2', 'settings', 'share-2', 'share', 'sheet', 'shield-alert', 'shield-check', 'shield-close', 'shield-off', 'shield', 'shirt', 'shopping-bag', 'shopping-cart', 'shovel', 'shrink', 'shuffle', 'sidebar-close', 'sidebar-open', 'sidebar', 'sigma', 'signal-high', 'signal-low', 'signal-medium', 'signal-zero', 'signal', 'skip-back', 'skip-forward', 'skull', 'slack', 'slash', 'sliders', 'smartphone-charging', 'smartphone', 'smile', 'snowflake', 'sort-asc', 'sort-desc', 'speaker', 'sprout', 'square', 'star-half', 'star', 'stop-circle', 'stretch-horizontal', 'stretch-vertical', 'strikethrough', 'subscript', 'sun', 'sunrise', 'sunset', 'superscript', 'swiss-franc', 'switch-camera', 'table', 'tablet', 'tag', 'target', 'tent', 'terminal-square', 'terminal', 'text-cursor-input', 'text-cursor', 'thermometer-snowflake', 'thermometer-sun', 'thermometer', 'thumbs-down', 'thumbs-up', 'ticket', 'timer-off', 'timer-reset', 'timer', 'toggle-left', 'toggle-right', 'tornado', 'trash-2', 'trash', 'trello', 'trending-down', 'trending-up', 'triangle', 'truck', 'tv-2', 'tv', 'twitch', 'twitter', 'type', 'umbrella', 'underline', 'undo', 'unlink-2', 'unlink', 'unlock', 'upload-cloud', 'upload', 'user-check', 'user-minus', 'user-plus', 'user-x', 'user', 'users', 'verified', 'vibrate', 'video-off', 'video', 'view', 'voicemail', 'volume-1', 'volume-2', 'volume-x', 'volume', 'wallet', 'wand', 'watch', 'waves', 'webcam', 'wifi-off', 'wifi', 'wind', 'wrap-text', 'wrench', 'x-circle', 'x-octagon', 'x-square', 'x', 'youtube', 'zap-off', 'zap', 'zoom-in', 'zoom-out', 'search-large', 'search', 'activity', 'airplay', 'alarm-check', 'alarm-clock-off', 'alarm-clock', 'alarm-minus', 'alarm-plus', 'album', 'alert-circle', 'alert-octagon', 'alert-triangle', 'align-center-horizontal', 'align-center-vertical', 'align-center', 'align-end-horizontal', 'align-end-vertical', 'align-horizontal-distribute-center', 'align-horizontal-distribute-end', 'align-horizontal-distribute-start', 'align-horizontal-justify-center', 'align-horizontal-justify-end', 'align-horizontal-justify-start', 'align-horizontal-space-around', 'align-horizontal-space-between', 'align-justify', 'align-left', 'align-right', 'align-start-horizontal', 'align-start-vertical', 'align-vertical-distribute-center', 'align-vertical-distribute-end', 'align-vertical-distribute-start', 'align-vertical-justify-center', 'align-vertical-justify-end', 'align-vertical-justify-start', 'align-vertical-space-around', 'align-vertical-space-between', 'anchor', 'aperture', 'archive', 'arrow-big-down', 'arrow-big-left', 'arrow-big-right', 'arrow-big-up', 'arrow-down-circle', 'arrow-down-left', 'arrow-down-right', 'arrow-down', 'arrow-left-circle', 'arrow-left-right', 'arrow-left', 'arrow-right-circle', 'arrow-right', 'arrow-up-circle', 'arrow-up-left', 'arrow-up-right', 'arrow-up', 'asterisk', 'at-sign', 'award', 'axe', 'banknote', 'bar-chart-2', 'bar-chart', 'baseline', 'battery-charging', 'battery-full', 'battery-low', 'battery-medium', 'battery', 'beaker', 'bell-minus', 'bell-off', 'bell-plus', 'bell-ring', 'bell', 'bike', 'binary', 'bitcoin', 'bluetooth-connected', 'bluetooth-off', 'bluetooth-searching', 'bluetooth', 'bold', 'book-open', 'book', 'bookmark-minus', 'bookmark-plus', 'bookmark', 'bot', 'box-select', 'box', 'briefcase', 'brush', 'bug', 'building-2', 'building', 'bus', 'calculator', 'calendar', 'camera-off', 'camera', 'car', 'carrot', 'cast', 'check-circle-2', 'check-circle', 'check-square', 'check', 'chevron-down', 'chevron-first', 'chevron-last', 'chevron-left', 'chevron-right', 'chevron-up', 'chevrons-down-up', 'chevrons-down', 'chevrons-left', 'chevrons-right', 'chevrons-up-down', 'chevrons-up', 'chrome', 'circle-slashed', 'circle', 'clipboard-check', 'clipboard-copy', 'clipboard-list', 'clipboard-x', 'clipboard', 'clock-1', 'clock-10', 'clock-11', 'clock-12', 'clock-2', 'clock-3', 'clock-4', 'clock-5', 'clock-6', 'clock-7', 'clock-8', 'clock-9', 'lucide-clock', 'cloud-drizzle', 'cloud-fog', 'cloud-hail', 'cloud-lightning', 'cloud-moon', 'cloud-off', 'cloud-rain-wind', 'cloud-rain', 'cloud-snow', 'cloud-sun', 'lucide-cloud', 'cloudy', 'clover', 'code-2', 'code', 'codepen', 'codesandbox', 'coffee', 'coins', 'columns', 'command', 'compass', 'contact', 'contrast', 'cookie', 'copy', 'copyleft', 'copyright', 'corner-down-left', 'corner-down-right', 'corner-left-down', 'corner-left-up', 'corner-right-down', 'corner-right-up', 'corner-up-left', 'corner-up-right', 'cpu', 'credit-card', 'crop', 'lucide-cross', 'crosshair', 'crown', 'currency', 'database', 'delete', 'dice-1', 'dice-2', 'dice-3', 'dice-4', 'dice-5', 'dice-6', 'disc', 'divide-circle', 'divide-square', 'divide', 'dollar-sign', 'download-cloud', 'download', 'dribbble', 'droplet', 'droplets', 'drumstick', 'edit-2', 'edit-3', 'edit', 'egg', 'equal-not', 'equal', 'eraser', 'euro', 'expand', 'external-link', 'eye-off', 'eye', 'facebook', 'fast-forward', 'feather', 'figma', 'file-check-2', 'file-check', 'file-code', 'file-digit', 'file-input', 'file-minus-2', 'file-minus', 'file-output', 'file-plus-2', 'file-plus', 'file-search', 'file-text', 'file-x-2', 'file-x', 'file', 'files', 'film', 'filter', 'flag-off', 'flag-triangle-left', 'flag-triangle-right', 'flag', 'flame', 'flashlight-off', 'flashlight', 'flask-conical', 'flask-round', 'folder-minus', 'folder-open', 'folder-plus', 'lucide-folder', 'form-input', 'forward', 'frame', 'framer', 'frown', 'function-square', 'gamepad-2', 'gamepad', 'gauge', 'gavel', 'gem', 'ghost', 'gift', 'git-branch-plus', 'git-branch', 'git-commit', 'git-fork', 'git-merge', 'git-pull-request', 'github', 'gitlab', 'glasses', 'globe-2', 'globe', 'grab', 'graduation-cap', 'grid', 'grip-horizontal', 'grip-vertical', 'hammer', 'hand-metal', 'hand', 'hard-drive', 'hard-hat', 'hash', 'haze', 'headphones', 'heart', 'help-circle', 'hexagon', 'highlighter', 'history', 'home', 'image-minus', 'image-off', 'image-plus', 'image', 'import', 'inbox', 'indent', 'indian-rupee', 'infinity', 'lucide-info', 'inspect', 'instagram', 'italic', 'japanese-yen', 'key', 'keyboard', 'landmark', 'lucide-languages', 'laptop-2', 'laptop', 'lasso-select', 'lasso', 'layers', 'layout-dashboard', 'layout-grid', 'layout-list', 'layout-template', 'layout', 'library', 'life-buoy', 'lightbulb-off', 'lightbulb', 'link-2-off', 'link-2', 'lucide-link', 'linkedin', 'list-checks', 'list-minus', 'list-ordered', 'list-plus', 'list-x', 'list', 'loader-2', 'loader', 'locate-fixed', 'locate-off', 'locate', 'lock', 'log-in', 'log-out', 'mail', 'map-pin', 'map', 'maximize-2', 'maximize', 'megaphone', 'meh', 'menu', 'message-circle', 'message-square', 'mic-off', 'mic', 'minimize-2', 'minimize', 'minus-circle', 'minus-square', 'minus', 'monitor-off', 'monitor-speaker', 'monitor', 'moon', 'more-horizontal', 'more-vertical', 'mountain-snow', 'mountain', 'mouse-pointer-2', 'mouse-pointer-click', 'mouse-pointer', 'mouse', 'move-diagonal-2', 'move-diagonal', 'move-horizontal', 'move-vertical', 'move', 'music', 'navigation-2', 'navigation', 'network', 'octagon', 'option', 'outdent', 'package-check', 'package-minus', 'package-plus', 'package-search', 'package-x', 'package', 'palette', 'palmtree', 'paperclip', 'pause-circle', 'pause-octagon', 'pause', 'pen-tool', 'lucide-pencil', 'percent', 'person-standing', 'phone-call', 'phone-forwarded', 'phone-incoming', 'phone-missed', 'phone-off', 'phone-outgoing', 'phone', 'pie-chart', 'piggy-bank', 'lucide-pin', 'pipette', 'plane', 'play-circle', 'play', 'plug-zap', 'plus-circle', 'plus-square', 'plus', 'pocket', 'podcast', 'pointer', 'pound-sterling', 'power-off', 'power', 'printer', 'qr-code', 'quote', 'radio-receiver', 'radio', 'redo', 'refresh-ccw', 'refresh-cw', 'regex', 'repeat-1', 'repeat', 'reply-all', 'reply', 'rewind', 'rocket', 'rocking-chair', 'rotate-ccw', 'rotate-cw', 'rss', 'ruler', 'russian-ruble', 'save', 'scale', 'scan-line', 'scan', 'scissors', 'screen-share-off', 'screen-share', 'lucide-search', 'send', 'separator-horizontal', 'separator-vertical', 'server-crash', 'server-off', 'server', 'settings-2', 'settings', 'share-2', 'share', 'sheet', 'shield-alert', 'shield-check', 'shield-close', 'shield-off', 'shield', 'shirt', 'shopping-bag', 'shopping-cart', 'shovel', 'shrink', 'shuffle', 'sidebar-close', 'sidebar-open', 'sidebar', 'sigma', 'signal-high', 'signal-low', 'signal-medium', 'signal-zero', 'signal', 'skip-back', 'skip-forward', 'skull', 'slack', 'slash', 'sliders', 'smartphone-charging', 'smartphone', 'smile', 'snowflake', 'sort-asc', 'sort-desc', 'speaker', 'sprout', 'square', 'star-half', 'lucide-star', 'stop-circle', 'stretch-horizontal', 'stretch-vertical', 'strikethrough', 'subscript', 'sun', 'sunrise', 'sunset', 'superscript', 'swiss-franc', 'switch-camera', 'table', 'tablet', 'tag', 'target', 'tent', 'terminal-square', 'terminal', 'text-cursor-input', 'text-cursor', 'thermometer-snowflake', 'thermometer-sun', 'thermometer', 'thumbs-down', 'thumbs-up', 'ticket', 'timer-off', 'timer-reset', 'timer', 'toggle-left', 'toggle-right', 'tornado', 'trash-2', 'lucide-trash', 'trello', 'trending-down', 'trending-up', 'triangle', 'truck', 'tv-2', 'tv', 'twitch', 'twitter', 'type', 'umbrella', 'underline', 'undo', 'unlink-2', 'unlink', 'unlock', 'upload-cloud', 'upload', 'user-check', 'user-minus', 'user-plus', 'user-x', 'user', 'users', 'verified', 'vibrate', 'video-off', 'video', 'view', 'voicemail', 'volume-1', 'volume-2', 'volume-x', 'volume', 'wallet', 'wand', 'watch', 'waves', 'webcam', 'wifi-off', 'wifi', 'wind', 'wrap-text', 'wrench', 'x-circle', 'x-octagon', 'x-square', 'x', 'youtube', 'zap-off', 'zap', 'zoom-in', 'zoom-out', 'search-large', 'lucide-search']; +