Timeline機能: Front-end

いよいよTimeline機能のフロントエンドを実装していきましょう。

Timeline

./src/containers/Timeline.jsを作成し、編集していきます。

touch ./src/containers/Timeline.js

以下のTimeline.jsの中身をコピーし、./src/containers/Timeline.jsを置き換えてください。

主なポイントは以下です。

Timelineの取得

const getPosts = async (type, currentUser, nextToken = null) => {
  const res = await API.graphql(graphqlOperation(listTimelines, {
    userId: currentUser.username,
    sortDirection: 'DESC',
    limit: 20, //default = 10
    nextToken: nextToken,
  }));
  dispatch({ type: type, posts: _.map(res.data.listTimelines.items, 'post') })
  setNextToken(res.data.listTimelines.nextToken);
  setIsLoading(false);
}
  • AllPosts.jsではlistPostsを利用していましたが、今回はlistTimelinesを利用しています
  • userIdに現在のログインユーザーのusernameを指定しています

Sidebar.jsとApp.jsにTimelineへの参照を追加

App.jsの変更

以下のApp.jsの中身をコピーし、./src/App.jsを置き換えてください。

  • App.js (2 kb)
  • <HashRouter>
      <Switch>
        <Route exact path='/' component={Timeline} />
        <Route exact path='/global-timeline' component={AllPosts} />
        <Route exact path='/:userId' component={PostsBySpecifiedUser}/>
        <Redirect path="*" to="/" />
      </Switch>
    </HashRouter>
    
    • /へアクセスがあった場合、これまでのAllPostsでなく、Timelineをレンダリングするよう変更しました

    Sidebar.jsの変更

    以下のSidebar.jsの中身をコピーし、./src/containers/Sidebar.jsを置き換えてください。

    ポイントは以下です。

    const onPost = async () => {
      /** Before
      const res = await API.graphql(graphqlOperation(createPost, { input: {
        type: 'post',
        content: value,
        timestamp: Math.floor(Date.now() / 1000),
      }})); 
      */
    
      //After
      const res = await API.graphql(graphqlOperation(createPostAndTimeline, { content: value })); 
    
      setValue('');
    }
    
    • createPostの代わりに、新しく作成したcreatePostAndTimelineを呼び出すようにします

    クラウドへの反映

    ここまでの内容をクラウドに反映しましょう。実行には数分かかります。

    $ amplify publish
    

    $ amplify mock apiを動かしている状態で$ amplify push$ amplify publishを実行した場合、Parameters: [authRoleName] must have valuesというエラーがでて$ amplify push$ amplify publishが失敗する場合があります。 その場合は、Ctrl + C$ amplify mock apiのプロセスを中断してから、$ amplify push$ amplify publishを実行してください。

    動作確認

    1. ウェブブラウザでhttps://production.XXXXXXXXXXX.amplifyapp.comにアクセスし、ログインしましょう(ユーザーA)
    2. 他のブラウザを用いて他のユーザー(ユーザーB)でログインしておきましょう
    3. お互いのアカウントをフォローする前は、PostをしてもGlobal Timelineにしか相手のPostが表示されないことを確認します
    4. ユーザーAのGlobal Timelineから、ユーザーBのPostのアイコンをクリックし、ユーザーBをフォローしましょう
    5. フォロー後にユーザーBでPostを行い、ユーザーAのTimeline上にユーザーBのPostが表示されることを確認しましょう。

    現在はフォロー後に作成されたPostしかTimelineに表示されません。 フォローするまえのPostもTimelineに表示したい場合は、createFollowRelationshipMutationが実行された際に、Followeeの過去のPostをTimelineに複製するような実装が必要です。 ($ amplify add function@functionや、Amazon DynamoDB Streamsを実装することで実現できます)

    現在はフォロー解除後でも、フォローしてからフォロー解除するまでにTimelineに表示されたPostは残り続けます。 フォロー解除後に該当のユーザーのPostをTimelineから削除したい場合は、deleteFollowRelationshipMutationが実行された際に、Timelineから該当ユーザーのPostを削除する実装が必要です。 ($ amplify add function@functionや、Amazon DynamoDB Streamsを実装することで実現できます)