Skip to content

Commit

Permalink
lazyLoading fastboiiii. Add sort dropdown to filters, maybe change or…
Browse files Browse the repository at this point in the history
…der of image downloads to match order of apps
  • Loading branch information
cbartondock committed Jun 13, 2024
1 parent f6db2ea commit 63c622c
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 57 deletions.
11 changes: 5 additions & 6 deletions src/renderer/components/preview.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,11 @@ export class PreviewComponent implements OnDestroy {
return posterUrl ? posterUrl : require('../../assets/images/no-images.svg');
}

/*onAppInView(inView: boolean, appElement: ElementRef, app: PreviewDataApp) {
this.inViewDict[app.extractedTitle]||=inView
}*/

setBackgroundImage(appId: string, app: PreviewDataApp, image: ImageContent,
artworkType?: ArtworkType, imageIndex?: number, notLazy?: boolean) {
const currentViewType = this.previewService.getCurrentViewType();
const actualArtworkType: ArtworkType = this.getActualArtworkType(artworkType);
if(!notLazy && (!this.inViewDict[appId] || !this.inViewDict[appId][actualArtworkType])) { return null; }
if(!notLazy && !this.inViewDict[appId + currentViewType]) { return null; }
if (image == undefined) {
let imagepool: string = app.images[actualArtworkType].imagePool;
if (this.previewService.getImages(actualArtworkType)[imagepool].online)
Expand Down Expand Up @@ -400,6 +396,10 @@ export class PreviewComponent implements OnDestroy {
this.changeDetectionRef.detectChanges();
}

updateDOM() {
this.changeDetectionRef.detectChanges();
}

searchMatches(searchTitle: string) {
this.previewService.getMatchFixes(searchTitle).then((games: any[])=>{
this.matchFixDict = Object.fromEntries(games.map((x: any)=>[x.id.toString(), {name: x.name, posterUrl: x.posterUrl}]));
Expand Down Expand Up @@ -648,7 +648,6 @@ export class PreviewComponent implements OnDestroy {
cancelExcludes() {
this.showExcludes = false;
this.renderer.setStyle(this.elementRef.nativeElement, '--excludes-lower-width', '0%', RendererStyleFlags2.DashCase);

this.excludedAppIds = {};
this.exclusionCount = 0;
}
Expand Down
66 changes: 27 additions & 39 deletions src/renderer/directives/inview.directive.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,50 @@
import { Directive, ElementRef, Input, Output, EventEmitter, OnInit, OnDestroy } from '@angular/core';
import { debounce } from "lodash";
import { ArtworkType, initArtworkRecord } from '../../models';

@Directive({
selector: '[ng-inview]'
})
export class InViewDirective implements OnInit, OnDestroy {
@Input() parentSelector: string;
@Input() childSelector: string;
@Input() margin: number;
@Input() artworkType: ArtworkType;
@Input() inViewDict: {[appId: string]: Record<ArtworkType,boolean>}
@Input() appId: string;
//@Output() inView = new EventEmitter<{inView: boolean, target: ElementRef}>();

private parentElement: HTMLElement;
private parentRect: DOMRect;
@Input() inViewDict: {[inviewkey: string]: boolean}
@Output() updateDOM: EventEmitter<void> = new EventEmitter();
private checkInterval: NodeJS.Timer;
constructor(private el: ElementRef) {}

ngOnInit() {
this.parentElement = this.getParentElement();
if (this.parentElement && (!this.inViewDict[this.appId]||!this.inViewDict[this.appId][this.artworkType])) {
this.parentElement.addEventListener('scroll', this.onParentScroll);
this.parentRect = this.parentElement.getBoundingClientRect();
this.checkInView();
}
this.el.nativeElement.addEventListener('scroll', debounce(() => this.checkInView(), 100))
this.checkInterval = setInterval(()=>this.checkInView(), 500);
}

ngOnDestroy() {
if (this.parentElement) {
this.parentElement.removeEventListener('scroll', this.onParentScroll);
}
this.el.nativeElement.removeEventListener('scroll', this.checkInView)
clearInterval(this.checkInterval);
}

private getParentElement(): HTMLElement {
if (this.parentSelector) {
return document.querySelector(this.parentSelector);
private getChildElements() {
if(this.childSelector) {
return this.el.nativeElement.querySelectorAll(this.childSelector);
} else {
return this.el.nativeElement.parentElement;
return new NodeList() as NodeListOf<Element>;
}
}

private onParentScroll = debounce(() => {
this.checkInView();
}, 200);

private checkInView() {
const rect = this.el.nativeElement.getBoundingClientRect();
const inView = (
rect.top >= this.parentRect.top - this.margin &&
rect.bottom <= this.parentRect.bottom + this.margin
//&& rect.left >= parentRect.left &&
//rect.right <= parentRect.right
);
//this.inView.emit({inView: inView, target: this.el});
if(inView) {
if(!this.inViewDict[this.appId]) {this.inViewDict[this.appId]= initArtworkRecord<boolean>(()=>false)}
this.inViewDict[this.appId][this.artworkType] = true;
this.parentElement.removeEventListener('scroll', this.onParentScroll)
}
const childElements = this.getChildElements();
const scrollRect = this.el.nativeElement.getBoundingClientRect();
childElements.forEach((childElement: Element) => {
if(!this.inViewDict[childElement.getAttribute("data-inviewkey")]) {
const childRect = childElement.getBoundingClientRect();
const inView = (
childRect.top >= scrollRect.top - this.margin &&
childRect.bottom <= scrollRect.bottom + this.margin
);
if(inView) {
this.inViewDict[childElement.getAttribute("data-inviewkey")] = true;
}
}
})
this.updateDOM.emit()
}
}
2 changes: 1 addition & 1 deletion src/renderer/services/preview.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export class PreviewService {
private batchProgress: BehaviorSubject<{update: string, batch: number}>;
private categoryManager: CategoryManager;
private sgdbToArt: SGDBToArt;
inViewDict: {[appId: string]: Record<ArtworkType, boolean>} = {};
inViewDict: {[innerHTML: string]: boolean} = {};

constructor(private parsersService: ParsersService, private loggerService: LoggerService, private imageProviderService: ImageProviderService, private settingsService: SettingsService, private http: HttpClient) {
this.previewData = undefined;
Expand Down
23 changes: 12 additions & 11 deletions src/renderer/templates/preview.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,10 @@ <h1>Add your games to Steam</h1>
</ng-toggle-button>
</div>
</div>

<div
<ng-container *ngVar="getCurrentViewType() as currentViewType">
<div
class="entries"
ng-inview [childSelector]="'.app:not(.retrieving)'" [margin]="400" [inViewDict]="inViewDict" (updateDOM)="updateDOM()"
*ngVar="{ hoverIndex: undefined, hoverType: undefined } as entries"
[class.detailsOpen]="!!this.detailsApp && showDetails"
[class.listImagesOpen]="!!currentApp && showListImages"
Expand All @@ -322,7 +323,7 @@ <h1>Add your games to Steam</h1>
>
</div>
<div class="apps">
<ng-container *ngIf="getCurrentViewType()==='list'">
<ng-container *ngIf="currentViewType==='list'">
<div class="listItem header">
<div class="infoField" (click)="listSortBy='extractedTitle'" [class.sortBy]="listSortBy=='extractedTitle'"><span>Extracted Title</span></div>
<div class="infoField" (click)="listSortBy='title'" [class.sortBy]="listSortBy=='title'"><span>Final Title</span></div>
Expand All @@ -331,17 +332,16 @@ <h1>Add your games to Steam</h1>
</ng-container>
<ng-container *ngFor="let appId of sortedAppIds(previewData[steamDir][steamUser].apps)">
<ng-container *ngVar="previewData[steamDir][steamUser].apps[appId] as app">
<ng-container *ngIf="getCurrentViewType() === 'games'">
<ng-container *ngIf="currentViewType === 'games'">
<div class="title" *ngIf="isAppVisible(app)">
<span [attr.title]="app.extractedTitle">{{ app.title }}</span>
</div>
<ng-container *ngFor="let artworkType of artworkTypes">
<ng-container *ngVar="getBackgroundImage(app, artworkType) as image">
<ng-container *ngVar="getAppImages(app, artworkType) as appimages">
<!-- ng-inview [parentSelector]="'.entries'" [margin]="400" (inView)="onAppInView($event.inView, $event.target, app)" -->
<div
ng-inview [parentSelector]="'.entries'" [margin]="400" [appId]="appId" [inViewDict]="inViewDict" [artworkType]="artworkType"
class="app"
[attr.data-inviewkey]="appId + currentViewType"
*ngIf="isAppVisible(app)"
[style.backgroundImage]="setBackgroundImage(appId, app, image, artworkType) | cssUrl | safeStyle"
[class.retrieving]="getImagePool(appimages.imagePool, artworkType).retrieving"
Expand Down Expand Up @@ -519,7 +519,7 @@ <h1>Add your games to Steam</h1>
</ng-container>
</ng-container>
</ng-container>
<ng-container *ngIf="getCurrentViewType()==='list'">
<ng-container *ngIf="currentViewType==='list'">
<div class="listItem"
*ngIf="isAppVisible(app)"
[class.current]="currentApp && currentApp.appId==appId"
Expand All @@ -542,12 +542,11 @@ <h1>Add your games to Steam</h1>
</div>
</div>
</ng-container>
<ng-container *ngIf="isArtworkType(getCurrentViewType())">
<ng-container *ngIf="isArtworkType(currentViewType)">
<ng-container *ngVar="getBackgroundImage(app) as image">
<ng-container *ngVar="getAppImages(app) as appimages">
<!-- ng-inview [parentSelector]="'.entries'" [margin]="400" (inView)="onAppInView($event.inView, $event.target, app)" -->
<div
ng-inview [parentSelector]="'.entries'" [margin]="400" [appId]="appId" [inViewDict]="inViewDict" [artworkType]="getActualArtworkType()"
[attr.data-inviewkey]="appId + currentViewType"
[style.backgroundImage]="setBackgroundImage(appId, app, image) | cssUrl | safeStyle"
class="app"
*ngIf="isAppVisible(app)"
Expand Down Expand Up @@ -718,7 +717,9 @@ <h1>Add your games to Steam</h1>
</ng-container>
</div>
</ng-container>
</div>
</div>
</ng-container>

<div
class="lowerMenu not-emudeck"
*ngIf="previewVariables.listHasGenerated && previewVariables.numberOfListItems !== 0"
Expand Down

0 comments on commit 63c622c

Please sign in to comment.