Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified bun.lockb
Binary file not shown.
81 changes: 81 additions & 0 deletions libraries/modules/src/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// from https://github.com/Vendicated/Vencord/blob/dev/src/api/Commands/types.ts

import type { Channel, Guild } from 'discord-types/general'

export interface CommandContext {
channel: Channel
guild?: Guild
}

export enum ApplicationCommandOptionType {
SubCommand = 1,
SubCommandGroup = 2,
String = 3,
Integer = 4,
Boolean = 5,
User = 6,
Channel = 7,
Role = 8,
Mentionable = 9,
Number = 10,
Attachment = 11,
}

export enum ApplicationCommandInputType {
BuiltIn = 0,
BuiltInText = 1,
BuiltInIntegration = 2,
Bot = 3,
Placeholder = 4,
}

export interface Option {
name: string
displayName?: string
type: ApplicationCommandOptionType
description: string
displayDescription?: string
required?: boolean
options?: Option[]
choices?: Array<ChoicesOption>
}

export interface ChoicesOption {
label: string
value: string
name: string
displayName?: string
}

export enum ApplicationCommandType {
ChatInput = 1,
User = 2,
Message = 3,
}

export interface CommandReturnValue {
content: string
}

export interface Argument {
type: ApplicationCommandOptionType
name: string
value: string
focused: undefined
options: Argument[]
}

export interface Command {
id: string
untranslatedName: string
displayName: string
type: ApplicationCommandType
inputType: ApplicationCommandInputType
applicationId: string
untranslatedDescription?: string
displayDescription?: string
options?: Option[]

predicate?(ctx: CommandContext): boolean
execute(args: Argument[], ctx: CommandContext): void | CommandReturnValue | Promise<void | CommandReturnValue>
}
2 changes: 1 addition & 1 deletion libraries/modules/src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const channels = findByProps('getVoiceChannelId')!
export const links = findByProps<DiscordModules.LinkingUtils>('openURL', 'openDeeplink')!
export const clipboard = findByProps<DiscordModules.ClipboardUtils>('getImagePNG')!
export const invites = findByProps<DiscordModules.InviteUtils>('createInvite')!
export const commands = findByProps('getBuiltInCommands')!
export const commands = findByProps<DiscordModules.CommandUtils>('getBuiltInCommands')!
export const toasts = findByFilePath<DiscordModules.ToastActionCreators, true>(
'modules/toast/native/ToastActionCreators.tsx',
true,
Expand Down
11 changes: 10 additions & 1 deletion libraries/modules/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import type {
ViewStyle,
} from 'react-native'

import type { Message } from 'discord-types/general'
import type { Command } from './commands'
import type { MetroModuleFilePathKey } from './constants'
import type { lazyContextSymbol } from './utils/lazy'

Expand Down Expand Up @@ -278,14 +280,21 @@ export namespace DiscordModules {
}
}

export interface CommandUtils {
// STUB document these args
getBuiltInCommands(foo: [1], bar: true, baz: false): Command[]
}

export type InviteUtils = {
__stub?: any
}

export type ClipboardUtils = typeof import('@react-native-clipboard/clipboard').default

export type MessageUtils = {
__stub?: any
sendMessage(channelId: string, { content: string }): Promise<Message>
editMessage(channelId: string, messageId: string, { content: string }): Promise<Message>
sendBotMessage(channelId: string, content: string): Promise<Message>
}

/**
Expand Down
6 changes: 4 additions & 2 deletions libraries/plugins/src/internals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import { awaitStorage, createStorage } from '@revenge-mod/storage'
import { getErrorStack } from '@revenge-mod/utils/errors'
import { objectFreeze, objectSeal } from '@revenge-mod/utils/functions'
import { lazyValue } from '@revenge-mod/utils/lazy'

import { logger } from './shared'

import type { FC } from 'react'
import { type FC, createElement } from 'react'

import type { PluginManifest, PluginDefinition } from './schemas'
import type { PluginContext, PluginStopConfig, PluginStorage } from './types'
Expand Down Expand Up @@ -112,6 +111,9 @@ export function registerPlugin<
get stopped() {
return this.status === PluginStatus.Stopped
},
SettingsComponent: definition.SettingsComponent
? () => createElement(definition.SettingsComponent!, ctx!)
: undefined,
disable() {
if (!this.manageable) throw new Error(`Cannot disable unmanageable plugin: ${this.id}`)

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"buffer": "^6.0.3",
"chalk": "^5.3.0",
"clipboardy": "^4.0.0",
"discord-types": "^1.3.3",
"esbuild": "^0.24.0",
"esbuild-plugin-globals": "^0.2.0",
"react-native": "^0.76.3",
Expand Down
16 changes: 14 additions & 2 deletions src/plugins/developer-settings/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/// <reference path="./debugger.d.ts" />

import { toasts } from '@revenge-mod/modules/common'
import { registerPlugin } from '@revenge-mod/plugins/internals'
import { externalPluginsMetadata, registerPlugin } from '@revenge-mod/plugins/internals'
import { sleep } from '@revenge-mod/utils/functions'

import AssetBrowserSettingsPage from './pages/AssetBrowser'
Expand All @@ -11,9 +11,10 @@ import DeveloperSettingsPage from './pages/Developer'
import { DebuggerContext, connectToDebugger } from './debugger'
import { DevToolsEvents, connectToDevTools } from './devtools'

import { BundleUpdaterManager } from '@revenge-mod/modules/native'
import { BundleUpdaterManager, FileModule } from '@revenge-mod/modules/native'
import type { PluginContextFor } from '@revenge-mod/plugins'
import type { FunctionComponent } from 'react'
import { PluginsDirectoryPath } from '@revenge-mod/shared/paths'

const plugin = registerPlugin<{
reactDevTools: {
Expand Down Expand Up @@ -137,6 +138,15 @@ function setupDebugger({ patcher, cleanup }: PluginContextFor<typeof plugin, 'Af
)

globalThis.reload = () => BundleUpdaterManager.reload()
globalThis.getRidOfPlugin = id => {
try {
FileModule.removeFile('documents', `${PluginsDirectoryPath}/${id}`)
delete externalPluginsMetadata[id]
return true
} catch {
return false
}
}
globalThis.patcher = {
snipe: (object, key, callback) =>
debuggerCleanups.add(
Expand All @@ -163,6 +173,8 @@ function setupDebugger({ patcher, cleanup }: PluginContextFor<typeof plugin, 'Af
delete globalThis.reload
// biome-ignore lint/performance/noDelete: This happens once
delete globalThis.patcher
// biome-ignore lint/performance/noDelete: This happens once
delete globalThis.getRidOfPlugin
},
() => {
for (const c of debuggerCleanups) c()
Expand Down
6 changes: 4 additions & 2 deletions src/plugins/settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ const plugin = registerPlugin<Storage>(
},
} = context

for (const member of Contributors.team.concat(Contributors.contributors)) {
if (!member.icon) continue
const contributors = new Set<string>()
for (const member of Object.values(Contributors).flat()) {
if (!member.icon || contributors.has(member.name)) continue

contributors.add(member.name)
assets.registerCustom(
{
name: `Revenge.Contributors.${member.name}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ import PluginCard, { type PluginCardProps } from './PluginCard'
import PluginCardContext from '../contexts/PluginCardContext'

export default function InstalledPluginCard(props: PluginCardProps) {
const { plugin, navigation } = useContext(PluginCardContext)
const {
plugin,
manifest: { name },
navigation,
} = useContext(PluginCardContext)
const { SettingsComponent, enabled, id, manageable, context } = plugin!

const rerender = useRerenderer()
Expand All @@ -29,17 +33,25 @@ export default function InstalledPluginCard(props: PluginCardProps) {
<Show when={SettingsComponent}>
<IconButton
disabled={!enabled}
size="sm"
icon={getAssetIndexByName('SettingsIcon')}
variant="tertiary"
onPress={() => {
navigation.navigate('RevengeCustomPage', {
title: name,
// @ts-expect-error: I love TypeScript
render: () => <SettingsComponent {...context} />,
})
}}
style={{ marginBottom: 'auto' }}
/>
</Show>
<IconButton size="sm" icon={getAssetIndexByName('MoreHorizontalIcon')} variant="tertiary" />
<IconButton
size="sm"
icon={getAssetIndexByName('MoreHorizontalIcon')}
variant="tertiary"
style={{ marginBottom: 'auto' }}
/>
Comment on lines +46 to +54
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the margin-bottom needed here now?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alignment issues when the plugin name takes >1 line, I might take a look into how to fix it by applying styles to the container instead of the children.

<FormSwitch
value={enabled}
disabled={!manageable}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const usePluginCardStyles = createStyles({
},
topContainer: {
alignItems: 'center',
flexShrink: 1,
},
alignedContainer: {
paddingLeft: 28,
Expand Down
5 changes: 5 additions & 0 deletions types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ declare global {
var React: typeof import('react')
var ReactNative: typeof import('react-native')

var __PYON_LOADER__: {
loaderName: string
loaderVersion: string
}

var __REACT_DEVTOOLS_GLOBAL_HOOK__: unknown | undefined
var __reactDevTools:
| {
Expand Down
Loading