+
}
+ type="text"
+ value={value}
+ onChange={(e) => {
+ onChange(e.target.value)
+ setSelectedIndex(-1)
+ setShowSuggestions(true)
+ }}
+ onFocus={() => setShowSuggestions(true)}
+ onKeyDown={handleKeyDown}
+ onTouchEnd={onTouchEnd}
+ placeholder={placeholder}
+ className={className}
+ style={style}
+ autoFocus={autoFocus}
+ disabled={disabled}
+ />
+ {showSuggestions && hasSuggestions && (
+
+ {suggestions.map((path: string, i: number) => (
+ - {
+ e.preventDefault()
+ handleSelect(path)
+ }}
+ className="px-3 py-1.5 text-xs cursor-pointer truncate"
+ style={{
+ color: 'var(--text-primary)',
+ backgroundColor: i === selectedIndex ? 'var(--bg-hover)' : undefined,
+ }}
+ onMouseEnter={() => setSelectedIndex(i)}
+ >
+ {path}
+
+ ))}
+
+ )}
+
+ )
+}
+
+
+
diff --git a/src/components/ui/index.ts b/src/components/ui/index.ts
index 50ca0e0..23f2689 100644
--- a/src/components/ui/index.ts
+++ b/src/components/ui/index.ts
@@ -2,3 +2,5 @@ export { Toggle } from './Toggle'
export { Checkbox } from './Checkbox'
export { Select } from './Select'
export { MultiSelect } from './MultiSelect'
+export { PathInput } from './PathInput'
+
diff --git a/src/hooks/usePathHistory.ts b/src/hooks/usePathHistory.ts
new file mode 100644
index 0000000..61213db
--- /dev/null
+++ b/src/hooks/usePathHistory.ts
@@ -0,0 +1,39 @@
+import { useCallback } from 'react'
+
+const STORAGE_KEY = 'qbit-path-history'
+const MAX_ENTRIES = 50
+
+function getHistory(): string[] {
+ try {
+ const raw = localStorage.getItem(STORAGE_KEY)
+ if (!raw) return []
+ const parsed = JSON.parse(raw)
+ return Array.isArray(parsed) ? parsed.filter((p): p is string => typeof p === 'string') : []
+ } catch {
+ return []
+ }
+}
+
+function saveHistory(paths: string[]) {
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(paths.slice(0, MAX_ENTRIES)))
+}
+
+export function usePathHistory() {
+ const addPath = useCallback((path: string) => {
+ const trimmed = path.trim()
+ if (!trimmed) return
+ const history = getHistory().filter((p) => p !== trimmed)
+ history.unshift(trimmed)
+ saveHistory(history)
+ }, [])
+
+ const getSuggestions = useCallback((input: string): string[] => {
+ const history = getHistory()
+ if (!input) return history.slice(0, 5)
+ const lower = input.toLowerCase()
+ return history.filter((p) => p.toLowerCase().includes(lower))
+ }, [])
+
+ return { addPath, getSuggestions }
+}
+
diff --git a/src/mobile/MobileSearchPanel.tsx b/src/mobile/MobileSearchPanel.tsx
index fb4c922..cf79f60 100644
--- a/src/mobile/MobileSearchPanel.tsx
+++ b/src/mobile/MobileSearchPanel.tsx
@@ -18,6 +18,8 @@ import { type Instance } from '../api/instances'
import { getCategories, type Category } from '../api/qbittorrent'
import { formatSize } from '../utils/format'
import { extractTags, sortResults, filterResults, type SortKey } from '../utils/search'
+import { PathInput } from '../components/ui/PathInput'
+import { usePathHistory } from '../hooks/usePathHistory'
function formatAge(dateStr: string): string {
const date = new Date(dateStr)
@@ -39,6 +41,7 @@ interface Props {
export function MobileSearchPanel({ instances, onBack }: Props) {
const [integrations, setIntegrations] = useState