@WidgetComponent

nm-gallery

File

src/app/shared/widgets/gallery/gallery.component.ts

Implements

OnInit OnDestroy

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector nm-gallery
styleUrls gallery.component.scss
templateUrl ./gallery.component.html

Index

Widget inputs
Widget outputs
Properties
Methods
Inputs
Outputs

Constructor

constructor(_widgetframeService: WidgetframeService, _progressbarService: ProgressbarService, gallery: Gallery, lightbox: Lightbox, ngZone: NgZone, cdr: ChangeDetectorRef)
Parameters :
Name Type Optional
_widgetframeService WidgetframeService no
_progressbarService ProgressbarService no
gallery Gallery no
lightbox Lightbox no
ngZone NgZone no
cdr ChangeDetectorRef no

Inputs

assets

Sets the assets.

height

Sets the height of the gallery (in pixels).

Type: string

Default value: "200px"

href

Sets the href for backend REST service returns JSON reponse containing assets.

showSpinner

Shows\Hides the spinner.

Default value: false

thumbnailsEnabled

Enable\Disable thumbnails.

Default value: true

width

Sets the width of the gallery (in pixels).

Type: string

Outputs

closed

Emits when the gallery popup is closed

$event type: Subject<any>
opened

Emits when the gallery popup is opened

$event type: Subject<any>

Methods

Static fallBackImage
fallBackImage()
Returns : string
indexChange
indexChange(index: any)
Parameters :
Name Type Optional
index any no
Returns : void
mapToTapEvent
mapToTapEvent(event: MouseEvent)
Parameters :
Name Type Optional
event MouseEvent no
Returns : { center: { x: any; y: any; }; }
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
openLightbox
openLightbox(index: number)
Parameters :
Name Type Optional
index number no
Returns : void
Private processImages
processImages(images: any[])
Parameters :
Name Type Optional
images any[] no
Returns : void
Static toGalleryItems
toGalleryItems(images: any[])
Parameters :
Name Type Optional
images any[] no
Returns : GalleryItem[]
Static toLightboxItem
toLightboxItem(item: )
Parameters :
Name Optional
item no
Returns : any
Static toLightboxItems
toLightboxItems(images: any[])
Parameters :
Name Type Optional
images any[] no
Returns : any

Properties

Private assetObservables
assetObservables:
Default value : new ReplaySubject<Observable<any[]>>(1)
currentIndex
currentIndex: number
Type : number
Private hrefObservables
hrefObservables:
Default value : new ReplaySubject<Observable<string>>(1)
id
id: string
Type : string
items
items: Subject<GalleryItem[]>
Type : Subject<GalleryItem[]>
Default value : new ReplaySubject(1)
itemTemplate
itemTemplate: TemplateRef<any>
Type : TemplateRef<any>
Decorators : ViewChild
lightboxId
lightboxId: string
Type : string
lightboxRef
lightboxRef: GalleryRef
Type : GalleryRef
loading
loading:
Default value : false
Private unsubscribe
unsubscribe:
Default value : NgUnsubscribe.create()

Accessors

assets
setassets(assets: )

Sets the assets.

Parameters :
Name Optional
assets no
Returns : void
href
sethref(href: )

Sets the href for backend REST service returns JSON reponse containing assets.

Parameters :
Name Optional
href no
Returns : void
import {
  debounceTime,
  distinctUntilChanged,
  filter,
  map,
  switchAll,
  switchMap,
  takeUntil,
  tap,
} from "rxjs/operators";
import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  Input,
  NgZone,
  OnDestroy,
  OnInit,
  Output,
  TemplateRef,
  ViewChild,
} from "@angular/core";
import { WidgetframeService } from "../widgetframe/widgetframe.service";
import { ProgressbarService } from "../../components/progressbar/progressbar.service";
import { Observable, of, ReplaySubject, Subject } from "rxjs";
import { NgUnsubscribe } from "../../ng-unsubscribe";
import {
  Gallery,
  GalleryItem,
  GalleryItemType,
  GalleryRef,
  IframeItem,
  ImageItem,
  VideoItem,
  YoutubeItem,
} from "ng-gallery";
import { Lightbox } from "ng-gallery/lightbox";
import { uuid } from "../configuration";

declare var contextPath: string;

@Component({
  selector: "nm-gallery",
  templateUrl: "./gallery.component.html",
  styleUrls: ["./gallery.component.scss"],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class GalleryComponent implements OnInit, OnDestroy {
  private unsubscribe = NgUnsubscribe.create();

  @ViewChild("itemTemplate", { static: true }) itemTemplate: TemplateRef<any>;
  /**
   * Sets the width of the gallery (in pixels).
   */
  @Input() width: string;
  /**
   * Sets the height of the gallery (in pixels).
   */
  @Input() height: string = "200px";
  /**
   * Enable\Disable thumbnails.
   */
  @Input() thumbnailsEnabled = true;
  /**
   * Shows\Hides the spinner.
   */
  @Input() showSpinner = false;

  private assetObservables = new ReplaySubject<Observable<any[]>>(1);

  /**
   * Sets the assets.
   */
  @Input() set assets(assets: Observable<any[]> | any[]) {
    if (assets == null) {
      return;
    }

    if (Array.isArray(assets)) {
      this.assetObservables.next(of(assets));
    } else {
      this.assetObservables.next(assets);
    }
  }

  private hrefObservables = new ReplaySubject<Observable<string>>(1);
  /**
  * Sets the href for backend REST service returns JSON reponse containing assets.
  */
  @Input() set href(href: Subject<string> | string) {
    if (href == null) {
      return;
    }

    if (typeof href === "string") {
      this.hrefObservables.next(of(href));
    } else {
      this.hrefObservables.next(href);
    }
  }
  /**
   * Emits when the gallery popup is opened
   */
  @Output() opened: Subject<any>;
  /**
   * Emits when the gallery popup is closed
   */
  @Output() closed: Subject<any>;

  id: string;
  lightboxId: string;
  lightboxRef: GalleryRef;
  currentIndex: number;

  items: Subject<GalleryItem[]> = new ReplaySubject(1);

  loading = false;

  constructor(
    private _widgetframeService: WidgetframeService,
    private _progressbarService: ProgressbarService,
    private gallery: Gallery,
    private lightbox: Lightbox,
    private ngZone: NgZone,
    private cdr: ChangeDetectorRef
  ) {
    this.opened = lightbox.opened;
    this.closed = lightbox.closed;

    this.id = uuid();
    this.lightboxId = `lb-${this.id};`;
  }

  ngOnInit() {
    this.lightboxRef = this.gallery.ref(this.lightboxId);
    this.lightboxRef.setConfig({
      itemTemplate: this.itemTemplate,
      thumb: this.thumbnailsEnabled,
    });

    // update the lightbox in lockstep, but make sure, to rewrite images to imageViewer
    // to allow zooming etc
    this.items
      .pipe(
        takeUntil(this.unsubscribe),
        map((items) =>
          items.map((item) => {
            return GalleryComponent.toLightboxItem(item);
          })
        )
      )
      .subscribe((items) => this.lightboxRef.load(items));

    this.assetObservables
      .asObservable()
      .pipe(switchAll(), takeUntil(this.unsubscribe))
      .subscribe((assets) => {
        this.processImages(assets);
      });

    this.hrefObservables
      .pipe(
        switchAll(),
        filter((data) => !!data),
        tap(() => {
          this.loading = true;
          this.cdr.markForCheck();
        }),
        switchMap((href) => this._widgetframeService.getData(href)),
        takeUntil(this.unsubscribe),
        debounceTime(100),
        distinctUntilChanged()
      )
      .subscribe(
        (data) => {
          this._progressbarService.addRequest();
          const images = [];

          if (data._embedded != null) {
            if (data._embedded["asset-relations"] != undefined) {
              for (var relation of data._embedded["asset-relations"]) {
                if (relation["_embedded"]) {
                  for (var assets of relation["_embedded"]["assets"]) {
                    images.push(assets);
                  }
                }
              }
            }
            if (data._embedded["images"] != undefined) {
              for (var image of data._embedded["images"]) {
                images.push(image);
              }
            }
            if (data._embedded["main-asset"] != undefined) {
              images.push(data._embedded["main-asset"]);
            }

            this.processImages(images);
          }

          this.loading = false;
          this._progressbarService.requestFinished();
          this.cdr.markForCheck();
        },
        (error) => {
          this.loading = false;
          this._progressbarService.requestFinished();
          this.cdr.markForCheck();
        }
      );
  }

  mapToTapEvent(event: MouseEvent) {
    return { center: { x: event.clientX, y: event.clientY } };
  }

  indexChange(index: any) {
    this.currentIndex = index.currIndex;
  }

  openLightbox(index: number) {
    this.lightbox.open(index, this.lightboxId);
  }

  ngOnDestroy() {
    this.unsubscribe.destroy();
  }

  private processImages(images: any[]) {
    const items = GalleryComponent.toGalleryItems(images);

    this.items.next(items);
  }

  public static toLightboxItems(images: any[]) {
    const mapped = GalleryComponent.toGalleryItems(images);
    return mapped.map((item) => GalleryComponent.toLightboxItem(item));
  }

  public static toLightboxItem(item) {
    if (item.type === GalleryItemType.Image) {
      return { type: "imageViewer", data: item.data };
    }

    return item;
  }

  public static toGalleryItems(images: any[]): GalleryItem[] {
    if (images == null) {
      return [];
    }

    const items: GalleryItem[] = [];

    for (const image of images) {
      if (image._links == undefined) {
        continue;
      }

      if (image.type === "image") {
        let small: string;
        let big: string;

        if (image._links.thumbnail != undefined) {
          small = image._links.thumbnail.href;
        } else {
          small = image._links.default.href;
        }

        if (image._links.full != undefined) {
          big = image._links.full.href;
        } else {
          big = image._links.default.href;
        }

        items.push(new ImageItem({ src: big, thumb: small }));
      } else if (image.type === "youtube") {
        // autoplay == true required, otherwise the gallery resets
        // the iframe's src to "null", which then loads the base-href (i.e., portal)
        items.push(new YoutubeItem({ src: image.youtubeId, autoplay: true }));
      } else if (image.type === "link") {
        const thumb = contextPath + "/assets/placeholder_281x202.jpg";
        items.push(new IframeItem({ src: image._links.default.href, thumb }));
      } else if (image.type === "document") {
        const thumb =
          image.extension === "pdf"
            ? contextPath + "/assets/placeholder_pdf_281x202.jpg"
            : contextPath + "/assets/placeholder_281x202.jpg";
        items.push(new IframeItem({ src: image._links.default.href, thumb }));
      } else if (image.type === "video") {
        items.push(
          new VideoItem({
            src: image._links.default.href,
            thumb: contextPath + "/assets/placeholder_movie_281x202.jpg",
          })
        );
      }
    }

    if (images.length == 0) {
      const fallback = GalleryComponent.fallBackImage();
      items.push(new ImageItem({ src: fallback, thumb: fallback }));
    }

    return items;
  }

  static fallBackImage() {
    return contextPath + "/assets/placeholder_281x202.jpg";
  }
}
<gallery
  #gallery
  [id]="id"
  [items]="items | async"
  [thumb]="thumbnailsEnabled"
  [thumbWidth]="90"
  [thumbHeight]="50"
  [ngStyle]="{ width: width, height: height }"
  [itemTemplate]="itemTemplate"
  [thumbTemplate]="thumbTemplate"
  (indexChange)="indexChange($event)"
  (itemClick)="openLightbox($event)"
  *ngIf="!loading; else spinner"
>
  <button
    mat-icon-button
    class="nm-gallery-fullScreen"
    (click)="openLightbox(currentIndex)"
  >
    <mat-icon svgIcon="fullscreen"></mat-icon>
  </button>
</gallery>

<ng-template
  #itemTemplate
  let-index="index"
  let-type="type"
  let-data="data"
  let-currIndex="currIndex"
>
  <ng-container *ngIf="type === 'imageViewer' && index === currIndex">
    <ngx-imageviewer
      [src]="data.src"
      [width]="800"
      [height]="600"
      #imageViewer
      (click)="imageViewer.onTap(mapToTapEvent($event))"
    >
    </ngx-imageviewer>
  </ng-container>
</ng-template>

<ng-template #thumbTemplate let-type="type">
  <mat-icon
    *ngIf="type === 'youtube'"
    class="nm-gallery-thumbnailIcon"
    svgIcon="youtube"
  ></mat-icon>
  <mat-icon
    *ngIf="type === 'video'"
    class="nm-gallery-thumbnailIcon"
    svgIcon="play"
  ></mat-icon>
</ng-template>

<ng-template #spinner>
  <div class="spinner-container" [ngStyle]="{ width: width, height: height }">
    <mat-spinner [diameter]="40"></mat-spinner>
  </div>
</ng-template>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""