Fix avatar photo editing.
This commit is contained in:
parent
921c903190
commit
b99855afbe
7 changed files with 80 additions and 27 deletions
|
@ -514,6 +514,13 @@
|
||||||
android:windowSoftInputMode="stateHidden"
|
android:windowSoftInputMode="stateHidden"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".avatar.photo.PhotoEditorActivity"
|
||||||
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize|uiMode"
|
||||||
|
android:label="@string/AndroidManifest__media_preview"
|
||||||
|
android:theme="@style/TextSecure.DarkNoActionBar"
|
||||||
|
android:windowSoftInputMode="stateHidden" />
|
||||||
|
|
||||||
<activity android:name=".mediaoverview.MediaOverviewActivity"
|
<activity android:name=".mediaoverview.MediaOverviewActivity"
|
||||||
android:theme="@style/Theme.Signal.DayNight.NoActionBar"
|
android:theme="@style/Theme.Signal.DayNight.NoActionBar"
|
||||||
android:windowSoftInputMode="stateHidden"
|
android:windowSoftInputMode="stateHidden"
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package org.thoughtcrime.securesms.avatar.photo
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.activity.result.contract.ActivityResultContract
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import org.thoughtcrime.securesms.avatar.Avatar
|
||||||
|
import org.thoughtcrime.securesms.avatar.AvatarBundler
|
||||||
|
import org.thoughtcrime.securesms.components.FragmentWrapperActivity
|
||||||
|
|
||||||
|
class PhotoEditorActivity : FragmentWrapperActivity() {
|
||||||
|
|
||||||
|
override fun attachBaseContext(newBase: Context) {
|
||||||
|
delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_YES
|
||||||
|
super.attachBaseContext(newBase)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
||||||
|
super.onCreate(savedInstanceState, ready)
|
||||||
|
|
||||||
|
supportFragmentManager.setFragmentResultListener(PhotoEditorFragment.REQUEST_KEY_EDIT, this) { _, bundle ->
|
||||||
|
setResult(Activity.RESULT_OK, Intent().putExtras(bundle))
|
||||||
|
finishAfterTransition()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFragment(): Fragment = PhotoEditorFragment().apply {
|
||||||
|
arguments = intent.extras
|
||||||
|
}
|
||||||
|
|
||||||
|
class Contract : ActivityResultContract<Avatar.Photo, Avatar.Photo?>() {
|
||||||
|
override fun createIntent(context: Context, input: Avatar.Photo): Intent {
|
||||||
|
return Intent(context, PhotoEditorActivity::class.java).apply {
|
||||||
|
putExtras(PhotoEditorActivityArgs.Builder(AvatarBundler.bundlePhoto(input)).build().toBundle())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun parseResult(resultCode: Int, intent: Intent?): Avatar.Photo? {
|
||||||
|
val extras = intent?.extras
|
||||||
|
if (resultCode != Activity.RESULT_OK || extras == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return AvatarBundler.extractPhoto(extras)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,6 @@ import android.view.View
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.commit
|
import androidx.fragment.app.commit
|
||||||
import androidx.fragment.app.setFragmentResult
|
import androidx.fragment.app.setFragmentResult
|
||||||
import androidx.navigation.Navigation
|
|
||||||
import org.signal.core.util.ThreadUtil
|
import org.signal.core.util.ThreadUtil
|
||||||
import org.signal.core.util.concurrent.SignalExecutors
|
import org.signal.core.util.concurrent.SignalExecutors
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
|
@ -18,7 +17,7 @@ import org.thoughtcrime.securesms.scribbles.ImageEditorFragment
|
||||||
class PhotoEditorFragment : Fragment(R.layout.avatar_photo_editor_fragment), ImageEditorFragment.Controller {
|
class PhotoEditorFragment : Fragment(R.layout.avatar_photo_editor_fragment), ImageEditorFragment.Controller {
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
val args = PhotoEditorFragmentArgs.fromBundle(requireArguments())
|
val args = PhotoEditorActivityArgs.fromBundle(requireArguments())
|
||||||
val photo = AvatarBundler.extractPhoto(args.photoAvatar)
|
val photo = AvatarBundler.extractPhoto(args.photoAvatar)
|
||||||
val imageEditorFragment = ImageEditorFragment.newInstanceForAvatarEdit(photo.uri)
|
val imageEditorFragment = ImageEditorFragment.newInstanceForAvatarEdit(photo.uri)
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ class PhotoEditorFragment : Fragment(R.layout.avatar_photo_editor_fragment), Ima
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDoneEditing() {
|
override fun onDoneEditing() {
|
||||||
val args = PhotoEditorFragmentArgs.fromBundle(requireArguments())
|
val args = PhotoEditorActivityArgs.fromBundle(requireArguments())
|
||||||
val applicationContext = requireContext().applicationContext
|
val applicationContext = requireContext().applicationContext
|
||||||
val imageEditorFragment: ImageEditorFragment = childFragmentManager.findFragmentByTag(IMAGE_EDITOR) as ImageEditorFragment
|
val imageEditorFragment: ImageEditorFragment = childFragmentManager.findFragmentByTag(IMAGE_EDITOR) as ImageEditorFragment
|
||||||
|
|
||||||
|
@ -52,13 +51,12 @@ class PhotoEditorFragment : Fragment(R.layout.avatar_photo_editor_fragment), Ima
|
||||||
|
|
||||||
ThreadUtil.runOnMain {
|
ThreadUtil.runOnMain {
|
||||||
setFragmentResult(REQUEST_KEY_EDIT, AvatarBundler.bundlePhoto(newPhoto))
|
setFragmentResult(REQUEST_KEY_EDIT, AvatarBundler.bundlePhoto(newPhoto))
|
||||||
Navigation.findNavController(requireView()).popBackStack()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCancelEditing() {
|
override fun onCancelEditing() {
|
||||||
Navigation.findNavController(requireView()).popBackStack()
|
requireActivity().finishAfterTransition()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun restoreState() {
|
override fun restoreState() {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.PopupMenu
|
import android.widget.PopupMenu
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.setFragmentResult
|
import androidx.fragment.app.setFragmentResult
|
||||||
|
@ -20,6 +21,7 @@ import org.signal.core.util.getParcelableExtraCompat
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.avatar.Avatar
|
import org.thoughtcrime.securesms.avatar.Avatar
|
||||||
import org.thoughtcrime.securesms.avatar.AvatarBundler
|
import org.thoughtcrime.securesms.avatar.AvatarBundler
|
||||||
|
import org.thoughtcrime.securesms.avatar.photo.PhotoEditorActivity
|
||||||
import org.thoughtcrime.securesms.avatar.photo.PhotoEditorFragment
|
import org.thoughtcrime.securesms.avatar.photo.PhotoEditorFragment
|
||||||
import org.thoughtcrime.securesms.avatar.text.TextAvatarCreationFragment
|
import org.thoughtcrime.securesms.avatar.text.TextAvatarCreationFragment
|
||||||
import org.thoughtcrime.securesms.avatar.vector.VectorAvatarCreationFragment
|
import org.thoughtcrime.securesms.avatar.vector.VectorAvatarCreationFragment
|
||||||
|
@ -50,6 +52,7 @@ class AvatarPickerFragment : Fragment(R.layout.avatar_picker_fragment) {
|
||||||
private val viewModel: AvatarPickerViewModel by viewModels(factoryProducer = this::createFactory)
|
private val viewModel: AvatarPickerViewModel by viewModels(factoryProducer = this::createFactory)
|
||||||
|
|
||||||
private lateinit var recycler: RecyclerView
|
private lateinit var recycler: RecyclerView
|
||||||
|
private lateinit var photoEditorLauncher: ActivityResultLauncher<Avatar.Photo>
|
||||||
|
|
||||||
private fun createFactory(): AvatarPickerViewModel.Factory {
|
private fun createFactory(): AvatarPickerViewModel.Factory {
|
||||||
val args = AvatarPickerFragmentArgs.fromBundle(requireArguments())
|
val args = AvatarPickerFragmentArgs.fromBundle(requireArguments())
|
||||||
|
@ -138,10 +141,14 @@ class AvatarPickerFragment : Fragment(R.layout.avatar_picker_fragment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
setFragmentResultListener(PhotoEditorFragment.REQUEST_KEY_EDIT) { _, bundle ->
|
setFragmentResultListener(PhotoEditorFragment.REQUEST_KEY_EDIT) { _, bundle ->
|
||||||
val photo = AvatarBundler.extractPhoto(bundle)
|
}
|
||||||
|
|
||||||
|
photoEditorLauncher = registerForActivityResult(PhotoEditorActivity.Contract()) { photo ->
|
||||||
|
if (photo != null) {
|
||||||
viewModel.onAvatarEditCompleted(photo)
|
viewModel.onAvatarEditCompleted(photo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
@ -197,8 +204,7 @@ class AvatarPickerFragment : Fragment(R.layout.avatar_picker_fragment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openPhotoEditor(photo: Avatar.Photo) {
|
private fun openPhotoEditor(photo: Avatar.Photo) {
|
||||||
Navigation.findNavController(requireView())
|
photoEditorLauncher.launch(photo)
|
||||||
.safeNavigate(AvatarPickerFragmentDirections.actionAvatarPickerFragmentToAvatarPhotoEditorFragment(AvatarBundler.bundlePhoto(photo)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openVectorEditor(vector: Avatar.Vector) {
|
private fun openVectorEditor(vector: Avatar.Vector) {
|
||||||
|
|
|
@ -293,6 +293,10 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||||
imageEditorHud.enterMode(ImageEditorHudV2.Mode.CROP);
|
imageEditorHud.enterMode(ImageEditorHudV2.Mode.CROP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mode == Mode.AVATAR_EDIT) {
|
||||||
|
imageEditorHud.enterMode(ImageEditorHudV2.Mode.DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
imageEditorView.setModel(editorModel);
|
imageEditorView.setModel(editorModel);
|
||||||
|
|
||||||
if (!SignalStore.tooltips().hasSeenBlurHudIconTooltip()) {
|
if (!SignalStore.tooltips().hasSeenBlurHudIconTooltip()) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:viewBindingIgnore="true"
|
|
||||||
android:id="@+id/fragment_container"
|
android:id="@+id/fragment_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent"
|
||||||
|
tools:viewBindingIgnore="true" />
|
|
@ -39,18 +39,6 @@
|
||||||
|
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
<action
|
|
||||||
android:id="@+id/action_avatarPickerFragment_to_avatarPhotoEditorFragment"
|
|
||||||
app:destination="@id/avatarPhotoEditorFragment"
|
|
||||||
app:enterAnim="@anim/fragment_open_enter"
|
|
||||||
app:exitAnim="@anim/fragment_open_exit"
|
|
||||||
app:popEnterAnim="@anim/fragment_close_enter"
|
|
||||||
app:popExitAnim="@anim/fragment_close_exit">
|
|
||||||
<argument
|
|
||||||
android:name="photo_avatar"
|
|
||||||
app:argType="android.os.Bundle" />
|
|
||||||
</action>
|
|
||||||
|
|
||||||
<argument
|
<argument
|
||||||
android:name="group_id"
|
android:name="group_id"
|
||||||
app:argType="org.thoughtcrime.securesms.groups.ParcelableGroupId"
|
app:argType="org.thoughtcrime.securesms.groups.ParcelableGroupId"
|
||||||
|
@ -86,13 +74,13 @@
|
||||||
app:nullable="true" />
|
app:nullable="true" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<activity
|
||||||
android:id="@+id/avatarPhotoEditorFragment"
|
android:id="@+id/avatarPhotoEditorActivity"
|
||||||
android:name="org.thoughtcrime.securesms.avatar.photo.PhotoEditorFragment"
|
android:name="org.thoughtcrime.securesms.avatar.photo.PhotoEditorActivity"
|
||||||
android:label="fragment_avatar_photo_editor">
|
android:label="fragment_avatar_photo_editor">
|
||||||
<argument
|
<argument
|
||||||
android:name="photo_avatar"
|
android:name="photo_avatar"
|
||||||
app:argType="android.os.Bundle" />
|
app:argType="android.os.Bundle" />
|
||||||
</fragment>
|
</activity>
|
||||||
|
|
||||||
</navigation>
|
</navigation>
|
Loading…
Add table
Reference in a new issue