'use strict'; /** * Licensed Materials - Property of IBM * IBM Cognos Products: Storytelling * (C) Copyright IBM Corp. 2014, 2020 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ define(['baglass/core-client/js/core-client/ui/core/View', 'baglass/core-client/js/core-client/utils/Utils', './PlayerViewProgressBar', 'text!./templates/TimelinePlayerView.html', 'gemini/app/util/ScreenReaderUtil', 'storytelling-ui/storytelling-ui.min', '../lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/chevron-left_16', '../lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/chevron-right_16', '../lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/settings_16', '../lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/play_16', '../lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/pause_16', '../lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/minimize_16', '../lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/skip-back_32', '../lib/@ba-ui-toolkit/ba-graphics/dist/icons-js/skip-forward_32', 'jquery', 'react', 'react-dom'], function (View, Utils, PlayerProgressBar, Template, ScreenReaderUtil, StorytellingUI, chevronLeftIcon, chevronRightIcon, manageIcon, playIcon, pauseIcon, exitFullscreenIcon, skipBack, skipForward, $, React, ReactDOM) { var TimelinePlayerView = View.extend({ templateString: Template, controller: null, currentPlayState: null, events: { 'primaryaction button.playPause': 'onPlayPauseClick', 'primaryaction button.sceneStart': 'onSceneStartClick', 'primaryaction button.sceneEnd': 'onSceneEndClick', 'primaryaction button.fullscreen': 'onExitFullscreenClick', 'primaryaction button.timelineSettings': 'onTimelineSettingsClick', 'primaryaction button.prevScene': 'onPreviousSceneClick', 'primaryaction button.nextScene': 'onNextSceneClick' }, init: function init(options) { TimelinePlayerView.inherited('init', this, arguments); this.controller = options.controller; // StoryPaneController this.glassContext = options.glassContext; this.services = options.services; this._ScreenReader = new ScreenReaderUtil(); this.stringResources = this.services.getSvcSync('.StringResources'); this.flyoutHolder = document.createElement('div'); this.flyoutHolder.classList.add('flyout-holder'); }, /** * Renders the TimelinePlayerView. * * @returns */ render: function render() { this.$el.addClass('timelinePlayer').attr('role', 'application'); // we want to be blocked when widgets are expanded this.$el.addClass('blockOnExpandView'); this.currentPlayState = {}; var sHtml = this.dotTemplate({ stringSceneCount: this._getSceneCountString(), sceneStartLabel: this.stringResources.get('sceneStart', { position: '0:00.0' }), playLabel: this.stringResources.get('timelinePlay'), prevSceneLabel: this.stringResources.get('navPrevScene'), prevSceneAbbreviatedLabel: this.stringResources.get('navPrevSceneAbbreviated'), nextSceneLabel: this.stringResources.get('navNextScene'), navModelLabel: this.stringResources.get('sceneNavigation'), showOverview: this.controller.hasOverview(), toggleOverviewLabel: this.stringResources.get('navToggleOverview'), // TODO: delete me? fullscreenLabel: this.stringResources.get('navExitFullScreen'), timelineSettingsLabel: this.stringResources.get('timelineSettingsButton') }); this.$el.html(sHtml); this.$sceneCountLabel = this.$el.find('.numScenes'); this.progressBar = new PlayerProgressBar({ el: this.$el.find('.progressInfo > .progressBarView'), timelineController: this.controller.getTimelineController(), controller: this.controller, glassContext: this.glassContext, services: this.services }); this.progressBar.render(); this.timeLabel = this.$el.find('.progressInfo > .timeLabel'); this.durationLabel = this.$el.find('.progressInfo > .durationLabel'); this.$previousSceneButton = this.$el.find('button.prevScene'); this.$sceneStartButton = this.$el.find('button.sceneStart'); this.$playPauseButton = this.$el.find('button.playPause'); this.$sceneEndButton = this.$el.find('button.sceneEnd'); this.$nextSceneButton = this.$el.find('button.nextScene'); this.$timelineSettingsButton = this.$el.find('button.timelineSettings'); this.$fullscreenButton = this.$el.find('button.fullscreen'); this.$fullscreenButtonContainer = this.$el.find('.storyContainer.fullscreen'); this.$fullscreenButtonContainer.hide(); // Set/insert SVG icons Utils.setIcon(this.$previousSceneButton, chevronLeftIcon.default.id); Utils.setIcon(this.$sceneStartButton, skipBack.default.id); Utils.setIcon(this.$sceneEndButton, skipForward.default.id); Utils.setIcon(this.$nextSceneButton, chevronRightIcon.default.id, null, null, true); Utils.setIcon(this.$timelineSettingsButton, manageIcon.default.id); Utils.setIcon(this.$fullscreenButton, exitFullscreenIcon.default.id); // register events $(window).on('resize.privateViewEvents' + this.viewId, this.onSmallScreenUpdate.bind(this)); this.controller.on('scene:add', this.onSceneAdded, this); this.controller.on('time:update', this.onTimeUpdated, this); this.controller.on('playState:change', this.onPlayStateChanged, this); this.controller.on('scene:select', this.onSceneSelected, this); this.controller.on('scene:expand', this.onSceneExpand, this); this.controller.on('scene:collapse', this.onSceneCollapse, this); this.controller.on('navigation:complete', this.onNavigationComplete, this); this.controller.on('change:showOverviews', this.onShowOverviewsChanged, this); this.controller.on('mode:change', this.onModeChange, this); this.controller.on('kioskMode:change', this._updateLabels, this); this.controller.on('navigateMarkers:change', this._onNavigateMarkersChange, this); this.controller.getTimelineController().on('duration:changed', this.onDurationChanged, this); this._updateTime(this.controller.getStoryCurrentTimeLabel()); this._updateDuration(); this._updatePlayState(); this._updateLabels(); this._updateLabelsVisibility(); return this; }, onSmallScreenUpdate: function onSmallScreenUpdate() { if (this._flyout) { this._closePlayThroughFlyout(); } this._updateLabelsVisibility(); }, _updateLabelsVisibility: function _updateLabelsVisibility() { var width = this.$el.width(); var $prevLabel = this.$previousSceneButton.find('.navLabel'); var $nextLabel = this.$nextSceneButton.find('.navLabel'); if (width < 1050) { $prevLabel.addClass('hidden'); $nextLabel.addClass('hidden'); } else { $prevLabel.removeClass('hidden'); $nextLabel.removeClass('hidden'); } }, remove: function remove() { this.timeLabel = null; $(window).off('resize.privateViewEvents' + this.viewId); this.controller.off('scene:add', this.onSceneAdded, this); this.controller.off('time:update', this.onTimeUpdated, this); this.controller.off('playState:change', this.onPlayStateChanged, this); this.controller.off('scene:select', this.onSceneSelected, this); this.controller.off('scene:expand', this.onSceneExpand, this); this.controller.off('scene:collapse', this.onSceneCollapse, this); this.controller.off('navigation:complete', this.onNavigationComplete, this); this.controller.off('change:showOverviews', this.onShowOverviewsChanged, this); this.controller.off('mode:change', this.onModeChange, this); this.controller.off('kioskMode:change', this._updateLabels, this); this.controller.off('navigateMarkers:change', this._onNavigateMarkersChange, this); this.controller.getTimelineController().off('duration:changed', this.onDurationChanged, this); if (this.progressBar) { this.progressBar.remove(); } TimelinePlayerView.inherited('remove', this, arguments); }, /* * View events. */ onPlayPauseClick: function onPlayPauseClick() { this.controller.togglePlayPause(); }, onSceneStartClick: function onSceneStartClick() { this.controller.pause(); this.controller.setCurrentTime(0); }, onSceneEndClick: function onSceneEndClick() { this.controller.pause(); this.controller.setCurrentTime(this.controller.getDuration()); }, /* * Controller events. */ onSceneAdded: function onSceneAdded() { this._updateLabels(); }, onModeChange: function onModeChange() { this.updateProgressBar(); this._updateLabels(); }, onDurationChanged: function onDurationChanged() { this._updateDuration(); this.updateProgressBar(); }, onTimeUpdated: function onTimeUpdated(evt) { var isPlaying = this.controller.isPlaying(); if (!isPlaying) { this._updateLabels(); } this._updateTime(evt.label); this._updatePlayState({ time: evt.time, playing: isPlaying }); }, onPlayStateChanged: function onPlayStateChanged(evt) { var isPlaying = this.controller.isPlaying(); if (!isPlaying && evt.currentTime !== 0) { this.progressBar.timeIndicatorView.handleTimelinePositionIndicatorMove(); } this._updatePlayState({ time: evt.currentTime, playing: isPlaying }); }, onSceneSelected: function onSceneSelected() { this._updateLabels(); this._updateTime(this.controller.getStoryCurrentTimeLabel()); this._updateDuration(); }, onSceneExpand: function onSceneExpand() { this.$el.addClass('viewingScene'); }, onSceneCollapse: function onSceneCollapse() { this.$el.removeClass('viewingScene'); }, onNavigationComplete: function onNavigationComplete() { this._updatePlayState(); }, toggleFullscreenControls: function toggleFullscreenControls(toggleFullscreen) { // Show the exit fullscreen button when in fullscreen if (toggleFullscreen) { this.$fullscreenButtonContainer.show(); if (this.controller.isAuthoring()) { // Reset only when going to full screen this.controller.setCurrentTime(0); } } else { this.$fullscreenButtonContainer.hide(); } if (toggleFullscreen) { this.$el.hide(); } }, onTimelineSettingsClick: function onTimelineSettingsClick(event) { if (this._flyout) { this._closePlayThroughFlyout(); } else { this._createPlayThroughFlyout(event); } }, onExitFullscreenClick: function onExitFullscreenClick() { // Exit fullscreen. this.controller.eventRouter.trigger('fullscreen:exit'); }, onPreviousSceneClick: function onPreviousSceneClick() { this.controller.previousScene(); this.progressBar.timeIndicatorView.handlePositionMoveLeft(); }, onNextSceneClick: function onNextSceneClick() { this.controller.nextScene(); this.progressBar.timeIndicatorView.handlePositionMoveRight(); }, onShowOverviewsChanged: function onShowOverviewsChanged() { this._updateLabels(); }, /* * Helpers. */ _createPlayThroughFlyout: function _createPlayThroughFlyout(event) { this.$el.append(this.flyoutHolder); this._flyout = React.createElement(StorytellingUI.PlayThroughFlyout, { anchorElement: event.currentTarget, closeFlyout: this._closePlayThroughFlyout.bind(this), controller: this.controller }); ReactDOM.render(this._flyout, this.flyoutHolder); this.$timelineSettingsButton.addClass('selected'); }, _closePlayThroughFlyout: function _closePlayThroughFlyout() { ReactDOM.unmountComponentAtNode(this.flyoutHolder); this.$el.find('.flyout-holder').remove(); this._flyout = null; this.$timelineSettingsButton.removeClass('selected'); }, _getSceneCountString: function _getSceneCountString() { var count = this.controller.getSceneCount(); var text; var currentSceneIndex = this.controller.getSelectedSceneIndex(); if (currentSceneIndex >= 0) { text = this.stringResources.get('storySceneRangeCountLabel', { index: currentSceneIndex + 1, count: count }); } else if (count === 1) { text = this.stringResources.get('storySceneSingleCountLabel'); } else { text = this.stringResources.get('storySceneCountLabel', { count: count }); } return text; }, _onNavigateMarkersChange: function _onNavigateMarkersChange() { this._updateLabels(); this.updateProgressBar(); }, _updateLabels: function _updateLabels() { var canShowPrevious; var canShowNext; // update button states if (this.controller.isKioskMode()) { canShowNext = true; canShowPrevious = true; } else { canShowPrevious = !this.controller.isOnFirstScene(); canShowNext = !this.controller.isOnLastScene(); if (this.controller.isNavigateMarkers()) { if (!canShowPrevious) { canShowPrevious = !this.controller.isAtStartOfScene(); } if (!canShowNext) { canShowNext = !this.controller.isAtEndOfScene(); } } } this.$previousSceneButton.prop('disabled', !canShowPrevious); this.$nextSceneButton.prop('disabled', !canShowNext); this.$sceneCountLabel.html(this._getSceneCountString()); // update button labels var previousSceneLabels = { abbreviatedString: this.stringResources.get('navPrevSceneAbbreviated'), string: this.stringResources.get('navPrevScene') }; var nextSceneLabels = { string: this.stringResources.get('navNextScene') }; if (this.controller.isNavigateMarkers()) { var previousMarkerLabels = { abbreviatedString: this.stringResources.get('navPrevMarkerAbbreviated'), string: this.stringResources.get('navPrevMarker') }; var nextMarkerLabels = { string: this.stringResources.get('navNextMarker') }; this._updateLabel(this.$previousSceneButton, this.controller.isAtStartOfScene() ? previousSceneLabels : previousMarkerLabels); this._updateLabel(this.$nextSceneButton, this.controller.isAtEndOfScene() ? nextSceneLabels : nextMarkerLabels); } else { this._updateLabel(this.$previousSceneButton, previousSceneLabels); this._updateLabel(this.$nextSceneButton, nextSceneLabels); } }, _updateLabel: function _updateLabel($button, labels) { $button.attr('aria-label', labels.string); $button.attr('title', labels.string); $button.find('.navLabel').text(labels.abbreviatedString ? labels.abbreviatedString : labels.string); }, updateProgressBar: function updateProgressBar() { if (this.progressBar) { this.progressBar.refresh(); } }, _updateDuration: function _updateDuration() { if (this.durationLabel) { var _label = this.controller.getStoryDurationLabel(); this.durationLabel.text(_label); } var $button = this.$el.find('.sceneEnd'); var label = this.stringResources.get('sceneEnd', { position: this.progressBar.timeIndicatorView.getEndTime() }); $button.attr('aria-label', label); $button.attr('title', label); }, _updateTime: function _updateTime(time) { if (this.timeLabel) { this.timeLabel.text(time); } }, _getCurrentTime: function _getCurrentTime() { return this.progressBar.timeIndicatorView.getCurrentTime(); }, _updatePlayState: function _updatePlayState(options) { options = options || { time: this.controller.getCurrentTime(), playing: this.controller.isPlaying() }; var duration = this.controller.getDuration(), playing = options.playing; var canPlayPause = duration > 0 || this.controller.isStartOverview(), canGoToStart = options.time > 0, canGoToEnd = options.time < duration; if (playing !== this.currentPlayState.playing) { var buttonLabel = playing ? this.stringResources.get('timelinePause') : this.stringResources.get('timelinePlay'); this.$playPauseButton.attr('title', buttonLabel).attr('aria-label', buttonLabel).html(''); this._ScreenReader.callOut(buttonLabel); if (playing) { Utils.setIcon(this.$playPauseButton, pauseIcon.default.id); } else { Utils.setIcon(this.$playPauseButton, playIcon.default.id); } this.currentPlayState.playing = playing; } if (canPlayPause !== this.currentPlayState.canPlayPause) { this.$playPauseButton.prop('disabled', !canPlayPause); this.currentPlayState.canPlayPause = canPlayPause; } if (canGoToStart !== this.currentPlayState.canGoToStart) { this.$sceneStartButton.prop('disabled', !canGoToStart); this.currentPlayState.canGoToStart = canGoToStart; } if (canGoToEnd !== this.currentPlayState.canGoToEnd) { this.$sceneEndButton.prop('disabled', !canGoToEnd); this.currentPlayState.canGoToEnd = canGoToEnd; } } }); return TimelinePlayerView; }); //# sourceMappingURL=TimelinePlayerView.js.map