docs: add README with features, architecture, and build instructions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8d92720d63
commit
999f6c075b
1 changed files with 155 additions and 0 deletions
155
README.md
Normal file
155
README.md
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
# Implausibly
|
||||
|
||||
An open-source Android dashboard app for self-hosted [Plausible Analytics](https://plausible.io/) CE.
|
||||
|
||||
The existing third-party apps are all closed-source. If you're running self-hosted Plausible specifically because you care about control and transparency, a closed-source dashboard app is an odd fit.
|
||||
|
||||
Implausibly is:
|
||||
|
||||
- **Fully open source** (GPL-3.0) — audit it, fork it, contribute
|
||||
- **Self-hosted first** — configurable base URL, no Plausible.io assumptions
|
||||
- **No account or subscription** — just your Plausible API key
|
||||
- **Zero telemetry** — no analytics in the analytics app
|
||||
- **No Google Play Services** — pure AndroidX, F-Droid compatible
|
||||
|
||||
## Screenshots
|
||||
|
||||
*Coming soon — the app is functional but screenshots haven't been captured yet.*
|
||||
|
||||
## Features
|
||||
|
||||
- **Multi-instance support** — connect to multiple Plausible servers
|
||||
- **Full dashboard** — visitors, pageviews, bounce rate, visit duration
|
||||
- **Visitor chart** — custom Canvas line chart with area fill
|
||||
- **Dimension breakdowns** — top sources, pages, countries, devices, browsers, OS
|
||||
- **Date range selector** — today, 7d, 30d, 6mo, 12mo
|
||||
- **Pull-to-refresh** — swipe down to reload
|
||||
- **Caching** — SQLDelight cache with TTL per date range; shows cached data instantly on launch
|
||||
- **Encrypted API keys** — stored via EncryptedSharedPreferences (AES-256-GCM)
|
||||
- **Clone instances** — duplicate an instance config to track a different site with the same credentials
|
||||
- **Smart navigation** — remembers your last-viewed dashboard and opens directly to it
|
||||
- **Material 3** — light and dark theme
|
||||
|
||||
## Requirements
|
||||
|
||||
- Android 8.0+ (API 26)
|
||||
- A self-hosted Plausible CE instance with API v2 enabled
|
||||
- An API key (or a public shared link)
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
# Clone
|
||||
git clone ssh://git@kode.naiv.no:2222/olemd/implausible.git
|
||||
cd implausible
|
||||
|
||||
# Build debug APK
|
||||
./gradlew assembleDebug
|
||||
|
||||
# Run unit tests
|
||||
./gradlew test
|
||||
|
||||
# Install on connected device
|
||||
./gradlew installDebug
|
||||
|
||||
# Lint
|
||||
./gradlew lint
|
||||
```
|
||||
|
||||
Requires JDK 17. The Gradle wrapper is included — no separate Gradle installation needed.
|
||||
|
||||
## Architecture
|
||||
|
||||
Four-layer unidirectional data flow:
|
||||
|
||||
```
|
||||
UI (Jetpack Compose + Material 3)
|
||||
| observes StateFlow
|
||||
ViewModel (per screen, sealed UiState)
|
||||
| calls
|
||||
Repository (cache-first, coordinates API + DB)
|
||||
| delegates to
|
||||
Remote (Ktor) + Local Cache (SQLDelight)
|
||||
```
|
||||
|
||||
Everything goes through one API endpoint: `POST /api/v2/query`. The dashboard fires 8 concurrent queries per load.
|
||||
|
||||
### Tech stack
|
||||
|
||||
| Component | Library |
|
||||
|-----------|---------|
|
||||
| UI | Jetpack Compose + Material 3 |
|
||||
| HTTP | Ktor (OkHttp engine) |
|
||||
| Serialization | kotlinx.serialization |
|
||||
| Local DB | SQLDelight |
|
||||
| DI | Hilt |
|
||||
| Preferences | DataStore |
|
||||
| Secrets | EncryptedSharedPreferences |
|
||||
| Charts | Custom Canvas (no library) |
|
||||
|
||||
### Package structure
|
||||
|
||||
```
|
||||
no.naiv.implausibly/
|
||||
data/
|
||||
remote/ Ktor API client, DTOs
|
||||
local/ SQLDelight generated code
|
||||
repository/ StatsRepository, InstanceRepository, SiteRepository, CacheManager
|
||||
ApiKeyStore Encrypted key storage
|
||||
AppPreferences DataStore preferences
|
||||
domain/model/ Domain models (decoupled from API/DB)
|
||||
di/ Hilt modules
|
||||
ui/
|
||||
setup/ Instance onboarding
|
||||
sites/ Site list / management
|
||||
dashboard/ Stats dashboard, components, sections
|
||||
navigation/ NavHost, routes
|
||||
theme/ Material 3 theme
|
||||
common/ Shared UI (UiState, LoadingIndicator, ErrorState)
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
The app uses the [Plausible Stats API v2](https://plausible.io/docs/stats-api). Rate limit is 600 requests/hour — with 8 queries per dashboard load, that's ~75 refreshes/hour.
|
||||
|
||||
### Caching
|
||||
|
||||
Cache key = SHA-256 hash of `(instanceId, siteId, dateRange)`. TTL varies:
|
||||
|
||||
| Date range | Cache TTL |
|
||||
|------------|-----------|
|
||||
| Realtime | Never cached |
|
||||
| Today | 5 min |
|
||||
| 7d, 30d | 30 min |
|
||||
| 6mo, 12mo | 2 hours |
|
||||
|
||||
On app open: show cached data immediately, refresh in background.
|
||||
|
||||
## Roadmap
|
||||
|
||||
### Phase 2 (planned)
|
||||
- Filter system (bottom sheet, combinable filters)
|
||||
- Material You dynamic color
|
||||
- Landscape layout
|
||||
- Realtime polling
|
||||
- Sites API auto-discovery
|
||||
- Custom date ranges
|
||||
- F-Droid submission
|
||||
|
||||
### Phase 3 (future)
|
||||
- Comparison mode (this period vs previous)
|
||||
- Goal conversions
|
||||
- Segments support
|
||||
- Home screen widgets (Glance)
|
||||
|
||||
## License
|
||||
|
||||
[GPL-3.0-only](LICENSE)
|
||||
|
||||
This means any distributed fork must also be open source under the same license. All dependencies are GPL-compatible (Apache 2.0, MIT).
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions welcome. The project is hosted on Forgejo at `kode.naiv.no`.
|
||||
|
||||
All source files must include the SPDX header: `// SPDX-License-Identifier: GPL-3.0-only`
|
||||
Loading…
Add table
Add a link
Reference in a new issue