Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b18d33cec7 | |||
| 4a3f5da521 | |||
| d0335b552a | |||
| 134dbe214e | |||
| 7617779a18 |
@@ -1,4 +1,4 @@
|
|||||||
modules = ["nodejs-24", "python-3.11"]
|
modules = ["nodejs-24"]
|
||||||
|
|
||||||
[deployment]
|
[deployment]
|
||||||
router = "application"
|
router = "application"
|
||||||
@@ -17,7 +17,7 @@ expertMode = true
|
|||||||
|
|
||||||
[postMerge]
|
[postMerge]
|
||||||
path = "scripts/post-merge.sh"
|
path = "scripts/post-merge.sh"
|
||||||
timeoutMs = 120000
|
timeoutMs = 20000
|
||||||
|
|
||||||
[[ports]]
|
[[ports]]
|
||||||
localPort = 8080
|
localPort = 8080
|
||||||
|
|||||||
@@ -1,367 +0,0 @@
|
|||||||
# PostizMobile
|
|
||||||
|
|
||||||
Application mobile React Native (Expo) pour piloter une instance **Postiz** auto-hébergée depuis votre téléphone Android ou iOS.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Sommaire
|
|
||||||
|
|
||||||
1. [Fonctionnalités](#fonctionnalités)
|
|
||||||
2. [Prérequis](#prérequis)
|
|
||||||
3. [Installation & développement](#installation--développement)
|
|
||||||
4. [Configuration de l'application](#configuration-de-lapplication)
|
|
||||||
5. [Architecture du projet](#architecture-du-projet)
|
|
||||||
6. [API Postiz utilisée](#api-postiz-utilisée)
|
|
||||||
7. [Build APK Android (EAS)](#build-apk-android-eas)
|
|
||||||
8. [Build iOS (Expo Launch)](#build-ios-expo-launch)
|
|
||||||
9. [Pousser les modifications sur Gitea](#pousser-les-modifications-sur-gitea)
|
|
||||||
10. [Variables d'environnement & secrets](#variables-denvironnement--secrets)
|
|
||||||
11. [Dépannage](#dépannage)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Fonctionnalités
|
|
||||||
|
|
||||||
| Écran | Description |
|
|
||||||
|-------|-------------|
|
|
||||||
| **Calendrier** | Vue mensuelle avec points de couleur par jour (indigo = planifié, vert = publié, rouge = erreur). Tap sur un jour pour voir les posts. |
|
|
||||||
| **Posts** | Liste filtrée (Tous / Queue / Publié / Brouillon / Erreur) avec pull-to-refresh et swipe gauche pour supprimer. |
|
|
||||||
| **Composer** | Éditeur de texte, sélecteur de canaux, date/heure, importation d'image galerie + upload, publier maintenant ou planifier. |
|
|
||||||
| **Paramètres** | Saisie de la clé API et de l'URL de base, test de connexion, sauvegarde sécurisée (SecureStore). |
|
|
||||||
| **Notifications** | Alertes locales automatiques quand un post passe à PUBLISHED ou ERROR (polling toutes les 15 minutes). |
|
|
||||||
|
|
||||||
**Thème** : dark forcé (`userInterfaceStyle: dark`).
|
|
||||||
**Authentification** : clé API stockée dans `expo-secure-store`, jamais en dur dans le code.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prérequis
|
|
||||||
|
|
||||||
| Outil | Version minimale |
|
|
||||||
|-------|-----------------|
|
|
||||||
| Node.js | 20 LTS |
|
|
||||||
| pnpm | 10+ |
|
|
||||||
| Expo Go (téléphone) | SDK 54 compatible |
|
|
||||||
| Compte EAS (pour APK) | gratuit sur expo.dev |
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install -g pnpm
|
|
||||||
npm install -g eas-cli
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Installation & développement
|
|
||||||
|
|
||||||
### 1. Cloner le dépôt
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git
|
|
||||||
cd Postiz-android
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Installer les dépendances
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm install
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Lancer le serveur de développement
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm --filter @workspace/postiz-mobile run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
Le terminal affiche un QR code. Scannez-le avec **Expo Go** (Android) ou l'app **Appareil photo** (iOS) pour voir l'app en direct.
|
|
||||||
|
|
||||||
### 4. Ouvrir dans le navigateur (web preview)
|
|
||||||
|
|
||||||
```
|
|
||||||
http://localhost:<PORT>
|
|
||||||
```
|
|
||||||
|
|
||||||
Le port est assigné dynamiquement par l'environnement Replit.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Configuration de l'application
|
|
||||||
|
|
||||||
Au premier lancement, l'écran **Paramètres** s'affiche car aucune clé n'est configurée.
|
|
||||||
|
|
||||||
1. **URL de base** : `https://votre-instance-postiz.fr/public/v1`
|
|
||||||
2. **Clé API** : générée depuis votre instance Postiz → *Settings → API Keys*
|
|
||||||
3. Appuyez sur **Test Connection** pour valider
|
|
||||||
4. Appuyez sur **Save Settings**
|
|
||||||
|
|
||||||
La clé est chiffrée et stockée localement via `expo-secure-store`. Elle n'est jamais envoyée à un service tiers.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Architecture du projet
|
|
||||||
|
|
||||||
```
|
|
||||||
artifacts/postiz-mobile/
|
|
||||||
├── app/
|
|
||||||
│ ├── _layout.tsx # Root layout : providers, fonts, notifications
|
|
||||||
│ └── (tabs)/
|
|
||||||
│ ├── _layout.tsx # Tab bar (NativeTabs iOS 26+ / Tabs classique)
|
|
||||||
│ ├── index.tsx # Écran Calendrier
|
|
||||||
│ ├── posts.tsx # Écran Liste des posts
|
|
||||||
│ ├── compose.tsx # Écran Composer
|
|
||||||
│ └── settings.tsx # Écran Paramètres
|
|
||||||
├── components/
|
|
||||||
│ ├── ChannelChip.tsx # Chip de sélection de canal
|
|
||||||
│ ├── ErrorBoundary.tsx # Gestionnaire d'erreurs global
|
|
||||||
│ ├── PostCard.tsx # Carte post avec swipe-to-delete
|
|
||||||
│ └── StatusBadge.tsx # Badge QUEUE / PUBLISHED / ERROR / DRAFT
|
|
||||||
├── constants/
|
|
||||||
│ └── colors.ts # Palette dark theme
|
|
||||||
├── context/
|
|
||||||
│ └── PostizContext.tsx # Client axios + SecureStore (apiKey, baseUrl)
|
|
||||||
├── hooks/
|
|
||||||
│ ├── useColors.ts # Tokens couleur selon le thème
|
|
||||||
│ └── useNotifications.ts # Permissions + polling + notifications locales
|
|
||||||
├── assets/
|
|
||||||
│ └── images/
|
|
||||||
│ └── icon.png # Icône générée par IA
|
|
||||||
└── app.json # Config Expo (permissions, plugins, thème)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Dépendances principales
|
|
||||||
|
|
||||||
| Package | Usage |
|
|
||||||
|---------|-------|
|
|
||||||
| `expo-router` | Navigation file-based |
|
|
||||||
| `axios` | Client HTTP vers l'API Postiz |
|
|
||||||
| `expo-secure-store` | Stockage chiffré de la clé API |
|
|
||||||
| `react-native-calendars` | Vue calendrier mensuelle |
|
|
||||||
| `@react-native-community/datetimepicker` | Sélecteur date/heure dans Composer |
|
|
||||||
| `expo-image-picker` | Accès galerie photos |
|
|
||||||
| `expo-notifications` | Notifications locales de statut |
|
|
||||||
| `expo-task-manager` | Tâche de fond pour le polling |
|
|
||||||
| `@tanstack/react-query` | Cache et refetch des données API |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## API Postiz utilisée
|
|
||||||
|
|
||||||
Base URL configurée par l'utilisateur (ex. `https://postiz.example.com/public/v1`).
|
|
||||||
|
|
||||||
| Méthode | Endpoint | Usage |
|
|
||||||
|---------|----------|-------|
|
|
||||||
| `GET` | `/integrations` | Lister les canaux (Twitter, LinkedIn, etc.) |
|
|
||||||
| `GET` | `/posts?startDate=&endDate=` | Posts sur une plage de dates |
|
|
||||||
| `POST` | `/posts` | Créer / planifier un post |
|
|
||||||
| `DELETE` | `/posts/:id` | Supprimer un post |
|
|
||||||
| `POST` | `/upload` | Uploader une image (multipart) |
|
|
||||||
|
|
||||||
### Exemple de payload POST /posts
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "schedule",
|
|
||||||
"date": "2025-01-15T10:00:00.000Z",
|
|
||||||
"content": [
|
|
||||||
{
|
|
||||||
"content": "Mon super post 🚀",
|
|
||||||
"image": [{ "id": "upload-id", "path": "/uploads/photo.jpg" }]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"integrations": ["integration-id-twitter", "integration-id-linkedin"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Pour publier immédiatement, utilisez `"type": "now"`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Build APK Android (EAS)
|
|
||||||
|
|
||||||
> **Prérequis** : compte gratuit sur [expo.dev](https://expo.dev) et `eas-cli` installé.
|
|
||||||
|
|
||||||
### 1. Se connecter à EAS
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx eas login
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Initialiser EAS dans le projet
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd artifacts/postiz-mobile
|
|
||||||
npx eas init
|
|
||||||
```
|
|
||||||
|
|
||||||
Cela génère un `projectId` dans `app.json`.
|
|
||||||
|
|
||||||
### 3. Créer le fichier de configuration EAS
|
|
||||||
|
|
||||||
Créez `artifacts/postiz-mobile/eas.json` :
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"cli": {
|
|
||||||
"version": ">= 16.0.0"
|
|
||||||
},
|
|
||||||
"build": {
|
|
||||||
"preview": {
|
|
||||||
"android": {
|
|
||||||
"buildType": "apk"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"production": {
|
|
||||||
"android": {
|
|
||||||
"buildType": "app-bundle"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"submit": {
|
|
||||||
"production": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Lancer le build APK
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# APK de test (sideload)
|
|
||||||
npx eas build --platform android --profile preview
|
|
||||||
|
|
||||||
# AAB pour le Play Store
|
|
||||||
npx eas build --platform android --profile production
|
|
||||||
```
|
|
||||||
|
|
||||||
Le build se fait dans le cloud EAS. Vous recevez un lien de téléchargement à la fin (~10-15 min).
|
|
||||||
|
|
||||||
### 5. Installer l'APK sur votre téléphone
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Via adb
|
|
||||||
adb install postiz-mobile.apk
|
|
||||||
|
|
||||||
# Ou scannez le QR code affiché par EAS
|
|
||||||
```
|
|
||||||
|
|
||||||
### Permissions Android déclarées
|
|
||||||
|
|
||||||
```xml
|
|
||||||
READ_EXTERNAL_STORAGE
|
|
||||||
WRITE_EXTERNAL_STORAGE
|
|
||||||
READ_MEDIA_IMAGES <!-- photos galerie -->
|
|
||||||
RECEIVE_BOOT_COMPLETED
|
|
||||||
VIBRATE <!-- notifications -->
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Build iOS (Expo Launch)
|
|
||||||
|
|
||||||
> Disponible uniquement via **Replit Expo Launch** (soumission App Store automatisée).
|
|
||||||
|
|
||||||
1. Dans Replit, cliquez sur le bouton **Publish**
|
|
||||||
2. Sélectionnez **Expo Launch**
|
|
||||||
3. Suivez le wizard (compte Apple Developer requis)
|
|
||||||
|
|
||||||
**Note** : la publication Google Play n'est pas encore supportée par Expo Launch — utilisez EAS pour Android.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Pousser les modifications sur Gitea
|
|
||||||
|
|
||||||
Le dépôt distant est : `ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git`
|
|
||||||
|
|
||||||
La clé SSH utilisée est stockée dans la variable d'environnement `GITEA_SSH_KEY` (côté Replit).
|
|
||||||
|
|
||||||
### Push depuis votre machine locale
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ajouter le remote (une seule fois)
|
|
||||||
git remote add gitea ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git
|
|
||||||
|
|
||||||
# Pousser
|
|
||||||
git push gitea main
|
|
||||||
```
|
|
||||||
|
|
||||||
Assurez-vous que votre clé SSH publique est ajoutée dans Gitea → *Paramètres utilisateur → SSH / GPG Keys*.
|
|
||||||
|
|
||||||
### Push depuis Replit (via script)
|
|
||||||
|
|
||||||
Depuis Replit, les commandes `git push` directes sont protégées. Utilisez le script de bundle :
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Créer le bundle
|
|
||||||
git bundle create /tmp/postiz.bundle main
|
|
||||||
|
|
||||||
# Cloner le bundle et pousser
|
|
||||||
git clone /tmp/postiz.bundle /tmp/repo_push
|
|
||||||
cd /tmp/repo_push
|
|
||||||
git remote add gitea ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git
|
|
||||||
GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=no -p 2222" \
|
|
||||||
git push --force gitea main
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Variables d'environnement & secrets
|
|
||||||
|
|
||||||
| Variable | Stockage | Description |
|
|
||||||
|----------|----------|-------------|
|
|
||||||
| `GITEA_SSH_KEY` | Replit Secrets (shared) | Clé SSH privée pour push vers Gitea |
|
|
||||||
| `SESSION_SECRET` | Replit Secrets | Secret de session (API server) |
|
|
||||||
|
|
||||||
Les variables côté app (clé API Postiz, URL) sont **saisies par l'utilisateur** dans l'écran Paramètres et stockées dans `expo-secure-store` — elles ne transitent jamais dans le code source.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Dépannage
|
|
||||||
|
|
||||||
### L'app affiche "Not Configured" sur tous les écrans
|
|
||||||
|
|
||||||
→ Allez dans l'onglet **Paramètres**, entrez votre clé API et URL, puis tapez **Test Connection**.
|
|
||||||
|
|
||||||
### "Connection failed" dans les Paramètres
|
|
||||||
|
|
||||||
- Vérifiez que l'URL se termine bien par `/public/v1`
|
|
||||||
- Vérifiez que la clé API est valide (générée dans Postiz → API Keys)
|
|
||||||
- Vérifiez que votre instance Postiz est accessible depuis internet
|
|
||||||
|
|
||||||
### Pas de notifications reçues
|
|
||||||
|
|
||||||
- Acceptez les permissions de notification au premier lancement
|
|
||||||
- Le polling se fait toutes les 15 minutes — attendez un cycle complet
|
|
||||||
- Sur Android, vérifiez que les notifications de l'app ne sont pas désactivées dans les paramètres système
|
|
||||||
|
|
||||||
### Erreur Metro "module not found"
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm install
|
|
||||||
# Puis redémarrer le workflow Expo
|
|
||||||
```
|
|
||||||
|
|
||||||
### Le calendrier ne charge pas les posts
|
|
||||||
|
|
||||||
- Vérifiez que l'API Postiz supporte les paramètres `startDate` / `endDate` sur `GET /posts`
|
|
||||||
- Consultez les logs réseau : dans Expo Go, secouez l'appareil → *Open Debugger*
|
|
||||||
|
|
||||||
### Build EAS échoue
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Vérifier la version Expo
|
|
||||||
npx expo --version
|
|
||||||
|
|
||||||
# Vérifier la cohérence des packages
|
|
||||||
npx expo install --check
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Contribuer
|
|
||||||
|
|
||||||
1. Forkez sur Gitea : `https://homegit.gyozamancave.fr/billisdead/Postiz-android`
|
|
||||||
2. Créez une branche feature : `git checkout -b feature/ma-fonctionnalite`
|
|
||||||
3. Committez vos changements
|
|
||||||
4. Poussez et ouvrez une Pull Request
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Généré avec ❤️ sur Replit — PostizMobile v1.0.0*
|
|
||||||
@@ -2,7 +2,3 @@
|
|||||||
set -e
|
set -e
|
||||||
pnpm install --frozen-lockfile
|
pnpm install --frozen-lockfile
|
||||||
pnpm --filter db push
|
pnpm --filter db push
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
echo "Syncing to Gitea..."
|
|
||||||
bash "$SCRIPT_DIR/push-to-gitea.sh" || echo "Warning: Gitea push failed (non-fatal)."
|
|
||||||
|
|||||||
+36
-10
@@ -2,24 +2,50 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
GITEA_HOST="homegit.gyozamancave.fr"
|
GITEA_HOST="homegit.gyozamancave.fr"
|
||||||
GITEA_USER="billisdead"
|
GITEA_PORT="2222"
|
||||||
GITEA_REPO="Postiz-android"
|
GITEA_USER="gitea"
|
||||||
|
GITEA_REMOTE_URL="ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git"
|
||||||
GITEA_REMOTE_NAME="gitea"
|
GITEA_REMOTE_NAME="gitea"
|
||||||
GITEA_REMOTE_URL="https://${GITEA_HOST}/${GITEA_USER}/${GITEA_REPO}.git"
|
|
||||||
|
|
||||||
if [ -z "${GITEA_SSH_KEY:-}" ]; then
|
if [ -z "${GITEA_SSH_KEY:-}" ]; then
|
||||||
echo "Error: GITEA_SSH_KEY environment variable is not set. Add the Gitea API token as a Replit secret named GITEA_SSH_KEY." >&2
|
echo "Error: GITEA_SSH_KEY environment variable is not set. Add it as a Replit secret." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if git remote get-url "$GITEA_REMOTE_NAME" &>/dev/null; then
|
SSH_DIR="$HOME/.ssh"
|
||||||
git remote set-url "$GITEA_REMOTE_NAME" "$GITEA_REMOTE_URL"
|
KEY_FILE="$SSH_DIR/id_ed25519_gitea"
|
||||||
else
|
|
||||||
|
mkdir -p "$SSH_DIR"
|
||||||
|
chmod 700 "$SSH_DIR"
|
||||||
|
|
||||||
|
printf '%s\n' "$GITEA_SSH_KEY" > "$KEY_FILE"
|
||||||
|
chmod 600 "$KEY_FILE"
|
||||||
|
|
||||||
|
cat > "$SSH_DIR/config" <<EOF
|
||||||
|
Host $GITEA_HOST
|
||||||
|
HostName $GITEA_HOST
|
||||||
|
User $GITEA_USER
|
||||||
|
Port $GITEA_PORT
|
||||||
|
IdentityFile $KEY_FILE
|
||||||
|
StrictHostKeyChecking no
|
||||||
|
EOF
|
||||||
|
chmod 600 "$SSH_DIR/config"
|
||||||
|
|
||||||
|
if ! git remote get-url "$GITEA_REMOTE_NAME" &>/dev/null; then
|
||||||
git remote add "$GITEA_REMOTE_NAME" "$GITEA_REMOTE_URL"
|
git remote add "$GITEA_REMOTE_NAME" "$GITEA_REMOTE_URL"
|
||||||
echo "Added remote '$GITEA_REMOTE_NAME'."
|
echo "Added remote '$GITEA_REMOTE_NAME'."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Pushing main branch to Gitea..."
|
echo "Creating git bundle..."
|
||||||
git -c "http.extraHeader=Authorization: token ${GITEA_SSH_KEY}" \
|
BUNDLE_FILE="$(mktemp /tmp/repo-XXXXXX.bundle)"
|
||||||
push --force "$GITEA_REMOTE_NAME" main
|
git bundle create "$BUNDLE_FILE" main
|
||||||
|
|
||||||
|
echo "Pushing to Gitea via bundle..."
|
||||||
|
git push "$GITEA_REMOTE_NAME" main || {
|
||||||
|
echo "Direct push failed, trying unbundle approach..."
|
||||||
|
GIT_SSH_COMMAND="ssh -i $KEY_FILE -o StrictHostKeyChecking=no -p $GITEA_PORT" \
|
||||||
|
git push "$GITEA_REMOTE_NAME" main
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -f "$BUNDLE_FILE"
|
||||||
echo "Push to Gitea complete."
|
echo "Push to Gitea complete."
|
||||||
|
|||||||
Reference in New Issue
Block a user