diff --git a/html/src/app.js b/html/src/app.js index 8b82eed0..c5932508 100644 --- a/html/src/app.js +++ b/html/src/app.js @@ -329,8 +329,8 @@ speechSynthesis.getVoices(); console.error('API.$on(USER) invalid args', args); return; } - $app.updateFriend({ id: args.json.id, state: args.json.state }); - args.ref = this.applyUser(args.json); + $app.updateFriend({ id: args.json.id, state: args.json.state }); // online/offline + args.ref = this.applyUser(args.json); // GPS }); API.$on('USER:LIST', function (args) { @@ -1355,47 +1355,6 @@ speechSynthesis.getVoices(); userId: json.id } }); - - // we don't update friend state here, it's not reliable - var state = 'offline'; - if (json.platform === 'web') { - state = 'active'; - } else if (json.platform) { - state = 'online'; - } - var ref = $app.friends.get(json.id); - if (ref?.state !== state) { - if ($app.debugFriendState) { - console.log( - `Bulk friend fetch, friend state does not match ${json.displayName} from ${ref?.state} to ${state}`, - json - ); - } - this.getUser({ - userId: json.id - }); - } else if (json.location === 'traveling') { - if ($app.debugFriendState) { - console.log( - 'Bulk friend fetch, fetching traveling user', - json - ); - } - this.getUser({ - userId: json.id - }); - } - - // if ( - // !args.params.offline && - // json.platform !== 'web' && - // json.location === 'offline' - // ) { - // console.log('Fetching offline user', json); - // this.getUser({ - // userId: json.id - // }); - // } } }); @@ -1404,9 +1363,18 @@ speechSynthesis.getVoices(); API.refreshFriends = async function () { this.isRefreshFriendsLoading = true; try { - var onlineFriends = await this.refreshOnlineFriends(); - var offlineFriends = await this.refreshOfflineFriends(); + var onlineFriends = await this.bulkRefreshFriends({ + offline: false + }); + var offlineFriends = await this.bulkRefreshFriends({ + offline: true + }); var friends = onlineFriends.concat(offlineFriends); + friends = await this.refetchBrokenFriends(friends); + if (!$app.friendLogInitStatus) { + friends = await this.refreshRemainingFriends(friends); + } + this.isRefreshFriendsLoading = false; return friends; } catch (err) { @@ -1415,18 +1383,14 @@ speechSynthesis.getVoices(); } }; - API.refreshOnlineFriends = async function () { + API.bulkRefreshFriends = async function (params) { var friends = []; var params = { + ...params, n: 50, - offset: 0, - offline: false + offset: 0 }; - var N = - this.currentUser.onlineFriends.length + - this.currentUser.activeFriends.length; - var count = Math.trunc(N / 50); - mainLoop: for (var i = count; i > -1; i--) { + mainLoop: for (var i = 100; i > -1; i--) { if (params.offset > 5000) { // API offset limit is 5000 break; @@ -1436,6 +1400,9 @@ speechSynthesis.getVoices(); try { var args = await this.getFriends(params); friends = friends.concat(args.json); + if (!args.json || args.json.length < 50) { + break mainLoop; + } break retryLoop; } catch (err) { console.error(err); @@ -1460,48 +1427,60 @@ speechSynthesis.getVoices(); return friends; }; - API.refreshOfflineFriends = async function () { - var friends = []; - var params = { - n: 50, - offset: 0, - offline: true - }; - var onlineCount = - this.currentUser.onlineFriends.length + - this.currentUser.activeFriends.length; - var N = this.currentUser.friends.length - onlineCount; - var count = Math.trunc(N / 50); - mainLoop: for (var i = count; i > -1; i--) { - if (params.offset > 5000) { - // API offset limit is 5000 - break; - } - retryLoop: for (var j = 0; j < 10; j++) { - // handle 429 ratelimit error, retry 10 times + API.refreshRemainingFriends = async function (friends) { + for (var userId of this.currentUser.friends) { + if (!friends.some((x) => x.id === userId)) { try { - var args = await this.getFriends(params); - friends = friends.concat(args.json); - break retryLoop; + console.log('Fetching remaining friend', userId); + var args = await this.getUser({ userId }); + friends.push(args.json); } catch (err) { console.error(err); - if (!API.currentUser.isLoggedIn) { - console.error(`User isn't logged in`); - break mainLoop; - } - if (err?.message?.includes('Not Found')) { - console.error('Awful workaround for awful VRC API bug'); - break retryLoop; - } - if (j === 9) { - throw err; - } - await new Promise((resolve) => { - workerTimers.setTimeout(resolve, 5000); - }); } } - params.offset += 50; + } + return friends; + }; + + API.refetchBrokenFriends = async function (friends) { + // attempt to broken data from bulk friend fetch + for (var i = 0; i < friends.length; i++) { + var friend = friends[i]; + try { + // we don't update friend state here, it's not reliable + var state = 'offline'; + if (friend.platform === 'web') { + state = 'active'; + } else if (friend.platform) { + state = 'online'; + } + var ref = $app.friends.get(friend.id); + if (ref?.state !== state) { + if ($app.debugFriendState) { + console.log( + `Refetching friend state it does not match ${friend.displayName} from ${ref?.state} to ${state}`, + friend + ); + } + var args = await this.getUser({ + userId: friend.id + }); + friends[i] = args.json; + } else if (friend.location === 'traveling') { + if ($app.debugFriendState) { + console.log( + 'Refetching traveling friend', + friend.displayName + ); + } + var args = await this.getUser({ + userId: friend.id + }); + friends[i] = args.json; + } + } catch (err) { + console.error(err); + } } return friends; }; @@ -5495,6 +5474,7 @@ speechSynthesis.getVoices(); $app.applyGroupDialogInstances(); } if ( + !props.state && props.location && props.location[0] !== 'offline' && props.location[0] !== '' && @@ -5506,7 +5486,7 @@ speechSynthesis.getVoices(); var previousLocation = props.location[1]; var newLocation = props.location[0]; var time = props.location[2]; - if (previousLocation === 'traveling') { + if (previousLocation === 'traveling' && ref.$previousLocation) { previousLocation = ref.$previousLocation; var travelTime = Date.now() - ref.$travelingToTime; time -= travelTime; @@ -6877,8 +6857,8 @@ speechSynthesis.getVoices(); this.updateFriendship(ref); } } - if (typeof API.currentUser.friends !== 'undefined') { - this.updateFriendships(API.currentUser); + if (typeof currentUser.friends !== 'undefined') { + this.updateFriendships(currentUser); } };