-
Notifications
You must be signed in to change notification settings - Fork 0
feat: added dashboard screen #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| /build |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| plugins { | ||
| alias(libs.plugins.android.library) | ||
| alias(libs.plugins.kotlin.android) | ||
| alias(libs.plugins.kotlin.parcelize) | ||
| alias(libs.plugins.ksp) | ||
| id 'maven-publish' | ||
| } | ||
|
|
||
| android { | ||
| namespace 'com.tejpratapsingh.motion.datastore' | ||
| compileSdk 36 | ||
|
|
||
| defaultConfig { | ||
| minSdk 25 | ||
|
|
||
| testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
| consumerProguardFiles "consumer-rules.pro" | ||
| } | ||
|
|
||
| buildTypes { | ||
| release { | ||
| minifyEnabled false | ||
| proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
| } | ||
| } | ||
| compileOptions { | ||
| sourceCompatibility JavaVersion.VERSION_11 | ||
| targetCompatibility JavaVersion.VERSION_11 | ||
| } | ||
| kotlinOptions { | ||
| jvmTarget = '11' | ||
| } | ||
| } | ||
|
|
||
| afterEvaluate { | ||
| publishing { | ||
| publications { | ||
| release(MavenPublication) { | ||
| from components.release | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| dependencies { | ||
| api libs.androidx.room.runtime | ||
| ksp libs.androidx.room.compiler | ||
| api libs.androidx.room.ktx | ||
| testImplementation libs.androidx.room.testing | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # Add project specific ProGuard rules here. | ||
| # You can control the set of applied configuration files using the | ||
| # proguardFiles setting in build.gradle. | ||
| # | ||
| # For more details, see | ||
| # http://developer.android.com/guide/developing/tools/proguard.html | ||
|
|
||
| # If your project uses WebView with JS, uncomment the following | ||
| # and specify the fully qualified class name to the JavaScript interface | ||
| # class: | ||
| #-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
| # public *; | ||
| #} | ||
|
|
||
| # Uncomment this to preserve the line number information for | ||
| # debugging stack traces. | ||
| #-keepattributes SourceFile,LineNumberTable | ||
|
|
||
| # If you keep the line number information, uncomment this to | ||
| # hide the original source file name. | ||
| #-renamesourcefileattribute SourceFile | ||
|
Comment on lines
+1
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add Room-specific ProGuard rules. The datastore module contains Room entities and DAOs that must be preserved during code shrinking and obfuscation. Without proper ProGuard/R8 rules, release builds will fail at runtime with reflection errors. 🔎 Recommended ProGuard rules for Room # Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
+# Room-specific rules
+-keep class * extends androidx.room.RoomDatabase
+-keep @androidx.room.Entity class *
+-dontwarn androidx.room.paging.**
+
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <manifest /> |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,17 @@ | ||||||
| package com.tejpratapsingh.motion.datastore.data.dao | ||||||
|
|
||||||
| import androidx.room.Dao | ||||||
| import androidx.room.Insert | ||||||
| import androidx.room.OnConflictStrategy | ||||||
| import androidx.room.Query | ||||||
| import com.tejpratapsingh.motion.datastore.data.entity.ProjectEntity | ||||||
|
|
||||||
| @Dao | ||||||
| interface ProjectDao { | ||||||
|
|
||||||
| @Insert(onConflict = OnConflictStrategy.REPLACE) | ||||||
| suspend fun insert(projectEntity: ProjectEntity) | ||||||
|
|
||||||
| @Query("SELECT * FROM projects") | ||||||
| suspend fun getAll(): List<ProjectEntity> | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For better integration with Compose and to build a reactive UI, consider returning a
Suggested change
|
||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,21 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| package com.tejpratapsingh.motion.datastore.data.database | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| import android.content.Context | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.room.Room | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| object DatabaseProvider { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| @Volatile | ||||||||||||||||||||||||||||||||||||||||||||||||||
| private var INSTANCE: ProjectDatabase? = null | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| fun getDatabase(context: Context): ProjectDatabase { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return INSTANCE ?: synchronized(this) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| val instance = Room.databaseBuilder( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| context.applicationContext, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ProjectDatabase::class.java, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| "LyricMaker" | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ).build() | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+12
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add database migration strategy to prevent crashes on schema changes. The Room database is built without a migration strategy. If the schema changes in future releases, the app will crash when users upgrade. You must either:
🔧 Proposed fix optionsOption 1: For development (destroys data on schema changes): val instance = Room.databaseBuilder(
context.applicationContext,
ProjectDatabase::class.java,
"LyricMaker"
-)
+)
+.fallbackToDestructiveMigration()
.build()Option 2: For production (preserves data with migrations): val instance = Room.databaseBuilder(
context.applicationContext,
ProjectDatabase::class.java,
"LyricMaker"
-)
+)
+.addMigrations(MIGRATION_1_2, MIGRATION_2_3, /* etc */)
.build()You'll need to define migration objects separately. See Room Migration documentation. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||
| INSTANCE = instance | ||||||||||||||||||||||||||||||||||||||||||||||||||
| instance | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
tejpratap46 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+10
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add database migration strategy. The database builder doesn't specify a migration strategy. When you update the schema in future versions (e.g., adding columns, new tables), the app will crash unless you provide migrations or explicitly allow destructive migrations. 🔎 Recommended approachFor development/MVP, add fallback to destructive migration: fun getDatabase(context: Context): ProjectDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
ProjectDatabase::class.java,
"LyricMaker"
- ).build()
+ )
+ .fallbackToDestructiveMigration()
+ .build()
INSTANCE = instance
instance
}
}Note: For production, replace with proper migrations to preserve user data: .addMigrations(MIGRATION_1_2, MIGRATION_2_3)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,11 @@ | ||||||
| package com.tejpratapsingh.motion.datastore.data.database | ||||||
|
|
||||||
| import androidx.room.Database | ||||||
| import androidx.room.RoomDatabase | ||||||
| import com.tejpratapsingh.motion.datastore.data.dao.ProjectDao | ||||||
| import com.tejpratapsingh.motion.datastore.data.entity.ProjectEntity | ||||||
|
|
||||||
| @Database(entities = [ProjectEntity::class], version = 1, exportSchema = false) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a best practice to enable schema exporting for Room databases, especially in production apps. Setting
Suggested change
|
||||||
| abstract class ProjectDatabase : RoomDatabase() { | ||||||
| abstract fun projectDao(): ProjectDao | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,26 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package com.tejpratapsingh.motion.datastore.data.entity | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.room.Entity | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.room.PrimaryKey | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Entity(tableName = "projects") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data class ProjectEntity( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @PrimaryKey(autoGenerate = true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val id: Long = 0L, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val title: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val description: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val image: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val siteName: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val twitterCard: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val url: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val trackName: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val artistName: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val albumName: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val duration: Float?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val instrumental: Boolean?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val plainLyrics: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val syncedLyrics: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val totalLyrics: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val selectedLyrics: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val savedFilePath: String?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
6
to
26
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add database migration strategy. The database is created without
Suggested change
Comment on lines
7
to
26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All properties in this data class are nullable. While this provides flexibility, it can also lead to a high number of null checks throughout the codebase and potentially allow for inconsistent or incomplete data to be saved. Consider making fields that should always be present non-nullable and providing default values if appropriate. This will make your data model more robust and your code safer. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,16 @@ | ||||||
| package com.tejpratapsingh.motion.metadataextractor | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix the package name to match the module structure. The package declaration is 🔎 Proposed fix-package com.tejpratapsingh.motion.metadataextractor
+package com.tejpratapsingh.motion.datastore📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
|
|
||||||
| import org.junit.Assert.* | ||||||
| import org.junit.Test | ||||||
|
|
||||||
| /** | ||||||
| * Example local unit test, which will execute on the development machine (host). | ||||||
| * | ||||||
| * See [testing documentation](http://d.android.com/tools/testing). | ||||||
| */ | ||||||
| class ExampleUnitTest { | ||||||
| @Test | ||||||
| fun addition_isCorrect() { | ||||||
| assertEquals(4, 2 + 2) | ||||||
| } | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| plugins { | ||
| alias(libs.plugins.android.library) | ||
| alias(libs.plugins.kotlin.android) | ||
| alias(libs.plugins.kotlin.parcelize) | ||
| alias(libs.plugins.ksp) | ||
| id 'maven-publish' | ||
| } | ||
|
|
||
| android { | ||
| namespace 'com.tejpratapsingh.motion.imageloader' | ||
| compileSdk 36 | ||
|
|
||
| defaultConfig { | ||
| minSdk 25 | ||
|
|
||
| testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
| consumerProguardFiles "consumer-rules.pro" | ||
| } | ||
|
|
||
| buildTypes { | ||
| release { | ||
| minifyEnabled false | ||
| proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
| } | ||
| } | ||
| compileOptions { | ||
| sourceCompatibility JavaVersion.VERSION_11 | ||
| targetCompatibility JavaVersion.VERSION_11 | ||
| } | ||
| kotlinOptions { | ||
| jvmTarget = '11' | ||
| } | ||
| } | ||
|
|
||
| afterEvaluate { | ||
| publishing { | ||
| publications { | ||
| release(MavenPublication) { | ||
| from components.release | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| dependencies { | ||
| api libs.glide | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # Add project specific ProGuard rules here. | ||
| # You can control the set of applied configuration files using the | ||
| # proguardFiles setting in build.gradle. | ||
| # | ||
| # For more details, see | ||
| # http://developer.android.com/guide/developing/tools/proguard.html | ||
|
|
||
| # If your project uses WebView with JS, uncomment the following | ||
| # and specify the fully qualified class name to the JavaScript interface | ||
| # class: | ||
| #-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
| # public *; | ||
| #} | ||
|
|
||
| # Uncomment this to preserve the line number information for | ||
| # debugging stack traces. | ||
| #-keepattributes SourceFile,LineNumberTable | ||
|
|
||
| # If you keep the line number information, uncomment this to | ||
| # hide the original source file name. | ||
| #-renamesourcefileattribute SourceFile |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <manifest /> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,37 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package com.tejpratapsingh.motion.imageloader | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import android.content.Context | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import android.graphics.Bitmap | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import android.graphics.drawable.Drawable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import android.util.Log | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.bumptech.glide.Glide | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.bumptech.glide.request.target.CustomTarget | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.bumptech.glide.request.transition.Transition | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import kotlinx.coroutines.suspendCancellableCoroutine | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import kotlin.coroutines.resume | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| object ImageLoader { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fun loadImage(context: Context, url: String) = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Glide.with(context).load(url) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| suspend fun loadBitmap(context: Context, url: String): Bitmap = suspendCancellableCoroutine { cont -> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val target = object : CustomTarget<Bitmap>() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cont.resume(resource) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| override fun onLoadCleared(placeholder: Drawable?) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!cont.isCompleted) cont.cancel() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Glide.with(context) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .asBitmap() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .load(url) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .into(target) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cont.invokeOnCancellation { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Glide.with(context).clear(target) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+18
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling for failed image loads. The 🐛 Proposed fix to handle load failures suspend fun loadBitmap(context: Context, url: String): Bitmap = suspendCancellableCoroutine { cont ->
val target = object : CustomTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
cont.resume(resource)
}
override fun onLoadCleared(placeholder: Drawable?) {
if (!cont.isCompleted) cont.cancel()
}
+ override fun onLoadFailed(errorDrawable: Drawable?) {
+ cont.cancel(Exception("Failed to load image from URL: $url"))
+ }
}
Glide.with(context)
.asBitmap()
.load(url)
.into(target)
cont.invokeOnCancellation {
Glide.with(context).clear(target)
}
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.tejpratapsingh.motion.imageloader | ||
|
|
||
| import org.junit.Assert.* | ||
| import org.junit.Test | ||
|
|
||
| /** | ||
| * Example local unit test, which will execute on the development machine (host). | ||
| * | ||
| * See [testing documentation](http://d.android.com/tools/testing). | ||
| */ | ||
| class ExampleUnitTest { | ||
| @Test | ||
| fun addition_isCorrect() { | ||
| assertEquals(4, 2 + 2) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
latest stable androidx.room version 2025 2026💡 Result:
The latest stable AndroidX Room release is 2.8.4 (released November 19, 2025). [1][2]
Sources:
[1] Android Developers — Room release notes.
[2] Maven Repository — androidx.room:room-runtime (latest).
🌐 Web query:
latest stable KSP Kotlin Symbol Processing version 2025 2026💡 Result:
The latest stable KSP release is 2.3.4 (released Dec 16, 2025). [1][2]
Sources:
🌐 Web query:
latest stable Glide image loading library version 2025 2026💡 Result:
Latest stable Glide (bumptech/glide) release is v5.0.5 (released Sep 13, 2025). [1][2]
Sources:
🌐 Web query:
latest stable androidx material icons version 2025 2026💡 Result:
Latest stable androidx Material Icons: 1.7.8 (released Feb 12, 2025). [1][2]
Note: the androidx.compose.material.icons library is no longer recommended (Material Symbols preferred). [1]
Sources:
Update KSP to 2.3.4 and consider Material Symbols instead of Material Icons.
Room 2.8.4, Glide 5.0.5, and Material Icons 1.7.8 are latest stable. However, KSP 2.0.4 is outdated; the latest stable is 2.3.4 (released Dec 16, 2025). Update the KSP version accordingly.
Additionally, androidx.compose.material.icons (Material Icons) is deprecated in favor of Material Symbols. If possible, migrate to Material Symbols for future compatibility.
🤖 Prompt for AI Agents