diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /browser/components/syncedtabs/SyncedTabsDeckComponent.js | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/components/syncedtabs/SyncedTabsDeckComponent.js')
-rw-r--r-- | browser/components/syncedtabs/SyncedTabsDeckComponent.js | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/browser/components/syncedtabs/SyncedTabsDeckComponent.js b/browser/components/syncedtabs/SyncedTabsDeckComponent.js new file mode 100644 index 0000000000..529418c0ee --- /dev/null +++ b/browser/components/syncedtabs/SyncedTabsDeckComponent.js @@ -0,0 +1,197 @@ +/* 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/. */ + +"use strict"; + +const { XPCOMUtils } = ChromeUtils.importESModule( + "resource://gre/modules/XPCOMUtils.sys.mjs" +); + +const { SyncedTabsDeckStore } = ChromeUtils.import( + "resource:///modules/syncedtabs/SyncedTabsDeckStore.js" +); +const { SyncedTabsDeckView } = ChromeUtils.import( + "resource:///modules/syncedtabs/SyncedTabsDeckView.js" +); +const { SyncedTabsListStore } = ChromeUtils.import( + "resource:///modules/syncedtabs/SyncedTabsListStore.js" +); +const { TabListComponent } = ChromeUtils.import( + "resource:///modules/syncedtabs/TabListComponent.js" +); +const { TabListView } = ChromeUtils.import( + "resource:///modules/syncedtabs/TabListView.js" +); +let { getChromeWindow } = ChromeUtils.import( + "resource:///modules/syncedtabs/util.js" +); +const { UIState } = ChromeUtils.import("resource://services-sync/UIState.jsm"); + +let log = ChromeUtils.importESModule( + "resource://gre/modules/Log.sys.mjs" +).Log.repository.getLogger("Sync.RemoteTabs"); + +var EXPORTED_SYMBOLS = ["SyncedTabsDeckComponent"]; + +/* SyncedTabsDeckComponent + * This component instantiates views and storage objects as well as defines + * behaviors that will be passed down to the views. This helps keep the views + * isolated and easier to test. + */ + +function SyncedTabsDeckComponent({ + window, + SyncedTabs, + deckStore, + listStore, + listComponent, + DeckView, + getChromeWindowMock, +}) { + this._window = window; + this._SyncedTabs = SyncedTabs; + this._DeckView = DeckView || SyncedTabsDeckView; + // used to stub during tests + this._getChromeWindow = getChromeWindowMock || getChromeWindow; + + this._deckStore = deckStore || new SyncedTabsDeckStore(); + this._syncedTabsListStore = listStore || new SyncedTabsListStore(SyncedTabs); + this.tabListComponent = + listComponent || + new TabListComponent({ + window: this._window, + store: this._syncedTabsListStore, + View: TabListView, + SyncedTabs, + clipboardHelper: Cc["@mozilla.org/widget/clipboardhelper;1"].getService( + Ci.nsIClipboardHelper + ), + getChromeWindow: this._getChromeWindow, + }); +} + +SyncedTabsDeckComponent.prototype = { + PANELS: { + TABS_CONTAINER: "tabs-container", + TABS_FETCHING: "tabs-fetching", + LOGIN_FAILED: "reauth", + NOT_AUTHED_INFO: "notAuthedInfo", + SYNC_DISABLED: "syncDisabled", + SINGLE_DEVICE_INFO: "singleDeviceInfo", + TABS_DISABLED: "tabs-disabled", + UNVERIFIED: "unverified", + }, + + get container() { + return this._deckView ? this._deckView.container : null; + }, + + init() { + Services.obs.addObserver(this, this._SyncedTabs.TOPIC_TABS_CHANGED); + Services.obs.addObserver(this, UIState.ON_UPDATE); + + // Add app locale change support for HTML sidebar + Services.obs.addObserver(this, "intl:app-locales-changed"); + this.updateDir(); + + // Go ahead and trigger sync + this._SyncedTabs.syncTabs().catch(Cu.reportError); + + this._deckView = new this._DeckView(this._window, this.tabListComponent, { + onConnectDeviceClick: event => this.openConnectDevice(event), + onSyncPrefClick: event => this.openSyncPrefs(event), + }); + + this._deckStore.on("change", state => this._deckView.render(state)); + // Trigger the initial rendering of the deck view + // Object.values only in nightly + this._deckStore.setPanels( + Object.keys(this.PANELS).map(k => this.PANELS[k]) + ); + // Set the initial panel to display + this.updatePanel(); + }, + + uninit() { + Services.obs.removeObserver(this, this._SyncedTabs.TOPIC_TABS_CHANGED); + Services.obs.removeObserver(this, UIState.ON_UPDATE); + Services.obs.removeObserver(this, "intl:app-locales-changed"); + this._deckView.destroy(); + }, + + observe(subject, topic, data) { + switch (topic) { + case this._SyncedTabs.TOPIC_TABS_CHANGED: + this._syncedTabsListStore.getData(); + this.updatePanel(); + break; + case UIState.ON_UPDATE: + this.updatePanel(); + break; + case "intl:app-locales-changed": + this.updateDir(); + break; + default: + break; + } + }, + + async getPanelStatus() { + try { + const state = UIState.get(); + const { status } = state; + if (status == UIState.STATUS_NOT_CONFIGURED) { + return this.PANELS.NOT_AUTHED_INFO; + } else if (status == UIState.STATUS_LOGIN_FAILED) { + return this.PANELS.LOGIN_FAILED; + } else if (status == UIState.STATUS_NOT_VERIFIED) { + return this.PANELS.UNVERIFIED; + } else if (!state.syncEnabled) { + return this.PANELS.SYNC_DISABLED; + } else if (!this._SyncedTabs.isConfiguredToSyncTabs) { + return this.PANELS.TABS_DISABLED; + } else if (!this._SyncedTabs.hasSyncedThisSession) { + return this.PANELS.TABS_FETCHING; + } + const clients = await this._SyncedTabs.getTabClients(); + if (clients.length) { + return this.PANELS.TABS_CONTAINER; + } + return this.PANELS.SINGLE_DEVICE_INFO; + } catch (err) { + Cu.reportError(err); + return this.PANELS.NOT_AUTHED_INFO; + } + }, + + updateDir() { + // If the HTML document doesn't exist, we can't update the window + if (!this._window.document) { + return; + } + + if (Services.locale.isAppLocaleRTL) { + this._window.document.body.dir = "rtl"; + } else { + this._window.document.body.dir = "ltr"; + } + }, + + updatePanel() { + // return promise for tests + return this.getPanelStatus() + .then(panelId => this._deckStore.selectPanel(panelId)) + .catch(Cu.reportError); + }, + + openSyncPrefs() { + this._getChromeWindow(this._window).gSync.openPrefs("tabs-sidebar"); + }, + + openConnectDevice() { + this._getChromeWindow(this._window).gSync.openConnectAnotherDevice( + "tabs-sidebar" + ); + }, +}; |