feat: add search toggle functionality

- Add search toggle option in Others settings
- Add searchEnabled state to ConfigContext
- Add search catalogs to manifest when search is enabled
- Make search enabled by default
- Update manifest to include search catalogs for both movies and series

This change allows users to control search functionality independently
from catalog selection.
This commit is contained in:
mrcanelas
2025-02-14 19:03:07 -03:00
parent c529cbca7d
commit 39927a6072
9 changed files with 100 additions and 50 deletions
+43 -21
View File
@@ -114,27 +114,49 @@ async function getManifest(config) {
const filterLanguages = setOrderLanguage(language, languagesArray);
const options = { years, genres_movie, genres_series, filterLanguages };
const catalogs = userCatalogs
.filter(userCatalog => {
const catalogDef = getCatalogDefinition(userCatalog.id);
if (!catalogDef) return false;
if (catalogDef.requiresAuth && !sessionId) return false;
return true;
})
.map(userCatalog => {
const catalogDef = getCatalogDefinition(userCatalog.id);
const catalogOptions = getOptionsForCatalog(catalogDef, userCatalog.type, userCatalog.showInHome, options);
return createCatalog(
userCatalog.id,
userCatalog.type,
catalogDef,
catalogOptions,
tmdbPrefix,
translatedCatalogs,
userCatalog.showInHome
);
});
// Criar catálogos base
let catalogs = userCatalogs
.filter(userCatalog => {
const catalogDef = getCatalogDefinition(userCatalog.id);
if (!catalogDef) return false;
if (catalogDef.requiresAuth && !sessionId) return false;
return true;
})
.map(userCatalog => {
const catalogDef = getCatalogDefinition(userCatalog.id);
const catalogOptions = getOptionsForCatalog(catalogDef, userCatalog.type, userCatalog.showInHome, options);
return createCatalog(
userCatalog.id,
userCatalog.type,
catalogDef,
catalogOptions,
tmdbPrefix,
translatedCatalogs,
userCatalog.showInHome
);
});
// Adicionar catálogo de busca se searchEnabled não for false
if (config.searchEnabled !== "false") {
const searchCatalogMovie = {
id: "tmdb.search",
type: "movie",
name: `${tmdbPrefix ? "TMDB - " : ""}${translatedCatalogs.search}`,
pageSize: 20,
extra: [{ name: "search" }]
};
const searchCatalogSeries = {
id: "tmdb.search",
type: "series",
name: `${tmdbPrefix ? "TMDB - " : ""}${translatedCatalogs.search}`,
pageSize: 20,
extra: [{ name: "search" }]
};
catalogs = [...catalogs, searchCatalogMovie, searchCatalogSeries];
}
const descriptionSuffix = language && language !== DEFAULT_LANGUAGE ? ` with ${language} language.` : ".";
+1 -1
View File
@@ -2,7 +2,7 @@
"default": {
"top": {
"nameKey": "popular",
"extraSupported": ["genre", "skip", "search"]
"extraSupported": ["genre", "skip"]
},
"year": {
"nameKey": "year",
+1
View File
@@ -6,6 +6,7 @@
"trending": "Trending",
"favorites": "Favorites",
"watchlist": "Watchlist",
"search": "Search",
"nfx": "Netflix",
"nfk": "Netflix Kids",
"hbm": "HBO Max",
+1 -1
View File
@@ -22,7 +22,7 @@ export function AgeRatingSelect() {
return (
<div className="flex flex-col gap-2">
<div className="flex items-center justify-between">
<label className="text-sm font-medium">Age Rating</label>
<label className="text-sm font-semibold mb-1">Age Rating</label>
<div className="flex items-center text-xs text-muted-foreground">
<Info className="h-3 w-3 mr-1" />
Not available for trending catalogs
+19
View File
@@ -0,0 +1,19 @@
import { Switch } from "@/components/ui/switch";
import { useConfig } from "@/contexts/ConfigContext";
import { Card } from "@/components/ui/card";
export function SearchToggle() {
const { searchEnabled, setSearchEnabled } = useConfig();
return (
<Card className="flex flex-row items-center justify-between p-6">
<div className="space-y-0.5">
<label className="text-sm font-semibold mb-1">Enable Search</label>
<p className="text-gray-500 text-sm">
Allow searching for movies and TV shows
</p>
</div>
<Switch checked={searchEnabled} onCheckedChange={setSearchEnabled} />
</Card>
);
}
+5
View File
@@ -26,6 +26,7 @@ export function ConfigProvider({ children }: { children: React.ReactNode }) {
const [streaming, setStreaming] = useState<string[]>([]);
const [catalogs, setCatalogs] = useState<CatalogConfig[]>([]);
const [ageRating, setAgeRating] = useState<string | undefined>(undefined);
const [searchEnabled, setSearchEnabled] = useState<boolean>(true);
const loadConfigFromUrl = () => {
try {
@@ -60,6 +61,8 @@ export function ConfigProvider({ children }: { children: React.ReactNode }) {
setStreaming(Array.from(selectedStreamingServices) as string[]);
}
if (config.searchEnabled) setSearchEnabled(config.searchEnabled === "true");
window.history.replaceState({}, '', '/configure');
} catch (error) {
console.error('Error loading config from URL:', error);
@@ -82,6 +85,7 @@ export function ConfigProvider({ children }: { children: React.ReactNode }) {
streaming,
catalogs,
ageRating,
searchEnabled,
setRpdbkey,
setMdblistkey,
setIncludeAdult,
@@ -92,6 +96,7 @@ export function ConfigProvider({ children }: { children: React.ReactNode }) {
setStreaming,
setCatalogs,
setAgeRating,
setSearchEnabled,
loadConfigFromUrl
};
+16 -13
View File
@@ -7,7 +7,7 @@ export type CatalogConfig = {
showInHome: boolean;
};
export interface ConfigContextType {
export type ConfigContextType = {
rpdbkey: string;
mdblistkey: string;
includeAdult: boolean;
@@ -17,17 +17,20 @@ export interface ConfigContextType {
sessionId: string;
streaming: string[];
catalogs: CatalogConfig[];
ageRating: string;
setRpdbkey: (value: string) => void;
setMdblistkey: (value: string) => void;
setIncludeAdult: (value: boolean) => void;
setProvideImdbId: (value: boolean) => void;
setTmdbPrefix: (value: boolean) => void;
setLanguage: (value: string) => void;
setSessionId: (value: string) => void;
setStreaming: (value: string[]) => void;
setCatalogs: (value: CatalogConfig[] | ((prev: CatalogConfig[]) => CatalogConfig[])) => void;
setAgeRating: (value: string) => void;
}
ageRating: string | undefined;
searchEnabled: boolean;
setRpdbkey: (rpdbkey: string) => void;
setMdblistkey: (mdblistkey: string) => void;
setIncludeAdult: (includeAdult: boolean) => void;
setProvideImdbId: (provideImdbId: boolean) => void;
setTmdbPrefix: (tmdbPrefix: boolean) => void;
setLanguage: (language: string) => void;
setSessionId: (sessionId: string) => void;
setStreaming: (streaming: string[]) => void;
setCatalogs: (catalogs: CatalogConfig[]) => void;
setAgeRating: (ageRating: string | undefined) => void;
setSearchEnabled: (enabled: boolean) => void;
loadConfigFromUrl: () => void;
};
export const ConfigContext = createContext<ConfigContextType | undefined>(undefined);
+3 -1
View File
@@ -7,6 +7,7 @@ interface AddonConfig {
language?: string;
sessionId?: string;
ageRating?: string;
searchEnabled?: boolean;
catalogs?: Array<{
id: string;
type: string;
@@ -28,7 +29,8 @@ export function generateAddonUrl(config: AddonConfig): string {
})) || undefined,
includeAdult: config.includeAdult === true ? "true" : undefined,
provideImdbId: config.provideImdbId === true ? "true" : undefined,
tmdbPrefix: config.tmdbPrefix === true ? "true" : undefined
tmdbPrefix: config.tmdbPrefix === true ? "true" : undefined,
searchEnabled: config.searchEnabled === false ? "false" : undefined,
};
// Remover propriedades undefined/null
+11 -13
View File
@@ -2,6 +2,7 @@ import { Card } from "@/components/ui/card";
import { Switch } from "@/components/ui/switch";
import { useConfig } from "@/contexts/ConfigContext";
import { AgeRatingSelect } from "@/components/AgeRatingSelect";
import { SearchToggle } from "@/components/SearchToggle";
const Others = () => {
const { includeAdult, setIncludeAdult } = useConfig();
@@ -17,20 +18,15 @@ const Others = () => {
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<Card className="p-6">
<AgeRatingSelect />
</Card>
<SearchToggle />
<Card className="flex flex-row items-center justify-between p-6">
<div className="space-y-0.5">
<h2 className="text-sm font-medium">Enable adult content</h2>
<p className="text-sm text-muted-foreground">
<h1 className="text-sm font-semibold mb-1">Enable adult content</h1>
<p className="text-gray-500 text-sm">
Include adult content in search results
</p>
</div>
<Switch
checked={includeAdult}
onCheckedChange={setIncludeAdult}
/>
<Switch checked={includeAdult} onCheckedChange={setIncludeAdult} />
</Card>
<Card className="flex flex-row items-center justify-between p-4 sm:p-6 hover:shadow-lg transition-shadow cursor-pointer">
<div className="space-y-0.5">
@@ -38,7 +34,8 @@ const Others = () => {
Provide IMDB metadata
</h1>
<p className="text-gray-500 text-sm">
Include IMDB IDs in metadata for better integration with other addons.
Include IMDB IDs in metadata for better integration with other
addons.
</p>
</div>
<Switch
@@ -48,9 +45,7 @@ const Others = () => {
</Card>
<Card className="flex flex-row items-center justify-between p-4 sm:p-6 hover:shadow-lg transition-shadow cursor-pointer">
<div className="space-y-0.5">
<h1 className="text-sm font-semibold mb-1">
Use TMDB prefix
</h1>
<h1 className="text-sm font-semibold mb-1">Use TMDB prefix</h1>
<p className="text-gray-500 text-sm">
Add "TMDB -" prefix to all catalog names for better organization.
</p>
@@ -60,6 +55,9 @@ const Others = () => {
onCheckedChange={() => setTmdbPrefix(!tmdbPrefix)}
/>
</Card>
<Card className="p-6">
<AgeRatingSelect />
</Card>
</div>
</main>
);