Files
Postiz-android/artifacts/postiz-mobile/README.md
T
billisdead aaf6b2aa07 fix: force JAVA_HOME to ~/jdk21 when system Java ≥ 25
Gradle 8.x supports up to Java 24. Fedora 44 ships Java 25 by default,
causing "Unsupported class file major version 69" at build time.

build-apk.sh now auto-detects system Java version and falls back to
~/jdk21 (Temurin 21 LTS) when Java ≥ 25 is detected.
README documents the one-time JDK 21 install step.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 20:52:54 +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 ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/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.