digital realities

The online portfolio of ømar mashaal.

Senior Digital Engineer at Museum of Old and New Art

Co-organizer of Node Melbourne

Tunnel of Love

w/ squirting eggplants

MONA FOMA is an annual music and arts festival held in January in Hobart, Tasmania, Australia, curated by Violent Femmes member Brian Ritchie.


This year, I went a bit wild with attaching design and interactivity to user's mouse position. This can be seen in the tunnel, program listing, program pages as well as the sparkling eggplant.

Using the React Context API, I created a mouse provider component, which allowed the sharing of single event listeners across all of the previously mentioned components! I think that's pretty cool (and hopefully a massive performance boost at the same time)!

class MouseProvider extends React.Component {
  constructor() {
    this.state = {
      x: 0,
      y: 0
    this.calibrate = this.calibrate.bind(this)
    this.handleMouseMove = this.handleMouseMove.bind(this)
  componentDidMount() {
    window.addEventListener('mousemove', this.handleMouseMove, {
      passive: true
    window.addEventListener('resize', this.calibrate, {
      passive: true
  componentWillUnmount() {
    window.removeEventListener('resize', this.calibrate)
    window.removeEventListener('mousemove', this.handleMouseMove)
  calibrate() {
    requestAnimationFrame(() =>
      this.setState({ x: window.innerWidth / 2, y: window.innerHeight / 2 })
  handleMouseMove(event) {
    requestAnimationFrame(() =>
      this.setState({ x: event.clientX, y: event.clientY })
  render() {
    return <Provider value={this.state}>{this.props.children}</Provider>

This is barebones example of our mouse provider. The calibration is set to the center of the viewport, as some elements needed to be centered by default.

Note: This is a helpful article which explains some of the performance benefits of bound vs arrow functions.


mona foma status board

Each festival has multi-phased rollouts, which cater for things like lineup annoucements, ticketing, and on-ground usage. The codenames for our first two phases were Acid-Gelati and Seizure-Bong.


We utilise dedicated Contentful 'spaces' for each phase. A 'space' is essentially an instance of our API/CMS. Contentful CLI makes things like backing up, syncing, or copying data accross spaces incredibly easy. One of the biggest benefits of Contentful is that it empowers our content authors to help shape our API design, blurring the line between developer and content author.

By default, Contentful returns a large payload of metadata with each request. I made a cleaner helper which strips away much of the unused data. It works with referenced/nested entries as well! The following is a very basic example, which is run on our node.js API server.

import traverse from 'traverse'

const cleaner = obj =>
  traverse(obj).map(function() {
    if (this.node.fields && this.node.sys) this.update(this.node.fields)

export default cleaner

This can easily be extended for custom use cases, such as date and time formatting. Here is a preview of our API output.

Browser Support

A lose/lose situation

We use a mixture of browserlist and Google Analytics data to focus our full support to our largest user base. Roughly this translates to browsers with an Australian market share greater than 1.5%.

In a mildly controversial move, we decided to provide unsupported browsers an alert to notify that the site may not work as intended.


Mona Foma Lite

mona foma lite

The following day, we pushed unsupported users to a text-based, lite version, of the website. Much of the interactivity and design elements have been removed, while keeping expected functionality.

Because all of our program data is API driven, this was able to be built and deployed quite quickly!

mona foma lite

🍑 Quivering Peach 🍑



'lil bits of 💚

"...need to escape the matrix for a while and would love to take whoever designed this website out on a date"

mona foma review

"Just fucking GET IN ME the website made me boygasm"

mona foma review

"Very funny website by the way. Love."

mona foma review

💦 Leaked internal memo 💦

mona foma status board


Mona Foma runs 13-20 of January 2019.