PowerApps で テレビでよくあるTwitterが流れるやつを作ってみる

# 本投稿について
本投稿は、Low-Code/No-Code Advent Calendar 2018 21日目の記事です。

# ちなみに今の状況
明日の登壇資料鋭意作成中ｗｗｗ

# さて本題
明日のイベントで使う発表用アプリにて、Twitterの内容をこんな風に流すと面白いよなと思い立って作ったわけですよ！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/269159/695aa6d8-20f1-8071-8e81-ade2ff4eeaba.png)

※テレビのキャプチャをどっかから引っ張ってきているのでモザイク多めですｗｗ

## というわけで作ったのがこちら
![twitter.gif](https://qiita-image-store.s3.amazonaws.com/0/269159/f55eacfe-f437-e086-c7f1-a00787aba17b.gif)

# 作り方
## 材料
- 表示用の枠組み画像(png形式)×1
![image.png](https://qiita-image-store.s3.amazonaws.com/0/269159/b9c8c6fd-3b5b-859d-4d36-022e9d4479aa.png)

- タイマーコントロール ×5
    - TwitterStart_Control (ツイート表示開始スクロール制御用)
    - TwitterEnd_Control (ツイート表示完了スクロール制御用)
    - TwitterEndwait_Control (ツイート表示中待ち制御用)
    - TweetGetIconColorControl (ツイート表示中の矢印アイコン点滅切替制御用)
    - TweetGetControl (ツイート取得処理制御用)
- ツイッター表示用ラベル (TwitterText) ×1
- 表示中の点滅アイコン (TweetGetIcons) ×1

## 変数
|変数名|型|用途|
|:--|:--|:--|
|SearchTweet|Text|表示するツイートの検索文字列|
|beforetweetid|Record|前回表示したツイートのID|
|TweetStart|Boolean|ツイート表示開始スクロール実行判定|
|TweetEnd|Boolean|ツイート表示完了スクロール実行判定|
|TweetViewWait|Boolean|ツイート表示中判定|
|TweetIconMode|Number|矢印アイコンの点滅切替用|

## Screen1
### OnVisible プロパティ
```
UpdateContext({SearchTweet:"PowerApps"});
ClearCollect(tweetdata,Twitter.SearchTweet(SearchTweet,{maxResults:1}));
UpdateContext({beforetweetid:First(tweetdata.TweetId)});
UpdateContext({tweetStart:false,tweetEnd:true,TweetViewWait:false})
```

## TwitterStart_Control
新規ツイートが検知されると、このタイマーが動き出し
スクロールが開始されます。

### AutoStart 及び Start プロパティ
自動開始及び停止を制御するプロパティになります。
Trueになることでタイマーが実行されます。

```
tweetStart
```

### Duration プロパティ
実行期間をmsecで指定します。

```
2000
```

### OnTimerEnd プロパティ
Duration時間経過後に実行する処理を指定します。
ツイートのスクロールが開始されて、表示位置まで到達した後は
しばらくそのままキープさせたいので、管理するフラグ変数を更新します。


```
UpdateContext({TweetViewWait:true,tweetStart:false})
```

## TwitterEnd_Control
ツイート表示を一定期間行った後、このタイマーが動き出し
表示画面をスクロールさせ画面上から消し去ります。

### AutoStart 及び Start プロパティ
自動開始及び停止を制御するプロパティになります。
Trueになることでタイマーが実行されます。

```
tweetEnd
```

### Duration プロパティ
実行期間をmsecで指定します。

```
2000
```

### OnTimerEnd プロパティ
Duration時間経過後に実行する処理を指定します。
表示したツイートIDを格納するのと
各種タイマーをリセットし、次回に備えます。

```
UpdateContext({beforedisptweetid:First(tweetdata).TweetId});
Reset(TwitterStart_Control);
Reset(TwitterEnd_Control);
Reset(TwitterEndwaitControl)
```

## TwitterEndwait_Control
ツイート表示を一定期間固定します。

### AutoStart 及び Start プロパティ
自動開始及び停止を制御するプロパティになります。
Trueになることでタイマーが実行されます。

```
TweetViewWait
```

### Duration プロパティ
実行期間をmsecで指定します。

```
5000
```

### OnTimerEnd プロパティ
Duration時間経過後に実行する処理を指定します。
TwitterEnd_Controlタイマーを開始するためのフラグをセットします。

```
UpdateContext({tweetEnd:true,TweetViewWait:false})
```

## TweetGetIconColorControl
ツイート表示中に矢印アイコンを点滅させます。
これは常に切り替えていますので
繰り返し、自動開始、自動一時停止はすべてONにしてください。

### Duration プロパティ
実行期間をmsecで指定します。

```
750
```

### OnTimerStart プロパティ
タイマー開始時に実行される処理です。
TweetIconModeを1と0で交互に切り替えます。

```
If(tweetIconMode = 1,
    UpdateContext({tweetIconMode:0}),
    UpdateContext({tweetIconMode:1})
)
```

## TweetGetControl
ツイートの取得を制御します。
こちらも常に動かすため
繰り返し、自動開始、自動一時停止はすべてONにしてください。

### Duration プロパティ
実行期間をmsecで指定します。
Twitter APIの仕様上、検索する処理は
15分に180回以内という制限がありますので
単純計算すると900/180となり 6秒 間隔で実行する必要があります。
一応安全を考慮し、10秒としておきましょう。

```
10000
```

### OnTimerEnd プロパティ
Duration経過後に実行される処理です。
最初のIF文では、スクロール表示中にツイート内容が変わると非常にかっこ悪いので表示中はツイートを取得しないようにしています。
表示していないときの各フラグは

- tweetStart:False
- TweetEnd:True
- TweetViewWait:False

ですので、条件式にその旨記載します。
条件式に合致したときのみ、Twitterの検索処理（SearchTweet）が実行されます。
最新データ1件だけ欲しいので、MaxResultは1としています。

2番目のIF分では、前回表示したものと同じツイートを毎回出すのもかっこ悪いですので、前回表示したツイートのIDを確保しておき、それと比較して今回違うものだった場合は表示するように制御しています。

```
If((!(tweetStart) && tweetEnd && !(TweetViewWait)),
	ClearCollect(tweetdata,Twitter.SearchTweet(SearchTweet,{maxResults:1})
);
If(beforetweetid.TweetId <> First(tweetdata.TweetId).TweetId,
	UpdateContext({tweetStart:true,tweetEnd:false,beforetweetid:First(tweetdata.TweetId)})),
	""
)
```

## TwitterText
ツイートの表示やスクロールはこのラベルを使用します。

### X プロパティ
横方向の表示位置を制御しています。
これには、TwitterStart_Control及びTwitterEnd_Controlの値（経過時間）を使っています。
タイマーが進むと、経過時間の値が増えていきますので、これを使用してスクロールアニメーションを表現しているわけです。

```
// 何もタイマーが動いていない時
If((TwitterStart_Control.Value = 0) && (TwitterEnd_Control.Value = 0),
	192+(TwitterStart_Control.Duration),
	
	//スタートタイマーが開始されているとき
	If((TwitterStart_Control.Value > 0) && (TwitterEnd_Control.Value = 0),
		//Xの値を2192から減算させる。最終終了位置 X:192
		192+(TwitterStart_Control.Duration-TwitterStart_Control.Value),
		//終了タイマーが開始されたとき
		//Xの値を192から減算させる。最終終了位置 X:-1808
		192-TwitterEnd_Control.Value
	)
)

```

### Text プロパティ
ツイートの内容を表示します。
こちらは、先頭にツイートした人の表示名、その後にツイート内容を表示させています。
ただし、ツイート内容は改行されると、改行コードが付加されてしまう為
改行コードを除外しています。

```
Concatenate(
	First(tweetdata).UserDetails.FullName,
	":",
	Substitute((First(tweetdata).TweetText),Char(10),"")
)
```

なお、この改行コードの除外を色々試してみても全然ダメだったのですが、PowerAppsの中の人である、Mr.Dangからアドバイスを頂き、無事1行で表示させることができました！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/269159/ce0085ba-84e1-cb98-45d4-7f4c7ba6ae5b.png)


## TweetGetIcons
ツイート固定表示中に点滅するアイコンです。

### Color プロパティ
TweetIconModeの変数値によって色を切り替えています。

```
If(tweetIconMode = 0,RGBA(250, 155, 112, 1),RGBA(168, 0, 0, 1))
```

### Visible プロパティ
ツイート固定表示中以外は非表示としたいですよね！
なので、このようにしています。

```
TweetViewWait
```

以上で終わりです！

# まとめ
いかがだったでしょうか。。。
ちょっとつらつら書いたため長ったらしくなりややこしいと思われる部分もあるかと思いますが
実際に書いているコードはほんのわずかです！

これをまともに書こうとすると結構大変なんじゃないかなと思います。
なので、まずはPowerAppsを使っていろんなアプリを作ってみて
作る楽しさを実感してみてください！
また、SNSを活用することで、困ったことなどは私を含めたいろんな方がアドバイス頂けたりします！
恐れずに何事も前向きに取り組んでいきましょうね♪