I
I
Igor2020-10-16 16:29:44
Vue.js
Igor, 2020-10-16 16:29:44

How to make the plugin so that it becomes reactive in the template?

How to make the plugin so that it becomes reactive in the template?

And so, I made a plugin,

spoiler

/* eslint-disable */
import { JsSIPFactory, JsSPConfiguration } from './JsSIPFactory'
import { UA } from 'jssip'
import {
  ConnectingEvent,
  EndEvent,
  IncomingEvent,
  OutgoingEvent,
  RTCSession
} from 'jssip/lib/RTCSession'

export enum JsSIPState {
  idle = 'idle',
  call = 'call',
  connecting = 'connecting',
  accepted = 'accepted'
}

export class JsSIP {
  private _state: string = JsSIPState.idle
  private _target: string = ''
  private ua: UA

  constructor (url: string, config: JsSPConfiguration) {
    this.ua = JsSIPFactory.create(url, {
      /* eslint-disable */
      uri: config.uri,
      display_name: config.display_name,
      password: config.password
      /* eslint-enable */
    })
    return this
  }

  get target () {
    return this._target
  }

  set target (value: string) {
    this._target = value
  }

  get state (): string {
    return this._state
  }

  /**
   * call up
   * @param target
   */
  public call (target: string): RTCSession {
    if (!this.ua) {
      throw new Error('Initialization required')
    }
    const _this: JsSIP = this as JsSIP
    this._target = target
    this._state = JsSIPState.call
    const session: RTCSession = this.ua.call(target, {
      eventHandlers: {
        connecting: (event: ConnectingEvent) => {
          console.log('session: connecting', event)
          _this._state = JsSIPState.connecting
        },
        accepted: (event: IncomingEvent | OutgoingEvent) => {
          console.log('session: accepted', event)
          _this._state = JsSIPState.accepted
        },
        progress: (event: IncomingEvent | OutgoingEvent) => {
          console.log('session: progress', event)
          _this._state = JsSIPState.idle
        },
        failed: (event: EndEvent) => {
          console.log('session: failed', event)
          _this._state = JsSIPState.idle
        }
      },
      pcConfig: {
        rtcpMuxPolicy: 'negotiate', // Важно для хрома, чтоб работал multiplexing. Эту штуку обязательно нужно включить на астере.
        iceServers: []
      },
      mediaConstraints: {
        audio: true, // Поддерживаем только аудио
        video: false
      }
    })
    session.connection.addEventListener('addstream', (e: any) => {
      // Remote audio control
      const audio: HTMLAudioElement = document.getElementById('audio') as HTMLAudioElement
      audio.srcObject = e.stream
      audio.play()
    })
    return session
  }

  /**
   * Cancel call
   */
  public cancel () {
    this.ua.terminateSessions()
  }

  /**
   * Change configuration
   * @param url
   * @param config
   */
  public setConfiguration (url: string, config: JsSPConfiguration) {
    this.ua = JsSIPFactory.create(url, {
      /* eslint-disable */
      uri: config.uri,
      display_name: config.display_name,
      password: config.password
      /* eslint-enable */
    })
    return this
  }

  public start (): JsSIP {
    this.ua.start()
    return this
  }

  public on (event: string, handler: (...args: any[]) => void): JsSIP {
    (this.ua as UA).addListener(event, handler)
    return this
  }

  public off (event: string, handler: (...args: any[]) => void): JsSIP {
    (this.ua as UA).removeListener(event, handler)
    return this
  }
}



I install like this
import Vue from 'vue'
import { JsSIP } from '@/jsSIP/plugin'

/* eslint-disable */
const $jssip: JsSIP = new JsSIP(`wss://server:8089/ws`, {
  /* eslint-disable */
  uri: `sip:[email protected]`,
  display_name: 'Test',
  password: 'password'
  /* eslint-enable */
})

class JsSIPlugin {
  public install () {
    Object.defineProperties(Vue.prototype, {
      $jsSIP: {
        get (): JsSIP {
          return $jssip
        }
      }
    })
  }
}

Vue.use(new JsSIPlugin())


Now in the template I want to call the $jsSIP.state property.
As a result, there is no reactivity, there are a lot of crappy examples on the Internet.

While the plugin is running, the $jsSIP.state property changes, but is not rendered in the template.

I want to implement standalone plugin.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
Igor, 2020-10-16
@IgorPI

In general, the situation is as follows. Vue
has an observable method You need to specify the object that we plan to monitor

Vue.observable({
      count: 0
    })

In my case, so
class JsSIPlugin {
  public install () {
    Object.defineProperties(Vue.prototype, {
      $jsSIP: {
        get (): JsSIP {
          return $jssip
        }
      }
    })

    Vue.observable($jssip)
  }
}

Now the magic happens in the template.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question