Эх сурвалжийг харах

wip

Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
tobiasKaminsky 4 жил өмнө
parent
commit
fcb0147d71

+ 4 - 1
src/main/java/com/nextcloud/ui/ChooseAccountDialogFragment.kt

@@ -61,6 +61,7 @@ class ChooseAccountDialogFragment : DialogFragment(),
     private lateinit var dialogView: View
     private var currentUser: User? = null
     private lateinit var accountManager: UserAccountManager
+    private lateinit var currentStatus: Status
 
     @Inject
     lateinit var clientFactory: ClientFactory
@@ -131,7 +132,7 @@ class ChooseAccountDialogFragment : DialogFragment(),
             }
 
             set_status.setOnClickListener {
-                val setStatusDialog = SetStatusDialogFragment.newInstance(accountManager.user)
+                val setStatusDialog = SetStatusDialogFragment.newInstance(accountManager.user, currentStatus)
                 setStatusDialog.show((activity as DrawerActivity).supportFragmentManager, "fragment_set_status")
 
                 dismiss()
@@ -196,6 +197,8 @@ class ChooseAccountDialogFragment : DialogFragment(),
     }
 
     fun setStatus(newStatus: Status) {
+        currentStatus = newStatus
+
         val size = DisplayUtils.convertDpToPixel(9f, context)
         ticker.background = null
         ticker.setImageDrawable(StatusDrawable(newStatus, size.toFloat(), context))

+ 127 - 48
src/main/java/com/nextcloud/ui/SetStatusDialogFragment.kt

@@ -1,8 +1,8 @@
 /*
  * Nextcloud Android client application
  *
- * @author Infomaniak Network SA
- * Copyright (C) 2020 Infomaniak Network SA
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Nextcloud GmbH
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -20,14 +20,14 @@
 
 package com.nextcloud.ui
 
+import android.accounts.Account
 import android.annotation.SuppressLint
 import android.app.Dialog
-import android.graphics.drawable.Drawable
+import android.content.Context
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import android.widget.ImageView
 import androidx.annotation.VisibleForTesting
 import androidx.fragment.app.DialogFragment
 import androidx.recyclerview.widget.LinearLayoutManager
@@ -36,38 +36,45 @@ import com.google.gson.Gson
 import com.google.gson.reflect.TypeToken
 import com.nextcloud.client.account.User
 import com.nextcloud.client.account.UserAccountManager
+import com.nextcloud.client.core.AsyncRunner
 import com.nextcloud.client.di.Injectable
 import com.nextcloud.client.network.ClientFactory
 import com.owncloud.android.R
 import com.owncloud.android.datamodel.ArbitraryDataProvider
+import com.owncloud.android.lib.common.OwnCloudClientFactory
+import com.owncloud.android.lib.resources.users.ClearStatusMessageRemoteOperation
 import com.owncloud.android.lib.resources.users.PredefinedStatus
+import com.owncloud.android.lib.resources.users.SetPredefinedCustomStatusMessageRemoteOperation
+import com.owncloud.android.lib.resources.users.SetStatusRemoteOperation
+import com.owncloud.android.lib.resources.users.SetUserDefinedCustomStatusMessageRemoteOperation
 import com.owncloud.android.lib.resources.users.Status
-import com.owncloud.android.ui.StatusDrawable
+import com.owncloud.android.lib.resources.users.StatusType
 import com.owncloud.android.ui.activity.BaseActivity
-import com.owncloud.android.ui.activity.DrawerActivity
+import com.owncloud.android.ui.adapter.PredefinedStatusClickListener
 import com.owncloud.android.ui.adapter.PredefinedStatusListAdapter
-import com.owncloud.android.ui.adapter.UserListAdapter
-import com.owncloud.android.utils.DisplayUtils
-import com.owncloud.android.utils.DisplayUtils.AvatarGenerationListener
-import kotlinx.android.synthetic.main.account_item.*
 import kotlinx.android.synthetic.main.dialog_set_status.*
 import java.util.ArrayList
 import javax.inject.Inject
 
 private const val ARG_CURRENT_USER_PARAM = "currentUser"
+private const val ARG_CURRENT_STATUS_PARAM = "currentStatus"
 
 class SetStatusDialogFragment : DialogFragment(),
-    AvatarGenerationListener,
-    UserListAdapter.ClickListener,
+    PredefinedStatusClickListener,
     Injectable {
     private lateinit var dialogView: View
     private var currentUser: User? = null
+    private var currentStatus: Status? = null
     private lateinit var accountManager: UserAccountManager
     private lateinit var predefinedStatus: ArrayList<PredefinedStatus>
+    private lateinit var adapter: PredefinedStatusListAdapter
+    private var selectedPredefinedMessageId: String? = null
 
     @Inject
     lateinit var arbitraryDataProvider: ArbitraryDataProvider
-    private lateinit var adapter: PredefinedStatusListAdapter
+
+    @Inject
+    lateinit var asyncRunner: AsyncRunner
 
     @Inject
     lateinit var clientFactory: ClientFactory
@@ -76,6 +83,7 @@ class SetStatusDialogFragment : DialogFragment(),
         super.onCreate(savedInstanceState)
         arguments?.let {
             currentUser = it.getParcelable(ARG_CURRENT_USER_PARAM)
+            currentStatus = it.getParcelable(ARG_CURRENT_STATUS_PARAM)
 
             val json = arbitraryDataProvider.getValue(currentUser, ArbitraryDataProvider.PREDEFINED_STATUS)
 
@@ -98,64 +106,135 @@ class SetStatusDialogFragment : DialogFragment(),
         super.onViewCreated(view, savedInstanceState)
         accountManager = (activity as BaseActivity).userAccountManager
 
-        adapter = PredefinedStatusListAdapter(requireContext())
+        currentStatus?.let {
+            emoji.text = it.icon
+            customStatusInput.text.clear()
+            customStatusInput.text.append(it.message)
+        }
+
+        adapter = PredefinedStatusListAdapter(this, requireContext())
         if (this::predefinedStatus.isInitialized) {
             adapter.list = predefinedStatus
         }
         predefinedStatusList.adapter = adapter
         predefinedStatusList.layoutManager = LinearLayoutManager(context)
+
+        onlineStatus.setOnClickListener { setStatus(StatusType.ONLINE) }
+        dndStatus.setOnClickListener { setStatus(StatusType.DND) }
+        awayStatus.setOnClickListener { setStatus(StatusType.AWAY) }
+        invisibleStatus.setOnClickListener { setStatus(StatusType.INVISIBLE) }
+
+        clearStatus.setOnClickListener { clearStatus() }
+        setStatus.setOnClickListener { setStatusMessage() }
     }
 
-    /**
-     * Fragment creator
-     */
-    companion object {
-        @JvmStatic
-        fun newInstance(user: User) =
-            SetStatusDialogFragment().apply {
-                arguments = Bundle().apply {
-                    putParcelable(ARG_CURRENT_USER_PARAM, user)
-                }
-            }
+    private fun clearStatus() {
+        asyncRunner.postQuickTask(ClearStatusTask(accountManager.currentOwnCloudAccount?.savedAccount, context),
+            { dismiss(it) })
     }
 
-    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
-        return dialogView
+    private fun setStatus(statusType: StatusType) {
+        asyncRunner.postQuickTask(
+            SetStatusTask(
+                statusType,
+                accountManager.currentOwnCloudAccount?.savedAccount,
+                context)
+        )
+    }
+
+    private fun setStatusMessage() {
+        if (selectedPredefinedMessageId != null) {
+            asyncRunner.postQuickTask(
+                SetPredefinedCustomStatusTask(
+                    selectedPredefinedMessageId!!,
+                    1603719631,
+                    accountManager.currentOwnCloudAccount?.savedAccount,
+                    context),
+                { dismiss(it) }
+            )
+        } else {
+            asyncRunner.postQuickTask(
+                SetUserDefinedCustomStatusTask(
+                    customStatusInput.text.toString(),
+                    emoji.text.toString(),
+                    1603719631,
+                    accountManager.currentOwnCloudAccount?.savedAccount,
+                    context),
+                { dismiss(it) }
+            )
+        }
     }
 
-    override fun shouldCallGeneratedCallback(tag: String?, callContext: Any?): Boolean {
-        return (callContext as ImageView).tag.toString() == tag
+    private fun dismiss(boolean: Boolean) {
+        if (boolean) {
+            dismiss()
+        }
     }
 
-    override fun avatarGenerated(avatarDrawable: Drawable?, callContext: Any?) {
-        if (user_icon != null) {
-            user_icon.setImageDrawable(avatarDrawable)
+    private class SetPredefinedCustomStatusTask(val messageId: String,
+                                                val clearAt: Long,
+                                                val account: Account?,
+                                                val context: Context?) : Function0<Boolean> {
+        override fun invoke(): Boolean {
+            val client = OwnCloudClientFactory.createNextcloudClient(account, context)
+
+            return SetPredefinedCustomStatusMessageRemoteOperation(messageId, clearAt).execute(client).isSuccess
         }
     }
 
-    override fun onAccountClicked(user: User?) {
-        (activity as DrawerActivity).accountClicked(user.hashCode())
+    private class SetUserDefinedCustomStatusTask(val message: String,
+                                                 val icon: String,
+                                                 val clearAt: Long,
+                                                 val account: Account?,
+                                                 val context: Context?) : Function0<Boolean> {
+        override fun invoke(): Boolean {
+            val client = OwnCloudClientFactory.createNextcloudClient(account, context)
+
+            return SetUserDefinedCustomStatusMessageRemoteOperation(message, icon, clearAt).execute(client).isSuccess
+        }
     }
 
-    override fun onOptionItemClicked(user: User?, view: View?) {
-        // Un-needed for this context
+    private class SetStatusTask(val statusType: StatusType,
+                                val account: Account?,
+                                val context: Context?) : Function0<Boolean> {
+        override fun invoke(): Boolean {
+            val client = OwnCloudClientFactory.createNextcloudClient(account, context)
+
+            return SetStatusRemoteOperation(statusType).execute(client).isSuccess
+        }
     }
 
-    fun setStatus(newStatus: Status) {
-        val size = DisplayUtils.convertDpToPixel(9f, context)
-        ticker.background = null
-        ticker.setImageDrawable(StatusDrawable(newStatus, size.toFloat(), context))
-        ticker.visibility = View.VISIBLE
+    private class ClearStatusTask(val account: Account?, val context: Context?) : Function0<Boolean> {
+        override fun invoke(): Boolean {
+            val client = OwnCloudClientFactory.createNextcloudClient(account, context)
 
-        if (newStatus.message.isNullOrBlank()) {
-            status.text = ""
-            status.visibility = View.GONE
-        } else {
-            status.text = newStatus.message
-            status.visibility = View.VISIBLE
+            return ClearStatusMessageRemoteOperation().execute(client).isSuccess
         }
+    }
+
+    /**
+     * Fragment creator
+     */
+    companion object {
+        @JvmStatic
+        fun newInstance(user: User, status: Status?) =
+            SetStatusDialogFragment().apply {
+                arguments = Bundle().apply {
+                    putParcelable(ARG_CURRENT_USER_PARAM, user)
+                    putParcelable(ARG_CURRENT_STATUS_PARAM, status)
+                }
+            }
+    }
+
+    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+        return dialogView
+    }
 
-        view?.invalidate()
+    override fun onClick(predefinedStatus: PredefinedStatus) {
+        selectedPredefinedMessageId = predefinedStatus.id
+        emoji.text = predefinedStatus.icon
+        customStatusInput.text.clear()
+        customStatusInput.text.append(predefinedStatus.message)
     }
 
     @VisibleForTesting

+ 29 - 0
src/main/java/com/owncloud/android/ui/adapter/PredefinedStatusClickListener.kt

@@ -0,0 +1,29 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.ui.adapter
+
+import com.owncloud.android.lib.resources.users.PredefinedStatus
+
+interface PredefinedStatusClickListener {
+    fun onClick(predefinedStatus: PredefinedStatus)
+}

+ 3 - 2
src/main/java/com/owncloud/android/ui/adapter/PredefinedStatusListAdapter.kt

@@ -29,7 +29,8 @@ import androidx.recyclerview.widget.RecyclerView
 import com.owncloud.android.databinding.PredefinedStatusBinding
 import com.owncloud.android.lib.resources.users.PredefinedStatus
 
-class PredefinedStatusListAdapter(val context: Context) : RecyclerView.Adapter<PredefinedStatusViewHolder>() {
+class PredefinedStatusListAdapter(private val clickListener: PredefinedStatusClickListener,
+                                  val context: Context) : RecyclerView.Adapter<PredefinedStatusViewHolder>() {
     internal var list: List<PredefinedStatus> = emptyList()
 
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PredefinedStatusViewHolder {
@@ -38,7 +39,7 @@ class PredefinedStatusListAdapter(val context: Context) : RecyclerView.Adapter<P
     }
 
     override fun onBindViewHolder(holder: PredefinedStatusViewHolder, position: Int) {
-        holder.bind(list[position], context)
+        holder.bind(list[position], clickListener, context)
     }
 
     override fun getItemCount(): Int {

+ 2 - 1
src/main/java/com/owncloud/android/ui/adapter/PredefinedStatusViewHolder.kt

@@ -30,7 +30,8 @@ import com.owncloud.android.lib.resources.users.PredefinedStatus
 import com.owncloud.android.utils.DisplayUtils
 
 class PredefinedStatusViewHolder(private val binding: PredefinedStatusBinding) : RecyclerView.ViewHolder(binding.root) {
-    fun bind(status: PredefinedStatus, context: Context) {
+    fun bind(status: PredefinedStatus, clickListener: PredefinedStatusClickListener, context: Context) {
+        binding.root.setOnClickListener { clickListener.onClick(status) }
         binding.icon.text = status.icon
         binding.name.text = status.message
 

+ 6 - 5
src/main/res/layout/dialog_set_status.xml

@@ -165,12 +165,13 @@
         tools:layout_editor_absoluteX="201dp"
         tools:layout_editor_absoluteY="141dp">
 
-        <ImageButton
-            android:id="@+id/imageButton"
-            android:layout_width="wrap_content"
+        <TextView
+            android:id="@+id/emoji"
+            android:layout_width="48dp"
             android:layout_height="match_parent"
-            android:contentDescription="@string/set_status_icon"
-            android:src="@drawable/ic_cloud_sync_on" />
+            android:textSize="25sp"
+            android:gravity="center"
+            tools:text="☁️" />
 
         <EditText
             android:id="@+id/customStatusInput"