diff --git a/src/renderer/components/ScreenSharePicker.tsx b/src/renderer/components/ScreenSharePicker.tsx index ef0c942..f69f9d5 100644 --- a/src/renderer/components/ScreenSharePicker.tsx +++ b/src/renderer/components/ScreenSharePicker.tsx @@ -22,7 +22,7 @@ import { import { Node } from "@vencord/venmic"; import type { Dispatch, SetStateAction } from "react"; import { addPatch } from "renderer/patches/shared"; -import { useSettings } from "renderer/settings"; +import { State, useSettings, useVesktopState } from "renderer/settings"; import { classNameFactory, isLinux, isWindows } from "renderer/utils"; const StreamResolutions = ["480", "720", "1080", "1440", "2160"] as const; @@ -46,8 +46,6 @@ interface AudioItem { } interface StreamSettings { - resolution: StreamResolution; - fps: StreamFps; audio: boolean; contentHint?: string; includeSources?: AudioSources; @@ -79,10 +77,11 @@ addPatch({ } ], patchStreamQuality(opts: any) { - if (!currentSettings) return; + const { screenshareQuality } = State.store; + if (!screenshareQuality) return; - const framerate = Number(currentSettings.fps); - const height = Number(currentSettings.resolution); + const framerate = Number(screenshareQuality.frameRate); + const height = Number(screenshareQuality.resolution); const width = Math.round(height * (16 / 9)); Object.assign(opts, { @@ -316,14 +315,14 @@ function AudioSettingsModal({ ); } -function OptionRadio(props: { +function OptionRadio(props: { options: Array | ReadonlyArray; labels?: Array; - settingsKey: string; - settings: StreamSettings; - setSettings: Dispatch>; + settings: Settings; + settingsKey: Key; + onChange: (option: string) => void; }) { - const { options, setSettings, settings, settingsKey, labels } = props; + const { options, settings, settingsKey, labels, onChange } = props; return (
@@ -336,7 +335,7 @@ function OptionRadio(props: { name="fps" value={option} checked={settings[settingsKey] === option} - onChange={() => setSettings(s => ({ ...s, [settingsKey]: option }))} + onChange={() => onChange(option)} /> ))} @@ -344,7 +343,7 @@ function OptionRadio(props: { ); } -function StreamSettings({ +function StreamSettingsUi({ source, settings, setSettings, @@ -356,6 +355,7 @@ function StreamSettings({ skipPicker: boolean; }) { const Settings = useSettings(); + const qualitySettings = State.store.screenshareQuality!; const [thumb] = useAwaiter( () => (skipPicker ? Promise.resolve(source.url) : VesktopNative.capturer.getLargeThumbnail(source.id)), @@ -393,9 +393,9 @@ function StreamSettings({ Resolution (qualitySettings.resolution = value)} /> @@ -403,9 +403,9 @@ function StreamSettings({ Frame Rate (qualitySettings.frameRate = value)} />
@@ -416,9 +416,9 @@ function StreamSettings({ setSettings(s => ({ ...s, contentHint: option }))} />

@@ -696,12 +696,14 @@ function ModalComponent({ }) { const [selected, setSelected] = useState(skipPicker ? screens[0].id : void 0); const [settings, setSettings] = useState({ - resolution: "720", - fps: "30", contentHint: "motion", audio: true, includeSources: "None" }); + const qualitySettings = (useVesktopState().screenshareQuality ??= { + resolution: "720", + frameRate: "30" + }); return ( @@ -713,7 +715,7 @@ function ModalComponent({ {!selected ? ( ) : ( - s.id === selected)!} settings={settings} setSettings={setSettings} @@ -727,8 +729,8 @@ function ModalComponent({ onClick={() => { currentSettings = settings; try { - const frameRate = Number(settings.fps); - const height = Number(settings.resolution); + const frameRate = Number(qualitySettings.frameRate); + const height = Number(qualitySettings.resolution); const width = Math.round(height * (16 / 9)); const conn = [...MediaEngineStore.getMediaEngine().connections].find( diff --git a/src/renderer/patches/screenShareFixes.ts b/src/renderer/patches/screenShareFixes.ts index 00487d3..21f5049 100644 --- a/src/renderer/patches/screenShareFixes.ts +++ b/src/renderer/patches/screenShareFixes.ts @@ -6,6 +6,7 @@ import { Logger } from "@vencord/types/utils"; import { currentSettings } from "renderer/components/ScreenSharePicker"; +import { State } from "renderer/settings"; import { isLinux } from "renderer/utils"; const logger = new Logger("VesktopStreamFixes"); @@ -27,8 +28,8 @@ if (isLinux) { const stream = await original.call(this, opts); const id = await getVirtmic(); - const frameRate = Number(currentSettings?.fps); - const height = Number(currentSettings?.resolution); + const frameRate = Number(State.store.screenshareQuality?.frameRate ?? 30); + const height = Number(State.store.screenshareQuality?.resolution ?? 720); const width = Math.round(height * (16 / 9)); const track = stream.getVideoTracks()[0]; diff --git a/src/renderer/settings.ts b/src/renderer/settings.ts index ed6bb10..5c5ed32 100644 --- a/src/renderer/settings.ts +++ b/src/renderer/settings.ts @@ -7,6 +7,9 @@ import { useEffect, useReducer } from "@vencord/types/webpack/common"; import { SettingsStore } from "shared/utils/SettingsStore"; +import { VesktopLogger } from "./logger"; +import { localStorage } from "./utils"; + export const Settings = new SettingsStore(VesktopNative.settings.get()); Settings.addGlobalChangeListener((o, p) => VesktopNative.settings.set(o, p)); @@ -28,3 +31,38 @@ export function getValueAndOnChange(key: keyof typeof Settings.store) { onChange: (value: any) => (Settings.store[key] = value) }; } + +interface TState { + screenshareQuality?: { + resolution: string; + frameRate: string; + }; +} + +const stateKey = "VesktopState"; + +const currentState: TState = (() => { + const stored = localStorage.getItem(stateKey); + if (!stored) return {}; + try { + return JSON.parse(stored); + } catch (e) { + VesktopLogger.error("Failed to parse stored state", e); + return {}; + } +})(); + +export const State = new SettingsStore(currentState); +State.addGlobalChangeListener((o, p) => localStorage.setItem(stateKey, JSON.stringify(o))); + +export function useVesktopState() { + const [, update] = useReducer(x => x + 1, 0); + + useEffect(() => { + State.addGlobalChangeListener(update); + + return () => State.removeGlobalChangeListener(update); + }, []); + + return State.store; +} diff --git a/src/renderer/utils.ts b/src/renderer/utils.ts index 16c8480..307b1d4 100644 --- a/src/renderer/utils.ts +++ b/src/renderer/utils.ts @@ -4,6 +4,7 @@ * Copyright (c) 2023 Vendicated and Vencord contributors */ +// Discord deletes this from the window so we need to capture it in a variable export const { localStorage } = window; export const isFirstRun = (() => {