/* * Vencord, a modification for Discord's desktop app * Copyright (c) 2022 Vendicated and contributors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import { useSettings } from "@api/Settings"; import { ErrorCard } from "@components/ErrorCard"; import { Flex } from "@components/Flex"; import { Link } from "@components/Link"; import { Margins } from "@utils/margins"; import { classes } from "@utils/misc"; import { relaunch } from "@utils/native"; import { useAwaiter } from "@utils/react"; import { changes, checkForUpdates, getRepo, isNewer, update, updateError, UpdateLogger } from "@utils/updater"; import { Alerts, Button, Card, Forms, Parser, React, Switch, Toasts } from "@webpack/common"; import gitHash from "~git-hash"; import { SettingsTab, wrapTab } from "./shared"; function withDispatcher(dispatcher: React.Dispatch>, action: () => any) { return async () => { dispatcher(true); try { await action(); } catch (e: any) { UpdateLogger.error("Failed to update", e); if (!e) { var err = "An unknown error occurred (error is undefined).\nPlease try again."; } else if (e.code && e.cmd) { const { code, path, cmd, stderr } = e; if (code === "ENOENT") var err = `Command \`${path}\` not found.\nPlease install it and try again`; else { var err = `An error occurred while running \`${cmd}\`:\n`; err += stderr || `Code \`${code}\`. See the console for more info`; } } else { var err = "An unknown error occurred. See the console for more info."; } Alerts.show({ title: "Oops!", body: ( {err.split("\n").map((line, i) =>
{Parser.parse(line)}
)}
) }); } finally { dispatcher(false); } }; } interface CommonProps { repo: string; repoPending: boolean; } function HashLink({ repo, hash, disabled = false }: { repo: string, hash: string, disabled?: boolean; }) { return {hash} ; } function Changes({ updates, repo, repoPending }: CommonProps & { updates: typeof changes; }) { return ( {updates.map(({ hash, author, message }) => (
{message} - {author}
))}
); } function Updatable(props: CommonProps) { const [updates, setUpdates] = React.useState(changes); const [isChecking, setIsChecking] = React.useState(false); const [isUpdating, setIsUpdating] = React.useState(false); const isOutdated = (updates?.length ?? 0) > 0; return ( <> {!updates && updateError ? ( <> Failed to check updates. Check the console for more info

{updateError.stderr || updateError.stdout || "An unknown error occurred"}

) : ( {isOutdated ? `There are ${updates.length} Updates` : "Up to Date!"} )} {isOutdated && } {isOutdated && } ); } function Newer(props: CommonProps) { return ( <> Your local copy has more recent commits. Please stash or reset them. ); } function Updater() { const settings = useSettings(["notifyAboutUpdates", "autoUpdate", "autoUpdateNotification"]); const [repo, err, repoPending] = useAwaiter(getRepo, { fallbackValue: "Loading..." }); React.useEffect(() => { if (err) UpdateLogger.error("Failed to retrieve repo", err); }, [err]); const commonProps: CommonProps = { repo, repoPending }; return ( Updater Settings settings.notifyAboutUpdates = v} note="Shows a notification on startup" disabled={settings.autoUpdate} > Get notified about new updates settings.autoUpdate = v} note="Automatically update Vencord without confirmation prompt" > Automatically update settings.autoUpdateNotification = v} note="Shows a notification when Vencord automatically updates" disabled={!settings.autoUpdate} > Get notified when an automatic update completes Repo {repoPending ? repo : err ? "Failed to retrieve - check console" : ( {repo.split("/").slice(-2).join("/")} ) } {" "}() Updates {isNewer ? : } ); } export default IS_UPDATER_DISABLED ? null : wrapTab(Updater, "Updater");