diff --git a/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.ts b/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.ts
index e045c04..3c4f421 100644
--- a/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.ts
+++ b/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.ts
@@ -130,7 +130,7 @@ export class RepositoriesTabComponent implements OnInit, AfterViewInit {
"Opening repository...");
let dialog = this.dialog.open(BusyDialogComponent, {
data: {
- title: `Opening repository ${repository.name}`,
+ title: `Opening repository '${repository.name}'`,
message: dialogMessage,
allowCancel: true,
}, disableClose: true,
diff --git a/mediarepo-ui/src/app/components/shared/file/file-multiview/file-gallery/file-gallery.component.html b/mediarepo-ui/src/app/components/shared/file/file-multiview/file-gallery/file-gallery.component.html
index df8426b..2e48be3 100644
--- a/mediarepo-ui/src/app/components/shared/file/file-multiview/file-gallery/file-gallery.component.html
+++ b/mediarepo-ui/src/app/components/shared/file/file-multiview/file-gallery/file-gallery.component.html
@@ -1,4 +1,8 @@
-
();
@Output() fileDeleted = new EventEmitter();
- @ViewChild("virtualScroll") virtualScroll!: CdkVirtualScrollViewport;
-
@ViewChild("inner") inner!: ElementRef;
+ @ViewChild("previewStripContainer") stripContainer!: ElementRef;
public entries: Selectable[] = [];
public selectedFile: Selectable | undefined;
@@ -45,15 +47,16 @@ export class FileGalleryComponent implements OnChanges, OnInit, AfterViewInit {
public imageViewHeightPercent = 80;
public previewStripVisible = true;
+ public previewedEntries: (Selectable | undefined)[] = [];
- private scrollTimeout: number | undefined;
+ private previewStripCount = 5;
private escapeCount = 0;
constructor(
+ private changeDetector: ChangeDetectorRef,
private tabService: TabService,
private fileService: FileService
) {
- tabService.selectedTab.subscribe(() => this.adjustElementSizes());
}
async ngOnInit(): Promise {
@@ -61,6 +64,8 @@ export class FileGalleryComponent implements OnChanges, OnInit, AfterViewInit {
this.selectedFile.data) < 0) {
await this.onEntrySelect(
this.getPreselectedEntry() ?? this.entries[0]);
+ } else {
+ this.buildPreviewedFiles();
}
}
@@ -84,6 +89,10 @@ export class FileGalleryComponent implements OnChanges, OnInit, AfterViewInit {
}
}
+ public ngAfterViewChecked(): void {
+ this.calculatePreviewCount();
+ }
+
/**
* Called when a new entry is selected
* @param {Selectable} entry
@@ -96,15 +105,8 @@ export class FileGalleryComponent implements OnChanges, OnInit, AfterViewInit {
this.selectedFile = entry;
await this.loadSelectedFile();
- if (this.virtualScroll) {
- clearTimeout(this.scrollTimeout);
- this.scrollTimeout = setTimeout(
- () => this.scrollToSelection(),
- 0
- ); // we need to make sure the viewport has rendered
- }
-
this.fileSelect.emit(this.selectedFile.data);
+ this.buildPreviewedFiles();
}
}
@@ -151,13 +153,6 @@ export class FileGalleryComponent implements OnChanges, OnInit, AfterViewInit {
}
}
- public adjustElementSizes(): void {
- if (this.virtualScroll) {
- this.virtualScroll.checkViewportSize();
- this.scrollToSelection();
- }
- }
-
public focus() {
this.inner.nativeElement.focus();
}
@@ -181,8 +176,8 @@ export class FileGalleryComponent implements OnChanges, OnInit, AfterViewInit {
}
}
- public trackByFileId(index: number, item: Selectable) {
- return item.data.id;
+ public trackByFileId(index: number, item?: Selectable) {
+ return item?.data.id;
}
public onFileStatusChange(): void {
@@ -199,23 +194,24 @@ export class FileGalleryComponent implements OnChanges, OnInit, AfterViewInit {
}
}
- private scrollToSelection(): void {
- if (this.selectedFile) {
- const selectedIndex = this.entries.indexOf(this.selectedFile);
- const viewportSize = this.virtualScroll.getViewportSize();
- const indexAdjustment = (viewportSize / 260) / 2; // adjustment to have the selected item centered
- this.virtualScroll.scrollToIndex(
- Math.max(selectedIndex - indexAdjustment, 0), "smooth");
-
- if (selectedIndex > indexAdjustment) {
- this.virtualScroll.scrollToOffset(
- this.virtualScroll.measureScrollOffset("left") + 130,
- "smooth"
- );
+ public calculatePreviewCount() {
+ if (this.stripContainer && this.stripContainer.nativeElement) {
+ const width = Math.abs(this.stripContainer.nativeElement.clientWidth);
+ const height = Math.abs(this.stripContainer.nativeElement.clientHeight);
+
+ const count = Math.floor(Math.floor(width / height) / 2) * 2 + 1;
+
+ if (count != this.previewStripCount) {
+ this.previewStripCount = count;
+ this.buildPreviewedFiles();
}
}
}
+ public onResize(): void {
+ this.changeDetector.markForCheck();
+ }
+
private getPreselectedEntry(): Selectable | undefined {
if (this.preselectedFile) {
const entry = this.entries.find(
@@ -235,4 +231,26 @@ export class FileGalleryComponent implements OnChanges, OnInit, AfterViewInit {
setTimeout(() => this.escapeCount--, 500);
}
}
+
+ private buildPreviewedFiles() {
+ if (!this.selectedFile) {
+ if (this.entries) {
+ this.onEntrySelect(this.entries[0]).catch(console.error);
+ }
+ return;
+ }
+ const selectedIndex = this.entries.indexOf(this.selectedFile!);
+ const previewCountLR = Math.floor(this.previewStripCount / 2);
+ const previewedEntries = [];
+
+ for (let i = selectedIndex - previewCountLR; i <= selectedIndex + previewCountLR; i++) {
+ if (i >= 0 && i < this.entries.length) {
+ previewedEntries.push(this.entries[i]);
+ } else {
+ previewedEntries.push(undefined);
+ }
+ }
+ this.previewedEntries = previewedEntries;
+ this.changeDetector.markForCheck();
+ }
}
diff --git a/mediarepo-ui/src/app/components/shared/file/file-multiview/file-grid/file-grid.component.html b/mediarepo-ui/src/app/components/shared/file/file-multiview/file-grid/file-grid.component.html
index f2e0528..bf3f256 100644
--- a/mediarepo-ui/src/app/components/shared/file/file-multiview/file-grid/file-grid.component.html
+++ b/mediarepo-ui/src/app/components/shared/file/file-multiview/file-grid/file-grid.component.html
@@ -1,7 +1,7 @@