| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js'; |
| import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.js'; |
| import './profile_picker_main_view.js'; |
| import './profile_picker_shared.css.js'; |
| import './strings.m.js'; |
| |
| import {CrViewManagerElement} from 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js'; |
| import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js'; |
| import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; |
| import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; |
| import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js'; |
| import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; |
| |
| import {ensureLazyLoaded} from './ensure_lazy_loaded.js'; |
| import {AutogeneratedThemeColorInfo, ManageProfilesBrowserProxy, ManageProfilesBrowserProxyImpl} from './manage_profiles_browser_proxy.js'; |
| import {navigateTo, NavigationMixin, ProfileCreationSteps, Routes} from './navigation_mixin.js'; |
| import {isForceSigninEnabled, isProfileCreationAllowed} from './policy_helper.js'; |
| import {getTemplate} from './profile_picker_app.html.js'; |
| |
| export interface ProfilePickerAppElement { |
| $: { |
| viewManager: CrViewManagerElement, |
| }; |
| } |
| |
| const ProfilePickerAppElementBase = |
| WebUiListenerMixin(I18nMixin(NavigationMixin(PolymerElement))); |
| |
| export class ProfilePickerAppElement extends ProfilePickerAppElementBase { |
| static get is() { |
| return 'profile-picker-app'; |
| } |
| |
| static get template() { |
| return getTemplate(); |
| } |
| |
| static get properties() { |
| return { |
| /** |
| * Suggested new profile theme info for the profile creation flow. |
| */ |
| newProfileThemeInfo: { |
| type: Object, |
| notify: true, |
| }, |
| |
| /** |
| * True if a new profile (local or signed-in) is being created, all |
| * buttons that create a new profile are then disabled (to avoid creating |
| * two profiles). |
| */ |
| profileCreationInProgress: { |
| type: Boolean, |
| value: false, |
| notify: true, |
| }, |
| |
| /** |
| * Feature to open a profile customization dialog in a browser window for |
| * the local profile created. |
| */ |
| isLocalProfileCreationDialogEnabled_: { |
| type: Boolean, |
| value: () => |
| loadTimeData.getBoolean('isLocalProfileCreationDialogEnabled'), |
| }, |
| |
| shouldDisplayVerticalBanners_: { |
| type: Boolean, |
| value: false, |
| }, |
| }; |
| } |
| |
| newProfileThemeInfo: AutogeneratedThemeColorInfo; |
| profileCreationInProgress: boolean; |
| private isLocalProfileCreationDialogEnabled_: boolean; |
| private shouldDisplayVerticalBanners_: boolean; |
| private currentRoute_: Routes|null = null; |
| private manageProfilesBrowserProxy_: ManageProfilesBrowserProxy = |
| ManageProfilesBrowserProxyImpl.getInstance(); |
| |
| override connectedCallback() { |
| super.connectedCallback(); |
| this.setMinimumSize_(); |
| } |
| |
| override ready() { |
| super.ready(); |
| this.addWebUiListener( |
| 'create-profile-finished', |
| () => this.handleCreateLocalProfileFinished_()); |
| } |
| |
| override onRouteChange(route: Routes, step: string) { |
| if (!isProfileCreationAllowed() && route === Routes.NEW_PROFILE) { |
| navigateTo(Routes.MAIN); |
| return; |
| } |
| |
| if (step === ProfileCreationSteps.LOAD_FORCE_SIGNIN) { |
| assert( |
| route === Routes.NEW_PROFILE, |
| 'LOAD_FORCE_SIGNIN step must be a part of NEW_PROFILE route'); |
| assert( |
| isForceSigninEnabled(), |
| 'Force signin policy must be enabled to start the force signin flow'); |
| // The force sign-in flow is displayed in a dialog on top of the main |
| // view. Load the main view if it isn't already shown. |
| // Do not call `navigateTo(Routes.MAIN)` to not update the history. |
| // It's fine to skip `initializeModules()` for the main view since the |
| // main view will never be lazy loaded. |
| if (this.currentRoute_ !== Routes.MAIN) { |
| this.currentRoute_ = Routes.MAIN; |
| document.title = this.getDocumentTitle_('mainView'); |
| this.$.viewManager.switchView('mainView', 'fade-in', 'no-animation'); |
| } |
| this.manageProfilesBrowserProxy_.selectNewAccount(null); |
| |
| return; |
| } |
| |
| assert( |
| step !== ProfileCreationSteps.LOAD_SIGNIN, |
| 'LOAD_SIGNIN should not appear in navigation (only used for metrics)'); |
| |
| if (step === ProfileCreationSteps.LOCAL_PROFILE_CUSTOMIZATION && |
| this.isLocalProfileCreationDialogEnabled_) { |
| if (this.profileCreationInProgress) { |
| return; |
| } |
| this.profileCreationInProgress = true; |
| // TODO(https://crbug.com/1282157): Add createShortcut parameter. |
| this.initializeNewProfileThemeInfo_().then( |
| () => this.manageProfilesBrowserProxy_ |
| .createProfileAndOpenCustomizationDialog( |
| this.newProfileThemeInfo?.color)); |
| return; |
| } |
| |
| const setStep = () => { |
| document.title = this.getDocumentTitle_(step); |
| this.updateShouldDisplayVerticalBanners_(step); |
| this.$.viewManager.switchView(step, 'fade-in', 'no-animation'); |
| }; |
| |
| // If the route changed, initialize modules for that route. |
| if (this.currentRoute_ !== route) { |
| this.currentRoute_ = route; |
| this.initializeModules_().then(setStep); |
| } else { |
| setStep(); |
| } |
| } |
| |
| private updateShouldDisplayVerticalBanners_(step: string) { |
| // <if expr="chromeos_lacros"> |
| if (this.currentRoute_ === Routes.ACCOUNT_SELECTION_LACROS) { |
| this.shouldDisplayVerticalBanners_ = true; |
| return; |
| } |
| // </if> |
| |
| if (this.currentRoute_ === Routes.MAIN || |
| (this.currentRoute_ === Routes.NEW_PROFILE && |
| step === ProfileCreationSteps.PROFILE_TYPE_CHOICE)) { |
| this.shouldDisplayVerticalBanners_ = true; |
| } else { |
| this.shouldDisplayVerticalBanners_ = false; |
| } |
| } |
| |
| private getDocumentTitle_(step: string): string { |
| switch (step) { |
| case 'mainView': |
| return this.i18n('mainViewTitle'); |
| case ProfileCreationSteps.PROFILE_TYPE_CHOICE: |
| return this.i18n('profileTypeChoiceTitle'); |
| case ProfileCreationSteps.LOCAL_PROFILE_CUSTOMIZATION: |
| return this.i18n('localProfileCreationTitle'); |
| case 'profileSwitch': |
| return this.i18n('profileSwitchTitle'); |
| // <if expr="chromeos_lacros"> |
| case 'accountSelectionLacros': |
| return this.i18n('accountSelectionLacrosTitle'); |
| // </if> |
| default: |
| return ''; |
| } |
| } |
| |
| private initializeModules_(): Promise<any> { |
| switch (this.currentRoute_) { |
| case Routes.MAIN: |
| return Promise.resolve(); |
| case Routes.NEW_PROFILE: |
| // <if expr="chromeos_lacros"> |
| case Routes.ACCOUNT_SELECTION_LACROS: |
| // </if> |
| return Promise.all( |
| [this.initializeNewProfileThemeInfo_(), ensureLazyLoaded()]); |
| case Routes.PROFILE_SWITCH: |
| return ensureLazyLoaded(); |
| default: |
| // |this.currentRoute_| should be set by now. |
| assertNotReached(); |
| } |
| } |
| |
| private async initializeNewProfileThemeInfo_(): Promise<void> { |
| if (this.newProfileThemeInfo) { |
| return Promise.resolve(); |
| } |
| this.newProfileThemeInfo = await this.manageProfilesBrowserProxy_ |
| .getNewProfileSuggestedThemeInfo(); |
| } |
| |
| private setMinimumSize_() { |
| this.style.setProperty( |
| '--view-min-size', loadTimeData.getString('minimumPickerSize')); |
| } |
| |
| private handleCreateLocalProfileFinished_() { |
| // On profile creation, the picker window is closed. |
| // 'navigateTo' is meaningful if the picker is shown in a tab. |
| navigateTo(Routes.MAIN); |
| this.profileCreationInProgress = false; |
| } |
| } |
| |
| declare global { |
| interface HTMLElementTagNameMap { |
| 'profile-picker-app': ProfilePickerAppElement; |
| } |
| } |
| |
| customElements.define(ProfilePickerAppElement.is, ProfilePickerAppElement); |