Files
JaredTherriault-ComfyUI-JNodes/web/js/ImageDrawer/Sorting.js
T
JaredTherriault f0338b0c5f Batch selection, batch deletion, classifying some scripts, module manager
-Added new batch selection and batch deletion features. All imageElements now have a checkbox and each selected element is tracked within a context or folder. When you've selected all you want to delete, click the recycle button on the toolbar, then again to confirm. All checked items will be recylced/deleted. You can also click on the selection widget next to the batch delete button to toggle select/deselect all.
-Renamed ImageDrawer.js to ImageDrawerMain.js
-Separated ImageListAndSearch out into separate scripts and classes named ImageDrawerList and ImageDrawerSearch
-Changed order of some initialized functions and variables in imageElements to better accommodate batch selection
-
-Moved some scripts over to a classy architecture. More scripts will be moved over time. This will eventually allow for multiple image drawer instances in the same window.
-Added a new module script that manages all class instances. See ImageDrawerModule.js for an explanation of the new architecture. Basically, it makes cyclical dependencies impossible.
-Updated imports
-Updated various scripts to use class instances where applicable
-Updated some outdated comments
-Added option to prepend or append labels to Labeled widgets
-Parameter optimizations
-
2024-05-07 20:39:40 -07:00

252 lines
7.1 KiB
JavaScript

import { $el } from "/scripts/ui.js";
import { imageDrawerComponentManagerInstance } from "./Core/ImageDrawerModule.js";
let SortingWidget;
let SortTypes;
export function initializeSortTypes() {
SortTypes = {
filenameAscending: new SortTypeFilename(true),
filenameDescending: new SortTypeFilename(false),
friendlyNameAscending: new SortTypeFriendlyName(true),
friendlyNameDescending: new SortTypeFriendlyName(false),
dateAscending: new SortTypeDate(true),
dateDescending: new SortTypeDate(false),
fileSizeAscending: new SortTypeFileSize(true),
fileSizeDescending: new SortTypeFileSize(false),
imageWidthAscending: new SortTypeImageWidth(true),
imageWidthDescending: new SortTypeImageWidth(false),
imageHeightAscending: new SortTypeImageHeight(true),
imageHeightDescending: new SortTypeImageHeight(false),
imageAspectRatioAscending: new SortTypeImageAspectRatio(true),
imageAspectRatioDescending: new SortTypeImageAspectRatio(false),
fileTypeAscending: new SortTypeFileType(true),
fileTypeDescending: new SortTypeFileType(false),
}
}
export function getSortTypes() {
return SortTypes;
}
export function getCurrentSortTypeName() {
return SortingWidget.value;
}
export function getCurrentSortTypeObject() {
return getSortTypeObjectFromName(getCurrentSortTypeName());
}
export function sortWithCurrentType() {
getCurrentSortTypeObject()?.sortImageList();
}
export function getSortTypeObjectFromName(sortName, bIsAscending = undefined) {
const sortValues = Object.values(SortTypes);
let foundSortType;
for (const value of sortValues) {
// returns true if the name at least partially matched and bIsAscending is not specified,
// or is specified and matches the SortType instance
if (value.name.includes(sortName) && (bIsAscending == undefined || value.bIsAscending == bIsAscending)) {
foundSortType = value;
break;
}
}
if (foundSortType) {
return foundSortType;
} else {
console.error(`SortType with name '${foundSortType}' not found.`);
return null;
}
}
export function getSortTypeObjectFromClassType(classType, bIsAscending = undefined) {
const sortValues = Object.values(SortTypes);
let foundSortType;
for (const value of sortValues) {
// returns true if the name at least partially matched and bIsAscending is not specified,
// or is specified and matches the SortType instance
const valueType = value.constructor.name;
if (valueType == classType.name && (bIsAscending == undefined || value.bIsAscending == bIsAscending)) {
foundSortType = value;
break;
}
}
if (foundSortType) {
return foundSortType;
} else {
console.error(`SortType with name '${foundSortType}' not found.`);
return null;
}
}
export class SortType {
constructor(name, bIsAscending) {
this.name = `${name} ${bIsAscending ? "⬆️" : "⬇️"}`;
this.bIsAscending = bIsAscending;
}
sortImageList() {
let imageListChildren = this.getSortableChildren();
imageListChildren.sort(this.getSortingLambda());
const imageDrawerListInstance = imageDrawerComponentManagerInstance.getComponentByName("ImageDrawerList");
imageDrawerListInstance.replaceImageListChildren(imageListChildren);
}
getSortingLambda() { }
getSortableChildren() {
const imageDrawerListInstance = imageDrawerComponentManagerInstance.getComponentByName("ImageDrawerList");
let imageListChildren = imageDrawerListInstance.getImageListChildren();
return Array.from(imageListChildren);
}
}
export class SortTypeFilename extends SortType {
constructor(bIsAscending) {
super('Filename', bIsAscending)
}
getSortingLambda() {
return (a, b) => this.bIsAscending ? a.filename.localeCompare(b.filename) : b.filename.localeCompare(a.filename);
}
}
export class SortTypeFriendlyName extends SortType {
constructor(bIsAscending) {
super('Friendly Name', bIsAscending)
}
getSortingLambda() {
return (a, b) => this.bIsAscending ? a.friendlyName.localeCompare(b.friendlyName) : b.friendlyName.localeCompare(a.friendlyName);
}
}
export class SortTypeDate extends SortType {
constructor(bIsAscending) {
super('Date', bIsAscending)
}
getSortingLambda() {
return (a, b) => this.bIsAscending ? a.file_age - b.file_age : b.file_age - a.file_age;
}
}
export class SortTypeFileSize extends SortType {
constructor(bIsAscending) {
super('File Size', bIsAscending)
}
getSortingLambda() {
return (a, b) => this.bIsAscending ? a.displayData.FileSize - b.displayData.FileSize : b.displayData.FileSize - a.displayData.FileSize;
}
}
export class SortTypeImageWidth extends SortType {
constructor(bIsAscending) {
super('Image Width', bIsAscending)
}
getSortingLambda() {
return (a, b) => this.bIsAscending ? a.displayData.FileDimensions[0] - b.displayData.FileDimensions[0] : b.displayData.FileDimensions[0] - a.displayData.FileDimensions[0];
}
}
export class SortTypeImageHeight extends SortType {
constructor(bIsAscending) {
super('Image Height', bIsAscending)
}
getSortingLambda() {
return (a, b) => this.bIsAscending ? a.displayData.FileDimensions[1] - b.displayData.FileDimensions[1] : b.displayData.FileDimensions[1] - a.displayData.FileDimensions[1];
}
}
export class SortTypeImageAspectRatio extends SortType {
constructor(bIsAscending) {
super('Image Aspect Ratio', bIsAscending)
}
getSortingLambda() {
return (a, b) => this.bIsAscending ? a.displayData.AspectRatio - b.displayData.AspectRatio : b.displayData.AspectRatio - a.displayData.AspectRatio;
}
}
export class SortTypeFileType extends SortType {
constructor(bIsAscending) {
super('File Type', bIsAscending)
}
getSortingLambda() {
return (a, b) => this.bIsAscending ? a.fileType.localeCompare(b.fileType) : b.fileType.localeCompare(a.fileType);
}
}
// Selector
export function setOptionSelectedFromOptionName(option) {
SortingWidget.value = option;
onOptionSelected(option);
}
export function setOptionSelectedFromSortType(type, bIsAscending) {
const foundType = getSortTypeObjectFromClassType(type, bIsAscending);
setOptionSelectedFromOptionName(foundType.name);
}
export function onOptionSelected(option) {
const NewType = getSortTypeObjectFromName(option);
NewType.sortImageList();
}
export function setSortingOptionsFromSortTypeArray(inOptionArray) {
SortingWidget.replaceChildren();
for (const sortType of inOptionArray) {
for (let bool = 1; bool > -1; bool--) { // Ascending and descending
const sortObject = getSortTypeObjectFromClassType(sortType, bool);
if (sortObject) {
const option = document.createElement("option");
option.value = sortObject.name;
option.textContent = sortObject.name;
SortingWidget.appendChild(option);
}
}
}
}
export function setSortingOptionsFromStringArray(inOptionArray) {
SortingWidget.replaceChildren();
for (const optionKey in inOptionArray) {
const option = document.createElement("option");
option.value = optionKey;
option.textContent = optionKey;
SortingWidget.appendChild(option);
}
}
export function makeSortingWidget() {
SortingWidget = $el("select");
// Add an event listener for the "change" event
SortingWidget.addEventListener("change", async function() {
onOptionSelected(SortingWidget.value);
});
initializeSortTypes();
return SortingWidget;
}