Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[i110] control options icon for each channel #4928

Merged
merged 3 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@

### ✅ Added
- Added `MessageListView.setCustomItemAnimator` to allow customizing the item animator used by the `MessageListView`. [#4926](https://github.com/GetStream/stream-chat-android/pull/4926)
- Added `ChannelListView.setMoreOptionsIconProvider` and `ChannelListView.setDeleteOptionIconProvider` to allow customizing the options icons used by the `ChannelListView`. [#4928](https://github.com/GetStream/stream-chat-android/pull/4928)

### ⚠️ Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,7 @@ public final class io/getstream/chat/android/ui/channel/list/ChannelListView : a
public final fun setChannelListUpdateListener (Lio/getstream/chat/android/ui/channel/list/ChannelListView$ChannelListUpdateListener;)V
public final fun setChannelLongClickListener (Lio/getstream/chat/android/ui/channel/list/ChannelListView$ChannelLongClickListener;)V
public final fun setChannels (Ljava/util/List;)V
public final fun setDeleteOptionIconProvider (Lkotlin/jvm/functions/Function1;)V
public final fun setEmptyStateView (Landroid/view/View;)V
public final fun setEmptyStateView (Landroid/view/View;Landroid/widget/FrameLayout$LayoutParams;)V
public static synthetic fun setEmptyStateView$default (Lio/getstream/chat/android/ui/channel/list/ChannelListView;Landroid/view/View;Landroid/widget/FrameLayout$LayoutParams;ILjava/lang/Object;)V
Expand All @@ -1000,6 +1001,7 @@ public final class io/getstream/chat/android/ui/channel/list/ChannelListView : a
public final fun setLoadingView (Landroid/view/View;Landroid/widget/FrameLayout$LayoutParams;)V
public static synthetic fun setLoadingView$default (Lio/getstream/chat/android/ui/channel/list/ChannelListView;Landroid/view/View;Landroid/widget/FrameLayout$LayoutParams;ILjava/lang/Object;)V
public final fun setMoreOptionsClickListener (Lio/getstream/chat/android/ui/channel/list/ChannelListView$ChannelClickListener;)V
public final fun setMoreOptionsIconProvider (Lkotlin/jvm/functions/Function1;)V
public final fun setOnEndReachedListener (Lio/getstream/chat/android/ui/channel/list/ChannelListView$EndReachedListener;)V
public final fun setPaginationEnabled (Z)V
public final fun setShouldDrawItemSeparatorOnLastItem (Z)V
Expand Down Expand Up @@ -1037,6 +1039,15 @@ public abstract interface class io/getstream/chat/android/ui/channel/list/Channe
public final class io/getstream/chat/android/ui/channel/list/ChannelListView$ChannelLongClickListener$Companion {
}

public abstract interface class io/getstream/chat/android/ui/channel/list/ChannelListView$ChannelOptionIconProvider : kotlin/jvm/functions/Function1 {
public static final field Companion Lio/getstream/chat/android/ui/channel/list/ChannelListView$ChannelOptionIconProvider$Companion;
public static final field DEFAULT Lio/getstream/chat/android/ui/channel/list/ChannelListView$ChannelOptionIconProvider;
public abstract fun invoke (Lio/getstream/chat/android/client/models/Channel;)Landroid/graphics/drawable/Drawable;
}

public final class io/getstream/chat/android/ui/channel/list/ChannelListView$ChannelOptionIconProvider$Companion {
}

public abstract interface class io/getstream/chat/android/ui/channel/list/ChannelListView$ChannelOptionVisibilityPredicate : kotlin/jvm/functions/Function1 {
public static final field Companion Lio/getstream/chat/android/ui/channel/list/ChannelListView$ChannelOptionVisibilityPredicate$Companion;
public static final field DEFAULT Lio/getstream/chat/android/ui/channel/list/ChannelListView$ChannelOptionVisibilityPredicate;
Expand Down Expand Up @@ -1197,11 +1208,17 @@ public abstract class io/getstream/chat/android/ui/channel/list/adapter/viewhold
public fun bind (Lio/getstream/chat/android/ui/channel/list/adapter/ChannelListItem$ChannelItem;Lio/getstream/chat/android/ui/channel/list/adapter/ChannelListPayloadDiff;)V
}

public abstract interface class io/getstream/chat/android/ui/channel/list/adapter/viewholder/ChannelListIconProviderContainer {
public abstract fun getGetDeleteOptionIcon ()Lio/getstream/chat/android/ui/channel/list/ChannelListView$ChannelOptionIconProvider;
public abstract fun getGetMoreOptionsIcon ()Lio/getstream/chat/android/ui/channel/list/ChannelListView$ChannelOptionIconProvider;
}

public class io/getstream/chat/android/ui/channel/list/adapter/viewholder/ChannelListItemViewHolderFactory {
public fun <init> ()V
protected fun createChannelViewHolder (Landroid/view/ViewGroup;)Lio/getstream/chat/android/ui/channel/list/adapter/viewholder/BaseChannelListItemViewHolder;
protected fun createLoadingMoreViewHolder (Landroid/view/ViewGroup;)Lio/getstream/chat/android/ui/channel/list/adapter/viewholder/BaseChannelListItemViewHolder;
public fun createViewHolder (Landroid/view/ViewGroup;I)Lio/getstream/chat/android/ui/channel/list/adapter/viewholder/BaseChannelListItemViewHolder;
protected final fun getIconProviderContainer ()Lio/getstream/chat/android/ui/channel/list/adapter/viewholder/ChannelListIconProviderContainer;
public fun getItemViewType (Lio/getstream/chat/android/ui/channel/list/adapter/ChannelListItem;)I
protected final fun getListenerContainer ()Lio/getstream/chat/android/ui/channel/list/adapter/viewholder/ChannelListListenerContainer;
protected final fun getStyle ()Lio/getstream/chat/android/ui/channel/list/ChannelListViewStyle;
Expand Down
1 change: 1 addition & 0 deletions stream-chat-android-ui-components/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
<ID>MaxLineLength:AutoLinkableTextTransformer.kt$AutoLinkableTextTransformer$*</ID>
<ID>MaxLineLength:AvatarView.kt$AvatarView$*</ID>
<ID>MaxLineLength:ChannelActionsDialogViewStyle.kt$ChannelActionsDialogViewStyle$*</ID>
<ID>MaxLineLength:ChannelListIconProviderContainerImpl.kt$ChannelListIconProviderContainerImpl$override</ID>
<ID>MaxLineLength:ChannelListView.kt$ChannelListView$is ChannelListViewModel.ErrorEvent.DeleteChannelError -> R.string.stream_ui_channel_list_error_delete_channel</ID>
<ID>MaxLineLength:ChannelListViewModel.kt$ChannelListViewModel$*</ID>
<ID>MaxLineLength:ChannelListViewModelFactory.kt$ChannelListViewModelFactory$*</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import kotlin.reflect.KProperty
* wrapped can be referenced by calling the realListener() method. This
* function always returns the current listener, even if it changes.
*/
// TODO Needs to be renamed to something like WrapDelegate. It is no longer used for listeners only.
@InternalStreamChatApi
public class ListenerDelegate<L : Any>(
initialValue: L,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.getstream.chat.android.ui.channel.list

import android.content.Context
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Parcelable
import android.util.AttributeSet
Expand Down Expand Up @@ -314,6 +315,24 @@ public class ChannelListView : FrameLayout {
simpleChannelListView.setIsDeleteOptionVisible(isDeleteOptionVisible)
}

/**
* Allows clients to override a "more options" icon in ViewHolder items.
*
* @param getMoreOptionsIcon Provides icon for a "more options".
*/
public fun setMoreOptionsIconProvider(getMoreOptionsIcon: (Channel) -> Drawable?) {
simpleChannelListView.setMoreOptionsIconProvider(getMoreOptionsIcon)
}

/**
* Allows clients to override a "delete option" icon in ViewHolder items.
*
* @param getDeleteOptionIcon Provides icon for delete option.
*/
public fun setDeleteOptionIconProvider(getDeleteOptionIcon: (Channel) -> Drawable?) {
simpleChannelListView.setDeleteOptionIconProvider(getDeleteOptionIcon)
}

/**
* Allows a client to set a click listener to be notified of "channel info" clicks in the "more options" menu.
*
Expand Down Expand Up @@ -533,7 +552,25 @@ public class ChannelListView : FrameLayout {
*
* @return True if the option is visible.
*/
override fun invoke(p1: Channel): Boolean
override fun invoke(channel: Channel): Boolean
}

public fun interface ChannelOptionIconProvider : Function1<Channel, Drawable?> {

public companion object {
@JvmField
public val DEFAULT: ChannelOptionIconProvider = ChannelOptionIconProvider {
// option has no customized icon by default
null
}
}

/**
* Called to provide option's icon for the specified [channel].
*
* @return Drawable which overrides ChannelListViewStyle values.
*/
override fun invoke(channel: Channel): Drawable?
}

public fun interface EndReachedListener {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2014-2022 Stream.io Inc. All rights reserved.
*
* Licensed under the Stream License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.getstream.chat.android.ui.channel.list.adapter.viewholder

import io.getstream.chat.android.ui.channel.list.ChannelListView.ChannelOptionIconProvider

public sealed interface ChannelListIconProviderContainer {
public val getMoreOptionsIcon: ChannelOptionIconProvider
public val getDeleteOptionIcon: ChannelOptionIconProvider
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2014-2022 Stream.io Inc. All rights reserved.
*
* Licensed under the Stream License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.getstream.chat.android.ui.channel.list.adapter.viewholder

import com.getstream.sdk.chat.utils.ListenerDelegate
import io.getstream.chat.android.ui.channel.list.ChannelListView.ChannelOptionIconProvider

internal class ChannelListIconProviderContainerImpl(
getMoreOptionsIcon: ChannelOptionIconProvider = ChannelOptionIconProvider.DEFAULT,
getDeleteOptionIcon: ChannelOptionIconProvider = ChannelOptionIconProvider.DEFAULT,
) : ChannelListIconProviderContainer {

override var getMoreOptionsIcon: ChannelOptionIconProvider by ListenerDelegate(getMoreOptionsIcon) { realPredicate ->
ChannelOptionIconProvider { channel ->
realPredicate().invoke(channel)
}
}

override var getDeleteOptionIcon: ChannelOptionIconProvider by ListenerDelegate(getDeleteOptionIcon) { realPredicate ->
ChannelOptionIconProvider { channel ->
realPredicate().invoke(channel)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public open class ChannelListItemViewHolderFactory {
protected lateinit var visibilityContainer: ChannelListVisibilityContainer
private set

protected lateinit var iconProviderContainer: ChannelListIconProviderContainer
private set

protected lateinit var style: ChannelListViewStyle
private set

Expand All @@ -43,6 +46,10 @@ public open class ChannelListItemViewHolderFactory {
this.visibilityContainer = visibilityContainer
}

internal fun setIconProviderContainer(iconProviderContainer: ChannelListIconProviderContainer) {
this.iconProviderContainer = iconProviderContainer
}

internal fun setStyle(style: ChannelListViewStyle) {
this.style = style
}
Expand Down Expand Up @@ -89,6 +96,8 @@ public open class ChannelListItemViewHolderFactory {
style,
visibilityContainer.isMoreOptionsVisible,
visibilityContainer.isDeleteOptionVisible,
iconProviderContainer.getMoreOptionsIcon,
iconProviderContainer.getDeleteOptionIcon,
)
}

Expand All @@ -106,6 +115,9 @@ public open class ChannelListItemViewHolderFactory {
if (!::visibilityContainer.isInitialized) {
visibilityContainer = ChannelListVisibilityContainerImpl()
}
if (!::iconProviderContainer.isInitialized) {
iconProviderContainer = ChannelListIconProviderContainerImpl()
}
if (!::style.isInitialized) {
style = ChannelListViewStyle(context, null)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ internal class ChannelViewHolder @JvmOverloads constructor(
private val swipeListener: ChannelListView.SwipeListener,
private val style: ChannelListViewStyle,
private val isMoreOptionsVisible: ChannelListView.ChannelOptionVisibilityPredicate,
private val isDeleteOptionsVisible: ChannelListView.ChannelOptionVisibilityPredicate,
private val isDeleteOptionVisible: ChannelListView.ChannelOptionVisibilityPredicate,
private val getMoreOptionsIcon: ChannelListView.ChannelOptionIconProvider,
private val getDeleteOptionIcon: ChannelListView.ChannelOptionIconProvider,
private val binding: StreamUiChannelListItemViewBinding = StreamUiChannelListItemViewBinding.inflate(
parent.streamThemeInflater,
parent,
Expand Down Expand Up @@ -188,15 +190,17 @@ internal class ChannelViewHolder @JvmOverloads constructor(
binding.itemBackgroundView.moreOptionsImageView.apply {
if (style.optionsEnabled && isMoreOptionsVisible(channel)) {
isVisible = true
getMoreOptionsIcon.invoke(channel)?.also { setImageDrawable(it) }
optionsCount++
} else {
isVisible = false
}
}
binding.itemBackgroundView.deleteImageView.apply {
val canDeleteChannel = channel.ownCapabilities.contains(ChannelCapabilities.DELETE_CHANNEL)
if (style.deleteEnabled && canDeleteChannel && isDeleteOptionsVisible(channel)) {
if (style.deleteEnabled && canDeleteChannel && isDeleteOptionVisible(channel)) {
isVisible = true
getDeleteOptionIcon.invoke(channel)?.also { setImageDrawable(it) }
optionsCount++
} else {
isVisible = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import io.getstream.chat.android.ui.channel.list.ChannelListView
import io.getstream.chat.android.ui.channel.list.ChannelListViewStyle
import io.getstream.chat.android.ui.channel.list.adapter.ChannelListItem
import io.getstream.chat.android.ui.channel.list.adapter.internal.ChannelListItemAdapter
import io.getstream.chat.android.ui.channel.list.adapter.viewholder.ChannelListIconProviderContainerImpl
import io.getstream.chat.android.ui.channel.list.adapter.viewholder.ChannelListItemViewHolderFactory
import io.getstream.chat.android.ui.channel.list.adapter.viewholder.ChannelListListenerContainerImpl
import io.getstream.chat.android.ui.channel.list.adapter.viewholder.ChannelListVisibilityContainerImpl
Expand Down Expand Up @@ -57,6 +58,8 @@ internal class SimpleChannelListView @JvmOverloads constructor(

internal val visibilityContainer = ChannelListVisibilityContainerImpl()

internal val iconProviderContainer = ChannelListIconProviderContainerImpl()

private lateinit var style: ChannelListViewStyle

init {
Expand Down Expand Up @@ -100,6 +103,7 @@ internal class SimpleChannelListView @JvmOverloads constructor(

viewHolderFactory.setListenerContainer(this.listenerContainer)
viewHolderFactory.setVisibilityContainer(this.visibilityContainer)
viewHolderFactory.setIconProviderContainer(this.iconProviderContainer)
viewHolderFactory.setStyle(style)

adapter = ChannelListItemAdapter(viewHolderFactory)
Expand Down Expand Up @@ -146,6 +150,14 @@ internal class SimpleChannelListView @JvmOverloads constructor(
visibilityContainer.isDeleteOptionVisible = isDeleteOptionVisible
}

fun setMoreOptionsIconProvider(getMoreOptionsIcon: ChannelListView.ChannelOptionIconProvider) {
iconProviderContainer.getMoreOptionsIcon = getMoreOptionsIcon
}

fun setDeleteOptionIconProvider(getDeleteOptionIcon: ChannelListView.ChannelOptionIconProvider) {
iconProviderContainer.getDeleteOptionIcon = getDeleteOptionIcon
}

fun setSwipeListener(listener: ChannelListView.SwipeListener?) {
listenerContainer.swipeListener = listener ?: ChannelListView.SwipeListener.DEFAULT
}
Expand Down