Skip to content

huobanteam/app-sdk-js

Repository files navigation

Huoban App SDK (中文版)

for building applications on Huoban


Import

// ES6
import {client, host} from 'huoban-app-sdk'
// or
import * as HuobanAppSDK from 'huoban-app-sdk'

// CommonJS
var HuobanAppSDK = require('huoban-app-sdk')

// RequireJS
define(['huoban-app-sdk'], function (HuobanAppSDK) {/*...*/})
<!-- Script, available as `window.HuobanAppSDK` -->
<script src="//unpkg.com/huoban-app-sdk@latest/lib/HuobanAppSDK.min.js"></script>

Initialize & Example

Client: HuobanAppSDK.client()

Create a app client to communicate with the host:

const client = HuobanAppSDK.client()

// Normally send a message(action) to the host
client.send('hello', {word: 'i am a client'}).then(message => {
  console.log(message)
})

Host: HuobanAppSDK.host()

Create a host, just pass in your message handlers:

const host = HuobanAppSDK.host({
  init: handleClientInit
})

// or use the `on` method to add handler
host.on('connect', (data, respond) => {
  console.log('client connected:', data.client)
  // use the `respond` to response data
  respond('welcome')
  // or refuse the connect, use the second param
  // respond(null, 'connect refused.')
})

// add a special handler to handle all message
host.on('*', (action, data) => {
  // the * handler without a `respond`
  console.log('client send an action:', action, data)
})

// Send something directly to the special client.
// {CLIENT} is from the `connect` handler
host.push({CLIENT}, 'app.change', {app_id: 123, name: ...})

function handleClientInit (data, respond) {
  fetchInitDataFromServer(data.app_id).then((ret) => {
    respond(ret)
  })
}

SDK API

HuobanAppSDK.client(handlers) : Client

Initialize a client.

  • handlers {Object} An object of message action/handler mappings

Returns a Client_(extends Channel)_. See the Channel API Docs for more details.

Example:

HuobanAppSDK.client({
  broadcast: (data, respond) => {
    new Notification('You have a broadcast! ' + data.action)
    respond('GOT_IT')
  }
})

HuobanAppSDK.host(handlers) : Host

Initialize a host.

  • handlers {Object} An object of message action/handler mappings

Returns a Host_(extends Channel)_. See the Channel API Docs for more details.

Example:

HuobanAppSDK.host({
  init: handleClientInit
})

HuobanAppSDK.isClient (Property)

Boolean if in Huoban native APP

HuobanAppSDK.isPC (Property)

Boolean if in Huoban Web (https://app.huoban.com/)

Channel API

channel.ready(handler)

Register a handler to be called when the channel is opened between client and host.

  • handler {Function} The ready handler

Although you can register ready handlers, you can send messages before the channel is open using channel.send() and these will be queued and sent as soon as the channel is ready.

Example:

channel.ready(() => {
  application.start()
})

channel.send(action, data) : Promise

Send a message through the channel to the host/client.

  • action {String} The message action
  • data {Any} The message data

Returns a Message(Promise). See the Message API Docs for more details.

If called before the channel is ready the message will be queued and sent as soon as the channel is open.

Example:

// Typed message, will invoke registered action handlers
channel.send('notify')

// Typed message with data, will invoke registered action handlers
channel.send('openUrl', { url: 'https://app.huoban.com/' })

channel.push(action, data)

Send a message through the channel to the host/client, and without a return value.

  • action {String} The message action
  • data {Any} The message data

If called before the channel is ready the message will be queued and sent as soon as the channel is open.

Example:

// Typed message, will invoke registered action handlers
channel.push('broadcast', {action: 'refresh'})

channel.on(action, handler) : {revoke, revokes, on}

Handle an special action message.

  • action {String} The message action
  • handler {Function} The message handler

The handler receives two arguments: the data of the message and a respond function.

Returns an object {revoke, revokes, on}.

Example:

let connectBinder = channel.on('connect', (data, respond) => {
  console.log('new connection: ', data)
  respond('ok')
})
// remove the listener when needed
connectBinder.revoke()
// or
connectBinder.revokes.forEach(revoke => revoke())

channel.off(action, handler)

Remove an special action handler.

  • action {String} The message action, pass * will remove all handlers
  • [handler] {Function} (optional) The message handler, if omit will remove all handlers for action

Example:

 // remove the special `handleClientInit` handler
channel.off('init', handleClientInit)

// remove all `init` action's handlers
channel.off('init')

// remove all handlers
channel.off('*')

channel.emit(action, data, respond)

Trigger an special action.

  • action {String} The message action
  • [data] {Any} (optional) The message data
  • [respond] {Function} (optional) The message responder

Example:

 channel.emit('connect', {app_id: 123, ...})

Client API

Client extends Channel

client.init(applicationId) : Promise

Get the init data from the host. this should be the first call for an application

  • applicationId application id

Return a Promise, resolved by data:

  • user {Object} current logged in user
  • table {Object} current table
  • ticket {String} the ticket for authenticating

Example:

client.init(applicationId).then((data) => {
  let {user, ticket, table} = data
})

client.openWebPage(url, title)

Tell host to open a new page with url.

  • url {String} The web url
  • title {String} The web page's title

client.closeWebPage()

Tell host to close current page.

client.setTitle(title)

Tell host to set current page's title.

  • title {String} The page title

client.openItemDetail(itemId)

Tell host to open the default item detail page.

  • itemId {Integer} The id of the item

client.openItemList()

Tell host to open the default item list page.

client.openItemDiff(itemId, fromRevId, toRevId, opts = {})

Tell host to open the item diff component.

  • itemId {Integer} The id of the item
  • fromRevId {Integer} The id of the old reversion
  • toRevId {Integer} The id of the new reversion
  • opts {Object} The extra params
    • field_id {Integer} The specified field_id to show
    • created_by {Object} The modifier
    • created_by_id {Integer} The modifier's id
    • updated_on {String} The updated time

Example:

let itemId = 6078229
let fromRevId = 7308234
let toRevId = 7308410
client.openItemDiff(itemId, fromRevId, toRevId, {
  field_id: 3034388,
  created_by: {name: 'airwin', user_id: 11003, avatar: {}, ...},
  created_by_id: 11003,
  updated_on: '2016-07-31 11:22:33'
})

client.openFilter(table, filters, fn)

this method use the fn to receive callback, not return a Promise

Tell host to open the native filter component.

  • table {Object} The Table Info
  • filters {Object} The specialed filters
  • fn {Function} handler, fn(data, error)
    • data {Object} data of callback, eg: {filters: {and: [{field: 110001, query: {..}}, ..]}}
      • filters {Object} selected filters
    • error {Object} error info eg: {cancelled: true} for user cancel the operation, {message: 'default value error'} for some actual error
      • cancelled {Boolean} true for user cancel the operation
      • message {String} error message

Example:

client.openFilter(table, null, (data) => {
  console.log('filters changed:', data.filters)
})

client.openUserPicker(opts, fn)

this method use the fn to receive callback, not return a Promise

Tell host to open the user picker component.

  • opts {Object} The picker options
    • values {Array} selected users's id, eg: [11001, 11003]
    • multi {Boolean} if allow select multiple users
    • required {Boolean} if must select one user at least
    • title {String} the picker's title
    • placement {String} (web only) picker's position relative to the target, can be: left-bottom/right-bottom/left-top/right-top, default: 'right-bottom'
    • width {Integer} (web only) picker's layer's width
  • fn {Function} handler, fn(data, error)
    • data {Object} data of callback eg: {users: [{user_id: 11001, name: 'test1'}, {user_id: 11003, name: 'test2'}, ...]}
      • users {Array} selected users
    • error {Object} error info eg: {cancelled: true} for user cancel the operation, {message: 'default value error'} for some actual error
      • cancelled {Boolean} true for user cancel the operation
      • message {String} error message

Example:

client.openUserPicker({multi: true, values: [11001, 11003]}, (data) => {
  console.log('users picked:', data.users)
})

client.openDatePicker(opts, fn)

this method use the fn to receive callback, not return a Promise

Tell host to open the date picker component.

  • opts {Object} The picker options
    • [value] {String} (optional) default datetime
    • [type] {String} select type: date/time/datetime
    • [showClear] {Boolean} if show a clear button to clear current datetime
    • [showToday] {Boolean} if show a today button to select today
    • [range] {Object} range of the selectable date, eg: {gte: '2016-08-01', lte: '2016-11-11'}
    • placement {String} (web only) picker's position relative to the target, can be: left-bottom/right-bottom/left-top/right-top, default: 'right-bottom'
  • fn {Function} handler, fn(data, error)
    • data {Object} data of callback, eg: {datetime: '2016-07-28 12:33', date: '2016-07-28', time: '12:33'}
      • [datetime] {String} (optional) selected datetime
      • [date] {String} (optional) selected date
      • [time] {String} (optional) selected time
    • error {Object} error info eg: {cancelled: true} for user cancel the operation, {message: 'default value error'} for some actual error
      • cancelled {Boolean} true for user cancel the operation
      • message {String} error message

Example:

client.openDatePicker({value: '2016-07-27', type: 'date'}, (data) => {
  console.log('date picked:', data.date)
})

client.openRichEditor(opts, fn)

this method use the fn to receive callback, not return a Promise

Tell host to open the rich text editor.

  • opts {Object} The picker options
    • title {String} editor's title
    • [value] {String} (optional) default text
  • fn {Function} handler, fn(data, error)
    • data {Object} data of callback, eg: {value: '

      abc

      '}
      • value {String} edited text
    • error {Object} error info eg: {cancelled: true} for user cancel the operation, {message: 'default value error'} for some actual error
      • cancelled {Boolean} true for user cancel the operation
      • message {String} error message

client.openShare(opts, fn)

this method use the fn to receive callback, not return a Promise

Tell host to open the share component.

  • opts {Object} The share options
    • [title] {String} share title
    • [content] {String} description of the share
    • [image] {String} share image's url
    • [url] {String} the link to share
    • [type] {String} share type, can be: url(default)/image(share image blob)
    • [content_info] {Object} extra info, eg: {size: 1024} (when type is 'image')
    • [via] {String} specified share with, can be: wechat/wechat_timeline/qq/weibo/clipboard/browser/tongren
  • fn {Function} handler, fn(data, error)
    • data {Object} data of callback, eg: {via: 'wechat'}
      • [via] {String} the app's name which shared with, can be: wechat/wechat_timeline/qq/weibo/clipboard/browser/tongren
    • error {Object} error info eg: {cancelled: true} for user cancel the operation, {message: 'default value error'} for some actual error
      • cancelled {Boolean} true for user cancel the operation
      • message {String} error message

Example:

client.openShare({title: 'huoban', content: 'welcome', url: 'https://app.huoban.com'}, (data, error) => {
  if (!error) {
    console.log('share successed with:', data.via)
  } else {
    console.log('share failed.')
  }
})

client.getSpaceMembers(opts) : Promise

get the full list of space's members from host.

  • opts {Object} options
    • [keyword] {String} (optional) search keyword

Return a Promise, resolved by data:

  • members {Array} list of members, eg: [{name: 'test1', user_id: 11003, avatar:..}, ..]

Example:

client.getSpaceMembers({keyword: 'air'}).then((data) => {
  console.log('got members:', data.members)
})

client.openAttachment(fileInfo)

Tell host to show an attachment.

  • fileInfo {Object} The attachment info

client.genQRCode(text) : Promise

generate a QRCode.

  • text {Object} text to generate

Return a Promise, resolved by data:

  • dataURL {String} base64 encoded string for using in images' src

Example:

client.genQRCode('hello world').then((data) => {
  console.log('got dataURL:', data.dataURL)
})

client.scanQRCode(opts) : Promise

scan a QRCode. (native only)

  • opts {Object} options
    • needResult {Boolean} true for return the result of the scanned QRCode

Return a Promise, resolved by data:

  • result {String} result of scan

Example:

client.scanQRCode().then((data) => {
  console.log('got result:', data.result)
})

client.getLocation(opts = {}, fn)

this method use the fn to receive callback, not return a Promise

request the current location.

  • opts {Object} options

    • [position] {Object} (optional) current position (gcj02) eg: {lng: 116.397428, lat: 39.90923}
    • enableHighAccuracy {Boolean} request high accuracy (GPS), default: true
    • timeout {Integer} timeout (ms), default: 10000
    • convert {Boolean} if convert (wgs84 to gcj02), default: true
    • title {String} title to show
  • fn {Function} handler, fn(data, error)

    • data {Object} data of callback
      • location {Object} current location eg: {name: 'xx', address: 'xx', distance: 10, lng: 116.32, lat: 40.033}
    • error {Object} error info eg: {cancelled: true} for user cancel the operation, {message: 'default value error'} for some actual error
      • cancelled {Boolean} true for user cancel the operation
      • message {String} error message

Example:

client.getLocation({}, (data, error) => {
  console.log('got location:', data, error)
})

client.openUserProfile(userId, opts)

Tell host to open an user's profile card.

  • userId {Integer} The User's user_id
  • opts {Object} options
    • placement {String} (web only) picker's position relative to the target, can be: left-bottom/right-bottom/left-top/right-top/bottom/top, default: 'bottom'

client.broadcast(action, data)

Broadcast an action to all other clients.

  • action {String} The broadcast action
  • [data] {Any} (optional) The broadcast data

client.setPageConfig(config)

set the current page's behavior. (native only)

  • config {Object}
    • landscape {Object} behavior when screen turned to landscape eg: {nav_bar: false, bottom_bar: false}
      • nav_bar {Boolean} if show the navigation bar
      • bottom_bar {Boolean} if show the botttom bar

client.setNavigationBarVisibility(isVisible)

Tell host to toggle the navbar. (native only)

  • isVisible {Boolean} visible

client.setBottomToolBarVisibility(isVisible)

Tell host to toggle the toolbar. (native only)

  • isVisible {Boolean} visible

client.installApplication(applicationId)

Tell host to install an application. (native only)

  • applicationId {Integer} application's id

Host API

Host extends Channel

host.send(client, action, data) : Promise

Get the init data from the host. this should be the first call for an application

  • client the client id (from the connect event handler)
  • action the action name
  • [data] (optional) the action data

host.push(client, action, data)

same as the send but without a return.

  • client the client id (from the connect event handler)
  • action the action name
  • [data] (optional) the action data

host.broadcast(action, data, applicationId)

broadcast an action to all clients

  • action the action name
  • [data] (optional) the action data
  • [applicationId] (optional) special an application by id

Message API

message.then(handler)

Register a handler to receive the response to a message.

  • handler {Function} Response handler

Example:

// In host
HuobanAppSDK.host({
  init: (data, respond) => {
    // may some async action
    fetchSomething(data.app_id).then((ret) => {
      respond({ticket: ret.ticket, user: {name: 'test1', ...}})
    })
  }
})

// In client
const client = HuobanAppSDK.client()
client.send('init', { app_id: 100117 }).then((data) => {
  console.log(data.ticket, data.user, data.table)
})

respond([data])

Send a response to a received message.

This function is passed as the second argument to message handlers.

  • [data] {Any} (optional) The data to respond to the message with.

Author & License

created by airwin and released under the MIT license.