Portrait of Patrice GADEGBEPatrice GADEGBE

Mooduo

Mooduo is a prototype mood journal kept by two: each partner sets their mood on a five-level scale, and the application displays both side by side, with their history.

Role
Sole author
Period
December 2021 and January 2022
Status
Prototype. Prototype, never published
Technologies
Flutter, provider, Django 4, Django Channels, PostgreSQL, Redis
Repositories
Two folders, without git history
Architecture of MooduoThe Flutter application talks to a Django API through ordinary requests and through a WebSocket channel. The server stores the moods in PostgreSQL and relies on Redis to broadcast the signals to both phones.ApplicationFlutter, providertwo phonesAPIDjango 4, Channelsfive endpointsPostgreSQLduos, moodsRedissignal broadcastHTTP, WebSocket
Figure 1. Architecture of Mooduo. The dashed line is the WebSocket channel, through which the server notifies both phones.

Context

Mooduo represents two to three weeks of work around New Year 2022. Each of the two partners chooses their current mood; the application displays both, signals that they match, and keeps a history that can be filtered by person and by period. The project was not continued, and no git history of it remains.

Problem

The prototype sets out to pair two phones without creating an account, and to make a change of mood on one side appear on the other’s without the latter having to refresh the screen.

Answer

Pairing without an account

The first partner asks the server for a duo identifier, then passes it to the other through a share link. The second phone receives this link, keeps the identifier and declares itself as the second member, after which the server considers the duo validated on both sides. First names never leave the phones, where they are kept with the identifier.

One row per couple and per hour

A mood is not one row per person. The server keeps one row per duo and per hour, with two columns, and each submission writes into its author’s column. Knowing whether the two partners agree then comes down to comparing two columns of the same row.

today = datetime.today()
try:
    mood = MoodLevel.objects.get(duo=duo,
                                 time__year=today.year,
                                 time__month=today.month,
                                 time__day=today.day,
                                 time__hour=today.hour)
except MoodLevel.DoesNotExist:
    mood = MoodLevel.objects.create(duo=duo, time=today)

if data['duo'] == 1:
    mood.first_duo_level = data['level']
elif data['duo'] == 2:
    mood.second_duo_level = data['level']
else:
    return Response(status=status.HTTP_400_BAD_REQUEST)

mood.save()
Listing 1. Recording a mood in the row of the current hour.

A channel that carries only a signal

The WebSocket channel conveys no data. The server pushes a single letter onto it, which indicates that the duo is complete or that a mood has changed, and the phone reacts by reading the data again through an ordinary request. The data format thus exists in one place only.

Limits and outlook

The duo identifier is the only secret of the system: whoever holds it can read and write the couple’s moods. This choice suited a prototype that only ever ran on my network, and it would rule out a publication as it stands.

Pairing by link is moreover configured for Android only, the daily reminders remained unfinished, and the hour retained is the server’s and not the user’s. Finally, the prototype has no tests.

Back to the other projects