mirror of
https://github.com/XFox111/TabsAsideExtension.git
synced 2026-04-22 07:58:01 +03:00
Major 3.0 (#118)
Co-authored-by: Maison da Silva <maisonmdsgreen@hotmail.com>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import { useCollections } from "@/entrypoints/sidepanel/contexts/CollectionsProvider";
|
||||
import useSettings, { SettingsValue } from "@/hooks/useSettings";
|
||||
import saveTabsToCollection from "@/utils/saveTabsToCollection";
|
||||
import watchTabSelection from "@/utils/watchTabSelection";
|
||||
import { Menu, MenuButtonProps, MenuItem, MenuList, MenuPopover, MenuTrigger, SplitButton } from "@fluentui/react-components";
|
||||
import * as ic from "@fluentui/react-icons";
|
||||
import { ReactElement } from "react";
|
||||
|
||||
export default function ActionButton(): ReactElement
|
||||
{
|
||||
const { addCollection } = useCollections();
|
||||
const [defaultAction] = useSettings("defaultSaveAction");
|
||||
const [selection, setSelection] = useState<"all" | "selected">("all");
|
||||
|
||||
const handleAction = async (primary: boolean) =>
|
||||
{
|
||||
const colection = await saveTabsToCollection(primary === (defaultAction === "set_aside"));
|
||||
addCollection(colection);
|
||||
};
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
return watchTabSelection(setSelection);
|
||||
}, []);
|
||||
|
||||
if (defaultAction === null)
|
||||
return <div />;
|
||||
|
||||
const primaryActionKey: ActionsKey = `${defaultAction}.${selection}`;
|
||||
const PrimaryIcon = actionIcons[primaryActionKey];
|
||||
const secondaryActionKey: ActionsKey = `${defaultAction === "save" ? "set_aside" : "save"}.${selection}`;
|
||||
const SecondaryIcon = actionIcons[secondaryActionKey];
|
||||
|
||||
return (
|
||||
<Menu positioning="below-end">
|
||||
<MenuTrigger disableButtonEnhancement>
|
||||
{ (triggerProps: MenuButtonProps) => (
|
||||
<SplitButton
|
||||
appearance="primary"
|
||||
icon={ <PrimaryIcon /> }
|
||||
menuButton={ triggerProps }
|
||||
primaryActionButton={ { onClick: () => handleAction(true) } }
|
||||
>
|
||||
{ i18n.t(`actions.${primaryActionKey}`) }
|
||||
</SplitButton>
|
||||
) }
|
||||
</MenuTrigger>
|
||||
|
||||
<MenuPopover>
|
||||
<MenuList>
|
||||
<MenuItem icon={ <SecondaryIcon /> } onClick={ () => handleAction(false) }>
|
||||
{ i18n.t(`actions.${secondaryActionKey}`) }
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</MenuPopover>
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
const actionIcons: Record<ActionsKey, ic.FluentIcon> =
|
||||
{
|
||||
"save.all": ic.bundleIcon(ic.SaveArrowRight20Filled, ic.SaveArrowRight20Regular),
|
||||
"save.selected": ic.bundleIcon(ic.SaveCopy20Filled, ic.SaveCopy20Regular),
|
||||
"set_aside.all": ic.bundleIcon(ic.ArrowRight20Filled, ic.ArrowRight20Regular),
|
||||
"set_aside.selected": ic.bundleIcon(ic.CopyArrowRight20Filled, ic.CopyArrowRight20Regular)
|
||||
};
|
||||
|
||||
export type ActionsKey = `${SettingsValue<"defaultSaveAction">}.${"all" | "selected"}`;
|
||||
|
||||
export type ActionsValue =
|
||||
{
|
||||
label: string;
|
||||
icon: ic.FluentIcon;
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
import { useDialog } from "@/contexts/DialogProvider";
|
||||
import { useCollections } from "@/entrypoints/sidepanel/contexts/CollectionsProvider";
|
||||
import { Button, makeStyles, tokens, Tooltip } from "@fluentui/react-components";
|
||||
import { CollectionsAddRegular } from "@fluentui/react-icons";
|
||||
import { ReactElement } from "react";
|
||||
import EditDialog from "../../components/EditDialog";
|
||||
import ActionButton from "./ActionButton";
|
||||
import MoreButton from "./MoreButton";
|
||||
|
||||
export default function Header(): ReactElement
|
||||
{
|
||||
const { addCollection } = useCollections();
|
||||
const dialog = useDialog();
|
||||
const cls = useStyles();
|
||||
|
||||
const handleCreateCollection = () =>
|
||||
dialog.pushCustom(
|
||||
<EditDialog
|
||||
type="collection"
|
||||
onSave={ addCollection } />
|
||||
);
|
||||
|
||||
return (
|
||||
<header className={ cls.header }>
|
||||
<ActionButton />
|
||||
|
||||
<div className={ cls.headerSecondary }>
|
||||
<MoreButton />
|
||||
<Tooltip relationship="label" content={ i18n.t("main.header.create_collection") }>
|
||||
<Button
|
||||
appearance="subtle"
|
||||
icon={ <CollectionsAddRegular /> }
|
||||
onClick={ handleCreateCollection } />
|
||||
</Tooltip>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
const useStyles = makeStyles({
|
||||
header:
|
||||
{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
padding: `${tokens.spacingVerticalS} ${tokens.spacingHorizontalS}`,
|
||||
gap: tokens.spacingHorizontalS
|
||||
},
|
||||
headerSecondary:
|
||||
{
|
||||
display: "flex",
|
||||
gap: tokens.spacingHorizontalXS
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,86 @@
|
||||
import { BuyMeACoffee20Filled, BuyMeACoffee20Regular } from "@/assets/BuyMeACoffee20";
|
||||
import { buyMeACoffeeLink, githubLinks, storeLink } from "@/data/links";
|
||||
import { track } from "@/features/analytics";
|
||||
import useSettings from "@/hooks/useSettings";
|
||||
import extLink from "@/utils/extLink";
|
||||
import sendNotification from "@/utils/sendNotification";
|
||||
import * as fui from "@fluentui/react-components";
|
||||
import * as ic from "@fluentui/react-icons";
|
||||
import { ReactElement } from "react";
|
||||
|
||||
export default function MoreButton(): ReactElement
|
||||
{
|
||||
const [tilesView, setTilesView] = useSettings("tilesView");
|
||||
|
||||
const SettingsIcon: ic.FluentIcon = ic.bundleIcon(ic.Settings20Filled, ic.Settings20Regular);
|
||||
const ViewIcon: ic.FluentIcon = ic.bundleIcon(ic.GridKanban20Filled, ic.GridKanban20Regular);
|
||||
const FeedbackIcon: ic.FluentIcon = ic.bundleIcon(ic.PersonFeedback20Filled, ic.PersonFeedback20Regular);
|
||||
const LearnIcon: ic.FluentIcon = ic.bundleIcon(ic.QuestionCircle20Filled, ic.QuestionCircle20Regular);
|
||||
const BmcIcon: ic.FluentIcon = ic.bundleIcon(BuyMeACoffee20Filled, BuyMeACoffee20Regular);
|
||||
|
||||
return (
|
||||
<fui.Menu
|
||||
hasIcons hasCheckmarks
|
||||
checkedValues={ { tilesView: tilesView ? ["true"] : [] } }
|
||||
onCheckedValueChange={ (_, e) => setTilesView(e.checkedItems.length > 0) }
|
||||
>
|
||||
<fui.Tooltip relationship="label" content={ i18n.t("common.tooltips.more") }>
|
||||
<fui.MenuTrigger disableButtonEnhancement>
|
||||
<fui.Button appearance="subtle" icon={ <ic.MoreVerticalRegular /> } />
|
||||
</fui.MenuTrigger>
|
||||
</fui.Tooltip>
|
||||
|
||||
<fui.MenuPopover>
|
||||
<fui.MenuList>
|
||||
|
||||
<fui.MenuItem icon={ <SettingsIcon /> } onClick={ () => browser.runtime.openOptionsPage() }>
|
||||
{ i18n.t("options_page.title") }
|
||||
</fui.MenuItem>
|
||||
<fui.MenuItemCheckbox name="tilesView" value="true" icon={ <ViewIcon /> }>
|
||||
{ i18n.t("main.header.menu.tiles_view") }
|
||||
</fui.MenuItemCheckbox>
|
||||
|
||||
<fui.MenuDivider />
|
||||
|
||||
<fui.MenuItemLink icon={ <BmcIcon /> } { ...extLink(buyMeACoffeeLink) } onClick={ () => track("feedback_clicked") }>
|
||||
{ i18n.t("common.cta.sponsor") }
|
||||
</fui.MenuItemLink>
|
||||
<fui.MenuItemLink icon={ <FeedbackIcon /> } { ...extLink(storeLink) } onClick={ () => track("bmc_clicked") }>
|
||||
{ i18n.t("common.cta.feedback") }
|
||||
</fui.MenuItemLink>
|
||||
<fui.MenuItemLink icon={ <LearnIcon /> } { ...extLink(githubLinks.release) } >
|
||||
{ i18n.t("main.header.menu.changelog") }
|
||||
</fui.MenuItemLink>
|
||||
|
||||
{ import.meta.env.DEV &&
|
||||
<fui.MenuGroup>
|
||||
<fui.MenuGroupHeader>Dev tools</fui.MenuGroupHeader>
|
||||
<fui.MenuItem
|
||||
icon={ <ic.ArrowClockwise20Regular /> }
|
||||
onClick={ () => document.location.reload() }
|
||||
>
|
||||
Reload page
|
||||
</fui.MenuItem>
|
||||
<fui.MenuItem
|
||||
icon={ <ic.Open20Regular /> }
|
||||
onClick={ () => browser.tabs.create({ url: browser.runtime.getURL("/sidepanel.html"), active: true }) }
|
||||
>
|
||||
Open in tab
|
||||
</fui.MenuItem>
|
||||
<fui.MenuItem
|
||||
icon={ <ic.Alert20Regular /> }
|
||||
onClick={ async () => await sendNotification({
|
||||
icon: "/notification_icons/cloud_error.png",
|
||||
message: "Notification message",
|
||||
title: "Notification title"
|
||||
}) }
|
||||
>
|
||||
Show test notification
|
||||
</fui.MenuItem>
|
||||
</fui.MenuGroup>
|
||||
}
|
||||
</fui.MenuList>
|
||||
</fui.MenuPopover>
|
||||
</fui.Menu>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user