/* * Vencord, a Discord client mod * Copyright (c) 2026 Vendicated and contributors * SPDX-License-Identifier: GPL-3.0-or-later */ import { QuestTaskType } from "@vencord/discord-types/enums"; import type { JSX } from "react"; import { getQuestifySettings, useQuestifySettings } from "../settings/access"; import { resetDangerousSettings } from "../settings/dangerous"; import { autoCompleteQuestTaskTypes, defaultAutoCompleteQuestTypes, isDesktopCompatible } from "../settings/def"; import { Alerts, q } from "../utils/ui"; import { ManaButton, type ManaSelectOption, SettingsCard, SettingsDescription, SettingsHeader, SettingsNotice, SettingsParagraph, SettingsSelect, SettingsSubheader, SettingsSubtleSwitch } from "./shared"; type QuestDisableSettingKey = | "disableAccountPanelPromo" | "disableAccountPanelQuestProgress" | "disableFriendsListPromo" | "disableMembersListPromo" | "disableOrbsAndQuestsBadges" | "disableRelocationNotices" | "disableSponsoredBanner"; type QuestModifySettingKey = | "autoCompleteQuestsSimultaneously" | "resumeInterruptedQuests" | "completeVideoQuestsQuicker" | "preventVideoQuestsPausing" | "makeMobileVideoQuestsDesktopCompatible"; interface QuestDisableOption { key: QuestDisableSettingKey; label: string; } const disableFeatureOptions = [ { key: "disableSponsoredBanner", label: "Sponsored Banner", }, { key: "disableRelocationNotices", label: "Relocation Notices", }, { key: "disableFriendsListPromo", label: "Friends List Promo", }, { key: "disableMembersListPromo", label: "Members List Promo", }, { key: "disableAccountPanelPromo", label: "Account Panel Promo", }, { key: "disableAccountPanelQuestProgress", label: "Account Panel Progress", }, { key: "disableOrbsAndQuestsBadges", label: "Quest & Orbs Badges", }, ] as const satisfies readonly QuestDisableOption[]; const disableManaOptions: ManaSelectOption[] = disableFeatureOptions.map(({ key, label }) => ({ id: key, label, value: key, })); const autoCompleteQuestTypeLabels = { [QuestTaskType.WATCH_VIDEO]: "Watch Video", [QuestTaskType.WATCH_VIDEO_ON_MOBILE]: "Watch Video on Mobile", [QuestTaskType.ACHIEVEMENT_IN_ACTIVITY]: "Achievement in Activity", [QuestTaskType.PLAY_ACTIVITY]: "Play Activity", [QuestTaskType.PLAY_ON_DESKTOP]: "Play on Desktop", [QuestTaskType.PLAY_ON_PLAYSTATION]: "Play on PlayStation", [QuestTaskType.PLAY_ON_XBOX]: "Play on Xbox", } as const satisfies Record; const autoCompleteQuestTypeOptions = autoCompleteQuestTaskTypes.map(questType => ({ label: autoCompleteQuestTypeLabels[questType], value: questType, })) satisfies { label: string; value: QuestTaskType; }[]; const autoCompleteQuestTypeManaOptions: ManaSelectOption[] = autoCompleteQuestTypeOptions.map(({ label, value }) => ({ id: String(value), label, value: String(value), disabled: !isDesktopCompatible(value), })); interface SettingsAllowDangerousButtonProps { allowed: boolean; disabled?: boolean; onClick?: (e: React.MouseEvent) => void; } function SettingsAllowDangerousButton({ allowed, disabled, onClick, }: SettingsAllowDangerousButtonProps): JSX.Element { return (
); } export function QuestFeaturesSetting(): JSX.Element { const questFeatures = useQuestifySettings([ "disableQuestsEverything", "disableSponsoredBanner", "disableRelocationNotices", "disableFriendsListPromo", "disableMembersListPromo", "disableAccountPanelPromo", "disableAccountPanelQuestProgress", "disableOrbsAndQuestsBadges", "resumeInterruptedQuests", "allowChangingDangerousSettings", "makeMobileVideoQuestsDesktopCompatible", "autoCompleteQuestsSimultaneously", "autoCompleteQuestTypes", "completeVideoQuestsQuicker", "preventVideoQuestsPausing", ]); const selectedDisableValues = disableFeatureOptions .filter(({ key }) => questFeatures[key]) .map(({ key }) => key); const selectedAutoCompleteQuestTypeValues = autoCompleteQuestTypeOptions .filter(({ value }) => isDesktopCompatible(value) && questFeatures.autoCompleteQuestTypes[value] === true) .map(({ value }) => String(value)); function updateDisableValue(value: string | string[] | null) { const selectedKeys = new Set(Array.isArray(value) ? value : value ? [value] : []); for (const { key } of disableFeatureOptions) { getQuestifySettings()[key] = selectedKeys.has(key); } } function confirmDangerousSettingChange(body: string, onConfirm: () => void) { Alerts.show({ title: "Are you sure?", body, confirmText: "Continue", confirmVariant: "critical-primary", cancelText: "Cancel", onConfirm, }); } function updateAutoCompleteQuestTypes(value: string | string[] | null) { const selectedValues = new Set(Array.isArray(value) ? value : value ? [value] : []); const nextAutoCompleteQuestTypes = { ...defaultAutoCompleteQuestTypes }; for (const { value: questType } of autoCompleteQuestTypeOptions) { const nextValue = selectedValues.has(String(questType)) && isDesktopCompatible(questType); nextAutoCompleteQuestTypes[questType] = nextValue; } getQuestifySettings().autoCompleteQuestTypes = nextAutoCompleteQuestTypes; } function updateDisableEverything(checked: boolean) { function setDisableEverything() { getQuestifySettings().disableQuestsEverything = checked; } if (checked) { confirmDangerousSettingChange( "This will completely disable Quest functionality.", () => { resetDangerousSettings(); setDisableEverything(); } ); } else { setDisableEverything(); } } function updateDangerousAccess(checked: boolean) { function setDangerousAccess() { getQuestifySettings().allowChangingDangerousSettings = checked; } if (checked) { confirmDangerousSettingChange( "This will allow changing dangerous settings.", setDangerousAccess ); } else { resetDangerousSettings(); setDangerousAccess(); } } function updateModifyValue(key: QuestModifySettingKey, checked: boolean) { getQuestifySettings()[key] = checked; } return ( Quest Features Modify how Quests behave to enhance or remove functionality. Disable Features Modify Features c !== undefined)}> Discord is known to punish users of scripts or plugins that modify the completion of Quests. Modifying the completion of Quests is against Discord's Terms of Service.
The punishment consists of a temporary or permanent loss of access to Quests and their rewards. The punishment also consists of an account standing violation which lasts 2 years per violation.
Due to the various methods Discord uses to track users, there's no way to realistically evade detection. If you proceed, understand that Discord likely will detect your use at some point.
Use the following toggle to access potentially dangerous settings at your own risk. updateDangerousAccess(!questFeatures.allowChangingDangerousSettings)} /> {questFeatures.allowChangingDangerousSettings && <> updateModifyValue("completeVideoQuestsQuicker", checked)} topSpacing="10" bottomSpacing="5" tooltip={{ position: "top", text: "Discord allows Video Quests to be completed once 24 seconds less than the duration of the video has passed since you enrolled into the Quest." + "\n\nThis means that if a Video Quest is 24 seconds or less, or if you enroll in a Video Quest and return later to complete it, it can be completed immediately." + "\n\nThis setting will only apply to auto-completing Video Quests and relies on the auto-complete setting below. Manually completing Video Quests will still require waiting the full duration and is not dependent on enrollment time." }} /> updateModifyValue("preventVideoQuestsPausing", checked)} bottomSpacing="5" tooltip={{ position: "top", text: "Discord forces you to be tabbed into the client for Video Quests to play their video." + "\n\nThis setting prevents the video from pausing and allows completion to progress as normal." + "\n\nThis setting applies only to manually completing Video Quests." }} /> updateModifyValue("makeMobileVideoQuestsDesktopCompatible", checked)} bottomSpacing="5" tooltip={{ position: "top", text: "Some mobile-only Video Quests can be enrolled in on desktop, but still must be completed on mobile. This setting will allow those to be completed on desktop." + "\n\nSome mobile-only Video Quests are only enrollable on mobile. For this setting to affect those, you must enroll in those Quests on your mobile device before returning to desktop and refreshing your Quests." + "\n\nThis setting, when enabled independently, applies only to manually completing Video Quests. Auto-completing mobile Video Quests from desktop relies on the auto-complete setting below, and will implicitly enable this setting as well." }} /> updateModifyValue("autoCompleteQuestsSimultaneously", checked)} bottomSpacing="5" tooltip={{ position: "top", text: "By default, attempting to auto-complete multiple Quests will queue them to be completed in order." + "\n\nThis setting will alternatively allow all auto-complete Quests to run at the same time." + "\n\nThis setting will only apply to auto-completing Quests and relies on the auto-complete setting below." }} /> updateModifyValue("resumeInterruptedQuests", checked)} bottomSpacing="5" tooltip={{ position: "top", text: "This setting will automatically resume any interrupted auto-completions caused by reloads or restarts, including requeuing Quests which had yet to start auto-completing but had been queued." }} /> }
); }