{"id":31906877,"url":"https://github.com/giomjds/commitly","last_synced_at":"2026-04-17T08:03:22.161Z","repository":{"id":318597811,"uuid":"1071911091","full_name":"GioMjds/Commitly","owner":"GioMjds","description":"A dedicated habit tracker for coding","archived":false,"fork":false,"pushed_at":"2025-10-08T04:09:25.000Z","size":1155,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-08T06:10:38.716Z","etag":null,"topics":["expo-router","firebase","react-native"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/GioMjds.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-10-08T01:52:48.000Z","updated_at":"2025-10-08T04:09:28.000Z","dependencies_parsed_at":"2025-10-08T06:20:50.902Z","dependency_job_id":null,"html_url":"https://github.com/GioMjds/Commitly","commit_stats":null,"previous_names":["giomjds/commitly"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/GioMjds/Commitly","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GioMjds%2FCommitly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GioMjds%2FCommitly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GioMjds%2FCommitly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GioMjds%2FCommitly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GioMjds","download_url":"https://codeload.github.com/GioMjds/Commitly/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GioMjds%2FCommitly/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279015756,"owners_count":26085751,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["expo-router","firebase","react-native"],"created_at":"2025-10-13T14:59:41.493Z","updated_at":"2026-04-17T08:03:22.146Z","avatar_url":"https://github.com/GioMjds.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Commitly — Track your daily progress with automated GitHub sync\n\nCommitly is a small productivity app built with Expo + React Native that helps you track daily \"commits\" (tasks/mini-retros) and optionally syncs coding activity from GitHub into daily commit entries.\n\nThis repository contains the mobile app and client-side logic. It integrates with Firebase (Realtime Database + Firestore) for user data, settings, and syncing.\n\nHighlights\n\n- File-based Expo Router (app/ directory)\n- GitHub sync with SHA-based duplicate detection\n- \"Call it a Day\" flow to mark a day complete (with optional automatic GitHub sync)\n- Light/dark theming and local stores for auth, commits, and theme\n\n## Quick start\n\nPrerequisites\n\n- Node.js (16+ recommended)\n- npm or yarn\n- Expo CLI (optional but useful): `npm install -g expo-cli`\n\n1) Install dependencies\n\n```powershell\nnpm install\n```\n\n2) Start the dev server\n\n```powershell\nnpx expo start\n```\n\nOpen the project in Expo Go, a simulator, or a development build.\n\n3) Environment\n\nCreate a `.env` file (the repo contains `.env` used for development). Key variables used by the app:\n\n- EXPO_PUBLIC_FIREBASE_API_KEY\n- EXPO_PUBLIC_FIREBASE_AUTH_DOMAIN\n- EXPO_PUBLIC_FIREBASE_PROJECT_ID\n- EXPO_PUBLIC_FIREBASE_STORAGE_BUCKET\n- EXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID\n- EXPO_PUBLIC_FIREBASE_APP_ID\n- EXPO_PUBLIC_FIREBASE_DATABASE_URL\n- EXPO_PUBLIC_GITHUB_CLIENT_ID\n- EXPO_PUBLIC_GITHUB_CLIENT_SECRET\n- EXPO_PUBLIC_GITHUB_CALLBACK_URL\n\nThe project uses `configs/firebase.ts` to initialize Firebase using these values.\n\n## Project structure (important files)\n\n- `app/` — Expo Router pages and screens\n  - `(screens)/commits.tsx` — Commits screen, Call it a Day button and UI\n  - `(screens)/index.tsx` — Dashboard\n- `hooks/` — Custom hooks\n  - `useCallItADay.tsx` — Contains `callItADay()`, `canCallItADay()` and a testing `resetCallItADay()` function\n  - `useGithubCommits.tsx` — GitHub sync logic (fetches commits, dedupes by SHA, creates/updates daily commit entries)\n  - `useCommit.tsx` — Local commit management and fetch logic\n  - `useAuth.tsx` — Authentication helpers\n- `store/` — Zustand/other stores for `AuthStore`, `CommitStore`, `ThemeStore`\n- `types/` — Shared TypeScript types (`Commit.types.ts`, `GithubSettings.types.ts`, ...)\n- `configs/firebase.ts` — Firebase initialization (Realtime DB + Firestore)\n\n## How GitHub sync works (important)\n\n1. `useGithubCommits.syncGithubCommits()` does the heavy lifting:\n    - Reads the user's GitHub token (SecureStore)\n    - Fetches recent commits using the GitHub API (a 7-day lookback is used)\n    - Uses SHA-based deduplication by checking Firestore existing commits' `githubCommits` SHAs\n    - Creates or updates daily commit documents in Firestore. If a commit for a date already exists, new GitHub commits for that date are appended.\n\n2. Why 7 days? GitHub's search API may take a few minutes to index new pushes. The app uses a 7-day window to reduce missed commits due to indexing delays.\n\n3. Important limitation: GitHub search/indexing can be delayed (5–10 minutes). If you push and immediately try to sync, the new commit may not appear yet. Possible mitigations:\n\n- Add UI messaging to tell users to wait a minute after pushing\n- Provide a manual \"Sync Now\" button\n\n## \"Call it a Day\" flow\n\n- When the user taps \"Call it a Day\":\n   1. If signed in with GitHub, the app attempts a GitHub sync first\n   2. It then writes a `callItADay` status for the user in Realtime Database with `lastCalledDate`\n   3. The button is disabled for the rest of the day (based on local date comparison)\n\nFor testing there's a temporary `resetCallItADay()` helper and a small refresh icon added to the \"Day Complete\" banner that clears the status (remove before production).\n\n## Resetting \u0026 testing\n\n- Quick manual reset (client): On the Commits screen, when the \"Day Complete\" banner is visible there's a small refresh icon — tapping that will call `resetCallItADay()` and allow you to re-test the Call it a Day flow.\n- Scripted reset (server-side): You can also reset via an admin script using Firebase Admin SDK by clearing `users/{uid}/callItADay`.\n\nExample reset script (not committed with service-account in repo):\n\n```powershell\n# node scripts/resetCallItADay.js\n# Edit the script to set USER_ID and point to your service account key\nnode scripts/resetCallItADay.js\n```\n\n## Troubleshooting\n\n- If GitHub sync shows no new commits but you have pushed recently, wait 5–10 minutes and try again. The GitHub index can be delayed.\n- Use the app logs (React Native console) — `useGithubCommits` now logs fetched commits, SHAs, and duplicate checks.\n- If the Call it a Day button appears disabled even after reset, ensure you are logged in and that your Realtime Database rules allow the operation.\n\n## Developer notes\n\n- Lint / Type checking: this is a TypeScript project — run your editor's TypeScript checks and `npm run lint` if configured.\n- Tests: There are no unit tests at the moment. Adding tests for `useGithubCommits` and `useCallItADay` is a high-value next step.\n\n## Contributing\n\nIf you'd like to contribute:\n\n1. Fork the repo and create a feature branch\n2. Run the app locally and reproduce the issue or feature\n3. Open a PR with a clear description and testing steps\n\n## Notes before production\n\n- Remove the `resetCallItADay()` helper and the test-only refresh UI element\n- Reduce verbose debug logs to only warnings/errors in production\n- Consider rate-limiting sync calls and exposing a manual sync control for users\n\n---\n\nIf you want, I can also generate a short CONTRIBUTING.md, or add a dedicated troubleshooting page that lists the exact console messages and what they mean. Which would you prefer next?\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiomjds%2Fcommitly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgiomjds%2Fcommitly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiomjds%2Fcommitly/lists"}