One of the areas where Cheogram Android seeks to forge ahead is to provide high-quality mobile-first UI for services that operate of the Jabber network.


Many kinds of services require a registration or login flow. These are all covered by XEP-0077 so if you need this feature your service should implement that.

You may find that sometimes your flow needs more than the one-form-one-step model that XEP-0077 supports. In this case it is recommended to also have a XEP-0050 command with node of jabber:iq:register. The response from a XEP-0077 registration attempt by a new user thus becomes only a reply with instructions to use the command instead. Sensible clients can detect this situation and work it to their UI accordingly.

XEP-0077 remains important for use cases where a user checks if they are still registered or removed their registration.

Command Payloads

Most service interaction with a user happens over XEP-0050 and family.

A command MAY contain zero or more <note/> elements and MAY contain other namespaced elements as payload. Elements qualified by the "jabber:x:data" and "jabber:x:oob" namespaces are the typical payload.

The order of these elements denote their precedence, so that those 
elements earlier in the list have higher precedence.

So each step of the flow can be defined by one or more elements, to allow clients with different abilities to render what works for them, for example:

<command xmlns='' node='doit' status='excecuting'>
  <x xmlns="jabber:x:oob">
    <desc>This is what's up here...</desc>
  <note type="info">This is what's up here: scheme:some-uri</note>

Cheogram Android currently supports http(s) OOB by always rendering as a webview (with some optional JavaScript hooks injected to allow the page to advance the flow when done) and xmpp OOB by auto-triggering the URI in-app. Likely for most other schemes it makes sense to instead render a button to trigger the URI as an intent, which will be done in a future release.

Data Forms

Most command payloads are based on XEP-0004. Cheogram Android implements most of this XEP though currently lacks a good UI for list-multi editing and improvements are always possible.

The XEP does not ban mixing a single reported table with other result fields, and so we support this, but due to confusion out in the community if this is desirable no sopranica service currently generates this. A new release of the XEP actually does ban this now.

XEP-0122 provides a way to give more granular type information about a field. This can be used for client-side validation of submittable fields (and Cheogram Android does this, along with the required-field and basic data type validation possible with XEP-0004), but can also provide UX hints (for example cheogram Android changes the keyboard in use for html:tel type etc. Even for result or fixed fields this is useful to give type information for use in formatting. For example a date type can be localized, a URI made a clickable link, etc

XEP-0122 also provides a way for a list-single or list-multi to be set to a totally custom value not present in the list (called "open").


Depending on various factors and heuristics a list-single may get quite a different UI. At time of writing if there is a value already set and the list is small it will use a drop down box, if there is no value already set and the list is small it will use a list of radio buttons, if the list is "open" and small if will use a list of radio buttons paired with a text box, if the list is large it will use a searchable list-box type widget.

If the list is the only field in the form, and there is only one possible non-cancel action for the command step, then the list is rendered as a grid of button, tap one to select that value and go to next step.

An SVG child inside an option will be rendered as an icon for the label (at least in grid-of-buttons view).


Cheogram Android injects a JavaScript API in the xmpp_xep0050 variable for interaction with the flow from the page.

RSM tags can be used to limit the length of a result. Since no other client supports this, if you support it in your service the result will be their client getting your default/small size. Cheogram Android sends RSM with a large max when present because it has UI designed to work well with eg long lists.

We interpret a field of var as augmenting/replacing the buttons generated for command actions, to allow for custom actions like "generate new BTC address"

When a list-single field has a direct child of <media-selector xmlns="" /> then any SVG child in the options will be displayed larger as though it is the main focus of the label, rather than small as though it is a decorative icon.


Regular XMPP stanza-level errors (with iq type=error) can be returned from a command flow, and the UI will render them appropriately. Or you may use a note with type=error

Finishing Command

When a command has status=completed or status=canceled and no payloads at all, it's just over and Cheogram Android closes the tab. It if has one final payload it will show the payload along with a "close" button which isn't really an action but just closes the tab.

Pain points remaining

One of our pain points in data forms is it's not trivial to have a form that is partly results but also has any submittable fields. type=fixed can be used, but then more specific type information is lost, and some implementations do not support type=fixed with a label (though cheogram Android supports this of course).

Another is structured lists and/or multiple tables. There can only be one reported table per form, and thus realistically one per step, and it is unspecified what this means for anything other than a result form. There is some desire to have one or more structured lists on a form, such that their data is still more than just a single string, but they can be selected (ala list-single or list-multi) for further action.

CheogramApp/CommandUI (last edited 2023-287 23:46:15 by Singpolyma)