From 382153f9ed1a57318b79dd394ec3374f8ac611af Mon Sep 17 00:00:00 2001 From: Etorix <92535668+EtorixDev@users.noreply.github.com> Date: Thu, 21 Aug 2025 11:02:43 -0700 Subject: [PATCH] Improve some things. (#355) --- src/equicordplugins/questify/index.tsx | 37 ++++++++--- src/equicordplugins/questify/settings.tsx | 70 ++++++++++----------- src/equicordplugins/questify/utils/misc.tsx | 4 +- 3 files changed, 64 insertions(+), 47 deletions(-) diff --git a/src/equicordplugins/questify/index.tsx b/src/equicordplugins/questify/index.tsx index 30de075fc..70baf9d43 100644 --- a/src/equicordplugins/questify/index.tsx +++ b/src/equicordplugins/questify/index.tsx @@ -430,7 +430,7 @@ function preprocessQuests(quests: Quest[]): Quest[] { const unclaimedSortFunction = createSortFunction(unclaimedSubsort || "Recent DESC"); - // Divide unclaimed quests by completion status before applying subsort. + // Divide unclaimed Quests by completion status before applying subsort. questGroups.unclaimed.sort((a: Quest, b: Quest) => { const aCompleted = !!a.userStatus?.completedAt; const bCompleted = !!b.userStatus?.completedAt; @@ -688,12 +688,12 @@ function processQuestForAutoComplete(quest: Quest): boolean { if (quest.userStatus?.completedAt || existingInterval) { return true; } else if (!playType && !watchType) { - QuestifyLogger.warn(`[${getFormattedNow()}] Could not recognize the quest type for ${questName}.`); + QuestifyLogger.warn(`[${getFormattedNow()}] Could not recognize the Quest type for ${questName}.`); return true; } else if ((watchType && !completeVideoQuestsInBackground) || (playType && (!completeGameQuestsInBackground || !IS_DISCORD_DESKTOP))) { return true; } else if (!questDuration) { - QuestifyLogger.warn(`[${getFormattedNow()}] Could not find duration for quest ${questName}.`); + QuestifyLogger.warn(`[${getFormattedNow()}] Could not find duration for Quest ${questName}.`); return true; } else if (watchType) { startVideoProgressTracking(quest, questDuration); @@ -747,7 +747,7 @@ function getQuestAcceptedButtonText(quest: Quest): string | null { return null; } -function getActiveQuestClosestToCompletion(): Quest | null { +function getQuestPanelOverride(): Quest | null { let closestQuest: Quest | null = null; let closestTimeRemaining = Infinity; @@ -766,6 +766,23 @@ function getActiveQuestClosestToCompletion(): Quest | null { } }); + if (!closestQuest) { + const completedQuests = Array.from(QuestsStore.quests.values() as Quest[]).filter(q => q.userStatus?.completedAt).sort((a, b) => { + const aTime = new Date(a.userStatus?.completedAt as string); + const bTime = new Date(b.userStatus?.completedAt as string); + return bTime.getTime() - aTime.getTime(); + }); + + completedQuests.forEach(quest => { + const completedQuest = quest.userStatus?.completedAt; + const questStatus = getQuestStatus(quest); + + if (completedQuest && questStatus === QuestStatus.Unclaimed) { + closestQuest = quest; + } + }); + } + return closestQuest; } @@ -789,7 +806,7 @@ export default definePlugin({ shouldHideGiftInventoryRelocationNotice, shouldHideFriendsListActiveNowPromotion, shouldDisableQuestAcceptedButton, - getActiveQuestClosestToCompletion, + getQuestPanelOverride, getQuestAcceptedButtonText, processQuestForAutoComplete, activeQuestIntervals, @@ -858,7 +875,7 @@ export default definePlugin({ }, { // Hides the new Quest popup above the account panel. - // Allows in-progress quests to still show. + // Allows in-progress Quests to still show. find: "QUESTS_BAR,questId", replacement: { match: /return null==(\i)\?null:\(/, @@ -871,7 +888,7 @@ export default definePlugin({ find: "questDeliveryOverride)?", replacement: { match: /(\i=)(\i.\i.questDeliveryOverride)/, - replace: "$1$self.getActiveQuestClosestToCompletion()??$2" + replace: "$1$self.getQuestPanelOverride()??$2" } }, { @@ -957,7 +974,7 @@ export default definePlugin({ group: true, replacement: [ { - // Restyles quest tiles with colors. + // Restyles Quest tiles with colors. match: /className:(\i\(\)\(\i.container,\i\)),/, replace: "className:$self.getQuestTileClasses($1,arguments[0].quest),style:$self.getQuestTileStyle(arguments[0].quest)," }, @@ -974,7 +991,7 @@ export default definePlugin({ ] }, { - // Sorts the "All Quests" tab quest tiles. + // Sorts the "All Quests" tab Quest tiles. // Also sets mobile-only Quests as desktop compatible if the setting is enabled. find: ".ALL);return(", replacement: { @@ -983,7 +1000,7 @@ export default definePlugin({ } }, { - // Sorts the "Claimed Quests" tab quest tiles. + // Sorts the "Claimed Quests" tab Quest tiles. find: ".ALL)}):(", replacement: { match: /(claimedQuests:(\i).{0,50}?;)/, diff --git a/src/equicordplugins/questify/settings.tsx b/src/equicordplugins/questify/settings.tsx index 65a133056..51c82ebb7 100644 --- a/src/equicordplugins/questify/settings.tsx +++ b/src/equicordplugins/questify/settings.tsx @@ -50,10 +50,10 @@ export function fetchAndAlertQuests(source: string, logger: Logger): void { const shouldAlert = settings.store.fetchingQuestsAlert; if (shouldAlert) { - logger.info(`[${getFormattedNow()}] New quests detected. Playing alert sound.`); + logger.info(`[${getFormattedNow()}] New Quests detected. Playing alert sound.`); AudioPlayer(shouldAlert, 1).play(); } else { - logger.info(`[${getFormattedNow()}] New quests detected.`); + logger.info(`[${getFormattedNow()}] New Quests detected.`); } } } @@ -75,13 +75,13 @@ export function startAutoFetchingQuests(seconds?: number): void { } const interval = seconds ? seconds * 1000 : settings.store.fetchingQuestsInterval * 1000; - QuestifyLogger.info(`[${getFormattedNow()}] Starting AutoFetch of quests every ${(interval / 60000).toFixed(2)} minutes.`); + QuestifyLogger.info(`[${getFormattedNow()}] Starting AutoFetch of Quests every ${(interval / 60000).toFixed(2)} minutes.`); autoFetchInterval = setInterval(() => { fetchAndAlertQuests("Questify-AutoFetch", QuestifyLogger); }, interval); } export function stopAutoFetchingQuests(): void { if (autoFetchInterval) { - QuestifyLogger.info(`[${getFormattedNow()}] Stopping AutoFetch of quests.`); + QuestifyLogger.info(`[${getFormattedNow()}] Stopping AutoFetch of Quests.`); clearInterval(autoFetchInterval); autoFetchInterval = null; } @@ -712,8 +712,7 @@ function RestyleQuestsSetting() { restyleQuestsIgnored, restyleQuestsExpired, restyleQuestsGradient, - restyleQuestsPreload, - ignoredQuestProfile + restyleQuestsPreload } = settings.use([ "restyleQuestsUnclaimed", "restyleQuestsClaimed", @@ -721,7 +720,6 @@ function RestyleQuestsSetting() { "restyleQuestsExpired", "restyleQuestsGradient", "restyleQuestsPreload", - "ignoredQuestProfile" ]); const [unclaimedColor, setUnclaimedColor] = useState(restyleQuestsUnclaimed); @@ -871,26 +869,6 @@ function RestyleQuestsSetting() { /> -
-
- - Ignored Quest Profile - - value === ignoredQuestProfile} + select={(value: string) => { + settings.store.ignoredQuestProfile = value; + }} + /> +
+
@@ -1314,7 +1314,7 @@ function FetchingQuestsSetting(): JSX.Element { Configure how often to fetch Quests from Discord and set up alerts for new Quests.

- By default, Discord only fetches quests on load and when visiting the Quests page. + By default, Discord only fetches Quests on load and when visiting the Quests page. This means that without a fetch interval defined below, this plugin will become unaware of new Quests added throughout the day.

@@ -1609,25 +1609,25 @@ export const settings = definePluginSettings({ }, unclaimedSubsort: { type: OptionType.STRING, - description: "Subsort method for unclaimed quests.", + description: "Subsort method for unclaimed Quests.", default: "Expiring ASC", // "Recent ASC", "Recent DESC", "Expiring ASC", "Expiring DESC" hidden: true }, claimedSubsort: { type: OptionType.STRING, - description: "Subsort method for claimed quests.", + description: "Subsort method for claimed Quests.", default: "Claimed DESC", // "Recent ASC", "Recent DESC", "Claimed ASC", "Claimed DESC" hidden: true }, ignoredSubsort: { type: OptionType.STRING, - description: "Subsort method for ignored quests.", + description: "Subsort method for ignored Quests.", default: "Recent DESC", // "Recent ASC", "Recent DESC", "Expiring ASC", "Expiring DESC" hidden: true }, expiredSubsort: { type: OptionType.STRING, - description: "Subsort method for expired quests.", + description: "Subsort method for expired Quests.", default: "Expiring DESC", // "Recent ASC", "Recent DESC", "Expiring ASC", "Expiring DESC" hidden: true }, @@ -1639,7 +1639,7 @@ export const settings = definePluginSettings({ }, onQuestsPage: { type: OptionType.BOOLEAN, - description: "Whether the user is currently on the quests page.", + description: "Whether the user is currently on the Quests page.", default: false, hidden: true }, diff --git a/src/equicordplugins/questify/utils/misc.tsx b/src/equicordplugins/questify/utils/misc.tsx index 1aeff166d..5f62452b5 100644 --- a/src/equicordplugins/questify/utils/misc.tsx +++ b/src/equicordplugins/questify/utils/misc.tsx @@ -18,7 +18,7 @@ export const QuestifyLogger = new Logger("Questify"); export const PlayAudio = findByCodeLazy("Unable to find sound for pack name:"); // Takes an audio name or URL, volume, and a callback function. Plays when play() is called. const AudioPlayerConstructor = findByCodeLazy("sound has no duration"); -export function AudioPlayer(name: string, volume: number = 1, callback?: () => void): any { return new AudioPlayerConstructor(name, null, volume, "default", callback || (() => { })); } +export function AudioPlayer(name: string, volume: number = 1, callback?: () => void): any { return new AudioPlayerConstructor(name, null, volume, "default", callback ?? (() => { })); } export const QuestsStore = findStoreLazy("QuestsStore"); export const questPath = "/discovery/quests"; export const leftClick = 0; @@ -267,7 +267,7 @@ export async function reportPlayGameQuestProgress(quest: Quest, terminal: boolea const progress = progressPlayType?.value || 1; if (!questPlayType) { - logger?.warn(`[${getFormattedNow()}] Could not recognize the quest type for Quest ${questName}.`); + logger?.warn(`[${getFormattedNow()}] Could not recognize the Quest type for Quest ${questName}.`); return { progress: null }; }