mirror of
https://github.com/XFox111/TabsAsideExtension.git
synced 2026-07-02 19:52:47 +03:00
Compare commits
14 Commits
v3.0.0-rc5
...
v3.0.0-rc7
| Author | SHA1 | Date | |
|---|---|---|---|
| e803636c35 | |||
| c8b4ef3e15 | |||
| eeefd1feff | |||
| 53adbd4f75 | |||
| 3eed3b4b01 | |||
| 525130b7e9 | |||
| 1a274348e0 | |||
| 2c8cfa1583 | |||
| e844a68f49 | |||
| 794f6e3af0 | |||
| d85d10dc58 | |||
| 213cc84602 | |||
| 9675b65e81 | |||
| 6bce330a8f |
@@ -0,0 +1,2 @@
|
||||
* @XFox111
|
||||
locales/pt_BR.yml @maisondasilva @XFox111
|
||||
@@ -12,9 +12,7 @@ updates:
|
||||
directory: "/" # Location of package manifests
|
||||
target-branch: "next"
|
||||
assignees:
|
||||
- "xfox111"
|
||||
reviewers:
|
||||
- "xfox111"
|
||||
- "XFox111"
|
||||
schedule:
|
||||
interval: monthly
|
||||
rebase-strategy: disabled
|
||||
@@ -24,9 +22,7 @@ updates:
|
||||
directory: "/"
|
||||
target-branch: "next"
|
||||
assignees:
|
||||
- "xfox111"
|
||||
reviewers:
|
||||
- "xfox111"
|
||||
- "XFox111"
|
||||
schedule:
|
||||
interval: monthly
|
||||
rebase-strategy: disabled
|
||||
@@ -36,9 +32,7 @@ updates:
|
||||
directory: "/"
|
||||
target-branch: "next"
|
||||
assignees:
|
||||
- "xfox111"
|
||||
reviewers:
|
||||
- "xfox111"
|
||||
- "XFox111"
|
||||
schedule:
|
||||
interval: monthly
|
||||
rebase-strategy: disabled
|
||||
|
||||
@@ -257,7 +257,7 @@ export default defineBackground(() =>
|
||||
|
||||
for (const openWindow of openWindows)
|
||||
{
|
||||
if (openWindow.incognito)
|
||||
if (openWindow.incognito || openWindow.type !== "normal")
|
||||
continue;
|
||||
|
||||
const activeTabs: Tabs.Tab[] = openWindow.tabs!.filter(tab =>
|
||||
|
||||
@@ -27,7 +27,7 @@ export const useStyles_CollectionView = makeStyles({
|
||||
},
|
||||
verticalRoot:
|
||||
{
|
||||
height: "560px"
|
||||
maxHeight: "560px"
|
||||
},
|
||||
empty:
|
||||
{
|
||||
@@ -74,7 +74,8 @@ export const useStyles_CollectionView = makeStyles({
|
||||
{
|
||||
gridAutoFlow: "row",
|
||||
width: "100%",
|
||||
paddingBottom: tokens.spacingVerticalS
|
||||
paddingBottom: tokens.spacingVerticalS,
|
||||
gridAutoRows: import.meta.env.FIREFOX ? "min-content" : undefined
|
||||
},
|
||||
dragOverlay:
|
||||
{
|
||||
|
||||
@@ -50,26 +50,30 @@ export default function CollectionView({ collection, index: collectionIndex, dra
|
||||
|
||||
<CollectionHeader dragHandleProps={ activatorProps } dragHandleRef={ setActivatorNodeRef } />
|
||||
|
||||
{ collection.items.length < 1 ?
|
||||
<div className={ cls.empty }>
|
||||
<CollectionsRegular fontSize={ 32 } />
|
||||
<Body1Strong>{ i18n.t("collections.empty") }</Body1Strong>
|
||||
</div>
|
||||
:
|
||||
<div className={ mergeClasses(cls.list, !tilesView && cls.verticalList) }>
|
||||
<SortableContext
|
||||
items={ collection.items.map((_, index) => [collectionIndex, index].join("/")) }
|
||||
strategy={ tilesView ? horizontalListSortingStrategy : verticalListSortingStrategy }
|
||||
>
|
||||
{ collection.items.map((i, index) =>
|
||||
i.type === "group" ?
|
||||
<GroupView
|
||||
key={ index } group={ i } indices={ [collectionIndex, index] } />
|
||||
:
|
||||
<TabView key={ index } tab={ i } indices={ [collectionIndex, index] } />
|
||||
) }
|
||||
</SortableContext>
|
||||
</div>
|
||||
{ (!activeItem || activeItem.item.type !== "collection") && !dragOverlay &&
|
||||
<>
|
||||
{ collection.items.length < 1 ?
|
||||
<div className={ cls.empty }>
|
||||
<CollectionsRegular fontSize={ 32 } />
|
||||
<Body1Strong>{ i18n.t("collections.empty") }</Body1Strong>
|
||||
</div>
|
||||
:
|
||||
<div className={ mergeClasses(cls.list, !tilesView && cls.verticalList) }>
|
||||
<SortableContext
|
||||
items={ collection.items.map((_, index) => [collectionIndex, index].join("/")) }
|
||||
strategy={ tilesView ? horizontalListSortingStrategy : verticalListSortingStrategy }
|
||||
>
|
||||
{ collection.items.map((i, index) =>
|
||||
i.type === "group" ?
|
||||
<GroupView
|
||||
key={ index } group={ i } indices={ [collectionIndex, index] } />
|
||||
:
|
||||
<TabView key={ index } tab={ i } indices={ [collectionIndex, index] } />
|
||||
) }
|
||||
</SortableContext>
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
}
|
||||
</div >
|
||||
</CollectionContext.Provider>
|
||||
|
||||
@@ -58,8 +58,6 @@ export const useStyles_TabView = makeStyles({
|
||||
display: "grid",
|
||||
gridTemplateColumns: "auto 1fr auto",
|
||||
alignItems: "center",
|
||||
gap: tokens.spacingHorizontalSNudge,
|
||||
paddingLeft: tokens.spacingHorizontalS,
|
||||
|
||||
borderBottomLeftRadius: tokens.borderRadiusMedium,
|
||||
borderBottomRightRadius: tokens.borderRadiusMedium,
|
||||
@@ -72,6 +70,9 @@ export const useStyles_TabView = makeStyles({
|
||||
icon:
|
||||
{
|
||||
cursor: "grab",
|
||||
padding: `${tokens.spacingVerticalSNudge} ${tokens.spacingHorizontalSNudge}`,
|
||||
height: "32px",
|
||||
boxSizing: "border-box",
|
||||
|
||||
"&:active":
|
||||
{
|
||||
|
||||
@@ -83,7 +83,6 @@ export default function TabView({ tab, indices, dragOverlay }: TabViewProps): Re
|
||||
ref={ setActivatorNodeRef } { ...activatorProps }
|
||||
src={ graphics[tab.url]?.icon ?? faviconPlaceholder }
|
||||
onError={ e => e.currentTarget.src = faviconPlaceholder }
|
||||
height={ 20 } width={ 20 }
|
||||
className={ cls.icon } draggable={ false } />
|
||||
|
||||
<Tooltip relationship="description" content={ tab.title ?? tab.url }>
|
||||
|
||||
@@ -12,6 +12,7 @@ import saveTabsToCollection from "@/utils/saveTabsToCollection";
|
||||
|
||||
export default function CollectionHeader({ dragHandleRef, dragHandleProps }: CollectionHeaderProps): React.ReactElement
|
||||
{
|
||||
const [contextOpen, setContextOpen] = useState<boolean>(false);
|
||||
const [listLocation] = useSettings("listLocation");
|
||||
const isTab: boolean = listLocation === "tab" || listLocation === "pinned";
|
||||
const { updateCollection } = useCollections();
|
||||
@@ -53,7 +54,7 @@ export default function CollectionHeader({ dragHandleRef, dragHandleProps }: Col
|
||||
mergeClasses(
|
||||
cls.toolbar,
|
||||
"CollectionView__toolbar",
|
||||
alwaysShowToolbars === true && cls.showToolbar
|
||||
(alwaysShowToolbars === true || contextOpen) && cls.showToolbar
|
||||
) }
|
||||
>
|
||||
{ tabCount < 1 ?
|
||||
@@ -61,10 +62,10 @@ export default function CollectionHeader({ dragHandleRef, dragHandleProps }: Col
|
||||
{ isTab ? i18n.t("collections.menu.add_all") : i18n.t("collections.menu.add_selected") }
|
||||
</Button>
|
||||
:
|
||||
<OpenCollectionButton />
|
||||
<OpenCollectionButton onOpenChange={ (_, e) => setContextOpen(e.open) } />
|
||||
}
|
||||
|
||||
<CollectionMoreButton onAddSelected={ handleAddSelected } />
|
||||
<CollectionMoreButton onAddSelected={ handleAddSelected } onOpenChange={ (_, e) => setContextOpen(e.open) } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { useDialog } from "@/contexts/DialogProvider";
|
||||
import { useDangerStyles } from "@/hooks/useDangerStyles";
|
||||
import useSettings from "@/hooks/useSettings";
|
||||
import { Button, Menu, MenuDivider, MenuItem, MenuList, MenuPopover, MenuTrigger, Tooltip } from "@fluentui/react-components";
|
||||
import { Button, Menu, MenuDivider, MenuItem, MenuList, MenuOpenChangeData, MenuOpenEvent, MenuPopover, MenuTrigger, Tooltip } from "@fluentui/react-components";
|
||||
import * as ic from "@fluentui/react-icons";
|
||||
import CollectionContext, { CollectionContextType } from "../../contexts/CollectionContext";
|
||||
import { useCollections } from "../../contexts/CollectionsProvider";
|
||||
import exportCollectionToBookmarks from "../../utils/exportCollectionToBookmarks";
|
||||
import EditDialog from "../EditDialog";
|
||||
|
||||
export default function CollectionMoreButton({ onAddSelected }: CollectionMoreButtonProps): React.ReactElement
|
||||
export default function CollectionMoreButton({ onAddSelected, onOpenChange }: CollectionMoreButtonProps): React.ReactElement
|
||||
{
|
||||
const [listLocation] = useSettings("listLocation");
|
||||
const isTab: boolean = listLocation === "tab" || listLocation === "pinned";
|
||||
@@ -56,7 +56,7 @@ export default function CollectionMoreButton({ onAddSelected }: CollectionMoreBu
|
||||
);
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<Menu onOpenChange={ onOpenChange }>
|
||||
<Tooltip relationship="label" content={ i18n.t("common.tooltips.more") }>
|
||||
<MenuTrigger>
|
||||
<Button appearance="subtle" icon={ <ic.MoreVertical20Regular /> } />
|
||||
@@ -94,4 +94,5 @@ export default function CollectionMoreButton({ onAddSelected }: CollectionMoreBu
|
||||
export type CollectionMoreButtonProps =
|
||||
{
|
||||
onAddSelected?: () => void;
|
||||
onOpenChange?: (e: MenuOpenEvent, data: MenuOpenChangeData) => void;
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { useDialog } from "@/contexts/DialogProvider";
|
||||
import useSettings from "@/hooks/useSettings";
|
||||
import browserLocaleKey from "@/utils/browserLocaleKey";
|
||||
import { Menu, MenuButtonProps, MenuItem, MenuList, MenuPopover, MenuTrigger, SplitButton } from "@fluentui/react-components";
|
||||
import { Menu, MenuButtonProps, MenuItem, MenuList, MenuOpenChangeData, MenuOpenEvent, MenuPopover, MenuTrigger, SplitButton } from "@fluentui/react-components";
|
||||
import * as ic from "@fluentui/react-icons";
|
||||
import CollectionContext, { CollectionContextType } from "../../contexts/CollectionContext";
|
||||
import { useCollections } from "../../contexts/CollectionsProvider";
|
||||
import { openCollection } from "../../utils/opener";
|
||||
|
||||
export default function OpenCollectionButton(): React.ReactElement
|
||||
export default function OpenCollectionButton({ onOpenChange }: OpenCollectionButtonProps): React.ReactElement
|
||||
{
|
||||
const [defaultAction] = useSettings("defaultRestoreAction");
|
||||
const { removeItem } = useCollections();
|
||||
@@ -54,7 +54,7 @@ export default function OpenCollectionButton(): React.ReactElement
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<Menu onOpenChange={ onOpenChange }>
|
||||
<MenuTrigger disableButtonEnhancement>
|
||||
{ (triggerProps: MenuButtonProps) => defaultAction === "restore" ?
|
||||
<SplitButton
|
||||
@@ -95,3 +95,8 @@ export default function OpenCollectionButton(): React.ReactElement
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
export type OpenCollectionButtonProps =
|
||||
{
|
||||
onOpenChange?: (e: MenuOpenEvent, data: MenuOpenChangeData) => void;
|
||||
};
|
||||
|
||||
@@ -46,6 +46,10 @@ export const useStyles_CollectionListView = makeStyles({
|
||||
listView:
|
||||
{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(auto-fit, minmax(360px, 1fr))"
|
||||
|
||||
"@media screen and (min-width: 360px)":
|
||||
{
|
||||
gridTemplateColumns: "repeat(auto-fit, minmax(360px, 1fr))"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -33,7 +33,7 @@ export default function CollectionListView(): ReactElement
|
||||
const [active, setActive] = useState<DndItem | null>(null);
|
||||
|
||||
const sensors = useSensors(
|
||||
useSensor(MouseSensor, { activationConstraint: { delay: 100, tolerance: 0 } }),
|
||||
useSensor(MouseSensor, { activationConstraint: { delay: 10, tolerance: 20 } }),
|
||||
useSensor(TouchSensor, { activationConstraint: { delay: 300, tolerance: 20 } })
|
||||
);
|
||||
|
||||
|
||||
@@ -1,8 +1,24 @@
|
||||
import { TabItem } from "@/models/CollectionModels";
|
||||
import sendNotification from "@/utils/sendNotification";
|
||||
import { Tabs } from "wxt/browser";
|
||||
|
||||
export default async function getSelectedTabs(): Promise<TabItem[]>
|
||||
{
|
||||
const tabs: Tabs.Tab[] = await browser.tabs.query({ currentWindow: true, highlighted: true });
|
||||
return tabs.filter(i => i.url).map(i => ({ type: "tab", url: i.url!, title: i.title }));
|
||||
let tabs: Tabs.Tab[] = await browser.tabs.query({ currentWindow: true, highlighted: true });
|
||||
const tabCount: number = tabs.length;
|
||||
|
||||
tabs = tabs.filter(i =>
|
||||
i.url
|
||||
&& new URL(i.url).protocol !== "about:"
|
||||
&& new URL(i.url).hostname !== "newtab"
|
||||
);
|
||||
|
||||
if (tabs.length < tabCount)
|
||||
await sendNotification({
|
||||
title: i18n.t("notifications.partial_save.title"),
|
||||
message: i18n.t("notifications.partial_save.message"),
|
||||
icon: "/notification_icons/save_warning.png"
|
||||
});
|
||||
|
||||
return tabs.map(i => ({ type: "tab", url: i.url!, title: i.title }));
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default async function getCollectionsFromCloud(): Promise<CollectionItem[
|
||||
const chunks: Record<string, string> =
|
||||
await browser.storage.sync.get(getChunkKeys(0, chunkCount)) as Record<string, string>;
|
||||
|
||||
const data: string = decompress(Object.values(chunks).join(), { inputEncoding: "StorageBinaryString" });
|
||||
const data: string = decompress(Object.values(chunks).join(), { inputEncoding: "Base64" });
|
||||
|
||||
return parseCollections(data);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default async function saveCollectionsToCloud(collections: CollectionItem
|
||||
return;
|
||||
}
|
||||
|
||||
const data: string = compress(serializeCollections(collections), { outputEncoding: "StorageBinaryString" });
|
||||
const data: string = compress(serializeCollections(collections), { outputEncoding: "Base64" });
|
||||
const chunks: string[] = splitIntoChunks(data);
|
||||
|
||||
if (chunks.length > collectionStorage.maxChunkCount)
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ options_page:
|
||||
icon_action:
|
||||
title: "Po kliknięciu ikony rozszerzenia:"
|
||||
options:
|
||||
action: "Wykonaj domyślną akcję"
|
||||
action: "Zapisz karty (domyślna akcja)"
|
||||
context: "Pokaż menu kontekstowe"
|
||||
open: "Otwórz listę kolekcji"
|
||||
change_shortcuts: "Zmień skróty klawiszowe"
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ options_page:
|
||||
icon_action:
|
||||
title: "При нажатии на иконку расширения:"
|
||||
options:
|
||||
action: "Выполнить действие по умолчанию"
|
||||
action: "Сохранить вкладки (действие по умолчанию)"
|
||||
context: "Показать контекстное меню"
|
||||
open: "Открыть список коллекций"
|
||||
change_shortcuts: "Изменить горячие клавиши"
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ options_page:
|
||||
icon_action:
|
||||
title: "При натисканні на іконку розширення:"
|
||||
options:
|
||||
action: "Виконати дію за замовчуванням"
|
||||
action: "Зберегти вкладки (дія за замовчуванням)"
|
||||
context: "Показати контекстне меню"
|
||||
open: "Відкрити список колекцій"
|
||||
change_shortcuts: "Змінити гарячі клавіші"
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "tabs-aside",
|
||||
"private": true,
|
||||
"version": "3.0.0-rc5",
|
||||
"version": "3.0.0-rc7",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "wxt",
|
||||
|
||||
Reference in New Issue
Block a user