Developing TV Apps with React-TV

TVs usually have limited graphics acceleration, single core CPUs and high memory usage for a common TV App. These restrictions make super responsive 60fps experiences especially tricky.

React-TV is an ecosystem for React Applications on TVs. Includes a Renderer and a CLI tool for building applications. Focused on be a better tool for building and developing fast for TVs.

React-TV optimizations includes removing cross-browser support, being friendly to TVs’ events, preventing DOM or Fiber caching to reduce memory sweep and adding support to canvas-based components.

Netflix have also been tackling this problem.

As a pre 1.0 release it currently only works for LG WebOS. Support for Samsung Tizen, Samsung Orsay, and Amazon Fire TV are on the roadmap.

import React from 'react'
import ReactTV, { Platform } from 'react-tv'

class Clock extends React.Component {
  state = { date: new Date() }

  componentDidMount() {
    setInterval(() => this.setState({date: new Date()}), 1000)
  }

  render() {
    if (Platform('webos')) {
      return (
        <h1>Time is {this.state.date.toLocaleTimeString()}</h1>
      )
    }

    return <h2>This App is available only at LG WebOS</h2>
  }
}

ReactTV.render(<Clock />, document.getElementById('root'))

If you’re interested in this project I recommend you to follow React-TV developer Raphael on Twitter, as he frequently posts some nice work in progress videos.

Developing for TVs with React-TV →
React-TV (GitHub) →
React-TV YouTube Example App →

Elsewhere , , , Leave a comment

Do we need a new heading element? We don’t know.

Great insightful post by Jake Archibald on the generic <h> element, which could act as a replacement for the current set of <h1>, <h2>, <h3>, …

I always thought this to be a good case, as it’d would allow you to move components around in the DOM, and the “importance”
of the heading would be defined based upon its position/nesting level (e.g. the outline algorithm).

The suggestion is that <h> would solve this, as browsers would implement it & do the right thing in terms of the accessibility tree.

This is a common mistake in standards discussion – a mistake I’ve made many times before. You cannot compare the current state of things, beholden to reality, with a utopian implementation of some currently non-existent thing.

If you’re proposing something almost identical to something that failed, you better know why your proposal will succeed where the other didn’t.

We need evidence. And the first step is understanding what went wrong with the previous proposal.

Do we need a new heading element? We don’t know →

Elsewhere , , Leave a comment

PanelKit 2.0

Version 2.0 of the aforementioned PanelKit.

PanelKit is a UI framework that enables panels on iOS. A panel can be presented in the following ways:

  • Modally
  • As a popover
  • Floating (drag the panel around)
  • Pinned (either left or right)

This framework does all the heavy lifting for dragging panels, pinning them and even moving/resizing them when a keyboard is shown/dismissed.

Next to an underlying upgrade to Swift 4, these are the main changes:

  • Multi-pinning, pin multiple panels to a side
  • Panel resizing
  • State restoring, save and load panel states

PanelKit is featured – and was built for – Pixure (version 3 just got released). It’s always great to see a product getting built, and a part of it being spun off into open source.

PanelKit →

Elsewhere , , , Leave a comment

No Hand’s Land – A map of the iPhone X for your fingers

By Sebastiaan de With, as featured in How to Design for iPhone X (without an iPhone X).

Made me smile … “Mt Notch” 🙂

Elsewhere , , , Leave a comment

Cancel a JavaScript Promise with AbortController

In How to Cancel Your Promise Seva Zaikov has done a nice writeup on several techniques on how to cancel promises. After also touching generators and async/await the conclusion is that you can’t (you may introduce some workarounds to track the cancelled state yourself, yet that won’t actually cancel an ongoing promise).

At the end of the article the author mentions abortable fetch, but doesn’t dig deeper into it. A shame though, as the shiny AbortController – the driving force behind the abortable fetch – is something which will allow you to actually cancel any promise (and not just fetch)!

To use the AbortController, create an instance of it, and pass its signal into a promise.

// Creation of an AbortController signal
const controller = new AbortController();
const signal = controller.signal;

// Call a promise, with the signal injected into it
doSomethingAsync({ signal })
	.then(result => {
		console.log(result);
	})
	.catch(err => {
		if (err.name === 'AbortError') {
			console.log('Promise Aborted');
		} else {
			console.log('Promise Rejected');
		}
	});

Inside the actual promise you listen for the abort event to be fired on the given signal, upon which the promise will be cancelled.

// Example Promise, which takes signal into account
function doSomethingAsync({signal}) {
	if (signal.aborted) {
		return Promise.reject(new DOMException('Aborted', 'AbortError'));
	}

	return new Promise((resolve, reject) => {
		console.log('Promise Started');

		// Something fake async
		const timeout = window.setTimeout(resolve, 2500, 'Promise Resolved')

		// Listen for abort event on signal
		signal.addEventListener('abort', () => {
			window.clearTimeout(timeout);
			reject(new DOMException('Aborted', 'AbortError'));
		});
	});
}

With this set up, you can call controller.abort(); from anywhere you like in order to abort/cancel the promise:

document.getElementById('stop').addEventListener('click', (e) => {
	e.preventDefault();
	controller.abort();
});

Below is a combined example with two buttons. The “start” button starts a promise which resolves after 2.5 seconds. When hitting “stop/abort” during that timeframe however, the promise will be cancelled.

See the Pen AbortController Example by Bramus (@bramus) on CodePen.

My personal nitpick with AbortController is the fact that it’s part of the DOM spec, and not the ECMAScript Spec. This makes it a browser feature, not a language feature. There once was a proposal for cancelable promises, yet it got withdrawn at Stage-1.

AbortController is available in Firefox 57 and Edge 16. Chrome and Safari are still working on it.

MDN: AbortController
WhatWG DOM Spec: Aborting Ongoing Activities →

Elsewhere , , Leave a comment

Design Systems and CSS Grid

Stuart Robson uses CSS Grid for what it’s meant to be used for: creating a grid. He evens creates a faux subgrid by leveraging calc() to define the two margin-columns.

.container {
    grid-template-columns:
    [full-start]
      minmax(calc(calc(100% - 1008px) / 2), 1fr)
        [main-start]
          repeat(14, [col-start] 1fr)
        [main-end]
      minmax(calc(calc(100% - 1008px) / 2), 1fr)
    [full-end];
}

Add in some media queries to cater for other screen dimensions and you have an elegant grid system 🙂

Design Systems and CSS Grid →

Elsewhere , , , Leave a comment

Parcel: A blazing fast, zero configuration web application bundler

Earlier this week Parcel got dropped and it received quite some attention, because it tackles two important things when compared to other bundlers such as Webpack:

The first reason I was motivated to build a new bundler was performance. I’ve worked on some pretty large apps with thousands of modules, and was always disappointed with the speed of existing bundlers. Large apps can take minutes to build, which is especially frustrating during development.

The second reason I built Parcel was to help with the pain of managing configuration. Most other bundlers are built around config files with lots of plugins, and it is not uncommon to see applications with upwards of 500 lines of configuration just to get things working. […] Parcel is designed to need zero configuration: just point it at the entry point of your application, and it does the right thing. Parcel has out of the box support for JS, CSS, HTML, images, file assets, and more — no plugins needed.

🚀 Announcing Parcel: A blazing fast, zero configuration bundler →
Parcel →

Elsewhere , , Leave a comment

Ready Player One Trailer

From filmmaker Steven Spielberg comes the science fiction action adventure “Ready Player One,” based on Ernest Cline’s bestseller of the same name, which has become a worldwide phenomenon.

The film is set in 2045, with the world on the brink of chaos and collapse. But the people have found salvation in the OASIS, an expansive virtual reality universe created by the brilliant and eccentric James Halliday (Mark Rylance). When Halliday dies, he leaves his immense fortune to the first person to find a digital Easter egg he has hidden somewhere in the OASIS, sparking a contest that grips the entire world. When an unlikely young hero named Wade Watts (Tye Sheridan) decides to join the contest, he is hurled into a breakneck, reality-bending treasure hunt through a fantastical universe of mystery, discovery and danger.

Release is due March 30, 2018.

Elsewhere , , , Leave a comment

JavaScript’s setTimeout “other” arguments

When using setTimeout, it’s not needed to wrap a function with arguments into an anonymous function and call it from there.

What you can do instead is pass the function in via its name (as you would do with a function that has no arguments), and pass in the arguments via the 3rd, 4th, 5th, etc. argument of setTimeout itself:

MDN: setTimeout

Elsewhere , Leave a comment

Customizing Pull-to-Refresh and Overflow Effects with CSS’ overscroll-behavior

Next to dynamic imports, another feature that landed in Chrome 63 is CSS overscroll-behavior:

Scrolling is one of the most fundamental ways to interact with a page, but certain patterns can be tricky to deal with. For example, the browsers pull to refresh feature, where swiping down at the top of the page, does a hard reload.

In some cases, you might want to override that behavior and provide your own experience.

The CSS overscroll-behavior property allows you to do just that: override the default scroll behavior. With it you can prevent a full reload when a pull-to-refresh gesture is performed (and inject your own logic), disable rubber banding (no more for need this nasty hack), etc.

Another typical use case is one where you have a scrollable piece of content that is layed out above another scrollable piece of content – yes: a modal. The default behavior is that when reaching the scroll boundary of the modal, the content underneath it starts to scroll:

Setting overscroll-behavior: contain; on the modal will prevent this default behavior, resulting in a better experience :

overscroll-behavior is available in the new Chrome 63 and in Firefox (ever since version 36!). Other browsers currently don’t support this.

Take control of your scroll: customizing pull-to-refresh and overflow effects →

Elsewhere , , , Leave a comment