Skip to content

Latest commit

 

History

History
282 lines (206 loc) · 5.51 KB

File metadata and controls

282 lines (206 loc) · 5.51 KB
title Core API
description Using Jindong without Compose Runtime

Core API

**Module**: `jindong-core` | **Package**: `io.github.compose.jindong.core`

The Core API allows you to use Jindong haptic patterns without Compose Runtime dependency. This is useful for:

  • Non-Compose Kotlin Multiplatform projects
  • ViewModel or Repository layer haptic triggers
  • Background services or workers

Installation

kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("io.github.compose-jindong:jindong-core:<version>")
        }
    }
}

Building Patterns

Use buildHapticPattern to create haptic patterns:

import io.github.compose.jindong.core.dsl.*
import io.github.compose.jindong.core.model.HapticIntensity
import kotlin.time.Duration.Companion.ms

val tapPattern = buildHapticPattern {
    haptic(50.ms)
}

val notificationPattern = buildHapticPattern {
    haptic(50.ms, HapticIntensity.MEDIUM)
    delay(50.ms)
    haptic(100.ms, HapticIntensity.STRONG)
}

val alertPattern = buildHapticPattern {
    repeat(3) {
        haptic(80.ms, HapticIntensity.HIGH)
        delay(50.ms)
    }
}

Executing Patterns

Suspend Function (Recommended)

Use play() to execute and wait for completion:

import io.github.compose.jindong.core.play

suspend fun onButtonClick() {
    tapPattern.play()
}

// In a coroutine scope
lifecycleScope.launch {
    notificationPattern.play()
}

Fire-and-Forget

Use playAsync() when you don't need to wait:

import io.github.compose.jindong.core.playAsync

fun onButtonClick() {
    val handle = tapPattern.playAsync()

    // Optionally cancel later
    // handle.cancel()
}

Inline Execution

Use playHaptic for one-off patterns:

import io.github.compose.jindong.core.playHaptic

suspend fun onSuccess() {
    playHaptic {
        haptic(50.ms, HapticIntensity.MEDIUM)
        delay(50.ms)
        haptic(100.ms, HapticIntensity.STRONG)
    }
}

HapticManager

HapticManager is a singleton that manages haptic execution:

import io.github.compose.jindong.core.HapticManager

// Check device support
if (HapticManager.isSupported) {
    // Execute pattern
    HapticManager.executeAsync(pattern)
}

// Cancel ongoing haptic
HapticManager.cancel()

// Release resources (optional, auto-reinitializes on next use)
HapticManager.release()

Platform Initialization

Android

Automatic initialization via JindongInitializer ContentProvider. No manual setup needed.

For multi-process apps, call manually:

// In Application.onCreate()
HapticManager.initialize(applicationContext)

iOS

No initialization required.

DSL Reference

haptic

Creates a vibration event:

haptic(duration: Duration)
haptic(duration: Duration, intensity: HapticIntensity)
haptic(duration: Duration, intensity: HapticIntensity, iosParameters: IosHapticParameters?)

delay

Adds a pause between events:

delay(duration: Duration)

repeat

Repeats a block N times:

repeat(count: Int) {
    haptic(50.ms)
    delay(30.ms)
}

repeatWithIndex

Repeats with index access for dynamic patterns:

repeatWithIndex(5) { index ->
    val fade = HapticIntensity.Custom(1.0f - (index * 0.2f))
    haptic(50.ms, fade)
    delay(30.ms)
}

sequence

Groups elements (optional, for organization):

sequence {
    haptic(50.ms)
    delay(30.ms)
}

include

Includes an existing pattern:

val clickPattern = buildHapticPattern {
    haptic(50.ms)
}

val composedPattern = buildHapticPattern {
    include(clickPattern)
    delay(100.ms)
    include(clickPattern)
}

If included patterns overlap in time, they are not summed. A single vibration motor plays one amplitude at a time, so at each instant the strongest active event wins:

val composed = buildHapticPattern {
    include(strongPattern)  // e.g. 0-100ms at HIGH
    include(softPattern)    // e.g. 50-150ms at LIGHT
}
// 0-100ms plays at HIGH (it dominates the overlap), then 100-150ms plays at LIGHT.

Examples

ViewModel Usage

class MyViewModel : ViewModel() {

    private val successPattern = buildHapticPattern {
        haptic(50.ms, HapticIntensity.MEDIUM)
        delay(50.ms)
        haptic(100.ms, HapticIntensity.STRONG)
    }

    fun onAction() {
        viewModelScope.launch {
            // Do work...
            successPattern.play()
        }
    }
}

Repository Pattern

class HapticRepository {

    val tapFeedback = buildHapticPattern {
        haptic(50.ms, HapticIntensity.LIGHT)
    }

    val errorFeedback = buildHapticPattern {
        repeat(3) {
            haptic(80.ms, HapticIntensity.HIGH)
            delay(50.ms)
        }
    }

    suspend fun playTap() = tapFeedback.play()
    suspend fun playError() = errorFeedback.play()
}

Comparison with Compose API

Feature Core API Compose API
Compose Runtime Not required Required
Trigger mechanism Manual (play()) Key-based (like LaunchedEffect)
Pattern definition buildHapticPattern {} Jindong {} composable
DSL style Regular functions @Composable functions
Use case ViewModels, services UI components

See Also