Unverified Commit 4d3e1402 authored by Lucio Maciel's avatar Lucio Maciel Committed by GitHub

Merge pull request #1527 from RocketChat/new/update-avatar-by-photo

[NEW] Upload/reset avatar.
parents 2358e213 c412154b
......@@ -330,7 +330,7 @@ class DatabaseManager(val context: Application,
id = room.id,
subscriptionId = subscription.id,
type = room.type.toString(),
name = room.name ?: subscription.name ?: throw NullPointerException(),// this should be filtered on the SDK
name = room.name ?: subscription.name ?: throw NullPointerException(), // this should be filtered on the SDK
fullname = subscription.fullName ?: room.fullName,
userId = userId,
ownerId = room.user?.id,
......
......@@ -135,7 +135,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
text_user_name.text = userDisplayName
}
if (userAvatar != null) {
image_avatar.setImageURI(userAvatar)
setAvatar(userAvatar)
}
if (serverLogo != null) {
server_logo.setImageURI(serverLogo)
......@@ -257,6 +257,10 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
}
}
fun setAvatar(avatarUrl: String) {
headerLayout.image_avatar.setImageURI(avatarUrl)
}
fun getDrawerLayout(): DrawerLayout = drawer_layout
fun openDrawer() = drawer_layout.openDrawer(Gravity.START)
......
package chat.rocket.android.profile.presentation
import android.graphics.Bitmap
import android.net.Uri
import chat.rocket.android.chatroom.domain.UriInteractor
import chat.rocket.android.core.behaviours.showMessage
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.helper.UserHelper
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.extension.compressImageAndGetByteArray
import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.extensions.avatarUrl
import chat.rocket.android.util.retryIO
import chat.rocket.common.RocketChatException
import chat.rocket.common.util.ifNull
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.me
import chat.rocket.core.internal.rest.resetAvatar
import chat.rocket.core.internal.rest.setAvatar
import chat.rocket.core.internal.rest.updateProfile
import java.util.*
import javax.inject.Inject
class ProfilePresenter @Inject constructor(
private val view: ProfileView,
private val strategy: CancelStrategy,
private val uriInteractor: UriInteractor,
val userHelper: UserHelper,
serverInteractor: GetCurrentServerInteractor,
factory: RocketChatClientFactory
) {
private val serverUrl = serverInteractor.get()!!
private val client: RocketChatClient = factory.create(serverUrl)
private lateinit var myselfId: String
private val myselfId = userHelper.user()?.id ?: ""
private var myselfName = userHelper.user()?.name ?: ""
private var myselfUsername = userHelper.username() ?: ""
private var myselfEmailAddress = userHelper.user()?.emails?.getOrNull(0)?.address ?: ""
fun loadUserProfile() {
launchUI(strategy) {
view.showLoading()
try {
val myself = retryIO("me") { client.me() }
val id = myself.id
val username = myself.username
if (id == null || username == null) {
view.showGenericErrorMessage()
} else {
myselfId = id
val avatarUrl = serverUrl.avatarUrl(username)
val email = myself.emails?.getOrNull(0)?.address
view.showProfile(
avatarUrl,
myself.name ?: "",
myself.username ?: "",
email
serverUrl.avatarUrl(myselfUsername),
myselfName,
myselfUsername,
myselfEmailAddress
)
}
} catch (exception: RocketChatException) {
view.showMessage(exception)
} finally {
......@@ -53,18 +54,16 @@ class ProfilePresenter @Inject constructor(
}
}
fun updateUserProfile(email: String, name: String, username: String, avatarUrl: String = "") {
fun updateUserProfile(email: String, name: String, username: String) {
launchUI(strategy) {
view.showLoading()
try {
if (avatarUrl != "") {
retryIO { client.setAvatar(avatarUrl) }
}
val user = retryIO {
client.updateProfile(
userId = myselfId, email = email, name = name, username = username
)
}
retryIO { client.updateProfile(myselfId, email, name, username) }
myselfEmailAddress = email
myselfName = name
myselfUsername = username
view.showProfileUpdateSuccessfullyMessage()
loadUserProfile()
} catch (exception: RocketChatException) {
......@@ -78,4 +77,74 @@ class ProfilePresenter @Inject constructor(
}
}
}
fun updateAvatar(uri: Uri) {
launchUI(strategy) {
view.showLoading()
try {
retryIO {
client.setAvatar(
uriInteractor.getFileName(uri) ?: uri.toString(),
uriInteractor.getMimeType(uri)
) {
uriInteractor.getInputStream(uri)
}
}
view.reloadUserAvatar(serverUrl.avatarUrl(myselfUsername))
} catch (exception: RocketChatException) {
exception.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
} finally {
view.hideLoading()
}
}
}
fun preparePhotoAndUpdateAvatar(bitmap: Bitmap) {
launchUI(strategy) {
view.showLoading()
try {
val byteArray = bitmap.compressImageAndGetByteArray("image/png")
retryIO {
client.setAvatar(
UUID.randomUUID().toString() + ".png",
"image/png"
) {
byteArray?.inputStream()
}
}
view.reloadUserAvatar(serverUrl.avatarUrl(myselfUsername))
} catch (exception: RocketChatException) {
exception.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
} finally {
view.hideLoading()
}
}
}
fun resetAvatar() {
launchUI(strategy) {
view.showLoading()
try {
retryIO { client.resetAvatar(myselfId) }
view.reloadUserAvatar(serverUrl.avatarUrl(myselfUsername))
} catch (exception: RocketChatException) {
exception.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
} finally {
view.hideLoading()
}
}
}
}
\ No newline at end of file
......@@ -15,6 +15,13 @@ interface ProfileView : LoadingView, MessageView {
*/
fun showProfile(avatarUrl: String, name: String, username: String, email: String?)
/**
* Reloads the user avatar (after successfully updating it).
*
* @param avatarUrl The user avatar URL.
*/
fun reloadUserAvatar(avatarUrl: String)
/**
* Shows a profile update successfully message
*/
......
package chat.rocket.android.profile.ui
import DrawableHelper
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.appcompat.view.ActionMode
import android.view.*
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import chat.rocket.android.R
import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.profile.presentation.ProfilePresenter
import chat.rocket.android.profile.presentation.ProfileView
import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.*
import chat.rocket.android.util.extension.dispatchImageSelection
import chat.rocket.android.util.extension.dispatchTakePicture
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.extensions.ui
import com.facebook.drawee.backends.pipeline.Fresco
import dagger.android.support.AndroidSupportInjection
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.rxkotlin.Observables
import kotlinx.android.synthetic.main.avatar_profile.*
import kotlinx.android.synthetic.main.fragment_profile.*
import kotlinx.android.synthetic.main.update_avatar_options.*
import javax.inject.Inject
private const val REQUEST_CODE_FOR_PERFORM_SAF = 1
private const val REQUEST_CODE_FOR_PERFORM_CAMERA = 2
class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
@Inject
lateinit var presenter: ProfilePresenter
private lateinit var currentName: String
private lateinit var currentUsername: String
private lateinit var currentEmail: String
private lateinit var currentAvatar: String
private var currentName = ""
private var currentUsername = ""
private var currentEmail = ""
private var actionMode: ActionMode? = null
private val editTextsDisposable = CompositeDisposable()
......@@ -50,11 +63,12 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
super.onViewCreated(view, savedInstanceState)
setupToolbar()
setupListeners()
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
tintEditTextDrawableStart()
}
presenter.loadUserProfile()
subscribeEditTexts()
}
override fun onDestroyView() {
......@@ -62,56 +76,61 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
unsubscribeEditTexts()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
if (resultData != null && resultCode == Activity.RESULT_OK) {
if (requestCode == REQUEST_CODE_FOR_PERFORM_SAF) {
presenter.updateAvatar(resultData.data)
} else if (requestCode == REQUEST_CODE_FOR_PERFORM_CAMERA) {
presenter.preparePhotoAndUpdateAvatar(resultData.extras["data"] as Bitmap)
}
}
}
override fun showProfile(avatarUrl: String, name: String, username: String, email: String?) {
ui {
image_avatar.setImageURI(avatarUrl)
text_name.textContent = name
text_username.textContent = username
text_email.textContent = email ?: ""
text_avatar_url.textContent = ""
currentName = name
currentUsername = username
currentEmail = email ?: ""
currentAvatar = avatarUrl
profile_container.setVisible(true)
subscribeEditTexts()
profile_container.isVisible = true
}
}
override fun reloadUserAvatar(avatarUrl: String) {
Fresco.getImagePipeline().evictFromCache(avatarUrl.toUri())
image_avatar.setImageURI(avatarUrl)
(activity as MainActivity).setAvatar(avatarUrl)
}
override fun showProfileUpdateSuccessfullyMessage() {
showMessage(getString(R.string.msg_profile_update_successfully))
}
override fun showLoading() {
enableUserInput(false)
ui {
view_loading.setVisible(true)
}
ui { view_loading.isVisible = true }
}
override fun hideLoading() {
ui {
if (view_loading != null) {
view_loading.setVisible(false)
view_loading.isVisible = false
}
}
enableUserInput(true)
}
override fun showMessage(resId: Int) {
ui {
showToast(resId)
}
ui { showToast(resId) }
}
override fun showMessage(message: String) {
ui {
showToast(message)
}
ui { showToast(message) }
}
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
......@@ -130,8 +149,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
presenter.updateUserProfile(
text_email.textContent,
text_name.textContent,
text_username.textContent,
text_avatar_url.textContent
text_username.textContent
)
mode.finish()
true
......@@ -151,6 +169,37 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
getString(R.string.title_profile)
}
private fun setupListeners() {
image_avatar.setOnClickListener { showUpdateAvatarOptions() }
view_dim.setOnClickListener { hideUpdateAvatarOptions() }
button_open_gallery.setOnClickListener {
dispatchImageSelection(REQUEST_CODE_FOR_PERFORM_SAF)
hideUpdateAvatarOptions()
}
button_take_photo.setOnClickListener {
dispatchTakePicture(REQUEST_CODE_FOR_PERFORM_CAMERA)
hideUpdateAvatarOptions()
}
button_reset_avatar.setOnClickListener {
hideUpdateAvatarOptions()
presenter.resetAvatar()
}
}
private fun showUpdateAvatarOptions() {
view_dim.isVisible = true
layout_update_avatar_options.isVisible = true
}
private fun hideUpdateAvatarOptions() {
layout_update_avatar_options.isVisible = false
view_dim.isVisible = false
}
private fun tintEditTextDrawableStart() {
(activity as MainActivity).apply {
val personDrawable =
......@@ -158,14 +207,12 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_at_black_24dp, this)
val emailDrawable =
DrawableHelper.getDrawableFromId(R.drawable.ic_email_black_24dp, this)
val linkDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_link_black_24dp, this)
val drawables = arrayOf(personDrawable, atDrawable, emailDrawable, linkDrawable)
val drawables = arrayOf(personDrawable, atDrawable, emailDrawable)
DrawableHelper.wrapDrawables(drawables)
DrawableHelper.tintDrawables(drawables, this, R.color.colorDrawableTintGrey)
DrawableHelper.compoundDrawables(
arrayOf(text_name, text_username, text_email, text_avatar_url),
drawables
arrayOf(text_name, text_username, text_email), drawables
)
}
}
......@@ -174,13 +221,11 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
editTextsDisposable.add(Observables.combineLatest(
text_name.asObservable(),
text_username.asObservable(),
text_email.asObservable(),
text_avatar_url.asObservable()
) { text_name, text_username, text_email, text_avatar_url ->
text_email.asObservable()
) { text_name, text_username, text_email ->
return@combineLatest (text_name.toString() != currentName ||
text_username.toString() != currentUsername ||
text_email.toString() != currentEmail ||
(text_avatar_url.toString() != "" && text_avatar_url.toString() != currentAvatar))
text_email.toString() != currentEmail)
}.subscribe { isValid ->
if (isValid) {
startActionMode()
......@@ -190,9 +235,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
})
}
private fun unsubscribeEditTexts() {
editTextsDisposable.clear()
}
private fun unsubscribeEditTexts() = editTextsDisposable.clear()
private fun startActionMode() {
if (actionMode == null) {
......@@ -207,7 +250,6 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
text_username.isEnabled = value
text_username.isEnabled = value
text_email.isEnabled = value
text_avatar_url.isEnabled = value
}
}
}
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3.9,12c0,-1.71 1.39,-3.1 3.1,-3.1h4L11,7L7,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5h4v-1.9L7,15.1c-1.71,0 -3.1,-1.39 -3.1,-3.1zM8,13h8v-2L8,11v2zM17,7h-4v1.9h4c1.71,0 3.1,1.39 3.1,3.1s-1.39,3.1 -3.1,3.1h-4L13,17h4c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0" />
<path
android:fillColor="#FF000000"
android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z" />
</vector>
......@@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
app:layout_behavior=" com.google.android.material.bottomsheet.BottomSheetBehavior">
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/image_bottom_sheet_avatar"
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relative_layout"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/relative_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
......@@ -48,20 +48,11 @@
android:id="@+id/text_email"
style="@style/Profile.EditText"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:drawableStart="@drawable/ic_email_black_24dp"
android:hint="@string/msg_email"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/text_avatar_url"
style="@style/Profile.EditText"
android:layout_marginTop="16dp"
android:drawableStart="@drawable/ic_link_black_24dp"
android:hint="@string/msg_avatar_url"
android:inputType="text"
android:layout_marginBottom="16dp"/>
</LinearLayout>
</ScrollView>
<com.wang.avi.AVLoadingIndicatorView
......@@ -72,4 +63,19 @@
app:indicatorColor="@color/colorBlack"
app:indicatorName="BallPulseIndicator" />
<View
android:id="@+id/view_dim"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorDim"
android:visibility="gone" />
<include
android:id="@+id/layout_update_avatar_options"
layout="@layout/update_avatar_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:visibility="gone" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/style_attachment_options"
android:orientation="vertical">
<Button
android:id="@+id/button_open_gallery"
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_image_black_24dp"
android:drawablePadding="20dp"
android:gravity="start|center"
android:text="@string/action_select_photo_from_gallery" />
<Button
android:id="@+id/button_take_photo"
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_photo_camera_black_24dp"
android:drawablePadding="20dp"
android:gravity="start|center"
android:text="@string/action_take_photo" />
<Button
android:id="@+id/button_reset_avatar"
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_close_black_24dp"
android:drawablePadding="20dp"
android:gravity="start|center"
android:text="@string/action_reset_avatar" />
</LinearLayout>
\ No newline at end of file
......@@ -38,6 +38,9 @@
<string name="action_invisible">Unsichtbar</string>
<string name="action_drawing">Zeichnung</string>
<string name="action_save_to_gallery">Sichern in Gallerie</string>
<string name="action_select_photo_from_gallery">Select photo from gallery</string> <!-- TODO Add translation -->
<string name="action_take_photo">Select photo from gallery</string> <!-- TODO Add translation -->
<string name="action_reset_avatar">Reset avatar</string> <!-- TODO Add translation -->
<!-- Settings List -->
<string-array name="settings_actions">
......@@ -78,6 +81,7 @@
<string name="msg_content_description_log_in_using_meteor">Login mit Meteor</string>
<string name="msg_content_description_log_in_using_twitter">Login mit Twitter</string>
<string name="msg_content_description_log_in_using_gitlab">Login mit Gitlab</string>
<string name="msg_content_description_log_in_using_wordprees">Login using WordPress</string> <!-- TODO Translate-->
<string name="msg_content_description_send_message">Sende Nachricht</string>
<string name="msg_content_description_show_attachment_options">Zeige Anhang Optionen</string>
<string name="msg_you">Du</string>
......
......@@ -36,8 +36,11 @@
<string name="action_away">Ausente</string>
<string name="action_busy">Ocupado</string>
<string name="action_invisible">Invisible</string>
<string name="action_drawing">dibujo</string>
<string name="action_drawing">Dibujo</string>
<string name="action_save_to_gallery">Guardar en la galería</string>
<string name="action_select_photo_from_gallery">Select photo from gallery</string> <!-- TODO Add translation -->
<string name="action_take_photo">Select photo from gallery</string> <!-- TODO Add translation -->
<string name="action_reset_avatar">Reset avatar</string> <!-- TODO Add translation -->
<!-- Settings List -->
<string-array name="settings_actions">
......@@ -135,7 +138,6 @@
<string name="msg_member_not_found">Miembro no encontrado</string>
<string name="msg_channel_created_successfully">Canal creado con éxito</string>
<!-- System messages -->
<string name="message_room_name_changed">Nombre de la sala cambiado para: %1$s por %2$s</string>
<string name="message_user_added_by">Usuario %1$s añadido por %2$s</string>
......
......@@ -27,8 +27,7 @@
<string name="action_search">Chercher</string>
<string name="action_update">Mettre à jour</string>
<string name="action_settings">Paramètres</string>
// TODO: Add proper translation.
<string name="action_create_channel">Create channel</string>
<string name="action_create_channel">Create channel</string> <!-- TODO Add translation -->
<string name="action_create">Create</string>
<string name="action_logout">Se déconnecter</string>
<string name="action_files">Fichiers</string>
......@@ -40,8 +39,10 @@
<string name="action_busy">Occupé</string>
<string name="action_invisible">Invisible</string>
<string name="action_drawing">Dessin</string>
// TODO: Add proper translation.
<string name="action_save_to_gallery">Save to gallery</string>
<string name="action_save_to_gallery">Save to gallery</string> <!-- TODO Add translation -->
<string name="action_select_photo_from_gallery">Select photo from gallery</string> <!-- TODO Add translation -->
<string name="action_take_photo">Select photo from gallery</string> <!-- TODO Add translation -->
<string name="action_reset_avatar">Reset avatar</string> <!-- TODO Add translation -->
<!-- Settings List -->
<string-array name="settings_actions">
......
......@@ -39,6 +39,9 @@
<string name="action_invisible">अदृश्य</string>
<string name="action_save_to_gallery">गैलरी में सहेजें</string>
<string name="action_drawing">चित्रकारी</string>
<string name="action_select_photo_from_gallery">Select photo from gallery</string> <!-- TODO Add translation -->
<string name="action_take_photo">Select photo from gallery</string> <!-- TODO Add translation -->
<string name="action_reset_avatar">Reset avatar</string> <!-- TODO Add translation -->
<string name="action_share">शेयर</string>
<!-- Settings List -->
......
......@@ -39,6 +39,9 @@
<string name="action_invisible">Invisível</string>
<string name="action_drawing">Desenhando</string>
<string name="action_save_to_gallery">Salvar na galeria</string>
<string name="action_select_photo_from_gallery">Escolher foto da galeria</string>
<string name="action_take_photo">Tirar foto</string>
<string name="action_reset_avatar">Resetar avatar</string>
<!-- Settings List -->
<string-array name="settings_actions">
......
......@@ -39,6 +39,9 @@
<string name="action_invisible">Невидимый</string>
<string name="action_drawing">Рисование</string>
<string name="action_save_to_gallery">Сохранить в галерею</string>
<string name="action_select_photo_from_gallery">Select photo from gallery</string> <!-- TODO Add translation -->
<string name="action_take_photo">Select photo from gallery</string> <!-- TODO Add translation -->
<string name="action_reset_avatar">Reset avatar</string> <!-- TODO Add translation -->
<!-- Settings List -->
<string-array name="settings_actions">
......
......@@ -40,6 +40,9 @@
<string name="action_invisible">Invisible</string>
<string name="action_drawing">Drawing</string>
<string name="action_save_to_gallery">Save to gallery</string>
<string name="action_select_photo_from_gallery">Select photo from gallery</string>
<string name="action_take_photo">Take photo</string>
<string name="action_reset_avatar">Reset avatar</string>
<!-- Settings List -->
<string-array name="settings_actions">
......
package chat.rocket.android.util.extension
import android.content.Intent
import android.graphics.Bitmap
import android.provider.MediaStore
import androidx.fragment.app.Fragment
import kotlinx.coroutines.experimental.DefaultDispatcher
import kotlinx.coroutines.experimental.withContext
import java.io.ByteArrayInputStream
......@@ -62,3 +65,17 @@ fun String.getCompressFormat(): Bitmap.CompressFormat {
else -> Bitmap.CompressFormat.PNG
}
}
fun Fragment.dispatchImageSelection(requestCode: Int) {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "image/*"
intent.addCategory(Intent.CATEGORY_OPENABLE)
startActivityForResult(intent, requestCode)
}
fun Fragment.dispatchTakePicture(requestCode: Int) {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (takePictureIntent.resolveActivity(context?.packageManager) != null) {
startActivityForResult(takePictureIntent, requestCode)
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment