Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ This is a Todo List application built using Kotlin Multiplatform and Compose Mul

[Screen_recording_20251213_010429.webm](https://github.com/user-attachments/assets/245ef69a-1d8f-4c10-806f-a6580a787dc2)




## Why I created this project

I started this project to learn and demonstrate the power of Kotlin Multiplatform and Compose Multiplatform. My goal was to build a functional app that looks and feels great on both mobile platforms without writing separate code for each. It serves as a playground for experimenting with shared UI, animations, and state management in a modern cross-platform environment.
Expand Down
8 changes: 1 addition & 7 deletions androidApp/src/main/java/io/jadu/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.tooling.preview.Preview
import io.jadu.todoApp.ui.theme.TodoColors

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -23,11 +21,7 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
initKoin()
setContent {
Surface(
color = TodoColors.LightPrimary.color
) {
App()
}
App()
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions composeApp/src/commonMain/composeResources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
<string name="settings_edit_name_photo">Edit Your Name and Photo</string>
<string name="settings_infocard_compl">Completed</string>
<string name="settings_infocard_remain">Remaining</string>
<string name="settings_dark_mode">Dark Mode</string>
<string name="settings_dark_mode_desc">Switch between light and dark theme</string>
<string name="settings_about">About Us</string>
<string name="settings_about_desc">Know more about us</string>
<string name="settings_feedback">Feedback</string>
Expand Down
13 changes: 10 additions & 3 deletions composeApp/src/commonMain/kotlin/io/jadu/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@ package io.jadu


import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import io.jadu.todoApp.data.local.ThemeRepository
import io.jadu.todoApp.ui.screens.MainScreen
import io.jadu.todoApp.ui.theme.TodoAppTheme
import org.koin.compose.koinInject

@Composable
@Preview
fun App() {
TodoAppTheme {
val themeRepository: ThemeRepository = koinInject()
val isDarkMode by themeRepository.isDarkMode.collectAsState(initial = null)

val resolvedDarkMode = isDarkMode ?: return

TodoAppTheme(darkTheme = resolvedDarkMode) {
MainScreen()
}
}
4 changes: 3 additions & 1 deletion composeApp/src/commonMain/kotlin/io/jadu/di.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package io.jadu
import androidx.room.RoomDatabase
import io.jadu.todoApp.data.TodoRepositoryImpl
import io.jadu.todoApp.data.local.AppDatabase
import io.jadu.todoApp.data.local.ThemeRepository
import io.jadu.todoApp.domain.TodoRepository
import io.jadu.todoApp.ui.notification.NotificationViewModel
import io.jadu.todoApp.ui.viewModel.AddProjectViewModel
Expand Down Expand Up @@ -37,12 +38,13 @@ val appModule = module {
single { get<AppDatabase>().getDao() }
single { get<AppDatabase>().getUserProfileDao() }
single { OnBoardingViewModel(get()) }
single { ThemeRepository(get()) }
single<TodoRepository> { TodoRepositoryImpl() }
single { AddProjectViewModel(get()) }
single { EditTodoViewModel(get()) }
single { TaskScreenViewModel(get()) }
single { HomeScreenViewModel(get(), get()) }
single { SettingsViewModel(get(), get()) }
single { SettingsViewModel(get(), get(), get()) }
single { MostUsedCategoryViewModel(get()) }
single { NotificationViewModel(get()) }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.jadu.todoApp.data.local

import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.emptyPreferences
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map

class ThemeRepository(private val dataStore: DataStore<Preferences>) {

private val darkModeKey = booleanPreferencesKey("dark_mode")

val isDarkMode: Flow<Boolean?> = dataStore.data
.catch { emit(emptyPreferences()) }
.map { preferences ->
preferences[darkModeKey]
}

suspend fun setDarkMode(enabled: Boolean) {
dataStore.edit { preferences ->
preferences[darkModeKey] = enabled
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
Expand Down Expand Up @@ -103,8 +104,8 @@ fun CustomDialog(
CurvedButton(
modifier = Modifier.weight(1f).height(Spacing.s8),
buttonConfig = CurvedButtonConfig(
containerColor = TodoColors.Light.color,
contentColor = TodoColors.Dark.color,
containerColor = MaterialTheme.colorScheme.surface,
contentColor = MaterialTheme.colorScheme.onSurface,
cornerRadius = Spacing.s3.value,
gradientShadowColor = Color.Transparent,
verticalBulgeFactor = 0f
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
Expand All @@ -17,7 +18,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.window.Dialog
import io.jadu.todoApp.ui.theme.Spacing
import io.jadu.todoApp.ui.theme.TodoColors
import kotlinx.datetime.LocalDate
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
Expand All @@ -42,7 +42,7 @@ fun DatePickerDialog(
Dialog(onDismissRequest = onDismiss) {
Surface(
shape = RoundedCornerShape(Spacing.s6),
color = TodoColors.White.color
color = MaterialTheme.colorScheme.surface
) {
Column(modifier = Modifier) {
MonthCalendar(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,22 @@ package io.jadu.todoApp.ui.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.jadu.todoApp.ui.theme.BodyLarge
import io.jadu.todoApp.ui.theme.BodySmall
import io.jadu.todoApp.ui.theme.BodyXSmall
import io.jadu.todoApp.ui.theme.Spacing
import io.jadu.todoApp.ui.theme.TodoColors
import org.jetbrains.compose.resources.stringResource
Expand All @@ -53,7 +45,7 @@ fun EditDetailCard(
spotColor = TodoColors.Black.color.copy(alpha = 0.12f)
)
.clip(RoundedCornerShape(Spacing.s4))
.background(TodoColors.White.color),
.background(MaterialTheme.colorScheme.surface),
verticalArrangement = Arrangement.spacedBy(Spacing.s1),
horizontalAlignment = Alignment.Start
) {
Expand All @@ -67,7 +59,7 @@ fun EditDetailCard(
TodoTextField(
value = value,
onValueChange = onTextChange,
textColor = TodoColors.Dark.color,
textColor = MaterialTheme.colorScheme.onSurface,
unfocusedBorderColor = Color.Transparent,
focusedBorderColor = Color.Transparent,
placeholder = placeHolderText,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
Expand Down Expand Up @@ -87,14 +88,11 @@ fun MonthCalendar(
modifier = Modifier.padding(16.dp)
) {
VSpacer(8.dp)
Box(
modifier =
Modifier
.background(Color.White, shape = RoundedCornerShape(Spacing.s6))
.padding(horizontal = 16.dp)
.padding(bottom = 16.dp)
Surface(
shape = RoundedCornerShape(Spacing.s6),
color = MaterialTheme.colorScheme.surface
) {
Column(modifier = Modifier) {
Column(modifier = Modifier.padding(horizontal = 16.dp).padding(bottom = 16.dp)) {
SimpleCalendarTitle(
modifier = Modifier.padding(vertical = 10.dp, horizontal = 8.dp),
currentMonth = state.firstVisibleMonth,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
Expand Down Expand Up @@ -64,7 +65,7 @@ fun SelectGroupBottomSheet(
)

ModalBottomSheet(
containerColor = TodoColors.Light.color,
containerColor = MaterialTheme.colorScheme.surface,
sheetState = sheetState,
onDismissRequest = onDismiss,
dragHandle = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
Expand Down Expand Up @@ -71,7 +72,7 @@ fun SelectTaskStatusBottomSheet(
)

ModalBottomSheet(
containerColor = TodoColors.Light.color,
containerColor = MaterialTheme.colorScheme.surface,
sheetState = sheetState,
onDismissRequest = onDismiss,
dragHandle = null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,20 @@
package io.jadu.todoApp.ui.components

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.jadu.todoApp.data.model.TaskGroupCategory
import io.jadu.todoApp.ui.screens.homescreen.components.TaskGroupCard
import io.jadu.todoApp.ui.theme.BodyLarge
import io.jadu.todoApp.ui.theme.BodySmall
import io.jadu.todoApp.ui.theme.BodyXSmall
import io.jadu.todoApp.ui.theme.Spacing
import io.jadu.todoApp.ui.theme.TodoColors
Expand Down Expand Up @@ -76,7 +62,7 @@ fun SelectionCard(
overflow = TextOverflow.Ellipsis,
style = BodyLarge().copy(
fontWeight = FontWeight.Bold,
color = Color.Black
color = MaterialTheme.colorScheme.onSurface
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
Expand Down Expand Up @@ -40,7 +41,7 @@ fun TodoElevatedCard(
spotColor = TodoColors.Black.color.copy(alpha = 0.12f)
)
.clip(RoundedCornerShape(Spacing.s4))
.background(TodoColors.White.color)
.background(MaterialTheme.colorScheme.surface)
.padding(Spacing.s4)
) {
content()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.jadu.todoApp.ui.components.CurvedButton
import io.jadu.todoApp.ui.theme.LocalDarkTheme
import io.jadu.todoApp.ui.theme.Spacing
import io.jadu.todoApp.ui.theme.TodoColors
import io.jadu.todoApp.ui.viewModel.OnBoardingViewModel
Expand Down Expand Up @@ -137,20 +138,32 @@ fun TodoBackgroundScreen(
shouldShowDotsAndIcons: Boolean = false,
content: @Composable BoxWithConstraintsScope.() -> Unit = {},
) {
val isDark = LocalDarkTheme.current
val backgroundBrush = if (isDark) {
Brush.radialGradient(
colors = listOf(
TodoColors.DarkBackground.color,
TodoColors.DarkSurface.color,
TodoColors.DarkCard.color
),
center = Offset(0.5f, 0.3f),
radius = 1500f
)
} else {
Brush.radialGradient(
colors = listOf(
TodoColors.Cream.color,
TodoColors.SoftCyan.color,
TodoColors.LightBlue.color
),
center = Offset(0.5f, 0.3f),
radius = 1500f
)
}
BoxWithConstraints (
modifier = modifier
.fillMaxSize()
.background(
brush = Brush.radialGradient(
colors = listOf(
TodoColors.Cream.color,
TodoColors.SoftCyan.color,
TodoColors.LightBlue.color
),
center = Offset(0.5f,0.3f),
radius = 1500f
)
)
.background(brush = backgroundBrush)
) {
FloatingElements(shouldShowDotsAndIcons = shouldShowDotsAndIcons)
content()
Expand Down
Loading