The Project Setup

Introduction

You HTML-based App will run inside different wrappers:

  • The Moment Class configuration window preview;

  • The Mobile App;

  • The WebView integration;

  • The Browser integration.

It is, therefore, necessary to follow a specific project folder structure and include some JSON files that are going to describe how the app will be rendered and configured.

To be more specific, you will have to think about the following artefacts:

  • The App template (ie. the manifest);

  • The App configuration form

Folder Structure

- manifest.json
- config
- mobile.config.json
- results.config.json
- src
- mobile
- index.html
- ... your other files
- results
- index.html
- ... your other files

Moment Manifest

Manifest Schema
manifest.json Example
Manifest Schema
{
"bundleId": "<string>",
"version": "<string>",
"category": "<string>",
"description": "<string>",
"tags": "<string[]>",
"template": {
"name": "<string>",
"displayName": "<string>",
"defaultMessage": "<string>",
"labels": "<string[]>",
"icons": [
{
"size": "<number>",
"url": "<string>",
"name": "<string>",
"type": "<string>",
"contentId": "<string>"
}
],
"presentation": {
"screenshots": "<string[]>",
"cover": "<string>",
"body": "<string>"
},
"plugins": "<string[]>",
"branding": {
"brandActivation": "<boolean>",
"theming": "<boolean>",
"defaultTheme": "<string>"
},
"screens": {
"mobile": "<string>",
"stage": "<string>"
},
"general": {
"type": "<string>",
"accessibility": "<string[]>",
"hasModeration": "<boolean>",
"isInteractive": "<boolean>",
"isFeedContent": "<boolean>",
"feedItemTitle": "<string>",
"supportedLanguages": "<string[]>"
},
"provider": {
"developer": "<string>",
"org": "<string>",
"support": "<string>"
}
}
}
manifest.json Example
{
"bundleId": "com.stagecast.voting",
"version": "1.2.1",
"category": "crowd game",
"description": "Create a poll and let your audience vote.",
"tags": [
"voting",
"interaction"
],
"template": {
"name": "voting",
"displayName": "Voting Moment",
"defaultMessage": "",
"labels": [
"free",
"basic"
],
"icons": [
{
"size": 200,
"url": "",
"name": "voting.png",
"type": "image/png",
"contentId": ""
}
],
"presentation": {
"screenshots": [],
"cover": "",
"body": "<h2>What the moment does</h2><p>A good old multiple choice voting - with instant result delivery!</p><h2>How to use the Moment at your event</h2><p>Use the Voting Moment to involve your audience in the outcome of the event! How about letting the audience vote for the favorite player of a match or what encore to perform after a concert?</p>"
},
"plugins": [
"sponsors"
],
"branding": {
"brandActivation": true,
"theming": true,
"defaultTheme": ""
},
"screens": {
"mobile": "mandatory",
"stage": "optional"
},
"general": {
"type": "html",
"accessibility": [
"stagecast app",
"browser",
"app integration"
],
"hasModeration": false,
"isInteractive": true,
"isFeedContent": false,
"feedItemTitle": "Voting",
"supportedLanguages": [
"en",
"sv",
"it"
]
},
"provider": {
"developer": "Stagecast AB",
"org": "Stagecast AB",
"support": "support@stagecast.se"
}
}
}

Root Fields:

  • bundleId: the unique template identifier. The suggested format is com.<org_name>.<moment_title> eg. com.stagecast.voting.

  • version: the current semantic version .

  • category: the name of the category the template falls into. (currently available options: marketing, utils, crowd game, special effect , if your moment doesn't fall into any of these categories, please propose one to our support team).

  • description: a brief description of the moment (no more than 140chars)

  • tags: a list of tags that could make the search easier

  • template: the template body

Template fileds:

  • name: the moment title in com.<org_name>.<moment_title>

  • displayName: a nice name for smaller screens.

  • defaultMessage: the default message that will appear in the mobile push notifications. This default message can be disabled or overwritten by the event organizer;

  • labels: a list of label to be applied to the template (eg. "free", "new" etc..)

  • icons: the template icons as a list of objects in the following format

    • size

    • url

    • name

    • type

    • contentId

  • presentation

    • screenshot: a list of screenshot that will be displayed in the moment description page

    • cover: the template cover image for the description page

    • body: the html of the description page

  • plugins: the list of supported plugins. Right now we only offer the sponsors and theming plugins

  • branding:

    • brandActivation:

    • theming:

    • defaultTheme: can be left empty

  • screens: the supported screen (mobile, results, moderation)

  • general

    • type: native or html. You are most likely implementing an html based moment, not a native one.

    • accessibility: where the moment runs.

    • hasModeration:

    • isInteractive: is it a full screen moment?

    • isFeedContent: is it a feed moment

    • feedItemTitle: only if it is a feed moment

    • supportedLanguages: the supported languages as a list of 2-char strings

  • provider

    • developer: the developer name

    • org: the organization name

    • support: an email contact

The Configuration Form Definition

While designing the Moment, you should keep in mind that some parameters might be configured by an external user. Having dynamic variables that can be set from an external resource makes your moment configurable and attracts the attention of the event organizers. The configurations can be seen as the query params in web url. This params tell the frontend code what data to fetch and sometimes how to render the page content.

Let's take as an example a Poll Moment: you might want to receive the question text and the options from an external configuration. You might also have a dynamic background that can change depending on the event type and the audience type: a poll launched during a convention on kittens and puppies might display a nice-looking as a background.

The possible configuration object might look like the following:

let configObj = {
backgroundImage: "https://puppies.org/images/nicepuppy.jpeg"
question: "How many puppies would you like to posses?"
answerOptions: [
{ text: "1" },
{ text: "2" },
{ text: "As many as possible" }
]
}

Such a structure allows someone to set the background Image of your Moment, the question text, and the possible answers.

To define the configuration object schema, you have to specify a Form Definition object. This object defines the field names, their type, their default value and how they can be set in the Stagecast Web-Platform configuration window.

The Form Definition object is currently a beta feature and we are actively working on that. It follow the Ngx-Formly notation.

A "simple" Definition object for our Color Moment looks like the following:

config/mobile.config.json
config/mobile.config.json
[{
"fieldGroupClassName": "row",
"fieldGroup": [{
"key": "pattern",
"type": "dropdown",
"defaultValue": "soft",
"className": "col-6",
"wrappers": [
"form-field"
],
"templateOptions": {
"required": true,
"hideRequiredMarker": true,
"arrayValues": [
{"value": "soft", "display": "Soft"},
{"value": "hard", "display": "Hard"}
],
"labelProp": "display",
"valueProp": "value",
"label": "Pattern",
"description": "Choose a pattern to change fades between colors."
}
},
{
"key": "interval",
"type": "input",
"defaultValue": 1000,
"className": "col-6",
"wrappers": [
"form-field"
],
"templateOptions": {
"min": 300,
"max": 5000,
"required": true,
"type": "number",
"label": "Interval (ms)",
"description": "Choose a fixed time interval between the change of color."
},
"validation": {
"messages": {
"min": "The min value is 300.",
"max": "The max value is 5000."
}
}
}
]
},
{
"key": "colors",
"defaultValue": ["#005aff", "#c500ff", "#ff00d1", "#ff0057", "#ff8b00", "#ffe200"],
"type": "color-input",
"wrappers": [
"form-field"
],
"templateOptions": {
"advanced": true,
"required": true,
"label": "Colors",
"description": "Use different colors to create entertaining light shows.",
"maxLength": 10,
"minLenght": 1
},
"validation": {
"messages": {
"minLenght": "Select at least 1 color.",
"maxLength": "You can select at most 10 colors."
}
}
}
]

Once rendered, the configuration page looks like this:

As you can see, the structure can get quite complex. We are currently working on mechanism to make the creation of this Definition object easier. In the meanwhile, we have a support team you can reach out to.