Member location
The member location feature enables you to track where members are within a space, to see which part of your application they’re interacting with. A location could be the form field they have selected, the cell they’re currently editing in a spreadsheet, or the slide they’re viewing within a slide deck. Multiple members can be present in the same location.
Member locations are used to visually display which component other members currently have selected, or are currently active on. Events are emitted whenever a member sets their location, such as when they click on a new cell, or slide. Events are received by members subscribed to location events and the UI component can be highlighted with the active member’s profile data to visually display their location.
Set member location
Use the set()
method to emit a location event in realtime when a member changes their location. This will be received by all location subscribers to inform them of the location change. A location
can be any JSON-serializable object, such as a slide number or element ID.
A member must have been entered into the space to set their location.
The set()
method is commonly combined with addEventListener()
or a React synthetic event, such as onClick
or onHover
.
The following is an example of a member setting their location to a specific slide number, and element on that slide:
await space.locations.set({ slide: '3', component: 'slide-title' });
CopyCopied!
Subscribe to location events
Subscribe to location events by registering a listener. Location events are emitted whenever a member changes location by calling set()
. Use the subscribe()
method on the locations
namespace of the space to receive updates.
All location changes are update
events. When a location update is received, clear the highlight from the UI component of the member’s previousLocation
and add it to currentLocation
.
The following is an example of subscribing to location events:
space.locations.subscribe('update', (locationUpdate) => {
console.log(locationUpdate);
});
CopyCopied!
The following is an example payload of a location event. Information about location is returned in currentLocation
and previousLocation
:
{
"member": {
"clientId": "clemons#142",
"connectionId": "hd9743gjDc",
"isConnected": true,
"profileData": {
"username": "Claire Lemons",
"avatar": "https://slides-internal.com/users/clemons.png"
},
"location": {
"slide": "3",
"component": "slide-title"
},
"lastEvent": {
"name": "update",
"timestamp": 1972395669758
}
},
"previousLocation": {
"slide": "2",
"component": null
},
"currentLocation": {
"slide": "3",
"component": "slide-title"
}
}
CopyCopied!
The following are the properties of a location event payload:
Property | Description | Type |
---|---|---|
member.clientId | The client identifier for the member. | String |
member.connectionId | The unique identifier of the member’s connection. | String |
member.isConnected | Whether the member is connected to Ably or not. | Boolean |
member.lastEvent.name | The most recent event emitted by the member. Will be one of enter , update , present or leave . | String |
member.lastEvent.timestamp | The timestamp of the most recently emitted event. | Number |
member.profileData | The optional profile data associated with the member. | Object |
previousLocation | The previous location of the member. | Object |
currentLocation | The new location of the member. | Object |
Unsubscribe from location events to remove previously registered listeners.
The following is an example of removing a listener for location update events:
space.locations.unsubscribe('update', listener);
CopyCopied!
Or remove all listeners:
space.locations.unsubscribe();
CopyCopied!
Retrieve member locations
Member locations can also be retrieved in one-off calls. These are local calls and retrieve the location of members retained in memory by the SDK.
The following is an example of retrieving a member’s own location:
const myLocation = await space.locations.getSelf();
CopyCopied!
The following is an example payload returned by space.locations.getSelf()
. It will return the properties of the member’s location
:
{
"slide": "3",
"component": "slide-title"
}
CopyCopied!
The following is an example of retrieving the location objects of all members other than the member themselves.
const othersLocations = await space.locations.getOthers();
CopyCopied!
The following is an example payload returned by space.locations.getOthers()
. It will return the properties of all member’s location
by their connectionId
:
{
"xG6H3lnrCn": {
"slide": "1",
"component": "textBox-1"
},
"el29SVLktW": {
"slide": "1",
"component": "image-2"
}
}
CopyCopied!
The following is an example of retrieving the location objects of all members, including the member themselves:
const allLocations = await space.locations.getAll();
CopyCopied!
The following is an example payload returned by space.locations.getAll()
. It will return the properties of all member’s location
by their connectionId
:
{
"xG6H3lnrCn": {
"slide": "1",
"component": "textBox-1"
},
"el29SVLktW": {
"slide": "1",
"component": "image-2"
},
"dieF3291kT": {
"slide": "3",
"component": "slide-title"
}
}
CopyCopied!
Example usage
The following is an example of the steps involved in implementing member locations.
import Spaces from '@ably/spaces';
import { Realtime } from 'ably';
// Import your custom logic for handling member location updates
import updateLocations from '/src/own-logic';
// Create an Ably client
const client = new Realtime({ authUrl: '<authEndpoint>', clientId: '<clientId>' });
// Initialize the Spaces SDK using the Ably client
const spaces = new Spaces(client);
// Create a new space
const space = await spaces.get('board-presentation');
// Enter the space to become a member, passing a nickname
await space.enter({ name: 'Amelie' });
// Listen to member location updates
space.locations.subscribe('update', ({ member, currentLocation, previousLocation }) => {
// Update the UI to reflect member locations when receiving an update by adding a highlight to their currentLocation and removing the one from their previousLocation
updateLocations(member, currentLocation, previousLocation);
});
// Publish the member's location
await space.locations.set({ slide: 0, elementId: 'title' });
CopyCopied!
Member location foundations
The Spaces SDK is built upon existing Ably functionality available in Ably’s Core SDKs. Understanding which core features are used to provide the abstractions in the Spaces SDK enables you to manage space state and build additional functionality into your application.
Member locations build upon the functionality of the Ably Pub/Sub presence feature. Members are entered into the presence set when they enter the space.