Files
Postiz-android/artifacts/postiz-mobile/README.md
T
billisdead 614a353b3c chore: remove Replit/homegit references for public GitHub repo
- Simplify dev script (drop Replit-specific env vars)
- Remove REPLIT_* fallbacks from scripts/build.js
- Rewrite root README for GitHub (local build, no EAS, no homegit URLs)
- Update clone URL in artifacts README → GitHub
- Remove replit.md (Replit workspace descriptor, no longer needed)
- Untrack scripts/push-to-gitea.sh (internal-only, added to .gitignore)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 09:05:46 +02:00

229 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PostizMobile
React Native (Expo) mobile app to control a self-hosted [Postiz](https://postiz.com) instance from Android.
Build is fully local — no expo.dev account or EAS cloud required.
---
## Features
| Screen | Description |
|--------|-------------|
| **Calendar** | Monthly view with color dots per day (indigo = scheduled, green = published, red = error). Tap a day post to copy or edit it. |
| **Posts** | Filtered list (All / Queue / Published / Draft / Error) with post counts, sort toggle (newest/oldest, persisted), pull-to-refresh, swipe left to delete, swipe right to reschedule. |
| **Compose** | Text editor with per-network character limit, channel picker, date/time picker, gallery image pick + upload, publish now or schedule. Local draft save/restore. |
| **Settings** | API key and base URL, connection test, secure storage. 401 auto-redirect to Settings. |
| **Notifications** | Local alerts when a post transitions to PUBLISHED or ERROR (polling every 15 min). |
**Theme**: forced dark. **Auth**: API key in `expo-secure-store`, never hardcoded.
---
## Prerequisites
| Tool | Version |
|------|---------|
| Node.js | 20 LTS |
| pnpm | 10+ |
| Java (JDK) | 1724 (Java 25+ not yet supported by Gradle 8) |
| Android SDK | see below |
No expo.dev account needed for builds.
---
## Development
### Install dependencies
```bash
git clone https://github.com/pirona/postiz-android.git
cd postiz-android
pnpm install
```
### Start dev server (Expo Go)
```bash
pnpm --filter @workspace/postiz-mobile run dev
```
Scan the QR code with Expo Go on Android to preview the app live.
---
## Building an APK (local, no EAS)
### First-time setup
**1. Java 21 LTS**
Gradle 8 requires Java ≤ 24. If the system Java is 25+ (Fedora 44), install Temurin 21 locally:
```bash
wget -O /tmp/jdk21.tar.gz \
"https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.7%2B6/OpenJDK21U-jdk_x64_linux_hotspot_21.0.7_6.tar.gz"
mkdir -p ~/jdk21 && tar -xzf /tmp/jdk21.tar.gz -C ~/jdk21 --strip-components=1
```
`build-apk.sh` will use `~/jdk21` automatically if the system Java is ≥ 25.
**2. Android SDK**
```bash
cd artifacts/postiz-mobile
./install-android-sdk.sh
```
Add to `~/.bashrc` or `~/.zshrc`:
```bash
export ANDROID_HOME="$HOME/android-sdk"
export PATH="$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/35.0.0"
```
**2. Signing keystore**
The release keystore is stored at `~/.config/postiz-mobile/postiz-mobile.jks` (not in the repo).
To export it from EAS (one-time):
```bash
cd artifacts/postiz-mobile
eas credentials --platform android
# → Keystore: Manage everything → Download existing keystore
# Note the key alias and passwords shown during export
```
**3. Signing credentials**
```bash
cp ~/.config/postiz-mobile/signing.env.example ~/.config/postiz-mobile/signing.env
$EDITOR ~/.config/postiz-mobile/signing.env
```
Fill in:
```bash
KEYSTORE_PATH="$HOME/.config/postiz-mobile/postiz-mobile.jks"
KEYSTORE_ALIAS="<alias shown during export>"
KEYSTORE_STORE_PASSWORD="<store password>"
KEYSTORE_KEY_PASSWORD="<key password>"
```
### Build
```bash
cd artifacts/postiz-mobile
./build-apk.sh # → dist/postiz-mobile-YYYYMMDD-HHMM.apk
./build-apk.sh --aab # → dist/postiz-mobile-YYYYMMDD-HHMM.aab (Play Store)
```
The script runs `expo prebuild`, patches `android/app/build.gradle` for release signing, runs Gradle, copies the artifact to `dist/`, then wipes the credentials from `gradle.properties`.
### Install on device
```bash
adb install dist/postiz-mobile-*.apk
```
---
## How the build works
```
build-apk.sh
├── source ~/.config/postiz-mobile/signing.env
├── expo prebuild --platform android --clean
│ └── generates android/ from app.json + plugins
├── python3 patch: injects release signingConfig into build.gradle
├── append MYAPP_UPLOAD_* to gradle.properties
├── ./gradlew assembleRelease (or bundleRelease)
├── wipe signing block from gradle.properties
└── copy APK → dist/
```
The `android/` directory is not committed (gitignored). It is regenerated on each build.
---
## App configuration
On first launch, go to **Settings**:
1. **Base URL**: `https://your-postiz-instance/api/public/v1`
2. **API Key**: generated in Postiz → Settings → API Keys
3. Tap **Test Connection**, then **Save Settings**
The key is encrypted locally via `expo-secure-store` and never sent to third parties.
---
## Architecture
```
artifacts/postiz-mobile/
├── app/
│ ├── _layout.tsx # Root layout: providers, fonts, 401 handler
│ └── (tabs)/
│ ├── _layout.tsx # Tab bar
│ ├── index.tsx # Calendar screen
│ ├── posts.tsx # Post list screen
│ ├── compose.tsx # Compose screen
│ └── settings.tsx # Settings screen
├── components/
│ ├── ChannelChip.tsx # Channel selector chip
│ ├── ErrorBoundary.tsx
│ ├── PostCard.tsx # Swipe-to-delete / swipe-to-reschedule
│ └── StatusBadge.tsx
├── context/
│ └── PostizContext.tsx # axios client + SecureStore + 401 interceptor
├── hooks/
│ ├── useColors.ts
│ └── useNotifications.ts # Permission + polling + local notifications
├── lib/
│ └── extractError.ts # Shared axios/fetch error formatter
├── build-apk.sh # Local build script
└── install-android-sdk.sh # One-time Android SDK bootstrap
```
### Key dependencies
| Package | Role |
|---------|------|
| `expo-router` | File-based navigation |
| `axios` | Postiz API HTTP client |
| `expo-secure-store` | Encrypted key storage |
| `react-native-calendars` | Calendar view |
| `@react-native-community/datetimepicker` | Date/time picker |
| `expo-image-picker` | Gallery access |
| `expo-notifications` | Local status notifications |
| `@tanstack/react-query` | API cache + refetch |
---
## Postiz API
| Method | Endpoint | Usage |
|--------|----------|-------|
| `GET` | `/integrations` | List channels |
| `GET` | `/posts?startDate=&endDate=` | Posts over a date range |
| `POST` | `/posts` | Create / schedule a post |
| `DELETE` | `/posts/:id` | Delete a post |
| `POST` | `/upload` | Upload an image (multipart) |
---
## Troubleshooting
**"Not Configured" on all screens** → Settings tab → enter API key and URL → Test Connection.
**"Connection failed"** → URL must end with `/api/public/v1` — check Postiz is reachable.
**No notifications** → Accept permissions on first launch. Polling runs every 15 min.
**Build fails at Gradle** → Make sure `ANDROID_HOME` is set and `./gradlew` is executable (`chmod +x android/gradlew`).
**`expo prebuild` fails** → Run `pnpm install` from the repo root first.