P5 Stream S: cross-platform Haptics (expect/actual)
Common API + platform actuals (Android HapticFeedbackConstants/Vibrator, iOS UIImpact/NotificationFeedback, JVM/JS/WASM no-op). 5 call-sites wired. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,7 @@ import com.tt.honeyDue.platform.rememberCameraPicker
|
|||||||
import com.tt.honeyDue.platform.HapticFeedbackType
|
import com.tt.honeyDue.platform.HapticFeedbackType
|
||||||
import com.tt.honeyDue.platform.rememberHapticFeedback
|
import com.tt.honeyDue.platform.rememberHapticFeedback
|
||||||
import com.tt.honeyDue.platform.rememberImageBitmap
|
import com.tt.honeyDue.platform.rememberImageBitmap
|
||||||
|
import com.tt.honeyDue.ui.haptics.Haptics
|
||||||
import kotlinx.datetime.*
|
import kotlinx.datetime.*
|
||||||
import org.jetbrains.compose.resources.stringResource
|
import org.jetbrains.compose.resources.stringResource
|
||||||
|
|
||||||
@@ -350,6 +351,7 @@ fun CompleteTaskDialog(
|
|||||||
confirmButton = {
|
confirmButton = {
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
|
Haptics.success() // P5 Stream S — task completion haptic
|
||||||
// Get current date in ISO format
|
// Get current date in ISO format
|
||||||
val currentDate = getCurrentDateTime()
|
val currentDate = getCurrentDateTime()
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import com.tt.honeyDue.ui.haptics.Haptics
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reusable error dialog component that shows network errors with retry/cancel options
|
* Reusable error dialog component that shows network errors with retry/cancel options
|
||||||
@@ -28,6 +30,8 @@ fun ErrorDialog(
|
|||||||
retryButtonText: String = "Try Again",
|
retryButtonText: String = "Try Again",
|
||||||
dismissButtonText: String = "Cancel"
|
dismissButtonText: String = "Cancel"
|
||||||
) {
|
) {
|
||||||
|
// P5 Stream S — error haptic when the dialog appears
|
||||||
|
LaunchedEffect(message) { Haptics.error() }
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismiss,
|
onDismissRequest = onDismiss,
|
||||||
title = {
|
title = {
|
||||||
@@ -46,6 +50,7 @@ fun ErrorDialog(
|
|||||||
confirmButton = {
|
confirmButton = {
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
|
Haptics.light() // P5 Stream S — primary-tap haptic on retry
|
||||||
onDismiss()
|
onDismiss()
|
||||||
onRetry()
|
onRetry()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ import androidx.compose.foundation.layout.*
|
|||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.tt.honeyDue.ui.haptics.Haptics
|
||||||
import org.jetbrains.compose.ui.tooling.preview.Preview
|
import org.jetbrains.compose.ui.tooling.preview.Preview
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -14,6 +16,8 @@ fun ErrorCard(
|
|||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
if (message.isNotEmpty()) {
|
if (message.isNotEmpty()) {
|
||||||
|
// P5 Stream S — form-validation / network error haptic
|
||||||
|
LaunchedEffect(message) { Haptics.error() }
|
||||||
Card(
|
Card(
|
||||||
colors = CardDefaults.cardColors(
|
colors = CardDefaults.cardColors(
|
||||||
containerColor = MaterialTheme.colorScheme.errorContainer
|
containerColor = MaterialTheme.colorScheme.errorContainer
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import com.tt.honeyDue.models.TaskCompletionCreateRequest
|
|||||||
import com.tt.honeyDue.models.ContractorSummary
|
import com.tt.honeyDue.models.ContractorSummary
|
||||||
import com.tt.honeyDue.network.ApiResult
|
import com.tt.honeyDue.network.ApiResult
|
||||||
import com.tt.honeyDue.platform.*
|
import com.tt.honeyDue.platform.*
|
||||||
|
import com.tt.honeyDue.ui.haptics.Haptics
|
||||||
import com.tt.honeyDue.ui.theme.*
|
import com.tt.honeyDue.ui.theme.*
|
||||||
import com.tt.honeyDue.viewmodel.ContractorViewModel
|
import com.tt.honeyDue.viewmodel.ContractorViewModel
|
||||||
import org.jetbrains.compose.resources.stringResource
|
import org.jetbrains.compose.resources.stringResource
|
||||||
@@ -383,6 +384,7 @@ fun CompleteTaskScreen(
|
|||||||
OrganicPrimaryButton(
|
OrganicPrimaryButton(
|
||||||
text = stringResource(Res.string.completions_complete_button),
|
text = stringResource(Res.string.completions_complete_button),
|
||||||
onClick = {
|
onClick = {
|
||||||
|
Haptics.success() // P5 Stream S — task completion haptic
|
||||||
isSubmitting = true
|
isSubmitting = true
|
||||||
val notesWithContractor = buildString {
|
val notesWithContractor = buildString {
|
||||||
selectedContractor?.let {
|
selectedContractor?.let {
|
||||||
|
|||||||
Reference in New Issue
Block a user