diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76731dd..f631a2d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1731,3 +1731,5 @@ packages: /yallist/4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true + +publishDirectory: lib diff --git a/src/api/Commands.ts b/src/api/Commands.ts index b6c0dd7..f180384 100644 --- a/src/api/Commands.ts +++ b/src/api/Commands.ts @@ -3,6 +3,7 @@ import { SnowflakeUtils } from "../metro"; export interface CommandSection { id: string; name: string; + type: number; icon?: string; } @@ -81,7 +82,9 @@ export class Commands { public static _aliucordSection: CommandSection = { id: Commands.generateId(), - name: "Aliucord" + type: 1, + name: "Aliucord", + icon: "https://github.com/aliucord.png" }; public static _commands: AliucordCommand[] = []; diff --git a/src/core-plugins/CommandHandler.ts b/src/core-plugins/CommandHandler.ts index fd94f36..e8e5c57 100644 --- a/src/core-plugins/CommandHandler.ts +++ b/src/core-plugins/CommandHandler.ts @@ -1,4 +1,4 @@ -import { ApplicationCommand, ApplicationCommandType, Commands, CommandSection } from "../api/Commands"; +import { ApplicationCommand, ApplicationCommandType, Commands } from "../api/Commands"; import { Plugin } from "../entities/Plugin"; import { getByProps } from "../metro"; import { after } from "../utils/patcher"; @@ -6,33 +6,18 @@ import { after } from "../utils/patcher"; export default class CommandHandler extends Plugin { start() { const commands = getByProps("getBuiltInCommands"); + commands.BUILT_IN_SECTIONS["aliucord"] = Commands._aliucordSection; after(commands, "getBuiltInCommands", context => { if (context.args[0] != ApplicationCommandType.CHAT) return; context.result = [...context.result, ...Commands._commands]; }); - const discovery = getByProps("useApplicationCommandsDiscoveryState"); - after(discovery, "useApplicationCommandsDiscoveryState", context => { - const res = context.result as any; - if (!res.discoverySections.find((s: any) => s.key === Commands._aliucordSection.id) && Commands._commands.length) { - res.discoveryCommands.push(...Commands._commands); - res.commands.push(...Commands._commands.filter( - command => !res.commands.some((cmd: ApplicationCommand) => cmd.name === command.name)) - ); - - res.discoverySections.push({ - data: Commands._commands, - key: Commands._aliucordSection.id, - section: Commands._aliucordSection - }); - - const offsets = res.sectionsOffset; - offsets.push(offsets[offsets.length - 1] + commands.BUILT_IN_COMMANDS.length - 1); - } - - if (!res.applicationCommandSections.find((s: CommandSection) => s.id === Commands._aliucordSection.id) && Commands._commands.length) { - res.applicationCommandSections.push(Commands._aliucordSection); - } + const assets = getByProps("getApplicationIconURL"); + after(assets, "getApplicationIconURL", context => { + const [props] = context.args; + if (props.id === Commands._aliucordSection.id) + context.result = Commands._aliucordSection.icon; }); + } } diff --git a/src/metro/index.ts b/src/metro/index.ts index 03d4b5f..14ac81c 100644 --- a/src/metro/index.ts +++ b/src/metro/index.ts @@ -261,6 +261,7 @@ export const FluxDispatcher = getByProps("isDispatching"); export const FetchUserActions = getByProps("fetchProfile"); export const ContextMenuActions = getByProps("openContextMenu"); export const SnowflakeUtils = getByProps("fromTimestamp", "extractTimestamp"); +export const Locale = getByProps("Messages"); export const Clipboard = getByProps("getString", "setString") as { getString(): Promise, diff --git a/src/ui/ThemesPage.tsx b/src/ui/ThemesPage.tsx new file mode 100644 index 0000000..6362db5 --- /dev/null +++ b/src/ui/ThemesPage.tsx @@ -0,0 +1,17 @@ +import { Forms, React } from "../metro"; +import { getAssetId } from "../utils/getAssetId"; + +const { FormSection, FormRow } = Forms; + +export default function ThemesPage() { + return ( + <> + + } + label="Coming soon" + /> + + + ); +} diff --git a/src/ui/UpdaterPage.tsx b/src/ui/UpdaterPage.tsx index f079037..38889be 100644 --- a/src/ui/UpdaterPage.tsx +++ b/src/ui/UpdaterPage.tsx @@ -1,4 +1,17 @@ +import { Forms, React } from "../metro"; +import { getAssetId } from "../utils/getAssetId"; + +const { FormSection, FormRow } = Forms; export default function UpdaterPage() { - return null; + return ( + <> + + } + label="Coming soon" + /> + + + ); } diff --git a/src/ui/patchSettings.tsx b/src/ui/patchSettings.tsx index 81a8ad0..48512f2 100644 --- a/src/ui/patchSettings.tsx +++ b/src/ui/patchSettings.tsx @@ -1,15 +1,16 @@ import { sha } from "aliucord-version"; -import { Forms, getByName, i18n, React, ReactNative as RN } from "../metro"; +import { Forms, getByName, Locale, React } from "../metro"; +import { findInReactTree } from "../utils/findInReactTree"; import { after } from "../utils/patcher"; +import { getAssetId } from "../utils/getAssetId"; import AliucordPage from "./AliucordPage"; import PluginsPage from "./PluginsPage"; import UpdaterPage from "./UpdaterPage"; - +import ThemesPage from "./ThemesPage"; export default function patchSettings() { const { FormSection, FormRow } = Forms; - const UserSettingsOverviewWrapper = getByName("UserSettingsOverviewWrapper"); - + const UserSettingsOverviewWrapper = getByName("UserSettingsOverviewWrapper", { default: false }); after(getByName("getScreens"), "default", (_, res) => { res.ASettings = { title: "Aliucord", @@ -21,7 +22,7 @@ export default function patchSettings() { }; res.AThemes = { title: "Themes", - render: () => Hello World + render: ThemesPage }; res.AUpdater = { title: "Updater", @@ -33,55 +34,59 @@ export default function patchSettings() { }); const unpatch = after(UserSettingsOverviewWrapper, "default", (_, res) => { - unpatch(); - - const { navigation } = res.props; + const Overview = findInReactTree(res, m => m.type?.name === "UserSettingsOverview"); // Yeet the funny Upload Logs button - after(res.type.prototype, "renderSupportAndAcknowledgements", (_, { props }) => { + after(Overview.type.prototype, "renderSupportAndAcknowledgements", (_, { props }) => { const idx = props.children.findIndex(c => c?.type?.name === "UploadLogsButton"); if (idx !== -1) { props.children.splice(idx, 1); } }); - after(res.type.prototype, "render", (_, { props }) => { - const nitroIndex = props.children.findIndex(c => c?.props?.title === i18n.Messages.PREMIUM_SETTINGS); + after(Overview.type.prototype, "render", (_, { props }) => { + const { children } = props; - const aliucordSection = ( + const searchable = [Locale.Messages["BILLING_SETTINGS"], Locale.Messages["PREMIUM_SETTINGS"]]; + const index = children.findIndex(x => searchable.includes(x.props.title)); + + children.splice(index === -1 ? 4 : index, 0, <> } label="Aliucord" trailing={FormRow.Arrow} onPress={() => - navigation.push("ASettings") + Overview.props.navigation.push("ASettings") } /> } label="Plugins" trailing={FormRow.Arrow} onPress={() => - navigation.push("APlugins") + Overview.props.navigation.push("APlugins") } /> } label="Themes" trailing={FormRow.Arrow} onPress={() => - navigation.push("AThemes") + Overview.props.navigation.push("AThemes") } /> } label="Updater" trailing={FormRow.Arrow} onPress={() => - navigation.push("AUpdater") + Overview.props.navigation.push("AUpdater") } /> - ); - - props.children.splice(nitroIndex, 0, aliucordSection); + ); }); + unpatch(); }); } diff --git a/src/utils/index.ts b/src/utils/index.ts index 159ea13..be32706 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,6 +1,6 @@ export * as constants from "./constants"; export * from "./debug"; -// export * from "./findInReactTree"; just exporting this makes the app crash with ReferenceError: Property 'ref' doesn't exist, bruh? +export * from "./findInReactTree"; export * from "./getAssetId"; export * from "./Logger"; export * from "./misc"; diff --git a/src/utils/patcher.ts b/src/utils/patcher.ts index ce817b0..d2117a8 100644 --- a/src/utils/patcher.ts +++ b/src/utils/patcher.ts @@ -144,7 +144,7 @@ class PatchInfo { const lastError = ctx.error; try { - const result = patches[idx].after(ctx as AfterPatchContext, ctx.result!, ...ctx.args); + const result = patches[idx].after(ctx as AfterPatchContext, ctx.result as R, ...ctx.args); if (result !== undefined) ctx.result = result; } catch (err: any) { this.error(patches[idx], "PostPatch", err);