diff --git a/app/premium/page.tsx b/app/premium/page.tsx index f7e3e43..9408fe3 100644 --- a/app/premium/page.tsx +++ b/app/premium/page.tsx @@ -41,6 +41,7 @@ function PremiumHomePage() { checkedSources={completedSources} totalSources={totalSources} placeholder="输入关键词开始搜索..." + isPremium={true} /> diff --git a/app/settings/hooks/useSettingsPage.ts b/app/settings/hooks/useSettingsPage.ts index 6674a44..6f89af0 100644 --- a/app/settings/hooks/useSettingsPage.ts +++ b/app/settings/hooks/useSettingsPage.ts @@ -26,7 +26,7 @@ export function useSettingsPage() { // Display settings const [realtimeLatency, setRealtimeLatency] = useState(false); const [searchDisplayMode, setSearchDisplayMode] = useState('normal'); - const [fullscreenType, setFullscreenType] = useState<'native' | 'window'>('native'); + const [fullscreenType, setFullscreenType] = useState<'auto' | 'native' | 'window'>('auto'); const [proxyMode, setProxyMode] = useState('retry'); const [rememberScrollPosition, setRememberScrollPosition] = useState(true); @@ -285,7 +285,7 @@ export function useSettingsPage() { }); }; - const handleFullscreenTypeChange = (type: 'native' | 'window') => { + const handleFullscreenTypeChange = (type: 'auto' | 'native' | 'window') => { setFullscreenType(type); const currentSettings = settingsStore.getSettings(); settingsStore.saveSettings({ diff --git a/components/search/SearchBox.tsx b/components/search/SearchBox.tsx index ea60500..3a2ea98 100644 --- a/components/search/SearchBox.tsx +++ b/components/search/SearchBox.tsx @@ -11,9 +11,10 @@ interface SearchBoxProps { onClear?: () => void; initialQuery?: string; placeholder?: string; + isPremium?: boolean; } -export function SearchBox({ onSearch, onClear, initialQuery = '', placeholder = '搜索电影、电视剧、综艺...' }: SearchBoxProps) { +export function SearchBox({ onSearch, onClear, initialQuery = '', placeholder = '搜索电影、电视剧、综艺...', isPremium = false }: SearchBoxProps) { const [query, setQuery] = useState(initialQuery); const inputRef = useRef(null); @@ -35,7 +36,7 @@ export function SearchBox({ onSearch, onClear, initialQuery = '', placeholder = onSearch(selectedQuery); // Blur the input after selecting from history inputRef.current?.blur(); - }); + }, isPremium); // Update query when initialQuery changes useEffect(() => { diff --git a/components/search/SearchForm.tsx b/components/search/SearchForm.tsx index 0643547..55cb846 100644 --- a/components/search/SearchForm.tsx +++ b/components/search/SearchForm.tsx @@ -12,6 +12,7 @@ interface SearchFormProps { checkedSources?: number; totalSources?: number; placeholder?: string; + isPremium?: boolean; } export function SearchForm({ @@ -23,6 +24,7 @@ export function SearchForm({ checkedSources = 0, totalSources = 16, placeholder, + isPremium = false, }: SearchFormProps) { return (
@@ -31,6 +33,7 @@ export function SearchForm({ onClear={onClear} initialQuery={initialQuery} placeholder={placeholder} + isPremium={isPremium} /> {/* Loading Animation */} diff --git a/components/settings/PlayerSettings.tsx b/components/settings/PlayerSettings.tsx index 40094cf..420206c 100644 --- a/components/settings/PlayerSettings.tsx +++ b/components/settings/PlayerSettings.tsx @@ -9,8 +9,8 @@ import { Icons } from '@/components/ui/Icon'; import type { ProxyMode } from '@/lib/store/settings-store'; interface PlayerSettingsProps { - fullscreenType: 'native' | 'window'; - onFullscreenTypeChange: (type: 'native' | 'window') => void; + fullscreenType: 'auto' | 'native' | 'window'; + onFullscreenTypeChange: (type: 'auto' | 'native' | 'window') => void; proxyMode: ProxyMode; onProxyModeChange: (mode: ProxyMode) => void; } diff --git a/lib/hooks/useSearchHistory.ts b/lib/hooks/useSearchHistory.ts index b6a5d54..89369d2 100644 --- a/lib/hooks/useSearchHistory.ts +++ b/lib/hooks/useSearchHistory.ts @@ -5,7 +5,7 @@ */ import { useState, useEffect, useCallback, useRef } from 'react'; -import { useSearchHistoryStore } from '@/lib/store/search-history-store'; +import { useSearchHistoryStoreSelector } from '@/lib/store/search-history-store'; import type { SearchHistoryItem } from '@/lib/store/search-history-store'; interface UseSearchHistoryReturn { @@ -23,7 +23,8 @@ interface UseSearchHistoryReturn { } export function useSearchHistory( - onSelectHistory?: (query: string) => void + onSelectHistory?: (query: string) => void, + isPremium: boolean = false ): UseSearchHistoryReturn { const { searchHistory, @@ -31,7 +32,7 @@ export function useSearchHistory( removeFromSearchHistory, clearSearchHistory, getRecentSearches, - } = useSearchHistoryStore(); + } = useSearchHistoryStoreSelector(isPremium); const [isDropdownOpen, setIsDropdownOpen] = useState(false); const [highlightedIndex, setHighlightedIndex] = useState(-1); diff --git a/lib/store/search-history-store.ts b/lib/store/search-history-store.ts index e94fc5d..569ad8e 100644 --- a/lib/store/search-history-store.ts +++ b/lib/store/search-history-store.ts @@ -17,7 +17,7 @@ export interface SearchHistoryItem { interface SearchHistoryStore { searchHistory: SearchHistoryItem[]; - + // Actions addToSearchHistory: (query: string, resultCount?: number) => void; removeFromSearchHistory: (query: string) => void; @@ -32,82 +32,95 @@ function normalizeQuery(query: string): string { return query.trim().toLowerCase(); } -export const useSearchHistoryStore = create()( - persist( - (set, get) => ({ - searchHistory: [], +const createSearchHistoryStore = (name: string) => + create()( + persist( + (set, get) => ({ + searchHistory: [], - addToSearchHistory: (query, resultCount) => { - const trimmedQuery = query.trim(); - - // Don't add empty queries - if (!trimmedQuery) return; + addToSearchHistory: (query, resultCount) => { + const trimmedQuery = query.trim(); - const normalized = normalizeQuery(trimmedQuery); - const timestamp = Date.now(); + // Don't add empty queries + if (!trimmedQuery) return; - set((state) => { - // Check if query already exists (case-insensitive) - const existingIndex = state.searchHistory.findIndex( - (item) => normalizeQuery(item.query) === normalized - ); + const normalized = normalizeQuery(trimmedQuery); + const timestamp = Date.now(); - let newHistory: SearchHistoryItem[]; + set((state) => { + // Check if query already exists (case-insensitive) + const existingIndex = state.searchHistory.findIndex( + (item) => normalizeQuery(item.query) === normalized + ); - if (existingIndex !== -1) { - // Update existing item and move to top - const updatedItem: SearchHistoryItem = { - query: trimmedQuery, // Keep original casing from new search - timestamp, - resultCount, - }; + let newHistory: SearchHistoryItem[]; - newHistory = [ - updatedItem, - ...state.searchHistory.filter((_, index) => index !== existingIndex), - ]; - } else { - // Add new item at the top - const newItem: SearchHistoryItem = { - query: trimmedQuery, - timestamp, - resultCount, - }; + if (existingIndex !== -1) { + // Update existing item and move to top + const updatedItem: SearchHistoryItem = { + query: trimmedQuery, // Keep original casing from new search + timestamp, + resultCount, + }; - newHistory = [newItem, ...state.searchHistory]; - } + newHistory = [ + updatedItem, + ...state.searchHistory.filter((_, index) => index !== existingIndex), + ]; + } else { + // Add new item at the top + const newItem: SearchHistoryItem = { + query: trimmedQuery, + timestamp, + resultCount, + }; - // Trim to max items - if (newHistory.length > MAX_HISTORY_ITEMS) { - newHistory = newHistory.slice(0, MAX_HISTORY_ITEMS); - } + newHistory = [newItem, ...state.searchHistory]; + } - return { searchHistory: newHistory }; - }); - }, + // Trim to max items + if (newHistory.length > MAX_HISTORY_ITEMS) { + newHistory = newHistory.slice(0, MAX_HISTORY_ITEMS); + } - removeFromSearchHistory: (query) => { - const normalized = normalizeQuery(query); - - set((state) => ({ - searchHistory: state.searchHistory.filter( - (item) => normalizeQuery(item.query) !== normalized - ), - })); - }, + return { searchHistory: newHistory }; + }); + }, - clearSearchHistory: () => { - set({ searchHistory: [] }); - }, + removeFromSearchHistory: (query) => { + const normalized = normalizeQuery(query); - getRecentSearches: (limit = 10) => { - const history = get().searchHistory; - return history.slice(0, limit); - }, - }), - { - name: 'kvideo-search-history', - version: 1, - } - ) -); + set((state) => ({ + searchHistory: state.searchHistory.filter( + (item) => normalizeQuery(item.query) !== normalized + ), + })); + }, + + clearSearchHistory: () => { + set({ searchHistory: [] }); + }, + + getRecentSearches: (limit = 10) => { + const history = get().searchHistory; + return history.slice(0, limit); + }, + }), + { + name, + version: 1, + } + ) + ); + +export const useSearchHistoryStore = createSearchHistoryStore('kvideo-search-history'); +export const usePremiumSearchHistoryStore = createSearchHistoryStore('kvideo-premium-search-history'); + +/** + * Helper hook to get the appropriate search history store + */ +export function useSearchHistoryStoreSelector(isPremium = false) { + const normalStore = useSearchHistoryStore(); + const premiumStore = usePremiumSearchHistoryStore(); + return isPremium ? premiumStore : normalStore; +} diff --git a/package-lock.json b/package-lock.json index 9093cc7..a70c135 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "kvideo", - "version": "4.0.9", + "version": "4.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "kvideo", - "version": "4.0.9", + "version": "4.1.0", "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", diff --git a/package.json b/package.json index 551c362..ec784f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kvideo", - "version": "4.0.9", + "version": "4.1.0", "private": true, "scripts": { "dev": "next dev",