From c45664b53b285a11e762fef7605d41271925aec5 Mon Sep 17 00:00:00 2001 From: "kbuffington@gmail.com" Date: Wed, 6 Jan 2021 20:09:41 -0600 Subject: [PATCH] Fixing issues with configuration and renamed globals.js to settings.js --- georgia-theme.js | 4 +- js/configuration.js | 42 +++++++++++---- js/georgia-main.js | 38 +++++++------ js/helpers.js | 2 +- js/{globals.js => settings.js} | 99 ++++++++++++++++++++-------------- js/themes.js | 24 ++++----- 6 files changed, 124 insertions(+), 85 deletions(-) rename js/{globals.js => settings.js} (83%) diff --git a/georgia-theme.js b/georgia-theme.js index 554d40a6..be4a70df 100644 --- a/georgia-theme.js +++ b/georgia-theme.js @@ -28,8 +28,8 @@ includeFiles([ 'js\\configuration.js', // reads/write from config file. The actual configuration values are specified in globals.js 'js\\helpers.js', 'js\\CaTRoX_QWR\\Common.js', - 'js\\hyperlinks.js', // used in globals.js - 'js\\globals.js', // if we stop using PanelProperties can move this above Common.js + 'js\\hyperlinks.js', // used in settings.js + 'js\\settings.js', // must be below hyperlinks.js and Common.js 'js\\CaTRoX_QWR\\Utility_LinkedList.js', 'js\\CaTRoX_QWR\\Control_ContextMenu.js', 'js\\CaTRoX_QWR\\Control_Scrollbar.js', diff --git a/js/configuration.js b/js/configuration.js index 2a0f6dd2..39b2b7de 100644 --- a/js/configuration.js +++ b/js/configuration.js @@ -1,6 +1,7 @@ const ConfigurationObjectType = { Array: 'array', Object: 'object', + Value: 'value' // not currently handled }; /** @@ -13,7 +14,7 @@ class ConfigurationObjectSchema { /** * @param {string} name The name to be used for the object in the configuration file. i.e. if the object is `grid: {}`, then name should be `'grid'` * @param {string} container The type of container for the object. Should be of ConfigurationObjectType. - * @param {Array=} fields The fields for each entry in the object. If undefined, uses key/value pairs. + * @param {Array=} fields The fields for each entry in the object. If undefined, uses key/value pairs for objects, or comma separated values for arrays. * @param {string=} comment Adds a '//' field as first entry in the object. Used for explaining things to the user. */ constructor(name, container, fields = undefined, comment = undefined) { @@ -112,7 +113,8 @@ class Configuration { return config; } catch (e) { - throw new ThemeError(``) + throw new ThemeError(``) } } @@ -127,11 +129,24 @@ class Configuration { p.WriteLine(' on the next reload. To ensure changes are not lost, reload the theme immediately'); p.WriteLine(' after manually changing values. */'); p.WriteLine('{'); + p.WriteLine(`\t"version": "${currentVersion}",`) this._configuration.forEach((conf, i) => { const container = conf.definition.container === ConfigurationObjectType.Array ? '[' : '{'; p.WriteLine(`\t"${conf.definition.name}": ${container}`); if (conf.definition.comment) { - p.WriteLine(`\t\t// ${conf.definition.comment}`); + let line = conf.definition.comment; + let done = false; + while (!done) { + const lineLen = 100; + if (line.length < lineLen) { + p.WriteLine(`\t\t// ${line.trim()}`); + done = true; + } else { + const idx = line.lastIndexOf(' ', lineLen); + p.WriteLine(`\t\t// ${line.substr(0, idx).trim()}`); + line = line.substr(idx); + } + } } if (conf.definition.fields) { // array of fields @@ -150,13 +165,20 @@ class Configuration { p.WriteLine(`\t\t${entry}${i < conf.values.length - 1 ? ',' : ''}${comment}`); } } else { - // object with key/value pairs - const keys = Object.keys(conf.values); - keys.forEach((key, i) => { - const comment = conf.comments[key] ? ` // ${conf.comments[key]}` : ''; - const quotes = typeof conf.values[key] === 'string' ? '"': ''; - p.WriteLine(`\t\t"${key}": ${quotes}${conf.values[key]}${quotes}${i < keys.length - 1 ? ',' : ''}${comment}`) - }); + if (conf.definition.container === ConfigurationObjectType.Array) { + // array of comma separated entries + conf.values.forEach((val, i) => { + p.WriteLine(`\t\t"${val.replace(/\\/g, '\\\\')}"${i < conf.values.length - 1 ? ',' : ''}`); + }) + } else { + // object with key/value pairs + const keys = Object.keys(conf.values); + keys.forEach((key, i) => { + const comment = conf.comments[key] ? ` // ${conf.comments[key]}` : ''; + const quotes = typeof conf.values[key] === 'string' ? '"': ''; + p.WriteLine(`\t\t"${key}": ${quotes}${conf.values[key]}${quotes}${i < keys.length - 1 ? ',' : ''}${comment}`) + }); + } } const closeContainer = conf.definition.container === ConfigurationObjectType.Array ? ']' : '}'; p.WriteLine(`\t${closeContainer}${i < this._configuration.length - 1 ? ',' : ''}`); diff --git a/js/georgia-main.js b/js/georgia-main.js index e09f0e4e..c5b739f3 100644 --- a/js/georgia-main.js +++ b/js/georgia-main.js @@ -1159,10 +1159,10 @@ function onOptionsMenu(x, y) { menu.addSeparator(); const debugMenu = new Menu('Debug Settings'); - debugMenu.addToggleItem('Enable debug output', pref, 'show_debug_log'); - debugMenu.addItem('Enable theme debug output', pref.show_theme_log, () => { - pref.show_theme_log = !pref.show_theme_log; - if (pref.show_theme_log) { + debugMenu.addToggleItem('Enable debug output', settings, 'showDebugLog'); + debugMenu.addItem('Enable theme debug output', settings.showThemeLog, () => { + settings.showThemeLog = !settings.showThemeLog; + if (settings.showThemeLog) { albumart = null; on_playback_new_track(fb.GetNowPlaying()); } @@ -1175,7 +1175,7 @@ function onOptionsMenu(x, y) { menu.addSeparator(); - menu.addToggleItem('Lock right click...', pref, 'locked'); + menu.addToggleItem('Lock right click...', settings, 'locked'); menu.addItem('Restart foobar', false, () => { fb.RunMainMenuCommand("File/Restart"); }); var idx = menu.trackPopupMenu(x, y); @@ -1497,10 +1497,10 @@ function on_metadb_changed(handle_list, fromhook) { str.length = (h > 0 ? h + ":" + (m < 10 ? "0" : '') + m : m) + ":" + (s < 10 ? "0" : '') + s; str.grid = []; - for (let k = 0; k < tf.grid.length; k++) { - let val = $(tf.grid[k].val); - if (val && tf.grid[k].label) { - if (tf.grid[k].age) { + for (let k = 0; k < metadataGrid.length; k++) { + let val = $(metadataGrid[k].val); + if (val && metadataGrid[k].label) { + if (metadataGrid[k].age) { val = $('$date(' + val + ')'); // never show time var age = calcAgeDateString(val); if (age) { @@ -1508,8 +1508,8 @@ function on_metadb_changed(handle_list, fromhook) { } } str.grid.push({ - age: tf.grid[k].age, - label: tf.grid[k].label, + age: metadataGrid[k].age, + label: metadataGrid[k].label, val: val, }); } @@ -1673,7 +1673,7 @@ function on_mouse_rbtn_up(x, y, m) { trace_call && console.log(qwr_utils.function_name()); return library.on_mouse_rbtn_up(x, y, m); } else - return pref.locked; + return settings.locked; } function on_mouse_move(x, y, m) { @@ -1683,7 +1683,7 @@ function on_mouse_move(x, y, m) { state.mouse_x = x; state.mouse_y = y; - if (settings.hide_cursor) { + if (settings.hideCursor) { clearTimeout(hideCursorTimer); hideCursorTimer = setTimeout(() => { // if there's a menu id (i.e. a menu is down) we don't want the cursor to ever disappear @@ -1962,7 +1962,7 @@ function on_playback_stop(reason) { } function on_playback_starting(cmd, is_paused) { - if (settings.hide_cursor) { + if (settings.hideCursor) { window.SetCursor(-1); // hide cursor } refreshPlayButton(); @@ -2537,13 +2537,11 @@ function fetchNewArtwork(metadb) { getThemeColors(albumart); ResizeArtwork(true); } else { - for (let k = 0; k < tf.glob_paths.length; k++) { - aa_list = aa_list.concat(utils.Glob($(tf.glob_paths[k]))); - } - const pattern = new RegExp('(cd|vinyl|' + settings.cdart_basename + ')([0-9]*|[a-h])\.png', 'i'); - const imageTest = /jpg|png$/i; + aa_list = tf.imgPaths.map(path => utils.Glob($(path))).flat(); + const pattern = new RegExp('(cd|vinyl|' + settings.cdArtBasename + ')([0-9]*|[a-h])\.png', 'i'); + const imageType = /jpg|png$/i; // remove duplicates and cd/vinyl art and make sure all files are jpg or pngs - aa_list = [... new Set(aa_list)].filter(path => !pattern.test(path) && imageTest.test(path)); + aa_list = [... new Set(aa_list)].filter(path => !pattern.test(path) && imageType.test(path)); if (aa_list.length) { noArtwork = false; diff --git a/js/helpers.js b/js/helpers.js index 7c5687c9..feea8ace 100644 --- a/js/helpers.js +++ b/js/helpers.js @@ -55,7 +55,7 @@ function getMetaValues(name, metadb = undefined) { * @type {function(...*):void} var_args */ const debugLog = (var_args) => { - if (pref.show_debug_log) console.log(var_args); + if (settings.showDebugLog) console.log(var_args); } /** diff --git a/js/globals.js b/js/settings.js similarity index 83% rename from js/globals.js rename to js/settings.js index ad71f73a..a231f34c 100644 --- a/js/globals.js +++ b/js/settings.js @@ -29,7 +29,6 @@ globals.add_properties({ // THEME PREFERENCES/PROPERTIES EXPLANATIONS - After initial run, these values are changed in Options Menu or by Right Click >> Properties and not here! pref.add_properties({ - // locked: ['Lock theme', false], // true: prevent changing theme with right click rotation_amt: ['Art: Degrees to rotate CDart', 3], // # of degrees to rotate per track change. aa_glob: ['Art: Cycle through all images', true], // true: use glob, false: use albumart reader (front only) display_cdart: ['Art: Display CD art', true], // true: show CD artwork behind album artwork. This artwork is expected to be named cd.png and have transparent backgrounds (can be found at fanart.tv) @@ -37,9 +36,6 @@ pref.add_properties({ rotate_cdart: ['Art: Rotate CD art on new track', true], // true: rotate cdArt based on track number. i.e. rotationAmt = %tracknum% * x degrees cdart_ontop: ['Art: Show CD art above front cover', false], // true: display cdArt above front cover labelArtOnBg: ['Art: Draw label art on background', false], // true: don't show the theme color background behind label art - show_debug_log: ['Debug: Show Debug Output', false], // true: show debug output in console - show_theme_log: ['Debug: Show Theme Logging', false], // true: show theme logging in console - hide_cursor: ['Hide Cursor when stationary', false], // true: hide cursor when not moving, false: don't show_flags: ['Show country flags', true], // true: show the artist country flags // check_multich: ['Check for MultiChannel version', false], // true: search paths in tf.MultiCh_paths to see if there is a multichannel version of the current album available use_vinyl_nums: ['Use vinyl style numbering (e.g. A1)', true], // true: if the tags specified in tf.vinyl_side and tf.vinyl_tracknum are set, then we'll show vinyl style track numbers (i.e. "B2." instead of "04.") @@ -113,14 +109,14 @@ const titleFormatComments = { year: 'Just the year portion of any stored date.', } const titleFormatSchema = new ConfigurationObjectSchema('title_format_strings', ConfigurationObjectType.Object, undefined, - 'Title formatting fields, used throughout the display. Do NOT change the key names.'); + 'Title formatting strings, used throughout the display. Do NOT change the key names or add new ones.'); // TEXT FIELDS var stoppedStr1 = 'foobar2000'; var stoppedStr2 = 'plays music'; var stoppedTime = 'Georgia v' + currentVersion; -/* My ridiculous artist string: +/* My old ridiculous artist string: $ifgreater($meta_num(ArtistFilter),1,$puts(mArtist,$meta(ArtistFilter,0))$if($put(comma,$sub($strstr($get(mArtist),', '),1)),$puts(mArtist,$substr($get(mArtist),$add($get(comma),3),$len($get(mArtist))) $substr($get(mArtist),0,$get(comma))),)\ $if($get(mArtist),$if($or($stricmp($get(mArtist),'Soundtrack'),$stricmp($get(mArtist),'Various Artists')),,$get(mArtist)\ $if($stricmp($get(mArtist),%artist%),$puts(feat,1),)\ @@ -135,17 +131,18 @@ $if($get(mArtist),$if($or($stricmp($get(mArtist),'Soundtrack'),$stricmp($get(mAr )))))))))),%artist%); In one line for adding to config file: -$puts(AF,$ifgreater($meta_num(ArtistFilter),1,$puts(mArtist,$meta(ArtistFilter,0))$if($put(comma,$sub($strstr($get(mArtist),', '),1)),$puts(mArtist,$substr($get(mArtist),$add($get(comma),3),$len($get(mArtist))) $substr($get(mArtist),0,$get(comma))),)$if($get(mArtist),$if($or($stricmp($get(mArtist),'Soundtrack'),$stricmp($get(mArtist),'Various Artists')),,$get(mArtist)$if($stricmp($get(mArtist),%artist%),$puts(feat,1),)$puts(mArtist,$meta(ArtistFilter,1))$if($put(comma,$sub($strstr($get(mArtist),', '),1)),$puts(mArtist,$substr($get(mArtist),$add($get(comma),3),$len($get(mArtist))) $substr($get(mArtist),0,$get(comma))),)$if($get(mArtist),$if($or($stricmp($get(mArtist),'Soundtrack'),$stricmp($get(mArtist),'Various Artists')),,$if($get(feat), feat. ,', ')$get(mArtist)$puts(mArtist,$meta(ArtistFilter,2))$if($put(comma,$sub($strstr($get(mArtist),', '),1)),$puts(mArtist,$substr($get(mArtist),$add($get(comma),3),$len($get(mArtist))) $substr($get(mArtist),0,$get(comma))),)$if($get(mArtist),$if($or($stricmp($get(mArtist),'Soundtrack'),$stricmp($get(mArtist),'Various Artists')),,$ifequal($meta_num(ArtistFilter),3,' & ',', ')$get(mArtist)$puts(mArtist,$meta(ArtistFilter,3))$if($put(comma,$sub($strstr($get(mArtist),', '),1)),$puts(mArtist,$substr($get(mArtist),$add($get(comma),3),$len($get(mArtist))) $substr($get(mArtist),0,$get(comma))),)$if($get(mArtist),$if($or($stricmp($get(mArtist),'Soundtrack'),$stricmp($get(mArtist),'Various Artists')),,$ifequal($meta_num(ArtistFilter),4,' & ',', ')$get(mArtist)$puts(mArtist,$meta(ArtistFilter,4))$if($put(comma,$sub($strstr($get(mArtist),', '),1)),$puts(mArtist,$substr($get(mArtist),$add($get(comma),3),$len($get(mArtist))) $substr($get(mArtist),0,$get(comma))),)$if($get(mArtist),$if($or($stricmp($get(mArtist),'Soundtrack'),$stricmp($get(mArtist),'Various Artists')),,$ifequal($meta_num(ArtistFilter),5,' & ',', ')$get(mArtist))))))))))),%artist%)) +$puts(AF,$ifgreater($meta_num(ArtistFilter),1,$puts(mArtist,$meta(ArtistFilter,0))$if($put(comma,$sub($strstr($get(mArtist),', '),1)),$puts(mArtist,$substr($get(mArtist),$add($get(comma),3),$len($get(mArtist))) $substr($get(mArtist),0,$get(comma))),)$if($get(mArtist),$if($or($stricmp($get(mArtist),'Soundtrack'),$stricmp($get(mArtist),'Various Artists')),,$get(mArtist)$if($stricmp($get(mArtist),%artist%),$puts(feat,1),)$puts(mArtist,$meta(ArtistFilter,1))$if($put(comma,$sub($strstr($get(mArtist),', '),1)),$puts(mArtist,$substr($get(mArtist),$add($get(comma),3),$len($get(mArtist))) $substr($get(mArtist),0,$get(comma))),)$if($get(mArtist),$if($or($stricmp($get(mArtist),'Soundtrack'),$stricmp($get(mArtist),'Various Artists')),,$if($get(feat), feat. ,', ')$get(mArtist)$puts(mArtist,$meta(ArtistFilter,2))$if($put(comma,$sub($strstr($get(mArtist),', '),1)),$puts(mArtist,$substr($get(mArtist),$add($get(comma),3),$len($get(mArtist))) $substr($get(mArtist),0,$get(comma))),)$if($get(mArtist),$if($or($stricmp($get(mArtist),'Soundtrack'),$stricmp($get(mArtist),'Various Artists')),,$ifequal($meta_num(ArtistFilter),3,' & ',', ')$get(mArtist)$puts(mArtist,$meta(ArtistFilter,3))$if($put(comma,$sub($strstr($get(mArtist),', '),1)),$puts(mArtist,$substr($get(mArtist),$add($get(comma),3),$len($get(mArtist))) $substr($get(mArtist),0,$get(comma))),)$if($get(mArtist),$if($or($stricmp($get(mArtist),'Soundtrack'),$stricmp($get(mArtist),'Various Artists')),,$ifequal($meta_num(ArtistFilter),4,' & ',', ')$get(mArtist)$puts(mArtist,$meta(ArtistFilter,4))$if($put(comma,$sub($strstr($get(mArtist),', '),1)),$puts(mArtist,$substr($get(mArtist),$add($get(comma),3),$len($get(mArtist))) $substr($get(mArtist),0,$get(comma))),)$if($get(mArtist),$if($or($stricmp($get(mArtist),'Soundtrack'),$stricmp($get(mArtist),'Various Artists')),,$ifequal($meta_num(ArtistFilter),5,' & ',', ')$get(mArtist))))))))))),%artist%))$ifequal($strcmp(%album artist%,%artist%),1,$get(AF),$if3($meta(artist),%composer%,%performer%,%album artist%)) */ -// Info grid. Simply add, change, reorder, or remove entries to change grid layout -const grid = [ +// Info grid visible when a song is playing. +// NOTE: If you wish to make changes to this, edit it in your georgia-config.jsonc file and NOT here. +let metadataGrid = [ { label: 'Disc', val: '$if('+ tf.disc_subtitle +',[Disc %discnumber% - ]'+ tf.disc_subtitle +')' }, { label: 'Release Type', val: '$if($strstr(%releasetype%,Album),,[%releasetype%])' }, - { label: 'Year', val: '$puts(d,'+tf.date+')$if($strcmp($year($get(d)),$get(d)),$get(d),)', comment: 'Year is shown if the date format is YYYY' }, - { label: 'Release Date', val: '$puts(d,'+tf.date+')$if($strcmp($year($get(d)),$get(d)),,$get(d))', age: true, comment: 'is used if the date is YYYY-MM-DD' }, + { label: 'Year', val: '$puts(d,'+tf.date+')$if($strcmp($year($get(d)),$get(d)),$get(d),)', comment: '\'Year\' is shown if the date format is YYYY' }, + { label: 'Release Date', val: '$puts(d,'+tf.date+')$if($strcmp($year($get(d)),$get(d)),,$get(d))', age: true, comment: '\'Release Date\' is shown if the date format is YYYY-MM-DD' }, { label: 'Edition', val: tf.edition }, - { label: 'Label', val: '[$meta_sep(label, \u2022 )]' }, + { label: 'Label', val: '[$meta_sep(label, \u2022 )]', comment: 'The label(s) or publisher(s) that released the album.' }, { label: 'Catalog #', val: '[%catalognumber%]' }, { label: 'Track', val: '$if(%tracknumber%,$num(%tracknumber%,1)$if(%totaltracks%,/$num(%totaltracks%,1))$ifgreater(%totaldiscs%,1, CD %discnumber%/$num(%totaldiscs%,1),)' }, { label: 'Genre', val: '[$meta_sep(genre, \u2022 )]' }, @@ -161,61 +158,83 @@ const grid = [ { label: 'Rating', val: '$if(%rating%,$repeat(\u2605 ,%rating%))' }, { label: 'Mood', val: '$if(%mood%,$puts(X,5)$puts(Y,$mul(5,%mood%))$repeat($repeat(I,$get(X)) ,$div($get(Y),$get(X)))$repeat(I,$mod($get(Y),$get(X)))$replace(%mood%,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9))' }, ]; -const gridSchema = new ConfigurationObjectSchema('metadata_grid', ConfigurationObjectType.Array, [ +const gridSchema = new ConfigurationObjectSchema('metadataGrid', ConfigurationObjectType.Array, [ { name: 'label' }, { name: 'val' }, // todo: change this to 'value'? { name: 'age', optional: true }, ], '*NOTE* Entries that evaluate to an empty string will not be shown in the grid'); + +const imgPaths = [ // simply add, change or re-order entries as needed + '$replace(%path%,%filename_ext%,)folder*', + '$replace(%path%,%filename_ext%,)front*', + '$replace(%path%,%filename_ext%,)cover*', + '$replace(%path%,%directoryname%\\%filename_ext%,)folder*', // all folder images in parent directory + '$replace(%path%,%directoryname%\\%filename_ext%,)front*', // all folder images in parent directory + '$replace(%path%,%directoryname%\\%filename_ext%,)cover*', // all folder images in parent directory + '$replace(%path%,%filename_ext%,)*.jpg', + '$replace(%path%,%filename_ext%,)*.png', +]; +const imgPathSchema = new ConfigurationObjectSchema('imgPaths', ConfigurationObjectType.Array, undefined, + 'The titleformatting defined paths for artwork to be displayed. The first image matched will be shown first.' + + ' Re-arrange, add, or remove as needed. NOTE: folder delimiters must be double-slashes ("\\\\")'); + const settingsPref = { - cdart_basename: 'cd', - hide_cursor: false, + cdArtBasename: 'cd', + hideCursor: false, + showDebugLog: false, + showThemeLog: false, locked: false, } const settingsComments = { - cdart_basename: 'Do not include extension. Example: "discart", if metadata consumer uses that name for cdart and you want those filtered from showing as albumart', - hide_cursor: 'Hides cursor when song is playing after 10 seconds of no mouse activity', + cdArtBasename: 'Do not include extension. Example: "discart", if the image provider uses that name for saving cdart and you want those filtered from showing up as albumart. Would also filter out discart1.png, etc.', + hideCursor: 'Hides cursor when song is playing after 10 seconds of no mouse activity', + showDebugLog: 'Enables extra logging in the console. Probably not needed unless you encounter a problem or you\'re asked to enable it.', + showThemeLog: 'Logs the output of the algorithm which determines the primary theme color.', locked: 'Locks theme by preventing right-clicking on the background from bringing up a menu.', } const settingsSchema = new ConfigurationObjectSchema('settings', ConfigurationObjectType.Object, // will display as key/val pairs with comments attached undefined, 'General settings for the theme.'); -const configPath = fb.ProfilePath + '\\georgia\\georgia-config.jsonc'; +const configPath = fb.ProfilePath + 'georgia\\georgia-config.jsonc'; const config = new Configuration(configPath); let titleformat = {}; if (!config.fileExists) { settings = config.addConfigurationObject(settingsSchema, settingsPref, settingsComments); tf = config.addConfigurationObject(titleFormatSchema, tf, titleFormatComments); - config.addConfigurationObject(gridSchema, grid); + config.addConfigurationObject(gridSchema, metadataGrid); // we don't assign an object here because these aren't key/value pairs and thus can't use the get/setters + config.addConfigurationObject(imgPathSchema, imgPaths); + console.log('writing', configPath); config.writeConfiguration(); - tf.grid = grid; // these aren't key/value pairs so can't be updated using ThemeSettings } if (config.fileExists) { const prefs = config.readConfiguration(); - settings = config.addConfigurationObject(settingsSchema, prefs.settings, settingsComments); + /** + * While we've read all the values in, we still need to call addConfigurationObject to add the getters/setters + * for the objects so that the file gets automatically written when a setting is changed. + **/ + settings = config.addConfigurationObject(settingsSchema, Object.assign(settingsPref, prefs.settings), settingsComments); tf = config.addConfigurationObject(titleFormatSchema, prefs.title_format_strings, titleFormatComments); - config.addConfigurationObject(gridSchema, prefs.metadata_grid, titleFormatComments); - tf.grid = prefs.metadata_grid; // these aren't key/value pairs so can't be updated using ThemeSettings for now + prefs.metadataGrid.forEach(entry => { + // copy comments over to existing object so they aren't lost + const gridEntryDefinition = metadataGrid.find(gridDefItem => gridDefItem.label === entry.label); + if (gridEntryDefinition && gridEntryDefinition.comment) { + entry.comment = gridEntryDefinition.comment; + } + }); + config.addConfigurationObject(gridSchema, prefs.metadataGrid); + config.addConfigurationObject(imgPathSchema, prefs.imgPaths); + tf.imgPaths = prefs.imgPaths; + metadataGrid = prefs.metadataGrid; + // when adding new objects to the config file, add them in the version check below } /* Safety checks. Fix up potentially bad vals from config */ -settings.cdart_basename = settings.cdart_basename.trim().length ? settings.cdart_basename.trim() : 'cd'; - +settings.cdArtBasename = settings.cdArtBasename && settings.cdArtBasename.trim().length ? settings.cdArtBasename.trim() : 'cd'; -/* All tf values from here below will NOT be writting to the Config file */ +/* All tf values from here below will NOT be written to the georgia-config file */ tf.vinyl_track = '$if2(' + tf.vinyl_side + '[' + tf.vinyl_tracknum + ']. ,[%tracknumber%. ])'; -// GLOB PICTURES -tf.glob_paths = [ // simply add, change or re-order entries as needed - '$replace(%path%,%filename_ext%,)folder*', - '$replace(%path%,%filename_ext%,)front*', - '$replace(%path%,%filename_ext%,)cover*', - '$replace(%path%,%directoryname%\\%filename_ext%,)folder*', // all folder images in parent directory - '$replace(%path%,%directoryname%\\%filename_ext%,)front*', // all folder images in parent directory - '$replace(%path%,%directoryname%\\%filename_ext%,)cover*', // all folder images in parent directory - '$replace(%path%,%filename_ext%,)*.jpg', - '$replace(%path%,%filename_ext%,)*.png', -]; tf.lyr_path = [ // simply add, change or re-order entries as needed '$replace($replace(%path%,%filename_ext%,),\,\\)', @@ -240,8 +259,8 @@ tf.labels = [ // Array of fields to test for publisher. Add, change or re-order // we expect cd-art will be in .png with transparent background, best found at fanart.tv. pref.vinylside_path = '$replace(%path%,%filename_ext%,)vinyl$if2(' + tf.vinyl_side + ',).png' // vinyl cdart named vinylA.png, vinylB.png, etc. pref.vinyl_path = '$replace(%path%,%filename_ext%,)vinyl.png' // vinyl cdart named vinylA.png, vinylB.png, etc. -pref.cdartdisc_path = '$replace(%path%,%filename_ext%,)' + settings.cdart_basename + '$ifgreater(%totaldiscs%,1,%discnumber%,).png'; // cdart named cd1.png, cd2.png, etc. -pref.cdart_path = '$replace(%path%,%filename_ext%,)' + settings.cdart_basename + '.png'; // cdart named cd.png (or whatever custom value was specified). This is the most common single disc case. +pref.cdartdisc_path = '$replace(%path%,%filename_ext%,)' + settings.cdArtBasename + '$ifgreater(%totaldiscs%,1,%discnumber%,).png'; // cdart named cd1.png, cd2.png, etc. +pref.cdart_path = '$replace(%path%,%filename_ext%,)' + settings.cdArtBasename + '.png'; // cdart named cd.png (or whatever custom value was specified). This is the most common single disc case. pref.cdart_amount = 0.48; // show 48% of the CD image if it will fit on the screen function migrateCheck(version, storedVersion) { @@ -249,7 +268,7 @@ function migrateCheck(version, storedVersion) { // this function clears default values which have changed switch (storedVersion) { - case '1.1.9': + case '1.9.9': // replace with 2.0.0-beta.1 // after all previous versions have fallen through console.log('Upgrading Georgia Theme settings'); globals.version = currentVersion; diff --git a/js/themes.js b/js/themes.js index a7fc3a71..112dd6e1 100644 --- a/js/themes.js +++ b/js/themes.js @@ -49,11 +49,11 @@ function setTheme(theme) { var themeCol = new Color(theme.primary); if (colorDistance(theme.primary, col.bg, true) < (themeCol.isCloseToGreyscale ? 60 : 45)) { if (pref.darkMode) { - if (pref.show_theme_log) console.log('>>> Theme primary color is too close to bg color. Tinting theme color.'); + if (settings.showThemeLog) console.log('>>> Theme primary color is too close to bg color. Tinting theme color.'); theme.primary = tintColor(theme.primary, 5); themeCol = new Color(theme.primary); } else { - if (pref.show_theme_log) console.log('>>> Theme primary color is too close to bg color. Shading theme color.'); + if (settings.showThemeLog) console.log('>>> Theme primary color is too close to bg color. Shading theme color.'); theme.primary = shadeColor(theme.primary, 5); themeCol = new Color(theme.primary); } @@ -67,7 +67,7 @@ function setTheme(theme) { } if (colorDistance(theme.primary, col.progress_bar, true) < (themeCol.isCloseToGreyscale ? 60 : 45)) { // progress fill is too close in color to bg - if (pref.show_theme_log) console.log('>>> Theme primary color is too close to progress bar. Adjusting progress_bar'); + if (settings.showThemeLog) console.log('>>> Theme primary color is too close to progress bar. Adjusting progress_bar'); if (themeCol.brightness < 125) { col.progress_bar = rgb(138,138,138); } else { @@ -103,7 +103,7 @@ function getThemeColorsJson(image, maxColorsToPull) { c.col = new Color(c.col); }); - if (pref.show_theme_log) console.log('idx color bright freq weight'); + if (settings.showThemeLog) console.log('idx color bright freq weight'); let maxWeight = 0; selectedColor = colorsWeighted[0].col; // choose first color in case no color selected below colorsWeighted.forEach((c, i) => { @@ -112,21 +112,21 @@ function getThemeColorsJson(image, maxColorsToPull) { c.weight = c.freq * midBrightness * 10; // multiply by 10 so numbers are easier to compare if (c.freq >= minFrequency && !col.isCloseToGreyscale && col.brightness < maxBrightness) { - if (pref.show_theme_log) console.log(leftPad(i, 2), col.getRGB(true,true), leftPad(col.brightness, 4), ' ', leftPad((c.freq*100).toFixed(2),5) + '%', leftPad(c.weight.toFixed(2), 7)); + if (settings.showThemeLog) console.log(leftPad(i, 2), col.getRGB(true,true), leftPad(col.brightness, 4), ' ', leftPad((c.freq*100).toFixed(2),5) + '%', leftPad(c.weight.toFixed(2), 7)); if (c.weight > maxWeight) { maxWeight = c.weight; selectedColor = col; } } else if (col.isCloseToGreyscale) { - if (pref.show_theme_log) console.log(' -', col.getRGB(true,true), leftPad(col.brightness, 4), ' ', leftPad((c.freq*100).toFixed(2),5) + '%', ' grey'); + if (settings.showThemeLog) console.log(' -', col.getRGB(true,true), leftPad(col.brightness, 4), ' ', leftPad((c.freq*100).toFixed(2),5) + '%', ' grey'); } else { - if (pref.show_theme_log) console.log(' -', col.getRGB(true,true), leftPad(col.brightness, 4), ' ', leftPad((c.freq*100).toFixed(2),5) + '%', + if (settings.showThemeLog) console.log(' -', col.getRGB(true,true), leftPad(col.brightness, 4), ' ', leftPad((c.freq*100).toFixed(2),5) + '%', (c.freq < minFrequency) ? ' freq' : ' bright'); } }); if (selectedColor.brightness < 37) { - if (pref.show_theme_log) console.log(selectedColor.getRGB(true), 'brightness:', selectedColor.brightness, 'too dark -- searching for highlight color'); + if (settings.showThemeLog) console.log(selectedColor.getRGB(true), 'brightness:', selectedColor.brightness, 'too dark -- searching for highlight color'); let brightest = selectedColor; maxWeight = 0; colorsWeighted.forEach(c => { @@ -141,7 +141,7 @@ function getThemeColorsJson(image, maxColorsToPull) { }); selectedColor = brightest; } - if (pref.show_theme_log) console.log('Selected Color:', selectedColor.getRGB(true)); + if (settings.showThemeLog) console.log('Selected Color:', selectedColor.getRGB(true)); return selectedColor.val; } catch (e) { console.log(''); @@ -166,12 +166,12 @@ function getThemeColors(image) { let color = new Color(calculatedColor); while (!pref.darkMode && color.brightness > 200) { calculatedColor = shadeColor(calculatedColor, 3); - if (pref.show_theme_log) console.log(' >> Shading: ', colToRgb(calculatedColor), ' - brightness: ', color.brightness); + if (settings.showThemeLog) console.log(' >> Shading: ', colToRgb(calculatedColor), ' - brightness: ', color.brightness); color = new Color(calculatedColor); } while (!color.isGreyscale && color.brightness <= 17) { calculatedColor = tintColor(calculatedColor, 3); - if (pref.show_theme_log) console.log(' >> Tinting: ', colToRgb(calculatedColor), ' - brightness: ', color.brightness); + if (settings.showThemeLog) console.log(' >> Tinting: ', colToRgb(calculatedColor), ' - brightness: ', color.brightness); color = new Color(calculatedColor); } const tObj = createThemeColorObject(color) @@ -241,7 +241,7 @@ function colorDistance(a, b, log) { const distance = Math.sqrt(2 * deltaR + 4 * deltaG + 3 * deltaB + (rho * (deltaR - deltaB))/256); if (log === true) { - if (pref.show_theme_log) console.log('distance from:', aCol.getRGB(), 'to:', bCol.getRGB(), '=', distance); + if (settings.showThemeLog) console.log('distance from:', aCol.getRGB(), 'to:', bCol.getRGB(), '=', distance); } return distance; } \ No newline at end of file