mirror of
https://github.com/KuekHaoYang/KVideo.git
synced 2026-08-15 00:33:44 +08:00
perf: Optimize UI performance by simplifying glass effects, removing complex gradients and backdrop-filter, and adding hardware acceleration.
This commit is contained in:
+44
-103
@@ -4,34 +4,34 @@
|
||||
:root {
|
||||
--font-family-system: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif;
|
||||
|
||||
/* Light Mode Palette */
|
||||
--bg-color-light: #f0f2f5;
|
||||
--bg-image-light: linear-gradient(120deg, #fdfbfb 0%, #ebedee 100%);
|
||||
/* Light Mode Palette - Optimized for Performance */
|
||||
--bg-color-light: #f2f4f7;
|
||||
/* Removed complex gradient for solid color or very simple gradient */
|
||||
--bg-image-light: none;
|
||||
--text-color-light: #1d1d1f;
|
||||
--text-color-secondary-light: #6e6e73;
|
||||
--accent-color-light: #0056b3;
|
||||
/* Updated from #007aff for WCAG AA compliance (6.85:1 with white) */
|
||||
--glass-bg-light: rgba(242, 242, 247, 0.8);
|
||||
--glass-border-light: rgba(255, 255, 255, 0.5);
|
||||
--shadow-color-light: rgba(0, 0, 0, 0.1);
|
||||
/* Increased opacity to replace blur effect */
|
||||
--glass-bg-light: rgba(255, 255, 255, 0.95);
|
||||
--glass-border-light: rgba(0, 0, 0, 0.05);
|
||||
--shadow-color-light: rgba(0, 0, 0, 0.05);
|
||||
|
||||
/* Dark Mode Palette */
|
||||
--bg-color-dark: #121212;
|
||||
--bg-image-dark: linear-gradient(120deg, #272B30 0%, #121212 100%);
|
||||
--bg-image-dark: linear-gradient(120deg, #1a1a1a 0%, #121212 100%);
|
||||
--text-color-dark: #f5f5f7;
|
||||
--text-color-secondary-dark: #8e8e93;
|
||||
--accent-color-dark: #1A6DBF;
|
||||
/* Updated for WCAG AA compliance (5.27:1 with white) */
|
||||
--glass-bg-dark: rgba(28, 28, 30, 0.75);
|
||||
--glass-border-dark: rgba(60, 60, 60, 0.7);
|
||||
--glass-bg-dark: rgba(30, 30, 30, 0.9);
|
||||
--glass-border-dark: rgba(255, 255, 255, 0.1);
|
||||
--shadow-color-dark: rgba(0, 0, 0, 0.3);
|
||||
|
||||
/* Universal Variables */
|
||||
--radius-2xl: 1.5rem;
|
||||
--radius-full: 9999px;
|
||||
--shadow-sm: 0 2px 4px var(--shadow-color);
|
||||
--shadow-md: 0 4px 12px var(--shadow-color);
|
||||
--transition-fluid: 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||||
--shadow-sm: 0 1px 2px var(--shadow-color);
|
||||
--shadow-md: 0 4px 6px var(--shadow-color);
|
||||
--transition-fluid: 0.3s ease;
|
||||
|
||||
/* Active Theme Variables */
|
||||
--bg-color: var(--bg-color-light);
|
||||
@@ -43,7 +43,7 @@
|
||||
--glass-border: var(--glass-border-light);
|
||||
--shadow-color: var(--shadow-color-light);
|
||||
|
||||
--background: #f0f2f5;
|
||||
--background: #f2f4f7;
|
||||
--foreground: #1d1d1f;
|
||||
}
|
||||
|
||||
@@ -346,25 +346,25 @@ select:focus-visible {
|
||||
animation: gradient-x 3s ease infinite;
|
||||
}
|
||||
|
||||
/* Liquid Glass Components */
|
||||
/* Liquid Glass Components - OPTIMIZED */
|
||||
.glass-card {
|
||||
/* background: var(--glass-bg); */
|
||||
/* Performance fix: Use solid color with opacity instead of blur */
|
||||
background: var(--bg-color);
|
||||
opacity: 0.95;
|
||||
|
||||
/* backdrop-filter: blur(8px) saturate(120%); */
|
||||
/* -webkit-backdrop-filter: blur(8px) saturate(120%); */
|
||||
opacity: 1;
|
||||
/* Removed backdrop-filter */
|
||||
|
||||
border-radius: var(--radius-2xl);
|
||||
box-shadow: var(--shadow-md);
|
||||
box-shadow: var(--shadow-sm);
|
||||
border: 1px solid var(--glass-border);
|
||||
transition: transform 0.2s ease-out;
|
||||
transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;
|
||||
|
||||
/* Hardware acceleration */
|
||||
transform: translateZ(0);
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.glass-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 24px var(--shadow-color);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
/* Optimize fixed/sticky elements for scrolling */
|
||||
@@ -373,13 +373,12 @@ nav:where(.sticky, .fixed),
|
||||
.fixed {
|
||||
backface-visibility: hidden;
|
||||
-webkit-backface-visibility: hidden;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.glass-input {
|
||||
background: var(--glass-bg);
|
||||
/* Performance fix: Disable blur */
|
||||
/* backdrop-filter: blur(6px) saturate(120%); */
|
||||
/* -webkit-backdrop-filter: blur(6px) saturate(120%); */
|
||||
/* Removed backdrop-filter */
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: var(--radius-2xl);
|
||||
color: var(--text-color);
|
||||
@@ -407,7 +406,7 @@ nav:where(.sticky, .fixed),
|
||||
.glass-button:hover {
|
||||
transform: translateY(-2px);
|
||||
filter: brightness(1.1);
|
||||
box-shadow: 0 4px 8px var(--shadow-color);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.glass-button:active {
|
||||
@@ -477,7 +476,7 @@ nav:where(.sticky, .fixed),
|
||||
min-width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
/* Removed backdrop-filter */
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: var(--radius-2xl);
|
||||
color: white;
|
||||
@@ -612,6 +611,8 @@ nav:where(.sticky, .fixed),
|
||||
/* Reduce paint complexity on scroll */
|
||||
img {
|
||||
content-visibility: auto;
|
||||
/* Hardware acceleration for images */
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
/* Disable pointer events during scroll for better performance */
|
||||
@@ -635,19 +636,18 @@ nav {
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
SEARCH HISTORY DROPDOWN - LIQUID GLASS
|
||||
SEARCH HISTORY DROPDOWN - OPTIMIZED
|
||||
=========================================== */
|
||||
|
||||
/* Search History Dropdown - Absolute positioning under search bar, Liquid Glass effect */
|
||||
/* Search History Dropdown - Absolute positioning under search bar */
|
||||
.search-history-dropdown {
|
||||
/* Removed position: fixed - now using absolute from component */
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
|
||||
/* Liquid Glass effect - Core aesthetic */
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(25px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(25px) saturate(180%);
|
||||
/* Optimized: High opacity background instead of blur */
|
||||
background: var(--bg-color);
|
||||
opacity: 0.98;
|
||||
/* Removed backdrop-filter */
|
||||
|
||||
/* Rounded-2xl corners - Universal softness */
|
||||
border-radius: var(--radius-2xl);
|
||||
@@ -662,7 +662,7 @@ nav {
|
||||
/* Smooth appearance animation */
|
||||
opacity: 0;
|
||||
transform: translateY(-10px) scale(0.95);
|
||||
animation: search-dropdown-appear 0.3s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
|
||||
animation: search-dropdown-appear 0.2s ease-out forwards;
|
||||
|
||||
/* Transform origin for natural scaling */
|
||||
transform-origin: top center;
|
||||
@@ -670,6 +670,9 @@ nav {
|
||||
/* Prevent text selection during interaction */
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
|
||||
/* Hardware acceleration */
|
||||
will-change: transform, opacity;
|
||||
}
|
||||
|
||||
@keyframes search-dropdown-appear {
|
||||
@@ -722,7 +725,7 @@ nav {
|
||||
cursor: pointer;
|
||||
|
||||
/* Fluid animation - Physics-based transitions */
|
||||
transition: all var(--transition-fluid);
|
||||
transition: background-color 0.2s ease;
|
||||
|
||||
/* Subtle background for hover/highlight */
|
||||
background: transparent;
|
||||
@@ -731,13 +734,11 @@ nav {
|
||||
/* Hover state - Light interaction */
|
||||
.search-history-item:hover {
|
||||
background: color-mix(in srgb, var(--accent-color) 10%, transparent);
|
||||
transform: translateX(2px);
|
||||
}
|
||||
|
||||
/* Highlighted state - Keyboard navigation */
|
||||
.search-history-item.highlighted {
|
||||
background: color-mix(in srgb, var(--accent-color) 15%, transparent);
|
||||
transform: translateX(4px);
|
||||
|
||||
/* Subtle inner-glow effect - Lensing principle */
|
||||
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-color) 30%, transparent);
|
||||
@@ -762,7 +763,7 @@ nav {
|
||||
flex-shrink: 0;
|
||||
|
||||
/* Fluid animation */
|
||||
transition: all 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||||
transition: all 0.2s ease;
|
||||
|
||||
/* Prevent triggering parent hover */
|
||||
z-index: 1;
|
||||
@@ -797,64 +798,4 @@ nav {
|
||||
.search-history-dropdown::-webkit-scrollbar-thumb {
|
||||
background: color-mix(in srgb, var(--glass-bg) 80%, transparent);
|
||||
border-radius: var(--radius-full);
|
||||
}
|
||||
|
||||
.search-history-dropdown::-webkit-scrollbar-thumb:hover {
|
||||
background: color-mix(in srgb, var(--accent-color) 50%, transparent);
|
||||
}
|
||||
|
||||
/* Empty state styling */
|
||||
.search-history-empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 2rem 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Accessibility - Focus visible states */
|
||||
.search-history-item:focus-visible {
|
||||
outline: 2px solid var(--accent-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.search-history-remove:focus-visible {
|
||||
outline: 2px solid var(--accent-color);
|
||||
outline-offset: 1px;
|
||||
border-radius: var(--radius-full);
|
||||
}
|
||||
|
||||
/* Mobile optimizations */
|
||||
@media (max-width: 640px) {
|
||||
.search-history-dropdown {
|
||||
/* Increase touch target sizes */
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.search-history-item {
|
||||
padding: 1rem 0.75rem;
|
||||
/* Larger minimum touch target */
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.search-history-remove {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark mode enhancements */
|
||||
body.dark .search-history-dropdown,
|
||||
.dark .search-history-dropdown {
|
||||
/* Enhanced glass effect in dark mode */
|
||||
backdrop-filter: blur(30px) saturate(200%);
|
||||
-webkit-backdrop-filter: blur(30px) saturate(200%);
|
||||
|
||||
/* Stronger shadow for depth */
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
END SEARCH HISTORY DROPDOWN
|
||||
=========================================== */
|
||||
}
|
||||
+1
-1
@@ -110,7 +110,7 @@ function HomePage() {
|
||||
willChange: 'transform'
|
||||
}}>
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
<div className="bg-[var(--glass-bg)] backdrop-blur-[12px] saturate-[120%] [-webkit-backdrop-filter:blur(12px)_saturate(120%)] border border-[var(--glass-border)] shadow-[var(--shadow-md)] px-6 py-4 rounded-[var(--radius-2xl)]" style={{
|
||||
<div className="bg-[var(--glass-bg)] border border-[var(--glass-border)] shadow-[var(--shadow-sm)] px-6 py-4 rounded-[var(--radius-2xl)]" style={{
|
||||
transform: 'translate3d(0, 0, 0)'
|
||||
}}>
|
||||
<div className="flex items-center justify-between">
|
||||
|
||||
+17
-17
@@ -70,7 +70,7 @@ function PlayerContent() {
|
||||
setCurrentEpisode(index);
|
||||
setPlayUrl(episode.url);
|
||||
setVideoError('');
|
||||
|
||||
|
||||
// Update URL to reflect current episode
|
||||
const params = new URLSearchParams(searchParams.toString());
|
||||
params.set('episode', index.toString());
|
||||
@@ -81,24 +81,24 @@ function PlayerContent() {
|
||||
<div className="min-h-screen bg-[var(--bg-color)]">
|
||||
{/* Glass Navbar */}
|
||||
<nav className="sticky top-0 z-50 pt-4 pb-2 px-4" style={{ transform: 'translateZ(0)' }}>
|
||||
<div className="max-w-7xl mx-auto bg-[var(--glass-bg)] backdrop-blur-[25px] saturate-[180%] border border-[var(--glass-border)] rounded-[var(--radius-2xl)] shadow-[0_4px_12px_color-mix(in_srgb,var(--shadow-color)_40%,transparent)] px-4 sm:px-6 py-4">
|
||||
<div className="max-w-7xl mx-auto bg-[var(--glass-bg)] border border-[var(--glass-border)] rounded-[var(--radius-2xl)] shadow-[var(--shadow-sm)] px-4 sm:px-6 py-4">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<div className="flex items-center gap-2 sm:gap-4 min-w-0">
|
||||
<button
|
||||
<button
|
||||
onClick={() => router.push('/')}
|
||||
className="flex items-center justify-center hover:opacity-80 transition-opacity flex-shrink-0"
|
||||
title="返回首页"
|
||||
>
|
||||
<Image
|
||||
src="/icon.png"
|
||||
alt="KVideo"
|
||||
width={40}
|
||||
<Image
|
||||
src="/icon.png"
|
||||
alt="KVideo"
|
||||
width={40}
|
||||
height={40}
|
||||
className="object-contain"
|
||||
/>
|
||||
</button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => router.back()}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
@@ -120,10 +120,10 @@ function PlayerContent() {
|
||||
<p className="text-[var(--text-color-secondary)]">正在加载视频详情...</p>
|
||||
</div>
|
||||
) : videoError && !videoData ? (
|
||||
<PlayerError
|
||||
error={videoError}
|
||||
onBack={() => router.back()}
|
||||
onRetry={fetchVideoDetails}
|
||||
<PlayerError
|
||||
error={videoError}
|
||||
onBack={() => router.back()}
|
||||
onRetry={fetchVideoDetails}
|
||||
/>
|
||||
) : (
|
||||
<div className="grid lg:grid-cols-3 gap-6">
|
||||
@@ -135,10 +135,10 @@ function PlayerContent() {
|
||||
currentEpisode={currentEpisode}
|
||||
onBack={() => router.back()}
|
||||
/>
|
||||
<VideoMetadata
|
||||
videoData={videoData}
|
||||
source={source}
|
||||
title={title}
|
||||
<VideoMetadata
|
||||
videoData={videoData}
|
||||
source={source}
|
||||
title={title}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ export default function SettingsPage() {
|
||||
|
||||
useEffect(() => {
|
||||
const settings = settingsStore.getSettings();
|
||||
setSources(settings.sources);
|
||||
setSources(settings.sources || []);
|
||||
setSortBy(settings.sortBy);
|
||||
}, []);
|
||||
|
||||
@@ -90,7 +90,7 @@ export default function SettingsPage() {
|
||||
返回上一页
|
||||
</button>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-12 h-12 flex items-center justify-center rounded-[var(--radius-2xl)] bg-[var(--glass-bg)] backdrop-blur-md border border-[var(--glass-border)]">
|
||||
<div className="w-12 h-12 flex items-center justify-center rounded-[var(--radius-2xl)] bg-[var(--glass-bg)] border border-[var(--glass-border)]">
|
||||
<svg className="w-6 h-6 text-[var(--text-color)]" viewBox="0 -960 960 960" fill="currentColor">
|
||||
<path d="m370-80-16-128q-13-5-24.5-12T307-235l-119 50L78-375l103-78q-1-7-1-13.5v-27q0-6.5 1-13.5L78-585l110-190 119 50q11-8 23-15t24-12l16-128h220l16 128q13 5 24.5 12t22.5 15l119-50 110 190-103 78q1 7 1 13.5v27q0 6.5-2 13.5l103 78-110 190-118-50q-11 8-23 15t-24 12L590-80H370Zm70-80h79l14-106q31-8 57.5-23.5T639-327l99 41 39-68-86-65q5-14 7-29.5t2-31.5q0-16-2-31.5t-7-29.5l86-65-39-68-99 42q-22-23-48.5-38.5T533-694l-13-106h-79l-14 106q-31 8-57.5 23.5T321-633l-99-41-39 68 86 64q-5 15-7 30t-2 32q0 16 2 31t7 30l-86 65 39 68 99-42q22 23 48.5 38.5T427-266l13 106Zm42-180q58 0 99-41t41-99q0-58-41-99t-99-41q-59 0-99.5 41T342-480q0 58 40.5 99t99.5 41Zm-2-140Z" />
|
||||
</svg>
|
||||
@@ -103,7 +103,7 @@ export default function SettingsPage() {
|
||||
</div>
|
||||
|
||||
{/* Source Management */}
|
||||
<div className="bg-[var(--glass-bg)] backdrop-blur-md border border-[var(--glass-border)] rounded-[var(--radius-2xl)] shadow-[var(--shadow-md)] p-6 mb-6">
|
||||
<div className="bg-[var(--glass-bg)] border border-[var(--glass-border)] rounded-[var(--radius-2xl)] shadow-[var(--shadow-sm)] p-6 mb-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h2 className="text-xl font-semibold text-[var(--text-color)]">视频源管理</h2>
|
||||
<div className="flex gap-2">
|
||||
@@ -139,7 +139,7 @@ export default function SettingsPage() {
|
||||
</div>
|
||||
|
||||
{/* Sort Options */}
|
||||
<div className="bg-[var(--glass-bg)] backdrop-blur-md border border-[var(--glass-border)] rounded-[var(--radius-2xl)] shadow-[var(--shadow-md)] p-6 mb-6">
|
||||
<div className="bg-[var(--glass-bg)] border border-[var(--glass-border)] rounded-[var(--radius-2xl)] shadow-[var(--shadow-sm)] p-6 mb-6">
|
||||
<h2 className="text-xl font-semibold text-[var(--text-color)] mb-4">搜索结果排序</h2>
|
||||
<p className="text-sm text-[var(--text-color-secondary)] mb-4">
|
||||
选择搜索结果的默认排序方式
|
||||
@@ -161,7 +161,7 @@ export default function SettingsPage() {
|
||||
</div>
|
||||
|
||||
{/* Data Management */}
|
||||
<div className="bg-[var(--glass-bg)] backdrop-blur-md border border-[var(--glass-border)] rounded-[var(--radius-2xl)] shadow-[var(--shadow-md)] p-6">
|
||||
<div className="bg-[var(--glass-bg)] border border-[var(--glass-border)] rounded-[var(--radius-2xl)] shadow-[var(--shadow-sm)] p-6">
|
||||
<h2 className="text-xl font-semibold text-[var(--text-color)] mb-4">数据管理</h2>
|
||||
<div className="space-y-3">
|
||||
<button
|
||||
|
||||
@@ -31,6 +31,10 @@ export const MovieCard = memo(function MovieCard({ movie, onMovieClick }: MovieC
|
||||
onMovieClick(movie);
|
||||
}}
|
||||
className="group cursor-pointer"
|
||||
style={{
|
||||
contain: 'layout style paint',
|
||||
contentVisibility: 'auto'
|
||||
}}
|
||||
>
|
||||
<Card hover className="overflow-hidden p-0 h-full" blur={false}>
|
||||
<div className="relative aspect-[2/3] overflow-hidden bg-[var(--glass-bg)] rounded-[var(--radius-2xl)]">
|
||||
|
||||
+17
-10
@@ -4,9 +4,9 @@
|
||||
|
||||
import type { VideoSource } from '@/lib/types';
|
||||
|
||||
export type SortOption =
|
||||
export type SortOption =
|
||||
| 'default'
|
||||
| 'relevance'
|
||||
| 'relevance'
|
||||
| 'latency-asc'
|
||||
| 'date-desc'
|
||||
| 'date-asc'
|
||||
@@ -102,7 +102,14 @@ export const settingsStore = {
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(stored);
|
||||
const parsed = JSON.parse(stored);
|
||||
// Validate that parsed data has all required properties
|
||||
return {
|
||||
sources: Array.isArray(parsed.sources) ? parsed.sources : getDefaultSources(),
|
||||
sortBy: parsed.sortBy || 'default',
|
||||
searchHistory: parsed.searchHistory !== undefined ? parsed.searchHistory : true,
|
||||
watchHistory: parsed.watchHistory !== undefined ? parsed.watchHistory : true,
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
sources: getDefaultSources(),
|
||||
@@ -128,7 +135,7 @@ export const settingsStore = {
|
||||
if (includeHistory && typeof window !== 'undefined') {
|
||||
const searchHistory = localStorage.getItem(SEARCH_HISTORY_KEY);
|
||||
const watchHistory = localStorage.getItem(WATCH_HISTORY_KEY);
|
||||
|
||||
|
||||
if (searchHistory) exportData.searchHistory = JSON.parse(searchHistory);
|
||||
if (watchHistory) exportData.watchHistory = JSON.parse(watchHistory);
|
||||
}
|
||||
@@ -139,19 +146,19 @@ export const settingsStore = {
|
||||
importSettings(jsonString: string): boolean {
|
||||
try {
|
||||
const data = JSON.parse(jsonString);
|
||||
|
||||
|
||||
if (data.settings) {
|
||||
this.saveSettings(data.settings);
|
||||
}
|
||||
|
||||
|
||||
if (data.searchHistory && typeof window !== 'undefined') {
|
||||
localStorage.setItem(SEARCH_HISTORY_KEY, JSON.stringify(data.searchHistory));
|
||||
}
|
||||
|
||||
|
||||
if (data.watchHistory && typeof window !== 'undefined') {
|
||||
localStorage.setItem(WATCH_HISTORY_KEY, JSON.stringify(data.watchHistory));
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
@@ -163,12 +170,12 @@ export const settingsStore = {
|
||||
localStorage.removeItem(SETTINGS_KEY);
|
||||
localStorage.removeItem(SEARCH_HISTORY_KEY);
|
||||
localStorage.removeItem(WATCH_HISTORY_KEY);
|
||||
|
||||
|
||||
// Clear all cookies
|
||||
document.cookie.split(";").forEach((c) => {
|
||||
document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/");
|
||||
});
|
||||
|
||||
|
||||
// Clear cache if available
|
||||
if ('caches' in window) {
|
||||
caches.keys().then((names) => {
|
||||
|
||||
Reference in New Issue
Block a user