Skip to content

Commit 4cad3b4

Browse files
authored
Merge pull request #724 from WatchItDev/next
Next
2 parents 237d9ab + 8b831d0 commit 4cad3b4

File tree

3 files changed

+97
-86
lines changed

3 files changed

+97
-86
lines changed

src/components/login-modal/modal.tsx

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ export interface LoginModalProps {
1616
}
1717

1818
export const LoginModal: React.FC<LoginModalProps> = ({ open, onClose }) => {
19-
const { session, isAuthLoading: accountLoading } = useAuth();
20-
const { login, logout, syncAddress } = useAccountSession();
19+
const { session } = useAuth();
20+
const { login, logout, syncAddress, loading: sessionLoading } = useAccountSession();
2121
const [showForm, setShowForm] = useState(false);
2222
const loginTriggered = useRef(false);
2323

@@ -47,30 +47,25 @@ export const LoginModal: React.FC<LoginModalProps> = ({ open, onClose }) => {
4747
}, [open, session]);
4848

4949
useEffect(() => {
50+
if (sessionLoading) return;
51+
5052
if (session.user) {
51-
setShowForm(false);
5253
onClose();
53-
} else if (session.address && !session.user) {
54+
} else if (session.address) {
5455
setShowForm(true);
5556
}
56-
}, [session]);
57-
58-
const handleSuccess = () => {
59-
syncAddress();
60-
}
57+
}, [sessionLoading, session]);
6158

62-
const handleCancel = () => {
63-
logout();
64-
onClose();
65-
}
59+
const handleSuccess = () => syncAddress();
60+
const handleCancel = () => { logout(); onClose(); };
6661

6762
return (
6863
<Modal
6964
sx={{ overflow: 'scroll', display: open ? 'flex' : 'none' }}
7065
open={open}
7166
onClose={onClose}
7267
closeAfterTransition
73-
disableScrollLock={true}
68+
disableScrollLock
7469
BackdropComponent={Backdrop}
7570
BackdropProps={{ timeout: 500, onClick: handleCancel }}
7671
>
@@ -90,13 +85,13 @@ export const LoginModal: React.FC<LoginModalProps> = ({ open, onClose }) => {
9085
overflow: 'auto',
9186
}}
9287
>
93-
{accountLoading && (
88+
{sessionLoading && (
9489
<Box display="flex" justifyContent="center" alignItems="center" height={200}>
9590
<WatchitLoader />
9691
</Box>
9792
)}
9893

99-
{!accountLoading && showForm && session.address && (
94+
{!sessionLoading && showForm && session.address && (
10095
<ProfileFormView
10196
onSuccess={handleSuccess}
10297
onCancel={handleCancel}

src/components/publication-detail-main/index.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,13 @@ import { useAuth } from '@src/hooks/use-auth.ts';
5151
import { useToggleBookmark } from '@src/hooks/use-toggle-bookmark';
5252
import {
5353
useHidePostMutation,
54-
useGetIsPostLikedQuery,
54+
useGetIsPostLikedLazyQuery,
5555
useTogglePostLikeMutation,
5656
} from '@src/graphql/generated/hooks.tsx';
5757
import { resolveSrc } from '@src/utils/image.ts';
5858
import { useBookmarks } from '@src/hooks/use-bookmark.ts';
5959
import { RootState } from '@redux/store.ts';
60+
import { decrementCounterLikes, incrementCounterLikes, setCounterLikes } from '@redux/comments';
6061

6162
// ----------------------------------------------------------------------
6263

@@ -72,7 +73,8 @@ export default function PublicationDetailMain({
7273
const [openConfirmModal, setOpenConfirmModal] = useState(false);
7374
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
7475
const [hasLiked, setHasLiked] = useState(false);
75-
const [likesCount, setLikesCount] = useState(post.likeCount);
76+
const likesCount = useSelector((s: RootState) => s.comments.counterLikes[post.id] ?? post.likeCount);
77+
const counters = useSelector((s: RootState) => s.comments.counterLikes);
7678

7779
const router = useRouter();
7880
const theme = useTheme();
@@ -81,7 +83,7 @@ export default function PublicationDetailMain({
8183
const [ hidePost ] = useHidePostMutation();
8284
const { sendNotification } = useNotifications();
8385
const { generatePayload } = useNotificationPayload(sessionData);
84-
const { data: postLikedData, loading: postLikedLoading } = useGetIsPostLikedQuery({ variables: { postId: post.id } })
86+
const [getIsPostLiked, { data: postLikedData, loading: postLikedLoading }] = useGetIsPostLikedLazyQuery()
8587
const [ togglePostLike, { loading: togglePostLikeLoading } ] = useTogglePostLikeMutation()
8688
const { has, loading: loadingList } = useBookmarks();
8789
const { toggle, loading: loadingToggle } = useToggleBookmark();
@@ -119,8 +121,11 @@ export default function PublicationDetailMain({
119121
}
120122
});
121123

122-
setHasLiked(res?.data?.togglePostLike ?? false); // Toggle the UI based on the reaction state
123-
setLikesCount(res?.data?.togglePostLike ? likesCount + 1 : likesCount - 1); // Update the likes count
124+
const isLiked = res?.data?.togglePostLike ?? false;
125+
126+
setHasLiked(isLiked);
127+
dispatch(isLiked ? incrementCounterLikes(post.id) : decrementCounterLikes(post.id));
128+
124129
// Send notification to the author when not already liked
125130
if (res?.data?.togglePostLike) {
126131
sendNotification(post.author.address, sessionData?.user?.address ?? '', payloadForNotification);
@@ -134,6 +139,13 @@ export default function PublicationDetailMain({
134139
setHasLiked(postLikedData?.getIsPostLiked ?? false);
135140
}, [postLikedData]);
136141

142+
useEffect(() => {
143+
getIsPostLiked({ variables: { postId: post.id }, fetchPolicy: 'network-only' });
144+
if (post.likeCount !== undefined) {
145+
dispatch(setCounterLikes({ publicationId: post.id, likes: post.likeCount }));
146+
}
147+
}, [post.likeCount, post.id]);
148+
137149
const handleHide = async () => {
138150
await hidePost({ variables: { postId: post.id } });
139151
router.reload();

src/hooks/use-account-session.ts

Lines changed: 69 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -21,32 +21,55 @@ import { ADAPTER_EVENTS } from '@web3auth/base';
2121

2222
// LOCAL IMPORTS
2323
import { useAuth } from '@src/hooks/use-auth';
24-
import { ensureAAReady } from '@src/utils/wallet.ts';
24+
import { ensureAAReady } from '@src/utils/wallet';
2525
import { useWeb3Auth } from '@src/hooks/use-web3-auth';
2626
import { useGetUserLazyQuery } from '@src/graphql/generated/hooks';
2727

2828
interface UseAccountSessionHook {
29-
login: () => Promise<void>;
30-
logout: (silent?: boolean) => Promise<void>;
31-
syncAddress: () => Promise<void>;
32-
refreshUser: () => Promise<void>;
33-
loading: boolean;
29+
login: () => Promise<void>;
30+
logout: () => Promise<void>;
31+
syncAddress: () => Promise<void>;
32+
refreshUser: () => Promise<void>;
33+
loading: boolean;
34+
userChecked: boolean;
3435
}
3536

3637
let listenerAttached = false;
3738
let restoreDone = false;
3839
let loginPerformed = false;
3940

4041
export const useAccountSession = (): UseAccountSessionHook => {
41-
const [bootstrapping, setBootstrapping] = useState(true);
42-
const [loginInProgress, setLoginInProgress] = useState(false);
42+
const { session, isAuthLoading: reduxLoading } = useAuth();
43+
const { web3Auth } = useWeb3Auth();
4344
const dispatch = useDispatch();
44-
const { web3Auth, bundlerClient, smartAccount } = useWeb3Auth();
45-
const { isAuthLoading: reduxLoading, session } = useAuth();
46-
const [loadUser, { data: userData, loading: apiLoading }] = useGetUserLazyQuery({ fetchPolicy: 'cache-and-network' });
47-
const lastFetchedAddressRef = useRef<Address | undefined>(undefined);
48-
const userAddressRef = useRef<Address | undefined>(undefined);
49-
const sessionRef = useRef(session);
45+
const [loadUser] = useGetUserLazyQuery({ fetchPolicy: 'cache-and-network' });
46+
47+
const [loginInProgress, setLoginInProgress] = useState(false);
48+
const [verifyingUser, setVerifyingUser] = useState(false);
49+
const [userChecked, setUserChecked] = useState(false);
50+
51+
const sessionRef = useRef(session);
52+
const lastVerifiedRef = useRef<Address | null>(null);
53+
const loading = loginInProgress || reduxLoading || verifyingUser;
54+
55+
const mergeSession = (patch: Partial<ReduxSession>) => {
56+
const prev = sessionRef.current;
57+
const derivedAddress = patch.user?.address as Address | undefined;
58+
59+
const next: ReduxSession = {
60+
...prev,
61+
...patch,
62+
address: patch.address ?? prev.address ?? derivedAddress,
63+
authenticated: Boolean(
64+
(patch.address ?? prev.address ?? derivedAddress) &&
65+
(patch.user ?? prev.user)
66+
),
67+
};
68+
69+
if (JSON.stringify(prev) !== JSON.stringify(next)) {
70+
dispatch(setSession({ session: next }));
71+
}
72+
};
5073

5174
const getPrimaryAddress = useCallback(async (): Promise<Address | undefined> => {
5275
const accs = (await web3Auth.provider?.request({ method: 'eth_accounts' })) as string[] | undefined;
@@ -56,46 +79,55 @@ export const useAccountSession = (): UseAccountSessionHook => {
5679
const clearRedux = () => {
5780
dispatch(setBalance({ balance: 0 }));
5881
dispatch(setSession({ session: defaultSession }));
59-
userAddressRef.current = undefined;
60-
lastFetchedAddressRef.current = undefined;
82+
setUserChecked(false);
6183
loginPerformed = false;
6284
};
6385

64-
const mergeSession = (patch: Partial<ReduxSession>) => {
65-
const prev = sessionRef.current;
66-
const next = { ...prev, ...patch };
67-
next.authenticated = Boolean(next.address && next.user);
68-
69-
if (JSON.stringify(next) !== JSON.stringify(prev)) {
70-
dispatch(setSession({ session: next }));
71-
}
72-
};
73-
7486
const syncAddress = async () => {
7587
const address = await getPrimaryAddress();
76-
let { info } = sessionRef.current;
7788
if (!address) throw new Error('No address found');
89+
if (address === lastVerifiedRef.current && userChecked && !verifyingUser) return;
90+
91+
lastVerifiedRef.current = address;
92+
93+
let { info } = sessionRef.current;
7894
if (!info) info = await web3Auth.getUserInfo?.();
7995

8096
mergeSession({ address, info });
81-
loadUser({ variables: { input: { address, idSession: info?.idToken } } });
97+
setVerifyingUser(true);
98+
setUserChecked(false);
99+
100+
const { data } = await loadUser({
101+
variables: { input: { address, idSession: info?.idToken } },
102+
});
103+
if (data?.getUser) {
104+
dispatch(setUser({ user: data.getUser }));
105+
mergeSession({
106+
user: data.getUser,
107+
address: data.getUser.address as Address,
108+
});
109+
}
110+
setVerifyingUser(false);
111+
setUserChecked(true);
82112
};
83113

84114
const refreshUser = async () => {
85115
const address = await getPrimaryAddress();
86116
if (!address) throw new Error('No address found');
87-
const result = await loadUser({ variables: { input: { address } } });
88-
89-
dispatch(setUser({ user: result.data.getUser }));
117+
const { data } = await loadUser({ variables: { input: { address } } });
118+
if (data?.getUser) {
119+
dispatch(setUser({ user: data.getUser }));
120+
mergeSession({ user: data.getUser });
121+
}
90122
};
91123

92124
const logout = useCallback(async () => {
93-
if (web3Auth.connected) await web3Auth.logout();
125+
await web3Auth.logout?.();
94126
clearRedux();
127+
restoreDone = false;
95128
}, [web3Auth]);
96129

97130
const login = useCallback(async () => {
98-
if (loginInProgress) return;
99131
if (loginInProgress || loginPerformed) return;
100132

101133
setLoginInProgress(true);
@@ -113,15 +145,9 @@ export const useAccountSession = (): UseAccountSessionHook => {
113145
setLoginInProgress(false);
114146
dispatch(setAuthLoading({ isAuthLoading: false }));
115147
}
116-
}, [web3Auth, bundlerClient, smartAccount, loginInProgress]);
117-
118-
useEffect(() => {
119-
sessionRef.current = session;
120-
}, [session]);
148+
}, [web3Auth, loginInProgress]);
121149

122-
useEffect(() => {
123-
userAddressRef.current = session.user ? session.address : undefined;
124-
}, [session.user, session.address]);
150+
useEffect(() => { sessionRef.current = session }, [session]);
125151

126152
useEffect(() => {
127153
if (!web3Auth || restoreDone) return;
@@ -134,8 +160,6 @@ export const useAccountSession = (): UseAccountSessionHook => {
134160
}
135161
} catch {
136162
await logout();
137-
} finally {
138-
setBootstrapping(false);
139163
}
140164
})();
141165
}, [logout]);
@@ -152,27 +176,7 @@ export const useAccountSession = (): UseAccountSessionHook => {
152176
web3Auth.off(ADAPTER_EVENTS.CONNECTED, syncAddress);
153177
listenerAttached = false;
154178
};
155-
}, [logout]);
156-
157-
useEffect(() => {
158-
if (userData?.getUser) {
159-
const address = sessionRef.current.address as Address;
179+
}, [web3Auth, logout]);
160180

161-
if (!address) { return; }
162-
163-
if (userAddressRef.current !== address) {
164-
userAddressRef.current = address;
165-
dispatch(setUser({ user: userData.getUser }));
166-
mergeSession({ user: userData.getUser });
167-
}
168-
}
169-
}, [userData]);
170-
171-
return {
172-
login,
173-
logout,
174-
syncAddress,
175-
refreshUser,
176-
loading: bootstrapping || reduxLoading || apiLoading || loginInProgress,
177-
};
181+
return { login, logout, syncAddress, refreshUser, loading, userChecked };
178182
};

0 commit comments

Comments
 (0)