From a503686954931ad7943f498c32373a69a89e8ee6 Mon Sep 17 00:00:00 2001 From: vidvidvid Date: Sun, 27 Apr 2025 11:18:11 +0200 Subject: [PATCH 1/2] fix light mode connection fix rename fix fix rename --- src/app/globals.css | 10 ---- src/app/page.tsx | 8 +-- src/components/chat/ChatLayout.tsx | 4 +- src/components/chat/RootLayout.tsx | 4 +- src/components/header/theme-toggle.tsx | 12 ++++- ...nectedMessage.tsx => DisconnectedCard.tsx} | 26 ++++----- src/components/shared/MatrixCanvas.tsx | 7 +-- src/components/shared/WalletGuard.tsx | 13 ++++- src/components/shared/Web3Provider.tsx | 23 +++++--- src/contexts/theme-context.tsx | 53 +------------------ src/contexts/user-context.tsx | 5 +- src/hooks/useDisconnectedDarkMode.ts | 27 ---------- 12 files changed, 64 insertions(+), 128 deletions(-) rename src/components/shared/{DIsconnectedMessage.tsx => DisconnectedCard.tsx} (85%) delete mode 100644 src/hooks/useDisconnectedDarkMode.ts diff --git a/src/app/globals.css b/src/app/globals.css index dc0cf2bf..f18000e7 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -150,16 +150,6 @@ text-decoration: none; } - /* Removed macOS day/night mode detection to use our app's theme setting exclusively */ -} - -/* Custom styling for AppKit button text */ -:root:not(.dark) appkit-button wui-text[variant="paragraph-600"] { - color: #333333 !important; -} - -:root:not(.dark) appkit-button { - --wui-color-inherit: #333333 !important; } @layer base { diff --git a/src/app/page.tsx b/src/app/page.tsx index 2005cee8..15bb4bd3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -5,11 +5,9 @@ import * as React from "react"; import { useAccount } from "wagmi"; import { RootLayout } from "@/components/chat/RootLayout"; -import { DisconnectedMessage } from "@/components/shared/DIsconnectedMessage"; +import { DisconnectedCard } from "@/components/shared/DisconnectedCard"; import MatrixCanvas from "@/components/shared/MatrixCanvas"; -import { useDisconnectedDarkMode } from "@/hooks/useDisconnectedDarkMode"; - import { useChat } from "@/contexts/chat-context"; export default function HomePage() { @@ -20,8 +18,6 @@ export default function HomePage() { handleNavigateToRoot(); }, []); - useDisconnectedDarkMode(isConnected); - return ( <>
@@ -29,7 +25,7 @@ export default function HomePage() { {!isConnected && ( <> - + )} diff --git a/src/components/chat/ChatLayout.tsx b/src/components/chat/ChatLayout.tsx index c78d8f9d..fd12fc90 100644 --- a/src/components/chat/ChatLayout.tsx +++ b/src/components/chat/ChatLayout.tsx @@ -9,7 +9,7 @@ import { Loader2 } from "lucide-react"; import ChatInput from "@/components/chat/chat-input"; import { Messages } from "@/components/chat/messages"; -import { ChatDisconnectedMessage } from "@/components/shared/DIsconnectedMessage"; +import { ChatDisconnectedCard } from "@/components/shared/DisconnectedCard"; import { useLayoutState } from "@/hooks/useLayoutState"; @@ -68,7 +68,7 @@ export function ChatLayout() { {showDisconnected && (
- +
)} diff --git a/src/components/chat/RootLayout.tsx b/src/components/chat/RootLayout.tsx index ee05ddd3..ec62be8b 100644 --- a/src/components/chat/RootLayout.tsx +++ b/src/components/chat/RootLayout.tsx @@ -7,7 +7,7 @@ import { useAccount } from "wagmi"; import RootChatInput from "@/components/chat/chat-input-root"; import { ExampleQueries } from "@/components/chat/example-queries"; -import { ChatDisconnectedMessage } from "@/components/shared/DIsconnectedMessage"; +import { ChatDisconnectedCard } from "@/components/shared/DisconnectedCard"; import { useChat } from "@/contexts/chat-context"; @@ -47,7 +47,7 @@ export function RootLayout() {
- +
diff --git a/src/components/header/theme-toggle.tsx b/src/components/header/theme-toggle.tsx index f9f88e45..9b84725a 100644 --- a/src/components/header/theme-toggle.tsx +++ b/src/components/header/theme-toggle.tsx @@ -10,7 +10,17 @@ const ThemeToggle = () => { const { theme, setTheme } = useTheme(); const toggleTheme = () => { - setTheme(theme === "light" ? "dark" : "light"); + const newTheme = theme === "light" ? "dark" : "light"; + setTheme(newTheme); + + // Directly apply theme to document element as well for immediate effect + if (newTheme === "dark") { + document.documentElement.classList.add("dark"); + document.documentElement.style.colorScheme = "dark"; + } else { + document.documentElement.classList.remove("dark"); + document.documentElement.style.colorScheme = "light"; + } }; return ( diff --git a/src/components/shared/DIsconnectedMessage.tsx b/src/components/shared/DisconnectedCard.tsx similarity index 85% rename from src/components/shared/DIsconnectedMessage.tsx rename to src/components/shared/DisconnectedCard.tsx index c3a32f57..58c98cdb 100644 --- a/src/components/shared/DIsconnectedMessage.tsx +++ b/src/components/shared/DisconnectedCard.tsx @@ -3,7 +3,7 @@ import Link from "next/link"; import { ConnectKitButton } from "connectkit"; import { RefreshCw, Shield, Sparkles } from "lucide-react"; -export function ChatDisconnectedMessage() { +export function ChatDisconnectedCard() { return (
@@ -41,9 +41,9 @@ export function ChatDisconnectedMessage() { ); } -export function DisconnectedMessage() { +export function DisconnectedCard() { return ( -
+
{[...Array(30)].map((_, i) => (
@@ -109,25 +109,27 @@ export function DisconnectedMessage() {
-

+

Connect your Wallet to access the Terminal. Sign in via Signature to unlock the Matrix.

-
+
- + Secure Connection
-
+
- Premium Access + + Premium Access +
-

+

This signature does not give anyone access to your funds and will not be shared with any third parties. Signing your blockchain address is anonymous and does not compromise your @@ -152,8 +154,8 @@ export function DisconnectedMessage() { Return to Home diff --git a/src/components/shared/MatrixCanvas.tsx b/src/components/shared/MatrixCanvas.tsx index 8bf6b663..ecf9e674 100644 --- a/src/components/shared/MatrixCanvas.tsx +++ b/src/components/shared/MatrixCanvas.tsx @@ -6,10 +6,6 @@ const MatrixCanvas = () => { const canvasRef = useRef(null); useEffect(() => { - // Enforce dark mode on client-side - document.documentElement.classList.add("dark"); - document.body.classList.add("dark"); - const canvas = canvasRef.current; if (!canvas) return; @@ -42,6 +38,7 @@ const MatrixCanvas = () => { } const isDarkMode = document.documentElement.classList.contains("dark"); + console.log("isDarkMode", isDarkMode); ctx.fillStyle = isDarkMode ? "rgba(0, 0, 0, 1)" : "rgba(255, 255, 255, 1)"; ctx.fillRect(0, 0, canvas.width, canvas.height); @@ -49,7 +46,7 @@ const MatrixCanvas = () => { const draw = () => { // Black BG for the canvas with opacity to create trail effect const isDarkMode = document.documentElement.classList.contains("dark"); - + // Theme-aware background - dark in dark mode, white in light mode if (isDarkMode) { ctx.fillStyle = "rgba(0, 0, 0, 0.06)"; // Dark mode: black with opacity diff --git a/src/components/shared/WalletGuard.tsx b/src/components/shared/WalletGuard.tsx index 43c31eb4..45574d74 100644 --- a/src/components/shared/WalletGuard.tsx +++ b/src/components/shared/WalletGuard.tsx @@ -6,6 +6,8 @@ import { usePathname, useRouter } from "next/navigation"; import { useAccount } from "wagmi"; +import { useTheme } from "@/contexts/theme-context"; + // Allow root path and chat paths to be accessed without redirecting const isPublicPath = (path: string) => path === "/" || path.startsWith("/chat/"); @@ -14,6 +16,7 @@ export function WalletGuard({ children }: { children: React.ReactNode }) { const { isConnecting, isConnected } = useAccount(); const router = useRouter(); const pathname = usePathname(); + const { setTheme } = useTheme(); const [isInitialized, setIsInitialized] = useState(false); // Wait for wallet state to be fully determined @@ -28,7 +31,7 @@ export function WalletGuard({ children }: { children: React.ReactNode }) { } }, [isConnecting, isInitialized]); - // Handle redirects + // Handle redirects and theme application useEffect(() => { if ( isInitialized && // Only after initialization @@ -38,7 +41,13 @@ export function WalletGuard({ children }: { children: React.ReactNode }) { ) { router.push("/"); } - }, [isConnected, isConnecting, pathname, router, isInitialized]); + + // Force theme reapplication when connection state changes (especially when connecting) + if (isConnected) { + const savedTheme = localStorage.getItem("theme") || "dark"; + setTheme(savedTheme === "dark" ? "dark" : "light"); + } + }, [isConnected, isConnecting, pathname, router, isInitialized, setTheme]); // During initialization, render children if (!isInitialized || isConnecting) { diff --git a/src/components/shared/Web3Provider.tsx b/src/components/shared/Web3Provider.tsx index e0731289..bba58ca8 100644 --- a/src/components/shared/Web3Provider.tsx +++ b/src/components/shared/Web3Provider.tsx @@ -4,6 +4,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ConnectKitProvider, getDefaultConfig } from "connectkit"; import { WagmiProvider, createConfig, http } from "wagmi"; import { arbitrum, base, mainnet, optimism } from "wagmi/chains"; +import { useTheme } from "@/contexts/theme-context"; // Define custom chains that aren't in wagmi directly const mode = { @@ -90,23 +91,33 @@ const queryClient = new QueryClient(); // Web3 Provider component export const Web3Provider = ({ children }: { children: React.ReactNode }) => { + const { theme } = useTheme(); + const isDarkMode = theme === "dark"; + return ( {children} diff --git a/src/contexts/theme-context.tsx b/src/contexts/theme-context.tsx index 043644bc..64f686e8 100644 --- a/src/contexts/theme-context.tsx +++ b/src/contexts/theme-context.tsx @@ -34,17 +34,6 @@ export const ThemeProvider: React.FC<{ // Apply the theme to the HTML element applyTheme(savedTheme); - - // Update the AppKit theme (if it exists) - try { - // @ts-expect-error - AppKit may not be fully typed - if (window.AppKit && window.AppKit.setThemeMode) { - // @ts-expect-error - AppKit may not be fully typed - window.AppKit.setThemeMode(savedTheme); - } - } catch (error) { - console.error("Failed to update AppKit theme:", error); - } } }, []); @@ -53,17 +42,6 @@ export const ThemeProvider: React.FC<{ setThemeState(newTheme); localStorage.setItem("theme", newTheme); applyTheme(newTheme); - - // Update AppKit theme if available - try { - // @ts-expect-error - AppKit may not be fully typed - if (window.AppKit && window.AppKit.setThemeMode) { - // @ts-expect-error - AppKit may not be fully typed - window.AppKit.setThemeMode(newTheme); - } - } catch (error) { - console.error("Failed to update AppKit theme:", error); - } }; // Apply theme to document @@ -72,6 +50,7 @@ export const ThemeProvider: React.FC<{ if (typeof window === "undefined" || typeof document === "undefined") return; + console.log("theme", theme); if (theme === "dark") { document.documentElement.classList.add("dark"); document.documentElement.style.colorScheme = "dark"; @@ -81,36 +60,6 @@ export const ThemeProvider: React.FC<{ } }; - // Add script to apply theme immediately before React hydration - useEffect(() => { - // Skip server-side rendering - if (typeof window === "undefined" || typeof document === "undefined") - return; - - const existingScript = document.getElementById("theme-script"); - if (!existingScript) { - const script = document.createElement("script"); - script.id = "theme-script"; - script.innerHTML = ` - (function() { - try { - const savedTheme = localStorage.getItem('theme') || '${defaultTheme}'; - if (savedTheme === 'dark') { - document.documentElement.classList.add('dark'); - document.documentElement.style.colorScheme = 'dark'; - } else { - document.documentElement.classList.remove('dark'); - document.documentElement.style.colorScheme = 'light'; - } - } catch (e) { - console.error('Error setting initial theme:', e); - } - })(); - `; - document.head.appendChild(script); - } - }, []); - // Don't render until we have a theme to avoid hydration issues if (theme === undefined) { return <>{children}; diff --git a/src/contexts/user-context.tsx b/src/contexts/user-context.tsx index 93c648fb..cfa482c1 100644 --- a/src/contexts/user-context.tsx +++ b/src/contexts/user-context.tsx @@ -13,7 +13,6 @@ import { useAccount } from "wagmi"; import { supabaseReadOnly } from "@/lib/supabaseClient"; import { UserQuota, getUserProfile } from "@/lib/userManager"; -// Define the shape of the user context interface UserContextType { address: string | undefined; isConnected: boolean; @@ -26,9 +25,9 @@ interface UserContextType { }) | null; isProfileLoading: boolean; + fetchUserProfile: () => Promise; } -// Create context with default values const UserContext = createContext({ address: undefined, isConnected: false, @@ -37,9 +36,9 @@ const UserContext = createContext({ isLoading: true, userProfile: null, isProfileLoading: true, + fetchUserProfile: async () => {}, }); -// Custom hook to use the user context export const useUser = () => useContext(UserContext); interface UserProviderProps { diff --git a/src/hooks/useDisconnectedDarkMode.ts b/src/hooks/useDisconnectedDarkMode.ts deleted file mode 100644 index 8feb3fba..00000000 --- a/src/hooks/useDisconnectedDarkMode.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { useEffect } from "react"; - -/** - * Force dark mode when the user is disconnected from wallet - * Restores original theme preference when reconnected - */ -export function useDisconnectedDarkMode(isConnected: boolean) { - useEffect(() => { - // Only enforce dark mode when disconnected - if (!isConnected) { - // Save the current theme preference - const savedTheme = localStorage.getItem("theme"); - - // Add dark class for disconnected state - document.documentElement.classList.add("dark"); - document.documentElement.style.colorScheme = "dark"; - - // Return cleanup function to restore original theme when connected - return () => { - if (savedTheme === "light") { - document.documentElement.classList.remove("dark"); - document.documentElement.style.colorScheme = "light"; - } - }; - } - }, [isConnected]); -} From 048af2917f3d18e6e7e56445b331c2bf35f60ae3 Mon Sep 17 00:00:00 2001 From: vidvidvid Date: Sun, 27 Apr 2025 11:43:22 +0200 Subject: [PATCH 2/2] cleanup --- src/components/header/theme-toggle.tsx | 9 --------- src/components/shared/WalletGuard.tsx | 15 ++++----------- src/components/shared/Web3Provider.tsx | 21 ++++++++++++++++----- src/contexts/theme-context.tsx | 8 -------- 4 files changed, 20 insertions(+), 33 deletions(-) diff --git a/src/components/header/theme-toggle.tsx b/src/components/header/theme-toggle.tsx index 9b84725a..197207de 100644 --- a/src/components/header/theme-toggle.tsx +++ b/src/components/header/theme-toggle.tsx @@ -12,15 +12,6 @@ const ThemeToggle = () => { const toggleTheme = () => { const newTheme = theme === "light" ? "dark" : "light"; setTheme(newTheme); - - // Directly apply theme to document element as well for immediate effect - if (newTheme === "dark") { - document.documentElement.classList.add("dark"); - document.documentElement.style.colorScheme = "dark"; - } else { - document.documentElement.classList.remove("dark"); - document.documentElement.style.colorScheme = "light"; - } }; return ( diff --git a/src/components/shared/WalletGuard.tsx b/src/components/shared/WalletGuard.tsx index 45574d74..010ce8ec 100644 --- a/src/components/shared/WalletGuard.tsx +++ b/src/components/shared/WalletGuard.tsx @@ -8,7 +8,6 @@ import { useAccount } from "wagmi"; import { useTheme } from "@/contexts/theme-context"; -// Allow root path and chat paths to be accessed without redirecting const isPublicPath = (path: string) => path === "/" || path.startsWith("/chat/"); @@ -19,10 +18,8 @@ export function WalletGuard({ children }: { children: React.ReactNode }) { const { setTheme } = useTheme(); const [isInitialized, setIsInitialized] = useState(false); - // Wait for wallet state to be fully determined useEffect(() => { if (!isConnecting && !isInitialized) { - // Add a small delay to ensure state is fully rehydrated const timer = setTimeout(() => { setIsInitialized(true); }, 500); @@ -31,30 +28,26 @@ export function WalletGuard({ children }: { children: React.ReactNode }) { } }, [isConnecting, isInitialized]); - // Handle redirects and theme application useEffect(() => { if ( - isInitialized && // Only after initialization - !isConnecting && // Not in the process of connecting - !isConnected && // Definitely not connected - !isPublicPath(pathname) // Not on a public path + isInitialized && + !isConnecting && + !isConnected && + !isPublicPath(pathname) ) { router.push("/"); } - // Force theme reapplication when connection state changes (especially when connecting) if (isConnected) { const savedTheme = localStorage.getItem("theme") || "dark"; setTheme(savedTheme === "dark" ? "dark" : "light"); } }, [isConnected, isConnecting, pathname, router, isInitialized, setTheme]); - // During initialization, render children if (!isInitialized || isConnecting) { return <>{children}; } - // After initialization, block if definitely not connected and not on a public path if (!isConnected && !isPublicPath(pathname)) { return null; } diff --git a/src/components/shared/Web3Provider.tsx b/src/components/shared/Web3Provider.tsx index bba58ca8..75ec8033 100644 --- a/src/components/shared/Web3Provider.tsx +++ b/src/components/shared/Web3Provider.tsx @@ -4,6 +4,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ConnectKitProvider, getDefaultConfig } from "connectkit"; import { WagmiProvider, createConfig, http } from "wagmi"; import { arbitrum, base, mainnet, optimism } from "wagmi/chains"; + import { useTheme } from "@/contexts/theme-context"; // Define custom chains that aren't in wagmi directly @@ -93,12 +94,12 @@ const queryClient = new QueryClient(); export const Web3Provider = ({ children }: { children: React.ReactNode }) => { const { theme } = useTheme(); const isDarkMode = theme === "dark"; - + return ( { "--ck-primary-button-background": "#47D8A3", "--ck-primary-button-hover-background": "#3bb990", "--ck-primary-button-color": "#000000", - + // Theme-specific colors "--ck-body-background": isDarkMode ? "#000000" : "#ffffff", "--ck-body-color": isDarkMode ? "#ffffff" : "#111111", "--ck-body-color-muted": isDarkMode ? "#aaaaaa" : "#666666", - "--ck-secondary-button-background": isDarkMode ? "#222222" : "#f0f0f0", + "--ck-secondary-button-background": isDarkMode + ? "#222222" + : "#f0f0f0", "--ck-secondary-button-color": isDarkMode ? "#ffffff" : "#111111", - "--ck-overlay-background": isDarkMode ? "rgba(0, 0, 0, 0.8)" : "rgba(0, 0, 0, 0.4)", + "--ck-overlay-background": isDarkMode + ? "rgba(0, 0, 0, 0.8)" + : "rgba(0, 0, 0, 0.4)", "--ck-focus-color": "#47D8A3", "--ck-border-color": isDarkMode ? "#333333" : "#e0e0e0", + + // Badge styling for "Recent" tag + "--ck-recent-badge-background": isDarkMode ? "#000000" : "#ffffff", + "--ck-recent-badge-color": isDarkMode ? "#47D8A3" : "#118860", + "--ck-recent-badge-border": "none", + "--ck-recent-badge-box-shadow": "none", }} > {children} diff --git a/src/contexts/theme-context.tsx b/src/contexts/theme-context.tsx index 64f686e8..26dd7803 100644 --- a/src/contexts/theme-context.tsx +++ b/src/contexts/theme-context.tsx @@ -21,7 +21,6 @@ export const useTheme = () => useContext(ThemeContext); export const ThemeProvider: React.FC<{ children: React.ReactNode; }> = ({ children }) => { - // Start with undefined to avoid hydration mismatch const [theme, setThemeState] = useState(undefined); // Initialize theme from localStorage on mount @@ -31,26 +30,20 @@ export const ThemeProvider: React.FC<{ const savedTheme = (localStorage.getItem("theme") as Theme) || defaultTheme; setThemeState(savedTheme); - - // Apply the theme to the HTML element applyTheme(savedTheme); } }, []); - // Apply theme changes const setTheme = (newTheme: Theme) => { setThemeState(newTheme); localStorage.setItem("theme", newTheme); applyTheme(newTheme); }; - // Apply theme to document const applyTheme = (theme: Theme) => { - // Skip server-side rendering if (typeof window === "undefined" || typeof document === "undefined") return; - console.log("theme", theme); if (theme === "dark") { document.documentElement.classList.add("dark"); document.documentElement.style.colorScheme = "dark"; @@ -60,7 +53,6 @@ export const ThemeProvider: React.FC<{ } }; - // Don't render until we have a theme to avoid hydration issues if (theme === undefined) { return <>{children}; }