Skip to content

Commit

Permalink
Fixed create medicine.
Browse files Browse the repository at this point in the history
Fixed share pharmacy button.
  • Loading branch information
andre-j3sus committed May 10, 2024
1 parent 3c4725b commit 8f4a26e
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,22 @@ package pt.ulisboa.ist.pharmacist.ui.screens.createMedicine
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaType
import pt.ulisboa.ist.pharmacist.ui.screens.PharmacistActivity
import pt.ulisboa.ist.pharmacist.ui.screens.shared.ImageHandlingUtils
import pt.ulisboa.ist.pharmacist.ui.screens.shared.hasCameraPermission
import pt.ulisboa.ist.pharmacist.ui.screens.shared.navigateToForResult
import pt.ulisboa.ist.pharmacist.ui.screens.shared.viewModelInit
import java.io.ByteArrayOutputStream
import java.io.InputStream

/**
* Activity for the [MedicineScreen].
* Activity for the [CreateMedicine].
*/
class CreateMedicineActivity : PharmacistActivity() {

Expand All @@ -35,61 +29,30 @@ class CreateMedicineActivity : PharmacistActivity() {
)
}

@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private val imageResultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode != RESULT_OK) return@registerForActivityResult

if (result.data?.extras?.getParcelable("data", Bitmap::class.java) != null) {
if (result.data?.extras?.get("data") is Bitmap)
handleTakePhoto(result)
} else {
else
handleImageSelection(result)
}
}

private fun handleImageSelection(result: ActivityResult) {
val uri = result.data?.data

if (uri == null) {
Log.e("CreateMedicineActivity", "Failed to get uri")
return
}

val inputStream: InputStream? = contentResolver.openInputStream(uri)

if (inputStream == null) {
Log.e("CreateMedicineActivity", "Failed to open input stream")
return
}

val mimeTypeStr = contentResolver.getType(uri)
val mimeType = mimeTypeStr?.toMediaType()

if (mimeType == null) {
Log.e("CreateMedicineActivity", "Failed to get mime type")
return
}

viewModel.uploadBoxPhoto(inputStream.readBytes(), mimeType)
ImageHandlingUtils.handleImageSelection(contentResolver, result)
?.let { (inputStream, mediaType) ->
viewModel.uploadBoxPhoto(inputStream.readBytes(), mediaType)
}
}

@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private fun handleTakePhoto(result: ActivityResult) {
val imageBitmap = result.data?.extras?.getParcelable("data", Bitmap::class.java)

if (imageBitmap !is Bitmap) {
Log.e("CreateMedicineActivity", "Failed to get image bitmap")
return
}

val stream = ByteArrayOutputStream()
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream)
val imageBytes = stream.toByteArray()

viewModel.uploadBoxPhoto(imageBytes, "image/jpeg".toMediaType())
ImageHandlingUtils.handleTakePhoto(result)
?.let { (boxPhotoData, mediaType) ->
viewModel.uploadBoxPhoto(boxPhotoData, mediaType)
}
}

@RequiresApi(Build.VERSION_CODES.TIRAMISU)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

Expand All @@ -110,17 +73,8 @@ class CreateMedicineActivity : PharmacistActivity() {
}
}
},
onSelectImage = {
val galIntent = Intent(Intent.ACTION_OPEN_DOCUMENT)
galIntent.addCategory(Intent.CATEGORY_OPENABLE)
galIntent.setType("image/jpeg")

val camIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

val chooser = Intent.createChooser(galIntent, "Some text here")
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(camIntent))

imageResultLauncher.launch(chooser)
onAddPictureButtonClick = {
imageResultLauncher.launch(ImageHandlingUtils.getChooserIntent())
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,22 @@ import androidx.compose.ui.unit.dp
import pt.ulisboa.ist.pharmacist.R
import pt.ulisboa.ist.pharmacist.ui.screens.PharmacistScreen
import pt.ulisboa.ist.pharmacist.ui.screens.pharmacyMap.components.PermissionScreen
import pt.ulisboa.ist.pharmacist.ui.screens.shared.components.IconTextButton
import pt.ulisboa.ist.pharmacist.ui.screens.shared.components.ScreenTitle


/**
* Create Medicine screen.
*
* @param boxPhoto the box photo
* @param onSelectImage function to be executed when the user selects an image
* @param onAddPictureButtonClick function to be executed when the user selects an image
* @param onCreateMedicine function to be executed when the user creates a medicine
*/
@Composable
fun CreateMedicineScreen(
hasCameraPermission: Boolean,
boxPhoto: ImageBitmap?,
onSelectImage: () -> Unit,
onAddPictureButtonClick: () -> Unit,
onCreateMedicine: (String, String) -> Unit
) {
PharmacistScreen {
Expand Down Expand Up @@ -89,7 +90,7 @@ fun CreateMedicineScreen(
)

IconButton(
onClick = onSelectImage,
onClick = onAddPictureButtonClick,
modifier = Modifier.padding(16.dp)
) {
Icon(
Expand All @@ -100,7 +101,7 @@ fun CreateMedicineScreen(
}
}

pt.ulisboa.ist.pharmacist.ui.screens.shared.components.IconTextButton(
IconTextButton(
enabled = name.isNotBlank() && description.isNotBlank() && boxPhoto != null,
onClick = { onCreateMedicine(name, description) },
imageVector = Icons.Rounded.Add,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,40 +38,33 @@ class CreateMedicineViewModel(
}
}

fun createMedicine(name: String, description: String): Long? {
var createdMedicineId: Long? = null
viewModelScope.launch {
val boxPhotoUrl = boxPhotoUrl
if (boxPhotoUrl == null) {
Log.e("CreateMedicineModel", "Box photo URL is null")
createdMedicineId = null
return@launch
}
if (name == "" || description == "") {
Log.e("CreateMedicineModel", "Name and description must not be empty")
createdMedicineId = null
return@launch
}
suspend fun createMedicine(name: String, description: String): Long? {
val boxPhotoUrl = boxPhotoUrl
if (boxPhotoUrl == null) {
Log.e("CreateMedicineModel", "Box photo URL is null")
return null
}
if (name == "" || description == "") {
Log.e("CreateMedicineModel", "Name and description must not be empty")
return null
}

state = CreateMedicineState.CREATING_MEDICINE
state = CreateMedicineState.CREATING_MEDICINE

val createMedicineResult =
pharmacistService.medicinesService.createMedicine(name, description, boxPhotoUrl)
val createMedicineResult =
pharmacistService.medicinesService.createMedicine(name, description, boxPhotoUrl)

if (createMedicineResult.isFailure()) {
Log.e("CreateMedicineModel", "Failed to create medicine")
createdMedicineId = null
return@launch
}
if (createMedicineResult.isFailure()) {
Log.e("CreateMedicineModel", "Failed to create medicine")
return null
}

Log.d("CreateMedicineModel", "Medicine created successfully")
state = CreateMedicineState.MEDICINE_CREATED
Log.d("CreateMedicineModel", "Medicine created successfully")
state = CreateMedicineState.MEDICINE_CREATED

createdMedicineId = createMedicineResult.data.medicineId
}
boxPhoto = null
boxPhotoUrl = null
return createdMedicineId
this.boxPhotoUrl = null
return createMedicineResult.data.medicineId
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
package pt.ulisboa.ist.pharmacist.ui.screens.pharmacy

import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.util.Log
import androidx.activity.compose.setContent
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import pt.ulisboa.ist.pharmacist.service.http.services.pharmacies.models.changeMedicineStock.MedicineStockOperation
import pt.ulisboa.ist.pharmacist.ui.screens.PharmacistActivity
import pt.ulisboa.ist.pharmacist.ui.screens.addMedicineToPharmacy.AddMedicineToPharmacyActivity
import pt.ulisboa.ist.pharmacist.ui.screens.medicine.MedicineActivity
import pt.ulisboa.ist.pharmacist.ui.screens.shared.navigateTo
import pt.ulisboa.ist.pharmacist.ui.screens.shared.viewModelInit


/**
* Activity for the [PharmacyScreen].
*/
Expand Down Expand Up @@ -72,18 +80,31 @@ class PharmacyActivity : PharmacistActivity() {
},
onShareClick = {
viewModel.pharmacy?.let {
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TITLE, it.pharmacy.name)
putExtra(
Intent.EXTRA_TEXT,
PHARMACY_SHARE_TEXT + " " + it.pharmacy.pictureUrl
)
setDataAndType(Uri.parse(it.pharmacy.pictureUrl), "image/*")
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
lifecycleScope.launch {
val imageUri = downloadAndStoreImage()
if (imageUri != null) {
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(
Intent.EXTRA_TEXT,
"Check out this pharmacy!" +
"\n\nName: ${it.pharmacy.name}" +
"\nAddress: https://www.google.com/maps/search/?api=1&query=${it.pharmacy.location.lat},${it.pharmacy.location.lon}" +
(if (it.pharmacy.globalRating != null) "\nRating: ${it.pharmacy.globalRating}" else "") +
"\n\nDownload the Pharmacist app to see more details!"
)
putExtra(Intent.EXTRA_TITLE, "Check out this pharmacy!")
putExtra(Intent.EXTRA_SUBJECT, "Check out this pharmacy!")
putExtra(Intent.EXTRA_STREAM, imageUri)
type = "image/*"
}
val shareIntent = Intent.createChooser(
sendIntent,
"Share this pharmacy"
)
startActivity(shareIntent)
}
}
val shareIntent = Intent.createChooser(sendIntent, null)
startActivity(shareIntent)
}
},
onReportClick = {
Expand All @@ -96,9 +117,55 @@ class PharmacyActivity : PharmacistActivity() {
}
}

/**
* Downloads and stores the image of the pharmacy.
* Used to share the pharmacy image.
*/
private suspend fun downloadAndStoreImage(): Uri? {
viewModel.downloadImage()
val contentValues = ContentValues().apply {
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
put(MediaStore.Images.Media.DISPLAY_NAME, "pharmacy")
put(
MediaStore.MediaColumns.RELATIVE_PATH,
Environment.DIRECTORY_PICTURES
)
put(MediaStore.Images.Media.IS_PENDING, 1)
}

val imageUri = contentResolver.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
contentValues
)
if (imageUri == null) {
Log.e("PharmacyActivity", "Failed to create image uri")
return null
}

contentResolver.openOutputStream(imageUri).use { outputStream ->
if (outputStream == null) {
Log.e("PharmacyActivity", "Failed to open output stream")
return null
}

val imageBitmap = viewModel.pharmacyImage?.asAndroidBitmap()
if (imageBitmap == null) {
Log.e("PharmacyActivity", "Failed to get image bitmap")
return null
}

imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
}

contentValues.clear()
contentValues.put(MediaStore.Images.Media.IS_PENDING, 0)
contentResolver.update(imageUri, contentValues, null, null)

return imageUri
}

companion object {
private const val PHARMACY_ID = "pharmacyId"
private const val PHARMACY_SHARE_TEXT = "Check out this pharmacy: "

/**
* Navigates to the [PharmacyActivity].
Expand Down
Loading

0 comments on commit 8f4a26e

Please sign in to comment.