# innovaphone.lib1

## Includes

The library has no dependencies on other Javascript files.

## Static helper functions

Functionality that is often needed in apps.

innovaphone.lib1.openLink(url)
  Used for opening mailto-Links.

## Events

innovaphone.lib1.Event defines an interface for events. Listeners can attach an detach to an event. Attached listeners are called when the event fires.

innovaphone.lib1.Event(sender)
  Constructor for the event. The specified sender object will be passed to the attached listener functions.
attach(listener)
  Attaches a listener function with the following parameters.
  sender
    The sender object specified by the constructor of the event.
  value (optional)
    Additional information about the event, typically an object.
detach(listener)
  Detaches a listener function.
notify(value)
  Fires the event and notifies the attached listeners

### Example

        // define event
        var oncall = new Event(this);

        // attach a listener
        oncall.attach(function(sender, value) {
            console.log(value.name + " calling");
        });

        // notify listeners
        oncall.notify({ name: "John Doe" });

## The start object

The start object is passed to an app. It provides access to the parameters of the app itself and encapsulates the communication with the client.

### Properties

url
  The websocket base URL to be used by the app.
  Can be used to esablish a websocket connection to the App Service using innovaphone.appwebsocket.Connection.
originalUrl
  The direct http: URL of the app.
  Can be used to create links pointing to the App Service.
clientUrl
  The direct http: URL of the myApps client.
proxyUrl
  The URL prefix of the AppProxy in the myApps launcher, e.g. "http://localhost:10008/appproxy/ext".
name
  The name of the app.
title
  The display name of the app.
args
  An object containing the URI parameters that have been passed to the app.
margs
  An object containing the URI parameters that have been passed to the app as arrays so that no argument is lost, if the same argument is passed multiple times.
lang
  The two-letter code of the current language (e.g. "en").
scheme
  The current color scheme ("light" or "dark").
visible
  true, if the app is currently visible to the user.
  This is the case if the app is the current app in the myApps window or if the app is in a detached window.

### Events

onshow
  Fires when the app is brought to the foreground.
onargschanged
  Fires when the content of the "args" property has changed.
onlangchanged
  Fires when the content of the "lang" property has changed.
onschemechanged
  Fires when the content of the "scheme" property has changed.
onmenustatechanged
  Fires if the optional hamburger menu of the app (initialized using start.setMenuState) has been opened or closed by the user. Possible values are "open" or "closed".
onvisiblechanged
  Fires if the content of the "visible" property has changed

### Callback functions

onopenchannel(channel, opener, args)
  Apps can set this callback function in order to accept incoming communication channels from other apps.

### Methods

show()
  Tells the client to bring the app to the front.
show(applink)
  Opens the specified app link that might be the same app or a different app.
bringToFront()
  Tells the client that the window of the app (detached app window or main window of the client) should be brought to the front and get the focus. Depending on the operating system this function might not have an effect.
close()
  Tells the client to close the app.
blur()
  Tells the client to take the focus away from the app and put it on the app icon in the start bar.
home()
  Tells the client to show the home screen without closing the app.
setArgs(args, title)
  Sets the app arguments that are needed to re-open the current page. Will be used by the client to create booksmarks and for the browser history. Additionally an optional title for the current page can be given.
startActivity()
  Brings the app to the front for displaying an activity, like an incoming call. After the activity is finished, the app must call finishActivity().
finishActivity()
  Tells the client that the app has finished the activity that was started using startActivity(). The client will go back to the last app that was displayed before the activity.
provideApi(api)
  Tells the client that the app is providing a specific API (e.g. "com.innovaphone.phone"). The function should be called only after the app is connected and ready to receive API messages. Returns an object that encapsulates the handling of that API.
consumeApi(api)
  Subscribes for a specific API (e.g. "com.innovaphone.phone"). Returns an object that encapsulates the handling of that API.
openChannel(dst, args)
  Opens a communication channel to another app (dst) and returns an object that encapsulates the handling of that channel.
acceptChannel(channel)
  Can be used inside the `onopenchannel` callback to accept an incoming channel. Returns an object that encapsulates the handling of that channel.
rejectChannel(channel)
  Can be used inside the `onopenchannel` callback to reject an incoming channel.
requestPrepareReload(callback)
  Registers a callback that is called before the app is closed and reloaded in a new iframe by the client. For example this happens when the app is attached or detached from the main window of myApps for windows. When the app has finished its preparations for reloading it should call start.prepareReloadComplete().
prepareReloadComplete()
  Tells the client that the app has finished its preparations for reloading the app in a new iframe and that the current iframe can be closed now.
setMenuState(state)
  Tells the client if the optional hamburger menu of the app is open or closed. Possible states are "open" and "closed". The function needs to be called once to tell the client that the app provides a menu. With a value of null for state, the menu is removed
setBadge(value)
  Sets a badge at the app icon in the start bar and on home. Usually value is a number, but you can use any UTF8-Character to indicate states of the running app. Note that this function is only useful to indicate states while the app is running. If badge counts should appear also while it's not running the badge count should be set from the backend.

### Example

The following example demonstrates how apps can use the initial parameters in the start object and handle parameter changes during runtime.

    var innovaphone = innovaphone || {};
    innovaphone.Example = innovaphone.Example || function (start) {
        var colors = {
            dark: {
                "--background": "black",
                "--foreground": "white"
            },
            light: {
                "--background": "white",
                "--foreground": "black"
            }
        };

        var translations = {
            en: {
                hello: "Hello!"
            },
            de: {
                hello: "Hallo!"
            }
        };

        var schemes = new innovaphone.ui1.CssVariables(colors, start.scheme),
            langs = new innovaphone.lib1.Languages(translations, start.lang),
            app = new innovaphone.appwebsocket.Connection(start.url, start.name);

        start.setMenuState("closed");
        showPage(start.args.page);

        start.onschemechanged.attach(function () {
            schemes.activate(start.scheme);
        });

        start.onlangchanged.attach(function () {
            langs.activate(start.lang);
        });

        start.onargschanged.attach(function () {
            showPage(start.args.page);
        });

        start.onmenustatechanged.attach(function(sender, value) {
            if (value == "open") {
                // show menu
            }
            else {
                // hide menu
            }
        });

        function showPage(id) {
            // ...
        }
    };

## Client APIs

Apps can communicate with other apps using APIs. Each API is identified using a string constant (e.g. "com.innovaphone.phone"). Apps can both provide APIs and consume APIs that are provided by another app.

### API messages

A consumer can send requests to a provider. The provider can send back responses to the originating consumer. The framework treats the messages as opaque data and does not interpret them. The actual format is specified by the API.

### API model

An API provider can publish a model object containing its current state. The model can be observed by the consumers of the API. For example a phone API provider could publish the registration state and the active calls. Phone API consumers.

### Providing an API

An App Client API must be announced by the App Service, prior it can be used in the App Client. Please refer to the AppWebsocket App Platform Library documentation or JavaScript Runtime config documentation.

Apps that want to provide an API, must register at the client using the start.provideApi method. The method returns an object that encapulates the interface to be used by the API provider.

#### The API provider interface

onmessage
  Event that fires on incoming requests. The value of the event is an object with the following properties:
  msg
    The actual message, typically an object.
  consumer
    The name of the consumer that sent the request.
  src
    A value that should be echoed back to the consumer in every response to that request.
onconsumerclosed
  Event that fires if an API consumer for the API is closed. The provider can abort pending API requests from that consumer.
  consumer
    The name of the consumer that sent the request.
send(msg, consumer, src)
  Sends a response to a request that was received using the onmessage event.
  msg
    The response message, typically an object.
  consumer
    The name of the consumer that sent the request.
  src
    The src value from the corresponding request.
update(model)
  Publishes an arbitrary model object, that can be observed by the consumers of the API.
isDefaultApiProvider()
  Returns true, if the app is the default provider of the API.

#### Example

    // register API
    var phoneApi = start.provideApi("com.innovaphone.phone");

    // process incoming messages
    phoneApi.onmessage.attach(function(sender, obj) {
        if (obj.msg.mt == "StartCall") {
            startCall(obj.msg.num);
            phoneApi.send({ mt: "StartCallResult" }, obj.consumer, obj.src);
        }
    });

    // publish model
    phoneApi.update({ calls: [] });

### Consuming an API

Apps can consume an API by calling the start.consumeApi method. The method returns an object that encapsulates the interface to be used by the API consumer.

#### The API consumer interface

providers
  An array that contains the names of all providers of the API.
model
  An object, that contains all providers of the API with some additional information and their published model.
  title
    The displayname of API provider.
  url
    The URL of the API provider.
  info
    An object that contains static info provided by the app service of the provider. The format is defined by the API.
  model
    An object that contains dynamic info published by the app provider. The format is defined by the API.
  defaultApiProvider
    The name of the current defaultApiProvider (can be null).
  restart
    A counter that reflects how many times the API provider was restarted. This information can be used to detect restarts in order to renew subscriptions to that provider. Note that the initial value is undefined and changes to 0 when the provider was started the first time. So a change to 0 does not indicate a restart.
send(msg, provider, src, title)
  Sends a request to an API provider.
  msg
    The request message, typically an object.
  provider (optional)
    The name of the provider that should receive the request. If no provider is specified, the client lets the user select the provider. If "*" is specified, the request is broadcasted to all available providers of the API.
  src (optional)
    An optional value that will be echoed in the responses.
  title (optional)
    An optional title that is displayed by the client, if the user is asked which app should be used.
onmessage
  Event that fires on incoming responses. The value of the event is an object with the following properties:
  msg
    The actual message, typically an object.
  provider
    The name of the provider that sent the request.
  src
    The value from the corresponding request.
onupdate
  An event that fires on API model changes. The consumer is supposed to re-evaluate the model, if needed.

#### Example

        var phoneApi = start.consumeApi("com.innovaphone.phone");
        phoneApi.send({ mt: "StartCall", num: "200" });

### List of app APIs

The API messages and models are transparent to the client, so every app developer can define new APIs. As of now innovaphone defined the following APIs to communicate with their apps.

- com.innovaphone.avatar
- com.innovaphone.calllist
- com.innovaphone.chat
- com.innovaphone.client
- com.innovaphone.devices
- com.innovaphone.devicesui
- com.innovaphone.discussion
- com.innovaphone.files
- com.innovaphone.launcher
- com.innovaphone.manager
- com.innovaphone.phone
- com.innovaphone.search
- com.innovaphone.autostart

## Communication channels between apps

Apps or other iframes like status info displays can open a direct communication channel to another app. The programming interface of a channel is similar to a websocket connection. The channel implementation uses window messages.

### Opening a channel

The `start.openChannel` method can be used to open a channel to another app. Additionally arguments with additional information for the app can be passed. The method returns a channel object.

#### Example

        var ch = start.openChannel("someapp", {arg1: 3});

### Accepting channels

If an app wants to accept incoming channels, it needs to set the `start.onopenchannel` callback. Inside the callback the incoming channel can be accepted using `start.acceptChannel` or rejected using `start.rejectChannel`.

#### Example

        start.onopenchannel = function(channel, opener, args) {
            if (opener == expectedOpener) {
                var ch = start.acceptChannel(channel);
            }
            else {
                start.rejectChannel(channel);
            }
        };

### The channel object

The channel object provides an interface to handle the lifetime of the communication channel and for sending and receiving messages.

#### Callbacks

onconnected()
  Called if the connection was established.
onclosed()
  Called if the connection failed or has been closed by the remote endpoint.
onmessage(msg)
  Called on an incoming message. The message is a javascript object.

#### Methods

send(msg)
  Sends the `msg` object. The remote endpoint will get it using the `onmessage` callback.
close()
  Closes the channel. The remote endpoint will get the `onclosed` callback.

#### Example

        // source endpoint
        var ch = start.openChannel("someapp", {arg1: 4});
        ch.onconnected = function() {
            ch.send({mt: "Echo"});
        };
        ch.onclosed = function() {};
        ch.onmessage = function(msg) {
            if (msg.mt == "EchoResult") ch.close();
        };

        // destination endpoint
        start.onopenchannel = function(channel, opener, args) {
            var ch = start.acceptChannel(channel);
            ch.onconnected = function() {};
            ch.onclosed = function() {};
            ch.onmessage = function(msg) {
                if (msg.mt == "Echo") {
                    ch.send({mt: "EchoResult"});
                }
            };
        };

## Multi-language support

innovaphone.lib1.Languages defines a library for translating texts. Standalone it can be used to create static texts.

In conjunction with innovaphone.ui1.lib (see innovaphone.ui1.nodePrototype.addTranslation) dynamic texts can be put into UI nodes that are updated automatically, when the language changes.

innovaphone.lib1.Languages(texts, lang)
  Constructor for the event. The specified sender object will be passed to the attached listener functions.
  texts
    An object containing the translations for all supported languages.
    The texts can contain numbered placeholders ($0, $1, $2, ...) that can be substituted during translation.
  lang
    The two-letter code of the current language (e.g. "en").
  Example:

      var texts = {
          en: {
              conn: "Connected as $0",
              hello: "Hello!"
          },
          de: {
              conn: "Verbunden als $0",
              hello: "Hallo!"
          }
      };

      var langs = innovaphone.lib1.Languages(texts, "en");

current
  Property containing the two-letter code of the current language.
activate(lang)
  Switches the current language.
  lang
    The two-letter code of the language (e.g. "en").
  Example:

      langs.activate("de");

text(id, args)
  Returns the translation of a text and substitues placeholders.
  id
    The ID of the text.
  args (optional)
    An array containing the values for substituting the placeholders in the tranlated text.
  Example:

      var text1 = langs.text("hello");
      var text2 = langs.text("conn", ["John Doe"]);

clear(node)
  Detaches UI nodes, so that they won't receive further updates when the language is changing.
  This method is needed only when the library is used by innovaphone.ui1.lib.
  node (optional)
    If specified, the library only detaches the UI nodes that are in the subtree of the given node. Otherwise all UI nodes are detached.