fix viewport following (#1411)

Forgot to port over my fix for viewport following for the new ephemeral
state stuff.

### Change Type

<!-- 💡 Indicate the type of change your pull request is. -->
<!-- 🤷‍♀️ If you're not sure, don't select anything -->
<!-- ✂️ Feel free to delete unselected options -->

<!-- To select one, put an x in the box: [x] -->

- [x] `patch` — Bug Fix
- [ ] `minor` — New Feature
- [ ] `major` — Breaking Change
- [ ] `dependencies` — Dependency Update (publishes a `patch` release,
for devDependencies use `internal`)
- [ ] `documentation` — Changes to the documentation only (will not
publish a new version)
- [ ] `tests` — Changes to any testing-related code only (will not
publish a new version)
- [ ] `internal` — Any other changes that don't affect the published
package (will not publish a new version)

### Test Plan

1. Open a multiplayer room in two different browsers
2. Open the people menu and click the follow button next to the other
user's name.
3. pan and zoom in the viewport of the user being followed
4. the other viewport should follow the same movements
This commit is contained in:
David Sheldrick 2023-05-18 16:19:41 +01:00 committed by GitHub
parent 2a9ff82a70
commit ddca01918f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -8448,20 +8448,12 @@ export class App extends EventEmitter<TLEventMap> {
// Currently, we get the leader's viewport page bounds from their user presence. // Currently, we get the leader's viewport page bounds from their user presence.
// This is a placeholder until the ephemeral PR lands. // This is a placeholder until the ephemeral PR lands.
// After that, we'll be able to get the required data from their instance presence instead. // After that, we'll be able to get the required data from their instance presence instead.
const leaderPresenceRecord = this.store.query.record('user_presence', () => ({ const leaderPresences = this.store.query.records('instance_presence', () => ({
userId: { eq: userId }, userId: { eq: userId },
})) }))
const leaderInstanceRecord = this.store.query.record('instance', () => ({
userId: { eq: userId },
}))
if (!leaderInstanceRecord || !leaderPresenceRecord) {
throw new Error("Couldn't find user to follow")
}
// If the leader is following us, then we can't follow them // If the leader is following us, then we can't follow them
if (leaderInstanceRecord.value?.followingUserId === this.userId) { if (leaderPresences.value.some((p) => p.followingUserId === this.userId)) {
return return
} }
@ -8482,32 +8474,37 @@ export class App extends EventEmitter<TLEventMap> {
const moveTowardsUser = () => { const moveTowardsUser = () => {
// Stop following if we can't find the user // Stop following if we can't find the user
const leaderInstance = leaderInstanceRecord.value const leaderPresence = [...leaderPresences.value]
const leaderPresence = leaderPresenceRecord.value .sort((a, b) => {
if (!leaderInstance || !leaderPresence) { return a.lastActivityTimestamp - b.lastActivityTimestamp
})
.pop()
if (!leaderPresence) {
this.stopFollowingUser() this.stopFollowingUser()
return return
} }
// Change page if leader is on a different page // Change page if leader is on a different page
const isOnSamePage = leaderInstance.currentPageId === this.currentPageId const isOnSamePage = leaderPresence.currentPageId === this.currentPageId
const chaseProportion = isOnSamePage ? FOLLOW_CHASE_PROPORTION : 1 const chaseProportion = isOnSamePage ? FOLLOW_CHASE_PROPORTION : 1
if (!isOnSamePage) { if (!isOnSamePage) {
this.setCurrentPageId(leaderInstance.currentPageId, { stopFollowing: false }) this.setCurrentPageId(leaderPresence.currentPageId, { stopFollowing: false })
} }
// Get the bounds of the follower (me) and the leader (them) // Get the bounds of the follower (me) and the leader (them)
const { center, width, height } = this.viewportPageBounds const { center, width, height } = this.viewportPageBounds
const { const leaderScreen = Box2d.From(leaderPresence.screenBounds)
width: leaderWidth, const leaderWidth = leaderScreen.width / leaderPresence.camera.z
height: leaderHeight, const leaderHeight = leaderScreen.height / leaderPresence.camera.z
center: leaderCenter, const leaderCenter = new Vec2d(
} = Box2d.From(leaderPresence.viewportPageBounds) leaderWidth / 2 - leaderPresence.camera.x,
leaderHeight / 2 - leaderPresence.camera.y
)
// At this point, let's check if we're following someone who's following us. // At this point, let's check if we're following someone who's following us.
// If so, we can't try to contain their entire viewport // If so, we can't try to contain their entire viewport
// because that would become a feedback loop where we zoom, they zoom, etc. // because that would become a feedback loop where we zoom, they zoom, etc.
const isFollowingFollower = leaderInstance.followingUserId === this.userId const isFollowingFollower = leaderPresence.followingUserId === this.userId
// Figure out how much to zoom // Figure out how much to zoom
const desiredWidth = width + (leaderWidth - width) * chaseProportion const desiredWidth = width + (leaderWidth - width) * chaseProportion