mirror of
https://github.com/XFox111/TabsAsideExtension.git
synced 2026-04-22 07:58:01 +03:00
chore(deps): WXT 0.20.0 bump + lockfile regen (#199)
* chore(deps): wxt 0.20.0 bump #134 * chore: 3.2.1 manifest bump
This commit is contained in:
+1
-1
@@ -20,6 +20,6 @@ export const githubLinks =
|
||||
export const storeLink: string =
|
||||
import.meta.env.FIREFOX
|
||||
? "https://addons.mozilla.org/en-US/firefox/addon/ms-edge-tabs-aside/" :
|
||||
chrome.runtime.getManifest().update_url?.startsWith("https://edge.microsoft.com/") ?
|
||||
browser.runtime.getManifest().update_url?.startsWith("https://edge.microsoft.com/") ?
|
||||
"https://microsoftedge.microsoft.com/addons/detail/tabs-aside/kmnblllmalkiapkfknnlpobmjjdnlhnd" :
|
||||
"https://chromewebstore.google.com/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin";
|
||||
|
||||
+26
-24
@@ -1,26 +1,25 @@
|
||||
import { track, trackError } from "@/features/analytics";
|
||||
import { collectionCount, getCollections, saveCollections, thumbnailCaptureEnabled } from "@/features/collectionStorage";
|
||||
import { collectionStorage } from "@/features/collectionStorage/utils/collectionStorage";
|
||||
import getCollectionsFromCloud from "@/features/collectionStorage/utils/getCollectionsFromCloud";
|
||||
import getCollectionsFromLocal from "@/features/collectionStorage/utils/getCollectionsFromLocal";
|
||||
import { migrateStorage } from "@/features/migration";
|
||||
import { setSettingsReviewNeeded } from "@/features/settingsReview/utils";
|
||||
import { showWelcomeDialog } from "@/features/v3welcome/utils/showWelcomeDialog";
|
||||
import { SettingsValue } from "@/hooks/useSettings";
|
||||
import { CollectionItem, GraphicsStorage } from "@/models/CollectionModels";
|
||||
import { closeTabsAsync } from "@/utils/closeTabsAsync";
|
||||
import { createCollectionFromTabs } from "@/utils/createCollectionFromTabs";
|
||||
import getLogger from "@/utils/getLogger";
|
||||
import { getTabsToSaveAsync } from "@/utils/getTabsToSaveAsync";
|
||||
import { onMessage, sendMessage } from "@/utils/messaging";
|
||||
import sendNotification from "@/utils/sendNotification";
|
||||
import sendPartialSaveNotification from "@/utils/sendPartialSaveNotification";
|
||||
import { settings } from "@/utils/settings";
|
||||
import watchTabSelection from "@/utils/watchTabSelection";
|
||||
import { RemoveListenerCallback } from "@webext-core/messaging";
|
||||
import { Tabs, Windows } from "wxt/browser";
|
||||
import { Unwatch } from "wxt/storage";
|
||||
import { Unwatch } from "wxt/utils/storage";
|
||||
import { openCollection, openGroup } from "./sidepanel/utils/opener";
|
||||
import { closeTabsAsync } from "@/utils/closeTabsAsync";
|
||||
import { getTabsToSaveAsync } from "@/utils/getTabsToSaveAsync";
|
||||
import { createCollectionFromTabs } from "@/utils/createCollectionFromTabs";
|
||||
import getCollectionsFromLocal from "@/features/collectionStorage/utils/getCollectionsFromLocal";
|
||||
import { collectionStorage } from "@/features/collectionStorage/utils/collectionStorage";
|
||||
import getCollectionsFromCloud from "@/features/collectionStorage/utils/getCollectionsFromCloud";
|
||||
|
||||
export default defineBackground(() =>
|
||||
{
|
||||
@@ -99,7 +98,7 @@ export default defineBackground(() =>
|
||||
let unwatchAddThumbnail: RemoveListenerCallback | null = null;
|
||||
let captureInterval: NodeJS.Timeout | null = null;
|
||||
|
||||
const captureFavicon = (_: any, __: any, tab: Tabs.Tab): void =>
|
||||
const captureFavicon = (_: any, __: any, tab: Browser.tabs.Tab): void =>
|
||||
{
|
||||
if (!tab.url)
|
||||
return;
|
||||
@@ -111,7 +110,7 @@ export default defineBackground(() =>
|
||||
};
|
||||
};
|
||||
|
||||
const tryCaptureTab = async (tab: Tabs.Tab): Promise<void> =>
|
||||
const tryCaptureTab = async (tab: Browser.tabs.Tab): Promise<void> =>
|
||||
{
|
||||
if (!tab.url || tab.status !== "complete" || !tab.active)
|
||||
return;
|
||||
@@ -123,7 +122,7 @@ export default defineBackground(() =>
|
||||
{
|
||||
// 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 });
|
||||
const capture: string = await browser.tabs.captureVisibleTab(tab.windowId!, { format: "jpeg", quality: 1 });
|
||||
|
||||
if (capture)
|
||||
{
|
||||
@@ -287,6 +286,7 @@ export default defineBackground(() =>
|
||||
};
|
||||
|
||||
const toggleSidebarFirefox = async (): Promise<void> =>
|
||||
// @ts-expect-error Firefox-only API
|
||||
await browser.sidebarAction.toggle();
|
||||
|
||||
const updateButton = async (action: SettingsValue<"contextAction">): Promise<void> =>
|
||||
@@ -303,7 +303,7 @@ export default defineBackground(() =>
|
||||
unwatchActionTitle?.();
|
||||
|
||||
if (!import.meta.env.FIREFOX)
|
||||
await chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: false });
|
||||
await browser.sidePanel.setPanelBehavior({ openPanelOnActionClick: false });
|
||||
|
||||
// Setup new behavior
|
||||
if (action === "action")
|
||||
@@ -322,7 +322,7 @@ export default defineBackground(() =>
|
||||
if (import.meta.env.FIREFOX)
|
||||
browser.action.onClicked.addListener(toggleSidebarFirefox);
|
||||
else
|
||||
chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true });
|
||||
browser.sidePanel.setPanelBehavior({ openPanelOnActionClick: true });
|
||||
}
|
||||
else if (location !== "popup")
|
||||
browser.action.onClicked.addListener(openCollectionsInTab);
|
||||
@@ -341,17 +341,17 @@ export default defineBackground(() =>
|
||||
{
|
||||
logger("enforcePinnedTab");
|
||||
|
||||
const openWindows: Windows.Window[] = await browser.windows.getAll({ populate: true });
|
||||
const openWindows: Browser.windows.Window[] = await browser.windows.getAll({ populate: true });
|
||||
|
||||
for (const openWindow of openWindows)
|
||||
{
|
||||
if (openWindow.incognito || openWindow.type !== "normal")
|
||||
continue;
|
||||
|
||||
const activeTabs: Tabs.Tab[] = openWindow.tabs!.filter(tab =>
|
||||
const activeTabs: Browser.tabs.Tab[] = openWindow.tabs!.filter(tab =>
|
||||
tab.url === browser.runtime.getURL("/sidepanel.html"));
|
||||
|
||||
const targetTab: Tabs.Tab | undefined = activeTabs.find(tab => tab.pinned);
|
||||
const targetTab: Browser.tabs.Tab | undefined = activeTabs.find(tab => tab.pinned);
|
||||
|
||||
if (!targetTab)
|
||||
await browser.tabs.create({
|
||||
@@ -361,7 +361,7 @@ export default defineBackground(() =>
|
||||
pinned: true
|
||||
});
|
||||
|
||||
const tabsToClose: Tabs.Tab[] = activeTabs.filter(tab => tab.id !== targetTab?.id);
|
||||
const tabsToClose: Browser.tabs.Tab[] = activeTabs.filter(tab => tab.id !== targetTab?.id);
|
||||
|
||||
if (tabsToClose.length > 0)
|
||||
await browser.tabs.remove(tabsToClose.map(tab => tab.id!));
|
||||
@@ -373,7 +373,7 @@ export default defineBackground(() =>
|
||||
logger("updateView", viewLocation);
|
||||
|
||||
browser.tabs.onHighlighted.removeListener(enforcePinnedTab);
|
||||
const tabs: Tabs.Tab[] = await browser.tabs.query({
|
||||
const tabs: Browser.tabs.Tab[] = await browser.tabs.query({
|
||||
url: browser.runtime.getURL("/sidepanel.html")
|
||||
});
|
||||
await browser.tabs.remove(tabs.map(tab => tab.id!));
|
||||
@@ -383,11 +383,12 @@ export default defineBackground(() =>
|
||||
});
|
||||
|
||||
if (import.meta.env.FIREFOX)
|
||||
// @ts-expect-error Firefox-only API
|
||||
await browser.sidebarAction.setPanel({
|
||||
panel: viewLocation === "sidebar" ? browser.runtime.getURL("/sidepanel.html") : ""
|
||||
});
|
||||
else
|
||||
await chrome.sidePanel.setOptions({ enabled: viewLocation === "sidebar" });
|
||||
await browser.sidePanel.setOptions({ enabled: viewLocation === "sidebar" });
|
||||
|
||||
if (viewLocation === "pinned")
|
||||
{
|
||||
@@ -418,9 +419,10 @@ export default defineBackground(() =>
|
||||
if (view === "sidebar")
|
||||
{
|
||||
if (import.meta.env.FIREFOX)
|
||||
// @ts-expect-error Firefox-only API
|
||||
browser.sidebarAction.open();
|
||||
else
|
||||
chrome.sidePanel.open({ windowId });
|
||||
browser.sidePanel.open({ windowId });
|
||||
}
|
||||
else
|
||||
browser.action.openPopup();
|
||||
@@ -430,11 +432,11 @@ export default defineBackground(() =>
|
||||
{
|
||||
logger("openCollectionsInTab");
|
||||
|
||||
const currentWindow: Windows.Window = await browser.windows.getCurrent({ populate: true });
|
||||
const currentWindow: Browser.windows.Window = await browser.windows.getCurrent({ populate: true });
|
||||
|
||||
if (currentWindow.incognito)
|
||||
{
|
||||
let availableWindows: Windows.Window[] = await browser.windows.getAll({ populate: true });
|
||||
let availableWindows: Browser.windows.Window[] = await browser.windows.getAll({ populate: true });
|
||||
|
||||
availableWindows = availableWindows.filter(window =>
|
||||
!window.incognito &&
|
||||
@@ -443,7 +445,7 @@ export default defineBackground(() =>
|
||||
|
||||
if (availableWindows.length > 0)
|
||||
{
|
||||
const availableTab: Tabs.Tab = availableWindows[0].tabs!.find(
|
||||
const availableTab: Browser.tabs.Tab = availableWindows[0].tabs!.find(
|
||||
tab => tab.url === browser.runtime.getURL("/sidepanel.html")
|
||||
)!;
|
||||
|
||||
@@ -460,7 +462,7 @@ export default defineBackground(() =>
|
||||
}
|
||||
else
|
||||
{
|
||||
const collectionTab: Tabs.Tab | undefined = currentWindow.tabs!.find(
|
||||
const collectionTab: Browser.tabs.Tab | undefined = currentWindow.tabs!.find(
|
||||
tab => tab.url === browser.runtime.getURL("/sidepanel.html")
|
||||
);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { analyticsPermission } from "@/features/analytics";
|
||||
import useSettings, { SettingsValue } from "@/hooks/useSettings";
|
||||
import { Button, Checkbox, Dropdown, Field, Option, OptionOnSelectData } from "@fluentui/react-components";
|
||||
import { KeyCommand20Regular } from "@fluentui/react-icons";
|
||||
import { useOptionsStyles } from "../hooks/useOptionsStyles";
|
||||
import { analyticsPermission } from "@/features/analytics";
|
||||
|
||||
export default function GeneralSection(): React.ReactElement
|
||||
{
|
||||
@@ -45,6 +45,7 @@ export default function GeneralSection(): React.ReactElement
|
||||
setContextAction("open");
|
||||
|
||||
if (import.meta.env.FIREFOX && e.optionValue !== "sidebar")
|
||||
// @ts-expect-error Firefox-only API
|
||||
browser.sidebarAction.close();
|
||||
|
||||
setListLocation(e.optionValue as ListLocationType);
|
||||
|
||||
@@ -4,10 +4,10 @@ import { useDangerStyles } from "@/hooks/useDangerStyles";
|
||||
import useStorageInfo from "@/hooks/useStorageInfo";
|
||||
import { Button, Field, InfoLabel, LabelProps, MessageBar, MessageBarBody, MessageBarTitle, ProgressBar, Switch } from "@fluentui/react-components";
|
||||
import { ArrowDownload20Regular, ArrowUpload20Regular } from "@fluentui/react-icons";
|
||||
import { Unwatch } from "wxt/utils/storage";
|
||||
import { useOptionsStyles } from "../hooks/useOptionsStyles";
|
||||
import exportData from "../utils/exportData";
|
||||
import importData from "../utils/importData";
|
||||
import { Unwatch } from "wxt/storage";
|
||||
|
||||
export default function StorageSection(): React.ReactElement
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ export default function EditDialog(props: GroupEditDialogProps): ReactElement
|
||||
?? ""
|
||||
);
|
||||
|
||||
const [color, setColor] = useState<chrome.tabGroups.ColorEnum | undefined | "pinned">(
|
||||
const [color, setColor] = useState<`${Browser.tabGroups.Color}` | undefined | "pinned">(
|
||||
props.type === "collection"
|
||||
? props.collection?.color :
|
||||
props.group?.pinned === true ? "pinned" : (props.group?.color ?? "blue")
|
||||
@@ -112,8 +112,8 @@ export default function EditDialog(props: GroupEditDialogProps): ReactElement
|
||||
{ Object.keys(colorCls).map(i =>
|
||||
<fui.ToggleButton
|
||||
checked={ color === i }
|
||||
onClick={ () => setColor(i as chrome.tabGroups.ColorEnum) }
|
||||
className={ fui.mergeClasses(cls.colorButton, colorCls[i as chrome.tabGroups.ColorEnum]) }
|
||||
onClick={ () => setColor(i as `${Browser.tabGroups.Color}`) }
|
||||
className={ fui.mergeClasses(cls.colorButton, colorCls[i as `${Browser.tabGroups.Color}`]) }
|
||||
icon={ {
|
||||
className: cls.colorButton_icon,
|
||||
children: <Circle20Filled />
|
||||
@@ -121,7 +121,7 @@ export default function EditDialog(props: GroupEditDialogProps): ReactElement
|
||||
key={ i }
|
||||
shape="circular"
|
||||
>
|
||||
{ i18n.t(`colors.${i as chrome.tabGroups.ColorEnum}`) }
|
||||
{ i18n.t(`colors.${i as `${Browser.tabGroups.Color}`}`) }
|
||||
</fui.ToggleButton>
|
||||
) }
|
||||
</div>
|
||||
|
||||
@@ -44,11 +44,11 @@ export default function FilterCollectionsButton({ value, onChange }: FilterColle
|
||||
<ColorIcon
|
||||
className={ fui.mergeClasses(
|
||||
cls.colorIcon,
|
||||
colorCls[i as chrome.tabGroups.ColorEnum]
|
||||
colorCls[i as `${Browser.tabGroups.Color}`]
|
||||
) } />
|
||||
}
|
||||
>
|
||||
{ i18n.t(`colors.${i as chrome.tabGroups.ColorEnum}`) }
|
||||
{ i18n.t(`colors.${i as `${Browser.tabGroups.Color}`}`) }
|
||||
</fui.MenuItemCheckbox>
|
||||
) }
|
||||
</fui.MenuList>
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { track } from "@/features/analytics";
|
||||
import { CollectionItem, TabItem } from "@/models/CollectionModels";
|
||||
import sendNotification from "@/utils/sendNotification";
|
||||
import { Bookmarks, Permissions } from "wxt/browser";
|
||||
import { getCollectionTitle } from "./getCollectionTitle";
|
||||
import { track } from "@/features/analytics";
|
||||
|
||||
export default async function exportCollectionToBookmarks(collection: CollectionItem)
|
||||
{
|
||||
const permissions: Permissions.AnyPermissions = await browser.permissions.getAll();
|
||||
const permissions: Browser.permissions.Permissions = await browser.permissions.getAll();
|
||||
|
||||
if (!permissions.permissions?.includes("bookmarks"))
|
||||
{
|
||||
@@ -16,7 +15,7 @@ export default async function exportCollectionToBookmarks(collection: Collection
|
||||
return;
|
||||
}
|
||||
|
||||
const rootFolder: Bookmarks.BookmarkTreeNode = await browser.bookmarks.create({
|
||||
const rootFolder: Browser.bookmarks.BookmarkTreeNode = await browser.bookmarks.create({
|
||||
title: getCollectionTitle(collection)
|
||||
});
|
||||
|
||||
|
||||
@@ -61,5 +61,5 @@ export default function filterCollections(
|
||||
export type CollectionFilterType =
|
||||
{
|
||||
query: string;
|
||||
colors: (chrome.tabGroups.ColorEnum | "none")[];
|
||||
colors: (`${Browser.tabGroups.Color}` | "none")[];
|
||||
};
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { TabItem } from "@/models/CollectionModels";
|
||||
import sendNotification from "@/utils/sendNotification";
|
||||
import { Tabs } from "wxt/browser";
|
||||
|
||||
export default async function getSelectedTabs(): Promise<TabItem[]>
|
||||
{
|
||||
let tabs: Tabs.Tab[] = await browser.tabs.query({ currentWindow: true, highlighted: true });
|
||||
let tabs: Browser.tabs.Tab[] = await browser.tabs.query({ currentWindow: true, highlighted: true });
|
||||
const tabCount: number = tabs.length;
|
||||
|
||||
tabs = tabs.filter(i =>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { getCollectionTitle } from "@/entrypoints/sidepanel/utils/getCollectionTitle";
|
||||
import { CollectionItem, GroupItem, TabItem } from "@/models/CollectionModels";
|
||||
import { settings } from "@/utils/settings";
|
||||
import { Tabs, Windows } from "wxt/browser";
|
||||
|
||||
export async function openCollection(collection: CollectionItem, targetWindow?: "current" | "new" | "incognito"): Promise<void>
|
||||
{
|
||||
@@ -55,7 +54,7 @@ export async function openGroup(group: GroupItem, newWindow: boolean = false): P
|
||||
async function createGroup(group: GroupItem, windowId: number, discard?: boolean): Promise<void>
|
||||
{
|
||||
discard ??= await settings.dismissOnLoad.getValue();
|
||||
const tabs: Tabs.Tab[] = await Promise.all(group.items.map(async i =>
|
||||
const tabs: Browser.tabs.Tab[] = await Promise.all(group.items.map(async i =>
|
||||
await createTab(i.url, windowId, discard, group.pinned)
|
||||
));
|
||||
|
||||
@@ -63,21 +62,21 @@ async function createGroup(group: GroupItem, windowId: number, discard?: boolean
|
||||
if (group.pinned === true)
|
||||
return;
|
||||
|
||||
const groupId: number = await chrome.tabs.group({
|
||||
tabIds: tabs.filter(i => i.windowId === windowId).map(i => i.id!),
|
||||
const groupId: number = await browser.tabs.group({
|
||||
tabIds: tabs.filter(i => i.windowId === windowId).map(i => i.id!) as [number, ...number[]],
|
||||
createProperties: { windowId }
|
||||
});
|
||||
|
||||
await chrome.tabGroups.update(groupId, {
|
||||
await browser.tabGroups.update(groupId, {
|
||||
title: group.title,
|
||||
color: group.color
|
||||
});
|
||||
}
|
||||
|
||||
async function manageWindow(handle: (windowId: number) => Promise<void>, windowProps?: Windows.CreateCreateDataType): Promise<void>
|
||||
async function manageWindow(handle: (windowId: number) => Promise<void>, windowProps?: Browser.windows.CreateData): Promise<void>
|
||||
{
|
||||
const currentWindow: Windows.Window = windowProps ?
|
||||
await browser.windows.create({ url: "about:blank", focused: false, ...windowProps }) :
|
||||
const currentWindow: Browser.windows.Window = windowProps ?
|
||||
(await browser.windows.create({ url: "about:blank", focused: false, ...windowProps }))! :
|
||||
await browser.windows.getCurrent();
|
||||
const windowId: number = currentWindow.id!;
|
||||
|
||||
@@ -90,7 +89,7 @@ async function manageWindow(handle: (windowId: number) => Promise<void>, windowP
|
||||
await browser.tabs.remove(currentWindow.tabs![0].id!);
|
||||
}
|
||||
|
||||
async function createTab(url: string, windowId: number, discard: boolean, pinned?: boolean): Promise<Tabs.Tab>
|
||||
async function createTab(url: string, windowId: number, discard: boolean, pinned?: boolean): Promise<Browser.tabs.Tab>
|
||||
{
|
||||
const tab = await browser.tabs.create({ url, windowId: windowId, active: false, pinned });
|
||||
|
||||
@@ -102,7 +101,7 @@ async function createTab(url: string, windowId: number, discard: boolean, pinned
|
||||
|
||||
function discardOnLoad(tabId: number): void
|
||||
{
|
||||
const handleTabUpdated = (id: number, _: any, tab: Tabs.Tab) =>
|
||||
const handleTabUpdated = (id: number, _: any, tab: Browser.tabs.Tab) =>
|
||||
{
|
||||
if (id !== tabId || !tab.url)
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Unwatch, WatchCallback, WxtStorageItem } from "wxt/storage";
|
||||
import { Unwatch, WatchCallback } from "wxt/utils/storage";
|
||||
import { analytics } from "./analytics";
|
||||
import { Permissions } from "wxt/browser";
|
||||
|
||||
const analyticsPermission: Pick<WxtStorageItem<boolean, Record<string, unknown>>, "getValue" | "watch" | "setValue"> =
|
||||
{
|
||||
@@ -9,7 +8,7 @@ const analyticsPermission: Pick<WxtStorageItem<boolean, Record<string, unknown>>
|
||||
const isGranted: boolean = import.meta.env.FIREFOX
|
||||
? await browser.permissions.contains({
|
||||
data_collection: ["technicalAndInteraction"]
|
||||
})
|
||||
} as Browser.permissions.Permissions)
|
||||
: await allowAnalytics.getValue();
|
||||
|
||||
analytics.setEnabled(isGranted);
|
||||
@@ -30,11 +29,11 @@ const analyticsPermission: Pick<WxtStorageItem<boolean, Record<string, unknown>>
|
||||
if (value)
|
||||
result = await browser.permissions.request({
|
||||
data_collection: ["technicalAndInteraction"]
|
||||
});
|
||||
} as Browser.permissions.Permissions);
|
||||
else
|
||||
result = await browser.permissions.remove({
|
||||
data_collection: ["technicalAndInteraction"]
|
||||
});
|
||||
} as Browser.permissions.Permissions);
|
||||
|
||||
if (!result)
|
||||
throw new Error("Permission request was denied");
|
||||
@@ -45,11 +44,14 @@ const analyticsPermission: Pick<WxtStorageItem<boolean, Record<string, unknown>>
|
||||
if (!import.meta.env.FIREFOX)
|
||||
return allowAnalytics.watch(cb);
|
||||
|
||||
const listener = async (permissions: Permissions.Permissions): Promise<void> =>
|
||||
const listener = async (permissions: Browser.permissions.Permissions): Promise<void> =>
|
||||
{
|
||||
// @ts-expect-error Firefox-only API
|
||||
if (permissions.data_collection?.includes("technicalAndInteraction"))
|
||||
{
|
||||
const isGranted: boolean = await browser.permissions.contains({ data_collection: ["technicalAndInteraction"] });
|
||||
const isGranted: boolean = await browser.permissions.contains({
|
||||
data_collection: ["technicalAndInteraction"]
|
||||
} as Browser.permissions.Permissions);
|
||||
cb(isGranted, !isGranted);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,7 +44,7 @@ function parseCollection(data: string): CollectionItem
|
||||
return {
|
||||
type: "collection",
|
||||
timestamp: parseInt(data.match(/(?<=^c)\d+/)!.toString()),
|
||||
color: data.match(/(?<=^c\d+\/)[a-z]+/)?.toString() as chrome.tabGroups.ColorEnum,
|
||||
color: data.match(/(?<=^c\d+\/)[a-z]+/)?.toString() as `${Browser.tabGroups.Color}`,
|
||||
title: data.match(/(?<=^c[\da-z/]*\|).*/)?.toString(),
|
||||
items: []
|
||||
};
|
||||
@@ -64,7 +64,7 @@ function parseGroup(data: string): GroupItem
|
||||
return {
|
||||
type: "group",
|
||||
pinned: false,
|
||||
color: data.match(/(?<=^\tg\/)[a-z]+/)?.toString() as chrome.tabGroups.ColorEnum,
|
||||
color: data.match(/(?<=^\tg\/)[a-z]+/)?.toString() as `${Browser.tabGroups.Color}`,
|
||||
title: data.match(/(?<=^\tg\/[a-z]+\|).*$/)?.toString(),
|
||||
items: []
|
||||
};
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { trackError } from "@/features/analytics";
|
||||
import { CollectionItem } from "@/models/CollectionModels";
|
||||
import getLogger from "@/utils/getLogger";
|
||||
import sendNotification from "@/utils/sendNotification";
|
||||
import { compress } from "lzutf8";
|
||||
import { WxtStorageItem } from "wxt/storage";
|
||||
import { collectionStorage } from "./collectionStorage";
|
||||
import getChunkKeys from "./getChunkKeys";
|
||||
import serializeCollections from "./serializeCollections";
|
||||
import { trackError } from "@/features/analytics";
|
||||
import sendNotification from "@/utils/sendNotification";
|
||||
import getLogger from "@/utils/getLogger";
|
||||
|
||||
const logger = getLogger("saveCollectionsToCloud");
|
||||
|
||||
@@ -70,7 +69,7 @@ function splitIntoChunks(data: string): string[]
|
||||
{
|
||||
// QUOTA_BYTES_PER_ITEM includes length of key name, length of content and 2 more bytes (for unknown reason).
|
||||
const chunkKey: string = getChunkKeys(collectionStorage.maxChunkCount - 1)[0];
|
||||
const chunkSize = (chrome.storage.sync.QUOTA_BYTES_PER_ITEM ?? 8192) - chunkKey.length - 2;
|
||||
const chunkSize = (browser.storage.sync.QUOTA_BYTES_PER_ITEM ?? 8192) - chunkKey.length - 2;
|
||||
const chunks: string[] = [];
|
||||
|
||||
for (let i = 0; i < data.length; i += chunkSize)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Permissions } from "wxt/browser";
|
||||
import { Unwatch, WatchCallback, WxtStorageItem } from "wxt/storage";
|
||||
import { Unwatch, WatchCallback } from "wxt/utils/storage";
|
||||
|
||||
const thumbnailCaptureEnabled: Pick<WxtStorageItem<boolean, Record<string, unknown>>, "getValue" | "watch" | "setValue"> =
|
||||
{
|
||||
@@ -8,7 +7,7 @@ const thumbnailCaptureEnabled: Pick<WxtStorageItem<boolean, Record<string, unkno
|
||||
|
||||
watch: (cb: WatchCallback<boolean>): Unwatch =>
|
||||
{
|
||||
const listener = async (permissions: Permissions.Permissions): Promise<void> =>
|
||||
const listener = async (permissions: Browser.permissions.Permissions): Promise<void> =>
|
||||
{
|
||||
if (permissions.permissions?.includes("scripting") || permissions.origins?.includes("<all_urls>"))
|
||||
{
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { githubLinks } from "@/data/links";
|
||||
import { analyticsPermission } from "@/features/analytics";
|
||||
import { thumbnailCaptureEnabled } from "@/features/collectionStorage";
|
||||
import extLink from "@/utils/extLink";
|
||||
import * as fui from "@fluentui/react-components";
|
||||
import { settingsForReview } from "../utils/showSettingsReviewDialog";
|
||||
import { Unwatch } from "wxt/utils/storage";
|
||||
import { reviewSettings } from "../utils/setSettingsReviewNeeded";
|
||||
import { Unwatch } from "wxt/storage";
|
||||
import { thumbnailCaptureEnabled } from "@/features/collectionStorage";
|
||||
import { settingsForReview } from "../utils/showSettingsReviewDialog";
|
||||
|
||||
export default function SettingsReviewDialog(): React.ReactElement
|
||||
{
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { analyticsPermission } from "@/features/analytics";
|
||||
import { Runtime } from "wxt/browser";
|
||||
import { settingsForReview } from "./showSettingsReviewDialog";
|
||||
|
||||
export default async function setSettingsReviewNeeded(installReason: Runtime.OnInstalledReason, previousVersion?: string): Promise<void>
|
||||
export default async function setSettingsReviewNeeded(installReason: `${Browser.runtime.OnInstalledReason}`, previousVersion?: string): Promise<void>
|
||||
{
|
||||
const needsReview: string[] = await settingsForReview.getValue();
|
||||
|
||||
@@ -25,7 +24,7 @@ export const reviewSettings =
|
||||
THUMBNAILS: "thumbnails"
|
||||
};
|
||||
|
||||
async function checkAnalyticsReviewNeeded(installReason: Runtime.OnInstalledReason, previousVersion?: string): Promise<boolean>
|
||||
async function checkAnalyticsReviewNeeded(installReason: `${Browser.runtime.OnInstalledReason}`, previousVersion?: string): Promise<boolean>
|
||||
{
|
||||
if (installReason === "install")
|
||||
return !await analyticsPermission.getValue();
|
||||
@@ -45,7 +44,7 @@ async function checkAnalyticsReviewNeeded(installReason: Runtime.OnInstalledReas
|
||||
return false;
|
||||
}
|
||||
|
||||
async function checkThumbnailsReviewNeeded(installReason: Runtime.OnInstalledReason, previousVersion?: string): Promise<boolean>
|
||||
async function checkThumbnailsReviewNeeded(installReason: `${Browser.runtime.OnInstalledReason}`, previousVersion?: string): Promise<boolean>
|
||||
{
|
||||
if (installReason === "install")
|
||||
return true;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { makeStyles, tokens } from "@fluentui/react-components";
|
||||
|
||||
export const useGroupColors: () => Record<chrome.tabGroups.ColorEnum, string> = makeStyles({
|
||||
export const useGroupColors: () => Record<`${Browser.tabGroups.Color}`, string> = makeStyles({
|
||||
blue:
|
||||
{
|
||||
"--border": tokens.colorPaletteBlueBorderActive,
|
||||
|
||||
@@ -14,8 +14,8 @@ export default function useStorageInfo(): StorageInfoHook
|
||||
|
||||
return {
|
||||
bytesInUse,
|
||||
storageQuota: chrome.storage.sync.QUOTA_BYTES ?? 102400,
|
||||
usedStorageRatio: bytesInUse / (chrome.storage.sync.QUOTA_BYTES ?? 102400)
|
||||
storageQuota: browser.storage.sync.QUOTA_BYTES ?? 102400,
|
||||
usedStorageRatio: bytesInUse / (browser.storage.sync.QUOTA_BYTES ?? 102400)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ export type DefaultGroupItem =
|
||||
type: "group";
|
||||
pinned?: false;
|
||||
title?: string;
|
||||
color: chrome.tabGroups.ColorEnum;
|
||||
color: `${Browser.tabGroups.Color}`;
|
||||
items: TabItem[];
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ export type CollectionItem =
|
||||
type: "collection";
|
||||
timestamp: number;
|
||||
title?: string;
|
||||
color?: chrome.tabGroups.ColorEnum;
|
||||
color?: `${Browser.tabGroups.Color}`;
|
||||
items: (TabItem | GroupItem)[];
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "tabs-aside",
|
||||
"private": true,
|
||||
"version": "3.2.0",
|
||||
"version": "3.2.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "wxt",
|
||||
@@ -40,7 +40,7 @@
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.46.4",
|
||||
"vite": "^7.2.2",
|
||||
"wxt": "~0.19.29"
|
||||
"wxt": "^0.20.11"
|
||||
},
|
||||
"packageManager": "yarn@4.9.2"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { Tabs } from "wxt/browser";
|
||||
|
||||
export async function closeTabsAsync(tabs: Tabs.Tab[]): Promise<void>
|
||||
export async function closeTabsAsync(tabs: Browser.tabs.Tab[]): Promise<void>
|
||||
{
|
||||
if (tabs.length < 1)
|
||||
return;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { CollectionItem, GroupItem } from "@/models/CollectionModels";
|
||||
import { Tabs } from "wxt/browser";
|
||||
|
||||
export async function createCollectionFromTabs(tabs: Tabs.Tab[]): Promise<CollectionItem>
|
||||
export async function createCollectionFromTabs(tabs: Browser.tabs.Tab[]): Promise<CollectionItem>
|
||||
{
|
||||
const collection: CollectionItem = {
|
||||
type: "collection",
|
||||
@@ -36,7 +35,7 @@ export async function createCollectionFromTabs(tabs: Tabs.Tab[]): Promise<Collec
|
||||
tabs.every(i => i.groupId === tabs[0].groupId)
|
||||
)
|
||||
{
|
||||
const group = await chrome.tabGroups.get(tabs[0].groupId);
|
||||
const group = await browser.tabGroups.get(tabs[0].groupId);
|
||||
collection.title = group.title;
|
||||
collection.color = group.color;
|
||||
|
||||
@@ -63,7 +62,7 @@ export async function createCollectionFromTabs(tabs: Tabs.Tab[]): Promise<Collec
|
||||
if (!activeGroup || activeGroup !== tab.groupId)
|
||||
{
|
||||
activeGroup = tab.groupId;
|
||||
const group = await chrome.tabGroups.get(activeGroup);
|
||||
const group = await browser.tabGroups.get(activeGroup!);
|
||||
|
||||
collection.items.push({
|
||||
type: "group",
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { Tabs } from "wxt/browser";
|
||||
import { settings } from "./settings";
|
||||
|
||||
export async function getTabsToSaveAsync(): Promise<[Tabs.Tab[], number]>
|
||||
export async function getTabsToSaveAsync(): Promise<[Browser.tabs.Tab[], number]>
|
||||
{
|
||||
let tabs: Tabs.Tab[] = await browser.tabs.query({
|
||||
let tabs: Browser.tabs.Tab[] = await browser.tabs.query({
|
||||
currentWindow: true,
|
||||
highlighted: true
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Unwatch } from "wxt/storage";
|
||||
import { Unwatch } from "wxt/utils/storage";
|
||||
|
||||
export default function watchTabSelection(onChange: TabSelectChangeHandler): Unwatch
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user