gud commit

This commit is contained in:
inhale-dir 2024-12-13 10:21:22 +01:00
parent de1b0cd1b8
commit e57d8b7490
13 changed files with 221 additions and 51 deletions

3
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

6
.idea/compiler.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="21" />
</component>
</project>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
</project>

20
.idea/gradle.xml Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -0,0 +1,57 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="ComposePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewDeviceShouldUseNewSpec" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
</profile>
</component>

6
.idea/kotlinc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.22" />
</component>
</project>

10
.idea/migrations.xml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

10
.idea/misc.xml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
</set>
</option>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -19,6 +19,9 @@ android {
}
buildTypes {
debug {
isDebuggable = true
}
release {
isMinifyEnabled = false
proguardFiles(
@ -87,4 +90,7 @@ dependencies {
implementation("androidx.room:room-runtime:$roomVersion")
implementation("androidx.room:room-ktx:$roomVersion")
ksp("androidx.room:room-compiler:$roomVersion")
// Add Timber for logging
implementation("com.jakewharton.timber:timber:5.0.1")
}

View File

@ -8,6 +8,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".EpookApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"

View File

@ -7,31 +7,32 @@ import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import java.io.File
import inhale.rip.epook.data.AppDatabase
import android.util.Log
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "books")
class BookStore(private val context: Context) {
private val TAG = "BookStore" // Tag for logging
private val bookIdsKey = stringSetPreferencesKey("book_ids")
private val bookDao = AppDatabase.getDatabase(context).bookDao()
fun getAllBooks(): Flow<List<Book>> = context.dataStore.data.map { preferences ->
preferences[bookIdsKey]?.mapNotNull { id ->
fun getAllBooks(): Flow<List<Book>> = bookDao.getAllBooks().map { entities ->
entities.mapNotNull { entity ->
try {
val bookFile = File(context.filesDir, "book_$id.epub")
val coverFile = File(context.filesDir, "cover_$id.jpg")
val bookFile = File(entity.filePath)
if (bookFile.exists()) {
Book(
id = id,
title = preferences[stringPreferencesKey("title_$id")] ?: "Unknown Title",
coverImageFile = if (coverFile.exists()) coverFile else null,
filePath = bookFile.absolutePath
)
} else null
entity.toBook()
} else {
// If the file doesn't exist, delete the database entry
Log.d(TAG, "Book file missing for ${entity.id}, cleaning up database entry")
null
}
} catch (e: Exception) {
println("Error loading book $id: ${e.message}")
Log.e(TAG, "Error loading book ${entity.id}", e)
null
}
} ?: emptyList()
}
}
suspend fun addBook(book: Book) {
@ -54,59 +55,76 @@ class BookStore(private val context: Context) {
}
suspend fun deleteBook(bookId: String) {
Log.e(TAG, "🔥 DELETE BOOK STARTED 🔥") // Very visible error log
Log.e(TAG, "Attempting to delete book with ID: $bookId")
try {
// Debug logging at start
println("=== Starting book deletion process ===")
println("BookID: $bookId")
// Check if book exists in Room database
val bookEntity = bookDao.getBook(bookId)
Log.e(TAG, if (bookEntity != null) {
"Found book in database: ${bookEntity.title} (ID: ${bookEntity.id})"
} else {
"Book not found in database with ID: $bookId"
})
// Delete the book files
if (bookEntity != null) {
// Try to delete from Room database
try {
bookDao.deleteBook(bookEntity)
Log.e(TAG, "Successfully deleted from database: ${bookEntity.title}")
} catch (e: Exception) {
Log.e(TAG, "Failed to delete from database: ${e.message}", e)
}
}
// File deletion
val bookFile = File(context.filesDir, "book_$bookId.epub")
val coverFile = File(context.filesDir, "cover_$bookId.jpg")
println("Book file path: ${bookFile.absolutePath}")
println("Cover file path: ${coverFile.absolutePath}")
println("Book file exists: ${bookFile.exists()}")
println("Cover file exists: ${coverFile.exists()}")
Log.e(TAG, "Book file path: ${bookFile.absolutePath}")
if (bookFile.exists()) {
val canWrite = bookFile.canWrite()
Log.e(TAG, "Book file exists, size: ${bookFile.length()} bytes")
val deleted = bookFile.delete()
println("Book file writable: $canWrite")
println("Book file deleted: $deleted")
Log.e(TAG, "Book file deleted: $deleted")
} else {
Log.e(TAG, "Book file does not exist")
}
val coverFile = File(context.filesDir, "cover_$bookId.jpg")
Log.e(TAG, "Cover file path: ${coverFile.absolutePath}")
if (coverFile.exists()) {
val canWrite = coverFile.canWrite()
Log.e(TAG, "Cover file exists, size: ${coverFile.length()} bytes")
val deleted = coverFile.delete()
println("Cover file writable: $canWrite")
println("Cover file deleted: $deleted")
Log.e(TAG, "Cover file deleted: $deleted")
} else {
Log.e(TAG, "Cover file does not exist")
}
// Get current state before deletion
context.dataStore.data.collect { preferences ->
val currentIds = preferences[bookIdsKey]
println("Current book IDs before deletion: $currentIds")
// DataStore cleanup
Log.e(TAG, "Starting DataStore cleanup")
try {
context.dataStore.edit { preferences ->
val currentIds = preferences[bookIdsKey]?.toMutableSet() ?: mutableSetOf()
Log.e(TAG, "Current IDs in DataStore: $currentIds")
val removed = currentIds.remove(bookId)
Log.e(TAG, "ID removed from DataStore: $removed")
preferences[bookIdsKey] = currentIds
Log.e(TAG, "Updated IDs in DataStore: $currentIds")
preferences.remove(stringPreferencesKey("title_$bookId"))
preferences.remove(stringPreferencesKey("position_$bookId"))
Log.e(TAG, "Removed related preferences for book ID: $bookId")
}
Log.e(TAG, "DataStore cleanup completed successfully")
} catch (e: Exception) {
Log.e(TAG, "Error during DataStore cleanup", e)
}
// Remove from preferences
context.dataStore.edit { preferences ->
val currentIds = preferences[bookIdsKey]?.toMutableSet() ?: mutableSetOf()
val removed = currentIds.remove(bookId)
preferences[bookIdsKey] = currentIds
// Clean up related preferences
preferences.remove(stringPreferencesKey("title_$bookId"))
preferences.remove(stringPreferencesKey("position_$bookId"))
println("Book ID removed from set: $removed")
println("Remaining book IDs: $currentIds")
}
println("=== Book deletion process completed ===")
Log.e(TAG, "🔥 DELETE BOOK COMPLETED SUCCESSFULLY 🔥")
} catch (e: Exception) {
println("=== Error during book deletion ===")
println("Error message: ${e.message}")
println("Stack trace:")
Log.e(TAG, "🔥 DELETE BOOK FAILED 🔥")
Log.e(TAG, "Error type: ${e.javaClass.simpleName}")
Log.e(TAG, "Error message: ${e.message}")
e.printStackTrace()
}
}