-
-
-
{{ 'ADF_VIEWER.LOADING' | translate }}
-
-
-
+
+
{{ 'ADF_VIEWER.LOADING' | translate }}
+
+
-
-
+
@@ -35,6 +32,7 @@
[urlFile]="urlFile"
[fileName]="internalFileName"
[cacheType]="cacheTypeForContent"
+ (pagesLoaded)="isContentReady = true"
(close)="onClose()"
(error)="onUnsupportedFile()" />
@@ -47,6 +45,7 @@
[blobFile]="blobFile"
(error)="onUnsupportedFile()"
(submit)="onSubmitFile($event)"
+ (imageLoaded)="isContentReady = true"
(isSaving)="isSaving.emit($event)"
/>
@@ -58,7 +57,8 @@
[mimeType]="mimeType"
[blobFile]="blobFile"
[fileName]="internalFileName"
- (error)="onUnsupportedFile()" />
+ (error)="onUnsupportedFile()"
+ (canPlay)="isContentReady = true"/>
diff --git a/lib/core/src/lib/viewer/components/viewer-render/viewer-render.component.scss b/lib/core/src/lib/viewer/components/viewer-render/viewer-render.component.scss
index c79a8b0669..11051c7541 100644
--- a/lib/core/src/lib/viewer/components/viewer-render/viewer-render.component.scss
+++ b/lib/core/src/lib/viewer/components/viewer-render/viewer-render.component.scss
@@ -7,6 +7,18 @@
background-color: var(--adf-theme-background-card-color);
}
+.adf-viewer-render-main-loader {
+ position: fixed;
+ top: 64px;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 1000;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
.adf-viewer-render {
&-main {
width: 0;
diff --git a/lib/core/src/lib/viewer/components/viewer-render/viewer-render.component.spec.ts b/lib/core/src/lib/viewer/components/viewer-render/viewer-render.component.spec.ts
index cb70a24941..8569eb08fe 100644
--- a/lib/core/src/lib/viewer/components/viewer-render/viewer-render.component.spec.ts
+++ b/lib/core/src/lib/viewer/components/viewer-render/viewer-render.component.spec.ts
@@ -18,13 +18,13 @@
import { AppExtensionService, ViewerExtensionRef } from '@alfresco/adf-extensions';
import { Location } from '@angular/common';
import { SpyLocation } from '@angular/common/testing';
-import { Component, TemplateRef, ViewChild } from '@angular/core';
+import { Component, DebugElement, TemplateRef, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { NoopTranslateModule, UnitTestingUtils } from '../../../testing';
import { RenderingQueueServices } from '../../services/rendering-queue.services';
import { ViewerRenderComponent } from './viewer-render.component';
-import { ViewerExtensionDirective } from '@alfresco/adf-core';
+import { ImgViewerComponent, MediaPlayerComponent, PdfViewerComponent, ViewerExtensionDirective } from '@alfresco/adf-core';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
@Component({
@@ -476,4 +476,75 @@ describe('ViewerComponent', () => {
});
});
});
+
+ describe('Spinner', () => {
+ const getMainLoader = (): DebugElement => testingUtils.getByCSS('.adf-viewer-render-main-loader');
+
+ it('should show spinner when isLoading is true', () => {
+ component.isLoading = true;
+ fixture.detectChanges();
+ expect(getMainLoader()).not.toBeNull();
+ });
+
+ it('should show spinner until content is ready when viewerType is media', () => {
+ component.isLoading = false;
+ component.urlFile = 'some-file.mp4';
+
+ component.ngOnChanges();
+ fixture.detectChanges();
+
+ expect(getMainLoader()).not.toBeNull();
+
+ const mediaViewer = testingUtils.getByDirective(MediaPlayerComponent);
+ mediaViewer.triggerEventHandler('canPlay', null);
+ fixture.detectChanges();
+
+ expect(getMainLoader()).toBeNull();
+ expect(component.viewerType).toBe('media');
+ });
+
+ it('should show spinner until content is ready when viewerType is pdf', () => {
+ component.isLoading = false;
+ component.urlFile = 'some-url.pdf';
+
+ component.ngOnChanges();
+ fixture.detectChanges();
+
+ expect(getMainLoader()).not.toBeNull();
+
+ const pdfViewer = testingUtils.getByDirective(PdfViewerComponent);
+ pdfViewer.triggerEventHandler('pagesLoaded', null);
+ fixture.detectChanges();
+
+ expect(getMainLoader()).toBeNull();
+ expect(component.viewerType).toBe('pdf');
+ });
+
+ it('should show spinner until content is ready when viewerType is image', () => {
+ component.isLoading = false;
+ component.urlFile = 'some-url.png';
+
+ component.ngOnChanges();
+ fixture.detectChanges();
+ expect(getMainLoader()).not.toBeNull();
+
+ const imgViewer = testingUtils.getByDirective(ImgViewerComponent);
+ imgViewer.triggerEventHandler('imageLoaded', null);
+ fixture.detectChanges();
+
+ expect(getMainLoader()).toBeNull();
+ expect(component.viewerType).toBe('image');
+ });
+
+ it('should not show spinner when isLoading = false and isContentReady = false for other viewer types', () => {
+ component.isLoading = false;
+ component.urlFile = 'some-url.txt';
+
+ component.ngOnChanges();
+ fixture.detectChanges();
+
+ expect(getMainLoader()).toBeNull();
+ expect(component.isContentReady).toBeFalse();
+ });
+ });
});
diff --git a/lib/core/src/lib/viewer/components/viewer-render/viewer-render.component.ts b/lib/core/src/lib/viewer/components/viewer-render/viewer-render.component.ts
index 316e7648b3..61b41fef69 100644
--- a/lib/core/src/lib/viewer/components/viewer-render/viewer-render.component.ts
+++ b/lib/core/src/lib/viewer/components/viewer-render/viewer-render.component.ts
@@ -142,6 +142,7 @@ export class ViewerRenderComponent implements OnChanges, OnInit {
extension: string;
internalFileName: string;
viewerType: string = 'unknown';
+ isContentReady = false;
/**
* Returns a list of the active Viewer content extensions.
@@ -184,6 +185,7 @@ export class ViewerRenderComponent implements OnChanges, OnInit {
}
ngOnChanges() {
+ this.isContentReady = false;
this.isLoading = !this.blobFile && !this.urlFile;
if (this.blobFile) {
diff --git a/lib/core/src/lib/viewer/components/viewer.component.spec.ts b/lib/core/src/lib/viewer/components/viewer.component.spec.ts
index f428fb170e..9ac7e4b251 100644
--- a/lib/core/src/lib/viewer/components/viewer.component.spec.ts
+++ b/lib/core/src/lib/viewer/components/viewer.component.spec.ts
@@ -121,6 +121,26 @@ describe('ViewerComponent', () => {
expect(thumbnailService.getMimeTypeIcon).toHaveBeenCalledWith('application/pdf');
expect(component.mimeTypeIconUrl).toBe('application/pdf');
});
+
+ it('should reset urlFile and blobFile on onNavigateBeforeClick', () => {
+ component.urlFile = 'some-url';
+ component.blobFile = new Blob(['content'], { type: 'text/plain' });
+
+ component.onNavigateBeforeClick(new MouseEvent('click'));
+
+ expect(component.urlFile).toBe('');
+ expect(component.blobFile).toBeNull();
+ });
+
+ it('should reset urlFile and blobFile on onNavigateNextClick', () => {
+ component.urlFile = 'some-url';
+ component.blobFile = new Blob(['content'], { type: 'text/plain' });
+
+ component.onNavigateNextClick(new MouseEvent('click'));
+
+ expect(component.urlFile).toBe('');
+ expect(component.blobFile).toBeNull();
+ });
});
describe('File Name Test', () => {
diff --git a/lib/core/src/lib/viewer/components/viewer.component.ts b/lib/core/src/lib/viewer/components/viewer.component.ts
index dce8eeb721..4a3764c616 100644
--- a/lib/core/src/lib/viewer/components/viewer.component.ts
+++ b/lib/core/src/lib/viewer/components/viewer.component.ts
@@ -387,10 +387,12 @@ export class ViewerComponent implements OnDestroy, OnInit, OnChanges {
}
onNavigateBeforeClick(event: MouseEvent | KeyboardEvent) {
+ this.resetLoadingSpinner();
this.navigateBefore.next(event);
}
onNavigateNextClick(event: MouseEvent | KeyboardEvent) {
+ this.resetLoadingSpinner();
this.navigateNext.next(event);
}
@@ -416,22 +418,17 @@ export class ViewerComponent implements OnDestroy, OnInit, OnChanges {
return;
}
- const key = event.keyCode;
-
- // Left arrow
- if (key === 37 && this.canNavigateBefore) {
+ if (event.key === 'ArrowLeft' && this.canNavigateBefore) {
event.preventDefault();
this.onNavigateBeforeClick(event);
}
- // Right arrow
- if (key === 39 && this.canNavigateNext) {
+ if (event.key === 'ArrowRight' && this.canNavigateNext) {
event.preventDefault();
this.onNavigateNextClick(event);
}
- // Ctrl+F
- if (key === 70 && event.ctrlKey) {
+ if (event.code === 'KeyF' && event.ctrlKey) {
event.preventDefault();
this.enterFullScreen();
}
@@ -527,4 +524,9 @@ export class ViewerComponent implements OnDestroy, OnInit, OnChanges {
});
}
}
+
+ private resetLoadingSpinner() {
+ this.urlFile = '';
+ this.blobFile = null;
+ }
}