{"id":49396470,"url":"https://github.com/darthedu/esfotalk","last_synced_at":"2026-04-28T16:02:36.779Z","repository":{"id":318885723,"uuid":"1062915498","full_name":"DarthEdu/ESFOTalk","owner":"DarthEdu","description":"Repositorio de mi aplicación móvil como propuesta de Tesis","archived":false,"fork":false,"pushed_at":"2025-11-21T00:09:11.000Z","size":487,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-21T00:14:28.316Z","etag":null,"topics":["android","appwrite","flutter","social-media"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DarthEdu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-23T23:08:40.000Z","updated_at":"2025-11-21T00:10:51.000Z","dependencies_parsed_at":"2025-10-17T02:27:24.971Z","dependency_job_id":null,"html_url":"https://github.com/DarthEdu/ESFOTalk","commit_stats":null,"previous_names":["darthedu/esfotalk"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/DarthEdu/ESFOTalk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarthEdu%2FESFOTalk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarthEdu%2FESFOTalk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarthEdu%2FESFOTalk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarthEdu%2FESFOTalk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DarthEdu","download_url":"https://codeload.github.com/DarthEdu/ESFOTalk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarthEdu%2FESFOTalk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32387923,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-28T14:34:11.604Z","status":"ssl_error","status_checked_at":"2026-04-28T14:32:37.009Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","appwrite","flutter","social-media"],"created_at":"2026-04-28T16:02:28.960Z","updated_at":"2026-04-28T16:02:36.773Z","avatar_url":"https://github.com/DarthEdu.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ESFOTalk\n\n![Logo ESFOTalk](assets/icon/splash_logo.png)\n\nRed social tipo Twitter construida con Flutter + Appwrite.\n\n---\n\n## Tabla de Contenido\n\n1. [Descripción](#descripción)\n2. [Arquitectura y Tecnologías](#arquitectura-y-tecnologías)\n3. [Estructura de Directorios](#estructura-de-directorios)\n4. [Principales Features](#principales-features)\n5. [Gestión de Estado y Errores](#gestión-de-estado-y-errores)\n6. [Realtime y Actualizaciones](#realtime-y-actualizaciones)\n7. [Configuración de Entorno](#configuración-de-entorno)\n8. [Build y Firma (APK/AAB)](#build-y-firma-apkaab)\n9. [Permisos Android](#permisos-android)\n10. [Icono y Splash Screen](#icono-y-splash-screen)\n11. [Descarga del APK](#descarga-del-apk)\n12. [Contribución](#contribución)\n13. [Licencia](#licencia)\n\n---\n\n## Descripción\n\n**ESFOTalk** es una aplicación móvil inspirada en Twitter/X donde los usuarios pueden publicar *roars* (posts), responder, dar like, reenviar (reshare) y seguir a otros perfiles. Construida para aprendizaje y demostración de arquitectura limpia con Flutter + Appwrite como Backend-as-a-Service.\n\n## Arquitectura y Tecnologías\n\n| Capa | Tecnología |\n|------|------------|\n| Frontend | Flutter (Dart) |\n| Estado | Riverpod (StateNotifier, FutureProvider, StreamProvider) |\n| Backend | Appwrite (Auth, DB, Storage, Realtime) |\n| Manejo de errores | FpDart (`Either\u003cFailure, T\u003e`) |\n| Persistencia imágenes | Appwrite Storage |\n| Iconos SVG | `flutter_svg` |\n| Compresión imágenes | `flutter_image_compress` |\n\nPatrón **feature-first**: cada dominio (auth, roar, explore, notifications, user_profile, home) tiene `controller/`, `view/`, `widgets/`.\n\n## Estructura de Directorios\n\n```text\nlib/\n ├── apis/            # Comunicación Appwrite (AuthAPI, RoarAPI, UserAPI, etc.)\n ├── common/          # Widgets reutilizables (Loader, ErrorText, etc.)\n ├── constants/       # Constantes (AppwriteConstants, assets)\n ├── core/            # Tipos base, providers globales, utils\n ├── features/        # Features organizados por dominio\n │   ├── auth/\n │   ├── roar/\n │   ├── explore/\n │   ├── notifications/\n │   ├── user_profile/\n │   └── home/\n ├── models/          # Modelos inmutables (UserModel, Roar, NotificationModel)\n └── theme/           # Paleta y tema\n```\n\n## Principales Features\n\n- Registro e inicio de sesión (email/password)\n- Publicar roars con texto e imágenes\n- Responder roars (vista `RoarReplyScreen` optimizada para teclado)\n- Likes, reshares y contador de comentarios\n- Perfiles con bio, banner y foto\n- Seguidores / Siguiendo + notificación al ser seguido\n- Feed en tiempo real (actualización por eventos Appwrite Realtime)\n- Búsqueda por hashtags y usuarios\n\n## Gestión de Estado y Errores\n\nLos controladores extienden `StateNotifier\u003cbool\u003e` (indicando `isLoading`). Se usan:\n\n- `FutureProvider` para cargas puntuales\n- `StreamProvider` para feeds y perfiles en tiempo real\n\nErrores manejados con `Either\u003cFailure, T\u003e`:\n\n```dart\ntypedef FutureEither\u003cT\u003e = Future\u003cEither\u003cFailure, T\u003e\u003e;\nres.fold((failure) =\u003e showSnackBar(context, failure.message), (value) =\u003e ...);\n```\n\n## Realtime y Actualizaciones\n\nSe suscribe a canales Appwrite:\n\n```dart\n_realtime.subscribe([\n  'databases.{dbId}.collections.{collectionId}.documents'\n]).stream;\n```\n\nLos providers de roars procesan eventos `create/update/delete`. Para perfil se invalida el provider tras edición para reflejar cambios inmediatos.\n\n## Configuración de Entorno\n\nArchivo `lib/constants/appwrite_constants.dart`:\n\n```dart\nclass AppwriteConstants {\n  static const String databaseId = '...';\n  static const String projectId  = '...';\n  static const String endPoint   = 'https://sfo.cloud.appwrite.io/v1';\n  // Tablas y bucket\n}\n```\n\nCliente Appwrite (`core/providers.dart`):\n\n```dart\nClient()\n  .setEndpoint(AppwriteConstants.endPoint)\n  .setProject(AppwriteConstants.projectId); // sin setSelfSigned en Cloud\n```\n\n## Build y Firma (APK/AAB)\n\nPasos para generar un APK/AAB firmado:\n\n- Crear keystore\n\n```bash\nkeytool -genkeypair -v -keystore /c/keystores/esfotalk-keystore.jks -alias esfotalk_key -keyalg RSA -keysize 2048 -validity 3650\n```\n\n- Crear archivo `android/key.properties`\n\n```properties\nstorePassword=********\nkeyPassword=********\nkeyAlias=esfotalk_key\nstoreFile=C:/keystores/esfotalk-keystore.jks\n```\n\n- Configurar `signingConfigs` en `android/app/build.gradle.kts` (release)\n\n- Compilar APK\n\n```bash\nflutter build apk --release\n```\n\n- Generar App Bundle (Play Store)\n\n```bash\nflutter build appbundle --release\n```\n\n## Permisos Android\n\nIncluidos en `AndroidManifest.xml`:\n\n`INTERNET`, `ACCESS_NETWORK_STATE`, `CAMERA`, `READ_MEDIA_IMAGES`, `READ_EXTERNAL_STORAGE (\u003c=12)`, `POST_NOTIFICATIONS (\u003e=13)`, `VIBRATE`.\n\n## Icono y Splash Screen\n\nConfigurados en `pubspec.yaml` usando:\n\n- `flutter_launcher_icons`\n- `flutter_native_splash`\n\nAgregar imágenes en `assets/icon/`:\n\n```text\napp_icon.png\napp_icon_foreground.png\nsplash_logo.png\n```\n\nGenerar:\n\n```bash\ndart run flutter_launcher_icons\ndart run flutter_native_splash:create\n```\n\n## Descarga del APK\n\nVersión estable (release) compilada:\n\n| Plataforma | Archivo | Estado |\n|------------|---------|--------|\n| Android | `release/ESFOTalk-v1.0.0.apk` | ✅ Disponible (añadir tras commit) |\n\n### Cómo anexar el APK al repositorio\n\n- Copiar archivo generado:\n\n```text\nbuild/app/outputs/flutter-apk/app-release.apk\n```\n\n- Renombrar a `ESFOTalk-v1.0.0.apk`\n\n- Mover a carpeta dedicada:\n\n```bash\nmkdir release\nmv build/app/outputs/flutter-apk/app-release.apk release/ESFOTalk-v1.0.0.apk\n```\n\n- Commit y push:\n\n```bash\ngit add release/ESFOTalk-v1.0.0.apk\ngit commit -m \"chore: add ESFOTalk v1.0.0 APK\"\ngit push origin main\n```\n\n- (Recomendado) Crear un **GitHub Release** y subir el APK como asset.\n\n\u003e Nota: Evita subir muchos APK pesados al historial para no inflar el repositorio. Usa Releases cuando sea posible.\n\n## Contribución\n\n1. Haz fork del repositorio\n2. Crea rama: `git checkout -b feature/nueva-funcionalidad`\n3. Commit descriptivo: `feat: agregar contador de comentarios`\n4. Push y Pull Request\n\n## Licencia\n\nProyecto educativo. Si se formaliza, añadir una licencia (MIT / Apache-2.0) aquí.\n\n---\n\n¿Sugerencias o mejoras? Abre un issue o PR. ¡Ruge tus ideas! 🐲\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarthedu%2Fesfotalk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdarthedu%2Fesfotalk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarthedu%2Fesfotalk/lists"}