diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 462c754..9262349 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -405,6 +405,7 @@ export default function App() {
const [search, setSearch] = useState('')
const [categoryFilter, setCategoryFilter] = useState('all')
+ const [developerFilter, setDeveloperFilter] = useState('all')
const [viewMode, setViewMode] = useState<'full' | 'compact'>(() => {
const saved = localStorage.getItem('packageViewMode')
return saved === 'compact' ? 'compact' : 'full'
@@ -424,6 +425,11 @@ export default function App() {
return Array.from(cats).sort()
}, [packages])
+ const developers = useMemo(() => {
+ const devs = new Set(packages.map(p => p.upstreamAuthor).filter(Boolean))
+ return Array.from(devs).sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' }))
+ }, [packages])
+
const resolvedAppTheme = useMemo((): 'dark' | 'light' => {
if (theme === 'system') {
return systemPrefersDark ? 'dark' : 'light'
@@ -480,9 +486,12 @@ export default function App() {
if (categoryFilter !== 'all' && !(pkg.categories || []).includes(categoryFilter)) {
return false
}
+ if (developerFilter !== 'all' && pkg.upstreamAuthor !== developerFilter) {
+ return false
+ }
return true
})
- }, [packages, search, categoryFilter, deviceInfo.firmware])
+ }, [packages, search, categoryFilter, developerFilter, deviceInfo.firmware])
const installedFiltered = useMemo(() =>
filteredPackages.filter(pkg => installedPackages.has(pkg.name)),
@@ -2218,6 +2227,17 @@ export default function App() {
))}
+