Merge pull request #2663 from d-ber/bulkTagImport Add bulk tag import
Signed| @@ -99,6 +99,6 @@ | |||
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | #bulk_tag_shadow_popup #bulk_tag_popup #dialogue_popup_controls .menu_button { | 101 | #bulk_tag_shadow_popup #bulk_tag_popup #dialogue_popup_controls .menu_button { |
| 102 | width: 100px; | 102 | width: unset; |
| 103 | padding: 0.25em; | 103 | padding: 0.25em; |
| 104 | } | 104 | } |
| @@ -10740,7 +10740,7 @@ jQuery(async function () { | |||
| 10740 | } | 10740 | } |
| 10741 | } break; | 10741 | } break; |
| 10742 | case 'import_tags': { | 10742 | case 'import_tags': { |
| 10743 | await importTags(characters[this_chid], { forceShow: true }); | 10743 | await importTags(characters[this_chid], { importSetting: tag_import_setting.ASK }); |
| 10744 | } break; | 10744 | } break; |
| 10745 | /*case 'delete_button': | 10745 | /*case 'delete_button': |
| 10746 | popup_type = "del_ch"; | 10746 | popup_type = "del_ch"; |
| @@ -18,7 +18,7 @@ import { | |||
| 18 | import { favsToHotswap } from './RossAscends-mods.js'; | 18 | import { favsToHotswap } from './RossAscends-mods.js'; |
| 19 | import { hideLoader, showLoader } from './loader.js'; | 19 | import { hideLoader, showLoader } from './loader.js'; |
| 20 | import { convertCharacterToPersona } from './personas.js'; | 20 | import { convertCharacterToPersona } from './personas.js'; |
| 21 | import { createTagInput, getTagKeyForEntity, getTagsList, printTagList, tag_map, compareTagsForSort, removeTagFromMap } from './tags.js'; | 21 | import { createTagInput, getTagKeyForEntity, getTagsList, printTagList, tag_map, compareTagsForSort, removeTagFromMap, importTags, tag_import_setting } from './tags.js'; |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * Static object representing the actions of the | 24 | * Static object representing the actions of the |
| @@ -197,10 +197,10 @@ class BulkTagPopupHandler { | |||
| 197 | #getHtml = () => { | 197 | #getHtml = () => { |
| 198 | const characterData = JSON.stringify({ characterIds: this.characterIds }); | 198 | const characterData = JSON.stringify({ characterIds: this.characterIds }); |
| 199 | return `<div id="bulk_tag_shadow_popup"> | 199 | return `<div id="bulk_tag_shadow_popup"> |
| 200 | <div id="bulk_tag_popup"> | 200 | <div id="bulk_tag_popup" class="wider_dialogue_popup"> |
| 201 | <div id="bulk_tag_popup_holder"> | 201 | <div id="bulk_tag_popup_holder"> |
| 202 | <h3 class="marginBot5">Modify tags of ${this.characterIds.length} characters</h3> | 202 | <h3 class="marginBot5">Modify tags of ${this.characterIds.length} characters</h3> |
| 203 | <small class="bulk_tags_desc m-b-1">Add or remove the mutual tags of all selected characters.</small> | 203 | <small class="bulk_tags_desc m-b-1">Add or remove the mutual tags of all selected characters. Import all or existing tags for all selected characters.</small> |
| 204 | <div id="bulk_tags_avatars_block" class="avatars_inline avatars_inline_small tags tags_inline"></div> | 204 | <div id="bulk_tags_avatars_block" class="avatars_inline avatars_inline_small tags tags_inline"></div> |
| 205 | <br> | 205 | <br> |
| 206 | <div id="bulk_tags_div" class="marginBot5" data-characters='${characterData}'> | 206 | <div id="bulk_tags_div" class="marginBot5" data-characters='${characterData}'> |
| @@ -219,6 +219,12 @@ class BulkTagPopupHandler { | |||
| 219 | <i class="fa-solid fa-trash-can margin-right-10px"></i> | 219 | <i class="fa-solid fa-trash-can margin-right-10px"></i> |
| 220 | Mutual | 220 | Mutual |
| 221 | </div> | 221 | </div> |
| 222 | <div id="bulk_tag_popup_import_all_tags" class="menu_button" title="Import all tags from selected characters" data-i18n="[title]Import all tags from selected characters"> | ||
| 223 | Import All | ||
| 224 | </div> | ||
| 225 | <div id="bulk_tag_popup_import_existing_tags" class="menu_button" title="Import existing tags from selected characters" data-i18n="[title]Import existing tags from selected characters"> | ||
| 226 | Import Existing | ||
| 227 | </div> | ||
| 222 | <div id="bulk_tag_popup_cancel" class="menu_button" data-i18n="Cancel">Close</div> | 228 | <div id="bulk_tag_popup_cancel" class="menu_button" data-i18n="Cancel">Close</div> |
| 223 | </div> | 229 | </div> |
| 224 | </div> | 230 | </div> |
| @@ -254,6 +260,30 @@ class BulkTagPopupHandler { | |||
| 254 | document.querySelector('#bulk_tag_popup_reset').addEventListener('click', this.resetTags.bind(this)); | 260 | document.querySelector('#bulk_tag_popup_reset').addEventListener('click', this.resetTags.bind(this)); |
| 255 | document.querySelector('#bulk_tag_popup_remove_mutual').addEventListener('click', this.removeMutual.bind(this)); | 261 | document.querySelector('#bulk_tag_popup_remove_mutual').addEventListener('click', this.removeMutual.bind(this)); |
| 256 | document.querySelector('#bulk_tag_popup_cancel').addEventListener('click', this.hide.bind(this)); | 262 | document.querySelector('#bulk_tag_popup_cancel').addEventListener('click', this.hide.bind(this)); |
| 263 | document.querySelector('#bulk_tag_popup_import_all_tags').addEventListener('click', this.importAllTags.bind(this)); | ||
| 264 | document.querySelector('#bulk_tag_popup_import_existing_tags').addEventListener('click', this.importExistingTags.bind(this)); | ||
| 265 | } | ||
| 266 | |||
| 267 | /** | ||
| 268 | * Import existing tags for all selected characters | ||
| 269 | */ | ||
| 270 | async importExistingTags() { | ||
| 271 | for (const characterId of this.characterIds) { | ||
| 272 | await importTags(characters[characterId], { importSetting: tag_import_setting.ONLY_EXISTING }); | ||
| 273 | } | ||
| 274 | |||
| 275 | $('#bulkTagList').empty(); | ||
| 276 | } | ||
| 277 | |||
| 278 | /** | ||
| 279 | * Import all tags for all selected characters | ||
| 280 | */ | ||
| 281 | async importAllTags() { | ||
| 282 | for (const characterId of this.characterIds) { | ||
| 283 | await importTags(characters[characterId], { importSetting: tag_import_setting.ALL }); | ||
| 284 | } | ||
| 285 | |||
| 286 | $('#bulkTagList').empty(); | ||
| 257 | } | 287 | } |
| 258 | 288 | ||
| 259 | /** | 289 | /** |
| @@ -570,7 +600,7 @@ class BulkEditOverlay { | |||
| 570 | this.container.removeEventListener('mouseup', cancelHold); | 600 | this.container.removeEventListener('mouseup', cancelHold); |
| 571 | this.container.removeEventListener('touchend', cancelHold); | 601 | this.container.removeEventListener('touchend', cancelHold); |
| 572 | }, | 602 | }, |
| 573 | BulkEditOverlay.longPressDelay); | 603 | BulkEditOverlay.longPressDelay); |
| 574 | }; | 604 | }; |
| 575 | 605 | ||
| 576 | handleLongPressEnd = (event) => { | 606 | handleLongPressEnd = (event) => { |
| @@ -708,12 +708,12 @@ const ANTI_TROLL_MAX_TAGS = 15; | |||
| 708 | * | 708 | * |
| 709 | * @param {Character} character - The character | 709 | * @param {Character} character - The character |
| 710 | * @param {object} [options] - Options | 710 | * @param {object} [options] - Options |
| 711 | * @param {boolean} [options.forceShow=false] - Whether to force showing the import dialog | 711 | * @param {tag_import_setting} [options.importSetting=null] - Force a tag import setting |
| 712 | * @returns {Promise<boolean>} Boolean indicating whether any tag was imported | 712 | * @returns {Promise<boolean>} Boolean indicating whether any tag was imported |
| 713 | */ | 713 | */ |
| 714 | async function importTags(character, { forceShow = false } = {}) { | 714 | async function importTags(character, { importSetting = null } = {}) { |
| 715 | // Gather the tags to import based on the selected setting | 715 | // Gather the tags to import based on the selected setting |
| 716 | const tagNamesToImport = await handleTagImport(character, { forceShow }); | 716 | const tagNamesToImport = await handleTagImport(character, { importSetting }); |
| 717 | if (!tagNamesToImport?.length) { | 717 | if (!tagNamesToImport?.length) { |
| 718 | console.debug('No tags to import'); | 718 | console.debug('No tags to import'); |
| 719 | return; | 719 | return; |
| @@ -732,10 +732,10 @@ async function importTags(character, { forceShow = false } = {}) { | |||
| 732 | * | 732 | * |
| 733 | * @param {Character} character - The character | 733 | * @param {Character} character - The character |
| 734 | * @param {object} [options] - Options | 734 | * @param {object} [options] - Options |
| 735 | * @param {boolean} [options.forceShow=false] - Whether to force showing the import dialog | 735 | * @param {tag_import_setting} [options.importSetting=null] - Force a tag import setting |
| 736 | * @returns {Promise<string[]>} Array of strings representing the tags to import | 736 | * @returns {Promise<string[]>} Array of strings representing the tags to import |
| 737 | */ | 737 | */ |
| 738 | async function handleTagImport(character, { forceShow = false } = {}) { | 738 | async function handleTagImport(character, { importSetting = null } = {}) { |
| 739 | /** @type {string[]} */ | 739 | /** @type {string[]} */ |
| 740 | const importTags = character.tags.map(t => t.trim()).filter(t => t) | 740 | const importTags = character.tags.map(t => t.trim()).filter(t => t) |
| 741 | .filter(t => !IMPORT_EXLCUDED_TAGS.includes(t)) | 741 | .filter(t => !IMPORT_EXLCUDED_TAGS.includes(t)) |
| @@ -745,9 +745,9 @@ async function handleTagImport(character, { forceShow = false } = {}) { | |||
| 745 | .map(newTag); | 745 | .map(newTag); |
| 746 | const folderTags = getOpenBogusFolders(); | 746 | const folderTags = getOpenBogusFolders(); |
| 747 | 747 | ||
| 748 | // Choose the setting for this dialog. If from settings, verify the setting really exists, otherwise take "ASK". | 748 | // Choose the setting for this dialog. First check override, then saved setting or finally use "ASK". |
| 749 | const setting = forceShow ? tag_import_setting.ASK | 749 | const setting = importSetting ? importSetting : |
| 750 | : Object.values(tag_import_setting).find(setting => setting === power_user.tag_import_setting) ?? tag_import_setting.ASK; | 750 | Object.values(tag_import_setting).find(setting => setting === power_user.tag_import_setting) ?? tag_import_setting.ASK; |
| 751 | 751 | ||
| 752 | switch (setting) { | 752 | switch (setting) { |
| 753 | case tag_import_setting.ALL: | 753 | case tag_import_setting.ALL: |