diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 0a1c2bf2d1..25386222d4 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -1408,6 +1408,12 @@ "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" }, + "showInlineMenuIdentitiesLabel": { + "message": "Display identities as suggestions" + }, + "showInlineMenuCardsLabel": { + "message": "Display cards as suggestions" + }, "showInlineMenuOnIconSelectionLabel": { "message": "Display suggestions when icon is selected" }, diff --git a/apps/browser/src/autofill/background/abstractions/overlay.background.ts b/apps/browser/src/autofill/background/abstractions/overlay.background.ts index e91a58a84c..abe7d09701 100644 --- a/apps/browser/src/autofill/background/abstractions/overlay.background.ts +++ b/apps/browser/src/autofill/background/abstractions/overlay.background.ts @@ -188,6 +188,8 @@ export type OverlayBackgroundExtensionMessageHandlers = { updateIsFieldCurrentlyFilling: ({ message }: BackgroundMessageParam) => void; checkIsFieldCurrentlyFilling: () => boolean; getAutofillInlineMenuVisibility: () => void; + getInlineMenuCardsVisibility: () => void; + getInlineMenuIdentitiesVisibility: () => void; openAutofillInlineMenu: () => void; closeAutofillInlineMenu: ({ message, sender }: BackgroundOnMessageHandlerParams) => void; checkAutofillInlineMenuFocused: ({ sender }: BackgroundSenderParam) => void; diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts index b45a4a2548..5b42a39ac1 100644 --- a/apps/browser/src/autofill/background/overlay.background.ts +++ b/apps/browser/src/autofill/background/overlay.background.ts @@ -132,6 +132,8 @@ export class OverlayBackground implements OverlayBackgroundInterface { updateIsFieldCurrentlyFilling: ({ message }) => this.updateIsFieldCurrentlyFilling(message), checkIsFieldCurrentlyFilling: () => this.checkIsFieldCurrentlyFilling(), getAutofillInlineMenuVisibility: () => this.getInlineMenuVisibility(), + getInlineMenuCardsVisibility: () => this.getInlineMenuCardsVisibility(), + getInlineMenuIdentitiesVisibility: () => this.getInlineMenuIdentitiesVisibility(), openAutofillInlineMenu: () => this.openInlineMenu(false), closeAutofillInlineMenu: ({ message, sender }) => this.closeInlineMenu(sender, message), checkAutofillInlineMenuFocused: ({ sender }) => this.checkInlineMenuFocused(sender), @@ -1483,6 +1485,20 @@ export class OverlayBackground implements OverlayBackgroundInterface { return await firstValueFrom(this.autofillSettingsService.inlineMenuVisibility$); } + /** + * Gets the inline menu's visibility setting for Cards from the settings service. + */ + private async getInlineMenuCardsVisibility(): Promise { + return await firstValueFrom(this.autofillSettingsService.showInlineMenuCards$); + } + + /** + * Gets the inline menu's visibility setting for Identities from the settings service. + */ + private async getInlineMenuIdentitiesVisibility(): Promise { + return await firstValueFrom(this.autofillSettingsService.showInlineMenuIdentities$); + } + /** * Gets the user's authentication status from the auth service. */ diff --git a/apps/browser/src/autofill/content/abstractions/autofill-init.ts b/apps/browser/src/autofill/content/abstractions/autofill-init.ts index ba815a0f29..529607949d 100644 --- a/apps/browser/src/autofill/content/abstractions/autofill-init.ts +++ b/apps/browser/src/autofill/content/abstractions/autofill-init.ts @@ -1,4 +1,5 @@ import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { InlineMenuVisibilitySetting } from "@bitwarden/common/autofill/types"; import { CipherType } from "@bitwarden/common/vault/enums"; import { AutofillOverlayElementType } from "../../enums/autofill-overlay.enum"; @@ -23,7 +24,7 @@ export type AutofillExtensionMessage = { data?: { direction?: "previous" | "next" | "current"; forceCloseInlineMenu?: boolean; - inlineMenuVisibility?: number; + newSettingValue?: InlineMenuVisibilitySetting; }; }; diff --git a/apps/browser/src/autofill/popup/settings/autofill-v1.component.html b/apps/browser/src/autofill/popup/settings/autofill-v1.component.html index 9c7047c4cb..ec8aeac37e 100644 --- a/apps/browser/src/autofill/popup/settings/autofill-v1.component.html +++ b/apps/browser/src/autofill/popup/settings/autofill-v1.component.html @@ -46,6 +46,32 @@ +
+
+
+ + +
+
+ + +
+
+
diff --git a/apps/browser/src/autofill/popup/settings/autofill-v1.component.ts b/apps/browser/src/autofill/popup/settings/autofill-v1.component.ts index 8adee86bcf..7879e4b343 100644 --- a/apps/browser/src/autofill/popup/settings/autofill-v1.component.ts +++ b/apps/browser/src/autofill/popup/settings/autofill-v1.component.ts @@ -8,10 +8,12 @@ import { InlineMenuVisibilitySetting, ClearClipboardDelaySetting, } from "@bitwarden/common/autofill/types"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { UriMatchStrategy, UriMatchStrategySetting, } from "@bitwarden/common/models/domain/domain-service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -20,7 +22,6 @@ import { DialogService } from "@bitwarden/components"; import { BrowserApi } from "../../../platform/browser/browser-api"; import { enableAccountSwitching } from "../../../platform/flags"; -import { AutofillService } from "../../services/abstractions/autofill.service"; @Component({ selector: "app-autofill-v1", @@ -32,6 +33,10 @@ export class AutofillV1Component implements OnInit { protected autoFillOverlayVisibility: InlineMenuVisibilitySetting; protected autoFillOverlayVisibilityOptions: any[]; protected disablePasswordManagerLink: string; + protected inlineMenuPositioningImprovementsEnabled: boolean = false; + protected showInlineMenuIdentities: boolean = true; + protected showInlineMenuCards: boolean = true; + inlineMenuIsEnabled: boolean = false; enableAutoFillOnPageLoad = false; autoFillOnPageLoadDefault = false; autoFillOnPageLoadOptions: any[]; @@ -50,7 +55,7 @@ export class AutofillV1Component implements OnInit { private i18nService: I18nService, private platformUtilsService: PlatformUtilsService, private domainSettingsService: DomainSettingsService, - private autofillService: AutofillService, + private configService: ConfigService, private dialogService: DialogService, private autofillSettingsService: AutofillSettingsServiceAbstraction, private messagingService: MessagingService, @@ -109,6 +114,20 @@ export class AutofillV1Component implements OnInit { this.autofillSettingsService.inlineMenuVisibility$, ); + this.inlineMenuPositioningImprovementsEnabled = await this.configService.getFeatureFlag( + FeatureFlag.InlineMenuPositioningImprovements, + ); + + this.inlineMenuIsEnabled = this.isInlineMenuEnabled(); + + this.showInlineMenuIdentities = + this.inlineMenuPositioningImprovementsEnabled && + (await firstValueFrom(this.autofillSettingsService.showInlineMenuIdentities$)); + + this.showInlineMenuCards = + this.inlineMenuPositioningImprovementsEnabled && + (await firstValueFrom(this.autofillSettingsService.showInlineMenuCards$)); + this.enableAutoFillOnPageLoad = await firstValueFrom( this.autofillSettingsService.autofillOnPageLoad$, ); @@ -140,9 +159,18 @@ export class AutofillV1Component implements OnInit { ); } + isInlineMenuEnabled() { + return ( + this.autoFillOverlayVisibility === AutofillOverlayVisibility.OnFieldFocus || + this.autoFillOverlayVisibility === AutofillOverlayVisibility.OnButtonClick + ); + } + async updateAutoFillOverlayVisibility() { await this.autofillSettingsService.setInlineMenuVisibility(this.autoFillOverlayVisibility); await this.requestPrivacyPermission(); + + this.inlineMenuIsEnabled = this.isInlineMenuEnabled(); } async updateAutoFillOnPageLoad() { @@ -298,4 +326,12 @@ export class AutofillV1Component implements OnInit { async updateShowIdentitiesCurrentTab() { await this.vaultSettingsService.setShowIdentitiesCurrentTab(this.showIdentitiesCurrentTab); } + + async updateShowInlineMenuCards() { + await this.autofillSettingsService.setShowInlineMenuCards(this.showInlineMenuCards); + } + + async updateShowInlineMenuIdentities() { + await this.autofillSettingsService.setShowInlineMenuIdentities(this.showInlineMenuIdentities); + } } diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.html b/apps/browser/src/autofill/popup/settings/autofill.component.html index 99ac51bcdb..b9e4ad222d 100644 --- a/apps/browser/src/autofill/popup/settings/autofill.component.html +++ b/apps/browser/src/autofill/popup/settings/autofill.component.html @@ -27,7 +27,37 @@ {{ "showInlineMenuOnFormFieldsDescAlt" | i18n }} - + + + + {{ "showInlineMenuIdentitiesLabel" | i18n }} + + + + + + {{ "showInlineMenuCardsLabel" | i18n }} + + + { it("updates the inlineMenuVisibility property", () => { sendMockExtensionMessage({ command: "updateAutofillInlineMenuVisibility", - data: { inlineMenuVisibility: AutofillOverlayVisibility.OnButtonClick }, + data: { newSettingValue: AutofillOverlayVisibility.OnButtonClick }, }); expect(autofillOverlayContentService["inlineMenuVisibility"]).toEqual( diff --git a/apps/browser/src/autofill/services/autofill-overlay-content.service.ts b/apps/browser/src/autofill/services/autofill-overlay-content.service.ts index 2e85fa2281..66b603188e 100644 --- a/apps/browser/src/autofill/services/autofill-overlay-content.service.ts +++ b/apps/browser/src/autofill/services/autofill-overlay-content.service.ts @@ -9,6 +9,7 @@ import { AUTOFILL_OVERLAY_HANDLE_REPOSITION, AUTOFILL_TRIGGER_FORM_FIELD_SUBMIT, } from "@bitwarden/common/autofill/constants"; +import { InlineMenuVisibilitySetting } from "@bitwarden/common/autofill/types"; import { CipherType } from "@bitwarden/common/vault/enums"; import { @@ -51,7 +52,9 @@ import { AutoFillConstants } from "./autofill-constants"; export class AutofillOverlayContentService implements AutofillOverlayContentServiceInterface { pageDetailsUpdateRequired = false; - inlineMenuVisibility: number; + inlineMenuVisibility: InlineMenuVisibilitySetting; + private showInlineMenuIdentities: boolean; + private showInlineMenuCards: boolean; private readonly findTabs = tabbable; private readonly sendExtensionMessage = sendExtensionMessage; private formFieldElements: Map, AutofillField> = new Map(); @@ -183,6 +186,18 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ autofillFieldData: AutofillField, pageDetails: AutofillPageDetails, ) { + if (!this.inlineMenuVisibility) { + await this.getInlineMenuVisibility(); + } + + if (this.showInlineMenuCards == null) { + await this.getInlineMenuCardsVisibility(); + } + + if (this.showInlineMenuIdentities == null) { + await this.getInlineMenuIdentitiesVisibility(); + } + if ( this.formFieldElements.has(formFieldElement) || this.isIgnoredField(autofillFieldData, pageDetails) @@ -1019,10 +1034,16 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ const { width, height, top, left } = await this.getMostRecentlyFocusedFieldRects(formFieldElement); const autofillFieldData = this.formFieldElements.get(formFieldElement); + let accountCreationFieldType = null; + if ( + // user setting allows display of identities in inline menu + this.showInlineMenuIdentities && + // `showInlineMenuAccountCreation` has been set or field is filled by Login cipher (autofillFieldData?.showInlineMenuAccountCreation || autofillFieldData?.filledByCipherType === CipherType.Login) && + // field is a username field, which is relevant to both Identity and Login ciphers this.inlineMenuFieldQualificationService.isUsernameField(autofillFieldData) ) { accountCreationFieldType = this.inlineMenuFieldQualificationService.isEmailField( @@ -1125,6 +1146,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ } if ( + this.showInlineMenuCards && this.inlineMenuFieldQualificationService.isFieldForCreditCardForm( autofillFieldData, pageDetails, @@ -1135,6 +1157,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ } if ( + this.showInlineMenuIdentities && this.inlineMenuFieldQualificationService.isFieldForAccountCreationForm( autofillFieldData, pageDetails, @@ -1146,6 +1169,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ } if ( + this.showInlineMenuIdentities && this.inlineMenuFieldQualificationService.isFieldForIdentityForm( autofillFieldData, pageDetails, @@ -1244,6 +1268,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ autofillFieldData.readonly = getAttributeBoolean(formFieldElement, "disabled"); autofillFieldData.disabled = getAttributeBoolean(formFieldElement, "disabled"); autofillFieldData.viewable = true; + void this.setupOverlayListenersOnQualifiedField(formFieldElement, autofillFieldData); } @@ -1266,10 +1291,6 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ await this.updateMostRecentlyFocusedField(formFieldElement); } - if (!this.inlineMenuVisibility) { - await this.getInlineMenuVisibility(); - } - this.setupFormFieldElementEventListeners(formFieldElement); this.setupFormSubmissionEventListeners(formFieldElement, autofillFieldData); @@ -1291,6 +1312,30 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ this.inlineMenuVisibility = inlineMenuVisibility || AutofillOverlayVisibility.OnFieldFocus; } + /** + * Queries the background script for the autofill inline menu's Cards visibility setting. + * If the setting is not found, a default value of true will be used + * @private + */ + private async getInlineMenuCardsVisibility() { + const inlineMenuCardsVisibility = await this.sendExtensionMessage( + "getInlineMenuCardsVisibility", + ); + this.showInlineMenuCards = inlineMenuCardsVisibility ?? true; + } + + /** + * Queries the background script for the autofill inline menu's Identities visibility setting. + * If the setting is not found, a default value of true will be used + * @private + */ + private async getInlineMenuIdentitiesVisibility() { + const inlineMenuIdentitiesVisibility = await this.sendExtensionMessage( + "getInlineMenuIdentitiesVisibility", + ); + this.showInlineMenuIdentities = inlineMenuIdentitiesVisibility ?? true; + } + /** * Returns a value that indicates if we should hide the inline menu list due to a filled field. * @@ -1318,8 +1363,10 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ * @param data - The data object from the extension message. */ private updateInlineMenuVisibility({ data }: AutofillExtensionMessage) { - if (!isNaN(data?.inlineMenuVisibility)) { - this.inlineMenuVisibility = data.inlineMenuVisibility; + const newSettingValue = data?.newSettingValue; + + if (!isNaN(newSettingValue)) { + this.inlineMenuVisibility = newSettingValue; } } diff --git a/apps/browser/src/autofill/services/autofill.service.spec.ts b/apps/browser/src/autofill/services/autofill.service.spec.ts index 7bd08caaf3..3f33caccc4 100644 --- a/apps/browser/src/autofill/services/autofill.service.spec.ts +++ b/apps/browser/src/autofill/services/autofill.service.spec.ts @@ -75,6 +75,8 @@ describe("AutofillService", () => { let autofillService: AutofillService; const cipherService = mock(); let inlineMenuVisibilityMock$!: BehaviorSubject; + let showInlineMenuCardsMock$!: BehaviorSubject; + let showInlineMenuIdentitiesMock$!: BehaviorSubject; let autofillSettingsService: MockProxy; const mockUserId = Utils.newGuid() as UserId; const accountService: FakeAccountService = mockAccountServiceWith(mockUserId); @@ -98,8 +100,12 @@ describe("AutofillService", () => { beforeEach(() => { scriptInjectorService = new BrowserScriptInjectorService(platformUtilsService, logService); inlineMenuVisibilityMock$ = new BehaviorSubject(AutofillOverlayVisibility.OnFieldFocus); + showInlineMenuCardsMock$ = new BehaviorSubject(false); + showInlineMenuIdentitiesMock$ = new BehaviorSubject(false); autofillSettingsService = mock(); autofillSettingsService.inlineMenuVisibility$ = inlineMenuVisibilityMock$; + autofillSettingsService.showInlineMenuCards$ = showInlineMenuCardsMock$; + autofillSettingsService.showInlineMenuIdentities$ = showInlineMenuIdentitiesMock$; activeAccountStatusMock$ = new BehaviorSubject(AuthenticationStatus.Unlocked); authService = mock(); authService.activeAccountStatus$ = activeAccountStatusMock$; @@ -291,12 +297,12 @@ describe("AutofillService", () => { expect(BrowserApi.tabSendMessageData).toHaveBeenCalledWith( tab1, "updateAutofillInlineMenuVisibility", - { inlineMenuVisibility: AutofillOverlayVisibility.OnButtonClick }, + { newSettingValue: AutofillOverlayVisibility.OnButtonClick }, ); expect(BrowserApi.tabSendMessageData).toHaveBeenCalledWith( tab2, "updateAutofillInlineMenuVisibility", - { inlineMenuVisibility: AutofillOverlayVisibility.OnButtonClick }, + { newSettingValue: AutofillOverlayVisibility.OnButtonClick }, ); }); @@ -308,12 +314,12 @@ describe("AutofillService", () => { expect(BrowserApi.tabSendMessageData).toHaveBeenCalledWith( tab1, "updateAutofillInlineMenuVisibility", - { inlineMenuVisibility: AutofillOverlayVisibility.OnFieldFocus }, + { newSettingValue: AutofillOverlayVisibility.OnFieldFocus }, ); expect(BrowserApi.tabSendMessageData).toHaveBeenCalledWith( tab2, "updateAutofillInlineMenuVisibility", - { inlineMenuVisibility: AutofillOverlayVisibility.OnFieldFocus }, + { newSettingValue: AutofillOverlayVisibility.OnFieldFocus }, ); }); }); diff --git a/apps/browser/src/autofill/services/autofill.service.ts b/apps/browser/src/autofill/services/autofill.service.ts index ea68b80e84..0b25426728 100644 --- a/apps/browser/src/autofill/services/autofill.service.ts +++ b/apps/browser/src/autofill/services/autofill.service.ts @@ -130,10 +130,23 @@ export default class AutofillService implements AutofillServiceInterface { async loadAutofillScriptsOnInstall() { BrowserApi.addListener(chrome.runtime.onConnect, this.handleInjectedScriptPortConnection); void this.injectAutofillScriptsInAllTabs(); + this.autofillSettingsService.inlineMenuVisibility$ .pipe(startWith(undefined), pairwise()) .subscribe(([previousSetting, currentSetting]) => - this.handleInlineMenuVisibilityChange(previousSetting, currentSetting), + this.handleInlineMenuVisibilitySettingsChange(previousSetting, currentSetting), + ); + + this.autofillSettingsService.showInlineMenuCards$ + .pipe(startWith(undefined), pairwise()) + .subscribe(([previousSetting, currentSetting]) => + this.handleInlineMenuVisibilitySettingsChange(previousSetting, currentSetting), + ); + + this.autofillSettingsService.showInlineMenuIdentities$ + .pipe(startWith(undefined), pairwise()) + .subscribe(([previousSetting, currentSetting]) => + this.handleInlineMenuVisibilitySettingsChange(previousSetting, currentSetting), ); } @@ -3043,27 +3056,36 @@ export default class AutofillService implements AutofillServiceInterface { } /** - * Updates the autofill inline menu visibility setting in all active tabs - * when the InlineMenuVisibilitySetting observable is updated. + * Updates the autofill inline menu visibility settings in all active tabs + * when the inlineMenuVisibility, showInlineMenuCards, or showInlineMenuIdentities + * observables are updated. * - * @param previousSetting - The previous setting value - * @param currentSetting - The current setting value + * @param oldSettingValue - The previous setting value + * @param newSettingValue - The current setting value + * @param cipherType - The cipher type of the changed inline menu setting */ - private async handleInlineMenuVisibilityChange( - previousSetting: InlineMenuVisibilitySetting, - currentSetting: InlineMenuVisibilitySetting, + private async handleInlineMenuVisibilitySettingsChange( + oldSettingValue: InlineMenuVisibilitySetting | boolean, + newSettingValue: InlineMenuVisibilitySetting | boolean, ) { - if (previousSetting === undefined || previousSetting === currentSetting) { + if (oldSettingValue === undefined || oldSettingValue === newSettingValue) { return; } - const inlineMenuPreviouslyDisabled = previousSetting === AutofillOverlayVisibility.Off; - const inlineMenuCurrentlyDisabled = currentSetting === AutofillOverlayVisibility.Off; - if (!inlineMenuPreviouslyDisabled && !inlineMenuCurrentlyDisabled) { + const isInlineMenuVisibilitySubSetting = + typeof oldSettingValue === "boolean" || typeof newSettingValue === "boolean"; + const inlineMenuPreviouslyDisabled = oldSettingValue === AutofillOverlayVisibility.Off; + const inlineMenuCurrentlyDisabled = newSettingValue === AutofillOverlayVisibility.Off; + + if ( + !isInlineMenuVisibilitySubSetting && + !inlineMenuPreviouslyDisabled && + !inlineMenuCurrentlyDisabled + ) { const tabs = await BrowserApi.tabsQuery({}); tabs.forEach((tab) => BrowserApi.tabSendMessageData(tab, "updateAutofillInlineMenuVisibility", { - inlineMenuVisibility: currentSetting, + newSettingValue, }), ); return; diff --git a/libs/common/src/autofill/services/autofill-settings.service.ts b/libs/common/src/autofill/services/autofill-settings.service.ts index 123f69550c..09fdde8997 100644 --- a/libs/common/src/autofill/services/autofill-settings.service.ts +++ b/libs/common/src/autofill/services/autofill-settings.service.ts @@ -59,6 +59,24 @@ const INLINE_MENU_VISIBILITY = new KeyDefinition( }, ); +const SHOW_INLINE_MENU_IDENTITIES = new UserKeyDefinition( + AUTOFILL_SETTINGS_DISK, + "showInlineMenuIdentities", + { + deserializer: (value: boolean) => value ?? true, + clearOn: [], + }, +); + +const SHOW_INLINE_MENU_CARDS = new UserKeyDefinition( + AUTOFILL_SETTINGS_DISK, + "showInlineMenuCards", + { + deserializer: (value: boolean) => value ?? true, + clearOn: [], + }, +); + const ENABLE_CONTEXT_MENU = new KeyDefinition(AUTOFILL_SETTINGS_DISK, "enableContextMenu", { deserializer: (value: boolean) => value ?? true, }); @@ -86,6 +104,10 @@ export abstract class AutofillSettingsServiceAbstraction { setAutoCopyTotp: (newValue: boolean) => Promise; inlineMenuVisibility$: Observable; setInlineMenuVisibility: (newValue: InlineMenuVisibilitySetting) => Promise; + showInlineMenuIdentities$: Observable; + setShowInlineMenuIdentities: (newValue: boolean) => Promise; + showInlineMenuCards$: Observable; + setShowInlineMenuCards: (newValue: boolean) => Promise; enableContextMenu$: Observable; setEnableContextMenu: (newValue: boolean) => Promise; clearClipboardDelay$: Observable; @@ -113,6 +135,12 @@ export class AutofillSettingsService implements AutofillSettingsServiceAbstracti private inlineMenuVisibilityState: GlobalState; readonly inlineMenuVisibility$: Observable; + private showInlineMenuIdentitiesState: ActiveUserState; + readonly showInlineMenuIdentities$: Observable; + + private showInlineMenuCardsState: ActiveUserState; + readonly showInlineMenuCards$: Observable; + private enableContextMenuState: GlobalState; readonly enableContextMenu$: Observable; @@ -157,6 +185,14 @@ export class AutofillSettingsService implements AutofillSettingsServiceAbstracti map((x) => x ?? AutofillOverlayVisibility.Off), ); + this.showInlineMenuIdentitiesState = this.stateProvider.getActive(SHOW_INLINE_MENU_IDENTITIES); + this.showInlineMenuIdentities$ = this.showInlineMenuIdentitiesState.state$.pipe( + map((x) => x ?? true), + ); + + this.showInlineMenuCardsState = this.stateProvider.getActive(SHOW_INLINE_MENU_CARDS); + this.showInlineMenuCards$ = this.showInlineMenuCardsState.state$.pipe(map((x) => x ?? true)); + this.enableContextMenuState = this.stateProvider.getGlobal(ENABLE_CONTEXT_MENU); this.enableContextMenu$ = this.enableContextMenuState.state$.pipe(map((x) => x ?? true)); @@ -190,6 +226,14 @@ export class AutofillSettingsService implements AutofillSettingsServiceAbstracti await this.inlineMenuVisibilityState.update(() => newValue); } + async setShowInlineMenuIdentities(newValue: boolean): Promise { + await this.showInlineMenuIdentitiesState.update(() => newValue); + } + + async setShowInlineMenuCards(newValue: boolean): Promise { + await this.showInlineMenuCardsState.update(() => newValue); + } + async setEnableContextMenu(newValue: boolean): Promise { await this.enableContextMenuState.update(() => newValue); }