model-optin.mjs (5653B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { html } from "chrome://global/content/vendor/lit.all.mjs"; 6 import { MozLitElement } from "chrome://global/content/lit-utils.mjs"; 7 8 /** 9 * Model Optin Component 10 * 11 * Displays a prompt allowing the user to opt in or out of a model download. 12 * Can also show a progress bar while downloading. 13 */ 14 class ModelOptin extends MozLitElement { 15 static properties = { 16 headingL10nId: { type: String, fluent: true }, 17 headingIcon: { type: String }, 18 iconAtEnd: { type: Boolean }, 19 messageL10nId: { type: String, fluent: true }, 20 optinButtonL10nId: { type: String, fluent: true }, 21 optoutButtonL10nId: { type: String, fluent: true }, 22 footerMessageL10nId: { type: String, fluent: true }, 23 cancelDownloadButtonL10nId: { type: String, fluent: true }, 24 isLoading: { type: Boolean, reflect: true }, 25 progressStatus: { type: Number }, // Expected to be a number between 0 and 100 26 isHidden: { type: Boolean }, 27 }; 28 29 static events = { 30 confirm: "MlModelOptinConfirm", 31 deny: "MlModelOptinDeny", 32 cancelDownload: "MlModelOptinCancelDownload", 33 messageLinkClick: "MlModelOptinMessageLinkClick", 34 footerLinkClick: "MlModelOptinFooterLinkClick", 35 }; 36 37 static eventBehaviors = { 38 bubbles: true, 39 composed: true, 40 }; 41 42 constructor() { 43 super(); 44 this.isLoading = false; 45 this.isHidden = false; 46 this.iconAtEnd = false; 47 this.optinButtonL10nId = "genai-model-optin-continue"; 48 this.optoutButtonL10nId = "genai-model-optin-optout"; 49 this.cancelDownloadButtonL10nId = "genai-model-optin-cancel"; 50 this.footerMessageL10nId = ""; 51 } 52 53 dispatch(event) { 54 this.dispatchEvent( 55 new CustomEvent(event, { bubbles: true, composed: true }) 56 ); 57 } 58 59 handleConfirmClick() { 60 this.dispatch(ModelOptin.events.confirm); 61 } 62 63 handleDenyClick() { 64 this.dispatch(ModelOptin.events.deny); 65 this.isHidden = true; 66 } 67 68 handleCancelDownloadClick() { 69 this.dispatch(ModelOptin.events.cancelDownload); 70 this.isLoading = false; 71 this.progressStatus = undefined; 72 } 73 74 handleMessageLinkClick(e) { 75 // ftl overrides the html, need to manually watch for event in parent. 76 if (e.target.id !== "optin-message-link") { 77 return; 78 } 79 this.dispatch(ModelOptin.events.messageLinkClick); 80 } 81 82 handleFooterLinkClick(e) { 83 // ftl overrides the html, need to manually watch for event in parent. 84 if (e.target.id !== "optin-footer-link") { 85 return; 86 } 87 this.dispatch(ModelOptin.events.footerLinkClick); 88 } 89 90 render() { 91 return html` 92 <link 93 rel="stylesheet" 94 href="chrome://browser/content/genai/content/model-optin.css" 95 /> 96 <section ?hidden=${this.isHidden} class="optin-wrapper"> 97 ${this.isLoading 98 ? html` 99 <div class="optin-progress-bar-wrapper"> 100 <progress 101 class="optin-progress-bar" 102 value=${this.progressStatus} 103 max="100" 104 ></progress> 105 </div> 106 ` 107 : ""} 108 109 <div class="optin-header-wrapper"> 110 <div class="optin-header"> 111 ${this.headingIcon 112 ? html`<img 113 src=${this.headingIcon} 114 alt=${this.headingL10nId} 115 class="optin-heading-icon ${this.iconAtEnd 116 ? "icon-at-end" 117 : ""}" 118 />` 119 : ""} 120 <h3 class="optin-heading" data-l10n-id=${this.headingL10nId}></h3> 121 </div> 122 </div> 123 124 <p 125 class="optin-message" 126 data-l10n-id=${this.messageL10nId} 127 @click=${this.handleMessageLinkClick} 128 > 129 <a id="optin-message-link" data-l10n-name="support" href="#"></a> 130 </p> 131 <slot></slot> 132 133 ${this.isLoading 134 ? html` 135 <div class="optin-actions"> 136 <moz-button 137 size="small" 138 data-l10n-id=${this.cancelDownloadButtonL10nId} 139 @click=${this.handleCancelDownloadClick} 140 > 141 </moz-button> 142 </div> 143 ` 144 : html` 145 <div class="optin-actions"> 146 <moz-button-group> 147 <moz-button 148 size="small" 149 id="optin-confirm-button" 150 type="primary" 151 data-l10n-id=${this.optinButtonL10nId} 152 @click=${this.handleConfirmClick} 153 > 154 </moz-button> 155 <moz-button 156 size="small" 157 id="optin-deny-button" 158 data-l10n-id=${this.optoutButtonL10nId} 159 @click=${this.handleDenyClick} 160 > 161 </moz-button> 162 </moz-button-group> 163 </div> 164 `} 165 ${!this.isLoading && this.footerMessageL10nId !== "" 166 ? html` 167 <p 168 class="optin-footer-message" 169 data-l10n-id=${this.footerMessageL10nId} 170 @click=${this.handleFooterLinkClick} 171 > 172 <a 173 id="optin-footer-link" 174 data-l10n-name="settings" 175 href="#" 176 ></a> 177 </p> 178 ` 179 : ""} 180 </section> 181 `; 182 } 183 } 184 customElements.define("model-optin", ModelOptin);