sel: refactor backtracking

Signed-off-by: Varun Patil <radialapps@gmail.com>
pull/953/head
Varun Patil 2023-11-26 18:51:59 -08:00
parent 0250b27bdf
commit 366c6dc5e2
1 changed files with 53 additions and 33 deletions

View File

@ -652,53 +652,73 @@ export default defineComponent({
const pIdx = pRow.photos?.indexOf(photo) ?? -1; const pIdx = pRow.photos?.indexOf(photo) ?? -1;
if (pIdx === -1) return; if (pIdx === -1) return;
const updateDaySet = new Set<number>(); /**
let behind: IPhoto[] = []; * @brief Look behind for a selected photo.
let behindFound = false; * @returns the list of photos behind the current photo upto
* the first selected photo.
* @returns null if no selected photo is found.
*/
const lookBehind = (): IPhoto[] | undefined => {
const result: IPhoto[] = [];
for (let i = rowIdx; i >= Math.max(rowIdx - 1000, 0); i--) {
const row = rows[i];
if (row.type !== 1) continue; // skip non-photo rows
// Look behind // Give up if unloaded rows are found
for (let i = rowIdx; i > rowIdx - 100; i--) { if (!row.photos?.length) break;
if (i < 0) break;
if (rows[i].type !== 1) continue;
if (!rows[i].photos?.length) break;
const sj = i === rowIdx ? pIdx : rows[i].photos!.length - 1; // Iterate photos in this row from the end
for (let j = sj; j >= 0; j--) { const sj = i === rowIdx ? pIdx : row.photos.length - 1;
const p = rows[i].photos![j]; for (let j = sj; j >= 0; j--) {
if (p.flag & this.c.FLAG_PLACEHOLDER || !p.fileid) continue; const p = row.photos[j];
if (p.flag & this.c.FLAG_SELECTED) { if (p.flag & this.c.FLAG_PLACEHOLDER || !p.fileid) continue;
behindFound = true;
break; if (p.flag & this.c.FLAG_SELECTED) {
// Found a selected photo, return everything excluding this
return result;
}
result.push(p);
} }
behind.push(p);
updateDaySet.add(p.dayid);
} }
};
if (behindFound) break; // Set of dayIds to update
} const touchedDays = new Set<number>();
// Select everything behind // Select everything behind
if (behindFound) { const behind = lookBehind();
const detail = photo.d!.detail!; if (behind) {
// Clear everything in front in this day // Clear everything in front in this day
const detail = photo.d!.detail!;
const pdIdx = detail.indexOf(photo); const pdIdx = detail.indexOf(photo);
for (let i = pdIdx + 1; i < detail.length; i++) { for (let i = pdIdx + 1; i < detail.length; i++) {
if (detail[i].flag & this.c.FLAG_SELECTED) this.selectPhoto(detail[i], false, true); if (detail[i].flag & this.c.FLAG_SELECTED) {
this.selectPhoto(detail[i], false, true);
}
} }
// Clear everything else in front // De-select everything else in front (other days)
Array.from(this.selection.values()) for (const [_, p] of this.selection) {
.filter((p: IPhoto) => (this.isreverse ? p.dayid > photo.dayid : p.dayid < photo.dayid)) if (this.isreverse ? p.dayid > photo.dayid : p.dayid < photo.dayid) {
.forEach((photo: IPhoto) => { this.selectPhoto(p, false, true);
this.selectPhoto(photo, false, true); touchedDays.add(p.dayid);
updateDaySet.add(photo.dayid); }
}); }
behind.forEach((p) => this.selectPhoto(p, true, true)); // Select everything behind upto the selected photo
updateDaySet.forEach((dayid) => this.updateHeadSelected(this.heads.get(dayid)!)); for (const p of behind) {
this.$forceUpdate(); this.selectPhoto(p, true, true);
touchedDays.add(p.dayid);
}
} }
// Force update for all days that were touched
for (const dayid of touchedDays) {
this.updateHeadSelected(this.heads.get(dayid)!);
}
this.$forceUpdate();
}, },
/** Select or deselect all photos in a head */ /** Select or deselect all photos in a head */