Bug 1946523 - STG - Step 1 UI migration r=fluent-reviewers,desktop-theme-reviewers,tabbrowser-reviewers,dao,bolsson
Adding additional UI elements and filling out state machine with actualy UI updates. Some functions are stubbed out while waiting on ML to have API up on central. These UI changes should have no change to current UI if pref is turned off. Differential Revision: https://phabricator.services.mozilla.com/D237277
This commit is contained in:
@@ -100,6 +100,7 @@
|
||||
<link rel="localization" href="browser/sidebar.ftl"/>
|
||||
<link rel="localization" href="browser/profiles.ftl"/>
|
||||
<link rel="localization" href="preview/onboarding.ftl"/>
|
||||
<link rel="localization" href="preview/smartTabGroups.ftl"/>
|
||||
<link rel="localization" href="preview/tabUnload.ftl"/>
|
||||
|
||||
<title data-l10n-id="browser-main-window-default-title"></title>
|
||||
|
||||
@@ -252,7 +252,7 @@ export class SmartTabGroupingManager {
|
||||
* This function will terminate a grouping or label generation in progress
|
||||
* It is currently not implemented.
|
||||
*/
|
||||
terminateProcesses() {
|
||||
terminateProcess() {
|
||||
// TODO - teminate AI processes, This method will be
|
||||
// called when tab grouping panel is closed.
|
||||
}
|
||||
@@ -382,13 +382,11 @@ export class SmartTabGroupingManager {
|
||||
) {
|
||||
this.embeddingEngine = await this._createMLEngine(this.config.embedding);
|
||||
}
|
||||
const result = [];
|
||||
for (let runArg of inputData.inputArgs) {
|
||||
const request = { args: [[runArg]], options: inputData.runOptions };
|
||||
let embeddingsPerTab = await this.embeddingEngine.run(request);
|
||||
result.push(Object.values(embeddingsPerTab.ort_tensor.cpuData));
|
||||
}
|
||||
return result;
|
||||
const request = {
|
||||
args: [inputData.inputArgs],
|
||||
options: inputData.runOptions,
|
||||
};
|
||||
return await this.embeddingEngine.run(request);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
this.tabContainer = document.getElementById("tabbrowser-tabs");
|
||||
this.tabGroupMenu = document.getElementById("tab-group-editor");
|
||||
this.tabbox = document.getElementById("tabbrowser-tabbox");
|
||||
this.tabGroupNameField = document.getElementById("tab-group-name");
|
||||
this.tabpanels = document.getElementById("tabbrowser-tabpanels");
|
||||
this.verticalPinnedTabsContainer = document.getElementById(
|
||||
"vertical-pinned-tabs-container"
|
||||
@@ -2948,6 +2949,13 @@
|
||||
return null;
|
||||
}
|
||||
|
||||
gBrowser.getGroupTitleForTabs(tabs).then(newLabel => {
|
||||
group.label = newLabel;
|
||||
if (this.tabGroupMenu.panel.state !== "closed") {
|
||||
this.tabGroupNameField.value = newLabel;
|
||||
}
|
||||
});
|
||||
|
||||
group.dispatchEvent(
|
||||
new CustomEvent("TabGroupCreate", {
|
||||
bubbles: true,
|
||||
|
||||
@@ -30,15 +30,8 @@
|
||||
"gray",
|
||||
"red",
|
||||
];
|
||||
static markup = `
|
||||
<panel
|
||||
type="arrow"
|
||||
class="panel tab-group-editor-panel"
|
||||
orient="vertical"
|
||||
role="dialog"
|
||||
ignorekeys="true"
|
||||
norolluponanchor="true">
|
||||
|
||||
static headerSection = /*html*/ `
|
||||
<html:div class="panel-header">
|
||||
<html:h1
|
||||
id="tab-group-editor-title-create"
|
||||
@@ -51,46 +44,9 @@
|
||||
data-l10n-id="tab-group-editor-title-edit">
|
||||
</html:h1>
|
||||
</html:div>
|
||||
`;
|
||||
|
||||
<toolbarseparator />
|
||||
|
||||
<html:div
|
||||
class="panel-body
|
||||
tab-group-editor-name">
|
||||
<html:label
|
||||
for="tab-group-name"
|
||||
data-l10n-id="tab-group-editor-name-label">
|
||||
</html:label>
|
||||
<html:input
|
||||
id="tab-group-name"
|
||||
type="text"
|
||||
name="tab-group-name"
|
||||
value=""
|
||||
data-l10n-id="tab-group-editor-name-field"
|
||||
/>
|
||||
</html:div>
|
||||
|
||||
<html:div
|
||||
class="panel-body tab-group-editor-swatches"
|
||||
role="radiogroup"
|
||||
data-l10n-id="tab-group-editor-color-selector"
|
||||
/>
|
||||
|
||||
<html:moz-button-group
|
||||
class="panel-body tab-group-create-actions tab-group-create-mode-only">
|
||||
<html:moz-button
|
||||
id="tab-group-editor-button-cancel"
|
||||
data-l10n-id="tab-group-editor-cancel">
|
||||
</html:moz-button>
|
||||
<html:moz-button
|
||||
type="primary"
|
||||
id="tab-group-editor-button-create"
|
||||
data-l10n-id="tab-group-editor-done">
|
||||
</html:moz-button>
|
||||
</html:moz-button-group>
|
||||
|
||||
<toolbarseparator class="tab-group-edit-mode-only" />
|
||||
|
||||
static editActions = /*html*/ `
|
||||
<html:div
|
||||
class="panel-body tab-group-edit-actions tab-group-edit-mode-only">
|
||||
<toolbarbutton
|
||||
@@ -129,6 +85,162 @@
|
||||
data-l10n-id="tab-group-editor-action-delete">
|
||||
</toolbarbutton>
|
||||
</html:div>
|
||||
`;
|
||||
|
||||
static suggestionsHeader = /*html*/ `
|
||||
<html:div id="tab-group-suggestions-heading" hidden="true">
|
||||
<html:div class="panel-header">
|
||||
<html:h1 data-l10n-id="tab-group-editor-title-suggest"></html:h1>
|
||||
</html:div>
|
||||
<toolbarseparator />
|
||||
</html:div>
|
||||
`;
|
||||
|
||||
static suggestionsSection = /*html*/ `
|
||||
<html:div id="tab-group-suggestions-container" hidden="true">
|
||||
|
||||
<html:div
|
||||
id="tab-group-suggestions-header"
|
||||
data-l10n-id="tab-group-editor-suggestions-header">
|
||||
</html:div>
|
||||
|
||||
<html:div id="tab-group-suggestions"></html:div>
|
||||
|
||||
<html:moz-button
|
||||
id="tab-group-select-toggle"
|
||||
data-l10n-id="tab-group-editor-deselect-suggestions"
|
||||
size="small"
|
||||
data-state="deselect">
|
||||
</html:moz-button>
|
||||
|
||||
<html:moz-button-group class="panel-body tab-group-create-actions">
|
||||
<html:moz-button
|
||||
id="tab-group-cancel-suggestions-button"
|
||||
data-l10n-id="tab-group-editor-cancel">
|
||||
</html:moz-button>
|
||||
<html:moz-button
|
||||
type="primary"
|
||||
id="tab-group-create-suggestions-button"
|
||||
data-l10n-id="tab-group-editor-done">
|
||||
</html:moz-button>
|
||||
</html:moz-button-group>
|
||||
|
||||
</html:div>
|
||||
`;
|
||||
|
||||
static suggestionsButton = /*html*/ `
|
||||
<html:moz-button
|
||||
hidden="true"
|
||||
id="tab-group-suggestion-button"
|
||||
type="icon ghost"
|
||||
data-l10n-id="tab-group-editor-smart-suggest-button-create">
|
||||
</html:moz-button>
|
||||
`;
|
||||
|
||||
static loadingSection = /*html*/ `
|
||||
<html:div id="tab-group-suggestions-loading" hidden="true">
|
||||
<html:div
|
||||
class="tab-group-suggestions-loading-header"
|
||||
data-l10n-id="tab-group-suggestions-loading-header">
|
||||
</html:div>
|
||||
<html:div class="tab-group-suggestions-loading-block"></html:div>
|
||||
<html:div class="tab-group-suggestions-loading-block"></html:div>
|
||||
<html:div class="tab-group-suggestions-loading-block"></html:div>
|
||||
</html:div>
|
||||
`;
|
||||
|
||||
static defaultActions = /*html*/ `
|
||||
<html:moz-button-group
|
||||
class="panel-body tab-group-create-actions tab-group-create-mode-only"
|
||||
id="tab-group-default-actions">
|
||||
<html:moz-button
|
||||
id="tab-group-editor-button-cancel"
|
||||
data-l10n-id="tab-group-editor-cancel">
|
||||
</html:moz-button>
|
||||
<html:moz-button
|
||||
type="primary"
|
||||
id="tab-group-editor-button-create"
|
||||
data-l10n-id="tab-group-editor-done">
|
||||
</html:moz-button>
|
||||
</html:moz-button-group>
|
||||
`;
|
||||
|
||||
static loadingActions = /*html*/ `
|
||||
<html:moz-button-group id="tab-group-suggestions-load-actions" hidden="true">
|
||||
<html:moz-button
|
||||
id="tab-group-suggestions-load-cancel"
|
||||
data-l10n-id="tab-group-editor-cancel">
|
||||
</html:moz-button>
|
||||
</html:moz-button-group>
|
||||
`;
|
||||
|
||||
static markup = /*html*/ `
|
||||
<panel
|
||||
type="arrow"
|
||||
class="panel tab-group-editor-panel"
|
||||
orient="vertical"
|
||||
role="dialog"
|
||||
ignorekeys="true"
|
||||
norolluponanchor="true">
|
||||
|
||||
<html:div id="tab-group-main">
|
||||
${this.headerSection}
|
||||
|
||||
<toolbarseparator />
|
||||
|
||||
<html:div
|
||||
class="panel-body
|
||||
tab-group-editor-name">
|
||||
<html:label
|
||||
for="tab-group-name"
|
||||
data-l10n-id="tab-group-editor-name-label">
|
||||
</html:label>
|
||||
<html:input
|
||||
id="tab-group-name"
|
||||
type="text"
|
||||
name="tab-group-name"
|
||||
value=""
|
||||
data-l10n-id="tab-group-editor-name-field"
|
||||
/>
|
||||
</html:div>
|
||||
|
||||
<html:div
|
||||
class="panel-body tab-group-editor-swatches"
|
||||
role="radiogroup"
|
||||
data-l10n-id="tab-group-editor-color-selector"
|
||||
/>
|
||||
|
||||
<toolbarseparator class="tab-group-edit-mode-only"/>
|
||||
|
||||
${this.editActions}
|
||||
|
||||
<toolbarseparator id="tab-group-suggestions-separator" hidden="true"/>
|
||||
|
||||
${this.suggestionsButton}
|
||||
|
||||
<html:p
|
||||
hidden="true"
|
||||
id="tab-group-suggestions-disclaimer"
|
||||
data-l10n-id="tab-group-suggestions-disclaimer">
|
||||
<a data-l10n-name="support" href="#"></a>
|
||||
</html:p>
|
||||
|
||||
<html:moz-button
|
||||
hidden="true"
|
||||
disabled="true"
|
||||
type="icon ghost"
|
||||
id="tab-group-suggestions-message"
|
||||
data-l10n-id="tab-group-editor-no-tabs-found">
|
||||
</html:moz-button>
|
||||
|
||||
${this.defaultActions}
|
||||
|
||||
</html:div>
|
||||
|
||||
${this.suggestionsHeader}
|
||||
${this.loadingSection}
|
||||
${this.loadingActions}
|
||||
${this.suggestionsSection}
|
||||
|
||||
</panel>
|
||||
`;
|
||||
@@ -158,6 +270,7 @@
|
||||
ERROR: 11,
|
||||
};
|
||||
|
||||
#tabGroupMain;
|
||||
#activeGroup;
|
||||
#cancelButton;
|
||||
#createButton;
|
||||
@@ -167,7 +280,25 @@
|
||||
#panel;
|
||||
#swatches;
|
||||
#swatchesContainer;
|
||||
#defaultActions;
|
||||
#suggestionState = MozTabbrowserTabGroupMenu.State.CREATE_STANDARD_INITIAL;
|
||||
#suggestionsHeading;
|
||||
#suggestionsHeader;
|
||||
#suggestionsContainer;
|
||||
#suggestions;
|
||||
#suggestionButton;
|
||||
#cancelSuggestionsButton;
|
||||
#createSuggestionsButton;
|
||||
#suggestionsLoading;
|
||||
#selectSuggestionsToggle;
|
||||
#suggestionsMessage;
|
||||
#suggestionsDisclaimer;
|
||||
#selectedSuggestedTabs = [];
|
||||
#suggestedTabs = [];
|
||||
#suggestionsLoadActions;
|
||||
#suggestionsLoadCancel;
|
||||
#suggestionsSeparator;
|
||||
#smartTabGroupingManager;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -195,6 +326,11 @@
|
||||
this.#swatchesContainer = this.querySelector(
|
||||
".tab-group-editor-swatches"
|
||||
);
|
||||
|
||||
this.#defaultActions = this.querySelector("#tab-group-default-actions");
|
||||
this.#tabGroupMain = this.querySelector("#tab-group-main");
|
||||
this.#initSuggestions();
|
||||
|
||||
this.#populateSwatches();
|
||||
|
||||
this.#cancelButton.addEventListener("click", () => {
|
||||
@@ -211,6 +347,22 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Check if the smart suggest button should be shown
|
||||
* If there are no ungrouped tabs, the button should be hidden
|
||||
*/
|
||||
this.canShowAIUserInterface = () => {
|
||||
const { tabs } = gBrowser;
|
||||
let show = false;
|
||||
tabs.forEach(tab => {
|
||||
if (tab.group === null) {
|
||||
show = true;
|
||||
}
|
||||
});
|
||||
|
||||
return show;
|
||||
};
|
||||
|
||||
document
|
||||
.getElementById("tabGroupEditor_addNewTabInGroup")
|
||||
.addEventListener("command", () => {
|
||||
@@ -247,6 +399,78 @@
|
||||
this.#swatchesContainer.addEventListener("change", this);
|
||||
}
|
||||
|
||||
#initSuggestions() {
|
||||
const AI_ICON = "chrome://global/skin/icons/highlights.svg";
|
||||
const { SmartTabGroupingManager } = ChromeUtils.importESModule(
|
||||
"resource:///modules/SmartTabGrouping.sys.mjs"
|
||||
);
|
||||
this.#smartTabGroupingManager = new SmartTabGroupingManager();
|
||||
|
||||
// Init Suggestion Button
|
||||
this.#suggestionButton = this.querySelector(
|
||||
"#tab-group-suggestion-button"
|
||||
);
|
||||
this.#suggestionButton.iconSrc = AI_ICON;
|
||||
this.#suggestionButton.addEventListener("click", () => {
|
||||
this.#handleSmartSuggest();
|
||||
});
|
||||
|
||||
// Init Suggestions UI
|
||||
this.#suggestionsHeading = this.querySelector(
|
||||
"#tab-group-suggestions-heading"
|
||||
);
|
||||
this.#suggestionsHeader = this.querySelector(
|
||||
"#tab-group-suggestions-header"
|
||||
);
|
||||
this.#suggestionsContainer = this.querySelector(
|
||||
"#tab-group-suggestions-container"
|
||||
);
|
||||
this.#suggestions = this.querySelector("#tab-group-suggestions");
|
||||
this.#selectSuggestionsToggle = this.querySelector(
|
||||
"#tab-group-select-toggle"
|
||||
);
|
||||
this.#selectSuggestionsToggle.addEventListener("click", () => {
|
||||
this.#handleSelectToggle();
|
||||
});
|
||||
this.#suggestionsMessage = this.querySelector(
|
||||
"#tab-group-suggestions-message"
|
||||
);
|
||||
this.#suggestionsMessage.iconSrc = AI_ICON;
|
||||
this.#suggestionsDisclaimer = this.querySelector(
|
||||
"#tab-group-suggestions-disclaimer"
|
||||
);
|
||||
this.#createSuggestionsButton = this.querySelector(
|
||||
"#tab-group-create-suggestions-button"
|
||||
);
|
||||
this.#createSuggestionsButton.addEventListener("click", () => {
|
||||
this.activeGroup.addTabs(this.#selectedSuggestedTabs);
|
||||
this.close(true);
|
||||
});
|
||||
this.#cancelSuggestionsButton = this.querySelector(
|
||||
"#tab-group-cancel-suggestions-button"
|
||||
);
|
||||
this.#cancelSuggestionsButton.addEventListener("click", () => {
|
||||
this.close();
|
||||
});
|
||||
this.#suggestionsSeparator = this.querySelector(
|
||||
"#tab-group-suggestions-separator"
|
||||
);
|
||||
|
||||
// Init Loading UI
|
||||
this.#suggestionsLoading = this.querySelector(
|
||||
"#tab-group-suggestions-loading"
|
||||
);
|
||||
this.#suggestionsLoadActions = this.querySelector(
|
||||
"#tab-group-suggestions-load-actions"
|
||||
);
|
||||
this.#suggestionsLoadCancel = this.querySelector(
|
||||
"#tab-group-suggestions-load-cancel"
|
||||
);
|
||||
this.#suggestionsLoadCancel.addEventListener("click", () => {
|
||||
this.#handleLoadSuggestionsCancel();
|
||||
});
|
||||
}
|
||||
|
||||
#populateSwatches() {
|
||||
this.#clearSwatches();
|
||||
for (let colorCode of MozTabbrowserTabGroupMenu.COLORS) {
|
||||
@@ -348,11 +572,10 @@
|
||||
openCreateModal(group) {
|
||||
this.activeGroup = group;
|
||||
this.createMode = true;
|
||||
this.suggestionState =
|
||||
MozTabbrowserTabGroupMenu.State.CREATE_STANDARD_INITIAL;
|
||||
if (lazy.smartTabGroupsEnabled) {
|
||||
//TODO: set appropriate state
|
||||
}
|
||||
this.suggestionState = lazy.smartTabGroupsEnabled
|
||||
? MozTabbrowserTabGroupMenu.State.CREATE_AI_INITIAL
|
||||
: MozTabbrowserTabGroupMenu.State.CREATE_STANDARD_INITIAL;
|
||||
|
||||
this.#panel.openPopup(group.firstChild, {
|
||||
position: this.#panelPosition,
|
||||
});
|
||||
@@ -361,11 +584,10 @@
|
||||
openEditModal(group) {
|
||||
this.activeGroup = group;
|
||||
this.createMode = false;
|
||||
this.suggestionState =
|
||||
MozTabbrowserTabGroupMenu.State.EDIT_STANDARD_INITIAL;
|
||||
if (lazy.smartTabGroupsEnabled) {
|
||||
//TODO: set appropriate state
|
||||
}
|
||||
this.suggestionState = lazy.smartTabGroupsEnabled
|
||||
? MozTabbrowserTabGroupMenu.State.EDIT_AI_INITIAL
|
||||
: MozTabbrowserTabGroupMenu.State.EDIT_STANDARD_INITIAL;
|
||||
|
||||
this.#panel.openPopup(group.firstChild, {
|
||||
position: this.#panelPosition,
|
||||
});
|
||||
@@ -419,6 +641,7 @@
|
||||
}
|
||||
}
|
||||
this.activeGroup = null;
|
||||
this.#smartTabGroupingManager.terminateProcess();
|
||||
}
|
||||
|
||||
on_keypress(event) {
|
||||
@@ -487,8 +710,192 @@
|
||||
this.#renderSuggestionState();
|
||||
}
|
||||
|
||||
#handleLoadSuggestionsCancel() {
|
||||
// TODO look into actually canceling any processes
|
||||
this.suggestionState = this.createMode
|
||||
? MozTabbrowserTabGroupMenu.State.CREATE_AI_INITIAL
|
||||
: MozTabbrowserTabGroupMenu.State.EDIT_AI_INITIAL;
|
||||
}
|
||||
|
||||
#handleSelectToggle() {
|
||||
const currentState =
|
||||
this.#selectSuggestionsToggle.getAttribute("data-state");
|
||||
const isDeselect = currentState === "deselect";
|
||||
|
||||
isDeselect ? this.#handleDeselectAll() : this.#handleSelectAll();
|
||||
const newState = isDeselect ? "select" : "deselect";
|
||||
this.#setSelectToggleState(newState);
|
||||
}
|
||||
|
||||
#handleSelectAll() {
|
||||
document
|
||||
.querySelectorAll(".tab-group-suggestion-checkbox")
|
||||
.forEach(checkbox => {
|
||||
checkbox.checked = true;
|
||||
});
|
||||
// Reset selected tabs to all suggested tabs
|
||||
this.#selectedSuggestedTabs = this.#suggestedTabs;
|
||||
}
|
||||
|
||||
#handleDeselectAll() {
|
||||
document
|
||||
.querySelectorAll(".tab-group-suggestion-checkbox")
|
||||
.forEach(checkbox => {
|
||||
checkbox.checked = false;
|
||||
});
|
||||
this.#selectedSuggestedTabs = [];
|
||||
}
|
||||
|
||||
async #handleSmartSuggest() {
|
||||
// Loading
|
||||
this.suggestionState = MozTabbrowserTabGroupMenu.State.LOADING;
|
||||
const tabs = await this.#smartTabGroupingManager.smartTabGroupingForGroup(
|
||||
this.activeGroup,
|
||||
gBrowser.tabs
|
||||
);
|
||||
|
||||
if (!tabs.length) {
|
||||
// No un-grouped tabs found
|
||||
this.suggestionState = this.#createMode
|
||||
? MozTabbrowserTabGroupMenu.State.CREATE_AI_WITH_NO_SUGGESTIONS
|
||||
: MozTabbrowserTabGroupMenu.State.EDIT_AI_WITH_NO_SUGGESTIONS;
|
||||
return;
|
||||
}
|
||||
|
||||
this.#selectedSuggestedTabs = tabs;
|
||||
this.#suggestedTabs = tabs;
|
||||
tabs.forEach((tab, index) => {
|
||||
this.#createRow(tab, index);
|
||||
});
|
||||
|
||||
this.suggestionState = this.#createMode
|
||||
? MozTabbrowserTabGroupMenu.State.CREATE_AI_WITH_SUGGESTIONS
|
||||
: MozTabbrowserTabGroupMenu.State.EDIT_AI_WITH_SUGGESTIONS;
|
||||
}
|
||||
|
||||
#createRow(tab, index) {
|
||||
// Create Row
|
||||
let row = document.createXULElement("toolbaritem");
|
||||
row.setAttribute("context", "tabContextMenu");
|
||||
row.setAttribute("id", `tab-bar-${index}`);
|
||||
|
||||
// Create Checkbox
|
||||
let checkbox = document.createXULElement("checkbox");
|
||||
checkbox.value = tab;
|
||||
checkbox.setAttribute("checked", true);
|
||||
checkbox.classList.add("tab-group-suggestion-checkbox");
|
||||
checkbox.addEventListener("CheckboxStateChange", e => {
|
||||
const isChecked = e.target.checked;
|
||||
const currentTab = e.target.value;
|
||||
|
||||
if (isChecked) {
|
||||
this.#selectedSuggestedTabs.push(currentTab);
|
||||
} else {
|
||||
this.#selectedSuggestedTabs = this.#selectedSuggestedTabs.filter(
|
||||
t => t != currentTab
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
row.appendChild(checkbox);
|
||||
|
||||
// Create Row Label
|
||||
let label = document.createXULElement("toolbarbutton");
|
||||
label.classList.add(
|
||||
"all-tabs-button",
|
||||
"subviewbutton",
|
||||
"subviewbutton-iconic",
|
||||
"tab-group-suggestion-label"
|
||||
);
|
||||
label.setAttribute("flex", "1");
|
||||
label.setAttribute("crop", "end");
|
||||
label.label = tab.label;
|
||||
label.image = tab.image;
|
||||
label.disabled = true;
|
||||
row.appendChild(label);
|
||||
|
||||
// Apply Row to Suggestions
|
||||
this.#suggestions.appendChild(row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the state of the select toggle button
|
||||
* @param {string} "select" | "deselect"
|
||||
*/
|
||||
#setSelectToggleState(state) {
|
||||
this.#selectSuggestionsToggle.setAttribute("data-state", state);
|
||||
this.#selectSuggestionsToggle.setAttribute(
|
||||
"data-l10n-id",
|
||||
`tab-group-editor-${state}-suggestions`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Element visibility utility function.
|
||||
* Toggles the `hidden` attribute of a DOM element.
|
||||
*
|
||||
* @param {HTMLElement|XULElement} element - The DOM element to show/hide.
|
||||
* @param {boolean} shouldShow - Whether the element should be shown (true) or hidden (false).
|
||||
*/
|
||||
#setElementVisibility(element, shouldShow) {
|
||||
element.hidden = !shouldShow;
|
||||
}
|
||||
|
||||
#showDefaultTabGroupActions(value) {
|
||||
this.#setElementVisibility(this.#defaultActions, value);
|
||||
}
|
||||
|
||||
#showSmartSuggestionsContainer(value) {
|
||||
this.#setElementVisibility(this.#suggestionsContainer, value);
|
||||
}
|
||||
|
||||
#showSuggestionButton(value) {
|
||||
this.#setElementVisibility(this.#suggestionButton, value);
|
||||
}
|
||||
|
||||
#showSuggestionMessage(value) {
|
||||
this.#setElementVisibility(this.#suggestionsMessage, value);
|
||||
}
|
||||
|
||||
#showSuggestionsDisclaimer(value) {
|
||||
this.#setElementVisibility(this.#suggestionsDisclaimer, value);
|
||||
}
|
||||
|
||||
#showSuggestionsSeparator(value) {
|
||||
this.#setElementVisibility(this.#suggestionsSeparator, value);
|
||||
}
|
||||
|
||||
#setLoadingState(value) {
|
||||
this.#setElementVisibility(this.#suggestionsLoadActions, value);
|
||||
this.#setElementVisibility(this.#suggestionsLoading, value);
|
||||
}
|
||||
|
||||
#setSuggestionsButtonCreateModeState(value) {
|
||||
const translationString = value
|
||||
? "tab-group-editor-smart-suggest-button-create"
|
||||
: "tab-group-editor-smart-suggest-button-edit";
|
||||
|
||||
this.#suggestionButton.setAttribute("data-l10n-id", translationString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique state setter for a "3rd" panel state while in Edit Mode
|
||||
* that just shows suggestions and hides the majority of the panel
|
||||
* @param {boolean} value
|
||||
*/
|
||||
#setEditModeSuggestionState(value) {
|
||||
this.#setElementVisibility(this.#suggestionsHeader, !value);
|
||||
this.#setElementVisibility(this.#tabGroupMain, !value);
|
||||
this.#setElementVisibility(this.#suggestionsHeading, value);
|
||||
}
|
||||
|
||||
#resetCommonUI() {
|
||||
// TODO - has commun UI reset logic
|
||||
this.#setLoadingState(false);
|
||||
this.#setEditModeSuggestionState(false);
|
||||
this.#suggestedTabs = [];
|
||||
this.#selectedSuggestedTabs = [];
|
||||
this.#suggestions.innerHTML = "";
|
||||
this.#showSmartSuggestionsContainer(false);
|
||||
}
|
||||
|
||||
#renderSuggestionState() {
|
||||
@@ -496,64 +903,111 @@
|
||||
// CREATE STANDARD INITIAL
|
||||
case MozTabbrowserTabGroupMenu.State.CREATE_STANDARD_INITIAL:
|
||||
this.#resetCommonUI();
|
||||
//TODO
|
||||
this.#showDefaultTabGroupActions(true);
|
||||
this.#showSuggestionButton(false);
|
||||
this.#showSuggestionMessage(false);
|
||||
this.#showSuggestionsDisclaimer(false);
|
||||
this.#showSuggestionsSeparator(false);
|
||||
break;
|
||||
|
||||
//CREATE AI INITIAL
|
||||
case MozTabbrowserTabGroupMenu.State.CREATE_AI_INITIAL:
|
||||
this.#resetCommonUI();
|
||||
//TODO
|
||||
this.#showSuggestionButton(true);
|
||||
this.#showDefaultTabGroupActions(true);
|
||||
this.#showSuggestionMessage(false);
|
||||
this.#setSelectToggleState("deselect");
|
||||
this.#showSuggestionsDisclaimer(true);
|
||||
this.#setSuggestionsButtonCreateModeState(true);
|
||||
this.#showSuggestionsSeparator(true);
|
||||
break;
|
||||
|
||||
// CREATE AI INITIAL SUGGESTIONS DISABLED
|
||||
case MozTabbrowserTabGroupMenu.State
|
||||
.CREATE_AI_INITIAL_SUGGESTIONS_DISABLED:
|
||||
this.#resetCommonUI();
|
||||
//TODO
|
||||
this.#showSuggestionButton(false);
|
||||
this.#showSuggestionsDisclaimer(false);
|
||||
this.#showSuggestionMessage(true);
|
||||
this.#showDefaultTabGroupActions(true);
|
||||
this.#showSuggestionsSeparator(true);
|
||||
break;
|
||||
|
||||
// CREATE AI WITH SUGGESTIONS
|
||||
case MozTabbrowserTabGroupMenu.State.CREATE_AI_WITH_SUGGESTIONS:
|
||||
//TODO
|
||||
this.#setLoadingState(false);
|
||||
this.#showSmartSuggestionsContainer(true);
|
||||
this.#showSuggestionButton(false);
|
||||
this.#showSuggestionsSeparator(true);
|
||||
this.$showDefaultTabGroupActions(false);
|
||||
break;
|
||||
|
||||
// CREATE AI WITH NO SUGGESTIONS
|
||||
case MozTabbrowserTabGroupMenu.State.CREATE_AI_WITH_NO_SUGGESTIONS:
|
||||
//TODO
|
||||
this.#setLoadingState(false);
|
||||
this.#showSuggestionMessage(true);
|
||||
this.#showDefaultTabGroupActions(true);
|
||||
this.#showSuggestionButton(false);
|
||||
this.#showSuggestionsSeparator(true);
|
||||
break;
|
||||
|
||||
// EDIT STANDARD INITIAL
|
||||
case MozTabbrowserTabGroupMenu.State.EDIT_STANDARD_INITIAL:
|
||||
this.#resetCommonUI();
|
||||
//TODO
|
||||
this.#showSuggestionButton(false);
|
||||
this.#showSuggestionMessage(false);
|
||||
this.#showDefaultTabGroupActions(false);
|
||||
this.#showSuggestionsDisclaimer(false);
|
||||
this.#showSuggestionsSeparator(false);
|
||||
break;
|
||||
|
||||
// EDIT AI INITIAL
|
||||
case MozTabbrowserTabGroupMenu.State.EDIT_AI_INITIAL:
|
||||
this.#resetCommonUI();
|
||||
//TODO
|
||||
this.#showSuggestionMessage(false);
|
||||
this.#setSelectToggleState("deselect");
|
||||
this.#showSuggestionButton(true);
|
||||
this.#showDefaultTabGroupActions(false);
|
||||
this.#showSuggestionsDisclaimer(false);
|
||||
this.#setSuggestionsButtonCreateModeState(false);
|
||||
this.#showSuggestionsSeparator(true);
|
||||
break;
|
||||
|
||||
// EDIT AI INITIAL SUGGESTIONS DISABLED
|
||||
case MozTabbrowserTabGroupMenu.State
|
||||
.EDIT_AI_INITIAL_SUGGESTIONS_DISABLED:
|
||||
this.#resetCommonUI();
|
||||
//TODO
|
||||
this.#showSuggestionMessage(true);
|
||||
this.#showSuggestionButton(false);
|
||||
this.#showDefaultTabGroupActions(false);
|
||||
this.#showSuggestionsDisclaimer(false);
|
||||
this.#showSuggestionsSeparator(true);
|
||||
break;
|
||||
|
||||
// EDIT AI WITH SUGGESTIONS
|
||||
case MozTabbrowserTabGroupMenu.State.EDIT_AI_WITH_SUGGESTIONS:
|
||||
//TODO
|
||||
this.#setLoadingState(false);
|
||||
this.#showSmartSuggestionsContainer(true);
|
||||
this.#setEditModeSuggestionState(true);
|
||||
this.#showSuggestionsSeparator(false);
|
||||
break;
|
||||
|
||||
// EDIT AI WITH NO SUGGESTIONS
|
||||
case MozTabbrowserTabGroupMenu.State.EDIT_AI_WITH_NO_SUGGESTIONS:
|
||||
//TODO
|
||||
this.#setLoadingState(false);
|
||||
this.#showSuggestionMessage(true);
|
||||
this.#showSuggestionsSeparator(true);
|
||||
break;
|
||||
|
||||
// LOADING
|
||||
case MozTabbrowserTabGroupMenu.State.LOADING:
|
||||
//TODO
|
||||
this.#showDefaultTabGroupActions(false);
|
||||
this.#showSuggestionButton(false);
|
||||
this.#showSuggestionsDisclaimer(false);
|
||||
this.#showSuggestionMessage(false);
|
||||
this.#setLoadingState(true);
|
||||
this.#showSuggestionsSeparator(true);
|
||||
this.#showDefaultTabGroupActions(false);
|
||||
break;
|
||||
|
||||
// ERROR
|
||||
|
||||
28
browser/locales-preview/smartTabGroups.ftl
Normal file
28
browser/locales-preview/smartTabGroups.ftl
Normal file
@@ -0,0 +1,28 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
tab-group-editor-title-suggest = Suggested tabs
|
||||
|
||||
tab-group-editor-smart-suggest-button-edit=
|
||||
.label = Suggest more tabs for group
|
||||
|
||||
# Button appearing during creation of new tab group.
|
||||
# Clicking will suggest tabs to group together in the tab group.
|
||||
tab-group-editor-smart-suggest-button-create=
|
||||
.label = Suggest tabs to group
|
||||
|
||||
tab-group-editor-suggestions-header = Suggested Tabs
|
||||
|
||||
tab-group-suggestions-loading-header = Suggested Tabs
|
||||
|
||||
tab-group-editor-deselect-suggestions =
|
||||
.label = Deselect all
|
||||
|
||||
tab-group-editor-select-suggestions =
|
||||
.label = Select all
|
||||
|
||||
tab-group-editor-no-tabs-found =
|
||||
.label = As you open similar tabs, { -brand-short-name } will suggest them for this group.
|
||||
|
||||
tab-group-suggestions-disclaimer = { -brand-short-name } uses AI to <a data-l10n-name="support">suggest tabs and group names.</a> Some suggestions may be inaccurate.
|
||||
@@ -17,6 +17,7 @@
|
||||
preview/credentialChooser.ftl (../../toolkit/components/credentialmanagement/credentialChooser.ftl)
|
||||
browser (%browser/**/*.ftl)
|
||||
preview/backupSettings.ftl (../locales-preview/backupSettings.ftl)
|
||||
preview/smartTabGroups.ftl (../locales-preview/smartTabGroups.ftl)
|
||||
preview/tabUnload.ftl (../locales-preview/tabUnload.ftl)
|
||||
|
||||
@AB_CD@.jar:
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
--tabstrip-inner-border: 1px solid color-mix(in srgb, currentColor 25%, transparent);
|
||||
--tabstrip-min-height: calc(var(--tab-min-height) + 2 * var(--tab-block-margin));
|
||||
--tab-min-height: 36px;
|
||||
--tab-group-suggestions-loading-animation-color-1: color-mix(in srgb, currentColor 5%, transparent);
|
||||
--tab-group-suggestions-loading-animation-color-2: color-mix(in srgb, currentColor 35%, transparent);
|
||||
&[uidensity=compact] {
|
||||
--tab-min-height: 29px;
|
||||
}
|
||||
@@ -1690,3 +1692,110 @@ toolbar:not(#TabsToolbar) #firefox-view-button {
|
||||
fill: transparent;
|
||||
stroke: light-dark(var(--tab-group-color), var(--tab-group-color-invert));
|
||||
}
|
||||
|
||||
.tab-group-suggestion-label {
|
||||
--text-color-disabled: var(--panel-color);
|
||||
--button-opacity-disabled: 1;
|
||||
}
|
||||
|
||||
#tab-group-suggestions-heading,
|
||||
#tab-group-main {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#tab-group-default-actions,
|
||||
#tab-group-suggestions-load-actions,
|
||||
#tab-group-suggestion-button,
|
||||
#tab-group-suggestions-message {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#tab-group-suggestions-heading:not([hidden]),
|
||||
#tab-group-main:not([hidden]),
|
||||
#tab-group-suggestions-separator:not([hidden]),
|
||||
#tab-group-suggestions-load-actions:not([hidden]),
|
||||
#tab-group-suggestions-loading:not([hidden]),
|
||||
#tab-group-default-actions:not([hidden]),
|
||||
#tab-group-suggestion-button:not([hidden]),
|
||||
#tab-group-suggestions-message:not([hidden]) {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#tab-group-suggestions-container:not([hidden]) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#tab-group-suggestions-disclaimer > a {
|
||||
display: inline;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#tab-group-suggestions-disclaimer:not([hidden]) {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
#tab-group-select-toggle {
|
||||
position: relative;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
#tab-group-suggestion-button {
|
||||
color: var(--color-accent-primary);
|
||||
--button-font-weight: var(--font-weight-normal);
|
||||
}
|
||||
|
||||
#tab-group-suggestions-loading {
|
||||
gap: 4px;
|
||||
flex-direction: column;
|
||||
margin: 0 8px 8px;
|
||||
}
|
||||
|
||||
#tab-group-suggestions-message {
|
||||
font-size: 0.85em;
|
||||
--button-font-weight: var(--font-weight-normal);
|
||||
}
|
||||
|
||||
.tab-group-suggestions-loading-header,
|
||||
#tab-group-suggestions-header {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
@keyframes tab-group-loading-block-animation {
|
||||
0% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
|
||||
50% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-group-suggestions-loading-block:nth-of-type(2) {
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
.tab-group-suggestions-loading-block:nth-of-type(3) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
.tab-group-suggestions-loading-block:nth-of-type(4) {
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
|
||||
.tab-group-suggestions-loading-block {
|
||||
animation: tab-group-loading-block-animation 3s infinite;
|
||||
background: linear-gradient(100deg,
|
||||
color-mix(in srgb, var(--tab-group-suggestions-loading-animation-color-2), transparent 60%) 30%,
|
||||
var(--tab-group-suggestions-loading-animation-color-1) 50%,
|
||||
color-mix(in srgb, var(--tab-group-suggestions-loading-animation-color-2), transparent 60%) 70%);
|
||||
background-size: 200% 100%;
|
||||
border-radius: var(--border-radius-small);
|
||||
height: 1.5em;
|
||||
margin: 0;
|
||||
margin-bottom: 0.5em;
|
||||
padding: 0;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user