@@ -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