| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- import Pusher from 'pusher-js'
- import * as PusherTypes from 'pusher-js'
- import state from 'state/state'
- import { Shape } from 'types'
-
- class RoomClient {
- room: string
- pusher: Pusher
- channel: PusherTypes.PresenceChannel
- lastCursorEventTime = 0
- id: string
-
- constructor() {
- // Create pusher instance and bind events
-
- this.pusher = new Pusher('5dc87c88b8684bda655a', {
- cluster: 'eu',
- authEndpoint: 'http://localhost:3000/api/pusher-auth',
- })
-
- this.pusher.connection.bind('connecting', () =>
- state.send('RT_CHANGED_STATUS', { status: 'connecting' })
- )
-
- this.pusher.connection.bind('connected', () =>
- state.send('RT_CHANGED_STATUS', { status: 'connected' })
- )
-
- this.pusher.connection.bind('unavailable', () =>
- state.send('RT_CHANGED_STATUS', { status: 'unavailable' })
- )
-
- this.pusher.connection.bind('failed', () => {
- state.send('RT_CHANGED_STATUS', { status: 'failed' })
- })
-
- this.pusher.connection.bind('disconnected', () => {
- state.send('RT_CHANGED_STATUS', { status: 'disconnected' })
- })
- }
-
- connect(roomId: string) {
- this.room = 'presence-' + roomId
-
- // Subscribe to channel
-
- this.channel = this.pusher.subscribe(
- this.room
- ) as PusherTypes.PresenceChannel
-
- this.channel.bind('pusher:subscription_error', (err: string) => {
- console.warn(err)
- state.send('RT_CHANGED_STATUS', { status: 'subscription-error' })
- })
-
- this.channel.bind('pusher:subscription_succeeded', () => {
- const me = this.channel.members.me
- const userId = me.id
-
- this.id = userId
-
- state.send('RT_CHANGED_STATUS', { status: 'subscribed' })
- })
-
- this.channel.bind(
- 'created_shape',
- (payload: { id: string; pageId: string; shape: Shape }) => {
- if (payload.id === this.id) return
- state.send('RT_CREATED_SHAPE', payload)
- }
- )
-
- this.channel.bind(
- 'deleted_shape',
- (payload: { id: string; pageId: string; shape: Shape }) => {
- if (payload.id === this.id) return
- state.send('RT_DELETED_SHAPE', payload)
- }
- )
-
- this.channel.bind(
- 'edited_shape',
- (payload: { id: string; pageId: string; change: Partial<Shape> }) => {
- if (payload.id === this.id) return
- state.send('RT_EDITED_SHAPE', payload)
- }
- )
-
- this.channel.bind(
- 'client-moved-cursor',
- (payload: { id: string; pageId: string; point: number[] }) => {
- if (payload.id === this.id) return
- state.send('RT_MOVED_CURSOR', payload)
- }
- )
- }
-
- disconnect() {
- this.pusher.unsubscribe(this.room)
- }
-
- reconnect() {
- this.pusher.subscribe(this.room)
- }
-
- moveCursor(pageId: string, point: number[]) {
- if (!this.channel) return
-
- const now = Date.now()
-
- if (now - this.lastCursorEventTime > 200) {
- this.lastCursorEventTime = now
-
- this.channel?.trigger('client-moved-cursor', {
- id: this.id,
- pageId,
- point,
- })
- }
- }
- }
-
- export default new RoomClient()
|