diff --git a/src/renderer/appBadge.ts b/src/renderer/appBadge.ts new file mode 100644 index 0000000..2e8ea2c --- /dev/null +++ b/src/renderer/appBadge.ts @@ -0,0 +1,47 @@ +/* + * SPDX-License-Identifier: GPL-3.0 + * Aerocord, a vesktop fork for older microsoft NT releases such as NT 6.0, 6.1, 6.2 and 6.3. + * Credits to vendicated and the rest of the vesktop contribuitors for making Vesktop! + */ + +import { filters, waitFor } from "@vencord/types/webpack"; +import { RelationshipStore } from "@vencord/types/webpack/common"; + +import { Settings } from "./settings"; + +let GuildReadStateStore: any; +let NotificationSettingsStore: any; + +export function setBadge() { + if (Settings.store.appBadge === false) return; + + try { + const mentionCount = GuildReadStateStore.getTotalMentionCount(); + const pendingRequests = RelationshipStore.getPendingCount(); + const hasUnread = GuildReadStateStore.hasAnyUnread(); + const disableUnreadBadge = NotificationSettingsStore.getDisableUnreadBadge(); + + let totalCount = mentionCount + pendingRequests; + if (!totalCount && hasUnread && !disableUnreadBadge) totalCount = -1; + + VesktopNative.app.setBadgeCount(totalCount); + } catch (e) { + console.error(e); + } +} + +let toFind = 3; + +function waitForAndSubscribeToStore(name: string, cb?: (m: any) => void) { + waitFor(filters.byStoreName(name), store => { + cb?.(store); + store.addChangeListener(setBadge); + + toFind--; + if (toFind === 0) setBadge(); + }); +} + +waitForAndSubscribeToStore("GuildReadStateStore", store => (GuildReadStateStore = store)); +waitForAndSubscribeToStore("NotificationSettingsStore", store => (NotificationSettingsStore = store)); +waitForAndSubscribeToStore("RelationshipStore"); diff --git a/src/renderer/fixes.css b/src/renderer/fixes.css new file mode 100644 index 0000000..87e601d --- /dev/null +++ b/src/renderer/fixes.css @@ -0,0 +1,11 @@ +/* Download Desktop button in guilds list */ +[class^=listItem_]:has([data-list-item-id=guildsnav___app-download-button]), +[class^=listItem_]:has(+ [class^=listItem_] [data-list-item-id=guildsnav___app-download-button]) { + display: none; +} + +/* FIXME: remove this once Discord fixes their css to not explode scrollbars on chromium >=121 */ +* { + scrollbar-width: unset !important; + scrollbar-color: unset !important; +} \ No newline at end of file diff --git a/src/renderer/fixes.ts b/src/renderer/fixes.ts new file mode 100644 index 0000000..a7a9bba --- /dev/null +++ b/src/renderer/fixes.ts @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: GPL-3.0 + * Aerocord, a vesktop fork for older microsoft NT releases such as NT 6.0, 6.1, 6.2 and 6.3. + * Credits to vendicated and the rest of the vesktop contribuitors for making Vesktop! + */ + +import "./fixes.css"; + +import { isWindows, localStorage } from "./utils"; + +// Make clicking Notifications focus the window +const originalSetOnClick = Object.getOwnPropertyDescriptor(Notification.prototype, "onclick")!.set!; +Object.defineProperty(Notification.prototype, "onclick", { + set(onClick) { + originalSetOnClick.call(this, function (this: unknown) { + onClick.apply(this, arguments); + VesktopNative.win.focus(); + }); + }, + configurable: true +}); + +// Hide "Download Discord Desktop now!!!!" banner +localStorage.setItem("hideNag", "true"); + +// FIXME: Remove eventually. +// Originally, Vencord always used a Windows user agent. This seems to cause captchas +// Now, we use a platform specific UA - HOWEVER, discord FOR SOME REASON????? caches +// device props in localStorage. This code fixes their cache to properly update the platform in SuperProps +if (!isWindows) + try { + const deviceProperties = localStorage.getItem("deviceProperties"); + if (deviceProperties && JSON.parse(deviceProperties).os === "Windows") + localStorage.removeItem("deviceProperties"); + } catch {} diff --git a/src/renderer/index.ts b/src/renderer/index.ts new file mode 100644 index 0000000..92aabd3 --- /dev/null +++ b/src/renderer/index.ts @@ -0,0 +1,59 @@ +/* + * SPDX-License-Identifier: GPL-3.0 + * Aerocord, a vesktop fork for older microsoft NT releases such as NT 6.0, 6.1, 6.2 and 6.3. + * Credits to vendicated and the rest of the vesktop contribuitors for making Vesktop! + */ + +import "./fixes"; +import "./appBadge"; +import "./patches"; +import "./themedSplash"; + +console.log("read if cute :3"); + +export * as Components from "./components"; +import { findByPropsLazy } from "@vencord/types/webpack"; +import { FluxDispatcher } from "@vencord/types/webpack/common"; + +import SettingsUi from "./components/settings/Settings"; +import { Settings } from "./settings"; +export { Settings }; + +const InviteActions = findByPropsLazy("resolveInvite"); + +export async function openInviteModal(code: string) { + const { invite } = await InviteActions.resolveInvite(code, "Desktop Modal"); + if (!invite) return false; + + VesktopNative.win.focus(); + + FluxDispatcher.dispatch({ + type: "INVITE_MODAL_OPEN", + invite, + code, + context: "APP" + }); + + return true; +} + +const customSettingsSections = ( + Vencord.Plugins.plugins.Settings as any as { customSections: ((ID: Record) => any)[] } +).customSections; + +customSettingsSections.push(() => ({ + section: "Aerocord", + label: "Aerocord Settings", + element: SettingsUi, + className: "vc-vesktop-settings" +})); + +const arRPC = Vencord.Plugins.plugins["WebRichPresence (arRPC)"] as any as { + handleEvent(e: MessageEvent): void; +}; + +VesktopNative.arrpc.onActivity(data => { + if (!Settings.store.arRPC) return; + + arRPC.handleEvent(new MessageEvent("message", { data })); +}); diff --git a/src/renderer/settings.ts b/src/renderer/settings.ts new file mode 100644 index 0000000..edc070e --- /dev/null +++ b/src/renderer/settings.ts @@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: GPL-3.0 + * Aerocord, a vesktop fork for older microsoft NT releases such as NT 6.0, 6.1, 6.2 and 6.3. + * Credits to vendicated and the rest of the vesktop contribuitors for making Vesktop! + */ + +import { useEffect, useReducer } from "@vencord/types/webpack/common"; +import { SettingsStore } from "shared/utils/SettingsStore"; + +export const Settings = new SettingsStore(VesktopNative.settings.get()); +Settings.addGlobalChangeListener((o, p) => VesktopNative.settings.set(o, p)); + +export function useSettings() { + const [, update] = useReducer(x => x + 1, 0); + + useEffect(() => { + Settings.addGlobalChangeListener(update); + + return () => Settings.removeGlobalChangeListener(update); + }, []); + + return Settings.store; +} + +export function getValueAndOnChange(key: keyof typeof Settings.store) { + return { + value: Settings.store[key] as any, + onChange: (value: any) => (Settings.store[key] = value) + }; +}