Last Week

Major Feature Enhancements & Additions:

  • Host Dashboard: Significant UI/UX improvements, including dynamic titles, FAB for adding entries, drawer improvements (toggle, queue code display in NATO alphabet), optimistic updates for queue entries, enhanced dialogs (appearance, animation, edit/delete functionality for restaurants/queues), better network error handling.
  • Landing Page: UI improvements, added OTP lockout mechanism.
  • Queue Management: Added delete functionality for queues and queue entries. Implemented form dialogs (potentially as bottom sheets) for creating/editing queue entries. Added countdown for seating action on queue entry cards. Improved queue entry card UI.
  • Restaurant Management: Added delete functionality for restaurants. Implemented edit functionality.
  • Static Analysis: Integrated ktlint and detekt for code quality.
  • Dependency Injection: Refactored DI setup with modularization and scoping.

Refactoring & UI Improvements:

  • Extensive refactoring of UI components: HostNavigationDrawer, QueueEntryCard, SubscriptionBottomSheet, various dialogs (refactored to use ModalBottomSheet), Input components, LandingScreen.
  • Improved theme colors and introduced spacing dimensions for consistent UI.
  • Refactored dialogs for creating/editing restaurants and queues.
  • Improved error handling, particularly for OTP expiration/invalid OTPs and Supabase Auth errors.

Other:

  • Updated README with marketing materials and TODO lists.
  • Updated dependencies.
  • Applied Detekt auto-fixes.

Nerdy Details

ktlint

ktlint is a static code analysis tool for Kotlin that focuses on enforcing the official Kotlin coding conventions and detecting formatting issues. It provides:

  1. Consistent Code Style: Enforces uniform formatting across the entire codebase regardless of platform-specific code (Android, iOS, common).

  2. Automatic Formatting: Can automatically fix style violations with ktlintFormat task, saving developer time.

  3. Customizable Rules: You can customize rules like disabling wildcard imports and setting specific naming conventions for Composable functions.

  4. Integration with Kotlin Multiplatform: Works across all source sets in a KMP project, ensuring consistent style between shared and platform-specific code.

  5. CI/CD Integration: Provides HTML and Checkstyle reports that can be integrated into continuous integration pipelines.

detekt

detekt is a more comprehensive static analysis tool for Kotlin that goes beyond style checks to find code smells, complexity issues, and potential bugs. Benefits include:

  1. Code Quality Metrics: Monitors complexity metrics like method length (60 lines) and cyclomatic complexity (15) to prevent unmaintainable code.

  2. Customizable Rules: Detailed detekt.yml configuration can allow for customized rules tailored to your project’s needs.

  3. Performance Optimization: Runs in parallel to speed up analysis on larger codebases.

  4. Auto-correction: Set to automatically fix certain issues through autoCorrect = true.

  5. Cross-platform Analysis: Analyzes shared code as well as platform-specific code in the multiplatform project.

  6. Enhanced Naming Conventions: Provides more detailed naming standards beyond what ktlint covers, with special exceptions for Composable functions.

  7. Exception Handling Checks: Guards against overly generic exception handling, which is particularly important in cross-platform code.

How They Work Together

These tools are configured to complement each other:

  1. ktlint focuses primarily on code style and formatting issues
  2. detekt handles deeper code quality concerns like complexity, potential bugs, and naming

The project has a combined staticAnalysis task that runs both tools sequentially, and a formatCode task that applies automatic fixes from both tools.

How to Set Up ktlint and detekt in a KMP Project

1. Add Dependencies to libs.versions.toml file:
[versions]
ktlint = "12.1.0"  # Or latest version
detekt = "1.23.5"  # Or latest version

[libraries]
detekt-formatting = { group = "io.gitlab.arturbosch.detekt", name = "detekt-formatting", version.ref = "detekt" }

[plugins]
ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" }
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
2. Configure both tools in root build.gradle.kts:
plugins {
    // Other plugins...
    alias(libs.plugins.ktlint)
    alias(libs.plugins.detekt)
}

allprojects {
    apply(plugin = "io.gitlab.arturbosch.detekt")
    apply(plugin = "org.jlleitschuh.gradle.ktlint")

    ktlint {
        version.set("1.1.1")  // ktlint engine version
        android.set(true)     // Set to true for Android projects
        verbose.set(true)
        filter {
            exclude { element -> element.file.path.contains("generated/") }
            exclude { element -> element.file.path.contains("build/") }
        }
        reporters {
            reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.HTML)
            reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.CHECKSTYLE)
        }
    }

    detekt {
        buildUponDefaultConfig = true
        allRules = false
        config.setFrom(files("$rootDir/config/detekt/detekt.yml"))
        parallel = true
        autoCorrect = true
        basePath = rootDir.absolutePath
    }
}

dependencies {
    detektPlugins(libs.detekt.formatting)
}

// Tasks to run both tools together
tasks.register("staticAnalysis") {
    description = "Run both ktlint and detekt checks"
    dependsOn("ktlintCheck", "detekt")
}

// Task to format code with both tools
tasks.register("formatCode") {
    description = "Format code with ktlint and detekt"
    dependsOn("ktlintFormat", "detekt")
}
3. Create a detekt.yml configuration file:

Create a file at config/detekt/detekt.yml with custom rule configurations.

4. Configure ktlint rules via .editorconfig:

Create or update .editorconfig file with ktlint-specific rules:

[*.{kt,kts}]
ktlint_code_style = ktlint_official
ktlint_ignore_back_ticked_identifier = true
ktlint_standard_no-wildcard-imports = disabled 
5. Run the analysis:

To check your code without fixing issues:

./gradlew staticAnalysis

To format your code automatically when possible:

./gradlew formatCode

For CI/CD integration, add the staticAnalysis task to your pipeline to fail builds when issues are found.

Next Week

Apply for Google Developer Account and Apple Developer Account.