diff --git a/src/main/java/com/nextcloud/ui/ChooseAccountDialogFragment.kt b/src/main/java/com/nextcloud/ui/ChooseAccountDialogFragment.kt index 31b704c675..12847645cf 100644 --- a/src/main/java/com/nextcloud/ui/ChooseAccountDialogFragment.kt +++ b/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)) diff --git a/src/main/java/com/nextcloud/ui/SetStatusDialogFragment.kt b/src/main/java/com/nextcloud/ui/SetStatusDialogFragment.kt index ec64626c44..81c356915f 100644 --- a/src/main/java/com/nextcloud/ui/SetStatusDialogFragment.kt +++ b/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 + 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,12 +106,110 @@ 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() } + } + + private fun clearStatus() { + asyncRunner.postQuickTask(ClearStatusTask(accountManager.currentOwnCloudAccount?.savedAccount, context), + { dismiss(it) }) + } + + 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) } + ) + } + } + + private fun dismiss(boolean: Boolean) { + if (boolean) { + dismiss() + } + } + + private class SetPredefinedCustomStatusTask(val messageId: String, + val clearAt: Long, + val account: Account?, + val context: Context?) : Function0 { + override fun invoke(): Boolean { + val client = OwnCloudClientFactory.createNextcloudClient(account, context) + + return SetPredefinedCustomStatusMessageRemoteOperation(messageId, clearAt).execute(client).isSuccess + } + } + + private class SetUserDefinedCustomStatusTask(val message: String, + val icon: String, + val clearAt: Long, + val account: Account?, + val context: Context?) : Function0 { + override fun invoke(): Boolean { + val client = OwnCloudClientFactory.createNextcloudClient(account, context) + + return SetUserDefinedCustomStatusMessageRemoteOperation(message, icon, clearAt).execute(client).isSuccess + } + } + + private class SetStatusTask(val statusType: StatusType, + val account: Account?, + val context: Context?) : Function0 { + override fun invoke(): Boolean { + val client = OwnCloudClientFactory.createNextcloudClient(account, context) + + return SetStatusRemoteOperation(statusType).execute(client).isSuccess + } + } + + private class ClearStatusTask(val account: Account?, val context: Context?) : Function0 { + override fun invoke(): Boolean { + val client = OwnCloudClientFactory.createNextcloudClient(account, context) + + return ClearStatusMessageRemoteOperation().execute(client).isSuccess + } } /** @@ -111,10 +217,11 @@ class SetStatusDialogFragment : DialogFragment(), */ companion object { @JvmStatic - fun newInstance(user: User) = + fun newInstance(user: User, status: Status?) = SetStatusDialogFragment().apply { arguments = Bundle().apply { putParcelable(ARG_CURRENT_USER_PARAM, user) + putParcelable(ARG_CURRENT_STATUS_PARAM, status) } } } @@ -123,39 +230,11 @@ class SetStatusDialogFragment : DialogFragment(), return dialogView } - override fun shouldCallGeneratedCallback(tag: String?, callContext: Any?): Boolean { - return (callContext as ImageView).tag.toString() == tag - } - - override fun avatarGenerated(avatarDrawable: Drawable?, callContext: Any?) { - if (user_icon != null) { - user_icon.setImageDrawable(avatarDrawable) - } - } - - override fun onAccountClicked(user: User?) { - (activity as DrawerActivity).accountClicked(user.hashCode()) - } - - override fun onOptionItemClicked(user: User?, view: View?) { - // Un-needed for this context - } - - fun setStatus(newStatus: Status) { - val size = DisplayUtils.convertDpToPixel(9f, context) - ticker.background = null - ticker.setImageDrawable(StatusDrawable(newStatus, size.toFloat(), context)) - ticker.visibility = View.VISIBLE - - if (newStatus.message.isNullOrBlank()) { - status.text = "" - status.visibility = View.GONE - } else { - status.text = newStatus.message - status.visibility = View.VISIBLE - } - - view?.invalidate() + override fun onClick(predefinedStatus: PredefinedStatus) { + selectedPredefinedMessageId = predefinedStatus.id + emoji.text = predefinedStatus.icon + customStatusInput.text.clear() + customStatusInput.text.append(predefinedStatus.message) } @VisibleForTesting diff --git a/src/main/java/com/owncloud/android/ui/adapter/PredefinedStatusClickListener.kt b/src/main/java/com/owncloud/android/ui/adapter/PredefinedStatusClickListener.kt new file mode 100644 index 0000000000..e79c821711 --- /dev/null +++ b/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 . + */ + +package com.owncloud.android.ui.adapter + +import com.owncloud.android.lib.resources.users.PredefinedStatus + +interface PredefinedStatusClickListener { + fun onClick(predefinedStatus: PredefinedStatus) +} diff --git a/src/main/java/com/owncloud/android/ui/adapter/PredefinedStatusListAdapter.kt b/src/main/java/com/owncloud/android/ui/adapter/PredefinedStatusListAdapter.kt index a22d87fa68..153932f27f 100644 --- a/src/main/java/com/owncloud/android/ui/adapter/PredefinedStatusListAdapter.kt +++ b/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() { +class PredefinedStatusListAdapter(private val clickListener: PredefinedStatusClickListener, + val context: Context) : RecyclerView.Adapter() { internal var list: List = emptyList() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PredefinedStatusViewHolder { @@ -38,7 +39,7 @@ class PredefinedStatusListAdapter(val context: Context) : RecyclerView.Adapter

- + android:textSize="25sp" + android:gravity="center" + tools:text="☁️" />