mirror of
https://github.com/pawelorzech/Swoosh.git
synced 2026-03-31 11:55:47 +00:00
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
This commit is contained in:
parent
7da55c4b35
commit
74f42fd2f1
8 changed files with 409 additions and 9 deletions
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
|
@ -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.
|
||||
19
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
19
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
|
@ -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.
|
||||
12
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
12
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
## Summary
|
||||
|
||||
Brief description of the changes.
|
||||
|
||||
## Changes
|
||||
|
||||
-
|
||||
|
||||
## Testing
|
||||
|
||||
- [ ] Unit tests pass (`./gradlew test`)
|
||||
- [ ] Tested on device/emulator
|
||||
38
.gitignore
vendored
38
.gitignore
vendored
|
|
@ -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
|
||||
|
|
|
|||
24
CHANGELOG.md
Normal file
24
CHANGELOG.md
Normal file
|
|
@ -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)
|
||||
42
CONTRIBUTING.md
Normal file
42
CONTRIBUTING.md
Normal file
|
|
@ -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).
|
||||
135
LICENSE
Normal file
135
LICENSE
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
# PolyForm Noncommercial License 1.0.0
|
||||
|
||||
<https://polyformproject.org/licenses/noncommercial/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)
|
||||
119
README.md
Normal file
119
README.md
Normal file
|
|
@ -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.
|
||||
|
||||
[](https://developer.android.com)
|
||||
[](https://kotlinlang.org)
|
||||
[](https://developer.android.com/jetpack/compose)
|
||||
[](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)
|
||||
Loading…
Reference in a new issue