Browse Source

Performance improvements.

pull/95/head
Sebastian Stehle 9 years ago
parent
commit
425cc0f286
  1. 1
      src/Squidex/Controllers/Api/Assets/Models/AssetReplacedDto.cs
  2. 55
      src/Squidex/app/framework/angular/image-source.directive.ts
  3. 17
      src/Squidex/app/framework/angular/panel-container.directive.ts
  4. 8
      src/Squidex/app/framework/angular/panel.component.ts
  5. 2
      src/Squidex/app/framework/angular/sorted.directive.ts
  6. 6
      src/Squidex/app/shared/components/pipes.ts
  7. 2
      src/Squidex/app/shared/services/apps-store.service.spec.ts
  8. 65
      src/Squidex/app/shared/services/auth.service.ts

1
src/Squidex/Controllers/Api/Assets/Models/AssetReplacedDto.cs

@ -8,7 +8,6 @@
using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Write.Assets.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS.Commands;
namespace Squidex.Controllers.Api.Assets.Models

55
src/Squidex/app/framework/angular/image-source.directive.ts

@ -13,8 +13,9 @@ import { MathHelper } from './../utils/math-helper';
selector: '[sqxImageSource]'
})
export class ImageSourceDirective implements OnChanges, OnInit, AfterViewInit {
private retries = 0;
private query: string | null = null;
private size: any;
private loadRetries = 0;
private loadQuery: string | null = null;
@Input('sqxImageSource')
public imageSource: string;
@ -32,8 +33,8 @@ export class ImageSourceDirective implements OnChanges, OnInit, AfterViewInit {
}
public ngOnChanges() {
this.query = null;
this.retries = 0;
this.loadQuery = null;
this.loadRetries = 0;
this.setImageSource();
}
@ -43,19 +44,20 @@ export class ImageSourceDirective implements OnChanges, OnInit, AfterViewInit {
}
public ngOnInit() {
this.renderer.setElementStyle(this.element.nativeElement, 'display', 'inline-block');
if (this.parent === null) {
this.parent = this.element.nativeElement.parentElement;
}
this.resize(this.parent);
this.renderer.listen(this.parent, 'resize', () => {
this.resize(this.parent);
});
}
@HostListener('load')
public onLoad() {
this.renderer.setElementStyle(this.element.nativeElement, 'visibility', 'visible');
}
@HostListener('error')
public onError() {
this.renderer.setElementStyle(this.element.nativeElement, 'visibility', 'hidden');
@ -63,36 +65,29 @@ export class ImageSourceDirective implements OnChanges, OnInit, AfterViewInit {
this.retryLoadingImage();
}
@HostListener('resize')
public onResize() {
this.setImageSource();
}
@HostListener('load')
public onLoad() {
this.renderer.setElementStyle(this.element.nativeElement, 'visibility', 'visible');
}
private resize(parent: any) {
const size = parent.getBoundingClientRect();
this.size = this.parent.getBoundingClientRect();
this.renderer.setElementStyle(this.element.nativeElement, 'width', size.width + 'px');
this.renderer.setElementStyle(this.element.nativeElement, 'height', size.height + 'px');
this.renderer.setElementStyle(this.element.nativeElement, 'display', 'inline-block');
this.renderer.setElementStyle(this.element.nativeElement, 'width', this.size.width + 'px');
this.renderer.setElementStyle(this.element.nativeElement, 'height', this.size.height + 'px');
this.setImageSource();
}
private setImageSource() {
const size = this.element.nativeElement.getBoundingClientRect();
if (!this.size) {
return;
}
const w = Math.round(size.width);
const h = Math.round(size.height);
const w = Math.round(this.size.width);
const h = Math.round(this.size.height);
if (w > 0 && h > 0) {
let source = `${this.imageSource}&width=${w}&height=${h}&mode=Crop`;
if (this.query !== null) {
source += `&q=${this.query}`;
if (this.loadQuery !== null) {
source += `&q=${this.loadQuery}`;
}
this.renderer.setElementAttribute(this.element.nativeElement, 'src', source);
@ -100,14 +95,14 @@ export class ImageSourceDirective implements OnChanges, OnInit, AfterViewInit {
}
private retryLoadingImage() {
this.retries++;
this.loadRetries++;
if (this.retries <= 10) {
if (this.loadRetries <= 10) {
setTimeout(() => {
this.query = MathHelper.guid();
this.loadQuery = MathHelper.guid();
this.setImageSource();
}, this.retries * 1000);
}, this.loadRetries * 1000);
}
}
}

17
src/Squidex/app/framework/angular/panel-container.directive.ts

@ -14,6 +14,7 @@ import { PanelComponent } from './panel.component';
})
export class PanelContainerDirective implements AfterViewInit, OnDestroy {
private readonly panels: PanelComponent[] = [];
private containerWidth = 0;
private isInit = false;
constructor(
@ -28,7 +29,7 @@ export class PanelContainerDirective implements AfterViewInit, OnDestroy {
}
public ngAfterViewInit() {
this.invalidate(true);
this.invalidate({ force: true, resize: true });
}
public ngOnDestroy() {
@ -47,14 +48,16 @@ export class PanelContainerDirective implements AfterViewInit, OnDestroy {
this.invalidate();
}
public invalidate(force = false) {
this.isInit = this.isInit || force;
public invalidate(params?: { force: boolean, resize: boolean }) {
this.isInit = this.isInit || (params && params.force);
if (!this.isInit) {
return;
}
const containerWidth = this.element.nativeElement.getBoundingClientRect().width;
if (params && params.resize) {
this.containerWidth = this.element.nativeElement.getBoundingClientRect().width;
}
let currentPosition = 0;
let currentLayer = this.panels.length * 10;
@ -64,10 +67,10 @@ export class PanelContainerDirective implements AfterViewInit, OnDestroy {
for (let panel of this.panels) {
const panelRoot = panel.panel.nativeElement;
let width = panelRoot.getBoundingClientRect().width;
let width = panel.clientWidth;
if (panel.expand && panel === last) {
width = containerWidth - currentPosition;
width = this.containerWidth - currentPosition;
panel.panelWidth = width + 'px';
}
@ -82,7 +85,7 @@ export class PanelContainerDirective implements AfterViewInit, OnDestroy {
currentLayer -= 10;
}
const diff = currentPosition - containerWidth;
const diff = currentPosition - this.containerWidth;
if (diff > 0) {
this.element.nativeElement.scrollLeft = diff;

8
src/Squidex/app/framework/angular/panel.component.ts

@ -24,6 +24,8 @@ import { PanelContainerDirective } from './panel-container.directive';
]
})
export class PanelComponent implements AfterViewInit, OnDestroy, OnInit {
private clientWidthValue = 0;
@Input()
public theme = 'light';
@ -36,6 +38,10 @@ export class PanelComponent implements AfterViewInit, OnDestroy, OnInit {
@ViewChild('panel')
public panel: ElementRef;
public get clientWidth() {
return this.clientWidthValue;
}
constructor(
private readonly container: PanelContainerDirective
) {
@ -50,6 +56,8 @@ export class PanelComponent implements AfterViewInit, OnDestroy, OnInit {
}
public ngAfterViewInit() {
this.clientWidthValue = this.panel.nativeElement.getBoundingClientRect().width;
this.container.invalidate();
}
}

2
src/Squidex/app/framework/angular/sorted.directive.ts

@ -30,7 +30,7 @@ export class SortedDirective {
) {
const oldDragStartCallback = sortableComponent._onDragStartCallback.bind(sortableComponent);
sortableComponent._onDragStartCallback = (event: Event) => {
sortableComponent._onDragStartCallback = () => {
oldDragStartCallback();
this.oldArray = [...sortableContainer.sortableData];

6
src/Squidex/app/shared/components/pipes.ts

@ -196,7 +196,7 @@ export class UserPictureRefPipe extends UserAsyncPipe implements PipeTransform {
@Pipe({
name: 'sqxAssetUrl',
pure: false
pure: true
})
export class AssetUrlPipe implements PipeTransform {
constructor(
@ -211,7 +211,7 @@ export class AssetUrlPipe implements PipeTransform {
@Pipe({
name: 'sqxAssetPreviewUrl',
pure: false
pure: true
})
export class AssetPreviewUrlPipe implements PipeTransform {
constructor(
@ -226,7 +226,7 @@ export class AssetPreviewUrlPipe implements PipeTransform {
@Pipe({
name: 'sqxFileIcon',
pure: false
pure: true
})
export class FileIconPipe implements PipeTransform {
public transform(asset: { mimeType: string, fileType: string }): string {

2
src/Squidex/app/shared/services/apps-store.service.spec.ts

@ -70,7 +70,7 @@ describe('AppsStoreService', () => {
result1 = x;
}).unsubscribe();
store.createApp(new CreateAppDto('new-name'), now).subscribe(() => { /* Do Nothing */ });
store.createApp(new CreateAppDto('new-name'), now).subscribe();
store.apps.subscribe(x => {
result2 = x;

65
src/Squidex/app/shared/services/auth.service.ts

@ -6,7 +6,7 @@
*/
import { Injectable } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs';
import { Observable, Observer, ReplaySubject, TimeoutError } from 'rxjs';
import {
Log,
@ -101,28 +101,67 @@ export class AuthService {
this.checkState(this.userManager.getUser());
}
public logoutRedirect(): Observable<any> {
return Observable.fromPromise(this.userManager.signoutRedirect());
public logoutRedirect() {
this.userManager.signoutRedirect();
}
public logoutRedirectComplete(): Observable<any> {
return Observable.fromPromise(this.userManager.signoutRedirectCallback());
public loginRedirect() {
this.userManager.signinRedirect();
}
public loginPopup(): Observable<Profile> {
return Observable.fromPromise(this.userManager.signinPopup()).map(u => this.createProfile(u));
public logoutRedirectComplete(): Observable<any> {
return Observable.create((observer: Observer<any>) => {
this.userManager.signoutRedirectCallback()
.then(x => {
observer.next(x);
observer.complete();
}, err => {
observer.error(err);
observer.complete();
});
});
}
public loginSilent(): Observable<any> {
return Observable.fromPromise(this.userManager.signinSilent()).map(u => this.createProfile(u));
public loginPopup(): Observable<Profile> {
return Observable.create((observer: Observer<Profile>) => {
this.userManager.signinPopup()
.then(x => {
observer.next(this.createProfile(x));
observer.complete();
}, err => {
observer.error(err);
observer.complete();
});
});
}
public loginRedirect(): Observable<any> {
return Observable.fromPromise(this.userManager.signinRedirect());
public loginRedirectComplete(): Observable<Profile> {
return Observable.create((observer: Observer<Profile>) => {
this.userManager.signinRedirectCallback()
.then(x => {
observer.next(this.createProfile(x));
observer.complete();
}, err => {
observer.error(err);
observer.complete();
});
});
}
public loginRedirectComplete(): Observable<Profile> {
return Observable.fromPromise(this.userManager.signinRedirectCallback()).map(u => this.createProfile(u));
public loginSilent(): Observable<Profile> {
const observable: Observable<Profile> =
Observable.create((observer: Observer<Profile>) => {
this.userManager.signinSilent()
.then(x => {
observer.next(this.createProfile(x));
observer.complete();
}, err => {
observer.error(err);
observer.complete();
});
});
return observable.timeout(1000).retryWhen(errors => errors.filter(e => e instanceof TimeoutError));
}
private createProfile(user: User) {

Loading…
Cancel
Save