Skip to content
Ahtat204Public

About

Android Application I can use to see my Reposistories on Gitlab without having to open a browser every time

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

781 Commits

Folders and files

Repository files navigation

📱 GitLab Client

Status Language Platform License

A native Android client for GitLab that brings your repositories to your fingertips. Browse projects, view merge requests, and manage issues without opening a web browser.

📸 Screenshots

Home Screen Project List Issues MRs Members Project Overview Profile Repository Commits Pipelines
Home Screen Project List issues mrs members Project Details Developper Profile Project Repository Repository Commits Pipelines

📑 Table of Contents


Overview

GitLab Client is a modern Android application built with Kotlin and Jetpack Compose that provides a native, efficient way to interact with GitLab. Whether you're a developer on the go or prefer a dedicated mobile experience, this app eliminates the need to open a web browser while maintaining full access to your GitLab workspace.

The application leverages Apollo Kotlin for GraphQL queries and OAuth2 for secure authentication, ensuring a seamless and secure user experience.


✨ Key Features

  • 📱 Modern Jetpack Compose UI — Clean, responsive, and fully native Android interface built with Jetpack Compose for an intuitive user experience.
  • 🔐 GitLab OAuth2 Authentication — Secure login using GitLab's official OAuth2 authorization flow.
  • ⚡ GraphQL Integration — Efficient data fetching using Apollo Kotlin for optimized performance.
  • 📂 Repository Browsing — Quickly view and navigate your GitLab projects on mobile.
  • 🔍 Project Details — Access comprehensive project information including merge requests, issues, and statistics.
  • 💾 Secure Token Storage — Encrypted storage of authentication tokens for safe credential management.
  • 🎨 Dark & Light Themes — Adaptive UI themes for comfortable viewing in any lighting condition.

🛠️ Tech Stack

Layer Technologies
UI Framework Jetpack Compose, Material Design 3
Language Kotlin
Data Layer Apollo Kotlin (GraphQL), OkHttp
Authentication OAuth2
Security Crypto/Encryption utilities
Dependency Injection Hilt
Image Loading Coil
Platform Android (Native)
Build System Gradle (Kotlin DSL)

🚀 Quick Start

Prerequisites

  • Android Studio Giraffe or later
  • Android SDK 24 (or higher)
  • Kotlin 1.9+
  • Git

Installation

# 1. Clone the repository
git clone https://github.com/Ahtat204/Gitlab.git
cd Gitlab

# 2. Open in Android Studio
# File > Open > Select the project directory

# 3. Configure GitLab OAuth2 credentials
# Update AuthConfig.kt with your GitLab app credentials

# 4. Sync Gradle and run the app
./gradlew build
# Then run on emulator or physical device

Configuration

  1. Register a GitLab Application:

    • Go to GitLab → Preferences → Applications
    • Create a new application with redirect URI: gitlab://oauth-callback
    • Note your Application ID and Secret
  2. Update AuthConfig.kt:

    object AuthConfig {
        const val GITLAB_CLIENT_ID = "your_client_id"
        const val GITLAB_CLIENT_SECRET = "your_client_secret"
        const val REDIRECT_URI = "gitlab://oauth-callback"
    }
  3. Build and Run:

    ./gradlew installDebug

📁 Project Structure

Gitlab/
├── app
│   ├── build.gradle.kts
│   ├── proguard-rules.pro
│   └── src
│       ├── androidTest
│       │   └── java
│       │       └── com
│       │           └── ahtat204
│       │               └── gitlab
│       │                   └── ExampleInstrumentedTest.kt
│       ├── main
│       │   ├── AndroidManifest.xml
│       │   ├── graphql
│       │   │   └── com
│       │   │       └── ahtat204
│       │   │           ├── mutation
│       │   │           ├── project
│       │   │           │   ├── GetProjectDetails.graphql
│       │   │           │   ├── GetProjectIssues.graphql
│       │   │           │   ├── GetProjectMembers.graphql
│       │   │           │   ├── GetProjectMRs.graphql
│       │   │           │   ├── GetProjectPipelines.graphql
│       │   │           │   ├── mergerequests
│       │   │           │   │   └── GetProjectMergeRequests.graphql
│       │   │           │   └── repository
│       │   │           │       ├── GetProjectRepository.graphql
│       │   │           │       ├── GetRepositoryBlob.graphql
│       │   │           │       ├── GetRepositoryBranches.graphql
│       │   │           │       ├── GetRepositoryCommits.graphql
│       │   │           │       └── GetRepositoryTree.graphql
│       │   │           ├── schema.graphqls
│       │   │           └── user
│       │   │               ├── currentUser
│       │   │               │   ├── GetAllProjects.graphql
│       │   │               │   ├── GetMyContributedProjects.graphql
│       │   │               │   ├── GetMyPersonalProjects.graphql
│       │   │               │   └── GetMyProfile.graphql
│       │   │               └── GetUserProjectsByName.graphql
│       │   └── java
│       │       └── com
│       │           └── ahtat204
│       │               └── gitlab
│       │                   ├── data
│       │                   │   ├── helpers
│       │                   │   │   ├── fetchAndMergeCommits.kt
│       │                   │   │   ├── fetchAndMergeIssues.kt
│       │                   │   │   ├── fetchAndMergeMembers.kt
│       │                   │   │   ├── fetchAndMergeMRs.kt
│       │                   │   │   ├── fetchAndMergePipelines.kt
│       │                   │   │   ├── fetchAndMergeProjects.kt
│       │                   │   │   └── mapAndHandleErrors.kt
│       │                   │   ├── remote
│       │                   │   │   └── repositories
│       │                   │   │       └── graphql
│       │                   │   │           ├── ApolloGraphQLRepository.kt
│       │                   │   │           └── GraphQlRepository.kt
│       │                   │   └── security
│       │                   │       └── AuthenticationInterceptor.kt
│       │                   ├── domain
│       │                   │   ├── authentication
│       │                   │   │   ├── AuthStateSerializer.kt
│       │                   │   │   ├── constants
│       │                   │   │   │   ├── AuthConfig.kt
│       │                   │   │   │   └── Tokens.kt
│       │                   │   │   ├── SafeStore.kt
│       │                   │   │   └── security
│       │                   │   │       └── CryptoUtility.kt
│       │                   │   ├── di
│       │                   │   │   ├── ApolloModule.kt
│       │                   │   │   ├── OkHttpModule.kt
│       │                   │   │   └── ProjectRepositoryModule.kt
│       │                   │   └── logging
│       │                   │       └── Logger.kt
│       │                   ├── GitlabApp.kt
│       │                   └── presentation
│       │                       ├── activities
│       │                       │   ├── AuthenticationActivity.kt
│       │                       │   ├── LauncherActivity.kt
│       │                       │   ├── MainActivity.kt
│       │                       │   └── ui
│       │                       │       └── theme
│       │                       │           ├── Color.kt
│       │                       │           ├── Theme.kt
│       │                       │           └── Type.kt
│       │                       ├── components
│       │                       │   ├── About.kt
│       │                       │   ├── AutoLinkText.kt
│       │                       │   ├── BlobCard.kt
│       │                       │   ├── BranchesList.kt
│       │                       │   ├── CoilCache.kt
│       │                       │   ├── CollaborationDetails.kt
│       │                       │   ├── CommitCard.kt
│       │                       │   ├── Contact.kt
│       │                       │   ├── FileBrowser.kt
│       │                       │   ├── GeneralDetails.kt
│       │                       │   ├── Header.kt
│       │                       │   ├── Info.kt
│       │                       │   ├── ISO8601ToRelativeDate.kt
│       │                       │   ├── IssueCard.kt
│       │                       │   ├── LanguageCircle.kt
│       │                       │   ├── LanguagesBar.kt
│       │                       │   ├── measureTestWidth.kt
│       │                       │   ├── MergeRequest.kt
│       │                       │   ├── Panel.kt
│       │                       │   ├── PanelSlider.kt
│       │                       │   ├── Pipeline.kt
│       │                       │   ├── PipelineStatusIcon.kt
│       │                       │   ├── ProjectItem.kt
│       │                       │   ├── ProjectWorkItems.kt
│       │                       │   ├── RemoveElementsAfterKey.kt
│       │                       │   ├── RepositoryHead.kt
│       │                       │   ├── RepositoryTree.kt
│       │                       │   ├── Tag.kt
│       │                       │   ├── TopAppBar.kt
│       │                       │   ├── TopBar.kt
│       │                       │   ├── WorkItem.kt
│       │                       │   └── WorkItems.kt
│       │                       ├── navigation
│       │                       │   ├── BottomBar.kt
│       │                       │   ├── BottomBarScreen.kt
│       │                       │   ├── NavigationGraph.kt
│       │                       │   └── UIState.kt
│       │                       ├── screens
│       │                       │   ├── Home.kt
│       │                       │   ├── PersonalProjects.kt
│       │                       │   ├── Profile.kt
│       │                       │   ├── project
│       │                       │   │   ├── Commits.kt
│       │                       │   │   ├── Issues.kt
│       │                       │   │   ├── Members.kt
│       │                       │   │   ├── MergeRequests.kt
│       │                       │   │   ├── Overview.kt
│       │                       │   │   ├── Pipelines.kt
│       │                       │   │   └── Repository.kt
│       │                       │   ├── Projects.kt
│       │                       │   └── SplashScreen.kt
│       │                       └── viewmodels
│       │                           ├── ProfileViewModel.kt
│       │                           └── project
│       │                               ├── IssuesViewModel.kt
│       │                               ├── MembersViewModel.kt
│       │                               ├── PersonalProjectsViewModel.kt
│       │                               ├── PipelinesViewModel.kt
│       │                               ├── ProjectMRsViewModel.kt
│       │                               ├── ProjectsViewModel.kt
│       │                               └── repository
│       │                                   └── RepositoryViewModel.kt
│       └── test
│           └── java
│               └── com
│                   └── ahtat204
│                       └── gitlab
│                           ├── data
│                           │   └── remote
│                           │       └── repositories
│                           │           └── graphql
│                           │               └── ApolloGraphQLRepositoryTest.kt
│                           ├── presentation
│                           │   └── viewmodels
│                           │       ├── ProfileViewModelTest.kt
│                           │       ├── project
│                           │       │   ├── IssuesViewModelTest.kt
│                           │       │   ├── MembersViewModelTest.kt
│                           │       │   ├── PersonalProjectsViewModelTest.kt
│                           │       │   ├── PipelinesViewModelTest.kt
│                           │       │   ├── ProjectMRsViewModelTest.kt
│                           │       │   ├── ProjectsViewModelTest.kt
│                           │       │   └── repository
│                           │       │       └── RepositoryViewModelTest.kt
│                           │       └── testBase.kt
│                           └── reponses
│                               ├── json
│                               │   ├── mockedAllProjects.kt
│                               │   ├── mockedBranches.kt
│                               │   ├── mockedCommits.kt
│                               │   ├── mockedIssues.kt
│                               │   ├── mockedMembers.kt
│                               │   ├── mockedMrs.kt
│                               │   ├── mockedPipelines.kt
│                               │   ├── mockedProject.kt
│                               │   ├── mockedProjects.kt
│                               │   └── mockedRepository.kt
│                               └── objects
│                                   ├── mockedAllProjects.kt
│                                   ├── mockedBranches.kt
│                                   ├── mockedCommits.kt
│                                   ├── mockedIssues.kt
│                                   ├── mockedMembers.kt
│                                   ├── mockedMRs.kt
│                                   ├── mockedProfile.kt
│                                   ├── mockedProject.kt
│                                   ├── mockedProjects.kt
│                                   ├── mockProjectPipelinesData.kt
│                                   └── mockRepository.kt
├── ARCHITECTURE.md
├── build.gradle.kts
├── gradle
│   ├── libs.versions.toml
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── history.jpg
├── home.jpg
├── homescreen.jpg
├── issues.jpg
├── members.jpg
├── mrs.jpg
├── personalprojects.jpg
├── profile.jpg
├── projectdetails.jpg
├── projectlist.jpg
├── projectsScreen.jpg
├── README.md
├── repository.jpg
└── settings.gradle.kts

⚙️ Configuration

Environment Variables

# secrets.properties
CLIENT_ID:# this the Gitlab OAuth2 ClientID you get when creating an application on Gitlab , you define scope, redirect URL , you also get a Client Secret as well  

Dependencies

Key dependencies are managed in gradle/libs.versions.toml. Update versions as needed:

  • Apollo Kotlin: GraphQL client
  • Jetpack Compose: UI framework
  • Coil: Image loading library
  • OkHttp: HTTP client with interceptors
  • Material Design 3: Design components

🔒 Security

  • OAuth2 Flow: Secure authentication without storing passwords
  • Encrypted Token Storage: Access tokens are encrypted using Android's Crypto API
  • HTTPS Only: All API communications are encrypted
  • ProGuard Rules: Code obfuscation for production builds

Best Practices

  1. Never commit API credentials to the repository
  2. Store OAuth secrets in a secure configuration file (not in version control)
  3. Regularly update dependencies for security patches
  4. Review GraphQL queries to minimize exposed data

📚 Architecture

This project follows Clean Architecture principles with a layered approach:

Layers

  1. Presentation Layer (UI)

    • Composable screens using Jetpack Compose
    • ViewModels for state management
    • Navigation graph for screen transitions
  2. Domain Layer (Business Logic)

    • Use cases for business operations
    • Domain models
    • Repository interfaces
  3. Data Layer (Data Sources)

    • Repository implementations
    • Remote data sources (API)
    • Local caching (if applicable)
    • Interceptors for request/response handling

Design Patterns

  • MVVM: ViewModel-based state management
  • Repository Pattern: Abstraction of data sources
  • Dependency Injection: Using Hilt for DI
  • Single Responsibility Principle: Each component has one responsibility

🤝 Contributing

Contributions are welcome! Whether it's bug fixes, feature requests, or improvements, please follow these guidelines:

Development Workflow

  1. Fork the repository

    git clone https://github.com/Ahtat204/Gitlab.git
  2. Create a feature branch

    git checkout -b feature/your-feature-name
  3. Make your changes

    • Follow Kotlin coding conventions
    • Add comments for complex logic
    • Test your changes locally
  4. Commit with clear messages

    git commit -m "feat: add awesome feature"
    # or
    git commit -m "fix: resolve issue with X"
  5. Push to your fork

    git push origin feature/your-feature-name
  6. Open a Pull Request

    • Provide a clear description of your changes
    • Link to any related issues
    • Include screenshots for UI changes

Commit Convention

  • feat: - New feature
  • fix: - Bug fix
  • refactor: - Code refactoring
  • docs: - Documentation
  • style: - Code style (formatting, etc.)
  • test: - Adding or updating tests
  • chore: - Build, dependencies, etc.

Code Style

  • Follow Kotlin coding conventions
  • Use meaningful variable and function names
  • Keep functions small and focused
  • Add KDoc comments for public APIs

🙏 Acknowledgments


📞 Support

Have questions or found a bug?

  • Open an Issue
  • Check existing issues for similar problems
  • Provide detailed error messages and reproduction steps

About

Android Application I can use to see my Reposistories on Gitlab without having to open a browser every time

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages