From 93d0982a6fe947a560299e21a7614b52e1f487f0 Mon Sep 17 00:00:00 2001 From: Sawyer Blatz Date: Mon, 20 May 2019 13:34:58 -0700 Subject: [PATCH] For #1576: Adds tab collection renaming --- .../CollectionCreationComponent.kt | 11 ++- .../collections/CollectionCreationUIView.kt | 74 +++++++++++++++++-- .../collections/CreateCollectionFragment.kt | 22 +++++- .../collections/CreateCollectionViewModel.kt | 1 + .../org/mozilla/fenix/home/HomeFragment.kt | 14 +++- app/src/main/res/values/strings.xml | 2 + 6 files changed, 112 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationComponent.kt b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationComponent.kt index c3ab1236a..5922fc376 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationComponent.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationComponent.kt @@ -22,13 +22,15 @@ sealed class SaveCollectionStep { object SelectTabs : SaveCollectionStep() object SelectCollection : SaveCollectionStep() object NameCollection : SaveCollectionStep() + object RenameCollection : SaveCollectionStep() } data class CollectionCreationState( val tabs: List = listOf(), val selectedTabs: Set = setOf(), val saveCollectionStep: SaveCollectionStep = SaveCollectionStep.SelectTabs, - val tabCollections: List = listOf() + val tabCollections: List = listOf(), + val selectedTabCollection: TabCollection? ) : ViewState sealed class CollectionCreationChange : Change { @@ -37,6 +39,7 @@ sealed class CollectionCreationChange : Change { data class TabAdded(val tab: Tab) : CollectionCreationChange() data class TabRemoved(val tab: Tab) : CollectionCreationChange() data class StepChanged(val saveCollectionStep: SaveCollectionStep) : CollectionCreationChange() + data class CollectionSelected(val collection: TabCollection) : CollectionCreationChange() } sealed class CollectionCreationAction : Action { @@ -49,7 +52,8 @@ sealed class CollectionCreationAction : Action { data class BackPressed(val backPressFrom: SaveCollectionStep) : CollectionCreationAction() data class SaveCollectionName(val tabs: List, val name: String) : CollectionCreationAction() - + data class RenameCollection(val collection: TabCollection, val name: String) : + CollectionCreationAction() data class SelectCollection(val collection: TabCollection) : CollectionCreationAction() } @@ -103,6 +107,9 @@ class CollectionCreationViewModel( is CollectionCreationChange.StepChanged -> { state.copy(saveCollectionStep = change.saveCollectionStep) } + is CollectionCreationChange.CollectionSelected -> { + state.copy(selectedTabCollection = change.collection) + } } } } diff --git a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationUIView.kt b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationUIView.kt index d7c418b56..3964851bb 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationUIView.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationUIView.kt @@ -21,11 +21,14 @@ import io.reactivex.Observer import io.reactivex.functions.Consumer import kotlinx.android.synthetic.main.component_collection_creation.* import kotlinx.android.synthetic.main.component_collection_creation.view.* +import kotlinx.android.synthetic.main.sign_in_preference.* import mozilla.components.support.ktx.android.view.hideKeyboard import mozilla.components.support.ktx.android.view.showKeyboard import org.mozilla.fenix.R import org.mozilla.fenix.ext.increaseTapArea +import org.mozilla.fenix.ext.urlToTrimmedHost import org.mozilla.fenix.home.sessioncontrol.Tab +import org.mozilla.fenix.home.sessioncontrol.TabCollection import org.mozilla.fenix.mvi.UIView class CollectionCreationUIView( @@ -45,6 +48,7 @@ class CollectionCreationUIView( private val collectionCreationTabListAdapter = CollectionCreationTabListAdapter(actionEmitter) private val collectionSaveListAdapter = SaveCollectionListAdapter(actionEmitter) + private var selectedCollection: TabCollection? = null private var selectedTabs: Set = setOf() private val selectTabsConstraints = ConstraintSet() private val selectCollectionConstraints = ConstraintSet() @@ -77,12 +81,21 @@ class CollectionCreationUIView( view.name_collection_edittext.setOnEditorActionListener { v, actionId, event -> if (actionId == EditorInfo.IME_ACTION_DONE && !v.text.toString().isEmpty()) { - actionEmitter.onNext( - CollectionCreationAction.SaveCollectionName( - selectedTabs.toList(), - v.text.toString() - ) - ) + when (step) { + is SaveCollectionStep.NameCollection -> { + actionEmitter.onNext( + CollectionCreationAction.SaveCollectionName( + selectedTabs.toList(), + v.text.toString() + ) + ) + } + is SaveCollectionStep.RenameCollection -> { + selectedCollection?.let { + actionEmitter.onNext(CollectionCreationAction.RenameCollection(it, v.text.toString())) + } + } + } } false } @@ -197,6 +210,52 @@ class CollectionCreationUIView( back_button.text = view.context.getString(R.string.create_collection_name_collection) } + is SaveCollectionStep.RenameCollection -> { + it.selectedTabCollection?.let { tabCollection -> + selectedCollection = tabCollection + tabCollection.tabs.map { tab -> + Tab( + tab.id.toString(), + tab.url, + tab.url.urlToTrimmedHost(), + tab.title + ) + }.let { tabs -> + collectionCreationTabListAdapter.updateData(tabs, setOf(), true) + } + } + + back_button.setOnClickListener { + name_collection_edittext.hideKeyboard() + val handler = Handler() + handler.postDelayed({ + actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.RenameCollection)) + }, TRANSITION_DURATION) + } + transition.addListener(object : Transition.TransitionListener { + override fun onTransitionStart(transition: Transition) { + } + + override fun onTransitionEnd(transition: Transition) { + view.name_collection_edittext.showKeyboard() + transition.removeListener(this) + } + + override fun onTransitionCancel(transition: Transition) {} + override fun onTransitionPause(transition: Transition) {} + override fun onTransitionResume(transition: Transition) {} + }) + TransitionManager.beginDelayedTransition( + view.collection_constraint_layout, + transition + ) + val constraint = nameCollectionConstraints + constraint.applyTo(view.collection_constraint_layout) + name_collection_edittext.setText(it.selectedTabCollection?.title) + name_collection_edittext.setSelection(0, name_collection_edittext.text.length) + back_button.text = + view.context.getString(R.string.create_collection_name_collection) + } } collectionSaveListAdapter.reloadData(it.tabCollections) @@ -220,6 +279,9 @@ class CollectionCreationUIView( SaveCollectionStep.NameCollection -> { actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.NameCollection)) } + SaveCollectionStep.RenameCollection -> { + actionEmitter.onNext(CollectionCreationAction.BackPressed(SaveCollectionStep.RenameCollection)) + } } return true } else { diff --git a/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionFragment.kt b/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionFragment.kt index e855feba2..9040c09bc 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionFragment.kt @@ -66,7 +66,8 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope { viewModel.tabs, viewModel.selectedTabs, viewModel.saveCollectionStep, - viewModel.tabCollections + viewModel.tabCollections, + viewModel.selectedTabCollection )) } ) @@ -138,6 +139,24 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope { } } } + is CollectionCreationAction.RenameCollection -> { + showRenamedSnackbar() + dismiss() + launch(Dispatchers.IO) { + requireComponents.core.tabCollectionStorage.renameCollection(it.collection, it.name) + } + } + } + } + } + + private fun showRenamedSnackbar() { + context?.let { context: Context -> + val rootView = context.getRootView() + rootView?.let { view: View -> + val string = context.getString(R.string.snackbar_collection_renamed) + FenixSnackbar.make(view, Snackbar.LENGTH_LONG).setText(string) + .show() } } } @@ -166,6 +185,7 @@ class CreateCollectionFragment : DialogFragment(), CoroutineScope { CollectionCreationChange.StepChanged(SaveCollectionStep.SelectCollection) ) } + SaveCollectionStep.RenameCollection -> { dismiss() } } } } diff --git a/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionViewModel.kt b/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionViewModel.kt index 9d480e9d0..fb14a2da7 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionViewModel.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CreateCollectionViewModel.kt @@ -13,4 +13,5 @@ class CreateCollectionViewModel : ViewModel() { var tabs = listOf() var saveCollectionStep: SaveCollectionStep = SaveCollectionStep.SelectTabs var tabCollections = listOf() + var selectedTabCollection: TabCollection? = null } diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 17ebb63a7..9ba1290a9 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -351,7 +351,10 @@ class HomeFragment : Fragment(), CoroutineScope { ItsNotBrokenSnack(context!!).showSnackbar(issueNumber = "1575") } is CollectionAction.Rename -> { - ItsNotBrokenSnack(context!!).showSnackbar(issueNumber = "1575") + showCollectionCreationFragment( + selectedTabCollection = action.collection, + step = SaveCollectionStep.RenameCollection + ) } is CollectionAction.OpenTab -> { invokePendingDeleteSessionJob() @@ -546,7 +549,11 @@ class HomeFragment : Fragment(), CoroutineScope { ) } - private fun showCollectionCreationFragment(selectedTabId: String?) { + private fun showCollectionCreationFragment( + selectedTabId: String? = null, + selectedTabCollection: TabCollection? = null, + step: SaveCollectionStep = SaveCollectionStep.SelectTabs + ) { val tabs = requireComponents.core.sessionManager.sessions.filter { !it.private } .map { Tab(it.id, it.url, it.url.urlToTrimmedHost(), it.title) } @@ -557,8 +564,9 @@ class HomeFragment : Fragment(), CoroutineScope { val selectedTabs = tabs.find { tab -> tab.sessionId == selectedTabId } val selectedSet = if (selectedTabs == null) mutableSetOf() else mutableSetOf(selectedTabs) viewModel?.selectedTabs = selectedSet - viewModel?.saveCollectionStep = SaveCollectionStep.SelectTabs + viewModel?.saveCollectionStep = step viewModel?.tabCollections = requireComponents.core.tabCollectionStorage.cachedTabCollections.reversed() + viewModel?.selectedTabCollection = selectedTabCollection view?.let { val directions = HomeFragmentDirections.actionHomeFragmentToCreateCollectionFragment() diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b03bf1ea2..8b1dc5449 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -478,6 +478,8 @@ Collection deleted + + Collection renamed Tab deleted