From 35ed8f1d5ebd23a2d37dc9925fcfbd71d2ea4ff6 Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Fri, 20 Oct 2023 12:28:36 +0200 Subject: [PATCH] [PM-4306] Extract file-popout-callout component used within Send on browser (#6564) * Extract callout in send-add-edit into separate component - Created new file-popout-callout.component - Register component within app.module - Replaced usage within send-add-edit.component * Override popup header style to fix bit-callout * [PM-4375] Reuse show file selector callout logic (#6606) * Added FilePopoutUtilsService with the logic of showing/hiding the popout callout and file selector button * Added documentation to FilePopoutUtilsService * Added documentation for class and constructor on FilePopoutUtilsService --------- Co-authored-by: Daniel James Smith Co-authored-by: aj-rosado <109146700+aj-rosado@users.noreply.github.com> --- apps/browser/src/popup/app.module.ts | 2 + .../src/popup/services/services.module.ts | 11 +++ .../file-popout-callout.component.html | 11 +++ .../file-popout-callout.component.ts | 37 +++++++++ .../popup/send/send-add-edit.component.html | 13 +--- .../popup/send/send-add-edit.component.ts | 44 ++--------- .../services/file-popout-utils.service.ts | 76 +++++++++++++++++++ 7 files changed, 145 insertions(+), 49 deletions(-) create mode 100644 apps/browser/src/tools/popup/components/file-popout-callout.component.html create mode 100644 apps/browser/src/tools/popup/components/file-popout-callout.component.ts create mode 100644 apps/browser/src/tools/popup/services/file-popout-utils.service.ts diff --git a/apps/browser/src/popup/app.module.ts b/apps/browser/src/popup/app.module.ts index d452e2d512b..2d67a470050 100644 --- a/apps/browser/src/popup/app.module.ts +++ b/apps/browser/src/popup/app.module.ts @@ -31,6 +31,7 @@ import { SsoComponent } from "../auth/popup/sso.component"; import { TwoFactorOptionsComponent } from "../auth/popup/two-factor-options.component"; import { TwoFactorComponent } from "../auth/popup/two-factor.component"; import { UpdateTempPasswordComponent } from "../auth/popup/update-temp-password.component"; +import { FilePopoutCalloutComponent } from "../tools/popup/components/file-popout-callout.component"; import { GeneratorComponent } from "../tools/popup/generator/generator.component"; import { PasswordGeneratorHistoryComponent } from "../tools/popup/generator/password-generator-history.component"; import { SendListComponent } from "../tools/popup/send/components/send-list.component"; @@ -98,6 +99,7 @@ import "../platform/popup/locales"; ScrollingModule, ServicesModule, DialogModule, + FilePopoutCalloutComponent, ], declarations: [ ActionButtonsComponent, diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index 06235809458..2bdeaffc3d9 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -104,6 +104,7 @@ import BrowserMessagingService from "../../platform/services/browser-messaging.s import { BrowserStateService } from "../../platform/services/browser-state.service"; import { BrowserSendService } from "../../services/browser-send.service"; import { BrowserSettingsService } from "../../services/browser-settings.service"; +import { FilePopoutUtilsService } from "../../tools/popup/services/file-popout-utils.service"; import { BrowserFolderService } from "../../vault/services/browser-folder.service"; import { VaultFilterService } from "../../vault/services/vault-filter.service"; @@ -520,6 +521,16 @@ function getBgService(service: keyof MainBackground) { LogService, ], }, + { + provide: FilePopoutUtilsService, + useFactory: ( + platformUtilsService: PlatformUtilsService, + popupUtilsService: PopupUtilsService + ) => { + return new FilePopoutUtilsService(platformUtilsService, popupUtilsService); + }, + deps: [PlatformUtilsService, PopupUtilsService], + }, ], }) export class ServicesModule {} diff --git a/apps/browser/src/tools/popup/components/file-popout-callout.component.html b/apps/browser/src/tools/popup/components/file-popout-callout.component.html new file mode 100644 index 00000000000..0df77dc4367 --- /dev/null +++ b/apps/browser/src/tools/popup/components/file-popout-callout.component.html @@ -0,0 +1,11 @@ + +
{{ "sendLinuxChromiumFileWarning" | i18n }}
+
{{ "sendFirefoxFileWarning" | i18n }}
+
{{ "sendSafariFileWarning" | i18n }}
+
diff --git a/apps/browser/src/tools/popup/components/file-popout-callout.component.ts b/apps/browser/src/tools/popup/components/file-popout-callout.component.ts new file mode 100644 index 00000000000..2231b2ab595 --- /dev/null +++ b/apps/browser/src/tools/popup/components/file-popout-callout.component.ts @@ -0,0 +1,37 @@ +import { CommonModule } from "@angular/common"; +import { Component, OnInit } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { CalloutModule } from "@bitwarden/components"; + +import { PopupUtilsService } from "../../../popup/services/popup-utils.service"; +import { FilePopoutUtilsService } from "../services/file-popout-utils.service"; + +@Component({ + selector: "tools-file-popout-callout", + templateUrl: "file-popout-callout.component.html", + standalone: true, + imports: [CommonModule, JslibModule, CalloutModule], +}) +export class FilePopoutCalloutComponent implements OnInit { + protected showFilePopoutMessage: boolean; + protected showFirefoxFileWarning: boolean; + protected showSafariFileWarning: boolean; + protected showChromiumFileWarning: boolean; + + constructor( + private popupUtilsService: PopupUtilsService, + private filePopoutUtilsService: FilePopoutUtilsService + ) {} + + ngOnInit() { + this.showFilePopoutMessage = this.filePopoutUtilsService.showFilePopoutMessage(window); + this.showFirefoxFileWarning = this.filePopoutUtilsService.showFirefoxFileWarning(window); + this.showSafariFileWarning = this.filePopoutUtilsService.showSafariFileWarning(window); + this.showChromiumFileWarning = this.filePopoutUtilsService.showChromiumFileWarning(window); + } + + popOutWindow() { + this.popupUtilsService.popOut(window); + } +} diff --git a/apps/browser/src/tools/popup/send/send-add-edit.component.html b/apps/browser/src/tools/popup/send/send-add-edit.component.html index 11dca222fca..38c8a8175bb 100644 --- a/apps/browser/src/tools/popup/send/send-add-edit.component.html +++ b/apps/browser/src/tools/popup/send/send-add-edit.component.html @@ -22,18 +22,7 @@

{{ "sendOptionsPolicyInEffect" | i18n }} - -
{{ "sendLinuxChromiumFileWarning" | i18n }}
-
{{ "sendFirefoxFileWarning" | i18n }}
-
{{ "sendSafariFileWarning" | i18n }}
-
+
diff --git a/apps/browser/src/tools/popup/send/send-add-edit.component.ts b/apps/browser/src/tools/popup/send/send-add-edit.component.ts index 2d90957de7f..ae81779b08a 100644 --- a/apps/browser/src/tools/popup/send/send-add-edit.component.ts +++ b/apps/browser/src/tools/popup/send/send-add-edit.component.ts @@ -17,6 +17,7 @@ import { DialogService } from "@bitwarden/components"; import { BrowserStateService } from "../../../platform/services/abstractions/browser-state.service"; import { PopupUtilsService } from "../../../popup/services/popup-utils.service"; +import { FilePopoutUtilsService } from "../services/file-popout-utils.service"; @Component({ selector: "app-send-add-edit", @@ -29,9 +30,7 @@ export class SendAddEditComponent extends BaseAddEditComponent { // File visibility isFirefox = false; inPopout = false; - inSidebar = false; - isLinux = false; - isUnsupportedMac = false; + showFileSelector = false; constructor( i18nService: I18nService, @@ -49,7 +48,8 @@ export class SendAddEditComponent extends BaseAddEditComponent { logService: LogService, sendApiService: SendApiService, dialogService: DialogService, - formBuilder: FormBuilder + formBuilder: FormBuilder, + private filePopoutUtilsService: FilePopoutUtilsService ) { super( i18nService, @@ -67,46 +67,16 @@ export class SendAddEditComponent extends BaseAddEditComponent { ); } - get showFileSelector(): boolean { - return !(this.editMode || this.showFilePopoutMessage); - } - - get showFilePopoutMessage(): boolean { - return ( - !this.editMode && - (this.showFirefoxFileWarning || this.showSafariFileWarning || this.showChromiumFileWarning) - ); - } - - get showFirefoxFileWarning(): boolean { - return this.isFirefox && !(this.inSidebar || this.inPopout); - } - - get showSafariFileWarning(): boolean { - return this.isSafari && !this.inPopout; - } - - // Only show this for Chromium based browsers in Linux and Mac > Big Sur - get showChromiumFileWarning(): boolean { - return ( - (this.isLinux || this.isUnsupportedMac) && - !this.isFirefox && - !(this.inSidebar || this.inPopout) - ); - } - popOutWindow() { this.popupUtilsService.popOut(window); } async ngOnInit() { // File visibility - this.isFirefox = this.platformUtilsService.isFirefox(); + this.showFileSelector = + !this.editMode && !this.filePopoutUtilsService.showFilePopoutMessage(window); this.inPopout = this.popupUtilsService.inPopout(window); - this.inSidebar = this.popupUtilsService.inSidebar(window); - this.isLinux = window?.navigator?.userAgent.indexOf("Linux") !== -1; - this.isUnsupportedMac = - this.platformUtilsService.isChrome() && window?.navigator?.appVersion.includes("Mac OS X 11"); + this.isFirefox = this.platformUtilsService.isFirefox(); // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe this.route.queryParams.pipe(first()).subscribe(async (params) => { diff --git a/apps/browser/src/tools/popup/services/file-popout-utils.service.ts b/apps/browser/src/tools/popup/services/file-popout-utils.service.ts new file mode 100644 index 00000000000..0dde2b1a3d2 --- /dev/null +++ b/apps/browser/src/tools/popup/services/file-popout-utils.service.ts @@ -0,0 +1,76 @@ +import { Injectable } from "@angular/core"; + +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; + +import { PopupUtilsService } from "../../../popup/services/popup-utils.service"; + +/** + * Service for determining whether to display file popout callout messages. + */ +@Injectable() +export class FilePopoutUtilsService { + /** + * Creates an instance of FilePopoutUtilsService. + */ + constructor( + private platformUtilsService: PlatformUtilsService, + private popupUtilsService: PopupUtilsService + ) {} + + /** + * Determines whether to show any file popout callout message in the current browser. + * @param win - The window context in which the check should be performed. + * @returns True if a file popout callout message should be displayed; otherwise, false. + */ + showFilePopoutMessage(win: Window): boolean { + return ( + this.showFirefoxFileWarning(win) || + this.showSafariFileWarning(win) || + this.showChromiumFileWarning(win) + ); + } + + /** + * Determines whether to show a file popout callout message for the Firefox browser + * @param win - The window context in which the check should be performed. + * @returns True if the extension is not in a sidebar or popout; otherwise, false. + */ + showFirefoxFileWarning(win: Window): boolean { + return ( + this.platformUtilsService.isFirefox() && + !(this.popupUtilsService.inSidebar(win) || this.popupUtilsService.inPopout(win)) + ); + } + + /** + * Determines whether to show a file popout message for the Safari browser + * @param win - The window context in which the check should be performed. + * @returns True if the extension is not in a popout; otherwise, false. + */ + showSafariFileWarning(win: Window): boolean { + return this.platformUtilsService.isSafari() && !this.popupUtilsService.inPopout(win); + } + + /** + * Determines whether to show a file popout callout message for Chromium-based browsers in Linux and Mac OS X Big Sur + * @param win - The window context in which the check should be performed. + * @returns True if the extension is not in a sidebar or popout; otherwise, false. + */ + showChromiumFileWarning(win: Window): boolean { + return ( + (this.isLinux(win) || this.isUnsupportedMac(win)) && + !this.platformUtilsService.isFirefox() && + !(this.popupUtilsService.inSidebar(win) || this.popupUtilsService.inPopout(win)) + ); + } + + private isLinux(win: Window): boolean { + return win?.navigator?.userAgent.indexOf("Linux") !== -1; + } + + private isUnsupportedMac(win: Window): boolean { + return ( + this.platformUtilsService.isChrome() && win?.navigator?.appVersion.includes("Mac OS X 11") + ); + } +}