import { useCallback, useState } from "react"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import { Button } from "@/components/buttons/Button"; import { Icon, Icons } from "@/components/Icon"; import { SettingsCard } from "@/components/layout/SettingsCard"; import { Stepper } from "@/components/layout/Stepper"; import { CenterContainer } from "@/components/layout/ThinContainer"; import { Divider } from "@/components/utils/Divider"; import { Heading2, Paragraph } from "@/components/utils/Text"; import { MinimalPageLayout } from "@/pages/layouts/MinimalPageLayout"; import { PageTitle } from "@/pages/parts/util/PageTitle"; import { useAuthStore } from "@/stores/auth"; import { useBookmarkStore } from "@/stores/bookmarks"; import { useGroupOrderStore } from "@/stores/groupOrder"; import { useProgressStore } from "@/stores/progress"; import { useSubtitleStore } from "@/stores/subtitles"; import { useWatchHistoryStore } from "@/stores/watchHistory"; export function MigrationDownloadPage() { const { t } = useTranslation(); const user = useAuthStore(); const navigate = useNavigate(); const bookmarks = useBookmarkStore((s) => s.bookmarks); const progress = useProgressStore((s) => s.items); const watchHistory = useWatchHistoryStore((s) => s.items); const groupOrder = useGroupOrderStore((s) => s.groupOrder); // Get data from localStorage directly to ensure we have the persisted data const getPersistedData = (key: string) => { try { const stored = localStorage.getItem(key); return stored ? JSON.parse(stored).state : {}; } catch { return {}; } }; const persistedBookmarks = getPersistedData("__MW::bookmarks"); const persistedProgress = getPersistedData("__MW::progress"); const persistedWatchHistory = getPersistedData("__MW::watchHistory"); const persistedGroupOrder = getPersistedData("__MW::groupOrder"); const persistedPreferences = getPersistedData("__MW::preferences"); const persistedSubtitles = getPersistedData("__MW::subtitles"); const persistedTheme = getPersistedData("__MW::theme"); const persistedLocale = getPersistedData("__MW::locale"); const subtitleLanguage = useSubtitleStore((s) => s.lastSelectedLanguage); const [status, setStatus] = useState<"idle" | "success" | "error">("idle"); const handleDownload = useCallback(() => { try { const exportData = { account: { profile: user.account?.profile, deviceName: user.account?.deviceName, }, bookmarks: persistedBookmarks.bookmarks || bookmarks, progress: persistedProgress.items || progress, watchHistory: persistedWatchHistory.items || watchHistory, groupOrder: persistedGroupOrder.groupOrder || groupOrder, settings: { ...persistedPreferences, defaultSubtitleLanguage: persistedSubtitles.lastSelectedLanguage || subtitleLanguage, }, theme: persistedTheme.theme || null, language: persistedLocale.language || null, exportDate: new Date().toISOString(), }; // Convert to JSON and create a downloadable link const dataStr = JSON.stringify(exportData, null, 2); const blob = new Blob([dataStr], { type: "application/json;charset=utf-8", }); // Create filename with current date const exportFileDefaultName = `mw-account-data-${new Date().toISOString().split("T")[0]}.json`; // Create download link using Blob URL const url = URL.createObjectURL(blob); const linkElement = document.createElement("a"); linkElement.href = url; linkElement.download = exportFileDefaultName; try { // Add link to DOM temporarily and trigger download document.body.appendChild(linkElement); linkElement.click(); // Small delay to ensure download is initiated before cleanup setTimeout(() => { document.body.removeChild(linkElement); URL.revokeObjectURL(url); }, 100); // Set success status (download is initiated) setStatus("success"); } catch (downloadError) { // Clean up on error document.body.removeChild(linkElement); URL.revokeObjectURL(url); throw downloadError; } } catch (error) { console.error("Error during data download:", error); setStatus("error"); } }, [ bookmarks, progress, watchHistory, user.account, groupOrder, persistedBookmarks, persistedProgress, persistedWatchHistory, persistedGroupOrder, persistedPreferences, persistedSubtitles, persistedTheme, persistedLocale, subtitleLanguage, ]); return (
{t("migration.download.title")}
{t("migration.download.description")}

{t("migration.preview.downloadDescription")}

{t("migration.preview.items.progress")}
{Object.keys(persistedProgress.items || progress).length}
{t("migration.preview.items.bookmarks")}
{ Object.keys(persistedBookmarks.bookmarks || bookmarks) .length }
{t("migration.preview.items.progress")}
{ Object.keys(persistedWatchHistory.items || watchHistory) .length }
{t("migration.preview.items.settings")}
{status !== "success" && ( )} {status === "success" && (
)}
{status === "success" && (

{t("migration.download.status.success")}

)} {status === "error" && (

{t("migration.download.status.error")}

)}
); }