1
0
mirror of https://github.com/XFox111/TabsAsideExtension.git synced 2026-04-22 07:58:01 +03:00

feat: captureVisibleTab fallback for tab previews

This commit is contained in:
2025-05-04 15:22:33 +03:00
parent e59782973b
commit f89d036ab8
7 changed files with 49 additions and 7 deletions
+37
View File
@@ -48,6 +48,7 @@ export default defineBackground(() =>
graphicsCache[tab.url] = { graphicsCache[tab.url] = {
preview: graphicsCache[tab.url]?.preview, preview: graphicsCache[tab.url]?.preview,
capture: graphicsCache[tab.url]?.capture,
icon: tab.favIconUrl ?? graphicsCache[tab.url]?.icon icon: tab.favIconUrl ?? graphicsCache[tab.url]?.icon
}; };
}); });
@@ -61,10 +62,46 @@ export default defineBackground(() =>
{ {
graphicsCache[data.url] = { graphicsCache[data.url] = {
preview: data.thumbnail, preview: data.thumbnail,
capture: graphicsCache[data.url]?.capture,
icon: graphicsCache[data.url]?.icon icon: graphicsCache[data.url]?.icon
}; };
}); });
setupTabCaputre();
async function setupTabCaputre(): Promise<void>
{
const tryCaptureTab = async (tab: Tabs.Tab): Promise<void> =>
{
if (!tab.url || tab.status !== "complete" || !tab.active)
return;
try
{
// We use chrome here because polyfill throws uncatchable errors for some reason
// It's a compatible API anyway
const capture: string = await chrome.tabs.captureVisibleTab(tab.windowId!, { format: "jpeg", quality: 1 });
if (capture)
{
graphicsCache[tab.url] = {
capture,
preview: graphicsCache[tab.url]?.preview,
icon: graphicsCache[tab.url]?.icon
};
logger("Captured tab", tab.url);
}
}
catch (ex) { logger(ex); }
};
setInterval(() =>
{
browser.tabs.query({ active: true })
.then(tabs => tabs.forEach(tab => tryCaptureTab(tab)));
}, 1000);
}
setupContextMenu(); setupContextMenu();
async function setupContextMenu(): Promise<void> async function setupContextMenu(): Promise<void>
{ {
+1 -1
View File
@@ -69,7 +69,7 @@ export default function TabView({ tab, indices, dragOverlay }: TabViewProps): Re
> >
{ tilesView && { tilesView &&
<img <img
src={ graphics[tab.url]?.preview ?? pagePlaceholder } src={ graphics[tab.url]?.preview ?? graphics[tab.url]?.capture ?? pagePlaceholder }
onError={ e => e.currentTarget.src = pagePlaceholder } onError={ e => e.currentTarget.src = pagePlaceholder }
className={ cls.image } draggable={ false } /> className={ cls.image } draggable={ false } />
} }
+2 -1
View File
@@ -87,7 +87,8 @@ export default defineConfig([
"@stylistic/no-mixed-spaces-and-tabs": ["warn"], "@stylistic/no-mixed-spaces-and-tabs": ["warn"],
"@typescript-eslint/no-unused-vars": ["warn"], "@typescript-eslint/no-unused-vars": ["warn"],
"prefer-const": ["warn"], "prefer-const": ["warn"],
"@stylistic/padded-blocks": ["warn"] "@stylistic/padded-blocks": ["warn"],
"no-empty": ["off"]
} }
}, },
{ {
@@ -13,6 +13,7 @@ export default async function updateGraphics(
function getGraphics(url: string): GraphicsItem | null function getGraphics(url: string): GraphicsItem | null
{ {
const preview = tempGraphics[url]?.preview ?? localGraphics[url]?.preview; const preview = tempGraphics[url]?.preview ?? localGraphics[url]?.preview;
const capture = tempGraphics[url]?.capture ?? localGraphics[url]?.capture;
const icon = tempGraphics[url]?.icon ?? localGraphics[url]?.icon; const icon = tempGraphics[url]?.icon ?? localGraphics[url]?.icon;
const graphics: GraphicsItem = {}; const graphics: GraphicsItem = {};
@@ -21,6 +22,8 @@ export default async function updateGraphics(
graphics.preview = preview; graphics.preview = preview;
if (icon) if (icon)
graphics.icon = icon; graphics.icon = icon;
if (capture)
graphics.capture = capture;
return preview || icon ? graphics : null; return preview || icon ? graphics : null;
} }
@@ -13,12 +13,12 @@ export default function migrateCollections(legacyCollections: LegacyCollection[]
{ {
const title: string | undefined = legacyCollection.titles[index]; const title: string | undefined = legacyCollection.titles[index];
const icon: string | undefined = legacyCollection.icons?.[index]; const icon: string | undefined = legacyCollection.icons?.[index];
const preview: string | undefined = legacyCollection.thumbnails?.[index]; const capture: string | undefined = legacyCollection.thumbnails?.[index];
if (!graphics[url]) if (!graphics[url])
graphics[url] = { icon, preview }; graphics[url] = { icon, capture };
else else
graphics[url] = { icon: graphics[url].icon ?? icon, preview: graphics[url].preview ?? preview }; graphics[url] = { icon: graphics[url].icon ?? icon, capture: graphics[url].preview ?? capture };
return { return {
type: "tab", type: "tab",
+2 -2
View File
@@ -38,11 +38,11 @@ export default async function migrateStorage(): Promise<void>
for (const [key, record] of Object.entries(v2Graphics)) for (const [key, record] of Object.entries(v2Graphics))
{ {
if (!graphics[key]) if (!graphics[key])
graphics[key] = { icon: record.iconUrl, preview: record.pageCapture }; graphics[key] = { icon: record.iconUrl, capture: record.pageCapture };
else else
{ {
graphics[key].icon ??= record.iconUrl; graphics[key].icon ??= record.iconUrl;
graphics[key].preview ??= record.pageCapture; graphics[key].capture ??= record.pageCapture;
} }
} }
+1
View File
@@ -37,5 +37,6 @@ export type GraphicsStorage = Record<string, GraphicsItem>;
export type GraphicsItem = export type GraphicsItem =
{ {
preview?: string; preview?: string;
capture?: string;
icon?: string; icon?: string;
}; };