Development Update #1: My Steem TV Show and Movie App by jrawsthorne

View this thread on steempeak.com
· @jrawsthorne ·
$163.59
Development Update #1: My Steem TV Show and Movie App
#### Repository
https://github.com/jrawsthorne/review.app

### New Features
- ~~User authentication system using SteemConnect~~ (uh-oh)
- ~~Database to store ids of posts~~
- ~~Posts need to be displayed with the linked metadata~~
- ~~Custom API to allow for more complex querying of posts~~

### #1 Database
The database needed to store a variety of information about a post including a way to reference each post. The common way to query the steemit api is by author and the permanent link so these fields were mandatory. On the front end I also wanted to be able to filter by the type of post, for example a review, or just a discussion. The database will also store the metadata relating to each post. For a review of a TV episode this would include the MovieDB ID, season number and episode number. To reduce the number of api requests to TheMovieDB I decided to also store the title, which would be the name of the show in this case, as well as the paths to relevant images. There will also be a rating field. In the future I will add this to a user model so all users can rate something.

This is the schema ([GitHub Link](https://github.com/jrawsthorne/review.app/blob/804400323a6c981978841f523469d11182c38776/src/apis/models/Post.js#L3-L55))
```javascript
const schema = new mongoose.Schema(
  {
    author: {
      type: String,
      required: true,
    },
    permlink: {
      type: String,
      required: true,
      unique: true,
    },
    postType: {
      type: String,
      required: true,
    },
    mediaType: {
      type: String,
      required: true,
    },
    tmdbid: {
      type: Number,
      required: true,
    },
    title: {
      type: String,
      required: true,
    },
    posterPath: {
      type: String,
    },
    backdropPath: {
      type: String,
    },
    episodePath: {
      type: String,
    },
    seasonPath: {
      type: String,
    },
    seasonNum: {
      type: Number,
    },
    episodeNum: {
      type: Number,
    },
    rating: {
      type: Number,
    },
  },
  {
    timestamps: true,
  },
);
```

### #2 API routes

Retrieve post by author and permlink with related metadata ([GitHub Link](https://github.com/jrawsthorne/review.app/blob/804400323a6c981978841f523469d11182c38776/src/apis/routes/posts.js#L8-L17))
```javascript
router.get('/@:author/:permlink', (req, res) => {
  const { author, permlink } = req.params;
  Post.findOne({ author, permlink })
    .then((post) => {
      if (!post) {
        return res.status(404).json({ error: "Post couldn't be found" });
      }
      return res.json(post);
    });
});
```

Front end makes the request and merges with the data from the steemit api ([GitHub Link](https://github.com/jrawsthorne/review.app/blob/804400323a6c981978841f523469d11182c38776/src/actions/postActions.js#L52-L65))
```javascript
export const fetchPost = (author, permlink) => ({
  type: FETCH_POST,
  payload: axios.get(`/api/posts/@${author}/${permlink}`)
    .then(res => res.data)
    .then(post => steemAPI.getContentAsync(post.author, post.permlink)
      .then(steemPost => getPostData(steemPost, post)))
    .then(steemPost => steemPost.id !== 0 && steemPost),
  meta: {
    author,
    permlink,
    globalError: 'Sorry, there was an error fetching the post',
  },
});
```

Retrieve posts matching certain criteria ([GitHub Link](https://github.com/jrawsthorne/review.app/blob/804400323a6c981978841f523469d11182c38776/src/apis/routes/posts.js#L19-L40))
```javascript
router.get('/', (req, res) => {
  const {
    postType = 'all', mediaType, tmdbid, seasonNum, episodeNum, rating, limit = 20,
  } = req.query;
  const query = {};
  if (mediaType) query.mediaType = mediaType;
  if (tmdbid) query.tmdbid = tmdbid;
  if (seasonNum) query.seasonNum = seasonNum;
  if (episodeNum) query.episodeNum = episodeNum;
  if (rating) query.rating = rating;
  if (postType !== 'all') {
    query.postType = postType;
  }
  Post.count(query)
    .then((count) => {
      Post.find(query).limit(limit)
        .then(posts => res.json({
          count,
          results: posts,
        }));
    });
});
```

Front end makes the request and calls the steemit api for every post it finds that isn't already stored locally ([GitHub Link](https://github.com/jrawsthorne/review.app/blob/804400323a6c981978841f523469d11182c38776/src/actions/postActions.js#L29-L50))

```javascript
export const fetchPosts = (posts, {
  postType = 'all', mediaType = null, tmdbid = null, seasonNum = null, episodeNum = null, rating = null,
}) => ({
  type: FETCH_POSTS,
  payload: axios.get('/api/posts', {
    params: {
      postType: postType || 'all',
      mediaType: mediaType || undefined,
      tmdbid: tmdbid || undefined,
      seasonNum: seasonNum || undefined,
      episodeNum: seasonNum && episodeNum ? episodeNum : undefined,
      rating: rating || undefined,
    },
  })
    .then(res =>
      Promise.all(res.data.results.filter(post => !_.get(posts, `@${post.author}/${post.permlink}`)).map(post => steemAPI.getContentAsync(post.author, post.permlink)
        .then(steemPost => getPostData(steemPost, post))))
        .then(steemPosts => arrayToObject(steemPosts.filter(post => post.id !== 0), 'url'))),
  meta: {
    globalError: 'Sorry, there was an error fetching posts',
  },
});
```

Ability to update the metadata associated with a post if an image path changes for some reason ([GitHub Link](https://github.com/jrawsthorne/review.app/blob/804400323a6c981978841f523469d11182c38776/src/apis/routes/posts.js#L44-L95))

```javascript
router.post('/update-metadata', (req, res) => {
  /* checking whether necessary values exist */
  return Post.findOne({
    author, permlink, postType, mediaType, tmdbid, seasonNum, episodeNum,
  })
    .then((post) => {
      if (!post) return res.status(404).json({ error: "Post couldn't be found" });
      if (mediaType === 'movie') {
        theMovieDBAPI.movieInfo(tmdbid)
          .then(movie => Post.findOneAndUpdate({
            author, permlink, postType, mediaType, tmdbid,
          }, { posterPath: movie.poster_path, backdropPath: movie.backdrop_path }, { new: true })
            .then(newPost => res.json(newPost)));
      }
      /* checking other media types */
      return post;
    });
});
```

### #3 Display posts

Home page shows all posts, can filter by media type

![Home page](https://i.imgur.com/cRfWp71.jpg)
![Filtered home page](https://i.imgur.com/yLfeQdJ.png)

Every show/movie page shows the posts for it

![Movie page](https://i.imgur.com/4i5Lnt0.jpg)
![Show page](https://i.imgur.com/EpVzQvZ.jpg)
![Episode page](https://i.imgur.com/F0cgSjE.png)

Single post page shows metadata, post title and formatted body

![Movie post](https://i.imgur.com/ehTihba.png)
![Show post](https://i.imgur.com/mh32Nat.jpg)
![Episode post](https://i.imgur.com/bOOSOgb.png)

### #4 Mobile styling

Until I come up with a final design I added some mobile styling so content wouldn't expand out of the page. On the home page, a landscape image is shown to use the limited space better.

![Post page](https://i.imgur.com/TJYFBEP.jpg)
![Home page](https://i.imgur.com/eEQA2kX.jpg)

### #5 Login with SteemConnect

I fixed the SteemConnect login redirecting to localhost and now when you login it shows your avatar in the top right. The access token is only stored client side so there is no possibility of a leak if the server is hacked. I also only request an online token and not an offline one which can be used to generate unlimited tokens. Logout revokes the token so it can't ever be used again.

### Roadmap

- Better filters for pages - store list of posts matching filter in redux store
- Post formatting - youtube/dtube/more complex markdown/html
- Ability to actually write new posts
- Store all database info in JSON metadata of a post as backup
- User profile pages
- Allow all users to give star rating
- User actions (like, comment)
- Subscribe to certain show - get notifications when new episode airs
- Subscribed page showing all posts from subscribed shows/movies

#### Proof of Work Done
https://github.com/jrawsthorne
👍  , , , , , , , , , , , , , , , , , ,
properties (23)
post_id47,284,184
authorjrawsthorne
permlinkdevelopment-update-1-my-steem-tv-show-and-movie-app
categoryutopian-io
json_metadata"{"links": ["https://github.com/jrawsthorne/review.app", "https://github.com/jrawsthorne/review.app/blob/804400323a6c981978841f523469d11182c38776/src/apis/models/Post.js#L3-L55", "https://github.com/jrawsthorne/review.app/blob/804400323a6c981978841f523469d11182c38776/src/apis/routes/posts.js#L8-L17", "https://github.com/jrawsthorne/review.app/blob/804400323a6c981978841f523469d11182c38776/src/actions/postActions.js#L52-L65", "https://github.com/jrawsthorne/review.app/blob/804400323a6c981978841f523469d11182c38776/src/apis/routes/posts.js#L19-L40", "https://github.com/jrawsthorne/review.app/blob/804400323a6c981978841f523469d11182c38776/src/actions/postActions.js#L29-L50", "https://github.com/jrawsthorne/review.app/blob/804400323a6c981978841f523469d11182c38776/src/apis/routes/posts.js#L44-L95", "https://github.com/jrawsthorne"], "users": ["jrawsthorne"], "community": "busy", "tags": ["utopian-io", "development", "steemdev"], "app": "busy/2.4.0", "format": "markdown"}"
created2018-05-06 21:38:09
last_update2018-05-06 21:38:09
depth0
children2
net_rshares35,681,777,571,149
last_payout2018-05-13 21:38:09
cashout_time1969-12-31 23:59:59
total_payout_value123.154 SBD
curator_payout_value40.435 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length8,070
author_reputation6,883,000,130,340
root_title"Development Update #1: My Steem TV Show and Movie App"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars0
author_curate_reward""
vote details (19)
@amosbastian ·
Thanks for the contribution. It has been approved.

----------------------------------------------------------------------
Need help? Write a ticket on https://support.utopian.io/.
Chat with us on [Discord](https://discord.gg/uTyJkNm).
[[utopian-moderator]](https://utopian.io/moderators)
👍  
properties (23)
post_id47,365,831
authoramosbastian
permlinkre-jrawsthorne-development-update-1-my-steem-tv-show-and-movie-app-20180507t110235289z
categoryutopian-io
json_metadata"{"links": ["https://support.utopian.io/", "https://discord.gg/uTyJkNm", "https://utopian.io/moderators"], "app": "steemit/0.1", "tags": ["utopian-io"]}"
created2018-05-07 11:02:36
last_update2018-05-07 11:02:36
depth1
children0
net_rshares4,358,110,484
last_payout2018-05-14 11:02:36
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length288
author_reputation174,225,255,912,876
root_title"Development Update #1: My Steem TV Show and Movie App"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (1)
@utopian-io ·
#### Hey @jrawsthorne
We're already looking forward to your next contribution! 

#### Contributing on Utopian
Learn how to contribute on <a href="https://join.utopian.io">our website</a> or by watching <a href="https://www.youtube.com/watch?v=8S1AtrzYY1Q">this tutorial</a> on Youtube.

##### Utopian Witness!
<a href="https://v2.steemconnect.com/sign/account-witness-vote?witness=utopian-io&approve=1">Vote for Utopian Witness!</a> We are made of developers, system administrators, entrepreneurs, artists, content creators, thinkers. We embrace every nationality, mindset and belief.

**Want to chat? Join us on Discord https://discord.gg/h52nFrV**
👍  
properties (23)
post_id47,407,902
authorutopian-io
permlinkre-jrawsthorne-development-update-1-my-steem-tv-show-and-movie-app-20180507t155819825z
categoryutopian-io
json_metadata"{"links": ["https://join.utopian.io", "https://www.youtube.com/watch?v=8S1AtrzYY1Q", "https://v2.steemconnect.com/sign/account-witness-vote?witness=utopian-io&approve=1", "https://discord.gg/h52nFrV"], "app": "steemit/0.1", "users": ["jrawsthorne"], "tags": ["utopian-io"]}"
created2018-05-07 15:58:18
last_update2018-05-07 15:58:18
depth1
children0
net_rshares4,270,988,178
last_payout2018-05-14 15:58:18
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length649
author_reputation152,913,012,544,965
root_title"Development Update #1: My Steem TV Show and Movie App"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (1)