| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| Polymer({ |
| is: 'print-preview-destination-dialog', |
| |
| behaviors: [I18nBehavior], |
| |
| properties: { |
| /** @type {?print_preview.DestinationStore} */ |
| destinationStore: { |
| type: Object, |
| observer: 'onDestinationStoreSet_', |
| }, |
| |
| /** @type {?print_preview.InvitationStore} */ |
| invitationStore: { |
| type: Object, |
| observer: 'onInvitationStoreSet_', |
| }, |
| |
| /** @private {?print_preview.Invitation} */ |
| invitation_: { |
| type: Object, |
| value: null, |
| }, |
| |
| /** @type {!print_preview.UserInfo} */ |
| userInfo: { |
| type: Object, |
| notify: true, |
| }, |
| |
| /** @type {boolean} */ |
| showCloudPrintPromo: { |
| type: Boolean, |
| notify: true, |
| observer: 'onShowCloudPrintPromoChanged_', |
| }, |
| |
| /** @private {!Array<!print_preview.Destination>} */ |
| destinations_: { |
| type: Array, |
| notify: true, |
| value: [], |
| }, |
| |
| /** @private {boolean} */ |
| loadingDestinations_: { |
| type: Boolean, |
| value: false, |
| }, |
| |
| /** @type {!Array<!print_preview.RecentDestination>} */ |
| recentDestinations: Array, |
| |
| /** @private {!Array<!print_preview.Destination>} */ |
| recentDestinationList_: { |
| type: Array, |
| notify: true, |
| computed: 'computeRecentDestinationList_(' + |
| 'destinationStore, recentDestinations, recentDestinations.*, ' + |
| 'userInfo, destinations_.*)', |
| }, |
| |
| /** @private {?RegExp} */ |
| searchQuery_: { |
| type: Object, |
| value: null, |
| }, |
| }, |
| |
| /** @private {!EventTracker} */ |
| tracker_: new EventTracker(), |
| |
| /** @private {!print_preview.DestinationSearchMetricsContext} */ |
| metrics_: new print_preview.DestinationSearchMetricsContext(), |
| |
| // <if expr="chromeos"> |
| /** @private {?print_preview.Destination} */ |
| destinationInConfiguring_: null, |
| // </if> |
| |
| /** @override */ |
| ready: function() { |
| this.$$('.promo-text').innerHTML = |
| this.i18nAdvanced('cloudPrintPromotion', { |
| substitutions: ['<a is="action-link" class="sign-in">', '</a>'], |
| attrs: { |
| 'is': (node, v) => v == 'action-link', |
| 'class': (node, v) => v == 'sign-in', |
| 'tabindex': (node, v) => v == '0', |
| 'role': (node, v) => v == 'link', |
| }, |
| }); |
| }, |
| |
| /** @override */ |
| attached: function() { |
| this.tracker_.add( |
| assert(this.$$('.sign-in')), 'click', this.onSignInClick_.bind(this)); |
| this.tracker_.add( |
| assert(this.$$('#cloudprintPromo > .close-button')), 'click', |
| this.onCloudPrintPromoDismissed_.bind(this)); |
| }, |
| |
| /** @private */ |
| onDestinationStoreSet_: function() { |
| assert(this.destinations_.length == 0); |
| const destinationStore = assert(this.destinationStore); |
| this.tracker_.add( |
| destinationStore, |
| print_preview.DestinationStore.EventType.DESTINATIONS_INSERTED, |
| this.updateDestinations_.bind(this)); |
| this.tracker_.add( |
| destinationStore, |
| print_preview.DestinationStore.EventType.DESTINATION_SEARCH_DONE, |
| this.onDestinationSearchDone_.bind(this)); |
| }, |
| |
| /** @private */ |
| onInvitationStoreSet_: function() { |
| const invitationStore = assert(this.invitationStore); |
| this.tracker_.add( |
| invitationStore, |
| print_preview.InvitationStore.EventType.INVITATION_SEARCH_DONE, |
| this.updateInvitations_.bind(this)); |
| this.tracker_.add( |
| invitationStore, |
| print_preview.InvitationStore.EventType.INVITATION_PROCESSED, |
| this.updateInvitations_.bind(this)); |
| }, |
| |
| /** @private */ |
| onDestinationSearchDone_: function() { |
| this.updateDestinations_(); |
| this.invitationStore.startLoadingInvitations(); |
| }, |
| |
| /** @private */ |
| updateDestinations_: function() { |
| this.notifyPath('userInfo.users'); |
| this.notifyPath('userInfo.activeUser'); |
| this.notifyPath('userInfo.loggedIn'); |
| if (this.userInfo.loggedIn) |
| this.showCloudPrintPromo = false; |
| |
| this.destinations_ = this.userInfo ? |
| this.destinationStore.destinations(this.userInfo.activeUser) : |
| []; |
| this.loadingDestinations_ = |
| this.destinationStore.isPrintDestinationSearchInProgress; |
| }, |
| |
| /** |
| * @return {!Array<!print_preview.Destination>} |
| * @private |
| */ |
| computeRecentDestinationList_: function() { |
| let recentDestinations = []; |
| const filterAccount = this.userInfo.activeUser; |
| this.recentDestinations.forEach((recentDestination) => { |
| const destination = this.destinationStore.getDestination( |
| recentDestination.origin, recentDestination.id, |
| recentDestination.account || ''); |
| if (destination && |
| (!destination.account || destination.account == filterAccount)) { |
| recentDestinations.push(destination); |
| } |
| }); |
| return recentDestinations; |
| }, |
| |
| /** @private */ |
| onCloseOrCancel_: function() { |
| if (this.searchQuery_) |
| this.$.searchBox.setValue(''); |
| if (this.$.dialog.getNative().returnValue == 'success') { |
| this.metrics_.record(print_preview.Metrics.DestinationSearchBucket |
| .DESTINATION_CLOSED_CHANGED); |
| } else { |
| this.metrics_.record(print_preview.Metrics.DestinationSearchBucket |
| .DESTINATION_CLOSED_UNCHANGED); |
| } |
| }, |
| |
| /** @private */ |
| onCancelButtonClick_: function() { |
| this.$.dialog.cancel(); |
| }, |
| |
| /** |
| * @param {!CustomEvent} e Event containing the selected destination list item |
| * element. |
| * @private |
| */ |
| onDestinationSelected_: function(e) { |
| const listItem = |
| /** @type {!PrintPreviewDestinationListItemElement} */ (e.detail); |
| const destination = listItem.destination; |
| |
| // ChromeOS local destinations that don't have capabilities need to be |
| // configured before selecting, and provisional destinations need to be |
| // resolved. Other destinations can be selected. |
| if (destination.readyForSelection) { |
| this.selectDestination_(destination); |
| return; |
| } |
| |
| // Provisional destinations |
| if (destination.isProvisional) { |
| this.$.provisionalResolver.resolveDestination(destination) |
| .then(this.selectDestination_.bind(this)) |
| .catch(function() { |
| console.error( |
| 'Failed to resolve provisional destination: ' + destination.id); |
| }) |
| .then(() => { |
| if (this.$.dialog.open && !!listItem && !listItem.hidden) { |
| listItem.focus(); |
| } |
| }); |
| return; |
| } |
| |
| // <if expr="chromeos"> |
| // Destination must be a CrOS local destination that needs to be set up. |
| // The user is only allowed to set up printer at one time. |
| if (this.destinationInConfiguring_) |
| return; |
| |
| // Show the configuring status to the user and resolve the destination. |
| listItem.onConfigureRequestAccepted(); |
| this.destinationInConfiguring_ = destination; |
| this.destinationStore.resolveCrosDestination(destination) |
| .then( |
| response => { |
| this.destinationInConfiguring_ = null; |
| listItem.onConfigureComplete(response.success); |
| if (response.success) { |
| destination.capabilities = response.capabilities; |
| this.selectDestination_(destination); |
| } |
| }, |
| () => { |
| this.destinationInConfiguring_ = null; |
| listItem.onConfigureComplete(false); |
| }); |
| // </if> |
| }, |
| |
| /** |
| * @param {!print_preview.Destination} destination The destination to select. |
| * @private |
| */ |
| selectDestination_: function(destination) { |
| this.destinationStore.selectDestination(destination); |
| this.$.dialog.close(); |
| }, |
| |
| show: function() { |
| this.loadingDestinations_ = |
| this.destinationStore.isPrintDestinationSearchInProgress; |
| this.$.dialog.showModal(); |
| this.metrics_.record( |
| print_preview.Metrics.DestinationSearchBucket.DESTINATION_SHOWN); |
| }, |
| |
| /** @return {boolean} Whether the dialog is open. */ |
| isOpen: function() { |
| return this.$.dialog.hasAttribute('open'); |
| }, |
| |
| /** @private */ |
| isSelected_: function(account) { |
| return account == this.userInfo.activeUser; |
| }, |
| |
| /** @private */ |
| onSignInClick_: function() { |
| this.metrics_.record( |
| print_preview.Metrics.DestinationSearchBucket.SIGNIN_TRIGGERED); |
| print_preview.NativeLayer.getInstance().signIn(false).then(() => { |
| this.destinationStore.onDestinationsReload(); |
| }); |
| }, |
| |
| /** @private */ |
| onCloudPrintPromoDismissed_: function() { |
| this.showCloudPrintPromo = false; |
| }, |
| |
| /** |
| * Updates printer sharing invitations UI. |
| * @private |
| */ |
| updateInvitations_: function() { |
| const invitations = this.userInfo.activeUser ? |
| this.invitationStore.invitations(this.userInfo.activeUser) : |
| []; |
| if (this.invitation_ != invitations[0]) { |
| this.metrics_.record( |
| print_preview.Metrics.DestinationSearchBucket.INVITATION_AVAILABLE); |
| } |
| this.invitation_ = invitations.length > 0 ? invitations[0] : null; |
| }, |
| |
| /** |
| * @return {string} The text show show on the "accept" button in the |
| * invitation promo. 'Accept', 'Accept for group', or empty if there is no |
| * invitation. |
| * @private |
| */ |
| getAcceptButtonText_: function() { |
| if (!this.invitation_) |
| return ''; |
| |
| return this.invitation_.asGroupManager ? this.i18n('acceptForGroup') : |
| this.i18n('accept'); |
| }, |
| |
| /** |
| * @return {string} The formatted text to show for the invitation promo. |
| * @private |
| */ |
| getInvitationText_: function() { |
| if (!this.invitation_) |
| return ''; |
| |
| if (this.invitation_.asGroupManager) { |
| return this.i18nAdvanced('groupPrinterSharingInviteText', { |
| substitutions: [ |
| this.invitation_.sender, this.invitation_.destination.displayName, |
| this.invitation_.receiver |
| ] |
| }); |
| } |
| |
| return this.i18nAdvanced('printerSharingInviteText', { |
| substitutions: |
| [this.invitation_.sender, this.invitation_.destination.displayName] |
| }); |
| }, |
| |
| /** @private */ |
| onInvitationAcceptClick_: function() { |
| this.metrics_.record( |
| print_preview.Metrics.DestinationSearchBucket.INVITATION_ACCEPTED); |
| this.invitationStore.processInvitation(assert(this.invitation_), true); |
| this.updateInvitations_(); |
| }, |
| |
| /** @private */ |
| onInvitationRejectClick_: function() { |
| this.metrics_.record( |
| print_preview.Metrics.DestinationSearchBucket.INVITATION_REJECTED); |
| this.invitationStore.processInvitation(assert(this.invitation_), false); |
| this.updateInvitations_(); |
| }, |
| |
| /** @private */ |
| onUserChange_: function() { |
| const select = this.$$('select'); |
| const account = select.value; |
| if (account) { |
| this.showCloudPrintPromo = false; |
| this.userInfo.activeUser = account; |
| this.notifyPath('userInfo.activeUser'); |
| this.notifyPath('userInfo.loggedIn'); |
| this.destinationStore.reloadUserCookieBasedDestinations(); |
| this.invitationStore.startLoadingInvitations(); |
| this.metrics_.record( |
| print_preview.Metrics.DestinationSearchBucket.ACCOUNT_CHANGED); |
| } else { |
| print_preview.NativeLayer.getInstance().signIn(true).then( |
| this.destinationStore.onDestinationsReload.bind( |
| this.destinationStore)); |
| const options = select.querySelectorAll('option'); |
| for (let i = 0; i < options.length; i++) { |
| if (options[i].value == this.userInfo.activeUser) { |
| select.selectedIndex = i; |
| break; |
| } |
| } |
| this.metrics_.record( |
| print_preview.Metrics.DestinationSearchBucket.ADD_ACCOUNT_SELECTED); |
| } |
| }, |
| |
| /** @private */ |
| onShowCloudPrintPromoChanged_: function() { |
| if (this.showCloudPrintPromo) { |
| this.metrics_.record( |
| print_preview.Metrics.DestinationSearchBucket.SIGNIN_PROMPT); |
| } |
| }, |
| }); |