From eeca2ec5462d888ca92ed0eb6876484616f3422e Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Bajpai Date: Tue, 16 Jun 2026 17:28:26 +0530 Subject: [PATCH] fix: sync profile avatar across open tabs via localStorage Use the storage event to propagate avatar URL changes to all open tabs. When a user updates their avatar in Profile settings, the new URL is written to localStorage. Other tabs detect the change via the window 'storage' event and update userData state immediately. Closes #550 --- src/context/AuthContext.jsx | 16 +++++++++++++++- src/pages/Profile.jsx | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/context/AuthContext.jsx b/src/context/AuthContext.jsx index 37f962d..875ec54 100644 --- a/src/context/AuthContext.jsx +++ b/src/context/AuthContext.jsx @@ -1,6 +1,6 @@ /* eslint-disable react-refresh/only-export-components */ import { githubFetch, getRateLimitMessage } from "../utils/githubRateLimit"; -import React, { createContext, useContext, useState, useEffect } from "react"; +import React, { createContext, useContext, useState, useEffect, useRef } from "react"; import { onAuthStateChanged, getAdditionalUserInfo, @@ -95,6 +95,18 @@ export const AuthProvider = ({ children }) => { const [loading, setLoading] = useState(auth ? true : false); const [isOnboarding, setIsOnboarding] = useState(false); const [ghAccessToken, setGhAccessToken] = useState(null); + const uidRef = useRef(null); + + // Cross-tab avatar sync: listen for avatar updates from other tabs + useEffect(() => { + const handleStorage = (e) => { + if (e.key?.startsWith('rh_avatar_') && e.newValue && e.key.replace('rh_avatar_', '') === uidRef.current) { + setUserData(prev => prev ? { ...prev, avatar: e.newValue } : prev); + } + }; + window.addEventListener('storage', handleStorage); + return () => window.removeEventListener('storage', handleStorage); + }, []); useEffect(() => { if (!auth) { @@ -169,6 +181,7 @@ export const AuthProvider = ({ children }) => { if (currentUser) { setUser(currentUser); + uidRef.current = currentUser.uid; const userDocRef = doc(db, "users", currentUser.uid); @@ -210,6 +223,7 @@ export const AuthProvider = ({ children }) => { setUserData(null); setIsOnboarding(false); setLoading(false); + uidRef.current = null; } }); diff --git a/src/pages/Profile.jsx b/src/pages/Profile.jsx index 4761e57..8df17b5 100644 --- a/src/pages/Profile.jsx +++ b/src/pages/Profile.jsx @@ -245,6 +245,8 @@ export const Profile = () => { ...updateData })); } + // Sync avatar across open tabs via localStorage + localStorage.setItem(`rh_avatar_${user.uid}`, editAvatar.trim()); setToasts((prev) => [...prev, { id: Date.now() + Math.random(), message: "Profile updated successfully!", type: "success" }]); setIsEditModalOpen(false);