Skip to content

Instantly share code, notes, and snippets.

View iVamsi's full-sized avatar

Vamsi Vaddavalli iVamsi

  • Roku
  • Austin
  • 06:26 (UTC -06:00)
  • LinkedIn in/ivamsi
View GitHub Profile
@iVamsi
iVamsi / CustomDurationWithWithTimeoutOrNull.kt
Last active October 27, 2025 03:31
CustomDurationWithWithTimeoutOrNull
LaunchedEffect(currentMessage.value) {
currentMessage.value?.let { message ->
scope.launch {
val effectiveDuration = message.customDuration
if (effectiveDuration is SnackbarDurationWrapper.Custom &&
!effectiveDuration.isIndefinite()) {
// Simpler approach using withTimeoutOrNull
val result = withTimeoutOrNull(effectiveDuration.getMilliseconds()) {
// Undo action with precise 5-second window
showCustomSnackbar(
message = "Item deleted",
actionLabel = "Undo",
onAction = { restoreItem() },
durationMillis = 5000
)
// Quick success confirmation
showCustomSnackbar(
LaunchedEffect(currentMessage.value) {
currentMessage.value?.let { message ->
val result: SnackbarResult
if (message.duration is SnackbarDurationWrapper.Custom) {
// Create two competing operations
val snackbarDeferred = async {
snackbarHostState.showSnackbar(
message = message.text,
actionLabel = message.actionLabel,
sealed class SnackbarDurationWrapper {
data class Standard(val duration: SnackbarDuration) : SnackbarDurationWrapper()
data class Custom(val millis: Long) : SnackbarDurationWrapper()
companion object {
fun fromMillis(milliseconds: Long): SnackbarDurationWrapper {
require(milliseconds > 0) { "Duration must be positive" }
return Custom(milliseconds)
}
// Before
fun processPayment(payment: Payment) {
val logger = ServiceLocator.get<Logger>()
val paymentGateway = ServiceLocator.get<PaymentGateway>()
// ...
}
// After
context(Logger, PaymentGateway)
fun processPayment(payment: Payment) {
// Before
class OrderService(
private val database: Database,
private val logger: Logger,
private val emailService: EmailService
) {
fun processOrder(order: Order) { /* ... */ }
}
// After
// Good: Focused contexts
context(DatabaseContext, LoggingContext)
fun processOrder(order: Order) { /* ... */ }
// Avoid: Too many contexts
context(DatabaseContext, LoggingContext, EmailContext, PaymentContext, InventoryContext, ShippingContext)
fun processComplexOrder(order: Order) { /* ... */ }
class FakeTracker : ActivityTracker {
val activities = mutableListOf<String>()
override fun record(activity: String) { activities.add(activity) }
}
@Test
fun verifyUserRegistration() {
val fakeTracker = FakeTracker()
val fakeStorage = InMemoryStorage()
interface UserStorage {
suspend fun persist(user: User)
}
interface ActivityTracker {
fun record(activity: String)
}
context(storage: UserStorage, tracker: ActivityTracker)
class AccountManager {
// Declaring a function with context parameters
context(ExecutionContext, Logger)
suspend fun fetchUserData(userId: String): User {
log("Fetching user data for $userId")
return withContext(Dispatchers.IO) {
// Database operation
userRepository.findById(userId)
}
}