Skip to content

Repository files navigation

trickle

trickle is a podcast player and feed reader for iOS and Android, with a cyberpunk interface.

Features

  • Apple podcast catalog search with complete pre-subscription details, direct feed subscription, website feed discovery, YouTube channel and playlist discovery, Nostr profile feeds, standard OPML import, and an OPML export scope chooser for podcasts, feeds, or all compatible subscriptions
  • RSS 2.0, RSS 1.0, Atom, and JSON Feed parsing that keeps podcasts separate from other feeds
  • Verified Nostr profile posts from secure relays, with replies and reposts excluded; Markdown, content warnings, images, native audio, and direct video are supported when supplied by a post
  • Streaming, resumable app-private downloads, storage totals and bulk cleanup, persistent Up Next, automatic download cleanup, and per-feed automation
  • Native system playback, background audio, lock-screen controls, interruptions, headphone-disconnect pause, repeat-one, sleep timer, bookmarks, chapters, searchable timed transcripts, and per-feed intro/outro skip
  • One global playback speed with 1x, 1.25x, 1.5x, 1.75x, and 2x
  • Unread, all, and saved article views; category timelines; per-source search, filters, and sorting; persistent reader text size; offline saved article text; link previews; local full-text search; and external share/browser actions
  • Reusable optional categories for non-podcast sources, with assignment while subscribing, one-tap reassignment from source details, bulk moves, confirmed merges, unread counts, case-insensitive suggestions and grouping, and standard OPML folder import and export
  • New, in-progress, and played episode states; New, In Progress, and All podcast filters; partial-progress bars and Resume actions; full show notes; no play-on-open side effect; and separate quick-play buttons throughout episode lists
  • YouTube video entries and recognized YouTube attachments play without ads when supported, with an official-source fallback and a live minimized Now Playing preview that does not reload; Picture in Picture supports background and locked-screen audio
  • Public and private feeds, including credentials in URL query strings or opaque paths and Basic or Bearer authorization
  • Add feeds from the iOS or Android system share sheet, with an editable confirmation before subscription
  • Local ZIP backup/restore for portable subscriptions and local state, local notifications, and best-effort operating-system background refresh
  • trickle does not collect your information

Supported platforms

  • Android 7.0 (API 24) or later
  • iOS 17.0 or later on iPhone

Desktop, web, CarPlay, Android Auto, and Android Automotive are intentionally out of scope.

Interface

The home flow starts with a horizontally scrolling two-row shelf of recent episodes with direct Play and Resume controls, followed by compact collection shortcuts, subscriptions, feed actions, and unread entries. Four-button collections divide the available width evenly, with longer labels wrapping inside their cell. Section-level See all actions open the complete library or Feeds destination. The Podcasts screen separates New, In Progress, and All episodes without duplicating queue state. Episodes distinguish New, In Progress, and Played at a glance. The only number badge is on the Home screen’s Sources shortcut; it shows the exact unread feed-item count and hides at zero. Feeds separates the item timeline from Sources, and the Library repeats the full collection navigation in one place. A persistent mini player keeps the current episode or video reachable without taking over navigation.

The visual system uses clipped control geometry, functional state rails, and a sparse signal-line backdrop instead of decorating every content row. Cyan identifies listening actions, magenta identifies feed actions, and acid green is reserved for active playback. Content lists remain continuous and low-chrome. Route changes use a brief full-surface signal glitch after an instantaneous handoff and skip the effect when reduced motion is enabled. Persistent audio and video hosts stay outside the effect so navigation cannot reset playback. Playback, Picture in Picture, article reading, and in-place controls remain stable through navigation. Display typography is limited to page and section hierarchy; reading and metadata use the more neutral text face. Controls reflow at accessibility text sizes rather than shrinking labels or touch targets.

Prerequisites

  • Flutter 3.44.4 or later with Dart 3.12.2 or later; the current release is verified with Flutter 3.47.2
  • oxfmt 0.57.0 or later for Markdown formatting
  • Android SDK 36 for Android builds
  • JDK 17 or 21 for Android builds; JDK 26 is not supported by the current Android toolchain
  • Xcode 26 or later and CocoaPods for iOS builds

Getting started

flutter pub get
flutter run

Select an Android emulator/device or an iOS Simulator/device when Flutter prompts for a target.

Generated Drift sources are committed. Regenerate them only after changing the database schema:

dart run build_runner build --delete-conflicting-outputs

Quality checks

Run the same checks used before release:

oxfmt --check README.md 'docs/**/*.md' 'store/**/*.md'
dart format --output=none --set-exit-if-changed lib test
flutter analyze
flutter test
(cd android && ./gradlew :app:lintRelease)
flutter build appbundle --release
flutter build ios --release --no-codesign

The unsigned build commands verify compilation without requiring publisher credentials. Store uploads must use production signing; see store/RELEASE.md.

Architecture

  • lib/core: product rules, constants, formatting, URL identity, and user-safe errors
  • lib/data: Drift/SQLite persistence, hardened HTTPS and secure WebSocket networking, feed and verified Nostr parsing, private-feed storage, and repositories
  • lib/features: background downloads, long-lived audio handling, and the active video session
  • lib/services: refresh scheduling, incoming shares, feed automation, notifications, OPML, and local backup
  • lib/presentation: Riverpod-driven screens, the shared visual system, reusable content components, and the persistent player shell

Data and refresh

The SQLite database uses schema version 5, WAL mode, foreign keys, indexed timeline queries, and FTS5 search. Feed refreshes and restores update state in bounded batches. Older refresh results cannot replace newer content or settings. Background automation stages Up Next additions, and the audio handler acknowledges them only after merging them into the active queue.

Playback

The latest audio or video selection owns playback. Native player commands are ordered, and a slow media lookup cannot block a newer selection. Podcast playback reapplies its spoken-audio session before starting and makes one bounded recovery attempt after an unexpected stop.

Performance

Shared library snapshots keep rows from opening duplicate database streams. Expensive feed, article, and Nostr verification work runs off the UI isolate. Lists are lazy, reader content is revealed in bounded fragments, and artwork uses bounded, aspect-preserving decoding. Network deadlines are 10 seconds for connections and video sources, 15 seconds for interactive catalog, media, and background work, and 30 seconds for feed, relay, article, image, and OPML documents. Playback progress is saved every 15 seconds, and download progress writes are limited to once every 2 seconds.

Project layout

  • android/ and ios/: native application and release configuration
  • assets/brand/: source artwork for deterministic app/store asset generation
  • docs/: user-facing privacy and support documents
  • store/: release checklist, store metadata, App Store screenshots, and signing export configuration
  • test/: unit, repository, database, network, and widget regression tests; Nostr relay protocol tests use injected in-memory sockets and never contact public relays
  • tool/: deterministic brand-asset generation, screenshot capture, and command-line release tooling

After changing a brand source, run tool/generate_brand_assets.sh to rebuild the required Android, iOS, launch, and store raster assets.

Privacy and support

The repository publishes these documents from main/docs through GitHub Pages.

Release

Use the release checklist, store metadata, App Review notes, and TestFlight notes. The release workflow and screenshot-capture tooling are in store/apple/ and tool/maestro/; private signing-key material remains outside the repository. The checked-in copyright-safe images were regenerated and visually verified against 1.2 on August 26, 2026.

About

Podcast player and feed reader for iOS and Android, with a cyberpunk interface.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages