diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryFlowDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryFlowDialogFragment.kt index 701a2d42d..1938ec22a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryFlowDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryFlowDialogFragment.kt @@ -6,6 +6,7 @@ import androidx.fragment.app.setFragmentResult import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.stories.settings.select.BaseStoryRecipientSelectionFragment +import org.thoughtcrime.securesms.util.WindowUtil class CreateStoryFlowDialogFragment : DialogFragment(R.layout.create_story_flow_dialog_fragment), BaseStoryRecipientSelectionFragment.Callback, CreateStoryWithViewersFragment.Callback { @@ -27,4 +28,8 @@ class CreateStoryFlowDialogFragment : DialogFragment(R.layout.create_story_flow_ ) dismissAllowingStateLoss() } + + override fun setStatusBarColor(color: Int) { + WindowUtil.setStatusBarColor(requireDialog().window!!, color) + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryWithViewersFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryWithViewersFragment.kt index 4f455b98e..186332ca0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryWithViewersFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/settings/create/CreateStoryWithViewersFragment.kt @@ -2,17 +2,24 @@ package org.thoughtcrime.securesms.stories.settings.create import android.os.Bundle import android.view.View +import androidx.annotation.ColorInt +import androidx.appcompat.widget.Toolbar import androidx.fragment.app.setFragmentResult import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.components.ViewBinderDelegate import org.thoughtcrime.securesms.components.settings.DSLConfiguration import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment import org.thoughtcrime.securesms.components.settings.configure +import org.thoughtcrime.securesms.databinding.StoriesCreateWithRecipientsFragmentBinding import org.thoughtcrime.securesms.recipients.RecipientId +import org.thoughtcrime.securesms.util.Material3OnScrollHelper +import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter import org.thoughtcrime.securesms.util.fragments.findListener +import org.thoughtcrime.securesms.util.fragments.requireListener import org.thoughtcrime.securesms.util.viewholders.RecipientMappingModel import org.thoughtcrime.securesms.util.viewholders.RecipientViewHolder @@ -35,27 +42,48 @@ class CreateStoryWithViewersFragment : DSLSettingsFragment( } ) + private val binding by ViewBinderDelegate(StoriesCreateWithRecipientsFragmentBinding::bind) + private val recipientIds: Array get() = CreateStoryWithViewersFragmentArgs.fromBundle(requireArguments()).recipients override fun bindAdapter(adapter: MappingAdapter) { adapter.registerFactory(RecipientMappingModel.RecipientIdMappingModel::class.java, LayoutFactory({ RecipientViewHolder(it, null) }, R.layout.stories_recipient_item)) - CreateStoryNameFieldItem.register(adapter) { + + binding.create.setOnClickListener { viewModel.create(recipientIds.toSet()) } + + val nameViewHolder = CreateStoryNameFieldItem.ViewHolder(binding.nameField.root) { viewModel.setLabel(it) } - val createButton: View = requireView().findViewById(R.id.create) - createButton.setOnClickListener { viewModel.create(recipientIds.toSet()) } - + adapter.submitList(getConfiguration().toMappingModelList()) viewModel.state.observe(viewLifecycleOwner) { state -> - adapter.submitList(getConfiguration(state).toMappingModelList()) + + val nameModel = CreateStoryNameFieldItem.Model( + body = state.label, + error = presentError(state.error) + ) + + nameViewHolder.bind(nameModel) when (state.saveState) { - CreateStoryWithViewersState.SaveState.Init -> createButton.setCanPress(state.label.isNotEmpty()) - CreateStoryWithViewersState.SaveState.Saving -> createButton.setCanPress(false) + CreateStoryWithViewersState.SaveState.Init -> binding.create.setCanPress(state.label.isNotEmpty()) + CreateStoryWithViewersState.SaveState.Saving -> binding.create.setCanPress(false) is CreateStoryWithViewersState.SaveState.Saved -> onDone(state.saveState.recipientId) } } + + Material3OnScrollHelper(requireContext(), { requireListener().setStatusBarColor(it) }, listOf(binding.toolbar)).attach(binding.appBarLayout) + ViewUtil.focusAndShowKeyboard(binding.nameField.editText) + } + + override fun onPause() { + super.onPause() + ViewUtil.hideKeyboard(requireContext(), binding.nameField.editText) + } + + override fun onToolbarNavigationClicked() { + findNavController().popBackStack() } private fun View.setCanPress(canPress: Boolean) { @@ -63,15 +91,12 @@ class CreateStoryWithViewersFragment : DSLSettingsFragment( alpha = if (canPress) 1f else 0.5f } - private fun getConfiguration(state: CreateStoryWithViewersState): DSLConfiguration { - return configure { - customPref( - CreateStoryNameFieldItem.Model( - body = state.label, - error = presentError(state.error) - ) - ) + override fun getMaterial3OnScrollHelper(toolbar: Toolbar?): Material3OnScrollHelper? { + return null + } + private fun getConfiguration(): DSLConfiguration { + return configure { dividerPref() sectionHeaderPref(R.string.CreateStoryWithViewersFragment__viewers) @@ -106,6 +131,7 @@ class CreateStoryWithViewersFragment : DSLSettingsFragment( } interface Callback { + fun setStatusBarColor(@ColorInt color: Int) fun onDone(recipientId: RecipientId) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/settings/custom/name/EditStoryNameFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/settings/custom/name/EditStoryNameFragment.kt index 7b32d2645..62de406f2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/settings/custom/name/EditStoryNameFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/settings/custom/name/EditStoryNameFragment.kt @@ -68,6 +68,8 @@ class EditStoryNameFragment : Fragment(R.layout.stories_edit_story_name_fragment saveButton.setOnClickListener { onSaveClicked() } + + ViewUtil.focusAndShowKeyboard(storyName) } override fun onPause() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/Material3OnScrollHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/util/Material3OnScrollHelper.kt index 2d842df65..b7254adf5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/Material3OnScrollHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/Material3OnScrollHelper.kt @@ -2,12 +2,14 @@ package org.thoughtcrime.securesms.util import android.animation.ValueAnimator import android.app.Activity +import android.content.Context import android.view.View import androidx.annotation.ColorInt import androidx.annotation.ColorRes import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import com.google.android.material.animation.ArgbEvaluatorCompat +import com.google.android.material.appbar.AppBarLayout import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.util.views.Stub @@ -17,11 +19,18 @@ import org.thoughtcrime.securesms.util.views.Stub * for other purposes. */ open class Material3OnScrollHelper( - private val activity: Activity, + private val context: Context, + private val setStatusBarColor: (Int) -> Unit, private val views: List, private val viewStubs: List> = emptyList() ) { + constructor(activity: Activity, views: List, viewStubs: List>) : this(activity, { WindowUtil.setStatusBarColor(activity.window, it) }, views, viewStubs) + + constructor(activity: Activity, views: List) : this(activity, { WindowUtil.setStatusBarColor(activity.window, it) }, views, emptyList()) + + constructor(activity: Activity, view: View) : this(activity, { WindowUtil.setStatusBarColor(activity.window, it) }, listOf(view), emptyList()) + /** * A pair of colors tied to a specific state. */ @@ -35,15 +44,23 @@ open class Material3OnScrollHelper( open val activeColorSet: ColorSet = ColorSet(R.color.signal_colorSurface2) open val inactiveColorSet: ColorSet = ColorSet(R.color.signal_colorBackground) - constructor(activity: Activity, view: View) : this(activity, listOf(view), emptyList()) - private var animator: ValueAnimator? = null private var active: Boolean? = null - private val scrollListener = OnScrollListener() fun attach(recyclerView: RecyclerView) { - recyclerView.addOnScrollListener(scrollListener) - scrollListener.onScrolled(recyclerView, 0, 0) + recyclerView.addOnScrollListener( + OnScrollListener().apply { + onScrolled(recyclerView, 0, 0) + } + ) + } + + fun attach(appBarLayout: AppBarLayout) { + appBarLayout.addOnOffsetChangedListener( + OnOffsetChangedListener().apply { + onOffsetChanged(appBarLayout, 0) + } + ) } /** @@ -56,8 +73,8 @@ open class Material3OnScrollHelper( animator?.cancel() val colorSet = if (active == true) activeColorSet else inactiveColorSet - setToolbarColor(ContextCompat.getColor(activity, colorSet.toolbarColorRes)) - setStatusBarColor(ContextCompat.getColor(activity, colorSet.statusBarColorRes)) + setToolbarColor(ContextCompat.getColor(context, colorSet.toolbarColorRes)) + setStatusBarColor(ContextCompat.getColor(context, colorSet.statusBarColorRes)) } private fun updateActiveState(isActive: Boolean) { @@ -78,10 +95,10 @@ open class Material3OnScrollHelper( val endColorSet = if (isActive) activeColorSet else inactiveColorSet if (hadActiveState) { - val startToolbarColor = ContextCompat.getColor(activity, startColorSet.toolbarColorRes) - val endToolbarColor = ContextCompat.getColor(activity, endColorSet.toolbarColorRes) - val startStatusBarColor = ContextCompat.getColor(activity, startColorSet.statusBarColorRes) - val endStatusBarColor = ContextCompat.getColor(activity, endColorSet.statusBarColorRes) + val startToolbarColor = ContextCompat.getColor(context, startColorSet.toolbarColorRes) + val endToolbarColor = ContextCompat.getColor(context, endColorSet.toolbarColorRes) + val startStatusBarColor = ContextCompat.getColor(context, startColorSet.statusBarColorRes) + val endStatusBarColor = ContextCompat.getColor(context, endColorSet.statusBarColorRes) animator = ValueAnimator.ofFloat(0f, 1f).apply { duration = 200 @@ -102,13 +119,15 @@ open class Material3OnScrollHelper( viewStubs.filter { it.resolved() }.forEach { it.get().setBackgroundColor(color) } } - private fun setStatusBarColor(@ColorInt color: Int) { - WindowUtil.setStatusBarColor(activity.window, color) - } - private inner class OnScrollListener : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { updateActiveState(recyclerView.canScrollVertically(-1)) } } + + private inner class OnOffsetChangedListener : AppBarLayout.OnOffsetChangedListener { + override fun onOffsetChanged(appBarLayout: AppBarLayout, verticalOffset: Int) { + updateActiveState(verticalOffset != 0) + } + } } diff --git a/app/src/main/res/layout/dsl_settings_toolbar.xml b/app/src/main/res/layout/dsl_settings_toolbar.xml index 00342db82..38493bfde 100644 --- a/app/src/main/res/layout/dsl_settings_toolbar.xml +++ b/app/src/main/res/layout/dsl_settings_toolbar.xml @@ -1,7 +1,6 @@ diff --git a/app/src/main/res/layout/stories_create_story_name_field_item.xml b/app/src/main/res/layout/stories_create_story_name_field_item.xml index c73a80973..30862e6b6 100644 --- a/app/src/main/res/layout/stories_create_story_name_field_item.xml +++ b/app/src/main/res/layout/stories_create_story_name_field_item.xml @@ -1,7 +1,5 @@ - + android:layout_height="match_parent" + android:orientation="vertical"> - - - + app:layout_constraintTop_toTopOf="parent" + app:navigationContentDescription="@string/DSLSettingsToolbar__navigate_up" + app:navigationIcon="@drawable/ic_arrow_left_24" + app:titleTextAppearance="@style/Signal.Text.TitleLarge" + tools:title="Settings" /> - - \ No newline at end of file + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/stories_multiselect_forward_activity.xml b/app/src/main/res/layout/stories_multiselect_forward_activity.xml index a7b001109..bcddd24b3 100644 --- a/app/src/main/res/layout/stories_multiselect_forward_activity.xml +++ b/app/src/main/res/layout/stories_multiselect_forward_activity.xml @@ -5,8 +5,7 @@ android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" - tools:viewBindingIgnore="true"> + android:orientation="vertical">