mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ACA-4676][ACA-4678] Added Non Responsive Preview Dialog to viewer component (#8428)
* [ACA-4676] Added NonResponsivePreview dialog to download file incase file preview takes longer than a set period of time. * [ACA-4676] Updated button positioning for non responsive preview dialog * [ACA-4676] Added documentation for NonResponsivePreviewDialog functionality for viewer.component.ts * [ACA-4676] Added unit tests for NonResponsivePreviewDialog * [ACA-4676] Updated template of NonResponsivePreviewDialog to use components and directives from mat-dialog. Removed non-responsive-dialog.component.scss. Removed unused methods from non-responsive-dialog.component.ts * [ACA-4676] Corrected typo in NonResponsivePreviewDialog unit tests * [ACA-4676] Added test cases for NonResponsivePreviewDialog in viewer.component.ts. NOT WORKING * [ACA-4676] Fixed test cases for non-responsive preview dialog. Moved NonResponsivePreview dialog tests to separate describe block. Updated component code to make properties and methods visible to testing environment * [ACA-4676] Migrated viewer component test env setup from setupTestBed() to TestBed.configureTestingModule(). Moved NonResponsivePreviewDialog unit tests to inside parent Viewer component describe block * [ACA-4676] Removed unused async tag. Added license info to non-responsive-dialog.component.ts and non-responsive-preview-actions.enum.ts * [ACA-4676] Updated code to use "viewer" appConfig object instead of "preview-config". Added non-responsive-preview-actions.enum.ts to public-api.ts * [ACA-4676] Resolved potential lint issues * [ACA-4676] Updated non responsive preview to look for viewer config object inside app.config instead of preview-config * [ACA-4676] Removed duplicate import for @adf/core. Added NonResponsiveDialogComponent to adf/core exports * [ACA-4676] Renamed properties/config/documentation from nonResponsivePreview to downloadPrompt. Renamed NonResponsivePreviewActionsEnum to DownloadPromptActions. * [ACA-4676] Resolved linting and unit test failures * [ACA-4676] Changed dataType for timers to number. Updated code to use window.setTimeout(), instead of just setTimeout(). Added missing whitespace. Updated method names in demo shell to use 'downloadPrompt' naming scheme. * [ACA-4676] Fixed incorrect import statement in viewer.module.ts for download-prompt-dialog * [ACA-4676] Testing disabled by default behaviour of downloadPrompt feature * [ACA-4676] Changed default value for enableDownloadPrompt and enableDownloadPromptReminders to false in app.config.json * [ACA-4676] Removed un-needed AppConfig configurations from unit tests
This commit is contained in:
@@ -1478,6 +1478,10 @@
|
||||
]
|
||||
},
|
||||
"viewer": {
|
||||
"enableDownloadPrompt": false,
|
||||
"enableDownloadPromptReminder": false,
|
||||
"downloadPromptDelay": 50,
|
||||
"downloadPromptReminderDelay": 30,
|
||||
"enableFileAutoDownload": true,
|
||||
"fileAutoDownloadSizeThresholdInMB": 15
|
||||
}
|
||||
|
@@ -653,6 +653,30 @@
|
||||
</mat-form-field>
|
||||
</form>
|
||||
|
||||
<section>
|
||||
<mat-slide-toggle
|
||||
color="primary" [(ngModel)]="enableDownloadPrompt" id="enableDownloadPrompt" (change)="onEnableDownloadPrompt()">
|
||||
Enable Download Prompt
|
||||
</mat-slide-toggle>
|
||||
</section>
|
||||
<section *ngIf="enableDownloadPrompt">
|
||||
<mat-form-field>
|
||||
<input matInput type="number" [(ngModel)]="downloadPromptDelay" (change)="onDownloadPromptDelayChange()">
|
||||
</mat-form-field>
|
||||
</section>
|
||||
|
||||
<section *ngIf="enableDownloadPrompt">
|
||||
<mat-slide-toggle
|
||||
color="primary" [(ngModel)]="enableDownloadPromptReminder" id="enableDownloadPromptReminders" (change)="onEnableDownloadPromptReminderChange()">
|
||||
Enable Download Prompt Reminders
|
||||
</mat-slide-toggle>
|
||||
</section>
|
||||
<section *ngIf="enableDownloadPrompt && enableDownloadPromptReminder">
|
||||
<mat-form-field>
|
||||
<input matInput type="number" [(ngModel)]="downloadPromptReminderDelay" (change)="onDownloadPromptReminderChange()">
|
||||
</mat-form-field>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<mat-slide-toggle
|
||||
color="primary" [(ngModel)]="enableFileAutoDownload" id="enableFileAutoDownload" (change)="onEnableFileAutoDownloadChange()">
|
||||
|
@@ -251,6 +251,10 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
selectedNodes = [];
|
||||
|
||||
enableDownloadPrompt: boolean = this.appConfig.get('viewer.enableDownloadPrompt', false);
|
||||
enableDownloadPromptReminder: boolean = this.appConfig.get('viewer.enableDownloadPromptReminders', false);
|
||||
downloadPromptDelay = this.appConfig.get('viewer.downloadPromptDelay', 50);
|
||||
downloadPromptReminderDelay = this.appConfig.get('viewer.downloadPromptReminderDelay', 30);
|
||||
enableFileAutoDownload: boolean = this.appConfig.get('viewer.enableFileAutoDownload', true);
|
||||
fileAutoDownloadSizeThresholdInMB: number = this.appConfig.get('viewer.fileAutoDownloadSizeThresholdInMB', 15);
|
||||
|
||||
@@ -780,6 +784,26 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.selectedNodes = [];
|
||||
}
|
||||
|
||||
onEnableDownloadPrompt() {
|
||||
const previewConfig = this.appConfig?.config['viewer'];
|
||||
previewConfig['enableDownloadPrompt'] = this.enableDownloadPrompt;
|
||||
}
|
||||
|
||||
onDownloadPromptDelayChange() {
|
||||
const previewConfig = this.appConfig?.config['viewer'];
|
||||
previewConfig['downloadPromptDelay'] = this.downloadPromptDelay;
|
||||
}
|
||||
|
||||
onEnableDownloadPromptReminderChange() {
|
||||
const previewConfig = this.appConfig?.config['viewer'];
|
||||
previewConfig['enableDownloadPromptReminder'] = this.enableDownloadPromptReminder;
|
||||
}
|
||||
|
||||
onDownloadPromptReminderChange() {
|
||||
const previewConfig = this.appConfig?.config['viewer'];
|
||||
previewConfig['downloadPromptReminderDelay'] = this.downloadPromptReminderDelay;
|
||||
}
|
||||
|
||||
onEnableFileAutoDownloadChange() {
|
||||
const previewConfig = this.appConfig?.config['viewer'];
|
||||
previewConfig['enableFileAutoDownload'] = this.enableFileAutoDownload;
|
||||
|
@@ -380,6 +380,31 @@ In the same way you can set a default zoom scaling value for the image viewer by
|
||||
|
||||
By default the viewer's zoom scaling is set to 100%.
|
||||
|
||||
## Handling non responsive file preview
|
||||
|
||||
It is possible that trying to load a large file, especially over a slow network, can cause the viewer component to get stuck in the loading state. To handle such cases,
|
||||
the viewer can be configured to display a prompt to ask the user to either download the file locally and then close the viewer, or wait for the viewer to load the file.
|
||||
In case the user decides to wait, the viewer can further be configured to display subsequent reminder prompts asking the same options.
|
||||
|
||||
In order to configure this feature, add the following code in `app.config.json`.
|
||||
|
||||
```
|
||||
"viewer": {
|
||||
"enableDownloadPrompt": true,
|
||||
"enableDownloadPromptReminder": true,
|
||||
"downloadPromptDelay": 50,
|
||||
"downloadPromptReminderDelay": 30
|
||||
}
|
||||
```
|
||||
|
||||
Here `enableDownloadPrompt: true` enables the dialog to be visible after a set period of time. This time can be configured by updating the value in the
|
||||
`downloadPromptDelay` property.
|
||||
|
||||
The second boolean flag `enableDownloadPromptReminder: true` can be used to configure whether the reminder prompts should be displayed or not.
|
||||
`downloadPromptReminderDelay` property can be used to configure the time to wait between reminder prompts.
|
||||
|
||||
Note: All times in this configuration must be provided in seconds
|
||||
|
||||
## See also
|
||||
|
||||
- [Document List component](../../content-services/components/document-list.component.md)
|
||||
|
@@ -391,7 +391,8 @@
|
||||
"FULLSCREEN": "Activate full-screen mode",
|
||||
"CLOSE": "Close",
|
||||
"NEXT_FILE": "Next File",
|
||||
"PREV_FILE": "Previous File"
|
||||
"PREV_FILE": "Previous File",
|
||||
"WAIT": "Wait"
|
||||
},
|
||||
"ARIA": {
|
||||
"PREVIOUS_PAGE": "Previous page",
|
||||
@@ -429,7 +430,11 @@
|
||||
"PLACEHOLDER": "Password",
|
||||
"ERROR": "Password is wrong"
|
||||
},
|
||||
"SUBTITLES": "Subtitles"
|
||||
"SUBTITLES": "Subtitles",
|
||||
"NON_RESPONSIVE_DIALOG": {
|
||||
"HEADER": "Preview loading delayed",
|
||||
"LABEL": "You can continue to wait, or download the document."
|
||||
}
|
||||
},
|
||||
"ERROR_CONTENT": {
|
||||
"UNKNOWN": {
|
||||
|
@@ -0,0 +1,23 @@
|
||||
<div mat-dialog-title>
|
||||
<h3>{{ 'ADF_VIEWER.NON_RESPONSIVE_DIALOG.HEADER' | translate }}</h3>
|
||||
</div>
|
||||
<mat-dialog-content>
|
||||
{{ 'ADF_VIEWER.NON_RESPONSIVE_DIALOG.LABEL' | translate }}
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions align="end">
|
||||
<button
|
||||
mat-button
|
||||
id="downloadButton"
|
||||
[attr.aria-label]="'ADF_VIEWER.ACTIONS.DOWNLOAD' | translate"
|
||||
[mat-dialog-close]="DownloadPromptActions.DOWNLOAD">
|
||||
{{ 'ADF_VIEWER.ACTIONS.DOWNLOAD' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
id="waitButton"
|
||||
color="primary"
|
||||
[attr.aria-label]="'ADF_VIEWER.ACTIONS.WAIT' | translate"
|
||||
[mat-dialog-close]="DownloadPromptActions.WAIT">
|
||||
{{ 'ADF_VIEWER.ACTIONS.WAIT' | translate }}
|
||||
</button>
|
||||
</mat-dialog-actions>
|
@@ -0,0 +1,73 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CoreTestingModule, DownloadPromptDialogComponent, DownloadPromptActions } from '@alfresco/adf-core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
const mockDialog = {
|
||||
close: jasmine.createSpy('close')
|
||||
};
|
||||
|
||||
describe('DownloadPromptDialogComponent', () => {
|
||||
let matDialogRef: MatDialogRef<DownloadPromptDialogComponent>;
|
||||
let fixture: ComponentFixture<DownloadPromptDialogComponent>;
|
||||
|
||||
const getButton = (buttonId: string) => {
|
||||
return fixture.debugElement.query(By.css(buttonId)).nativeElement;
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [DownloadPromptDialogComponent],
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
CoreTestingModule
|
||||
],
|
||||
providers: [
|
||||
{ provide: MatDialogRef, useValue: mockDialog }
|
||||
]
|
||||
});
|
||||
matDialogRef = TestBed.inject(MatDialogRef);
|
||||
|
||||
fixture = TestBed.createComponent(DownloadPromptDialogComponent);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should emit DownloadPromptActions.WAIT and close dialog when clicking on the wait button', async () => {
|
||||
const waitButton = getButton('#waitButton');
|
||||
waitButton.dispatchEvent(new Event('click'));
|
||||
|
||||
await fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(matDialogRef.close).toHaveBeenCalledWith(DownloadPromptActions.WAIT);
|
||||
});
|
||||
|
||||
it('should emit DownloadPromptActions.DOWNLOAD and close dialog when clicking on the download button', async () => {
|
||||
const waitButton = getButton('#downloadButton');
|
||||
waitButton.dispatchEvent(new Event('click'));
|
||||
|
||||
await fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(matDialogRef.close).toHaveBeenCalledWith(DownloadPromptActions.DOWNLOAD);
|
||||
});
|
||||
});
|
@@ -0,0 +1,27 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { DownloadPromptActions } from '../../models/download-prompt.actions';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-download-prompt-dialog',
|
||||
templateUrl: './download-prompt-dialog.component.html'
|
||||
})
|
||||
export class DownloadPromptDialogComponent {
|
||||
DownloadPromptActions = DownloadPromptActions;
|
||||
}
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, discardPeriodicTasks, fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
|
||||
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
@@ -24,12 +24,15 @@ import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import {
|
||||
CoreTestingModule,
|
||||
setupTestBed,
|
||||
EventMock,
|
||||
ViewerComponent,
|
||||
ViewUtilService
|
||||
ViewUtilService,
|
||||
AppConfigService,
|
||||
DownloadPromptDialogComponent,
|
||||
DownloadPromptActions
|
||||
} from '@alfresco/adf-core';
|
||||
import { Component } from '@angular/core';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer-container-toolbar',
|
||||
@@ -135,35 +138,48 @@ describe('ViewerComponent', () => {
|
||||
let element: HTMLElement;
|
||||
let dialog: MatDialog;
|
||||
let viewUtilService: ViewUtilService;
|
||||
|
||||
setupTestBed({
|
||||
imports: [
|
||||
NoopAnimationsModule,
|
||||
TranslateModule.forRoot(),
|
||||
CoreTestingModule,
|
||||
MatButtonModule,
|
||||
MatIconModule
|
||||
],
|
||||
declarations: [
|
||||
ViewerWithCustomToolbarComponent,
|
||||
ViewerWithCustomSidebarComponent,
|
||||
ViewerWithCustomOpenWithComponent,
|
||||
ViewerWithCustomMoreActionsComponent,
|
||||
ViewerWithCustomToolbarActionsComponent
|
||||
],
|
||||
providers: [
|
||||
MatDialog
|
||||
]
|
||||
});
|
||||
let appConfigService: AppConfigService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
NoopAnimationsModule,
|
||||
TranslateModule.forRoot(),
|
||||
CoreTestingModule,
|
||||
MatButtonModule,
|
||||
MatIconModule
|
||||
],
|
||||
declarations: [
|
||||
ViewerWithCustomToolbarComponent,
|
||||
ViewerWithCustomSidebarComponent,
|
||||
ViewerWithCustomOpenWithComponent,
|
||||
ViewerWithCustomMoreActionsComponent,
|
||||
ViewerWithCustomToolbarActionsComponent
|
||||
],
|
||||
providers: [
|
||||
MatDialog,
|
||||
{ provide: DownloadPromptDialogComponent, useClass: DummyDialogComponent}
|
||||
]
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(ViewerComponent);
|
||||
element = fixture.nativeElement;
|
||||
component = fixture.componentInstance;
|
||||
|
||||
dialog = TestBed.inject(MatDialog);
|
||||
viewUtilService = TestBed.inject(ViewUtilService);
|
||||
appConfigService = TestBed.inject(AppConfigService);
|
||||
component.fileName = 'test-file.pdf';
|
||||
|
||||
appConfigService.config = {
|
||||
...appConfigService.config,
|
||||
'viewer': {
|
||||
'enableDownloadPrompt': false,
|
||||
'enableDownloadPromptReminder': false,
|
||||
'downloadPromptDelay': 3,
|
||||
'downloadPromptReminderDelay': 2
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -604,4 +620,60 @@ describe('ViewerComponent', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Download Prompt Dialog',() => {
|
||||
|
||||
let dialogOpenSpy: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
appConfigService.config = {
|
||||
...appConfigService.config,
|
||||
'viewer': {
|
||||
'enableDownloadPrompt': true,
|
||||
'enableDownloadPromptReminder': true,
|
||||
'downloadPromptDelay': 3,
|
||||
'downloadPromptReminderDelay': 2
|
||||
}
|
||||
};
|
||||
dialogOpenSpy = spyOn(dialog, 'open').and.returnValue({afterClosed: () => of(null)} as any);
|
||||
component.urlFile = undefined;
|
||||
component.clearDownloadPromptTimeouts();
|
||||
});
|
||||
|
||||
it('should configure initial timeout to display non responsive dialog when initialising component', (() => {
|
||||
fixture.detectChanges();
|
||||
expect(component.downloadPromptTimer).toBeDefined();
|
||||
}));
|
||||
|
||||
it('should configure reminder timeout to display non responsive dialog after initial dialog', fakeAsync( () => {
|
||||
dialogOpenSpy.and.returnValue({ afterClosed: () => of(DownloadPromptActions.WAIT) } as any);
|
||||
fixture.detectChanges();
|
||||
tick(3000);
|
||||
expect(component.downloadPromptReminderTimer).toBeDefined();
|
||||
dialogOpenSpy.and.returnValue({ afterClosed: () => of(null) } as any);
|
||||
flush();
|
||||
discardPeriodicTasks();
|
||||
}));
|
||||
|
||||
it('should show initial non responsive dialog after initial timeout', fakeAsync( () => {
|
||||
fixture.detectChanges();
|
||||
tick(3000);
|
||||
fixture.detectChanges();
|
||||
expect(dialogOpenSpy).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should show reminder non responsive dialog after initial dialog', fakeAsync( () => {
|
||||
dialogOpenSpy.and.returnValue({ afterClosed: () => of(DownloadPromptActions.WAIT) } as any);
|
||||
fixture.detectChanges();
|
||||
tick(3000);
|
||||
expect(dialogOpenSpy).toHaveBeenCalled();
|
||||
|
||||
dialogOpenSpy.and.returnValue({ afterClosed: () => of(null) } as any);
|
||||
tick(2000);
|
||||
expect(dialogOpenSpy).toHaveBeenCalledTimes(2);
|
||||
|
||||
flush();
|
||||
discardPeriodicTasks();
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
@@ -30,15 +30,25 @@ import {
|
||||
TemplateRef,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { fromEvent, Subject } from 'rxjs';
|
||||
import { fromEvent, Subject } from 'rxjs';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ViewerToolbarComponent } from './viewer-toolbar.component';
|
||||
import { ViewerOpenWithComponent } from './viewer-open-with.component';
|
||||
import { ViewerMoreActionsComponent } from './viewer-more-actions.component';
|
||||
import { ViewerSidebarComponent } from './viewer-sidebar.component';
|
||||
import { filter, skipWhile, takeUntil } from 'rxjs/operators';
|
||||
import { filter, first, skipWhile, takeUntil } from 'rxjs/operators';
|
||||
import { Track } from '../models/viewer.model';
|
||||
import { ViewUtilService } from '../services/view-util.service';
|
||||
import { DownloadPromptDialogComponent } from './download-prompt-dialog/download-prompt-dialog.component';
|
||||
import { AppConfigService } from '../../app-config';
|
||||
import { DownloadPromptActions } from '../models/download-prompt.actions';
|
||||
|
||||
const DEFAULT_NON_PREVIEW_CONFIG = {
|
||||
enableDownloadPrompt: false,
|
||||
enableDownloadPromptReminder: false,
|
||||
downloadPromptDelay: 50,
|
||||
downloadPromptReminderDelay: 30
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer',
|
||||
@@ -160,6 +170,26 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
||||
@Input()
|
||||
sidebarLeftTemplateContext: T = null;
|
||||
|
||||
/**
|
||||
* Enable dialog box to allow user to download the previewed file, in case the preview is not responding for a set period of time.
|
||||
* */
|
||||
enableDownloadPrompt: boolean = false;
|
||||
|
||||
/**
|
||||
* Enable reminder dialogs to prompt user to download the file, in case the preview is not responding for a set period of time.
|
||||
* */
|
||||
enableDownloadPromptReminder: boolean = false;
|
||||
|
||||
/**
|
||||
* Initial time in seconds to wait before giving the first prompt to user to download the file
|
||||
* */
|
||||
downloadPromptDelay: number = 50;
|
||||
|
||||
/**
|
||||
* Time in seconds to wait before giving the second and consequent reminders to the user to download the file.
|
||||
* */
|
||||
downloadPromptReminderDelay: number = 15;
|
||||
|
||||
/** Emitted when user clicks 'Navigate Before' ("<") button. */
|
||||
@Output()
|
||||
navigateBefore = new EventEmitter<MouseEvent | KeyboardEvent>();
|
||||
@@ -180,10 +210,14 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
||||
|
||||
private closeViewer = true;
|
||||
private keyDown$ = fromEvent<KeyboardEvent>(document, 'keydown');
|
||||
private isDialogVisible: boolean = false;
|
||||
public downloadPromptTimer: number;
|
||||
public downloadPromptReminderTimer: number;
|
||||
|
||||
constructor(private el: ElementRef,
|
||||
public dialog: MatDialog,
|
||||
private viewUtilsService: ViewUtilService
|
||||
private viewUtilsService: ViewUtilService,
|
||||
private appConfigService: AppConfigService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -202,6 +236,7 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
||||
|
||||
ngOnInit(): void {
|
||||
this.closeOverlayManager();
|
||||
this.configureAndInitDownloadPrompt();
|
||||
}
|
||||
|
||||
private closeOverlayManager() {
|
||||
@@ -304,8 +339,64 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.clearDownloadPromptTimeouts();
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
private configureAndInitDownloadPrompt() {
|
||||
this.configureDownloadPromptProperties();
|
||||
if (this.enableDownloadPrompt) {
|
||||
this.initDownloadPrompt();
|
||||
}
|
||||
}
|
||||
|
||||
private configureDownloadPromptProperties() {
|
||||
const nonResponsivePreviewConfig = this.appConfigService.get('viewer', DEFAULT_NON_PREVIEW_CONFIG);
|
||||
|
||||
this.enableDownloadPrompt = nonResponsivePreviewConfig.enableDownloadPrompt;
|
||||
this.enableDownloadPromptReminder = nonResponsivePreviewConfig.enableDownloadPromptReminder;
|
||||
this.downloadPromptDelay = nonResponsivePreviewConfig.downloadPromptDelay;
|
||||
this.downloadPromptReminderDelay = nonResponsivePreviewConfig.downloadPromptReminderDelay;
|
||||
}
|
||||
|
||||
private initDownloadPrompt() {
|
||||
this.downloadPromptTimer = window.setTimeout(() => {
|
||||
this.showOrClearDownloadPrompt();
|
||||
}, this.downloadPromptDelay * 1000);
|
||||
}
|
||||
|
||||
private showOrClearDownloadPrompt() {
|
||||
if (!this.urlFile) {
|
||||
this.showDownloadPrompt();
|
||||
} else {
|
||||
this.clearDownloadPromptTimeouts();
|
||||
}
|
||||
}
|
||||
|
||||
public clearDownloadPromptTimeouts() {
|
||||
if (this.downloadPromptTimer) {
|
||||
clearTimeout(this.downloadPromptTimer);
|
||||
}
|
||||
if (this.downloadPromptReminderTimer) {
|
||||
clearTimeout(this.downloadPromptReminderTimer);
|
||||
}
|
||||
}
|
||||
|
||||
private showDownloadPrompt() {
|
||||
if (!this.isDialogVisible) {
|
||||
this.isDialogVisible = true;
|
||||
this.dialog.open(DownloadPromptDialogComponent, { disableClose: true }).afterClosed().pipe(first()).subscribe((result: DownloadPromptActions) => {
|
||||
this.isDialogVisible = false;
|
||||
if (result === DownloadPromptActions.WAIT) {
|
||||
if (this.enableDownloadPromptReminder) {
|
||||
this.clearDownloadPromptTimeouts();
|
||||
this.downloadPromptReminderTimer = window.setTimeout(() => {
|
||||
this.showOrClearDownloadPrompt();
|
||||
}, this.downloadPromptReminderDelay * 1000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
22
lib/core/src/lib/viewer/models/download-prompt.actions.ts
Normal file
22
lib/core/src/lib/viewer/models/download-prompt.actions.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* Enum listing the allowed actions that can be emitted from the NonResponsivePreview dialog component */
|
||||
export enum DownloadPromptActions {
|
||||
'WAIT',
|
||||
'DOWNLOAD'
|
||||
}
|
@@ -33,9 +33,11 @@ export * from './components/viewer-toolbar-actions.component';
|
||||
export * from './components/viewer-toolbar-custom-actions.component';
|
||||
export * from './components/viewer-render.component';
|
||||
export * from './components/viewer.component';
|
||||
export * from './components/download-prompt-dialog/download-prompt-dialog.component';
|
||||
|
||||
export * from './directives/viewer-extension.directive';
|
||||
|
||||
export * from './viewer.module';
|
||||
|
||||
export * from './models/viewer.model';
|
||||
export * from './models/download-prompt.actions';
|
||||
|
@@ -45,6 +45,7 @@ import { DirectiveModule } from '../directives/directive.module';
|
||||
import { A11yModule } from '@angular/cdk/a11y';
|
||||
import { ViewerComponent } from './components/viewer.component';
|
||||
import { ViewerToolbarCustomActionsComponent } from './components/viewer-toolbar-custom-actions.component';
|
||||
import { DownloadPromptDialogComponent } from './components/download-prompt-dialog/download-prompt-dialog.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -77,7 +78,8 @@ import { ViewerToolbarCustomActionsComponent } from './components/viewer-toolbar
|
||||
ViewerMoreActionsComponent,
|
||||
ViewerToolbarActionsComponent,
|
||||
ViewerComponent,
|
||||
ViewerToolbarCustomActionsComponent
|
||||
ViewerToolbarCustomActionsComponent,
|
||||
DownloadPromptDialogComponent
|
||||
],
|
||||
exports: [
|
||||
ViewerRenderComponent,
|
||||
|
Reference in New Issue
Block a user