From 74f42fd2f14b1da7f9fb2364d384232709969ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Orzech?= Date: Thu, 19 Mar 2026 10:17:46 +0100 Subject: [PATCH] docs: add open-source project files (README, license, contributing) Add professional open-source scaffolding: - README.md with badges, features, architecture, and setup guide - LICENSE (PolyForm Noncommercial 1.0.0) - CONTRIBUTING.md with guidelines - CHANGELOG.md for v1.0.0 - GitHub issue and PR templates - Updated .gitignore --- .github/ISSUE_TEMPLATE/bug_report.md | 29 +++++ .github/ISSUE_TEMPLATE/feature_request.md | 19 +++ .github/PULL_REQUEST_TEMPLATE.md | 12 ++ .gitignore | 38 ++++-- CHANGELOG.md | 24 ++++ CONTRIBUTING.md | 42 +++++++ LICENSE | 135 ++++++++++++++++++++++ README.md | 119 +++++++++++++++++++ 8 files changed, 409 insertions(+), 9 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 README.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..4cff084 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,29 @@ +--- +name: Bug report +about: Report a bug to help improve Swoosh +title: '' +labels: bug +assignees: '' +--- + +**Describe the bug** +A clear description of what the bug is. + +**Steps to reproduce** +1. Go to '...' +2. Tap on '...' +3. See error + +**Expected behavior** +What you expected to happen. + +**Screenshots** +If applicable, add screenshots. + +**Device info** +- Device: [e.g. Pixel 7] +- Android version: [e.g. 14] +- App version: [e.g. 1.0] + +**Additional context** +Any other context about the problem. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..89212dc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,19 @@ +--- +name: Feature request +about: Suggest an idea for Swoosh +title: '' +labels: enhancement +assignees: '' +--- + +**Problem** +What problem does this solve? + +**Proposed solution** +How do you think it should work? + +**Alternatives considered** +Any alternative solutions you've thought about. + +**Additional context** +Any other context, mockups, or references. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..9a80f4f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,12 @@ +## Summary + +Brief description of the changes. + +## Changes + +- + +## Testing + +- [ ] Unit tests pass (`./gradlew test`) +- [ ] Tested on device/emulator diff --git a/.gitignore b/.gitignore index e3bdbed..46823c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,31 @@ +# Gradle +.gradle/ +build/ +/app/build/ + +# IDE *.iml -.gradle -/local.properties -/.idea -.DS_Store -/build -/captures -.externalNativeBuild -.cxx +.idea/ +*.swp +*~ + +# Local properties local.properties -/app/build + +# Android +/captures +.externalNativeBuild/ +.cxx/ + +# macOS +.DS_Store + +# Keystore (do not commit signing keys) +*.jks +*.keystore + +# Debug logs +firebase-debug.log + +# Secrets +*.env diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..21dc620 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). + +## [1.0.0] - 2024-12-01 + +### Added + +- Ghost Admin API integration with JWT authentication +- Post creation with title and body +- Image upload from gallery and camera +- Link preview extraction via Open Graph +- Scheduled publishing +- Offline-first architecture with Room database +- Background sync via WorkManager with exponential backoff +- Encrypted credential storage (AES-256-GCM) +- Setup wizard for Ghost blog configuration +- Feed screen with pull-to-refresh +- Post detail view +- Settings screen with logout +- Material 3 UI with Jetpack Compose +- Comprehensive unit test suite (116 tests) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..466c8e5 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,42 @@ +# Contributing to Swoosh + +Thanks for your interest in contributing! Here's how you can help. + +## Getting started + +1. Fork the repository +2. Clone your fork: `git clone https://github.com/YOUR_USERNAME/Swoosh.git` +3. Create a feature branch: `git checkout -b feature/your-feature` +4. Make your changes +5. Run the tests: `./gradlew test` +6. Commit and push to your fork +7. Open a Pull Request + +## Development setup + +- Android Studio Hedgehog (2023.1.1) or later +- JDK 17 +- Android SDK 34 + +## Guidelines + +- Follow existing code style and patterns (MVVM, Repository, Compose) +- Write tests for new functionality +- Keep commits focused — one logical change per commit +- Use descriptive commit messages + +## Reporting bugs + +Open an [issue](https://github.com/pawelorzech/Swoosh/issues) with: + +- Steps to reproduce +- Expected vs actual behavior +- Android version and device info + +## Feature requests + +Open an [issue](https://github.com/pawelorzech/Swoosh/issues) with a description of the feature and why it would be useful. + +## License + +By contributing, you agree that your contributions will be licensed under the [PolyForm Noncommercial License 1.0.0](LICENSE). diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..663d526 --- /dev/null +++ b/LICENSE @@ -0,0 +1,135 @@ +# PolyForm Noncommercial License 1.0.0 + + + +## Acceptance + +In order to get any license under these terms, you must agree +to them as both strict obligations and conditions to all +your licenses. + +## Copyright License + +The licensor grants you a copyright license for the +software to do everything you might do with the software +that would otherwise infringe the licensor's copyright +in it for any permitted purpose. However, you may +only distribute the software according to [Distribution +License](#distribution-license) and make changes or new works +based on the software according to [Changes and New Works +License](#changes-and-new-works-license). + +## Distribution License + +The licensor grants you an additional copyright license +to distribute copies of the software. Your license +to distribute covers distributing the software with +changes and new works permitted by [Changes and New Works +License](#changes-and-new-works-license). + +## Notices + +You must ensure that anyone who gets a copy of any part of +the software from you also gets a copy of these terms or the +URL for them above, as well as copies of any plain-text lines +beginning with `Required Notice:` that the licensor provided +with the software. For example: + +> Required Notice: Copyright Paweł Orzech (https://pawelorzech.pl) + +## Changes and New Works License + +The licensor grants you an additional copyright license to +make changes and new works based on the software for any +permitted purpose. + +## Patent License + +The licensor grants you a patent license for the software that +covers patent claims the licensor can license, or becomes able +to license, that you would infringe by using the software. + +## Noncommercial Purposes + +Any noncommercial purpose is a permitted purpose. + +## Personal Uses + +Personal use for research, experiment, and testing for +the benefit of public knowledge, personal study, private +entertainment, hobby projects, amateur pursuits, or religious +observance, without any anticipated commercial application, +is use for a permitted purpose. + +## Noncommercial Organizations + +Use by any charitable organization, educational institution, +public research organization, public safety or health +organization, environmental protection organization, +or government institution is use for a permitted purpose +regardless of the source of funding or obligations resulting +from the funding. + +## Fair Use + +You may have "fair use" rights for the software under the +law. These terms do not limit them. + +## No Other Rights + +These terms do not allow you to sublicense or transfer any of +your licenses to anyone else, or prevent the licensor from +granting licenses to anyone else. These terms do not imply +any other licenses. + +## Patent Defense + +If you make any written claim that the software infringes or +contributes to infringement of any patent, your patent license +for the software granted under these terms ends immediately. If +your company makes such a claim, your patent license ends +immediately for work on behalf of your company. + +## Violations + +The first time you are notified in writing that you have +violated any of these terms, or done anything with the software +not covered by your licenses, your licenses can nonetheless +continue if you come into full compliance with these terms, +and take practical steps to correct past violations, within +32 days of receiving notice. Otherwise, all your licenses +end immediately. + +## No Liability + +***As far as the law allows, the software comes as is, without +any warranty or condition, and the licensor will not be liable +to you for any damages arising out of these terms or the use +or nature of the software, under any kind of legal claim.*** + +## Definitions + +The **licensor** is the individual or entity offering these +terms, and the **software** is the software the licensor makes +available under these terms. + +**You** refers to the individual or entity agreeing to these +terms. + +**Your company** is any legal entity, sole proprietorship, +or other kind of organization that you work for, plus all +organizations that have control over, are under the control of, +or are under common control with that organization. **Control** +means ownership of substantially all the assets of an entity, +or the power to direct its management and policies by vote, +contract, or otherwise. Control can be direct or indirect. + +**Your licenses** are all the licenses granted to you for the +software under these terms. + +**Use** means anything you do with the software requiring one +of your licenses. + +--- + +Required Notice: Copyright (c) 2024 Paweł Orzech (https://pawelorzech.pl) diff --git a/README.md b/README.md new file mode 100644 index 0000000..737ab31 --- /dev/null +++ b/README.md @@ -0,0 +1,119 @@ +# 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) + +## Features + +- **Ghost Admin API** — Full integration via JWT authentication (HS256) +- **Offline-first** — Posts are saved locally and synced when connectivity returns +- **Image uploads** — Attach photos from your gallery or camera +- **Link previews** — Automatic Open Graph metadata extraction (title, description, thumbnail) +- **Scheduled publishing** — Set a future publish date for your posts +- **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, modern interface built entirely with Jetpack Compose + +## Screenshots + +> Coming soon — contributions welcome! + +## 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) +│ └── repository/ # PostRepository, OpenGraphFetcher +├── ui/ +│ ├── feed/ # Post list with pull-to-refresh +│ ├── composer/ # Post creation and editing +│ ├── detail/ # Full post view +│ ├── setup/ # Initial configuration wizard +│ ├── settings/ # App settings and logout +│ ├── navigation/ # Compose Navigation graph +│ └── theme/ # Material 3 theming +└── 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. + +## 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/pawelorzech/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 +``` + +Test coverage includes JWT generation, mobiledoc building, URL normalization, data model serialization, auth interceptors, and time formatting. + +## Tech stack + +| Layer | Technology | +|-------|-----------| +| UI | Jetpack Compose, Material 3 | +| Navigation | Compose Navigation | +| Architecture | MVVM, StateFlow, Repository pattern | +| Networking | Retrofit 2, OkHttp 4 | +| Images | Coil | +| 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)