Skip to content
Open
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
106 changes: 106 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<<<<<<< HEAD
# Gradle files
.gradle/
build/

# Local configuration file
local.properties

# Android Studio generated files
*.iml
.idea/
=======
# Android Studio
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild

# Gradle files
gradle-app.setting
!gradle-wrapper.jar
.gradletasknamecache
>>>>>>> pr-7-Ralfmal-kotlinTodoApp

# Compiled class files
*.class

# Log files
*.log

<<<<<<< HEAD
# Android generated files
bin/
gen/
out/

# Dependency directories
/captures
.externalNativeBuild
.cxx

# macOS system files
.DS_Store

# Backup files
*.bak
*.swp

# Kotlin build artifacts
*.jar
*.war
*.ear
=======
# Package Files
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
>>>>>>> pr-7-Ralfmal-kotlinTodoApp

# Virtual machine crash logs
hs_err_pid*

<<<<<<< HEAD
# Android Profiling
*.hprof
=======
# Android specific
bin/
gen/
out/
release/

# Android Profiling
*.hprof

# Dependency directories
/node_modules
/jspm_packages

# Editor directories and files
.idea/
.vscode/
*.swp
*.swo

# Environment files
.env

# Secrets
*.key
secrets.json

# Build output
/build
/dist
/target
>>>>>>> pr-7-Ralfmal-kotlinTodoApp
61 changes: 61 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("kotlin-kapt")
}

android {
namespace = "com.todoapp"
compileSdk = 33

defaultConfig {
applicationId = "com.todoapp"
minSdk = 26 // Updated to support Java 8 time
targetSdk = 33
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
isCoreLibraryDesugaringEnabled = true // Enable desugaring for Java 8 features
}
kotlinOptions {
jvmTarget = "1.8"
}
}

dependencies {
// Room Database
val roomVersion = "2.5.1"
implementation("androidx.room:room-runtime:$roomVersion")
implementation("androidx.room:room-ktx:$roomVersion")
kapt("androidx.room:room-compiler:$roomVersion")
testImplementation("androidx.room:room-testing:$roomVersion")

// Java 8 time support
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")

// Kotlin standard library
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.20")

// Testing
testImplementation("junit:junit:4.13.2")
testImplementation("org.jetbrains.kotlin:kotlin-test:1.8.20")

// Android testing
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}
80 changes: 80 additions & 0 deletions app/src/main/java/com/example/todoapp/data/dao/TodoItemDao.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.example.todoapp.data.dao

import androidx.room.*
import com.example.todoapp.data.model.TodoItem
import kotlinx.coroutines.flow.Flow

@Dao
interface TodoItemDao {
/**
* Inserts a new todo item into the database.
* @param todoItem The todo item to insert
* @return The ID of the newly inserted item
*/
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(todoItem: TodoItem): Long

/**
* Inserts multiple todo items into the database.
* @param todoItems The list of todo items to insert
* @return List of inserted item IDs
*/
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(todoItems: List<TodoItem>): List<Long>

/**
* Updates an existing todo item.
* @param todoItem The todo item with updated information
*/
@Update
suspend fun update(todoItem: TodoItem)

/**
* Deletes a specific todo item.
* @param todoItem The todo item to delete
*/
@Delete
suspend fun delete(todoItem: TodoItem)

/**
* Retrieves a todo item by its ID.
* @param id The ID of the todo item
* @return The todo item or null if not found
*/
@Query("SELECT * FROM todo_items WHERE id = :id")
suspend fun getById(id: Long): TodoItem?

/**
* Retrieves all todo items, sorted by creation date.
* @return A Flow of todo items
*/
@Query("SELECT * FROM todo_items ORDER BY createdAt DESC")
fun getAllTodoItems(): Flow<List<TodoItem>>

/**
* Retrieves completed todo items.
* @return A Flow of completed todo items
*/
@Query("SELECT * FROM todo_items WHERE isCompleted = 1 ORDER BY updatedAt DESC")
fun getCompletedTodoItems(): Flow<List<TodoItem>>

/**
* Retrieves active (not completed) todo items.
* @return A Flow of active todo items
*/
@Query("SELECT * FROM todo_items WHERE isCompleted = 0 ORDER BY createdAt DESC")
fun getActiveTodoItems(): Flow<List<TodoItem>>

/**
* Deletes all todo items from the database.
*/
@Query("DELETE FROM todo_items")
suspend fun deleteAll()

/**
* Counts the total number of todo items.
* @return The total number of todo items
*/
@Query("SELECT COUNT(*) FROM todo_items")
suspend fun count(): Int
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.example.todoapp.data.database

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.example.todoapp.data.dao.TodoItemDao
import com.example.todoapp.data.model.TodoItem
import java.time.LocalDateTime

@Database(entities = [TodoItem::class], version = 2, exportSchema = false)
@TypeConverters(Converters::class)
abstract class TodoDatabase : RoomDatabase() {
abstract fun todoItemDao(): TodoItemDao

companion object {
@Volatile
private var INSTANCE: TodoDatabase? = null

fun getDatabase(context: Context): TodoDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
TodoDatabase::class.java,
"todo_database"
)
.fallbackToDestructiveMigration() // Use with caution in production
.build()
INSTANCE = instance
instance
}
}
}
}

// Type converters for LocalDateTime
class Converters {
@androidx.room.TypeConverter
fun fromTimestamp(value: String?): LocalDateTime? {
return value?.let { LocalDateTime.parse(it) }
}

@androidx.room.TypeConverter
fun dateToTimestamp(date: LocalDateTime?): String? {
return date?.toString()
}
}
50 changes: 50 additions & 0 deletions app/src/main/java/com/example/todoapp/data/model/TodoItem.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.example.todoapp.data.model

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.time.LocalDateTime

/**
* Room database entity representing a Todo item.
*
* @property id Unique identifier for the Todo item
* @property title Title of the Todo item
* @property description Detailed description of the Todo item
* @property isCompleted Indicates whether the Todo item is completed
* @property createdAt Timestamp of when the Todo item was created
* @property dueDate Optional due date for the Todo item
*/
@Entity(tableName = "todo_items")
data class TodoItem(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,

@ColumnInfo(name = "title")
val title: String,

@ColumnInfo(name = "description")
val description: String? = null,

@ColumnInfo(name = "is_completed")
val isCompleted: Boolean = false,

@ColumnInfo(name = "created_at")
val createdAt: LocalDateTime = LocalDateTime.now(),

@ColumnInfo(name = "due_date")
val dueDate: LocalDateTime? = null
) {
/**
* Validates the Todo item properties.
*
* @throws IllegalArgumentException if validation fails
*/
init {
require(title.isNotBlank()) { "Title cannot be blank" }
require(title.length <= 100) { "Title cannot exceed 100 characters" }
description?.let {
require(it.length <= 500) { "Description cannot exceed 500 characters" }
}
}
}
2 changes: 2 additions & 0 deletions app/src/main/java/com/todoapp/data/entity/Todo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Deprecated: Replaced by TodoItem in com.example.todoapp.data.model package
// This file is kept for historical reference and can be safely removed in future cleanup
Loading