Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/wwwroot/css/genpage.css
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,16 @@ body {
margin-left: 0.5rem;
opacity: 0.8;
}
.browser-multiselect-toggle-active,
.browser-multiselect-entry-selected {
outline: 2px solid var(--emphasis) !important;
outline-offset: 1px;
}
.browser-multiselect-action-select {
max-width: 11rem;
margin-left: 0.15rem;
vertical-align: middle;
}
.browser-fullcontent-container {
margin-left: 0.2rem;
display: inline-block;
Expand Down
8 changes: 8 additions & 0 deletions src/wwwroot/js/genpage/gentab/currentimagehandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,11 @@ function toggleSeparateBatches() {

function clickImageInBatch(div) {
let imgElem = div.getElementsByTagName('img')[0];
let multiSelectKey = getImageFullSrc(div.dataset.src);
if (imageHistoryBrowser.enableBrowserMultiSelect && imageHistoryBrowser.multiSelectActive && multiSelectKey && !div.classList.contains('image-block-placeholder')) {
imageHistoryBrowser.toggleBrowserMultiSelectForKey(multiSelectKey);
return;
}
if (currentImgSrc == div.dataset.src) {
imageFullView.showImage(div.dataset.src, div.dataset.metadata, div.dataset.batch_id);
return;
Expand Down Expand Up @@ -786,6 +791,9 @@ function toggleStar(path, rawSrc) {
imageFullView.showImage(rawSrc, JSON.stringify(newMetadata), imageFullView.currentBatchId);
imageFullView.pasteState(state);
}
if (imageHistoryBrowser.enableBrowserMultiSelect && imageHistoryBrowser.multiSelectActive) {
imageHistoryBrowser.syncBrowserMultiSelectHeader();
}
});
}

Expand Down
3 changes: 2 additions & 1 deletion src/wwwroot/js/genpage/gentab/models.js
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ class ModelBrowserWrapper {
let format = subType == 'Wildcards' ? 'Small Cards' : 'Cards';
extraHeader += `<label for="models_${subType}_sort_by">Sort:</label> <select id="models_${subType}_sort_by"><option>Name</option><option>Title</option><option>DateCreated</option><option>DateModified</option></select> <input type="checkbox" id="models_${subType}_sort_reverse"> <label for="models_${subType}_sort_reverse">Reverse</label>`;
this.browser = new GenPageBrowserClass(container, this.listModelFolderAndFiles.bind(this), id, format, this.describeModel.bind(this), this.selectModel.bind(this), extraHeader);
this.browser.enableBrowserMultiSelect = true;
this.promptBox = getRequiredElementById('alt_prompt_textbox');
this.models = {};
this.browser.refreshHandler = (callback) => {
Expand Down Expand Up @@ -717,7 +718,7 @@ class ModelBrowserWrapper {
}, can_multi: true }];
}
let isStarred = this.isStarred(model.data.name);
let starButton = { label: isStarred ? 'Unstar' : 'Star', onclick: () => { this.toggleStar(model.data.name); } };
let starButton = { label: isStarred ? 'Unstar' : 'Star', onclick: () => { this.toggleStar(model.data.name); }, can_multi: true };
buttons.push(starButton);
let name = cleanModelName(model.data.name);
let display = (model.data.display || name).replaceAll('/', ' / ');
Expand Down
69 changes: 66 additions & 3 deletions src/wwwroot/js/genpage/gentab/outputhistory.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
let registeredMediaButtons = [];

/** Registers a media button for extensions. 'mediaTypes' filters by type eg ['audio'], null means all. 'isDefault' promotes to visible (vs More dropdown). 'showInHistory' controls whether button appears in the History panel. */
function registerMediaButton(name, action, title = '', mediaTypes = null, isDefault = false, showInHistory = true, href = null, is_download = false, can_multi = false, multi_only = false) {
registeredMediaButtons.push({ name, action, title, mediaTypes, isDefault, showInHistory, href, is_download, can_multi, multi_only });
function registerMediaButton(name, action, title = '', mediaTypes = null, isDefault = false, showInHistory = true, href = null, is_download = false, can_multi = false, multi_only = false, max_selected = null) {
registeredMediaButtons.push({ name, action, title, mediaTypes, isDefault, showInHistory, href, is_download, can_multi, multi_only, max_selected });
}

function listOutputHistoryFolderAndFiles(path, isRefresh, callback, depth) {
Expand Down Expand Up @@ -72,7 +72,8 @@ function buttonsForImage(fullsrc, src, metadata, isCurrentImage = false) {
className: (metadata && metaParsed.is_starred) ? ' star-button button-starred-image' : ' star-button',
onclick: (e) => {
toggleStar(fullsrc, src);
}
},
can_multi: true
});
buttons.push({
label: 'Enable Starred',
Expand Down Expand Up @@ -167,6 +168,11 @@ function buttonsForImage(fullsrc, src, metadata, isCurrentImage = false) {
if (div) {
removeImageBlockFromBatch(div);
}
if (imageHistoryBrowser.enableBrowserMultiSelect) {
imageHistoryBrowser.multiSelectedKeys.delete(fullsrc);
imageHistoryBrowser.applyBrowserMultiSelectVisuals();
imageHistoryBrowser.syncBrowserMultiSelectHeader();
}
});
},
// TODO: Only ask once for the multi-set rather than once per each
Expand All @@ -182,6 +188,7 @@ function buttonsForImage(fullsrc, src, metadata, isCurrentImage = false) {
is_download: reg.is_download,
can_multi: reg.can_multi,
multi_only: reg.multi_only,
max_selected: reg.max_selected,
onclick: () => reg.action(src)
});
}
Expand Down Expand Up @@ -247,6 +254,62 @@ function selectOutputInHistory(image, div) {

let imageHistoryBrowser = new GenPageBrowserClass('image_history', listOutputHistoryFolderAndFiles, 'imagehistorybrowser', 'Thumbnails', describeOutputFile, selectOutputInHistory,
`<label for="image_history_sort_by">Sort:</label> <select id="image_history_sort_by"><option>Name</option><option>Date</option></select> <input type="checkbox" id="image_history_sort_reverse"> <label for="image_history_sort_reverse">Reverse</label> &emsp; <input type="checkbox" id="image_history_allow_anims" checked autocomplete="off"> <label for="image_history_allow_anims">Allow Animation</label>`);
imageHistoryBrowser.enableBrowserMultiSelect = true;
imageHistoryBrowser.keepBrowserMultiSelectKeyAfterPrune = function(key, namesInCurrentList) {
if (namesInCurrentList.has(key)) {
return true;
}
let currentImageBatchDiv = getRequiredElementById('current_image_batch');
for (let candidate of currentImageBatchDiv.querySelectorAll('.image-block:not(.image-block-placeholder)')) {
if (getImageFullSrc(candidate.dataset.src) == key) {
return true;
}
}
return false;
};
imageHistoryBrowser.applyExtraMultiSelectVisuals = function() {
let currentImageBatchDiv = getRequiredElementById('current_image_batch');
for (let candidate of currentImageBatchDiv.querySelectorAll('.image-block:not(.image-block-placeholder)')) {
let blockKey = getImageFullSrc(candidate.dataset.src);
if (!blockKey) {
continue;
}
let on = this.multiSelectActive && this.multiSelectedKeys.has(blockKey);
candidate.classList.toggle('browser-multiselect-entry-selected', on);
}
};

imageHistoryBrowser.getExtraMultiSelectedFiles = function(seen) {
let out = [];
let currentImageBatchDiv = getRequiredElementById('current_image_batch');
for (let key of this.multiSelectedKeys) {
if (seen.has(key)) {
continue;
}
seen.add(key);
let block = null;
for (let candidate of currentImageBatchDiv.querySelectorAll('.image-block:not(.image-block-placeholder)')) {
if (getImageFullSrc(candidate.dataset.src) == key) {
block = candidate;
break;
}
}
let slash = key.lastIndexOf('/');
let baseName = slash >= 0 ? key.substring(slash + 1) : key;
let src = block && block.dataset.src ? block.dataset.src : `${getImageOutPrefix()}/${key}`;
let metadata = block && block.dataset.metadata ? block.dataset.metadata : '{}';
out.push({
name: key,
data: {
src,
fullsrc: key,
name: baseName,
metadata
}
});
}
return out;
};

function storeImageToHistoryWithCurrentParams(img) {
let data = getGenInput();
Expand Down
9 changes: 5 additions & 4 deletions src/wwwroot/js/genpage/gentab/presets.js
Original file line number Diff line number Diff line change
Expand Up @@ -626,18 +626,18 @@ function listPresetFolderAndFiles(path, isRefresh, callback, depth) {
function describePreset(preset) {
let buttons = [
{ label: 'Toggle', onclick: () => selectPreset(preset) },
{ label: 'Direct Apply', onclick: () => applyOnePreset(preset.data) },
{ label: preset.data.is_starred ? 'Unstar' : 'Star', onclick: () => togglePresetStar(preset) },
{ label: 'Direct Apply', onclick: () => applyOnePreset(preset.data), can_multi: true },
{ label: preset.data.is_starred ? 'Unstar' : 'Star', onclick: () => togglePresetStar(preset), can_multi: true },
{ label: 'Edit Preset', onclick: () => editPreset(preset.data) },
{ label: 'Duplicate Preset', onclick: () => duplicatePreset(preset.data) },
{ label: 'Export Preset', onclick: () => exportOnePresetButton(preset.data) },
{ label: 'Export Preset', onclick: () => exportOnePresetButton(preset.data), can_multi: true },
{ label: 'Delete Preset', onclick: () => {
if (confirm("Are you sure want to delete that preset?")) {
genericRequest('DeletePreset', { preset: preset.data.title }, data => {
loadUserData();
});
}
} }
}, can_multi: true }
];
let paramText = Object.keys(preset.data.param_map).map(key => `${key}: ${preset.data.param_map[key]}`);
let description = `${preset.data.title}:\n${preset.data.description}\n\n${paramText.join('\n')}`;
Expand Down Expand Up @@ -696,6 +696,7 @@ let presetBrowser = new GenPageBrowserClass('preset_list', listPresetFolderAndFi
<button id="preset_list_import_button translate" class="basic-button" onclick="importPresetsButton()">Import</button>
<button id="preset_list_export_button translate" class="basic-button" onclick="exportPresetsButton()">Export All</button>
<button id="preset_list_apply_button translate" class="basic-button" onclick="apply_presets()" title="Apply all current presets directly to your parameter list.">Apply</button>`);
presetBrowser.enableBrowserMultiSelect = true;

function importPresetsButton() {
getRequiredElementById('import_presets_textarea').value = '';
Expand Down
Loading
Loading