diff --git a/src/i18n/en-US.properties b/src/i18n/en-US.properties index 43c7a421d..4f6dae52c 100644 --- a/src/i18n/en-US.properties +++ b/src/i18n/en-US.properties @@ -34,6 +34,8 @@ loading_preview=Loading Preview... download_file=Download File # Text shown when a text file has been truncated due to size limits. text_truncated=This file has been truncated due to size limits. Please download to view the whole file. +# Button tooltip to toggle Thumbnails Sidebar +toggle_thumbnails=Toggle thumbnails # Error messages # Default preview error message diff --git a/src/lib/icons/icons.js b/src/lib/icons/icons.js index 95243ec1f..cfc7665b2 100644 --- a/src/lib/icons/icons.js +++ b/src/lib/icons/icons.js @@ -44,6 +44,7 @@ import FIND_DROP_UP from './arrow_drop_up.svg'; import CLOSE from './close.svg'; import SEARCH from './search.svg'; import PRINT_CHECKMARK from './print_checkmark.svg'; +import THUMBNAILS_TOGGLE from './thumbnails-toggle-icon.svg'; export const ICON_DROP_DOWN = DROP_DOWN; export const ICON_DROP_UP = DROP_UP; @@ -68,6 +69,7 @@ export const ICON_FIND_DROP_UP = FIND_DROP_UP; export const ICON_CLOSE = CLOSE; export const ICON_SEARCH = SEARCH; export const ICON_PRINT_CHECKMARK = PRINT_CHECKMARK; +export const ICON_THUMBNAILS_TOGGLE = THUMBNAILS_TOGGLE; const FILE_LOADING_ICONS = { FILE_AUDIO, diff --git a/src/lib/icons/thumbnails-toggle-icon.svg b/src/lib/icons/thumbnails-toggle-icon.svg new file mode 100644 index 000000000..86fccb296 --- /dev/null +++ b/src/lib/icons/thumbnails-toggle-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/lib/viewers/doc/DocBaseViewer.js b/src/lib/viewers/doc/DocBaseViewer.js index 58d402b9f..254be1da5 100644 --- a/src/lib/viewers/doc/DocBaseViewer.js +++ b/src/lib/viewers/doc/DocBaseViewer.js @@ -29,7 +29,14 @@ import { getDistance, getClosestPageToPinch } from '../../util'; -import { ICON_PRINT_CHECKMARK } from '../../icons/icons'; +import { + ICON_PRINT_CHECKMARK, + ICON_ZOOM_OUT, + ICON_ZOOM_IN, + ICON_FULLSCREEN_IN, + ICON_FULLSCREEN_OUT, + ICON_THUMBNAILS_TOGGLE +} from '../../icons/icons'; import { JS, PRELOAD_JS, CSS } from './docAssets'; import { ERROR_CODE, VIEWER_EVENT, LOAD_METRIC } from '../../events'; import Timer from '../../Timer'; @@ -83,6 +90,7 @@ class DocBaseViewer extends BaseViewer { this.pinchToZoomChangeHandler = this.pinchToZoomChangeHandler.bind(this); this.pinchToZoomEndHandler = this.pinchToZoomEndHandler.bind(this); this.emitMetric = this.emitMetric.bind(this); + this.toggleThumbnails = this.toggleThumbnails.bind(this); } /** @@ -971,12 +979,31 @@ class DocBaseViewer extends BaseViewer { } /** - * Binds listeners for document controls. Overridden. + * Binds listeners for document controls * * @protected * @return {void} */ - bindControlListeners() {} + bindControlListeners() { + this.controls.add( + __('toggle_thumbnails'), + this.toggleThumbnails, + 'bp-toggle-thumbnails-icon', + ICON_THUMBNAILS_TOGGLE + ); + this.controls.add(__('zoom_out'), this.zoomOut, 'bp-doc-zoom-out-icon', ICON_ZOOM_OUT); + this.controls.add(__('zoom_in'), this.zoomIn, 'bp-doc-zoom-in-icon', ICON_ZOOM_IN); + + this.pageControls.add(this.pdfViewer.currentPageNumber, this.pdfViewer.pagesCount); + + this.controls.add( + __('enter_fullscreen'), + this.toggleFullscreen, + 'bp-enter-fullscreen-icon', + ICON_FULLSCREEN_IN + ); + this.controls.add(__('exit_fullscreen'), this.toggleFullscreen, 'bp-exit-fullscreen-icon', ICON_FULLSCREEN_OUT); + } /** * Handler for 'pagesinit' event. @@ -1237,6 +1264,14 @@ class DocBaseViewer extends BaseViewer { this.pinchScale = 1; this.pinchPage = null; } + + /** + * Callback when the toggle thumbnail sidebar button is clicked. + * + * @protected + * @return {void} + */ + toggleThumbnails() {} } export default DocBaseViewer; diff --git a/src/lib/viewers/doc/DocumentViewer.js b/src/lib/viewers/doc/DocumentViewer.js index f76a55cfd..a6e74e290 100644 --- a/src/lib/viewers/doc/DocumentViewer.js +++ b/src/lib/viewers/doc/DocumentViewer.js @@ -1,7 +1,6 @@ import DocBaseViewer from './DocBaseViewer'; import DocPreloader from './DocPreloader'; import fullscreen from '../../Fullscreen'; -import { ICON_FULLSCREEN_IN, ICON_FULLSCREEN_OUT, ICON_ZOOM_IN, ICON_ZOOM_OUT } from '../../icons/icons'; import './Document.scss'; class DocumentViewer extends DocBaseViewer { @@ -59,29 +58,6 @@ class DocumentViewer extends DocBaseViewer { //-------------------------------------------------------------------------- // Event Listeners //-------------------------------------------------------------------------- - - /** - * Bind event listeners for document controls - * - * @private - * @return {void} - */ - bindControlListeners() { - super.bindControlListeners(); - - this.controls.add(__('zoom_out'), this.zoomOut, 'bp-doc-zoom-out-icon', ICON_ZOOM_OUT); - this.controls.add(__('zoom_in'), this.zoomIn, 'bp-doc-zoom-in-icon', ICON_ZOOM_IN); - - this.pageControls.add(this.pdfViewer.currentPageNumber, this.pdfViewer.pagesCount); - - this.controls.add( - __('enter_fullscreen'), - this.toggleFullscreen, - 'bp-enter-fullscreen-icon', - ICON_FULLSCREEN_IN - ); - this.controls.add(__('exit_fullscreen'), this.toggleFullscreen, 'bp-exit-fullscreen-icon', ICON_FULLSCREEN_OUT); - } } export default DocumentViewer; diff --git a/src/lib/viewers/doc/PresentationViewer.js b/src/lib/viewers/doc/PresentationViewer.js index c355c1516..f7189257f 100644 --- a/src/lib/viewers/doc/PresentationViewer.js +++ b/src/lib/viewers/doc/PresentationViewer.js @@ -2,7 +2,6 @@ import throttle from 'lodash/throttle'; import DocBaseViewer from './DocBaseViewer'; import PresentationPreloader from './PresentationPreloader'; import { CLASS_INVISIBLE } from '../../constants'; -import { ICON_FULLSCREEN_IN, ICON_FULLSCREEN_OUT, ICON_ZOOM_IN, ICON_ZOOM_OUT } from '../../icons/icons'; import './Presentation.scss'; const WHEEL_THROTTLE = 200; @@ -177,30 +176,6 @@ class PresentationViewer extends DocBaseViewer { } } - /** - * Adds event listeners for presentation controls - * - * @override - * @return {void} - * @protected - */ - bindControlListeners() { - super.bindControlListeners(); - - this.controls.add(__('zoom_out'), this.zoomOut, 'bp-exit-zoom-out-icon', ICON_ZOOM_OUT); - this.controls.add(__('zoom_in'), this.zoomIn, 'bp-enter-zoom-in-icon', ICON_ZOOM_IN); - - this.pageControls.add(this.pdfViewer.currentPageNumber, this.pdfViewer.pagesCount); - - this.controls.add( - __('enter_fullscreen'), - this.toggleFullscreen, - 'bp-enter-fullscreen-icon', - ICON_FULLSCREEN_IN - ); - this.controls.add(__('exit_fullscreen'), this.toggleFullscreen, 'bp-exit-fullscreen-icon', ICON_FULLSCREEN_OUT); - } - /** * Handler for mobile scroll events. * diff --git a/src/lib/viewers/doc/__tests__/DocBaseViewer-test.js b/src/lib/viewers/doc/__tests__/DocBaseViewer-test.js index 5dfa3d472..5f9ebba94 100644 --- a/src/lib/viewers/doc/__tests__/DocBaseViewer-test.js +++ b/src/lib/viewers/doc/__tests__/DocBaseViewer-test.js @@ -20,7 +20,14 @@ import { QUERY_PARAM_ENCODING, ENCODING_TYPES } from '../../../constants'; -import { ICON_PRINT_CHECKMARK } from '../../../icons/icons'; +import { + ICON_PRINT_CHECKMARK, + ICON_THUMBNAILS_TOGGLE, + ICON_ZOOM_OUT, + ICON_ZOOM_IN, + ICON_FULLSCREEN_IN, + ICON_FULLSCREEN_OUT +} from '../../../icons/icons'; import { VIEWER_EVENT, LOAD_METRIC } from '../../../events'; import Timer from '../../../Timer'; @@ -2013,4 +2020,63 @@ describe('src/lib/viewers/doc/DocBaseViewer', () => { expect(docBase.getStartPage(startAt)).to.be.undefined; }); }); + + describe('bindControlListeners()', () => { + beforeEach(() => { + docBase.pdfViewer = { + pagesCount: 4, + currentPageNumber: 1, + cleanup: sandbox.stub() + }; + + docBase.controls = { + add: sandbox.stub(), + removeListener: sandbox.stub() + }; + + docBase.pageControls = { + add: sandbox.stub(), + removeListener: sandbox.stub() + }; + }); + + it('should add the correct controls', () => { + docBase.bindControlListeners(); + + expect(docBase.controls.add).to.be.calledWith( + __('toggle_thumbnails'), + docBase.toggleThumbnails, + 'bp-toggle-thumbnails-icon', + ICON_THUMBNAILS_TOGGLE + ); + + expect(docBase.controls.add).to.be.calledWith( + __('zoom_out'), + docBase.zoomOut, + 'bp-doc-zoom-out-icon', + ICON_ZOOM_OUT + ); + expect(docBase.controls.add).to.be.calledWith( + __('zoom_in'), + docBase.zoomIn, + 'bp-doc-zoom-in-icon', + ICON_ZOOM_IN + ); + + expect(docBase.pageControls.add).to.be.calledWith(1, 4); + + expect(docBase.controls.add).to.be.calledWith( + __('enter_fullscreen'), + docBase.toggleFullscreen, + 'bp-enter-fullscreen-icon', + ICON_FULLSCREEN_IN + ); + expect(docBase.controls.add).to.be.calledWith( + __('exit_fullscreen'), + docBase.toggleFullscreen, + 'bp-exit-fullscreen-icon', + ICON_FULLSCREEN_OUT + ); + }); + }); }); diff --git a/src/lib/viewers/doc/__tests__/DocumentViewer-test.js b/src/lib/viewers/doc/__tests__/DocumentViewer-test.js index 1d6d4b989..53635bcc2 100644 --- a/src/lib/viewers/doc/__tests__/DocumentViewer-test.js +++ b/src/lib/viewers/doc/__tests__/DocumentViewer-test.js @@ -4,7 +4,6 @@ import DocBaseViewer from '../DocBaseViewer'; import BaseViewer from '../../BaseViewer'; import DocPreloader from '../DocPreloader'; import fullscreen from '../../../Fullscreen'; -import { ICON_FULLSCREEN_IN, ICON_FULLSCREEN_OUT, ICON_ZOOM_IN, ICON_ZOOM_OUT } from '../../../icons/icons'; const sandbox = sinon.sandbox.create(); @@ -147,44 +146,4 @@ describe('lib/viewers/doc/DocumentViewer', () => { expect(docbaseStub).to.have.been.calledTwice; }); }); - - describe('bindControlListeners()', () => { - beforeEach(() => { - doc.pdfViewer = { - pagesCount: 4, - cleanup: sandbox.stub() - }; - - doc.pageControls = { - add: sandbox.stub(), - removeListener: sandbox.stub() - }; - }); - - it('should add the correct controls', () => { - doc.bindControlListeners(); - expect(doc.controls.add).to.be.calledWith( - __('zoom_out'), - doc.zoomOut, - 'bp-doc-zoom-out-icon', - ICON_ZOOM_OUT - ); - expect(doc.controls.add).to.be.calledWith(__('zoom_in'), doc.zoomIn, 'bp-doc-zoom-in-icon', ICON_ZOOM_IN); - - expect(doc.pageControls.add).to.be.called; - - expect(doc.controls.add).to.be.calledWith( - __('enter_fullscreen'), - doc.toggleFullscreen, - 'bp-enter-fullscreen-icon', - ICON_FULLSCREEN_IN - ); - expect(doc.controls.add).to.be.calledWith( - __('exit_fullscreen'), - doc.toggleFullscreen, - 'bp-exit-fullscreen-icon', - ICON_FULLSCREEN_OUT - ); - }); - }); }); diff --git a/src/lib/viewers/doc/__tests__/PresentationViewer-test.js b/src/lib/viewers/doc/__tests__/PresentationViewer-test.js index 4823e600d..5bd7b6cfa 100644 --- a/src/lib/viewers/doc/__tests__/PresentationViewer-test.js +++ b/src/lib/viewers/doc/__tests__/PresentationViewer-test.js @@ -5,8 +5,6 @@ import DocBaseViewer from '../DocBaseViewer'; import PresentationPreloader from '../PresentationPreloader'; import { CLASS_INVISIBLE } from '../../../constants'; -import { ICON_ZOOM_OUT, ICON_ZOOM_IN, ICON_FULLSCREEN_IN, ICON_FULLSCREEN_OUT } from '../../../icons/icons'; - const sandbox = sinon.sandbox.create(); let containerEl; @@ -293,52 +291,6 @@ describe('lib/viewers/doc/PresentationViewer', () => { }); }); - describe('bindControlListeners()', () => { - beforeEach(() => { - presentation.pdfViewer = { - pagesCount: 4, - currentPageNumber: 1, - cleanup: sandbox.stub() - }; - - presentation.pageControls = { - add: sandbox.stub(), - removeListener: sandbox.stub() - }; - }); - - it('should add the correct controls', () => { - presentation.bindControlListeners(); - expect(presentation.controls.add).to.be.calledWith( - __('zoom_out'), - presentation.zoomOut, - 'bp-exit-zoom-out-icon', - ICON_ZOOM_OUT - ); - expect(presentation.controls.add).to.be.calledWith( - __('zoom_in'), - presentation.zoomIn, - 'bp-enter-zoom-in-icon', - ICON_ZOOM_IN - ); - - expect(presentation.pageControls.add).to.be.calledWith(1, 4); - - expect(presentation.controls.add).to.be.calledWith( - __('enter_fullscreen'), - presentation.toggleFullscreen, - 'bp-enter-fullscreen-icon', - ICON_FULLSCREEN_IN - ); - expect(presentation.controls.add).to.be.calledWith( - __('exit_fullscreen'), - presentation.toggleFullscreen, - 'bp-exit-fullscreen-icon', - ICON_FULLSCREEN_OUT - ); - }); - }); - describe('mobileScrollHandler()', () => { beforeEach(() => { stubs.checkOverflow = sandbox.stub(presentation, 'checkOverflow').returns(false);