# Presence

## Content

`spread-sheets-collaboration`, based on [js-collaboration-presence](/spreadjs/docs/v19/spreadjs-collaboration-server/collaboration-framework/js-collaboration-presence), provides a Presence feature specifically designed for SpreadJS Sheets Collaborative editing scenarios. It supports **real-time display of user presence states** (e.g., cursor position, selection areas), helping users understand the activity status of other collaborators and improving collaboration efficiency. You can associate workbook and Presence using [setPresences](/spreadjs/api/v19/classes/GC.Spread.Sheets.Collaboration.Collaboration#setpresences)/[getPresences](/spreadjs/api/v19/classes/GC.Spread.Sheets.Collaboration.Collaboration#getpresences) or [bindPresence](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/README#bindpresence).

## Core Feature: Real-Time User State Sharing

### Functionality Description

In the active worksheet, real-time rendering of selection areas or selected cells for all collaborating users working on the current active sheet.

* Each user is assigned a unique color, with the username displayed in the top-right corner of the selection area.

![use-presence](https://cdn.mescius.io/document-site-files/images/7719ad0a-f083-46d7-aff6-f63e2e187c15/use-presence.e9da53.png)

### Application Scenarios

* During multi-user editing, users can clearly see the cells or areas others are working on to avoid conflicts.
* Facilitates team coordination, such as real-time visibility of other collaborators’ editing positions in financial spreadsheets.

## Interfaces

### ISelections

The **[ISelections](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/interfaces/ISelections)**[ ](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/interfaces/ISelections)interface defines the structure of an object representing specific selection area information in workbook.

```typescript
//* typedef GC.Spread.Sheets.Collaboration.ISelections
/**
 * @property {GC.Spread.Sheets.Range[]} [selections]
 * @property {string} [sheetId]
 */
export interface ISelections {
    selections?: GC.Spread.Sheets.Range[];
    sheetId?: string;
}
```

**Property Descriptions**

| Property Name | Type | Description |
| ------------- | ---- | ----------- |
| selections (optional) | [GC.Spread.Sheets.Range](/spreadjs/api/v19/classes/GC.Spread.Sheets.Range)[] | All selection areas in SpreadSheets. |
| sheetId (optional) | string | The Sheet ID where the selection areas reside. |

### IStatus

The **[IStatus](/spreadjs/api/v19/modules/GC.Spread.Sheets.Collaboration#istatus)**[ ](/spreadjs/api/v19/modules/GC.Spread.Sheets.Collaboration#istatus)interface defines the structure of all status objects.

```typescript
//* typedef GC.Spread.Sheets.Collaboration.IStatus
/**
 * @property {GC.Spread.Sheets.Collaboration.ISelections} [selections]
 */
export interface IStatus {
    selections?: GC.Spread.Sheets.Collaboration.ISelections;
}
```

**Property Descriptions**

| Property Name | Type | Description |
| ------------- | ---- | ----------- |
| selections | [ISelections](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/interfaces/ISelections) | All selection states. |

### IPresence

The **[IPresence](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/interfaces/IPresence)**[ ](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/interfaces/IPresence)interface defines the structure of a user presence state object in workbook.

```typescript
//* typedef GC.Spread.Sheets.Collaboration.IPresence
/**
 * @property {GC.Spread.Common.IUser} [user]
 * @property {GC.Spread.Sheets.Collaboration.IStatus} [status]
 */
export interface IPresence {
    user: GC.Spread.Common.IUser;
    status: GC.Spread.Sheets.Collaboration.IStatus;
}
```

**Property Descriptions**

| Property Name | Type | Description |
| ------------- | ---- | ----------- |
| user  | [GC.Spread.Common.IUser](/spreadjs/api/v19/interfaces/GC.Spread.Common.IUser) | User object information. |
| status | [GC.Spread.Sheets.Collaboration.IStatus](/spreadjs/api/v19/modules/GC.Spread.Sheets.Collaboration#istatus) | Presence state information. |

### IBindPresenceOptions

The [IBindPresenceOptions ](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/interfaces/IBindPresenceOptions)interface defines the configuration options for [bindPresence](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/README#bindpresence).

```typescript
export interface IBindPresenceOptions {
    onPresencesUpdate?: (presences?: IPresence[]) => void
}
```

**Property Descriptions**

| Property Name | Type | Description |
| ------------- | ---- | ----------- |
| onPresencesUpdate (optional) | (presences?: IPresence[]) => void | Callback method triggered after presence updates via `bindPresence`. |

## Methods

### setPresences

The [setPresences ](/spreadjs/api/v19/classes/GC.Spread.Sheets.Collaboration.Collaboration#setpresences)method updates user presence state information.

```typescript
function setPresences(presences: GC.Spread.Sheets.Collaboration.IPresence[]): void
```

**Parameter**

* **presences (**`GC.Spread.Sheets.Collaboration.IPresence[]`**)**: The user presence states to be set.

**Example**

```typescript
let presences = [{
	user: {
		id: '1',
		name: 'User1',
		color: '#FF0000'
	},
	status: {
		selections: {
			selections: [new GC.Spread.Sheets.Range(0, 0, 1, 1)],
			sheetId: 'vbHbfEVB' //sheet.getId();
		}
	}
}];
spread.collaboration.setPresences(presences);
```

### getPresences

The [getPresences ](/spreadjs/api/v19/classes/GC.Spread.Sheets.Collaboration.Collaboration#getpresences)method get current presences

```typescript
function getPresences(): GC.Spread.Sheets.Collaboration.IPresence[]
```

**Return**

* **presences(**`GC.Spread.Sheets.Collaboration.IPresence[]`): the current presences

**Example**

```typescript
const presences = spread.collaboration.getPresences();
```

### bindPresence

The [bindPresence ](/spreadjs/api/v19/collaboration/spread-sheets-collaboration-client/README#bindpresence)method binds presence and user information and permission info to the current workbook, providing a simpler way to simultaneously bind both presence and user info and permission to the workbook.

```typescript
export interface IUserWithPermission extends GC.Spread.Common.IUser {
    permission?: IPermission;
}
export declare function bindPresence(workbook: any, presence: Presence<IPresence>, user: IUserWithPermission, options?: IBindPresenceOptions): Promise<void>;
```

**Parameters**

* **workbook (**`GC.Spread.Sheets.Workbook`**)**: The Workbook instance.
* **presence (**`IPresence`**)**: The Presence instance.
* **user (**`IUserWithPermission`**)**: User information with permission.
* **options (**`IBindPresenceOptions`**)**: Configuration options for binding user presence states.

**Return**

* **Promise\<void>:** Will return a promise, which will resolve when the bind is complete.

**Example**

```typescript
import { Client } from "@mescius/js-collaboration-client";
import { Presence } from "@mescius/js-collaboration-presence-client";
import { bindPresence, IUserWithPermission } from 'spread-sheets-collaboration-client';

const conn = new Client('ws://localhost:8080/').connect('room1');
const presence = new Presence(conn);

const user:IUserWithPermission = {
    id: '1',
    name: "user1",
    permission: {
        mode: GC.Spread.Sheets.Collaboration.BrowsingMode.edit,
    }
}

bindPresence(workbook, presence, user);
```

## Usage

### Client Side

1. Install Npm Packages

    ```bash
    npm install @mescius/js-collaboration-client @mescius/js-collaboration-presence-client @mescius/spread-sheets-collaboration-client
    ```
2. Create Presence Instance

    ```typescript
    import { Client } from "@mescius/js-collaboration-client";
    import { Presence } from "@mescius/js-collaboration-presence-client";
    
    const conn = new Client('ws://localhost:8080/').connect('room1');
    const presence = new Presence(conn);
    ```
3. Bind Workbook and Presence (without user info)
<br>
    This method does not include user information. If user info is needed, use the approach in Step 4.

    ```typescript
    const presences: IPresence[] = Object.values(presence.otherStates);
    workbook.collaboration.setPresences(presences.map(p => ({ user: p.user, status: p.status })));
    ```
4. Get User Instance and Bind Workbook, Presence, and User

>type=note
> This is an example only. Replace `user` with actual user info from your production environment.

```typescript
import { bindPresence, IUserWithPermission } from 'spread-sheets-collaboration-client';
var seed = new Date().valueOf() + "";
const user: IUserWithPermission = {
    id: seed,
    name: "user" + seed,
    permission: {
        mode: GC.Spread.Sheets.Collaboration.BrowsingMode.edit,
    }
}
bindPresence(workbook, presence, user);
```

### Server Side

The server-side usage aligns with [Presence Server](/spreadjs/docs/v19/spreadjs-collaboration-server/collaboration-framework/js-collaboration-presence/presence-server).