Skip to content

Commit 7d5533c

Browse files
anhanh11001nikit19
authored andcommitted
feat: Add edit/remove/take image for speaker profile photo (#2190)
Fixes: #2189
1 parent cd4acdc commit 7d5533c

File tree

2 files changed

+103
-10
lines changed

2 files changed

+103
-10
lines changed

app/src/main/java/org/fossasia/openevent/general/speakercall/EditSpeakerFragment.kt

Lines changed: 96 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,26 @@ import android.content.Intent
66
import android.content.pm.PackageManager
77
import android.graphics.Bitmap
88
import android.os.Bundle
9+
import android.provider.MediaStore
910
import android.util.Base64
1011
import android.view.LayoutInflater
1112
import android.view.MenuItem
1213
import android.view.View
1314
import android.view.ViewGroup
1415
import androidx.appcompat.app.AlertDialog
16+
import androidx.core.content.ContextCompat
17+
import androidx.core.graphics.drawable.toBitmap
18+
import androidx.core.view.isVisible
1519
import androidx.fragment.app.Fragment
1620
import androidx.lifecycle.Observer
1721
import androidx.navigation.Navigation.findNavController
1822
import androidx.navigation.fragment.navArgs
1923
import com.squareup.picasso.MemoryPolicy
2024
import com.squareup.picasso.Picasso
25+
import kotlinx.android.synthetic.main.dialog_edit_profile_image.view.editImage
26+
import kotlinx.android.synthetic.main.dialog_edit_profile_image.view.takeImage
27+
import kotlinx.android.synthetic.main.dialog_edit_profile_image.view.replaceImage
28+
import kotlinx.android.synthetic.main.dialog_edit_profile_image.view.removeImage
2129
import kotlinx.android.synthetic.main.fragment_proposal_speaker.view.speakerName
2230
import kotlinx.android.synthetic.main.fragment_proposal_speaker.view.speakerImage
2331
import kotlinx.android.synthetic.main.fragment_proposal_speaker.view.speakerOrganization
@@ -61,10 +69,17 @@ class EditSpeakerFragment : Fragment(), ComplexBackPressFragment {
6169
private val editSpeakerViewModel by viewModel<EditSpeakerViewModel>()
6270
private val safeArgs: EditSpeakerFragmentArgs by navArgs()
6371
private var isCreatingNewSpeaker = true
64-
private var permissionGranted = false
72+
private var storagePermissionGranted = false
6573
private val PICK_IMAGE_REQUEST = 100
6674
private val READ_STORAGE = arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
67-
private val REQUEST_CODE = 1
75+
private val READ_STORAGE_REQUEST_CODE = 1
76+
77+
private var cameraPermissionGranted = false
78+
private val TAKE_IMAGE_REQUEST = 101
79+
private val CAMERA_REQUEST = arrayOf(Manifest.permission.CAMERA)
80+
private val CAMERA_REQUEST_CODE = 2
81+
82+
private lateinit var speakerAvatar: String
6883

6984
override fun onCreate(savedInstanceState: Bundle?) {
7085
super.onCreate(savedInstanceState)
@@ -77,6 +92,11 @@ class EditSpeakerFragment : Fragment(), ComplexBackPressFragment {
7792
setToolbar(activity, getString(R.string.proposal_speaker))
7893
setHasOptionsMenu(true)
7994

95+
storagePermissionGranted = (ContextCompat.checkSelfPermission(requireContext(),
96+
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
97+
cameraPermissionGranted = (ContextCompat.checkSelfPermission(requireContext(),
98+
Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)
99+
80100
editSpeakerViewModel.user
81101
.nonNull()
82102
.observe(viewLifecycleOwner, Observer {
@@ -143,11 +163,7 @@ class EditSpeakerFragment : Fragment(), ComplexBackPressFragment {
143163
})
144164

145165
rootView.speakerImage.setOnClickListener {
146-
if (permissionGranted) {
147-
showFileChooser()
148-
} else {
149-
requestPermissions(READ_STORAGE, REQUEST_CODE)
150-
}
166+
showEditPhotoDialog()
151167
}
152168

153169
rootView.submitButton.setOnClickListener {
@@ -195,7 +211,9 @@ class EditSpeakerFragment : Fragment(), ComplexBackPressFragment {
195211

196212
override fun onActivityResult(requestCode: Int, resultCode: Int, intentData: Intent?) {
197213
super.onActivityResult(requestCode, resultCode, intentData)
198-
if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK && intentData?.data != null) {
214+
if (resultCode != Activity.RESULT_OK) return
215+
216+
if (requestCode == PICK_IMAGE_REQUEST && intentData?.data != null) {
199217
val imageUri = intentData.data ?: return
200218

201219
try {
@@ -204,6 +222,11 @@ class EditSpeakerFragment : Fragment(), ComplexBackPressFragment {
204222
} catch (e: FileNotFoundException) {
205223
Timber.d(e, "File Not Found Exception")
206224
}
225+
} else if (requestCode == TAKE_IMAGE_REQUEST) {
226+
val imageBitmap = intentData?.extras?.get("data")
227+
if (imageBitmap is Bitmap) {
228+
editSpeakerViewModel.encodedImage = imageBitmap.let { encodeImage(it) }
229+
}
207230
}
208231
}
209232

@@ -212,14 +235,22 @@ class EditSpeakerFragment : Fragment(), ComplexBackPressFragment {
212235
permissions: Array<String>,
213236
grantResults: IntArray
214237
) {
215-
if (requestCode == REQUEST_CODE) {
238+
if (requestCode == READ_STORAGE_REQUEST_CODE) {
216239
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
217-
permissionGranted = true
240+
storagePermissionGranted = true
218241
rootView.snackbar(getString(R.string.permission_granted_message, getString(R.string.external_storage)))
219242
showFileChooser()
220243
} else {
221244
rootView.snackbar(getString(R.string.permission_denied_message, getString(R.string.external_storage)))
222245
}
246+
} else if (requestCode == CAMERA_REQUEST_CODE) {
247+
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
248+
cameraPermissionGranted = true
249+
rootView.snackbar(getString(R.string.permission_granted_message, getString(R.string.camera)))
250+
takeImage()
251+
} else {
252+
rootView.snackbar(getString(R.string.permission_denied_message, getString(R.string.camera)))
253+
}
223254
}
224255
}
225256

@@ -239,6 +270,60 @@ class EditSpeakerFragment : Fragment(), ComplexBackPressFragment {
239270
.placeholder(R.drawable.ic_account_circle_grey)
240271
.transform(CircleTransform())
241272
.into(rootView.speakerImage)
273+
speakerAvatar = user.avatarUrl ?: ""
274+
}
275+
276+
private fun showEditPhotoDialog() {
277+
val editImageView = layoutInflater.inflate(R.layout.dialog_edit_profile_image, null)
278+
279+
editImageView.removeImage.isVisible = this::speakerAvatar.isInitialized && speakerAvatar.isNotEmpty()
280+
editImageView.editImage.isVisible = false
281+
282+
val dialog = AlertDialog.Builder(requireContext())
283+
.setView(editImageView)
284+
.create()
285+
286+
editImageView.editImage.isVisible = false
287+
288+
editImageView.removeImage.setOnClickListener {
289+
dialog.cancel()
290+
clearAvatar()
291+
}
292+
293+
editImageView.takeImage.setOnClickListener {
294+
dialog.cancel()
295+
if (cameraPermissionGranted) {
296+
takeImage()
297+
} else {
298+
requestPermissions(CAMERA_REQUEST, CAMERA_REQUEST_CODE)
299+
}
300+
}
301+
302+
editImageView.replaceImage.setOnClickListener {
303+
dialog.cancel()
304+
if (storagePermissionGranted) {
305+
showFileChooser()
306+
} else {
307+
requestPermissions(READ_STORAGE, READ_STORAGE_REQUEST_CODE)
308+
}
309+
}
310+
dialog.show()
311+
}
312+
313+
private fun clearAvatar() {
314+
val drawable = requireDrawable(requireContext(), R.drawable.ic_account_circle_grey)
315+
Picasso.get()
316+
.load(R.drawable.ic_account_circle_grey)
317+
.placeholder(drawable)
318+
.transform(CircleTransform())
319+
.into(rootView.speakerImage)
320+
val newSpeakerImage = encodeImage(drawable.toBitmap(120, 120))
321+
editSpeakerViewModel.encodedImage = newSpeakerImage
322+
}
323+
324+
private fun takeImage() {
325+
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
326+
startActivityForResult(intent, TAKE_IMAGE_REQUEST)
242327
}
243328

244329
private fun encodeImage(bitmap: Bitmap): String {
@@ -275,6 +360,7 @@ class EditSpeakerFragment : Fragment(), ComplexBackPressFragment {
275360
.placeholder(R.drawable.ic_account_circle_grey)
276361
.transform(CircleTransform())
277362
.into(rootView.speakerImage)
363+
speakerAvatar = speaker.photoUrl ?: ""
278364
rootView.speakerName.setText(speaker.name)
279365
rootView.speakerEmail.setText(speaker.email)
280366
rootView.speakerOrganization.setText(speaker.organisation)

app/src/main/res/navigation/navigation_graph.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,13 @@
460460
android:name="org.fossasia.openevent.general.speakercall.EditSpeakerFragment"
461461
android:label="EditSpeakerFragment"
462462
tools:layout="@layout/fragment_proposal_speaker">
463+
<action
464+
android:id="@+id/action_edit_speaker_to_crop_image"
465+
app:destination="@id/cropImageFragment"
466+
app:popEnterAnim="@anim/slide_in_left"
467+
app:popExitAnim="@anim/slide_out_right"
468+
app:enterAnim="@anim/slide_in_right"
469+
app:exitAnim="@anim/slide_out_left"/>
463470
<argument
464471
android:name="eventId"
465472
app:argType="long"

0 commit comments

Comments
 (0)