1
0
Fork 0
fenix/app/src/main/java/org/mozilla/fenix/settings/logins/SavedLoginsFragmentStore.kt

147 lines
5.0 KiB
Kotlin

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.settings.logins
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
import mozilla.components.lib.state.Action
import mozilla.components.lib.state.State
import mozilla.components.lib.state.Store
/**
* Class representing an saved logins item
* @property url Site of the saved login
* @property userName Username that's saved for this site
* @property password Password that's saved for this site
* @property id The unique identifier for this login entry
* @property timeLastUsed Time of last use in milliseconds from the unix epoch.
*/
@Parcelize
data class SavedLoginsItem(
val url: String,
val userName: String?,
val password: String?,
val id: String,
val timeLastUsed: Long
) :
Parcelable
/**
* The [Store] for holding the [SavedLoginsFragmentState] and applying [SavedLoginsFragmentAction]s.
*/
class SavedLoginsFragmentStore(initialState: SavedLoginsFragmentState) :
Store<SavedLoginsFragmentState, SavedLoginsFragmentAction>(
initialState,
::savedLoginsStateReducer
)
/**
* Actions to dispatch through the `SavedLoginsStore` to modify `SavedLoginsFragmentState` through the reducer.
*/
sealed class SavedLoginsFragmentAction : Action {
data class FilterLogins(val newText: String?) : SavedLoginsFragmentAction()
data class UpdateLogins(val list: List<SavedLoginsItem>) : SavedLoginsFragmentAction()
data class SortLogins(val sortingStrategy: SortingStrategy) : SavedLoginsFragmentAction()
}
/**
* The state for the Saved Logins Screen
* @property isLoading State to know when to show loading
* @property items Source of truth of list of logins
* @property filteredItems Filtered (or not) list of logins to display
* @property searchedForText String used by the user to filter logins
* @property sortingStrategy sorting strategy selected by the user (Currently we support
* sorting alphabetically and by last used)
*/
data class SavedLoginsFragmentState(
val isLoading: Boolean = false,
val items: List<SavedLoginsItem>,
val filteredItems: List<SavedLoginsItem>,
val searchedForText: String?,
val sortingStrategy: SortingStrategy,
val highlightedItem: SavedLoginsSortingStrategyMenu.Item
) : State
/**
* The SavedLoginsState Reducer.
*/
private fun savedLoginsStateReducer(
state: SavedLoginsFragmentState,
action: SavedLoginsFragmentAction
): SavedLoginsFragmentState {
return when (action) {
is SavedLoginsFragmentAction.UpdateLogins -> {
filterItems(
state.searchedForText, state.sortingStrategy, state.copy(
isLoading = false,
items = action.list,
filteredItems = emptyList()
)
)
}
is SavedLoginsFragmentAction.FilterLogins ->
filterItems(
action.newText,
state.sortingStrategy,
state
)
is SavedLoginsFragmentAction.SortLogins ->
filterItems(
state.searchedForText,
action.sortingStrategy,
state
)
}
}
/**
* @return [SavedLoginsFragmentState] containing a new [SavedLoginsFragmentState.filteredItems]
* with filtered [SavedLoginsFragmentState.items]
*
* @param searchedForText based on which [SavedLoginsFragmentState.items] will be filtered.
* @param sortingStrategy based on which [SavedLoginsFragmentState.items] will be sorted.
* @param state previous [SavedLoginsFragmentState] containing all the other properties
* with which a new state will be created
*/
private fun filterItems(
searchedForText: String?,
sortingStrategy: SortingStrategy,
state: SavedLoginsFragmentState
): SavedLoginsFragmentState {
return if (searchedForText.isNullOrBlank()) {
state.copy(
isLoading = false,
sortingStrategy = sortingStrategy,
highlightedItem = sortingStrategyToMenuItem(sortingStrategy),
searchedForText = searchedForText,
filteredItems = sortingStrategy(state.items)
)
} else {
state.copy(
isLoading = false,
sortingStrategy = sortingStrategy,
highlightedItem = sortingStrategyToMenuItem(sortingStrategy),
searchedForText = searchedForText,
filteredItems = sortingStrategy(state.items).filter {
it.url.contains(
searchedForText
)
}
)
}
}
private fun sortingStrategyToMenuItem(sortingStrategy: SortingStrategy): SavedLoginsSortingStrategyMenu.Item {
return when (sortingStrategy) {
is SortingStrategy.Alphabetically -> {
SavedLoginsSortingStrategyMenu.Item.AlphabeticallySort
}
is SortingStrategy.LastUsed -> {
SavedLoginsSortingStrategyMenu.Item.LastUsedSort
}
}
}