Twitterクライアントにプロフィールページを追加。

[iPhone5se](https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwjo1JOrw8bKAhVKJpQKHRzuBR4QqQIIHDAA&url=http%3A%2F%2Fiphone-mania.jp%2Fnews-99149%2F&usg=AFQjCNHlyVyWvyMfE8Lt0p95HpiTtZY_OQ&sig2=i78BuNsJVg_XbI96UuqmCg) の発表を今か今かと心待ちにしております。:iphone: 

[angularjs で Twitter クライアントを作成し AWS.S3 で動かす](http://qiita.com/Kurom96/items/59f540619d5cd651dbaf) の続きです。
前回作成した mytiwtter をいじります。
一緒にやってみたい方は [こちらのブランチ](https://github.com/KazuhikoKuroda/mytwitter/tree/phase1) から取得してください。

## やりたいこと

* プロフィールページの追加
 * コントローラの追加
 * Twitterサービスから他の情報を取得

最終的にこのようなプロフィールページができあがります。
<img width="400" alt="スクリーンショット 2016-01-26 10.57.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/86201/3372f913-3497-af44-6d4d-57f5fe534026.png">
プロフィール情報を表示して、自分のツィートを下にゔぁーっ、と。

## yeomanでルートの追加

前回仕様した `generator-angular` で新しいルートを作成します。

```bash
$ cd mytwitter
$ yo angular:route profile
   invoke   angular:controller:/Users/kuro/Documents/Practice/mytwitter/node_modules/generator-angular/route/index.js
   create     app/scripts/controllers/profile.js
   create     test/spec/controllers/profile.js
   invoke   angular:view:/Users/kuro/Documents/Practice/mytwitter/node_modules/generator-angular/route/index.js
   create     app/views/profile.html
```

結果、何がどうなったか？と言いますと、ファイルが３つ追加されています。
profileのテンプレート、コントローラとテストファイルです。

`index.html` に `prifile.js` の `script` タグが追加されています。

```html:mytwitter/app/index.html
    <!-- build:js({.tmp,app}) scripts/scripts.js -->
    <script src="scripts/app.js"></script>

    <script src="scripts/services.js"></script>
    <script src="scripts/controllers/main.js"></script>
    <script src="scripts/controllers/about.js"></script>
    <script src="scripts/controllers/profile.js"></script>
    <!-- endbuild -->
```

あと`app.js`にルートが追加されていますね。

```js:mytwitter/app/scripts/app.js
      .when('/profile', {
        templateUrl: 'views/profile.html',
        controller: 'ProfileCtrl',
        controllerAs: 'profile'
      })
```

`git diff --cached` 等で差分見るとわかりやすいです。
私は、SourceTree を使っているのでそちらで見ます。
<img width="400" alt="スクリーンショット 2016-01-25 15.53.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/86201/ad02d468-9ee5-f7f6-2939-6407f86a073a.png">

## ナビ追加

`index.html` のナビに `Profile` を追加します。

```js:mytwitter/app/index.html
<ul class="nav navbar-nav">
  <li class="active"><a href="#/">Home</a></li>
  <li><a ng-href="#/profile">Profile</a></li>
  <li><a ng-href="#/about">About</a></li>
  <li><a ng-href="#/">Contact</a></li>
</ul>
```

これでプロフィールページが表示できるようになりました。
`grunt serve` で確認してみてください。

## サービス

以下の２機能をTwitterServiceに追加します。

* プロフィール情報の取得
* ユーザーのTweet取得

プロフィールの取得
TwitterAPI のエンドポイント [users](https://syncer.jp/twitter-api-matome#sec-7-10) からも取得可能ですが、ここでは `OAuth` の `me()` で取得します。
詳しくは [こちら](http://docs.oauth.io/#user-data-api) を参照してください。

```js:mytwitter/app/scripts/services.js
getMe: function() {
	var deferred = $q.defer();

	authResult.me()
		.done(function(result) {
			deferred.resolve(result);
		})
		.fail(function(err) {
			deferred.reject(err);
		});
	return deferred.promise;
},
```

ユーザータイムラインの取得

```js:mytwitter/app/scripts/services.js
getUserTimeline: function() {
	var deferred = $q.defer(),
		url = '/1.1/statuses/user_timeline.json';

	authResult.get(url)
		.done(function(result) {
			deferred.resolve(result);
		})
		.fail(function(err) {
			deferred.reject(err);
		});
	return deferred.promise;
}
```

## プロフィールページ

### デザイン

画面のデザインをパパッと作っちゃいましょう。
今回は、[layoutit](http://www.layoutit.com/) というサービスを利用します。
`Bootstrap` のコンポーネントをドラッグ＆ドロップで配置でき、プレビューや共有、ダウンロードができます。べんり。

<img width="400" alt="スクリーンショット 2016-01-25 15.47.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/86201/ec146a42-9180-4e61-b048-15235d52961d.png">

ダウンロードボタンを押下して表示された `HTML` を `profile.html` にペーストして、前回同様に angularjs のディレクティブを記述します。

```html:mytwitter/app/views/profile.html
<div class="container-fluid">
	<div class="row" ng-show="profile.showProfile">
		<div class="col-md-3 text-center">
			<img ng-src="{{profile.info.avatar}}" class="img-rounded" />
			<div>
				<small>{{profile.alias}}</small>
			</div>
		</div>
		<div class="col-md-9">
			<dl class="dl-horizontal">
				<dt>Name</dt>
				<dd>{{profile.info.name}}</dd>
				<dt>bio</dt>
				<dd>{{profile.info.bio}}</dd>
				<dt>location</dt>
				<dd>{{profile.info.location}}</dd>
				<dt>url</dt>
				<dd><a href="{{profile.info.url}}">{{profile.info.url}}</a></dd>
				<dt>website</dt>
				<dd><a href="{{profile.info.website}}">{{profile.info.website}}</a></dd>
			</dl>
		</div>
	</div>
	<hr>
	<div class="row">
		<div class="col-md-12">
			<div class="media well" ng-repeat="tweet in profile.tweets">
				<div class="col-md-2">
					<img ng-src="{{tweet.user.profile_image_url}}" class="img-circle">
				</div>
				<div class="col-md-10">
					<small>{{tweet.user.name}}</small>
					<br> <span ng-bind-html="tweet.text"></span>
				</div>
			</div>
		</div>
	</div>
</div>
```

### コントローラ

最後にコントローラです。
`twitterService` を初期化して、プロフィール情報とユーザータイムラインを取得します。プロフィール画面は、メイン画面の認証情報を引き継いでいるため、サインアウトした状態だと何も表示しません。

```js:mytwitter/app/scripts/controllers/profile.js
'use strict';

function ProfileControl(twitterService) {
	var vm = this;
	vm.info = {};
	vm.tweets = [];
	vm.showProfile = false;

	twitterService.initialize();

	if (twitterService.isReady()) {
		twitterService.getMe()
			.then(function(result) {
				vm.info = result;
				vm.showProfile = true;
			}, function() {
				// error
			});

		twitterService.getUserTimeline()
			.then(function(result) {
				vm.tweets = vm.tweets.concat(result);
			}, function() {
				// error
			});
	}
}

angular.module('mytwitterApp')
	.controller('ProfileCtrl', ProfileControl);
```

`grunt serve` で確認し、問題なければ `grunt build` して `dist` ディレクトリ配下を S3 にアップして確認、と。
この辺の手順については、前回を参照してください。

<img width="400" alt="スクリーンショット 2016-01-25 18.30.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/86201/1da4bd02-e369-d43b-4d13-320b8e4659ed.png">

iPhone5s で見るとこんな感じです。
<img width="200" alt="スクリーンショット 2016-01-25 18.30.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/86201/22fe48e6-b350-63d0-e53d-573e776fa014.jpeg">

### おまけ：フィルタで画像URL置換

なんかダサい。
プロフィール用のアイコンが小さい。
もちっと大きいのに変えよう。

文字列置換のフィルタを登録します。
画像URL内の `_normal` を `_200x200` に変更してみます。

```js:mytwitter/app/scripts/app.js
	.filter('replace', function() {
		return function(input, pattern, replacement) {
			if ((typeof input) === 'string'){
				return input.replace(pattern, replacement, 'g');
			} else {
				return input;
			}
		};
	});
```

`profile.avatar` を表示している `img` タグを以下のように書き換えます。

```html:mytwitter/app/views/profile.html
<img ng-src="{{profile.info.avatar| replace:'_normal':'_200x200'}}" class="img-rounded" style="width:100%; max-width:200px;"/>

```

<img width="400" alt="スクリーンショット 2016-01-26 10.57.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/86201/3372f913-3497-af44-6d4d-57f5fe534026.png">

![スクリーンショット 2016-01-26 10.58.44.png](https://qiita-image-store.s3.amazonaws.com/0/86201/1cf40f2c-b700-4441-df97-465e18b1ab23.png)
:thumbsup: