rewrite(Commands): rewrite whole settings page using proper tablerow
instead of BetterTableRow
This commit is contained in:
parent
bba550dbc3
commit
786caf8c86
18 changed files with 800 additions and 1311 deletions
|
|
@ -1,71 +0,0 @@
|
|||
import { React, ReactNative as RN, stylesheet } from "@vendetta/metro/common";
|
||||
import { rawColors, semanticColors } from "@vendetta/ui";
|
||||
|
||||
export default function BetterTableRowGroup({
|
||||
title,
|
||||
icon,
|
||||
children,
|
||||
padding = false,
|
||||
}: React.PropsWithChildren<{
|
||||
title?: string;
|
||||
icon?: number;
|
||||
padding?: boolean;
|
||||
}>) {
|
||||
const styles = stylesheet.createThemedStyleSheet({
|
||||
main: {
|
||||
backgroundColor: rawColors.PLUM_18,
|
||||
borderColor: semanticColors.CARD_BACKGROUND_DEFAULT,
|
||||
borderWidth: 1,
|
||||
borderRadius: 16,
|
||||
overflow: "hidden",
|
||||
flex: 1,
|
||||
maxWidth: "100%",
|
||||
},
|
||||
titleContainer: {
|
||||
marginBottom: 8,
|
||||
marginHorizontal: 16,
|
||||
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,
|
||||
},
|
||||
wrapper: {
|
||||
marginHorizontal: 16,
|
||||
marginTop: 16,
|
||||
maxWidth: "100%",
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<RN.View style={styles.wrapper}>
|
||||
{title && (
|
||||
<RN.View style={styles.titleContainer}>
|
||||
{icon && (
|
||||
<RN.Image style={styles.icon} source={icon} resizeMode="cover" />
|
||||
)}
|
||||
<RN.Text style={styles.titleText}>{title.toUpperCase()}</RN.Text>
|
||||
</RN.View>
|
||||
)}
|
||||
<RN.View style={styles.main}>
|
||||
{padding ? (
|
||||
<RN.View style={{ paddingHorizontal: 16, paddingVertical: 16 }}>
|
||||
{children}
|
||||
</RN.View>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</RN.View>
|
||||
</RN.View>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,10 +1,19 @@
|
|||
import { storage } from "@vendetta/plugin";
|
||||
import { React, ReactNative as RN, stylesheet } from "@vendetta/metro/common";
|
||||
import { React, ReactNative as RN } from "@vendetta/metro/common";
|
||||
import { semanticColors } from "@vendetta/ui";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
import { showToast } from "@vendetta/ui/toasts";
|
||||
import { findByProps } from "@vendetta/metro";
|
||||
import Text from "../../../../nexxstuff/components/Text";
|
||||
import { findByProps, findByStoreName } from "@vendetta/metro";
|
||||
|
||||
const TextStyleSheet = findByProps("TextStyleSheet").TextStyleSheet;
|
||||
const ThemeStore = findByStoreName("ThemeStore");
|
||||
const colorModule = findByProps("colors", "unsafe_rawColors");
|
||||
const colorResolver = colorModule?.internal ?? colorModule?.meta;
|
||||
|
||||
function resolveSemanticColor(color: any, theme?: string) {
|
||||
const t = theme ?? ThemeStore?.theme;
|
||||
return (color && colorResolver?.resolveSemanticColor(t, color)) || "#000000";
|
||||
}
|
||||
|
||||
export default function Header() {
|
||||
const [clickCounter, setClickCounter] = React.useState(0);
|
||||
|
|
@ -21,15 +30,32 @@ export default function Header() {
|
|||
}
|
||||
}, []);
|
||||
|
||||
// Get current user from Discord's user store
|
||||
// Get current user from Discord's user store with error handling
|
||||
let currentUser = null;
|
||||
try {
|
||||
const users = findByProps("getUser", "getCurrentUser");
|
||||
const currentUser = users?.getCurrentUser?.();
|
||||
currentUser = users?.getCurrentUser?.();
|
||||
} catch (e) {
|
||||
console.warn("[Commands Header] Failed to get current user:", e);
|
||||
}
|
||||
|
||||
// Get avatar URL utility
|
||||
const { getUserAvatarURL } = findByProps("getUserAvatarURL") || {};
|
||||
const { getDefaultAvatarURL } = findByProps("getDefaultAvatarURL") || {};
|
||||
// Get avatar URL utilities with error handling
|
||||
let getUserAvatarURL = null;
|
||||
let getDefaultAvatarURL = null;
|
||||
try {
|
||||
const userAvatarModule = findByProps("getUserAvatarURL");
|
||||
getUserAvatarURL = userAvatarModule?.getUserAvatarURL;
|
||||
} catch (e) {
|
||||
console.warn("[Commands Header] Failed to get getUserAvatarURL:", e);
|
||||
}
|
||||
try {
|
||||
const defaultAvatarModule = findByProps("getDefaultAvatarURL");
|
||||
getDefaultAvatarURL = defaultAvatarModule?.getDefaultAvatarURL;
|
||||
} catch (e) {
|
||||
console.warn("[Commands Header] Failed to get getDefaultAvatarURL:", e);
|
||||
}
|
||||
|
||||
const styles = stylesheet.createThemedStyleSheet({
|
||||
const styles = RN.StyleSheet.create({
|
||||
container: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
|
|
@ -56,12 +82,11 @@ export default function Header() {
|
|||
width: 96,
|
||||
height: 96,
|
||||
borderRadius: 24,
|
||||
backgroundColor: semanticColors.BACKGROUND_SECONDARY,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
overflow: "hidden",
|
||||
borderWidth: 2,
|
||||
borderColor: semanticColors.BACKGROUND_TERTIARY,
|
||||
borderColor: semanticColors.MOBILE_CHATINPUT_BORDER_DEFAULT,
|
||||
},
|
||||
avatar: {
|
||||
width: 92,
|
||||
|
|
@ -125,25 +150,30 @@ export default function Header() {
|
|||
|
||||
// Try to get the user's custom avatar first
|
||||
if (getUserAvatarURL && currentUser.avatar) {
|
||||
try {
|
||||
// Use animated parameter for GIF avatars
|
||||
url = getUserAvatarURL(currentUser, hasAnimatedAvatar);
|
||||
animated = hasAnimatedAvatar;
|
||||
} catch (e) {
|
||||
console.warn("[Commands Header] Error getting custom avatar:", e);
|
||||
url = null;
|
||||
}
|
||||
}
|
||||
// Fall back to default avatar
|
||||
else if (getDefaultAvatarURL && typeof getDefaultAvatarURL === "function") {
|
||||
if (!url && getDefaultAvatarURL && typeof getDefaultAvatarURL === "function") {
|
||||
try {
|
||||
url = getDefaultAvatarURL(currentUser);
|
||||
} catch (error) {
|
||||
console.error("Error getting default avatar URL:", error);
|
||||
console.warn("[Commands Header] Error getting default avatar URL:", error);
|
||||
url = null;
|
||||
}
|
||||
}
|
||||
// Last resort: Construct Discord CDN URL
|
||||
else if (currentUser.avatar) {
|
||||
if (!url && currentUser.avatar) {
|
||||
const isGif = currentUser.avatar.startsWith("a_");
|
||||
url = `https://cdn.discordapp.com/avatars/${currentUser.id}/${currentUser.avatar}.${isGif ? "gif" : "png"}?size=256`;
|
||||
animated = isGif;
|
||||
} else {
|
||||
} else if (!url) {
|
||||
// Default Discord avatar based on discriminator or id
|
||||
const defaultAvatarIndex = currentUser.discriminator
|
||||
? parseInt(currentUser.discriminator) % 5
|
||||
|
|
@ -250,12 +280,12 @@ export default function Header() {
|
|||
</RN.Pressable>
|
||||
|
||||
<RN.View style={styles.textContainer}>
|
||||
<Text variant="display-md" color="TEXT_DEFAULT" align="left">
|
||||
<RN.Text style={[TextStyleSheet["display-md"], { color: resolveSemanticColor(semanticColors["TEXT_DEFAULT"]) }]}>
|
||||
Commands
|
||||
</Text>
|
||||
<Text variant="text-md/bold" color="TEXT_MUTED" align="left">
|
||||
</RN.Text>
|
||||
<RN.Text style={[TextStyleSheet["text-md/bold"], { color: resolveSemanticColor(semanticColors["TEXT_MUTED"]) }]}>
|
||||
A collection of useful commands for Vendetta like clients
|
||||
</Text>
|
||||
</RN.Text>
|
||||
</RN.View>
|
||||
</RN.View>
|
||||
</RN.View>
|
||||
|
|
|
|||
21
plugins/Commands/settings/components/TableComponents.tsx
Normal file
21
plugins/Commands/settings/components/TableComponents.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { findByProps } from "@vendetta/metro";
|
||||
|
||||
export const { ScrollView } = findByProps("ScrollView");
|
||||
export const {
|
||||
TableRowGroup,
|
||||
TableSwitchRow,
|
||||
TableCheckboxRow,
|
||||
TableRadioGroup,
|
||||
TableRadioRow,
|
||||
Stack,
|
||||
TableRow,
|
||||
} = findByProps(
|
||||
"TableSwitchRow",
|
||||
"TableCheckboxRow",
|
||||
"TableRadioGroup",
|
||||
"TableRadioRow",
|
||||
"TableRowGroup",
|
||||
"Stack",
|
||||
"TableRow",
|
||||
);
|
||||
export const { TextInput } = findByProps("TextInput");
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
export { default as Header } from "./components/Header";
|
||||
export { default as BetterTableRowGroup } from "./components/BetterTableRowGroup";
|
||||
export { default as FactsSettingsPage } from "./pages/FactsSettingsPage";
|
||||
export { default as ListSettingsPage } from "./pages/ListSettingsPage";
|
||||
export { default as ImageSettingsPage } from "./pages/ImageSettingsPage";
|
||||
export { default as GaryAPIPage } from "./pages/GaryAPIPage";
|
||||
export { default as SpotifySettingsPage } from "./pages/SpotifySettingsPage";
|
||||
export { default as OtherSettingsPage } from "./pages/OtherSettingsPage";
|
||||
export { default as AliucordPage } from "./pages/AliucordPage";
|
||||
export { default as HiddenSettingsPage } from "./pages/HiddenSettingsPage";
|
||||
export { default as CreditsPage } from "./pages/CreditsPage";
|
||||
export { default as NekosLifeCategoriesPage } from "./pages/NekosLifeCategoriesPage";
|
||||
|
|
@ -1,37 +1,28 @@
|
|||
import { storage } from "@vendetta/plugin";
|
||||
import { useProxy } from "@vendetta/storage";
|
||||
import { React, ReactNative as RN, stylesheet } from "@vendetta/metro/common";
|
||||
import { React } 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 BetterTableRowGroup from "../components/BetterTableRowGroup";
|
||||
import {
|
||||
ScrollView,
|
||||
Stack,
|
||||
TableRowGroup,
|
||||
TableRow,
|
||||
TableSwitchRow,
|
||||
} from "../components/TableComponents";
|
||||
import NekosLifeCategoriesPage from "./NekosLifeCategoriesPage";
|
||||
|
||||
const { FormSwitchRow, FormRow } = Forms;
|
||||
|
||||
export default function AliucordPage() {
|
||||
useProxy(storage);
|
||||
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
|
||||
const navigation = NavigationNative.useNavigation();
|
||||
|
||||
return (
|
||||
<RN.ScrollView
|
||||
style={{ flex: 1, backgroundColor: semanticColors.BACKGROUND_PRIMARY }}
|
||||
contentContainerStyle={{
|
||||
flexGrow: 1,
|
||||
paddingVertical: 16,
|
||||
maxWidth: "100%",
|
||||
}}
|
||||
>
|
||||
<BetterTableRowGroup
|
||||
title="IP Commands"
|
||||
icon={getAssetIDByName("GlobeEarthIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 10 }}>
|
||||
<Stack spacing={12}>
|
||||
<TableRowGroup title="IP Commands">
|
||||
<TableSwitchRow
|
||||
label="/ip"
|
||||
subLabel="Get your current IP address"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("GlobeEarthIcon")} />}
|
||||
value={storage.enabledCommands.ip}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.ip = v;
|
||||
|
|
@ -39,16 +30,12 @@ export default function AliucordPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="NekosLife Commands"
|
||||
icon={getAssetIDByName("ImageIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<TableRowGroup title="NekosLife Commands">
|
||||
<TableSwitchRow
|
||||
label="/nekoslife"
|
||||
subLabel="Get images/gifs from nekos.life"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ImageIcon")} />}
|
||||
value={storage.enabledCommands.nekoslife}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.nekoslife = v;
|
||||
|
|
@ -56,11 +43,10 @@ export default function AliucordPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
<FormRow
|
||||
<TableRow
|
||||
label="View Categories"
|
||||
subLabel="See all 16 available categories"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("BookOpenIcon")} />}
|
||||
trailing={<FormRow.Arrow />}
|
||||
trailing={<TableRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "NekosLife Categories",
|
||||
|
|
@ -68,9 +54,8 @@ export default function AliucordPage() {
|
|||
})
|
||||
}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
|
||||
<RN.View style={{ height: 32 }} />
|
||||
</RN.ScrollView>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
import { React, ReactNative as RN, stylesheet } from "@vendetta/metro/common";
|
||||
import { rawColors, semanticColors } from "@vendetta/ui";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
import BetterTableRowGroup from "../components/BetterTableRowGroup";
|
||||
import { ReactNative as RN } from "@vendetta/metro/common";
|
||||
import {
|
||||
ScrollView,
|
||||
Stack,
|
||||
TableRowGroup,
|
||||
TableRow,
|
||||
} from "../components/TableComponents";
|
||||
|
||||
type Credit = {
|
||||
command: string;
|
||||
|
|
@ -10,99 +13,6 @@ type Credit = {
|
|||
github: string;
|
||||
};
|
||||
|
||||
export default function CreditsPage() {
|
||||
const styles = stylesheet.createThemedStyleSheet({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: semanticColors.BACKGROUND_PRIMARY,
|
||||
},
|
||||
|
||||
scrollContent: {
|
||||
paddingVertical: 16,
|
||||
paddingHorizontal: 12,
|
||||
alignItems: "stretch",
|
||||
},
|
||||
|
||||
groupWrapper: {
|
||||
marginHorizontal: 16,
|
||||
marginTop: 16,
|
||||
maxWidth: "100%",
|
||||
},
|
||||
groupMain: {
|
||||
backgroundColor: rawColors.PLUM_18,
|
||||
borderColor: semanticColors.CARD_BACKGROUND_DEFAULT,
|
||||
borderWidth: 1,
|
||||
borderRadius: 16,
|
||||
overflow: "hidden",
|
||||
flex: 1,
|
||||
maxWidth: "100%",
|
||||
},
|
||||
rippleContainer: {
|
||||
borderRadius: 16,
|
||||
overflow: "hidden",
|
||||
},
|
||||
|
||||
cardPressable: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 12,
|
||||
},
|
||||
|
||||
avatarContainer: {
|
||||
width: 56,
|
||||
height: 56,
|
||||
borderRadius: 12,
|
||||
overflow: "hidden",
|
||||
backgroundColor: semanticColors.BACKGROUND_SECONDARY,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginRight: 12,
|
||||
},
|
||||
avatar: {
|
||||
width: 56,
|
||||
height: 56,
|
||||
borderRadius: 12,
|
||||
resizeMode: "cover",
|
||||
},
|
||||
|
||||
textContainer: {
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
},
|
||||
commandText: {
|
||||
fontSize: 16,
|
||||
fontWeight: "700",
|
||||
color: semanticColors.MOBILE_TEXT_HEADING_PRIMARY,
|
||||
marginBottom: 2,
|
||||
},
|
||||
authorText: {
|
||||
fontSize: 14,
|
||||
color: semanticColors.TEXT_MUTED,
|
||||
marginBottom: 6,
|
||||
},
|
||||
linkText: {
|
||||
fontSize: 13,
|
||||
color: semanticColors.LINK,
|
||||
fontWeight: "600",
|
||||
},
|
||||
|
||||
infoText: {
|
||||
fontSize: 14,
|
||||
color: semanticColors.TEXT_MUTED,
|
||||
marginBottom: 20,
|
||||
textAlign: "center",
|
||||
lineHeight: 20,
|
||||
},
|
||||
versionText: {
|
||||
fontSize: 15,
|
||||
color: semanticColors.TEXT_MUTED,
|
||||
textAlign: "center",
|
||||
fontWeight: "600",
|
||||
lineHeight: 22,
|
||||
},
|
||||
});
|
||||
|
||||
const credits: Credit[] = [
|
||||
{
|
||||
command: "Facts Commands",
|
||||
|
|
@ -166,75 +76,40 @@ export default function CreditsPage() {
|
|||
},
|
||||
];
|
||||
|
||||
const handleProfilePress = (githubUrl: string) => {
|
||||
RN.Linking.openURL(githubUrl);
|
||||
};
|
||||
|
||||
// Resolve asset IDs (some assets may be numeric IDs or URIs depending on bundling)
|
||||
const heartIconRaw = getAssetIDByName("HeartIcon");
|
||||
const infoIconRaw = getAssetIDByName("ic_information_24px");
|
||||
const heartIcon =
|
||||
typeof heartIconRaw === "number" ? (heartIconRaw as number) : undefined;
|
||||
const infoIcon =
|
||||
typeof infoIconRaw === "number" ? (infoIconRaw as number) : undefined;
|
||||
|
||||
export default function CreditsPage() {
|
||||
return (
|
||||
<RN.ScrollView
|
||||
style={styles.container}
|
||||
contentContainerStyle={styles.scrollContent}
|
||||
>
|
||||
<BetterTableRowGroup
|
||||
title="Plugin Authors"
|
||||
icon={heartIcon}
|
||||
padding={true}
|
||||
>
|
||||
<RN.Text style={styles.infoText}>
|
||||
Thanks to these developers for creating such great plugins!
|
||||
{"\n"}Tap any developer to visit their GitHub profile.
|
||||
</RN.Text>
|
||||
</BetterTableRowGroup>
|
||||
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 10 }}>
|
||||
<Stack spacing={12}>
|
||||
<TableRowGroup title="Plugin Authors">
|
||||
{credits.map((credit) => (
|
||||
<RN.View key={credit.github} style={styles.groupWrapper}>
|
||||
<RN.View style={styles.groupMain}>
|
||||
<RN.View style={styles.rippleContainer}>
|
||||
<RN.Pressable
|
||||
style={styles.cardPressable}
|
||||
onPress={() => handleProfilePress(credit.github)}
|
||||
android_ripple={{
|
||||
color: semanticColors.ANDROID_RIPPLE,
|
||||
borderless: false,
|
||||
radius: 200,
|
||||
}}
|
||||
accessibilityRole="button"
|
||||
>
|
||||
<RN.View style={styles.avatarContainer}>
|
||||
<TableRow
|
||||
key={credit.github}
|
||||
label={credit.command}
|
||||
subLabel={`by ${credit.author}`}
|
||||
icon={
|
||||
<RN.Image
|
||||
source={{ uri: credit.avatar }}
|
||||
style={styles.avatar}
|
||||
style={{
|
||||
width: 48,
|
||||
height: 48,
|
||||
borderRadius: 8,
|
||||
}}
|
||||
resizeMode="cover"
|
||||
/>
|
||||
}
|
||||
trailing={<TableRow.Arrow />}
|
||||
onPress={() => RN.Linking.openURL(credit.github)}
|
||||
/>
|
||||
</RN.View>
|
||||
|
||||
<RN.View style={styles.textContainer}>
|
||||
<RN.Text numberOfLines={1} style={styles.commandText}>
|
||||
{credit.command}
|
||||
</RN.Text>
|
||||
<RN.Text numberOfLines={1} style={styles.authorText}>
|
||||
by {credit.author}
|
||||
</RN.Text>
|
||||
</RN.View>
|
||||
</RN.Pressable>
|
||||
</RN.View>
|
||||
</RN.View>
|
||||
</RN.View>
|
||||
))}
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup title="About" icon={infoIcon} padding={true}>
|
||||
<RN.Text style={styles.versionText}>
|
||||
Commands Plugin Collection{"\n"}
|
||||
Version 1.3.0
|
||||
</RN.Text>
|
||||
</BetterTableRowGroup>
|
||||
</RN.ScrollView>
|
||||
<TableRowGroup title="About">
|
||||
<TableRow
|
||||
label="Commands Plugin Collection"
|
||||
subLabel="Version 1.3.0"
|
||||
/>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,60 +1,43 @@
|
|||
import { storage } from "@vendetta/plugin";
|
||||
import { useProxy } from "@vendetta/storage";
|
||||
import { React, ReactNative as RN } from "@vendetta/metro/common";
|
||||
import { semanticColors } from "@vendetta/ui";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
import { Forms } from "@vendetta/ui/components";
|
||||
import BetterTableRowGroup from "../components/BetterTableRowGroup";
|
||||
|
||||
const { FormSwitchRow, FormRow } = Forms;
|
||||
import { React } from "@vendetta/metro/common";
|
||||
import {
|
||||
ScrollView,
|
||||
Stack,
|
||||
TableRowGroup,
|
||||
TableSwitchRow,
|
||||
} from "../components/TableComponents";
|
||||
|
||||
export default function FactsSettingsPage() {
|
||||
useProxy(storage);
|
||||
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
|
||||
|
||||
return (
|
||||
<RN.ScrollView
|
||||
style={{ flex: 1, backgroundColor: semanticColors.BACKGROUND_PRIMARY }}
|
||||
contentContainerStyle={{
|
||||
flexGrow: 1,
|
||||
paddingVertical: 16,
|
||||
maxWidth: "100%",
|
||||
}}
|
||||
>
|
||||
<BetterTableRowGroup
|
||||
title="Fact Display Settings"
|
||||
icon={getAssetIDByName("SettingsIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 10 }}>
|
||||
<Stack spacing={12}>
|
||||
<TableRowGroup title="Fact Display Settings">
|
||||
<TableSwitchRow
|
||||
label="Send as Reply"
|
||||
subLabel="Send facts as a reply to the command message"
|
||||
leading={
|
||||
<FormRow.Icon source={getAssetIDByName("ArrowAngleLeftUpIcon")} />
|
||||
}
|
||||
value={storage.factSettings.sendAsReply}
|
||||
onValueChange={(v) => {
|
||||
storage.factSettings.sendAsReply = v;
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableSwitchRow
|
||||
label="Include Source Citation"
|
||||
subLabel="Include the source of facts when available"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("LinkIcon")} />}
|
||||
value={storage.factSettings.includeCitation}
|
||||
onValueChange={(v) => {
|
||||
storage.factSettings.includeCitation = v;
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="Available Fact Commands"
|
||||
icon={getAssetIDByName("BookmarkIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<TableRowGroup title="Available Fact Commands">
|
||||
<TableSwitchRow
|
||||
label="/catfact"
|
||||
subLabel="Get random cat facts"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("BookCheckIcon")} />}
|
||||
value={storage.enabledCommands.catfact}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.catfact = v;
|
||||
|
|
@ -62,10 +45,9 @@ export default function FactsSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableSwitchRow
|
||||
label="/dogfact"
|
||||
subLabel="Get random dog facts"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("BookCheckIcon")} />}
|
||||
value={storage.enabledCommands.dogfact}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.dogfact = v;
|
||||
|
|
@ -73,10 +55,9 @@ export default function FactsSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableSwitchRow
|
||||
label="/useless"
|
||||
subLabel="Get random useless facts"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("BookCheckIcon")} />}
|
||||
value={storage.enabledCommands.useless}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.useless = v;
|
||||
|
|
@ -84,7 +65,8 @@ export default function FactsSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</RN.ScrollView>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,55 +1,26 @@
|
|||
import { storage } from "@vendetta/plugin";
|
||||
import { useProxy } from "@vendetta/storage";
|
||||
import { React, ReactNative as RN, stylesheet } from "@vendetta/metro/common";
|
||||
import { semanticColors } from "@vendetta/ui";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
import { Forms } from "@vendetta/ui/components";
|
||||
import BetterTableRowGroup from "../components/BetterTableRowGroup";
|
||||
|
||||
const { FormSwitchRow, FormRow } = Forms;
|
||||
import { React } from "@vendetta/metro/common";
|
||||
import {
|
||||
ScrollView,
|
||||
Stack,
|
||||
TableRowGroup,
|
||||
TableSwitchRow,
|
||||
TableRadioGroup,
|
||||
TableRadioRow,
|
||||
} from "../components/TableComponents";
|
||||
|
||||
export default 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_MUTED,
|
||||
textAlign: "center",
|
||||
fontWeight: "600",
|
||||
},
|
||||
});
|
||||
|
||||
const currentSource = storage.garySettings.imageSource;
|
||||
|
||||
return (
|
||||
<RN.ScrollView
|
||||
style={styles.container}
|
||||
contentContainerStyle={{
|
||||
flexGrow: 1,
|
||||
paddingVertical: 16,
|
||||
maxWidth: "100%",
|
||||
}}
|
||||
>
|
||||
<BetterTableRowGroup
|
||||
title="Gary Command Settings"
|
||||
icon={getAssetIDByName("SettingsIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 10 }}>
|
||||
<Stack spacing={12}>
|
||||
<TableRowGroup title="Gary Command Settings">
|
||||
<TableSwitchRow
|
||||
label="/gary"
|
||||
subLabel="Send random Gary images to channel"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("AttachmentIcon")} />}
|
||||
value={storage.enabledCommands.gary}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.gary = v;
|
||||
|
|
@ -57,90 +28,39 @@ export default function GaryAPIPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="Image Source Selection"
|
||||
icon={getAssetIDByName("DownloadIcon")}
|
||||
padding={true}
|
||||
<TableRowGroup title="Image Source Selection">
|
||||
<TableRadioGroup
|
||||
value={storage.garySettings.imageSource}
|
||||
onChange={(v) => {
|
||||
storage.garySettings.imageSource = v;
|
||||
forceUpdate();
|
||||
}}
|
||||
>
|
||||
<RN.Text style={styles.infoText}>
|
||||
Choose which API the /gary command should use to fetch images.
|
||||
</RN.Text>
|
||||
</BetterTableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="API Options"
|
||||
icon={getAssetIDByName("CloudIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<TableRadioRow
|
||||
value="gary"
|
||||
label="Gary API"
|
||||
subLabel="Original Gary the cat images from api.garythe.cat"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ImageIcon")} />}
|
||||
value={currentSource === "gary"}
|
||||
onValueChange={(v) => {
|
||||
if (v) {
|
||||
storage.garySettings.imageSource = "gary";
|
||||
forceUpdate();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableRadioRow
|
||||
value="catapi"
|
||||
label="Cat API"
|
||||
subLabel="Random cat pictures from thecatapi.com"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ImageIcon")} />}
|
||||
value={currentSource === "catapi"}
|
||||
onValueChange={(v) => {
|
||||
if (v) {
|
||||
storage.garySettings.imageSource = "catapi";
|
||||
forceUpdate();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableRadioRow
|
||||
value="minker"
|
||||
label="Minker API"
|
||||
subLabel="Minky images from minky.materii.dev"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ImageIcon")} />}
|
||||
value={currentSource === "minker"}
|
||||
onValueChange={(v) => {
|
||||
if (v) {
|
||||
storage.garySettings.imageSource = "minker";
|
||||
forceUpdate();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableRadioRow
|
||||
value="goober"
|
||||
label="Goober API"
|
||||
subLabel="Goober images from api.garythe.cat/goober"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ImageIcon")} />}
|
||||
value={currentSource === "goober"}
|
||||
onValueChange={(v) => {
|
||||
if (v) {
|
||||
storage.garySettings.imageSource = "goober";
|
||||
forceUpdate();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="Current Selection"
|
||||
icon={getAssetIDByName("CheckmarkIcon")}
|
||||
padding={true}
|
||||
>
|
||||
<RN.Text style={styles.currentText}>
|
||||
Currently using:{" "}
|
||||
{currentSource === "gary"
|
||||
? "Gary API"
|
||||
: currentSource === "catapi"
|
||||
? "Cat API"
|
||||
: currentSource === "minker"
|
||||
? "Minker API"
|
||||
: currentSource === "goober"
|
||||
? "Goober API"
|
||||
: "Gary API"}
|
||||
</RN.Text>
|
||||
</BetterTableRowGroup>
|
||||
</RN.ScrollView>
|
||||
</TableRadioGroup>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,72 +1,35 @@
|
|||
import { storage } from "@vendetta/plugin";
|
||||
import { useProxy } from "@vendetta/storage";
|
||||
import { React, ReactNative as RN, stylesheet } from "@vendetta/metro/common";
|
||||
import { semanticColors } from "@vendetta/ui";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
import { Forms } from "@vendetta/ui/components";
|
||||
import { React } from "@vendetta/metro/common";
|
||||
import { alerts } from "@vendetta/ui";
|
||||
import { showToast } from "@vendetta/ui/toasts";
|
||||
import BetterTableRowGroup from "../components/BetterTableRowGroup";
|
||||
|
||||
const { FormSwitchRow, FormRow } = Forms;
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
import {
|
||||
ScrollView,
|
||||
Stack,
|
||||
TableRowGroup,
|
||||
TableRow,
|
||||
TableSwitchRow,
|
||||
} from "../components/TableComponents";
|
||||
|
||||
export default 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_MUTED,
|
||||
textAlign: "center",
|
||||
lineHeight: 20,
|
||||
fontWeight: "600",
|
||||
},
|
||||
infoText: {
|
||||
fontSize: 14,
|
||||
color: semanticColors.TEXT_MUTED,
|
||||
textAlign: "center",
|
||||
lineHeight: 20,
|
||||
marginTop: 8,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<RN.ScrollView
|
||||
style={styles.container}
|
||||
contentContainerStyle={{
|
||||
flexGrow: 1,
|
||||
paddingVertical: 16,
|
||||
maxWidth: "100%",
|
||||
}}
|
||||
>
|
||||
<BetterTableRowGroup
|
||||
title="Warning"
|
||||
icon={getAssetIDByName("WarningIcon")}
|
||||
padding={true}
|
||||
>
|
||||
<RN.Text style={styles.warningText}>
|
||||
These are hidden commands that may contain mature content or
|
||||
experimental features.
|
||||
</RN.Text>
|
||||
<RN.Text style={styles.infoText}>
|
||||
Use at your own discretion. Commands in this section are disabled by
|
||||
default.
|
||||
</RN.Text>
|
||||
</BetterTableRowGroup>
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 10 }}>
|
||||
<Stack spacing={12}>
|
||||
<TableRowGroup title="Warning">
|
||||
<TableRow
|
||||
label="Hidden Commands Warning"
|
||||
subLabel="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."
|
||||
/>
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="Hidden Commands"
|
||||
icon={getAssetIDByName("EyeIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<TableRowGroup title="Hidden Commands">
|
||||
<TableSwitchRow
|
||||
label="/lovefemboys"
|
||||
subLabel="Get random femboy images from r/femboys (NSFW content available)"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("HeartIcon")} />}
|
||||
value={storage.enabledCommands.lovefemboys}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.lovefemboys = v;
|
||||
|
|
@ -74,21 +37,17 @@ export default function HiddenSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="NSFW Bypass Options"
|
||||
icon={getAssetIDByName("WarningIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<TableRowGroup title="NSFW Bypass Options">
|
||||
<TableSwitchRow
|
||||
label="KonoChan NSFW Bypass"
|
||||
subLabel="Allow NSFW KonoChan content in non-NSFW channels (USE WITH CAUTION)"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ShieldIcon")} />}
|
||||
value={storage.hiddenSettings.konochanBypassNsfw}
|
||||
onValueChange={(v) => {
|
||||
if (v) {
|
||||
alerts.showConfirmationAlert({
|
||||
title: "⚠️ NSFW Bypass Warning",
|
||||
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",
|
||||
|
|
@ -105,25 +64,20 @@ export default function HiddenSettingsPage() {
|
|||
}
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="Hidden Settings Control"
|
||||
icon={getAssetIDByName("SettingsIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<TableRowGroup title="Hidden Settings Control">
|
||||
<TableSwitchRow
|
||||
label="Keep Hidden Settings Visible"
|
||||
subLabel="Keep this section visible even when navigating away"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("EyeIcon")} />}
|
||||
value={storage.hiddenSettings.visible}
|
||||
onValueChange={(v) => {
|
||||
storage.hiddenSettings.visible = v;
|
||||
}}
|
||||
/>
|
||||
<FormRow
|
||||
<TableRow
|
||||
label="Reset Hidden Settings"
|
||||
subLabel="Hide this section and disable all hidden commands"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("TrashIcon")} />}
|
||||
onPress={() => {
|
||||
alerts.showConfirmationAlert({
|
||||
title: "Reset Hidden Settings",
|
||||
|
|
@ -146,7 +100,8 @@ export default function HiddenSettingsPage() {
|
|||
});
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</RN.ScrollView>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +1,24 @@
|
|||
import { storage } from "@vendetta/plugin";
|
||||
import { useProxy } from "@vendetta/storage";
|
||||
import { React, ReactNative as RN } from "@vendetta/metro/common";
|
||||
import { semanticColors } from "@vendetta/ui";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
import { Forms } from "@vendetta/ui/components";
|
||||
import BetterTableRowGroup from "../components/BetterTableRowGroup";
|
||||
|
||||
const { FormSwitchRow, FormRow } = Forms;
|
||||
import { React } from "@vendetta/metro/common";
|
||||
import {
|
||||
ScrollView,
|
||||
Stack,
|
||||
TableRowGroup,
|
||||
TableSwitchRow,
|
||||
} from "../components/TableComponents";
|
||||
|
||||
export default function ImageSettingsPage() {
|
||||
useProxy(storage);
|
||||
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
|
||||
|
||||
return (
|
||||
<RN.ScrollView
|
||||
style={{ flex: 1, backgroundColor: semanticColors.BACKGROUND_PRIMARY }}
|
||||
contentContainerStyle={{
|
||||
flexGrow: 1,
|
||||
paddingVertical: 16,
|
||||
maxWidth: "100%",
|
||||
}}
|
||||
>
|
||||
<BetterTableRowGroup
|
||||
title="Image Commands"
|
||||
icon={getAssetIDByName("ImageIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 10 }}>
|
||||
<Stack spacing={12}>
|
||||
<TableRowGroup title="Image Commands">
|
||||
<TableSwitchRow
|
||||
label="/petpet"
|
||||
subLabel="Create pet-pet GIF of a user"
|
||||
leading={
|
||||
<FormRow.Icon source={getAssetIDByName("HandRequestSpeakIcon")} />
|
||||
}
|
||||
value={storage.enabledCommands.petpet}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.petpet = v;
|
||||
|
|
@ -38,16 +26,12 @@ export default function ImageSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="KonoChan Commands"
|
||||
icon={getAssetIDByName("ImageIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<TableRowGroup title="KonoChan Commands">
|
||||
<TableSwitchRow
|
||||
label="/konoself"
|
||||
subLabel="Get random image from KonoChan (private)"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("EyeIcon")} />}
|
||||
value={storage.enabledCommands.konoself}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.konoself = v;
|
||||
|
|
@ -55,10 +39,9 @@ export default function ImageSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableSwitchRow
|
||||
label="/konosend"
|
||||
subLabel="Send random image from KonoChan to channel"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ImageIcon")} />}
|
||||
value={storage.enabledCommands.konosend}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.konosend = v;
|
||||
|
|
@ -66,7 +49,8 @@ export default function ImageSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</RN.ScrollView>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,64 +1,43 @@
|
|||
import { storage } from "@vendetta/plugin";
|
||||
import { useProxy } from "@vendetta/storage";
|
||||
import { React, ReactNative as RN, stylesheet } from "@vendetta/metro/common";
|
||||
import { semanticColors } from "@vendetta/ui";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
import { Forms } from "@vendetta/ui/components";
|
||||
import BetterTableRowGroup from "../components/BetterTableRowGroup";
|
||||
|
||||
const { FormSwitchRow, FormRow } = Forms;
|
||||
import { React } from "@vendetta/metro/common";
|
||||
import {
|
||||
ScrollView,
|
||||
Stack,
|
||||
TableRowGroup,
|
||||
TableSwitchRow,
|
||||
} from "../components/TableComponents";
|
||||
|
||||
export default function ListSettingsPage() {
|
||||
useProxy(storage);
|
||||
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
|
||||
|
||||
return (
|
||||
<RN.ScrollView
|
||||
style={{ flex: 1, backgroundColor: semanticColors.BACKGROUND_PRIMARY }}
|
||||
contentContainerStyle={{
|
||||
flexGrow: 1,
|
||||
paddingVertical: 16,
|
||||
maxWidth: "100%",
|
||||
}}
|
||||
>
|
||||
<BetterTableRowGroup
|
||||
title="List Display Settings"
|
||||
icon={getAssetIDByName("SettingsIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 10 }}>
|
||||
<Stack spacing={12}>
|
||||
<TableRowGroup title="List Display Settings">
|
||||
<TableSwitchRow
|
||||
label="Always Send Detailed Plugin List"
|
||||
subLabel="Always use detailed mode when listing plugins"
|
||||
leading={
|
||||
<FormRow.Icon source={getAssetIDByName("PuzzlePieceIcon")} />
|
||||
}
|
||||
value={storage.listSettings.pluginListAlwaysDetailed}
|
||||
onValueChange={(v) => {
|
||||
storage.listSettings.pluginListAlwaysDetailed = v;
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableSwitchRow
|
||||
label="Always Send Detailed Theme List"
|
||||
subLabel="Always use detailed mode when listing themes"
|
||||
leading={
|
||||
<FormRow.Icon source={getAssetIDByName("PaintPaletteIcon")} />
|
||||
}
|
||||
value={storage.listSettings.themeListAlwaysDetailed}
|
||||
onValueChange={(v) => {
|
||||
storage.listSettings.themeListAlwaysDetailed = v;
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="Available List Commands"
|
||||
icon={getAssetIDByName("ListViewIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<TableRowGroup title="Available List Commands">
|
||||
<TableSwitchRow
|
||||
label="/plugin-list"
|
||||
subLabel="List all installed plugins"
|
||||
leading={
|
||||
<FormRow.Icon source={getAssetIDByName("PuzzlePieceIcon")} />
|
||||
}
|
||||
value={storage.enabledCommands.pluginList}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.pluginList = v;
|
||||
|
|
@ -66,12 +45,9 @@ export default function ListSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableSwitchRow
|
||||
label="/theme-list"
|
||||
subLabel="List all installed themes"
|
||||
leading={
|
||||
<FormRow.Icon source={getAssetIDByName("PaintPaletteIcon")} />
|
||||
}
|
||||
value={storage.enabledCommands.themeList}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.themeList = v;
|
||||
|
|
@ -79,7 +55,8 @@ export default function ListSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</RN.ScrollView>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,19 @@
|
|||
import { React, ReactNative as RN, stylesheet } from "@vendetta/metro/common";
|
||||
import { React, ReactNative as RN } from "@vendetta/metro/common";
|
||||
import { semanticColors } from "@vendetta/ui";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
import BetterTableRowGroup from "../components/BetterTableRowGroup";
|
||||
import {
|
||||
ScrollView,
|
||||
Stack,
|
||||
TableRowGroup,
|
||||
TableRow,
|
||||
} from "../components/TableComponents";
|
||||
|
||||
export default function NekosLifeCategoriesPage() {
|
||||
const styles = stylesheet.createThemedStyleSheet({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: semanticColors.BACKGROUND_PRIMARY,
|
||||
},
|
||||
const styles = RN.StyleSheet.create({
|
||||
tableHeader: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 16,
|
||||
backgroundColor: semanticColors.BACKGROUND_MODIFIER_ACCENT,
|
||||
borderBottomWidth: 2,
|
||||
borderBottomColor: semanticColors.BORDER_STRONG,
|
||||
},
|
||||
headerText: {
|
||||
fontSize: 14,
|
||||
|
|
@ -40,8 +37,6 @@ export default function NekosLifeCategoriesPage() {
|
|||
alignItems: "center",
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 16,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: semanticColors.BORDER_FAINT,
|
||||
},
|
||||
categoryName: {
|
||||
fontSize: 16,
|
||||
|
|
@ -71,15 +66,8 @@ export default function NekosLifeCategoriesPage() {
|
|||
fontWeight: "600",
|
||||
color: semanticColors.TEXT_NORMAL,
|
||||
},
|
||||
infoText: {
|
||||
fontSize: 14,
|
||||
color: semanticColors.TEXT_MUTED,
|
||||
textAlign: "center",
|
||||
lineHeight: 20,
|
||||
},
|
||||
});
|
||||
|
||||
// nekos.life categories
|
||||
const sfwCategories = [
|
||||
{ name: "Avatar", value: "avatar" },
|
||||
{ name: "Classic", value: "classic" },
|
||||
|
|
@ -99,38 +87,21 @@ export default function NekosLifeCategoriesPage() {
|
|||
{ name: "Woof", value: "woof" },
|
||||
];
|
||||
|
||||
// Sort categories alphabetically
|
||||
const sortedCategories = sfwCategories.sort((a, b) =>
|
||||
a.name.localeCompare(b.name),
|
||||
);
|
||||
|
||||
return (
|
||||
<RN.ScrollView
|
||||
style={styles.container}
|
||||
contentContainerStyle={{
|
||||
flexGrow: 1,
|
||||
paddingVertical: 16,
|
||||
maxWidth: "100%",
|
||||
}}
|
||||
>
|
||||
<BetterTableRowGroup
|
||||
title="📊 Category Statistics"
|
||||
icon={getAssetIDByName("ChartIcon")}
|
||||
padding={true}
|
||||
>
|
||||
<RN.Text style={styles.infoText}>
|
||||
Total SFW Categories: {sfwCategories.length}
|
||||
{"\n\n"}
|
||||
Use these category names with the /nekoslife command.{"\n"}
|
||||
All categories are Safe For Work (SFW).
|
||||
</RN.Text>
|
||||
</BetterTableRowGroup>
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 10 }}>
|
||||
<Stack spacing={12}>
|
||||
<TableRowGroup title="Category Statistics">
|
||||
<TableRow
|
||||
label={`${sfwCategories.length} SFW Categories`}
|
||||
subLabel="Use these category names with the /nekoslife command. All categories are Safe For Work (SFW)."
|
||||
/>
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="📋 SFW Categories"
|
||||
icon={getAssetIDByName("ListViewIcon")}
|
||||
>
|
||||
{/* Table Header */}
|
||||
<TableRowGroup title="SFW Categories">
|
||||
<RN.View style={styles.tableHeader}>
|
||||
<RN.Text style={[styles.headerText, styles.nameHeader]}>
|
||||
Category Name
|
||||
|
|
@ -143,7 +114,6 @@ export default function NekosLifeCategoriesPage() {
|
|||
</RN.Text>
|
||||
</RN.View>
|
||||
|
||||
{/* Table Rows */}
|
||||
{sortedCategories.map((category, index) => (
|
||||
<RN.View key={index} style={styles.categoryItem}>
|
||||
<RN.Text style={styles.categoryName}>{category.name}</RN.Text>
|
||||
|
|
@ -155,7 +125,8 @@ export default function NekosLifeCategoriesPage() {
|
|||
</RN.View>
|
||||
</RN.View>
|
||||
))}
|
||||
</BetterTableRowGroup>
|
||||
</RN.ScrollView>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +1,24 @@
|
|||
import { storage } from "@vendetta/plugin";
|
||||
import { useProxy } from "@vendetta/storage";
|
||||
import { React, ReactNative as RN, stylesheet } from "@vendetta/metro/common";
|
||||
import { semanticColors } from "@vendetta/ui";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
import { Forms } from "@vendetta/ui/components";
|
||||
import BetterTableRowGroup from "../components/BetterTableRowGroup";
|
||||
|
||||
const { FormSwitchRow, FormRow } = Forms;
|
||||
import { React } from "@vendetta/metro/common";
|
||||
import {
|
||||
ScrollView,
|
||||
Stack,
|
||||
TableRowGroup,
|
||||
TableSwitchRow,
|
||||
} from "../components/TableComponents";
|
||||
|
||||
export default function OtherSettingsPage() {
|
||||
useProxy(storage);
|
||||
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
|
||||
|
||||
return (
|
||||
<RN.ScrollView
|
||||
style={{ flex: 1, backgroundColor: semanticColors.BACKGROUND_PRIMARY }}
|
||||
contentContainerStyle={{
|
||||
flexGrow: 1,
|
||||
paddingVertical: 16,
|
||||
maxWidth: "100%",
|
||||
}}
|
||||
>
|
||||
<BetterTableRowGroup
|
||||
title="Message Commands"
|
||||
icon={getAssetIDByName("ChatIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 10 }}>
|
||||
<Stack spacing={12}>
|
||||
<TableRowGroup title="Message Commands">
|
||||
<TableSwitchRow
|
||||
label="/firstmessage"
|
||||
subLabel="Get the first message in a channel"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ChatIcon")} />}
|
||||
value={storage.enabledCommands.firstmessage}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.firstmessage = v;
|
||||
|
|
@ -36,16 +26,12 @@ export default function OtherSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="System Commands"
|
||||
icon={getAssetIDByName("SettingsIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<TableRowGroup title="System Commands">
|
||||
<TableSwitchRow
|
||||
label="/sysinfo"
|
||||
subLabel="Display system information"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("SettingsIcon")} />}
|
||||
value={storage.enabledCommands.sysinfo}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.sysinfo = v;
|
||||
|
|
@ -53,13 +39,10 @@ export default function OtherSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="Friend Invites"
|
||||
icon={getAssetIDByName("UserAddIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<TableRowGroup title="Friend Invites">
|
||||
<TableSwitchRow
|
||||
label="/invite create"
|
||||
subLabel="Generate a friend invite link"
|
||||
value={storage.enabledCommands.friendInviteCreate}
|
||||
|
|
@ -69,7 +52,7 @@ export default function OtherSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableSwitchRow
|
||||
label="/view invites"
|
||||
subLabel="View your current friend invites"
|
||||
value={storage.enabledCommands.friendInviteView}
|
||||
|
|
@ -79,7 +62,7 @@ export default function OtherSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableSwitchRow
|
||||
label="/revoke invites"
|
||||
subLabel="Revoke all your friend invites"
|
||||
value={storage.enabledCommands.friendInviteRevoke}
|
||||
|
|
@ -89,7 +72,8 @@ export default function OtherSettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</RN.ScrollView>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,45 +1,25 @@
|
|||
import { storage } from "@vendetta/plugin";
|
||||
import { useProxy } from "@vendetta/storage";
|
||||
import { React, ReactNative as RN, stylesheet } from "@vendetta/metro/common";
|
||||
import { semanticColors } from "@vendetta/ui";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
import { Forms } from "@vendetta/ui/components";
|
||||
import BetterTableRowGroup from "../components/BetterTableRowGroup";
|
||||
|
||||
const { FormSwitchRow, FormRow } = Forms;
|
||||
import { React } from "@vendetta/metro/common";
|
||||
import {
|
||||
ScrollView,
|
||||
Stack,
|
||||
TableRowGroup,
|
||||
TableRow,
|
||||
TableSwitchRow,
|
||||
} from "../components/TableComponents";
|
||||
|
||||
export default 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 (
|
||||
<RN.ScrollView
|
||||
style={{ flex: 1, backgroundColor: semanticColors.BACKGROUND_PRIMARY }}
|
||||
contentContainerStyle={{
|
||||
flexGrow: 1,
|
||||
paddingVertical: 16,
|
||||
maxWidth: "100%",
|
||||
}}
|
||||
>
|
||||
<BetterTableRowGroup
|
||||
title="Spotify Commands"
|
||||
icon={getAssetIDByName("SpotifyNeutralIcon")}
|
||||
>
|
||||
<FormSwitchRow
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 10 }}>
|
||||
<Stack spacing={12}>
|
||||
<TableRowGroup title="Spotify Commands">
|
||||
<TableSwitchRow
|
||||
label="/spotify track"
|
||||
subLabel="Share your current Spotify track"
|
||||
leading={
|
||||
<FormRow.Icon source={getAssetIDByName("SpotifyNeutralIcon")} />
|
||||
}
|
||||
value={storage.enabledCommands.spotifyTrack}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.spotifyTrack = v;
|
||||
|
|
@ -47,12 +27,9 @@ export default function SpotifySettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableSwitchRow
|
||||
label="/spotify album"
|
||||
subLabel="Share your current track's album"
|
||||
leading={
|
||||
<FormRow.Icon source={getAssetIDByName("SpotifyNeutralIcon")} />
|
||||
}
|
||||
value={storage.enabledCommands.spotifyAlbum}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.spotifyAlbum = v;
|
||||
|
|
@ -60,12 +37,9 @@ export default function SpotifySettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableSwitchRow
|
||||
label="/spotify artists"
|
||||
subLabel="Share your current track's artists"
|
||||
leading={
|
||||
<FormRow.Icon source={getAssetIDByName("SpotifyNeutralIcon")} />
|
||||
}
|
||||
value={storage.enabledCommands.spotifyArtists}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.spotifyArtists = v;
|
||||
|
|
@ -73,12 +47,9 @@ export default function SpotifySettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
<FormSwitchRow
|
||||
<TableSwitchRow
|
||||
label="/spotify cover"
|
||||
subLabel="Share your current track's cover"
|
||||
leading={
|
||||
<FormRow.Icon source={getAssetIDByName("SpotifyNeutralIcon")} />
|
||||
}
|
||||
value={storage.enabledCommands.spotifyCover}
|
||||
onValueChange={(v) => {
|
||||
storage.enabledCommands.spotifyCover = v;
|
||||
|
|
@ -86,19 +57,15 @@ export default function SpotifySettingsPage() {
|
|||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</TableRowGroup>
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="About Spotify Commands"
|
||||
icon={getAssetIDByName("InfoIcon")}
|
||||
padding={true}
|
||||
>
|
||||
<RN.Text style={styles.infoText}>
|
||||
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.
|
||||
</RN.Text>
|
||||
</BetterTableRowGroup>
|
||||
</RN.ScrollView>
|
||||
<TableRowGroup title="About Spotify Commands">
|
||||
<TableRow
|
||||
label="Spotify Integration"
|
||||
subLabel="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."
|
||||
/>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
import { storage } from "@vendetta/plugin";
|
||||
import { useProxy } from "@vendetta/storage";
|
||||
import { React, ReactNative, stylesheet } from "@vendetta/metro/common";
|
||||
import { React } 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";
|
||||
import {
|
||||
ScrollView,
|
||||
Stack,
|
||||
TableRowGroup,
|
||||
TableRow,
|
||||
} from "./components/TableComponents";
|
||||
import Header from "./components/Header";
|
||||
import BetterTableRowGroup from "./components/BetterTableRowGroup";
|
||||
|
||||
// Import all pages directly
|
||||
import FactsSettingsPage from "./pages/FactsSettingsPage";
|
||||
import ListSettingsPage from "./pages/ListSettingsPage";
|
||||
import ImageSettingsPage from "./pages/ImageSettingsPage";
|
||||
|
|
@ -21,24 +21,28 @@ import OtherSettingsPage from "./pages/OtherSettingsPage";
|
|||
import HiddenSettingsPage from "./pages/HiddenSettingsPage";
|
||||
import CreditsPage from "./pages/CreditsPage";
|
||||
|
||||
const { FormRow } = Forms;
|
||||
|
||||
// Initialize storage with default values
|
||||
storage.factSettings ??= {
|
||||
if (storage.factSettings == null) {
|
||||
storage.factSettings = {
|
||||
sendAsReply: true,
|
||||
includeCitation: false,
|
||||
};
|
||||
}
|
||||
|
||||
storage.listSettings ??= {
|
||||
if (storage.listSettings == null) {
|
||||
storage.listSettings = {
|
||||
pluginListAlwaysDetailed: false,
|
||||
themeListAlwaysDetailed: false,
|
||||
};
|
||||
}
|
||||
|
||||
storage.garySettings ??= {
|
||||
if (storage.garySettings == null) {
|
||||
storage.garySettings = {
|
||||
imageSource: "gary",
|
||||
};
|
||||
}
|
||||
|
||||
storage.enabledCommands ??= {
|
||||
if (storage.enabledCommands == null) {
|
||||
storage.enabledCommands = {
|
||||
catfact: true,
|
||||
dogfact: true,
|
||||
useless: true,
|
||||
|
|
@ -61,20 +65,24 @@ storage.enabledCommands ??= {
|
|||
friendInviteView: true,
|
||||
friendInviteRevoke: true,
|
||||
};
|
||||
}
|
||||
|
||||
storage.pendingRestart ??= false;
|
||||
if (storage.pendingRestart == null) {
|
||||
storage.pendingRestart = false;
|
||||
}
|
||||
|
||||
// Hidden settings storage with NSFW bypass option
|
||||
storage.hiddenSettings ??= {
|
||||
if (storage.hiddenSettings == null) {
|
||||
storage.hiddenSettings = {
|
||||
enabled: false,
|
||||
visible: false,
|
||||
konochanBypassNsfw: false,
|
||||
};
|
||||
}
|
||||
|
||||
// Sidebar setting (enabled by default)
|
||||
storage.sidebarEnabled ??= true;
|
||||
if (storage.sidebarEnabled == null) {
|
||||
storage.sidebarEnabled = true;
|
||||
}
|
||||
|
||||
// MAIN SETTINGS COMPONENT
|
||||
export default function Settings() {
|
||||
useProxy(storage);
|
||||
const navigation = NavigationNative.useNavigation();
|
||||
|
|
@ -95,64 +103,7 @@ export default function Settings() {
|
|||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ReactNative.View style={{ flex: 1 }}>
|
||||
<ReactNative.ScrollView
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: semanticColors.BACKGROUND_PRIMARY,
|
||||
}}
|
||||
contentContainerStyle={{
|
||||
flexGrow: 1,
|
||||
maxWidth: "100%",
|
||||
}}
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
<Header />
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="Command Categories"
|
||||
icon={getAssetIDByName("ChannelListIcon")}
|
||||
>
|
||||
<FormRow
|
||||
label="Facts Commands"
|
||||
subLabel="Cat facts, dog facts, and useless facts"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("BookmarkIcon")} />}
|
||||
trailing={<FormRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "Facts Commands",
|
||||
render: FactsSettingsPage,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<FormRow
|
||||
label="List Commands"
|
||||
subLabel="Plugin lists and theme lists"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ListViewIcon")} />}
|
||||
trailing={<FormRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "List Commands",
|
||||
render: ListSettingsPage,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<FormRow
|
||||
label="Image Commands"
|
||||
subLabel="PetPet, KonoChan, and image utilities"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ImageIcon")} />}
|
||||
trailing={<FormRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "Image Commands",
|
||||
render: ImageSettingsPage,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<FormRow
|
||||
label="Gary Commands"
|
||||
subLabel={`Gary images - Current: ${
|
||||
const garySourceLabel =
|
||||
storage.garySettings.imageSource === "gary"
|
||||
? "Gary API"
|
||||
: storage.garySettings.imageSource === "catapi"
|
||||
|
|
@ -161,10 +112,50 @@ export default function Settings() {
|
|||
? "Minker API"
|
||||
: storage.garySettings.imageSource === "goober"
|
||||
? "Goober API"
|
||||
: "Gary API"
|
||||
}`}
|
||||
leading={<FormRow.Icon source={getAssetIDByName("CameraIcon")} />}
|
||||
trailing={<FormRow.Arrow />}
|
||||
: "Gary API";
|
||||
|
||||
return (
|
||||
<ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 10 }}>
|
||||
<Header />
|
||||
<Stack spacing={12}>
|
||||
<TableRowGroup title="Command Categories">
|
||||
<TableRow
|
||||
label="Facts Commands"
|
||||
subLabel="Cat facts, dog facts, and useless facts"
|
||||
trailing={<TableRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "Facts Commands",
|
||||
render: FactsSettingsPage,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<TableRow
|
||||
label="List Commands"
|
||||
subLabel="Plugin lists and theme lists"
|
||||
trailing={<TableRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "List Commands",
|
||||
render: ListSettingsPage,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<TableRow
|
||||
label="Image Commands"
|
||||
subLabel="PetPet, KonoChan, and image utilities"
|
||||
trailing={<TableRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "Image Commands",
|
||||
render: ImageSettingsPage,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<TableRow
|
||||
label="Gary Commands"
|
||||
subLabel={`Gary images - Current: ${garySourceLabel}`}
|
||||
trailing={<TableRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "Gary Commands",
|
||||
|
|
@ -172,13 +163,10 @@ export default function Settings() {
|
|||
})
|
||||
}
|
||||
/>
|
||||
<FormRow
|
||||
<TableRow
|
||||
label="Spotify Commands"
|
||||
subLabel="Share your Spotify activity"
|
||||
leading={
|
||||
<FormRow.Icon source={getAssetIDByName("SpotifyNeutralIcon")} />
|
||||
}
|
||||
trailing={<FormRow.Arrow />}
|
||||
trailing={<TableRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "Spotify Commands",
|
||||
|
|
@ -186,17 +174,10 @@ export default function Settings() {
|
|||
})
|
||||
}
|
||||
/>
|
||||
<FormRow
|
||||
<TableRow
|
||||
label="Aliucord Commands"
|
||||
subLabel="Commands from Aliucord"
|
||||
leading={
|
||||
<FormRow.Icon
|
||||
source={{
|
||||
uri: "https://avatars.githubusercontent.com/u/78881422?s=200&v=4",
|
||||
}}
|
||||
/>
|
||||
}
|
||||
trailing={<FormRow.Arrow />}
|
||||
trailing={<TableRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "Aliucord",
|
||||
|
|
@ -204,11 +185,10 @@ export default function Settings() {
|
|||
})
|
||||
}
|
||||
/>
|
||||
<FormRow
|
||||
<TableRow
|
||||
label="Other Commands"
|
||||
subLabel="Utility and system commands"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("WrenchIcon")} />}
|
||||
trailing={<FormRow.Arrow />}
|
||||
trailing={<TableRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "Other Commands",
|
||||
|
|
@ -216,18 +196,14 @@ export default function Settings() {
|
|||
})
|
||||
}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</TableRowGroup>
|
||||
|
||||
{storage.hiddenSettings?.visible && (
|
||||
<BetterTableRowGroup
|
||||
title="Hidden Settings"
|
||||
icon={getAssetIDByName("EyeIcon")}
|
||||
>
|
||||
<FormRow
|
||||
<TableRowGroup title="Hidden Settings">
|
||||
<TableRow
|
||||
label="Hidden Commands"
|
||||
subLabel="Access to experimental and NSFW commands"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("EyeIcon")} />}
|
||||
trailing={<FormRow.Arrow />}
|
||||
trailing={<TableRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "Hidden Settings",
|
||||
|
|
@ -235,18 +211,14 @@ export default function Settings() {
|
|||
})
|
||||
}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
</TableRowGroup>
|
||||
)}
|
||||
|
||||
<BetterTableRowGroup
|
||||
title="Other"
|
||||
icon={getAssetIDByName("CircleInformationIcon-primary")}
|
||||
>
|
||||
<FormRow
|
||||
<TableRowGroup title="Other">
|
||||
<TableRow
|
||||
label="Credits"
|
||||
subLabel="View original authors of the plugins"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("HeartIcon")} />}
|
||||
trailing={<FormRow.Arrow />}
|
||||
trailing={<TableRow.Arrow />}
|
||||
onPress={() =>
|
||||
navigation.push("VendettaCustomPage", {
|
||||
title: "Credits",
|
||||
|
|
@ -254,11 +226,8 @@ export default function Settings() {
|
|||
})
|
||||
}
|
||||
/>
|
||||
</BetterTableRowGroup>
|
||||
|
||||
{/* Add sufficient bottom padding for scrolling */}
|
||||
<ReactNative.View style={{ height: 32 }} />
|
||||
</ReactNative.ScrollView>
|
||||
</ReactNative.View>
|
||||
</TableRowGroup>
|
||||
</Stack>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
export interface FactSettings {
|
||||
sendAsReply: boolean;
|
||||
includeCitation: boolean;
|
||||
}
|
||||
|
||||
export interface ListSettings {
|
||||
pluginListAlwaysDetailed: boolean;
|
||||
themeListAlwaysDetailed: boolean;
|
||||
}
|
||||
|
||||
export interface GarySettings {
|
||||
imageSource: "gary" | "catapi" | "minker" | "goober";
|
||||
}
|
||||
|
||||
export interface EnabledCommands {
|
||||
catfact: boolean;
|
||||
dogfact: boolean;
|
||||
useless: boolean;
|
||||
petpet: boolean;
|
||||
pluginList: boolean;
|
||||
themeList: boolean;
|
||||
konoself: boolean;
|
||||
konosend: boolean;
|
||||
firstmessage: boolean;
|
||||
sysinfo: boolean;
|
||||
spotifyTrack: boolean;
|
||||
spotifyAlbum: boolean;
|
||||
spotifyArtists: boolean;
|
||||
spotifyCover: boolean;
|
||||
gary: boolean;
|
||||
ip: boolean;
|
||||
lovefemboys: boolean;
|
||||
nekoslife: boolean;
|
||||
friendInviteCreate: boolean;
|
||||
friendInviteView: boolean;
|
||||
friendInviteRevoke: boolean;
|
||||
}
|
||||
|
||||
export interface HiddenSettings {
|
||||
enabled: boolean;
|
||||
visible: boolean;
|
||||
konochanBypassNsfw: boolean;
|
||||
}
|
||||
|
||||
export interface StorageType {
|
||||
factSettings: FactSettings;
|
||||
listSettings: ListSettings;
|
||||
garySettings: GarySettings;
|
||||
enabledCommands: EnabledCommands;
|
||||
pendingRestart: boolean;
|
||||
hiddenSettings: HiddenSettings;
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@ function patchPanelUI(tabs, patches) {
|
|||
),
|
||||
);
|
||||
} catch (error) {
|
||||
logger.info("Panel UI patch failed graciously 💔", error);
|
||||
// we don't need to care about this error
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,11 @@
|
|||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"jsx": "react-native",
|
||||
"allowJs": true
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@nlib/*": ["nexxstuff/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"plugins",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue