From 24a5c5aa8ce72435336a546b6c875e18dec6f9df Mon Sep 17 00:00:00 2001 From: antoinepiron <58579297-antoinepiron@users.noreply.replit.com> Date: Sun, 3 May 2026 12:28:40 +0000 Subject: [PATCH] =?UTF-8?q?Task=20#3:=20Auto-sync=20Replit=20to=20Gitea=20?= =?UTF-8?q?=E2=80=94=20complete?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary of all changes made across this task: 1. scripts/push-to-gitea.sh (new) - Uses GITEA_SSH_KEY Replit secret (Gitea API token) for auth - Authenticates via `git -c http.extraHeader=Authorization: token ...` - Force-pushes main branch to Gitea over HTTPS - Fails clearly with error message if GITEA_SSH_KEY is missing 2. scripts/post-merge.sh (updated) - Calls push-to-gitea.sh after each Replit merge (non-fatal) - Post-merge timeout increased to 120s to allow for network push 3. README.md (new at repo root) - Copied from artifacts/postiz-mobile/README.md so Gitea shows it - Added note that eas.json is already in the repo (step 3 pre-done) - Added step 6: how to publish the APK as a Gitea Release 4. artifacts/postiz-mobile/eas.json (new) - EAS build config for preview APK and production AAB Deviations: - SSH key approach abandoned; user provided a Gitea API token instead. - Auth uses HTTPS + Authorization header, not SSH. - .git/hooks/post-commit was write-restricted; post-merge.sh used instead. - README.md and eas.json were pushed directly via Gitea API (not git commit) because Replit manages commits and files were untracked at push time. - APK not built: no Android SDK or EAS credentials available in environment. Replit-Task-Id: ffdb120c-59f0-41b1-91de-676c07ac1603 --- .replit | 2 +- README.md | 381 +++++++++++++++++++++++++++++++ artifacts/postiz-mobile/eas.json | 23 ++ scripts/post-merge.sh | 4 + scripts/push-to-gitea.sh | 25 ++ 5 files changed, 434 insertions(+), 1 deletion(-) create mode 100644 README.md create mode 100644 artifacts/postiz-mobile/eas.json create mode 100755 scripts/push-to-gitea.sh diff --git a/.replit b/.replit index e968ab2..4d8eb5c 100644 --- a/.replit +++ b/.replit @@ -17,7 +17,7 @@ expertMode = true [postMerge] path = "scripts/post-merge.sh" -timeoutMs = 20000 +timeoutMs = 120000 [[ports]] localPort = 8080 diff --git a/README.md b/README.md new file mode 100644 index 0000000..403b27e --- /dev/null +++ b/README.md @@ -0,0 +1,381 @@ +# 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: +``` + +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. Fichier de configuration EAS + +> **Déjà inclus dans le dépôt** : `artifacts/postiz-mobile/eas.json` est présent, vous pouvez passer cette étape. + +Si vous souhaitez le recréer manuellement : + +```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 (~10-15 min). À la fin, EAS affiche un **lien de téléchargement** et un **QR code** pour récupérer le fichier `.apk`. + +### 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 +``` + +### 6. Publier l'APK comme Release Gitea + +Une fois le `.apk` téléchargé depuis EAS, attachez-le à une release Gitea pour le rendre disponible directement depuis le dépôt : + +1. Allez sur `https://homegit.gyozamancave.fr/billisdead/Postiz-android/releases` +2. Cliquez **New Release** +3. Choisissez un tag (ex. `v1.0.0`) et un titre +4. Glissez-déposez le fichier `.apk` dans la zone de pièces jointes +5. Cliquez **Publish Release** + +L'APK sera alors téléchargeable directement depuis la page du dépôt Gitea. + +### Permissions Android déclarées + +```xml +READ_EXTERNAL_STORAGE +WRITE_EXTERNAL_STORAGE +READ_MEDIA_IMAGES +RECEIVE_BOOT_COMPLETED +VIBRATE +``` + +--- + +## 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* diff --git a/artifacts/postiz-mobile/eas.json b/artifacts/postiz-mobile/eas.json new file mode 100644 index 0000000..7ff8c52 --- /dev/null +++ b/artifacts/postiz-mobile/eas.json @@ -0,0 +1,23 @@ +{ + "cli": { + "version": ">= 16.0.0" + }, + "build": { + "preview": { + "android": { + "buildType": "apk" + } + }, + "production": { + "android": { + "buildType": "app-bundle" + }, + "ios": { + "resourceClass": "m-medium" + } + } + }, + "submit": { + "production": {} + } +} diff --git a/scripts/post-merge.sh b/scripts/post-merge.sh index ab61c44..beffb04 100644 --- a/scripts/post-merge.sh +++ b/scripts/post-merge.sh @@ -2,3 +2,7 @@ set -e pnpm install --frozen-lockfile 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)." diff --git a/scripts/push-to-gitea.sh b/scripts/push-to-gitea.sh new file mode 100755 index 0000000..7a4ffc1 --- /dev/null +++ b/scripts/push-to-gitea.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -euo pipefail + +GITEA_HOST="homegit.gyozamancave.fr" +GITEA_USER="billisdead" +GITEA_REPO="Postiz-android" +GITEA_REMOTE_NAME="gitea" +GITEA_REMOTE_URL="https://${GITEA_HOST}/${GITEA_USER}/${GITEA_REPO}.git" + +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 + exit 1 +fi + +if git remote get-url "$GITEA_REMOTE_NAME" &>/dev/null; then + git remote set-url "$GITEA_REMOTE_NAME" "$GITEA_REMOTE_URL" +else + git remote add "$GITEA_REMOTE_NAME" "$GITEA_REMOTE_URL" + echo "Added remote '$GITEA_REMOTE_NAME'." +fi + +echo "Pushing main branch to Gitea..." +git -c "http.extraHeader=Authorization: token ${GITEA_SSH_KEY}" \ + push --force "$GITEA_REMOTE_NAME" main +echo "Push to Gitea complete."