Skip to content

Instantly share code, notes, and snippets.

@mig15
Created July 19, 2019 11:27
Show Gist options
  • Save mig15/1fcb99c037200ab1f04c424a5ce2a4e8 to your computer and use it in GitHub Desktop.
Save mig15/1fcb99c037200ab1f04c424a5ce2a4e8 to your computer and use it in GitHub Desktop.
package direct.farm.android.view.fragments.org_search.vm
import direct.farm.android.ext.*
import direct.farm.android.facade.AuthUserFacade
import direct.farm.android.facade.OrganisationFacade
import direct.farm.android.facade.SearchOrganisationFacade
import direct.farm.android.facade.hr.HumanResourcesFacade
import direct.farm.android.facade.org_parners.OrgPartnersFacade
import direct.farm.android.facade.private_office.FacadePrivateOffice
import direct.farm.android.facade.search.SearchPeopleFacade
import direct.farm.android.model.datasource.hr.JoinState
import direct.farm.android.model.loading
import direct.farm.android.model.rest.responses.SearchOrganisationResponse
import direct.farm.android.utils.logcat
import direct.farm.android.view.ActivityController
import direct.farm.android.view.FragmentNavigator
import direct.farm.android.view.adapters.single_recycler_adapter.DataType
import direct.farm.android.view.facade.InputDialogViewFacade
import direct.farm.android.view.fragments.org_search.org_search_adapter_item.OrgSearchAdapterItemVM
import direct.farm.android.view.fragments.org_search.people_adapter_item.PeopleItem
import direct.farm.android.view.fragments.org_search.vm.base.SearchVM
import direct.farm.android.view.fragments.org_profile.MyOrganisationFragment
import direct.farm.android.view.fragments.org_profile.OrganisationFragment
import direct.farm.android.view.fragments.org_profile.similar_companies.adapter_item.CardState
import direct.farm.android.view.fragments.profile.physical_profile.FragmentAlienPhysicalProfile
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.ConflatedBroadcastChannel
import kotlinx.coroutines.channels.ReceiveChannel
import java.lang.Exception
class SearchVMImpl(private val scope: CoroutineScope,
private val searchOrganisationFacade: SearchOrganisationFacade,
private val peopleFacade: SearchPeopleFacade,
private val organisationFacade: OrganisationFacade,
private val activityController: ActivityController,
private val userFacade: AuthUserFacade,
private val navigator: FragmentNavigator,
private val inputDialogViewFacade: InputDialogViewFacade,
private val orgPartnersFacade: OrgPartnersFacade,
private val humanResourcesFacade: HumanResourcesFacade,
private val privateOfficeFacade: FacadePrivateOffice) : SearchVM {
private var jobOrg: Job? = null
private var jobMen: Job? = null
private val peopleChanel = ConflatedBroadcastChannel<List<DataType>>()
private val totalCountChanel = ConflatedBroadcastChannel<Int>()
override val adapterItems = ChannelDataMutexConflated(listOf<DataType>())
override val textFilter: SuspendDataMutable<String?>
get() = searchOrganisationFacade.textFilter
override val peopleAdapterItems: ReceiveChannel<List<DataType>>
get() = peopleChanel.openSubscription()
override val totalCount: ReceiveChannel<Int>
get() = totalCountChanel.openSubscription()
override suspend fun loadFirstPage() {
try {
searchOrganisationFacade.loadFirstPage()
} catch (e: Exception) {
logcat("Exception $e")
}
}
override suspend fun loadNextPage() {
adapterItems.withLock {
set(get().plus(searchOrganisationFacade.loadNextPage().buildVMList()))
}
}
override suspend fun loadFirstPeoplePage() {
scope.launch {
try {
loading {
peopleFacade.loadFirstPage()
}
} catch (t: Throwable) {
activityController.showErrorDialog(t)
}
}
}
override suspend fun loadNextPeoplePage() {
scope.launch {
try {
loading {
peopleFacade.loadNextPage()
}
} catch (t: Throwable) {
activityController.showErrorDialog(t)
}
}
}
override fun applyFilter(search: String) {
scope.launch {
peopleFacade.setTextFilter(search)
}
}
override fun setTab(pos: Int) {
scope.launch {
peopleFacade.clickTab.set(pos)
}
}
private suspend fun List<SearchOrganisationResponse.Organisation>.buildVMList(): List<DataType> = withContext(Dispatchers.IO) {
return@withContext mapNotNull { org ->
OrgSearchAdapterItemVM(
id = org.id ?: return@mapNotNull null,
name = org.name ?: "no name",
address = org.geoAddress ?: "Не указан",
avatarUrl = org.avatar?.fullPath
).apply {
cardState = orgPartnersFacade.cardState.map {
it[id] ?: CardState.findByAlias(org.cardState)
}
clickAcceptButton = {
scope.launch(Dispatchers.Main) {
runCatching {
when (cardState?.get()) {
CardState.NULL -> {
val comment = inputDialogViewFacade.showMultilineInputTextDialog(
title = "Отправить визитку организации \"${org.name}\"?",
text = "",
hint = "Введите текст сообщения"
)
loading { orgPartnersFacade.sendCard(org.id!!, comment) }
}
CardState.AWAIT_IN -> {
loading { orgPartnersFacade.acceptCard(org.id!!) }
}
else -> {
loading { orgPartnersFacade.delCard(org.id!!) }
}
}
}.exceptionOrNull()?.showAlertDialog(activityController)
}
}
clickCancelButton = {
scope.launch(Dispatchers.Main) {
loading {
runCatching {
orgPartnersFacade.delCard(org.id)
}.exceptionOrNull()?.showAlertDialog(activityController)
}
}
}
clickListener = {
scope.launch {
loading {
runCatching {
val myOrgId = userFacade.currentUser.get()?.organisation?.id
if (org.id != myOrgId) {
OrganisationFragment.preparation(org.id, organisationFacade)
navigator.add(OrganisationFragment::class.java)
} else {
navigator.add(MyOrganisationFragment::class.java)
}
}.exceptionOrNull()?.showAlertDialog(activityController)
}
}
}
}
}
}
init {
scope.launch {
loading {
runCatching {
jobOrg?.cancel()
jobOrg = searchOrganisationFacade.searchOrganisationList.channel().subscribe(scope) {
logcat("Sub to org in VM")
val list = it?.list ?: emptyList()
adapterItems.set(list.buildVMList())
totalCountChanel.send(it?.totalItems!!)
}
jobMen?.cancel()
jobMen = peopleFacade.searchPeopleList.channel().subscribe(scope) {
logcat("Sub to men in VM")
val list = arrayListOf<DataType>()
for (item in it) {
val man = PeopleItem(avatarUri = item.avatarUri,
email = item.email,
id = item.id,
location = item.location,
name = item.name,
organisationAvatarUri = item.organisationAvatarUri,
organisationInn = item.organisationInn,
organisationName = item.organisationName,
personalCode = item.personalCode,
phone = item.phone,
role = item.role,
employeesState = humanResourcesFacade.employeesJoinState.map {
it[item.id] ?: JoinState.NONE
})
man.onClick = {
scope.launch {
privateOfficeFacade.getAlienProfile(it)
privateOfficeFacade.loadAlienFirstPosts(it)
navigator.add(FragmentAlienPhysicalProfile::class.java)
}
}
list.add(man)
}
peopleChanel.send(list)
peopleFacade.data.get()?.let { data ->
totalCountChanel.send(data.countAll)
}
}
when (peopleFacade.clickTab.get()) {
0 -> {
logcat("Load Org")
loadFirstPage()
}
1 -> {
logcat("Load men")
loadFirstPeoplePage()
}
}
}.onFailure { it.printStackTrace() }.exceptionOrNull()?.showAlertDialog(activityController)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment