itsnoddy.dev ← Back to the work
CASE STUDY TV & FILM TRACKER · iOS + ANDROID · JUL 2026 — PRESENT Updated 24 Sep 2026

OPENTV

A TV and film tracker for people leaving TV Time. It imports your whole export and rebuilds your history on the phone, and the database on the phone is the source of truth: it works offline, needs no account, and nothing about what you watched is sent anywhere unless you ask for it — by joining the optional community, or by switching on a backup.

App Store frame: 'Leaving TV Time? Bring everything.' A phone shows the OpenTV welcome screen over a wall of show posters, with the line 'Your data stays on your device' and a GET STARTED button.
The first screen makes the promise before anything else: your data stays on your device.
App Store frame: 'Every episode, checked off.' The Game of Thrones page, with Continue tracking on S01 E01 and Season 1 and Season 2 with their 10 of 10 and 1 of 10 counts.
A show's page: continue where you left off, and every season with its count.

01 / THE PROBLEMYour history, held by someone else

TV Time was where a lot of people kept a decade of what they had watched — every episode, with dates. When leaving it, you could ask for your data and get a GDPR export back: a ZIP nobody else could open into anything useful. The history was yours on paper and nowhere in practice.

I wanted a tracker where that could not happen again. So the rule I set on day one was not a feature, it was a constraint: the app must be complete without a server. Import the export, rebuild the history locally, keep it in a database on the phone, and export it back out at any time in TV Time's own format so nobody is ever locked in a second time.

That constraint decided almost everything that followed.

02 / HOW IT WORKSImport, track, and keep it

You start by importing — the official TV Time export, or the community browser-extension exports — and OpenTV rebuilds your shows, episodes and watch dates into SQLite on the device. From there it is a tracker: what to watch next, every episode checked off, films added in a tap, stats over your own library. Metadata comes from TheTVDB, with TMDB filling in the few things it does not carry.

The community — comments, ratings, follows, shared lists — is a separate, optional layer behind its own server, and nothing reaches it unless you join. Your episode-by-episode history is not part of what it carries either way.

Two other things can leave the phone, and only because you switched them on: a backup, to Google Drive, to OpenTV's server or to a server you run yourself; and crash reports, which arrived in 1.6.3. The default remains a tracker that talks to nobody.

03 / THE DECISIONLocal-first, and what it costs

Making the phone's database the source of truth is the decision the whole product hangs on. It is what lets the app work with no account, offline, and with no way for anybody — including me — to fetch a library off a phone. There is no route for it, no flag, no support path.

That is the point, and it has a price I chose to pay:

"There is no way for anybody, including us, to fetch your library off your phone. Not a route, not a flag, not a support path. Bug reports get reproduced from a description, like every other bug in this project."— the project README

04 / THE HARD PARTTwo different ideas of what episode 12 is

The first releases built episode lists from TMDB. TV Time, and therefore every export, numbers episodes the way TheTVDB does. For most shows the two agree. For anime they do not: TMDB files Detective Conan as one 1,208-episode season and Jujutsu Kaisen as one season of 59, where TheTVDB — and your export — has 34 seasons and 3. So anime imported with collapsed seasons, and watches landed on the wrong episodes. The app also carried code that shuffled watch rows around to fit TMDB's layout, which was the one place in the whole system that could quietly drop an episode rating.

The fix in 1.2.0 (30 July 2026) was to change the database the app runs on: seasons, episode numbers, titles and air dates now come from TheTVDB, matching what people saw in TV Time, with TMDB called only for the three things TheTVDB has no equivalent for. Existing libraries were repaired automatically on update behind a progress screen — nothing to re-import. I checked the result against a real export before shipping: 388 of 389 watch rows lined up exactly. A dead API key cannot break a library either: everything already stored stays, and only new imports fall back, clearly labelled.

A later one, from 1.6.3, is worth a line because it is the same lesson from the other side. An episode you un-tick is remembered as a tombstone so that re-importing your own export cannot resurrect it. A cloud restore is not a re-import, and a tombstone can be left by another of your own devices — so one restore dropped 215 episodes from a show and reported "verdict":"ok". Restores clear tombstones first now; imports still honour them. Both fixes are in the public changelog, with the numbers.

05 / KEEPING IT HONESTHow it is tested

06 / WHAT SHIPPEDTen weeks of shipping

WHENVERSIONWHAT LANDED
13 Jul 20261.1.0First release on Google Play
30 Jul 20261.2.0Both stores: TheTVDB becomes the source of episodes, lists, sharing, iPad
7 Aug 20261.2.1Six languages
11 Aug 20261.3.0The optional community layer
14–18 Aug 20261.4.xWrapped, filters, private accounts, Google Drive backup, widgets
30 Aug – 2 Sep 20261.5.0 – 1.6.1Shared lists, OpenTV Plus, the light theme, Plex, the films TV Time left out
21 Sep 20261.6.3Siri, episode ratings, cloud backup to OpenTV or your own server, Trakt and Simkl imports, crash reports

Dates are from the project's changelog, which is reconstructed from git and the store consoles; the rows above are the ones that reached both stores, so the changelog also lists versions that were submitted, folded into a later release or never shipped. The user count is my own, as written in my CV in August 2026; I have not had it verified by anyone else.

OpenTV also has a paid tier, OpenTV Plus, for the on-device extras — advanced filters, the activity heatmap, the watch timeline, deep stats. Wrapped is free for everybody on purpose: it is the one screen built to leave the app.

07 / WHAT I'D DO NEXTThe next version, honestly

The next release separates an account from a profile: sign in for a backup without becoming a public handle, and new profiles private by default. That is the sharpest contradiction still in the product, and the person most likely to want a backup — the privacy-minded one — is the person it currently serves worst.

Two more I want: a way to answer the one person who left a one-star review saying the import failed, without breaking the privacy policy; and moving the hand-built iOS widget extension into a config plugin, so iOS can be built in the cloud like Android already is.

building things I'd want to use, and keeping them.