### MainActivity: Configure Theme and Lifecycle in Android Source: https://context7.com/nsh07/tomato/llms.txt Handles the main activity entry point for the Android application. It configures theme settings based on user preferences and system defaults, and manages lifecycle events like starting and stopping the app to adjust timer update frequencies. ```kotlin import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.compose.foundation.isSystemInDarkTheme import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.nsh07.pomodoro.TomatoApplication import org.nsh07.pomodoro.ui.AppScreen import org.nsh07.pomodoro.ui.theme.TomatoTheme import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsViewModel import org.nsh07.pomodoro.utils.toColor class MainActivity : ComponentActivity() { private val settingsViewModel: SettingsViewModel by viewModels( factoryProducer = { SettingsViewModel.Factory } ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() val appContainer = (application as TomatoApplication).container // Configure screen wake behavior appContainer.activityTurnScreenOn = { shouldWake -> setShowWhenLocked(shouldWake) setTurnScreenOn(shouldWake) } setContent { val preferencesState by settingsViewModel.preferencesState.collectAsStateWithLifecycle() val isPlus by settingsViewModel.isPlus.collectAsStateWithLifecycle() // Determine theme val darkTheme = when (preferencesState.theme) { "dark" -> true "light" -> false else -> isSystemInDarkTheme() } val seedColor = preferencesState.colorScheme.toColor() TomatoTheme( darkTheme = darkTheme, seedColor = seedColor, blackTheme = preferencesState.blackTheme ) { AppScreen( isPlus = isPlus, isAODEnabled = preferencesState.aodEnabled, setTimerFrequency = { appContainer.appTimerRepository.timerFrequency = it } ) } } } override fun onStop() { super.onStop() // Reduce timer update frequency when app is in background to save battery (application as TomatoApplication).container.appTimerRepository.timerFrequency = 1f } override fun onStart() { super.onStart() // Increase timer update frequency when app is visible for smooth animations (application as TomatoApplication).container.appTimerRepository.timerFrequency = 10f } } ``` -------------------------------- ### Controlling Pomodoro Timer Service with Kotlin Functions Source: https://context7.com/nsh07/tomato/llms.txt Provides Kotlin functions to interact with the TimerService. These functions encapsulate the logic for starting, pausing, skipping, resetting the timer, and managing alarms. Each function creates an Intent with a specific action to communicate with the foreground service. ```kotlin import android.content.Context import android.content.Intent import org.nsh07.pomodoro.service.TimerService // Start the timer service and toggle timer state fun startTimer(context: Context) { val intent = Intent(context, TimerService::class.java).apply { action = TimerService.Actions.TOGGLE.toString() } context.startForegroundService(intent) } // Pause the running timer fun pauseTimer(context: Context) { val intent = Intent(context, TimerService::class.java).apply { action = TimerService.Actions.TOGGLE.toString() } context.startForegroundService(intent) } // Skip to next timer phase (focus -> break or break -> focus) fun skipTimer(context: Context) { val intent = Intent(context, TimerService::class.java).apply { action = TimerService.Actions.SKIP.toString() } context.startForegroundService(intent) } // Reset timer to initial focus state fun resetTimer(context: Context) { val intent = Intent(context, TimerService::class.java).apply { action = TimerService.Actions.RESET.toString() } context.startForegroundService(intent) } // Stop the alarm when timer completes fun stopAlarm(context: Context) { val intent = Intent(context, TimerService::class.java).apply { action = TimerService.Actions.STOP_ALARM.toString() } context.startForegroundService(intent) } // Update alarm tone after user changes it in settings fun updateAlarmTone(context: Context) { val intent = Intent(context, TimerService::class.java).apply { action = TimerService.Actions.UPDATE_ALARM_TONE.toString() } context.startForegroundService(intent) } ``` -------------------------------- ### Pomodoro Statistics Management with Kotlin StatRepository Source: https://context7.com/nsh07/tomato/llms.txt Demonstrates how to use the AppStatRepository in Kotlin to add focus and break times, retrieve daily and weekly statistics summaries, calculate average focus times per quarter, and get the last recorded date. It utilizes Kotlin Coroutines for asynchronous operations. ```kotlin import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking import org.nsh07.pomodoro.data.AppStatRepository import org.nsh07.pomodoro.data.AppDatabase import java.time.LocalDate val database = AppDatabase.getDatabase(context) val statRepository = AppStatRepository(database.statDao()) runBlocking { // Add focus time - automatically determines which quarter of the day statRepository.addFocusTime(1500000L) // 25 minutes in milliseconds // Add break time to today's stats statRepository.addBreakTime(300000L) // 5 minutes in milliseconds // Get today's statistics as Flow val todayStats = statRepository.getTodayStat().first() todayStats?.let { stat -> println("Today's total focus: ${stat.totalFocusTime() / 60000} minutes") println("Today's break time: ${stat.breakTime / 60000} minutes") } // Get last 7 days summary statistics val weekStats = statRepository.getLastNDaysStatsSummary(7).first() weekStats.forEach { summary -> println("${summary.date}: ${summary.focusTime / 60000} min focus, ${summary.breakTime / 60000} min break") } // Get average focus times by quarter for last 30 days val monthAvg = statRepository.getLastNDaysAverageFocusTimes(30).first() monthAvg?.let { avgTimes -> println("Morning (00-06): ${avgTimes.focusTimeQ1 / 60000} min avg") println("Midday (06-12): ${avgTimes.focusTimeQ2 / 60000} min avg") println("Afternoon (12-18): ${avgTimes.focusTimeQ3 / 60000} min avg") println("Evening (18-24): ${avgTimes.focusTimeQ4 / 60000} min avg") } // Get the last recorded date val lastDate = statRepository.getLastDate() } ``` -------------------------------- ### TimerScreen Composable UI - Kotlin Source: https://context7.com/nsh07/tomato/llms.txt The TimerScreen composable function in Jetpack Compose manages the UI for the Pomodoro timer. It observes timer state and time from the ViewModel and provides controls for starting, pausing, skipping, and resetting the timer. It also handles displaying an alarm dialog when a timer session completes. ```kotlin import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsStateWithLifecycle import androidx.compose.runtime.getValue import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.foundation.layout.Column import androidx.lifecycle.viewmodel.compose.viewModel import android.content.Intent import androidx.compose.ui.platform.LocalContext import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerViewModel import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerMode import org.nsh07.pomodoro.service.TimerService @Composable fun TimerScreen() { val context = LocalContext.current val viewModel: TimerViewModel = viewModel(factory = TimerViewModel.Factory) val timerState by viewModel.timerState.collectAsStateWithLifecycle() val timeMs by viewModel.time.collectAsStateWithLifecycle() Column { // Display current timer information Text(text = "Mode: ${timerState.timerMode.name}") Text(text = "Time: ${timerState.timeStr}") Text(text = "Session: ${timerState.currentFocusCount}/${timerState.totalFocusCount}") Text(text = "Next: ${timerState.nextTimerMode.name} (${timerState.nextTimeStr})") // Timer controls Button( onClick = { val intent = Intent(context, TimerService::class.java).apply { action = TimerService.Actions.TOGGLE.toString() } context.startForegroundService(intent) } ) { Text(if (timerState.timerRunning) "Pause" else "Start") } Button( onClick = { val intent = Intent(context, TimerService::class.java).apply { action = TimerService.Actions.SKIP.toString() } context.startForegroundService(intent) } ) { Text("Skip") } Button( onClick = { val intent = Intent(context, TimerService::class.java).apply { action = TimerService.Actions.RESET.toString() } context.startForegroundService(intent) }, enabled = !timerState.timerRunning ) { Text("Reset") } // Show alarm dialog when timer completes if (timerState.alarmRinging) { AlertDialog( onDismissRequest = { val intent = Intent(context, TimerService::class.java).apply { action = TimerService.Actions.STOP_ALARM.toString() } context.startForegroundService(intent) }, title = { Text("Timer Complete!") }, text = { Text("${timerState.timerMode.name} session finished") }, confirmButton = { Button(onClick = { val intent = Intent(context, TimerService::class.java).apply { action = TimerService.Actions.STOP_ALARM.toString() } context.startForegroundService(intent) }) { Text("OK") } } ) } } } ``` -------------------------------- ### Kotlin AppContainer Initialization and Usage Source: https://context7.com/nsh07/tomato/llms.txt Initializes the AppContainer within the TomatoApplication class and demonstrates how to access repositories, services, and observe timer states. It also shows how to control screen wake behavior. ```kotlin import android.app.Application import android.app.NotificationChannel import android.app.NotificationManager import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import kotlinx.coroutines.flow.MutableStateFlow import org.nsh07.pomodoro.TomatoApplication import org.nsh07.pomodoro.data.DefaultAppContainer import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerMode import org.nsh07.pomodoro.ui.timerScreen.viewModel.TimerState import org.nsh07.pomodoro.utils.millisecondsToStr // Access container from Application class class TomatoApplication : Application() { lateinit var container: AppContainer override fun onCreate() { super.onCreate() container = DefaultAppContainer(this) // Setup notification channel val notificationChannel = NotificationChannel( "timer", getString(R.string.timer_progress), NotificationManager.IMPORTANCE_DEFAULT ) container.notificationManager.createNotificationChannel(notificationChannel) } } // Access repositories and services from container val app = context.applicationContext as TomatoApplication val container = app.container // Access preference repository val preferences = container.appPreferenceRepository // Access statistics repository val stats = container.appStatRepository // Access timer repository val timer = container.appTimerRepository timer.focusTime = 30 * 60 * 1000L // Access billing manager val billing = container.billingManager // Access notification services val notificationManager = container.notificationManager val notificationBuilder = container.notificationBuilder // Observe timer state container.timerState.collect { state -> println("Timer mode: ${state.timerMode}") println("Time remaining: ${state.timeStr}") println("Is running: ${state.timerRunning}") } // Observe current time container.time.collect { timeMs -> println("Current time: ${millisecondsToStr(timeMs)}") } // Control screen wake behavior container.activityTurnScreenOn = { shouldWake -> if (shouldWake) { setShowWhenLocked(true) setTurnScreenOn(true) } else { setShowWhenLocked(false) setTurnScreenOn(false) } } ``` -------------------------------- ### Database Configuration: Room DB Operations in Android Source: https://context7.com/nsh07/tomato/llms.txt Sets up the Room database for the application, providing access to DAOs for managing preferences and statistics. It demonstrates basic CRUD operations for preferences and statistics, including querying single records and summaries. ```kotlin import android.content.Context import androidx.room.Room import org.nsh07.pomodoro.data.AppDatabase import kotlinx.coroutines.runBlocking import org.nsh07.pomodoro.data.entity.IntPreference import org.nsh07.pomodoro.data.entity.Stat import java.time.LocalDate // Get database instance (singleton pattern) val database = AppDatabase.getDatabase(context) // Access DAOs for database operations val preferenceDao = database.preferenceDao() val statDao = database.statDao() // Example: Direct DAO usage (typically wrapped in repositories) runBlocking { // Insert a preference preferenceDao.insertIntPreference(IntPreference("focus_time", 1500000)) // Query a preference val focusTime = preferenceDao.getIntPreference("focus_time") // Insert a stat statDao.insertStat(Stat( date = LocalDate.now(), focusTimeQ1 = 900000L, focusTimeQ2 = 1200000L, focusTimeQ3 = 800000L, focusTimeQ4 = 600000L, breakTime = 300000L )) // Query today's stat statDao.getStat(LocalDate.now()).collect { stat -> stat?.let { println("Total focus: ${it.totalFocusTime() / 60000} minutes") } } // Get statistics for last N days statDao.getLastNDaysStatsSummary(7).collect { summaries -> summaries.forEach { summary -> println("${summary.date}: ${summary.focusTime / 60000} min") } } } ``` -------------------------------- ### Pomodoro Timer Configuration with Kotlin TimerRepository Source: https://context7.com/nsh07/tomato/llms.txt Shows how to configure timer durations, session length, update frequency, alarm settings, and custom sounds using the AppTimerRepository. This repository acts as a central point for managing timer states across different parts of the application. ```kotlin import android.net.Uri import android.provider.Settings import androidx.compose.material3.darkColorScheme import org.nsh07.pomodoro.data.AppTimerRepository val timerRepository = AppTimerRepository() // Set timer durations (in milliseconds) timerRepository.focusTime = 25 * 60 * 1000L // 25 minutes timerRepository.shortBreakTime = 5 * 60 * 1000L // 5 minutes timerRepository.longBreakTime = 15 * 60 * 1000L // 15 minutes // Configure session parameters timerRepository.sessionLength = 4 // Number of focus sessions before long break // Set timer update frequency (Hz) timerRepository.timerFrequency = 10f // Updates 10 times per second for smooth UI // Configure alarm and notification settings timerRepository.alarmEnabled = true timerRepository.vibrateEnabled = true timerRepository.dndEnabled = true // Enable Do Not Disturb during focus // Set custom alarm sound timerRepository.alarmSoundUri = Uri.parse("content://media/internal/audio/media/123") // Set Material 3 color scheme for notifications timerRepository.colorScheme = darkColorScheme() // Check if timer service is running val isRunning = timerRepository.serviceRunning ``` -------------------------------- ### PreferenceRepository: Manage App Settings with Room Database (Kotlin) Source: https://context7.com/nsh07/tomato/llms.txt Implements a repository for managing application preferences using the Room database, providing a DataStore-like API. It supports saving and retrieving integer, boolean, and string preferences, as well as observing preference changes via Flows and resetting all settings. ```kotlin import kotlinx.coroutines.runBlocking import org.nsh07.pomodoro.data.AppPreferenceRepository import org.nsh07.pomodoro.data.AppDatabase val database = AppDatabase.getDatabase(context) val preferenceRepository = AppPreferenceRepository(database.preferenceDao()) runBlocking { // Save timer duration preferences (in milliseconds) preferenceRepository.saveIntPreference("focus_time", 25 * 60 * 1000) preferenceRepository.saveIntPreference("short_break_time", 5 * 60 * 1000) preferenceRepository.saveIntPreference("long_break_time", 15 * 60 * 1000) // Save boolean preferences preferenceRepository.saveBooleanPreference("alarm_enabled", true) preferenceRepository.saveBooleanPreference("dnd_enabled", false) // Save string preferences preferenceRepository.saveStringPreference("theme", "dark") preferenceRepository.saveStringPreference("colorScheme", "#FF5733") // Retrieve preferences val focusTime = preferenceRepository.getIntPreference("focus_time") // Returns 1500000 val isAlarmEnabled = preferenceRepository.getBooleanPreference("alarm_enabled") // Returns true val theme = preferenceRepository.getStringPreference("theme") // Returns "dark" // Observe preferences as Flow preferenceRepository.getBooleanPreferenceFlow("alarm_enabled").collect { println("Alarm enabled: $it") } // Reset all settings to defaults (requires manual rewriting of defaults) preferenceRepository.resetSettings() } ``` -------------------------------- ### Stat Entity: Create and Calculate Daily Productivity Statistics (Kotlin) Source: https://context7.com/nsh07/tomato/llms.txt Defines the Room database entity for storing user productivity statistics, including focus time and break time across different periods of the day. It also includes a method to calculate the total focus time for a given day. ```kotlin import androidx.room.Entity import androidx.room.PrimaryKey import org.nsh07.pomodoro.data.Stat import java.time.LocalDate // Create a new stat entry for today val todayStat = Stat( date = LocalDate.now(), focusTimeQ1 = 1800000L, // 30 minutes in milliseconds (00:00-06:00) focusTimeQ2 = 3600000L, // 60 minutes in milliseconds (06:00-12:00) focusTimeQ3 = 2700000L, // 45 minutes in milliseconds (12:00-18:00) focusTimeQ4 = 1500000L, // 25 minutes in milliseconds (18:00-24:00) breakTime = 900000L // 15 minutes total break time ) // Calculate total focus time for the day val totalFocusTime = todayStat.totalFocusTime() // Returns 9600000L (160 minutes) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.