Skip to content

Commit

Permalink
popup rendering via BrowserStateDao
Browse files Browse the repository at this point in the history
  • Loading branch information
metastable-void committed May 6, 2023
1 parent 966b56d commit da7f93a
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 91 deletions.
55 changes: 25 additions & 30 deletions src/pages/popup-v2/fragments/SiteDetailsFragmentBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,27 @@ import { SetMap } from "weeg-types";
import { CompatTab } from "weeg-tabs";
import { DisplayedContainer } from "weeg-containers";

import { AbstractFragmentBuilder } from "./AbstractFragmentBuilder";
import { BrowserStateDao } from "../../../lib/states/BrowserStateDao";
import { DisplayedContainerDao } from "../../../lib/states/DisplayedContainerDao";
import { TabGroupDirectorySnapshot } from "../../../lib/tabGroups/TabGroupDirectorySnapshot";
import { TabDao } from "../../../lib/states/TabDao";
import { IndexTabService } from "../../../lib/tabs/IndexTabService";

import { CtgFragmentElement } from "../../../components/ctg/ctg-fragment";
import { CtgTopBarElement } from "../../../components/ctg/ctg-top-bar";

import { AbstractFragmentBuilder } from "./AbstractFragmentBuilder";
import { PopupRendererService } from "../PopupRendererService";
import { BrowserStateSnapshot } from "../../../legacy-lib/tabs/BrowserStateSnapshot";
import { IndexTab } from "../../../legacy-lib/modules/IndexTab";

export class SiteDetailsFragmentBuilder extends AbstractFragmentBuilder {
protected static override readonly suppressBottomNavigation = true;

private readonly _popupRenderer = PopupRendererService.getInstance().popupRenderer;
private readonly _indexTabService = IndexTabService.getInstance();

private _domain = '(none)';
private _tabCount = 0;
private _firstPartyStateSnapshot: ReadonlyMap<string, ReadonlySet<CompatTab>> | null = null;
private _browserStateSnapshot: BrowserStateSnapshot | null = null;
private _isPrivate = false;
private _browserState: BrowserStateDao | null = null;
private _definedDisplayedContainers: DisplayedContainer[] = [];
private _tabs: CompatTab[] = [];

Expand Down Expand Up @@ -75,11 +80,8 @@ export class SiteDetailsFragmentBuilder extends AbstractFragmentBuilder {
topBarElement.headingText = `${this._domain || '(null)'} (${this._tabCount})`;
}

public render(browserStateSnapshot: BrowserStateSnapshot, isPrivate: boolean): void {
this._browserStateSnapshot = browserStateSnapshot;
const firstPartyStateSnapshot = browserStateSnapshot.getFirstPartyStateSnapshot(isPrivate);
this._firstPartyStateSnapshot = firstPartyStateSnapshot;
this._isPrivate = isPrivate;
public render(browserState: BrowserStateDao): void {
this._browserState = browserState;
this.setSite();
if (this.active) {
this.renderTopBarWithGlobalItems();
Expand All @@ -89,26 +91,23 @@ export class SiteDetailsFragmentBuilder extends AbstractFragmentBuilder {
}

private setSite(): void {
if (this._firstPartyStateSnapshot == null || this._browserStateSnapshot == null) {
if (this._browserState == null) {
return;
}
const tabGroupDirectorySnapshot = this._browserStateSnapshot.getTabGroupDirectorySnapshot();
const tabs = this._firstPartyStateSnapshot.get(this._domain) ?? new Set();
this._tabCount = tabs.size;
const browserState = this._browserState;
const tabGroupDirectorySnapshot = new TabGroupDirectorySnapshot(browserState.supergroups);
const displayedContainers = browserState.displayedContainers.map((dao) => DisplayedContainerDao.toDisplayedContainer(dao));
this._definedDisplayedContainers = [... displayedContainers].sort((a, b) => {
return tabGroupDirectorySnapshot.cookieStoreIdSortingCallback(a.cookieStore.id, b.cookieStore.id);
});
const tabIds = browserState.tabIdsBySite[this._domain] ?? [];
const tabs = this._indexTabService.filterOutIndexTabs(tabIds.map((tabId) => TabDao.toCompatTab(browserState.tabs[tabId] as TabDao)));
this._tabCount = tabs.length;
this._tabs = [... tabs];
if (this._isPrivate) {
this._definedDisplayedContainers = [... this._browserStateSnapshot.getDisplayedContainers()].sort((a, b) => {
return tabGroupDirectorySnapshot.cookieStoreIdSortingCallback(a.cookieStore.id, b.cookieStore.id);
}).filter((displayedContainer) => displayedContainer.cookieStore.isPrivate == true);
} else {
this._definedDisplayedContainers = [... this._browserStateSnapshot.getDisplayedContainers()].sort((a, b) => {
return tabGroupDirectorySnapshot.cookieStoreIdSortingCallback(a.cookieStore.id, b.cookieStore.id);
}).filter((displayedContainer) => displayedContainer.cookieStore.isPrivate == false);
}
}

public renderSite(): void {
if (this._firstPartyStateSnapshot == null) {
if (this._browserState == null) {
return;
}
const tabsByUserContextId = new SetMap<string, CompatTab>();
Expand All @@ -134,14 +133,10 @@ export class SiteDetailsFragmentBuilder extends AbstractFragmentBuilder {
if (!userContext) {
continue;
}
const userContextElement = this._popupRenderer.renderContainerForFirstPartyDomain(this._domain, userContext, this._isPrivate);
const userContextElement = this._popupRenderer.renderContainerForFirstPartyDomain(this._domain, userContext, userContext.cookieStore.isPrivate);
fragment.appendChild(userContextElement);
let tabCount = 0;
for (const tab of tabs) {
if (IndexTab.isIndexTabUrl(tab.url)) {
continue;
}

const tabElement = this._popupRenderer.renderTab(tab, userContext);
userContextElement.appendChild(tabElement);
tabCount++;
Expand Down
17 changes: 10 additions & 7 deletions src/pages/popup-v2/fragments/SitesFragmentBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,19 @@
import browser from "webextension-polyfill";
import { EventSink } from "weeg-events";
import { HostnameService } from "weeg-domains";
import { CompatTab } from "weeg-tabs";

import { TabQueryService } from "../../../lib/tabs/TabQueryService";
import { IndexTabService } from "../../../lib/tabs/IndexTabService";
import { CompatConsole } from "../../../lib/console/CompatConsole";
import { BrowserStateDao } from "../../../lib/states/BrowserStateDao";
import { TabDao } from "../../../lib/states/TabDao";

import { AbstractFragmentBuilder } from "./AbstractFragmentBuilder";
import { CtgFragmentElement } from "../../../components/ctg/ctg-fragment";
import { CtgTopBarElement } from "../../../components/ctg/ctg-top-bar";
import { MenulistSiteElement } from "../../../components/menulist-site";

import { AbstractFragmentBuilder } from "./AbstractFragmentBuilder";

const console = new CompatConsole(CompatConsole.tagFromFilename(__filename));

export class SitesFragmentBuilder extends AbstractFragmentBuilder {
Expand Down Expand Up @@ -68,17 +70,18 @@ export class SitesFragmentBuilder extends AbstractFragmentBuilder {
topBarElement.headingText = browser.i18n.getMessage('sitesN', this._siteCount.toFixed(0));
}

public render(firstPartyStateSnapshot: ReadonlyMap<string, ReadonlySet<CompatTab>>): void {
this._siteCount = firstPartyStateSnapshot.size;
public render(browserState: BrowserStateDao): void {
const keys = Object.keys(browserState.tabIdsBySite);
this._siteCount = keys.length;
if (this.active) {
this.renderTopBarWithGlobalItems();
}
const fragment = this.getFragment();
fragment.textContent = '';
const hostnames = this._hostnameService.sortDomains([... firstPartyStateSnapshot.keys()]);
const hostnames = this._hostnameService.sortDomains([... keys]);
for (const domain of hostnames) {
const tabSet = firstPartyStateSnapshot.get(domain) ?? new Set();
const tabs = this._indexTabService.filterOutIndexTabs([... tabSet]);
const tabIds = browserState.tabIdsBySite[domain] ?? [];
const tabs = this._indexTabService.filterOutIndexTabs(tabIds.map((tabId) => TabDao.toCompatTab(browserState.tabs[tabId] as TabDao)));
const lastAccessedTab = tabs.reduce((a, b) => a.lastAccessed > b.lastAccessed ? a : b);
const siteElement = new MenulistSiteElement();
siteElement.domain = domain || '(null)';
Expand Down
76 changes: 22 additions & 54 deletions src/pages/popup-v2/popup-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,10 @@

import browser from "webextension-polyfill";
import { MessagingService } from "weeg-utils";
import { ViewRefreshHandler } from "weeg-utils";
import { PromiseUtils } from "weeg-utils";

import { ConfigurationOption } from '../../lib/config/ConfigurationOption';
import { TabGroupDirectory } from "../../lib/tabGroups/TabGroupDirectory";
import { ExternalServiceProvider } from "../../lib/ExternalServiceProvider";
import { TagDirectory } from "../../lib/tabGroups/TagDirectory";
import { TagService } from "../../lib/tabGroups/TagService";
import { FpiService } from "../../lib/config/FpiService";
import { CompatConsole } from "../../lib/console/CompatConsole";
import { BrowserStateStore } from "../../lib/states/BrowserStateStore";
Expand All @@ -54,7 +51,6 @@ import { HelpFragmentBuilder } from "./fragments/HelpFragmentBuilder";
import { ContainerDetailsFragmentBuilder } from "./fragments/ContainerDetailsFragmentBuilder";
import { SiteDetailsFragmentBuilder } from "./fragments/SiteDetailsFragmentBuilder";

import { BrowserStateSnapshot } from "../../legacy-lib/tabs/BrowserStateSnapshot";

import { config, privacyConfig } from '../../config/config';

Expand All @@ -73,11 +69,8 @@ if (searchParams.get('popup') == '1') {
}

ExternalServiceProvider.getInstance();
const tabGroupDirectory = new TabGroupDirectory();
const tagDirectory = new TagDirectory();
const popupRenderer = PopupRendererService.getInstance().popupRenderer;
const messagingService = MessagingService.getInstance();
const tagService = TagService.getInstance();
const fpiService = FpiService.getInstance();

const extensionName = browser.runtime.getManifest().name;
Expand Down Expand Up @@ -143,48 +136,6 @@ topBarElement.onBackButtonClicked.addListener(() => {
// not used
globalMenuItems.defineDrawerMenuItems(drawerElement);

const renderer = new ViewRefreshHandler(async () => {
topBarElement.beginSpinnerTransaction('popup-rendering');
try {
const browserSnapshotStart = Date.now();
const browserStateSnapshot = await BrowserStateSnapshot.create();
const browserSnapshotEnd = Date.now();
const browserSnapshotTime = browserSnapshotEnd - browserSnapshotStart;
if (browserSnapshotTime > 500) {
console.info(`Browser snapshot took ${browserSnapshotTime}ms`);
}
const currentWindowSnapshot = browserStateSnapshot.getWindowStateSnapshot(browserStateSnapshot.currentWindowId);
sitesBuilder.render(browserStateSnapshot.getFirstPartyStateSnapshot(currentWindowSnapshot.isPrivate));

siteDetailsBuilder.render(browserStateSnapshot, currentWindowSnapshot.isPrivate);
} finally {
topBarElement.endSpinnerTransaction('popup-rendering');
// console.debug('rendering done');
}
});

const renderInBackground = renderer.renderInBackground.bind(renderer);

browser.tabs.onActivated.addListener(renderInBackground);
browser.tabs.onUpdated.addListener(renderInBackground);
browser.tabs.onCreated.addListener(renderInBackground);
browser.tabs.onRemoved.addListener(renderInBackground);
browser.tabs.onMoved.addListener(renderInBackground);
browser.tabs.onAttached.addListener(renderInBackground);
browser.tabs.onDetached.addListener(renderInBackground);
browser.tabs.onReplaced.addListener(renderInBackground); // this is not necessary in Firefox
browser.windows.onCreated.addListener(renderInBackground);
browser.windows.onRemoved.addListener(renderInBackground);
browser.contextualIdentities.onCreated.addListener(renderInBackground);
browser.contextualIdentities.onUpdated.addListener(renderInBackground);
browser.contextualIdentities.onRemoved.addListener(renderInBackground);

tabGroupDirectory.onChanged.addListener(renderInBackground);
tagDirectory.onChanged.addListener(renderInBackground);
tagService.onChanged.addListener(renderInBackground);

renderer.renderInBackground();

// Containers view

containersBuilder.onContainerSelected.addListener((cookieStoreId) => {
Expand Down Expand Up @@ -299,9 +250,26 @@ messagingService.addListener('tab-sorting-ended', () => {
});

const store = new BrowserStateStore();

let rendering = false;
const render = async () => {
if (rendering) return;
rendering = true;
try {
await PromiseUtils.sleep(200);
const value = store.value;
windowsBuilder.render(value);
containersBuilder.render(value);
containerDetailsBuilder.render(value);
sitesBuilder.render(value);
siteDetailsBuilder.render(value);
} finally {
rendering = false;
}
};

store.onChanged.addListener(() => {
windowsBuilder.render(store.value);
containersBuilder.render(store.value);
containerDetailsBuilder.render(store.value);
console.debug('BrowserStateStore changed:', store.value);
render().catch((e) => {
console.error('Rendering errored:', e);
});
});

0 comments on commit da7f93a

Please sign in to comment.