From 59bcb437f8301b6507918249801315e74e6db657 Mon Sep 17 00:00:00 2001 From: an-lee Date: Tue, 19 Nov 2024 09:34:40 +0800 Subject: [PATCH] Update sidebar (#1188) * refactor * fix build * refactor * refactor * display deposit in sidebar header menu * minor fix * fix * fix document locate --- 1000-hours/package.json | 2 +- enjoy/lib/whisper.cpp/x64/linux/.keep | 0 enjoy/lib/whisper.cpp/x64/win32/.keep | 0 enjoy/package.json | 6 +- .../components/documents/document-player.tsx | 7 +- .../src/renderer/components/layouts/index.ts | 1 + .../components/{misc => layouts}/sidebar.tsx | 90 ++++--- enjoy/src/renderer/components/misc/index.ts | 1 - .../preferences/balance-settings.tsx | 237 ++---------------- .../components/preferences/deposit.tsx | 177 +++++++++++++ .../renderer/components/preferences/index.ts | 2 + .../context/app-settings-provider.tsx | 47 +++- enjoy/src/renderer/pages/landing.tsx | 4 +- enjoy/vite.main.config.ts | 56 +++-- yarn.lock | 154 ++++++------ 15 files changed, 422 insertions(+), 362 deletions(-) create mode 100644 enjoy/lib/whisper.cpp/x64/linux/.keep create mode 100644 enjoy/lib/whisper.cpp/x64/win32/.keep rename enjoy/src/renderer/components/{misc => layouts}/sidebar.tsx (80%) create mode 100644 enjoy/src/renderer/components/preferences/deposit.tsx diff --git a/1000-hours/package.json b/1000-hours/package.json index f818b1ab..f5ea4794 100644 --- a/1000-hours/package.json +++ b/1000-hours/package.json @@ -20,6 +20,6 @@ }, "dependencies": { "cheerio": "^1.0.0", - "swiper": "^11.1.14" + "swiper": "^11.1.15" } } diff --git a/enjoy/lib/whisper.cpp/x64/linux/.keep b/enjoy/lib/whisper.cpp/x64/linux/.keep new file mode 100644 index 00000000..e69de29b diff --git a/enjoy/lib/whisper.cpp/x64/win32/.keep b/enjoy/lib/whisper.cpp/x64/win32/.keep new file mode 100644 index 00000000..e69de29b diff --git a/enjoy/package.json b/enjoy/package.json index eea0f59e..6ab87a89 100644 --- a/enjoy/package.json +++ b/enjoy/package.json @@ -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", diff --git a/enjoy/src/renderer/components/documents/document-player.tsx b/enjoy/src/renderer/components/documents/document-player.tsx index 7ee1a5e5..eb8d71aa 100644 --- a/enjoy/src/renderer/components/documents/document-player.tsx +++ b/enjoy/src/renderer/components/documents/document-player.tsx @@ -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" }); + } + }} > diff --git a/enjoy/src/renderer/components/layouts/index.ts b/enjoy/src/renderer/components/layouts/index.ts index 325b6fdc..b5c87d97 100644 --- a/enjoy/src/renderer/components/layouts/index.ts +++ b/enjoy/src/renderer/components/layouts/index.ts @@ -1,2 +1,3 @@ export * from "./layout"; export * from "./title-bar"; +export * from "./sidebar"; diff --git a/enjoy/src/renderer/components/misc/sidebar.tsx b/enjoy/src/renderer/components/layouts/sidebar.tsx similarity index 80% rename from enjoy/src/renderer/components/misc/sidebar.tsx rename to enjoy/src/renderer/components/layouts/sidebar.tsx index 62843bd1..4287b343 100644 --- a/enjoy/src/renderer/components/misc/sidebar.tsx +++ b/enjoy/src/renderer/components/layouts/sidebar.tsx @@ -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 (
- +
{ tooltip={t("sidebar.home")} active={activeTab === "/"} Icon={HomeIcon} - isOpen={isOpen} + isCollapsed={isCollapsed} /> { tooltip={t("sidebar.chats")} active={activeTab.startsWith("/chats")} Icon={MessagesSquareIcon} - isOpen={isOpen} + isCollapsed={isCollapsed} /> { tooltip={t("sidebar.courses")} active={activeTab.startsWith("/courses")} Icon={GraduationCapIcon} - isOpen={isOpen} + isCollapsed={isCollapsed} /> @@ -123,7 +124,7 @@ export const Sidebar = () => { tooltip={t("sidebar.audios")} active={activeTab.startsWith("/audios")} Icon={HeadphonesIcon} - isOpen={isOpen} + isCollapsed={isCollapsed} /> { tooltip={t("sidebar.videos")} active={activeTab.startsWith("/videos")} Icon={VideoIcon} - isOpen={isOpen} + isCollapsed={isCollapsed} /> { tooltip={t("sidebar.documents")} active={activeTab.startsWith("/documents")} Icon={NewspaperIcon} - isOpen={isOpen} + isCollapsed={isCollapsed} /> @@ -153,7 +154,7 @@ export const Sidebar = () => { active={activeTab.startsWith("/conversations")} Icon={BotIcon} testid="sidebar-conversations" - isOpen={isOpen} + isCollapsed={isCollapsed} /> { active={activeTab.startsWith("/pronunciation_assessments")} Icon={SpeechIcon} testid="sidebar-pronunciation-assessments" - isOpen={isOpen} + isCollapsed={isCollapsed} /> { tooltip={t("sidebar.notes")} active={activeTab === "/notes"} Icon={NotebookPenIcon} - isOpen={isOpen} + isCollapsed={isCollapsed} /> { tooltip={t("sidebar.vocabulary")} active={activeTab.startsWith("/vocabulary")} Icon={BookMarkedIcon} - isOpen={isOpen} + isCollapsed={isCollapsed} /> @@ -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)} > - {isOpen && ( + {!isCollapsed && ( {t("sidebar.preferences")} )} @@ -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 ? ( - - ) : ( + {isCollapsed ? ( + ) : ( + + )} + {!isCollapsed && ( + {t("sidebar.collapse")} )} - {isOpen && {t("sidebar.collapse")} }
@@ -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 ( - {isOpen && {label}} + {!isCollapsed && {label}} ); }; -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 (
- + - - - - - {t("deposit")} - {t("depositDescription")} - - - {paymentCreated ? ( - <> - -
- {t("pleaseCompletePaymentInPopupWindow")} -
- - ) : ( - <> -
- {[2, 10, 50, 100].map((amount) => ( -
setDepositAmount(amount)} - > - ${amount} -
- ))} -
-
{t("depositDisclaimer")}
- - )} - - - -
-
- - - - - - -
- - -
- -
-
- - - - - -
- -
- - - - - - - - - - {payments.length > 0 && ( -
- - {t("recentDeposits")} - - - ID - - {t("amount")} - - - {t("status")} - - - {t("processor")} - - {t("date")} - - - - {payments.map((payment) => ( - - - - {payment.id.split("-").shift()} - - - ${payment.amount} - {payment.status} - - {payment.processor} - - - {formatDateTime(payment.createdAt)} - - - ))} - -
-
- )} -
- + {t("deposit")} + diff --git a/enjoy/src/renderer/components/preferences/deposit.tsx b/enjoy/src/renderer/components/preferences/deposit.tsx new file mode 100644 index 00000000..81b0f5fe --- /dev/null +++ b/enjoy/src/renderer/components/preferences/deposit.tsx @@ -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(false); + const [payments, setPayments] = useState([]); + const [loading, setLoading] = useState(false); + const [depositAmount, setDepositAmount] = useState(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 ? ( + <> + +
+ {t("pleaseCompletePaymentInPopupWindow")} +
+ + ) : ( + <> +
+ {[2, 10, 50, 100].map((amount) => ( +
setDepositAmount(amount)} + > + ${amount} +
+ ))} +
+
{t("depositDisclaimer")}
+ + )} + + + +
+
+ + + + + + +
+ + +
+ +
+
+ + + + + +
+ +
+ + + + {payments.length > 0 && ( + + {t("recentDeposits")} + + + ID + {t("amount")} + {t("status")} + {t("processor")} + {t("date")} + + + + {payments.map((payment) => ( + + + + {payment.id.split("-").shift()} + + + ${payment.amount} + {payment.status} + + {payment.processor} + + + {formatDateTime(payment.createdAt)} + + + ))} + +
+ )} + + ); +}; diff --git a/enjoy/src/renderer/components/preferences/index.ts b/enjoy/src/renderer/components/preferences/index.ts index b40f2346..fe9fd2e5 100644 --- a/enjoy/src/renderer/components/preferences/index.ts +++ b/enjoy/src/renderer/components/preferences/index.ts @@ -37,3 +37,5 @@ export * from "./vocabulary-settings"; export * from "./dict-settings"; export * from "./echogarden-stt-settings"; + +export * from "./deposit"; diff --git a/enjoy/src/renderer/context/app-settings-provider.tsx b/enjoy/src/renderer/context/app-settings-provider.tsx index 52723263..f74e53b0 100644 --- a/enjoy/src/renderer/context/app-settings-provider.tsx +++ b/enjoy/src/renderer/context/app-settings-provider.tsx @@ -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; setLibraryPath?: (path: string) => Promise; 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(false); + const [displayDepositDialog, setDisplayDepositDialog] = + useState(false); const [displayPreferences, setDisplayPreferences] = useState(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 = ({ + + + + + {t("deposit")} + {t("depositDescription")} + + + {displayDepositDialog && } + + + + + + + + ); }; diff --git a/enjoy/src/renderer/pages/landing.tsx b/enjoy/src/renderer/pages/landing.tsx index 33a5b095..4b407255 100644 --- a/enjoy/src/renderer/pages/landing.tsx +++ b/enjoy/src/renderer/pages/landing.tsx @@ -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); diff --git a/enjoy/vite.main.config.ts b/enjoy/vite.main.config.ts index 23eda840..7d2434dc 100644 --- a/enjoy/vite.main.config.ts +++ b/enjoy/vite.main.config.ts @@ -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, diff --git a/yarn.lock b/yarn.lock index 303e1e34..45d8e082 100644 --- a/yarn.lock +++ b/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