Update sidebar (#1188)
* refactor * fix build * refactor * refactor * display deposit in sidebar header menu * minor fix * fix * fix document locate
This commit is contained in:
@@ -20,6 +20,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"cheerio": "^1.0.0",
|
||||
"swiper": "^11.1.14"
|
||||
"swiper": "^11.1.15"
|
||||
}
|
||||
}
|
||||
|
||||
0
enjoy/lib/whisper.cpp/x64/linux/.keep
Normal file
0
enjoy/lib/whisper.cpp/x64/linux/.keep
Normal file
0
enjoy/lib/whisper.cpp/x64/win32/.keep
Normal file
0
enjoy/lib/whisper.cpp/x64/win32/.keep
Normal file
@@ -40,7 +40,7 @@
|
||||
"@electron-forge/plugin-vite": "<7.5.0",
|
||||
"@electron-forge/publisher-github": "<7.5.0",
|
||||
"@electron/fuses": "^1.8.0",
|
||||
"@playwright/test": "^1.48.2",
|
||||
"@playwright/test": "^1.49.0",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"@types/ahoy.js": "^0.4.2",
|
||||
"@types/autosize": "^4.0.3",
|
||||
@@ -62,8 +62,8 @@
|
||||
"@types/unzipper": "^0.10.10",
|
||||
"@types/validator": "^13.12.2",
|
||||
"@types/wavesurfer.js": "^6.0.12",
|
||||
"@typescript-eslint/eslint-plugin": "^8.14.0",
|
||||
"@typescript-eslint/parser": "^8.14.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
||||
"@typescript-eslint/parser": "^8.15.0",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"electron": "^33.2.0",
|
||||
|
||||
@@ -199,7 +199,12 @@ export const DocumentPlayer = () => {
|
||||
data-tooltip-id="global-tooltip"
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={() => locateSegment(playingSegment.id)}
|
||||
onClick={() => {
|
||||
const el = locateSegment(playingSegment.id);
|
||||
if (el) {
|
||||
el.scrollIntoView({ behavior: "smooth" });
|
||||
}
|
||||
}}
|
||||
>
|
||||
<LocateFixedIcon className="w-4 h-4" />
|
||||
</Button>
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from "./layout";
|
||||
export * from "./title-bar";
|
||||
export * from "./sidebar";
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
PanelLeftCloseIcon,
|
||||
ChevronsUpDownIcon,
|
||||
LogOutIcon,
|
||||
CreditCardIcon,
|
||||
} from "lucide-react";
|
||||
import { useLocation, Link, useNavigate } from "react-router-dom";
|
||||
import { t } from "i18next";
|
||||
@@ -46,7 +47,7 @@ export const Sidebar = () => {
|
||||
const activeTab = location.pathname;
|
||||
const { EnjoyApp, cable, displayPreferences, setDisplayPreferences } =
|
||||
useContext(AppSettingsProviderContext);
|
||||
const [isOpen, setIsOpen] = useState(true);
|
||||
const [isCollapsed, setIsCollapsed] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!cable) return;
|
||||
@@ -61,14 +62,14 @@ export const Sidebar = () => {
|
||||
|
||||
// Save the sidebar state to cache
|
||||
useEffect(() => {
|
||||
EnjoyApp.cacheObjects.set("sidebarOpen", isOpen);
|
||||
}, [isOpen]);
|
||||
EnjoyApp.cacheObjects.set("sidebarOpen", isCollapsed);
|
||||
}, [isCollapsed]);
|
||||
|
||||
// Restore the sidebar state from cache
|
||||
useEffect(() => {
|
||||
EnjoyApp.cacheObjects.get("sidebarOpen").then((value) => {
|
||||
if (value !== undefined) {
|
||||
setIsOpen(!!value);
|
||||
setIsCollapsed(!!value);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
@@ -76,17 +77,17 @@ export const Sidebar = () => {
|
||||
return (
|
||||
<div
|
||||
className={`h-[calc(100vh-2rem)] pt-8 transition-all relative draggable-region ${
|
||||
isOpen ? "w-48" : "w-12"
|
||||
isCollapsed ? "w-12" : "w-48"
|
||||
}`}
|
||||
data-testid="sidebar"
|
||||
>
|
||||
<div
|
||||
className={`fixed top-0 left-0 h-full bg-muted ${
|
||||
isOpen ? "w-48" : "w-12"
|
||||
isCollapsed ? "w-12" : "w-48"
|
||||
}`}
|
||||
>
|
||||
<ScrollArea className="w-full h-full pb-12 pt-8">
|
||||
<SidebarHeader isOpen={isOpen} />
|
||||
<SidebarHeader isCollapsed={isCollapsed} />
|
||||
<div className="grid gap-2 mb-4">
|
||||
<SidebarItem
|
||||
href="/"
|
||||
@@ -94,7 +95,7 @@ export const Sidebar = () => {
|
||||
tooltip={t("sidebar.home")}
|
||||
active={activeTab === "/"}
|
||||
Icon={HomeIcon}
|
||||
isOpen={isOpen}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
|
||||
<SidebarItem
|
||||
@@ -103,7 +104,7 @@ export const Sidebar = () => {
|
||||
tooltip={t("sidebar.chats")}
|
||||
active={activeTab.startsWith("/chats")}
|
||||
Icon={MessagesSquareIcon}
|
||||
isOpen={isOpen}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
|
||||
<SidebarItem
|
||||
@@ -112,7 +113,7 @@ export const Sidebar = () => {
|
||||
tooltip={t("sidebar.courses")}
|
||||
active={activeTab.startsWith("/courses")}
|
||||
Icon={GraduationCapIcon}
|
||||
isOpen={isOpen}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
|
||||
<Separator />
|
||||
@@ -123,7 +124,7 @@ export const Sidebar = () => {
|
||||
tooltip={t("sidebar.audios")}
|
||||
active={activeTab.startsWith("/audios")}
|
||||
Icon={HeadphonesIcon}
|
||||
isOpen={isOpen}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
|
||||
<SidebarItem
|
||||
@@ -132,7 +133,7 @@ export const Sidebar = () => {
|
||||
tooltip={t("sidebar.videos")}
|
||||
active={activeTab.startsWith("/videos")}
|
||||
Icon={VideoIcon}
|
||||
isOpen={isOpen}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
|
||||
<SidebarItem
|
||||
@@ -141,7 +142,7 @@ export const Sidebar = () => {
|
||||
tooltip={t("sidebar.documents")}
|
||||
active={activeTab.startsWith("/documents")}
|
||||
Icon={NewspaperIcon}
|
||||
isOpen={isOpen}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
|
||||
<Separator />
|
||||
@@ -153,7 +154,7 @@ export const Sidebar = () => {
|
||||
active={activeTab.startsWith("/conversations")}
|
||||
Icon={BotIcon}
|
||||
testid="sidebar-conversations"
|
||||
isOpen={isOpen}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
|
||||
<SidebarItem
|
||||
@@ -163,7 +164,7 @@ export const Sidebar = () => {
|
||||
active={activeTab.startsWith("/pronunciation_assessments")}
|
||||
Icon={SpeechIcon}
|
||||
testid="sidebar-pronunciation-assessments"
|
||||
isOpen={isOpen}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
|
||||
<SidebarItem
|
||||
@@ -172,7 +173,7 @@ export const Sidebar = () => {
|
||||
tooltip={t("sidebar.notes")}
|
||||
active={activeTab === "/notes"}
|
||||
Icon={NotebookPenIcon}
|
||||
isOpen={isOpen}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
|
||||
<SidebarItem
|
||||
@@ -181,7 +182,7 @@ export const Sidebar = () => {
|
||||
tooltip={t("sidebar.vocabulary")}
|
||||
active={activeTab.startsWith("/vocabulary")}
|
||||
Icon={BookMarkedIcon}
|
||||
isOpen={isOpen}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
|
||||
<Separator />
|
||||
@@ -192,7 +193,7 @@ export const Sidebar = () => {
|
||||
variant={displayPreferences ? "default" : "ghost"}
|
||||
id="preferences-button"
|
||||
className={`w-full ${
|
||||
isOpen ? "justify-start" : "justify-center"
|
||||
isCollapsed ? "justify-center" : "justify-start"
|
||||
}`}
|
||||
data-tooltip-id="global-tooltip"
|
||||
data-tooltip-content={t("sidebar.preferences")}
|
||||
@@ -200,7 +201,7 @@ export const Sidebar = () => {
|
||||
onClick={() => setDisplayPreferences(true)}
|
||||
>
|
||||
<SettingsIcon className="size-4" />
|
||||
{isOpen && (
|
||||
{!isCollapsed && (
|
||||
<span className="ml-2"> {t("sidebar.preferences")} </span>
|
||||
)}
|
||||
</Button>
|
||||
@@ -228,16 +229,18 @@ export const Sidebar = () => {
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
className={`w-full non-draggable-region ${
|
||||
isOpen ? "justify-start" : "justify-center"
|
||||
isCollapsed ? "justify-center" : "justify-start"
|
||||
}`}
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
onClick={() => setIsCollapsed(!isCollapsed)}
|
||||
>
|
||||
{isOpen ? (
|
||||
<PanelLeftCloseIcon className="size-4" />
|
||||
) : (
|
||||
{isCollapsed ? (
|
||||
<PanelLeftOpenIcon className="size-4" />
|
||||
) : (
|
||||
<PanelLeftCloseIcon className="size-4" />
|
||||
)}
|
||||
{!isCollapsed && (
|
||||
<span className="ml-2"> {t("sidebar.collapse")} </span>
|
||||
)}
|
||||
{isOpen && <span className="ml-2"> {t("sidebar.collapse")} </span>}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -252,9 +255,9 @@ const SidebarItem = (props: {
|
||||
active: boolean;
|
||||
Icon: LucideIcon;
|
||||
testid?: string;
|
||||
isOpen: boolean;
|
||||
isCollapsed: boolean;
|
||||
}) => {
|
||||
const { href, label, tooltip, active, Icon, testid, isOpen } = props;
|
||||
const { href, label, tooltip, active, Icon, testid, isCollapsed } = props;
|
||||
|
||||
return (
|
||||
<Link
|
||||
@@ -268,38 +271,47 @@ const SidebarItem = (props: {
|
||||
<Button
|
||||
size="sm"
|
||||
variant={active ? "default" : "ghost"}
|
||||
className={`w-full ${isOpen ? "justify-start" : "justify-center"}`}
|
||||
className={`w-full ${isCollapsed ? "justify-center" : "justify-start"}`}
|
||||
>
|
||||
<Icon className="size-4" />
|
||||
{isOpen && <span className="ml-2">{label}</span>}
|
||||
{!isCollapsed && <span className="ml-2">{label}</span>}
|
||||
</Button>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
const SidebarHeader = (props: { isOpen: boolean }) => {
|
||||
const { isOpen } = props;
|
||||
const { user, logout } = useContext(AppSettingsProviderContext);
|
||||
const SidebarHeader = (props: { isCollapsed: boolean }) => {
|
||||
const { isCollapsed } = props;
|
||||
const { user, logout, refreshAccount, setDisplayDepositDialog } = useContext(
|
||||
AppSettingsProviderContext
|
||||
);
|
||||
const [open, setOpen] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
refreshAccount?.();
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="py-3 px-1 sticky top-0 bg-muted z-10 non-draggable-region">
|
||||
<DropdownMenu>
|
||||
<DropdownMenu open={open} onOpenChange={setOpen}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
className={`w-full h-12 hover:bg-background ${
|
||||
isOpen ? "justify-start" : "justify-center px-1"
|
||||
isCollapsed ? "justify-center px-1" : "justify-start"
|
||||
}`}
|
||||
>
|
||||
<Avatar className="size-8">
|
||||
<AvatarImage src={user.avatarUrl} />
|
||||
</Avatar>
|
||||
{isOpen && (
|
||||
{!isCollapsed && (
|
||||
<>
|
||||
<div className="ml-2 flex flex-col leading-none">
|
||||
<span className="text-left text-sm font-medium line-clamp-1">
|
||||
@@ -334,6 +346,14 @@ const SidebarHeader = (props: { isOpen: boolean }) => {
|
||||
<UsersRoundIcon className="size-4 ml-auto" />
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
onSelect={() => setDisplayDepositDialog(true)}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
<span className="flex-1 truncate">${user.balance}</span>
|
||||
<CreditCardIcon className="size-4 ml-auto" />
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem onSelect={logout} className="cursor-pointer">
|
||||
<span>{t("logout")}</span>
|
||||
<LogOutIcon className="size-4 ml-auto" />
|
||||
@@ -4,7 +4,6 @@ export * from "./markdown-wrapper";
|
||||
export * from "./no-records-found";
|
||||
export * from "./page-placeholder";
|
||||
export * from "./universal-player";
|
||||
export * from "./sidebar";
|
||||
export * from "./wavesurfer-player";
|
||||
export * from "./tts-form";
|
||||
export * from "./gpt-form";
|
||||
|
||||
@@ -6,248 +6,43 @@ import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
DialogClose,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCaption,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
toast,
|
||||
Separator,
|
||||
} from "@renderer/components/ui";
|
||||
import { LoaderSpin } from "@renderer/components";
|
||||
import { LoaderIcon } from "lucide-react";
|
||||
import { formatDateTime } from "@/renderer/lib/utils";
|
||||
import Chart from "chart.js/auto";
|
||||
|
||||
export const BalanceSettings = () => {
|
||||
const { webApi, EnjoyApp } = useContext(AppSettingsProviderContext);
|
||||
const [balance, setBalance] = useState<number>(0);
|
||||
const [depositAmount, setDepositAmount] = useState<number>(10);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [paymentCreated, setPaymentCreated] = useState<boolean>(false);
|
||||
const [payments, setPayments] = useState<any[]>([]);
|
||||
const { refreshAccount, user, setDisplayDepositDialog } = useContext(
|
||||
AppSettingsProviderContext
|
||||
);
|
||||
const [displayUsage, setDisplayUsage] = useState<boolean>(false);
|
||||
|
||||
const refreshPayments = () => {
|
||||
webApi
|
||||
.payments({
|
||||
paymentType: "deposit",
|
||||
})
|
||||
.then(({ payments }) => {
|
||||
setPayments(payments);
|
||||
})
|
||||
.catch((error) => {
|
||||
toast.error(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
const refreshBalance = () => {
|
||||
webApi.me().then((user) => {
|
||||
setBalance(user.balance);
|
||||
});
|
||||
};
|
||||
|
||||
const createDepositPayment = (processor = "stripe") => {
|
||||
if (loading) return;
|
||||
|
||||
setLoading(true);
|
||||
webApi
|
||||
.createPayment({
|
||||
amount: depositAmount,
|
||||
paymentType: "deposit",
|
||||
processor,
|
||||
})
|
||||
.then((payment) => {
|
||||
if (payment?.payUrl) {
|
||||
setPaymentCreated(true);
|
||||
EnjoyApp.shell.openExternal(payment.payUrl);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
toast.error(error.message);
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
refreshBalance();
|
||||
refreshAccount?.();
|
||||
}, []);
|
||||
|
||||
if (!balance) return null;
|
||||
if (!user?.balance) return null;
|
||||
|
||||
return (
|
||||
<div className="flex items-start justify-between py-4">
|
||||
<div className="">
|
||||
<div className="mb-2">{t("balance")}</div>
|
||||
<div className="text-sm text-muted-foreground mb-2">${balance}</div>
|
||||
<div className="text-sm text-muted-foreground mb-2">
|
||||
${user.balance}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2 items-center">
|
||||
<Dialog
|
||||
onOpenChange={(value) => {
|
||||
if (value) {
|
||||
refreshPayments();
|
||||
} else {
|
||||
setPaymentCreated(false);
|
||||
refreshBalance();
|
||||
}
|
||||
}}
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
className=""
|
||||
onClick={() => setDisplayDepositDialog(true)}
|
||||
>
|
||||
<DialogTrigger asChild>
|
||||
<Button
|
||||
onClick={() => setPaymentCreated(false)}
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
className=""
|
||||
>
|
||||
{t("deposit")}
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent className="max-h-full overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t("deposit")}</DialogTitle>
|
||||
<DialogDescription>{t("depositDescription")}</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
{paymentCreated ? (
|
||||
<>
|
||||
<LoaderSpin />
|
||||
<div className="text-center">
|
||||
{t("pleaseCompletePaymentInPopupWindow")}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
{[2, 10, 50, 100].map((amount) => (
|
||||
<div
|
||||
className={`text-xl w-full h-20 border rounded-md flex items-center justify-center cursor-pointer shadow hover:bg-gray-100 hover:dark:text-primary-foreground transition-colors duration-200 ease-in-out ${
|
||||
amount == depositAmount
|
||||
? "bg-gray-100 dark:text-primary-foreground"
|
||||
: ""
|
||||
}`}
|
||||
key={`deposit-amount-${amount}`}
|
||||
onClick={() => setDepositAmount(amount)}
|
||||
>
|
||||
${amount}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="text-sm">{t("depositDisclaimer")}</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Separator />
|
||||
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="flex items-center w-64 justify-around">
|
||||
<img
|
||||
src="assets/usdt.png"
|
||||
className="w-auto h-8 rounded-full"
|
||||
/>
|
||||
<img src="assets/usdc.png" className="w-auto h-8" />
|
||||
<img src="assets/eth.png" className="w-auto h-8" />
|
||||
<img src="assets/trx.png" className="w-auto h-8" />
|
||||
<img src="assets/doge.png" className="w-auto h-8" />
|
||||
<img src="assets/bnb.png" className="w-auto h-8" />
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="default"
|
||||
disabled={paymentCreated || loading}
|
||||
className="w-32 bg-blue-500 hover:bg-blue-600 transition-colors duration-200 ease-in-out"
|
||||
onClick={() => createDepositPayment("mixin")}
|
||||
>
|
||||
{loading && (
|
||||
<LoaderIcon className="w-4 h-4 mr-2 animate-spin" />
|
||||
)}
|
||||
<span>Crypto {t("pay")}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="flex items-center w-64 justify-around">
|
||||
<img src="assets/mastercard.png" className="w-auto h-8" />
|
||||
<img src="assets/visa.png" className="w-auto h-8" />
|
||||
<img src="assets/unionpay.png" className="w-auto h-8" />
|
||||
<img src="assets/alipay.png" className="w-auto h-8" />
|
||||
<img src="assets/wechatpay.png" className="w-auto h-8" />
|
||||
</div>
|
||||
<Button
|
||||
className="w-32"
|
||||
variant="default"
|
||||
disabled={paymentCreated || loading}
|
||||
onClick={() => createDepositPayment()}
|
||||
>
|
||||
{loading && (
|
||||
<LoaderIcon className="w-4 h-4 mr-2 animate-spin" />
|
||||
)}
|
||||
<span>Stripe {t("pay")}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
<Button variant="secondary">
|
||||
{paymentCreated ? t("finish") : t("cancel")}
|
||||
</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
|
||||
{payments.length > 0 && (
|
||||
<div className="">
|
||||
<Table>
|
||||
<TableCaption>{t("recentDeposits")}</TableCaption>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead className="capitalize">
|
||||
{t("amount")}
|
||||
</TableHead>
|
||||
<TableHead className="capitalize">
|
||||
{t("status")}
|
||||
</TableHead>
|
||||
<TableHead className="capitalize">
|
||||
{t("processor")}
|
||||
</TableHead>
|
||||
<TableHead className="capitalize">{t("date")}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{payments.map((payment) => (
|
||||
<TableRow key={payment.id}>
|
||||
<TableCell>
|
||||
<span className="text-xs bg-muted font-mono p-0.5 rounded select-text">
|
||||
{payment.id.split("-").shift()}
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell>${payment.amount}</TableCell>
|
||||
<TableCell className="">{payment.status}</TableCell>
|
||||
<TableCell className="capitalize">
|
||||
{payment.processor}
|
||||
</TableCell>
|
||||
<TableCell className="text-xs">
|
||||
{formatDateTime(payment.createdAt)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
)}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
{t("deposit")}
|
||||
</Button>
|
||||
|
||||
<Dialog open={displayUsage} onOpenChange={setDisplayUsage}>
|
||||
<DialogTrigger asChild>
|
||||
|
||||
177
enjoy/src/renderer/components/preferences/deposit.tsx
Normal file
177
enjoy/src/renderer/components/preferences/deposit.tsx
Normal file
@@ -0,0 +1,177 @@
|
||||
import { t } from "i18next";
|
||||
import { AppSettingsProviderContext } from "@renderer/context";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import {
|
||||
Button,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCaption,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
toast,
|
||||
Separator,
|
||||
} from "@renderer/components/ui";
|
||||
import { LoaderSpin } from "@renderer/components";
|
||||
import { LoaderIcon } from "lucide-react";
|
||||
import { formatDateTime } from "@/renderer/lib/utils";
|
||||
|
||||
export const Deposit = () => {
|
||||
const { webApi, EnjoyApp } = useContext(AppSettingsProviderContext);
|
||||
const [paymentCreated, setPaymentCreated] = useState<boolean>(false);
|
||||
const [payments, setPayments] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [depositAmount, setDepositAmount] = useState<number>(10);
|
||||
|
||||
const refreshPayments = () => {
|
||||
webApi
|
||||
.payments({
|
||||
paymentType: "deposit",
|
||||
})
|
||||
.then(({ payments }) => {
|
||||
setPayments(payments);
|
||||
})
|
||||
.catch((error) => {
|
||||
toast.error(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
const createDepositPayment = (processor = "stripe") => {
|
||||
if (loading) return;
|
||||
|
||||
setLoading(true);
|
||||
webApi
|
||||
.createPayment({
|
||||
amount: depositAmount,
|
||||
paymentType: "deposit",
|
||||
processor,
|
||||
})
|
||||
.then((payment) => {
|
||||
if (payment?.payUrl) {
|
||||
setPaymentCreated(true);
|
||||
EnjoyApp.shell.openExternal(payment.payUrl);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
toast.error(error.message);
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
refreshPayments();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
{paymentCreated ? (
|
||||
<>
|
||||
<LoaderSpin />
|
||||
<div className="text-center">
|
||||
{t("pleaseCompletePaymentInPopupWindow")}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
{[2, 10, 50, 100].map((amount) => (
|
||||
<div
|
||||
className={`text-xl w-full h-20 border rounded-md flex items-center justify-center cursor-pointer shadow hover:bg-gray-100 hover:dark:text-primary-foreground transition-colors duration-200 ease-in-out ${
|
||||
amount == depositAmount
|
||||
? "bg-gray-100 dark:text-primary-foreground"
|
||||
: ""
|
||||
}`}
|
||||
key={`deposit-amount-${amount}`}
|
||||
onClick={() => setDepositAmount(amount)}
|
||||
>
|
||||
${amount}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="text-sm">{t("depositDisclaimer")}</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Separator />
|
||||
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="flex items-center w-64 justify-around">
|
||||
<img src="assets/usdt.png" className="w-auto h-8 rounded-full" />
|
||||
<img src="assets/usdc.png" className="w-auto h-8" />
|
||||
<img src="assets/eth.png" className="w-auto h-8" />
|
||||
<img src="assets/trx.png" className="w-auto h-8" />
|
||||
<img src="assets/doge.png" className="w-auto h-8" />
|
||||
<img src="assets/bnb.png" className="w-auto h-8" />
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="default"
|
||||
disabled={paymentCreated || loading}
|
||||
className="w-32 bg-blue-500 hover:bg-blue-600 transition-colors duration-200 ease-in-out"
|
||||
onClick={() => createDepositPayment("mixin")}
|
||||
>
|
||||
{loading && <LoaderIcon className="w-4 h-4 mr-2 animate-spin" />}
|
||||
<span>Crypto {t("pay")}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="flex items-center w-64 justify-around">
|
||||
<img src="assets/mastercard.png" className="w-auto h-8" />
|
||||
<img src="assets/visa.png" className="w-auto h-8" />
|
||||
<img src="assets/unionpay.png" className="w-auto h-8" />
|
||||
<img src="assets/alipay.png" className="w-auto h-8" />
|
||||
<img src="assets/wechatpay.png" className="w-auto h-8" />
|
||||
</div>
|
||||
<Button
|
||||
className="w-32"
|
||||
variant="default"
|
||||
disabled={paymentCreated || loading}
|
||||
onClick={() => createDepositPayment()}
|
||||
>
|
||||
{loading && <LoaderIcon className="w-4 h-4 mr-2 animate-spin" />}
|
||||
<span>Stripe {t("pay")}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
{payments.length > 0 && (
|
||||
<Table>
|
||||
<TableCaption>{t("recentDeposits")}</TableCaption>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>ID</TableHead>
|
||||
<TableHead className="capitalize">{t("amount")}</TableHead>
|
||||
<TableHead className="capitalize">{t("status")}</TableHead>
|
||||
<TableHead className="capitalize">{t("processor")}</TableHead>
|
||||
<TableHead className="capitalize">{t("date")}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{payments.map((payment) => (
|
||||
<TableRow key={payment.id}>
|
||||
<TableCell>
|
||||
<span className="text-xs bg-muted font-mono p-0.5 rounded select-text">
|
||||
{payment.id.split("-").shift()}
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell>${payment.amount}</TableCell>
|
||||
<TableCell className="">{payment.status}</TableCell>
|
||||
<TableCell className="capitalize">
|
||||
{payment.processor}
|
||||
</TableCell>
|
||||
<TableCell className="text-xs">
|
||||
{formatDateTime(payment.createdAt)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -37,3 +37,5 @@ export * from "./vocabulary-settings";
|
||||
export * from "./dict-settings";
|
||||
|
||||
export * from "./echogarden-stt-settings";
|
||||
|
||||
export * from "./deposit";
|
||||
|
||||
@@ -15,10 +15,18 @@ import {
|
||||
AlertDialogFooter,
|
||||
AlertDialogCancel,
|
||||
AlertDialogAction,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogClose,
|
||||
Button,
|
||||
} from "@renderer/components/ui";
|
||||
import { t } from "i18next";
|
||||
import { redirect } from "react-router-dom";
|
||||
import { Preferences } from "@renderer/components";
|
||||
import { Deposit } from "@renderer/components";
|
||||
|
||||
type AppSettingsProviderState = {
|
||||
webApi: Client;
|
||||
@@ -31,6 +39,7 @@ type AppSettingsProviderState = {
|
||||
libraryPath?: string;
|
||||
login?: (user: UserType) => void;
|
||||
logout?: () => void;
|
||||
refreshAccount?: () => Promise<void>;
|
||||
setLibraryPath?: (path: string) => Promise<void>;
|
||||
EnjoyApp: EnjoyAppType;
|
||||
language?: "en" | "zh-CN";
|
||||
@@ -51,6 +60,8 @@ type AppSettingsProviderState = {
|
||||
ipaMappings?: { [key: string]: string };
|
||||
displayPreferences?: boolean;
|
||||
setDisplayPreferences?: (display: boolean) => void;
|
||||
displayDepositDialog?: boolean;
|
||||
setDisplayDepositDialog?: (display: boolean) => void;
|
||||
};
|
||||
|
||||
const EnjoyApp = window.__ENJOY_APP__;
|
||||
@@ -88,6 +99,8 @@ export const AppSettingsProvider = ({
|
||||
IPA_MAPPINGS
|
||||
);
|
||||
const [loggingOut, setLoggingOut] = useState<boolean>(false);
|
||||
const [displayDepositDialog, setDisplayDepositDialog] =
|
||||
useState<boolean>(false);
|
||||
const [displayPreferences, setDisplayPreferences] = useState<boolean>(false);
|
||||
|
||||
const db = useContext(DbProviderContext);
|
||||
@@ -245,6 +258,15 @@ export const AppSettingsProvider = ({
|
||||
setVocabularyConfig(config);
|
||||
};
|
||||
|
||||
const refreshAccount = async () => {
|
||||
webApi.me().then((u) => {
|
||||
setUser({
|
||||
...user,
|
||||
...u,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (db.state === "connected") {
|
||||
fetchLanguages();
|
||||
@@ -340,6 +362,7 @@ export const AppSettingsProvider = ({
|
||||
user,
|
||||
login,
|
||||
logout: () => setLoggingOut(true),
|
||||
refreshAccount,
|
||||
libraryPath,
|
||||
setLibraryPath: setLibraryPathHandler,
|
||||
proxy,
|
||||
@@ -354,6 +377,8 @@ export const AppSettingsProvider = ({
|
||||
ipaMappings,
|
||||
displayPreferences,
|
||||
setDisplayPreferences,
|
||||
displayDepositDialog,
|
||||
setDisplayDepositDialog,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
@@ -380,6 +405,26 @@ export const AppSettingsProvider = ({
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
||||
<Dialog
|
||||
open={displayDepositDialog}
|
||||
onOpenChange={setDisplayDepositDialog}
|
||||
>
|
||||
<DialogContent className="max-h-full overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t("deposit")}</DialogTitle>
|
||||
<DialogDescription>{t("depositDescription")}</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
{displayDepositDialog && <Deposit />}
|
||||
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
<Button variant="secondary">{t("close")}</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</AppSettingsProviderContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9,9 +9,7 @@ import {
|
||||
} from "@renderer/context";
|
||||
|
||||
export default () => {
|
||||
const { initialized, EnjoyApp, user } = useContext(
|
||||
AppSettingsProviderContext
|
||||
);
|
||||
const { initialized, user } = useContext(AppSettingsProviderContext);
|
||||
const [started, setStarted] = useState(false);
|
||||
const db = useContext(DbProviderContext);
|
||||
|
||||
|
||||
@@ -15,6 +15,35 @@ export default defineConfig((env) => {
|
||||
const forgeEnv = env as ConfigEnv<"build">;
|
||||
const { forgeConfigSelf } = forgeEnv;
|
||||
const define = getBuildDefine(forgeEnv);
|
||||
const staticCopyTargets = [
|
||||
{
|
||||
src: `lib/youtubedr/${
|
||||
process.env.PACKAGE_OS_ARCH || os.arch()
|
||||
}/${os.platform()}/*`,
|
||||
dest: "lib/youtubedr",
|
||||
},
|
||||
{
|
||||
src: "lib/dictionaries/*",
|
||||
dest: "lib/dictionaries",
|
||||
},
|
||||
{
|
||||
src: "src/main/db/migrations/*",
|
||||
dest: "migrations",
|
||||
},
|
||||
{
|
||||
src: "samples/*",
|
||||
dest: "samples",
|
||||
},
|
||||
];
|
||||
|
||||
if (os.platform() === "darwin") {
|
||||
staticCopyTargets.push({
|
||||
src: `lib/whisper.cpp/${
|
||||
process.env.PACKAGE_OS_ARCH || os.arch()
|
||||
}/${os.platform()}/*`,
|
||||
dest: "lib/whisper",
|
||||
});
|
||||
}
|
||||
const config: UserConfig = {
|
||||
build: {
|
||||
lib: {
|
||||
@@ -44,32 +73,7 @@ export default defineConfig((env) => {
|
||||
plugins: [
|
||||
pluginHotRestart("restart"),
|
||||
viteStaticCopy({
|
||||
targets: [
|
||||
{
|
||||
src: `lib/whisper.cpp/${
|
||||
process.env.PACKAGE_OS_ARCH || os.arch()
|
||||
}/${os.platform()}/*`,
|
||||
dest: "lib/whisper",
|
||||
},
|
||||
{
|
||||
src: `lib/youtubedr/${
|
||||
process.env.PACKAGE_OS_ARCH || os.arch()
|
||||
}/${os.platform()}/*`,
|
||||
dest: "lib/youtubedr",
|
||||
},
|
||||
{
|
||||
src: "lib/dictionaries/*",
|
||||
dest: "lib/dictionaries",
|
||||
},
|
||||
{
|
||||
src: "src/main/db/migrations/*",
|
||||
dest: "migrations",
|
||||
},
|
||||
{
|
||||
src: "samples/*",
|
||||
dest: "samples",
|
||||
},
|
||||
],
|
||||
targets: staticCopyTargets,
|
||||
}),
|
||||
],
|
||||
define,
|
||||
|
||||
154
yarn.lock
154
yarn.lock
@@ -18,7 +18,7 @@ __metadata:
|
||||
markdown-it-sup: "npm:^2.0.0"
|
||||
mermaid: "npm:^11.4.0"
|
||||
sass: "npm:^1.81.0"
|
||||
swiper: "npm:^11.1.14"
|
||||
swiper: "npm:^11.1.15"
|
||||
vitepress: "npm:^1.5.0"
|
||||
vitepress-plugin-mermaid: "npm:^2.0.17"
|
||||
vue: "npm:^3.5.13"
|
||||
@@ -4499,14 +4499,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@playwright/test@npm:^1.48.2":
|
||||
version: 1.48.2
|
||||
resolution: "@playwright/test@npm:1.48.2"
|
||||
"@playwright/test@npm:^1.49.0":
|
||||
version: 1.49.0
|
||||
resolution: "@playwright/test@npm:1.49.0"
|
||||
dependencies:
|
||||
playwright: "npm:1.48.2"
|
||||
playwright: "npm:1.49.0"
|
||||
bin:
|
||||
playwright: cli.js
|
||||
checksum: 10c0/68bab3bee8d716111e9a166785e6c3c406b6a184fc46d03b5468fcbb92b6242e5628f6a75f9d286e2491ec0e9e59af67542a1f114b6659d790b5a1f41e4d305b
|
||||
checksum: 10c0/2890d52ee45bd83b5501f17a77c77f12ba934d257fda4b288405c6d91f94b83c4fcbdff3c0be89c2aaeea3d13576b72ec9a70be667ff844b342044afd72a246e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -7719,15 +7719,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/eslint-plugin@npm:^8.14.0":
|
||||
version: 8.14.0
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:8.14.0"
|
||||
"@typescript-eslint/eslint-plugin@npm:^8.15.0":
|
||||
version: 8.15.0
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:8.15.0"
|
||||
dependencies:
|
||||
"@eslint-community/regexpp": "npm:^4.10.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.14.0"
|
||||
"@typescript-eslint/type-utils": "npm:8.14.0"
|
||||
"@typescript-eslint/utils": "npm:8.14.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.14.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.15.0"
|
||||
"@typescript-eslint/type-utils": "npm:8.15.0"
|
||||
"@typescript-eslint/utils": "npm:8.15.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.15.0"
|
||||
graphemer: "npm:^1.4.0"
|
||||
ignore: "npm:^5.3.1"
|
||||
natural-compare: "npm:^1.4.0"
|
||||
@@ -7738,66 +7738,68 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10c0/46c82eb45be82ffec0ab04728a5180691b1d17002c669864861a3044b6d2105a75ca23cc80d18721b40b5e7dff1eff4ed68a43d726e25d55f3e466a9fbeeb873
|
||||
checksum: 10c0/90ef10cc7d37a81abec4f4a3ffdfc3a0da8e99d949e03c75437e96e8ab2e896e34b85ab64718690180a7712581031b8611c5d8e7666d6ed4d60b9ace834d58e3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/parser@npm:^8.14.0":
|
||||
version: 8.14.0
|
||||
resolution: "@typescript-eslint/parser@npm:8.14.0"
|
||||
"@typescript-eslint/parser@npm:^8.15.0":
|
||||
version: 8.15.0
|
||||
resolution: "@typescript-eslint/parser@npm:8.15.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager": "npm:8.14.0"
|
||||
"@typescript-eslint/types": "npm:8.14.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.14.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.14.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.15.0"
|
||||
"@typescript-eslint/types": "npm:8.15.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.15.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.15.0"
|
||||
debug: "npm:^4.3.4"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10c0/522b7afd25cd302c0510cc71985ba55ff92ecc5dbe3fc74a76fefea0169252fdd4b8cad6291fef05f63dfc173951af450dca20859c7f23e387b2e7410e8b97b1
|
||||
checksum: 10c0/19c25aea0dc51faa758701a5319a89950fd30494d9d645db8ced84fb60714c5e7d4b51fc4ee8ccb07ddefec88c51ee307ee7e49addd6330ee8f3e7ee9ba329fc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/scope-manager@npm:8.14.0":
|
||||
version: 8.14.0
|
||||
resolution: "@typescript-eslint/scope-manager@npm:8.14.0"
|
||||
"@typescript-eslint/scope-manager@npm:8.15.0":
|
||||
version: 8.15.0
|
||||
resolution: "@typescript-eslint/scope-manager@npm:8.15.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.14.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.14.0"
|
||||
checksum: 10c0/1e1295c6f9febadf63559aad328b23d960510ce6b4c9f74e10d881c3858fa7f1db767cd1af5272d2fe7c9c5c7daebee71854e6f841e413e5d70af282f6616e26
|
||||
"@typescript-eslint/types": "npm:8.15.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.15.0"
|
||||
checksum: 10c0/c27dfdcea4100cc2d6fa967f857067cbc93155b55e648f9f10887a1b9372bb76cf864f7c804f3fa48d7868d9461cdef10bcea3dab7637d5337e8aa8042dc08b9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/type-utils@npm:8.14.0":
|
||||
version: 8.14.0
|
||||
resolution: "@typescript-eslint/type-utils@npm:8.14.0"
|
||||
"@typescript-eslint/type-utils@npm:8.15.0":
|
||||
version: 8.15.0
|
||||
resolution: "@typescript-eslint/type-utils@npm:8.15.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree": "npm:8.14.0"
|
||||
"@typescript-eslint/utils": "npm:8.14.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.15.0"
|
||||
"@typescript-eslint/utils": "npm:8.15.0"
|
||||
debug: "npm:^4.3.4"
|
||||
ts-api-utils: "npm:^1.3.0"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10c0/42616a664b38ca418e13504247e5e1bad6ae85c045b48e5735ffab977d4bd58cc86fb9d2292bbb314fa408d78d4b0454c3a27dbf9f881f9921917a942825c806
|
||||
checksum: 10c0/20f09c79c83b38a962cf7eff10d47a2c01bcc0bab7bf6d762594221cd89023ef8c7aec26751c47b524f53f5c8d38bba55a282529b3df82d5f5ab4350496316f9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/types@npm:8.14.0":
|
||||
version: 8.14.0
|
||||
resolution: "@typescript-eslint/types@npm:8.14.0"
|
||||
checksum: 10c0/7707f900e24e60e6780c5705f69627b7c0ef912cb3b095dfc8f4a0c84e866c66b1c4c10278cf99724560dc66985ec640750c4192786a09b853f9bb4c3ca5a7ce
|
||||
"@typescript-eslint/types@npm:8.15.0":
|
||||
version: 8.15.0
|
||||
resolution: "@typescript-eslint/types@npm:8.15.0"
|
||||
checksum: 10c0/84abc6fd954aff13822a76ac49efdcb90a55c0025c20eee5d8cebcfb68faff33b79bbc711ea524e0209cecd90c5ee3a5f92babc7083c081d3a383a0710264a41
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/typescript-estree@npm:8.14.0":
|
||||
version: 8.14.0
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:8.14.0"
|
||||
"@typescript-eslint/typescript-estree@npm:8.15.0":
|
||||
version: 8.15.0
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:8.15.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.14.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.14.0"
|
||||
"@typescript-eslint/types": "npm:8.15.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:8.15.0"
|
||||
debug: "npm:^4.3.4"
|
||||
fast-glob: "npm:^3.3.2"
|
||||
is-glob: "npm:^4.0.3"
|
||||
@@ -7807,31 +7809,34 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10c0/5e890d22bd067095f871cf144907a8c302db5b5f014c58906ad58d7f23569951cba805042eac6844744e5abb0d3648c9cc221a91b0703da0a8d6345dc1f83e74
|
||||
checksum: 10c0/3af5c129532db3575349571bbf64d32aeccc4f4df924ac447f5d8f6af8b387148df51965eb2c9b99991951d3dadef4f2509d7ce69bf34a2885d013c040762412
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/utils@npm:8.14.0":
|
||||
version: 8.14.0
|
||||
resolution: "@typescript-eslint/utils@npm:8.14.0"
|
||||
"@typescript-eslint/utils@npm:8.15.0":
|
||||
version: 8.15.0
|
||||
resolution: "@typescript-eslint/utils@npm:8.15.0"
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils": "npm:^4.4.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.14.0"
|
||||
"@typescript-eslint/types": "npm:8.14.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.14.0"
|
||||
"@typescript-eslint/scope-manager": "npm:8.15.0"
|
||||
"@typescript-eslint/types": "npm:8.15.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:8.15.0"
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
checksum: 10c0/1fcc2651d870832a799a5d1c85fc9421853508a006d6a6073c8316b012489dda77e123d13aea8f53eb9030a2da2c0eb273a6946a9941caa2519b99b33e89b720
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10c0/65743f51845a1f6fd2d21f66ca56182ba33e966716bdca73d30b7a67c294e47889c322de7d7b90ab0818296cd33c628e5eeeb03cec7ef2f76c47de7a453eeda2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/visitor-keys@npm:8.14.0":
|
||||
version: 8.14.0
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:8.14.0"
|
||||
"@typescript-eslint/visitor-keys@npm:8.15.0":
|
||||
version: 8.15.0
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:8.15.0"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:8.14.0"
|
||||
eslint-visitor-keys: "npm:^3.4.3"
|
||||
checksum: 10c0/d0faf70ed9ecff5e36694bbb161a90bea6db59e0e79a7d4f264d67d565c12b13733d664b736b2730935f013c87ce3155cea954a533d28e99987681bc5f6259c3
|
||||
"@typescript-eslint/types": "npm:8.15.0"
|
||||
eslint-visitor-keys: "npm:^4.2.0"
|
||||
checksum: 10c0/02a954c3752c4328482a884eb1da06ca8fb72ae78ef28f1d854b18f3779406ed47263af22321cf3f65a637ec7584e5f483e34a263b5c8cec60ec85aebc263574
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -11987,7 +11992,7 @@ __metadata:
|
||||
"@langchain/core": "npm:^0.3.18"
|
||||
"@langchain/ollama": "npm:^0.1.2"
|
||||
"@mozilla/readability": "npm:^0.5.0"
|
||||
"@playwright/test": "npm:^1.48.2"
|
||||
"@playwright/test": "npm:^1.49.0"
|
||||
"@radix-ui/react-accordion": "npm:^1.2.1"
|
||||
"@radix-ui/react-alert-dialog": "npm:^1.1.2"
|
||||
"@radix-ui/react-aspect-ratio": "npm:^1.1.0"
|
||||
@@ -12035,8 +12040,8 @@ __metadata:
|
||||
"@types/unzipper": "npm:^0.10.10"
|
||||
"@types/validator": "npm:^13.12.2"
|
||||
"@types/wavesurfer.js": "npm:^6.0.12"
|
||||
"@typescript-eslint/eslint-plugin": "npm:^8.14.0"
|
||||
"@typescript-eslint/parser": "npm:^8.14.0"
|
||||
"@typescript-eslint/eslint-plugin": "npm:^8.15.0"
|
||||
"@typescript-eslint/parser": "npm:^8.15.0"
|
||||
"@uidotdev/usehooks": "npm:^2.4.1"
|
||||
"@vidstack/react": "npm:^1.12.12"
|
||||
"@vitejs/plugin-react": "npm:^4.3.3"
|
||||
@@ -19236,7 +19241,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"playwright-core@npm:1.48.2, playwright-core@npm:^1.48.2":
|
||||
"playwright-core@npm:1.49.0":
|
||||
version: 1.49.0
|
||||
resolution: "playwright-core@npm:1.49.0"
|
||||
bin:
|
||||
playwright-core: cli.js
|
||||
checksum: 10c0/22c1a72fabdcc87bd1cd4d40a032d2c5b94cf94ba7484dc182048c3fa1c8ec26180b559d8cac4ca9870e8fd6bdf5ef9d9f54e7a31fd60d67d098fcffc5e4253b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"playwright-core@npm:^1.48.2":
|
||||
version: 1.48.2
|
||||
resolution: "playwright-core@npm:1.48.2"
|
||||
bin:
|
||||
@@ -19245,18 +19259,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"playwright@npm:1.48.2":
|
||||
version: 1.48.2
|
||||
resolution: "playwright@npm:1.48.2"
|
||||
"playwright@npm:1.49.0":
|
||||
version: 1.49.0
|
||||
resolution: "playwright@npm:1.49.0"
|
||||
dependencies:
|
||||
fsevents: "npm:2.3.2"
|
||||
playwright-core: "npm:1.48.2"
|
||||
playwright-core: "npm:1.49.0"
|
||||
dependenciesMeta:
|
||||
fsevents:
|
||||
optional: true
|
||||
bin:
|
||||
playwright: cli.js
|
||||
checksum: 10c0/ecde4ee4767556868b24d7700f3502692a3cb14c8ef127052b51b48833ffcce80942954fb188a9b72505122b48b1b625d1bb486721e1c4f2e980215328ba1ad5
|
||||
checksum: 10c0/e94d662747cd147d0573570fec90dadc013c1097595714036fc8934a075c5a82ab04a49111b03b1f762ea86429bdb7c94460901896901e20970b30ce817cc93f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -22103,10 +22117,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"swiper@npm:^11.1.14":
|
||||
version: 11.1.14
|
||||
resolution: "swiper@npm:11.1.14"
|
||||
checksum: 10c0/a1075cbd2254aedd22b411ea03cbd7a91ba1cc79d7c2dc41f215e987811e449a2915a26b39fdfc1d7c08250fa2cfbe51d28476f834e75033c73ea357a4ac9f8d
|
||||
"swiper@npm:^11.1.15":
|
||||
version: 11.1.15
|
||||
resolution: "swiper@npm:11.1.15"
|
||||
checksum: 10c0/3faabc5b33c0663513e8e41c4ef7920d4c9a1ca6b988848f2e51e1db0d01471a1bae22fce3177b9d3ab2c128fc6df23074415ae7957bd0f8542fd7387fa5263d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user