Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MMB-174] Remove named cursors #91

Merged
merged 2 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ space.locations.on('locationUpdate', (locationUpdate) => {
console.log(locationUpdate);
});

// You need to enter a space before setting your location
space.enter({
username: 'Claire Lemons',
avatar: 'https://slides-internal.com/users/clemons.png',
});

// Publish locationUpdate event with a client's location when they select a UI element
space.locations.set({ slide: '3', component: 'slide-title' });

Expand Down Expand Up @@ -187,16 +193,20 @@ The following is an example `locationUpdate` event received by subscribers when
Use the Cursors API to track client pointer events across an application. Events can also include associated data, such as pointer attributes and the IDs of associated UI elements:

```ts
// Register a cursor instance
const demoCursors = space.cursors.get('demoSlideshow-cursors');
// You need to enter a space before setting your cursor updates
space.enter({
username: 'Claire Lemons',
avatar: 'https://slides-internal.com/users/clemons.png',
});

// Publish a CursorUpdate with the location of a mouse, including optional data for the current member
window.addEventListener('mousemove', ({ clientX, clientY }) => {
demoCursors.set({ position: { x: clientX, y: clientY }, data: { color: 'red' } });
space.cursors.set({ position: { x: clientX, y: clientY }, data: { color: 'red' } });
});


// Listen to events published on "mousemove" by all members
demoCursors.on('cursorUpdate', (cursorUpdate) => {
space.cursors.on('cursorsUpdate', (cursorUpdate) => {
console.log(cursorUpdate);
});
```
Expand All @@ -205,7 +215,6 @@ The above listener will receive a `CursorUpdate` event:

```js
{
"name": "demoSlideshow-cursors",
"connectionId": "hd9743gjDc",
"clientId": "clemons#142",
"position": { "x": 864, "y": 32 },
Expand Down
11 changes: 5 additions & 6 deletions demo/app/components/cursors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,9 @@ const attachCursors = (space, slideId) => {
const cursorContainer = queryDataId(slideContainer, 'slide-cursor-container');
cursorContainer.innerHTML = '';

const cursor = space.cursors.get(slideId);
const self = space.getSelf();

cursor.on('cursorUpdate', (update) => {
space.cursors.on('cursorsUpdate', (update) => {
let cursorNode: HTMLElement = slideContainer.querySelector(`#cursor-${update.connectionId}`);

const membersOnSlide = space.getMembers().filter((member) => member.location?.slide === slideId);
Expand All @@ -77,15 +76,15 @@ const attachCursors = (space, slideId) => {
const cursorHandlers = {
enter: (event) => {
const { top, left } = cursorContainer.getBoundingClientRect();
cursor.set({ position: { x: event.clientX - left, y: event.clientY - top }, data: { state: 'enter' } });
space.cursors.set({ position: { x: event.clientX - left, y: event.clientY - top }, data: { state: 'enter' } });
},
move: (event) => {
const { top, left } = cursorContainer.getBoundingClientRect();
cursor.set({ position: { x: event.clientX - left, y: event.clientY - top }, data: { state: 'move' } });
space.cursors.set({ position: { x: event.clientX - left, y: event.clientY - top }, data: { state: 'move' } });
},
leave: (event) => {
const { top, left } = cursorContainer.getBoundingClientRect();
cursor.set({ position: { x: event.clientX - left, y: event.clientY - top }, data: { state: 'leave' } });
space.cursors.set({ position: { x: event.clientX - left, y: event.clientY - top }, data: { state: 'leave' } });
},
tabLeft: (event) => {
if (document.visibilityState === 'hidden') {
Expand All @@ -100,7 +99,7 @@ const attachCursors = (space, slideId) => {
document.addEventListener('visibilitychange', cursorHandlers.tabLeft);

return () => {
cursor.off();
space.cursors.off();
slideContainer.removeEventListener('mouseenter', cursorHandlers.enter);
slideContainer.removeEventListener('mousemove', cursorHandlers.move);
slideContainer.removeEventListener('mouseleave', cursorHandlers.leave);
Expand Down
72 changes: 14 additions & 58 deletions docs/class-definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,38 +330,41 @@ Handles tracking of member cursors within a space. Inherits from [EventEmitter](

## Methods

### get
### set

Set the position of a cursor. This will emit a `CursorUpdate` event. If a member has not yet entered the space, this method will error.

Get or create a named [Cursor](#cursor) instance.
A `CursorUpdate` is an object with 2 properties. `position` is an object with 2 required properties, `x` and `y`. These represent the position of the cursor on a 2D plane. A second optional property, `data` can also be passed. This is an object of any shape and is meant for data associated with the cursor movement (like drag or hover calculation results):

```ts
type get = (cursorName: string) => Cursor;
type set = (update: { position: CursorPosition, data?: CursorData })
```

Example:
Example usage:

```ts
const cursor = space.cursors.get('slidedeck-cursors');
window.addEventListner('mousemove', ({ clientX, clientY }) => {
space.cursors.set({ position: { x: clientX, y: clientY }, data: { color: "red" } });
});
```

### getAll

Get the last position of all cursors in this space, for each connection. Pass a cursor name to only get the last position of cursors that match that name.
Get the last CursorUpdate for each connection.

```ts
type getAll = () => Record<ConnectionId, Record<CursorName, Cursor>>;
type getAll = (cursorName: CursorName) => Record<ConnectionId, Cursor>;
type getAll = () => Record<ConnectionId, CursorUpdate>;
```

Example:

```ts
const lastPositions = space.cursors.getAll('slidedeck-cursors');
const lastPositions = space.cursors.getAll();
```

### on

Listen to events for all named cursors. See [EventEmitter](/docs/usage.md#event-emitters) for overloading usage.
Listen to `CursorUpdate` events. See [EventEmitter](/docs/usage.md#event-emitters) for overloading usage.

Available events:

Expand Down Expand Up @@ -414,51 +417,4 @@ Represent data that can be associated with a cursor update.

```ts
type CursorData = Record<string, unknown>;
```

# Cursor

An instance of a Cursor created using [spaces.cursors.get](#get-1). Inherits from [EventEmitter](/docs/usage.md#event-emitters).

## Properties

### name

Name of the cursor.

```ts
type name = string;
```

## Methods

### set

Set the position of this named cursor.

```ts
type set = (update: { position: CursorPosition, data?: CursorData })
```

### on

Listen to events for the named cursors. See [EventEmitter](/docs/usage.md#event-emitters) for overloading usage.

Available events:

- #### **cursorUpdate**

Emits an event when a new cursor position is set. The argument supplied to the event listener is a [CursorUpdate](#cursorupdate-1).

```ts
const cursor = space.cursors.get('slidedeck-cursors');
cursor.on('cursorUpdate', (cursorUpdate: CursorUpdate) => {});
```

### off

Remove all event listeners, all event listeners for an event, or specific listeners. See [EventEmitter](/docs/usage.md#event-emitters) for detailed usage.

```ts
cursor.off('cursorUpdate');
```
```
83 changes: 23 additions & 60 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,101 +261,64 @@ memberTracker.on((locationUpdate) => {

## Live Cursors

A common feature of collaborative apps is to show where a users cursors is positioned in realtime. It's easy to accomplish this with `cursors` API.
A common feature of collaborative apps is to show where a users cursors is positioned in realtime. It's easy to accomplish this with the `cursors` API.

Unlike a location, you can have multiple cursors. This can be used to represent multiple devices interacting with the UI or different ways of interacting with the browser (like scrolling).
The most common use case is to show the current mouse pointer position.

The most common use case is however to show the current mouse/touchpad position.

To get started, you'll need to get a named cursor instance:

```ts
const cursor = space.cursors.get('slidedeck-cursors');
```

This instance can emit events for [`self`](#members) and listen to all positions emitted for the given named cursor (`mouse`), for all members (including self).

```ts
window.addEventListner('mousemove', ({ clientX, clientY }) => {
cursor.set({ position: { x: clientX, y: clientY } });
});
```

`set` takes an object with 2 properties. `position` is an object with 2 required properties, `x` and `y`. These represent the position of the cursor on a 2D plane. A second property, `data` can passed. This is an object of any shape and is meant for data associated with the cursor movement (like drag or hover calculation results):

```ts
window.addEventListner('mousemove', ({ clientX, clientY }) => {
cursor.set({ position: { x: clientX, y: clientY }, data: '' });
});
```

The cursor instance is an [event emitter](#event-emitters):

```ts
cursor.on('cursorUpdate', (cursorUpdate) => {
console.log(cursorUpdate);
});
```

As is the `cursors` namespace itself, emitting events for all named cursors:
To start listing to cursor events, use the `.on` method:

```ts
space.cursors.on('cursorsUpdate', (cursorUpdate) => {
console.log(cursorUpdate);
});
```

The following is an `cursorUpdate` event received by listeners when a cursor sets their position or data:
The listener will be called with a `CursorUpdate`:

```json
{
"name": "slidedeck-cursors",
"connectionId": "hd9743gjDc",
"clientId": "clemons#142",
"position": { "x": 864, "y": 32 },
"data": { "color": "red" }
}
```

### Inital cursor position and data
To set the position of a cursor and emit a `CursorUpdate`, first enter the space:

To retrieve the initial position and data of all cursors within a space, you can use the `cursors.getAll()` method. This returns an object keyed by `connectionId` and cursor name. The value is the last `cursorUpdate` set by the given `connectionId`.
```ts
space.enter();
```

Example of calling `getAll` to return all cursor positions:
Then call `.set`:

```ts
const lastPositions = await space.cursors.getAll();
window.addEventListner('mousemove', ({ clientX, clientY }) => {
space.cursors.set({ position: { x: clientX, y: clientY } });
});
```

A `CursorUpdate` is an object with 2 properties. `position` is an object with 2 required properties, `x` and `y`. These represent the position of the cursor on a 2D plane. A second optional property, `data` can also be passed. This is an object of any shape and is meant for data associated with the cursor movement (like drag or hover calculation results):

```ts
{
"hd9743gjDc": {
"slidedeck-cursors": {
"name": "slidedeck-cursors",
"connectionId": "hd9743gjDc",
"clientId": "clemons#142",
"position": {
"x": 864,
"y": 32
},
"data": {
"color": "red"
}
}
}
}
window.addEventListner('mousemove', ({ clientX, clientY }) => {
space.cursors.set({ position: { x: clientX, y: clientY }, data: { color: 'red' } });
});
```

Example of calling `getAll` to get the last positions for the named cursor `slidedeck-cursors`:
### Inital cursor position and data

To retrieve the initial position and data of all cursors within a space, you can use the `space.cursors.getAll()` method. This returns an object keyed by `connectionId`. The value is the last `cursorUpdate` set by the given `connectionId`.

Example of calling `getAll()` to return all cursor positions:

```ts
const lastPositions = await space.cursors.getAll('slidedeck-cursors');
const lastPositions = await space.cursors.getAll();
```

```ts
{
"hd9743gjDc": {
"name": "slidedeck-cursors",
"connectionId": "hd9743gjDc",
"clientId": "clemons#142",
"position": {
Expand Down
80 changes: 0 additions & 80 deletions src/Cursor.ts

This file was deleted.

Loading