diff --git a/mediarepo-ui/src/app/app.module.ts b/mediarepo-ui/src/app/app.module.ts
index cc10402..aeb3a44 100644
--- a/mediarepo-ui/src/app/app.module.ts
+++ b/mediarepo-ui/src/app/app.module.ts
@@ -42,6 +42,7 @@ import {BlockUIModule} from "primeng/blockui";
import {PanelModule} from "primeng/panel";
import {DragDropModule} from "@angular/cdk/drag-drop";
import { ContentAwareImageComponent } from './components/content-aware-image/content-aware-image.component';
+import {MatSliderModule} from "@angular/material/slider";
@NgModule({
declarations: [
@@ -90,6 +91,7 @@ import { ContentAwareImageComponent } from './components/content-aware-image/con
BlockUIModule,
PanelModule,
DragDropModule,
+ MatSliderModule,
],
providers: [],
bootstrap: [AppComponent]
diff --git a/mediarepo-ui/src/app/components/content-aware-image/content-aware-image.component.ts b/mediarepo-ui/src/app/components/content-aware-image/content-aware-image.component.ts
index 183e301..e0a113a 100644
--- a/mediarepo-ui/src/app/components/content-aware-image/content-aware-image.component.ts
+++ b/mediarepo-ui/src/app/components/content-aware-image/content-aware-image.component.ts
@@ -22,10 +22,8 @@ export class ContentAwareImageComponent {
public adjustSize(image: HTMLImageElement, imageContainer: HTMLDivElement): void {
const containerHeight = Math.abs(imageContainer.clientHeight);
const containerWidth = Math.abs(imageContainer.clientWidth);
- console.log(containerHeight, ',', containerWidth);
const imageRelativeHeight = image.height / containerHeight;
const imageRelativeWidth = image.width / containerWidth;
- console.log(imageRelativeHeight, ',', imageRelativeWidth);
this.scaleWidth = imageRelativeWidth > imageRelativeHeight;
}
}
diff --git a/mediarepo-ui/src/app/components/file-gallery/file-gallery.component.html b/mediarepo-ui/src/app/components/file-gallery/file-gallery.component.html
index f4a3a4a..b0ef55d 100644
--- a/mediarepo-ui/src/app/components/file-gallery/file-gallery.component.html
+++ b/mediarepo-ui/src/app/components/file-gallery/file-gallery.component.html
@@ -4,11 +4,22 @@
-
diff --git a/mediarepo-ui/src/app/components/file-gallery/file-gallery.component.scss b/mediarepo-ui/src/app/components/file-gallery/file-gallery.component.scss
index 7eec01d..e21ad47 100644
--- a/mediarepo-ui/src/app/components/file-gallery/file-gallery.component.scss
+++ b/mediarepo-ui/src/app/components/file-gallery/file-gallery.component.scss
@@ -13,6 +13,7 @@
height: 100%;
width: 100%;
position: relative;
+ user-select: none;
}
app-file-gallery-entry, .file-item {
@@ -28,6 +29,7 @@ app-file-gallery-entry {
.file-full-view {
width: 100%;
height: 100%;
+ overflow: hidden;
}
.file-full-view-inner {
@@ -63,3 +65,30 @@ app-content-aware-image {
margin: auto;
}
}
+
+.image-drag-container, .image-scale-container {
+ height: 100%;
+ width: 100%;
+}
+
+.image-scale-container {
+ display: block;
+}
+
+.zoom-slider {
+ position: absolute;
+ display: flex;
+ flex-direction: column;
+ right: 1em;
+ bottom: 1em;
+ z-index: 10;
+ opacity: 0.5;
+ padding: 1em 0.5em;
+ transition-duration: 0.2s;
+}
+
+.zoom-slider:hover {
+ opacity: 1;
+ background-color: rgba(0, 0, 0, 0.3);
+ border-radius: 1em;
+}
diff --git a/mediarepo-ui/src/app/components/file-gallery/file-gallery.component.ts b/mediarepo-ui/src/app/components/file-gallery/file-gallery.component.ts
index e4fce1f..ee8d354 100644
--- a/mediarepo-ui/src/app/components/file-gallery/file-gallery.component.ts
+++ b/mediarepo-ui/src/app/components/file-gallery/file-gallery.component.ts
@@ -11,6 +11,7 @@ import {FileService} from "../../services/file/file.service";
import {SafeResourceUrl} from "@angular/platform-browser";
import {Selectable} from "../../models/Selectable";
import {CdkVirtualScrollViewport} from "@angular/cdk/scrolling";
+import {CdkDrag, CdkDragMove, DragRef, Point} from "@angular/cdk/drag-drop";
@Component({
selector: 'app-file-gallery',
@@ -27,10 +28,13 @@ export class FileGalleryComponent implements OnChanges, OnInit {
entries: Selectable
[] = [];
@ViewChild("virtualScroll") virtualScroll!: CdkVirtualScrollViewport;
+ @ViewChild("scaledImage") scaledImage: ElementRef | undefined;
+ @ViewChild("imageDragContainer") imageDragContainer: ElementRef | undefined;
public selectedFile: Selectable | undefined;
fileContentUrl: SafeResourceUrl | undefined;
- scaleWidth = false;
+ public imageZoom = 1;
+ public imagePosition = {x: 0, y: 0};
constructor(private fileService: FileService) {
}
@@ -42,6 +46,7 @@ export class FileGalleryComponent implements OnChanges, OnInit {
*/
async onEntrySelect(entry: Selectable) {
if (entry) {
+ this.resetImage();
this.selectedFile?.unselect();
entry.select();
this.selectedFile = entry;
@@ -58,7 +63,8 @@ export class FileGalleryComponent implements OnChanges, OnInit {
async loadSelectedFile() {
if (this.selectedFile) {
this.fileContentUrl = undefined;
- this.fileContentUrl = await this.fileService.readFile(this.selectedFile.data);
+ this.fileContentUrl = await this.fileService.readFile(
+ this.selectedFile.data);
}
}
@@ -69,8 +75,10 @@ export class FileGalleryComponent implements OnChanges, OnInit {
}
public async ngOnChanges(changes: SimpleChanges): Promise {
- this.entries = this.files.map(f => new Selectable(f, f.hash == this.selectedFile?.data.hash));
- const selectedIndex = this.files.findIndex(f => f.hash === this.selectedFile?.data.hash);
+ this.entries = this.files.map(
+ f => new Selectable(f, f.hash == this.selectedFile?.data.hash));
+ const selectedIndex = this.files.findIndex(
+ f => f.hash === this.selectedFile?.data.hash);
if (!this.selectedFile || selectedIndex < 0) {
await this.onEntrySelect(this.getPreselectedEntry() ?? this.entries[0])
@@ -111,6 +119,11 @@ export class FileGalleryComponent implements OnChanges, OnInit {
}
}
+ public resetImage() {
+ this.imageZoom = 1;
+ this.imagePosition = {x: 0, y: 0};
+ }
+
@HostListener("window:keydown", ["$event"])
private async handleKeydownEvent(event: KeyboardEvent) {
switch (event.key) {
@@ -120,12 +133,33 @@ export class FileGalleryComponent implements OnChanges, OnInit {
case "ArrowLeft":
await this.previousItem();
break;
+ case "Escape":
+ this.resetImage();
+ break;
+ }
+ }
+
+ @HostListener("mousewheel", ["$event"])
+ private handleScroll(event: any) {
+ const delta = event.wheelDelta ?? event.detail
+
+ if (delta > 0) {
+ this.imageZoom += 0.2
+ if (this.imageZoom > 4) {
+ this.imageZoom = 4;
+ }
+ } else if (delta < 0) {
+ this.imageZoom -= 0.2
+ if (this.imageZoom < 0.5) {
+ this.imageZoom = 0.5;
+ }
}
}
private getPreselectedEntry(): Selectable | undefined {
if (this.preselectedFile) {
- const entry = this.entries.find(e => e.data.hash == this.preselectedFile?.hash);
+ const entry = this.entries.find(
+ e => e.data.hash == this.preselectedFile?.hash);
if (entry) {
return entry;
}
@@ -133,10 +167,8 @@ export class FileGalleryComponent implements OnChanges, OnInit {
return undefined;
}
- public adjustImageSize(fullImage: HTMLImageElement, imageContainer: HTMLDivElement): void {
- const containerRatio = imageContainer.clientHeight / imageContainer.clientWidth;
- const imageAdjHeight = fullImage.height / containerRatio;
- const imageAdjWidth = fullImage.width * containerRatio;
- this.scaleWidth = imageAdjWidth > imageAdjHeight;
+ public onDragMoved($event: CdkDragMove): void {
+ this.imagePosition.x += $event.delta.x;
+ this.imagePosition.y += $event.delta.y;
}
}
diff --git a/mediarepo-ui/src/app/pages/home/search-page/search-page.component.html b/mediarepo-ui/src/app/pages/home/search-page/search-page.component.html
index d1ef5e6..d2fe202 100644
--- a/mediarepo-ui/src/app/pages/home/search-page/search-page.component.html
+++ b/mediarepo-ui/src/app/pages/home/search-page/search-page.component.html
@@ -26,7 +26,7 @@
(fileMultiselectEvent)="onFileMultiSelect($event)"
>
diff --git a/mediarepo-ui/src/app/pages/home/search-page/search-page.component.ts b/mediarepo-ui/src/app/pages/home/search-page/search-page.component.ts
index 32203e5..510a43b 100644
--- a/mediarepo-ui/src/app/pages/home/search-page/search-page.component.ts
+++ b/mediarepo-ui/src/app/pages/home/search-page/search-page.component.ts
@@ -86,19 +86,6 @@ export class SearchPageComponent implements OnInit {
event.source.deselectAll();
}
- async openFile(file: File) {
- if (this.openingLightbox) {
- return;
- }
- this.openingLightbox = true;
- try {
- await this.openLightbox(file);
- } catch (err) {
- this.errorBroker.showError(err);
- }
- this.openingLightbox = false;
- }
-
async openGallery(preselectedFile: File) {
this.preselectedFile = preselectedFile;
this.showGallery = true;
@@ -108,29 +95,4 @@ export class SearchPageComponent implements OnInit {
this.preselectedFile = preselectedFile;
this.showGallery = false;
}
-
- private async openLightbox(file: File): Promise {
- let url = await this.fileService.readFile(file);
-
- let albums = [
- {
- src: url as string,
- caption: file.name ?? file.comment,
- thumb: url as string,
- }
- ];
- this.lightbox.open(albums, 0, {
- disableScrolling: true,
- showImageNumberLabel: false,
- showDownloadButton: true,
- centerVertically: true,
- });
- const lighboxSubscription = this.lightboxEvent.lightboxEvent$.subscribe(
- (event: any) => {
- if (event?.id == LIGHTBOX_EVENT.CLOSE) {
- lighboxSubscription.unsubscribe();
- URL?.revokeObjectURL(url as string);
- }
- })
- }
}