Fixed sync/import updates not happening in the recipe list, removing sync temp files after parsing and removing unused tags
parent
d60cbe4678
commit
6dbd014519
|
|
@ -1 +1,2 @@
|
|||
/build
|
||||
/release
|
||||
|
|
|
|||
|
|
@ -1,55 +1,63 @@
|
|||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
alias(libs.plugins.devtools.ksp)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "xyz.pixelatedw.recipe"
|
||||
compileSdk = 35
|
||||
namespace = "xyz.pixelatedw.recipe"
|
||||
compileSdk = 35
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "xyz.pixelatedw.recipe"
|
||||
minSdk = 24
|
||||
targetSdk = 34
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
defaultConfig {
|
||||
applicationId = "xyz.pixelatedw.recipe"
|
||||
minSdk = 24
|
||||
targetSdk = 34
|
||||
versionCode = 2
|
||||
versionName = "1.1"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
}
|
||||
buildFeatures {
|
||||
compose = true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
compose = true
|
||||
}
|
||||
|
||||
lint {
|
||||
checkReleaseBuilds = false
|
||||
abortOnError = false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(platform(libs.androidx.compose.bom))
|
||||
implementation(libs.androidx.ui)
|
||||
implementation(libs.androidx.ui.graphics)
|
||||
implementation(libs.androidx.ui.tooling.preview)
|
||||
implementation(libs.androidx.material3)
|
||||
implementation(libs.androidx.documentfile)
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(platform(libs.androidx.compose.bom))
|
||||
implementation(libs.androidx.ui)
|
||||
implementation(libs.androidx.ui.graphics)
|
||||
implementation(libs.androidx.ui.tooling.preview)
|
||||
implementation(libs.androidx.material3)
|
||||
implementation(libs.androidx.documentfile)
|
||||
implementation(libs.androidx.navigation.fragment)
|
||||
implementation(libs.androidx.navigation.navigation.ui)
|
||||
implementation(libs.androidx.navigation.navigation.compose)
|
||||
|
|
@ -62,11 +70,11 @@ dependencies {
|
|||
|
||||
testImplementation(libs.junit)
|
||||
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
androidTestImplementation(platform(libs.androidx.compose.bom))
|
||||
androidTestImplementation(libs.androidx.ui.test.junit4)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
androidTestImplementation(platform(libs.androidx.compose.bom))
|
||||
androidTestImplementation(libs.androidx.ui.test.junit4)
|
||||
|
||||
debugImplementation(libs.androidx.ui.tooling)
|
||||
debugImplementation(libs.androidx.ui.test.manifest)
|
||||
debugImplementation(libs.androidx.ui.tooling)
|
||||
debugImplementation(libs.androidx.ui.test.manifest)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ import androidx.compose.material3.Scaffold
|
|||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.room.Room
|
||||
import xyz.pixelatedw.recipe.ui.theme.RecipeTheme
|
||||
import xyz.pixelatedw.recipe.data.AppDatabase
|
||||
import xyz.pixelatedw.recipe.data.RecipesView
|
||||
import xyz.pixelatedw.recipe.ui.components.MainScreen
|
||||
import xyz.pixelatedw.recipe.ui.theme.RecipeTheme
|
||||
import xyz.pixelatedw.recipe.utils.parseRecipes
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
|
@ -54,8 +54,7 @@ class MainActivity : ComponentActivity() {
|
|||
result.data?.data?.let { uri ->
|
||||
parseRecipes(this, uri)
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
importError = "Import cancelled"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ data class RecipeWithTags(
|
|||
|
||||
@Dao
|
||||
interface RecipeWithTagsDao {
|
||||
@Transaction
|
||||
@Query("SELECT * FROM recipe")
|
||||
fun getAll(): List<RecipeWithTags>
|
||||
|
||||
|
|
@ -47,6 +46,7 @@ interface RecipeWithTagsDao {
|
|||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(recipe: RecipeTag)
|
||||
|
||||
@Transaction
|
||||
@Query("DELETE FROM recipetag WHERE recipetag.title = :recipe")
|
||||
fun delete(recipe: String)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import androidx.room.Entity
|
|||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.PrimaryKey
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
|
||||
@Entity
|
||||
data class Tag(
|
||||
|
|
@ -14,6 +16,16 @@ data class Tag(
|
|||
|
||||
@Dao
|
||||
interface TagDao {
|
||||
@Query("SELECT * FROM tag")
|
||||
fun getAll(): List<Tag>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(tag: Tag)
|
||||
|
||||
@Query("SELECT COUNT(*) FROM tag")
|
||||
fun count(): Int
|
||||
|
||||
@Transaction
|
||||
@Query("DELETE FROM tag WHERE tag.name = :name")
|
||||
fun delete(name: String)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
|||
val search by view.search.collectAsState()
|
||||
val filters by view.tagFilters.collectAsState()
|
||||
|
||||
var activeRecipes by remember { mutableStateOf(recipes) }
|
||||
var activeTags = 0
|
||||
|
||||
val navController = rememberNavController()
|
||||
|
|
@ -80,8 +79,9 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
|||
value = search.orEmpty(),
|
||||
onValueChange = { search ->
|
||||
view.setSearch(search)
|
||||
activeRecipes =
|
||||
val newRecipes =
|
||||
recipes.filter { filterRecipe(it, search, filters) }
|
||||
view.setRecipes(newRecipes)
|
||||
},
|
||||
)
|
||||
// Tags / Delete
|
||||
|
|
@ -141,10 +141,10 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
|||
state = gridState,
|
||||
) {
|
||||
items(
|
||||
count = activeRecipes.size,
|
||||
key = { activeRecipes[it].recipe.title },
|
||||
count = recipes.size,
|
||||
key = { recipes[it].recipe.title },
|
||||
itemContent = { entryId ->
|
||||
val entry = activeRecipes[entryId]
|
||||
val entry = recipes[entryId]
|
||||
val isSelected = selectedEntries.contains(entry)
|
||||
RecipePreview(entry, isSelected, onClick = {
|
||||
view.setActive(entry)
|
||||
|
|
@ -194,13 +194,14 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
|||
openTagFilterDialog = false
|
||||
view.reloadTagFilterState()
|
||||
activeTags = filters.count { f -> f.checked }
|
||||
activeRecipes = recipes.filter {
|
||||
val newRecipes = recipes.filter {
|
||||
filterRecipe(
|
||||
it,
|
||||
search,
|
||||
filters
|
||||
)
|
||||
}
|
||||
ctx.recipeView.setRecipes(newRecipes)
|
||||
},
|
||||
view,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -42,6 +42,14 @@ fun parseRecipeFiles(ctx: MainActivity) {
|
|||
|
||||
reader.close()
|
||||
}
|
||||
|
||||
// Clearing unused tags after an import/sync
|
||||
val usedTags = ctx.recipeView.tagFilters.value.map { t -> t.tag }
|
||||
for (tag in ctx.db.tagDao().getAll()) {
|
||||
if (!usedTags.contains(tag.name)) {
|
||||
ctx.db.tagDao().delete(tag.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun parseDir(ctx: Context, dir: DocumentFile, path: String) {
|
||||
|
|
|
|||
|
|
@ -59,11 +59,11 @@ fun sync(ctx: MainActivity, nav: NavHostController, setLoading: (Boolean) -> Uni
|
|||
inputStream.read(buffer)
|
||||
val contentBufLen = ByteBuffer.wrap(buffer).getLong().toInt()
|
||||
|
||||
var parentDir = ctx.filesDir
|
||||
var parentDir = File(ctx.filesDir, ".sync")
|
||||
if (filePath.isNotEmpty()) {
|
||||
parentDir = File(ctx.filesDir, filePath)
|
||||
parentDir.mkdirs()
|
||||
}
|
||||
parentDir.mkdirs()
|
||||
|
||||
val newFile = File(parentDir, fileName)
|
||||
|
||||
|
|
@ -94,6 +94,10 @@ fun sync(ctx: MainActivity, nav: NavHostController, setLoading: (Boolean) -> Uni
|
|||
parseDir(ctx, docDir, "")
|
||||
parseRecipeFiles(ctx)
|
||||
|
||||
val syncFolder = File(ctx.filesDir, ".sync")
|
||||
if (syncFolder.exists()) {
|
||||
syncFolder.deleteRecursively()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ctx.importError = when (e) {
|
||||
is SocketTimeoutException -> "Connection timed out"
|
||||
|
|
|
|||
Loading…
Reference in New Issue