/* * 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 * as DataStore from "@api/DataStore"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import { useForceUpdater } from "@utils/misc"; import definePlugin from "@utils/types"; import { findByPropsLazy } from "@webpack"; import { Tooltip } from "webpack/common"; enum ActivitiesTypes { Game, Embedded } interface IgnoredActivity { id: string; type: ActivitiesTypes; } const RegisteredGamesClasses = findByPropsLazy("overlayToggleIconOff", "overlayToggleIconOn"); const PreviewBadgeClasses = findByPropsLazy("previewBadge", "previewBadgeIcon"); const BaseShapeRoundClasses = findByPropsLazy("baseShapeRound", "baseShapeRoundLeft", "baseShapeRoundRight"); const RunningGameStore = findByPropsLazy("getRunningGames", "getGamesSeen"); function ToggleIconOff() { return ( ); } function ToggleIconOn() { return ( ); } function ToggleActivityComponent({ activity }: { activity: IgnoredActivity; }) { const forceUpdate = useForceUpdater(); return ( {({ onMouseLeave, onMouseEnter }) => (
handleActivityToggle(e, activity, forceUpdate)} > { ignoredActivitiesCache.has(activity.id) ? : }
)}
); } function ToggleActivityComponentWithBackground({ activity }: { activity: IgnoredActivity; }) { return (
); } function handleActivityToggle(e: React.MouseEvent, activity: IgnoredActivity, forceUpdateComponent: () => void) { e.stopPropagation(); if (ignoredActivitiesCache.has(activity.id)) ignoredActivitiesCache.delete(activity.id); else ignoredActivitiesCache.set(activity.id, activity); forceUpdateComponent(); saveCacheToDatastore(); } async function saveCacheToDatastore() { await DataStore.set("IgnoreActivities_ignoredActivities", ignoredActivitiesCache); } let ignoredActivitiesCache = new Map(); export default definePlugin({ name: "IgnoreActivities", authors: [Devs.Nuckyz], description: "Ignore certain activities (like games and actual activities) from showing up on your status. You can configure which ones are ignored from the Registered Games and Activities tabs.", patches: [{ find: ".Messages.SETTINGS_GAMES_OVERLAY_ON", replacement: { match: /(this.renderLastPlayed\(\)]}\),this.renderOverlayToggle\(\))/, replace: "$1,Vencord.Plugins.plugins.IgnoreActivities.renderToggleGameActivityButton(this.props)" } }, { find: ".Messages.NEW,name", replacement: { match: /\(\)\.badgeContainer.+?.\?\(0,.\.jsx\)\(.{1,2},{name:(?.)\.name}\):null/, replace: "$&,Vencord.Plugins.plugins.IgnoreActivities.renderToggleActivityButton($)" } }, { find: '.displayName="LocalActivityStore"', replacement: { match: /((.)\.push\(.\({type:.\..{1,3}\.LISTENING.+?;)/, replace: "$1$2=$2.filter(Vencord.Plugins.plugins.IgnoreActivities.isActivityEnabled);" } }], async start() { const ignoredActivitiesData = await DataStore.get>("IgnoreActivities_ignoredActivities") ?? new Map(); /** Migrate old data */ if (Array.isArray(ignoredActivitiesData)) { for (const id of ignoredActivitiesData) { ignoredActivitiesCache.set(id, { id, type: ActivitiesTypes.Game }); } await saveCacheToDatastore(); } else ignoredActivitiesCache = ignoredActivitiesData; if (ignoredActivitiesCache.size !== 0) { const gamesSeen: { id?: string; exePath: string; }[] = RunningGameStore.getGamesSeen(); for (const ignoredActivity of ignoredActivitiesCache.values()) { if (ignoredActivity.type !== ActivitiesTypes.Game) continue; if (!gamesSeen.some(game => game.id === ignoredActivity.id || game.exePath === ignoredActivity.id)) { /** Custom added game which no longer exists */ ignoredActivitiesCache.delete(ignoredActivity.id); } } await saveCacheToDatastore(); } }, renderToggleGameActivityButton(props: { game: { id?: string; exePath: string; } | null; }) { if (!props.game) return (null); return ( ); }, renderToggleActivityButton(props: { id: string; }) { return ( ); }, isActivityEnabled(props: { type: number; application_id?: string; name?: string; }) { if (props.type === 0) { if (props.application_id !== undefined) return !ignoredActivitiesCache.has(props.application_id); else { const exePath = RunningGameStore.getRunningGames().find(game => game.name === props.name)?.exePath; if (exePath) return !ignoredActivitiesCache.has(exePath); } } return true; }, });