explosions
- update deps - major RichPresence rework
This commit is contained in:
parent
6f23ff1a0d
commit
6326b57d6f
6 changed files with 255 additions and 233 deletions
24
package.json
24
package.json
|
|
@ -5,22 +5,22 @@
|
||||||
"lint": "eslint plugins"
|
"lint": "eslint plugins"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-commonjs": "^24.0.1",
|
"@rollup/plugin-commonjs": "^24.1.0",
|
||||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
"@rollup/plugin-node-resolve": "^15.0.2",
|
||||||
"@swc/core": "^1.3.42",
|
"@swc/core": "^1.3.51",
|
||||||
"@types/react": "^18.0.28",
|
"@types/react": "^18.0.37",
|
||||||
"@types/react-native": "^0.70.12",
|
"@types/react-native": "^0.70.13",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.56.0",
|
"@typescript-eslint/eslint-plugin": "^5.59.0",
|
||||||
"@typescript-eslint/parser": "^5.56.0",
|
"@typescript-eslint/parser": "^5.59.0",
|
||||||
"esbuild": "^0.17.12",
|
"esbuild": "^0.17.17",
|
||||||
"eslint": "^8.36.0",
|
"eslint": "^8.38.0",
|
||||||
"eslint-plugin-react": "^7.32.2",
|
"eslint-plugin-react": "^7.32.2",
|
||||||
"rollup": "^3.20.1",
|
"rollup": "^3.20.6",
|
||||||
"rollup-plugin-esbuild": "^5.0.0",
|
"rollup-plugin-esbuild": "^5.0.0",
|
||||||
"typescript": "^4.9.5",
|
"typescript": "^4.9.5",
|
||||||
"vendetta-types": "^2.4.0"
|
"vendetta-types": "^2.4.18"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@swc/helpers": "^0.4.14"
|
"@swc/helpers": "^0.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
159
plugins/RichPresence/src/ConfigEditor.tsx
Normal file
159
plugins/RichPresence/src/ConfigEditor.tsx
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
import { React, stylesheet } from "@vendetta/metro/common";
|
||||||
|
import { storage } from "@vendetta/plugin";
|
||||||
|
import { useProxy } from "@vendetta/storage";
|
||||||
|
import { semanticColors } from "@vendetta/ui";
|
||||||
|
import { Forms } from "@vendetta/ui/components";
|
||||||
|
|
||||||
|
import { ScrollView } from "react-native";
|
||||||
|
|
||||||
|
const { FormSection, FormInput, FormRow, FormSwitch, FormText } = Forms;
|
||||||
|
|
||||||
|
const styles = stylesheet.createThemedStyleSheet({
|
||||||
|
subText: {
|
||||||
|
fontSize: 14,
|
||||||
|
marginLeft: 16,
|
||||||
|
marginRight: 16,
|
||||||
|
color: semanticColors.TEXT_MUTED
|
||||||
|
},
|
||||||
|
textLink: {
|
||||||
|
color: semanticColors.TEXT_LINK,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function ConfigEditor({ selection }: { selection: string }) {
|
||||||
|
const settings = useProxy(storage.selections[selection]) as Activity;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView>
|
||||||
|
<FormSection title="Basic">
|
||||||
|
<FormInput
|
||||||
|
title="Application Name"
|
||||||
|
value={settings.name}
|
||||||
|
placeholder="Vendetta"
|
||||||
|
onChange={v => settings.name = v}
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
title="Application ID"
|
||||||
|
value={settings.application_id}
|
||||||
|
placeholder="1054951789318909972"
|
||||||
|
onChange={v => settings.application_id = v}
|
||||||
|
keyboardType="numeric"
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
title="Type"
|
||||||
|
value={settings.type}
|
||||||
|
placeholder="0"
|
||||||
|
onChange={v => settings.type = v}
|
||||||
|
keyboardType="numeric"
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
title="Details"
|
||||||
|
value={settings.details}
|
||||||
|
placeholder="Competitive"
|
||||||
|
onChange={v => settings.details = v}
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
title="State"
|
||||||
|
value={settings.state}
|
||||||
|
placeholder="Playing Solo"
|
||||||
|
onChange={v => settings.state = v}
|
||||||
|
/>
|
||||||
|
</FormSection>
|
||||||
|
<FormSection title="Images">
|
||||||
|
<FormInput
|
||||||
|
title="Large Image Asset Key or URL"
|
||||||
|
value={settings.assets.large_image}
|
||||||
|
placeholder="large_image_here"
|
||||||
|
onChange={v => settings.assets.large_image = v}
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
title="Large Image Text"
|
||||||
|
value={settings.assets.large_text}
|
||||||
|
placeholder="Playing on Joe's lobby"
|
||||||
|
disabled={!settings.assets.large_image}
|
||||||
|
onChange={v => settings.assets.large_text = v}
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
title="Small Image Asset Key or URL"
|
||||||
|
value={settings.assets.small_image}
|
||||||
|
placeholder="small_image_here"
|
||||||
|
onChange={v => settings.assets.small_image = v}
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
title="Small Image Text"
|
||||||
|
value={settings.assets.small_text}
|
||||||
|
placeholder="Solo"
|
||||||
|
disabled={!settings.assets.small_image}
|
||||||
|
onChange={v => settings.assets.small_text = v}
|
||||||
|
/>
|
||||||
|
</FormSection>
|
||||||
|
<FormText style={styles.subText}>
|
||||||
|
{"Image assets key can be either a Discord app asset's name or a URL to an image."}
|
||||||
|
</FormText>
|
||||||
|
<FormSection title="Timestamps">
|
||||||
|
<FormRow
|
||||||
|
label="Enable timestamps"
|
||||||
|
subLabel="Set whether to show timestamps or not"
|
||||||
|
trailing={<FormSwitch
|
||||||
|
value={settings.timestamps._enabled}
|
||||||
|
onValueChange={v => settings.timestamps._enabled = v}
|
||||||
|
/>}
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
title="Start Timestamp (miliseconds)"
|
||||||
|
value={settings.timestamps.start}
|
||||||
|
placeholder="1234567890"
|
||||||
|
disabled={!settings.timestamps._enabled}
|
||||||
|
onChange={v => settings.timestamps.start = v}
|
||||||
|
keyboardType="numeric"
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
title="End Timestamp (miliseconds)"
|
||||||
|
value={settings.timestamps.end}
|
||||||
|
placeholder="1234567890"
|
||||||
|
disabled={!settings.timestamps._enabled}
|
||||||
|
onChange={v => settings.timestamps.end = v}
|
||||||
|
keyboardType="numeric"
|
||||||
|
/>
|
||||||
|
<FormRow
|
||||||
|
label="Use current time as start timestamp"
|
||||||
|
subLabel="This will override the start timestamp you set above"
|
||||||
|
disabled={!settings.timestamps._enabled}
|
||||||
|
onPress={() => settings.timestamps.start = String(Date.now())}
|
||||||
|
trailing={FormRow.Arrow}
|
||||||
|
/>
|
||||||
|
<FormText style={styles.subText}>
|
||||||
|
Leaving start timestamp blank will use the time the Discord started.
|
||||||
|
</FormText>
|
||||||
|
</FormSection>
|
||||||
|
<FormSection title="Buttons">
|
||||||
|
<FormInput
|
||||||
|
title="First Button Text"
|
||||||
|
value={settings.buttons[0].label}
|
||||||
|
placeholder="random link #1"
|
||||||
|
onChange={v => settings.buttons[0].label = v}
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
title="First Button URL"
|
||||||
|
value={settings.buttons[0].url}
|
||||||
|
placeholder="https://discord.com/vanityurl/dotcom/steakpants/flour/flower/index11.html"
|
||||||
|
disabled={!settings.buttons[0].label}
|
||||||
|
onChange={v => settings.buttons[0].url = v}
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
title="Second Button Text"
|
||||||
|
value={settings.buttons[1].label}
|
||||||
|
placeholder="random link #2"
|
||||||
|
onChange={v => settings.buttons[1].label = v}
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
title="Second Button URL"
|
||||||
|
value={settings.buttons[1].url}
|
||||||
|
placeholder="https://youtu.be/w0AOGeqOnFY"
|
||||||
|
disabled={!settings.buttons[1].label}
|
||||||
|
onChange={v => settings.buttons[1].url = v}
|
||||||
|
/>
|
||||||
|
</FormSection>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,159 +1,11 @@
|
||||||
import { React, stylesheet } from "@vendetta/metro/common";
|
import plugin from "@vendetta/plugin";
|
||||||
import { storage } from "@vendetta/plugin";
|
import ConfigEditor from "./ConfigEditor";
|
||||||
import { useProxy } from "@vendetta/storage";
|
|
||||||
import { semanticColors } from "@vendetta/ui";
|
|
||||||
import { Forms } from "@vendetta/ui/components";
|
|
||||||
|
|
||||||
import { ScrollView } from "react-native";
|
const storage = plugin.storage as typeof plugin.storage & {
|
||||||
|
selected: string;
|
||||||
|
selections: Record<string, Activity>;
|
||||||
|
};
|
||||||
|
|
||||||
const { FormSection, FormInput, FormRow, FormSwitch, FormText } = Forms;
|
export default () => (
|
||||||
|
<ConfigEditor selection={storage.selected} />
|
||||||
const styles = stylesheet.createThemedStyleSheet({
|
)
|
||||||
subText: {
|
|
||||||
fontSize: 14,
|
|
||||||
marginLeft: 16,
|
|
||||||
marginRight: 16,
|
|
||||||
color: semanticColors.TEXT_MUTED
|
|
||||||
},
|
|
||||||
textLink: {
|
|
||||||
color: semanticColors.TEXT_LINK,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default function Settings() {
|
|
||||||
const settings = useProxy(storage) as { [key: string]: any };
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ScrollView>
|
|
||||||
<FormSection title="Basic">
|
|
||||||
<FormInput
|
|
||||||
title="Application Name"
|
|
||||||
value={settings.app_name}
|
|
||||||
placeholder="Vendetta"
|
|
||||||
onChange={v => settings.app_name = v}
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
title="Application ID"
|
|
||||||
value={settings.application_id}
|
|
||||||
placeholder="1054951789318909972"
|
|
||||||
onChange={v => settings.application_id = v}
|
|
||||||
keyboardType="numeric"
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
title="Type"
|
|
||||||
value={settings.type}
|
|
||||||
placeholder="0"
|
|
||||||
onChange={v => settings.type = v}
|
|
||||||
keyboardType="numeric"
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
title="Details"
|
|
||||||
value={settings.details}
|
|
||||||
placeholder="Competitive"
|
|
||||||
onChange={v => settings.details = v}
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
title="State"
|
|
||||||
value={settings.state}
|
|
||||||
placeholder="Playing Solo"
|
|
||||||
onChange={v => settings.state = v}
|
|
||||||
/>
|
|
||||||
</FormSection>
|
|
||||||
<FormSection title="Images">
|
|
||||||
<FormInput
|
|
||||||
title="Large Image Asset Key or URL"
|
|
||||||
value={settings.large_image}
|
|
||||||
placeholder="large_image_here"
|
|
||||||
onChange={v => settings.large_image = v}
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
title="Large Image Text"
|
|
||||||
value={settings.large_image_text}
|
|
||||||
placeholder="Playing on Joe's lobby"
|
|
||||||
disabled={!settings.large_image}
|
|
||||||
onChange={v => settings.large_image_text = v}
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
title="Small Image Asset Key or URL"
|
|
||||||
value={settings.small_image}
|
|
||||||
placeholder="small_image_here"
|
|
||||||
onChange={v => settings.small_image = v}
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
title="Small Image Text"
|
|
||||||
value={settings.small_image_text}
|
|
||||||
placeholder="Solo"
|
|
||||||
disabled={!settings.small_image}
|
|
||||||
onChange={v => settings.small_image_text = v}
|
|
||||||
/>
|
|
||||||
<FormText style={styles.subText}>
|
|
||||||
{"Image assets key can be either a Discord app asset's name or a URL to an image."}
|
|
||||||
</FormText>
|
|
||||||
</FormSection>
|
|
||||||
<FormSection title="Timestamps">
|
|
||||||
<FormRow
|
|
||||||
label="Enable timestamps"
|
|
||||||
subLabel="Set whether to show timestamps or not"
|
|
||||||
trailing={<FormSwitch
|
|
||||||
value={settings.enable_timestamps}
|
|
||||||
onValueChange={v => settings.enable_timestamps = v}
|
|
||||||
/>}
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
title="Start Timestamp (seconds)"
|
|
||||||
value={settings.start_timestamp}
|
|
||||||
placeholder="1234567890"
|
|
||||||
disabled={!settings.enable_timestamps}
|
|
||||||
onChange={v => settings.start_timestamp = v}
|
|
||||||
keyboardType="numeric"
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
title="End Timestamp (seconds)"
|
|
||||||
value={settings.end_timestamp}
|
|
||||||
placeholder="1234567890"
|
|
||||||
disabled={!settings.enable_timestamps}
|
|
||||||
onChange={v => settings.end_timestamp = v}
|
|
||||||
keyboardType="numeric"
|
|
||||||
/>
|
|
||||||
<FormRow
|
|
||||||
label="Use current time as start timestamp"
|
|
||||||
subLabel="This will override the start timestamp you set above"
|
|
||||||
disabled={!settings.enable_timestamps}
|
|
||||||
onPress={() => settings.start_timestamp = String(Date.now())}
|
|
||||||
trailing={FormRow.Arrow}
|
|
||||||
/>
|
|
||||||
<FormText style={styles.subText}>
|
|
||||||
Leaving start timestamp blank will use the time the Discord started.
|
|
||||||
</FormText>
|
|
||||||
</FormSection>
|
|
||||||
<FormSection title="Buttons">
|
|
||||||
<FormInput
|
|
||||||
title="First Button Text"
|
|
||||||
value={settings.button1_text}
|
|
||||||
placeholder="random link #1"
|
|
||||||
onChange={v => settings.button1_text = v}
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
title="First Button URL"
|
|
||||||
value={settings.button1_URL}
|
|
||||||
placeholder="https://discord.com/vanityurl/dotcom/steakpants/flour/flower/index11.html"
|
|
||||||
disabled={!settings.button1_text}
|
|
||||||
onChange={v => settings.button1_URL = v}
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
title="Second Button Text"
|
|
||||||
value={settings.button2_text}
|
|
||||||
placeholder="random link #2"
|
|
||||||
onChange={v => settings.button2_text = v}
|
|
||||||
/>
|
|
||||||
<FormInput
|
|
||||||
title="Second Button URL"
|
|
||||||
value={settings.button2_URL}
|
|
||||||
placeholder="https://youtu.be/w0AOGeqOnFY"
|
|
||||||
disabled={!settings.button2_text}
|
|
||||||
onChange={v => settings.button2_URL = v}
|
|
||||||
/>
|
|
||||||
</FormSection>
|
|
||||||
</ScrollView>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
import { logger } from "@vendetta";
|
import { logger, plugin } from "@vendetta";
|
||||||
import { findByProps } from "@vendetta/metro";
|
import { findByProps } from "@vendetta/metro";
|
||||||
import { FluxDispatcher } from "@vendetta/metro/common";
|
import { FluxDispatcher } from "@vendetta/metro/common";
|
||||||
import { storage } from "@vendetta/plugin";
|
|
||||||
import Settings from "./Settings";
|
import Settings from "./Settings";
|
||||||
|
import { cloneAndFilter } from "./utils";
|
||||||
const AssetManager = findByProps("getAssetIds");
|
|
||||||
|
|
||||||
enum ActivityTypes {
|
enum ActivityTypes {
|
||||||
PLAYING = 0,
|
PLAYING = 0,
|
||||||
|
|
@ -15,59 +13,52 @@ enum ActivityTypes {
|
||||||
COMPETING = 5
|
COMPETING = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
// :nyaboom:
|
const AssetManager = findByProps("getAssetIds");
|
||||||
function constructActivity() {
|
const pluginStartSince = Date.now();
|
||||||
const activity: Activity = {
|
|
||||||
name: storage.app_name || "Discord",
|
const storage = plugin.storage as typeof plugin.storage & {
|
||||||
application_id: storage.application_id || "1054951789318909972",
|
selected: string;
|
||||||
|
selections: Record<string, Activity>;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!storage.selected) {
|
||||||
|
Object.assign(storage, {
|
||||||
|
selected: "default",
|
||||||
|
selections: {
|
||||||
|
default: createDefaultSelection()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDefaultSelection(): Activity {
|
||||||
|
return {
|
||||||
|
name: "Discord",
|
||||||
|
application_id: "1054951789318909972",
|
||||||
flags: 0,
|
flags: 0,
|
||||||
type: ActivityTypes.PLAYING, // PLAYING
|
type: ActivityTypes.PLAYING,
|
||||||
state: storage.state,
|
timestamps: {
|
||||||
details: storage.details
|
_enabled: false,
|
||||||
|
start: pluginStartSince
|
||||||
|
},
|
||||||
|
assets: {},
|
||||||
|
// @ts-ignore
|
||||||
|
buttons: [{}, {}]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Construct timestamps
|
|
||||||
if (storage.enable_timestamps) {
|
|
||||||
const timestamps = {} as any;
|
|
||||||
|
|
||||||
timestamps.start = Number(storage.start_timestamp) || Date.now();
|
|
||||||
if (!isNaN(storage.end_timestamp)) timestamps.end = Number(storage.end_timestamp);
|
|
||||||
|
|
||||||
activity.timestamps = timestamps;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct assets
|
|
||||||
const assets = {} as ActivityAssets;
|
|
||||||
|
|
||||||
if (storage.large_image) {
|
|
||||||
assets.large_image = storage.large_image;
|
|
||||||
if (storage.large_image_text) assets.large_text = storage.large_image_text;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (storage.small_image) {
|
|
||||||
assets.small_image = storage.small_image;
|
|
||||||
if (storage.small_image_text) assets.small_text = storage.small_image_text;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Object.keys(assets).length) activity.assets = assets;
|
|
||||||
|
|
||||||
// Construct buttons
|
|
||||||
if (storage.button1_text && storage.button1_URL) {
|
|
||||||
activity.buttons = [
|
|
||||||
{ label: storage.button1_text, url: storage.button1_URL }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (storage.button2_text && storage.button2_URL) {
|
|
||||||
(activity.buttons ??= []).push({ label: storage.button2_text, url: storage.button2_URL });
|
|
||||||
}
|
|
||||||
|
|
||||||
return activity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendRequest(activity: Activity | null): Promise<Activity> {
|
async function sendRequest(activity: Activity | null): Promise<Activity> {
|
||||||
if (typeof activity !== "object") throw new Error("Invalid activity");
|
if (typeof activity !== "object") throw new Error("Invalid activity");
|
||||||
|
|
||||||
|
const timestampEnabled = activity?.timestamps?._enabled;
|
||||||
|
activity = cloneAndFilter(activity);
|
||||||
|
|
||||||
|
if (timestampEnabled) {
|
||||||
|
delete activity.timestamps._enabled;
|
||||||
|
activity.timestamps.start ||= pluginStartSince;
|
||||||
|
} else {
|
||||||
|
delete activity.timestamps;
|
||||||
|
}
|
||||||
|
|
||||||
if (activity?.assets) {
|
if (activity?.assets) {
|
||||||
const [largeImage, smallImage] = await AssetManager.getAssetIds(activity.application_id, [activity.assets.large_image, activity.assets.small_image]);
|
const [largeImage, smallImage] = await AssetManager.getAssetIds(activity.application_id, [activity.assets.large_image, activity.assets.small_image]);
|
||||||
activity.assets.large_image = largeImage;
|
activity.assets.large_image = largeImage;
|
||||||
|
|
@ -76,20 +67,12 @@ async function sendRequest(activity: Activity | null): Promise<Activity> {
|
||||||
|
|
||||||
if (activity?.buttons?.length) {
|
if (activity?.buttons?.length) {
|
||||||
activity.buttons = activity.buttons.filter(x => x.label && x.url);
|
activity.buttons = activity.buttons.filter(x => x.label && x.url);
|
||||||
Object.assign(activity, {
|
activity.buttons.length && Object.assign(activity, {
|
||||||
metadata: { button_urls: activity.buttons.map(x => x.url) },
|
metadata: { button_urls: activity.buttons.map(x => x.url) },
|
||||||
buttons: activity.buttons.map(x => x.label)
|
buttons: activity.buttons.map(x => x.label)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate activity
|
|
||||||
for (const k in activity) {
|
|
||||||
if (activity[k] === undefined || activity[k] === null) delete activity[k];
|
|
||||||
if (typeof activity[k].length === "number" && activity[k].length === 0) delete activity[k];
|
|
||||||
if (typeof activity[k] === "object" && Object.keys(activity[k]).length === 0) delete activity[k];
|
|
||||||
if (typeof activity[k] === "object" && activity[k].length === 0) delete activity[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
FluxDispatcher.dispatch({
|
FluxDispatcher.dispatch({
|
||||||
type: "LOCAL_ACTIVITY_UPDATE",
|
type: "LOCAL_ACTIVITY_UPDATE",
|
||||||
activity: activity
|
activity: activity
|
||||||
|
|
@ -101,7 +84,9 @@ async function sendRequest(activity: Activity | null): Promise<Activity> {
|
||||||
export default new class RichPresence {
|
export default new class RichPresence {
|
||||||
onLoad() {
|
onLoad() {
|
||||||
logger.log("Sending RPC request");
|
logger.log("Sending RPC request");
|
||||||
sendRequest(constructActivity()).catch().then(x => {
|
|
||||||
|
const currentActivity = storage.selections[storage.selected];
|
||||||
|
sendRequest(currentActivity).catch().then(x => {
|
||||||
logger.log("RPC request sent");
|
logger.log("RPC request sent");
|
||||||
console.log(x);
|
console.log(x);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
25
plugins/RichPresence/src/utils.ts
Normal file
25
plugins/RichPresence/src/utils.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
function isValid(val: any) {
|
||||||
|
if (val && typeof val.length === "number") return val.length > 0;
|
||||||
|
return val || val === 0 || val === false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deep clone and filter empty objects/values or keys starting with "_"
|
||||||
|
export function cloneAndFilter<T extends object>(obj: T): T {
|
||||||
|
const filter = (k: PropertyKey, v: any) => {
|
||||||
|
if (v === obj) return v;
|
||||||
|
if (typeof k === "string" && k.startsWith("_")) return undefined;
|
||||||
|
|
||||||
|
switch (typeof v) {
|
||||||
|
case "object": {
|
||||||
|
if (Array.isArray(v) && v.length === 0) return undefined;
|
||||||
|
|
||||||
|
const filteredEntries = Object.entries(v).filter((e) => isValid(e[1]));
|
||||||
|
return filteredEntries.length > 0 ? Object.fromEntries(filteredEntries) : undefined;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return isValid(v) ? v : undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return JSON.parse(JSON.stringify(obj, filter));
|
||||||
|
}
|
||||||
9
plugins/defs.d.ts
vendored
9
plugins/defs.d.ts
vendored
|
|
@ -6,11 +6,12 @@ type Activity = {
|
||||||
details?: string;
|
details?: string;
|
||||||
state?: string;
|
state?: string;
|
||||||
timestamps?: {
|
timestamps?: {
|
||||||
start: number;
|
_enabled: boolean;
|
||||||
end?: number;
|
start: number | string;
|
||||||
|
end?: number | string;
|
||||||
};
|
};
|
||||||
assets?: ActivityAssets;
|
assets: ActivityAssets;
|
||||||
buttons?: ActivityButton[];
|
buttons: ActivityButton[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type ActivityButton = {
|
type ActivityButton = {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue