SetStatusDialogFragment.kt 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. * Nextcloud Android client application
  3. *
  4. * @author Tobias Kaminsky
  5. * Copyright (C) 2020 Nextcloud GmbH
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  9. * License as published by the Free Software Foundation; either
  10. * version 3 of the License, or any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  16. *
  17. * You should have received a copy of the GNU Affero General Public
  18. * License along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. package com.nextcloud.ui
  21. import android.accounts.Account
  22. import android.annotation.SuppressLint
  23. import android.app.Dialog
  24. import android.content.Context
  25. import android.os.Bundle
  26. import android.view.LayoutInflater
  27. import android.view.View
  28. import android.view.ViewGroup
  29. import androidx.annotation.VisibleForTesting
  30. import androidx.fragment.app.DialogFragment
  31. import androidx.recyclerview.widget.LinearLayoutManager
  32. import com.google.android.material.dialog.MaterialAlertDialogBuilder
  33. import com.google.gson.Gson
  34. import com.google.gson.reflect.TypeToken
  35. import com.nextcloud.client.account.User
  36. import com.nextcloud.client.account.UserAccountManager
  37. import com.nextcloud.client.core.AsyncRunner
  38. import com.nextcloud.client.di.Injectable
  39. import com.nextcloud.client.network.ClientFactory
  40. import com.owncloud.android.R
  41. import com.owncloud.android.datamodel.ArbitraryDataProvider
  42. import com.owncloud.android.lib.common.OwnCloudClientFactory
  43. import com.owncloud.android.lib.resources.users.ClearStatusMessageRemoteOperation
  44. import com.owncloud.android.lib.resources.users.PredefinedStatus
  45. import com.owncloud.android.lib.resources.users.SetPredefinedCustomStatusMessageRemoteOperation
  46. import com.owncloud.android.lib.resources.users.SetStatusRemoteOperation
  47. import com.owncloud.android.lib.resources.users.SetUserDefinedCustomStatusMessageRemoteOperation
  48. import com.owncloud.android.lib.resources.users.Status
  49. import com.owncloud.android.lib.resources.users.StatusType
  50. import com.owncloud.android.ui.activity.BaseActivity
  51. import com.owncloud.android.ui.adapter.PredefinedStatusClickListener
  52. import com.owncloud.android.ui.adapter.PredefinedStatusListAdapter
  53. import kotlinx.android.synthetic.main.dialog_set_status.*
  54. import java.util.ArrayList
  55. import javax.inject.Inject
  56. private const val ARG_CURRENT_USER_PARAM = "currentUser"
  57. private const val ARG_CURRENT_STATUS_PARAM = "currentStatus"
  58. class SetStatusDialogFragment : DialogFragment(),
  59. PredefinedStatusClickListener,
  60. Injectable {
  61. private lateinit var dialogView: View
  62. private var currentUser: User? = null
  63. private var currentStatus: Status? = null
  64. private lateinit var accountManager: UserAccountManager
  65. private lateinit var predefinedStatus: ArrayList<PredefinedStatus>
  66. private lateinit var adapter: PredefinedStatusListAdapter
  67. private var selectedPredefinedMessageId: String? = null
  68. @Inject
  69. lateinit var arbitraryDataProvider: ArbitraryDataProvider
  70. @Inject
  71. lateinit var asyncRunner: AsyncRunner
  72. @Inject
  73. lateinit var clientFactory: ClientFactory
  74. override fun onCreate(savedInstanceState: Bundle?) {
  75. super.onCreate(savedInstanceState)
  76. arguments?.let {
  77. currentUser = it.getParcelable(ARG_CURRENT_USER_PARAM)
  78. currentStatus = it.getParcelable(ARG_CURRENT_STATUS_PARAM)
  79. val json = arbitraryDataProvider.getValue(currentUser, ArbitraryDataProvider.PREDEFINED_STATUS)
  80. if (json.isNotEmpty()) {
  81. val myType = object : TypeToken<ArrayList<PredefinedStatus>>() {}.type
  82. predefinedStatus = Gson().fromJson(json, myType)
  83. }
  84. }
  85. }
  86. @SuppressLint("InflateParams")
  87. override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
  88. dialogView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_set_status, null)
  89. return MaterialAlertDialogBuilder(requireContext())
  90. .setView(dialogView)
  91. .create()
  92. }
  93. override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
  94. super.onViewCreated(view, savedInstanceState)
  95. accountManager = (activity as BaseActivity).userAccountManager
  96. currentStatus?.let {
  97. emoji.text = it.icon
  98. customStatusInput.text.clear()
  99. customStatusInput.text.append(it.message)
  100. }
  101. adapter = PredefinedStatusListAdapter(this, requireContext())
  102. if (this::predefinedStatus.isInitialized) {
  103. adapter.list = predefinedStatus
  104. }
  105. predefinedStatusList.adapter = adapter
  106. predefinedStatusList.layoutManager = LinearLayoutManager(context)
  107. onlineStatus.setOnClickListener { setStatus(StatusType.ONLINE) }
  108. dndStatus.setOnClickListener { setStatus(StatusType.DND) }
  109. awayStatus.setOnClickListener { setStatus(StatusType.AWAY) }
  110. invisibleStatus.setOnClickListener { setStatus(StatusType.INVISIBLE) }
  111. clearStatus.setOnClickListener { clearStatus() }
  112. setStatus.setOnClickListener { setStatusMessage() }
  113. }
  114. private fun clearStatus() {
  115. asyncRunner.postQuickTask(ClearStatusTask(accountManager.currentOwnCloudAccount?.savedAccount, context),
  116. { dismiss(it) })
  117. }
  118. private fun setStatus(statusType: StatusType) {
  119. asyncRunner.postQuickTask(
  120. SetStatusTask(
  121. statusType,
  122. accountManager.currentOwnCloudAccount?.savedAccount,
  123. context)
  124. )
  125. }
  126. private fun setStatusMessage() {
  127. if (selectedPredefinedMessageId != null) {
  128. asyncRunner.postQuickTask(
  129. SetPredefinedCustomStatusTask(
  130. selectedPredefinedMessageId!!,
  131. 1603719631,
  132. accountManager.currentOwnCloudAccount?.savedAccount,
  133. context),
  134. { dismiss(it) }
  135. )
  136. } else {
  137. asyncRunner.postQuickTask(
  138. SetUserDefinedCustomStatusTask(
  139. customStatusInput.text.toString(),
  140. emoji.text.toString(),
  141. 1603719631,
  142. accountManager.currentOwnCloudAccount?.savedAccount,
  143. context),
  144. { dismiss(it) }
  145. )
  146. }
  147. }
  148. private fun dismiss(boolean: Boolean) {
  149. if (boolean) {
  150. dismiss()
  151. }
  152. }
  153. private class SetPredefinedCustomStatusTask(val messageId: String,
  154. val clearAt: Long,
  155. val account: Account?,
  156. val context: Context?) : Function0<Boolean> {
  157. override fun invoke(): Boolean {
  158. val client = OwnCloudClientFactory.createNextcloudClient(account, context)
  159. return SetPredefinedCustomStatusMessageRemoteOperation(messageId, clearAt).execute(client).isSuccess
  160. }
  161. }
  162. private class SetUserDefinedCustomStatusTask(val message: String,
  163. val icon: String,
  164. val clearAt: Long,
  165. val account: Account?,
  166. val context: Context?) : Function0<Boolean> {
  167. override fun invoke(): Boolean {
  168. val client = OwnCloudClientFactory.createNextcloudClient(account, context)
  169. return SetUserDefinedCustomStatusMessageRemoteOperation(message, icon, clearAt).execute(client).isSuccess
  170. }
  171. }
  172. private class SetStatusTask(val statusType: StatusType,
  173. val account: Account?,
  174. val context: Context?) : Function0<Boolean> {
  175. override fun invoke(): Boolean {
  176. val client = OwnCloudClientFactory.createNextcloudClient(account, context)
  177. return SetStatusRemoteOperation(statusType).execute(client).isSuccess
  178. }
  179. }
  180. private class ClearStatusTask(val account: Account?, val context: Context?) : Function0<Boolean> {
  181. override fun invoke(): Boolean {
  182. val client = OwnCloudClientFactory.createNextcloudClient(account, context)
  183. return ClearStatusMessageRemoteOperation().execute(client).isSuccess
  184. }
  185. }
  186. /**
  187. * Fragment creator
  188. */
  189. companion object {
  190. @JvmStatic
  191. fun newInstance(user: User, status: Status?) =
  192. SetStatusDialogFragment().apply {
  193. arguments = Bundle().apply {
  194. putParcelable(ARG_CURRENT_USER_PARAM, user)
  195. putParcelable(ARG_CURRENT_STATUS_PARAM, status)
  196. }
  197. }
  198. }
  199. override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
  200. return dialogView
  201. }
  202. override fun onClick(predefinedStatus: PredefinedStatus) {
  203. selectedPredefinedMessageId = predefinedStatus.id
  204. emoji.text = predefinedStatus.icon
  205. customStatusInput.text.clear()
  206. customStatusInput.text.append(predefinedStatus.message)
  207. }
  208. @VisibleForTesting
  209. fun setPredefinedStatus(predefinedStatus: ArrayList<PredefinedStatus>) {
  210. adapter.list = predefinedStatus
  211. predefinedStatusList.adapter?.notifyDataSetChanged()
  212. }
  213. }