Selaa lähdekoodia

Fix up magical stuff

Signed-off-by: Mario Danic <mario@lovelyhq.com>
Mario Danic 5 vuotta sitten
vanhempi
commit
85b75b7da5

+ 0 - 3
app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java

@@ -39,8 +39,6 @@ import android.view.inputmethod.EditorInfo;
 import android.widget.ProgressBar;
 import android.widget.ProgressBar;
 import android.widget.RelativeLayout;
 import android.widget.RelativeLayout;
 
 
-import com.afollestad.materialdialogs.LayoutMode;
-import com.afollestad.materialdialogs.MaterialDialog;
 import com.bluelinelabs.conductor.RouterTransaction;
 import com.bluelinelabs.conductor.RouterTransaction;
 import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler;
 import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler;
 import com.bluelinelabs.logansquare.LoganSquare;
 import com.bluelinelabs.logansquare.LoganSquare;
@@ -57,7 +55,6 @@ import com.nextcloud.talk.controllers.bottomsheet.EntryMenuController;
 import com.nextcloud.talk.controllers.bottomsheet.OperationsMenuController;
 import com.nextcloud.talk.controllers.bottomsheet.OperationsMenuController;
 import com.nextcloud.talk.events.BottomSheetLockEvent;
 import com.nextcloud.talk.events.BottomSheetLockEvent;
 import com.nextcloud.talk.jobs.AddParticipantsToConversation;
 import com.nextcloud.talk.jobs.AddParticipantsToConversation;
-import com.nextcloud.talk.jobs.DeleteConversationWorker;
 import com.nextcloud.talk.models.RetrofitBucket;
 import com.nextcloud.talk.models.RetrofitBucket;
 import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall;
 import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall;

+ 8 - 4
app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt

@@ -54,6 +54,9 @@ import com.nextcloud.talk.adapters.items.UserItem
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.controllers.base.BaseController
 import com.nextcloud.talk.controllers.base.BaseController
+import com.nextcloud.talk.controllers.bottomsheet.items.BasicListItemWithImage
+import com.nextcloud.talk.controllers.bottomsheet.items.ListItemWithImage
+import com.nextcloud.talk.controllers.bottomsheet.items.listItemsWithImage
 import com.nextcloud.talk.events.BottomSheetLockEvent
 import com.nextcloud.talk.events.BottomSheetLockEvent
 import com.nextcloud.talk.events.EventStatus
 import com.nextcloud.talk.events.EventStatus
 import com.nextcloud.talk.jobs.DeleteConversationWorker
 import com.nextcloud.talk.jobs.DeleteConversationWorker
@@ -593,9 +596,9 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA
 
 
         if (participant.userId != conversationUser!!.userId) {
         if (participant.userId != conversationUser!!.userId) {
             val items = mutableListOf(
             val items = mutableListOf(
-                    context.getString(R.string.nc_promote),
-                    context.getString(R.string.nc_demote),
-                    context.getString(R.string.nc_remove_participant)
+                    BasicListItemWithImage(R.drawable.ic_pencil_grey600_24dp, context.getString(R.string.nc_promote)),
+                    BasicListItemWithImage(R.drawable.ic_pencil_grey600_24dp, context.getString(R.string.nc_demote)),
+                    BasicListItemWithImage(R.drawable.ic_delete_grey600_24dp, context.getString(R.string.nc_remove_participant))
             )
             )
 
 
             if (participant.type == Participant.ParticipantType.MODERATOR) {
             if (participant.type == Participant.ParticipantType.MODERATOR) {
@@ -610,8 +613,9 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA
 
 
             MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show {
             MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show {
                 cornerRadius(res = R.dimen.corner_radius)
                 cornerRadius(res = R.dimen.corner_radius)
+
                 title(text = participant.displayName)
                 title(text = participant.displayName)
-                listItems(items = items) { dialog, index, text ->
+                listItemsWithImage(items = items) { dialog, index, _ ->
 
 
                     if (index == 0) {
                     if (index == 0) {
                         if (participant.type == Participant.ParticipantType.MODERATOR) {
                         if (participant.type == Participant.ParticipantType.MODERATOR) {

+ 38 - 0
app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/items/BasicListItemWithImage.kt

@@ -0,0 +1,38 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.controllers.bottomsheet.items
+
+import android.widget.ImageView
+import androidx.annotation.DrawableRes
+
+interface ListItemWithImage {
+    val title: String
+    fun populateIcon(imageView: ImageView)
+}
+
+data class BasicListItemWithImage(
+        @DrawableRes val iconRes: Int,
+        override val title: String) : ListItemWithImage {
+
+    override fun populateIcon(imageView: ImageView) {
+        imageView.setImageResource(iconRes)
+    }
+}

+ 151 - 0
app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/items/ListIconDialogAdapter.kt

@@ -0,0 +1,151 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.controllers.bottomsheet.items
+
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import com.afollestad.materialdialogs.MaterialDialog
+import com.afollestad.materialdialogs.WhichButton
+import com.afollestad.materialdialogs.actions.hasActionButton
+import com.afollestad.materialdialogs.actions.hasActionButtons
+import com.afollestad.materialdialogs.internal.list.DialogAdapter
+import com.afollestad.materialdialogs.internal.rtl.RtlTextView
+import com.afollestad.materialdialogs.list.getItemSelector
+import com.afollestad.materialdialogs.utils.MDUtil.inflate
+import com.afollestad.materialdialogs.utils.MDUtil.maybeSetTextColor
+import com.google.android.material.textview.MaterialTextView
+import com.nextcloud.talk.R
+
+private const val KEY_ACTIVATED_INDEX = "activated_index"
+
+internal class ListItemViewHolder(
+        itemView: View,
+        private val adapter: ListIconDialogAdapter<*>) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
+    init {
+        itemView.setOnClickListener(this)
+    }
+
+    val iconView: ImageView = itemView.findViewById(R.id.icon)
+    val titleView: RtlTextView = itemView.findViewById(R.id.title)
+
+    override fun onClick(view: View) = adapter.itemClicked(adapterPosition)
+}
+
+internal class ListIconDialogAdapter<IT : ListItemWithImage>(
+        private var dialog: MaterialDialog,
+        private var items: List<IT>,
+        disabledItems: IntArray?,
+        private var waitForPositiveButton: Boolean,
+        private var selection: ListItemListener<IT>) : RecyclerView.Adapter<ListItemViewHolder>(), DialogAdapter<IT, ListItemListener<IT>> {
+
+    private var disabledIndices: IntArray = disabledItems ?: IntArray(0)
+
+    fun itemClicked(index: Int) {
+        if (waitForPositiveButton && dialog.hasActionButton(WhichButton.POSITIVE)) {
+            // Wait for positive action button, mark clicked item as activated so that we can call the
+            // selection listener when the button is pressed.
+            val lastActivated = dialog.config[KEY_ACTIVATED_INDEX] as? Int
+            dialog.config[KEY_ACTIVATED_INDEX] = index
+            if (lastActivated != null) {
+                notifyItemChanged(lastActivated)
+            }
+            notifyItemChanged(index)
+        } else {
+            // Don't wait for action buttons, call listener and dismiss if auto dismiss is applicable
+            this.selection?.invoke(dialog, index, this.items[index])
+            if (dialog.autoDismissEnabled && !dialog.hasActionButtons()) {
+                dialog.dismiss()
+            }
+        }
+    }
+
+    override fun onCreateViewHolder(
+            parent: ViewGroup,
+            viewType: Int): ListItemViewHolder {
+        val listItemView: View = parent.inflate(dialog.windowContext, R.layout.menu_item_sheet)
+        val viewHolder = ListItemViewHolder(
+                itemView = listItemView,
+                adapter = this
+        )
+        viewHolder.titleView.maybeSetTextColor(dialog.windowContext, R.attr.md_color_content)
+        return viewHolder
+    }
+
+    override fun getItemCount() = items.size
+
+    override fun onBindViewHolder(
+            holder: ListItemViewHolder,
+            position: Int) {
+        holder.itemView.isEnabled = !disabledIndices.contains(position)
+        val currentItem = items[position]
+
+        holder.titleView.text = currentItem.title
+        holder.itemView.background = dialog.getItemSelector()
+        currentItem.populateIcon(holder.iconView)
+
+        val activatedIndex = dialog.config[KEY_ACTIVATED_INDEX] as? Int
+        holder.itemView.isActivated = activatedIndex != null && activatedIndex == position
+
+        if (dialog.bodyFont != null) {
+            holder.titleView.typeface = dialog.bodyFont
+        }
+    }
+
+    override fun positiveButtonClicked() {
+        val activatedIndex = dialog.config[KEY_ACTIVATED_INDEX] as? Int
+        if (activatedIndex != null) {
+            selection?.invoke(dialog, activatedIndex, items[activatedIndex])
+            dialog.config.remove(KEY_ACTIVATED_INDEX)
+        }
+    }
+
+    override fun replaceItems(
+            items: List<IT>,
+            listener: ListItemListener<IT>) {
+        this.items = items
+        if (listener != null) {
+            this.selection = listener
+        }
+        this.notifyDataSetChanged()
+    }
+
+    override fun disableItems(indices: IntArray) {
+        this.disabledIndices = indices
+        notifyDataSetChanged()
+    }
+
+    override fun checkItems(indices: IntArray) = Unit
+
+    override fun uncheckItems(indices: IntArray) = Unit
+
+    override fun toggleItems(indices: IntArray) = Unit
+
+    override fun checkAllItems() = Unit
+
+    override fun uncheckAllItems() = Unit
+
+    override fun toggleAllChecked() = Unit
+
+    override fun isItemChecked(index: Int) = false
+}

+ 75 - 0
app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/items/MagicBottomSheets.kt

@@ -0,0 +1,75 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.controllers.bottomsheet.items
+
+import androidx.annotation.CheckResult
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.afollestad.materialdialogs.MaterialDialog
+import com.afollestad.materialdialogs.internal.list.DialogAdapter
+import com.afollestad.materialdialogs.list.customListAdapter
+import com.afollestad.materialdialogs.list.getListAdapter
+
+typealias ListItemListener<IT> =
+        ((dialog: MaterialDialog, index: Int, item: IT) -> Unit)?
+
+@CheckResult fun <IT : ListItemWithImage> MaterialDialog.listItemsWithImage(
+        items: List<IT>,
+        disabledIndices: IntArray? = null,
+        waitForPositiveButton: Boolean = true,
+        selection: ListItemListener<IT> = null): MaterialDialog {
+
+    if (getListAdapter() != null) {
+        return updateListItemsWithImage(
+                items = items,
+                disabledIndices = disabledIndices
+        )
+    }
+
+    val layoutManager = LinearLayoutManager(windowContext)
+    return customListAdapter(
+            adapter = ListIconDialogAdapter(
+                    dialog = this,
+                    items = items,
+                    disabledItems = disabledIndices,
+                    waitForPositiveButton = waitForPositiveButton,
+                    selection = selection
+            ),
+            layoutManager = layoutManager
+    )
+}
+
+fun MaterialDialog.updateListItemsWithImage(
+        items: List<ListItemWithImage>,
+        disabledIndices: IntArray? = null): MaterialDialog {
+    val adapter = getListAdapter()
+    check(adapter != null) {
+        "updateGridItems(...) can't be used before you've created a bottom sheet grid dialog."
+    }
+    if (adapter is DialogAdapter<*, *>) {
+        @Suppress("UNCHECKED_CAST")
+        (adapter as DialogAdapter<ListItemWithImage, *>).replaceItems(items)
+
+        if (disabledIndices != null) {
+            adapter.disableItems(disabledIndices)
+        }
+    }
+    return this
+}

+ 44 - 0
app/src/main/res/layout/menu_item_sheet.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Nextcloud Talk application
+  ~
+  ~ @author Mario Danic
+  ~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
+  ~
+  ~ This program is free software: you can redistribute it and/or modify
+  ~ it under the terms of the GNU 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 General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU General Public License
+  ~ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+  -->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    style="@style/MD_ListItem">
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <ImageView
+            android:id="@+id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:scaleType="center"
+            android:layout_centerVertical="true"
+            tools:src="@drawable/ic_delete_grey600_24dp"
+            android:layout_marginStart="16dp"
+            tools:ignore="ContentDescription"
+            />
+        <com.afollestad.materialdialogs.internal.rtl.RtlTextView
+            android:id="@+id/title"
+            tools:text="Item"
+            android:layout_toEndOf="@id/icon"
+            style="@style/MD_ListItemText" />
+    </RelativeLayout>
+</FrameLayout>