blob: 58d6be2d9f76d68f3a0373678b8c47c7faeb8ed4 [file] [log] [blame]
// 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);