Skip to content

architecture

Will follows domain/infrastructure separation.

domain model

Task is a pure Kotlin data class — zero Android or Room dependencies.

layers

layerpackageresponsibility
domaintask/Task model, TaskRepository interface, TaskViewModel
infrastructureinfrastructure/room/Room entity, DAO, database singleton
notificationnotification/listener, processor, action store
UIui/composable screens and components
overlayoverlay/system alert window overlay service
launcherlauncher/app list repository and ViewModel

notification pipeline

notification posted
  → WillNotificationListenerService.onNotificationPosted()
  → NotificationProcessor.process() — maps notification to Task (or null)
  → TaskDao.insert() — persists to Room
  → TaskFeed recomposes — StateFlow emits new list

overlay communication

the overlay communicates back to MainActivity via SharedFlow:

  • ACTION_DONE — mark task done
  • ACTION_LATER — dismiss overlay, keep task
  • ACTION_DELETE — delete task

no Hilt

dependency injection is manual via ViewModelProvider.Factory. each ViewModel receives a CoroutineDispatcher for testability.

released under the MIT license.