Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mobileapps 888 #40

Merged
merged 4 commits into from
Oct 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import com.alfresco.content.fragmentViewModelWithArgs
import com.alfresco.content.getLocalizedName
import com.alfresco.content.hideSoftInput
import com.alfresco.content.models.CategoriesItem
import com.alfresco.content.search.components.ComponentBuilder
import com.alfresco.content.search.components.ComponentMetaData
import com.alfresco.content.search.components.CreateComponentsSheet
import com.alfresco.content.search.databinding.FragmentSearchBinding
import com.alfresco.content.simpleController
import kotlin.coroutines.Continuation
Expand Down Expand Up @@ -328,20 +328,14 @@ class SearchFragment : Fragment(), MavericksView {
if (data.selectedName.isNotEmpty()) {
(chipView as FilterChip).isChecked = true
}
when (data.category.component?.selector) {
ChipComponentType.TEXT.component -> {
viewLifecycleOwner.lifecycleScope.launch {
val result = showComponentSheetDialog(requireContext(), data)
Logger.d("component result = ", result)
if (result != null) {
viewModel.updateChipName(state, data, result.name)
} else {
val isSelected = data.selectedName.isNotEmpty()
viewModel.updateSelected(state, data, isSelected)
}
}
}
else -> {
viewLifecycleOwner.lifecycleScope.launch {
val result = showComponentSheetDialog(requireContext(), data)
Logger.d("component result = ", result)
if (result != null) {
viewModel.updateChipComponentResult(state, data, result)
} else {
val isSelected = data.selectedName.isNotEmpty()
viewModel.updateSelected(state, data, isSelected)
}
}
}
Expand All @@ -353,7 +347,7 @@ class SearchFragment : Fragment(), MavericksView {
searchChipCategory: SearchChipCategory
) = withContext(Dispatchers.Main) {
suspendCoroutine<ComponentMetaData?> {
CreateComponentsSheet.Builder(context, searchChipCategory)
ComponentBuilder(context, searchChipCategory)
.onApply { name, query ->
executeContinuation(it, name, query)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.alfresco.content.listview.ListViewModel
import com.alfresco.content.listview.ListViewState
import com.alfresco.content.models.AppConfigModel
import com.alfresco.content.models.SearchItem
import com.alfresco.content.search.components.ComponentMetaData
import java.util.concurrent.CancellationException
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
Expand Down Expand Up @@ -203,17 +204,19 @@ class SearchViewModel(
}

/**
* update chip name after apply or reset the component
* update chip component data after apply or reset the component
*/
fun updateChipName(state: SearchResultsState, model: SearchChipCategory, name: String) {
fun updateChipComponentResult(state: SearchResultsState, model: SearchChipCategory, metaData: ComponentMetaData) {
val list = mutableListOf<SearchChipCategory>()

state.listSearchCategoryChips?.forEachIndexed { index, obj ->
state.listSearchCategoryChips?.forEach { obj ->
if (obj == model) {
list.add(
SearchChipCategory(
obj.category,
isSelected = name.isNotEmpty(), selectedName = name, selectedQuery = obj.selectedQuery
isSelected = metaData.name.isNotEmpty(),
selectedName = metaData.name,
selectedQuery = metaData.query
)
)
} else
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.alfresco.content.search.components

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import com.airbnb.mvrx.Mavericks
import com.alfresco.content.search.SearchChipCategory

internal typealias ComponentApplyCallback = (String, String) -> Unit
internal typealias ComponentResetCallback = (String, String) -> Unit
internal typealias ComponentCancelCallback = () -> Unit

/**
* Builder for build the component sheet
*/
data class ComponentBuilder(
val context: Context,
val searchChipCategory: SearchChipCategory,
var onApply: ComponentApplyCallback? = null,
var onReset: ComponentResetCallback? = null,
var onCancel: ComponentCancelCallback? = null
) {

/**
* Component sheet apply callback
*/
fun onApply(callback: ComponentApplyCallback?) =
apply { this.onApply = callback }

/**
* Component sheet reset callback
*/
fun onReset(callback: ComponentResetCallback?) =
apply { this.onReset = callback }

/**
* Component sheet cancel callback
*/
fun onCancel(callback: ComponentCancelCallback?) =
apply { this.onCancel = callback }

/**
* Component sheet show method
*/
fun show() {
val fragmentManager = when (context) {
is AppCompatActivity -> context.supportFragmentManager
is Fragment -> context.childFragmentManager
else -> throw IllegalArgumentException()
}
CreateComponentsSheet().apply {
arguments = bundleOf(Mavericks.KEY_ARG to searchChipCategory)
onApply = [email protected]
onReset = [email protected]
onCancel = [email protected]
}.show(fragmentManager, CreateComponentsSheet::class.java.simpleName)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,98 @@ package com.alfresco.content.search.components

import android.content.Context
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import com.airbnb.mvrx.Mavericks
import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.MavericksView
import com.airbnb.mvrx.MavericksViewModel
import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.ViewModelContext
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import com.alfresco.content.models.Options
import com.alfresco.content.search.ChipComponentType
import com.alfresco.content.search.R
import com.alfresco.content.search.SearchChipCategory
import com.alfresco.content.search.databinding.SheetComponentCreateBinding
import com.alfresco.ui.BottomSheetDialogFragment

internal data class ComponentCreateState(val parent: SearchChipCategory) : MavericksState
internal data class ComponentCreateState(
val parent: SearchChipCategory
) : MavericksState

internal class ComponentCreateViewModel(
val context: Context,
stateChipCreate: ComponentCreateState
) : MavericksViewModel<ComponentCreateState>(stateChipCreate) {

private var listOptionsData: MutableList<ComponentMetaData> = mutableListOf()

fun buildCheckListModel() = withState { state ->

if (state.parent.selectedQuery.isNotEmpty()) {
if (state.parent.selectedQuery.contains(",")) {
val arrayQuery = state.parent.selectedQuery.split(",")
val arrayName = state.parent.selectedName.split(",")

arrayQuery.forEachIndexed { index, query ->
listOptionsData.add(ComponentMetaData(arrayName[index], query))
}
} else {
listOptionsData.add(ComponentMetaData(state.parent.selectedName, state.parent.selectedQuery))
}
}
}

fun updateTextComponentData(name: String) = withState { state ->
val obj = SearchChipCategory(
category = state.parent.category,
isSelected = state.parent.isSelected,
selectedName = name,
selectedQuery = state.parent.category.component?.settings?.field ?: ""
)

setState { copy(parent = obj) }
}

fun updateComponentData(name: String, query: String) = withState { state ->

if (listOptionsData.find { it.query == query } == null) {
listOptionsData.add(ComponentMetaData(name, query))
} else {
val list = listOptionsData.filter { it.query != query }.toMutableList()
listOptionsData = list
}

val selectedName = listOptionsData.joinToString(",") { it.name }
val selectedQuery = listOptionsData.joinToString(",") { it.query }

val obj = SearchChipCategory(
category = state.parent.category,
isSelected = state.parent.isSelected,
selectedName = selectedName,
selectedQuery = selectedQuery
)

setState { copy(parent = obj) }
}

fun isOptionSelected(state: ComponentCreateState, options: Options): Boolean {
val selectedQuery = state.parent.selectedQuery
if (selectedQuery.contains(",")) {
selectedQuery.split(",").forEach { query ->
if (query == options.value)
return true
}
} else {
return selectedQuery == options.value
}
return false
}

companion object : MavericksViewModelFactory<ComponentCreateViewModel, ComponentCreateState> {
override fun create(
viewModelContext: ViewModelContext,
Expand All @@ -37,10 +102,6 @@ internal class ComponentCreateViewModel(
}
}

internal typealias ComponentApplyCallback = (String, String) -> Unit
internal typealias ComponentResetCallback = (String, String) -> Unit
internal typealias ComponentCancelCallback = () -> Unit

/**
* Component sheet for chip components
*/
Expand All @@ -67,81 +128,76 @@ class CreateComponentsSheet : BottomSheetDialogFragment(), MavericksView {
dialog?.setOnCancelListener {
onCancel?.invoke()
}
setupComponents()
setListeners()
}

private fun setupComponents() {
withState(viewModel) { state ->
if (state.parent.category.component?.selector == ChipComponentType.TEXT.component) {
binding.textComponent.nameInputLayout.hint = state.parent.category.component?.settings?.placeholder
binding.textComponent.nameInput.setText(state.parent.selectedName)
binding.title.text = getString(R.string.title_text_filter)
when (state.parent.category.component?.selector) {
ChipComponentType.TEXT.component -> {
binding.textComponent.componentParent.visibility = View.VISIBLE
binding.textComponent.nameInputLayout.hint = state.parent.category.component?.settings?.placeholder
binding.textComponent.nameInput.setText(state.parent.selectedName)
binding.title.text = getString(R.string.title_text_filter)
}
ChipComponentType.CHECK_LIST.component -> {
viewModel.buildCheckListModel()
binding.checkListComponent.componentParent.visibility = View.VISIBLE
binding.title.text = getString(R.string.title_file_type)
}
}
}
}

private fun setListeners() {
binding.applyButton.setOnClickListener {
withState(viewModel) { state ->
val query = state.parent.category.component?.settings?.field ?: ""
onApply?.invoke(binding.textComponent.nameInput.text.toString(), query)
onApply?.invoke(state.parent.selectedName, state.parent.selectedQuery)
dismiss()
}
}
binding.resetButton.setOnClickListener {
println("CreateComponentsSheet.onViewCreated resetButton")
onReset?.invoke("", "")
dismiss()
}
binding.cancelButton.setOnClickListener {
println("CreateComponentsSheet.onViewCreated cancelButton")
onCancel?.invoke()
dismiss()
}

binding.textComponent.nameInputLayout.editText?.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
// no-op
}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
// no-op
}

override fun afterTextChanged(s: Editable?) {
viewModel.updateTextComponentData(s.toString())
}
})
}

override fun invalidate() = withState(viewModel) { state ->
}

/**
* Builder for build the component sheet
*/
data class Builder(
val context: Context,
val searchChipCategory: SearchChipCategory,
var onApply: ComponentApplyCallback? = null,
var onReset: ComponentResetCallback? = null,
var onCancel: ComponentCancelCallback? = null
) {

/**
* Component sheet apply callback
*/
fun onApply(callback: ComponentApplyCallback?) =
apply { this.onApply = callback }

/**
* Component sheet reset callback
*/
fun onReset(callback: ComponentResetCallback?) =
apply { this.onReset = callback }

/**
* Component sheet cancel callback
*/
fun onCancel(callback: ComponentCancelCallback?) =
apply { this.onCancel = callback }

/**
* Component sheet show method
*/
fun show() {
val fragmentManager = when (context) {
is AppCompatActivity -> context.supportFragmentManager
is Fragment -> context.childFragmentManager
else -> throw IllegalArgumentException()
}
CreateComponentsSheet().apply {
arguments = bundleOf(Mavericks.KEY_ARG to searchChipCategory)
onApply = [email protected]
onReset = [email protected]
onCancel = [email protected]
}.show(fragmentManager, CreateComponentsSheet::class.java.simpleName)
binding.checkListComponent.recyclerView.withModels {
state.parent.category
.component?.settings?.options?.forEach { option ->
listViewCheckRow {
id(option.hashCode())
data(option)
optionSelected(viewModel.isOptionSelected(state, option))
clickListener { model, _, _, _ ->
viewModel.updateComponentData(
model.data().name ?: "",
model.data().value ?: ""
)
}
}
}
}
}
}
Loading