Customizing platform addons

Platform addons can be customized in several ways:

  • Customization via pluginOptions
  • Hiding or removing an addon
  • Overriding a platform addon with a custom implementation

The latter is somewhat more involved in terms of development effort and will be covered in the next section.

Customization via pluginOptions

Some platform addons offer customization that can be defined via the players’ pluginOptions
All of the pluginOptions customization for the different platform addons are available in their documentation, under the “schema” sections.

For example, the ProjectMetaData platform addon offers a way to customize its background color. To do so, add the following to the player option section in Falcon:

{
  "plugins": {
    "ekoshell": {
        "addons": {
            "projectmetadata": {
              "background": "#ff0000"            
          }
        }
    }
  } 
} 

Hiding or removing an addon

To prevent an addon from rendering, one can set its parentContainer as null. Note that the addon’s API, reducer, init function etc will still work as normal.
For example, disabling rendering for the ProjectMetaData addon:

{
  "plugins": {
    "ekoshell": {
        "addons": {
            "projectmetadata": {
              "parentContainer": null            
          }
        }
    }
  } 
} 

If false is specified as the options for a specific addon, it will be completely disabled (no component, api, reducer, init etc). If going this route, make sure no other addons rely on its API or actions.
For example, disabling the ProjectMetaData addon:

{
  "plugins": {
    "ekoshell": {
        "addons": {
            "projectmetadata": false
        }
    }
  } 
} 

Overriding a platform addon with a custom implementation

This provides a way to add functionality or completely alter it’s rendering and visibility, all while retaining its original functionality without having to re-implement it.

Technically, it means using the addAddon function to add an addon with the same ID as an existing platform addon. The addon will be added as if it was a brand new addon with some exceptions:

  • If a new component is specified in the meta descriptor, that component will get rendered instead of the original platform addon component
  • If a new API is specified, it will be available under player.ekoshell.addons.ADDON_ID while the original platform addon API will still be available for use at player.ekoshell.ADDON_ID

When overriding a platform addon with a custom implementation, it’s imperative that you go over the documentation of the relevant platform and take into account the following:

  • What props does it receive? Implement any functionality that they require.
  • What custom options does it receive in the schema? Be sure to implement thos.e
  • Please read over the notes section to see if there’s anything extra you should be aware of while implementing

As addons serve as platform-wide UI, make sure to thoroughly test your custom addon on different screen sizes (desktop, tablet, mobile), devices (desktops, laptops, mobile devices), browsers (Chrome, Firefox, Safari) and operating systems (Windows, OSX, Android, iOS). Take extra care to follow ADA best practices, and test with assistive technologies on both desktop and mobile (screen readers, VoiceOver).

For example, lets say we want to create a custom implementation of the ProjectMetaData addon.
Our implementation needs to take into accounting these important props:

  • isPaused to figure out if the Project MetaData component should be visible when the player is paused
  • The data to be displayed will be included in these props: showTitle, showSubtitle, showWatchTime etc
  • We should take into account visibility of these items as defined by the props: showBackButton, showTitle, showSubtitle, showStartOver, showCredits etc for their respective fields
  • We have to include and render a container called ProjectMetaData_buttonRow so that sub-addons of the original platform addon will be rendered (such as ShareButton)
  • backgroundColor is a customization we need to implement

Let’s say that our addon adds some functionality. We can do this by create our addon API, it will be accessible to other addons via player.ekoshell.addons.ProjectMetaData.doSometingCool()

let CustomProjectMetaData_Api = function createAddonApi(addonParams) {
    return {
        doSomethingCool: () => console.log("Hello from our custom addon implementation")    
    }    
}
//We can define our custom CSS/SASS 
import "./CustomProjectMetaData.scss"; 

function CustomProjectMetaData(props){   
    let original_api = props.player.ekoshell.ProjectMetaData; 
    let buttonRowContainer = props.useContainer("ProjectMetaData_buttonRow");

    let remainingTime = original_api.calculateRemainingTime(props.watchTime, props.player.currentTime);

    let watchTimeSec = props.watchTime;
    let showWatchTime = !!(props.showWatchTime && watchTimeSec && watchTimeSec > 0);

    let containerStyle = {
        display: props.isPaused ? "block" : "none",
        ...(props.backgroundColor ? {background: props.backgroundColor} : null)
    }

    // Buttons should be disabled in certain cases. See the original ProjectMetaData notes 
    // The isEnabled implementation is not covered by this tutorial for brevity
    let ariaHiddenValue = props.isEnabled === false ? true : null;
    let tabIndexValue = ariaHiddenValue ? -1 : null;

    return (    
        <div className="ekoshell_projectMetaData" onClick={original_api.hide} style={containerStyle}>
            <div className="projectInfo">
                { props.showBackButton && props.showTitle &&               
                    <button className="title"
                            onClick={(e) => original_api.onClickBackButton(e, props.showBackButton)}
                            aria-label="Back to show description"
                            aria-hidden={ariaHiddenValue}
                            tabIndex={tabIndexValue}>
                        {props.backButtonTitle}
                    </button>                
                }

                {props.showSubtitle && <div className="subTitle">{props.projectTitle}</div>}

                {showWatchTime && <div className="estTime alphaText" >About {remainingTime + (remainingTime > 1 ? ' minutes' : ' minute')} left to play</div>}

                { props.showStartOver &&                
                    <button className="startOver"
                            onClick={original_api.startOver}
                            aria-label="Start over"
                            aria-hidden={ariaHiddenValue}
                            tabIndex={tabIndexValue}>
                        Start over
                    </button>                
                }

                {props.showCredits &&                
                    <button className="credits"
                            onClick={(e) => original_api.onClickCredits(e, props.showCredits)}
                            aria-label="Credits"
                            aria-hidden={ariaHiddenValue}
                            tabIndex={tabIndexValue}>>
                        Credits
                    </button>                
                }


            </div>
            <div className="buttonRow">
                {buttonRowContainer}
            </div>

        </div>

    )
}

Finally we define the new addon meta descriptor and run

let CustomProjectMetaData_MetaDescriptor = {
    component: CustomProjectMetaData_Component,
    api: CustomProjectMetaData_Api,    
}

player.ekoshell.addAddon('ProjectMetaData', CustomProjectMetaData_MetaDescriptor)

The result could look something like this:

image of project metadata custom implementation

Rate this page: X
Tell us more!