meh meh
This commit is contained in:
parent
c752332e47
commit
a8fd46e5eb
2 changed files with 76 additions and 174 deletions
|
|
@ -209,7 +209,7 @@ function Header({ onHiddenUnlock }: { onHiddenUnlock?: () => void }) {
|
|||
);
|
||||
}
|
||||
|
||||
// NekosLife Categories Reference Page
|
||||
// NekosLife Categories Reference Page - SFW ONLY
|
||||
function NekosLifeCategoriesPage() {
|
||||
const styles = stylesheet.createThemedStyleSheet({
|
||||
container: {
|
||||
|
|
@ -236,12 +236,6 @@ function NekosLifeCategoriesPage() {
|
|||
fontFamily: "monospace",
|
||||
marginRight: 8,
|
||||
},
|
||||
nsfwBadge: {
|
||||
backgroundColor: semanticColors.STATUS_DANGER,
|
||||
paddingHorizontal: 8,
|
||||
paddingVertical: 4,
|
||||
borderRadius: 12,
|
||||
},
|
||||
sfwBadge: {
|
||||
backgroundColor: semanticColors.STATUS_POSITIVE,
|
||||
paddingHorizontal: 8,
|
||||
|
|
@ -261,88 +255,41 @@ function NekosLifeCategoriesPage() {
|
|||
},
|
||||
});
|
||||
|
||||
// All nekos.life categories with their API values and NSFW status
|
||||
const allCategories = [
|
||||
{ name: "Anal", value: "anal", nsfw: true },
|
||||
{ name: "Avatar", value: "avatar", nsfw: false },
|
||||
{ name: "Boobs", value: "boobs", nsfw: true },
|
||||
{ name: "Blowjob Image", value: "blowjob", nsfw: true },
|
||||
{ name: "Blowjob GIF", value: "bj", nsfw: true },
|
||||
{ name: "Classic", value: "classic", nsfw: false },
|
||||
{ name: "Cuddle", value: "cuddle", nsfw: false },
|
||||
{ name: "Cum", value: "cum", nsfw: true },
|
||||
{ name: "Cum JPG", value: "cum_jpg", nsfw: true },
|
||||
{ name: "Ero", value: "ero", nsfw: true },
|
||||
{ name: "Ero Feet", value: "erofeet", nsfw: true },
|
||||
{ name: "Ero Kemo", value: "erokemo", nsfw: true },
|
||||
{ name: "Ero Kitsune", value: "erok", nsfw: true },
|
||||
{ name: "Ero Neko", value: "eron", nsfw: true },
|
||||
{ name: "Ero Yuri", value: "eroyuri", nsfw: true },
|
||||
{ name: "Femdom", value: "femdom", nsfw: true },
|
||||
{ name: "Feet", value: "feet", nsfw: true },
|
||||
{ name: "Feet GIF", value: "feetg", nsfw: true },
|
||||
{ name: "Fox Girl", value: "fox_girl", nsfw: false },
|
||||
{ name: "Futanari", value: "futanari", nsfw: true },
|
||||
{ name: "Gasm", value: "gasm", nsfw: true },
|
||||
{ name: "Gecg", value: "gecg", nsfw: false },
|
||||
{ name: "Kemonomimi", value: "kemonomimi", nsfw: false },
|
||||
{ name: "Kiss", value: "kiss", nsfw: false },
|
||||
{ name: "Kuni", value: "kuni", nsfw: true },
|
||||
{ name: "Hentai", value: "hentai", nsfw: true },
|
||||
{ name: "Holo", value: "holo", nsfw: false },
|
||||
{ name: "Holo Ero", value: "holoero", nsfw: true },
|
||||
{ name: "Holo Lewd", value: "hololewd", nsfw: true },
|
||||
{ name: "Lesbian", value: "les", nsfw: true },
|
||||
{ name: "Lewd", value: "lewd", nsfw: true },
|
||||
{ name: "Lewd Kemo", value: "lewdkemo", nsfw: true },
|
||||
{ name: "Lewd Kitsune", value: "lewdk", nsfw: true },
|
||||
{ name: "Neko", value: "neko", nsfw: false },
|
||||
{ name: "Neko GIF", value: "ngif", nsfw: false },
|
||||
{ name: "NSFW Neko GIF", value: "nsfw_neko_gif", nsfw: true },
|
||||
{ name: "NSFW Avatar", value: "nsfw_avatar", nsfw: true },
|
||||
{ name: "Pussy", value: "pussy", nsfw: true },
|
||||
{ name: "Pussy JPG", value: "pussy_jpg", nsfw: true },
|
||||
{ name: "Pwank", value: "pwankg", nsfw: true },
|
||||
{ name: "Random Hentai GIF", value: "Random_hentai_gif", nsfw: true },
|
||||
{ name: "Small Boobs", value: "smallboobs", nsfw: true },
|
||||
{ name: "Smug", value: "smug", nsfw: false },
|
||||
{ name: "Solo", value: "solo", nsfw: true },
|
||||
{ name: "Solo GIF", value: "solog", nsfw: true },
|
||||
{ name: "Spank", value: "spank", nsfw: false },
|
||||
{ name: "Tits", value: "tits", nsfw: true },
|
||||
{ name: "Tickle", value: "tickle", nsfw: false },
|
||||
{ name: "Trap", value: "trap", nsfw: true },
|
||||
{ name: "Waifu", value: "waifu", nsfw: false },
|
||||
{ name: "Wallpaper", value: "wallpaper", nsfw: false },
|
||||
{ name: "Woof", value: "woof", nsfw: false },
|
||||
{ name: "Yuri", value: "yuri", nsfw: true }
|
||||
// Only SFW nekos.life categories
|
||||
const sfwCategories = [
|
||||
{ name: "Avatar", value: "avatar" },
|
||||
{ name: "Classic", value: "classic" },
|
||||
{ name: "Cuddle", value: "cuddle" },
|
||||
{ name: "Fox Girl", value: "fox_girl" },
|
||||
{ name: "Gecg", value: "gecg" },
|
||||
{ name: "Holo", value: "holo" },
|
||||
{ name: "Kemonomimi", value: "kemonomimi" },
|
||||
{ name: "Kiss", value: "kiss" },
|
||||
{ name: "Neko", value: "neko" },
|
||||
{ name: "Neko GIF", value: "ngif" },
|
||||
{ name: "Smug", value: "smug" },
|
||||
{ name: "Spank", value: "spank" },
|
||||
{ name: "Tickle", value: "tickle" },
|
||||
{ name: "Waifu", value: "waifu" },
|
||||
{ name: "Wallpaper", value: "wallpaper" },
|
||||
{ name: "Woof", value: "woof" }
|
||||
];
|
||||
|
||||
// Sort categories: SFW first, then NSFW, then alphabetically within each group
|
||||
const sortedCategories = allCategories.sort((a, b) => {
|
||||
if (a.nsfw !== b.nsfw) {
|
||||
return a.nsfw ? 1 : -1; // SFW first
|
||||
}
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
|
||||
const sfwCount = allCategories.filter(cat => !cat.nsfw).length;
|
||||
const nsfwCount = allCategories.filter(cat => cat.nsfw).length;
|
||||
// Sort categories alphabetically
|
||||
const sortedCategories = sfwCategories.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
return (
|
||||
<ScrollView style={styles.container}>
|
||||
<RN.View style={{ paddingVertical: 16 }}>
|
||||
<BetterTableRowGroup title="📊 Category Statistics" icon={getAssetIDByName("ChartIcon")} padding={true}>
|
||||
<RN.Text style={styles.infoText}>
|
||||
Total Categories: {allCategories.length}{'\n'}
|
||||
SFW Categories: {sfwCount}{'\n'}
|
||||
NSFW Categories: {nsfwCount}{'\n\n'}
|
||||
Use these category names with the /nekoslife command.
|
||||
Green = SFW, Red = NSFW
|
||||
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>
|
||||
|
||||
<BetterTableRowGroup title="📋 All Categories" icon={getAssetIDByName("ListViewIcon")}>
|
||||
<BetterTableRowGroup title="📋 SFW Categories" icon={getAssetIDByName("ListViewIcon")}>
|
||||
{sortedCategories.map((category, index) => (
|
||||
<RN.View key={index} style={styles.categoryItem}>
|
||||
<RN.Text style={styles.categoryName}>
|
||||
|
|
@ -351,9 +298,9 @@ function NekosLifeCategoriesPage() {
|
|||
<RN.Text style={styles.categoryValue}>
|
||||
{category.value}
|
||||
</RN.Text>
|
||||
<RN.View style={category.nsfw ? styles.nsfwBadge : styles.sfwBadge}>
|
||||
<RN.View style={styles.sfwBadge}>
|
||||
<RN.Text style={styles.badgeText}>
|
||||
{category.nsfw ? "NSFW" : "SFW"}
|
||||
SFW
|
||||
</RN.Text>
|
||||
</RN.View>
|
||||
</RN.View>
|
||||
|
|
@ -364,7 +311,7 @@ function NekosLifeCategoriesPage() {
|
|||
);
|
||||
}
|
||||
|
||||
// Hidden Commands Settings Page with NSFW bypass option and NekosLife
|
||||
// Hidden Commands Settings Page
|
||||
function HiddenSettingsPage() {
|
||||
useProxy(storage);
|
||||
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
|
||||
|
|
@ -417,7 +364,7 @@ function HiddenSettingsPage() {
|
|||
/>
|
||||
<FormSwitchRow
|
||||
label="/nekoslife"
|
||||
subLabel="Get images/gifs from nekos.life (NSFW content available)"
|
||||
subLabel="Get SFW images/gifs from nekos.life"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ImageIcon")} />}
|
||||
value={storage.enabledCommands.nekoslife}
|
||||
onValueChange={(v) => {
|
||||
|
|
@ -430,8 +377,8 @@ function HiddenSettingsPage() {
|
|||
|
||||
<BetterTableRowGroup title="NekosLife Reference" icon={getAssetIDByName("BookOpenIcon")}>
|
||||
<FormRow
|
||||
label="View All Categories"
|
||||
subLabel="See all 52 available nekos.life categories with SFW/NSFW status"
|
||||
label="View SFW Categories"
|
||||
subLabel="See all 16 available safe-for-work nekos.life categories"
|
||||
leading={<FormRow.Icon source={getAssetIDByName("ListViewIcon")} />}
|
||||
trailing={<FormRow.Arrow />}
|
||||
onPress={() => navigation.push("VendettaCustomPage", {
|
||||
|
|
@ -508,8 +455,6 @@ function HiddenSettingsPage() {
|
|||
);
|
||||
}
|
||||
|
||||
// ... [Keep all other existing functions: FactsSettingsPage, GaryAPIPage, ListSettingsPage, ImageSettingsPage, SpotifySettingsPage, OtherSettingsPage unchanged] ...
|
||||
|
||||
// Facts Commands Settings Page
|
||||
function FactsSettingsPage() {
|
||||
useProxy(storage);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { findByProps } from "@vendetta/metro";
|
||||
import { alerts } from "@vendetta/ui";
|
||||
import { showToast } from "@vendetta/ui/toasts";
|
||||
import { getAssetIDByName } from "@vendetta/ui/assets";
|
||||
|
||||
|
|
@ -10,18 +9,31 @@ interface NekosLifeResult {
|
|||
url: string;
|
||||
}
|
||||
|
||||
// Available categories as a simple array for validation
|
||||
const validCategories = [
|
||||
// SFW categories
|
||||
"neko", "waifu", "avatar", "cuddle", "kiss", "smug", "tickle", "wallpaper",
|
||||
"kemonomimi", "fox_girl", "classic", "gecg", "woof", "holo", "ngif", "spank",
|
||||
|
||||
// NSFW categories
|
||||
"nsfw_neko_gif", "lewd", "ero", "yuri", "trap", "futanari", "hentai",
|
||||
"boobs", "anal", "blowjob", "bj", "cum", "cum_jpg", "pussy", "pussy_jpg",
|
||||
"tits", "femdom", "feet", "feetg", "gasm", "kuni", "holoero", "hololewd",
|
||||
"les", "lewdkemo", "lewdk", "eron", "eroyuri", "erofeet", "erokemo", "erok",
|
||||
"nsfw_avatar", "pwankg", "Random_hentai_gif", "smallboobs", "solo", "solog"
|
||||
// Only SFW categories (exactly 16 - within Discord's 25 choice limit)
|
||||
const categoryChoices = [
|
||||
{ name: "Avatar", value: "avatar" },
|
||||
{ name: "Classic", value: "classic" },
|
||||
{ name: "Cuddle", value: "cuddle" },
|
||||
{ name: "Fox Girl", value: "fox_girl" },
|
||||
{ name: "Gecg", value: "gecg" },
|
||||
{ name: "Holo", value: "holo" },
|
||||
{ name: "Kemonomimi", value: "kemonomimi" },
|
||||
{ name: "Kiss", value: "kiss" },
|
||||
{ name: "Neko", value: "neko" },
|
||||
{ name: "Neko GIF", value: "ngif" },
|
||||
{ name: "Smug", value: "smug" },
|
||||
{ name: "Spank", value: "spank" },
|
||||
{ name: "Tickle", value: "tickle" },
|
||||
{ name: "Waifu", value: "waifu" },
|
||||
{ name: "Wallpaper", value: "wallpaper" },
|
||||
{ name: "Woof", value: "woof" }
|
||||
];
|
||||
|
||||
const limitChoices = [
|
||||
{ name: "1", value: 1 },
|
||||
{ name: "2", value: 2 },
|
||||
{ name: "3", value: 3 },
|
||||
{ name: "5", value: 5 }
|
||||
];
|
||||
|
||||
async function fetchNekosLifeImages(category: string, count: number): Promise<string[]> {
|
||||
|
|
@ -52,52 +64,35 @@ async function fetchNekosLifeImages(category: string, count: number): Promise<st
|
|||
return urls;
|
||||
}
|
||||
|
||||
function isNsfwCategory(category: string): boolean {
|
||||
if (!category || typeof category !== 'string') return false;
|
||||
|
||||
const nsfwCategories = [
|
||||
"nsfw_neko_gif", "lewd", "ero", "yuri", "trap", "futanari", "hentai",
|
||||
"boobs", "anal", "cum", "pussy", "tits", "blowjob", "bj", "femdom",
|
||||
"feet", "feetg", "gasm", "kuni", "holoero", "hololewd", "les",
|
||||
"lewdkemo", "lewdk", "eron", "eroyuri", "erofeet", "erokemo", "erok",
|
||||
"nsfw_avatar", "pussy_jpg", "pwankg", "Random_hentai_gif", "smallboobs",
|
||||
"solo", "solog", "cum_jpg"
|
||||
];
|
||||
return nsfwCategories.includes(category.toLowerCase());
|
||||
}
|
||||
|
||||
function isValidCategory(category: string): boolean {
|
||||
if (!category || typeof category !== 'string') return false;
|
||||
return validCategories.includes(category.toLowerCase());
|
||||
}
|
||||
|
||||
export const nekoslifeCommand = {
|
||||
name: "nekoslife",
|
||||
displayName: "nekoslife",
|
||||
description: "Get images/gifs from nekos.life",
|
||||
displayDescription: "Get images/gifs from nekos.life",
|
||||
description: "Get SFW images/gifs from nekos.life",
|
||||
displayDescription: "Get SFW images/gifs from nekos.life",
|
||||
options: [
|
||||
{
|
||||
name: "category",
|
||||
displayName: "category",
|
||||
description: "Category: neko, waifu, hentai, lewd, etc. (type the name)",
|
||||
displayDescription: "Category: neko, waifu, hentai, lewd, etc. (type the name)",
|
||||
type: 3, // String - no choices, just free text input
|
||||
description: "Category of SFW image/gif to get",
|
||||
displayDescription: "Category of SFW image/gif to get",
|
||||
type: 3, // String
|
||||
required: true,
|
||||
choices: categoryChoices
|
||||
},
|
||||
{
|
||||
name: "limit",
|
||||
displayName: "limit",
|
||||
description: "Number of images (1-5, default: 1)",
|
||||
displayDescription: "Number of images (1-5, default: 1)",
|
||||
type: 4, // Integer
|
||||
description: "Number of images to get (default: 1)",
|
||||
displayDescription: "Number of images to get (default: 1)",
|
||||
type: 4, // Integer
|
||||
required: false,
|
||||
choices: limitChoices
|
||||
},
|
||||
{
|
||||
name: "send",
|
||||
displayName: "send",
|
||||
description: "Send to chat (WARNING: Use NSFW channel for NSFW content)",
|
||||
displayDescription: "Send to chat (WARNING: Use NSFW channel for NSFW content)",
|
||||
description: "Send to chat",
|
||||
displayDescription: "Send to chat",
|
||||
type: 5, // Boolean
|
||||
required: false,
|
||||
},
|
||||
|
|
@ -114,16 +109,16 @@ export const nekoslifeCommand = {
|
|||
try {
|
||||
console.log('[NekosLife] Command executed with args:', args);
|
||||
|
||||
// Parse arguments like other commands
|
||||
// Parse arguments
|
||||
const category = args.find((arg: any) => arg.name === "category")?.value;
|
||||
const limitValue = args.find((arg: any) => arg.name === "limit")?.value;
|
||||
const limit = args.find((arg: any) => arg.name === "limit")?.value || 1;
|
||||
const shouldSend = args.find((arg: any) => arg.name === "send")?.value || false;
|
||||
const isEphemeral = args.find((arg: any) => arg.name === "ephemeral")?.value || false;
|
||||
|
||||
console.log('[NekosLife] Parsed values:', { category, limitValue, shouldSend, isEphemeral });
|
||||
console.log('[NekosLife] Parsed values:', { category, limit, shouldSend, isEphemeral });
|
||||
|
||||
if (!category || typeof category !== 'string') {
|
||||
const errorMsg = "❌ Category is required! Examples: neko, waifu, hentai, lewd";
|
||||
if (!category) {
|
||||
const errorMsg = "❌ Category is required!";
|
||||
console.error('[NekosLife] No category provided');
|
||||
|
||||
if (isEphemeral) {
|
||||
|
|
@ -139,52 +134,14 @@ export const nekoslifeCommand = {
|
|||
return { type: 4 };
|
||||
}
|
||||
|
||||
// Validate category
|
||||
const categoryLower = category.toLowerCase().trim();
|
||||
if (!isValidCategory(categoryLower)) {
|
||||
const errorMsg = `❌ Invalid category "${category}". Available: neko, waifu, hentai, lewd, yuri, etc.`;
|
||||
|
||||
if (isEphemeral) {
|
||||
return {
|
||||
type: 4,
|
||||
data: {
|
||||
content: errorMsg,
|
||||
flags: 64,
|
||||
},
|
||||
};
|
||||
}
|
||||
showToast(errorMsg, getAssetIDByName("CircleXIcon"));
|
||||
return { type: 4 };
|
||||
}
|
||||
|
||||
// Parse limit
|
||||
let limit = 1;
|
||||
if (limitValue !== undefined && limitValue !== null) {
|
||||
limit = parseInt(String(limitValue)) || 1;
|
||||
limit = Math.max(1, Math.min(5, limit)); // Clamp between 1-5
|
||||
}
|
||||
|
||||
const isNsfw = isNsfwCategory(categoryLower);
|
||||
|
||||
console.log('[NekosLife] Processing request:', { category: categoryLower, limit, isNsfw, shouldSend, isEphemeral });
|
||||
|
||||
// Check if trying to send NSFW content in non-NSFW channel
|
||||
if (shouldSend && !isEphemeral && isNsfw && !ctx.channel?.nsfw) {
|
||||
alerts.showConfirmationAlert({
|
||||
title: "⚠️ NSFW Content Warning",
|
||||
content: "This category contains NSFW content and can only be sent in NSFW channels!",
|
||||
confirmText: "Okay",
|
||||
cancelText: null,
|
||||
});
|
||||
return { type: 4 };
|
||||
}
|
||||
console.log('[NekosLife] Processing SFW request:', { category, limit, shouldSend, isEphemeral });
|
||||
|
||||
// Show loading toast
|
||||
if (!isEphemeral) {
|
||||
showToast(`Fetching ${limit} image(s) from nekos.life...`, getAssetIDByName("DownloadIcon"));
|
||||
showToast(`Fetching ${limit} SFW image(s) from nekos.life...`, getAssetIDByName("DownloadIcon"));
|
||||
}
|
||||
|
||||
const urls = await fetchNekosLifeImages(categoryLower, limit);
|
||||
const urls = await fetchNekosLifeImages(category, limit);
|
||||
|
||||
if (urls.length === 0) {
|
||||
const errorMsg = "❌ Failed to fetch images from nekos.life. Try again later!";
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue