React Settings Page

Hi everyone,

I wanted to share a project I’ve been working on, a React settings page. It allows to use all the homey functions inside the React app. I used TypeScript since I prefer it over JS but you can also use JS.
Also, I used class components instead of the more modern functional components, but this is purely personal preference.

You need 3 files to make it work.

public/index.html

<!DOCTYPE html>
<html lang="en" style="padding: 0 !important;">
<head>
    <meta charset="utf-8"/>
    <script data-origin="settings" src="/homey.js" type="text/javascript"></script>
    <script type="text/javascript">
      function onHomeyReady(Homey) {
        window.Homey = Homey;
        Homey.ready();
        window.HomeyReady = true;
      }
    </script>
</head>
<body style="padding: 0 !important; min-height: auto !important;">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

The index.html binds the Homey object to the window object. Homey can be used inside React using the window scope. The body style is optional, it makes the app full size so it looks better.
For development, you can include the homey.css in this index.html file.
<link href="https://<cloud-id>.connect.athom.com/manager/webserver/assets/css/homey.css" rel="stylesheet">

global.d.ts

import {HomeyAPI} from './Homey';

declare global {
    interface Window {
        Homey: HomeyAPI;
        HomeyReady: boolean;
    }
}

export const Homey: HomeyAPI = window.Homey;

This makes the window.Homey object available in the typescript scope.

Homey.ts

export interface HomeyAPI {
    __(key: string, tokens?: Object): string;

    ready(callback?: () => void): void;

    alert(message: string, callback?: () => void): void;

    confirm(eventName: string, listener: HomeyEventListener): Promise<any>;

    popup(url: string): void;

    trigger(eventName: string, data?: Record<string, any>): Promise<any>;

    get(key: string, callback?: (value: any) => void): Promise<any>;

    set(key: string, value: any, callback?: (err: any) => void): Promise<any>;

    unset(key: string, callback?: (value: any) => void): Promise<any>;

    api(key: string, path: string, body: any, callback?: () => void): Promise<any>;
}

export default class Homey {
    public static __(key: string, tokens?: Object) {
        if (window.HomeyReady)
            return window.Homey.__(key, tokens) ?? key;
        else return key;
    }

    public static set(key: string, value: any, callback?: (value: any) => void) {
        if (window.HomeyReady) return window.Homey.set(key, value, callback);
    }

    public static unset(key: string, callback?: (value: any) => void) {
        if (window.HomeyReady)
            return window.Homey.unset(key, callback);
    }

    public static get(key: string, callback?: (value: any) => void) {
        if (window.HomeyReady) return window.Homey.get(key, callback);
    }

    public static api(key: string, path: string, body: any, callback?: () => void) {
        if (window.HomeyReady) return window.Homey.api(key, path, body, callback);
    }

    public static alert(message: string, callback?: () => void) {
        if (window.HomeyReady) return window.Homey.alert(message, callback);
    }

    public static confirm(message: string, callback: HomeyEventListener) {
        if (window.HomeyReady) return window.Homey.confirm(message, callback);
    }

    public static popup(url: string) {
        if (window.HomeyReady) return window.Homey.popup(url);
    }

    public static trigger(eventName: string, callback?: (err: any) => void) {
        if (window.HomeyReady) return window.Homey.trigger(eventName, callback);
    }
}

export interface HomeyEvent {
    name: string;
    data?: Record<string, unknown>;
}

export interface HomeyEventListener {
    (event: HomeyEvent): void;
}

For the full project, take a look here.
Also, I would recommend making a check to see if “window.HomeyReady” is true before displaying any data. Like here.

You can use all the Homey function calling the static Homey file. e.g. Homey.set('myVar', true, (err) => console.log('hello world')); This is how I used it to get the data when it was needed.

If you have any questions, let me know.

Best regards :v:

4 Likes