parent
687b6e1aa9
commit
d1cc406f05
@ -50,7 +50,7 @@ function computeSelection(
|
|||||||
return !item.matched;
|
return !item.matched;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return items.filter(item => item.prevMatched !== item.matched). map(item => {
|
return items.filter(item => item.prevMatched !== item.matched).map(item => {
|
||||||
return {
|
return {
|
||||||
idx: item.idx,
|
idx: item.idx,
|
||||||
matched: item.matched
|
matched: item.matched
|
||||||
|
@ -48,6 +48,7 @@ type DELTAS = {deltaLinks: ItemDelta[]; deltaMedia: ItemDelta[]};
|
|||||||
|
|
||||||
interface BaseMatchedItem extends BaseItem {
|
interface BaseMatchedItem extends BaseItem {
|
||||||
matched?: string | null;
|
matched?: string | null;
|
||||||
|
rowid: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleaErrors() {
|
function cleaErrors() {
|
||||||
@ -96,8 +97,6 @@ class PausedModalDialog extends ModalDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CheckClasser extends Map<string, string> {
|
class CheckClasser extends Map<string, string> {
|
||||||
gen: IterableIterator<string>;
|
gen: IterableIterator<string>;
|
||||||
|
|
||||||
@ -126,19 +125,82 @@ class CheckClasser extends Map<string, string> {
|
|||||||
|
|
||||||
type KeyFn = (item: BaseMatchedItem) => any;
|
type KeyFn = (item: BaseMatchedItem) => any;
|
||||||
|
|
||||||
|
class ItemCollection {
|
||||||
|
private items: BaseMatchedItem[];
|
||||||
|
|
||||||
|
private indexes: Map<number, BaseMatchedItem>;
|
||||||
|
|
||||||
|
constructor(items: BaseMatchedItem[]) {
|
||||||
|
this.items = items;
|
||||||
|
this.assignRows();
|
||||||
|
this.indexes = new Map(items.map(i => [i.idx, i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
assignRows() {
|
||||||
|
this.items.forEach((item, idx) => item.rowid = idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
get length() {
|
||||||
|
return this.items.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
get checked() {
|
||||||
|
const rv: number[] = [];
|
||||||
|
this.items.forEach(function (item, idx) {
|
||||||
|
if (item.matched && item.matched !== "unmanual") {
|
||||||
|
rv.push(idx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
get checkedIndexes() {
|
||||||
|
const rv: number[] = [];
|
||||||
|
this.items.forEach(function (item) {
|
||||||
|
if (item.matched && item.matched !== "unmanual") {
|
||||||
|
rv.push(item.idx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
at(idx: number) {
|
||||||
|
return this.items[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
byIndex(idx: number) {
|
||||||
|
return this.indexes.get(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
sort(keyFn: KeyFn) {
|
||||||
|
sort(this.items, keyFn, naturalCaseCompare);
|
||||||
|
this.assignRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse() {
|
||||||
|
this.items.reverse();
|
||||||
|
this.assignRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
filter(fn: (item: BaseMatchedItem, idx: number) => boolean) {
|
||||||
|
return this.items.filter(fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class SelectionTable extends VirtualTable {
|
class SelectionTable extends VirtualTable {
|
||||||
checkClasser: CheckClasser;
|
checkClasser: CheckClasser;
|
||||||
|
|
||||||
icons: Icons;
|
icons: Icons;
|
||||||
|
|
||||||
links: BaseMatchedItem[];
|
links: ItemCollection;
|
||||||
|
|
||||||
media: BaseMatchedItem[];
|
media: ItemCollection;
|
||||||
|
|
||||||
|
items: ItemCollection;
|
||||||
|
|
||||||
type: string;
|
type: string;
|
||||||
|
|
||||||
items: BaseMatchedItem[];
|
|
||||||
|
|
||||||
status: HTMLElement;
|
status: HTMLElement;
|
||||||
|
|
||||||
linksTab: HTMLElement;
|
linksTab: HTMLElement;
|
||||||
@ -170,10 +232,10 @@ class SelectionTable extends VirtualTable {
|
|||||||
|
|
||||||
this.checkClasser = new CheckClasser(NUM_FILTER_CLASSES);
|
this.checkClasser = new CheckClasser(NUM_FILTER_CLASSES);
|
||||||
this.icons = new Icons($("#icons") as HTMLStyleElement);
|
this.icons = new Icons($("#icons") as HTMLStyleElement);
|
||||||
this.links = links;
|
this.links = new ItemCollection(links);
|
||||||
this.media = media;
|
this.media = new ItemCollection(media);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.items = (this as any)[type];
|
this.items = type === "links" ? this.links : this.media;
|
||||||
|
|
||||||
this.status = $("#statusItems");
|
this.status = $("#statusItems");
|
||||||
this.linksTab = $("#linksTab");
|
this.linksTab = $("#linksTab");
|
||||||
@ -217,8 +279,8 @@ class SelectionTable extends VirtualTable {
|
|||||||
if (!keyfn) {
|
if (!keyfn) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
sort(this.links, keyfn, naturalCaseCompare);
|
this.links.sort(keyfn);
|
||||||
sort(this.media, keyfn, naturalCaseCompare);
|
this.media.sort(keyfn);
|
||||||
const elem = document.querySelector<HTMLElement>(`#${colid}`);
|
const elem = document.querySelector<HTMLElement>(`#${colid}`);
|
||||||
const oldelem = (this.sortcol && document.querySelector<HTMLElement>(`#${this.sortcol}`));
|
const oldelem = (this.sortcol && document.querySelector<HTMLElement>(`#${this.sortcol}`));
|
||||||
if (this.sortcol === colid && this.sortasc) {
|
if (this.sortcol === colid && this.sortasc) {
|
||||||
@ -280,7 +342,7 @@ class SelectionTable extends VirtualTable {
|
|||||||
}
|
}
|
||||||
let oldmask = "";
|
let oldmask = "";
|
||||||
for (const r of this.selection) {
|
for (const r of this.selection) {
|
||||||
const m = this.items[r].mask;
|
const m = this.items.at(r).mask;
|
||||||
if (oldmask && m !== oldmask) {
|
if (oldmask && m !== oldmask) {
|
||||||
oldmask = "";
|
oldmask = "";
|
||||||
break;
|
break;
|
||||||
@ -292,7 +354,7 @@ class SelectionTable extends VirtualTable {
|
|||||||
const newmask = await ModalDialog.prompt(
|
const newmask = await ModalDialog.prompt(
|
||||||
"Renaming mask", "Set new renaming mask", oldmask);
|
"Renaming mask", "Set new renaming mask", oldmask);
|
||||||
for (const r of this.selection) {
|
for (const r of this.selection) {
|
||||||
this.items[r].mask = newmask;
|
this.items.at(r).mask = newmask;
|
||||||
this.invalidateRow(r);
|
this.invalidateRow(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,16 +379,6 @@ class SelectionTable extends VirtualTable {
|
|||||||
this.switchTab(type);
|
this.switchTab(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
get checkedIndexes() {
|
|
||||||
const rv: number[] = [];
|
|
||||||
this.items.forEach(function (item, idx) {
|
|
||||||
if (item.matched && item.matched !== "unmanual") {
|
|
||||||
rv.push(idx);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
get rowCount() {
|
get rowCount() {
|
||||||
return this.items.length;
|
return this.items.length;
|
||||||
}
|
}
|
||||||
@ -336,7 +388,7 @@ class SelectionTable extends VirtualTable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (const rowid of this.selection) {
|
for (const rowid of this.selection) {
|
||||||
const item = this.items[rowid];
|
const item = this.items.at(rowid);
|
||||||
if (!state) {
|
if (!state) {
|
||||||
state = matched(item) ? "unmanual" : "manual";
|
state = matched(item) ? "unmanual" : "manual";
|
||||||
}
|
}
|
||||||
@ -362,7 +414,7 @@ class SelectionTable extends VirtualTable {
|
|||||||
selectChecked() {
|
selectChecked() {
|
||||||
this.selection.clear();
|
this.selection.clear();
|
||||||
let min = null;
|
let min = null;
|
||||||
for (const ci of this.checkedIndexes) {
|
for (const ci of this.items.checked) {
|
||||||
this.selection.add(ci);
|
this.selection.add(ci);
|
||||||
min = min === null ? ci : Math.min(min, ci);
|
min = min === null ? ci : Math.min(min, ci);
|
||||||
}
|
}
|
||||||
@ -381,7 +433,7 @@ class SelectionTable extends VirtualTable {
|
|||||||
if (this.focusRow < 0) {
|
if (this.focusRow < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
items.push(this.items[this.focusRow]);
|
items.push(this.items.at(this.focusRow));
|
||||||
}
|
}
|
||||||
PORT.postMessage({
|
PORT.postMessage({
|
||||||
msg: "openUrls",
|
msg: "openUrls",
|
||||||
@ -389,14 +441,14 @@ class SelectionTable extends VirtualTable {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
applyDeltaTo(delta: ItemDelta[], items: BaseMatchedItem[]) {
|
applyDeltaTo(delta: ItemDelta[], items: ItemCollection) {
|
||||||
const active = items === this.items;
|
const active = items === this.items;
|
||||||
for (const d of delta) {
|
for (const d of delta) {
|
||||||
const {idx = -1, matched = null} = d;
|
const {idx = -1, matched = null} = d;
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const item = items[idx];
|
const item = items.byIndex(idx);
|
||||||
if (!item) {
|
if (!item) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -410,7 +462,7 @@ class SelectionTable extends VirtualTable {
|
|||||||
}
|
}
|
||||||
item.matched = matched;
|
item.matched = matched;
|
||||||
if (active) {
|
if (active) {
|
||||||
this.invalidateRow(idx);
|
this.invalidateRow(item.rowid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -435,7 +487,7 @@ class SelectionTable extends VirtualTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateStatus() {
|
updateStatus() {
|
||||||
const selected = this.checkedIndexes.length;
|
const selected = this.items.checked.length;
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
this.status.textContent = _("noitems.label");
|
this.status.textContent = _("noitems.label");
|
||||||
}
|
}
|
||||||
@ -446,7 +498,7 @@ class SelectionTable extends VirtualTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getRowClasses(rowid: number) {
|
getRowClasses(rowid: number) {
|
||||||
const item = this.items[rowid];
|
const item = this.items.at(rowid);
|
||||||
if (!item || !matched(item) || !item.matched) {
|
if (!item || !matched(item) || !item.matched) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -454,7 +506,7 @@ class SelectionTable extends VirtualTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCellIcon(rowid: number, colid: number) {
|
getCellIcon(rowid: number, colid: number) {
|
||||||
const item = this.items[rowid];
|
const item = this.items.at(rowid);
|
||||||
if (item && colid === COL_DOWNLOAD) {
|
if (item && colid === COL_DOWNLOAD) {
|
||||||
return this.icons.get(iconForPath(item.url, ICON_BASE_SIZE));
|
return this.icons.get(iconForPath(item.url, ICON_BASE_SIZE));
|
||||||
}
|
}
|
||||||
@ -471,7 +523,7 @@ class SelectionTable extends VirtualTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDownloadText(idx: number) {
|
getDownloadText(idx: number) {
|
||||||
const item = this.items[idx];
|
const item = this.items.at(idx);
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -482,7 +534,7 @@ class SelectionTable extends VirtualTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getText(prop: string, idx: number) {
|
getText(prop: string, idx: number) {
|
||||||
const item: any = this.items[idx];
|
const item: any = this.items.at(idx);
|
||||||
if (!item || !(prop in item) || !item[prop]) {
|
if (!item || !(prop in item) || !item[prop]) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -490,7 +542,7 @@ class SelectionTable extends VirtualTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getMaskText(idx: number) {
|
getMaskText(idx: number) {
|
||||||
const item = this.items[idx];
|
const item = this.items.at(idx);
|
||||||
if (item) {
|
if (item) {
|
||||||
return item.mask;
|
return item.mask;
|
||||||
}
|
}
|
||||||
@ -521,13 +573,13 @@ class SelectionTable extends VirtualTable {
|
|||||||
|
|
||||||
getCellCheck(rowid: number, colid: number) {
|
getCellCheck(rowid: number, colid: number) {
|
||||||
if (colid === COL_CHECK) {
|
if (colid === COL_CHECK) {
|
||||||
return !!matched(this.items[rowid]);
|
return !!matched(this.items.at(rowid));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
setCellCheck(rowid: number, colid: number, value: boolean) {
|
setCellCheck(rowid: number, colid: number, value: boolean) {
|
||||||
this.items[rowid].matched = value ? "manual" : "unmanual";
|
this.items.at(rowid).matched = value ? "manual" : "unmanual";
|
||||||
this.invalidateRow(rowid);
|
this.invalidateRow(rowid);
|
||||||
this.updateStatus();
|
this.updateStatus();
|
||||||
}
|
}
|
||||||
@ -539,7 +591,7 @@ async function download(paused = false) {
|
|||||||
if (!mask) {
|
if (!mask) {
|
||||||
throw new Error("error.invalidMask");
|
throw new Error("error.invalidMask");
|
||||||
}
|
}
|
||||||
const items = Table.checkedIndexes;
|
const items = Table.items.checkedIndexes;
|
||||||
if (!items.length) {
|
if (!items.length) {
|
||||||
throw new Error("error.noItemsSelected");
|
throw new Error("error.noItemsSelected");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user