react-nativeモジュール使い方メモ（タイマー・Youtube）

# はじめに
- 自分用メモ
- 適宜増やします。

# package.json
抜粋

``` json
{
    "react-native": "^0.62.2",
    "react-native-countdown-circle-timer": "^2.3.10",
    "react-native-svg": "^12.1.0",
    "react-native-youtube": "^2.0.1",
    "react-native-sound": "^0.11.0",
    "react-native-volume-control": "^1.0.1",
  }
}
```

# react-native-countdown-circle-timer
ちょっとお洒落なカウントダウンタイマーコンポーネント
- [react-native-countdown-circle-timer](https://github.com/vydimitrov/react-countdown-circle-timer)
- [サンプルコード](https://snack.expo.io/@vydimitrov/countdown-circle-timer?session_id=snack-session-8tgDhia5f&preview=true&platform=ios&iframeId=4a80oah677&theme=light)

### 注意点
- `colors`は `["カラーコード", "表示する割合"]`の配列として記載すること。
    - サンプルでは最後の0.33が記載されていないため注意。
- `child`に`(remainingTime, animatedColor)`を渡すことで、残り時間(秒)を外周の色と揃えた状態で表示することができる。
- `react-native-svg`を共にインストールすること。

``` bash
yarn add react-native-countdown-circle-timer
yarn add react-native-svg
```

``` typescript
<CountdownCircleTimer
    isPlaying
    duration={10}
    colors={[["#004777", 0.33], ["#F7B801", 0.33], ["#A30000", 0.33]]}
    onComplete={() => {
        this.timeupAlert()
        return [false, 1000] // タイマーのループをするかどうか
    }}
>
    {(info) => {    // 「※1 childrenについて」にて補足
        const { remainingTime, animatedColor } = info // animatedColorはTimePropsに存在しないが取得可能
        this.beforeAlert(remainingTime)
        return (
            <View style={{ alignItems: 'center' }}>
                <Text>残り時間</Text>
                <View style={{ flexDirection: 'row', alignItems: 'center' }}>
                    <Animated.Text style={{ color: animatedColor, fontSize: 25 }}>
                        {Math.floor((remainingTime % 3600) / 60)}
                    </Animated.Text>
                    <Text>分</Text>
                    <Animated.Text style={{ color: animatedColor, fontSize: 25 }}>
                        {remainingTime % 60}
                    </Animated.Text>
                    <Text>秒</Text>
                </View>
            </View>
        )
    }
    }
</CountdownCircleTimer>
```
### ※1 childrenについて
React側の記事ですがこちらを参照
- [コンポジション vs 継承](https://ja.reactjs.org/docs/composition-vs-inheritance.html)

# react-native-volume-control
デバイス自身の音量を調整する。
- [react-native-volume-control](https://www.npmjs.com/package/react-native-volume-control)

### 注意点
- max音量を`1`とする。
- 類似パッケージが多いため注意すること。

``` typescript
import VolumeControl from "react-native-volume-control"

playSound = () => {
    VolumeControl.change(0.5);
}
```

### タイムアップアラーム音を鳴らす
`react-native-sound`を利用。

```typescript
import Sound from 'react-native-sound'
import VolumeControl from "react-native-volume-control"
const sound: Sound = new Sound('alarm.mp3', Sound.MAIN_BUNDLE)

playSound = () => {
    VolumeControl.change(VOLUME);  // 再生前にボリュームを上げる
    sound.setNumberOfLoops(-1)     // 効果音をループさせる
    sound.play()                   // 再生
    setTimeout(() => {             // 規定時間鳴らしたら再生を停止する
        sound.stop()
    }, PLAYBACK_TIME)
}
```

スヌーズをしたいときは`setInterval`を利用。

- `setInterval`の第一引数には**オブジェクトまたは無名関数**を渡すこと
    - `undefined is not an object (evaluating 'func.apply')`のエラーが発生する
    - 参考）[Why does the setInterval callback execute only once?](https://stackoverflow.com/questions/10182714/why-does-the-setinterval-callback-execute-only-once)
- スヌーズを止める際に`clearTimeout(id)`を実行すること

```typescript
const id = setInterval(this.snooze, SNOOZE.TIME)

snooze = () => {
    this.playSound()
    Alert.alert(SNOOZE.TITLE,SNOOZE.MESSAGE,[{
        text: 'OK',
        onPress: () => {
            sound.stop()
        }
    }])            
}
```

# react-native-youtube
Youtubeを再生するコンポーネント
- [react-native-youtube](https://github.com/davidohayon669/react-native-youtube)
- [React NativeでYoutubeを表示する](https://dev-yakuza.posstree.com/react-native/react-native-youtube/#%E3%83%93%E3%83%87%E3%82%AA%E5%86%8D%E7%94%9F)

### 注意点
- APIkeyはGoogleCloudPlatformの「APIとサービス」から作成すること。（無料）
- APIkeyの作成方法は [Youtube Data API Key の取得手順](http://piyohiko.webcrow.jp/kids_tube/help/index.html) を参照のこと
- Youtubeコンポーネントの上部に別のオブジェクトを配置しないこと。
    - 干渉してコントローラーが動かなくなるなどのエラーが発生する
    - 上部に別のオブジェクトを配置したい場合はViewを分けること。
- `play`プロパティは効かない場合もあるため注意
- `fullscreen`プロパティはiPadでは動作しない（コントローラーから手動でフルスクリーンモードにすることもできない）
- 再生の停止は`play`プロパティのtrue/falseで制御可能
- YoutubeAPI自体ではないため、再生画面のボリュームコントロールなどは実装されていない

``` typescript
_youTubeRef = React.createRef();
render() {
    return (
        <View style={{ backgroundColor: 'black', height: '50%' }}>
                <React.Fragment>
                    <YouTube
                        apiKey={'取得したAPIキー'}
                        ref={this._youTubeRef}
                        videoIds={videoIds}
                        play={this.state.isVideoPlay}
                        fullscreen={false}
                        loop={true}
                        showFullscreenButton={true}
                        showinfo={false}
                        rel={false}
                        style={{ alignSelf: 'stretch', height: '100%' }}
                        onError={(e) => console.log('onError: ', e.error)}
                    />
                </React.Fragment>
        </View>
        )
}
```