https://d226lax1qjow5r.cloudfront.net/blog/blogposts/create-preact-netlify-cms-opentok-health-app-dr/preact.png

Preact.jsとVonageを使ったビデオコーチングによる健康ブログの構築

最終更新日 May 24, 2021

所要時間:7 分

このチュートリアルでは、ライブ・ビデオ・チャット機能を備えたパーソナル・ヘルス・ブログ・ツールとして機能するプログレッシブ・ウェブ・アプリ(PWA)を構築します!PWAは、ネイティブアプリのような感覚と機能を持つように強化されたウェブサイトで、以下のような従来のウェブサイトにはない多くの機能を誇ります:

  • モバイル機器にインストール可能

  • プッシュ通知

  • オフラインサポート

  • ウェブ検索結果やアプリストアから発見可能

そしてウェブ・サーバーのコードを直接編集することで、アプリを更新できる。

では、どうやって始めるのか?

従来のウェブ・アプリであれば、ほぼどんなものでも、PWAに変換できる。 manifest.jsonファイルとService Worker JavaScriptファイルを追加するだけで、どんな従来のウェブアプリでも基本的なPWAに変換できる。しかし、ゼロから始める場合は、いくつかのツールでプロセスを効率化できる。

Create React AppによるPWAとPreact CLIの比較

Reactアプリの作成(CRA)はPWAを作成するためのツールで、開発者の間で絶大な人気を誇っている。 React.jsエコシステムの規模を考えると特にそうだ。デフォルトでは、すべての新しいCRAプロジェクトはPWAである!しかし、PWAは可能な限り高速で高性能であるべきであり、CRAはコードの最適化にはあまり対応していない。

そのため、私たちのデモは Preact.jsを使用して構築されています。Reactの軽量かつ高速な代替であり、PWA向けの同じビルトインサポートを備えています。Preactは、パフォーマンス、サイズ、効率性、互換性を大幅に向上させています。特筆すべきは、サイズがわずか3.5kbで、npmで見つかるReactモジュールと互換性があることだ。ワークフローやコードベースに変更を加えることなくReact/React DOMコードを書くことができるため、学習曲線も大幅に制限される。
ライブラリの違いやPreact独自の機能の詳細については Preact ドキュメント.

プリアクトCLI Preact CLIは、Reactアプリの作成と同じように機能し、同じように使いやすい。最小限のわかりやすいプロジェクト構造で、すぐに使い始めることができます。 そしてプロジェクトを優れたパフォーマンスへと導きます。新しいプロジェクトは、本番環境ではわずか4.5KBのJavaScriptで出荷され、低速のデバイスやネットワークでも3秒未満でインタラクティブになります。注目すべき機能は以下のとおりです:

  • 100/100 ライトハウススコア、箱から出してすぐ

  • ルートの完全自動コード分割

  • JavaScriptの差分サービス

  • sw-precacheによるオフライン・キャッシングのための自動生成サービス・ワーカー

  • CSSモジュール、LESS、Sass、オートプレフィックス機能付きStylusのサポート

  • トラッキング機能によるバンドル/チャンクサイズのモニタリング

  • Push Render Pre-Cache Lazy-load(PRPL)パターンをサポートし、効率的なロードを実現。

機能に関する詳細は Preact CLI ドキュメント.

Preact CLIとVonage Video APIを使用したヘルスコーチングPWAの構築

ユースケース

健康になることは新年の抱負のひとつですか?このアプリケーションは、Preact CLIを使用して、毎日の活動、食事、エネルギーレベル、気分などをブログに書くことができ、進捗状況を追跡するのに役立ちます。 Netlify CMSテンプレートを使用します。あなたのアプリを一緒に働く専門家(パーソナルトレーナー、栄養士、セラピスト)と共有し、プラットフォームから直接ライブビデオコーチングを受けることができます。 VonageビデオAPI.

健康目標から外れてしまった場合、日記をつけることで説明責任を果たせることが証明されている!

その手順:

  1. Preact CLIをインストールしてプロジェクトを作成する

  2. デフォルトのテキストとスタイルを更新する

  3. Vonageビデオプロジェクトの作成

  4. カスタム・ビデオチャットの追加

  5. Netlifyでデプロイする

  6. Netlify CMSで投稿を公開する

前提条件

始める前に必要なものがいくつかある:

  • A Video APIアカウント- まだお持ちでない場合は、無料で作成してください。

  • 開発環境にNodeとNPMがインストールされていること。このチュートリアルでは、Node (> V6.x) と NPM 6 を使用します。ターミナルで以下を実行して、これらがインストールされ、最新であることを確認してください:

node --version
npm --version

必要に応じて nodejs.orgにアクセスして、正しいバージョン(> V6.x)をインストールしてください。

最後まで読み飛ばしたいですか?このチュートリアルのコードは GitHub.

ステップ1:Preact CLIをインストールし、プロジェクトを作成する

アプリケーションをセットアップするには、Preact CLIをグローバルにインストールする必要があります。以下のコマンドを使用してCLIをインストールします。

npm install -g preact-cli

では、この netlify-cmsテンプレートを使って新しいプロジェクトを作りましょう。これで、アプリケーションのベースとなるシンプルなブログができる。プロジェクトの名前を my-project-nameをプロジェクトの呼び名に置き換えてください。

preact create netlify my-project-name

以下のコマンドで開発サーバーを起動する:

cd my-project-name && npm run dev

準備完了!新しいプロジェクトが作成されました。ブラウザーを開いて http://localhost:8080にアクセスし、チュートリアルを続けながらアプリケーションの進捗状況を確認してください。

ステップ2:デフォルトのテキストとスタイルを更新する

私たちが構築しているアプリケーションは、あなた専用のプラットフォームです。 あなた-クリエイティブに、デザインをカスタマイズしてください!手っ取り早く始めたい方は、今のところ デモには基本的なテキストとスタイリングが実装されています。 GitHub.ホームページのデフォルトのテキストを変更するには、以下のコードを更新してください。 home/index.js.スタイリングの変更については style/index.css, home/style.css, blog/styles.cssおよび contact/styles.cssなどが良いでしょう。

インスピレーションが湧いたら、何度でもこのステップを見直し、スタイリングを変えてみてほしい!

ステップ 3: Vonage Videoプロジェクトの作成

あなたの Video API アカウントでをクリックし プロジェクトメニューをクリックし 新しいプロジェクトを作成.以下のオプションがあります 埋め込みプロジェクトの作成または カスタムプロジェクトの作成.Video Chat Embed は、基本的な Video 機能を素早く追加する最も簡単な方法で、コーディングを必要としません。しかし、現在のところ、モバイルアプリとの統合(これは重要な PWA 機能です)や、アーカイブ、画面共有、テキストチャットなどの高度な機能はできません。

OpenTok Project typesOpenTok Project types

それでは カスタムプロジェクトの作成ボタンをクリックします。新しいプロジェクトに名前を付けて 作成ボタンをクリックします。優先コーデックは「VP8」のままで構いません。

Create Custom ProjectCreate Custom Project

次に プロジェクトを見る.プロジェクト詳細ページの下部に、セッションIDとトークンを作成できるプロジェクトツールがあります。退出 ルーティングをセッションのメディアモードにしておき セッションIDの作成ボタンを押してください。

Create Video sessionCreate Video session

最後に、生成されたセッションIDをトークン生成フォームのセッションIDフィールドに貼り付け、トークン生成フォームの トークンの生成ボタンを押します。

注:トークンのデフォルトの有効期限は1時間です。最大30日間まで延長することができます。

Generate OpenTok tokenGenerate OpenTok token

これで、Videoコンポーネントを作り始める準備はすべて整った!

ステップ4: カスタムビデオチャットの追加

Preactの利点のひとつは、ビルドツールを必要とせず、ブラウザ上で使用できることだ。そのため JSXというReactアプリでよく使われる構文をトランスパイルする必要があるため、Preactは代替手段として HTM.カスタム構文を使う代わりに、すでにJavaScriptにあるネイティブのタグ付きテンプレート文字列に依存する。

読みやすくするために、このチュートリアルではほとんどJSXを使います。JSXとHTMを簡単に切り替えることができます。 preact-compat- 詳しくは後述します!

ビデオコンポーネントの作成

その中に componentsフォルダーの中に videoフォルダを作成する。構造は次のようにする:

project structureproject structure

次に、以下のファイルを videoフォルダに追加する:

  • Video.js

  • パブリッシャー

  • 購読者.js

  • チェックボックス

  • connectionStatus.js

にアクセスし src/routes/contact/index.jsにアクセスし Videoコンポーネントをインポートし、return文の中で呼び出します。必要なコンポーネントを作成したら、ビデオチャット画面はアプリのここに配置されます。コードはこのようになります:

import { h } from 'preact';
import { lazy, Suspense } from 'preact/compat';
import style from './style';

let Video;
if (typeof window !== 'undefined') {
    Video = lazy(() => import('../../components/video/video.js'));
}

const photographs = (props) => {
    return (
        <div class={style.pageContact}>
            <h1 class={style.pageTitle}>Hello.</h1>
            <p>Enable your audio and video to begin.</p>
            <div class={style.formWrapper}>
                <Suspense fallback={<div>loading...</div>}>
                    <Video />
                </Suspense>
            </div>
        </div>
    );
};

export default photographs;

注:アプリがプリレンダリングされるとき、コンポーネントとしてのモジュールは、ほとんどのWeb APIが利用できないNode.js環境で実行されます。これをAccountするために、コードを: if (typeof window !== ‘undefined’).このステップをおろそかにすると、デプロイプロセスは必然的に失敗します。

OpenTokをインストールする

ターミナルで

npm install opentok-react

このコマンドにタイプミスがあるのではないかと思うかもしれない。と思うかもしれない。 opentok-preact?興味深いことに、そうではない!

Preact CLIには以下が含まれる。 preact-compatこれは、Reactとの100%の互換性を達成するために動作する、Preactの上の薄いレイヤーである。 preact/compatを追加することで、バンドルサイズが2kbほど大きくなりますが、npmにある既存のReactモジュールの大部分をサポートするという利点があります。また、ワークフローやコードベースに変更を加えることなく、React/ReactDOMコードを書き続けることができる。

ビデオコンポーネントの構築

の値をコピーして挿入する。 API Key, Session IDTokenの値をコピーして video.jsコンポーネントに挿入します。の Video API Account で生成した値です。 ステップ 2.

その セッションは基本的にビデオチャットが行われる部屋です。セッションは無人で始まり、ユーザーの参加を待ちます。

import { h, Component } from 'preact';
import { OTSession, OTStreams, preloadScript } from 'opentok-react';
import ConnectionStatus from './connectionStatus';
import Publisher from './publisher';
import Subscriber from './subscriber';

class VideoComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            error: null,
            connected: false
        };
        this.sessionEvents = {
            sessionConnected: () => {
                this.setState({ connected: true });
            },
            sessionDisconnected: () => {
                this.setState({ connected: false });
            }
        };
    }
    onError = (err) => {
        this.setState({ error: `Failed to connect: ${err.message}` });
    }

    render() {
        return (
            <OTSession
                apiKey=''
                sessionId=''
                token=''
                eventHandlers={this.sessionEvents}
                onError={this.onError}
            >
                {this.state.error ? <div id="error">{this.state.error}</div> : null}
                <ConnectionStatus connected={this.state.connected} />
                <Publisher />
                <OTStreams>
                    <Subscriber />
                </OTStreams>
            </OTSession>
        );
    }
}

export default preloadScript(VideoComponent);

このコンポーネントは、あなたのビデオ(あなたが最初にセッションに参加した場合)を <Publisher />でコーチのビデオを表示します。 <Subscriber />でセッションに参加しているかどうかを表示します。 <ConnectionStatus />.

ビデオパブリッシング機能

セッションが確立されると、セッションIDとトークンは次のように使われる。 公開される。を公開するために使用される。この時点で、セッションの参加者は1人である。

インサート publisher.js挿入する:

import { h, Component } from 'preact';
import { OTPublisher } from "opentok-react";
import CheckBox from "./checkbox";

class Publisher extends Component {
    constructor(props) {
        super(props);

        this.state = {
            error: null,
            audio: false,
            video: false,
            videoSource: "camera"
        };
    }

    setAudio = audio => {
        this.setState({ audio });
    };

    setVideo = video => {
        this.setState({ video });
    };

    changeVideoSource = videoSource => {
        this.state.videoSource !== "camera"
            ? this.setState({ videoSource: "camera" })
            : this.setState({ videoSource: "screen" });
    };

    onError = err => {
        this.setState({ error: `Failed to publish: ${err.message}` });
    };

    render() {
        return (
            <div className="publisher">
                {this.state.error ? <div id="error">{this.state.error}</div> : null}
                <OTPublisher
                    properties={{
                        publishAudio: this.state.audio,
                        publishVideo: this.state.video,
                        videoSource:
                            this.state.videoSource === "screen" ? "screen" : undefined
                    }}
                    onError={this.onError}
                />
                <CheckBox label="Share Screen" checked={this.state.videoSource === "screen"} onChange={this.changeVideoSource} />
                <CheckBox label="Enable Audio" checked={this.state.audio === "audio"} onChange={this.setAudio} />
                <CheckBox label="Enable Video" checked={this.state.videoSource === "video"} onChange={this.setVideo} />
            </div>
        );
    }
}
export default Publisher;

コンポーネントを使って CheckBoxコンポーネントを使うことで、ユーザーが自分の画面を共有したり、オーディオやビデオを有効にしたりすることができます。

ビデオ配信機能

新規ユーザーがアプリを起動すると、アプリサーバーからセッションIDと一意のトークンが送信され、そのトークンを使ってセッションに接続します。接続されると、両ユーザーは 公開オーディオ・ビデオ・ストリームを公開し サブスクライブすることができます。

インサート subscriber.js挿入する:

import { h, Component } from 'preact';
import { OTSubscriber } from "opentok-react";
import CheckBox from "./checkbox";

class Subscriber extends Component {
    constructor(props) {
        super(props);

        this.state = {
            error: null,
            audio: false,
            video: false
        };
    }

    setAudio = audio => {
        this.setState({ audio });
    };

    setVideo = video => {
        this.setState({ video });
    };

    onError = err => {
        this.setState({ error: `Failed to subscribe: ${err.message}` });
    };

    render() {
        return (
            <div className="subscriber">
                Guest
        {this.state.error ? <div id="error">{this.state.error}</div> : null}
                <OTSubscriber
                    properties={{
                        subscribeToAudio: this.state.audio,
                        subscribeToVideo: this.state.video
                    }}
                    onError={this.onError}
                />
                <CheckBox
                    label="Enable Guest Audio"
                    initialChecked={this.state.audio}
                    onChange={this.setAudio}
                />
                <CheckBox
                    label="Enable Guest Video"
                    initialChecked={this.state.video}
                    onChange={this.setVideo}
                />
            </div>
        );
    }
}
export default Subscriber;

もう一度 CheckBoxコンポーネントを使い、2番目のユーザーに、音声やビデオを共有するかどうかの選択肢を与えます。

オーディオおよびビデオ機能の有効化/無効化

インサート checkbox.js挿入する:

import { h, Component } from 'preact';
import { uniqueId } from "lodash";

class CheckBox extends Component {
    constructor(props) {
        super(props);

        this.state = {
            id: uniqueId("Checkbox")
        };
    }

    onChange = e => {
        const checked = e.currentTarget.checked;
        if (checked !== this.props.value) {
            this.props.onChange(checked);
        }
    }

    render() {
        return <div>
            <label for={this.id}>{this.props.label}</label>
            <input id={this.id} type="checkbox" checked={this.checked} onChange={this.onChange} />
        </div>
    }
}

export default CheckBox;

もしユーザーに対してトグルやラジオボタンを表示したい場合は、このコンポーネントで切り替えてください。

チャット接続状況の表示

connectionStatus.jsで、チャットセッションが両方のユーザーに接続されているかどうかを表示します。このステップはオプションですが、お勧めします。

import { h, Component } from 'preact';

class ConnectionStatus extends Component {
    render() {
        let status = this.props.connected ? "Connected" : "Disconnected";
        return (
            <div className="connectionStatus">
                <strong>Coaching Session Status:</strong> {status}
            </div>
        );
    }
}
export default ConnectionStatus;

おめでとうございます!これで、ライブチャットセッションに必要なすべてのコンポーネントが追加されました。チェック http://localhost:8080をチェックしてください。

ステップ 5: Netlify でデプロイする

Netlify でのデプロイを強くお勧めします。 Preact CLI用Netlifyボット用の Netlify ボットは、ワンクリックで CMS 対応の健康アプリを起動できるため、Netlify でのデプロイを強くお勧めします。ボットがGitHub(またはGitLab)アカウントに接続されると、健康アプリ用のリポジトリを作成します。デプロイが完了したら、ローカルの変更をリポジトリにプッシュします。さらに変更をプッシュするたびに、ボットが自動的にグローバルCDNにデプロイします。

Netlify bot for easy deploymentNetlify bot for easy deployment

ステップ 6: Netlify CMSで投稿を公開する

テンプレートのデプロイプロセスにより、新しいアプリへの招待メールが送信されます。デプロイが完了するまで待ち、リンクをクリックして招待を承認します。アプリが開き、パスワードを作成するプロンプトが表示されます。パスワードを入力してサインインすると、CMSにアクセスできます。次回からは <yoursiteaddress.com>/admin/からCMSにアクセスできます。このプラットフォームに慣れるために、プレースホルダーの投稿を編集して公開してみてください。

CMS dashboardCMS dashboard

CMSを設定すれば、基本的なヘルスコーチングPWAは完成です!

監査

PWAを監査するには、Googleの ライトハウスを使うか、Firefoxの 拡張機能.Lighthouseはモバイルデバイスをシミュレートし、インターネットを3G速度にスロットルし、スコアと改善のためのアドバイスを生成します。

次はどうする?

このアプリケーションには、より実用的で使い勝手の良いものにするための改良の余地がいくつもある。

  • ビデオ・コーチング・セッションをアーカイブして記録しましょう。ビデオをオフラインで視聴したい場合は、以下のカスタム機能を追加してください。 カスタム機能を追加してください。

  • 使用しているその他の健康ツール(My Fitness Pal APIやFitBit APIなど)からデータをインポートします。これにより、トレーナーはより正確なコーチングを提供できるようになります。

  • 新しい投稿が公開されたら、SMS(またはWhatsApp、Viber、Facebook Messengerのメッセージ)をコーチに送信。Vonage メッセージAPIをご覧ください。

何か問題が発生したり、質問がある場合は、私たちの コミュニティ・スラック.お読みいただきありがとうございました!

Preact.jsチームには、デモ・アプリの作成にご協力いただき、ありがとうございました。

シェア:

https://a.storyblok.com/f/270183/250x250/54e86bba88/nahrinjalal.png
Nahrin Jalalヴォネージの卒業生

NahrinはVonageのデベロッパー・エデュケーターでした。インクルーシブなコミュニティの構築、実用的なソフトウェア・ソリューションによる現実世界のニーズへの対応、あらゆるスキルレベルの人がアクセスできる技術コンテンツの作成に情熱を注いでいる。