# Swoosh A native Android microblogging client for [Ghost CMS](https://ghost.org). Write, publish, and manage short-form posts from your phone — with offline support, image uploads, link previews, and scheduled publishing. [![Android](https://img.shields.io/badge/Android-8.0%2B-3DDC84?logo=android&logoColor=white)](https://developer.android.com) [![Kotlin](https://img.shields.io/badge/Kotlin-1.9-7F52FF?logo=kotlin&logoColor=white)](https://kotlinlang.org) [![Jetpack Compose](https://img.shields.io/badge/Jetpack%20Compose-Material%203-4285F4?logo=jetpackcompose&logoColor=white)](https://developer.android.com/jetpack/compose) [![License](https://img.shields.io/badge/License-PolyForm%20Noncommercial-blue)](LICENSE) ## Screenshots

Feed Newsletter Statistics Settings

## Features - **Ghost Admin API** — Full integration via JWT authentication (HS256) - **Offline-first** — Posts are saved locally and synced when connectivity returns - **Multi-account** — Connect up to 5 Ghost blogs and switch between them - **Image uploads** — Attach photos from your gallery or camera - **Link previews** — Automatic Open Graph metadata extraction (title, description, thumbnail) - **Hashtag support** — Auto-extracted hashtags converted to Ghost tags - **Scheduled publishing** — Set a future publish date for your posts - **Pin posts** — Feature/pin important posts to the top of your blog - **Newsletter integration** — Send posts as newsletters to your Ghost subscribers - **Members management** — View and manage your Ghost blog members - **Static pages** — Create, edit, and manage Ghost pages from the app - **Tag management** — Browse, create, and manage tags with per-tag post counts - **Statistics dashboard** — Post counts, word counts, reading time, tag breakdown, and more - **Search & filtering** — Filter by status (Published, Draft, Scheduled) and sort by date - **Mobiledoc format** — Native Ghost content format with text paragraphs and bookmark cards - **Encrypted credentials** — API keys stored with AES-256-GCM via AndroidX Security - **Background sync** — WorkManager handles upload queue with exponential backoff - **Material 3 UI** — Clean, green-tinted design with polished animations and Light/Dark/System themes ## Architecture MVVM with Repository pattern, single-module Gradle project. ``` com.swoosh.microblog/ ├── data/ │ ├── api/ # Retrofit client, JWT auth, interceptors │ ├── db/ # Room database, DAOs, type converters │ ├── model/ # GhostPost (API), LocalPost (DB), FeedPost (UI), PostStats, GhostAccount │ └── repository/ # PostRepository, OpenGraphFetcher ├── ui/ │ ├── animation/ # SwooshMotion shared animation specs │ ├── components/ # Reusable composables (dialogs, placeholders) │ ├── composer/ # Post creation with images, links, hashtags, scheduling │ ├── detail/ # Full post view with pin toggle │ ├── feed/ # Post feed with search and filtering │ ├── members/ # Ghost members/subscribers management │ ├── newsletter/ # Newsletter configuration and subscriber info │ ├── pages/ # Static pages CRUD │ ├── preview/ # HTML post preview │ ├── settings/ # App settings, account management, theme toggle │ ├── setup/ # Configuration wizard and add-account flow │ ├── stats/ # Statistics dashboard with animated counters │ ├── tags/ # Tag management │ ├── navigation/ # Compose Navigation with bottom nav bar │ └── theme/ # Material 3 theming (Light/Dark/System) └── worker/ # PostUploadWorker (WorkManager) ``` **Data flow:** Compose UI → ViewModel → Repository → Room (local) + Retrofit (remote). Posts are persisted to Room first, then queued for upload via WorkManager. **Navigation:** Bottom bar with four tabs — Home (Feed), Newsletter, Stats, and Settings. Composer, Detail, Pages, Members, and Tags screens slide in as overlays. ## Getting started ### Prerequisites - Android Studio Hedgehog (2023.1.1) or later - JDK 17 - Android SDK 34 - A [Ghost](https://ghost.org) blog with Admin API access ### Ghost setup 1. In your Ghost admin panel, go to **Settings → Integrations** 2. Create a new **Custom Integration** 3. Copy the **Admin API Key** (format: `id:secret`) 4. Note your Ghost blog URL (e.g. `https://yourblog.com`) ### Build and run ```bash git clone https://github.com/nicekid1/Swoosh.git cd Swoosh ./gradlew assembleDebug ``` Install the debug APK on your device or emulator, then follow the setup wizard to connect your Ghost blog. ## Building ```bash ./gradlew assembleDebug # Debug APK ./gradlew assembleRelease # Release APK (ProGuard enabled) ``` ## Testing The project includes unit tests with JUnit 4 and Robolectric: ```bash ./gradlew test # Run all tests ./gradlew app:testDebugUnitTest # Debug variant only ``` 31 test classes covering JWT generation, mobiledoc building, URL normalization, data model serialization, auth interceptors, time formatting, hashtag parsing, account management, feed preferences, newsletter preferences, member models, and theme modes. ## Tech stack | Layer | Technology | |-------|-----------| | UI | Jetpack Compose, Material 3 | | Navigation | Compose Navigation | | Architecture | MVVM, StateFlow, Repository pattern | | Networking | Retrofit 2, OkHttp 4 | | Images | Coil | | Media | Media3 ExoPlayer | | Database | Room | | Background | WorkManager | | Auth | JJWT (HS256), EncryptedSharedPreferences | | Link parsing | Jsoup | | Testing | JUnit 4, Robolectric, MockWebServer | ## Contributing Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. ## License This project is licensed under the [PolyForm Noncommercial License 1.0.0](LICENSE) — you can use, modify, and share it for any non-commercial purpose. Commercial use requires permission from the author. ## Author **Paweł Orzech** — [pawelorzech.pl](https://pawelorzech.pl)