SwitchAccountController.kt 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Nextcloud Talk application
  3. *
  4. * @author Mario Danic
  5. * @author Andy Scherzinger
  6. * Copyright (C) 2022 Andy Scherzinger (info@andy-scherzinger.de)
  7. * Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. * Parts related to account import were either copied from or inspired by the great work done by David Luhmer at:
  23. * https://github.com/nextcloud/ownCloud-Account-Importer
  24. */
  25. package com.nextcloud.talk.controllers
  26. import android.accounts.Account
  27. import android.os.Bundle
  28. import android.view.MenuItem
  29. import android.view.View
  30. import androidx.preference.PreferenceManager
  31. import androidx.recyclerview.widget.LinearLayoutManager
  32. import autodagger.AutoInjector
  33. import com.bluelinelabs.conductor.RouterTransaction
  34. import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
  35. import com.nextcloud.talk.R
  36. import com.nextcloud.talk.adapters.items.AdvancedUserItem
  37. import com.nextcloud.talk.application.NextcloudTalkApplication
  38. import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
  39. import com.nextcloud.talk.controllers.base.NewBaseController
  40. import com.nextcloud.talk.controllers.util.viewBinding
  41. import com.nextcloud.talk.databinding.ControllerGenericRvBinding
  42. import com.nextcloud.talk.models.ImportAccount
  43. import com.nextcloud.talk.models.database.UserEntity
  44. import com.nextcloud.talk.models.json.participants.Participant
  45. import com.nextcloud.talk.utils.AccountUtils.findAccounts
  46. import com.nextcloud.talk.utils.AccountUtils.getInformationFromAccount
  47. import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_BASE_URL
  48. import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_IS_ACCOUNT_IMPORT
  49. import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_TOKEN
  50. import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USERNAME
  51. import com.nextcloud.talk.utils.database.user.UserUtils
  52. import eu.davidea.flexibleadapter.FlexibleAdapter
  53. import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
  54. import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
  55. import io.reactivex.Observer
  56. import io.reactivex.disposables.Disposable
  57. import org.osmdroid.config.Configuration
  58. import java.net.CookieManager
  59. import java.util.ArrayList
  60. import javax.inject.Inject
  61. @AutoInjector(NextcloudTalkApplication::class)
  62. class SwitchAccountController(args: Bundle? = null) :
  63. NewBaseController(
  64. R.layout.controller_generic_rv,
  65. args
  66. ) {
  67. private val binding: ControllerGenericRvBinding by viewBinding(ControllerGenericRvBinding::bind)
  68. @Inject
  69. lateinit var userUtils: UserUtils
  70. @Inject
  71. lateinit var cookieManager: CookieManager
  72. private var adapter: FlexibleAdapter<AbstractFlexibleItem<*>>? = null
  73. private val userItems: MutableList<AbstractFlexibleItem<*>> = ArrayList()
  74. private var isAccountImport = false
  75. private val onImportItemClickListener = FlexibleAdapter.OnItemClickListener { _, position ->
  76. if (userItems.size > position) {
  77. val account = (userItems[position] as AdvancedUserItem).account
  78. reauthorizeFromImport(account)
  79. }
  80. true
  81. }
  82. private val onSwitchItemClickListener = FlexibleAdapter.OnItemClickListener { _, position ->
  83. if (userItems.size > position) {
  84. val userEntity = (userItems[position] as AdvancedUserItem).entity
  85. userUtils.createOrUpdateUser(
  86. null,
  87. null, null, null,
  88. null, java.lang.Boolean.TRUE, null, userEntity.id, null, null, null
  89. )
  90. .subscribe(object : Observer<UserEntity> {
  91. override fun onSubscribe(d: Disposable) {
  92. // unused atm
  93. }
  94. override fun onNext(userEntity: UserEntity) {
  95. cookieManager.cookieStore.removeAll()
  96. userUtils.disableAllUsersWithoutId(userEntity.id)
  97. if (activity != null) {
  98. activity!!.runOnUiThread { router.popCurrentController() }
  99. }
  100. }
  101. override fun onError(e: Throwable) {
  102. // unused atm
  103. }
  104. override fun onComplete() {
  105. // unused atm
  106. }
  107. })
  108. }
  109. true
  110. }
  111. init {
  112. setHasOptionsMenu(true)
  113. sharedApplication!!.componentApplication.inject(this)
  114. Configuration.getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(context))
  115. if (args?.containsKey(KEY_IS_ACCOUNT_IMPORT) == true) {
  116. isAccountImport = true
  117. }
  118. }
  119. override fun onOptionsItemSelected(item: MenuItem): Boolean {
  120. return when (item.itemId) {
  121. android.R.id.home -> {
  122. router.popCurrentController()
  123. true
  124. }
  125. else -> super.onOptionsItemSelected(item)
  126. }
  127. }
  128. override fun onViewBound(view: View) {
  129. super.onViewBound(view)
  130. binding.swipeRefreshLayout.isEnabled = false
  131. actionBar?.show()
  132. if (adapter == null) {
  133. adapter = FlexibleAdapter(userItems, activity, false)
  134. var userEntity: UserEntity?
  135. var participant: Participant
  136. if (!isAccountImport) {
  137. for (userEntityObject in userUtils.users) {
  138. userEntity = userEntityObject as UserEntity?
  139. if (!userEntity!!.current) {
  140. var userId: String?
  141. userId = if (userEntity.userId != null) {
  142. userEntity.userId
  143. } else {
  144. userEntity.username
  145. }
  146. participant = Participant()
  147. participant.setActorType(Participant.ActorType.USERS)
  148. participant.setActorId(userId)
  149. participant.setDisplayName(userEntity.displayName)
  150. userItems.add(AdvancedUserItem(participant, userEntity, null))
  151. }
  152. }
  153. adapter!!.addListener(onSwitchItemClickListener)
  154. adapter!!.updateDataSet(userItems, false)
  155. } else {
  156. var account: Account
  157. var importAccount: ImportAccount
  158. for (accountObject in findAccounts(userUtils.users as List<UserEntity>)) {
  159. account = accountObject
  160. importAccount = getInformationFromAccount(account)
  161. participant = Participant()
  162. participant.setActorType(Participant.ActorType.USERS)
  163. participant.setActorId(importAccount.getUsername())
  164. participant.setDisplayName(importAccount.getUsername())
  165. userEntity = UserEntity()
  166. userEntity.baseUrl = importAccount.getBaseUrl()
  167. userItems.add(AdvancedUserItem(participant, userEntity, account))
  168. }
  169. adapter!!.addListener(onImportItemClickListener)
  170. adapter!!.updateDataSet(userItems, false)
  171. }
  172. }
  173. prepareViews()
  174. }
  175. private fun prepareViews() {
  176. val layoutManager: LinearLayoutManager = SmoothScrollLinearLayoutManager(activity)
  177. binding.recyclerView.layoutManager = layoutManager
  178. binding.recyclerView.setHasFixedSize(true)
  179. binding.recyclerView.adapter = adapter
  180. binding.swipeRefreshLayout.isEnabled = false
  181. }
  182. private fun reauthorizeFromImport(account: Account?) {
  183. val importAccount = getInformationFromAccount(account!!)
  184. val bundle = Bundle()
  185. bundle.putString(KEY_BASE_URL, importAccount.getBaseUrl())
  186. bundle.putString(KEY_USERNAME, importAccount.getUsername())
  187. bundle.putString(KEY_TOKEN, importAccount.getToken())
  188. bundle.putBoolean(KEY_IS_ACCOUNT_IMPORT, true)
  189. router.pushController(
  190. RouterTransaction.with(AccountVerificationController(bundle))
  191. .pushChangeHandler(HorizontalChangeHandler())
  192. .popChangeHandler(HorizontalChangeHandler())
  193. )
  194. }
  195. override val title: String
  196. get() =
  197. resources!!.getString(R.string.nc_select_an_account)
  198. }