Change file grid to have a dynamic column count

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/14/head
trivernis 3 years ago
parent e9b77a3811
commit 398d904169
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -3,6 +3,7 @@ all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows" windows_subsystem = "windows"
)] )]
use tauri::{LogicalSize, Size};
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
use tracing_subscriber::fmt::format::FmtSpan; use tracing_subscriber::fmt::format::FmtSpan;
@ -15,7 +16,8 @@ fn main() {
.init(); .init();
mediarepo_api::tauri_plugin::register_plugin(tauri::Builder::default()) mediarepo_api::tauri_plugin::register_plugin(tauri::Builder::default())
.on_page_load(|window, _| { .on_page_load(|window, _| {
window.set_title(format!("mediarepo {}", env!("CARGO_PKG_VERSION")).as_str()).unwrap(); window.set_title(format!("mediarepo {}", env!("CARGO_PKG_VERSION")).as_str()).expect("failed to set window title");
window.set_min_size(Some(Size::Logical(LogicalSize { width: 1000.0, height: 750.0 }))).expect("failed to set minimal size");
}) })
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");

@ -1,12 +1,23 @@
import {Component, DoCheck, ElementRef, Input, OnInit, ViewChild} from "@angular/core"; import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
DoCheck,
ElementRef,
Input,
OnDestroy,
OnInit,
ViewChild
} from "@angular/core";
import {SafeResourceUrl} from "@angular/platform-browser"; import {SafeResourceUrl} from "@angular/platform-browser";
@Component({ @Component({
selector: "app-content-aware-image", selector: "app-content-aware-image",
templateUrl: "./content-aware-image.component.html", templateUrl: "./content-aware-image.component.html",
styleUrls: ["./content-aware-image.component.scss"] styleUrls: ["./content-aware-image.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class ContentAwareImageComponent implements OnInit, DoCheck { export class ContentAwareImageComponent implements OnInit, DoCheck, OnDestroy {
@Input() imageSrc!: string | SafeResourceUrl; @Input() imageSrc!: string | SafeResourceUrl;
@Input() maximizeHeight: boolean = true; @Input() maximizeHeight: boolean = true;
@Input() maximizeWidth: boolean = true; @Input() maximizeWidth: boolean = true;
@ -17,17 +28,28 @@ export class ContentAwareImageComponent implements OnInit, DoCheck {
scaleWidth = false; scaleWidth = false;
private previousHeight = 0; private previousHeight = 0;
private previousWidth = 0; private previousWidth = 0;
private readonly checkInterval?: number;
constructor() { constructor(private changeDetector: ChangeDetectorRef) {
this.checkInterval = setInterval(() => this.checkSize(), 1000);
} }
public ngOnInit(): void { public ngOnInit(): void {
if (this.image) { if (this.image) {
this.image.nativeElement.decoding = this.decoding; this.image.nativeElement.decoding = this.decoding;
this.changeDetector.detach();
} }
} }
public ngOnDestroy(): void {
clearInterval(this.checkInterval);
}
public ngDoCheck(): void { public ngDoCheck(): void {
this.checkSize();
}
public checkSize(): void {
if (this.image?.nativeElement && this.imageContainer?.nativeElement) { if (this.image?.nativeElement && this.imageContainer?.nativeElement) {
this.adjustSize(this.image.nativeElement, this.imageContainer.nativeElement); this.adjustSize(this.image.nativeElement, this.imageContainer.nativeElement);
} }
@ -47,7 +69,12 @@ export class ContentAwareImageComponent implements OnInit, DoCheck {
this.previousWidth = containerWidth; this.previousWidth = containerWidth;
const imageRelativeHeight = image.naturalHeight / containerHeight; const imageRelativeHeight = image.naturalHeight / containerHeight;
const imageRelativeWidth = image.naturalWidth / containerWidth; const imageRelativeWidth = image.naturalWidth / containerWidth;
this.scaleWidth = imageRelativeWidth > imageRelativeHeight; const scaleWidth = imageRelativeWidth > imageRelativeHeight;
if (scaleWidth != this.scaleWidth) {
this.scaleWidth = scaleWidth;
this.changeDetector.detectChanges();
}
} }
} }
} }

@ -1,6 +1,7 @@
<div #inner <div #inner
(keyDownEvent)="handleKeydownEvent($event)" (keyDownEvent)="handleKeydownEvent($event)"
(keyUpEvent)="handleKeyupEvent($event)" (keyUpEvent)="handleKeyupEvent($event)"
(window:resize)="this.calculateColumnCount()"
appInputReceiver appInputReceiver
class="file-grid-inner"> class="file-grid-inner">
<cdk-virtual-scroll-viewport #virtualScrollGrid class="file-scroll" itemSize="260" maxBufferPx="2000" <cdk-virtual-scroll-viewport #virtualScrollGrid class="file-scroll" itemSize="260" maxBufferPx="2000"

@ -1,6 +1,8 @@
import { import {
AfterViewChecked,
AfterViewInit, AfterViewInit,
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef,
Component, Component,
ElementRef, ElementRef,
EventEmitter, EventEmitter,
@ -27,10 +29,9 @@ import {LoggingService} from "../../../../../services/logging/logging.service";
styleUrls: ["./file-grid.component.scss"], styleUrls: ["./file-grid.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class FileGridComponent implements OnChanges, OnInit, AfterViewInit { export class FileGridComponent implements OnChanges, OnInit, AfterViewInit, AfterViewChecked {
@Input() files: File[] = []; @Input() files: File[] = [];
@Input() columns: number = 6;
@Input() preselectedFile: File | undefined; @Input() preselectedFile: File | undefined;
@Output() fileOpen = new EventEmitter<File>(); @Output() fileOpen = new EventEmitter<File>();
@Output() fileSelect = new EventEmitter<File[]>(); @Output() fileSelect = new EventEmitter<File[]>();
@ -44,11 +45,14 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit {
public selectedEntries: Selectable<File>[] = []; public selectedEntries: Selectable<File>[] = [];
public partitionedGridEntries: Selectable<File>[][] = []; public partitionedGridEntries: Selectable<File>[][] = [];
private columns = 6;
private entrySizePx = 260;
private shiftClicked = false; private shiftClicked = false;
private ctrlClicked = false; private ctrlClicked = false;
private gridEntries: Selectable<File>[] = []; private gridEntries: Selectable<File>[] = [];
constructor( constructor(
private changeDetector: ChangeDetectorRef,
private logger: LoggingService, private logger: LoggingService,
private tabService: TabService, private tabService: TabService,
private fileService: FileService, private fileService: FileService,
@ -64,6 +68,11 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit {
public ngAfterViewInit(): void { public ngAfterViewInit(): void {
this.focus(); this.focus();
this.calculateColumnCount();
}
public ngAfterViewChecked(): void {
this.calculateColumnCount();
} }
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
@ -190,6 +199,20 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit {
this.fileChanged.next(); this.fileChanged.next();
} }
public calculateColumnCount() {
if (this.inner && this.inner.nativeElement) {
const width = Math.abs(this.inner.nativeElement.clientWidth);
const columns = Math.floor(width / this.entrySizePx);
if (columns != this.columns) {
console.debug("grid displaying", columns, "columns");
this.columns = Math.max(columns, 1);
this.setPartitionedGridEntries();
this.changeDetector.detectChanges();
}
}
}
private setPartitionedGridEntries() { private setPartitionedGridEntries() {
this.partitionedGridEntries = []; this.partitionedGridEntries = [];
let scrollToIndex = -1; let scrollToIndex = -1;

Loading…
Cancel
Save