Skip to content

Latest commit

Β 

History

21 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Tavlan

Swedish Sweden for "the board"

An Android home-screen widget experience for live public transport departures, built with Expo and React Native. This project turns real-time departure data into a glanceable, home-screen-first interface for commuters in Stockholm, with provider-aware board styling and a compact configuration app.

Overview

Tavlan lets a user choose a transit provider, station, and transport type, then displays current departures in a widget-friendly layout. It currently includes two custom Android widget variants:

  • SL "Classic" board
  • SL "Modern" board

The widget content is refreshed to match the user’s selected station and is designed to fit the constraints of a home-screen widget while preserving an attractive, information-dense layout.

This project was built to explore the intersection of:

  • React Native + Expo for a lightweight native app shell
  • Android widgets for home-screen utilities
  • live transport data integration
  • provider abstraction and pluggable board rendering
  • mobile UX design for glanceable information

Features

  • Live departures for Stockholm public transport via a provider-based service layer
  • Two branded Android widget variants with distinct visual identities
  • Station and transport selection inside the app
  • Persistent preferences for provider, transport, and stop selection
  • Provider isolation with a clean abstraction for future transport operators
  • Responsive widget sizing with auto-fit departure row counts
  • Tapping a widget triggers a refresh flow for updated departures
  • Type-safe data flow between service, app state, and widget rendering layers

SL departure board widgets

For the SL provider, Tavlan supports two branded widget styles: a classic board and a modern board. Both are resizeable and tuned for the commuter experience, with a station header that reflects the current line type such as T-Bana or PendeltΓ₯g.

Classic SL board

This version recreates the retro public-transit board aesthetic with a pixel-inspired display, strong station branding, and a compact departure list.

Classic SL departures board

Modern SL board

This variant uses a cleaner commuter-panel layout with stronger separation between line badges, destination names, and countdowns while keeping the same home-screen usability.

Modern SL departures board

Different board header for T-Bana / PendeltΓ₯g

Header remains recognisable for transport type:

Modern SJ board at a medium size Classic SJ board at a medium size

Resizeable widget behavior

The board adapts to different widget heights and widths without losing legibility, which makes it practical on Android home screens and gives the design a native utility-app feel. The same widget can be compact or tall depending on the user’s home-screen layout, while keeping the SL identity intact.

  • Classic and modern variants both resize vertically

  • Departure rows adjust to the available space so the list remains readable

  • Compact layouts keep the most important information visible first

  • Tapping the widget can trigger a refresh flow for updated departures

Resize examples

These screenshots show the same SL board family at different heights and densities, demonstrating how the layouts remain usable as the widget grows or shrinks.

Modern SL board at a small size
Modern SL board at a medium size
Modern SL board at a larger size
Classic SL board at a small size
Classic SL board at a medium size
Classic SL board at a larger size

The practical result is a widget system that feels native to Android: compact enough for quick glanceability, but still rich enough to surface multiple departures and destination names when more space is available.

In-App features for widget configuration

Transport provider / type / station configurator
Transport Provider / Type / Station configurator
Station selection screen
Station selection
Widget preview screen
Widget preview

Tech stack

  • Expo SDK 56
  • React Native 0.85
  • Expo Router
  • TypeScript
  • Android widget support via react-native-android-widget
  • SQLite for local persistence
  • Custom native-like widget rendering and provider-driven theming

Project structure

.
β”œβ”€β”€ app.json                 # Expo + Android widget configuration
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app/                # App screens and routing
β”‚   β”œβ”€β”€ components/         # Reusable UI primitives
β”‚   β”œβ”€β”€ services/           # Transport provider and data access layer
β”‚   β”œβ”€β”€ utils/              # Local storage helpers
β”‚   └── widgets/            # Widget definitions and shared rendering logic
β”œβ”€β”€ assets/                 # Icons, fonts, widget previews, etc.
β”œβ”€β”€ android/                # Android project files
β”œβ”€β”€ plugins/                # Expo config plugins
β”œβ”€β”€ package.json
β”œβ”€β”€ README.md
└── tsconfig.json

How it works

  1. The user selects a transport provider, stop, and travel mode in the app.
  2. The app stores the selection locally so it survives future sessions.
  3. The app fetches live departures from the active provider.
  4. The widget is updated with the selected station and departure set.
  5. Each widget variant renders board data according to its own design and sizing rules.

This separation keeps the widget layer focused on display while service logic handles provider-specific data and normalization.

Product notes

Tavlan is based on product-oriented mobile engineering:

  • Is built around a real user scenario: checking departures in seconds
  • Balances app and widget UX instead of treating them as separate concerns
  • Includes abstractions aiming to make adding new providers or board styles straightforward
  • Leverages technical design to implement a polished user experience

Run locally

Install dependencies

npm install

Start the Expo dev server

npx expo start

Run on Android

npm run android

Start web preview

npm run web

Useful commands

npm run start
npm run android
npm run web
npm run lint

About

Live public transport departures πŸš‰πŸš„ on your home screen 🀳🏠, using realistic departure board widgets πŸ“±

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages