diff --git a/plugins/Commands/settings.tsx b/plugins/Commands/settings.tsx
index 96b3c96..8aa40e9 100644
--- a/plugins/Commands/settings.tsx
+++ b/plugins/Commands/settings.tsx
@@ -47,10 +47,11 @@ storage.enabledCommands ??= {
storage.pendingRestart ??= false;
-// Hidden settings storage
+// Hidden settings storage with NSFW bypass option
storage.hiddenSettings ??= {
enabled: false,
visible: false,
+ konochanBypassNsfw: false, // New bypass option - disabled by default
};
// Better Table Row Group Component
@@ -206,7 +207,7 @@ function Header({ onHiddenUnlock }: { onHiddenUnlock?: () => void }) {
);
}
-// Hidden Commands Settings Page
+// Hidden Commands Settings Page with NSFW bypass option
function HiddenSettingsPage() {
useProxy(storage);
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
@@ -258,6 +259,35 @@ function HiddenSettingsPage() {
/>
+
+ }
+ value={storage.hiddenSettings.konochanBypassNsfw}
+ onValueChange={(v) => {
+ if (v) {
+ alerts.showConfirmationAlert({
+ title: "⚠️ NSFW Bypass Warning",
+ content: "Enabling this allows NSFW content from KonoChan to be sent in any channel, including non-NSFW channels. This could violate server rules or Discord ToS. Use responsibly!",
+ confirmText: "I Understand",
+ cancelText: "Cancel",
+ onConfirm: () => {
+ storage.hiddenSettings.konochanBypassNsfw = true;
+ forceUpdate();
+ },
+ onCancel: () => {
+ // Do nothing - keep it disabled
+ },
+ });
+ } else {
+ storage.hiddenSettings.konochanBypassNsfw = false;
+ forceUpdate();
+ }
+ }}
+ />
+
+
{
storage.hiddenSettings.enabled = false;
storage.hiddenSettings.visible = false;
+ storage.hiddenSettings.konochanBypassNsfw = false; // Reset bypass option
storage.enabledCommands.lovefemboys = false;
storage.pendingRestart = true;
showToast("Hidden settings reset", getAssetIDByName("CheckmarkIcon"));
@@ -587,7 +618,7 @@ function ImageSettingsPage() {
);
}
-// Spotify Settings Page - FIXED with proper text styling
+// Spotify Settings Page
function SpotifySettingsPage() {
useProxy(storage);
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
@@ -701,7 +732,7 @@ function OtherSettingsPage() {
);
}
-// Credits Page - UPDATED VERSION TO 1.0.1
+// Credits Page
function CreditsPage() {
const styles = stylesheet.createThemedStyleSheet({
container: {
diff --git a/plugins/Commands/src/commands/konochan.ts b/plugins/Commands/src/commands/konochan.ts
index 2e55204..8aa40e9 100644
--- a/plugins/Commands/src/commands/konochan.ts
+++ b/plugins/Commands/src/commands/konochan.ts
@@ -1,131 +1,1016 @@
-import { findByProps } from "@vendetta/metro";
+import { storage } from "@vendetta/plugin";
+import { useProxy } from "@vendetta/storage";
+import { React, ReactNative as RN, stylesheet } from "@vendetta/metro/common";
+import { NavigationNative } from "@vendetta/metro/common";
+import { semanticColors } from "@vendetta/ui";
+import { getAssetIDByName } from "@vendetta/ui/assets";
+import { Forms } from "@vendetta/ui/components";
import { alerts } from "@vendetta/ui";
+import { showToast } from "@vendetta/ui/toasts";
-const MessageActions = findByProps("sendMessage");
-const messageUtil = findByProps("sendBotMessage", "sendMessage", "receiveMessage");
+const { ScrollView } = RN;
+const { FormRow, FormSwitchRow } = Forms;
-/**
- * Fetches a random image from KonoChan.
- * @param isNSFW - Whether to include NSFW content.
- * @returns The URL of the fetched image or null if none are found.
- */
-const fetchImage = async (isNSFW: boolean): Promise => {
- const baseURL = "https://konachan.com/post.json";
- const tag = isNSFW ? "rating:explicit" : "rating:safe";
- const randomPage = Math.floor(Math.random() * 100);
-
- try {
- const response = await fetch(`${baseURL}?tags=${tag}&limit=1&page=${randomPage}`);
- const data = await response.json();
-
- if (!Array.isArray(data) || data.length === 0) {
- return null;
- }
-
- return data[0].file_url;
- } catch (error) {
- console.error("[KonoChan Randomizer] Error fetching image:", error);
- return null;
- }
+// Initialize storage with default values
+storage.factSettings ??= {
+ sendAsReply: true,
+ includeCitation: false,
};
-const showNSFWWarning = () => {
- return alerts.showConfirmationAlert({
- title: "NSFW Content Warning",
- content: "NSFW content can only be sent in NSFW channels!",
- confirmText: "Okay",
- cancelText: null,
- confirmColor: "brand",
- isDismissable: true,
+storage.listSettings ??= {
+ pluginListAlwaysDetailed: false,
+ themeListAlwaysDetailed: false,
+};
+
+storage.garySettings ??= {
+ imageSource: "gary",
+};
+
+storage.enabledCommands ??= {
+ catfact: true,
+ dogfact: true,
+ useless: true,
+ petpet: true,
+ pluginList: true,
+ themeList: true,
+ konoself: true,
+ konosend: true,
+ firstmessage: true,
+ sysinfo: true,
+ spotifyTrack: true,
+ spotifyAlbum: true,
+ spotifyArtists: true,
+ spotifyCover: true,
+ gary: true,
+ lovefemboys: false, // Hidden command - disabled by default
+};
+
+storage.pendingRestart ??= false;
+
+// Hidden settings storage with NSFW bypass option
+storage.hiddenSettings ??= {
+ enabled: false,
+ visible: false,
+ konochanBypassNsfw: false, // New bypass option - disabled by default
+};
+
+// Better Table Row Group Component
+function BetterTableRowGroup({
+ title,
+ icon,
+ children,
+ padding = false,
+}: React.PropsWithChildren<{
+ title?: string;
+ icon?: number;
+ padding?: boolean;
+}>) {
+ const styles = stylesheet.createThemedStyleSheet({
+ main: {
+ backgroundColor: semanticColors.CARD_PRIMARY_BG,
+ borderColor: semanticColors.BORDER_FAINT,
+ borderWidth: 1,
+ borderRadius: 16,
+ overflow: "hidden",
+ flex: 1,
+ },
+ titleContainer: {
+ marginBottom: 8,
+ marginHorizontal: 0,
+ marginTop: 8,
+ gap: 4,
+ flexDirection: "row",
+ alignItems: "center",
+ },
+ icon: {
+ width: 16,
+ height: 16,
+ marginTop: 1.5,
+ tintColor: semanticColors.TEXT_MUTED,
+ },
+ titleText: {
+ fontSize: 14,
+ fontWeight: "600",
+ color: semanticColors.TEXT_MUTED,
+ },
});
-};
-// Common options for both commands
-const nsfwOption = {
- name: "nsfw",
- description: "Include NSFW content?",
- type: 5,
- required: false,
- displayName: "nsfw",
- displayDescription: "Include NSFW content?",
-};
+ return (
+
+ {title && (
+
+ {icon && (
+
+ )}
+
+ {title.toUpperCase()}
+
+
+ )}
+
+ {padding ? (
+
+ {children}
+
+ ) : children}
+
+
+ );
+}
-export const konoSelfCommand = {
- name: "konoself",
- displayName: "konoself",
- description: "Fetch a random image from KonoChan for yourself.",
- displayDescription: "Fetch a random image from KonoChan for yourself.",
- options: [nsfwOption],
- execute: async (args: any, ctx: any) => {
- try {
- const options = new Map(args.map((option: any) => [option.name, option]));
- const isNSFW = options.get("nsfw")?.value || false;
+// Header Component with secret unlock
+function Header({ onHiddenUnlock }: { onHiddenUnlock?: () => void }) {
+ const [clickCounter, setClickCounter] = React.useState(0);
+ const [clickTimeout, setClickTimeout] = React.useState(null);
+
+ const styles = stylesheet.createThemedStyleSheet({
+ container: {
+ flexDirection: "column",
+ alignItems: "center",
+ paddingVertical: 24,
+ paddingHorizontal: 16,
+ },
+ title: {
+ fontSize: 28,
+ fontWeight: "700",
+ color: semanticColors.TEXT_NORMAL,
+ marginBottom: 4,
+ },
+ subtitle: {
+ fontSize: 16,
+ fontWeight: "500",
+ color: semanticColors.TEXT_MUTED,
+ },
+ iconContainer: {
+ backgroundColor: semanticColors.BACKGROUND_SECONDARY,
+ borderRadius: 16,
+ padding: 12,
+ marginBottom: 16,
+ },
+ icon: {
+ width: 32,
+ height: 32,
+ tintColor: semanticColors.TEXT_NORMAL,
+ },
+ });
- // Check if channel is NSFW for NSFW content
- if (isNSFW && !ctx.channel.nsfw) {
- showNSFWWarning();
- return { type: 4 };
- }
-
- const imageUrl = await fetchImage(isNSFW);
-
- if (!imageUrl) {
- // Silent fail - no error message
- return { type: 4 };
- }
-
- messageUtil.sendBotMessage(
- ctx.channel.id,
- `Here's your random image: ${imageUrl}`,
+ const handleIconPress = () => {
+ if (storage.hiddenSettings.enabled) {
+ storage.hiddenSettings.visible = !storage.hiddenSettings.visible;
+ showToast(
+ `Hidden settings ${storage.hiddenSettings.visible ? "visible" : "hidden"}`,
+ getAssetIDByName("SettingsIcon")
);
- return { type: 4 };
- } catch (error) {
- console.error('[KonoSelf] Error:', error);
- // Silent fail - no error message in chat
- return { type: 4 };
+ onHiddenUnlock?.();
+ return;
}
- },
- applicationId: "-1",
- inputType: 1,
- type: 1,
-};
-export const konoSendCommand = {
- name: "konosend",
- displayName: "konosend",
- description: "Fetch a random image from KonoChan and send it to the channel.",
- displayDescription: "Fetch a random image from KonoChan and send it to the channel.",
- options: [nsfwOption],
- execute: async (args: any, ctx: any) => {
- try {
- const options = new Map(args.map((option: any) => [option.name, option]));
- const isNSFW = options.get("nsfw")?.value || false;
-
- // Check if channel is NSFW for NSFW content
- if (isNSFW && !ctx.channel.nsfw) {
- showNSFWWarning();
- return { type: 4 };
- }
-
- const imageUrl = await fetchImage(isNSFW);
-
- if (!imageUrl) {
- // Silent fail - no error message
- return { type: 4 };
- }
-
- const fixNonce = Date.now().toString();
- MessageActions.sendMessage(ctx.channel.id, { content: imageUrl }, void 0, {
- nonce: fixNonce,
- });
- return { type: 4 };
- } catch (error) {
- console.error('[KonoSend] Error:', error);
- // Silent fail - no error message in chat
- return { type: 4 };
+ if (clickTimeout) {
+ clearTimeout(clickTimeout);
}
- },
- applicationId: "-1",
- inputType: 1,
- type: 1,
-};
+
+ const newTimeout = setTimeout(() => {
+ setClickCounter(0);
+ }, 1000);
+ setClickTimeout(newTimeout);
+
+ const newCounter = clickCounter + 1;
+ setClickCounter(newCounter);
+
+ if (newCounter < 10) {
+ return;
+ }
+
+ showToast("🔓 Hidden settings unlocked!", getAssetIDByName("CheckmarkIcon"));
+ storage.hiddenSettings.enabled = true;
+ storage.hiddenSettings.visible = true;
+ setClickCounter(0);
+
+ onHiddenUnlock?.();
+ };
+
+ return (
+
+
+
+
+ Commands
+ A collection of useful commands
+
+ );
+}
+
+// Hidden Commands Settings Page with NSFW bypass option
+function HiddenSettingsPage() {
+ useProxy(storage);
+ const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
+
+ const styles = stylesheet.createThemedStyleSheet({
+ container: {
+ flex: 1,
+ backgroundColor: semanticColors.BACKGROUND_PRIMARY,
+ },
+ warningText: {
+ fontSize: 14,
+ color: semanticColors.TEXT_DANGER,
+ textAlign: "center",
+ lineHeight: 20,
+ fontWeight: "600",
+ },
+ infoText: {
+ fontSize: 14,
+ color: semanticColors.TEXT_MUTED,
+ textAlign: "center",
+ lineHeight: 20,
+ marginTop: 8,
+ },
+ });
+
+ return (
+
+
+
+
+ These are hidden commands that may contain mature content or experimental features.
+
+
+ Use at your own discretion. Commands in this section are disabled by default.
+
+
+
+
+ }
+ value={storage.enabledCommands.lovefemboys}
+ onValueChange={(v) => {
+ storage.enabledCommands.lovefemboys = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+
+
+
+ }
+ value={storage.hiddenSettings.konochanBypassNsfw}
+ onValueChange={(v) => {
+ if (v) {
+ alerts.showConfirmationAlert({
+ title: "⚠️ NSFW Bypass Warning",
+ content: "Enabling this allows NSFW content from KonoChan to be sent in any channel, including non-NSFW channels. This could violate server rules or Discord ToS. Use responsibly!",
+ confirmText: "I Understand",
+ cancelText: "Cancel",
+ onConfirm: () => {
+ storage.hiddenSettings.konochanBypassNsfw = true;
+ forceUpdate();
+ },
+ onCancel: () => {
+ // Do nothing - keep it disabled
+ },
+ });
+ } else {
+ storage.hiddenSettings.konochanBypassNsfw = false;
+ forceUpdate();
+ }
+ }}
+ />
+
+
+
+ }
+ value={storage.hiddenSettings.visible}
+ onValueChange={(v) => {
+ storage.hiddenSettings.visible = v;
+ }}
+ />
+ }
+ onPress={() => {
+ alerts.showConfirmationAlert({
+ title: "Reset Hidden Settings",
+ content: "This will hide the hidden settings section and disable all hidden commands. Are you sure?",
+ confirmText: "Reset",
+ onConfirm: () => {
+ storage.hiddenSettings.enabled = false;
+ storage.hiddenSettings.visible = false;
+ storage.hiddenSettings.konochanBypassNsfw = false; // Reset bypass option
+ storage.enabledCommands.lovefemboys = false;
+ storage.pendingRestart = true;
+ showToast("Hidden settings reset", getAssetIDByName("CheckmarkIcon"));
+ },
+ cancelText: "Cancel",
+ });
+ }}
+ />
+
+
+
+ );
+}
+
+// Facts Commands Settings Page
+function FactsSettingsPage() {
+ useProxy(storage);
+ const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
+
+ return (
+
+
+
+ }
+ value={storage.factSettings.sendAsReply}
+ onValueChange={(v) => {
+ storage.factSettings.sendAsReply = v;
+ }}
+ />
+ }
+ value={storage.factSettings.includeCitation}
+ onValueChange={(v) => {
+ storage.factSettings.includeCitation = v;
+ }}
+ />
+
+
+
+ }
+ value={storage.enabledCommands.catfact}
+ onValueChange={(v) => {
+ storage.enabledCommands.catfact = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+ }
+ value={storage.enabledCommands.dogfact}
+ onValueChange={(v) => {
+ storage.enabledCommands.dogfact = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+ }
+ value={storage.enabledCommands.useless}
+ onValueChange={(v) => {
+ storage.enabledCommands.useless = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+
+
+
+ );
+}
+
+// Gary API Settings Page
+function GaryAPIPage() {
+ useProxy(storage);
+ const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
+
+ const styles = stylesheet.createThemedStyleSheet({
+ container: {
+ flex: 1,
+ backgroundColor: semanticColors.BACKGROUND_PRIMARY,
+ },
+ infoText: {
+ fontSize: 14,
+ color: semanticColors.TEXT_MUTED,
+ marginBottom: 16,
+ textAlign: "center",
+ },
+ currentText: {
+ fontSize: 14,
+ color: semanticColors.TEXT_NORMAL,
+ textAlign: "center",
+ fontWeight: "600",
+ },
+ });
+
+ const currentSource = storage.garySettings.imageSource;
+
+ return (
+
+
+
+ }
+ value={storage.enabledCommands.gary}
+ onValueChange={(v) => {
+ storage.enabledCommands.gary = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+
+
+
+
+ Choose which API the /gary command should use to fetch images.
+
+
+
+
+ }
+ value={currentSource === "gary"}
+ onValueChange={(v) => {
+ if (v) {
+ storage.garySettings.imageSource = "gary";
+ forceUpdate();
+ }
+ }}
+ />
+ }
+ value={currentSource === "catapi"}
+ onValueChange={(v) => {
+ if (v) {
+ storage.garySettings.imageSource = "catapi";
+ forceUpdate();
+ }
+ }}
+ />
+ }
+ value={currentSource === "minker"}
+ onValueChange={(v) => {
+ if (v) {
+ storage.garySettings.imageSource = "minker";
+ forceUpdate();
+ }
+ }}
+ />
+ }
+ value={currentSource === "goober"}
+ onValueChange={(v) => {
+ if (v) {
+ storage.garySettings.imageSource = "goober";
+ forceUpdate();
+ }
+ }}
+ />
+
+
+
+
+ Currently using: {
+ currentSource === "gary" ? "Gary API" :
+ currentSource === "catapi" ? "Cat API" :
+ currentSource === "minker" ? "Minker API" :
+ currentSource === "goober" ? "Goober API" : "Gary API"
+ }
+
+
+
+
+ );
+}
+
+// List Settings Page
+function ListSettingsPage() {
+ useProxy(storage);
+ const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
+
+ return (
+
+
+
+ }
+ value={storage.listSettings.pluginListAlwaysDetailed}
+ onValueChange={(v) => {
+ storage.listSettings.pluginListAlwaysDetailed = v;
+ }}
+ />
+ }
+ value={storage.listSettings.themeListAlwaysDetailed}
+ onValueChange={(v) => {
+ storage.listSettings.themeListAlwaysDetailed = v;
+ }}
+ />
+
+
+
+ }
+ value={storage.enabledCommands.pluginList}
+ onValueChange={(v) => {
+ storage.enabledCommands.pluginList = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+ }
+ value={storage.enabledCommands.themeList}
+ onValueChange={(v) => {
+ storage.enabledCommands.themeList = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+
+
+
+ );
+}
+
+// Image Settings Page
+function ImageSettingsPage() {
+ useProxy(storage);
+ const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
+
+ return (
+
+
+
+ }
+ value={storage.enabledCommands.petpet}
+ onValueChange={(v) => {
+ storage.enabledCommands.petpet = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+
+
+
+ }
+ value={storage.enabledCommands.konoself}
+ onValueChange={(v) => {
+ storage.enabledCommands.konoself = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+ }
+ value={storage.enabledCommands.konosend}
+ onValueChange={(v) => {
+ storage.enabledCommands.konosend = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+
+
+
+ );
+}
+
+// Spotify Settings Page
+function SpotifySettingsPage() {
+ useProxy(storage);
+ const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
+
+ const styles = stylesheet.createThemedStyleSheet({
+ infoText: {
+ fontSize: 14,
+ color: semanticColors.TEXT_MUTED,
+ textAlign: "center",
+ lineHeight: 20,
+ },
+ });
+
+ return (
+
+
+
+ }
+ value={storage.enabledCommands.spotifyTrack}
+ onValueChange={(v) => {
+ storage.enabledCommands.spotifyTrack = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+ }
+ value={storage.enabledCommands.spotifyAlbum}
+ onValueChange={(v) => {
+ storage.enabledCommands.spotifyAlbum = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+ }
+ value={storage.enabledCommands.spotifyArtists}
+ onValueChange={(v) => {
+ storage.enabledCommands.spotifyArtists = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+ }
+ value={storage.enabledCommands.spotifyCover}
+ onValueChange={(v) => {
+ storage.enabledCommands.spotifyCover = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+
+
+
+
+ These commands allow you to share your current Spotify activity in Discord. Make sure you have Spotify connected to Discord for these commands to work properly.
+
+
+
+
+ );
+}
+
+// Other Settings Page
+function OtherSettingsPage() {
+ useProxy(storage);
+ const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
+
+ return (
+
+
+
+ }
+ value={storage.enabledCommands.firstmessage}
+ onValueChange={(v) => {
+ storage.enabledCommands.firstmessage = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+
+
+
+ }
+ value={storage.enabledCommands.sysinfo}
+ onValueChange={(v) => {
+ storage.enabledCommands.sysinfo = v;
+ storage.pendingRestart = true;
+ forceUpdate();
+ }}
+ />
+
+
+
+ );
+}
+
+// Credits Page
+function CreditsPage() {
+ const styles = stylesheet.createThemedStyleSheet({
+ container: {
+ flex: 1,
+ backgroundColor: semanticColors.BACKGROUND_PRIMARY,
+ },
+ creditItem: {
+ flexDirection: "row",
+ alignItems: "center",
+ paddingVertical: 16,
+ paddingHorizontal: 20,
+ backgroundColor: semanticColors.CARD_PRIMARY_BG,
+ borderRadius: 12,
+ marginHorizontal: 16,
+ marginVertical: 6,
+ shadowColor: semanticColors.BLACK,
+ shadowOffset: { width: 0, height: 1 },
+ shadowOpacity: 0.1,
+ shadowRadius: 2,
+ elevation: 2,
+ },
+ avatar: {
+ width: 48,
+ height: 48,
+ borderRadius: 24,
+ marginRight: 16,
+ backgroundColor: semanticColors.BACKGROUND_SECONDARY,
+ },
+ textContainer: {
+ flex: 1,
+ },
+ commandText: {
+ fontSize: 17,
+ fontWeight: "600",
+ color: semanticColors.TEXT_NORMAL,
+ marginBottom: 4,
+ },
+ authorText: {
+ fontSize: 15,
+ color: semanticColors.TEXT_MUTED,
+ marginBottom: 2,
+ },
+ linkText: {
+ fontSize: 13,
+ color: semanticColors.TEXT_BRAND,
+ fontWeight: "500",
+ },
+ infoText: {
+ fontSize: 14,
+ color: semanticColors.TEXT_MUTED,
+ marginBottom: 20,
+ textAlign: "center",
+ lineHeight: 20,
+ },
+ versionText: {
+ fontSize: 15,
+ color: semanticColors.TEXT_NORMAL,
+ textAlign: "center",
+ fontWeight: "600",
+ lineHeight: 22,
+ },
+ });
+
+ const credits = [
+ {
+ command: "Facts Commands",
+ author: "jdev082",
+ avatar: "https://github.com/jdev082.png",
+ github: "https://github.com/jdev082"
+ },
+ {
+ command: "List Commands",
+ author: "Kitomanari",
+ avatar: "https://github.com/Kitosight.png",
+ github: "https://github.com/Kitosight"
+ },
+ {
+ command: "PetPet",
+ author: "wolfieeee",
+ avatar: "https://github.com/WolfPlugs.png",
+ github: "https://github.com/WolfPlugs"
+ },
+ {
+ command: "KonoChan Commands",
+ author: "btmc727 & Rico040",
+ avatar: "https://github.com/OTKUSteyler.png",
+ github: "https://github.com/OTKUSteyler"
+ },
+ {
+ command: "FirstMessage Command",
+ author: "sapphire",
+ avatar: "https://github.com/aeongdesu.png",
+ github: "https://github.com/aeongdesu"
+ },
+ {
+ command: "Sysinfo Command",
+ author: "mugman",
+ avatar: "https://github.com/mugman174.png",
+ github: "https://github.com/mugman174"
+ },
+ {
+ command: "Spotify Commands",
+ author: "Kitomanari",
+ avatar: "https://github.com/Kitosight.png",
+ github: "https://github.com/Kitosight"
+ },
+ {
+ command: "Gary Command",
+ author: "Zach Orange",
+ avatar: "https://github.com/Zach11111.png",
+ github: "https://github.com/Zach11111"
+ },
+ ];
+
+ const handleProfilePress = (githubUrl: string) => {
+ RN.Linking.openURL(githubUrl);
+ };
+
+ return (
+
+
+
+
+ Thanks to this developers for creating such a nice plugins!{'\n'}
+ Tap on any developer to visit their GitHub profile.
+
+
+
+ {credits.map((credit, index) => (
+ handleProfilePress(credit.github)}
+ android_ripple={{ color: semanticColors.ANDROID_RIPPLE, radius: 200 }}
+ >
+
+
+ {credit.command}
+ by {credit.author}
+ {credit.github.replace('https://github.com/', '@')}
+
+
+ ))}
+
+
+
+ Commands Plugin Collection{'\n'}
+ Version 1.0.1
+
+
+
+
+ );
+}
+
+// MAIN SETTINGS COMPONENT
+export default function Settings() {
+ useProxy(storage);
+ const navigation = NavigationNative.useNavigation();
+ const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
+
+ React.useEffect(() => {
+ return () => {
+ if (storage.pendingRestart) {
+ storage.pendingRestart = false;
+ alerts.showConfirmationAlert({
+ title: "Restart Required",
+ content:
+ "You have made changes to commands. Please restart Discord to apply these changes.",
+ confirmText: "Okay",
+ cancelText: null,
+ });
+ }
+ };
+ }, []);
+
+ return (
+
+
+
+
+ }
+ trailing={}
+ onPress={() => navigation.push("VendettaCustomPage", {
+ title: "Facts Commands",
+ render: FactsSettingsPage,
+ })}
+ />
+ }
+ trailing={}
+ onPress={() => navigation.push("VendettaCustomPage", {
+ title: "List Commands",
+ render: ListSettingsPage,
+ })}
+ />
+ }
+ trailing={}
+ onPress={() => navigation.push("VendettaCustomPage", {
+ title: "Image Commands",
+ render: ImageSettingsPage,
+ })}
+ />
+ }
+ trailing={}
+ onPress={() => navigation.push("VendettaCustomPage", {
+ title: "Gary Commands",
+ render: GaryAPIPage,
+ })}
+ />
+ }
+ trailing={}
+ onPress={() => navigation.push("VendettaCustomPage", {
+ title: "Spotify Commands",
+ render: SpotifySettingsPage,
+ })}
+ />
+ }
+ trailing={}
+ onPress={() => navigation.push("VendettaCustomPage", {
+ title: "Other Commands",
+ render: OtherSettingsPage,
+ })}
+ />
+
+
+ {storage.hiddenSettings?.enabled && storage.hiddenSettings?.visible && (
+
+ }
+ trailing={}
+ onPress={() => navigation.push("VendettaCustomPage", {
+ title: "Hidden Settings",
+ render: HiddenSettingsPage,
+ })}
+ />
+
+ )}
+
+
+ }
+ trailing={}
+ onPress={() => navigation.push("VendettaCustomPage", {
+ title: "Credits",
+ render: CreditsPage,
+ })}
+ />
+
+
+
+
+ );
+}