diff --git a/src/core/i18n/default.json b/src/core/i18n/default.json
index 5764edf..b20e33e 100644
--- a/src/core/i18n/default.json
+++ b/src/core/i18n/default.json
@@ -7,6 +7,7 @@
"AUTO_DEBUGGER": "Automatically connect to Debugger",
"AUTO_DEVTOOLS": "Automatically connect to Devtools",
"ASSET_BROWSER": "Asset Browser",
+ "ASSET_TYPES": "Asset Types",
"BRAND": "Brand",
"SHIGGYCORD": "ShiggyCord",
"SHIGGYCORD_URL": "ShiggyCord URL",
diff --git a/src/core/ui/settings/pages/Developer/AssetBrowser.tsx b/src/core/ui/settings/pages/Developer/AssetBrowser.tsx
index 639dcb5..53645c6 100644
--- a/src/core/ui/settings/pages/Developer/AssetBrowser.tsx
+++ b/src/core/ui/settings/pages/Developer/AssetBrowser.tsx
@@ -1,21 +1,98 @@
import AssetDisplay from "@core/ui/settings/pages/Developer/AssetDisplay";
import { iterateAssets } from "@lib/api/assets";
-import { Text } from "@metro/common/components";
+import { findAssetId } from "@lib/api/assets";
+import { Strings } from "@core/i18n";
+import { IconButton, TableCheckboxRow, TableRowGroup, ActionSheet, BottomSheetTitleHeader } from "@metro/common/components";
import { ErrorBoundary, Search } from "@ui/components";
-import { useMemo } from "react";
+import { showSheet } from "@lib/ui/sheets";
+import { useProxy, createProxy } from "@core/vendetta/storage";
+import { useState, useMemo, useCallback } from "react";
import { FlatList, View } from "react-native";
+// Asset type categories
+const DISPLAYABLE_IMAGE_TYPES = new Set(["png", "jpg", "jpeg", "svg", "gif"]);
+const DISPLAYABLE_TEXT_TYPES = new Set(["jsona", "json", "lottie"]);
+
+// Define all available filters with their display names
+const FILTER_OPTIONS = [
+ { id: "images", label: "Images (PNG, JPG, SVG, GIF)", types: DISPLAYABLE_IMAGE_TYPES, defaultEnabled: true },
+ { id: "text", label: "Text Types (JSON, JSONA, Lottie)", types: DISPLAYABLE_TEXT_TYPES, defaultEnabled: false },
+];
+
+const { proxy: assetBrowserStorage } = createProxy({
+ enabledFilters: {
+ images: true,
+ text: false,
+ }
+});
+
export default function AssetBrowser() {
- const [search, setSearch] = React.useState("");
- const all = useMemo(() => Array.from(iterateAssets()), []);
+ const [search, setSearch] = useState("");
+ const [updateTick, setUpdateTick] = useState(0);
+
+ // Use useProxy to make the state reactive
+ useProxy(assetBrowserStorage);
+
+ const getFilteredAssets = useCallback(() => {
+ return Array.from(iterateAssets()).filter((asset) => {
+ const type = String(asset.type ?? "").toLowerCase();
+
+ // Check if this asset type is enabled in any filter
+ for (const filter of FILTER_OPTIONS) {
+ if (assetBrowserStorage.enabledFilters[filter.id as keyof typeof assetBrowserStorage.enabledFilters] && filter.types.has(type)) {
+ return true;
+ }
+ }
+ return false;
+ });
+ }, [updateTick]);
+
+ const all = useMemo(() => getFilteredAssets(), [getFilteredAssets]);
+
+ const toggleFilter = (filterId: string) => {
+ assetBrowserStorage.enabledFilters[filterId as keyof typeof assetBrowserStorage.enabledFilters] = !assetBrowserStorage.enabledFilters[filterId as keyof typeof assetBrowserStorage.enabledFilters];
+ setUpdateTick(prev => prev + 1);
+ };
+
+ const handleFilterPress = () => {
+ showSheet("AssetBrowserFilter", () => {
+ useProxy(assetBrowserStorage);
+
+ return (
+
+
+
+
+ {FILTER_OPTIONS.map(filter => (
+ toggleFilter(filter.id)}
+ />
+ ))}
+
+
+
+ );
+ });
+ };
return (
- setSearch(v)}
- />
+
+ setSearch(v)}
+ />
+
+
-
- Some assets types cannot be displayed and will be marked in red.
-
a.name.includes(search) || a.id.toString() === search,
+ (a) => (a.name.includes(search) || a.id.toString() === search),
)}
renderItem={({ item }: any) => }
contentContainerStyle={{