Skip to content

Latest commit

 

History

History
80 lines (53 loc) · 3.96 KB

File metadata and controls

80 lines (53 loc) · 3.96 KB

Contributing to CleanSweep

Thank you for your interest in contributing to CleanSweep! We're excited to have your help in making the app better. This document outlines our guidelines to ensure a smooth and effective collaboration process for everyone.

How to Contribute

The best way to contribute is by getting involved in the discussion. All feature proposals and bug reports should start as a GitHub Issue.

  • Found a Bug? Open a Bug Report. Please be as detailed as possible, including your device model, Android version, and steps to reproduce the issue.
  • Have a Feature Idea? Propose a New Feature. Explain the problem you're trying to solve and how your proposed feature would address it.

Please search the existing issues before creating a new one to avoid duplicates.

Our Development Process

To maintain project quality and clarity, we follow a structured development process:

  1. Proposal (Issue): Every change starts with a GitHub Issue. This is where the problem or feature is defined and discussed. This step prevents wasted effort on a change that might not align with the project's goals.
  2. Discussion & Approval: The project maintainers will review the issue. For new features, when needed, we will discuss the proposed solution and agree on a high-level plan before any code is written.
  3. Implementation (Pull Request): Once the plan is approved, you can begin implementation. Create a Pull Request (PR) and link it to the original issue. Please keep PRs focused on a single issue.

Architectural & Coding Standards

To ensure the codebase remains clean, stable, and maintainable, all contributions must adhere to our core architectural principles.

1. MVVM & Unidirectional Data Flow (UDF)

The app is built on a Model-View-ViewModel (MVVM) architecture with a strict UDF pattern. State should flow down from the ViewModel to the UI, and events should flow up from the UI to the ViewModel.

2. Core Composable Design: State Decoupling

This is a critical, non-negotiable principle for all UI code. To ensure components are reusable, testable, and have clear API contracts, we must avoid passing entire UiState objects to child composables.

Instead, a composable function must only accept the specific parameters it actually needs.

Rationale:

  • Reusability & Previewability: A component that accepts simple types (String, Boolean, () -> Unit) is trivial to reuse anywhere and to preview in Android Studio.
  • API Clarity: The function's signature becomes a perfect, self-documenting contract of its dependencies.
  • Encapsulation: It prevents a child component from accessing or depending on state it has no business knowing about.

Example:

INCORRECT (Violates the principle)

// This component is fragile and hard to reuse because it depends on the entire state.
@Composable
fun MyComponent(uiState: SwiperUiState) {
    Text(uiState.currentItem.displayName)
    Button(enabled = !uiState.isLoading) { /* ... */ }
}

CORRECT (Adheres to the principle)

// This component has a clear, reusable, and protected API.
@Composable
fun MyComponent(
    displayName: String,
    isLoading: Boolean,
    onButtonClicked: () -> Unit
) {
    Text(displayName)
    Button(enabled = !isLoading, onClick = onButtonClicked) { /* ... */ }
}

Submitting a Pull Request

When your changes are ready, please submit a Pull Request with the following:

  • A clear title that summarizes the change (e.g., [FEAT] Add folder exclusion to duplicate scan).
  • A description explaining what the change is and why it's being made.
  • A link to the GitHub Issue it resolves (e.g., Closes #123).
  • Ensure your code is formatted according to the project's existing style.

Thank you for helping make CleanSweep a better app!