Compare commits

...

2 Commits
0.4.1 ... 0.4.3

3 changed files with 27 additions and 62 deletions

View File

@@ -14,8 +14,8 @@ android {
applicationId = "com.atridad.openclimb"
minSdk = 31
targetSdk = 35
versionCode = 8
versionName = "0.4.1"
versionCode = 10
versionName = "0.4.3"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

View File

@@ -410,33 +410,6 @@ fun SessionDetailScreen(sessionId: String, viewModel: ClimbViewModel, onNavigate
value = "${((successfulAttempts.size.toDouble() / attempts.size) * 100).toInt()}%"
)
// Show average grade if available
val attemptedProblems = problems.filter { it.id in uniqueProblems }
if (attemptedProblems.isNotEmpty()) {
val boulderProblems = attemptedProblems.filter { it.climbType == ClimbType.BOULDER }
val ropeProblems = attemptedProblems.filter { it.climbType == ClimbType.ROPE }
val averageGrade = when {
boulderProblems.isNotEmpty() && ropeProblems.isNotEmpty() -> {
val boulderAvg = calculateAverageGrade(boulderProblems)
val ropeAvg = calculateAverageGrade(ropeProblems)
"${boulderAvg ?: "N/A"} / ${ropeAvg ?: "N/A"}"
}
boulderProblems.isNotEmpty() -> calculateAverageGrade(boulderProblems) ?: "N/A"
ropeProblems.isNotEmpty() -> calculateAverageGrade(ropeProblems) ?: "N/A"
else -> "N/A"
}
StatItem(
label = "Average Grade",
value = averageGrade
)
} else {
StatItem(
label = "Average Grade",
value = "N/A"
)
}
}
// Show grade range if available

View File

@@ -35,40 +35,32 @@ object ImageUtils {
*/
fun saveImageFromUri(context: Context, imageUri: Uri): String? {
return try {
val inputStream = context.contentResolver.openInputStream(imageUri)
inputStream?.use { input ->
// Decode with options to get EXIF data
val options = BitmapFactory.Options().apply {
inJustDecodeBounds = true
}
input.reset()
BitmapFactory.decodeStream(input, null, options)
// Reset stream and decode with proper orientation
input.reset()
val originalBitmap = BitmapFactory.decodeStream(input)
val orientedBitmap = correctImageOrientation(context, imageUri, originalBitmap)
val compressedBitmap = compressImage(orientedBitmap)
// Generate unique filename
val filename = "${UUID.randomUUID()}.jpg"
val imageFile = File(getImagesDirectory(context), filename)
// Save compressed image
FileOutputStream(imageFile).use { output ->
compressedBitmap.compress(Bitmap.CompressFormat.JPEG, IMAGE_QUALITY, output)
}
// Clean up bitmaps
originalBitmap.recycle()
if (orientedBitmap != originalBitmap) {
orientedBitmap.recycle()
}
compressedBitmap.recycle()
// Return relative path
"$IMAGES_DIR/$filename"
// Decode bitmap from a fresh stream to avoid mark/reset dependency
val originalBitmap = context.contentResolver.openInputStream(imageUri)?.use { input ->
BitmapFactory.decodeStream(input)
} ?: return null
val orientedBitmap = correctImageOrientation(context, imageUri, originalBitmap)
val compressedBitmap = compressImage(orientedBitmap)
// Generate unique filename
val filename = "${UUID.randomUUID()}.jpg"
val imageFile = File(getImagesDirectory(context), filename)
// Save compressed image
FileOutputStream(imageFile).use { output ->
compressedBitmap.compress(Bitmap.CompressFormat.JPEG, IMAGE_QUALITY, output)
}
// Clean up bitmaps
originalBitmap.recycle()
if (orientedBitmap != originalBitmap) {
orientedBitmap.recycle()
}
compressedBitmap.recycle()
// Return relative path
"$IMAGES_DIR/$filename"
} catch (e: Exception) {
e.printStackTrace()
null