# Presence

## Content

`spread-sheets-collaboration`, based on [js-collaboration-presence](/spreadjs/docs/v18/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/v18/classes/GC.Spread.Sheets.Collaboration.Collaboration#setpresences)/[getPresences](/spreadjs/api/v18/classes/GC.Spread.Sheets.Collaboration.Collaboration#getpresences) or [bindPresence](/spreadjs/api/v18/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.
* User Color Sources (in order of priority, high to low):
    * Color specified in User info
    * Custom `colorScheme`
    * Default color scheme (`['#0000ff', '#008000', '#9900cc', '#800000', '#00cc33', '#cc6600', '#cc0099']`)

![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/v18/collaboration/spread-sheets-collaboration-client/interfaces/ISelections)**[ ](/spreadjs/api/v18/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/v18/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/v18/modules/GC.Spread.Sheets.Collaboration#istatus)**[ ](/spreadjs/api/v18/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 | [GC.SpreadSheets.Collaboration.ISelections](/spreadjs/api/v18/collaboration/spread-sheets-collaboration-client/interfaces/ISelections) | All selection states. |

### IPresence

The **[IPresence](/spreadjs/api/v18/collaboration/spread-sheets-collaboration-client/interfaces/IPresence)**[ ](/spreadjs/api/v18/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.Sheets.Collaboration.IUser} [user]
 * @property {GC.Spread.Sheets.Collaboration.IStatus} [status]
 */
export interface IPresence {
    user: GC.Spread.Sheets.Collaboration.IUser;
    status: GC.Spread.Sheets.Collaboration.IStatus;
}
```

**Property Descriptions**

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

### IBindPresenceOptions

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

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

**Property Descriptions**

| Property Name | Type | Description |
| ------------- | ---- | ----------- |
| onPresencesUpdate (optional) | (presences?: IPresence[]) => void | Callback method triggered after presence updates via bindPresences. |
| colorScheme (optional) | string[] | User-defined color scheme. |

## Methods

### setPresences

The [setPresences ](/spreadjs/api/v18/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',
		permission: {
			mode: GC.Spread.Sheets.Collaboration.BrowsingMode.edit,
		}
	},
	status: {
		selections: {
			selections: [new GC.Spread.Sheets.Range(0, 0, 1, 1)],
			sheetId: 'sheet1'
		}
	}
}];
spread.collaboration.setPresences(presences);
```

### getPresences

The [getPresences ](/spreadjs/api/v18/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/v18/collaboration/spread-sheets-collaboration-client/README#bindpresence)method binds presence and user information to the current workbook, providing a simpler way to simultaneously bind both presence and user info to the workbook.

```typescript
export declare function bindPresence(workbook: any, presence: Presence<IPresence>, user: IUser, options?: IBindPresenceOptions): Promise<void>;
```

**Parameters**

* **workbook (**`GC.Spread.Sheets.Workbook`**)**: The Workbook instance.
* **presence (**`GC.Spread.Sheets.Collaboration.IPresence`**)**: The Presence instance.
* **user (**`GC.Spread.Sheets.Collaboration.IUser`**)**: User information.
* **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 } from 'spread-sheets-collaboration-client';

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

const user: IUser = {
    id: '1',
    name: "user1"
}

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.

```auto
```typescript
import { bindPresence } from 'spread-sheets-collaboration-client';
const Color_Scheme = ['#0000ff', '#008000', '#9900cc', '#800000', '#00cc33', '#cc6600', '#cc0099'];
var seed = new Date().valueOf() + "";
const user: IUser = {
    id: seed,
    name: "user" + seed,
    color: Color_Scheme[Math.floor(Math.random() * Color_Scheme.length)]
}
bindPresence(workbook, presence, user);
```

```auto

### Server Side

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

## API

* `spread-sheets-collaboration-client`

    ```typescript
    /**
     * Represents a user in the collaboration system.
     */
    export interface IUser {
        id: string;
        name: string;
        color?: string;
        permission?: IPermission;
    }
    /**
     * Represents selection data for a worksheet.
     */
    export interface ISelections {
        selections?: Range[];
        sheetId?: string;
    }
    /**
     * Represents presence information for a user.
     */
    export interface IPresence {
        user: IUser;
        status: { selections?: ISelections };
    }
    /**
     * Binds a workbook to a presence instance.
     * @param {any} workbook - The instance of GC.Spread.Sheets.Workbook.
     * @param {Presence<IPresence>} presence - The presence instance.
     * @param {IUser} user - The user information.
     * @param {IBindPresenceOptions} [options] - Optional binding options.
     * @returns {Promise<void>} A promise that resolves when the binding is complete.
     */
    export declare function bindPresence(workbook: any, presence: Presence<IPresence>, user: IUser, options?: IBindPresenceOptions): void;
    /**
     * Options for binding presence to a workbook.
     */
    export interface IBindPresenceOptions {
        onPresencesUpdate?: (presences?: IPresence[]) => void;
        colorScheme?: string[];
    }
    ```
* `GC.Spread.Sheets.@Workbook`

    ```typescript
    ///* function setPresences(presences: GC.Spread.Sheets.Collaboration.IPresence[]): void
    /**
      * Set the presences info.
      * @param {GC.Spread.Sheets.Collaboration.IPresence[]} presences - The presences info.
      * @example
      * //This example updates the current presences.
      * let presences = [{
      *     user: {
      *         id: '1',
      *         name: 'User1',
      *         color: '#FF0000',
      *         permission: {
      *             mode: GC.Spread.Sheets.Collaboration.BrowsingMode.edit,
      *         }
      *     },
      *     status: {
      *         selections: {
      *              selections: [new GC.Spread.Sheets.Range(0, 0, 1, 1)],
      *              sheetId: 'sheet1'
      *         }
      *     }
      * }, {
      *     user: {
      *         id: '2',
      *         name: 'User2',
      *         permission: {
      *             mode: GC.Spread.Sheets.Collaboration.BrowsingMode.edit,
      *         }
      *     },
      *     status: {
      *         selections: {
      *              selections: [new GC.Spread.Sheets.Range(2, 2, 3, 5)],
      *              sheetId: 'sheet1'
      *         }
      *     }
      * }]
      * spread.collaboration.setPresences(presences);
      */
    setPresences (presences: IPresence[]): void;
    
    ///* function getPresences(): GC.Spread.Sheets.Collaboration.IPresence[]
    /**
      * Get presences for workbook
      * @returns {GC.Spread.Sheets.Collaboration.IPresence[]} presences - The presences info.
      * @example
      * ```typescript
      * // This example gets presences.
      * const presences = spread.collaboration.getPresences();
      */
    getPresences (): GC.Spread.Sheets.Collaboration.IPresence[];
    ```
```