mirror of
https://github.com/RobinRMC/VencordPlus.git
synced 2025-05-10 17:35:39 +02:00
Update BetterScreenshare & PhilsPluginLibrary
This commit is contained in:
parent
7193b82bd6
commit
337c1a05af
6 changed files with 115 additions and 65 deletions
|
@ -12,7 +12,7 @@ import { addSettingsPanelButton, Emitter, removeSettingsPanelButton, Screenshare
|
|||
import { PluginInfo } from "./constants";
|
||||
import { openScreenshareModal } from "./modals";
|
||||
import { ScreenshareAudioPatcher, ScreensharePatcher } from "./patchers";
|
||||
import { replacedScreenshareModalComponent } from "./patches";
|
||||
import { GoLivePanelWrapper, replacedSubmitFunction } from "./patches";
|
||||
import { initScreenshareAudioStore, initScreenshareStore } from "./stores";
|
||||
|
||||
export default definePlugin({
|
||||
|
@ -22,10 +22,17 @@ export default definePlugin({
|
|||
dependencies: ["PhilsPluginLibrary"],
|
||||
patches: [
|
||||
{
|
||||
find: "Messages.SCREENSHARE_RELAUNCH",
|
||||
find: "GoLiveModal: user cannot be undefined", // Module: 60594; canaryRelease: 364525; L431
|
||||
replacement: {
|
||||
match: /(function .{1,2}\(.{1,2}\){)(.{1,40}(?=selectGuild).+?(?:]}\)}\)))(})/,
|
||||
replace: "$1return $self.replacedScreenshareModalComponent(function(){$2}, this, arguments)$3"
|
||||
match: /onSubmit:(\w+)/,
|
||||
replace: "onSubmit:$self.replacedSubmitFunction($1)"
|
||||
}
|
||||
},
|
||||
{
|
||||
find: "StreamSettings: user cannot be undefined", // Module: 641115; canaryRelease: 364525; L254
|
||||
replacement: {
|
||||
match: /\(.{0,10}(,{.{0,100}modalContent)/,
|
||||
replace: "($self.GoLivePanelWrapper$1"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -59,5 +66,6 @@ export default definePlugin({
|
|||
toolboxActions: {
|
||||
"Open Screenshare Settings": openScreenshareModal
|
||||
},
|
||||
replacedScreenshareModalComponent
|
||||
replacedSubmitFunction,
|
||||
GoLivePanelWrapper
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2024 Vendicated and contributors
|
||||
* Copyright (c) 2025 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
|
@ -46,30 +46,8 @@ const ReplacedStreamSettings = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export function replacedScreenshareModalSettingsContentType(oldType: (...args: any[]) => any, thisContext: any, functionArguments: any) {
|
||||
const { hideDefaultSettings } = Settings.plugins[PluginInfo.PLUGIN_NAME];
|
||||
const oldTypeResult = Reflect.apply(oldType, thisContext, functionArguments);
|
||||
|
||||
if (hideDefaultSettings)
|
||||
oldTypeResult.props.children = oldTypeResult.props.children.filter(c => !c?.props?.selectedFPS);
|
||||
oldTypeResult.props.children.push(<ReplacedStreamSettings />);
|
||||
|
||||
return oldTypeResult;
|
||||
}
|
||||
|
||||
export function replacedScreenshareModalComponent(oldComponent: (...args: any[]) => any, thisContext: any, functionArguments: any) {
|
||||
const oldComponentResult = Reflect.apply(oldComponent, thisContext, functionArguments);
|
||||
|
||||
const content = oldComponentResult.props.children.props.children[2].props.children[1].props.children[3].props.children.props.children;
|
||||
const oldContentType = content.type;
|
||||
|
||||
content.type = function () {
|
||||
return replacedScreenshareModalSettingsContentType(oldContentType, this, arguments);
|
||||
};
|
||||
|
||||
const [submitBtn, cancelBtn] = oldComponentResult.props.children.props.children[2].props.children[2].props.children;
|
||||
|
||||
submitBtn.props.onClick = () => {
|
||||
export function replacedSubmitFunction(fn) { // This is used to hook over the new OnSubmit function instead of implementing an OnClick function
|
||||
return (...args) => {
|
||||
const { screensharePatcher, screenshareAudioPatcher } = Plugin;
|
||||
|
||||
if (screensharePatcher) {
|
||||
|
@ -80,6 +58,20 @@ export function replacedScreenshareModalComponent(oldComponent: (...args: any[])
|
|||
|
||||
if (screenshareAudioPatcher)
|
||||
screenshareAudioPatcher.forceUpdateTransportationOptions();
|
||||
return fn(...args);
|
||||
};
|
||||
return oldComponentResult;
|
||||
}
|
||||
|
||||
export function GoLivePanelWrapper({ children }: { children: React.JSX.Element; }) {
|
||||
if (!children)
|
||||
return;
|
||||
|
||||
const { hideDefaultSettings } = Settings.plugins[PluginInfo.PLUGIN_NAME];
|
||||
if (hideDefaultSettings)
|
||||
return <ReplacedStreamSettings />;
|
||||
|
||||
children.props.children.push(<ReplacedStreamSettings />);
|
||||
|
||||
return children;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2024 Vendicated and contributors
|
||||
* Copyright (c) 2025 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
|
@ -18,8 +18,8 @@ const plugin = definePlugin({
|
|||
{
|
||||
find: "--custom-app-panels-height",
|
||||
replacement: {
|
||||
match: /(\w+\.\w+\(\w+,{\w+:function\(\){)return (\w)+}/,
|
||||
replace: "$1 $self.storedComp = $2; return $self.replacedUserPanelComponent}"
|
||||
match: /{}\)}\),/,
|
||||
replace: "{})}),$self.replacedUserPanelComponent(),"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -37,7 +37,11 @@ const plugin = definePlugin({
|
|||
}
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
plugin.replacedUserPanelComponent = replacedUserPanelComponent.bind(plugin);
|
||||
|
||||
|
||||
export default plugin;
|
||||
|
||||
export const DeafenIcon = (props: React.ComponentProps<"svg">) => {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2024 Vendicated and contributors
|
||||
* Copyright (c) 2025 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { React } from "@webpack/common";
|
||||
import { JSX } from "react";
|
||||
|
||||
import { SettingsPanel } from "../components";
|
||||
import { IconComponent, SettingsPanelButton } from "../components/settingsPanel/SettingsPanelButton";
|
||||
|
@ -49,10 +50,19 @@ export const ButtonsSettingsPanel = () => {
|
|||
const splicedButtons =
|
||||
settingsPanelButtonsClone
|
||||
.splice(0, 3)
|
||||
.map(({ icon, tooltipText, onClick }) =>
|
||||
.map(({ icon, tooltipText, onClick }, index) =>
|
||||
tooltipText
|
||||
? <SettingsPanelTooltipButton tooltipProps={{ text: tooltipText }} icon={icon} onClick={onClick} />
|
||||
: <SettingsPanelButton icon={icon} onClick={onClick} />
|
||||
? <SettingsPanelTooltipButton
|
||||
key={`tooltip-button-${index}`} // Add a unique key here
|
||||
tooltipProps={{ text: tooltipText }}
|
||||
icon={icon}
|
||||
onClick={onClick}
|
||||
/>
|
||||
: <SettingsPanelButton
|
||||
key={`button-${index}`} // Add a unique key here
|
||||
icon={icon}
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
|
||||
groupedButtons.push(splicedButtons);
|
||||
|
@ -63,24 +73,17 @@ export const ButtonsSettingsPanel = () => {
|
|||
|
||||
return rawPanelButtons.length > 0
|
||||
? <SettingsPanel>
|
||||
{...convertRawPanelButtons(rawPanelButtons).map(value => <SettingsPanelRow children={value} />)}
|
||||
{convertRawPanelButtons(rawPanelButtons).map((value, index) => (
|
||||
<SettingsPanelRow key={`panel-row-${index}`}>
|
||||
{value}
|
||||
</SettingsPanelRow>
|
||||
))}
|
||||
</SettingsPanel>
|
||||
: <>
|
||||
</>;
|
||||
: null;
|
||||
};
|
||||
|
||||
export function replacedUserPanelComponent() {
|
||||
// @ts-ignore
|
||||
const componentResult: JSX.Element = this.storedComp();
|
||||
if (!componentResult?.props) return componentResult;
|
||||
|
||||
const { children } = componentResult.props;
|
||||
|
||||
children.splice(children.length - 1, 0,
|
||||
<ButtonsSettingsPanel />
|
||||
);
|
||||
|
||||
return componentResult;
|
||||
export function replacedUserPanelComponent(oldComponent) {
|
||||
return <ButtonsSettingsPanel />;
|
||||
}
|
||||
|
||||
export function addSettingsPanelButton(settings: PanelButton) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2024 Vendicated and contributors
|
||||
* Copyright (c) 2025 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
|
@ -52,6 +52,7 @@ export function getStreamParameters(connection: types.Connection, get: Profilabl
|
|||
|
||||
return {
|
||||
...connection.videoStreamParameters[0],
|
||||
quality: 100,
|
||||
...(videoBitrateEnabled && videoBitrate
|
||||
? {
|
||||
maxBitrate: videoBitrate * 1000,
|
||||
|
@ -112,12 +113,12 @@ export function getReplaceableVideoTransportationOptions(connection: types.Conne
|
|||
return {
|
||||
...(videoBitrateEnabled && videoBitrate
|
||||
? {
|
||||
encodingVideoBitRate: videoBitrate * 1000,
|
||||
encodingVideoMinBitRate: videoBitrate * 1000,
|
||||
encodingVideoMaxBitRate: videoBitrate * 1000,
|
||||
callBitRate: videoBitrate * 1000,
|
||||
callMinBitRate: videoBitrate * 1000,
|
||||
callMaxBitRate: videoBitrate * 1000
|
||||
encodingVideoBitRate: Math.round(videoBitrate * 1000),
|
||||
encodingVideoMinBitRate: Math.round(videoBitrate * 1000),
|
||||
encodingVideoMaxBitRate: Math.round(videoBitrate * 1000),
|
||||
callBitRate: Math.round(videoBitrate * 1000),
|
||||
callMinBitRate: Math.round(videoBitrate * 1000),
|
||||
callMaxBitRate: Math.round(videoBitrate * 1000)
|
||||
}
|
||||
: {}
|
||||
),
|
||||
|
@ -213,6 +214,33 @@ export function patchConnectionVideoTransportOptions(
|
|||
logger?: Logger
|
||||
) {
|
||||
const oldSetTransportOptions = connection.conn.setTransportOptions;
|
||||
const oldGetQuality = connection.videoQualityManager.getQuality;
|
||||
|
||||
connection.videoQualityManager.getQuality = function (src) {
|
||||
const { currentProfile } = get();
|
||||
const { videoBitrateEnabled, videoBitrate, framerateEnabled, framerate, resolutionEnabled, width, height } = currentProfile;
|
||||
|
||||
const quality = oldGetQuality.call(this, src);
|
||||
|
||||
if (videoBitrateEnabled) {
|
||||
quality.bitrateMax = Math.round(videoBitrate! * 1000);
|
||||
quality.bitrateMin = Math.round(videoBitrate! * 1000);
|
||||
quality.bitrateTarget = Math.round(videoBitrate! * 1000);
|
||||
}
|
||||
|
||||
quality.localWant = 100;
|
||||
quality.capture.framerate = framerateEnabled ? framerate : quality.capture.framerate;
|
||||
|
||||
quality.capture.width = resolutionEnabled ? width : quality.capture.width;
|
||||
quality.capture.height = resolutionEnabled ? height : quality.capture.height;
|
||||
quality.capture.pixelCount = quality.capture.width * quality.capture.height;
|
||||
|
||||
quality.encode = quality.capture;
|
||||
|
||||
logger?.info("Overridden getQuality", quality);
|
||||
|
||||
return quality;
|
||||
};
|
||||
|
||||
connection.conn.setTransportOptions = function (this: any, options: Record<string, any>) {
|
||||
const replaceableTransportOptions = getReplaceableVideoTransportationOptions(connection, get);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2024 Vendicated and contributors
|
||||
* Copyright (c) 2025 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
|
@ -53,10 +53,12 @@ export function createPluginStore<Z extends PluginSettings = {}>(pluginName: str
|
|||
|
||||
const get: PluginGet<Z> = () => {
|
||||
const storeSettings = settingStorage.get(storeName);
|
||||
|
||||
if (!startupStates[storeName]) { // We do this so that we can load all the saved data without the proxy attempting to overwrite it
|
||||
const startupInfo = Settings.plugins[pluginName].stores[storeName];
|
||||
Object.keys(startupInfo).forEach(prop => storeSettings[prop] = startupInfo[prop]);
|
||||
|
||||
storeSettings.simpleMode = startupInfo.simpleMode;
|
||||
storeSettings.profiles = startupInfo.profiles || [];
|
||||
storeSettings.currentProfile = startupInfo.currentProfile || { name: "" };
|
||||
|
||||
startupStates[storeName] = true;
|
||||
}
|
||||
|
@ -70,16 +72,29 @@ export function createPluginStore<Z extends PluginSettings = {}>(pluginName: str
|
|||
const use: PluginUse<Z> = () => { useSettings().plugins[pluginName].stores[storeName]; return get(); }; // useSettings is called to update renderer (after settings change)
|
||||
|
||||
const initialSettings: Z = f(set, get);
|
||||
const proxiedSettings = createObjectProxy(initialSettings as any, updateCallback); // Setup our proxy that allows us connections to the datastore
|
||||
const settingData = Settings.plugins[pluginName].stores[storeName];
|
||||
const filteredInitialSettings: unknown = { // We make sure that everything we pass to the IPC is allowed
|
||||
profiles: settingData.profiles || [],
|
||||
currentProfile: settingData.currentProfile || { name: "" },
|
||||
simpleMode: settingData.simpleMode ?? false
|
||||
};
|
||||
|
||||
const proxiedSettings = createObjectProxy(initialSettings as unknown, updateCallback); // Setup our proxy that allows us connections to the datastore
|
||||
|
||||
function updateCallback(updatedObject: any) {
|
||||
if (!startupStates[storeName]) return; // Wait for the startup information to overwrite the blank proxy
|
||||
Settings.plugins[pluginName].stores[storeName] = JSON.parse(JSON.stringify(updatedObject));
|
||||
|
||||
Settings.plugins[pluginName].stores[storeName] = { // Whenever the proxy is updated we also update the datastore with data that we know can pass through the IPC
|
||||
simpleMode: updatedObject.simpleMode ?? false,
|
||||
profiles: updatedObject.profiles.map(profile => ({ ...profile })),
|
||||
currentProfile: { ...updatedObject.currentProfile } // No clue if this has to be spread or not (disregard the inconsistency ig)
|
||||
};
|
||||
}
|
||||
|
||||
for (const key of Object.keys(initialSettings)) { proxiedSettings[key] = initialSettings[key]; } // Set them so the nested objects also become proxies
|
||||
settingStorage.set(storeName, proxiedSettings);
|
||||
|
||||
set({ ...filteredInitialSettings as Z, ...Settings.plugins[pluginName].stores[storeName] });
|
||||
updateCallback(initialSettings);
|
||||
|
||||
return {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue