Do I actually need a native app for that?
Tags: pwa, react, javascript, scrum
Published: 2018-12-27 23:22:31

---
title: Do I actually need a native app for that?
published: true
tags: pwa,react, javascript,scrum
canonical_url: https://blog.simon-hofmann.org/pwa/js/2018/12/28/pwa_case_study.html
---

# TL;DR;

I created a planning-poker PWA.

Here's the [source](https://github.com/s1hofmann/planning-poker)
 and here’s the deployed [prototype](https://s1hofmann.github.io/planning-poker/).

# A little case study

When discussing new features, our distributed team makes heavy use of planning-poker apps. Everyone of us is sitting in front of a webcam with his phone equipped and on the count of three, everyone reveals his estimation by either tapping the screen or shaking the phone. It’s a nice way for us to socialize and get things done at the same time.

Depending on the task at hand, we’re using different types of decks, but most of the time it’s either “_Fibonacci_” or “_T-Shirt sizes_”.

So, when talking about features of a (very) basic planning-poker app, it should provide the following things:

1. Provide different decks of planning-poker cards to chose from
2. Allow the user to pick a card
3. Display the card, upside-down
4. Tapping the screen or shaking the phone flips the card

Sounds fairly straight-forward, but …

## Size matters?

The last time I scanned my phone for things I could get rid of (I’m constantly living on the edge of device memory), I recognized that my simple planning-poker app takes up almost 20 MB of storage, just to provide the above mentioned feature set.

_“20 MB? Really? For something I could build with a few lines of CSS and JS?”_ - Me, right when I decided to build a prototype for a planning-poker PWA over the holidays.

In case you’ve read any of my previous posts, you might already know that I’m a fan of PWAs. In my opinion, countless native apps out there could also be realized as a PWA, and I hope that the amount of PWAs out there will continue to grow! On the other hand, whenever I do projects like this, I’m also focussing on learning new things. Frontend projects are the perfect fit for this, since I’m mostly doing backend development, so here are some of my key takeaways after building this React-based PWA.

## 1. Can I do it with CSS?

When I started to implement a `Card` component, I thought about possible ways to flip it. My first approach was to flip the card body via CSS and render either the `Front` or `Back` child, depending on the cards state. That was when I learned more about [perspective](https://developer.mozilla.org/en-US/docs/Web/CSS/perspective) in CSS. The basic idea is simple:

- Rotate the back-faceing component by 180 degrees, keep the front-faceing

```css
.card-front, .card-back {
    ...
}

.card-front {
  transform: rotateY(0deg);
}

.card-back {
  transform: rotateY(180deg);
}
```

- Flip the **parent** container to switch back and forth between front / back
- Render either `Front` or `Back` component, depending on `flipped` state

The reason why I ditched this approach at the end was timing. As soon as the state changes, a different component is rendered. This means that during the actual flip we could already see the “other side”. I simply didn’t want to mess with timeouts aligned to CSS transition durations to properly switch between components, so I chose another solution which does not involve component switching after reading [this article](https://davidwalsh.name/css-flip).

We keep the rotation stuff just like before, but instead of rendering different components depending on the state, we **overlay** front- and backside via `absolute` positioning. Now both sides of the `Card` are rendered at once, so we additionally have to turn off [backface-visibility](https://developer.mozilla.org/en-US/docs/Web/CSS/backface-visibility). This way we don’t have to deal with timing and our `Card` flips just fine! :) In combination with [classnames](https://www.npmjs.com/package/classnames), we can seamlessly wire our flipping mechanism to our component state:

```js
<div
className={classNames(
    "card-body",
    { flipped: this.state.flipped },
    this.props.className
)}
onClick={this.props.onSelect || this.flip}
>
    <Front ... />
    <Back ... />
</div>
```

## 2. Device motion

Getting my cards to flip on device motion was easier than I thought. A quick search on [codepen.io](https://codepen.io) for _“devicemotion”_ gave me [this pen](https://codepen.io/Volorf/pen/BoVRyb). So, depending on the phone tilt I get either positive or negative values. Perfect!

Reading either [DeviceMotionEvent.acceleration](https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent/acceleration) or [DeviceMotionEvent.accelerationIncludingGravity](https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent/accelerationIncludingGravity) I’m detecting shakes by checking the amplitude and whether there’s been a change in sign or not. When the threshold is met, the `onShake` callback gets executed. There’s also an additional timeout to keep the `Seismograph` from fireing non-stop.

Seeing my cards flip on device motion and realizing how easy it was to use native device features in a web application made me smile big time! :)

## 3. Hosting? GitHub pages!

A while ago I created [another PWA](https://s1hofmann.github.io/xkcdpwa/) to randomly browse [xkcd comics](https://xkcd.com/). Back then, hosting a React-based PWA on GitHub pages required some configuration to get everything to work.

Things have changed since then! :)

- Configure a `homepage` in your `package.json`

```js
"homepage": "https://s1hofmann.github.io/planning-poker",
```

- Install the `gh-pages` package

```bash
yarn add -D gh-pages
```

- Add two scripts:

```js
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
```

- Run `yarn deploy`

Following these four steps everything should run out of the box and your PWA is online.

## 4. Useful things

I created just a single base icon for my application. [This tool](https://www.pwabuilder.com/imageGenerator) did the heavy lifting for me and created all the other sizes for me. Nice!

# Sooo …

As you can see [here](https://s1hofmann.github.io/planning-poker/), my little experiment turned out pretty well. (Ehm… pretty… At least according to me)

I already ditched my native planning-poker app and maybe there will be more in the near future!

So long

Simon