From 651072c61b29fa779f875081d11bb7e1aa338be4 Mon Sep 17 00:00:00 2001 From: d-ber Date: Thu, 15 Aug 2024 15:36:46 +0200 Subject: [PATCH 1/6] Add button to bulk import all tags --- public/scripts/BulkEditOverlay.js | 19 +++++++++++++++++-- public/scripts/tags.js | 11 +++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/public/scripts/BulkEditOverlay.js b/public/scripts/BulkEditOverlay.js index d121d0fc6..a70cfe782 100644 --- a/public/scripts/BulkEditOverlay.js +++ b/public/scripts/BulkEditOverlay.js @@ -18,7 +18,7 @@ import { import { favsToHotswap } from './RossAscends-mods.js'; import { hideLoader, showLoader } from './loader.js'; import { convertCharacterToPersona } from './personas.js'; -import { createTagInput, getTagKeyForEntity, getTagsList, printTagList, tag_map, compareTagsForSort, removeTagFromMap } from './tags.js'; +import { createTagInput, getTagKeyForEntity, getTagsList, printTagList, tag_map, compareTagsForSort, removeTagFromMap, importTags } from './tags.js'; /** * Static object representing the actions of the @@ -219,6 +219,9 @@ class BulkTagPopupHandler { Mutual + @@ -254,6 +257,18 @@ class BulkTagPopupHandler { document.querySelector('#bulk_tag_popup_reset').addEventListener('click', this.resetTags.bind(this)); document.querySelector('#bulk_tag_popup_remove_mutual').addEventListener('click', this.removeMutual.bind(this)); document.querySelector('#bulk_tag_popup_cancel').addEventListener('click', this.hide.bind(this)); + document.querySelector('#bulk_tag_popup_import_all_tags').addEventListener('click', this.importAllTags.bind(this)); + } + + /** + * Import all tags for all selected characters + */ + async importAllTags() { + for (const characterId of this.characterIds) { + await importTags(characters[characterId], { importAll: true }); + } + + $('#bulkTagList').empty(); } /** @@ -570,7 +585,7 @@ class BulkEditOverlay { this.container.removeEventListener('mouseup', cancelHold); this.container.removeEventListener('touchend', cancelHold); }, - BulkEditOverlay.longPressDelay); + BulkEditOverlay.longPressDelay); }; handleLongPressEnd = (event) => { diff --git a/public/scripts/tags.js b/public/scripts/tags.js index 43b52f74e..d563b00bc 100644 --- a/public/scripts/tags.js +++ b/public/scripts/tags.js @@ -708,12 +708,13 @@ const ANTI_TROLL_MAX_TAGS = 15; * * @param {Character} character - The character * @param {object} [options] - Options + * @param {boolean} [options.importAll=false] - Whether to import all tags without dialog * @param {boolean} [options.forceShow=false] - Whether to force showing the import dialog * @returns {Promise} Boolean indicating whether any tag was imported */ -async function importTags(character, { forceShow = false } = {}) { +async function importTags(character, { importAll = false, forceShow = false } = {}) { // Gather the tags to import based on the selected setting - const tagNamesToImport = await handleTagImport(character, { forceShow }); + const tagNamesToImport = await handleTagImport(character, { importAll, forceShow }); if (!tagNamesToImport?.length) { console.debug('No tags to import'); return; @@ -732,10 +733,11 @@ async function importTags(character, { forceShow = false } = {}) { * * @param {Character} character - The character * @param {object} [options] - Options + * @param {boolean} [options.importAll=false] - Whether to import all tags without dialog * @param {boolean} [options.forceShow=false] - Whether to force showing the import dialog * @returns {Promise} Array of strings representing the tags to import */ -async function handleTagImport(character, { forceShow = false } = {}) { +async function handleTagImport(character, { importAll = false, forceShow = false } = {}) { /** @type {string[]} */ const importTags = character.tags.map(t => t.trim()).filter(t => t) .filter(t => !IMPORT_EXLCUDED_TAGS.includes(t)) @@ -747,7 +749,8 @@ async function handleTagImport(character, { forceShow = false } = {}) { // Choose the setting for this dialog. If from settings, verify the setting really exists, otherwise take "ASK". const setting = forceShow ? tag_import_setting.ASK - : Object.values(tag_import_setting).find(setting => setting === power_user.tag_import_setting) ?? tag_import_setting.ASK; + : importAll ? tag_import_setting.ALL + : Object.values(tag_import_setting).find(setting => setting === power_user.tag_import_setting) ?? tag_import_setting.ASK; switch (setting) { case tag_import_setting.ALL: From d3ce9ea0d5d7238d0c9c2532d5319fddacf5c4d4 Mon Sep 17 00:00:00 2001 From: d-ber Date: Thu, 15 Aug 2024 15:47:04 +0200 Subject: [PATCH 2/6] Add button to bulk import existing tags --- public/scripts/BulkEditOverlay.js | 17 ++++++++++++++++- public/scripts/tags.js | 11 +++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/public/scripts/BulkEditOverlay.js b/public/scripts/BulkEditOverlay.js index a70cfe782..b10a59f26 100644 --- a/public/scripts/BulkEditOverlay.js +++ b/public/scripts/BulkEditOverlay.js @@ -200,7 +200,7 @@ class BulkTagPopupHandler {

Modify tags of ${this.characterIds.length} characters

- Add or remove the mutual tags of all selected characters. + Add or remove the mutual tags of all selected characters. Import all or existing tags for all selected characters.

@@ -222,6 +222,9 @@ class BulkTagPopupHandler { +
@@ -258,6 +261,18 @@ class BulkTagPopupHandler { document.querySelector('#bulk_tag_popup_remove_mutual').addEventListener('click', this.removeMutual.bind(this)); document.querySelector('#bulk_tag_popup_cancel').addEventListener('click', this.hide.bind(this)); document.querySelector('#bulk_tag_popup_import_all_tags').addEventListener('click', this.importAllTags.bind(this)); + document.querySelector('#bulk_tag_popup_import_existing_tags').addEventListener('click', this.importExistingTags.bind(this)); + } + + /** + * Import existing tags for all selected characters + */ + async importExistingTags() { + for (const characterId of this.characterIds) { + await importTags(characters[characterId], { importExisting: true }); + } + + $('#bulkTagList').empty(); } /** diff --git a/public/scripts/tags.js b/public/scripts/tags.js index d563b00bc..b97d19fdd 100644 --- a/public/scripts/tags.js +++ b/public/scripts/tags.js @@ -709,12 +709,13 @@ const ANTI_TROLL_MAX_TAGS = 15; * @param {Character} character - The character * @param {object} [options] - Options * @param {boolean} [options.importAll=false] - Whether to import all tags without dialog + * @param {boolean} [options.importExisting=false] - Whether to import existing tags without dialog * @param {boolean} [options.forceShow=false] - Whether to force showing the import dialog * @returns {Promise} Boolean indicating whether any tag was imported */ -async function importTags(character, { importAll = false, forceShow = false } = {}) { +async function importTags(character, { importAll = false, importExisting = false, forceShow = false } = {}) { // Gather the tags to import based on the selected setting - const tagNamesToImport = await handleTagImport(character, { importAll, forceShow }); + const tagNamesToImport = await handleTagImport(character, { importAll, importExisting, forceShow }); if (!tagNamesToImport?.length) { console.debug('No tags to import'); return; @@ -734,10 +735,11 @@ async function importTags(character, { importAll = false, forceShow = false } = * @param {Character} character - The character * @param {object} [options] - Options * @param {boolean} [options.importAll=false] - Whether to import all tags without dialog + * @param {boolean} [options.importExisting=false] - Whether to import existing tags without dialog * @param {boolean} [options.forceShow=false] - Whether to force showing the import dialog * @returns {Promise} Array of strings representing the tags to import */ -async function handleTagImport(character, { importAll = false, forceShow = false } = {}) { +async function handleTagImport(character, { importAll = false, importExisting = false, forceShow = false } = {}) { /** @type {string[]} */ const importTags = character.tags.map(t => t.trim()).filter(t => t) .filter(t => !IMPORT_EXLCUDED_TAGS.includes(t)) @@ -750,7 +752,8 @@ async function handleTagImport(character, { importAll = false, forceShow = false // Choose the setting for this dialog. If from settings, verify the setting really exists, otherwise take "ASK". const setting = forceShow ? tag_import_setting.ASK : importAll ? tag_import_setting.ALL - : Object.values(tag_import_setting).find(setting => setting === power_user.tag_import_setting) ?? tag_import_setting.ASK; + : importExisting ? tag_import_setting.ONLY_EXISTING + : Object.values(tag_import_setting).find(setting => setting === power_user.tag_import_setting) ?? tag_import_setting.ASK; switch (setting) { case tag_import_setting.ALL: From 1af51fc1291fffcb4d5b65365b76fb8c7a476046 Mon Sep 17 00:00:00 2001 From: d-ber Date: Thu, 15 Aug 2024 16:33:19 +0200 Subject: [PATCH 3/6] Adjust css to fit new buttons --- public/css/character-group-overlay.css | 2 +- public/style.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/css/character-group-overlay.css b/public/css/character-group-overlay.css index b0d4b4a14..5327694a8 100644 --- a/public/css/character-group-overlay.css +++ b/public/css/character-group-overlay.css @@ -99,6 +99,6 @@ } #bulk_tag_shadow_popup #bulk_tag_popup #dialogue_popup_controls .menu_button { - width: 100px; + width: unset; padding: 0.25em; } diff --git a/public/style.css b/public/style.css index 742a370ea..471470fcc 100644 --- a/public/style.css +++ b/public/style.css @@ -3195,7 +3195,7 @@ grammarly-extension { #bulk_tag_popup, #dialogue_popup { - width: 500px; + width: 750px; max-width: 90vw; max-width: 90dvw; position: absolute; From af30991d7740cba96a41e664eb82d7106cc86067 Mon Sep 17 00:00:00 2001 From: d-ber Date: Thu, 15 Aug 2024 17:40:57 +0200 Subject: [PATCH 4/6] Improve code readability --- public/scripts/tags.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/public/scripts/tags.js b/public/scripts/tags.js index b97d19fdd..22153dcc5 100644 --- a/public/scripts/tags.js +++ b/public/scripts/tags.js @@ -750,10 +750,16 @@ async function handleTagImport(character, { importAll = false, importExisting = const folderTags = getOpenBogusFolders(); // Choose the setting for this dialog. If from settings, verify the setting really exists, otherwise take "ASK". - const setting = forceShow ? tag_import_setting.ASK - : importAll ? tag_import_setting.ALL - : importExisting ? tag_import_setting.ONLY_EXISTING - : Object.values(tag_import_setting).find(setting => setting === power_user.tag_import_setting) ?? tag_import_setting.ASK; + let setting; + if (forceShow) { + setting = tag_import_setting.ASK; + } else if (importAll) { + setting = tag_import_setting.ALL; + } else if (importExisting) { + setting = tag_import_setting.ONLY_EXISTING; + } else { + setting = Object.values(tag_import_setting).find(setting => setting === power_user.tag_import_setting) ?? tag_import_setting.ASK; + } switch (setting) { case tag_import_setting.ALL: From 2d476d4461a0dffec712fa8f09ec42901a5552e3 Mon Sep 17 00:00:00 2001 From: d-ber Date: Fri, 16 Aug 2024 22:00:01 +0200 Subject: [PATCH 5/6] Use wider css class for bulk tag menu --- public/scripts/BulkEditOverlay.js | 2 +- public/style.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/scripts/BulkEditOverlay.js b/public/scripts/BulkEditOverlay.js index b10a59f26..05cb4632e 100644 --- a/public/scripts/BulkEditOverlay.js +++ b/public/scripts/BulkEditOverlay.js @@ -197,7 +197,7 @@ class BulkTagPopupHandler { #getHtml = () => { const characterData = JSON.stringify({ characterIds: this.characterIds }); return `
-
+

Modify tags of ${this.characterIds.length} characters

Add or remove the mutual tags of all selected characters. Import all or existing tags for all selected characters. diff --git a/public/style.css b/public/style.css index 471470fcc..742a370ea 100644 --- a/public/style.css +++ b/public/style.css @@ -3195,7 +3195,7 @@ grammarly-extension { #bulk_tag_popup, #dialogue_popup { - width: 750px; + width: 500px; max-width: 90vw; max-width: 90dvw; position: absolute; From 0f606642ce6f38fd2e41452d83d5c6201dd4c3a5 Mon Sep 17 00:00:00 2001 From: d-ber Date: Fri, 16 Aug 2024 22:43:22 +0200 Subject: [PATCH 6/6] Refactor tag import setting override --- public/script.js | 2 +- public/scripts/BulkEditOverlay.js | 6 +++--- public/scripts/tags.js | 28 ++++++++-------------------- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/public/script.js b/public/script.js index 8808320c8..291b874ef 100644 --- a/public/script.js +++ b/public/script.js @@ -10738,7 +10738,7 @@ jQuery(async function () { } } break; case 'import_tags': { - await importTags(characters[this_chid], { forceShow: true }); + await importTags(characters[this_chid], { importSetting: tag_import_setting.ASK }); } break; /*case 'delete_button': popup_type = "del_ch"; diff --git a/public/scripts/BulkEditOverlay.js b/public/scripts/BulkEditOverlay.js index 05cb4632e..28517d32f 100644 --- a/public/scripts/BulkEditOverlay.js +++ b/public/scripts/BulkEditOverlay.js @@ -18,7 +18,7 @@ import { import { favsToHotswap } from './RossAscends-mods.js'; import { hideLoader, showLoader } from './loader.js'; import { convertCharacterToPersona } from './personas.js'; -import { createTagInput, getTagKeyForEntity, getTagsList, printTagList, tag_map, compareTagsForSort, removeTagFromMap, importTags } from './tags.js'; +import { createTagInput, getTagKeyForEntity, getTagsList, printTagList, tag_map, compareTagsForSort, removeTagFromMap, importTags, tag_import_setting } from './tags.js'; /** * Static object representing the actions of the @@ -269,7 +269,7 @@ class BulkTagPopupHandler { */ async importExistingTags() { for (const characterId of this.characterIds) { - await importTags(characters[characterId], { importExisting: true }); + await importTags(characters[characterId], { importSetting: tag_import_setting.ONLY_EXISTING }); } $('#bulkTagList').empty(); @@ -280,7 +280,7 @@ class BulkTagPopupHandler { */ async importAllTags() { for (const characterId of this.characterIds) { - await importTags(characters[characterId], { importAll: true }); + await importTags(characters[characterId], { importSetting: tag_import_setting.ALL }); } $('#bulkTagList').empty(); diff --git a/public/scripts/tags.js b/public/scripts/tags.js index 22153dcc5..642821467 100644 --- a/public/scripts/tags.js +++ b/public/scripts/tags.js @@ -708,14 +708,12 @@ const ANTI_TROLL_MAX_TAGS = 15; * * @param {Character} character - The character * @param {object} [options] - Options - * @param {boolean} [options.importAll=false] - Whether to import all tags without dialog - * @param {boolean} [options.importExisting=false] - Whether to import existing tags without dialog - * @param {boolean} [options.forceShow=false] - Whether to force showing the import dialog + * @param {tag_import_setting} [options.importSetting=null] - Force a tag import setting * @returns {Promise} Boolean indicating whether any tag was imported */ -async function importTags(character, { importAll = false, importExisting = false, forceShow = false } = {}) { +async function importTags(character, { importSetting = null } = {}) { // Gather the tags to import based on the selected setting - const tagNamesToImport = await handleTagImport(character, { importAll, importExisting, forceShow }); + const tagNamesToImport = await handleTagImport(character, { importSetting }); if (!tagNamesToImport?.length) { console.debug('No tags to import'); return; @@ -734,12 +732,10 @@ async function importTags(character, { importAll = false, importExisting = false * * @param {Character} character - The character * @param {object} [options] - Options - * @param {boolean} [options.importAll=false] - Whether to import all tags without dialog - * @param {boolean} [options.importExisting=false] - Whether to import existing tags without dialog - * @param {boolean} [options.forceShow=false] - Whether to force showing the import dialog + * @param {tag_import_setting} [options.importSetting=null] - Force a tag import setting * @returns {Promise} Array of strings representing the tags to import */ -async function handleTagImport(character, { importAll = false, importExisting = false, forceShow = false } = {}) { +async function handleTagImport(character, { importSetting = null } = {}) { /** @type {string[]} */ const importTags = character.tags.map(t => t.trim()).filter(t => t) .filter(t => !IMPORT_EXLCUDED_TAGS.includes(t)) @@ -749,17 +745,9 @@ async function handleTagImport(character, { importAll = false, importExisting = .map(newTag); const folderTags = getOpenBogusFolders(); - // Choose the setting for this dialog. If from settings, verify the setting really exists, otherwise take "ASK". - let setting; - if (forceShow) { - setting = tag_import_setting.ASK; - } else if (importAll) { - setting = tag_import_setting.ALL; - } else if (importExisting) { - setting = tag_import_setting.ONLY_EXISTING; - } else { - setting = Object.values(tag_import_setting).find(setting => setting === power_user.tag_import_setting) ?? tag_import_setting.ASK; - } + // Choose the setting for this dialog. First check override, then saved setting or finally use "ASK". + const setting = importSetting ? importSetting : + Object.values(tag_import_setting).find(setting => setting === power_user.tag_import_setting) ?? tag_import_setting.ASK; switch (setting) { case tag_import_setting.ALL: