ott_filtering: v1.3.12

This commit is contained in:
Aman Vishwakarma 2025-04-08 14:52:06 +05:30
parent 788e61d1bf
commit b2303d405d
No known key found for this signature in database
6 changed files with 128 additions and 113 deletions

View file

@ -14,11 +14,12 @@ import SortFilter from './sortFilter';
import AddNew from './addNew';
import MovieTypeFilter from './typeFilter';
import MovieSelectPopUp from './movieSelectPopUp';
import ProviderFilter from './providerFilter';
import { Platform, requestUrl, Notice } from "obsidian";
const Header = ({ showTrailerAndPosterLinks, movieProperties, handleClearAllFilters, selectedProperties, handlePropertyChange, selectedRating, handleRatingChange, genres, selectedGenres, handleGenreChange, selectedTypes, handleTypeChange, createMarkdownFile, availableLanguages, handleSortChange, sortOption, sortOrder, toggleSortOrder, themeMode, plugin, selectedLanguages, handleLanguageChange }) => {
const Header = ({ showTrailerAndPosterLinks, movieProperties, handleClearAllFilters, selectedProperties, handlePropertyChange, selectedRating, handleRatingChange, genres, selectedGenres, handleGenreChange, selectedTypes, handleTypeChange, createMarkdownFile, availableLanguages, handleSortChange, sortOption, sortOrder, toggleSortOrder, themeMode, plugin, selectedLanguages, handleLanguageChange, selectedProviders, handleProviderChange, availableProviders }) => {
const [mobileFiltersOpen, setMobileFiltersOpen] = useState(false);
const [addDialogOpen, setAddDialogOpen] = useState(false);
@ -284,6 +285,15 @@ ${isTvShow ? '' : `release_date: ${releaseDate}`}
handleTypeChange={handleTypeChange}
/>
</Box>
<Box mb={2}>
<ProviderFilter
providers={availableProviders}
selectedProviders={selectedProviders}
handleProviderChange={handleProviderChange}
/>
</Box>
<Box mb={2}>
<Button variant="contained" onClick={handleClearAllFilters} style={{
color: 'inherit', maxWidth: '100px', height: 'auto',

View file

@ -0,0 +1,74 @@
import React from 'react';
import { FormControl, InputLabel, Select, MenuItem, OutlinedInput, Checkbox, Box } from '@mui/material';
import { providerLogos } from './providerLogos';
const ProviderFilter = ({ providers, selectedProviders, handleProviderChange }) => {
return (
<FormControl fullWidth variant="outlined" sx={{ width: '8vw', '.MuiOutlinedInput-notchedOutline': { borderColor: 'inherit' } }}>
<InputLabel sx={{ color: 'inherit' }}>Providers</InputLabel>
<Select
multiple
value={selectedProviders}
onChange={handleProviderChange}
input={<OutlinedInput label="Providers" />}
renderValue={(selected) => (
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
{selected.map((provider) => (
<img
key={provider}
src={providerLogos[provider] || ''}
alt={provider}
style={{
height: '20px',
width: '20px',
objectFit: 'contain',
marginRight: '4px'
}}
/>
))}
</Box>
)}
MenuProps={{
PaperProps: {
style: {
maxHeight: 224,
width: 250,
},
},
}}
sx={{
color: 'inherit',
'& .MuiSelect-select': {
paddingLeft: '5px',
display: 'flex',
flexWrap: 'wrap',
gap: '4px',
alignItems: 'center'
},
'& .MuiOutlinedInput-notchedOutline': { borderColor: 'inherit' },
'&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'inherit' },
'&.Mui-focused .MuiOutlinedInput-notchedOutline': { borderColor: 'inherit' },
'& .MuiSvgIcon-root': { color: 'inherit' },
}}
>
{providers.map((provider) => (
<MenuItem key={provider} value={provider} sx={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<Checkbox checked={selectedProviders.indexOf(provider) > -1} />
<img
src={providerLogos[provider] || ''}
alt={provider}
style={{
height: '24px',
width: '24px',
objectFit: 'contain'
}}
/>
<span style={{ marginLeft: '8px' }}>{provider}</span>
</MenuItem>
))}
</Select>
</FormControl>
);
};
export default ProviderFilter;

View file

@ -10,6 +10,9 @@ Movie and TV show tracker plugin for Obsidian
![Add new](https://raw.githubusercontent.com/Shreshth-mehra/Obsidian-TV-Tracker/main/Showcase/addnew2.gif)
# new in v1.3.12
- Added the filtering option OTT Providers
# New in v1.3.11
- Added Search filter option for OTT providers. Simply type the OTT in the search bar.
- Fixed a bug where movies with special characters in their name couldn't be added

View file

@ -69,6 +69,8 @@ export const ReactView = ({ moviesData, createMarkdownFile, themeMode, plugin, d
const [sortOrder, setSortOrder] = useState('descending');
const [showDiscoverPopup, setShowDiscoverPopup] = useState(false);
const [selectedLanguages, setSelectedLanguages] = useState(defaultLanguages);
const [selectedProviders, setSelectedProviders] = useState([]);
const [availableProviders, setAvailableProviders] = useState([]);
const [debugInfo, setDebugInfo] = useState('Should not be this');
const debouncedSearchTerm = useDebounce(searchTerm, 500);
@ -88,6 +90,7 @@ export const ReactView = ({ moviesData, createMarkdownFile, themeMode, plugin, d
setSelectedRating(1);
setShowWatchlist(false);
setSelectedLanguages([]); // Set this to default selected languages from settings instead
setSelectedProviders([]); // Clear provider filter
};
const handleGenreChange = (event) => {
@ -111,6 +114,13 @@ export const ReactView = ({ moviesData, createMarkdownFile, themeMode, plugin, d
setSelectedTypes(typeof value === 'string' ? value.split(',') : value);
};
const handleProviderChange = (event) => {
const {
target: { value },
} = event;
setSelectedProviders(typeof value === 'string' ? value.split(',') : value);
};
const sortMovies = (movies) => {
return movies.sort((a, b) => {
@ -155,10 +165,21 @@ export const ReactView = ({ moviesData, createMarkdownFile, themeMode, plugin, d
Object.keys(movie).forEach(key => propertiesSet.add(key));
});
setMovieProperties(Array.from(propertiesSet));
// Extract available providers from movies
const providersSet = new Set();
movies.forEach(movie => {
if (movie['Available On']) {
const providers = movie['Available On'].split(', ');
providers.forEach(provider => providersSet.add(provider));
}
});
setAvailableProviders(Array.from(providersSet));
// parseAndSetSelectedLanguages();
applyFilters();
}, [movies, selectedGenres, selectedTypes, selectedRating, debouncedSearchTerm, sortOption, showWatchlist, sortOrder, selectedLanguages]);
}, [movies, selectedGenres, selectedTypes, selectedRating, debouncedSearchTerm, sortOption, showWatchlist, sortOrder, selectedLanguages, selectedProviders]);
@ -211,7 +232,16 @@ export const ReactView = ({ moviesData, createMarkdownFile, themeMode, plugin, d
const matchesRating = movie.Rating >= selectedRating;
const matchesWatchlist = !showWatchlist || movie.Status === 'Watchlist';
const matchesLanguage = selectedLanguages.length === 0 || selectedLanguages.includes(movie.original_language);
return matchesGenre && matchesType && matchesRating && matchesLanguage && (matchesTitle || matchesCast || matchesDirector || matchesProductionComapny || matchesCollection || matchesYear || matchesAvailableOn) && matchesWatchlist;
// Add provider filter
const matchesProvider = selectedProviders.length === 0 ||
(movie['Available On'] && selectedProviders.some(provider =>
movie['Available On'].split(', ').includes(provider)
));
return matchesGenre && matchesType && matchesRating && matchesLanguage && matchesProvider &&
(matchesTitle || matchesCast || matchesDirector || matchesProductionComapny || matchesCollection || matchesYear || matchesAvailableOn) &&
matchesWatchlist;
} catch (error) {
new Notice(`Error processing movie ${movie.Title}. Showing rest of the results. Please console for detailed error`);
console.error(`Error processing movie ${movie.Title}: ${error.message}`);
@ -258,6 +288,9 @@ export const ReactView = ({ moviesData, createMarkdownFile, themeMode, plugin, d
handleLanguageChange={handleLanguageChange}
selectedLanguages={selectedLanguages}
availableLanguages={availableLanguages}
selectedProviders={selectedProviders}
handleProviderChange={handleProviderChange}
availableProviders={availableProviders}
/>
<Box style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<TextField

View file

@ -1,7 +1,7 @@
{
"id": "tv-tracker",
"name": "Movie and TV show tracker",
"version": "1.3.11",
"version": "1.3.12",
"minAppVersion": "0.15.0",
"description": "A Movie and TV show tracker.",
"author": "Shreshth Mehra",

113
package-lock.json generated
View file

@ -1,20 +1,18 @@
{
"name": "obsidian-sample-plugin",
"version": "1.0.0",
"name": "tv-tracker-plugin",
"version": "1.3.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "obsidian-sample-plugin",
"version": "1.0.0",
"name": "tv-tracker-plugin",
"version": "1.3.0",
"license": "MIT",
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.15.3",
"@mui/material": "^5.15.3",
"fs": "^0.0.1-security",
"gray-matter": "^4.0.3",
"path": "^0.12.7",
"react": "^18.2.0",
"react-dom": "^18.2.0"
@ -1946,18 +1944,6 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/esquery": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
@ -2021,17 +2007,6 @@
"node": ">=0.10.0"
}
},
"node_modules/extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
"dependencies": {
"is-extendable": "^0.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@ -2159,11 +2134,6 @@
"dev": true,
"peer": true
},
"node_modules/fs": {
"version": "0.0.1-security",
"resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
"integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w=="
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -2262,40 +2232,6 @@
"dev": true,
"peer": true
},
"node_modules/gray-matter": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz",
"integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==",
"dependencies": {
"js-yaml": "^3.13.1",
"kind-of": "^6.0.2",
"section-matter": "^1.0.0",
"strip-bom-string": "^1.0.0"
},
"engines": {
"node": ">=6.0"
}
},
"node_modules/gray-matter/node_modules/argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dependencies": {
"sprintf-js": "~1.0.2"
}
},
"node_modules/gray-matter/node_modules/js-yaml": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
"dependencies": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@ -2398,14 +2334,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-extendable": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
"integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@ -2507,14 +2435,6 @@
"json-buffer": "3.0.1"
}
},
"node_modules/kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -3015,18 +2935,6 @@
"loose-envify": "^1.1.0"
}
},
"node_modules/section-matter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
"integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==",
"dependencies": {
"extend-shallow": "^2.0.1",
"kind-of": "^6.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
@ -3082,11 +2990,6 @@
"node": ">=0.10.0"
}
},
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
},
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@ -3100,14 +3003,6 @@
"node": ">=8"
}
},
"node_modules/strip-bom-string": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
"integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",