Skip to content

Commit f15d1ef

Browse files
committed
fix(frontend): refresh user session on launcher startup
1 parent 07058b8 commit f15d1ef

1 file changed

Lines changed: 73 additions & 34 deletions

File tree

frontend/src/components/UserAvatar.tsx

Lines changed: 73 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -33,38 +33,89 @@ export const UserAvatar = () => {
3333
const [refreshing, setRefreshing] = useState(false);
3434
const [open, setOpen] = useState(false);
3535

36+
const clearUserState = React.useCallback(() => {
37+
setGamertag("");
38+
setXuid("");
39+
setAvatar("");
40+
setStats(null);
41+
}, []);
42+
43+
const refreshSessionIfNeeded = React.useCallback(async (force = false) => {
44+
try {
45+
const getState = (userService as any)?.XUserGetState;
46+
const reset = (userService as any)?.ResetSession;
47+
48+
if (typeof reset !== "function") {
49+
return false;
50+
}
51+
52+
let shouldReset = force;
53+
if (!shouldReset && typeof getState === "function") {
54+
const state = await getState();
55+
shouldReset = typeof state === "number" && state !== 0;
56+
}
57+
58+
if (!shouldReset) {
59+
return false;
60+
}
61+
62+
const result = await reset();
63+
if (result) {
64+
console.error("[UserAvatar] ResetSession error", result);
65+
}
66+
return true;
67+
} catch (e) {
68+
console.error("[UserAvatar] refreshSessionIfNeeded error", e);
69+
return false;
70+
}
71+
}, []);
72+
3673
useEffect(() => {
3774
if (!startupInteractive) return;
75+
let cancelled = false;
76+
3877
const fetchUser = async () => {
3978
try {
4079
if (!userService.GetLocalUserId) {
41-
setLoading(false);
4280
return;
4381
}
4482

83+
await refreshSessionIfNeeded();
84+
4585
const id = await userService.GetLocalUserId();
86+
if (cancelled) return;
4687
if (!id) {
47-
setGamertag("");
48-
setXuid("");
49-
setAvatar("");
88+
clearUserState();
5089
return;
5190
}
5291

92+
const [tag, pic] = await Promise.all([
93+
userService.GetLocalUserGamertag(),
94+
userService.GetLocalUserGamerPicture(1).catch((err) => {
95+
console.error("[UserAvatar] GetLocalUserGamerPicture error", err);
96+
return "";
97+
}),
98+
]);
99+
if (cancelled) return;
100+
53101
setXuid(id);
54-
const tag = await userService.GetLocalUserGamertag();
55-
if (!tag) {
56-
setGamertag("");
57-
return;
58-
}
59-
setGamertag(tag);
102+
setGamertag(String(tag || ""));
103+
setAvatar(pic ? `data:image/png;base64,${pic}` : "");
104+
setStats(null);
60105
} catch (e) {
61106
console.error("[UserAvatar] fetchUser error", e);
62107
} finally {
63-
setLoading(false);
108+
if (!cancelled) {
109+
setLoading(false);
110+
}
64111
}
65112
};
66-
fetchUser();
67-
}, [reloadNonce, startupInteractive]);
113+
114+
void fetchUser();
115+
return () => {
116+
cancelled = true;
117+
};
118+
}, [clearUserState, refreshSessionIfNeeded, reloadNonce, startupInteractive]);
68119

69120
useEffect(() => {
70121
if (!startupInteractive) return;
@@ -98,7 +149,7 @@ export const UserAvatar = () => {
98149
return () => {
99150
cancelled = true;
100151
};
101-
}, [open, startupInteractive, xuid]);
152+
}, [open, reloadNonce, startupInteractive, xuid]);
102153

103154
if (!startupInteractive || loading) {
104155
return (
@@ -122,9 +173,7 @@ export const UserAvatar = () => {
122173
size="sm"
123174
onPress={() => {
124175
setLoading(true);
125-
setGamertag("");
126-
setXuid("");
127-
setAvatar("");
176+
clearUserState();
128177
setReloadNonce((v) => v + 1);
129178
}}
130179
>
@@ -158,22 +207,15 @@ export const UserAvatar = () => {
158207
setOpen(nextOpen);
159208
if (!nextOpen) return;
160209
try {
161-
const getState = (userService as any)?.XUserGetState;
162-
if (typeof getState === "function") {
163-
const state = await getState();
164-
console.log("[UserAvatar] XUserGetState =>", state);
165-
if (typeof state === "number" && state !== 0) {
166-
setRefreshing(true);
167-
try {
168-
const reset = (userService as any)?.ResetSession;
169-
if (typeof reset === "function") await reset();
170-
} catch {}
171-
setReloadNonce((v) => v + 1);
172-
setRefreshing(false);
173-
}
210+
setRefreshing(true);
211+
const refreshed = await refreshSessionIfNeeded();
212+
if (refreshed) {
213+
setReloadNonce((v) => v + 1);
174214
}
175215
} catch (e) {
176216
console.error("[UserAvatar] XUserGetState error", e);
217+
} finally {
218+
setRefreshing(false);
177219
}
178220
}}
179221
>
@@ -209,10 +251,7 @@ export const UserAvatar = () => {
209251
isLoading={refreshing}
210252
onPress={async () => {
211253
setRefreshing(true);
212-
try {
213-
const reset = (userService as any)?.ResetSession;
214-
if (typeof reset === "function") await reset();
215-
} catch {}
254+
await refreshSessionIfNeeded(true);
216255
setReloadNonce((v) => v + 1);
217256
setRefreshing(false);
218257
}}

0 commit comments

Comments
 (0)